Skip to content

Commit c308856

Browse files
committed
Adding prereq check for SANO
1 parent 4ffa0cd commit c308856

1 file changed

Lines changed: 87 additions & 0 deletions

File tree

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
package io.temporal.workflow.shared;
2+
3+
import io.grpc.Status;
4+
import io.grpc.StatusRuntimeException;
5+
import io.temporal.api.workflowservice.v1.CountNexusOperationExecutionsRequest;
6+
import io.temporal.serviceclient.WorkflowServiceStubs;
7+
import io.temporal.serviceclient.WorkflowServiceStubsOptions;
8+
import io.temporal.testing.internal.SDKTestWorkflowRule;
9+
import org.junit.Assume;
10+
11+
/**
12+
* Skip-guard for tests that exercise standalone Nexus operation RPCs ({@code
13+
* StartNexusOperationExecution}, {@code DescribeNexusOperationExecution}, etc.). Call from
14+
* {@code @BeforeClass}.
15+
*
16+
* <p>{@link SDKTestWorkflowRule#useExternalService} only tells us that an external server is
17+
* reachable — not that it implements every RPC we want to call. The Temporal CLI's {@code
18+
* start-dev} server (which CI uses for the "Unit test with CLI" job) accepts connections but
19+
* returns {@code UNIMPLEMENTED} for the standalone Nexus RPCs. Hitting that mid-test produces a
20+
* confusing failure; this guard probes the server once and skips the suite cleanly if the RPCs
21+
* aren't wired through.
22+
*
23+
* <p>Suites are skipped via {@link Assume#assumeTrue} when:
24+
*
25+
* <ul>
26+
* <li>the rule is using the in-memory test server ({@code USE_EXTERNAL_SERVICE} unset/false), or
27+
* <li>the configured external server returns {@code UNIMPLEMENTED} for a standalone Nexus RPC.
28+
* </ul>
29+
*/
30+
public final class StandaloneNexusTestPrerequisites {
31+
32+
private static volatile Boolean cachedServerSupportsStandaloneNexus;
33+
private static final Object PROBE_LOCK = new Object();
34+
35+
private StandaloneNexusTestPrerequisites() {}
36+
37+
/**
38+
* Skips the calling suite if the configured server doesn't support standalone Nexus RPCs. Probes
39+
* the server at most once per JVM and caches the outcome.
40+
*/
41+
public static void requireServerSupport() {
42+
Assume.assumeTrue(
43+
"standalone Nexus operations require an external server (USE_EXTERNAL_SERVICE=true)",
44+
SDKTestWorkflowRule.useExternalService);
45+
Assume.assumeTrue(
46+
"configured external server does not implement standalone Nexus RPCs",
47+
probeServerSupport());
48+
}
49+
50+
private static boolean probeServerSupport() {
51+
Boolean cached = cachedServerSupportsStandaloneNexus;
52+
if (cached != null) {
53+
return cached;
54+
}
55+
synchronized (PROBE_LOCK) {
56+
if (cachedServerSupportsStandaloneNexus != null) {
57+
return cachedServerSupportsStandaloneNexus;
58+
}
59+
cachedServerSupportsStandaloneNexus = probeOnce();
60+
return cachedServerSupportsStandaloneNexus;
61+
}
62+
}
63+
64+
private static boolean probeOnce() {
65+
String address = System.getenv("TEMPORAL_SERVICE_ADDRESS");
66+
if (address == null || address.isEmpty()) {
67+
address = "127.0.0.1:7233";
68+
}
69+
WorkflowServiceStubs stubs =
70+
WorkflowServiceStubs.newServiceStubs(
71+
WorkflowServiceStubsOptions.newBuilder().setTarget(address).build());
72+
try {
73+
stubs
74+
.blockingStub()
75+
.countNexusOperationExecutions(
76+
CountNexusOperationExecutionsRequest.newBuilder().setNamespace("default").build());
77+
return true;
78+
} catch (StatusRuntimeException e) {
79+
// UNIMPLEMENTED is the only status that tells us the RPC method isn't wired through. Every
80+
// other status (NOT_FOUND for an absent namespace, INVALID_ARGUMENT, PERMISSION_DENIED, etc.)
81+
// proves the method exists on the server even if this particular call was rejected.
82+
return e.getStatus().getCode() != Status.Code.UNIMPLEMENTED;
83+
} finally {
84+
stubs.shutdownNow();
85+
}
86+
}
87+
}

0 commit comments

Comments
 (0)