private DiaNavigationData GetDiaNavigationData(MethodDebugInformationHandle handle) { if (this.reader == null) { throw new ObjectDisposedException(nameof(PortablePdbReader)); } DiaNavigationData diaNavigationData = null; try { var methodDebugDefinition = this.reader.GetMethodDebugInformation(handle); var fileName = this.GetMethodFileName(methodDebugDefinition); int minLineNumber, maxLineNumber; GetMethodMinAndMaxLineNumber(methodDebugDefinition, out minLineNumber, out maxLineNumber); diaNavigationData = new DiaNavigationData(fileName, minLineNumber, maxLineNumber); } catch (BadImageFormatException exception) { EqtTrace.Error("failed to get dia navigation data: {0}", exception); } return(diaNavigationData); }
private DiaNavigationData GetSymbolNavigationData(IDiaSymbol symbol) { ValidateArg.NotNull(symbol, "symbol"); DiaNavigationData navigationData = new DiaNavigationData(null, int.MaxValue, int.MinValue); IDiaEnumLineNumbers lines = null; try { this.session.findLinesByAddr(symbol.addressSection, symbol.addressOffset, (uint)symbol.length, out lines); uint celt; IDiaLineNumber lineNumber; while (true) { lines.Next(1, out lineNumber, out celt); if (celt != 1) { break; } IDiaSourceFile sourceFile = null; try { sourceFile = lineNumber.sourceFile; // The magic hex constant below works around weird data reported from GetSequencePoints. // The constant comes from ILDASM's source code, which performs essentially the same test. const uint Magic = 0xFEEFEE; if (lineNumber.lineNumber >= Magic || lineNumber.lineNumberEnd >= Magic) { continue; } navigationData.FileName = sourceFile.fileName; navigationData.MinLineNumber = Math.Min(navigationData.MinLineNumber, (int)lineNumber.lineNumber); navigationData.MaxLineNumber = Math.Max(navigationData.MaxLineNumber, (int)lineNumber.lineNumberEnd); } finally { ReleaseComObject(ref sourceFile); ReleaseComObject(ref lineNumber); } } } finally { ReleaseComObject(ref lines); } return(navigationData); }
public void GetNavigationDataShouldReturnCorrectDataForAsyncMethod() { var currentTargetFrameWork = GetAndSetTargetFrameWork(this.testEnvironment); var assemblyPath = this.GetAssetFullPath("SimpleClassLibrary.dll"); DiaSession diaSession = new DiaSession(assemblyPath); DiaNavigationData diaNavigationData = diaSession.GetNavigationData("SimpleClassLibrary.Class1+<AsyncTestMethod>d__1", "MoveNext"); Assert.IsNotNull(diaNavigationData, "Failed to get navigation data"); StringAssert.EndsWith(diaNavigationData.FileName, @"\SimpleClassLibrary\Class1.cs"); this.ValidateMinLineNumber(17, diaNavigationData.MinLineNumber); Assert.AreEqual(19, diaNavigationData.MaxLineNumber, "Incorrect max line number"); this.testEnvironment.TargetFramework = currentTargetFrameWork; }
public void GetNavigationDataShouldReturnCorrectFileNameAndLineNumber() { var currentTargetFrameWork = GetAndSetTargetFrameWork(this.testEnvironment); var assemblyPath = GetAssetFullPath("SimpleClassLibrary.dll"); DiaSession diaSession = new DiaSession(assemblyPath); DiaNavigationData diaNavigationData = diaSession.GetNavigationData("SimpleClassLibrary.Class1", "PassingTest"); Assert.IsNotNull(diaNavigationData, "Failed to get navigation data"); StringAssert.EndsWith(diaNavigationData.FileName, @"\SimpleClassLibrary\Class1.cs"); Assert.AreEqual(12, diaNavigationData.MinLineNumber, "Incorrect min line number"); Assert.AreEqual(14, diaNavigationData.MaxLineNumber, "Incorrect max line number"); this.testEnvironment.TargetFramework = currentTargetFrameWork; }
public void GetNavigationDataShouldReturnCorrectDataForOverLoadedMethod() { var currentTargetFrameWork = GetAndSetTargetFrameWork(this.testEnvironment); var assemblyPath = this.GetAssetFullPath("SimpleClassLibrary.dll"); DiaSession diaSession = new DiaSession(assemblyPath); DiaNavigationData diaNavigationData = diaSession.GetNavigationData("SimpleClassLibrary.Class1", "OverLoadedMethod"); Assert.IsNotNull(diaNavigationData, "Failed to get navigation data"); StringAssert.EndsWith(diaNavigationData.FileName, @"\SimpleClassLibrary\Class1.cs"); // Weird why DiaSession is now returning the first overloaded method // as compared to before when it used to return second method this.ValidateLineNumbers(diaNavigationData.MinLineNumber, diaNavigationData.MaxLineNumber); this.testEnvironment.TargetFramework = currentTargetFrameWork; }
public void it_should_return_no_navigation_data() { DiaNavigationData expected = new DiaNavigationData(String.Empty, 0, 0); SampleDebugInfo.ByClassActionName.Keys.Do(declaringClassName => { var actionInfos = SampleDebugInfo.ByClassActionName[declaringClassName]; actionInfos.Keys.Do(actionName => { DiaNavigationData actual = provider.GetNavigationData(declaringClassName, actionName); actual.ShouldBeEquivalentTo(expected, "ClassName: {0}, MethodName: {1}", declaringClassName, actionName); }); }); }
public void GetNavigationDataShouldReturnNullForNotExistMethodNameOrNotExistTypeName() { var currentTargetFrameWork = GetAndSetTargetFrameWork(this.testEnvironment); var assemblyPath = GetAssetFullPath("SimpleClassLibrary.dll"); DiaSession diaSession = new DiaSession(assemblyPath); // Not exist method name DiaNavigationData diaNavigationData = diaSession.GetNavigationData("SimpleClassLibrary.Class1", "NotExistMethod"); Assert.IsNull(diaNavigationData); // Not Exist Type name diaNavigationData = diaSession.GetNavigationData("SimpleClassLibrary.NotExistType", "PassingTest"); Assert.IsNull(diaNavigationData); this.testEnvironment.TargetFramework = currentTargetFrameWork; }
public virtual void before_each() { autoSubstitute = new AutoSubstitute(); debugInfoProvider = autoSubstitute.Resolve <IDebugInfoProvider>(); string specClassName = this.GetType().ToString(); string exampleMethodName = fixtureData.MethodName; var navigationData = new DiaNavigationData(someSourceCodePath, someLineNumber, someLineNumber + 4); var emptyNavigationData = new DiaNavigationData(String.Empty, 0, 0); debugInfoProvider.GetNavigationData(null, null).ReturnsForAnyArgs(emptyNavigationData); debugInfoProvider.GetNavigationData( Arg.Is <string>(arg => arg.StartsWith(specClassName, StringComparison.Ordinal)), exampleMethodName).Returns(navigationData); mapper = new DiscoveredExampleMapper(someAssemblyPath, debugInfoProvider); }
public void DiaSessionPerfTest() { var currentTargetFrameWork = GetAndSetTargetFrameWork(this.testEnvironment); var assemblyPath = this.GetAssetFullPath("SimpleClassLibrary.dll"); var watch = Stopwatch.StartNew(); DiaSession diaSession = new DiaSession(assemblyPath); DiaNavigationData diaNavigationData = diaSession.GetNavigationData("SimpleClassLibrary.HugeMethodSet", "MSTest_D1_01"); watch.Stop(); Assert.IsNotNull(diaNavigationData, "Failed to get navigation data"); StringAssert.EndsWith(diaNavigationData.FileName, @"\SimpleClassLibrary\HugeMethodSet.cs"); this.ValidateMinLineNumber(9, diaNavigationData.MinLineNumber); Assert.AreEqual(10, diaNavigationData.MaxLineNumber); var expectedTime = 150; Assert.IsTrue(watch.Elapsed.Milliseconds < expectedTime, string.Format("DiaSession Perf test Actual time:{0} ms Expected time:{1} ms", watch.Elapsed.Milliseconds, expectedTime)); this.testEnvironment.TargetFramework = currentTargetFrameWork; }
/// <summary> /// Extracts the data. /// </summary> /// <param name="type">The type.</param> /// <param name="method">The method.</param> /// <returns>The discovery information.</returns> internal DiscoveryInfo ExtractData(Type type, MethodInfo method) { if (method == null) { throw new ArgumentNullException(nameof(method)); } if (method.DeclaringType == null) { return(null); } DiscoveryInfo info = new DiscoveryInfo { AssemblyQualifiedName = method.DeclaringType.AssemblyQualifiedName, AssemblyPath = this.pathUnderInvestigation, AssemblyName = method.Module.Name, Namespace = method.DeclaringType.Namespace, ClassName = type.Name, MethodName = method.Name }; IEnumerable <TagAttribute> tagAttributesClass = type.GetCustomAttributes <TagAttribute>(false); IEnumerable <TagAttribute> tagAttributesMethod = method.GetCustomAttributes <TagAttribute>(false); AddTags(info, tagAttributesClass as TagAttribute[], tagAttributesMethod as TagAttribute[]); DiaNavigationData data = this.AnalyzeDiaData(string.Concat(info.Namespace, ".", type.Name), method.Name); if (data == null) { return(info); } info.LineOfCode = data.MinLineNumber; info.ClassFilePath = data.FileName; return(info); }
static TestCase GetTestCase(string source, XmlNode methodNode) { string typeName = methodNode.Attributes["type"].Value; string methodName = methodNode.Attributes["method"].Value; string displayName = methodNode.Attributes["name"].Value; string fullyQualifiedName = typeName + "." + methodName; TestCase testCase = new TestCase(fullyQualifiedName, uri) { DisplayName = GetDisplayName(displayName, methodName, fullyQualifiedName), Source = source, }; try { using (DiaSession diaSession = new DiaSession(source)) { DiaNavigationData navigationData = diaSession.GetNavigationData(typeName, methodName); testCase.CodeFilePath = navigationData.FileName; testCase.LineNumber = navigationData.MinLineNumber; } } catch { } // DiaSession throws if the PDB file is missing or corrupt return(testCase); }
private DiaNavigationData GetSymbolNavigationData(IDiaSymbol symbol) { ValidateArg.NotNull(symbol, "symbol"); DiaNavigationData navigationData = new DiaNavigationData(null, int.MaxValue, int.MinValue); IDiaEnumLineNumbers lines = null; try { // Get the address section if (HResult.Failed(symbol.GetAddressSection(out uint section))) { return(navigationData); } // Get the address offset if (HResult.Failed(symbol.GetAddressOffset(out uint offset))) { return(navigationData); } // Get the length of the symbol if (HResult.Failed(symbol.GetLength(out long length))) { return(navigationData); } this.session.FindLinesByAddress(section, offset, (uint)length, out lines); while (true) { lines.GetNext(1, out IDiaLineNumber lineNumber, out uint celt); if (celt != 1) { break; } IDiaSourceFile sourceFile = null; try { lineNumber.GetSourceFile(out sourceFile); // Get startline lineNumber.GetLineNumber(out uint startLine); // Get endline lineNumber.GetLineNumberEnd(out uint endLine); // The magic hex constant below works around weird data reported from GetSequencePoints. // The constant comes from ILDASM's source code, which performs essentially the same test. const uint Magic = 0xFEEFEE; if (startLine >= Magic || endLine >= Magic) { continue; } sourceFile.GetFilename(out var srcFileName); navigationData.FileName = srcFileName; navigationData.MinLineNumber = Math.Min(navigationData.MinLineNumber, (int)startLine); navigationData.MaxLineNumber = Math.Max(navigationData.MaxLineNumber, (int)endLine); } finally { ReleaseComObject(ref sourceFile); ReleaseComObject(ref lineNumber); } } } finally { ReleaseComObject(ref lines); } return(navigationData); }