165 lines
5.4 KiB
C#
165 lines
5.4 KiB
C#
using System;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using MxGateway.Contracts;
|
|
using MxGateway.Worker.Bootstrap;
|
|
using MxGateway.Worker.Ipc;
|
|
|
|
namespace MxGateway.Worker.Tests.Bootstrap;
|
|
|
|
public sealed class WorkerApplicationTests
|
|
{
|
|
[Fact]
|
|
public void Run_WithValidBootstrapArguments_ReturnsSuccessAndLogsRedactedNonce()
|
|
{
|
|
MemoryWorkerEnvironment environment = CreateEnvironment("nonce-secret");
|
|
MemoryWorkerLogger logger = new();
|
|
|
|
int exitCode = MxGateway.Worker.WorkerApplication.Run(
|
|
ValidArgs(),
|
|
environment,
|
|
logger,
|
|
new SucceedingPipeClient());
|
|
|
|
Assert.Equal((int)WorkerExitCode.Success, exitCode);
|
|
Assert.Equal(2, logger.Entries.Count);
|
|
MemoryWorkerLogEntry entry = logger.Entries[0];
|
|
Assert.Equal("Information", entry.Level);
|
|
Assert.Equal("WorkerBootstrapSucceeded", entry.EventName);
|
|
Assert.Equal("session-1", entry.Fields["session_id"]);
|
|
Assert.Equal("mxaccess-gateway-123-session-1", entry.Fields["pipe_name"]);
|
|
Assert.Equal(GatewayContractInfo.WorkerProtocolVersion, entry.Fields["protocol_version"]);
|
|
Assert.Equal("[redacted]", entry.Fields["nonce"]);
|
|
Assert.Equal("WorkerPipeHandshakeSucceeded", logger.Entries[1].EventName);
|
|
}
|
|
|
|
[Fact]
|
|
public void Run_WithMissingRequiredArguments_ReturnsInvalidArguments()
|
|
{
|
|
MemoryWorkerEnvironment environment = CreateEnvironment("nonce-secret");
|
|
MemoryWorkerLogger logger = new();
|
|
|
|
int exitCode = MxGateway.Worker.WorkerApplication.Run(
|
|
[],
|
|
environment,
|
|
logger);
|
|
|
|
Assert.Equal((int)WorkerExitCode.InvalidArguments, exitCode);
|
|
MemoryWorkerLogEntry entry = Assert.Single(logger.Entries);
|
|
Assert.Equal("Error", entry.Level);
|
|
Assert.Equal("WorkerBootstrapFailed", entry.EventName);
|
|
Assert.Equal(WorkerExitCode.InvalidArguments, entry.Fields["exit_code"]);
|
|
}
|
|
|
|
[Fact]
|
|
public void Run_WithInvalidProtocolVersion_ReturnsInvalidProtocolVersion()
|
|
{
|
|
MemoryWorkerEnvironment environment = CreateEnvironment("nonce-secret");
|
|
MemoryWorkerLogger logger = new();
|
|
|
|
int exitCode = MxGateway.Worker.WorkerApplication.Run(
|
|
ValidArgs(protocolVersion: "999"),
|
|
environment,
|
|
logger);
|
|
|
|
Assert.Equal((int)WorkerExitCode.InvalidProtocolVersion, exitCode);
|
|
}
|
|
|
|
[Fact]
|
|
public void Run_WithMissingNonce_ReturnsMissingNonce()
|
|
{
|
|
MemoryWorkerEnvironment environment = new();
|
|
MemoryWorkerLogger logger = new();
|
|
|
|
int exitCode = MxGateway.Worker.WorkerApplication.Run(
|
|
ValidArgs(),
|
|
environment,
|
|
logger);
|
|
|
|
Assert.Equal((int)WorkerExitCode.MissingNonce, exitCode);
|
|
}
|
|
|
|
[Fact]
|
|
public void Run_WithPipeProtocolFailure_ReturnsProtocolViolation()
|
|
{
|
|
MemoryWorkerEnvironment environment = CreateEnvironment("nonce-secret");
|
|
MemoryWorkerLogger logger = new();
|
|
|
|
int exitCode = MxGateway.Worker.WorkerApplication.Run(
|
|
ValidArgs(),
|
|
environment,
|
|
logger,
|
|
new ThrowingPipeClient(new WorkerFrameProtocolException(
|
|
WorkerFrameProtocolErrorCode.NonceMismatch,
|
|
"Bad nonce.")));
|
|
|
|
Assert.Equal((int)WorkerExitCode.ProtocolViolation, exitCode);
|
|
Assert.Equal("WorkerPipeProtocolFailure", logger.Entries[1].EventName);
|
|
}
|
|
|
|
[Fact]
|
|
public void Run_WithUnexpectedBootstrapFailure_ReturnsUnexpectedFailure()
|
|
{
|
|
MemoryWorkerEnvironment environment = new(new InvalidOperationException("environment failed"));
|
|
MemoryWorkerLogger logger = new();
|
|
|
|
int exitCode = MxGateway.Worker.WorkerApplication.Run(
|
|
ValidArgs(),
|
|
environment,
|
|
logger);
|
|
|
|
Assert.Equal((int)WorkerExitCode.UnexpectedFailure, exitCode);
|
|
MemoryWorkerLogEntry entry = Assert.Single(logger.Entries);
|
|
Assert.Equal("WorkerBootstrapUnexpectedFailure", entry.EventName);
|
|
Assert.Equal(WorkerExitCode.UnexpectedFailure, entry.Fields["exit_code"]);
|
|
Assert.Equal(typeof(InvalidOperationException).FullName, entry.Fields["exception_type"]);
|
|
}
|
|
|
|
private static string[] ValidArgs(string? protocolVersion = null)
|
|
{
|
|
return
|
|
[
|
|
"--session-id",
|
|
"session-1",
|
|
"--pipe-name",
|
|
"mxaccess-gateway-123-session-1",
|
|
"--protocol-version",
|
|
protocolVersion ?? GatewayContractInfo.WorkerProtocolVersion.ToString(),
|
|
];
|
|
}
|
|
|
|
private static MemoryWorkerEnvironment CreateEnvironment(string nonce)
|
|
{
|
|
MemoryWorkerEnvironment environment = new();
|
|
environment.Set(WorkerOptions.NonceEnvironmentVariableName, nonce);
|
|
return environment;
|
|
}
|
|
|
|
private sealed class SucceedingPipeClient : IWorkerPipeClient
|
|
{
|
|
public Task RunAsync(
|
|
WorkerOptions options,
|
|
CancellationToken cancellationToken = default)
|
|
{
|
|
return Task.CompletedTask;
|
|
}
|
|
}
|
|
|
|
private sealed class ThrowingPipeClient : IWorkerPipeClient
|
|
{
|
|
private readonly Exception _exception;
|
|
|
|
public ThrowingPipeClient(Exception exception)
|
|
{
|
|
_exception = exception;
|
|
}
|
|
|
|
public Task RunAsync(
|
|
WorkerOptions options,
|
|
CancellationToken cancellationToken = default)
|
|
{
|
|
throw _exception;
|
|
}
|
|
}
|
|
}
|