Exemple #1
0
        public VsTestRunnerPool(IStrykerOptions options, OptimizationFlags flags, ProjectInfo projectInfo)
        {
            _logger = ApplicationLogging.LoggerFactory.CreateLogger <VsTestRunnerPool>();

            _flags = flags;
            using (var runner = new VsTestRunner(options, _flags, projectInfo, null, helper: _helper))
            {
                _discoveredTests = runner.DiscoverTests();
                _availableRunners.Add(runner);
            }

            Parallel.For(1, options.ConcurrentTestRunners, (i, loopState) =>
            {
                _availableRunners.Add(new VsTestRunner(options, _flags, projectInfo, _discoveredTests, helper: _helper));
            });
        }
        public CsharpMutationProcess(MutationTestInput mutationTestInput,
                                     IFileSystem fileSystem     = null,
                                     IStrykerOptions options    = null,
                                     IMutantFilter mutantFilter = null,
                                     MutantOrchestrator <SyntaxNode> orchestrator = null)
        {
            _input            = mutationTestInput;
            _projectInfo      = (ProjectComponent <SyntaxTree>)mutationTestInput.ProjectInfo.ProjectContents;
            _options          = options;
            _orchestrator     = orchestrator ?? new CsharpMutantOrchestrator(options: _options);
            _compilingProcess = new CompilingProcess(mutationTestInput, new RollbackProcess());
            _fileSystem       = fileSystem ?? new FileSystem();
            _logger           = ApplicationLogging.LoggerFactory.CreateLogger <MutationTestProcess>();

            _mutantFilter = mutantFilter ?? MutantFilterFactory.Create(options);
        }
Exemple #3
0
        public ITestRunner Create(IStrykerOptions options, OptimizationFlags flags, ProjectInfo projectInfo)
        {
            _logger.LogInformation("Initializing test runners ({0})", options.TestRunner);
            ITestRunner testRunner;

            switch (options.TestRunner)
            {
            case TestRunner.DotnetTest:
            default:
                testRunner = new DotnetTestRunner(projectInfo.ProjectUnderTestAnalyzerResult.ProjectFilePath, new ProcessExecutor(), flags, projectInfo.TestProjectAnalyzerResults.Select(x => x.GetAssemblyPath()));
                break;

            case TestRunner.VsTest:
                testRunner = new VsTestRunnerPool(options, flags, projectInfo);
                break;
            }
            return(testRunner);
        }
 public MutationTestProcess(MutationTestInput mutationTestInput,
                            IReporter reporter,
                            IMutationTestExecutor mutationTestExecutor,
                            MutantOrchestrator <SyntaxNode> orchestrator = null,
                            IFileSystem fileSystem             = null,
                            IMutantFilter mutantFilter         = null,
                            ICoverageAnalyser coverageAnalyser = null,
                            IStrykerOptions options            = null)
 {
     Input                 = mutationTestInput;
     _projectContents      = mutationTestInput.ProjectInfo.ProjectContents;
     _reporter             = reporter;
     _options              = options;
     _mutationTestExecutor = mutationTestExecutor;
     _logger               = ApplicationLogging.LoggerFactory.CreateLogger <MutationTestProcess>();
     _coverageAnalyser     = coverageAnalyser ?? new CoverageAnalyser(_options, _mutationTestExecutor, Input);
     _mutationProcess      = new CsharpMutationProcess(Input, fileSystem ?? new FileSystem(), _options, mutantFilter, _reporter, orchestrator);
 }
Exemple #5
0
        /// <param name="mutators">The mutators that should be active during the mutation process</param>
        public CsharpMutantOrchestrator(IEnumerable <IMutator> mutators = null, IStrykerOptions options = null) : base(options)
        {
            Mutators = mutators ?? new List <IMutator>
            {
                // the default list of mutators
                new BinaryExpressionMutator(),
                new BooleanMutator(),
                new AssignmentExpressionMutator(),
                new PrefixUnaryMutator(),
                new PostfixUnaryMutator(),
                new CheckedMutator(),
                new LinqMutator(),
                new StringMutator(),
                new StringEmptyMutator(),
                new InterpolatedStringMutator(),
                new NegateConditionMutator(),
                new InitializerMutator(),
                new ObjectCreationMutator(),
                new ArrayCreationMutator(),
                new RegexMutator()
            };
            Mutants = new Collection <Mutant>();
            Logger  = ApplicationLogging.LoggerFactory.CreateLogger <CsharpMutantOrchestrator>();

            _specificOrchestrator.RegisterHandlers(new List <INodeMutator>
            {
                new ForStatementOrchestrator(this),
                new AssignmentStatementOrchestrator(this),
                new PostfixUnaryExpressionOrchestrator(this),
                new StaticFieldDeclarationOrchestrator(this),
                new StaticConstructorOrchestrator(this),
                new PropertyDeclarationOrchestrator(this),
                new ArrayInitializerOrchestrator(this),
                new MemberDeclarationOrchestrator <MemberDeclarationSyntax, MemberDeclarationSyntax>(this),
                new BaseMethodDeclarationOrchestrator <BaseMethodDeclarationSyntax>(this),
                new AccessorSyntaxOrchestrator(this),
                new LocalDeclarationOrchestrator(this),
                new StatementSpecificOrchestrator <StatementSyntax>(this),
                new BlockOrchestrator(this),
                new ExpressionSpecificOrchestrator <ExpressionSyntax>(this),
                new SyntaxNodeOrchestrator(this)
            });
        }
