public void GetBranchPoints_ExceptionFilter() { // arrange var type = _module.Types.Single(x => x.FullName == typeof(ExceptionFilter).FullName); var method = type.Methods.Single(x => x.FullName.Contains($"::{nameof(ExceptionFilter.Test)}")); // act var points = CecilSymbolHelper.GetBranchPoints(method); Assert.Empty(points); }
public void GetBranchPoints_GeneratedBranches_DueToCachedAnonymousMethodDelegate_Ignored() { // arrange var type = _module.Types.First(x => x.FullName == typeof(DeclaredConstructorClass).FullName); var method = type.Methods.First(x => x.FullName.Contains($"::{nameof(DeclaredConstructorClass.HasSimpleTaskWithLambda)}")); // act var points = CecilSymbolHelper.GetBranchPoints(method); Assert.Empty(points); }
public void GetBranchPoints_Using_Where_GeneratedBranchesIgnored() { // arrange var type = _module.Types.First(x => x.FullName == typeof(DeclaredConstructorClass).FullName); var method = type.Methods.First(x => x.FullName.Contains($"::{nameof(DeclaredConstructorClass.HasSimpleUsingStatement)}")); // act var points = CecilSymbolHelper.GetBranchPoints(method); Assert.Equal(2, points.Count()); }
public CecilSymbolHelperTests() { string location = GetType().Assembly.Location; _resolver = new DefaultAssemblyResolver(); _resolver.AddSearchDirectory(Path.GetDirectoryName(location)); _parameters = new ReaderParameters { ReadSymbols = true, AssemblyResolver = _resolver }; _module = ModuleDefinition.ReadModule(location, _parameters); _cecilSymbolHelper = new CecilSymbolHelper(); }
public void GetBranchPoints_IgnoresBranchesIn_AsyncAwaitStateMachine() { // arrange var nestedName = typeof(AsyncAwaitStateMachine).GetNestedTypes(BindingFlags.NonPublic).First().Name; var type = _module.Types.FirstOrDefault(x => x.FullName == typeof(AsyncAwaitStateMachine).FullName); var nestedType = type.NestedTypes.FirstOrDefault(x => x.FullName.EndsWith(nestedName)); var method = nestedType.Methods.First(x => x.FullName.EndsWith("::MoveNext()")); // act var points = CecilSymbolHelper.GetBranchPoints(method); // assert Assert.Empty(points); }
public void GetBranchPoints_CompleteIf() { // arrange var type = _module.Types.First(x => x.FullName == typeof(DeclaredConstructorClass).FullName); var method = type.Methods.First(x => x.FullName.Contains($"::{nameof(DeclaredConstructorClass.HasCompleteIf)}")); // act var points = CecilSymbolHelper.GetBranchPoints(method); // assert Assert.NotNull(points); Assert.Equal(2, points.Count()); Assert.Equal(points[0].Offset, points[1].Offset); Assert.Equal(34, points[0].StartLine); Assert.Equal(34, points[1].StartLine); }
public void GetBranchPoints_TwoBranch() { // arrange var type = _module.Types.First(x => x.FullName == typeof(DeclaredConstructorClass).FullName); var method = type.Methods.First(x => x.FullName.Contains("::HasTwoDecisions")); // act var points = CecilSymbolHelper.GetBranchPoints(method); // assert Assert.NotNull(points); Assert.Equal(4, points.Count()); Assert.Equal(points[0].Offset, points[1].Offset); Assert.Equal(points[2].Offset, points[3].Offset); Assert.Equal(27, points[0].StartLine); Assert.Equal(28, points[2].StartLine); }
public void Prepare(Project testProject, ConfigurationSelector configuration, DataCollectorSettings coverageSettings) { var unitTestDll = testProject.GetOutputFileName(configuration).ToString(); var sourceRootTranslator = new SourceRootTranslator(logger, fileSystem); var cecilSymbolHelper = new CecilSymbolHelper(); var instrumentationHelper = new InstrumentationHelper(new ProcessExitHandler(), new RetryHelper(), fileSystem, logger, sourceRootTranslator); var coverageParameters = GetCoverageParameters(coverageSettings); var coverage = new CoverletCoverage(unitTestDll, coverageParameters, logger, instrumentationHelper, fileSystem, sourceRootTranslator, cecilSymbolHelper); coverage.PrepareModules(); projectCoverageMap[new Tuple <Project, ConfigurationSelector>(testProject, configuration)] = coverage; }
public void GetBranchPoints_OneBranch() { // arrange var type = _module.Types.First(x => x.FullName == typeof(DeclaredConstructorClass).FullName); var method = type.Methods.First(x => x.FullName.Contains($"::{nameof(DeclaredConstructorClass.HasSingleDecision)}")); // act var points = CecilSymbolHelper.GetBranchPoints(method); // assert Assert.NotNull(points); Assert.Equal(2, points.Count()); Assert.Equal(points[0].Offset, points[1].Offset); Assert.Equal(0, points[0].Path); Assert.Equal(1, points[1].Path); Assert.Equal(21, points[0].StartLine); Assert.Equal(21, points[1].StartLine); Assert.NotNull(points[1].Document); Assert.Equal(points[0].Document, points[1].Document); }
public void GetBranchPoints_UsingWithException_Issue243_IgnoresBranchInFinallyBlock() { // arrange var type = _module.Types.First(x => x.FullName == typeof(DeclaredConstructorClass).FullName); var method = type.Methods.First(x => x.FullName.Contains($"::{nameof(DeclaredConstructorClass.UsingWithException_Issue243)}")); // check that the method is laid out the way we discovered it to be during the defect // @see https://github.com/OpenCover/opencover/issues/243 Assert.Single(method.Body.ExceptionHandlers); Assert.NotNull(method.Body.ExceptionHandlers[0].HandlerStart); Assert.Null(method.Body.ExceptionHandlers[0].HandlerEnd); Assert.Equal(1, method.Body.Instructions.Count(i => i.OpCode.FlowControl == FlowControl.Cond_Branch)); Assert.True(method.Body.Instructions.First(i => i.OpCode.FlowControl == FlowControl.Cond_Branch).Offset > method.Body.ExceptionHandlers[0].HandlerStart.Offset); // act var points = CecilSymbolHelper.GetBranchPoints(method); // assert Assert.Empty(points); }
public void GetBranchPoints_AssignsNegativeLineNumberToBranchesInMethodsThatHaveNoInstrumentablePoints() { /* * Yes these actually exist - the compiler is very inventive * in this case for an anonymous class the compiler will dynamically create an Equals 'utility' method. */ // arrange var type = _module.Types.First(x => x.FullName.Contains("f__AnonymousType")); var method = type.Methods.First(x => x.FullName.Contains("::Equals")); // act var points = CecilSymbolHelper.GetBranchPoints(method); // assert Assert.NotNull(points); foreach (var branchPoint in points) { Assert.Equal(-1, branchPoint.StartLine); } }
public void GetBranchPoints_SwitchWithBreaks() { // arrange var type = _module.Types.First(x => x.FullName == typeof(DeclaredConstructorClass).FullName); var method = type.Methods.First(x => x.FullName.Contains($"::{nameof(DeclaredConstructorClass.HasSwitchWithBreaks)}")); // act var points = CecilSymbolHelper.GetBranchPoints(method); // assert Assert.NotNull(points); Assert.Equal(4, points.Count()); Assert.Equal(points[0].Offset, points[1].Offset); Assert.Equal(points[0].Offset, points[2].Offset); Assert.Equal(3, points[3].Path); Assert.Equal(76, points[0].StartLine); Assert.Equal(76, points[1].StartLine); Assert.Equal(76, points[2].StartLine); Assert.Equal(76, points[3].StartLine); }
private void InstrumentIL(MethodDefinition method) { method.Body.SimplifyMacros(); ILProcessor processor = method.Body.GetILProcessor(); var index = 0; var count = processor.Body.Instructions.Count; var branchPoints = CecilSymbolHelper.GetBranchPoints(method); for (int n = 0; n < count; n++) { var instruction = processor.Body.Instructions[index]; var sequencePoint = method.DebugInformation.GetSequencePoint(instruction); var targetedBranchPoints = branchPoints.Where(p => p.EndOffset == instruction.Offset); if (sequencePoint != null && !sequencePoint.IsHidden) { var target = AddInstrumentationCode(method, processor, instruction, sequencePoint); foreach (var _instruction in processor.Body.Instructions) { ReplaceInstructionTarget(_instruction, instruction, target); } foreach (ExceptionHandler handler in processor.Body.ExceptionHandlers) { ReplaceExceptionHandlerBoundary(handler, instruction, target); } index += 2; } foreach (var _branchTarget in targetedBranchPoints) { /* * Skip branches with no sequence point reference for now. * In this case for an anonymous class the compiler will dynamically create an Equals 'utility' method. * The CecilSymbolHelper will create branch points with a start line of -1 and no document, which * I am currently not sure how to handle. */ if (_branchTarget.StartLine == -1 || _branchTarget.Document == null) { continue; } var target = AddInstrumentationCode(method, processor, instruction, _branchTarget); foreach (var _instruction in processor.Body.Instructions) { ReplaceInstructionTarget(_instruction, instruction, target); } foreach (ExceptionHandler handler in processor.Body.ExceptionHandlers) { ReplaceExceptionHandlerBoundary(handler, instruction, target); } index += 2; } index++; } method.Body.OptimizeMacros(); }