Skip to content

optimize: refactor mock-server to instance mode with random port support#8121

Open
slievrly wants to merge 15 commits into
apache:2.xfrom
slievrly:2.x_26_06_01_01
Open

optimize: refactor mock-server to instance mode with random port support#8121
slievrly wants to merge 15 commits into
apache:2.xfrom
slievrly:2.x_26_06_01_01

Conversation

@slievrly
Copy link
Copy Markdown
Member

Ⅰ. Describe what this PR did

refactor mock-server to instance mode with random port support

Ⅱ. Does this pull request fix one issue?

Ⅲ. Why don't you add test cases (unit test/integration test)?

Ⅳ. Describe how to verify it

Ⅴ. Special notes for reviews

slievrly and others added 12 commits May 26, 2026 20:34
Set forkCount=2 in server/pom.xml to run test classes across 2 parallel
JVMs. The seata-server module has 80+ test classes that each boot a fresh
Spring Boot context due to @DirtiesContext(BEFORE_CLASS), making it the
slowest module in CI (~5:27). Parallel forking cuts wall-clock time by
~45% without removing @DirtiesContext.

forkCount is kept at 2 (not 1C/4) to avoid port conflicts from Raft
tests that bind hardcoded ports (8091-8093, 9091).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Root cause: ConfigurationTestHelper.putConfig() blocks for 60 seconds
when the file config listener fails to detect system property changes.
This affected every multiversion test setUp/tearDown cycle, adding 60s
of dead wait per test method.

Changes:
- Replace ConfigurationTestHelper.putConfig/removeConfig with direct
  System.setProperty/clearProperty (sufficient since getConfig reads
  system properties with priority)
- Set transport.shutdown.wait=0 in tests to eliminate 13s Thread.sleep
  in NettyServerBootstrap.shutdown()
- Use shutdownGracefully(0, 2, SECONDS) instead of default (2s quiet
  period + 15s timeout) for test event loop groups
- Replace Thread.sleep(3000) in startServerSimple with polling loop
- Add forkCount=2 to seata-test for parallel test execution

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
With forkCount=2, StateMachineDBTests can land in a fork where no
other test triggers ConfigurationTestHelper's static initializer,
leaving service.default.grouplist unset and causing 27 "No available
service" errors. Add an explicit static init block to AbstractServerTest
that loads file.conf via ConfigurationFactory.reload().

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
forkCount=2 causes BranchSessionExecuteTest and LockExecuteTest to run
in separate JVMs simultaneously, both binding port 9091 and writing to
sessionStore/raft/9091/. This results in RocksDB lock conflicts
(IllegalStateException: Fail to init node) and forked VM crashes
(exit code 255) in CI.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
forkCount=2 causes MockFastJson2Test and MockGrpcServerTest to run in
separate JVMs that both try to bind MockServer on port 8099. The second
fork fails with "Server start failed", and retry tests see only 1 call
instead of the expected 3 because the MockCoordinator's async branch
commit/rollback calls go to the wrong server instance.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
MockServer tests (MockServerTest, MockFastJson2Test, MockGrpcServerTest,
GrpcTest, SeataMQProducerSendTest) all bind the same hardcoded port 8099.
With forkCount=2, two forks try to bind simultaneously and one fails.

Changes:
- ProtocolTestConstants: replace hardcoded port 8099 with dynamic port
  via ServerSocket(0), set service.mock.grouplist system property so
  file registry resolves to the correct random port
- MockServer: add getPort() method to expose the actual listening port
- AbstractServerTest: replace hardcoded port 8091 with dynamic port,
  override service.default.grouplist for saga test client discovery
- test-new-version/pom.xml: restore forkCount=2 (now safe with random
  ports per JVM fork)
- server/pom.xml: use Surefire group separation — forkCount=2 for 80+
  safe tests, separate forkCount=1 execution for 4 Raft tests that
  share port 9091 and RocksDB sessionStore directory

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…ort and improve test parallelism

Refactor MockServer/MockCoordinator from static singleton to instance pattern,
enabling multiple independent server instances per JVM. Each test class now
manages its own MockServer with random port (port=0), eliminating shared state
and port conflicts. Add forkCount=4 to core, rm-datasource, and compatible
modules for parallel test execution. Switch BaseH2Test from file-based to
in-memory H2 to avoid file lock conflicts under parallel forks.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings May 31, 2026 17:07
slievrly and others added 2 commits June 1, 2026 01:08
Use ThreadPoolExecutorFactory instead of direct ThreadPoolExecutor creation
in MockServer. Move string literal to left side of equalsIgnoreCase in
BaseH2Test.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR refactors the seata-mock-server test infrastructure from static/singleton usage to instance-based usage, enabling tests to run against independently started mock servers on randomly selected ports (to reduce port collision when running with more forks).

Changes:

  • Refactored MockServer/MockCoordinator to support instance mode while keeping static “default instance” helpers for backward compatibility.
  • Updated multiple test suites to start/stop per-test mock server instances and wire clients/configuration to the dynamically selected port.
  • Increased Maven Surefire forkCount in several modules and adjusted some tests/resources for better isolation (e.g., in-memory H2, safer temp file cleanup).

Reviewed changes

