/// <summary> /// Returns all possible mutations from the method its instructions. /// </summary> /// <returns></returns> public IEnumerable <OpCodeMutationGrouping> OpCodeMutations(MutationLevel mutationLevel) { foreach (var analyzer in _opcodeMethodAnalyzers) { if (MethodDefinition.Body?.Instructions != null) { foreach (var instruction in MethodDefinition.Body?.Instructions) { var mutations = analyzer.AnalyzeMutations(instruction, mutationLevel, MethodDefinition.DebugInformation.GetSequencePointMapping()).ToList(); if (mutations.Any()) { yield return new OpCodeMutationGrouping { Key = instruction.OpCode.ToString(), Mutations = mutations, AnalyzerName = analyzer.Name, AnalyzerDescription = analyzer.Description } } ; } } } }
/// <summary> /// Returns a list of <see cref="MutationVariant" /> that can be executed on this given test project duplication. /// </summary> /// <param name="mutationIdentifiers"></param> /// <param name="mutationLevel"></param> /// <returns></returns> public IList <MutationVariant> GetMutationVariants(IList <MutationVariantIdentifier> mutationIdentifiers, MutationLevel mutationLevel) { var foundMutations = new List <MutationVariant>(); foreach (var reference in TestProjectReferences) { // Read the reference its contents using var stream = reference.OpenReadStream(); using var binReader = new BinaryReader(stream); var data = binReader.ReadBytes((int)stream.Length); var decompiler = new CodeDecompiler(reference.FullFilePath(), new MemoryStream(data)); // Create assembly mutator and look up the mutations according to the passed identifiers. var assembly = new AssemblyMutator(new MemoryStream(data)); foreach (var type in assembly.Types) { var toMutateMethods = new HashSet <string>( mutationIdentifiers.Select(x => x.MemberName) ); foreach (var method in type.Methods) { if (!toMutateMethods.Contains(method.AssemblyQualifiedName)) { continue; } var methodMutationId = 0; foreach (var group in method.AllMutations(mutationLevel)) { foreach (var mutation in group) { var mutationIdentifier = mutationIdentifiers.FirstOrDefault(x => x.MutationId == methodMutationId && method.AssemblyQualifiedName == x.MemberName); if (mutationIdentifier.MemberName != null) { foundMutations.Add(new MutationVariant(false, assembly, mutationIdentifier, new MutationAnalyzerInfo { AnalyzerDescription = group.AnalyzerDescription, AnalyzerName = group.AnalyzerName }, method.Handle, mutation, "", decompiler.Decompile(method.Handle))); } methodMutationId++; } } } } } return(foundMutations); }
public MutationTestProject(string testProjectPath, MutationLevel mutationLevel, int parallel, ILoggerFactory loggerFactoryFactory, ITestHostRunFactory testHostRunFactory, TimeSpan timeOut) { _testProjectPath = testProjectPath; _mutationLevel = mutationLevel; _parallel = parallel; _testHostRunFactory = testHostRunFactory; _timeOut = timeOut; _testHostLogger = loggerFactoryFactory.CreateLogger("Faultify.TestHost"); }
public IEnumerable <ArrayMutationGrouping> ArrayMutations(MutationLevel mutationLevel) { return(_arrayMutationAnalyzers.Select(analyzer => new ArrayMutationGrouping { Mutations = analyzer.AnalyzeMutations(MethodDefinition, mutationLevel), Key = MethodDefinition.Name, AnalyzerName = analyzer.Name, AnalyzerDescription = analyzer.Description })); }
public IEnumerable <VariableMutationGrouping> VariableMutations(MutationLevel mutationLevel) { return(_variableMutationAnalyzers.Select(analyzer => new VariableMutationGrouping { Mutations = analyzer.AnalyzeMutations(MethodDefinition, mutationLevel, MethodDefinition.DebugInformation.GetSequencePointMapping()), Key = MethodDefinition.Name, AnalyzerName = analyzer.Name, AnalyzerDescription = analyzer.Description })); }
/// <summary> /// Analyzes the method body and searches for dynamic array. /// </summary> /// <param name="method"></param> /// <returns></returns> public IEnumerable <ArrayMutation> AnalyzeMutations(MethodDefinition method, MutationLevel mutationLevel, IDictionary <Instruction, SequencePoint> debug = null) { foreach (var instruction in method.Body.Instructions) { // Call the corresponding strategy based on the result if (instruction.IsDynamicArray() && SupportedTypeCheck(instruction)) { yield return(new ArrayMutation(new DynamicArrayRandomizerStrategy(method), method)); } } }
private StrykerOptions( string basePath, string outputPath, IEnumerable <Reporter> reporters, string projectUnderTestNameFilter, string projectUnderTest, int additionalTimeoutMS, IEnumerable <Mutator> excludedMutations, IEnumerable <Regex> ignoredMethods, LogOptions logOptions, OptimizationFlags optimizations, Threshold thresholds, bool devMode, string optimizationMode, int concurrentTestRunners, IEnumerable <FilePattern> filePatterns, TestRunner testRunner, string solutionPath, LanguageVersion languageVersion, string gitDiffSource, IEnumerable <string> testProjects, string azureSAS, string azureFileStorageUrl, BaselineProvider baselineProvider, MutationLevel mutationLevel) { IgnoredMethods = ignoredMethods; BasePath = basePath; OutputPath = outputPath; Reporters = reporters; ProjectUnderTestNameFilter = projectUnderTestNameFilter; ProjectUnderTest = projectUnderTest; AdditionalTimeoutMS = additionalTimeoutMS; ExcludedMutations = excludedMutations; LogOptions = logOptions; DevMode = devMode; ConcurrentTestrunners = concurrentTestRunners; Thresholds = thresholds; FilePatterns = filePatterns; TestRunner = testRunner; SolutionPath = solutionPath; LanguageVersion = languageVersion; OptimizationMode = optimizationMode; Optimizations = optimizations; GitDiffTarget = gitDiffSource; TestProjects = testProjects; AzureSAS = azureSAS; AzureFileStorageUrl = azureFileStorageUrl; BaselineProvider = baselineProvider; MutationLevel = mutationLevel; }
public IEnumerable <IMutationGrouping <IMutation> > AllMutations(MutationLevel mutationLevel) { if (MethodDefinition.Body == null) { return(Enumerable.Empty <IMutationGrouping <IMutation> >()); } MethodDefinition.Body.SimplifyMacros(); IEnumerable <IMutationGrouping <IMutation> > opcodeMutations = OpCodeMutations(mutationLevel); IEnumerable <IMutationGrouping <IMutation> > variableMutations = VariableMutations(mutationLevel); IEnumerable <IMutationGrouping <IMutation> > arrayMutations = ArrayMutations(mutationLevel); return(opcodeMutations.Concat(variableMutations).Concat(arrayMutations)); }
public override IEnumerable <ConstantMutation> AnalyzeMutations(FieldDefinition field, MutationLevel mutationLevel, IDictionary <Instruction, SequencePoint> debug = null) { if (field.Constant is bool original) { yield return new ConstantMutation { Original = original, ConstantName = field.Name, Replacement = !original, ConstantField = field } } ; } }
public IEnumerable <IMutationGrouping <IMutation> > AllMutations(MutationLevel mutationLevel) { foreach (var analyzer in _constantAnalyzers) { foreach (var field in TypeDefinition.Fields) { yield return new ConstMutationGrouping { Mutations = analyzer.AnalyzeMutations(field, mutationLevel), Key = field.Name, AnalyzerName = analyzer.Name, AnalyzerDescription = analyzer.Description } } } ; }
/// <summary> /// Returns possible constant field mutations. /// </summary> /// <returns></returns> public IEnumerable <ConstMutationGrouping> ConstantFieldMutations(MutationLevel mutationLevel) { foreach (var analyzer in _fieldAnalyzers) { var mutations = analyzer.AnalyzeMutations(_fieldDefinition, mutationLevel); if (mutations.Any()) { yield return new ConstMutationGrouping { Mutations = mutations, Key = analyzer.Name, AnalyzerName = analyzer.Name, AnalyzerDescription = analyzer.Description } } ; } } }
public IEnumerable <ConstMutationGrouping> ConstantReferenceMutations(MutationLevel mutationLevel) { var fieldReferences = MethodDefinition.Body.Instructions .OfType <FieldReference>(); foreach (var field in fieldReferences) { foreach (var analyzer in _constantReferenceMutationAnalyers) { var mutations = analyzer.AnalyzeMutations(field.Resolve(), mutationLevel); yield return(new ConstMutationGrouping { AnalyzerName = analyzer.Name, AnalyzerDescription = analyzer.Description, Key = field.Name, Mutations = mutations }); } } }
private IList <MutationVariantIdentifier> GetMutationsForCoverage( Dictionary <RegisteredCoverage, HashSet <string> > coverage, TestProjectInfo testProjectInfo, MutationLevel mutationLevel) { var allMutations = new List <MutationVariantIdentifier>(); foreach (var assembly in testProjectInfo.DependencyAssemblies) { foreach (var type in assembly.Types) { foreach (var method in type.Methods) { var methodMutationId = 0; var registeredMutation = coverage.FirstOrDefault(x => x.Key.AssemblyName == assembly.Module.Assembly.Name.Name && x.Key.EntityHandle == method.IntHandle); var mutationGroupId = 0; if (registeredMutation.Key != null) { foreach (var group in method.AllMutations(mutationLevel)) { foreach (var mutation in group) { allMutations.Add(new MutationVariantIdentifier(registeredMutation.Value, method.AssemblyQualifiedName, methodMutationId, mutationGroupId)); methodMutationId++; } mutationGroupId += 1; } } } } } return(allMutations); }
public IEnumerable <IMutationTestRun> GenerateMutationTestRuns( Dictionary <RegisteredCoverage, HashSet <string> > testsPerMethod, TestProjectInfo testProjectInfo, MutationLevel mutationLevel) { var mutationTestRuns = new List <IMutationTestRun>(); var allMutations = GetMutationsForCoverage(testsPerMethod, testProjectInfo, mutationLevel); var mutationGroups = GetTestGroups(allMutations).ToArray(); for (var i = 0; i < mutationGroups.Length; i++) { var mutationGroup = mutationGroups[i]; mutationTestRuns.Add(new DefaultMutationTestRun { MutationIdentifiers = mutationGroup, RunId = i, MutationLevel = mutationLevel }); } return(mutationTestRuns); }
private StrykerOptions( IFileSystem fileSystem, ILogger logger, string basePath, string outputPath, IEnumerable <Reporter> reporters, string projectUnderTestNameFilter, string projectUnderTest, int additionalTimeoutMS, IEnumerable <Mutator> excludedMutations, IEnumerable <Regex> ignoredMethods, LogOptions logOptions, OptimizationFlags optimizations, Threshold thresholds, bool devMode, string optimizationMode, int concurrentTestRunners, IEnumerable <FilePattern> filePatterns, TestRunner testRunner, string solutionPath, LanguageVersion languageVersion, bool diffEnabled, string gitDiffSource, IEnumerable <FilePattern> diffIgnoreFiles, IEnumerable <string> testProjects, string azureSAS, string azureFileStorageUrl, BaselineProvider baselineProvider, MutationLevel mutationLevel, bool compareToDashboard, string dashboardUrl, string dashboardApiKey, string projectName, string moduleName, string projectVersion, string fallbackVersion) { _fileSystem = fileSystem; _logger = logger; IgnoredMethods = ignoredMethods; BasePath = basePath; OutputPath = outputPath; Reporters = reporters; ProjectUnderTestNameFilter = projectUnderTestNameFilter; ProjectUnderTest = projectUnderTest; AdditionalTimeoutMS = additionalTimeoutMS; ExcludedMutations = excludedMutations; LogOptions = logOptions; DevMode = devMode; ConcurrentTestrunners = concurrentTestRunners; Thresholds = thresholds; FilePatterns = filePatterns; TestRunner = testRunner; SolutionPath = solutionPath; LanguageVersion = languageVersion; OptimizationMode = optimizationMode; Optimizations = optimizations; DiffEnabled = diffEnabled; GitDiffSource = gitDiffSource; DiffIgnoreFiles = diffIgnoreFiles; TestProjects = testProjects; AzureSAS = azureSAS; AzureFileStorageUrl = azureFileStorageUrl; BaselineProvider = baselineProvider; MutationLevel = mutationLevel; CompareToDashboard = compareToDashboard; DashboardUrl = dashboardUrl; DashboardApiKey = dashboardApiKey; ProjectName = projectName; ModuleName = moduleName; ProjectVersion = projectVersion; FallbackVersion = fallbackVersion; }
public abstract IEnumerable <ConstantMutation> AnalyzeMutations(FieldDefinition field, MutationLevel mutationLevel, IDictionary <Instruction, SequencePoint> debug = null);
public IEnumerable <VariableMutation> AnalyzeMutations(MethodDefinition method, MutationLevel mutationLevel, IDictionary <Instruction, SequencePoint> debug = null) { //TODO Check Quick fix if (method?.Body == null) { return(Enumerable.Empty <VariableMutation>()); } var lineNumber = -1; var mutations = new List <VariableMutation>(); foreach (var instruction in method.Body.Instructions) { // Booleans (0,1) or number literals are loaded on the evaluation stack with 'ldc_...' and popped of with 'stloc'. // Therefore if there is an 'ldc' instruction followed by 'stdloc' we can assert there is a literal of some type. // 'ldc' does not specify the variable type. // In order to know the type cast the 'Operand' to 'VariableDefinition'. if (instruction.OpCode != OpCodes.Stloc) { continue; } var variableDefinition = instruction.Operand as VariableDefinition; if (variableDefinition == null) { continue; } try { if (debug != null) { debug.TryGetValue(instruction, out var tempSeqPoint); if (tempSeqPoint != null) { lineNumber = tempSeqPoint.StartLine; } } // Get variable type. Might throw InvalidCastException var type = ((TypeReference)instruction.Operand).ToSystemType(); // Get previous instruction. var variableInstruction = instruction.Previous; // If the previous instruction is 'ldc' its loading a boolean or integer on the stack. if (!variableInstruction.IsLdc()) { continue; } // If the value is mapped then mutate it. if (TypeChecker.IsVariableType(type)) { mutations.Add( new VariableMutation { Original = variableInstruction.Operand, Replacement = _valueGenerator.GenerateValueForField(type, instruction.Previous.Operand), Variable = variableInstruction, LineNumber = lineNumber }); } } catch { // ignore (sometimes `Type.GetType` fails) } } return(mutations); }
public ExampleMutator(MutationLevel mutationLevel) { MutationLevel = mutationLevel; }
public IEnumerable <IMutationGrouping <IMutation> > AllMutations(MutationLevel mutationLevel) { return(ConstantFieldMutations(mutationLevel)); }