test: replace final fixed-delay oracles

This commit is contained in:
Erik 2026-08-18 13:12:26 +02:00
parent ad7ebe9425
commit 79a4489e03
6 changed files with 101 additions and 21 deletions

View file

@ -212,24 +212,44 @@ public sealed class HeadlessPluginSessionTests
Task subscribe = Task.Run(() => host.Events.EntitySpawned += handler);
Assert.True(replayCaptured.Wait(TimeSpan.FromSeconds(10)));
using var registrationStarted = new ManualResetEventSlim();
Task registration = Task.Run(() =>
Exception? registrationError = null;
var registrationThread = new Thread(() =>
{
registrationStarted.Set();
_ = session.Runtime.EntityObjects.RegisterEntity(
Spawn(0x50000002u, 2f));
});
Assert.True(registrationStarted.Wait(TimeSpan.FromSeconds(10)));
try
{
_ = session.Runtime.EntityObjects.RegisterEntity(
Spawn(0x50000002u, 2f));
}
catch (Exception error)
{
registrationError = error;
}
})
{
IsBackground = true,
Name = "Headless plugin concurrent registration contract",
};
registrationThread.Start();
bool registrationStartedInTime = registrationStarted.Wait(
TimeSpan.FromSeconds(10));
bool registrationBlockedOnReplay = registrationStartedInTime &&
SpinWait.SpinUntil(
() => (registrationThread.ThreadState & ThreadState.WaitSleepJoin) != 0,
TimeSpan.FromSeconds(10));
try
{
await Task.Delay(TimeSpan.FromMilliseconds(100));
Assert.False(registration.IsCompleted);
Assert.True(
registrationBlockedOnReplay,
"registration never waited for the active replay read lease");
}
finally
{
releaseReplay.Set();
}
await Task.WhenAll(subscribe, registration)
.WaitAsync(TimeSpan.FromSeconds(10));
await subscribe.WaitAsync(TimeSpan.FromSeconds(10));
Assert.True(registrationThread.Join(TimeSpan.FromSeconds(10)));
Assert.Null(registrationError);
host.Events.EntitySpawned -= handler;
Assert.Equal([1_000_000u, 1_000_001u], observed);

View file

@ -340,6 +340,10 @@ public sealed class LauncherInstallerTests : IDisposable
_bakeExecutable,
recordStore: new LauncherInstallRecordStore(_paths),
processRunner: runnerB);
var leaseContended = new TaskCompletionSource(
TaskCreationOptions.RunContinuationsAsynchronously);
installerB.TransactionLeaseContentionObservedForTest =
() => leaseContended.TrySetResult();
Task<LauncherInstallResult> operationA =
installerA.InstallAsync(_dats, 1);
@ -351,7 +355,8 @@ public sealed class LauncherInstallerTests : IDisposable
_dats,
1,
cancellationToken: cancellationB.Token);
await Task.Delay(150);
await leaseContended.Task.WaitAsync(TimeSpan.FromSeconds(5));
Assert.False(operationB.IsCompleted);
cancellationB.Cancel();
await Assert.ThrowsAnyAsync<OperationCanceledException>(() => operationB);
@ -537,6 +542,7 @@ public sealed class LauncherInstallerTests : IDisposable
orphanPid = int.Parse(
await File.ReadAllTextAsync(childPid),
System.Globalization.CultureInfo.InvariantCulture);
using Process orphan = Process.GetProcessById(orphanPid);
Assert.True(File.Exists(
LauncherInstallRecordStore.GetBackupPath(
store.PreparedAssetPath)));
@ -551,12 +557,16 @@ public sealed class LauncherInstallerTests : IDisposable
_paths,
_bakeExecutable,
recordStore: new LauncherInstallRecordStore(_paths));
var publicationContended = new TaskCompletionSource(
TaskCreationOptions.RunContinuationsAsynchronously);
restarted.PublicationLeaseContentionObservedForTest =
() => publicationContended.TrySetResult();
Task<InstallRecordVerification> recovery =
restarted.LoadExistingAsync();
InstallRecordVerification recovered;
if (schedule == "holds")
{
await Task.Delay(200);
await publicationContended.Task.WaitAsync(TimeSpan.FromSeconds(5));
Assert.False(recovery.IsCompleted);
File.WriteAllText(release, "release");
recovered = await recovery.WaitAsync(TimeSpan.FromSeconds(15));
@ -593,7 +603,7 @@ public sealed class LauncherInstallerTests : IDisposable
await File.ReadAllTextAsync(childExit + ".error"),
StringComparison.OrdinalIgnoreCase);
}
await Task.Delay(200);
await orphan.WaitForExitAsync().WaitAsync(TimeSpan.FromSeconds(15));
Assert.Equal(
canonicalAfterRecovery,