Exemple #6
0
        private static IEnumerable <IMutantFilter> DetermineEnabledMutantFilters(IStrykerOptions options)
        {
            var enabledFilters = new List <IMutantFilter> {
                new FilePatternMutantFilter(options),
                new IgnoredMethodMutantFilter(),
                new ExcludeMutationMutantFilter(),
                new ExcludeFromCodeCoverageFilter()
            };

            if (options.CompareToDashboard)
            {
                enabledFilters.Add(new DashboardMutantFilter(options, _baselineProvider, _gitInfoProvider));
            }
            if (options.DiffEnabled || options.CompareToDashboard)
            {
                enabledFilters.Add(new DiffMutantFilter(_diffProvider));
            }

            return(enabledFilters);
        }
Exemple #7
0
        public IMutationTestProcess MutateProject(IStrykerOptions options, IReporter reporters)
        {
            // get a new instance of InitialisationProcess for each project
            var initialisationProcess = _initialisationProcessProvider.Provide();
            // initialize
            var input = initialisationProcess.Initialize(options);

            var process = _mutationTestProcessProvider.Provide(
                mutationTestInput: input,
                reporter: reporters,
                mutationTestExecutor: new MutationTestExecutor(input.TestRunner),
                options: options);

            // initial test
            input.TimeoutMs = initialisationProcess.InitialTest(options);

            // mutate
            process.Mutate();

            return(process);
        }
        private void ValidateTestProjectsCanBeExecuted(ProjectInfo projectInfo, IStrykerOptions options)
        {
            // if references contains Microsoft.VisualStudio.QualityTools.UnitTestFramework
            // we have detected usage of mstest V1 and should exit
            if (projectInfo.TestProjectAnalyzerResults.Any(testProject => testProject.References
                                                           .Any(r => r.Contains("Microsoft.VisualStudio.QualityTools.UnitTestFramework"))))
            {
                throw new StrykerInputException("Please upgrade to MsTest V2. Stryker.NET uses VSTest which does not support MsTest V1.",
                                                @"See https://devblogs.microsoft.com/devops/upgrade-to-mstest-v2/ for upgrade instructions.");
            }

            // if IsTestProject true property not found and project is full framework, force vstest runner
            if (projectInfo.TestProjectAnalyzerResults.Any(testProject => testProject.GetTargetFrameworkAndVersion().Framework == Framework.DotNetClassic &&
                                                           options.TestRunner != TestRunner.VsTest &&
                                                           (!testProject.Properties.ContainsKey("IsTestProject") ||
                                                            (testProject.Properties.ContainsKey("IsTestProject") &&
                                                             !bool.Parse(testProject.Properties["IsTestProject"])))))
            {
                _logger.LogWarning($"Testrunner set from {options.TestRunner} to {TestRunner.VsTest} because IsTestProject property not set to true. This is only supported for vstest.");
                options.TestRunner = TestRunner.VsTest;
            }
        }
Exemple #9
0
 public ClearTextReporter(IStrykerOptions strykerOptions, TextWriter consoleWriter = null)
 {
     _options       = strykerOptions;
     _consoleWriter = consoleWriter ?? Console.Out;
 }
 public IEnumerable <Mutant> FilterMutants(IEnumerable <Mutant> mutants, ReadOnlyFileLeaf file, IStrykerOptions options)
 {
     return(mutants.Where(m => !Exclude(m.Mutation.OriginalNode)));
 }
Exemple #11
0
        public IEnumerable <Mutant> FilterMutants(IEnumerable <Mutant> mutants, ReadOnlyFileLeaf file, IStrykerOptions options)
        {
            if (!options.IgnoredMethods.Any())
            {
                return(mutants);
            }

            return(mutants.Where(m => !IsPartOfIgnoredMethodCall(m.Mutation.OriginalNode, options)));
        }
