Пример #1
0
        /// <summary>
        /// Starts a mutation test run
        /// </summary>
        /// <exception cref="StrykerException">For managed exceptions</exception>
        /// <param name="options">The user options</param>
        public void RunMutationTest(StrykerOptions options)
        {
            // start stopwatch
            var stopwatch = new Stopwatch();

            stopwatch.Start();

            // setup logging
            ApplicationLogging.ConfigureLogger(options.LogOptions);
            var logger = ApplicationLogging.LoggerFactory.CreateLogger <StrykerRunner>();

            try
            {
                // initialyze
                _reporter = ReporterFactory.Create(options.Reporter);
                _initialisationProcess = _initialisationProcess ?? new InitialisationProcess(_reporter);
                _input = _initialisationProcess.Initialize(options);

                _mutationTestProcess = _mutationTestProcess ?? new MutationTestProcess(
                    mutationTestInput: _input,
                    mutators: new List <IMutator> ()
                {
                    // the default list of mutators
                    new BinaryExpressionMutator(),
                    new BooleanMutator(),
                    new AssignmentStatementMutator(),
                    new PrefixUnaryMutator(),
                    new PostfixUnaryMutator(),
                    new CheckedMutator()
                },
                    reporter: _reporter,
                    mutationTestExecutor: new MutationTestExecutor(_input.TestRunner, _input.TimeoutMS));

                // mutate
                _mutationTestProcess.Mutate();

                // test mutations
                _mutationTestProcess.Test();
            }
            catch (Exception ex)
            {
                logger.LogError(ex, "An error occurred during the mutationtest run ");
                throw;
            }
            finally {
                // log duration
                stopwatch.Stop();
                logger.LogInformation("Time Elapsed {0}", stopwatch.Elapsed);
            }
        }
Пример #2
0
 public static void CreateReportFromFile(string path)
 {
     try
     {
         var reporter = ReporterFactory.Build(TestingFramework.NUnit, new TestDataProvider());
         var testRuns = GetTestRunsListFromFile(path);
         reporter.GenerateFullReport(testRuns);
     }
     catch (Exception ex)
     {
         var log = new Core.Utils.Log(GhprEventListener.OutputPath);
         log.Exception(ex, "Exception in CreateReportFromFile");
     }
 }
Пример #3
0
        /// <summary>
        /// Starts a mutation test run
        /// </summary>
        /// <exception cref="StrykerInputException">For managed exceptions</exception>
        /// <param name="options">The user options</param>
        public StrykerRunResult RunMutationTest(StrykerOptions options)
        {
            // start stopwatch
            var stopwatch = new Stopwatch();

            stopwatch.Start();

            // Create output dir with gitignore
            _fileSystem.Directory.CreateDirectory(options.OutputPath);
            _fileSystem.File.Create(Path.Combine(options.OutputPath, ".gitignore")).Close();
            using (var file = _fileSystem.File.CreateText(Path.Combine(options.OutputPath, ".gitignore")))
            {
                file.WriteLine("*");
            }

            // setup logging
            ApplicationLogging.ConfigureLogger(options.LogOptions);
            var logger = ApplicationLogging.LoggerFactory.CreateLogger <StrykerRunner>();

            try
            {
                // initialize
                _reporter = ReporterFactory.Create(options);
                _initialisationProcess = _initialisationProcess ?? new InitialisationProcess();
                _input = _initialisationProcess.Initialize(options);

                _mutationTestProcess = _mutationTestProcess ?? new MutationTestProcess(
                    mutationTestInput: _input,
                    reporter: _reporter,
                    mutationTestExecutor: new MutationTestExecutor(_input.TestRunner, _input.TimeoutMS));

                // mutate
                _mutationTestProcess.Mutate(options);

                // test mutations and return results
                return(_mutationTestProcess.Test(options));
            }
            catch (Exception ex) when(!(ex is StrykerInputException))
            {
                logger.LogError(ex, "An error occurred during the mutation test run ");
                throw;
            }
            finally
            {
                // log duration
                stopwatch.Stop();
                logger.LogInformation("Time Elapsed {0}", stopwatch.Elapsed);
            }
        }
Пример #4
0
        public void CanCreateWithSettings()
        {
            var s = new ReporterSettings
            {
                DefaultSettings = new ProjectSettings
                {
                    RunGuid            = Guid.NewGuid().ToString(),
                    DataServiceFile    = "Ghpr.LocalFileSystem.dll",
                    LoggerFile         = "",
                    OutputPath         = @"\\server\folder",
                    ProjectName        = "cool project",
                    RealTimeGeneration = true,
                    ReportName         = "report name",
                    Retention          = new RetentionSettings
                    {
                        Amount = 3,
                        Till   = DateTime.Now
                    },
                    RunName       = "run name",
                    RunsToDisplay = 7
                }
            };
            var r = ReporterFactory.Build(s, _provider);

            Assert.NotNull(r.ReporterSettings);
            Assert.NotNull(r.Action);
            Assert.NotNull(r.DataReaderService);
            Assert.NotNull(r.DataWriterService);
            Assert.NotNull(r.TestDataProvider);
            Assert.NotNull(r.Logger);
            Assert.IsInstanceOf(typeof(EmptyLogger), r.Logger);
            Assert.IsInstanceOf(typeof(MockTestDataProvider), r.TestDataProvider);
            Assert.AreEqual(s.DefaultSettings.ProjectName, r.ReporterSettings.ProjectName);
            Assert.AreEqual(s.DefaultSettings.ReportName, r.ReporterSettings.ReportName);
            Assert.AreEqual(s.DefaultSettings.RunGuid, r.ReporterSettings.RunGuid);
            Assert.AreEqual(s.DefaultSettings.DataServiceFile, r.ReporterSettings.DataServiceFile);
            Assert.AreEqual(s.DefaultSettings.LoggerFile, r.ReporterSettings.LoggerFile);
            Assert.AreEqual(s.DefaultSettings.OutputPath, r.ReporterSettings.OutputPath);
            Assert.AreEqual(s.DefaultSettings.RealTimeGeneration, r.ReporterSettings.RealTimeGeneration);
            Assert.AreEqual(s.DefaultSettings.Retention.Till, r.ReporterSettings.Retention.Till);
            Assert.AreEqual(s.DefaultSettings.Retention.Amount, r.ReporterSettings.Retention.Amount);
            Assert.AreEqual(s.DefaultSettings.RunName, r.ReporterSettings.RunName);
            Assert.AreEqual(s.DefaultSettings.RunsToDisplay, r.ReporterSettings.RunsToDisplay);
            Assert.AreEqual(s.DefaultSettings.OutputPath, r.ReporterSettings.OutputPath);
            Assert.AreEqual(s.DefaultSettings.RunsToDisplay, r.ReportSettings.RunsToDisplay);
            Assert.AreEqual(s.DefaultSettings.TestsToDisplay, r.ReportSettings.TestsToDisplay);
            Assert.AreEqual(s.DefaultSettings.ProjectName, r.ReportSettings.ProjectName);
            Assert.AreEqual(s.DefaultSettings.ReportName, r.ReportSettings.ReportName);
        }
Пример #5
0
        public override bool ConsistencyCheck(ReporterFactory reporterFactory)
        {
//JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final':
//ORIGINAL LINE: final LuceneIndexConsistencyCheckVisitor visitor = reporterFactory.getClass(LuceneIndexConsistencyCheckVisitor.class);
            LuceneIndexConsistencyCheckVisitor visitor = reporterFactory.GetClass(typeof(LuceneIndexConsistencyCheckVisitor));
//JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final':
//ORIGINAL LINE: final boolean isConsistent = !isDirty();
            bool isConsistent = !Dirty;

            if (!isConsistent)
            {
                visitor.IsInconsistent(Descriptor);
            }
            return(isConsistent);
        }
        public void ReporterFactory_CreatesAllReporters()
        {
            BroadcastReporter result = (BroadcastReporter)ReporterFactory.Create(new StrykerOptions(reporters: new[] { "All" }));

            result.ShouldBeOfType(typeof(BroadcastReporter));
            result.Reporters.ShouldContain(r => r is JsonReporter);
            result.Reporters.ShouldContain(r => r is HtmlReporter);
            result.Reporters.ShouldContain(r => r is ConsoleDotProgressReporter);
            result.Reporters.ShouldContain(r => r is ClearTextReporter);
            result.Reporters.ShouldContain(r => r is ProgressReporter);
            result.Reporters.ShouldContain(r => r is DashboardReporter);
            result.Reporters.ShouldContain(r => r is GitBaselineReporter);

            result.Reporters.Count().ShouldBe(7);
        }
