Beispiel #1
0
        private void SetBuildLog(CppBuildExecutor buildExecutor, string log)
        {
            _buildDiagnostics = string.Empty;

            if (buildExecutor.LastBuildStatus == Constants.BuildExecutionStatus.Failed && EnableDiagnostics)
            {
                _buildDiagnostics = log;
            }
        }
Beispiel #2
0
        public async Task ExecuteMutants()
        {
            var mutationProcessLog = new StringBuilder();

            if (!_cpp.Mutants.Any())
            {
                PrintMutationReport(mutationProcessLog, _cpp.Mutants);
                return;
            }

            var mutants = _cpp.NotRunMutants;

            var testTasks    = new List <Task>();
            int totalMutants = mutants.Count;

            for (var index = 0; index < mutants.Count; index += NumberOfMutantsExecutingInParallel)
            {
                if (CancelMutationOperation)
                {
                    break;
                }

                var directoryIndex = -1;
                var buildExecutor  = new CppBuildExecutor(
                    _settings,
                    _context.TestSolution.FullName,
                    _cpp.Target)
                {
                    EnableLogging          = false,
                    Configuration          = _cpp.Configuration,
                    Platform               = _cpp.Platform,
                    IntDir                 = _context.IntDir,
                    OutDir                 = _context.OutDir,
                    OutputPath             = _context.OutputPath,
                    IntermediateOutputPath = _context.IntermediateOutputPath
                };

                if (!_context.UseMultipleSolutions)
                {
                    for (var mutationIndex = index;
                         mutationIndex < Math.Min(index + NumberOfMutantsExecutingInParallel, mutants.Count);
                         mutationIndex++)
                    {
                        directoryIndex++;
                        var mutant = mutants[mutationIndex];

                        var testContext     = _context.TestContexts[directoryIndex];
                        var destinationFile = testContext.SourceClass.FullName;

                        _cpp.SourceClass.ReplaceLine(
                            mutant.Mutation.LineNumber,
                            mutant.Mutation.ReplacementNode,
                            destinationFile);

                        destinationFile.AddNameSpace(testContext.Index);
                    }

                    if (_context.EnableBuildOptimization)
                    {
                        if (!_cpp.IncludeBuildEvents)
                        {
                            _context.TestProject.FullName.RemoveBuildEvents();
                        }

                        _context.TestProject.FullName.OptimizeTestProject();
                    }

                    var buildLog = new StringBuilder();
                    void BuildOutputDataReceived(object sender, string args) => buildLog.Append(args.PrintWithPreTag());

                    buildExecutor.OutputDataReceived += BuildOutputDataReceived;

                    await buildExecutor.ExecuteBuild();

                    SetBuildLog(buildExecutor, buildLog.ToString());
                    buildExecutor.OutputDataReceived -= BuildOutputDataReceived;
                }

                directoryIndex = -1;
                for (var mutationIndex = index;
                     mutationIndex < Math.Min(index + NumberOfMutantsExecutingInParallel, mutants.Count);
                     mutationIndex++)
                {
                    if (CancelMutationOperation)
                    {
                        break;
                    }

                    if (decimal.Divide(mutants.Count(x => x.ResultStatus == MutantStatus.Survived), totalMutants) >
                        (decimal)SurvivedThreshold ||
                        decimal.Divide(mutants.Count(x => x.ResultStatus == MutantStatus.Killed), totalMutants) >
                        (decimal)KilledThreshold)
                    {
                        break;
                    }

                    var mutant = mutants[mutationIndex];
                    directoryIndex++;

                    try
                    {
                        if (_context.UseMultipleSolutions)
                        {
                            var testContext     = _context.TestContexts[directoryIndex];
                            var destinationFile = testContext.SourceClass.FullName;

                            if (_context.TestContexts.Any(x => x.BackupSourceClass != null))
                            {
                                _context.TestContexts[0]
                                .BackupSourceClass
                                .FullName
                                .ReplaceLine(
                                    mutant.Mutation.LineNumber,
                                    mutant.Mutation.ReplacementNode,
                                    destinationFile);
                            }
                            else
                            {
                                _cpp.SourceClass.ReplaceLine(
                                    mutant.Mutation.LineNumber,
                                    mutant.Mutation.ReplacementNode,
                                    destinationFile);
                            }
                        }
                        else if (buildExecutor.LastBuildStatus == Constants.BuildExecutionStatus.Failed)
                        {
                            mutant.ResultStatus = MutantStatus.BuildError;
                            OnMutantExecuted(new CppMutantEventArgs
                            {
                                Mutant   = mutant,
                                TestLog  = _testDiagnostics,
                                BuildLog = _buildDiagnostics
                            });
                            continue;
                        }

                        var current = directoryIndex;
                        testTasks.Add(Task.Run(() => BuildAndExecuteTests(mutant, current)));
                    }
                    catch (Exception e)
                    {
                        mutant.ResultStatus = MutantStatus.Skipped;
                        Trace.TraceError("Unable to Execute Mutant {0} Exception: {1}",
                                         mutant.Mutation.OriginalNode.Encode(), e);
                    }
                }

                await Task.WhenAll(testTasks);

                _context.EnableBuildOptimization = false;
            }

            PrintMutationReport(mutationProcessLog, _cpp.Mutants);
        }
