Java: Add InProcess FFI transport E2E test (task 4.8) - #2238
Conversation
Co-authored-by: edburns <75821+edburns@users.noreply.github.com>
This comment has been minimized.
This comment has been minimized.
edburns
left a comment
There was a problem hiding this comment.
@copilot Please fix the following CI failure:
CI Failure: InProcessTransportIT fails without -Pinprocess profile
The InProcessTransportIT test runs in standard CI (mvn verify without -Pinprocess) and fails because the copilot-sdk-java-runtime:linux-x64 classifier JAR is only added as a dependency in the -Pinprocess profile, so native/linux-x64/runtime.node is not on the classpath.
java.io.FileNotFoundException: Native runtime not found on classpath: native/linux-x64/runtime.node — add the matching classifier JAR to the classpath
Fix: The InProcessTransportIT test should only run when the -Pinprocess profile is active. Add a JUnit 5 condition that checks for COPILOT_SDK_DEFAULT_CONNECTION=inprocess (set by the -Pinprocess profile) and disables the test otherwise. You could:
- Add
@DisabledIfEnvironmentVariable(named = "COPILOT_SDK_DEFAULT_CONNECTION", matches = "(?!inprocess).*", disabledReason = "Requires -Pinprocess profile")or - Create a custom condition annotation (the inverse of
@SkipInProcess) that enables only whenCOPILOT_SDK_DEFAULT_CONNECTION=inprocess, or - Use
org.junit.jupiter.api.Assumptions.assumeTrue("inprocess".equals(System.getenv("COPILOT_SDK_DEFAULT_CONNECTION")))at the start of the test.
The simplest approach is option 3 with assumeTrue in a @BeforeAll method.
Co-authored-by: edburns <75821+edburns@users.noreply.github.com>
Fixed in d49df45 (pushed as new commit): added a |
This comment has been minimized.
This comment has been minimized.
edburns
left a comment
There was a problem hiding this comment.
@copilot Please fix the following CI failure:
CI Failure: Spotless formatting violation in RequireInProcess.java (JDK 25)
[ERROR] Failed to execute goal com.diffplug.spotless:spotless-maven-plugin:2.46.1:check on project copilot-sdk-java:
[ERROR] src/test/java/com/github/copilot/e2e/RequireInProcess.java
The Javadoc line wrapping does not match the Eclipse formatter output. The formatter wants to reflow some Javadoc lines.
Fix: Run mvn spotless:apply from java/sdk and commit the reformatted RequireInProcess.java.
Co-authored-by: edburns <75821+edburns@users.noreply.github.com>
Fixed by running |
This comment has been minimized.
This comment has been minimized.
There was a problem hiding this comment.
Pull request overview
Adds Java InProcess FFI test infrastructure and native runtime resolution support.
Changes:
- Adds InProcess environment guards and test conditions.
- Adds an InProcess Failsafe integration test and Maven profile.
- Supports npm
prebuilds/<classifier>/runtime.nodelayouts.
Show a summary per file
| File | Description |
|---|---|
NativeRuntimeLoader.java |
Resolves nested npm runtime binaries. |
NativeRuntimeLoaderTest.java |
Tests nested resolution and precedence. |
InProcessEnvGuard.java |
Mutates native process environment. |
InProcessTransportIT.java |
Exercises InProcess startup and ping. |
SkipInProcess.java |
Adds an InProcess exclusion annotation. |
RequireInProcess.java |
Adds an InProcess requirement annotation. |
pom.xml |
Adds the InProcess test profile and runtime dependency. |
Review details
- Files reviewed: 7/7 changed files
- Comments generated: 4
- Review effort level: Balanced
…cope Surefire in -Pinprocess profile, fix Javadoc - InProcessEnvGuard now reads previous env values via native getenv/ GetEnvironmentVariableW instead of System.getenv() JVM snapshot, and correctly distinguishes absent variables from empty ones. - The -Pinprocess Maven profile no longer overrides Surefire configuration, leaving existing unit tests on their standard transport. - Javadoc corrected to point contributors to the java reactor root. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This comment has been minimized.
This comment has been minimized.
There was a problem hiding this comment.
Review details
Suppressed comments (1)
java/sdk/src/test/java/com/github/copilot/ffi/InProcessEnvGuard.java:142
- On Windows, a zero return from
GetEnvironmentVariableWalso represents a variable that exists with an empty value; onlyGetLastError()==ERROR_ENVVAR_NOT_FOUNDmeans absent. Treating every zero asnullmeans the guard still restores an originally empty variable as unset, contrary to its save/restore contract. Preserve the Win32 last error through JNA and distinguishERROR_SUCCESS(empty string) fromERROR_ENVVAR_NOT_FOUND(null).
int len = kernel32.GetEnvironmentVariableW(new WString(name), buffer, buffer.length);
if (len == 0) {
// Variable not set (or error — treat as absent)
return null;
- Files reviewed: 7/7 changed files
- Comments generated: 1
- Review effort level: Balanced
Existing ITs set Environment/Cwd options incompatible with InProcess transport. Restrict the profile to only the in-process smoke test until the full in-process E2E suite is implemented. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Cross-SDK Consistency Review ✅This PR brings Java into alignment with all other SDK implementations. The bug fix in
No cross-SDK consistency issues found. The changes maintain feature parity across all implementations.
|
b138ca3
into
edburns/1917-java-embed-rust-cli-runtime-dd-3039924-agentic-run-02
Task 4.8 of the Java "Embed Rust CLI runtime" plan: an E2E integration test exercising the InProcess FFI transport end-to-end with a real
runtime.nodebinary — client connects, pings, disconnects — viaFfiRuntimeHost.New test infrastructure
InProcessEnvGuard— JNA-based utility that mutates the live OS process environment (setenv/SetEnvironmentVariableW) so native code loaded in-process (runtime.node) observes overrides Java'sSystem.getenv()snapshot cannot express.AutoCloseable, restores prior values on close.InProcessTransportIT— Failsafe IT performing apinground-trip overRuntimeConnection.forInProcess(). No replay proxy needed sincepingnever reaches the network, mirroring the Go/Node/Python/Rust InProcess smoke tests.SkipInProcess— JUnit 5 condition annotation to exclude tests incompatible with the InProcess transport (e.g. per-client env vars, see [Tracking] In-process (FFI) items to be cleaned up #1934).-PinprocessMaven profile —forkCount=1,parallel=none(InProcess mutates process-global state),COPILOT_SDK_DEFAULT_CONNECTION=inprocess, and a dedicatedcopilot.inprocess.cli.pathpointing at the real platform CLI binary rather than thenpm-loader.jsdispatcher. Adds a test-scoped dependency on thecopilot-sdk-java-runtime:linux-x64classifier jar as a classpath fallback forruntime.node.Bug fix:
runtime.noderesolutionNativeRuntimeLoader.resolveFromCliPath()only checked for a flatruntime.nodesibling next to the CLI binary. Real@github/copilot-<platform>npm packages ship it nested underprebuilds/<classifier>/runtime.node, so this path never resolved against actual installed packages:Also discovered along the way:
System.getenv()is an immutable JVM-startup snapshot, so nativesetenv()calls made viaInProcessEnvGuardafter the JVM starts cannot affectCOPILOT_CLI_PATHlookups done in Java code — that must be set before the JVM forks (handled via Surefire/Failsafe's<environmentVariables>in the new profile).Tests
Added unit test coverage in
NativeRuntimeLoaderTestfor the newprebuilds/<classifier>/runtime.noderesolution, including precedence over the flat layout when both exist.