Пример #7
0
        public static void CreateReportFromFile(string path, ITestDataProvider dataProvider)
        {
            var reporter = ReporterFactory.Build(TestingFramework.MSTest, dataProvider);

            try
            {
                var testRuns = GetTestRunsListFromFile(path);
                reporter.GenerateFullReport(testRuns);
                reporter.CleanUpJob();
                reporter.TearDown();
            }
            catch (Exception ex)
            {
                reporter.Logger.Exception("Exception in CreateReportFromFile", ex);
            }
        }
Пример #8
0
        public Program()
        {
            AnalyzerFactory analyzerFactory = new AnalyzerFactory
            {
                VulnerabilityDiscovered = OnVulnerabilityDiscovered
            };

            ScannerFactory = new ScannerFactory
            {
                CsAnalyzers = analyzerFactory.GetCsAnalyzers(),
                AndroidManifestAnalyzers = analyzerFactory.GetAndroidManifestAnalyzers(),
                TextAnalyzers            = analyzerFactory.GetTextAnalyzers()
            };

            EnvironmentWrapper = new EnvironmentWrapper();
            ReporterFactory    = new ReporterFactory(new ConsoleWrapper());
        }
Пример #9
0
        public static void ReporterSystem()
        {
            var pdfReporter = ReporterFactory.Create(ReportFormat.Pdf);

            var xmlReporter = ReporterFactory.Create(ReportFormat.Xml);

            var jsonReporter = ReporterFactory.Create(ReportFormat.Json);

            var xmlReport = xmlReporter.Report();

            var jsonReport = jsonReporter.Report();

            var pdfReport = pdfReporter.Report();

            Console.WriteLine(xmlReport);
            Console.WriteLine(jsonReport);
            Console.WriteLine(pdfReport);
        }
Пример #10
0
        public void CanCreateByFramework(TestingFramework framework, string outputPath)
        {
            var r = ReporterFactory.Build(framework, _provider);

            Assert.NotNull(r.ReporterSettings);
            Assert.NotNull(r.Action);
            Assert.NotNull(r.DataReaderService);
            Assert.NotNull(r.DataWriterService);
            Assert.NotNull(r.TestDataProvider);
            Assert.NotNull(r.Logger);
            Assert.IsInstanceOf(typeof(EmptyLogger), r.Logger);
            Assert.IsInstanceOf(typeof(MockTestDataProvider), r.TestDataProvider);
            Assert.AreEqual(outputPath, r.ReporterSettings.OutputPath);
            Assert.AreEqual(r.ReporterSettings.RunsToDisplay, r.ReportSettings.RunsToDisplay);
            Assert.AreEqual(r.ReporterSettings.TestsToDisplay, r.ReportSettings.TestsToDisplay);
            Assert.AreEqual(r.ReporterSettings.ProjectName, r.ReportSettings.ProjectName);
            Assert.AreEqual(r.ReporterSettings.ReportName, r.ReportSettings.ReportName);
        }
Пример #11
0
        public void CanCreate()
        {
            var r = ReporterFactory.Build(_provider);

            Assert.NotNull(r.ReporterSettings);
            Assert.NotNull(r.Action);
            Assert.NotNull(r.DataReaderService);
            Assert.NotNull(r.DataWriterService);
            Assert.NotNull(r.TestDataProvider);
            Assert.NotNull(r.Logger);
            Assert.IsInstanceOf(typeof(EmptyLogger), r.Logger);
            Assert.IsInstanceOf(typeof(MockTestDataProvider), r.TestDataProvider);
            Assert.AreEqual("C:\\_GHPReporter_Core_Report", r.ReporterSettings.OutputPath);
            Assert.AreEqual(r.ReporterSettings.RunsToDisplay, r.ReportSettings.RunsToDisplay);
            Assert.AreEqual(r.ReporterSettings.TestsToDisplay, r.ReportSettings.TestsToDisplay);
            Assert.AreEqual(r.ReporterSettings.ProjectName, r.ReportSettings.ProjectName);
            Assert.AreEqual(r.ReporterSettings.ReportName, r.ReportSettings.ReportName);
        }
Пример #12
0
        public void TestReportProcess()
        {
            var r = ReporterFactory.Build(new MockTestDataProvider());

            Assert.IsFalse(r.TestRunStarted);
            r.RunStarted();
            Assert.IsTrue(r.TestRunStarted);
            Assert.AreEqual(0, r.RunRepository.CurrentRun.TestsInfo.Count);
            Assert.AreEqual(0, r.RunRepository.CurrentRun.RunSummary.Total);
            Assert.AreEqual("", r.RunRepository.CurrentRun.Name);
            r.SetRunName("new name");
            Assert.AreEqual("new name", r.RunRepository.CurrentRun.Name);
            r.TestStarted(new TestRunDto());
            r.TestFinished(new TestRunDto(), new TestOutputDto());
            r.AddCompleteTestRun(new TestRunDto(), new TestOutputDto());
            r.RunFinished();
            r.TearDown();
        }
Пример #13
0
        /// <summary>
        /// Starts a mutation test run
        /// </summary>
        /// <exception cref="StrykerException">For managed exceptions</exception>
        /// <param name="options">The user options</param>
        public void RunMutationTest(StrykerOptions options)
        {
            // start stopwatch
            var stopwatch = new Stopwatch();

            stopwatch.Start();

            // setup logging
            ApplicationLogging.ConfigureLogger(options.LogOptions);
            var logger = ApplicationLogging.LoggerFactory.CreateLogger <StrykerRunner>();

            try
            {
                // validate options
                options = new StrykerOptionsValidator().Validate(options);

                // initialyze
                _reporter = ReporterFactory.Create(options.Reporter);
                _initialisationProcess = _initialisationProcess ?? new InitialisationProcess(_reporter);
                _input = _initialisationProcess.Initialize(options);

                _mutationTestProcess = _mutationTestProcess ?? new MutationTestProcess(
                    mutationTestInput: _input,
                    options: options,
                    reporter: _reporter,
                    mutationTestExecutor: new MutationTestExecutor(_input.TestRunner));

                // mutate
                _mutationTestProcess.Mutate();

                // test mutations
                _mutationTestProcess.Test();
            }
            catch (Exception ex)
            {
                logger.LogError(ex, "An error occurred during the mutationtest run ");
                throw;
            }
            finally {
                // log duration
                stopwatch.Stop();
                logger.LogInformation("Time Elapsed {0}", stopwatch.Elapsed);
            }
        }
Пример #14
0
 public CoverageManager(CoverletSettings settings, TestPlatformEqtTrace eqtTrace, TestPlatformLogger logger, ICoverageWrapper coverageWrapper)
     : this(settings,
            settings.ReportFormats.Select(format =>
 {
     var reporterFactory = new ReporterFactory(format);
     if (!reporterFactory.IsValidFormat())
     {
         eqtTrace.Warning($"Invalid report format '{format}'");
         return(null);
     }
     else
     {
         return(reporterFactory.CreateReporter());
     }
 }).Where(r => r != null).ToArray(),
            new CoverletLogger(eqtTrace, logger),
            coverageWrapper)
 {
 }
Пример #15
0
 public CoverageManager(CoverletSettings settings, TestPlatformEqtTrace eqtTrace, TestPlatformLogger logger, ICoverageWrapper coverageWrapper,
                        IInstrumentationHelper instrumentationHelper, IFileSystem fileSystem, ISourceRootTranslator sourceRootTranslator, ICecilSymbolHelper cecilSymbolHelper)
     : this(settings,
            settings.ReportFormats.Select(format =>
 {
     var reporterFactory = new ReporterFactory(format);
     if (!reporterFactory.IsValidFormat())
     {
         eqtTrace.Warning($"Invalid report format '{format}'");
         return(null);
     }
     else
     {
         return(reporterFactory.CreateReporter());
     }
 }).Where(r => r != null).ToArray(),
            new CoverletLogger(eqtTrace, logger),
            coverageWrapper, instrumentationHelper, fileSystem, sourceRootTranslator, cecilSymbolHelper)
 {
 }
        public void ReporterFactory_CreatesAllReporters()
        {
            var branchProviderMock = new Mock <IGitInfoProvider>(MockBehavior.Loose);

            var target = new ReporterFactory();

            var result = (BroadcastReporter)target.Create(new StrykerOptions(reporters: new[] { "All" }), branchProviderMock.Object);

            var broadcastReporter = result.ShouldBeOfType <BroadcastReporter>();

            broadcastReporter.Reporters.ShouldContain(r => r is JsonReporter);
            broadcastReporter.Reporters.ShouldContain(r => r is ConsoleDotProgressReporter);
            broadcastReporter.Reporters.ShouldContain(r => r is ClearTextReporter);
            broadcastReporter.Reporters.ShouldContain(r => r is ClearTextTreeReporter);
            broadcastReporter.Reporters.ShouldContain(r => r is ProgressReporter);
            broadcastReporter.Reporters.ShouldContain(r => r is DashboardReporter);
            broadcastReporter.Reporters.ShouldContain(r => r is GitBaselineReporter);

            result.Reporters.Count().ShouldBe(8);
        }
