Esempio n. 1
0
        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);
        }
Esempio n. 2
0
        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);
        }
Esempio n. 3
0
        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;
        }
Esempio n. 4
0
        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;
        }
Esempio n. 5
0
        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);
                });
            });
        }
Esempio n. 7
0
        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;
        }
Esempio n. 8
0
        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);
        }
Esempio n. 9
0
        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);
        }
Esempio n. 11
0
        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);
        }
Esempio n. 12
0
        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);
        }