On the C# rewrite, a test case was an ordinary C# source file. The harness loaded it, fed it through CSharpCodeProvider (and later Roslyn's compilation API), produced an in-memory assembly, instantiated the entry-point class, and invoked it against a configured environment:
{`// EncryptedConnectionTest.cs
// compiled by the harness · run inline · no separate build step
using Qualcomm.TestHarness;
using Qualcomm.TestHarness.Server;
[TestCase(
id: "server.tls.handshake.resume",
tags: new[]{ "server", "tls", "handshake", "fast" }
)]
public class EncryptedConnectionTest : ServerTest {
public override void Run(TestContext ctx) {
using var server = ctx.Server.StartFresh();
using var session1 = server.Connect();
session1.PerformHandshake();
var ticket = session1.SessionTicket;
session1.Disconnect();
using var session2 = server.Connect(resumeWith: ticket);
var report = session2.PerformHandshake();
ctx.Assert(report.WasResumed, "second handshake should resume");
ctx.Assert(report.RoundTrips == 1, "resumption is single-RT");
ctx.Record("ms", report.HandshakeMs);
}
}`}
Three things to read here. The [TestCase] attribute is metadata the harness picks up via reflection — id, tags, timeout, dependencies — letting any test be selected, scheduled, or filtered without parsing source. The body of Run has the full C# language surface: using for resource discipline, exceptions for failure propagation, LINQ for assertion construction, the language standard library for everything else. And ctx.Record(...) gives a structured way to emit performance numbers that roll up into the run report — tests aren't just pass/fail, they carry signal.