fix: resolve Client.Java + Worker.Tests findings (pending windev verification)
Client.Java-040..048, Worker.Tests-034/035/036. Edits applied on the Mac, which has no JRE and cannot build the x86+MXAccess worker tests; findings are marked In Progress pending gradle + x86 build verification on windev. Do not mark Resolved until verified there.
This commit is contained in:
@@ -980,7 +980,11 @@ public sealed class WorkerPipeSessionTests
|
||||
Task runTask = session.RunAsync(cancellation.Token);
|
||||
await CompleteGatewayHandshakeAsync(pipePair, cancellation.Token);
|
||||
|
||||
DateTimeOffset start = DateTimeOffset.UtcNow;
|
||||
// The heartbeatWait CTS (5s cancel-after) already enforces the timing bound:
|
||||
// if the first heartbeat is not received within 5s, ReadUntilAsync throws
|
||||
// OperationCanceledException and the test fails. A redundant wall-clock
|
||||
// elapsed < 5s assertion would add the same class of flakiness
|
||||
// Workers.Tests-003/004/013/020 corrected elsewhere, so it is omitted here.
|
||||
using CancellationTokenSource heartbeatWait = CancellationTokenSource
|
||||
.CreateLinkedTokenSource(cancellation.Token);
|
||||
heartbeatWait.CancelAfter(TimeSpan.FromSeconds(5));
|
||||
@@ -988,12 +992,8 @@ public sealed class WorkerPipeSessionTests
|
||||
pipePair.GatewayReader,
|
||||
WorkerEnvelope.BodyOneofCase.WorkerHeartbeat,
|
||||
heartbeatWait.Token);
|
||||
TimeSpan elapsed = DateTimeOffset.UtcNow - start;
|
||||
|
||||
Assert.Equal(WorkerEnvelope.BodyOneofCase.WorkerHeartbeat, heartbeat.BodyCase);
|
||||
Assert.True(
|
||||
elapsed < TimeSpan.FromSeconds(5),
|
||||
$"First heartbeat took {elapsed}, expected well under the 30s interval.");
|
||||
|
||||
await SendShutdownAndWaitAsync(pipePair, runTask, cancellation.Token);
|
||||
}
|
||||
|
||||
@@ -1123,6 +1123,36 @@ public sealed class MxAccessCommandExecutorTests
|
||||
Assert.Equal(500, fakeComObject.SetBufferedUpdateIntervalValue);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Verifies that a command with an unknown <see cref="MxCommandKind"/> value returns an
|
||||
/// <see cref="ProtocolStatusCode.InvalidRequest"/> reply whose diagnostic contains "Unsupported".
|
||||
/// This pins the <c>_ => CreateInvalidRequestReply(...)</c> discard arm in
|
||||
/// <c>MxAccessCommandExecutor.Execute</c>: a regression that changed the arm to
|
||||
/// <c>throw</c> would propagate an unhandled exception through <c>WorkerPipeSession</c>
|
||||
/// and no other test would catch it.
|
||||
/// </summary>
|
||||
[Fact]
|
||||
public async Task DispatchAsync_WithUnknownCommandKind_ReturnsInvalidRequestWithUnsupportedDiagnostic()
|
||||
{
|
||||
FakeMxAccessComObjectFactory factory = new(new FakeMxAccessComObject(registerHandle: 999));
|
||||
using StaRuntime runtime = CreateRuntime();
|
||||
using MxAccessStaSession session = new(runtime, factory, new NoopEventSink());
|
||||
await session.StartAsync(workerProcessId: 1234);
|
||||
|
||||
// Cast an integer outside the defined MxCommandKind range to an unknown kind value.
|
||||
MxCommandKind unknownKind = (MxCommandKind)int.MaxValue;
|
||||
MxCommandReply reply = await session.DispatchAsync(new StaCommand(
|
||||
"session-1",
|
||||
"unknown-kind-correlation",
|
||||
new MxCommand
|
||||
{
|
||||
Kind = unknownKind,
|
||||
}));
|
||||
|
||||
Assert.Equal(ProtocolStatusCode.InvalidRequest, reply.ProtocolStatus.Code);
|
||||
Assert.Contains("Unsupported", reply.DiagnosticMessage, StringComparison.OrdinalIgnoreCase);
|
||||
}
|
||||
|
||||
private static StaCommand CreateSuspendCommand(
|
||||
string correlationId,
|
||||
int serverHandle,
|
||||
@@ -2229,21 +2259,6 @@ public sealed class MxAccessCommandExecutorTests
|
||||
SetBufferedUpdateIntervalValue = updateIntervalMilliseconds;
|
||||
}
|
||||
|
||||
/// <summary>Status stand-in reflected over by the worker's MxStatusProxy converter.</summary>
|
||||
internal sealed class FakeMxStatus
|
||||
{
|
||||
/// <summary>Success indicator read by the status converter.</summary>
|
||||
public int success;
|
||||
|
||||
/// <summary>Status category read by the status converter.</summary>
|
||||
public int category;
|
||||
|
||||
/// <summary>Status detected-by read by the status converter.</summary>
|
||||
public int detectedBy;
|
||||
|
||||
/// <summary>Status detail read by the status converter.</summary>
|
||||
public int detail;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Factory for creating fake MXAccess COM objects in tests.</summary>
|
||||
|
||||
@@ -94,6 +94,11 @@ internal sealed class NoopMxAccessServer : IMxAccessServer
|
||||
/// <c>success</c>, <c>category</c>, <c>detectedBy</c>, and <c>detail</c>
|
||||
/// fields, so this fake exposes the same field shape with all-OK values.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Previously duplicated as a nested class in <c>MxAccessCommandExecutorTests.FakeMxAccessComObject</c>.
|
||||
/// Consolidated here per Worker.Tests-034 so a future field change to the real COM struct only
|
||||
/// requires updating one place.
|
||||
/// </remarks>
|
||||
internal sealed class FakeMxStatus
|
||||
{
|
||||
// These public fields exist solely so MxStatusProxyConverter can reflect
|
||||
|
||||
Reference in New Issue
Block a user