feat(gateway): forward operator credentials on alarm acknowledgement

Claude-Session: https://claude.ai/code/session_016J6isfcgqy4SB2RK3ZvFvT
This commit is contained in:
Joseph Doherty
2026-10-19 19:40:23 -04:00
parent d6db0ff40d
commit 2858e42e80
13 changed files with 192 additions and 5 deletions
@@ -22,6 +22,7 @@ public sealed class WorkerProcessLauncherTests
WorkerLaunchEnvironment.EventQueueCapacity,
WorkerLaunchEnvironment.AlarmPollIntervalMilliseconds,
WorkerLaunchEnvironment.MaxAlarmsPerFetch,
WorkerLaunchEnvironment.AlarmAckClientName,
];
/// <summary>Verifies that a valid worker executable starts with correct bootstrap arguments and nonce environment variable.</summary>
@@ -75,6 +76,10 @@ public sealed class WorkerProcessLauncherTests
"1024",
processFactory.LastStartInfo.Environment[
WorkerLaunchEnvironment.MaxAlarmsPerFetch]);
Assert.Equal(
"MxGateway",
processFactory.LastStartInfo.Environment[
WorkerLaunchEnvironment.AlarmAckClientName]);
Assert.All(
RequiredLaunchEnvironmentVariables,
variable => Assert.True(
@@ -86,6 +91,28 @@ public sealed class WorkerProcessLauncherTests
Assert.Equal(0, metrics.GetSnapshot().WorkersRunning);
}
/// <summary>Verifies a configured AckClientName reaches the worker environment.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task LaunchAsync_WithConfiguredAckClientName_ExportsItToTheWorkerEnvironment()
{
using TestDirectory directory = TestDirectory.Create();
string executablePath = directory.CreateWorkerExecutable(machine: 0x014c);
FakeWorkerProcessFactory processFactory = new(new FakeWorkerProcess(processId: 1234));
WorkerProcessLauncher launcher = CreateLauncher(
executablePath,
processFactory,
new SucceedingStartupProbe(),
ackClientName: "Plant-Ack");
using WorkerProcessHandle handle = await launcher.LaunchAsync(CreateRequest());
Assert.NotNull(processFactory.LastStartInfo);
Assert.Equal(
"Plant-Ack",
processFactory.LastStartInfo.Environment[WorkerLaunchEnvironment.AlarmAckClientName]);
}
/// <summary>
/// Verifies that a configured <see cref="WorkerOptions.EventQueueCapacity"/> — not the shipped
/// default — is what reaches the worker, so the option is deployable without a worker rebuild.
@@ -265,10 +292,12 @@ public sealed class WorkerProcessLauncherTests
int startupTimeoutSeconds = 30,
int startupProbeRetryAttempts = 3,
int startupProbeRetryDelayMilliseconds = 250,
int eventQueueCapacity = 10000)
int eventQueueCapacity = 10000,
string ackClientName = "MxGateway")
{
GatewayOptions options = new()
{
Alarms = new AlarmsOptions { AckClientName = ackClientName },
Worker = new WorkerOptions
{
ExecutablePath = executablePath,