Copilot reviewed 21 out of 21 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
test-suite/test-old-version/src/test/java/io/seata/MockTest.java Switches old-version tests to the new MockServer.startDefault/closeDefault APIs.
test-suite/test-old-version/src/test/java/io/seata/core/rpc/netty/ProtocolTestConstants.java Uses MockServer.findAvailablePort() and sets mock grouplist accordingly.
test-suite/test-new-version/src/test/java/org/apache/seata/integration/rocketmq/SeataMQProducerSendTest.java Uses ProtocolTestConstants.initMockServer/closeMockServer for instance-based mock server lifecycle.
test-suite/test-new-version/src/test/java/org/apache/seata/core/rpc/netty/v1/ProtocolV1Server.java Adds constructor/getPort() and updates start logic to support port 0 (random).
test-suite/test-new-version/src/test/java/org/apache/seata/core/rpc/netty/v1/ProtocolV1SerializerTest.java Connects to the dynamically assigned server port and increases connect timeout.
test-suite/test-new-version/src/test/java/org/apache/seata/core/rpc/netty/mockserver/TmClientTest.java Accepts a MockCoordinator instance instead of relying on the singleton coordinator.
test-suite/test-new-version/src/test/java/org/apache/seata/core/rpc/netty/mockserver/ProtocolTestConstants.java Adds helpers to start/close an independent MockServer and update system properties/config cache.
test-suite/test-new-version/src/test/java/org/apache/seata/core/rpc/netty/mockserver/MockServerTest.java Migrates to instance-based MockServer lifecycle and coordinator access.
test-suite/test-new-version/src/test/java/org/apache/seata/core/rpc/netty/mockserver/MockGrpcServerTest.java Migrates to instance-based MockServer lifecycle for GRPC transport tests.
test-suite/test-new-version/src/test/java/org/apache/seata/core/rpc/netty/mockserver/MockFastJson2Test.java Migrates to instance-based MockServer lifecycle and coordinator access.
test-suite/test-new-version/src/test/java/org/apache/seata/core/rpc/netty/mockserver/GrpcTest.java Migrates to instance-based mock server lifecycle and uses dynamic port for the gRPC channel.
test-suite/test-new-version/src/test/java/org/apache/seata/core/rpc/netty/ChannelManagerTestHelper.java Uses service.mock.grouplist system property instead of a fixed constant address.
test-suite/test-new-version/pom.xml Increases Surefire forkCount to 4 for the module.
rm-datasource/src/test/java/org/apache/seata/rm/datasource/undo/BaseH2Test.java Switches undo tests to per-class in-memory H2 DB instances.
rm-datasource/pom.xml Adds Surefire config with forkCount=4.
mock-server/src/main/java/org/apache/seata/mockserver/MockServer.java Refactors mock server to instance-based lifecycle and adds static default-instance compatibility APIs + port selection helper.
mock-server/src/main/java/org/apache/seata/mockserver/MockCoordinator.java Refactors coordinator initialization to support per-server instances while keeping a default singleton.
extensions/rpc/seata-http/src/test/java/org/apache/seata/integration/http/HttpTest.java Uses a dynamically allocated HTTP port for the mock HTTP server in tests.
core/pom.xml Adds Surefire config with forkCount=4.
compatible/pom.xml Adds Surefire config with forkCount=4.
common/src/test/java/org/apache/seata/common/io/FileLoaderTest.java Ensures temporary test files are always deleted via try/finally.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +56 to +58
} catch (IOException e) {
return 8081;
}
Comment on lines +33 to +34
String serverAddress = System.getProperty("service.mock.grouplist", "0.0.0.0:10091");
return getChannelManager(client).acquireChannel(serverAddress);
Comment on lines +88 to +92
future.await(5000, TimeUnit.MILLISECONDS);
if (!future.isSuccess()) {
throw new RuntimeException("Server start fail!", future.cause());
}
this.port = ((InetSocketAddress) future.channel().localAddress()).getPort();
Comment thread mock-server/src/main/java/org/apache/seata/mockserver/MockServer.java Outdated
@codecov
Copy link
Copy Markdown

codecov Bot commented May 31, 2026

Codecov Report

❌ Patch coverage is 66.66667% with 24 lines in your changes missing coverage. Please review.
✅ Project coverage is 72.43%. Comparing base (da65f1e) to head (387782a).

Files with missing lines Patch % Lines
...n/java/org/apache/seata/mockserver/MockServer.java 62.29% 14 Missing and 9 partials ⚠️
...a/org/apache/seata/mockserver/MockCoordinator.java 90.90% 0 Missing and 1 partial ⚠️
Additional details and impacted files
@@             Coverage Diff              @@
##                2.x    #8121      +/-   ##
============================================
- Coverage     72.66%   72.43%   -0.23%     
  Complexity      883      883              
============================================
  Files          1327     1327              
  Lines         50714    50731      +17     
  Branches       6049     6052       +3     
============================================
- Hits          36851    36747     -104     
- Misses        10848    10968     +120     
- Partials       3015     3016       +1     
Files with missing lines Coverage Δ
...a/org/apache/seata/mockserver/MockCoordinator.java 83.12% <90.90%> (-0.53%) ⬇️
...n/java/org/apache/seata/mockserver/MockServer.java 65.67% <62.29%> (-6.88%) ⬇️

... and 22 files with indirect coverage changes

Impacted file tree graph

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@funky-eyes funky-eyes added this to the 2.7.0 milestone Jun 1, 2026
Copy link
Copy Markdown
Contributor

@funky-eyes funky-eyes left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

Copy link
Copy Markdown
Contributor

@lokidundun lokidundun left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@funky-eyes funky-eyes modified the milestones: 2.7.0, 2.8.0 Jun 8, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants