コード例 #1
0
        public async Task Should_Allow_The_CoverageOutputManager_To_SetProjectCoverageOutputFolder()
        {
            var mockCoverageToolOutputManager = mocker.GetMock <ICoverageToolOutputManager>();

            mockCoverageToolOutputManager.Setup(om => om.SetProjectCoverageOutputFolder(It.IsAny <List <ICoverageProject> >())).
            Callback <List <ICoverageProject> >(coverageProjects =>
            {
                coverageProjects[0].CoverageOutputFolder = "Set by ICoverageToolOutputManager";
            });

            ICoverageProject coverageProjectAfterCoverageOutputManager = null;
            var coverageUtilManager = mocker.GetMock <ICoverageUtilManager>();

            coverageUtilManager.Setup(mgr => mgr.RunCoverageAsync(It.IsAny <ICoverageProject>(), It.IsAny <CancellationToken>()))
            .Callback <ICoverageProject, CancellationToken>((cp, _) =>
            {
                coverageProjectAfterCoverageOutputManager = cp;
            });

            await ReloadSuitableCoverageProject(mockCoverageProject => {
                mockCoverageProject.SetupProperty(cp => cp.CoverageOutputFolder);
                mockCoverageProject.Setup(p => p.StepAsync("Run Coverage Tool", It.IsAny <Func <ICoverageProject, Task> >())).Callback <string, Func <ICoverageProject, Task> >((_, runCoverTool) =>
                {
                    runCoverTool(mockCoverageProject.Object);
                });
            });

            Assert.AreEqual(coverageProjectAfterCoverageOutputManager.CoverageOutputFolder, "Set by ICoverageToolOutputManager");
        }
コード例 #2
0
        public async Task RunAsync(ICoverageProject project, CancellationToken cancellationToken)
        {
            var title = $"Coverlet Run ({project.ProjectName})";

            var coverletSettings = GetCoverletSettings(project);

            logger.Log($"{title} Arguments {Environment.NewLine}{string.Join($"{Environment.NewLine}", coverletSettings)}");

            var result = await processUtil
                         .ExecuteAsync(GetExecuteRequest(project, string.Join(" ", coverletSettings)), cancellationToken);



            /*
             * 0 - Success.
             * 1 - If any test fails.
             * 2 - Coverage percentage is below threshold.
             * 3 - Test fails and also coverage percentage is below threshold.
             */
            if (result.ExitCode > 3)
            {
                logger.Log($"{title} Error. Exit code: {result.ExitCode}");
                logger.Log($"{title} Error. Output: ", result.Output);

                throw new Exception(result.Output);
            }

            logger.Log(title, result.Output);
        }
コード例 #3
0
        internal List <string> GetCoverletSettings(ICoverageProject project)
        {
            var coverletSettings = new List <string>();

            coverletSettings.Add($@"""{project.TestDllFile}""");

            coverletSettings.Add($@"--format ""cobertura""");

            foreach (var value in (project.Settings.Exclude ?? new string[0]).Where(x => !string.IsNullOrWhiteSpace(x)))
            {
                coverletSettings.Add($@"--exclude ""{value.Replace("\"", "\\\"").Trim(' ', '\'')}""");
            }

            foreach (var referencedProjectExcludedFromCodeCoverage in project.ExcludedReferencedProjects)
            {
                coverletSettings.Add($@"--exclude ""[{referencedProjectExcludedFromCodeCoverage}]*""");
            }

            foreach (var value in (project.Settings.Include ?? new string[0]).Where(x => !string.IsNullOrWhiteSpace(x)))
            {
                coverletSettings.Add($@"--include ""{value.Replace("\"", "\\\"").Trim(' ', '\'')}""");
            }

            foreach (var includedReferencedProject in project.IncludedReferencedProjects)
            {
                coverletSettings.Add($@"--include ""[{includedReferencedProject}]*""");
            }

            foreach (var value in (project.Settings.ExcludeByFile ?? new string[0]).Where(x => !string.IsNullOrWhiteSpace(x)))
            {
                coverletSettings.Add($@"--exclude-by-file ""{value.Replace("\"", "\\\"").Trim(' ', '\'')}""");
            }

            foreach (var value in (project.Settings.ExcludeByAttribute ?? new string[0]).Where(x => !string.IsNullOrWhiteSpace(x)))
            {
                coverletSettings.Add($@"--exclude-by-attribute ""{value.Replace("\"", "\\\"").Trim(' ', '\'', '[', ']')}""");
            }

            if (project.Settings.IncludeTestAssembly)
            {
                coverletSettings.Add("--include-test-assembly");
            }

            coverletSettings.Add($@"--target ""dotnet""");

            coverletSettings.Add($@"--threshold-type line");

            coverletSettings.Add($@"--threshold-stat total");

            coverletSettings.Add($@"--threshold 0");

            coverletSettings.Add($@"--output ""{ project.CoverageOutputFile }""");

            var runSettings = !string.IsNullOrWhiteSpace(project.RunSettingsFile) ? $@"--settings """"{project.RunSettingsFile}""""" : default;

            coverletSettings.Add($@"--targetargs ""test  """"{project.TestDllFile}"""" --nologo --blame {runSettings} --results-directory """"{project.CoverageOutputFolder}"""" --diag """"{project.CoverageOutputFolder}/diagnostics.log""""  """);

            return(coverletSettings);
        }
コード例 #4
0
 public Task RunCoverletAsync(ICoverageProject project, CancellationToken cancellationToken)
 {
     if (coverletDataCollectorUtil.CanUseDataCollector(project))
     {
         return(coverletDataCollectorUtil.RunAsync(cancellationToken));
     }
     return(coverletGlobalUtil.RunAsync(project, cancellationToken));
 }
コード例 #5
0
        public async Task <IAppOptions> GetSettingsAsync(ICoverageProject coverageProject)
        {
            var projectDirectory       = Path.GetDirectoryName(coverageProject.ProjectFile);
            var settingsFilesElements  = fccSettingsFilesProvider.Provide(projectDirectory);
            var projectSettingsElement = await coverageProjectSettingsProvider.ProvideAsync(coverageProject);

            return(settingsMerger.Merge(appOptionsProvider.Get(), settingsFilesElements, projectSettingsElement));
        }
コード例 #6
0
 public Task <bool> RunCoverletAsync(ICoverageProject project, bool throwError = false)
 {
     if (coverletDataCollectorUtil.CanUseDataCollector(project))
     {
         return(coverletDataCollectorUtil.RunAsync(throwError));
     }
     return(coverletGlobalUtil.RunAsync(project, throwError));
 }
コード例 #7
0
 private XElement ProjectSettingsElementFromFCCLabelledPropertyGroup(ICoverageProject coverageProject)
 {
     /*
      * <PropertyGroup Label="FineCodeCoverage">
      *  ...
      * </PropertyGroup>
      */
     return(coverageProject.ProjectFileXElement.XPathSelectElement($"/PropertyGroup[@Label='{Vsix.Code}']"));
 }
コード例 #8
0
 private const string zipDirectoryName = "coverlet";        //backwards compatibility
 public ExecuteRequest GetRequest(ICoverageProject coverageProject, string coverletSettings)
 {
     return(new ExecuteRequest
     {
         FilePath = coverletExePath,
         Arguments = coverletSettings,
         WorkingDirectory = coverageProject.ProjectOutputFolder
     });
 }
コード例 #9
0
        public async Task <XElement> ProvideAsync(ICoverageProject coverageProject)
        {
            var settingsElement = ProjectSettingsElementFromFCCLabelledPropertyGroup(coverageProject);

            if (settingsElement == null)
            {
                settingsElement = await vsBuildFCCSettingsProvider.GetSettingsAsync(coverageProject.Id);
            }
            return(settingsElement);
        }
コード例 #10
0
 public async Task RunCoverageAsync(ICoverageProject project, CancellationToken cancellationToken)
 {
     if (project.IsDotNetSdkStyle())
     {
         await coverletUtil.RunCoverletAsync(project, cancellationToken);
     }
     else
     {
         await openCoverUtil.RunOpenCoverAsync(project, cancellationToken);
     }
 }
