test(java-cli): cover stream-events over in-process harness
This commit is contained in:
+78
@@ -5,6 +5,7 @@ import static org.junit.jupiter.api.Assertions.assertFalse;
|
|||||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
|
|
||||||
import com.zb.mom.ww.mxgateway.client.MxGatewayAlarmFeedSubscription;
|
import com.zb.mom.ww.mxgateway.client.MxGatewayAlarmFeedSubscription;
|
||||||
|
import com.zb.mom.ww.mxgateway.client.MxGatewayClient;
|
||||||
import com.zb.mom.ww.mxgateway.client.MxGatewayClientOptions;
|
import com.zb.mom.ww.mxgateway.client.MxGatewayClientOptions;
|
||||||
import galaxy_repository.v1.GalaxyRepositoryOuterClass.GalaxyObject;
|
import galaxy_repository.v1.GalaxyRepositoryOuterClass.GalaxyObject;
|
||||||
import io.grpc.stub.StreamObserver;
|
import io.grpc.stub.StreamObserver;
|
||||||
@@ -31,6 +32,7 @@ import mxaccess_gateway.v1.MxaccessGateway.CloseSessionRequest;
|
|||||||
import mxaccess_gateway.v1.MxaccessGateway.MxCommandKind;
|
import mxaccess_gateway.v1.MxaccessGateway.MxCommandKind;
|
||||||
import mxaccess_gateway.v1.MxaccessGateway.MxCommandReply;
|
import mxaccess_gateway.v1.MxaccessGateway.MxCommandReply;
|
||||||
import mxaccess_gateway.v1.MxaccessGateway.MxEvent;
|
import mxaccess_gateway.v1.MxaccessGateway.MxEvent;
|
||||||
|
import mxaccess_gateway.v1.MxaccessGateway.MxEventFamily;
|
||||||
import mxaccess_gateway.v1.MxaccessGateway.MxValue;
|
import mxaccess_gateway.v1.MxaccessGateway.MxValue;
|
||||||
import mxaccess_gateway.v1.MxaccessGateway.OnAlarmTransitionEvent;
|
import mxaccess_gateway.v1.MxaccessGateway.OnAlarmTransitionEvent;
|
||||||
import mxaccess_gateway.v1.MxaccessGateway.OpenSessionReply;
|
import mxaccess_gateway.v1.MxaccessGateway.OpenSessionReply;
|
||||||
@@ -693,6 +695,60 @@ final class MxGatewayCliTests {
|
|||||||
+ " out=\n" + run.output() + "\nerr=\n" + run.errors());
|
+ " out=\n" + run.output() + "\nerr=\n" + run.errors());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void streamEventsRendersScriptedEventsIncludingHighUint64Sequence() {
|
||||||
|
// Drive the REAL MxGatewayClient / MxGatewaySession / MxEventStream
|
||||||
|
// path over the in-process harness (Task 4), so the production
|
||||||
|
// stream-events command exercises the real streaming wrapper instead
|
||||||
|
// of a hand-written FakeSession seam.
|
||||||
|
//
|
||||||
|
// The high worker-sequence (-1L == 18446744073709551615 unsigned)
|
||||||
|
// covers the unsigned-rendering regression: worker_sequence is a
|
||||||
|
// proto uint64 carried as a Java long with the top bit set. The CLI's
|
||||||
|
// --json path renders it through protobuf's JsonFormat, which prints
|
||||||
|
// uint64 as an unsigned decimal STRING; a naive %d render would print
|
||||||
|
// a negative number instead.
|
||||||
|
MxEvent dataChange = MxEvent.newBuilder()
|
||||||
|
.setFamily(MxEventFamily.MX_EVENT_FAMILY_ON_DATA_CHANGE)
|
||||||
|
.setSessionId("session-cli")
|
||||||
|
.setServerHandle(7)
|
||||||
|
.setItemHandle(42)
|
||||||
|
.setWorkerSequence(5L)
|
||||||
|
.build();
|
||||||
|
MxEvent highSequence = MxEvent.newBuilder()
|
||||||
|
.setFamily(MxEventFamily.MX_EVENT_FAMILY_OPERATION_COMPLETE)
|
||||||
|
.setSessionId("session-cli")
|
||||||
|
.setServerHandle(9)
|
||||||
|
.setItemHandle(99)
|
||||||
|
// -1L unsigned == 18446744073709551615 (top bit set).
|
||||||
|
.setWorkerSequence(-1L)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
try (InProcessGatewayHarness harness = new InProcessGatewayHarness()) {
|
||||||
|
harness.setScriptedEvents(List.of(dataChange, highSequence));
|
||||||
|
CliRun run = execute(
|
||||||
|
new HarnessClientFactory(harness),
|
||||||
|
"stream-events",
|
||||||
|
"--session-id",
|
||||||
|
"session-cli",
|
||||||
|
"--json");
|
||||||
|
|
||||||
|
assertEquals(0, run.exitCode(), "errors:\n" + run.errors());
|
||||||
|
String out = run.output();
|
||||||
|
// Scripted event fields surface in the JSON render.
|
||||||
|
assertTrue(out.contains("\"family\":\"MX_EVENT_FAMILY_ON_DATA_CHANGE\""), out);
|
||||||
|
assertTrue(out.contains("\"family\":\"MX_EVENT_FAMILY_OPERATION_COMPLETE\""), out);
|
||||||
|
assertTrue(out.contains("\"serverHandle\":7"), out);
|
||||||
|
assertTrue(out.contains("\"itemHandle\":42"), out);
|
||||||
|
// The low sequence renders as the unsigned decimal string "5".
|
||||||
|
assertTrue(out.contains("\"workerSequence\":\"5\""), out);
|
||||||
|
// The high sequence renders as the FULL unsigned decimal, not -1.
|
||||||
|
assertTrue(out.contains("\"workerSequence\":\"18446744073709551615\""), out);
|
||||||
|
assertFalse(out.contains("\"workerSequence\":\"-1\""), out);
|
||||||
|
assertFalse(out.contains("\"workerSequence\":-1"), out);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void batchCommandExecutesVersionAndEmitsEorMarker() {
|
void batchCommandExecutesVersionAndEmitsEorMarker() {
|
||||||
CliRun run = executeBatch(new FakeClientFactory(), "version --json\n");
|
CliRun run = executeBatch(new FakeClientFactory(), "version --json\n");
|
||||||
@@ -849,6 +905,28 @@ final class MxGatewayCliTests {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Factory that wires the production {@link MxGatewayCli.GrpcMxGatewayCliClient}
|
||||||
|
* adapter around the harness's REAL {@link MxGatewayClient}, so the
|
||||||
|
* stream-events command runs against the in-process scripted gateway over
|
||||||
|
* a real channel (exercising the real {@code MxEventStream}). Mirrors the
|
||||||
|
* production {@code GrpcMxGatewayCliClientFactory}, swapping only the
|
||||||
|
* client construction for the harness-backed client.
|
||||||
|
*/
|
||||||
|
private static final class HarnessClientFactory implements MxGatewayCli.MxGatewayCliClientFactory {
|
||||||
|
private final InProcessGatewayHarness harness;
|
||||||
|
|
||||||
|
private HarnessClientFactory(InProcessGatewayHarness harness) {
|
||||||
|
this.harness = harness;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MxGatewayCli.MxGatewayCliClient connect(MxGatewayCli.CommonOptions options) {
|
||||||
|
return new MxGatewayCli.GrpcMxGatewayCliClient(
|
||||||
|
harness.gatewayClient(), options.spec.commandLine().getOut());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static final class OverflowingFakeClient implements MxGatewayCli.MxGatewayCliClient {
|
private static final class OverflowingFakeClient implements MxGatewayCli.MxGatewayCliClient {
|
||||||
private final PrintWriter out;
|
private final PrintWriter out;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user