Exemple #12
0
        private FolderComposite FindProjectFilesUsingBuildalyzer(IAnalyzerResult analyzerResult, IStrykerOptions options)
        {
            var inputFiles            = new FolderComposite();
            var projectUnderTestDir   = Path.GetDirectoryName(analyzerResult.ProjectFilePath);
            var projectRoot           = Path.GetDirectoryName(projectUnderTestDir);
            var generatedAssemblyInfo = analyzerResult.AssemblyAttributeFileName();
            var rootFolderComposite   = new FolderComposite()
            {
                Name         = string.Empty,
                FullPath     = projectRoot,
                RelativePath = string.Empty,
                RelativePathToProjectFile = Path.GetRelativePath(projectUnderTestDir, projectUnderTestDir)
            };
            var cache = new Dictionary <string, FolderComposite> {
                [string.Empty] = rootFolderComposite
            };

            // Save cache in a singleton so we can use it in other parts of the project
            FolderCompositeCache <FolderComposite> .Instance.Cache = cache;

            inputFiles.Add(rootFolderComposite);

            CSharpParseOptions cSharpParseOptions = BuildCsharpParseOptions(analyzerResult, options);

            InjectMutantHelpers(rootFolderComposite, cSharpParseOptions);

            foreach (var sourceFile in analyzerResult.SourceFiles)
            {
                // Skip xamarin UI generated files
                if (sourceFile.EndsWith(".xaml.cs"))
                {
                    continue;
                }

                var relativePath    = Path.GetRelativePath(projectUnderTestDir, sourceFile);
                var folderComposite = GetOrBuildFolderComposite(cache, Path.GetDirectoryName(relativePath), projectUnderTestDir, projectRoot, inputFiles);
                var fileName        = Path.GetFileName(sourceFile);

                var file = new FileLeaf()
                {
                    SourceCode   = _fileSystem.File.ReadAllText(sourceFile),
                    Name         = _fileSystem.Path.GetFileName(sourceFile),
                    RelativePath = _fileSystem.Path.Combine(folderComposite.RelativePath, fileName),
                    FullPath     = sourceFile,
                    RelativePathToProjectFile = Path.GetRelativePath(projectUnderTestDir, sourceFile)
                };

                // Get the syntax tree for the source file
                var syntaxTree = CSharpSyntaxTree.ParseText(file.SourceCode,
                                                            path: file.FullPath,
                                                            encoding: Encoding.UTF32,
                                                            options: cSharpParseOptions);

                // don't mutate auto generated code
                if (syntaxTree.IsGenerated())
                {
                    // we found the generated assemblyinfo file
                    if (_fileSystem.Path.GetFileName(sourceFile).ToLowerInvariant() == generatedAssemblyInfo)
                    {
                        // add the mutated text
                        syntaxTree = InjectMutationLabel(syntaxTree);
                    }
                    _logger.LogDebug("Skipping auto-generated code file: {fileName}", file.Name);
                    folderComposite.AddCompilationSyntaxTree(syntaxTree); // Add the syntaxTree to the list of compilationSyntaxTrees
                    continue;                                             // Don't add the file to the folderComposite as we're not reporting on the file
                }

                file.SyntaxTree = syntaxTree;
                folderComposite.Add(file);
            }

            return(inputFiles);
        }
Exemple #13
0
        public IEnumerable <Mutant> FilterMutants(IEnumerable <Mutant> mutants, ReadOnlyFileLeaf file, IStrykerOptions options)
        {
            return(mutants.Where(IsMutantIncluded));

            bool IsMutantIncluded(Mutant mutant)
            {
                // Check if the the mutant is included.
                if (!_includePattern.Any(MatchesPattern))
                {
                    return(false);
                }

                // Check if the mutant is excluded.
                if (_excludePattern.Any(MatchesPattern))
                {
                    return(false);
                }

                return(true);

                bool MatchesPattern(FilePattern pattern)
                {
                    // We check both the full and the relative path to allow for relative paths.
                    return(pattern.IsMatch(file.FullPath, mutant.Mutation.OriginalNode.Span) ||
                           pattern.IsMatch(file.RelativePath, mutant.Mutation.OriginalNode.Span));
                }
            }
        }