コード例 #11
0
 private System.Threading.Tasks.Task RunCoverToolAsync(ICoverageProject project)
 {
     if (project.IsDotNetSdkStyle())
     {
         return(coverletUtil.RunCoverletAsync(project, true));
     }
     else
     {
         return(openCoverUtil.RunOpenCoverAsync(project, true));
     }
 }
コード例 #12
0
        // for now FCCCoverletConsoleExeProvider can return null for exe path

        internal ExecuteRequest GetExecuteRequest(ICoverageProject project, string coverletSettings)
        {
            foreach (var exeProvider in executors)
            {
                var executeRequest = exeProvider.GetRequest(project, coverletSettings);
                if (executeRequest != null)
                {
                    return(executeRequest);
                }
            }
            return(null);           //todo change to throw when using zip file
        }
コード例 #13
0
        public async Task Should_Run_Coverage_ThrowingErrors_But_Safely_With_StepAsync()
        {
            ICoverageProject coverageProject = null;

            await ReloadSuitableCoverageProject(mockCoverageProject => {
                coverageProject = mockCoverageProject.Object;
                mockCoverageProject.Setup(p => p.StepAsync("Run Coverage Tool", It.IsAny <Func <ICoverageProject, Task> >())).Callback <string, Func <ICoverageProject, Task> >((_, runCoverTool) =>
                {
                    runCoverTool(coverageProject);
                });
            });

            mocker.Verify <ICoverageUtilManager>(coverageUtilManager => coverageUtilManager.RunCoverageAsync(coverageProject, It.IsAny <CancellationToken>()));
        }
        private async Task RunAndProcessReportAsync(IEnumerable <Uri> resultsUris, string[] expectedCoberturaFiles)
        {
            autoMocker = new AutoMoqer();
            var mockToolFolder = autoMocker.GetMock <IToolFolder>();

            mockToolFolder.Setup(tf => tf.EnsureUnzipped(
                                     It.IsAny <string>(),
                                     It.IsAny <string>(),
                                     It.IsAny <ZipDetails>(),
                                     It.IsAny <CancellationToken>()
                                     )).Returns("ZipDestination");

            var msCodeCoverageRunSettingsService = autoMocker.Create <MsCodeCoverageRunSettingsService>();

            msCodeCoverageRunSettingsService.threadHelper = new TestThreadHelper();

            var mockFccEngine = new Mock <IFCCEngine>();

            msCodeCoverageRunSettingsService.Initialize("", mockFccEngine.Object, CancellationToken.None);

            var mockOperation = new Mock <IOperation>();

            mockOperation.Setup(operation => operation.GetRunSettingsDataCollectorResultUri(new Uri(RunSettingsHelper.MsDataCollectorUri))).Returns(resultsUris);


            // IsCollecting
            var mockTestOperation = new Mock <ITestOperation>();

            runSettingsCoverageProject = CreateCoverageProject(".runsettings");
            var coverageProjects = new List <ICoverageProject>
            {
                CreateCoverageProject(null),
                runSettingsCoverageProject
            };

            mockTestOperation.Setup(testOperation => testOperation.GetCoverageProjectsAsync()).ReturnsAsync(coverageProjects);
            var mockAppOptionsProvider = autoMocker.GetMock <IAppOptionsProvider>();

            mockAppOptionsProvider.Setup(appOptionsProvider => appOptionsProvider.Get()).Returns(new Mock <IAppOptions>().Object);
            await msCodeCoverageRunSettingsService.IsCollectingAsync(mockTestOperation.Object);

            await msCodeCoverageRunSettingsService.CollectAsync(mockOperation.Object, mockTestOperation.Object);

            mockFccEngine.Verify(engine => engine.RunAndProcessReport(
                                     It.Is <string[]>(coberturaFiles => !expectedCoberturaFiles.Except(coberturaFiles).Any() && !coberturaFiles.Except(expectedCoberturaFiles).Any()), It.IsAny <Action>()
                                     )
                                 );
        }