Пример #17
0
        /// <summary>
        /// Starts a mutation test run
        /// </summary>
        /// <exception cref="StrykerInputException">For managed exceptions</exception>
        /// <param name="options">The user options</param>
        public StrykerRunResult RunMutationTest(StrykerOptions options)
        {
            // start stopwatch
            var stopwatch = new Stopwatch();

            stopwatch.Start();

            // setup logging
            ApplicationLogging.ConfigureLogger(options.LogOptions);
            var logger = ApplicationLogging.LoggerFactory.CreateLogger <StrykerRunner>();

            try
            {
                // initialize
                _reporter = ReporterFactory.Create(options);
                _initialisationProcess = _initialisationProcess ?? new InitialisationProcess();
                _input = _initialisationProcess.Initialize(options);

                _mutationTestProcess = _mutationTestProcess ?? new MutationTestProcess(
                    mutationTestInput: _input,
                    excludedMutations: options.ExcludedMutations,
                    reporter: _reporter,
                    mutationTestExecutor: new MutationTestExecutor(_input.TestRunner, _input.TimeoutMS));

                // mutate
                _mutationTestProcess.Mutate(options);

                // test mutations and return results
                return(_mutationTestProcess.Test(options));
            }
            catch (Exception ex) when(!(ex is StrykerInputException))
            {
                logger.LogError(ex, "An error occurred during the mutation test run ");
                throw;
            }
            finally {
                // log duration
                stopwatch.Stop();
                logger.LogInformation("Time Elapsed {0}", stopwatch.Elapsed);
            }
        }
Пример #18
0
        private static void ConsistencyCheckSchemaIndexes(IndexAccessors indexes, ConsistencyReporter report, ProgressListener listener)
        {
            IList <StoreIndexDescriptor> rulesToRemove = new List <StoreIndexDescriptor>();

            foreach (StoreIndexDescriptor onlineRule in indexes.OnlineRules())
            {
                ConsistencyReporter.FormattingDocumentedHandler handler = report.FormattingHandler(RecordType.INDEX);
                ReporterFactory reporterFactory = new ReporterFactory(handler);
                IndexAccessor   accessor        = indexes.AccessorFor(onlineRule);
                if (!accessor.ConsistencyCheck(reporterFactory))
                {
                    rulesToRemove.Add(onlineRule);
                }
                handler.UpdateSummary();
                listener.Add(1);
            }
            foreach (StoreIndexDescriptor toRemove in rulesToRemove)
            {
                indexes.Remove(toRemove);
            }
        }
Пример #19
0
        public void ReporterFactory_CreatesAllReporters()
        {
            var target  = new ReporterFactory();
            var options = new StrykerOptions {
                Reporters = new[] { Reporter.All }
            };

            var result = (BroadcastReporter)target.Create(options, _branchProviderMock.Object);

            var broadcastReporter = result.ShouldBeOfType <BroadcastReporter>();

            broadcastReporter.Reporters.ShouldContain(r => r is JsonReporter);
            broadcastReporter.Reporters.ShouldContain(r => r is ConsoleDotProgressReporter);
            broadcastReporter.Reporters.ShouldContain(r => r is ClearTextReporter);
            broadcastReporter.Reporters.ShouldContain(r => r is ClearTextTreeReporter);
            broadcastReporter.Reporters.ShouldContain(r => r is ProgressReporter);
            broadcastReporter.Reporters.ShouldContain(r => r is DashboardReporter);
            broadcastReporter.Reporters.ShouldContain(r => r is BaselineReporter);

            result.Reporters.Count().ShouldBe(8);
        }
Пример #20
0
        static void Main(string[] args)
        {
            #region 1
            // Инициализируем (регистрируем) связи
            // Конфигурирование связей отделено от их использования
            ServiceLocator.RegisterService <IReportBuilder>(typeof(ReportBuilder));
            ServiceLocator.RegisterService <IReportSender>(typeof(SmsReportSender));

            var reporter = new Reporter();
            reporter.SendReports();

            //или

            ServiceLocator.RegisterService <IReportBuilder>(typeof(ReportBuilder));
            ServiceLocator.RegisterService <IReportSender>(typeof(EmailReportSender));

            reporter = new Reporter();
            reporter.SendReports();

            #endregion

            #region 2
            ServiceLocator.RegisterService <IReportBuilder>(typeof(ReportBuilder));
            ServiceLocator.RegisterService <IReportSender>(typeof(SmsReportSender));
            ServiceLocator.RegisterService <IReporter>(typeof(Reporter));

            // Вызываем "сохраненную" ссылку на нужную реализацию
            var reporter1 = ReporterFactory.Create();
            reporter1.SendReports();

            //или

            ServiceLocator.RegisterService <IReportSender>(typeof(EmailReportSender));
            reporter1 = ServiceLocator.Resolve <IReporter>();

            reporter1.SendReports();
            #endregion
        }
Пример #21
0
        public static void CreateReportFromFile(string path)
        {
            IReporter reporter = null;

            try
            {
                reporter = ReporterFactory.Build(TestingFramework.NUnit, new TestDataProvider());
                var testRuns = GetTestRunsListFromFile(path, reporter.Logger);
                foreach (var ghprTestCase in testRuns.Where(t => t.GhprTestScreenshots.Any()))
                {
                    foreach (var screenshot in ghprTestCase.GhprTestScreenshots)
                    {
                        reporter.DataService.SaveScreenshot(screenshot);
                    }
                }
                reporter.GenerateFullReport(testRuns.Select(tr => new KeyValuePair <TestRunDto, TestOutputDto>(tr.GhprTestRun, tr.GhprTestOutput)).ToList());
                reporter.TearDown();
            }
            catch (Exception ex)
            {
                reporter?.Logger.Exception("Exception in CreateReportFromFile", ex);
            }
        }
Пример #22
0
        public void OnExecute()
        {
            if (EnableLogging)
            {
                XamarinSecurityScannerLogger.LogEvent = (m) => File.AppendAllText(LogFile, m);
            }

            if (IgnoreFile != null)
            {
                SetIgnoreObject();
            }

            Reporter = ReporterFactory.Create(Output);
            IScanner scanner = ScannerFactory.Create();

            Reporter.Start();
            Task task = scanner.Start(Path);

            task.Wait();

            Reporter.Finish();
            EnvironmentWrapper.Exit(Reporter.VulnerabilityCount < Threshold ? 0 : 1);
        }
Пример #23
0
        static void Main(string[] args)
        {
            string url        = args[0];
            string reportType = args[1];

            HtmlWeb web     = new HtmlWeb();
            var     htmlDoc = web.Load(url);

            // parsers
            ImgParser imgp = new ImgParser();

            imgp.parseContent("img", htmlDoc);

            H1Parser h1p = new H1Parser();

            h1p.parseContent("h1", htmlDoc);

            // reporter
            Reporter jrep = ReporterFactory.GetImpl(reportType);
            var      ret  = jrep.CreateReport(imgp, h1p);

            Console.Write(Encoding.Unicode.GetString(ret));
        }
