public (bool Success, string Report) CreateResults(int numThreads, int actionsPerThread) { string report; bool success = true; StringBuilder sbLog = new StringBuilder(); StringBuilder sbEntries = new StringBuilder(); SortedSet <int> threadIds = new SortedSet <int>(Entries.Select(entry => entry.ManagedThreadId).Distinct()); var managedThreadIdAndExpectedEntries = new SortedDictionary <int, int>((from id in threadIds let key = id let value = actionsPerThread select new KeyValuePair <int, int>(key, value)).ToDictionary(kvp => kvp.Key, kvp => kvp.Value)); var setifiedRes = SetifyTextResultsAndValidateLength(); Console.WriteLine(); Console.WriteLine( $"Setified ok: [{setifiedRes.Ok}], Entries ({setifiedRes.Set.Count}) matches product ({numThreads * actionsPerThread}): {setifiedRes.Set.Count == numThreads * actionsPerThread}; Text res length: [{TextResult.Length}]; Validated Length: [{setifiedRes.ValidatedSize}]."); Console.WriteLine($"Done writing setification info. {Environment.NewLine}"); if (managedThreadIdAndExpectedEntries.Count != numThreads) { success = false; sbLog.AppendLine($"FAILURE. There were missing thread ids from the entries. Expected {numThreads} thread ids but only found the following thread ids:"); foreach (var item in managedThreadIdAndExpectedEntries.Keys) { sbLog.AppendLine($"Thread id: {item}"); } sbLog.AppendLine("Listing all entries: "); Entries.ApplyToAll(entr => sbLog.AppendLine(entr.ToString())); sbLog.AppendLine(); sbLog.AppendLine("Logging text output: "); sbLog.AppendLine(TextResult); sbLog.AppendLine("Done logging FAILED simulation."); report = sbLog.ToString(); } else { try { foreach (StressTestEntry entry in Entries) { if (managedThreadIdAndExpectedEntries.ContainsKey(entry.ManagedThreadId)) { if (FindMatchingText(in entry, setifiedRes.Set, sbLog)) { managedThreadIdAndExpectedEntries[entry.ManagedThreadId] = managedThreadIdAndExpectedEntries[entry.ManagedThreadId] - 1; sbEntries.AppendLine(entry.ToString()); } else { success = false; } } else { sbLog.AppendLine( $"Unable to find managed thread id [{entry.ManagedThreadId}] while reading entry: [{entry.ToString()}]."); success = false; } } if (success) { var threadIdsMissingEntries = managedThreadIdAndExpectedEntries.Where(kvp => kvp.Value > 0) .Select(kvp => kvp.Key).ToImmutableSortedSet(); if (threadIdsMissingEntries.Any()) { success = false; foreach (var item in threadIdsMissingEntries) { sbLog.AppendLine( $"There remain {managedThreadIdAndExpectedEntries[item]} entries unaccounted for for managed thread id: [{item}]."); } sbLog.AppendLine("Logging entries: "); sbLog.Append(sbEntries); sbLog.AppendLine(); sbLog.AppendLine("Logging text output: "); sbLog.AppendLine(TextResult); sbLog.AppendLine(); sbLog.AppendLine(); sbLog.AppendLine("Done logging FAILED simulation."); report = sbLog.ToString(); } else { if (numThreads * actionsPerThread != Entries.Count) { throw new InvalidOperationException( $"Expected number of entries to be ({nameof(numThreads)} * {nameof(actionsPerThread)}) [{numThreads} * {actionsPerThread} == {numThreads * actionsPerThread}]; actual: [{Entries.Count}]."); } sbLog.AppendLine( $"Simulation SUCCESSFUL. Found {actionsPerThread} entries for each of the {numThreads} threads."); sbLog.AppendLine($"Logging {Entries.Count} ({nameof(numThreads)} - val: {numThreads} * {nameof(actionsPerThread)} - val: {actionsPerThread} == {numThreads * actionsPerThread}) entries: "); sbLog.Append(sbEntries); sbLog.AppendLine(); sbLog.AppendLine("Logging text output: "); sbLog.Append(TextResult); sbLog.AppendLine(); sbLog.AppendLine("END TEXT LOG"); string timestampOnly = GetEntriesByOrderedOnlyByTimeStamp(); sbLog.AppendLine(timestampOnly); sbLog.AppendLine(); sbLog.AppendLine("DONE SUCCESSFUL SIM LOGGING."); report = sbLog.ToString(); } } else { sbEntries.Clear(); Entries.ApplyToAll(entry => sbEntries.AppendLine(entry.ToString())); sbLog.AppendLine("SIMULATION FAILED -- MISSING TEXT FOR ONE OR MORE ENTRIES."); sbLog.AppendLine("Logging all entries:"); sbLog.Append(sbEntries); sbLog.AppendLine(); sbLog.AppendLine("Logging text output: "); sbLog.AppendLine(TextResult); sbLog.AppendLine("DONE LOGGING FAILED SIMULATION"); report = sbLog.ToString(); } }