コード例 #15
0
        public IRunSettingsTemplateReplacements Create(ICoverageProject coverageProject, string testAdapter)
        {
            var projectSettings = coverageProject.Settings;
            var additionalModulePathsExclude = coverageProject.ExcludedReferencedProjects.Select(
                rp => MsCodeCoverageRegex.RegexModuleName(rp)).ToList();

            if (!projectSettings.IncludeTestAssembly)
            {
                additionalModulePathsExclude.Add(MsCodeCoverageRegex.RegexEscapePath(coverageProject.TestDllFile));
            }

            var additionalModulePathsInclude = coverageProject.IncludedReferencedProjects.Select(rp => MsCodeCoverageRegex.RegexModuleName(rp)).ToList();
            var settings = new CombinedIncludesExcludesOptions(projectSettings, additionalModulePathsInclude, additionalModulePathsExclude);

            return(new RunSettingsTemplateReplacements(settings, coverageProject.CoverageOutputFolder, projectSettings.Enabled.ToString(), testAdapter));
        }
コード例 #16
0
 public ExecuteRequest GetRequest(ICoverageProject coverageProject, string coverletSettings)
 {
     if (coverageProject.Settings.CoverletConsoleGlobal)
     {
         var details = dotNetToolListCoverlet.Global();
         if (details == null)
         {
             return(null);
         }
         return(new ExecuteRequest
         {
             FilePath = details.Command,
             Arguments = coverletSettings,
             WorkingDirectory = coverageProject.ProjectOutputFolder
         });
     }
     return(null);
 }
コード例 #17
0
        public ExecuteRequest GetRequest(ICoverageProject coverageProject, string coverletSettings)
        {
            var coverletConsoleCustomPath = coverageProject.Settings.CoverletConsoleCustomPath;

            if (string.IsNullOrWhiteSpace(coverletConsoleCustomPath))
            {
                return(null);
            }
            if (File.Exists(coverletConsoleCustomPath) && Path.GetExtension(coverletConsoleCustomPath) == ".exe")
            {
                return(new ExecuteRequest
                {
                    FilePath = coverletConsoleCustomPath,
                    Arguments = coverletSettings,
                    WorkingDirectory = coverageProject.ProjectOutputFolder
                });
            }
            return(null);
        }
        public ExecuteRequest GetRequest(ICoverageProject coverageProject, string coverletSettings)
        {
            if (coverageProject.Settings.CoverletConsoleLocal)
            {
                foreach (var configContainingDirectory in dotNetConfigFinder.GetConfigDirectories(coverageProject.ProjectOutputFolder))
                {
                    var coverletToolDetails = dotnetToolListCoverlet.Local(configContainingDirectory);
                    if (coverletToolDetails != null)
                    {
                        return(new ExecuteRequest
                        {
                            FilePath = "dotnet",
                            Arguments = coverletToolDetails.Command + " " + coverletSettings,
                            WorkingDirectory = configContainingDirectory
                        });
                    }
                }

                return(null);
            }
            return(null);
        }
コード例 #19
0
        public bool CanUseDataCollector(ICoverageProject coverageProject)
        {
            runSettingsCoverletConfiguration = runSettingsCoverletConfigurationFactory.Create();
            this.coverageProject             = coverageProject;

            if (coverageProject.RunSettingsFile != null)
            {
                var runSettingsXml = fileUtil.ReadAllText(coverageProject.RunSettingsFile);

                runSettingsCoverletConfiguration.Read(runSettingsXml);
                switch (runSettingsCoverletConfiguration.CoverletDataCollectorState)
                {
                case CoverletDataCollectorState.Disabled:
                    return(false);

                case CoverletDataCollectorState.Enabled:
                    return(!OverriddenFromProjectFile());
                }
            }

            return(HasSetUseDataCollectorInProjectFile());
        }