Пример #24
0
        public override bool Execute()
        {
            try
            {
                Console.WriteLine("\nCalculating coverage result...");

                if (InstrumenterState is null || !File.Exists(InstrumenterState.ItemSpec))
                {
                    _logger.LogError("Result of instrumentation task not found");
                    return(false);
                }

                var coverage = new Coverage(CoveragePrepareResult.Deserialize(new FileStream(InstrumenterState.ItemSpec, FileMode.Open)), this._logger);
                var result   = coverage.GetCoverageResult();

                var directory = Path.GetDirectoryName(_output);
                if (directory == string.Empty)
                {
                    directory = Directory.GetCurrentDirectory();
                }
                else if (!Directory.Exists(directory))
                {
                    Directory.CreateDirectory(directory);
                }

                var formats = _format.Split(',');
                foreach (var format in formats)
                {
                    var reporter = new ReporterFactory(format).CreateReporter();
                    if (reporter == null)
                    {
                        throw new Exception($"Specified output format '{format}' is not supported");
                    }

                    if (reporter.OutputType == ReporterOutputType.Console)
                    {
                        // Output to console
                        Console.WriteLine("  Outputting results to console");
                        Console.WriteLine(reporter.Report(result));
                    }
                    else
                    {
                        // Output to file
                        var filename = Path.GetFileName(_output);
                        filename = (filename == string.Empty) ? $"coverage.{reporter.Extension}" : filename;
                        filename = Path.HasExtension(filename) ? filename : $"{filename}.{reporter.Extension}";

                        var report = Path.Combine(directory, filename);
                        Console.WriteLine($"  Generating report '{report}'");
                        File.WriteAllText(report, reporter.Report(result));
                    }
                }

                var thresholdTypeFlags = ThresholdTypeFlags.None;
                var thresholdStat      = ThresholdStatistic.Minimum;

                foreach (var thresholdType in _thresholdType.Split(',').Select(t => t.Trim()))
                {
                    if (thresholdType.Equals("line", StringComparison.OrdinalIgnoreCase))
                    {
                        thresholdTypeFlags |= ThresholdTypeFlags.Line;
                    }
                    else if (thresholdType.Equals("branch", StringComparison.OrdinalIgnoreCase))
                    {
                        thresholdTypeFlags |= ThresholdTypeFlags.Branch;
                    }
                    else if (thresholdType.Equals("method", StringComparison.OrdinalIgnoreCase))
                    {
                        thresholdTypeFlags |= ThresholdTypeFlags.Method;
                    }
                }

                if (_thresholdStat.Equals("average", StringComparison.OrdinalIgnoreCase))
                {
                    thresholdStat = ThresholdStatistic.Average;
                }
                else if (_thresholdStat.Equals("total", StringComparison.OrdinalIgnoreCase))
                {
                    thresholdStat = ThresholdStatistic.Total;
                }

                var coverageTable = new ConsoleTable("Module", "Line", "Branch", "Method");
                var summary       = new CoverageSummary();
                int numModules    = result.Modules.Count;

                var linePercentCalculation   = summary.CalculateLineCoverage(result.Modules);
                var branchPercentCalculation = summary.CalculateBranchCoverage(result.Modules);
                var methodPercentCalculation = summary.CalculateMethodCoverage(result.Modules);

                var totalLinePercent   = linePercentCalculation.Percent;
                var totalBranchPercent = branchPercentCalculation.Percent;
                var totalMethodPercent = methodPercentCalculation.Percent;

                var averageLinePercent   = linePercentCalculation.AverageModulePercent;
                var averageBranchPercent = branchPercentCalculation.AverageModulePercent;
                var averageMethodPercent = methodPercentCalculation.AverageModulePercent;

                foreach (var module in result.Modules)
                {
                    var linePercent   = summary.CalculateLineCoverage(module.Value).Percent;
                    var branchPercent = summary.CalculateBranchCoverage(module.Value).Percent;
                    var methodPercent = summary.CalculateMethodCoverage(module.Value).Percent;

                    coverageTable.AddRow(Path.GetFileNameWithoutExtension(module.Key), $"{linePercent}%", $"{branchPercent}%", $"{methodPercent}%");
                }

                Console.WriteLine();
                Console.WriteLine(coverageTable.ToStringAlternative());

                coverageTable.Columns.Clear();
                coverageTable.Rows.Clear();

                coverageTable.AddColumn(new[] { "", "Line", "Branch", "Method" });
                coverageTable.AddRow("Total", $"{totalLinePercent}%", $"{totalBranchPercent}%", $"{totalMethodPercent}%");
                coverageTable.AddRow("Average", $"{averageLinePercent}%", $"{averageBranchPercent}%", $"{averageMethodPercent}%");

                Console.WriteLine(coverageTable.ToStringAlternative());

                thresholdTypeFlags = result.GetThresholdTypesBelowThreshold(summary, _threshold, thresholdTypeFlags, thresholdStat);
                if (thresholdTypeFlags != ThresholdTypeFlags.None)
                {
                    var exceptionMessageBuilder = new StringBuilder();
                    if ((thresholdTypeFlags & ThresholdTypeFlags.Line) != ThresholdTypeFlags.None)
                    {
                        exceptionMessageBuilder.AppendLine($"The {thresholdStat.ToString().ToLower()} line coverage is below the specified {_threshold}");
                    }

                    if ((thresholdTypeFlags & ThresholdTypeFlags.Branch) != ThresholdTypeFlags.None)
                    {
                        exceptionMessageBuilder.AppendLine($"The {thresholdStat.ToString().ToLower()} branch coverage is below the specified {_threshold}");
                    }

                    if ((thresholdTypeFlags & ThresholdTypeFlags.Method) != ThresholdTypeFlags.None)
                    {
                        exceptionMessageBuilder.AppendLine($"The {thresholdStat.ToString().ToLower()} method coverage is below the specified {_threshold}");
                    }

                    throw new Exception(exceptionMessageBuilder.ToString());
                }
            }
            catch (Exception ex)
            {
                _logger.LogError(ex);
                return(false);
            }

            return(true);
        }
Пример #25
0
        static int Main(string[] args)
        {
            var logger = new ConsoleLogger();
            var app    = new CommandLineApplication();

            app.Name     = "coverlet";
            app.FullName = "Cross platform .NET Core code coverage tool";
            app.HelpOption("-h|--help");
            app.VersionOption("-v|--version", GetAssemblyVersion());

            CommandArgument module              = app.Argument("<ASSEMBLY>", "Path to the test assembly.");
            CommandOption   target              = app.Option("-t|--target", "Path to the test runner application.", CommandOptionType.SingleValue);
            CommandOption   targs               = app.Option("-a|--targetargs", "Arguments to be passed to the test runner.", CommandOptionType.SingleValue);
            CommandOption   output              = app.Option("-o|--output", "Output of the generated coverage report", CommandOptionType.SingleValue);
            CommandOption   formats             = app.Option("-f|--format", "Format of the generated coverage report.", CommandOptionType.MultipleValue);
            CommandOption   threshold           = app.Option("--threshold", "Exits with error if the coverage % is below value.", CommandOptionType.SingleValue);
            CommandOption   thresholdTypes      = app.Option("--threshold-type", "Coverage type to apply the threshold to.", CommandOptionType.MultipleValue);
            CommandOption   excludeFilters      = app.Option("--exclude", "Filter expressions to exclude specific modules and types.", CommandOptionType.MultipleValue);
            CommandOption   includeFilters      = app.Option("--include", "Filter expressions to include only specific modules and types.", CommandOptionType.MultipleValue);
            CommandOption   excludedSourceFiles = app.Option("--exclude-by-file", "Glob patterns specifying source files to exclude.", CommandOptionType.MultipleValue);
            CommandOption   mergeWith           = app.Option("--merge-with", "Path to existing coverage result to merge.", CommandOptionType.SingleValue);

            app.OnExecute(() =>
            {
                if (string.IsNullOrEmpty(module.Value) || string.IsNullOrWhiteSpace(module.Value))
                {
                    throw new CommandParsingException(app, "No test assembly specified.");
                }

                if (!target.HasValue())
                {
                    throw new CommandParsingException(app, "Target must be specified.");
                }

                Coverage coverage = new Coverage(module.Value, excludeFilters.Values.ToArray(), includeFilters.Values.ToArray(), excludedSourceFiles.Values.ToArray(), mergeWith.Value());
                coverage.PrepareModules();

                Process process                          = new Process();
                process.StartInfo.FileName               = target.Value();
                process.StartInfo.Arguments              = targs.HasValue() ? targs.Value() : string.Empty;
                process.StartInfo.CreateNoWindow         = true;
                process.StartInfo.RedirectStandardOutput = true;
                process.Start();
                logger.LogInformation(process.StandardOutput.ReadToEnd());
                process.WaitForExit();

                var dOutput         = output.HasValue() ? output.Value() : Directory.GetCurrentDirectory() + Path.DirectorySeparatorChar.ToString();
                var dThreshold      = threshold.HasValue() ? int.Parse(threshold.Value()) : 0;
                var dThresholdTypes = thresholdTypes.HasValue() ? thresholdTypes.Values : new List <string>(new string[] { "line", "branch", "method" });

                logger.LogInformation("\nCalculating coverage result...");

                var result    = coverage.GetCoverageResult();
                var directory = Path.GetDirectoryName(dOutput);
                if (!Directory.Exists(directory))
                {
                    Directory.CreateDirectory(directory);
                }

                foreach (var format in (formats.HasValue() ? formats.Values : new List <string>(new string[] { "json" })))
                {
                    var reporter = new ReporterFactory(format).CreateReporter();
                    if (reporter == null)
                    {
                        throw new Exception($"Specified output format '{format}' is not supported");
                    }

                    if (reporter.OutputType == ReporterOutputType.Console)
                    {
                        // Output to console
                        logger.LogInformation("  Outputting results to console");
                        logger.LogInformation(reporter.Report(result));
                    }
                    else
                    {
                        // Output to file
                        var filename = Path.GetFileName(dOutput);
                        filename     = (filename == string.Empty) ? $"coverage.{reporter.Extension}" : filename;
                        filename     = Path.HasExtension(filename) ? filename : $"{filename}.{reporter.Extension}";

                        var report = Path.Combine(directory, filename);
                        logger.LogInformation($"  Generating report '{report}'");
                        File.WriteAllText(report, reporter.Report(result));
                    }
                }

                var summary               = new CoverageSummary();
                var exceptionBuilder      = new StringBuilder();
                var coverageTable         = new ConsoleTable("Module", "Line", "Branch", "Method");
                var thresholdFailed       = false;
                var overallLineCoverage   = summary.CalculateLineCoverage(result.Modules);
                var overallBranchCoverage = summary.CalculateBranchCoverage(result.Modules);
                var overallMethodCoverage = summary.CalculateMethodCoverage(result.Modules);

                foreach (var _module in result.Modules)
                {
                    var linePercent   = summary.CalculateLineCoverage(_module.Value).Percent * 100;
                    var branchPercent = summary.CalculateBranchCoverage(_module.Value).Percent * 100;
                    var methodPercent = summary.CalculateMethodCoverage(_module.Value).Percent * 100;

                    coverageTable.AddRow(Path.GetFileNameWithoutExtension(_module.Key), $"{linePercent}%", $"{branchPercent}%", $"{methodPercent}%");

                    if (dThreshold > 0)
                    {
                        if (linePercent < dThreshold && dThresholdTypes.Contains("line"))
                        {
                            exceptionBuilder.AppendLine($"'{Path.GetFileNameWithoutExtension(_module.Key)}' has a line coverage '{linePercent}%' below specified threshold '{dThreshold}%'");
                            thresholdFailed = true;
                        }

                        if (branchPercent < dThreshold && dThresholdTypes.Contains("branch"))
                        {
                            exceptionBuilder.AppendLine($"'{Path.GetFileNameWithoutExtension(_module.Key)}' has a branch coverage '{branchPercent}%' below specified threshold '{dThreshold}%'");
                            thresholdFailed = true;
                        }

                        if (methodPercent < dThreshold && dThresholdTypes.Contains("method"))
                        {
                            exceptionBuilder.AppendLine($"'{Path.GetFileNameWithoutExtension(_module.Key)}' has a method coverage '{methodPercent}%' below specified threshold '{dThreshold}%'");
                            thresholdFailed = true;
                        }
                    }
                }

                logger.LogInformation(string.Empty);
                logger.LogInformation(coverageTable.ToStringAlternative());
                logger.LogInformation($"Total Line: {overallLineCoverage.Percent * 100}%");
                logger.LogInformation($"Total Branch: {overallBranchCoverage.Percent * 100}%");
                logger.LogInformation($"Total Method: {overallMethodCoverage.Percent * 100}%");

                if (thresholdFailed)
                {
                    throw new Exception(exceptionBuilder.ToString().TrimEnd(Environment.NewLine.ToCharArray()));
                }

                return(process.ExitCode == 0 ? 0 : process.ExitCode);
            });

            try
            {
                return(app.Execute(args));
            }
            catch (CommandParsingException ex)
            {
                logger.LogError(ex.Message);
                app.ShowHelp();
                return(1);
            }
            catch (Exception ex)
            {
                logger.LogError(ex.Message);
                return(1);
            }
        }
