/// <summary> /// Performs the actual code mutations, returning each with /// <c>yield</c> for the calling code to use. /// </summary> /// <remarks> /// Implementing classes should yield the result obtained by calling /// the <see mref="DoYield" /> method. /// </remarks> /// <param name="method"> /// A <see cref="MethodDefinition" /> for the method on which mutation /// testing is to be carried out. /// </param> /// <param name="module"> /// A <see cref="Module" /> representing the main module of the /// containing assembly. /// </param> /// <param name="originalOffsets"></param> /// <returns> /// An <see cref="IEnumerable{T}" /> of /// <see cref="MutantMetaData" /> structures. /// </returns> protected override IEnumerable <MutantMetaData> CreateMutant(MethodDefinition method, Module module, int[] originalOffsets) { var sequence = new Dictionary <int, OpCode>(); var startIndex = -1; var instructionsMaxIndex = method.Body.Instructions.Count - 1; for (int index = 0; index < method.Body.Instructions.Count; index++) { var instruction = method.Body.Instructions[index]; if (IsSequenceStartingInstruction(instruction)) { startIndex = index; sequence.Clear(); } if (startIndex >= 0) { sequence.Add(index, instruction.OpCode); } if (!IsLastSequenceInstruction(index, instructionsMaxIndex, instruction) || !ShouldDeleteSequence(method.Body, sequence, instruction)) { continue; } var originalInstruction = ReplaceOpcodeAndOperand(method, startIndex, OpCodes.Br, instruction.Next); var codes = string.Join(", ", sequence.Values.Select(o => o.Code)); var description = string.Format("{0:x4}: deleting {1}", originalOffsets[startIndex], codes); MutantMetaData mutation = DoYield(method, module, description, Description, startIndex); yield return(mutation); ReplaceOpcodeAndOperand(method, startIndex, originalInstruction.opcode, originalInstruction.operand); } }
internal void AddResult(Mono.Cecil.Cil.SequencePoint sequencePoint, MutantMetaData mutantMetaData, bool mutantKilled) { if (sequencePoint == null || sequencePoint.Document == null) { return; } _mutantsCount++; _mutantsKilledCount += (mutantKilled ? 1 : 0); string sourceFileUrl = sequencePoint.Document.Url; _readerWriterLock.EnterUpgradeableReadLock(); try { if (SourceFiles.All(s => s.Url != sourceFileUrl)) { _readerWriterLock.EnterWriteLock(); var newSourceFile = new SourceFile(); newSourceFile.SetUrl(sourceFileUrl); SourceFiles.Add(newSourceFile); _readerWriterLock.ExitWriteLock(); } } finally { _readerWriterLock.ExitUpgradeableReadLock(); } var sourceFile = SourceFiles.First(s => s.Url == sourceFileUrl); sourceFile.AddResult(sequencePoint, mutantMetaData, mutantKilled); }
/// <summary> /// Performs the actual code mutations, returning each with /// <c>yield</c> for the calling code to use. /// </summary> /// <remarks> /// Implementing classes should yield the result obtained by calling /// the <see mref="DoYield" /> method. /// </remarks> /// <param name="method"> /// A <see cref="MethodDefinition" /> for the method on which mutation /// testing is to be carried out. /// </param> /// <param name="module"> /// A <see cref="Module" /> representing the main module of the /// containing assembly. /// </param> /// <param name="originalOffsets"></param> /// <returns> /// An <see cref="IEnumerable{T}" /> of /// <see cref="MutantMetaData" /> structures. /// </returns> protected override IEnumerable <MutantMetaData> CreateMutant(MethodDefinition method, Module module, int[] originalOffsets) { for (int index = 0; index < method.Body.Instructions.Count; index++) { var instruction = method.Body.Instructions[index]; if (_opCodes.ContainsKey(instruction.OpCode)) { if (instruction.IsMeaninglessUnconditionalBranch()) { continue; } var originalOpCode = instruction.OpCode; foreach (var opCode in _opCodes[originalOpCode]) { instruction.OpCode = opCode; var description = string.Format("{0:x4}: {1} => {2}", originalOffsets[index], originalOpCode.Code, opCode.Code); MutantMetaData mutation = DoYield(method, module, description, Description, index); yield return(mutation); } instruction.OpCode = originalOpCode; } } }
private int MatchReplacement(MutantMetaData metaData, OpCode from, OpCode to) { int result = 0; if (metaData.MethodDefinition.Body.Instructions.Any(i => i.OpCode == to)) { result = 1; StringAssert.Contains(string.Format("{0} => {1}", from.Code, to.Code), metaData.Description); } return(result); }
internal void AddResult(Mono.Cecil.Cil.SequencePoint sequencePoint, MutantMetaData mutantMetaData, bool mutantKilled) { string identifier = SequencePoint.GetIdentifier(sequencePoint); _readerWriterLock.EnterUpgradeableReadLock(); try { if (SequencePoints.All(s => s.GetIdentifier() != identifier)) { _readerWriterLock.EnterWriteLock(); SequencePoints.Add(new SequencePoint(sequencePoint)); _readerWriterLock.ExitWriteLock(); } } finally { _readerWriterLock.ExitUpgradeableReadLock(); } var sourceSequencePoint = SequencePoints.First(s => s.GetIdentifier() == identifier); sourceSequencePoint.AddResult(mutantMetaData, mutantKilled); }
internal void AddResult(MutantMetaData mutantMetaData, bool mutantKilled) { _readerWriterLock.EnterUpgradeableReadLock(); try { if (AppliedMutants.All(s => s.Description != mutantMetaData.Description)) { _readerWriterLock.EnterWriteLock(); AppliedMutants.Add(new AppliedMutant { GenericDescription = mutantMetaData.GenericDescription, Description = mutantMetaData.Description, Killed = mutantKilled }); _readerWriterLock.ExitWriteLock(); } } finally { _readerWriterLock.ExitUpgradeableReadLock(); } }
internal void AddResult(MutantMetaData mutantMetaData, bool mutantKilled) { _readerWriterLock.EnterUpgradeableReadLock(); try { if (AppliedMutants.All(s => s.Description != mutantMetaData.Description)) { _readerWriterLock.EnterWriteLock(); AppliedMutants.Add(new AppliedMutant { Description = mutantMetaData.Description, Killed = mutantKilled }); _readerWriterLock.ExitWriteLock(); } } finally { _readerWriterLock.ExitUpgradeableReadLock(); } }
internal void AddResult(Mono.Cecil.Cil.SequencePoint sequencePoint, MutantMetaData mutantMetaData, bool mutantKilled) { if (sequencePoint == null || sequencePoint.Document == null) return; string sourceFileUrl = sequencePoint.Document.Url; _readerWriterLock.EnterUpgradeableReadLock(); try { if (SourceFiles.All(s => s.Url != sourceFileUrl)) { _readerWriterLock.EnterWriteLock(); var newSourceFile = new SourceFile(); newSourceFile.SetUrl(sourceFileUrl); SourceFiles.Add(newSourceFile); _readerWriterLock.ExitWriteLock(); } } finally { _readerWriterLock.ExitUpgradeableReadLock(); } var sourceFile = SourceFiles.First(s => s.Url == sourceFileUrl); sourceFile.AddResult(sequencePoint, mutantMetaData, mutantKilled); }
internal void MutantComplete(MutantMetaData metaData) { metaData.TestDirectory.Dispose(); }
private int MatchReplacement(MutantMetaData metaData, OpCode from, OpCode to) { int result = 0; if (metaData.MethodDefinition.Body.Instructions.Any(i => i.OpCode == to)) { result = 1; StringAssert.Contains(string.Format("{0} => {1}", from.Code, to.Code), metaData.Description); } return result; }