Beispiel #3
0
        private async Task BuildAndExecuteTests(CppMutant mutant, int index)
        {
            try
            {
                if (_context.UseMultipleSolutions)
                {
                    var buildExecutor = new CppBuildExecutor(
                        _settings,
                        string.Format(_context.TestSolution.FullName, index),
                        _cpp.Target)
                    {
                        EnableLogging          = false,
                        Configuration          = _cpp.Configuration,
                        Platform               = _cpp.Platform,
                        IntDir                 = string.Format(_context.IntDir, index),
                        OutDir                 = string.Format(_context.OutDir, index),
                        OutputPath             = string.Format(_context.OutputPath, index),
                        IntermediateOutputPath = string.Format(_context.IntermediateOutputPath, index)
                    };

                    if (_context.EnableBuildOptimization)
                    {
                        if (!_cpp.IncludeBuildEvents)
                        {
                            string.Format(_context.TestProject.FullName, index).RemoveBuildEvents();
                        }

                        string.Format(_context.TestProject.FullName, index).OptimizeTestProject();
                    }

                    var buildLog = new StringBuilder();

                    void BuildOutputDataReceived(object sender, string args)
                    {
                        lock (AppendLock)
                        {
                            buildLog.Append(args.PrintWithPreTag());
                        }
                    }

                    buildExecutor.OutputDataReceived += BuildOutputDataReceived;
                    await buildExecutor.ExecuteBuild();

                    if (buildExecutor.LastBuildStatus == Constants.BuildExecutionStatus.Failed)
                    {
                        buildLog.Clear();
                        buildExecutor.Rebuild = true;

                        await buildExecutor.ExecuteBuild();

                        buildExecutor.Rebuild = false;
                    }

                    lock (BuildAndExecuteTestLock)
                    {
                        SetBuildLog(buildExecutor, buildLog.ToString());
                        buildExecutor.OutputDataReceived -= BuildOutputDataReceived;
                    }

                    if (buildExecutor.LastBuildStatus == Constants.BuildExecutionStatus.Failed)
                    {
                        mutant.ResultStatus = MutantStatus.BuildError;
                        OnMutantExecuted(new CppMutantEventArgs
                        {
                            Mutant   = mutant,
                            TestLog  = _testDiagnostics,
                            BuildLog = _buildDiagnostics
                        });

                        return;
                    }
                }

                var testExecutor = new GoogleTestExecutor
                {
                    KillProcessOnTestFail = true,
                    EnableTestTimeout     = true,
                    TestTimeout           = _settings.TestTimeout
                };

                var log = new StringBuilder();
                void OutputDataReceived(object sender, string args) => log.Append(args.PrintWithPreTag());

                if (EnableDiagnostics)
                {
                    log.AppendLine("<fieldset style=\"margin-bottom:10\">");
                    var lineNumber = mutant.Mutation.LineNumber;
                    log.Append(
                        $"Line: {lineNumber.ToString().PrintImportant(color: Constants.Colors.Blue)} - {mutant.Mutation.DisplayName.Encode()}"
                        .PrintWithDateTime()
                        .PrintWithPreTag());
                    testExecutor.OutputDataReceived += OutputDataReceived;
                }

                var projectDirectory = Path.GetDirectoryName(_cpp.TestProject);
                var projectName      = Path.GetFileNameWithoutExtension(_cpp.TestProject);

                var projectNameFromTestContext =
                    string.Format(Path.GetFileNameWithoutExtension(_context.TestProject.Name), index);
                var app = $"{projectDirectory}/{string.Format(_context.OutDir, index)}{projectName}.exe";

                if (!File.Exists(app))
                {
                    app = $"{projectDirectory}/{string.Format(_context.OutDir, index)}{projectNameFromTestContext}.exe";
                }

                await testExecutor.ExecuteTests(
                    app,
                    _cpp.UseClassFilter
                    ?$"{Path.GetFileNameWithoutExtension(_context.TestContexts[index].TestClass.Name)}*"
                    : string.Empty);

                testExecutor.OutputDataReceived -= OutputDataReceived;
                if (EnableDiagnostics && testExecutor.LastTestExecutionStatus == Constants.TestExecutionStatus.Timeout)
                {
                    log.AppendLine("</fieldset>");
                    _testDiagnostics = log.ToString();
                }

                mutant.ResultStatus = testExecutor.LastTestExecutionStatus == Constants.TestExecutionStatus.Success
                    ? MutantStatus.Survived
                    : testExecutor.LastTestExecutionStatus == Constants.TestExecutionStatus.Timeout
                        ? MutantStatus.Timeout
                        : MutantStatus.Killed;
                OnMutantExecuted(new CppMutantEventArgs
                {
                    Mutant   = mutant,
                    BuildLog = _buildDiagnostics,
                    TestLog  = _testDiagnostics
                });
            }
            catch (Exception e)
            {
                mutant.ResultStatus = MutantStatus.BuildError;
                OnMutantExecuted(new CppMutantEventArgs
                {
                    Mutant   = mutant,
                    BuildLog = e.ToString(),
                });
            }
        }