Пример #26
0
        static int Main(string[] args)
        {
            var logger = new ConsoleLogger();
            var app    = new CommandLineApplication();

            app.Name     = "coverlet";
            app.FullName = "Cross platform .NET Core code coverage tool";
            app.HelpOption("-h|--help");
            app.VersionOption("-v|--version", GetAssemblyVersion());
            int exitCode = (int)CommandExitCodes.Success;

            CommandArgument          module              = app.Argument("<ASSEMBLY>", "Path to the test assembly.");
            CommandOption            target              = app.Option("-t|--target", "Path to the test runner application.", CommandOptionType.SingleValue);
            CommandOption            targs               = app.Option("-a|--targetargs", "Arguments to be passed to the test runner.", CommandOptionType.SingleValue);
            CommandOption            output              = app.Option("-o|--output", "Output of the generated coverage report", CommandOptionType.SingleValue);
            CommandOption <LogLevel> verbosity           = app.Option <LogLevel>("-v|--verbosity", "Sets the verbosity level of the command. Allowed values are quiet, minimal, normal, detailed.", CommandOptionType.SingleValue);
            CommandOption            formats             = app.Option("-f|--format", "Format of the generated coverage report.", CommandOptionType.MultipleValue);
            CommandOption            threshold           = app.Option("--threshold", "Exits with error if the coverage % is below value.", CommandOptionType.SingleValue);
            CommandOption            thresholdTypes      = app.Option("--threshold-type", "Coverage type to apply the threshold to.", CommandOptionType.MultipleValue);
            CommandOption            thresholdStat       = app.Option("--threshold-stat", "Coverage statistic used to enforce the threshold value.", CommandOptionType.SingleValue);
            CommandOption            excludeFilters      = app.Option("--exclude", "Filter expressions to exclude specific modules and types.", CommandOptionType.MultipleValue);
            CommandOption            includeFilters      = app.Option("--include", "Filter expressions to include only specific modules and types.", CommandOptionType.MultipleValue);
            CommandOption            excludedSourceFiles = app.Option("--exclude-by-file", "Glob patterns specifying source files to exclude.", CommandOptionType.MultipleValue);
            CommandOption            includeDirectories  = app.Option("--include-directory", "Include directories containing additional assemblies to be instrumented.", CommandOptionType.MultipleValue);
            CommandOption            excludeAttributes   = app.Option("--exclude-by-attribute", "Attributes to exclude from code coverage.", CommandOptionType.MultipleValue);
            CommandOption            includeTestAssembly = app.Option("--include-test-assembly", "Specifies whether to report code coverage of the test assembly.", CommandOptionType.NoValue);
            CommandOption            singleHit           = app.Option("--single-hit", "Specifies whether to limit code coverage hit reporting to a single hit for each location", CommandOptionType.NoValue);
            CommandOption            mergeWith           = app.Option("--merge-with", "Path to existing coverage result to merge.", CommandOptionType.SingleValue);
            CommandOption            useSourceLink       = app.Option("--use-source-link", "Specifies whether to use SourceLink URIs in place of file system paths.", CommandOptionType.NoValue);

            app.OnExecute(() =>
            {
                if (string.IsNullOrEmpty(module.Value) || string.IsNullOrWhiteSpace(module.Value))
                {
                    throw new CommandParsingException(app, "No test assembly specified.");
                }

                if (!target.HasValue())
                {
                    throw new CommandParsingException(app, "Target must be specified.");
                }

                if (verbosity.HasValue())
                {
                    // Adjust log level based on user input.
                    logger.Level = verbosity.ParsedValue;
                }

                // We add default exclusion filter if no specified
                if (excludeFilters.Values.Count == 0)
                {
                    excludeFilters.Values.Add("[xunit*]*");
                }

                Coverage coverage = new Coverage(module.Value,
                                                 includeFilters.Values.ToArray(),
                                                 includeDirectories.Values.ToArray(),
                                                 excludeFilters.Values.ToArray(),
                                                 excludedSourceFiles.Values.ToArray(),
                                                 excludeAttributes.Values.ToArray(),
                                                 includeTestAssembly.HasValue(),
                                                 singleHit.HasValue(),
                                                 mergeWith.Value(),
                                                 useSourceLink.HasValue(),
                                                 logger);
                coverage.PrepareModules();

                Process process                          = new Process();
                process.StartInfo.FileName               = target.Value();
                process.StartInfo.Arguments              = targs.HasValue() ? targs.Value() : string.Empty;
                process.StartInfo.CreateNoWindow         = true;
                process.StartInfo.RedirectStandardOutput = true;
                process.StartInfo.RedirectStandardError  = true;
                process.OutputDataReceived              += (sender, eventArgs) =>
                {
                    if (!string.IsNullOrEmpty(eventArgs.Data))
                    {
                        logger.LogInformation(eventArgs.Data, important: true);
                    }
                };

                process.ErrorDataReceived += (sender, eventArgs) =>
                {
                    if (!string.IsNullOrEmpty(eventArgs.Data))
                    {
                        logger.LogError(eventArgs.Data);
                    }
                };

                process.Start();

                process.BeginErrorReadLine();
                process.BeginOutputReadLine();

                process.WaitForExit();

                var dOutput         = output.HasValue() ? output.Value() : Directory.GetCurrentDirectory() + Path.DirectorySeparatorChar.ToString();
                var dThreshold      = threshold.HasValue() ? double.Parse(threshold.Value()) : 0;
                var dThresholdTypes = thresholdTypes.HasValue() ? thresholdTypes.Values : new List <string>(new string[] { "line", "branch", "method" });
                var dThresholdStat  = thresholdStat.HasValue() ? Enum.Parse <ThresholdStatistic>(thresholdStat.Value(), true) : Enum.Parse <ThresholdStatistic>("minimum", true);

                logger.LogInformation("\nCalculating coverage result...");

                var result    = coverage.GetCoverageResult();
                var directory = Path.GetDirectoryName(dOutput);
                if (directory == string.Empty)
                {
                    directory = Directory.GetCurrentDirectory();
                }
                else if (!Directory.Exists(directory))
                {
                    Directory.CreateDirectory(directory);
                }

                foreach (var format in (formats.HasValue() ? formats.Values : new List <string>(new string[] { "json" })))
                {
                    var reporter = new ReporterFactory(format).CreateReporter();
                    if (reporter == null)
                    {
                        throw new Exception($"Specified output format '{format}' is not supported");
                    }

                    if (reporter.OutputType == ReporterOutputType.Console)
                    {
                        // Output to console
                        logger.LogInformation("  Outputting results to console", important: true);
                        logger.LogInformation(reporter.Report(result), important: true);
                    }
                    else
                    {
                        // Output to file
                        var filename = Path.GetFileName(dOutput);
                        filename     = (filename == string.Empty) ? $"coverage.{reporter.Extension}" : filename;
                        filename     = Path.HasExtension(filename) ? filename : $"{filename}.{reporter.Extension}";

                        var report = Path.Combine(directory, filename);
                        logger.LogInformation($"  Generating report '{report}'", important: true);
                        File.WriteAllText(report, reporter.Report(result));
                    }
                }

                var thresholdTypeFlags = ThresholdTypeFlags.None;

                foreach (var thresholdType in dThresholdTypes)
                {
                    if (thresholdType.Equals("line", StringComparison.OrdinalIgnoreCase))
                    {
                        thresholdTypeFlags |= ThresholdTypeFlags.Line;
                    }
                    else if (thresholdType.Equals("branch", StringComparison.OrdinalIgnoreCase))
                    {
                        thresholdTypeFlags |= ThresholdTypeFlags.Branch;
                    }
                    else if (thresholdType.Equals("method", StringComparison.OrdinalIgnoreCase))
                    {
                        thresholdTypeFlags |= ThresholdTypeFlags.Method;
                    }
                }

                var coverageTable = new ConsoleTable("Module", "Line", "Branch", "Method");
                var summary       = new CoverageSummary();
                int numModules    = result.Modules.Count;

                var totalLinePercent   = summary.CalculateLineCoverage(result.Modules).Percent;
                var totalBranchPercent = summary.CalculateBranchCoverage(result.Modules).Percent;
                var totalMethodPercent = summary.CalculateMethodCoverage(result.Modules).Percent;

                foreach (var _module in result.Modules)
                {
                    var linePercent   = summary.CalculateLineCoverage(_module.Value).Percent;
                    var branchPercent = summary.CalculateBranchCoverage(_module.Value).Percent;
                    var methodPercent = summary.CalculateMethodCoverage(_module.Value).Percent;

                    coverageTable.AddRow(Path.GetFileNameWithoutExtension(_module.Key), $"{linePercent}%", $"{branchPercent}%", $"{methodPercent}%");
                }

                logger.LogInformation(coverageTable.ToStringAlternative());

                coverageTable.Columns.Clear();
                coverageTable.Rows.Clear();

                coverageTable.AddColumn(new[] { "", "Line", "Branch", "Method" });
                coverageTable.AddRow("Total", $"{totalLinePercent}%", $"{totalBranchPercent}%", $"{totalMethodPercent}%");
                coverageTable.AddRow("Average", $"{totalLinePercent / numModules}%", $"{totalBranchPercent / numModules}%", $"{totalMethodPercent / numModules}%");

                logger.LogInformation(coverageTable.ToStringAlternative());
                if (process.ExitCode > 0)
                {
                    exitCode += (int)CommandExitCodes.TestFailed;
                }
                thresholdTypeFlags = result.GetThresholdTypesBelowThreshold(summary, dThreshold, thresholdTypeFlags, dThresholdStat);
                if (thresholdTypeFlags != ThresholdTypeFlags.None)
                {
                    exitCode += (int)CommandExitCodes.CoverageBelowThreshold;
                    var exceptionMessageBuilder = new StringBuilder();
                    if ((thresholdTypeFlags & ThresholdTypeFlags.Line) != ThresholdTypeFlags.None)
                    {
                        exceptionMessageBuilder.AppendLine($"The {dThresholdStat.ToString().ToLower()} line coverage is below the specified {dThreshold}");
                    }

                    if ((thresholdTypeFlags & ThresholdTypeFlags.Branch) != ThresholdTypeFlags.None)
                    {
                        exceptionMessageBuilder.AppendLine($"The {dThresholdStat.ToString().ToLower()} branch coverage is below the specified {dThreshold}");
                    }

                    if ((thresholdTypeFlags & ThresholdTypeFlags.Method) != ThresholdTypeFlags.None)
                    {
                        exceptionMessageBuilder.AppendLine($"The {dThresholdStat.ToString().ToLower()} method coverage is below the specified {dThreshold}");
                    }

                    throw new Exception(exceptionMessageBuilder.ToString());
                }

                return(exitCode);
            });

            try
            {
                return(app.Execute(args));
            }
            catch (CommandParsingException ex)
            {
                logger.LogError(ex.Message);
                app.ShowHelp();
                return((int)CommandExitCodes.CommandParsingException);
            }
            catch (Exception ex)
            {
                logger.LogError(ex.Message);
                return(exitCode > 0 ? exitCode : (int)CommandExitCodes.Exception);
            }
        }
Пример #27
0
 public override bool ConsistencyCheck(ReporterFactory reporterFactory)
 {
     return(FusionIndexBase.consistencyCheck(this, reporterFactory));
 }
        public void OnTestEvent(string report)
        {
            var eventTime = DateTime.UtcNow;
            var xmlNode   = XmlHelper.CreateXmlNode(report);

            switch (xmlNode.Name)
            {
            case "start-run":
            {
                var cmd      = Environment.CommandLine;
                var args     = Environment.GetCommandLineArgs();
                var projName = args.Length >= 2 ? args[1] : cmd;
                Reporter = ReporterFactory.Build(TestingFramework.NUnit, new TestDataProvider(), projName);
                Reporter.RunStarted();
                _testCases  = new List <GhprTestCase>();
                _testSuites = new List <GhprTestSuite>();
                break;
            }

            case "start-test":
            {
                var testRun = TestRunHelper.GetTestRunOnStarted(xmlNode, eventTime, Reporter.Logger);
                Reporter.TestStarted(testRun.GhprTestRun);
                break;
            }

            case "test-case":
            {
                var testCase = TestRunHelper.GetTestRunOnFinished(xmlNode, eventTime, Reporter.Logger);
                testCase.GhprTestOutput.TestOutputInfo.Date = eventTime;
                foreach (var screenshot in testCase.GhprTestScreenshots)
                {
                    var testScreenshotInfo = Reporter.DataWriterService.SaveScreenshot(screenshot);
                    if (testCase.GhprTestRun.Screenshots.All(s => s.Date != screenshot.TestScreenshotInfo.Date))
                    {
                        testCase.GhprTestRun.Screenshots.Add(testScreenshotInfo);
                    }
                }
                Reporter.TestFinished(testCase.GhprTestRun, testCase.GhprTestOutput);
                _testCases.Add(testCase);
                break;
            }

            case "test-suite":
            {
                var testSuite = TestRunHelper.GetTestSuite(xmlNode);
                _testSuites.Add(testSuite);
                var tests = _testCases.Where(tc => tc.ParentId.Equals(testSuite.Id) && !tc.ParentId.Equals(""))
                            .ToList();
                var childSuites = _testSuites
                                  .Where(ts => ts.ParentId.Equals(testSuite.Id) && !ts.ParentId.Equals("") && ts.Type.Equals("ParameterizedFixture")).ToList();
                foreach (var suite in childSuites)
                {
                    tests.AddRange(_testCases.Where(tc => tc.ParentId.Equals(suite.Id) && !tc.ParentId.Equals("")));
                }
                foreach (var test in tests)
                {
                    test.GhprTestOutput.SuiteOutput = testSuite.Output;
                    Reporter.DataWriterService.UpdateTestOutput(test.GhprTestRun.TestInfo, test.GhprTestOutput);
                }

                break;
            }

            case "test-run":
            {
                Reporter.RunFinished();
                Reporter.CleanUpJob();
                Reporter.TearDown();
                break;
            }
            }
        }