コード例 #20
0
        public async Task Should_Run_The_Appropriate_Cover_Tool_Based_On_IsDotNetSdkStyle(bool isDotNetSdkStyle)
        {
            Task             waitForCoverage = null;
            ICoverageProject coverageProject = null;

            await ReloadSuitableCoverageProject(mockCoverageProject => {
                coverageProject = mockCoverageProject.Object;
                mockCoverageProject.Setup(p => p.IsDotNetSdkStyle()).Returns(isDotNetSdkStyle);
                mockCoverageProject.Setup(p => p.StepAsync("Run Coverage Tool", It.IsAny <Func <ICoverageProject, Task> >())).Callback <string, Func <ICoverageProject, Task> >((_, runCoverTool) =>
                {
                    waitForCoverage = runCoverTool(coverageProject);
                });
            });

            if (isDotNetSdkStyle)
            {
                mocker.Verify <ICoverletUtil>(coverlet => coverlet.RunCoverletAsync(coverageProject, true));
            }
            else
            {
                mocker.Verify <IOpenCoverUtil>(openCover => openCover.RunOpenCoverAsync(coverageProject, true));
            }
        }
コード例 #21
0
        public async Task <bool> RunAsync(ICoverageProject project, bool throwError = false)
        {
            var title = $"Coverlet Run ({project.ProjectName})";

            var coverletSettings = GetCoverletSettings(project);

            logger.Log($"{title} Arguments {Environment.NewLine}{string.Join($"{Environment.NewLine}", coverletSettings)}");

            var result = await processUtil
                         .ExecuteAsync(GetExecuteRequest(project, string.Join(" ", coverletSettings)));


            if (result != null)
            {
                /*
                 * 0 - Success.
                 * 1 - If any test fails.
                 * 2 - Coverage percentage is below threshold.
                 * 3 - Test fails and also coverage percentage is below threshold.
                 */
                if (result.ExitCode > 3)
                {
                    if (throwError)
                    {
                        throw new Exception(result.Output);
                    }

                    logger.Log($"{title} Error", result.Output);
                    return(false);
                }

                logger.Log(title, result.Output);

                return(true);
            }
            return(false);
        }
コード例 #22
0
 public string CoverageToolName(ICoverageProject project)
 {
     return(project.IsDotNetSdkStyle() ? "Coverlet" : "OpenCover");
 }
