public void CompilingProcessTests_SignedAssembliesMustBeSigned()
        {
            var syntaxTree = CSharpSyntaxTree.ParseText(@"

namespace ExampleProject
{
    public class Calculator
    {
        public int Subtract(int first, int second)
        {
            return first - second;
        }
    }
}");
            var input      = new MutationTestInput()
            {
                ProjectInfo = new ProjectInfo()
                {
                    ProjectUnderTestAnalyzerResult = new ProjectAnalyzerResult(null, null)
                    {
                        Properties = new Dictionary <string, string>()
                        {
                            { "AssemblyTitle", "AssemblyName" },
                        },
                        Resources    = new List <ResourceDescription>(),
                        SignAssembly = true,
                        AssemblyOriginatorKeyFile = Path.GetFullPath(Path.Combine("TestResources", "StrongNameKeyFile.snk"))
                    },
                    TestProjectAnalyzerResult = new ProjectAnalyzerResult(null, null)
                    {
                        Properties = new Dictionary <string, string>()
                        {
                            { "AssemblyTitle", "AssemblyName" },
                        },
                        Resources = new List <ResourceDescription>()
                    }
                },
                AssemblyReferences = new List <PortableExecutableReference>()
                {
                    MetadataReference.CreateFromFile(typeof(object).Assembly.Location)
                },
            };
            var rollbackProcessMock = new Mock <IRollbackProcess>(MockBehavior.Strict);

            var target = new CompilingProcess(input, rollbackProcessMock.Object);

            using (var ms = new MemoryStream())
            {
                var result = target.Compile(new Collection <SyntaxTree>()
                {
                    syntaxTree
                }, ms, false);
                result.Success.ShouldBe(true);

                var key = Assembly.Load(ms.ToArray()).GetName().GetPublicKey();
                key.Length.ShouldBe(160, "Assembly was not signed");
                ms.Length.ShouldBeGreaterThan(100, "No value was written to the MemoryStream by the compiler");
            }
        }
Example #2
0
        public void CompilingProcessTests_MustIncludeVersionInfo()
        {
            var syntaxTree = CSharpSyntaxTree.ParseText(@"using System;

namespace ExampleProject
{
    public class Calculator
    {
        public int Subtract(int first, int second)
        {
            return first - second;
        }
    }
}");
            var input      = new MutationTestInput()
            {
                ProjectInfo = new ProjectInfo()
                {
                    ProjectUnderTestAnalyzerResult = new ProjectAnalyzerResult(null, null)
                    {
                        Properties = new Dictionary <string, string>()
                        {
                            { "AssemblyTitle", "TargetFileName" },
                            { "TargetFileName", "TargetFileName.dll" },
                        },
                        Resources = new List <ResourceDescription>()
                    },
                    TestProjectAnalyzerResults = new List <ProjectAnalyzerResult> {
                        new ProjectAnalyzerResult(null, null)
                        {
                            Properties = new Dictionary <string, string>()
                            {
                                { "AssemblyTitle", "TargetFileName" },
                            },
                            Resources = new List <ResourceDescription>()
                        }
                    }
                },
                AssemblyReferences = new List <PortableExecutableReference>()
                {
                    MetadataReference.CreateFromFile(typeof(object).Assembly.Location)
                }
            };
            var rollbackProcessMock = new Mock <IRollbackProcess>(MockBehavior.Strict);

            var target = new CompilingProcess(input, rollbackProcessMock.Object);

            using (var ms = new MemoryStream())
            {
                var result = target.Compile(new Collection <SyntaxTree>()
                {
                    syntaxTree
                }, ms, null, false);
                result.Success.ShouldBe(true);

                Assembly.Load(ms.ToArray()).GetName().Version.ToString().ShouldBe("0.0.0.0");
            }
        }
Example #3
0
        public void CompilingProcessTests_ProperlyFailsWhenSigningKeyIsNotFound()
        {
            var syntaxTree = CSharpSyntaxTree.ParseText(@"

namespace ExampleProject
{
    public class Calculator
    {
        public int Subtract(int first, int second)
        {
            return first - second;
        }
    }
}");
            var input      = new MutationTestInput()
            {
                ProjectInfo = new ProjectInfo()
                {
                    ProjectUnderTestAnalyzerResult = new ProjectAnalyzerResult(null, null)
                    {
                        ProjectFilePath = "project.csproj",
                        Properties      = new Dictionary <string, string>()
                        {
                            { "AssemblyTitle", "TargetFileName" },
                            { "TargetFileName", "TargetFileName.dll" },
                            { "SignAssembly", "true" },
                            { "AssemblyOriginatorKeyFile", Path.GetFullPath(Path.Combine("TestResources", "DoesNotExists.snk")) }
                        },
                        Resources = new List <ResourceDescription>(),
                    },
                    TestProjectAnalyzerResults = new List <ProjectAnalyzerResult> {
                        new ProjectAnalyzerResult(null, null)
                        {
                            Properties = new Dictionary <string, string>()
                            {
                                { "AssemblyTitle", "TargetFileName" },
                            },
                            Resources = new List <ResourceDescription>()
                        }
                    }
                },
                AssemblyReferences = new List <PortableExecutableReference>()
                {
                    MetadataReference.CreateFromFile(typeof(object).Assembly.Location)
                },
            };
            var rollbackProcessMock = new Mock <IRollbackProcess>(MockBehavior.Strict);

            var target = new CompilingProcess(input, rollbackProcessMock.Object);

            using (var ms = new MemoryStream())
            {
                Should.Throw <StrykerCompilationException>(() => target.Compile(new Collection <SyntaxTree>()
                {
                    syntaxTree
                }, ms, null, false));
            }
        }
Example #4
0
        public void CompilingProcessTests_ShouldCallRollbackProcess_OnCompileError()
        {
            var syntaxTree = CSharpSyntaxTree.ParseText(@"using System;

namespace ExampleProject
{
    public class Calculator
    {
        public int Subtract(string first, string second)
        {
            return first - second;
        }
    }
}");
            var input      = new MutationTestInput()
            {
                ProjectInfo = new ProjectInfo()
                {
                    ProjectUnderTestAnalyzerResult = TestHelper.SetupProjectAnalyzerResult(properties: new Dictionary <string, string>()
                    {
                        { "TargetDir", "" },
                        { "AssemblyName", "AssemblyName" },
                        { "TargetFileName", "TargetFileName.dll" },
                    }).Object,
                    TestProjectAnalyzerResults = new List <IAnalyzerResult> {
                        TestHelper.SetupProjectAnalyzerResult(properties: new Dictionary <string, string>()
                        {
                            { "AssemblyName", "TargetFileName" },
                        }).Object
                    }
                },
                AssemblyReferences = new List <PortableExecutableReference>()
                {
                    MetadataReference.CreateFromFile(typeof(object).Assembly.Location)
                }
            };
            var rollbackProcessMock = new Mock <IRollbackProcess>(MockBehavior.Strict);

            rollbackProcessMock.Setup(x => x.Start(It.IsAny <CSharpCompilation>(), It.IsAny <ImmutableArray <Diagnostic> >(), It.IsAny <bool>(), false))
            .Returns((CSharpCompilation compilation, ImmutableArray <Diagnostic> diagnostics, bool devMode, bool _) =>
                     new RollbackProcessResult()
            {
                Compilation = compilation
            });

            var target = new CompilingProcess(input, rollbackProcessMock.Object);

            using (var ms = new MemoryStream())
            {
                Should.Throw <StrykerCompilationException>(() => target.Compile(new Collection <SyntaxTree>()
                {
                    syntaxTree
                }, ms, null, false));
            }
            rollbackProcessMock.Verify(x => x.Start(It.IsAny <CSharpCompilation>(), It.IsAny <ImmutableArray <Diagnostic> >(), false, false),
                                       Times.AtLeast(2));
        }
Example #5
0
        public void CompilingProcessTests_ShouldOnlyRollbackErrors()
        {
            var syntaxTree = CSharpSyntaxTree.ParseText(@"using System;

namespace ExampleProject
{
    public class Calculator
    {
        public int Subtract(int first, int second)
        {
            return first - second;
        }
    }
}");
            var input      = new MutationTestInput()
            {
                ProjectInfo = new ProjectInfo()
                {
                    ProjectUnderTestAnalyzerResult = new ProjectAnalyzerResult(null, null)
                    {
                        Properties = new Dictionary <string, string>()
                        {
                            { "AssemblyTitle", "TargetFileName" },
                            { "TargetFileName", "TargetFileName.dll" },
                        },
                        Resources = new List <ResourceDescription>()
                    },
                    TestProjectAnalyzerResults = new List <ProjectAnalyzerResult> {
                        new ProjectAnalyzerResult(null, null)
                        {
                            Properties = new Dictionary <string, string>()
                            {
                                { "AssemblyTitle", "TargetFileName" },
                            },
                            Resources = new List <ResourceDescription>()
                        }
                    }
                },
                AssemblyReferences = new List <PortableExecutableReference>()
                {
                    MetadataReference.CreateFromFile(typeof(object).Assembly.Location)
                }
            };
            var rollbackProcessMock = new Mock <IRollbackProcess>(MockBehavior.Strict);

            var target = new CompilingProcess(input, rollbackProcessMock.Object);

            using (var ms = new MemoryStream())
            {
                target.Compile(new Collection <SyntaxTree>()
                {
                    syntaxTree
                }, ms, null, false);

                ms.Length.ShouldBeGreaterThan(100, "No value was written to the MemoryStream by the compiler");
            }
        }
        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);
        }
        public void CompilingProcessTests_ShouldCallRollbackProcess_OnCompileError()
        {
            var syntaxTree = CSharpSyntaxTree.ParseText(@"using System;

namespace ExampleProject
{
    public class Calculator
    {
        public int Subtract(string first, string second)
        {
            return first - second;
        }
    }
}");
            var input      = new MutationTestInput()
            {
                ProjectInfo = new ProjectInfo()
                {
                    ProjectUnderTestAssemblyName = "The assembly name"
                },
                AssemblyReferences = new List <PortableExecutableReference>()
                {
                    MetadataReference.CreateFromFile(typeof(object).Assembly.Location)
                }
            };
            var rollbackProcessMock = new Mock <IRollbackProcess>(MockBehavior.Strict);

            rollbackProcessMock.Setup(x => x.Start(It.IsAny <CSharpCompilation>(), It.IsAny <ImmutableArray <Diagnostic> >(), It.IsAny <bool>()))
            .Returns((CSharpCompilation compilation, ImmutableArray <Diagnostic> diagnostics, bool devMode) =>
                     new RollbackProcessResult()
            {
                Compilation = compilation
            });

            var target = new CompilingProcess(input, rollbackProcessMock.Object);

            using (var ms = new MemoryStream())
            {
                Should.Throw <ApplicationException>(() => target.Compile(new Collection <SyntaxTree>()
                {
                    syntaxTree
                }, ms, false));
            }
            rollbackProcessMock.Verify(x => x.Start(It.IsAny <CSharpCompilation>(), It.IsAny <ImmutableArray <Diagnostic> >(), It.IsAny <bool>()),
                                       Times.Exactly(2));
        }
Example #8
0
        public void CompilingProcessTests_ShouldCompile()
        {
            var syntaxTree = CSharpSyntaxTree.ParseText(@"using System;

namespace ExampleProject
{
    public class Calculator
    {
        public int Subtract(int first, int second)
        {
            return first - second;
        }
    }
}");
            var input      = new MutationTestInput()
            {
                ProjectInfo = new Core.Initialisation.ProjectInfo()
                {
                    ProjectUnderTestAssemblyName = "The assembly name"
                },
                AssemblyReferences = new List <PortableExecutableReference>()
                {
                    MetadataReference.CreateFromFile(typeof(object).Assembly.Location)
                }
            };
            var rollbackProcessMock = new Mock <IRollbackProcess>(MockBehavior.Strict);

            var target = new CompilingProcess(input, rollbackProcessMock.Object);

            using (var ms = new MemoryStream())
            {
                target.Compile(new Collection <SyntaxTree>()
                {
                    syntaxTree
                }, ms, false);

                ms.Length.ShouldBeGreaterThan(100, "No value was written to the MemoryStream by the compiler");
            }
        }
        public void Mutate(StrykerOptions options)
        {
            var mutatedSyntaxTrees = new List <SyntaxTree>();

            // add helper
            Logger.LogDebug("Injecting helpers into assembly.");
            mutatedSyntaxTrees.AddRange(CodeInjection.MutantHelpers);

            foreach (var file in Input.ProjectInfo.ProjectContents.GetAllFiles())
            {
                // Get the syntax tree for the source file
                var syntaxTree = CSharpSyntaxTree.ParseText(file.SourceCode,
                                                            path: file.FullPath,
                                                            options: new CSharpParseOptions(LanguageVersion.Latest));

                if (!file.IsExcluded)
                {
                    // Mutate the syntax tree
                    var mutatedSyntaxTree = Orchestrator.Mutate(syntaxTree.GetRoot());
                    // Add the mutated syntax tree for compilation
                    mutatedSyntaxTrees.Add(mutatedSyntaxTree.SyntaxTree);
                    // Store the generated mutants in the file
                    file.Mutants = Orchestrator.GetLatestMutantBatch();
                }
                else
                {
                    // Add the original syntax tree for future compilation
                    mutatedSyntaxTrees.Add(syntaxTree);
                    // There aren't any mutants generated so a new list of mutants is sufficient
                    file.Mutants = new List <Mutant>();

                    Logger.LogDebug("Excluded file {0}, no mutants created", file.FullPath);
                }
            }

            Logger.LogDebug("{0} mutants created", Input.ProjectInfo.ProjectContents.Mutants.Count());

            using (var ms = new MemoryStream())
            {
                // compile the mutated syntax trees
                var compileResult = CompilingProcess.Compile(mutatedSyntaxTrees, ms, options.DevMode);

                var injectionPath = Input.ProjectInfo.GetInjectionPath();
                if (!FileSystem.Directory.Exists(Path.GetDirectoryName(injectionPath)) && !FileSystem.File.Exists(injectionPath))
                {
                    FileSystem.Directory.CreateDirectory(Path.GetDirectoryName(injectionPath));
                }

                // inject the mutated Assembly into the test project
                using (var fs = FileSystem.File.Create(injectionPath))
                {
                    ms.Position = 0;
                    ms.CopyTo(fs);
                }
                Logger.LogDebug("Injected the mutated assembly file into {0}", injectionPath);

                // if a rollback took place, mark the rollbacked mutants as status:BuildError
                if (compileResult.RollbackResult?.RollbackedIds.Any() ?? false)
                {
                    foreach (var mutant in Input.ProjectInfo.ProjectContents.Mutants
                             .Where(x => compileResult.RollbackResult.RollbackedIds.Contains(x.Id)))
                    {
                        mutant.ResultStatus = MutantStatus.CompileError;
                    }
                }
                var numberOfBuildErrors = compileResult.RollbackResult?.RollbackedIds.Count() ?? 0;
                if (numberOfBuildErrors > 0)
                {
                    Logger.LogInformation("{0} mutants could not compile and got status {1}", numberOfBuildErrors, MutantStatus.CompileError.ToString());
                }

                if (options.ExcludedMutations.Count() != 0)
                {
                    var mutantsToSkip = Input.ProjectInfo.ProjectContents.Mutants
                                        .Where(x => options.ExcludedMutations.Contains(x.Mutation.Type)).ToList();
                    foreach (var mutant in mutantsToSkip)
                    {
                        mutant.ResultStatus = MutantStatus.Skipped;
                    }
                    Logger.LogInformation("{0} mutants got status {1}", mutantsToSkip.Count(), MutantStatus.Skipped.ToString());
                }
            }

            Logger.LogInformation("{0} mutants ready for test", Input.ProjectInfo.ProjectContents.TotalMutants.Count());

            Reporter.OnMutantsCreated(Input.ProjectInfo.ProjectContents);
        }
Example #10
0
        public void ShouldRollbackIssueInExpression()
        {
            var syntaxTree = CSharpSyntaxTree.ParseText(@"
    using System;
    using System.Collections.Generic;
    using System.Linq;

    namespace ExampleProject
    {
       public class Test
       {
           public void SomeLinq()
           {
               var list = new List<List<double>>();
               int[] listProjected = list.Select(l => l.Count()).ToArray();
           }
       }
    }");
            var mutator    = new CsharpMutantOrchestrator(options: new StrykerOptions(mutationLevel: MutationLevel.Complete.ToString(), devMode: true));
            var helpers    = new List <SyntaxTree>();

            foreach (var(name, code) in CodeInjection.MutantHelpers)
            {
                helpers.Add(CSharpSyntaxTree.ParseText(code, path: name, encoding: Encoding.UTF32));
            }

            var mutant = mutator.Mutate(syntaxTree.GetRoot());

            helpers.Add(mutant.SyntaxTree);
            var references = new List <PortableExecutableReference>()
            {
                MetadataReference.CreateFromFile(typeof(object).Assembly.Location),
                MetadataReference.CreateFromFile(typeof(List <string>).Assembly.Location),
                MetadataReference.CreateFromFile(typeof(Enumerable).Assembly.Location),
                MetadataReference.CreateFromFile(typeof(PipeStream).Assembly.Location),
            };

            Assembly.GetEntryAssembly().GetReferencedAssemblies().ToList().ForEach(a => references.Add(MetadataReference.CreateFromFile(Assembly.Load(a).Location)));

            var input = new MutationTestInput()
            {
                ProjectInfo = new ProjectInfo()
                {
                    ProjectUnderTestAnalyzerResult = TestHelper.SetupProjectAnalyzerResult(properties: new Dictionary <string, string>()
                    {
                        { "TargetDir", "" },
                        { "AssemblyName", "AssemblyName" },
                        { "TargetFileName", "TargetFileName.dll" },
                        { "SignAssembly", "true" },
                        { "AssemblyOriginatorKeyFile", Path.GetFullPath(Path.Combine("TestResources", "StrongNameKeyFile.snk")) }
                    },
                                                                                           projectFilePath: "TestResources").Object,
                    TestProjectAnalyzerResults = new List <IAnalyzerResult> {
                        TestHelper.SetupProjectAnalyzerResult(properties: new Dictionary <string, string>()
                        {
                            { "AssemblyName", "AssemblyName" },
                        }).Object
                    }
                },
                AssemblyReferences = references
            };

            var rollbackProcess = new RollbackProcess();

            var target = new CompilingProcess(input, rollbackProcess);

            using (var ms = new MemoryStream())
            {
                var result = target.Compile(helpers, ms, null, true);
                result.RollbackResult.RollbackedIds.Count().ShouldBe(1);
            }
        }