Пример #29
0
        static int Main(string[] args)
        {
            IServiceCollection serviceCollection = new ServiceCollection();

            serviceCollection.AddTransient <IRetryHelper, RetryHelper>();
            serviceCollection.AddTransient <IProcessExitHandler, ProcessExitHandler>();
            serviceCollection.AddTransient <IFileSystem, FileSystem>();
            serviceCollection.AddTransient <ILogger, ConsoleLogger>();
            // We need to keep singleton/static semantics
            serviceCollection.AddSingleton <IInstrumentationHelper, InstrumentationHelper>();
            serviceCollection.AddSingleton <ISourceRootTranslator, SourceRootTranslator>(provider => new SourceRootTranslator(provider.GetRequiredService <ILogger>(), provider.GetRequiredService <IFileSystem>()));
            serviceCollection.AddSingleton <ICecilSymbolHelper, CecilSymbolHelper>();

            ServiceProvider serviceProvider = serviceCollection.BuildServiceProvider();

            var logger     = (ConsoleLogger)serviceProvider.GetService <ILogger>();
            var fileSystem = serviceProvider.GetService <IFileSystem>();

            var app = new CommandLineApplication
            {
                Name     = "coverlet",
                FullName = "Cross platform .NET Core code coverage tool"
            };

            app.HelpOption("-h|--help");
            app.VersionOption("-v|--version", GetAssemblyVersion());
            int exitCode = (int)CommandExitCodes.Success;

            CommandArgument          moduleOrAppDirectory = app.Argument("<ASSEMBLY|DIRECTORY>", "Path to the test assembly or application directory.");
            CommandOption            target                  = app.Option("-t|--target", "Path to the test runner application.", CommandOptionType.SingleValue);
            CommandOption            targs                   = app.Option("-a|--targetargs", "Arguments to be passed to the test runner.", CommandOptionType.SingleValue);
            CommandOption            output                  = app.Option("-o|--output", "Output of the generated coverage report", CommandOptionType.SingleValue);
            CommandOption <LogLevel> verbosity               = app.Option <LogLevel>("-v|--verbosity", "Sets the verbosity level of the command. Allowed values are quiet, minimal, normal, detailed.", CommandOptionType.SingleValue);
            CommandOption            formats                 = app.Option("-f|--format", "Format of the generated coverage report.", CommandOptionType.MultipleValue);
            CommandOption            threshold               = app.Option("--threshold", "Exits with error if the coverage % is below value.", CommandOptionType.SingleValue);
            CommandOption            thresholdTypes          = app.Option("--threshold-type", "Coverage type to apply the threshold to.", CommandOptionType.MultipleValue);
            CommandOption            thresholdStat           = app.Option("--threshold-stat", "Coverage statistic used to enforce the threshold value.", CommandOptionType.SingleValue);
            CommandOption            excludeFilters          = app.Option("--exclude", "Filter expressions to exclude specific modules and types.", CommandOptionType.MultipleValue);
            CommandOption            includeFilters          = app.Option("--include", "Filter expressions to include only specific modules and types.", CommandOptionType.MultipleValue);
            CommandOption            excludedSourceFiles     = app.Option("--exclude-by-file", "Glob patterns specifying source files to exclude.", CommandOptionType.MultipleValue);
            CommandOption            includeDirectories      = app.Option("--include-directory", "Include directories containing additional assemblies to be instrumented.", CommandOptionType.MultipleValue);
            CommandOption            excludeAttributes       = app.Option("--exclude-by-attribute", "Attributes to exclude from code coverage.", CommandOptionType.MultipleValue);
            CommandOption            includeTestAssembly     = app.Option("--include-test-assembly", "Specifies whether to report code coverage of the test assembly.", CommandOptionType.NoValue);
            CommandOption            singleHit               = app.Option("--single-hit", "Specifies whether to limit code coverage hit reporting to a single hit for each location", CommandOptionType.NoValue);
            CommandOption            skipAutoProp            = app.Option("--skipautoprops", "Neither track nor record auto-implemented properties.", CommandOptionType.NoValue);
            CommandOption            mergeWith               = app.Option("--merge-with", "Path to existing coverage result to merge.", CommandOptionType.SingleValue);
            CommandOption            useSourceLink           = app.Option("--use-source-link", "Specifies whether to use SourceLink URIs in place of file system paths.", CommandOptionType.NoValue);
            CommandOption            doesNotReturnAttributes = app.Option("--does-not-return-attribute", "Attributes that mark methods that do not return.", CommandOptionType.MultipleValue);

            app.OnExecute(() =>
            {
                if (string.IsNullOrEmpty(moduleOrAppDirectory.Value) || string.IsNullOrWhiteSpace(moduleOrAppDirectory.Value))
                {
                    throw new CommandParsingException(app, "No test assembly or application directory specified.");
                }

                if (!target.HasValue())
                {
                    throw new CommandParsingException(app, "Target must be specified.");
                }

                if (verbosity.HasValue())
                {
                    // Adjust log level based on user input.
                    logger.Level = verbosity.ParsedValue;
                }

                CoverageParameters parameters = new()
                {
                    IncludeFilters          = includeFilters.Values.ToArray(),
                    IncludeDirectories      = includeDirectories.Values.ToArray(),
                    ExcludeFilters          = excludeFilters.Values.ToArray(),
                    ExcludedSourceFiles     = excludedSourceFiles.Values.ToArray(),
                    ExcludeAttributes       = excludeAttributes.Values.ToArray(),
                    IncludeTestAssembly     = includeTestAssembly.HasValue(),
                    SingleHit               = singleHit.HasValue(),
                    MergeWith               = mergeWith.Value(),
                    UseSourceLink           = useSourceLink.HasValue(),
                    SkipAutoProps           = skipAutoProp.HasValue(),
                    DoesNotReturnAttributes = doesNotReturnAttributes.Values.ToArray()
                };

                ISourceRootTranslator sourceRootTranslator = serviceProvider.GetRequiredService <ISourceRootTranslator>();

                Coverage coverage = new(moduleOrAppDirectory.Value,
                                        parameters,
                                        logger,
                                        serviceProvider.GetRequiredService <IInstrumentationHelper>(),
                                        fileSystem,
                                        sourceRootTranslator,
                                        serviceProvider.GetRequiredService <ICecilSymbolHelper>());
                coverage.PrepareModules();

                Process process                          = new();
                process.StartInfo.FileName               = target.Value();
                process.StartInfo.Arguments              = targs.HasValue() ? targs.Value() : string.Empty;
                process.StartInfo.CreateNoWindow         = true;
                process.StartInfo.RedirectStandardOutput = true;
                process.StartInfo.RedirectStandardError  = true;
                process.OutputDataReceived              += (sender, eventArgs) =>
                {
                    if (!string.IsNullOrEmpty(eventArgs.Data))
                    {
                        logger.LogInformation(eventArgs.Data, important: true);
                    }
                };

                process.ErrorDataReceived += (sender, eventArgs) =>
                {
                    if (!string.IsNullOrEmpty(eventArgs.Data))
                    {
                        logger.LogError(eventArgs.Data);
                    }
                };

                process.Start();

                process.BeginErrorReadLine();
                process.BeginOutputReadLine();

                process.WaitForExit();

                var dOutput         = output.HasValue() ? output.Value() : Directory.GetCurrentDirectory() + Path.DirectorySeparatorChar.ToString();
                var dThresholdTypes = thresholdTypes.HasValue() ? thresholdTypes.Values : new List <string>(new string[] { "line", "branch", "method" });
                var dThresholdStat  = thresholdStat.HasValue() ? Enum.Parse <ThresholdStatistic>(thresholdStat.Value(), true) : Enum.Parse <ThresholdStatistic>("minimum", true);

                logger.LogInformation("\nCalculating coverage result...");

                var result = coverage.GetCoverageResult();

                var directory = Path.GetDirectoryName(dOutput);
                if (directory == string.Empty)
                {
                    directory = Directory.GetCurrentDirectory();
                }
                else if (!Directory.Exists(directory))
                {
                    Directory.CreateDirectory(directory);
                }

                foreach (var format in formats.HasValue() ? formats.Values : new List <string>(new string[] { "json" }))
                {
                    var reporter = new ReporterFactory(format).CreateReporter();
                    if (reporter == null)
                    {
                        throw new Exception($"Specified output format '{format}' is not supported");
                    }

                    if (reporter.OutputType == ReporterOutputType.Console)
                    {
                        // Output to console
                        logger.LogInformation("  Outputting results to console", important: true);
                        logger.LogInformation(reporter.Report(result, sourceRootTranslator), important: true);
                    }
                    else
                    {
                        // Output to file
                        var filename = Path.GetFileName(dOutput);
                        filename     = (filename == string.Empty) ? $"coverage.{reporter.Extension}" : filename;
                        filename     = Path.HasExtension(filename) ? filename : $"{filename}.{reporter.Extension}";

                        var report = Path.Combine(directory, filename);
                        logger.LogInformation($"  Generating report '{report}'", important: true);
                        fileSystem.WriteAllText(report, reporter.Report(result, sourceRootTranslator));
                    }
                }

                var thresholdTypeFlagQueue = new Queue <ThresholdTypeFlags>();

                foreach (var thresholdType in dThresholdTypes)
                {
                    if (thresholdType.Equals("line", StringComparison.OrdinalIgnoreCase))
                    {
                        thresholdTypeFlagQueue.Enqueue(ThresholdTypeFlags.Line);
                    }
                    else if (thresholdType.Equals("branch", StringComparison.OrdinalIgnoreCase))
                    {
                        thresholdTypeFlagQueue.Enqueue(ThresholdTypeFlags.Branch);
                    }
                    else if (thresholdType.Equals("method", StringComparison.OrdinalIgnoreCase))
                    {
                        thresholdTypeFlagQueue.Enqueue(ThresholdTypeFlags.Method);
                    }
                }

                Dictionary <ThresholdTypeFlags, double> thresholdTypeFlagValues = new Dictionary <ThresholdTypeFlags, double>();
                if (threshold.HasValue() && threshold.Value().Contains(','))
                {
                    var thresholdValues = threshold.Value().Split(',', StringSplitOptions.RemoveEmptyEntries).Select(t => t.Trim());
                    if (thresholdValues.Count() != thresholdTypeFlagQueue.Count())
                    {
                        throw new Exception($"Threshold type flag count ({thresholdTypeFlagQueue.Count()}) and values count ({thresholdValues.Count()}) doesn't match");
                    }

                    foreach (var thresholdValue in thresholdValues)
                    {
                        if (double.TryParse(thresholdValue, out var value))
                        {
                            thresholdTypeFlagValues[thresholdTypeFlagQueue.Dequeue()] = value;
                        }
                        else
                        {
                            throw new Exception($"Invalid threshold value must be numeric");
                        }
                    }
                }
                else
                {
                    double thresholdValue = threshold.HasValue() ? double.Parse(threshold.Value()) : 0;

                    while (thresholdTypeFlagQueue.Any())
                    {
                        thresholdTypeFlagValues[thresholdTypeFlagQueue.Dequeue()] = thresholdValue;
                    }
                }

                var coverageTable = new ConsoleTable("Module", "Line", "Branch", "Method");
                var summary       = new CoverageSummary();

                var linePercentCalculation   = summary.CalculateLineCoverage(result.Modules);
                var branchPercentCalculation = summary.CalculateBranchCoverage(result.Modules);
                var methodPercentCalculation = summary.CalculateMethodCoverage(result.Modules);

                var totalLinePercent   = linePercentCalculation.Percent;
                var totalBranchPercent = branchPercentCalculation.Percent;
                var totalMethodPercent = methodPercentCalculation.Percent;

                var averageLinePercent   = linePercentCalculation.AverageModulePercent;
                var averageBranchPercent = branchPercentCalculation.AverageModulePercent;
                var averageMethodPercent = methodPercentCalculation.AverageModulePercent;

                foreach (var _module in result.Modules)
                {
                    var linePercent   = summary.CalculateLineCoverage(_module.Value).Percent;
                    var branchPercent = summary.CalculateBranchCoverage(_module.Value).Percent;
                    var methodPercent = summary.CalculateMethodCoverage(_module.Value).Percent;

                    coverageTable.AddRow(Path.GetFileNameWithoutExtension(_module.Key), $"{InvariantFormat(linePercent)}%", $"{InvariantFormat(branchPercent)}%", $"{InvariantFormat(methodPercent)}%");
                }

                logger.LogInformation(coverageTable.ToStringAlternative());

                coverageTable.Columns.Clear();
                coverageTable.Rows.Clear();

                coverageTable.AddColumn(new[] { "", "Line", "Branch", "Method" });
                coverageTable.AddRow("Total", $"{InvariantFormat(totalLinePercent)}%", $"{InvariantFormat(totalBranchPercent)}%", $"{InvariantFormat(totalMethodPercent)}%");
                coverageTable.AddRow("Average", $"{InvariantFormat(averageLinePercent)}%", $"{InvariantFormat(averageBranchPercent)}%", $"{InvariantFormat(averageMethodPercent)}%");

                logger.LogInformation(coverageTable.ToStringAlternative());
                if (process.ExitCode > 0)
                {
                    exitCode += (int)CommandExitCodes.TestFailed;
                }

                var thresholdTypeFlags = result.GetThresholdTypesBelowThreshold(summary, thresholdTypeFlagValues, dThresholdStat);
                if (thresholdTypeFlags != ThresholdTypeFlags.None)
                {
                    exitCode += (int)CommandExitCodes.CoverageBelowThreshold;
                    var exceptionMessageBuilder = new StringBuilder();
                    if ((thresholdTypeFlags & ThresholdTypeFlags.Line) != ThresholdTypeFlags.None)
                    {
                        exceptionMessageBuilder.AppendLine($"The {dThresholdStat.ToString().ToLower()} line coverage is below the specified {thresholdTypeFlagValues[ThresholdTypeFlags.Line]}");
                    }

                    if ((thresholdTypeFlags & ThresholdTypeFlags.Branch) != ThresholdTypeFlags.None)
                    {
                        exceptionMessageBuilder.AppendLine($"The {dThresholdStat.ToString().ToLower()} branch coverage is below the specified {thresholdTypeFlagValues[ThresholdTypeFlags.Branch]}");
                    }

                    if ((thresholdTypeFlags & ThresholdTypeFlags.Method) != ThresholdTypeFlags.None)
                    {
                        exceptionMessageBuilder.AppendLine($"The {dThresholdStat.ToString().ToLower()} method coverage is below the specified {thresholdTypeFlagValues[ThresholdTypeFlags.Method]}");
                    }
                    throw new Exception(exceptionMessageBuilder.ToString());
                }

                return(exitCode);
            });

            try
            {
                return(app.Execute(args));
            }
            catch (CommandParsingException ex)
            {
                logger.LogError(ex.Message);
                app.ShowHelp();
                return((int)CommandExitCodes.CommandParsingException);
            }
            catch (Win32Exception we) when(we.Source == "System.Diagnostics.Process")
            {
                logger.LogError($"Start process '{target.Value()}' failed with '{we.Message}'");
                return(exitCode > 0 ? exitCode : (int)CommandExitCodes.Exception);
            }
            catch (Exception ex)
            {
                logger.LogError(ex.Message);
                return(exitCode > 0 ? exitCode : (int)CommandExitCodes.Exception);
            }
        }
