Add a test pinning down the parallel Markdown conversion

This commit is contained in:
Thorsten Sommer 2026-09-14 17:37:48 +02:00
parent 7d8310731a
commit 1c08b4a252
Signed by untrusted user who does not match committer: tsommer
GPG Key ID: 371BBA77A02C0108

View File

@ -38,27 +38,16 @@ public sealed class HTMLParserConcurrencyTests
// overlap for this test to mean anything, and only starting them together makes that
// certain.
//
// What a thread works with is handed over when it starts rather than captured. The barrier
// is disposed at the end of this method, and while the joins below make sure no thread is
// still at it by then, that is nothing one can see from inside a lambda.
//
using var startSignal = new Barrier(THREAD_COUNT);
var threads = new List<Thread>(THREAD_COUNT);
for (var threadIndex = 0; threadIndex < THREAD_COUNT; threadIndex++)
{
var thread = new Thread(() =>
{
startSignal.SignalAndWait();
for (var conversion = 0; conversion < CONVERSIONS_PER_THREAD; conversion++)
{
try
{
results.Add(HTMLParser.ParseToMarkdown(html));
}
catch (Exception exception)
{
failures.Add(exception);
}
}
});
thread.Start();
var thread = new Thread(ConvertRepeatedly);
thread.Start(new ConversionRun(startSignal, html, results, failures));
threads.Add(thread);
}
@ -75,6 +64,27 @@ public sealed class HTMLParserConcurrencyTests
});
}
/// <summary>
/// Converts the same page over and over, once every thread has arrived at the barrier.
/// </summary>
private static void ConvertRepeatedly(object? state)
{
var run = (ConversionRun)state!;
run.StartSignal.SignalAndWait();
for (var conversion = 0; conversion < CONVERSIONS_PER_THREAD; conversion++)
{
try
{
run.Results.Add(HTMLParser.ParseToMarkdown(run.Html));
}
catch (Exception exception)
{
run.Failures.Add(exception);
}
}
}
/// <summary>
/// Builds a page out of the elements the reported stack traces named.
/// </summary>
@ -118,4 +128,9 @@ public sealed class HTMLParserConcurrencyTests
return string.Concat(Enumerable.Repeat(BLOCK, 20));
}
/// <summary>
/// Everything one thread of this test needs, so that it is passed rather than captured.
/// </summary>
private sealed record ConversionRun(Barrier StartSignal, string Html, ConcurrentBag<string> Results, ConcurrentBag<Exception> Failures);
}