public PexMeFactoryGuesser(IPexComponent host) : base(host) { this.host = host; this.pmd = host.GetService <IPexMeDynamicDatabase>() as PexMeDynamicDatabase; this.psd = host.GetService <IPexMeStaticDatabase>() as PexMeStaticDatabase; }
protected override object BeforeExecution(IPexComponent host) { host.Services.CoverageManager.BeforePublishAssemblyCoverage += Handler(host); locations = host.GetService <ProblemTrackDatabase>().UnCoveredBranchCodeLocations; Log = new StringBuilder(); ErrorLog = host.GetService <ProblemTrackDatabase>().ErrorLog; return(null); }
/// <summary> /// Gets predefined types. Here tdef can be null. In that scenario, if a dictionary exists for the generic /// name, than the first element in the dictionary is returned /// </summary> /// <param name="host"></param> /// <param name="genericname"></param> /// <param name="tdef"></param> /// <param name="genericType"></param> /// <returns></returns> public static bool TryGetInstantiatedClass(IPexComponent host, string genericname, TypeDefinition tdef, out TypeEx genericType) { genericType = null; if (!bClassLoaded) { if (host != null) { string assemblyName = null; PexMeDynamicDatabase pmd = host.GetService <IPexMeDynamicDatabase>() as PexMeDynamicDatabase; if (pmd != null) { assemblyName = pmd.AssemblyName; } else { PexMeStaticDatabase psd = host.GetService <IPexMeStaticDatabase>() as PexMeStaticDatabase; if (psd != null) { assemblyName = psd.AssemblyName; } } //One of PMD or PSD should be available by this time. If not nothing can be done if (assemblyName == null) { host.Log.LogWarning(WikiTopics.MissingWikiTopic, "Hardcoded", "Could not load predefined generic classes data"); return(false); } bClassLoaded = true; LoadPredefinedGenericClasses(host, assemblyName); } } PreDefinedGenericClassesStore pdgc; if (predefinedClasses.TryGetValue(genericname, out pdgc)) { if (tdef != null) { if (pdgc.TryGetTypeExForTypename(tdef.FullName, out genericType)) { return(true); } } //tdef can be null in the case of instantiating methods and fields having generic arguments if (pdgc.TryGetSomeTypeEx(out genericType)) { return(true); } } return(false); }
public PexMePostProcessor(IPexComponent host) : base(host) { this.host = host; this.pmd = host.GetService<IPexMeDynamicDatabase>() as PexMeDynamicDatabase; this.psd = host.GetService<IPexMeStaticDatabase>() as PexMeStaticDatabase; this.pdw = new PexMeDumpWriter(host); this.currAssembly = this.pmd.Services.CurrentAssembly.Assembly.Assembly; var nestingdepth = System.Environment.GetEnvironmentVariable("PEXME_NESTED_DEPTH"); if (nestingdepth != null) ndepth = Convert.ToInt32(nestingdepth, 10); }
public PexMePostProcessor(IPexComponent host) : base(host) { this.host = host; this.pmd = host.GetService <IPexMeDynamicDatabase>() as PexMeDynamicDatabase; this.psd = host.GetService <IPexMeStaticDatabase>() as PexMeStaticDatabase; this.pdw = new PexMeDumpWriter(host); this.currAssembly = this.pmd.Services.CurrentAssembly.Assembly.Assembly; var nestingdepth = System.Environment.GetEnvironmentVariable("PEXME_NESTED_DEPTH"); if (nestingdepth != null) { ndepth = Convert.ToInt32(nestingdepth, 10); } }
public void AfterExecution(IPexComponent host, object data) { var problemTrackDatabase = host.GetService <ProblemTrackDatabase>(); problemTrackDatabase.ReportPath = host.Services.ReportManager.ReportPath; // host.Services.ReportManager.GeneratePexReport problemTrackDatabase.RelativePath = host.Services.ReportManager.RelativeRootPath; problemTrackDatabase.AssemblyUnderTest = assemblyUnderTest; problemTrackDatabase.AfterExecution(); }
private RemoteEventHandler <RemoteEventArgs> Handler(IPexComponent host) { return(e => { try { FindUncoveredBranches(host); if (debug) { host.GetService <ProblemTrackDatabase>().SimpleLog.AppendLine(Log.ToString()); } host.GetService <ProblemTrackDatabase>().DumpAssemblyCoverage(host); } catch (Exception ex) { host.GetService <ProblemTrackDatabase>().ErrorLog.AppendLine("exception in assembly cov: " + ex); } }); }
/// <summary> /// Gets invoked before execution /// </summary> /// <param name="host"></param> /// <returns></returns> protected override object BeforeExecution(IPexComponent host) { this.host = host; //register all explorables foreach (IPexExplorableGuesser guesser in this.CreateExplorableGuessers(host)) { host.Services.ExplorableGuesserManager.AddExplorableGuesser(guesser); } this.host.Log.ExplorableHandler += Log_ExplorableHandler; this.host.Log.ProblemHandler += Log_ProblemHandler; this.pmd = host.GetService<IPexMeDynamicDatabase>() as PexMeDynamicDatabase; //TargetBranch Handler cannot be instantiated with ExplorationServices from here if TERM_SOLVER //functionality is required if(!PexMeConstants.USE_TERM_SOLVER) this.tba = new TargetBranchAnalyzer(this.pmd, this.host.Services, null); return null; }
/// <summary> /// Gets invoked before execution /// </summary> /// <param name="host"></param> /// <returns></returns> protected override object BeforeExecution(IPexComponent host) { this.host = host; //register all explorables foreach (IPexExplorableGuesser guesser in this.CreateExplorableGuessers(host)) { host.Services.ExplorableGuesserManager.AddExplorableGuesser(guesser); } this.host.Log.ExplorableHandler += Log_ExplorableHandler; this.host.Log.ProblemHandler += Log_ProblemHandler; this.pmd = host.GetService <IPexMeDynamicDatabase>() as PexMeDynamicDatabase; //TargetBranch Handler cannot be instantiated with ExplorationServices from here if TERM_SOLVER //functionality is required if (!PexMeConstants.USE_TERM_SOLVER) { this.tba = new TargetBranchAnalyzer(this.pmd, this.host.Services, null); } return(null); }
/// <summary> /// Computes method effects statically. All written fields of a method. /// Can be imprecise and conservative /// </summary> /// <param name="declaringType"></param> /// <param name="method"></param> /// <param name="effects"></param> /// <returns></returns> public static bool TryComputeMethodEffects(IPexComponent host, TypeEx declaringType, Method method, SafeSet <Method> visitedMethods, out MethodEffects effects) { SafeDebug.AssumeNotNull(declaringType, "declaringType"); SafeDebug.AssumeNotNull(method, "method"); try { if (visitedMethods == null) { visitedMethods = new SafeSet <Method>(); } if (visitedMethods.Contains(method)) { effects = null; return(false); } visitedMethods.Add(method); //Check whether this has been computed before var psd = host.GetService <IPexMeStaticDatabase>() as PexMeStaticDatabase; if (psd.MethodEffectsDic.TryGetValue(method.GlobalIndex, out effects)) { return(true); } var res = new SafeSet <string>(); var directSetFields = new SafeSet <string>(); var directCalledMethods = new SafeSet <Method>(); var returnFields = new SafeSet <Field>(); var modificationTypeDic = new SafeDictionary <string, FieldModificationType>(); var parameters = method.Parameters; MethodBodyEx body; if (!method.TryGetBody(out body) || !body.HasInstructions) { effects = null; return(false); } int callDepth = 0; int offset = 0; Instruction instruction; OpCode prevOpcode = OpCodes.Nop; //Stack for load instructions Field lastAccessedArrayField = null; Field lastAccessedField = null; while (body.TryGetInstruction(offset, out instruction)) { SafeDebug.AssumeNotNull(instruction, "instruction"); OpCode opCode = instruction.OpCode; if (LdcOpCodes.Contains(opCode)) { //topIsConstant = true; } else if (ConvOpCodes.Contains(opCode)) { // do not change topIsConstant } else { if (opCode == OpCodes.Stfld) { SafeDebug.Assume(opCode.OperandType == OperandType.InlineField, "opCode.OperandType == OperandType.InlineField"); Field field = instruction.Field; AddFieldToMethodEffects(host, declaringType, res, directSetFields, modificationTypeDic, prevOpcode, field, field.Type); } else if (opCode == OpCodes.Ldfld || opCode == OpCodes.Ldflda) { SafeDebug.Assume(opCode.OperandType == OperandType.InlineField, "opCode.OperandType == OperandType.InlineField"); Field accessedField = instruction.Field; if (accessedField.Type.Spec == TypeSpec.SzArray) { lastAccessedArrayField = accessedField; } else { lastAccessedField = accessedField; } } else if (StElemOpCodes.Contains(opCode)) { if (lastAccessedArrayField != null) { //Indicates that there is n array type modified AddFieldToMethodEffects(host, declaringType, res, directSetFields, modificationTypeDic, prevOpcode, lastAccessedArrayField, lastAccessedArrayField.Type); lastAccessedArrayField = null; } } else if (opCode == OpCodes.Call || opCode == OpCodes.Callvirt) { SafeDebug.Assume(opCode.OperandType == OperandType.InlineMethod, "opCode.OperandType == OperandType.InlineMethod"); Method methodinner = instruction.Method; SafeDebug.AssumeNotNull(method, "method"); directCalledMethods.Add(methodinner); TypeEx methodDeclaringType; //are these function calls are within the parent types if (methodinner.TryGetDeclaringType(out methodDeclaringType) && declaringType.IsAssignableTo(methodDeclaringType)) { MethodEffects methodEffects; if (TryComputeMethodEffects(host, methodDeclaringType, methodinner, visitedMethods, out methodEffects)) { res.AddRange(methodEffects.WrittenInstanceFields); foreach (var key in methodEffects.ModificationTypeDictionary.Keys) { modificationTypeDic[key] = methodEffects.ModificationTypeDictionary[key]; } directSetFields.AddRange(methodEffects.DirectSetterFields); if (methodEffects.CallDepth > callDepth) { callDepth = methodEffects.CallDepth; } } } else { //introducing heuristics for inter-procedural static analysis if (lastAccessedField != null && lastAccessedField.Type.IsReferenceType && !(methodinner.ShortName.StartsWith("Get") || methodinner.ShortName.StartsWith("get") || methodinner.ShortName.StartsWith("Set") || methodinner.ShortName.StartsWith("set"))) { AddFieldToMethodEffects(host, declaringType, res, directSetFields, modificationTypeDic, prevOpcode, lastAccessedField, lastAccessedField.Type); } } } else if (opCode == OpCodes.Ret) { if (instruction.Field != null) { returnFields.Add(instruction.Field); } } //topIsConstant = false; } prevOpcode = opCode; offset = instruction.NextOffset; } effects = new MethodEffects((IFiniteSet <string>)res, directSetFields, directCalledMethods, returnFields, modificationTypeDic, callDepth + 1); psd.MethodEffectsDic[method.GlobalIndex] = effects; return(true); } catch (Exception ex) { host.Log.LogErrorFromException(ex, WikiTopics.MissingWikiTopic, "methodeffects", "Failed to compute method effects for method " + method.FullName + "," + ex.Message); effects = null; return(false); } }
/// <summary> /// Computes method effects statically. All written fields of a method. /// Can be imprecise and conservative /// </summary> /// <param name="declaringType"></param> /// <param name="method"></param> /// <param name="effects"></param> /// <returns></returns> public static bool TryComputeMethodEffects(IPexComponent host, TypeEx declaringType, Method method, SafeSet<Method> visitedMethods, out MethodEffects effects) { SafeDebug.AssumeNotNull(declaringType, "declaringType"); SafeDebug.AssumeNotNull(method, "method"); try { if (visitedMethods == null) visitedMethods = new SafeSet<Method>(); if (visitedMethods.Contains(method)) { effects = null; return false; } visitedMethods.Add(method); //Check whether this has been computed before var psd = host.GetService<IPexMeStaticDatabase>() as PexMeStaticDatabase; if (psd.MethodEffectsDic.TryGetValue(method.GlobalIndex, out effects)) return true; var res = new SafeSet<string>(); var directSetFields = new SafeSet<string>(); var directCalledMethods = new SafeSet<Method>(); var returnFields = new SafeSet<Field>(); var modificationTypeDic = new SafeDictionary<string, FieldModificationType>(); var parameters = method.Parameters; MethodBodyEx body; if (!method.TryGetBody(out body) || !body.HasInstructions) { effects = null; return false; } int callDepth = 0; int offset = 0; Instruction instruction; OpCode prevOpcode = OpCodes.Nop; //Stack for load instructions Field lastAccessedArrayField = null; Field lastAccessedField = null; while (body.TryGetInstruction(offset, out instruction)) { SafeDebug.AssumeNotNull(instruction, "instruction"); OpCode opCode = instruction.OpCode; if (LdcOpCodes.Contains(opCode)) { //topIsConstant = true; } else if (ConvOpCodes.Contains(opCode)) { // do not change topIsConstant } else { if (opCode == OpCodes.Stfld) { SafeDebug.Assume(opCode.OperandType == OperandType.InlineField, "opCode.OperandType == OperandType.InlineField"); Field field = instruction.Field; AddFieldToMethodEffects(host, declaringType, res, directSetFields, modificationTypeDic, prevOpcode, field, field.Type); } else if (opCode == OpCodes.Ldfld || opCode == OpCodes.Ldflda) { SafeDebug.Assume(opCode.OperandType == OperandType.InlineField, "opCode.OperandType == OperandType.InlineField"); Field accessedField = instruction.Field; if (accessedField.Type.Spec == TypeSpec.SzArray) { lastAccessedArrayField = accessedField; } else lastAccessedField = accessedField; } else if (StElemOpCodes.Contains(opCode)) { if (lastAccessedArrayField != null) { //Indicates that there is n array type modified AddFieldToMethodEffects(host, declaringType, res, directSetFields, modificationTypeDic, prevOpcode, lastAccessedArrayField, lastAccessedArrayField.Type); lastAccessedArrayField = null; } } else if (opCode == OpCodes.Call || opCode == OpCodes.Callvirt) { SafeDebug.Assume(opCode.OperandType == OperandType.InlineMethod, "opCode.OperandType == OperandType.InlineMethod"); Method methodinner = instruction.Method; SafeDebug.AssumeNotNull(method, "method"); directCalledMethods.Add(methodinner); TypeEx methodDeclaringType; //are these function calls are within the parent types if (methodinner.TryGetDeclaringType(out methodDeclaringType) && declaringType.IsAssignableTo(methodDeclaringType)) { MethodEffects methodEffects; if (TryComputeMethodEffects(host, methodDeclaringType, methodinner, visitedMethods, out methodEffects)) { res.AddRange(methodEffects.WrittenInstanceFields); foreach (var key in methodEffects.ModificationTypeDictionary.Keys) modificationTypeDic[key] = methodEffects.ModificationTypeDictionary[key]; directSetFields.AddRange(methodEffects.DirectSetterFields); if (methodEffects.CallDepth > callDepth) callDepth = methodEffects.CallDepth; } } else { //introducing heuristics for inter-procedural static analysis if (lastAccessedField != null && lastAccessedField.Type.IsReferenceType && !(methodinner.ShortName.StartsWith("Get") || methodinner.ShortName.StartsWith("get") || methodinner.ShortName.StartsWith("Set") || methodinner.ShortName.StartsWith("set"))) { AddFieldToMethodEffects(host, declaringType, res, directSetFields, modificationTypeDic, prevOpcode, lastAccessedField, lastAccessedField.Type); } } } else if (opCode == OpCodes.Ret) { if (instruction.Field != null) returnFields.Add(instruction.Field); } //topIsConstant = false; } prevOpcode = opCode; offset = instruction.NextOffset; } effects = new MethodEffects((IFiniteSet<string>)res, directSetFields, directCalledMethods, returnFields, modificationTypeDic, callDepth + 1); psd.MethodEffectsDic[method.GlobalIndex] = effects; return true; } catch (Exception ex) { host.Log.LogErrorFromException(ex, WikiTopics.MissingWikiTopic, "methodeffects", "Failed to compute method effects for method " + method.FullName + "," + ex.Message); effects = null; return false; } }
/// <summary> /// Gets predefined types. Here tdef can be null. In that scenario, if a dictionary exists for the generic /// name, than the first element in the dictionary is returned /// </summary> /// <param name="host"></param> /// <param name="genericname"></param> /// <param name="tdef"></param> /// <param name="genericType"></param> /// <returns></returns> public static bool TryGetInstantiatedClass(IPexComponent host, string genericname, TypeDefinition tdef, out TypeEx genericType) { genericType = null; if (!bClassLoaded) { if (host != null) { string assemblyName = null; PexMeDynamicDatabase pmd = host.GetService<IPexMeDynamicDatabase>() as PexMeDynamicDatabase; if (pmd != null) assemblyName = pmd.AssemblyName; else { PexMeStaticDatabase psd = host.GetService<IPexMeStaticDatabase>() as PexMeStaticDatabase; if (psd != null) assemblyName = psd.AssemblyName; } //One of PMD or PSD should be available by this time. If not nothing can be done if (assemblyName == null) { host.Log.LogWarning(WikiTopics.MissingWikiTopic, "Hardcoded", "Could not load predefined generic classes data"); return false; } bClassLoaded = true; LoadPredefinedGenericClasses(host, assemblyName); } } PreDefinedGenericClassesStore pdgc; if (predefinedClasses.TryGetValue(genericname, out pdgc)) { if (tdef != null) { if (pdgc.TryGetTypeExForTypename(tdef.FullName, out genericType)) return true; } //tdef can be null in the case of instantiating methods and fields having generic arguments if (pdgc.TryGetSomeTypeEx(out genericType)) return true; } return false; }
public void FindUncoveredBranches(IPexComponent host) { TaggedBranchCoverageBuilder <PexGeneratedTestName> cov; IPexCoverageManager manager = host.Services.CoverageManager; StringBuilder sb = new StringBuilder("method coverage: \n"); try { if (manager.TryGetAssemblyCoverageBuilder(out cov)) { // var definitions = cov.Methods; IEnumerable <MethodDefinition> definitions = cov.Methods; host.Log.Dump("test", "test", "methods: " + definitions.Count()); Log.AppendLine("assembly methods: " + definitions.Count()); sb.AppendLine("methods: " + definitions.Count()); foreach (var method in definitions) { Log.AppendLine("method: " + method.FullName); // Method m = method.Instantiate(TypeEx.NoTypes, TypeEx.NoTypes); // MethodBodyEx body; // if (!m.TryGetBody(out body)) // { // //error // Log.AppendLine("load method body failed"); // } // method.Instantiate() CoverageDomain domain; if (!branchCoverageDetails.ContainsKey(method)) { branchCoverageDetails.Add(method, new HashSet <BranchCoverageDetail>()); } int[] hits; if (cov.TryGetMethodHits(method, out domain, out hits)) { Log.AppendLine("method hits: " + hits.Length + " " + hits); for (int branchLabel = 0; branchLabel < hits.Length; branchLabel++) { CodeLocation location = method.GetBranchLabelSource(branchLabel); Log.AppendLine("current location: " + location); MethodDefinitionBodyInstrumentationInfo info; if (method.TryGetBodyInstrumentationInfo(out info)) { ISymbolManager sm = host.Services.SymbolManager; SequencePoint sp; sm.TryGetSequencePoint(method, location.Offset, out sp); Log.AppendLine("info: " + info.MethodDefinition.FullName); // foreach (var index in info.BasicBlockStartOffsets) // { // Log.AppendLine("start of BB: " + index.ToString("x")); // } // var util = new BasicBlockUtil(Log, body, info.BasicBlockStartOffsets); // ReadInstructionCov(method, hits, info); foreach ( var outgoingBranchLabel in info.GetOutgoingBranchLabels(location.Offset)) { CodeBranch codeBranch = new CodeBranch(location.Method, outgoingBranchLabel); if (!codeBranch.IsBranch && !codeBranch.IsSwitch && !codeBranch.IsCheck) // is explicit branch? { host.Log.Dump("coverage", "coverage", "CodeBranch: " + codeBranch + " is not explicit"); sb.AppendLine("CodeBranch: " + codeBranch + " is not explicit"); Log.AppendLine("CodeBranch: " + codeBranch + " is not explicit"); continue; // if not, we don't log it } var fromMethod = method.FullName + "," + sp.Document + "," + sp.Line + ", column: " + sp.Column + " outgoing label: " + outgoingBranchLabel; BranchInfo branchInfo = new BranchInfo(sp.Document, sp.Line, sp.Column, sp.EndColumn, method.FullName, location.Offset); Log.AppendLine("Checking CodeBranch: " + codeBranch); Log.AppendLine("CodeBranch location: " + fromMethod); Log.AppendLine("hits.Length: " + hits.Length); Log.AppendLine("codeBranch.IsBranch: " + codeBranch.IsBranch); Log.AppendLine("codeBranch.IsCheck: " + codeBranch.IsCheck); Log.AppendLine("codeBranch.IsContinue: " + codeBranch.IsContinue); Log.AppendLine("codeBranch.IsFailedCheck: " + codeBranch.IsFailedCheck); Log.AppendLine("codeBranch.IsStartMethod: " + codeBranch.IsStartMethod); Log.AppendLine("codeBranch.IsSwitch: " + codeBranch.IsSwitch); Log.AppendLine("codeBranch.IsTarget: " + codeBranch.IsTarget); int branchhit = 0; if (outgoingBranchLabel < hits.Length && hits[outgoingBranchLabel] != 0) { Log.AppendLine("CodeBranch: " + codeBranch + " is covered " + hits[outgoingBranchLabel] + " times"); branchhit = hits[outgoingBranchLabel]; } if (outgoingBranchLabel >= hits.Length) { Log.AppendLine("CodeBranch: " + codeBranch + " is not covered " + " since outgoing label" + outgoingBranchLabel + " is larger than" + hits.Length + "."); branchhit = 0; } string type = ""; if (codeBranch.IsBranch) { type = "Explicit"; } else if (codeBranch.IsCheck) { type = "Implicit"; } BranchCoverageDetail coverageDetail = new BranchCoverageDetail(branchInfo, branchhit, null, 0, type); coverageDetail.CopyBranchProperties(codeBranch); coverageDetail.OutgoingLabel = outgoingBranchLabel; coverageDetail.BranchLabel = branchLabel; int targetOffset; if (info.TryGetTargetOffset(outgoingBranchLabel, out targetOffset)) { sm.TryGetSequencePoint(method, targetOffset, out sp); var targetCovTimes = info.GetInstructionCoverage(hits).Invoke(targetOffset); Log.AppendLine(fromMethod + "\n going to: " + sp.Document + " line: " + sp.Line + " column: " + sp.Column + " endcolumn: " + sp.EndColumn + " target: " + targetOffset.ToString("x")); Log.AppendLine("target offset: " + targetOffset.ToString("x")); Log.AppendLine("it is covered at " + targetCovTimes + " times"); Log.AppendLine("outgoing lables: " + info.GetOutgoingBranchLabels(targetOffset).Count); BranchInfo targetInfo = new BranchInfo(sp.Document, sp.Line, sp.Column, sp.EndColumn, method.FullName, targetOffset); coverageDetail.TargetLocation = targetInfo; coverageDetail.targetCoveredTimes = targetCovTimes; if (!branchCoverageDetails[method].Contains(coverageDetail)) { branchCoverageDetails[method].Add(coverageDetail); } else { foreach (BranchCoverageDetail detail in branchCoverageDetails[method]) { if (detail.Equals(coverageDetail)) { if (coverageDetail.CoveredTimes > detail.CoveredTimes) { detail.CoveredTimes = coverageDetail.CoveredTimes; } } } } } if (outgoingBranchLabel < hits.Length && hits[outgoingBranchLabel] == 0 || branchhit == 0) { Log.AppendLine("CodeBranch: " + codeBranch + " is not covered" + " current offset: " + location.Offset.ToString("x")); // if (!targetBlockCovered) // { locations.Add(new BranchLocation(location, outgoingBranchLabel)); continue; // } if (info.TryGetTargetOffset(outgoingBranchLabel, out targetOffset)) { sm.TryGetSequencePoint(method, targetOffset, out sp); var times = info.GetInstructionCoverage(hits).Invoke(targetOffset); Log.AppendLine(fromMethod + " going to: " + sp.Document + " line: " + sp.Line + " column: " + sp.Column + " endcolumn: " + sp.EndColumn + " target: " + targetOffset.ToString("x")); Log.AppendLine("target offset: " + targetOffset.ToString("x")); Log.AppendLine("it is covered at " + times + " times"); Log.AppendLine("outgoing lables: " + info.GetOutgoingBranchLabels(targetOffset).Count); if (times == 0) { IIndexable <int> basicBlockStartOffsets = info.BasicBlockStartOffsets; int indexOfBasicBlock; for (indexOfBasicBlock = 0; indexOfBasicBlock < basicBlockStartOffsets.Count; indexOfBasicBlock++) { Log.AppendLine("basicBlockStartOffsets: " + basicBlockStartOffsets[indexOfBasicBlock]. ToString("x")); if (basicBlockStartOffsets[indexOfBasicBlock] == targetOffset) { break; } } bool targetBlockCovered = true; if (targetOffset + 1 >= basicBlockStartOffsets[indexOfBasicBlock + 1]) { Log.AppendLine("basicBlockStartOffsets: " + basicBlockStartOffsets[indexOfBasicBlock + 1]); Log.AppendLine("Target Offset " + (targetOffset + 1).ToString("x") + " reach next block"); targetBlockCovered = false; } else { Log.AppendLine("basicBlockStartOffsets: " + basicBlockStartOffsets[indexOfBasicBlock + 1]. ToString("x")); Log.AppendLine("Target Offset " + (targetOffset + 1).ToString("x") + " inside same block"); int coveredTimes = info.GetInstructionCoverage(hits).Invoke(targetOffset + 1); Log.AppendLine("Target Offset " + (targetOffset + 1).ToString("x") + " is covered at " + coveredTimes + " times."); if (coveredTimes == 0) { targetBlockCovered = false; } } if (!targetBlockCovered) { // locations.Add(location, outgoingBranchLabel); } } } } } } } } } } else { sb.AppendLine("manager.TryGetAssemblyCoverageBuilder is null!"); } host.GetService <ProblemTrackDatabase>().InstructionCov = instructionCov; host.GetService <ProblemTrackDatabase>().BasicBlocksOffsets = basicBlockOffsets; host.GetService <ProblemTrackDatabase>().BranchCoverageDetails = branchCoverageDetails; DumpInfoToDebugFile(sb.ToString(), assemblyCovFileName); } catch (Exception ex) { host.Log.Dump("coverage", "cov ex", ex.Message); host.GetService <ProblemTrackDatabase>().ErrorLog.AppendLine("exception in FindUncoveredBranches: " + ex); DumpInfoToDebugFile("cov ex" + ex.Message, assemblyCovFileName); } }
void Log_ExplorationBoundaryHandler(ExplorationBoundaryEventArgs e) { var database = Host.GetService <ProblemTrackDatabase>(); ProblemEventArgs successfulFlippedPathCondition = database.CurrentSuccessfulFlippedPathCondition; StringBuilder log = database.SimpleLog; SequencePoint sp; if (successfulFlippedPathCondition == null) { return; } CodeLocation location = successfulFlippedPathCondition.FlippedLocation; Host.Services.SymbolManager.TryGetSequencePoint(location.Method, location.Offset, out sp); StringBuilder sb = new StringBuilder("/////////////////////////////////// \n"); log.AppendLine("exception: " + e.Kind + " e.TargetName: " + e.TargetName + " message: " + e); sb.AppendLine("flipped location: " + sp.Document + " line: " + sp.Line); var branchInfo = new BranchInfo("", 0, 0, 0, "", 0); try { branchInfo = new BranchInfo(sp.Document, sp.Line, sp.Column, sp.EndColumn, location.Method.FullName, location.Offset); } catch (Exception) { } var flippedCondition = successfulFlippedPathCondition.Suffix; var stringWriter = new StringWriter(); var bodyWriter = this.Host.Services.LanguageManager.DefaultLanguage.CreateBodyWriter(stringWriter, VisibilityContext. Private); var emitter = new TermEmitter(successfulFlippedPathCondition.TermManager, new NameCreator()); if (emitter.TryEvaluate(Indexable.One(flippedCondition), 1000, bodyWriter)) { bodyWriter.Return(SystemTypes.Bool); } stringWriter.WriteLine(); stringWriter.WriteLine("Feasible prefixes:"); if (successfulFlippedPathCondition.FeasiblePrefix != null && successfulFlippedPathCondition.FeasiblePrefix.Length > 0) { var bodyWriter2 = this.Host.Services.LanguageManager.DefaultLanguage.CreateBodyWriter(stringWriter, VisibilityContext. Private); foreach (Term prefix in successfulFlippedPathCondition.FeasiblePrefix) { if (emitter.TryEvaluate(Indexable.One(prefix), 1000, bodyWriter2)) { bodyWriter2.Return(SystemTypes.Bool); } } } else { stringWriter.WriteLine("No feasible prefixes."); } this.Host.Log.Dump("My Category", "condition", stringWriter.ToString()); sb.AppendLine(stringWriter.ToString()); sb.AppendLine("///////////////////////////////////"); var issue = new BoundaryProblem(e.Kind.ToString(), e.TargetName.ToString(), e.Message, branchInfo, stringWriter.ToString()); Host.GetService <ProblemTrackDatabase>().BoundaryIssues.Add(issue); log.AppendLine(sb.ToString()); // e. }
public void FindUncoveredBranches(IPexComponent host) { TaggedBranchCoverageBuilder<PexGeneratedTestName> cov; IPexCoverageManager manager = host.Services.CoverageManager; StringBuilder sb = new StringBuilder("method coverage: \n"); try { if (manager.TryGetAssemblyCoverageBuilder(out cov)) { // var definitions = cov.Methods; IEnumerable<MethodDefinition> definitions = cov.Methods; host.Log.Dump("test", "test", "methods: " + definitions.Count()); Log.AppendLine("assembly methods: " + definitions.Count()); sb.AppendLine("methods: " + definitions.Count()); foreach (var method in definitions) { Log.AppendLine("method: " + method.FullName); // Method m = method.Instantiate(TypeEx.NoTypes, TypeEx.NoTypes); // MethodBodyEx body; // if (!m.TryGetBody(out body)) // { // //error // Log.AppendLine("load method body failed"); // } // method.Instantiate() CoverageDomain domain; if (!branchCoverageDetails.ContainsKey(method)) { branchCoverageDetails.Add(method,new HashSet<BranchCoverageDetail>()); } int[] hits; if (cov.TryGetMethodHits(method, out domain, out hits)) { Log.AppendLine("method hits: " + hits.Length + " " + hits); for (int branchLabel = 0; branchLabel < hits.Length; branchLabel++) { CodeLocation location = method.GetBranchLabelSource(branchLabel); Log.AppendLine("current location: " + location); MethodDefinitionBodyInstrumentationInfo info; if (method.TryGetBodyInstrumentationInfo(out info)) { ISymbolManager sm = host.Services.SymbolManager; SequencePoint sp; sm.TryGetSequencePoint(method, location.Offset, out sp); Log.AppendLine("info: " + info.MethodDefinition.FullName); // foreach (var index in info.BasicBlockStartOffsets) // { // Log.AppendLine("start of BB: " + index.ToString("x")); // } // var util = new BasicBlockUtil(Log, body, info.BasicBlockStartOffsets); // ReadInstructionCov(method, hits, info); foreach ( var outgoingBranchLabel in info.GetOutgoingBranchLabels(location.Offset)) { CodeBranch codeBranch = new CodeBranch(location.Method, outgoingBranchLabel); if (!codeBranch.IsBranch && !codeBranch.IsSwitch && !codeBranch.IsCheck) // is explicit branch? { host.Log.Dump("coverage", "coverage", "CodeBranch: " + codeBranch + " is not explicit"); sb.AppendLine("CodeBranch: " + codeBranch + " is not explicit"); Log.AppendLine("CodeBranch: " + codeBranch + " is not explicit"); continue; // if not, we don't log it } var fromMethod = method.FullName + "," + sp.Document + "," + sp.Line + ", column: " + sp.Column + " outgoing label: " + outgoingBranchLabel; BranchInfo branchInfo = new BranchInfo(sp.Document,sp.Line,sp.Column,sp.EndColumn,method.FullName,location.Offset); Log.AppendLine("Checking CodeBranch: " + codeBranch); Log.AppendLine("CodeBranch location: " + fromMethod); Log.AppendLine("hits.Length: " + hits.Length); Log.AppendLine("codeBranch.IsBranch: " + codeBranch.IsBranch); Log.AppendLine("codeBranch.IsCheck: " + codeBranch.IsCheck); Log.AppendLine("codeBranch.IsContinue: " + codeBranch.IsContinue); Log.AppendLine("codeBranch.IsFailedCheck: " + codeBranch.IsFailedCheck); Log.AppendLine("codeBranch.IsStartMethod: " + codeBranch.IsStartMethod); Log.AppendLine("codeBranch.IsSwitch: " + codeBranch.IsSwitch); Log.AppendLine("codeBranch.IsTarget: " + codeBranch.IsTarget); int branchhit = 0; if (outgoingBranchLabel < hits.Length && hits[outgoingBranchLabel] != 0) { Log.AppendLine("CodeBranch: " + codeBranch + " is covered " + hits[outgoingBranchLabel] + " times"); branchhit = hits[outgoingBranchLabel]; } if(outgoingBranchLabel >= hits.Length){ Log.AppendLine("CodeBranch: " + codeBranch + " is not covered " + " since outgoing label"+ outgoingBranchLabel +" is larger than" + hits.Length + "."); branchhit = 0; } string type = ""; if (codeBranch.IsBranch) { type = "Explicit"; } else if(codeBranch.IsCheck) { type = "Implicit"; } BranchCoverageDetail coverageDetail = new BranchCoverageDetail(branchInfo,branchhit,null,0,type); coverageDetail.CopyBranchProperties(codeBranch); coverageDetail.OutgoingLabel = outgoingBranchLabel; coverageDetail.BranchLabel = branchLabel; int targetOffset; if (info.TryGetTargetOffset(outgoingBranchLabel, out targetOffset)) { sm.TryGetSequencePoint(method, targetOffset, out sp); var targetCovTimes = info.GetInstructionCoverage(hits).Invoke(targetOffset); Log.AppendLine(fromMethod + "\n going to: " + sp.Document + " line: " + sp.Line + " column: " + sp.Column + " endcolumn: " + sp.EndColumn + " target: " + targetOffset.ToString("x")); Log.AppendLine("target offset: " + targetOffset.ToString("x")); Log.AppendLine("it is covered at " + targetCovTimes + " times"); Log.AppendLine("outgoing lables: " + info.GetOutgoingBranchLabels(targetOffset).Count); BranchInfo targetInfo = new BranchInfo(sp.Document, sp.Line, sp.Column, sp.EndColumn, method.FullName, targetOffset); coverageDetail.TargetLocation = targetInfo; coverageDetail.targetCoveredTimes = targetCovTimes; if (!branchCoverageDetails[method].Contains(coverageDetail)) { branchCoverageDetails[method].Add(coverageDetail); } else { foreach (BranchCoverageDetail detail in branchCoverageDetails[method]) { if (detail.Equals(coverageDetail)) { if (coverageDetail.CoveredTimes > detail.CoveredTimes) { detail.CoveredTimes = coverageDetail.CoveredTimes; } } } } } if (outgoingBranchLabel < hits.Length && hits[outgoingBranchLabel] == 0 || branchhit == 0) { Log.AppendLine("CodeBranch: " + codeBranch + " is not covered" + " current offset: " + location.Offset.ToString("x")); // if (!targetBlockCovered) // { locations.Add(new BranchLocation(location, outgoingBranchLabel)); continue; // } if (info.TryGetTargetOffset(outgoingBranchLabel, out targetOffset)) { sm.TryGetSequencePoint(method, targetOffset, out sp); var times = info.GetInstructionCoverage(hits).Invoke(targetOffset); Log.AppendLine(fromMethod + " going to: " + sp.Document + " line: " + sp.Line + " column: " + sp.Column + " endcolumn: " + sp.EndColumn + " target: " + targetOffset.ToString("x")); Log.AppendLine("target offset: " + targetOffset.ToString("x")); Log.AppendLine("it is covered at " + times + " times"); Log.AppendLine("outgoing lables: " + info.GetOutgoingBranchLabels(targetOffset).Count); if (times == 0) { IIndexable<int> basicBlockStartOffsets = info.BasicBlockStartOffsets; int indexOfBasicBlock; for (indexOfBasicBlock = 0; indexOfBasicBlock < basicBlockStartOffsets.Count; indexOfBasicBlock++) { Log.AppendLine("basicBlockStartOffsets: " + basicBlockStartOffsets[indexOfBasicBlock]. ToString("x")); if (basicBlockStartOffsets[indexOfBasicBlock] == targetOffset) { break; } } bool targetBlockCovered = true; if (targetOffset + 1 >= basicBlockStartOffsets[indexOfBasicBlock + 1]) { Log.AppendLine("basicBlockStartOffsets: " + basicBlockStartOffsets[indexOfBasicBlock + 1]); Log.AppendLine("Target Offset " + (targetOffset + 1).ToString("x") + " reach next block"); targetBlockCovered = false; } else { Log.AppendLine("basicBlockStartOffsets: " + basicBlockStartOffsets[indexOfBasicBlock + 1]. ToString("x")); Log.AppendLine("Target Offset " + (targetOffset + 1).ToString("x") + " inside same block"); int coveredTimes = info.GetInstructionCoverage(hits).Invoke(targetOffset + 1); Log.AppendLine("Target Offset " + (targetOffset + 1).ToString("x") + " is covered at " + coveredTimes + " times."); if (coveredTimes == 0) { targetBlockCovered = false; } } if (!targetBlockCovered) { // locations.Add(location, outgoingBranchLabel); } } } } } } } } } } else { sb.AppendLine("manager.TryGetAssemblyCoverageBuilder is null!"); } host.GetService<ProblemTrackDatabase>().InstructionCov = instructionCov; host.GetService<ProblemTrackDatabase>().BasicBlocksOffsets = basicBlockOffsets; host.GetService<ProblemTrackDatabase>().BranchCoverageDetails = branchCoverageDetails; DumpInfoToDebugFile(sb.ToString(), assemblyCovFileName); } catch (Exception ex) { host.Log.Dump("coverage", "cov ex", ex.Message); host.GetService<ProblemTrackDatabase>().ErrorLog.AppendLine("exception in FindUncoveredBranches: " + ex); DumpInfoToDebugFile("cov ex" + ex.Message, assemblyCovFileName); } }
private RemoteEventHandler<RemoteEventArgs> Handler(IPexComponent host) { return e => { try { FindUncoveredBranches(host); if (debug) { host.GetService<ProblemTrackDatabase>().SimpleLog.AppendLine(Log.ToString()); } host.GetService<ProblemTrackDatabase>().DumpAssemblyCoverage(host); } catch (Exception ex) { host.GetService<ProblemTrackDatabase>().ErrorLog.AppendLine("exception in assembly cov: " + ex); } }; }
protected override object BeforeExecution(IPexComponent host) { host.Services.CoverageManager.BeforePublishAssemblyCoverage += Handler(host); locations = host.GetService<ProblemTrackDatabase>().UnCoveredBranchCodeLocations; Log = new StringBuilder(); ErrorLog = host.GetService<ProblemTrackDatabase>().ErrorLog; return null; }