Пример #30
0
        public override bool Execute()
        {
            try
            {
                Console.WriteLine("\nCalculating coverage result...");

                var coverage = InstrumentationTask.Coverage;
                var result   = coverage.GetCoverageResult();

                var directory = Path.GetDirectoryName(_output);
                if (!Directory.Exists(directory))
                {
                    Directory.CreateDirectory(directory);
                }

                var formats = _format.Split(',');
                foreach (var format in formats)
                {
                    var reporter = new ReporterFactory(format).CreateReporter();
                    if (reporter == null)
                    {
                        throw new Exception($"Specified output format '{format}' is not supported");
                    }

                    var filename = Path.GetFileName(_output);
                    filename = (filename == string.Empty) ? $"coverage.{reporter.Extension}" : filename;

                    var report = Path.Combine(directory, filename);
                    Console.WriteLine($"  Generating report '{report}'");
                    File.WriteAllText(report, reporter.Report(result));
                }

                var thresholdFailed  = false;
                var thresholdTypes   = _thresholdType.Split(',').Select(t => t.Trim());
                var summary          = new CoverageSummary();
                var exceptionBuilder = new StringBuilder();
                var coverageTable    = new ConsoleTable("Module", "Line", "Branch", "Method");

                foreach (var module in result.Modules)
                {
                    var linePercent   = summary.CalculateLineCoverage(module.Value).Percent * 100;
                    var branchPercent = summary.CalculateBranchCoverage(module.Value).Percent * 100;
                    var methodPercent = summary.CalculateMethodCoverage(module.Value).Percent * 100;

                    coverageTable.AddRow(Path.GetFileNameWithoutExtension(module.Key), $"{linePercent}%", $"{branchPercent}%", $"{methodPercent}%");

                    if (_threshold > 0)
                    {
                        if (linePercent < _threshold && thresholdTypes.Contains("line"))
                        {
                            exceptionBuilder.AppendLine($"'{Path.GetFileNameWithoutExtension(module.Key)}' has a line coverage '{linePercent}%' below specified threshold '{_threshold}%'");
                            thresholdFailed = true;
                        }

                        if (branchPercent < _threshold && thresholdTypes.Contains("branch"))
                        {
                            exceptionBuilder.AppendLine($"'{Path.GetFileNameWithoutExtension(module.Key)}' has a branch coverage '{branchPercent}%' below specified threshold '{_threshold}%'");
                            thresholdFailed = true;
                        }

                        if (methodPercent < _threshold && thresholdTypes.Contains("method"))
                        {
                            exceptionBuilder.AppendLine($"'{Path.GetFileNameWithoutExtension(module.Key)}' has a method coverage '{methodPercent}%' below specified threshold '{_threshold}%'");
                            thresholdFailed = true;
                        }
                    }
                }

                Console.WriteLine();
                Console.WriteLine(coverageTable.ToStringAlternative());

                if (thresholdFailed)
                {
                    throw new Exception(exceptionBuilder.ToString().TrimEnd(Environment.NewLine.ToCharArray()));
                }
            }
            catch (Exception ex)
            {
                Log.LogErrorFromException(ex);
                return(false);
            }

            return(true);
        }