コード例 #23
0
        public async Task RunOpenCoverAsync(ICoverageProject project, CancellationToken cancellationToken)
        {
            var title = $"OpenCover Run ({project.ProjectName})";

            var opencoverSettings = new List <string>();

            opencoverSettings.Add($@" -mergebyhash ");

            opencoverSettings.Add($@" -hideskipped:all ");

            {
                // -register:

                var registerValue = "path32";

                if (project.Is64Bit)
                {
                    registerValue = "path64";
                }

                opencoverSettings.Add($@" -register:{registerValue} ");
            }

            {
                // -target:

                opencoverSettings.Add($@" ""-target:{msTestPlatformUtil.MsTestPlatformExePath}"" ");
            }

            {
                // -filter:

                var filters       = new List <string>();
                var defaultFilter = "+[*]*";

                foreach (var value in (project.Settings.Include ?? new string[0]).Where(x => !string.IsNullOrWhiteSpace(x)))
                {
                    filters.Add($@"+{value.Replace("\"", "\\\"").Trim(' ', '\'')}");
                }

                foreach (var includedReferencedProject in project.IncludedReferencedProjects)
                {
                    filters.Add($@"+[{includedReferencedProject}]*");
                }

                if (!filters.Any())
                {
                    filters.Add(defaultFilter);
                }

                foreach (var value in (project.Settings.Exclude ?? new string[0]).Where(x => !string.IsNullOrWhiteSpace(x)))
                {
                    filters.Add($@"-{value.Replace("\"", "\\\"").Trim(' ', '\'')}");
                }

                foreach (var referencedProjectExcludedFromCodeCoverage in project.ExcludedReferencedProjects)
                {
                    filters.Add($@"-[{referencedProjectExcludedFromCodeCoverage}]*");
                }

                if (filters.Any(x => !x.Equals(defaultFilter)))
                {
                    opencoverSettings.Add($@" ""-filter:{string.Join(" ", filters.Distinct())}"" ");
                }
            }

            {
                // -excludebyfile:

                var excludes = new List <string>();

                foreach (var value in (project.Settings.ExcludeByFile ?? new string[0]).Where(x => !string.IsNullOrWhiteSpace(x)))
                {
                    excludes.Add(value.Replace("\"", "\\\"").Trim(' ', '\''));
                }

                if (excludes.Any())
                {
                    opencoverSettings.Add($@" ""-excludebyfile:{string.Join(";", excludes)}"" ");
                }
            }

            {
                // -excludebyattribute:

                var excludes = new List <string>()
                {
                    // coverlet knows these implicitly
                    "ExcludeFromCoverage",
                    "ExcludeFromCodeCoverage"
                };

                foreach (var value in (project.Settings.ExcludeByAttribute ?? new string[0]).Where(x => !string.IsNullOrWhiteSpace(x)))
                {
                    excludes.Add(value.Replace("\"", "\\\"").Trim(' ', '\''));
                }

                foreach (var exclude in excludes.ToArray())
                {
                    var excludeAlternateName = default(string);

                    if (exclude.EndsWith("Attribute", StringComparison.OrdinalIgnoreCase))
                    {
                        // remove 'Attribute' suffix
                        excludeAlternateName = exclude.Substring(0, exclude.IndexOf("Attribute", StringComparison.OrdinalIgnoreCase));
                    }
                    else
                    {
                        // add 'Attribute' suffix
                        excludeAlternateName = $"{exclude}Attribute";
                    }

                    excludes.Add(excludeAlternateName);
                }

                excludes = excludes.Distinct(StringComparer.OrdinalIgnoreCase).OrderBy(x => x).ToList();

                if (excludes.Any())
                {
                    opencoverSettings.Add($@" ""-excludebyattribute:(*.{string.Join(")|(*.", excludes)})"" ");
                }
            }

            if (!project.Settings.IncludeTestAssembly)
            {
                // deleting the pdb of the test assembly seems to work; this is a VERY VERY shameful hack :(

                var testDllPdbFile = Path.Combine(project.ProjectOutputFolder, Path.GetFileNameWithoutExtension(project.TestDllFile)) + ".pdb";
                File.Delete(testDllPdbFile);

                // filtering out the test-assembly blows up the entire process and nothing gets instrumented or analysed

                //var nameOnlyOfDll = Path.GetFileNameWithoutExtension(project.TestDllFileInWorkFolder);
                //filters.Add($@"-[{nameOnlyOfDll}]*");
            }

            var runSettings = !string.IsNullOrWhiteSpace(project.RunSettingsFile) ? $@"/Settings:\""{project.RunSettingsFile}\""" : default;

            opencoverSettings.Add($@" ""-targetargs:\""{project.TestDllFile}\"" {runSettings}"" ");

            opencoverSettings.Add($@" ""-output:{ project.CoverageOutputFile }"" ");

            logger.Log($"{title} Arguments {Environment.NewLine}{string.Join($"{Environment.NewLine}", opencoverSettings)}");

            var result = await processUtil
                         .ExecuteAsync(new ExecuteRequest
            {
                FilePath         = GetOpenCoverExePath(project.Settings.OpenCoverCustomPath),
                Arguments        = string.Join(" ", opencoverSettings),
                WorkingDirectory = project.ProjectOutputFolder
            }, cancellationToken);

            if (result.ExitCode != 0)
            {
                throw new Exception(result.Output);
            }

            logger.Log(title, result.Output);
        }
コード例 #24
0
 internal static string GeneratedProjectRunSettingsFilePath(ICoverageProject coverageProject)
 {
     return(Path.Combine(coverageProject.CoverageOutputFolder, $"{coverageProject.ProjectName}-{fccGeneratedRunSettingsSuffix}.runsettings"));
 }
コード例 #25
0
        private ITemplateReplacementResult ReplaceTemplate(ICoverageProject coverageProject, string runSettingsTemplate, string fccMsTestAdapterPath)
        {
            var replacements = runSettingsTemplateReplacementsFactory.Create(coverageProject, fccMsTestAdapterPath);

            return(this.runSettingsTemplate.ReplaceTemplate(runSettingsTemplate, replacements, coverageProject.IsDotNetFramework));
        }