/// <inheritdoc />
        public async Task InitializeAsync(IClientFactory clientFactory, IPipelineConfig pipelineConfig, ITraceLogger traceLogger, ITelemetryDataCollector telemetry)
        {
            await Task.Run(() =>
            {
                _logger         = traceLogger;
                _telemetry      = telemetry;
                var publisher   = new PipelineTestRunPublisher(clientFactory, pipelineConfig, _logger, _telemetry);
                _testRunManager = new TestRunManager(publisher, _logger, _telemetry);
                var parsers     = ParserFactory.GetTestResultParsers(_testRunManager, traceLogger, _telemetry).ToList();

                _telemetry.AddOrUpdate(TelemetryConstants.ParserCount, parsers.Count);

                foreach (var parser in parsers)
                {
                    // Subscribe parsers to Pub-Sub model
                    Subscribe(parser.Parse);
                }
            });
        }
Example #2
0
        public async Task PublishAsync()
        {
            var testResultFiles = new List <string>();
            IList <TestRunData> testData;

            var testRunContext = new TestRunContextBuilder("JUnit test results")
                                 .WithBuildId(_pipelineConfig.BuildId)
                                 .WithBuildUri(_pipelineConfig.BuildUri)
                                 .WithStageName(_pipelineConfig.StageName)
                                 .WithStageAttempt(_pipelineConfig.StageAttempt)
                                 .WithPhaseName(_pipelineConfig.PhaseName)
                                 .WithPhaseAttempt(_pipelineConfig.PhaseAttempt)
                                 .WithJobName(_pipelineConfig.JobName)
                                 .WithJobAttempt(_pipelineConfig.JobAttempt)
                                 .Build();

            using (new SimpleTimer(TelemetryConstants.FindTestFilesAsync, _logger, TimeSpan.FromSeconds(60),
                                   new TelemetryDataWrapper(_telemetry, TelemetryConstants.FindTestFilesAsync)))
            {
                try
                {
                    testResultFiles.AddRange(await FindTestFilesAsync());

                    _logger.Info($"Number of files found with matching pattern {testResultFiles.Count}");
                }
                catch (Exception ex)
                {
                    _logger.Info($"Error: {ex.Message}");
                    _telemetry.AddOrUpdate("FindTestFilesError", ex);
                }
            }

            _telemetry.AddOrUpdate("NumberOfTestFilesFound", testResultFiles.Count);
            if (!testResultFiles.Any())
            {
                _logger.Info("No test result files are found");
                return;
            }

            using (new SimpleTimer(TelemetryConstants.ParseTestResultFiles, _logger, TimeSpan.FromSeconds(60),
                                   new TelemetryDataWrapper(_telemetry, TelemetryConstants.ParseTestResultFiles)))
            {
                testData = _testResultParser.ParseTestResultFiles(testRunContext, testResultFiles).GetTestRunData();

                _logger.Info($"Successfully parsed {testData?.Count} files");
                _telemetry.AddOrUpdate("NumberOfTestFilesRead", testData?.Count);
            }

            if (testData == null || !testData.Any())
            {
                _logger.Info("No valid Junit test result files are found which can be parsed");
                return;
            }

            using (new SimpleTimer(TelemetryConstants.PublishTestRunDataAsync, _logger, TimeSpan.FromSeconds(60),
                                   new TelemetryDataWrapper(_telemetry, TelemetryConstants.PublishTestRunDataAsync)))
            {
                var publishedRuns = await _testRunPublisher.PublishTestRunDataAsync(testRunContext, _pipelineConfig.ProjectName, testData, new PublishOptions(),
                                                                                    new CancellationToken());

                if (publishedRuns != null)
                {
                    _logger.Info($"Successfully published {publishedRuns.Count} runs");
                    _telemetry.AddOrUpdate("NumberOfTestRunsPublished", publishedRuns.Count);
                    _telemetry.AddOrUpdate("TestRunIds", string.Join(",", publishedRuns.Select(x => x.Id)));
                }
                else
                {
                    _telemetry.AddOrUpdate("NumberOfTestRunsPublished", 0);
                }
            }
        }
        public async Task ParseAndPublishCoverage(PublisherConfiguration config, CancellationToken token, Parser parser)
        {
            if (_publisher != null)
            {
                try
                {
                    _telemetry.AddOrUpdate("PublisherConfig", () =>
                    {
                        return("{" +
                               $"\"InputFilesCount\": {config.CoverageFiles.Count}," +
                               $"\"SourceDirectoryProvided\": {config.SourceDirectory != ""}," +
                               $"\"GenerateHtmlReport\": {config.GenerateHTMLReport}," +
                               $"\"GenerateHtmlReport\": {config.TimeoutInSeconds}" +
                               "}");
                    });

                    var supportsFileCoverageJson = _publisher.IsFileCoverageJsonSupported();

                    if (supportsFileCoverageJson)
                    {
                        TraceLogger.Debug("Publishing file json coverage is supported.");
                        var fileCoverage = parser.GetFileCoverageInfos();

                        _telemetry.AddOrUpdate("UniqueFilesCovered", fileCoverage.Count);

                        if (fileCoverage.Count == 0)
                        {
                            TraceLogger.Warning(Resources.NoCoverageFilesGenerated);
                        }
                        else
                        {
                            using (new SimpleTimer("CoverageProcesser", "PublishFileCoverage", _telemetry))
                            {
                                await _publisher.PublishFileCoverage(fileCoverage, token);
                            }
                        }
                    }
                    else
                    {
                        TraceLogger.Debug("Publishing file json coverage is not supported.");
                        var summary = parser.GetCoverageSummary();

                        if (summary == null || summary.CodeCoverageData.CoverageStats.Count == 0)
                        {
                            TraceLogger.Warning(Resources.NoSummaryStatisticsGenerated);
                        }
                        else
                        {
                            using (new SimpleTimer("CoverageProcesser", "PublishCoverageSummary", _telemetry))
                            {
                                await _publisher.PublishCoverageSummary(summary, token);
                            }
                        }
                    }

                    if (config.GenerateHTMLReport)
                    {
                        if (!Directory.Exists(config.ReportDirectory))
                        {
                            TraceLogger.Warning(Resources.NoReportDirectoryGenerated);
                        }
                        else
                        {
                            using (new SimpleTimer("CoverageProcesser", "PublishHTMLReport", _telemetry))
                            {
                                await _publisher.PublishHTMLReport(config.ReportDirectory, token);
                            }
                        }
                    }
                }
                // Only catastrophic failures should trickle down to these catch blocks
                catch (ParsingException ex)
                {
                    _telemetry.AddFailure(ex);
                    TraceLogger.Error($"{ex.Message} {ex.InnerException}");
                }
                catch (Exception ex)
                {
                    _telemetry.AddFailure(ex);
                    TraceLogger.Error(string.Format(Resources.ErrorOccuredWhilePublishing, ex));
                }
            }
        }