Exemple #14
0
 public HtmlReporter(IStrykerOptions options, IFileSystem fileSystem = null, TextWriter consoleWriter = null)
 {
     _options       = options;
     _fileSystem    = fileSystem ?? new FileSystem();
     _consoleWriter = consoleWriter ?? Console.Out;
 }
 public DiskBaselineProvider(IStrykerOptions options, IFileSystem fileSystem = null)
 {
     _options    = options;
     _fileSystem = fileSystem ?? new FileSystem();
     _logger     = ApplicationLogging.LoggerFactory.CreateLogger <DiskBaselineProvider>();
 }
 public GitBaselineReporter(IStrykerOptions options, IBaselineProvider baselineProvider = null, IGitInfoProvider gitInfoProvider = null)
 {
     _options          = options;
     _baselineProvider = baselineProvider ?? BaselineProviderFactory.Create(options);
     _gitInfoProvider  = gitInfoProvider ?? new GitInfoProvider(options);
 }
Exemple #17
0
 private bool IsPartOfIgnoredMethodCall(SyntaxNode syntaxNode, IStrykerOptions options) =>
 syntaxNode switch
 {
        public IEnumerable <Mutant> FilterMutants(IEnumerable <Mutant> mutants, ReadOnlyFileLeaf file, IStrykerOptions options)
        {
            // Mutants can be enabled for testing based on multiple reasons. We store all the filtered mutants in this list and return this list.
            IEnumerable <Mutant> filteredMutants;

            // If the dashboard feature is turned on we first filter based on previous results
            if (options.CompareToDashboard)
            {
                // If the dashboard feature is enabled but we cannot find a baseline. We are going to test the entire project. Thus none of the mutants can be filtered out and all are returned.
                if (_baseline == null)
                {
                    _logger.LogDebug("Testing all mutants on {0} because there is no baseline available", file.RelativePath);
                    return(mutants);
                }

                // Updates all the mutants in this file with their counterpart's result in the report of the previous run
                UpdateMutantsWithBaselineStatus(mutants, file);
            }

            // A non-csharp file is flagged by the diff result as modified. We cannot determine which mutants will be affected by this, thus all mutants have to be tested.
            if (_diffResult.ChangedTestFiles is { } && _diffResult.ChangedTestFiles.Any(x => !x.EndsWith(".cs")))
Exemple #19
0
        public IEnumerable <Mutant> FilterMutants(IEnumerable <Mutant> mutants, ReadOnlyFileLeaf file, IStrykerOptions options)
        {
            if (options.CompareToDashboard)
            {
                if (_baseline == null)
                {
                    _logger.LogDebug("Returning all mutants on {0} because there is no baseline available", file.RelativePath);
                }
                else
                {
                    UpdateMutantsWithBaselineStatus(mutants, file);
                }
            }

            return(mutants);
        }
Exemple #20
0
 public DashboardBaselineProvider(IStrykerOptions options, IDashboardClient client = null)
 {
     _client = client ?? new DashboardClient(options);
 }
Exemple #21
0
        public IEnumerable <Mutant> FilterMutants(IEnumerable <Mutant> mutants, ReadOnlyFileLeaf file, IStrykerOptions options)
        {
            // Mutants can be enabled for testing based on multiple reasons. We store all the filtered mutants in this list and return this list.
            IEnumerable <Mutant> filteredMutants;

            // A non-csharp file is flagged by the diff result as modified. We cannot determine which mutants will be affected by this, thus all mutants have to be tested.
            if (_diffResult.ChangedTestFiles is { } && _diffResult.ChangedTestFiles.Any(x => !x.EndsWith(".cs")))
        /// <summary>
        /// Finds the referencedProjects and looks for all files that should be mutated in those projects
        /// </summary>
        public ProjectInfo ResolveInput(IStrykerOptions options)
        {
            var projectInfo = new ProjectInfo();
            // Determine test projects
            var    testProjectFiles = new List <string>();
            string projectUnderTest = null;

            if (options.TestProjects != null && options.TestProjects.Any())
            {
                testProjectFiles = options.TestProjects.Select(FindTestProject).ToList();
            }
            else
            {
                testProjectFiles.Add(FindTestProject(options.BasePath));
            }

            var testProjectAnalyzerResults = new List <IAnalyzerResult>();

            foreach (var testProjectFile in testProjectFiles)
            {
                // Analyze the test project
                testProjectAnalyzerResults.Add(_projectFileReader.AnalyzeProject(testProjectFile, options.SolutionPath));
            }
            projectInfo.TestProjectAnalyzerResults = testProjectAnalyzerResults;

            // Determine project under test
            if (options.TestProjects != null && options.TestProjects.Any())
            {
                projectUnderTest = FindProjectFile(options.BasePath);
            }
            else
            {
                projectUnderTest = FindProjectUnderTest(projectInfo.TestProjectAnalyzerResults, options.ProjectUnderTestNameFilter);
            }

            _logger.LogInformation("The project {0} will be mutated.", projectUnderTest);

            // Analyze project under test
            projectInfo.ProjectUnderTestAnalyzerResult = _projectFileReader.AnalyzeProject(projectUnderTest, options.SolutionPath);

            // if we are in devmode, dump all properties as it can help diagnosing build issues for user project.
            if (projectInfo.ProjectUnderTestAnalyzerResult.Properties != null && options.DevMode)
            {
                _logger.LogInformation("**** Buildalyzer properties. ****");
                // dump properties
                foreach (var keyValuePair in projectInfo.ProjectUnderTestAnalyzerResult.Properties)
                {
                    _logger.LogInformation("{0}={1}", keyValuePair.Key, keyValuePair.Value);
                }

                _logger.LogInformation("**** Buildalyzer properties. ****");
            }

            IProjectComponent inputFiles = new CsharpProjectComponentsBuilder(projectInfo, options, _foldersToExclude, _logger, _fileSystem).Build();

            projectInfo.ProjectContents = inputFiles;

            ValidateTestProjectsCanBeExecuted(projectInfo, options);
            _logger.LogInformation("Analysis complete.");

            return(projectInfo);
        }
 protected MutantOrchestrator(IStrykerOptions input) : base(input)
 {
 }
Exemple #24
0
        private FolderComposite FindProjectFilesScanningProjectFolders(IAnalyzerResult analyzerResult, IStrykerOptions options)
        {
            var inputFiles          = new FolderComposite();
            var projectUnderTestDir = Path.GetDirectoryName(analyzerResult.ProjectFilePath);

            foreach (var dir in ExtractProjectFolders(analyzerResult))
            {
                var folder = _fileSystem.Path.Combine(Path.GetDirectoryName(projectUnderTestDir), dir);

                _logger.LogDebug($"Scanning {folder}");
                if (!_fileSystem.Directory.Exists(folder))
                {
                    throw new DirectoryNotFoundException($"Can't find {folder}");
                }

                inputFiles.Add(FindInputFiles(folder, projectUnderTestDir, analyzerResult, options));
            }

            return(inputFiles);
        }
Exemple #25
0
 public StrykerRunResult(IStrykerOptions options, double mutationScore)
 {
     _options      = options;
     MutationScore = mutationScore;
 }
Exemple #26
0
 public FilePatternMutantFilter(IStrykerOptions options)
 {
     _includePattern = options.FilePatterns.Where(x => !x.IsExclude).ToList();
     _excludePattern = options.FilePatterns.Where(x => x.IsExclude).ToList();
 }
Exemple #27
0
 public AzureFileShareBaselineProvider(IStrykerOptions options, HttpClient httpClient = null)
 {
     _options    = options;
     _httpClient = httpClient ?? new HttpClient();
     _logger     = ApplicationLogging.LoggerFactory.CreateLogger <AzureFileShareBaselineProvider>();
 }
Exemple #28
0
        /// <summary>
        /// Recursively scans the given directory for files to mutate
        /// </summary>
        private FolderComposite FindInputFiles(string path, string projectUnderTestDir, IAnalyzerResult analyzerResult, IStrykerOptions options)
        {
            var rootFolderComposite = new FolderComposite
            {
                Name         = Path.GetFileName(path),
                FullPath     = Path.GetFullPath(path),
                RelativePath = Path.GetFileName(path),
                RelativePathToProjectFile = Path.GetRelativePath(projectUnderTestDir, Path.GetFullPath(path))
            };

            CSharpParseOptions cSharpParseOptions = BuildCsharpParseOptions(analyzerResult, options);

            InjectMutantHelpers(rootFolderComposite, cSharpParseOptions);

            rootFolderComposite.Add(
                FindInputFiles(path, Path.GetDirectoryName(analyzerResult.ProjectFilePath), rootFolderComposite.RelativePath, cSharpParseOptions)
                );
            return(rootFolderComposite);
        }
Exemple #29
0
 public DashboardClient(IStrykerOptions options, HttpClient httpClient = null, ILogger <DashboardClient> logger = null)
 {
     _options    = options;
     _logger     = logger ?? ApplicationLogging.LoggerFactory.CreateLogger <DashboardClient>();
     _httpClient = httpClient ?? new HttpClient();
 }
Exemple #30
0
 private static CSharpParseOptions BuildCsharpParseOptions(IAnalyzerResult analyzerResult, IStrykerOptions options)
 {
     return(new CSharpParseOptions(options.LanguageVersion, DocumentationMode.None, preprocessorSymbols: analyzerResult.GetDefineConstants()));
 }