54 lines
2.8 KiB
C#
54 lines
2.8 KiB
C#
using Lumi.Companion.Abstractions;
|
|
using Lumi.Companion.Core;
|
|
|
|
static void Assert(bool condition, string message)
|
|
{
|
|
if (!condition) throw new InvalidOperationException(message);
|
|
}
|
|
|
|
var operation = new SingleFlightOperation();
|
|
var calls = 0;
|
|
await operation.RunAsync(_ => { calls += 1; return Task.CompletedTask; });
|
|
Assert(calls == 1 && !operation.IsRunning, "A successful update-style operation did not reset.");
|
|
|
|
await operation.RunAsync(_ => { calls += 1; return Task.CompletedTask; });
|
|
Assert(calls == 2 && !operation.IsRunning, "A no-update-style repeat did not execute.");
|
|
|
|
try
|
|
{
|
|
await operation.RunAsync(_ => throw new InvalidOperationException("expected"));
|
|
}
|
|
catch (InvalidOperationException error) when (error.Message == "expected") { }
|
|
await operation.RunAsync(_ => { calls += 1; return Task.CompletedTask; });
|
|
Assert(calls == 3 && !operation.IsRunning, "A failed operation left stale single-flight state.");
|
|
|
|
using (var cancelled = new CancellationTokenSource())
|
|
{
|
|
cancelled.Cancel();
|
|
try { await operation.RunAsync(token => Task.Delay(1, token), cancelled.Token); }
|
|
catch (OperationCanceledException) { }
|
|
}
|
|
await operation.RunAsync(_ => { calls += 1; return Task.CompletedTask; });
|
|
Assert(calls == 4 && !operation.IsRunning, "A cancelled operation left stale single-flight state.");
|
|
|
|
var release = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously);
|
|
var concurrentCalls = 0;
|
|
var first = operation.RunAsync(async _ => { concurrentCalls += 1; await release.Task; });
|
|
var second = operation.RunAsync(async _ => { concurrentCalls += 1; await Task.Yield(); });
|
|
Assert(operation.IsRunning && concurrentCalls == 1, "Rapid update checks started more than one operation.");
|
|
release.SetResult();
|
|
await Task.WhenAll(first, second);
|
|
Assert(concurrentCalls == 1 && !operation.IsRunning, "Rapid update checks did not share and reset the active operation.");
|
|
|
|
var sanitized = CompanionLogSanitizer.Sanitize(
|
|
"LumiDevice device-id.private-device-secret Authorization=private-value https://lumi.test/?token=private-token Cookie: session=private-cookie"
|
|
);
|
|
Assert(!sanitized.Contains("private-value"), "Companion logs retained an authorization value.");
|
|
Assert(!sanitized.Contains("private-cookie"), "Companion logs retained a cookie.");
|
|
Assert(!sanitized.Contains("private-token"), "Companion logs retained a query token.");
|
|
Assert(!sanitized.Contains("private-device-secret"), "Companion logs retained a paired-device credential.");
|
|
Assert(CompanionLogSanitizer.NormalizeEvent("Update Failed!") == "update_failed", "Companion event normalization drifted.");
|
|
Assert(CompanionLogSanitizer.LevelForEvent("update_failed") == "error", "Companion failed events must use the error level.");
|
|
|
|
Console.WriteLine("Companion core single-flight and logging regression checks passed.");
|