public TargetBranchAnalyzer(PexMeDynamicDatabase pmd, IPexComponentServices services, IPexExplorationComponent explorationComponent) { this.pmd = pmd; this.host = pmd; this.services = services; this.explorationComponent = explorationComponent; }
public static void DumpFactorySuggestionStore(PexMeDynamicDatabase pmd) { var filename = Path.Combine(PexMeConstants.PexMeStorageDirectory, PexMeConstants.PexMeFactorySuggestionStore); Stream streamWrite = File.Create(filename); BinaryFormatter binaryWrite = new BinaryFormatter(); binaryWrite.Serialize(streamWrite, pmd.FactorySuggestionsDictionary); streamWrite.Close(); }
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); }
protected override void Initialize() { base.Initialize(); this.pmd = this.GetService<IPexMeDynamicDatabase>() as PexMeDynamicDatabase; this.psd = this.GetService<IPexMeStaticDatabase>() as PexMeStaticDatabase; this.tba = new TargetBranchAnalyzer(this.pmd, this.Services, this); this.ExplorationServices.ExplorableManager.AddExplorableInsufficienyObserver(this); this.Log.LogMessage("hint provider", "Registered the hint provider"); this.thp = new TypeHintProvider(this.pmd, this.psd); this.ExplorationServices.DomainManager.AddTypeHintProvider(thp); }
public FieldAccessCollector(IFieldAccessPathObserver pathObserver, IFieldAccessExplorationObserver explorationObserver, IPexMeDynamicDatabase pmd, PexMeStaticDatabase psd, int level) { this.pathObserver = pathObserver; this.explorationObserver = explorationObserver; this.pmd = pmd as PexMeDynamicDatabase; this.psd = psd; this.trackedFrameId = -1; this.level = level; this.depth = -1; }
public DUCoverEngine() : base(new Container(new TypeEx[] { Microsoft.ExtendedReflection.Metadata.Metadata<IEngineOptions>.Type }), new IComponent[] { }) { EngineOptions options = new EngineOptions(); this.AddComponent("options", options); this.AddComponents(); var pmd = new PexMeDynamicDatabase(); pmd.AssemblyName = System.Environment.GetEnvironmentVariable(DUCoverConstants.DUCoverAssemblyVar); this.AddComponent("pmd", pmd); var psd = new PexMeStaticDatabase(); psd.AssemblyName = System.Environment.GetEnvironmentVariable(DUCoverConstants.DUCoverAssemblyVar); this.AddComponent("psd", psd); }
/// <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> /// Removes the uncovered location store. Mainly keeps the sequence /// that helped to cover the target location and drops all others /// </summary> /// <param name="pucls"></param> /// <param name="successful">Helps to distinguish between a removal during success and failure</param> internal void RemoveUncoveredLocationStore(PersistentUncoveredLocationStore pucls, bool successful, PexMeDynamicDatabase pmd) { var key = UncoveredCodeLocationStore.GetKey(pucls.CodeLocation, pucls.ExplorableType, pucls.TermIndex); this.locationStoreSpecificSequences.Remove(key); if (!successful) { return; } this.SuccessfulCoveredLocations.Add(key); this.PermanentFailedUncoveredLocations.Remove(key); this.TemporaryFailedUncoveredLocations.Remove(key); this.UncoveredSystemLibLocations.Remove(key); //Get the method associated with the current exploring PUT string methodcallname = PexMeConstants.DEFAULT_FINAL_SUGGESTION_STORE; Method assocMethod; if (PUTGenerator.PUTGenerator.TryRetrieveMethodCall(pmd.CurrentPUTMethod, out assocMethod)) methodcallname = MethodOrFieldAnalyzer.GetMethodSignature(assocMethod); //Get PUT independent sequence list MethodSignatureSequenceList putIndependentMssl; if (!this.FinalSuggestedMethodSequences.TryGetValue(methodcallname, out putIndependentMssl)) { putIndependentMssl = new MethodSignatureSequenceList(); this.FinalSuggestedMethodSequences.Add(methodcallname, putIndependentMssl); } //Also update the PUT specific sequences. These gets cleared once a //PUT is completely explored. var putsignature = MethodOrFieldAnalyzer.GetMethodSignature(pmd.CurrentPUTMethod); MethodSignatureSequenceList putSpecificMssl; if (!this.FinalPUTSequences.TryGetValue(putsignature, out putSpecificMssl)) { putSpecificMssl = new MethodSignatureSequenceList(); this.FinalPUTSequences.Add(putsignature, putSpecificMssl); } //Any Persistent Uncovered location store that is successfully //covered gets a hit sequence SafeDebug.AssumeNotNull(pucls.HitSequence, "pucls.HitSequence"); MethodSignatureSequence matchingseq; if (!FactorySuggestionStore.TryGetMatchingSequence(pucls.HitSequence, pucls.SuggestedMethodSequences, out matchingseq)) { //Failed to retrieve the hit sequence. However, a heuristic //can be used where there is only one suggested sequence if (pucls.SuggestedMethodSequences.Count == 1) { matchingseq = pucls.SuggestedMethodSequences[0]; putIndependentMssl.Add(matchingseq); putSpecificMssl.Add(matchingseq); } else { pmd.Log.LogWarning(WikiTopics.MissingWikiTopic, "SequenceMatch", "Failed to retrieve a matching sequence for a hit sequence, adding complete hit sequence " + pucls.HitSequence); var hitSubSequence = new MethodSignatureSequence(); foreach (var mhit in pucls.HitSequence.Sequence) { if (mhit.Contains("..ctor(")) //Don't add constructors continue; if (!mhit.Contains(this.DeclaringType)) //Ignore the method calls from other types continue; hitSubSequence.Sequence.Add(mhit); } //Add all sequences to final set of sequences for further usage. putIndependentMssl.Add(hitSubSequence); putSpecificMssl.Add(hitSubSequence); //this.UpgradeActiveULStores(putsignature, pucls.SuggestedMethodSequences); } } else { //Add all sequences to final set of sequences for further usage. putIndependentMssl.Add(matchingseq); putSpecificMssl.Add(matchingseq); //this.UpgradeActiveULStores(putsignature, matchingseq); } }
/// <summary> /// Adds a default method-call sequence that represents the first execution /// of the PUT /// </summary> internal void AddDefaultSequence(PexMeDynamicDatabase pmd, MethodSignatureSequence defaultSeq) { //Get the method associated with the current exploring PUT string methodcallname = PexMeConstants.DEFAULT_FINAL_SUGGESTION_STORE; Method assocMethod; if (PUTGenerator.PUTGenerator.TryRetrieveMethodCall(pmd.CurrentPUTMethod, out assocMethod)) methodcallname = MethodOrFieldAnalyzer.GetMethodSignature(assocMethod); //Get PUT independent sequence list MethodSignatureSequenceList putIndependentMssl; if (!this.FinalSuggestedMethodSequences.TryGetValue(methodcallname, out putIndependentMssl)) { putIndependentMssl = new MethodSignatureSequenceList(); this.FinalSuggestedMethodSequences.Add(methodcallname, putIndependentMssl); putIndependentMssl.Add(defaultSeq); } //Also update the PUT specific sequences. These gets cleared once a //PUT is completely explored. var putsignature = MethodOrFieldAnalyzer.GetMethodSignature(pmd.CurrentPUTMethod); MethodSignatureSequenceList putSpecificMssl; if (!this.FinalPUTSequences.TryGetValue(putsignature, out putSpecificMssl)) { putSpecificMssl = new MethodSignatureSequenceList(); this.FinalPUTSequences.Add(putsignature, putSpecificMssl); putSpecificMssl.Add(defaultSeq); } }
/// <summary> /// Gets the entire list of suggested methods /// </summary> /// <returns></returns> public IEnumerable<MethodSignatureSequence> GetSuggestedMethodSequences(PexMeDynamicDatabase pmd) { var uniqueSequenceList = new List<MethodSignatureSequence>(); //Gather all sequences among all location stores. Detect the unique //sequences among them and suggest the complete unique sequences foreach (var pucls in this.locationStoreSpecificSequences.Values) { if (pucls.IsDormat()) continue; foreach (var ms in pucls.SuggestedMethodSequences) { if (ms.Sequence.Count == 0) continue; if (!uniqueSequenceList.Contains(ms)) uniqueSequenceList.Add(ms); } } //Return all final sequence ever collected to help cover more //at the first time itself. Along with the final suggested method, //we also need to add the method itself foreach (var methodid in this.FinalSuggestedMethodSequences.Keys) { var seqlist = this.FinalSuggestedMethodSequences[methodid]; foreach (var seq in seqlist.SequenceList) { MethodSignatureSequence tempseq = new MethodSignatureSequence(); tempseq.Sequence.AddRange(seq.Sequence); tempseq.Sequence.Add(methodid); if (!uniqueSequenceList.Contains(tempseq)) uniqueSequenceList.Add(tempseq); } } foreach (var seqlist in this.FinalSuggestedMethodSequences.Values) { foreach(var seq in seqlist.SequenceList) { if (seq.Sequence.Count == 0) continue; if (!uniqueSequenceList.Contains(seq)) uniqueSequenceList.Add(seq); } } //Return all previously collected sequences for this PUT, if there exist //no sequences specific to any uncovered location yet. var putsignature = MethodOrFieldAnalyzer.GetMethodSignature(pmd.CurrentPUTMethod); MethodSignatureSequenceList mssl; if (this.FinalPUTSequences.TryGetValue(putsignature, out mssl)) { foreach (var seq in mssl.SequenceList) { if (seq.Sequence.Count == 0) continue; if (!uniqueSequenceList.Contains(seq)) uniqueSequenceList.Add(seq); } } foreach (var ms in uniqueSequenceList) yield return ms; }
public void Analyze() { //this.Log.LogMessage(PexMeLogCategories.MethodBegin, "Begin of FieldAccessPathObserver.Analyze() method"); if(this.explorationObserver == null) this.explorationObserver = this.GetService<IFieldAccessExplorationObserver>(); if (this.pmd == null) this.pmd = this.GetService<IPexMeDynamicDatabase>() as PexMeDynamicDatabase; if (this.psd == null) this.psd = this.GetService<IPexMeStaticDatabase>() as PexMeStaticDatabase; int framesCount = 0; int framesHandled = 0; int maxLevelCount = 16; //TODO: Why 16? pmd.LastExecutedFactoryMethodCallSequence = null; for (int level = 0; level < maxLevelCount; level++) { FieldAccessCollector controller = new FieldAccessCollector(this, this.explorationObserver, this.pmd, this.psd, level); this.pmd.DefectDetectingSequence = false; try { using (IEngine trackingEngine = this.PathServices.TrackingEngineFactory.CreateTrackingEngine(controller)) { IPexTrackingDriver driver = trackingEngine.GetService<IPexTrackingDriver>(); if (!driver.Run()) break; } } catch (Exception ex) { this.pmd.DefectDetectingSequence = true; } pmd.LastExecutedFactoryMethodCallSequence = controller.FactoryMethodCallSequence; pmd.LastExecutedCUTMethodCallSequence = controller.CUTMethodCallSequence; //StringBuilder sb = new StringBuilder(); //foreach(Method m in pmd.LastExecutedMethodCallSequence) //{ // sb.Append(m.ToString() + "\n"); //} //this.pmd.Log.LogMessage("debug", "Executed method call sequence " + sb.ToString()); framesCount = SafeMath.Max(framesCount, controller.FramesCount); framesHandled += controller.FramesHandled; if (framesHandled > framesCount) framesHandled = framesCount; //this.Log.LogMessage( // "FieldAccessObserver", // "collecting data, {0:P} of all frames up to level {1} / {2}", // ((double)framesHandled / framesCount), level, maxLevelCount); if (controller.FramesHandled == 0 || // did we make any progress? framesHandled >= framesCount) // or have we processed all frames there are? break; } //Gather the information of last visited term here to use it later in //InsufficientObjectFactoryObserver.LogExplorableInsufficiency //this.Log.LogMessage(PexMeLogCategories.MethodEnd, "End of FieldAccessPathObserver.Analyze() method"); }
public TypeHintProvider(PexMeDynamicDatabase pmd, PexMeStaticDatabase psd) { this.pmd = pmd; this.psd = psd; }
protected override void Load(Microsoft.ExtendedReflection.ComponentModel.IContainer container) { this.pmd = new PexMeDynamicDatabase(); container.AddComponent(null, pmd); this.psd = new PexMeStaticDatabase(); container.AddComponent(null, psd); if (PexMeConstants.ENABLE_MSEQGEN_RECOMMENDER) { mseqgen = new MSeqGenRecommender(); container.AddComponent(null, mseqgen); } base.Load(container); }
/// <summary> /// Returns a method that produce a given type. Static methods are given higher preference than dynamic methods /// </summary> /// <param name="targetTypeEx"></param> /// <param name="producingMethods"></param> /// <returns></returns> public static bool TryGetProducingMethods(PexMeDynamicDatabase pmd, TypeEx targetTypeEx, out Method producingMethod) { var currAssembly = pmd.CurrAssembly; foreach (var tdef in currAssembly.TypeDefinitions) { if (IsAPexClass(tdef)) continue; foreach (var smdef in tdef.DeclaredStaticMethods) { if (IsAPexMethod(smdef)) continue; if (!smdef.IsVisible(VisibilityContext.Exported)) continue; if (TryCheckReturnTypeOfMethod(pmd, tdef, smdef, targetTypeEx, out producingMethod)) return true; } foreach (var mdef in tdef.DeclaredInstanceMethods) { if (IsAPexMethod(mdef)) continue; if (!mdef.IsVisible(VisibilityContext.Exported)) continue; if (TryCheckReturnTypeOfMethod(pmd, tdef, mdef, targetTypeEx, out producingMethod)) return true; } } producingMethod = null; return false; }
public static bool TryCheckReturnTypeOfMethod(PexMeDynamicDatabase pmd, TypeDefinition tdef, MethodDefinition mdef, TypeEx targetTypeEx, out Method producingMethod) { var retType = mdef.ResultType; if (retType.ToString() == targetTypeEx.FullName) { producingMethod = mdef.Instantiate(MethodOrFieldAnalyzer.GetGenericTypeParameters(pmd, tdef), MethodOrFieldAnalyzer.GetGenericMethodParameters(pmd, mdef)); return true; } //Get the actual type of return type and see whether it is assinable TypeEx retTypeEx; if (MethodOrFieldAnalyzer.TryGetTypeExFromName(pmd, pmd.CurrAssembly, retType.ToString(), out retTypeEx)) { if (targetTypeEx.IsAssignableTo(retTypeEx)) { producingMethod = mdef.Instantiate(MethodOrFieldAnalyzer.GetGenericTypeParameters(pmd, tdef), MethodOrFieldAnalyzer.GetGenericMethodParameters(pmd, mdef)); return true; } } producingMethod = null; return false; }
/// <summary> /// Dumps entire database into different persistent stores (files) /// </summary> /// <param name="pmd"></param> public void DumpDynamicDatabase(PexMeDynamicDatabase pmd) { if (!Directory.Exists(PexMeConstants.PexMeStorageDirectory)) Directory.CreateDirectory(PexMeConstants.PexMeStorageDirectory); //Dumping only the contents of factory suggestion store for time being //as the classes in extended reflection are not serializable try { DumpFactorySuggestionStore(pmd); } catch (Exception ex) { pmd.Log.LogErrorFromException(ex, WikiTopics.MissingWikiTopic, "dumpwriter", "Failed to dump dynamic factory suggestion store"); } if (PexMeConstants.ENABLE_DYNAMICDB_STORAGE) { //Dump the dynamic field store that includes information of which method modify which fields try { var filename = Path.Combine(PexMeConstants.PexMeStorageDirectory, PexMeConstants.PexMeDynamicFieldStore); Stream streamWrite = File.Create(filename); BinaryFormatter binaryWrite = new BinaryFormatter(); var persistentFieldDic = this.GetPersistentFieldDictionary(pmd.FieldDictionary); binaryWrite.Serialize(streamWrite, persistentFieldDic); streamWrite.Close(); } catch (Exception ex) { pmd.Log.LogErrorFromException(ex, WikiTopics.MissingWikiTopic, "dumpwriter", "Failed to dump dynamic field store"); } } if (PexMeConstants.ENABLE_DYNAMICDB_STORAGE) { //Dump the dynamic method store that includes information of which method calls other methods and field they modify try { var filename = Path.Combine(PexMeConstants.PexMeStorageDirectory, PexMeConstants.PexMeDynamicMethodStore); Stream streamWrite = File.Create(filename); BinaryFormatter binaryWrite = new BinaryFormatter(); var persistentMethodDic = this.GetPersistentMethodDictionary(pmd.MethodDictionary); binaryWrite.Serialize(streamWrite, persistentMethodDic); streamWrite.Close(); } catch (Exception ex) { pmd.Log.LogErrorFromException(ex, WikiTopics.MissingWikiTopic, "dumpwriter", "Failed to dynamic dump method store"); } } //Dump the all explored methods try { var filename = Path.Combine(PexMeConstants.PexMeStorageDirectory, PexMeConstants.PexMeDynamicExploredMethods); Stream streamWrite = File.Create(filename); BinaryFormatter binaryWrite = new BinaryFormatter(); binaryWrite.Serialize(streamWrite, pmd.AllExploredMethods); streamWrite.Close(); } catch (Exception ex) { pmd.Log.LogErrorFromException(ex, WikiTopics.MissingWikiTopic, "dumpwriter", "Failed to dump all explored methods"); } //Dump the all explored methods try { var filename = Path.Combine(PexMeConstants.PexMeStorageDirectory, PexMeConstants.PexMePendingExplorationMethods); Stream streamWrite = File.Create(filename); BinaryFormatter binaryWrite = new BinaryFormatter(); binaryWrite.Serialize(streamWrite, pmd.PendingExplorationMethods); streamWrite.Close(); } catch (Exception ex) { pmd.Log.LogErrorFromException(ex, WikiTopics.MissingWikiTopic, "dumpwriter", "Failed to dump pending explored methods"); } /******************** BEGIN OF DEBUGGING INFO ***********************/ //Writing monitored methods if (PexMeConstants.ENABLE_DYNAMICDB_STORAGE) { var monitoredMethods = pmd.MonitoredMethods; var monitoredMethodsFileName = Path.Combine(PexMeConstants.PexMeStorageDirectory, pmd.AssemblyName + ".dynamic.monitoredmethods.txt"); using (StreamWriter sw = new StreamWriter(monitoredMethodsFileName)) { //Printing all monitored methods sw.WriteLine("All monitored methods"); foreach (var methodName in pmd.MonitoredMethods) sw.WriteLine(methodName); //Printing all controllable types sw.WriteLine(); sw.WriteLine("Controllable types"); foreach (var typeName in pmd.ControllableTypes) sw.WriteLine(typeName); //Printing all types for which factory methods are requested sw.WriteLine(); sw.WriteLine("Factory requested types"); foreach (var typeName in pmd.PexGeneratedFactories.Values) sw.WriteLine(typeName); } } //Writing method information if (PexMeConstants.ENABLE_DYNAMICDB_STORAGE) { var methodDic = pmd.MethodDictionary; var methodAccessFileName = Path.Combine(PexMeConstants.PexMeStorageDirectory, pmd.AssemblyName + ".dynamic.methodAccess.txt"); using (StreamWriter sw = new StreamWriter(methodAccessFileName)) { foreach (var methodEntry in methodDic.Values) { //Printing write fields sw.WriteLine("Methodname: " + methodEntry.methodName); if (methodEntry.WriteFields.Count > 0) { sw.WriteLine("Write fields: "); foreach (var writeField in methodEntry.WriteFields) sw.WriteLine("\tField: " + writeField); } if (methodEntry.CalledMethods.Count > 0) { sw.WriteLine("Called Methods: "); foreach (var calledMethod in methodEntry.CalledMethods) sw.WriteLine("\t" + calledMethod); } if (methodEntry.CallingMethods.Count > 0) { sw.WriteLine("Calling Methods: "); foreach (var callingMethod in methodEntry.CallingMethods) sw.WriteLine("\t" + callingMethod); } //TODO: Print read fields } } } //Writing field information if (PexMeConstants.ENABLE_DYNAMICDB_STORAGE) { var fieldDic = pmd.FieldDictionary; var fieldAccessFileName = Path.Combine(PexMeConstants.PexMeStorageDirectory, pmd.AssemblyName + ".dynamic.fieldAccess.txt"); using (StreamWriter sw = new StreamWriter(fieldAccessFileName)) { foreach (var fieldEntry in fieldDic.Values) { //Printing write methods sw.WriteLine("Fieldname: " + fieldEntry.FieldName); sw.WriteLine("Write methods: "); foreach (var writeMethodSet in fieldEntry.WriteMethods.Values) { foreach (var writeMethod in writeMethodSet) sw.WriteLine("\tMethod: " + writeMethod + ", ModificationType: " + FieldStore.GetModificationType(fieldEntry, writeMethod) + " PreciseModificationType: " + FieldStore.GetPreciseModificationType(fieldEntry, writeMethod)); } sw.WriteLine("Field values: "); foreach (var fieldValue in fieldEntry.FieldValues) { sw.WriteLine("\tValue: " + fieldValue); } //TODO: Print read methods } } } //Writing uncovered code locations information var uncoveredCLDic = pmd.UncoveredLocationDictionary; var uncoveredCLFileName = Path.Combine(PexMeConstants.PexMeStorageDirectory, pmd.AssemblyName + ".uncoveredloc.txt"); using (StreamWriter sw = new StreamWriter(uncoveredCLFileName)) { foreach (var ucstorelist in uncoveredCLDic.Values) { var ucstore = ucstorelist.StoreList[0]; sw.WriteLine("CodeLocation: " + ucstore.Location); sw.WriteLine("Relevant Fields: "); //Writing associated fields foreach (var field in ucstore.AllFields) sw.WriteLine("\t" + field); sw.WriteLine("Code Locations and Associated conditions: "); sw.WriteLine("=========================================="); //Writing associated terms foreach (var term in ucstore.TextualTerms) sw.WriteLine(term); sw.WriteLine("=========================================="); sw.WriteLine("Suggested target method for covering the branch location: "); sw.WriteLine("=========================================================="); sw.WriteLine(ucstore.SuggestedMethodsforFactory); sw.WriteLine("=========================================================="); } sw.WriteLine("Generted factory methods for this type: "); sw.WriteLine("========================================"); foreach (var facMethodList in pmd.PexGeneratedFactories.Values) { foreach (string factoryMethod in facMethodList) { sw.WriteLine(factoryMethod); } } } //Dumping the contents of factory suggestion store var fssdebugstore = Path.Combine(PexMeConstants.PexMeStorageDirectory, pmd.AssemblyName + ".fssdebug.txt"); using (StreamWriter sw = new StreamWriter(fssdebugstore)) { foreach (var fss in pmd.FactorySuggestionsDictionary.Values) { sw.WriteLine("=================================================="); sw.WriteLine("Records of explorable type: \"" + fss.DeclaringType + "\""); foreach (var codelockey in fss.locationStoreSpecificSequences.Keys) { sw.WriteLine("Key: \"" + codelockey + "\""); var pucls = fss.locationStoreSpecificSequences[codelockey]; sw.WriteLine("Dormant status: " + pucls.IsDormat()); if (pucls.IsDormat()) sw.WriteLine("Associated PUT: " + pucls.AssociatedPUTName); sw.WriteLine("Suggested Sequences........"); foreach (var seq in pucls.SuggestedMethodSequences) { sw.WriteLine(seq); sw.WriteLine(); } } sw.WriteLine("=================================================="); sw.WriteLine("Final suggested sequences"); foreach (var mkey in fss.FinalSuggestedMethodSequences.Keys) { sw.WriteLine("Suggested sequences for the method " + mkey + ":"); var value = fss.FinalSuggestedMethodSequences[mkey]; sw.WriteLine(value.ToString()); sw.WriteLine(); } sw.WriteLine("=================================================="); sw.WriteLine("PUT specific sequences"); foreach (var mkey in fss.FinalPUTSequences.Keys) { sw.WriteLine("Suggested sequences for the PUT " + mkey + ":"); var value = fss.FinalPUTSequences[mkey]; sw.WriteLine(value.ToString()); sw.WriteLine(); } sw.WriteLine("=================================================="); sw.WriteLine("Defect detecting sequences"); foreach (var seq in fss.DefectDetectingSequences) { sw.WriteLine(seq); } sw.WriteLine("=================================================="); sw.WriteLine("All given up locations (Permanent)"); foreach (var loc in fss.PermanentFailedUncoveredLocations) { sw.Write(loc.ToString()); if (fss.UncoveredSystemLibLocations.Contains(loc)) sw.Write(" ( SystemLib )"); sw.WriteLine(); } sw.WriteLine("All given up locations (Temporary)"); foreach (var loc in fss.TemporaryFailedUncoveredLocations.Keys) { sw.WriteLine(loc.ToString() + ", Attempt: " + fss.TemporaryFailedUncoveredLocations[loc]); } sw.WriteLine("=================================================="); sw.WriteLine("All successful locations"); foreach (var loc in fss.SuccessfulCoveredLocations) { sw.WriteLine(loc.ToString()); } } } /******************** END OF DEBUGGING INFO ***********************/ }