Skip to content

Commit 7af6689

Browse files
authored
optimize: remove hardcoded port configuration in test classes (#7460)
1 parent 3f86ccd commit 7af6689

File tree

6 files changed

+341
-302
lines changed

6 files changed

+341
-302
lines changed

changes/en-us/2.x.md

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,9 +41,8 @@ Add changes here for all PR submitted to the 2.x branch.
4141
- [[#7662](https://github.com/apache/incubator-seata/pull/7662)] ensure visibility of rm and The methods in MockTest are executed in order
4242

4343

44-
4544
### optimize:
46-
45+
- [[#7460](https://github.com/apache/incubator-seata/pull/7460)] Remove hardcoded port configuration in core module test classes
4746
- [[#7478](https://github.com/apache/incubator-seata/pull/7484)] optimize: remove client id metric
4847
- [[#7557](https://github.com/seata/seata/pull/7557)] upgrade some npmjs dependencies
4948
- [[#7576](https://github.com/seata/seata/pull/7576)] Add empty push protection for Configuration

changes/zh-cn/2.x.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@
4444

4545
### optimize:
4646

47+
- [[#7460](https://github.com/apache/incubator-seata/pull/7460)] 移除 core 模块测试类中的硬编码端口配置
4748
- [[#7478](https://github.com/apache/incubator-seata/pull/7484)] 删除client id指标
4849
- [[#7557](https://github.com/seata/seata/pull/7557)] 升级 npmjs 依赖
4950
- [[#7576](https://github.com/seata/seata/pull/7576)] 针对配置变更增加空推保护
Lines changed: 192 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,192 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one or more
3+
* contributor license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright ownership.
5+
* The ASF licenses this file to You under the Apache License, Version 2.0
6+
* (the "License"); you may not use this file except in compliance with
7+
* the License. You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
package org.apache.seata.core.rpc.netty;
18+
19+
import org.apache.seata.common.ConfigurationKeys;
20+
import org.apache.seata.common.ConfigurationTestHelper;
21+
import org.apache.seata.common.XID;
22+
import org.apache.seata.common.util.NetUtil;
23+
import org.apache.seata.common.util.UUIDGenerator;
24+
import org.apache.seata.server.coordinator.DefaultCoordinator;
25+
import org.apache.seata.server.session.SessionHolder;
26+
import org.junit.jupiter.api.AfterEach;
27+
import org.slf4j.Logger;
28+
import org.slf4j.LoggerFactory;
29+
30+
import java.io.IOException;
31+
import java.lang.management.ManagementFactory;
32+
import java.net.ServerSocket;
33+
import java.util.concurrent.LinkedBlockingQueue;
34+
import java.util.concurrent.ThreadPoolExecutor;
35+
import java.util.concurrent.TimeUnit;
36+
import java.util.concurrent.atomic.AtomicBoolean;
37+
38+
/**
39+
* Base test class for Netty client tests to eliminate code duplication
40+
*/
41+
public abstract class BaseNettyClientTest {
42+
43+
private static final Logger LOGGER = LoggerFactory.getLogger(BaseNettyClientTest.class);
44+
45+
/**
46+
* Get a dynamic available port
47+
*/
48+
protected static int getDynamicPort() throws IOException {
49+
try (ServerSocket serverSocket = new ServerSocket(0)) {
50+
return serverSocket.getLocalPort();
51+
}
52+
}
53+
54+
/**
55+
* Initialize message executor thread pool
56+
*/
57+
protected static ThreadPoolExecutor initMessageExecutor() {
58+
return new ThreadPoolExecutor(
59+
5,
60+
5,
61+
500,
62+
TimeUnit.SECONDS,
63+
new LinkedBlockingQueue<>(20000),
64+
new ThreadPoolExecutor.CallerRunsPolicy());
65+
}
66+
67+
/**
68+
* Start Seata server with dynamic port and intelligent waiting
69+
*/
70+
protected ServerInstance startServer(int port) throws Exception {
71+
ThreadPoolExecutor workingThreads = initMessageExecutor();
72+
NettyServerConfig serverConfig = new NettyServerConfig();
73+
serverConfig.setServerListenPort(port);
74+
NettyRemotingServer nettyRemotingServer = new NettyRemotingServer(workingThreads, serverConfig);
75+
76+
AtomicBoolean serverStatus = new AtomicBoolean();
77+
Thread thread = new Thread(() -> {
78+
try {
79+
SessionHolder.init(null);
80+
nettyRemotingServer.setHandler(DefaultCoordinator.getInstance(nettyRemotingServer));
81+
// set registry
82+
XID.setIpAddress(NetUtil.getLocalIp());
83+
XID.setPort(port);
84+
// init snowflake for transactionId, branchId
85+
UUIDGenerator.init(1L);
86+
System.out.println(
87+
"pid info: " + ManagementFactory.getRuntimeMXBean().getName());
88+
nettyRemotingServer.init();
89+
serverStatus.set(true);
90+
} catch (Throwable t) {
91+
serverStatus.set(false);
92+
LOGGER.error("The seata-server failed to start", t);
93+
}
94+
});
95+
thread.start();
96+
97+
// Wait for the seata-server to start with intelligent waiting
98+
long start = System.nanoTime();
99+
long maxWaitNanoTime = 10 * 1000 * 1000 * 1000L; // 10s
100+
while (System.nanoTime() - start < maxWaitNanoTime) {
101+
Thread.sleep(100);
102+
if (serverStatus.get()) {
103+
break;
104+
}
105+
}
106+
if (!serverStatus.get()) {
107+
throw new RuntimeException("Waiting for a while, but the seata-server did not start successfully.");
108+
}
109+
110+
return new ServerInstance(nettyRemotingServer, port);
111+
}
112+
113+
/**
114+
* Start server with simpler logic (for some tests that don't need intelligent waiting)
115+
*/
116+
protected ServerInstance startServerSimple(int port) throws Exception {
117+
ThreadPoolExecutor workingThreads = initMessageExecutor();
118+
NettyServerConfig serverConfig = new NettyServerConfig();
119+
serverConfig.setServerListenPort(port);
120+
NettyRemotingServer nettyRemotingServer = new NettyRemotingServer(workingThreads, serverConfig);
121+
122+
new Thread(() -> {
123+
SessionHolder.init(null);
124+
nettyRemotingServer.setHandler(DefaultCoordinator.getInstance(nettyRemotingServer));
125+
// set registry
126+
XID.setIpAddress(NetUtil.getLocalIp());
127+
XID.setPort(port);
128+
// init snowflake for transactionId, branchId
129+
UUIDGenerator.init(1L);
130+
nettyRemotingServer.init();
131+
})
132+
.start();
133+
134+
Thread.sleep(3000); // Simple wait
135+
return new ServerInstance(nettyRemotingServer, port);
136+
}
137+
138+
/**
139+
* Configure client to use the specified port
140+
*/
141+
protected void configureClient(int port) {
142+
ConfigurationTestHelper.putConfig("service.default.grouplist", "127.0.0.1:" + port);
143+
ConfigurationTestHelper.putConfig(ConfigurationKeys.SERVER_SERVICE_PORT_CAMEL, String.valueOf(port));
144+
}
145+
146+
/**
147+
* Clean up client configuration
148+
*/
149+
protected void cleanupClientConfig() {
150+
ConfigurationTestHelper.removeConfig("service.default.grouplist");
151+
ConfigurationTestHelper.removeConfig(ConfigurationKeys.SERVER_SERVICE_PORT_CAMEL);
152+
}
153+
154+
/**
155+
* Server instance wrapper to hold server and port information
156+
*/
157+
protected static class ServerInstance {
158+
private final NettyRemotingServer server;
159+
private final int port;
160+
161+
public ServerInstance(NettyRemotingServer server, int port) {
162+
this.server = server;
163+
this.port = port;
164+
}
165+
166+
public NettyRemotingServer getServer() {
167+
return server;
168+
}
169+
170+
public int getPort() {
171+
return port;
172+
}
173+
174+
public String getAddress() {
175+
return "127.0.0.1:" + port;
176+
}
177+
178+
public void destroy() {
179+
if (server != null) {
180+
server.destroy();
181+
}
182+
}
183+
}
184+
185+
/**
186+
* Clean up configuration after each test
187+
*/
188+
@AfterEach
189+
public void cleanupAfterTest() {
190+
cleanupClientConfig();
191+
}
192+
}

test/src/test/java/org/apache/seata/core/rpc/netty/MsgVersionHelperTest.java

Lines changed: 28 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -17,95 +17,52 @@
1717
package org.apache.seata.core.rpc.netty;
1818

1919
import io.netty.channel.Channel;
20-
import org.apache.seata.common.ConfigurationKeys;
21-
import org.apache.seata.common.ConfigurationTestHelper;
22-
import org.apache.seata.common.XID;
23-
import org.apache.seata.common.util.NetUtil;
24-
import org.apache.seata.common.util.UUIDGenerator;
2520
import org.apache.seata.core.protocol.ProtocolConstants;
2621
import org.apache.seata.core.protocol.RpcMessage;
2722
import org.apache.seata.core.protocol.Version;
2823
import org.apache.seata.core.protocol.VersionNotSupportMessage;
2924
import org.apache.seata.core.protocol.transaction.UndoLogDeleteRequest;
3025
import org.apache.seata.core.rpc.MsgVersionHelper;
31-
import org.apache.seata.server.coordinator.DefaultCoordinator;
32-
import org.apache.seata.server.session.SessionHolder;
33-
import org.junit.jupiter.api.AfterAll;
3426
import org.junit.jupiter.api.Assertions;
35-
import org.junit.jupiter.api.BeforeAll;
3627
import org.junit.jupiter.api.Test;
37-
import org.slf4j.Logger;
38-
import org.slf4j.LoggerFactory;
39-
40-
import java.util.concurrent.LinkedBlockingQueue;
41-
import java.util.concurrent.ThreadPoolExecutor;
42-
import java.util.concurrent.TimeUnit;
4328

4429
/**
45-
* MsgVersionHelper Test
46-
**/
47-
public class MsgVersionHelperTest {
48-
private static final Logger LOGGER = LoggerFactory.getLogger(MsgVersionHelperTest.class);
49-
50-
@BeforeAll
51-
public static void init() {
52-
ConfigurationTestHelper.putConfig(ConfigurationKeys.SERVER_SERVICE_PORT_CAMEL, "8091");
53-
}
54-
55-
@AfterAll
56-
public static void after() {
57-
ConfigurationTestHelper.removeConfig(ConfigurationKeys.SERVER_SERVICE_PORT_CAMEL);
58-
}
59-
60-
public static ThreadPoolExecutor initMessageExecutor() {
61-
return new ThreadPoolExecutor(
62-
5,
63-
5,
64-
500,
65-
TimeUnit.SECONDS,
66-
new LinkedBlockingQueue<>(20000),
67-
new ThreadPoolExecutor.CallerRunsPolicy());
68-
}
30+
* MsgVersionHelper Test - Refactored to use BaseNettyClientTest
31+
*/
32+
public class MsgVersionHelperTest extends BaseNettyClientTest {
6933

7034
@Test
7135
public void testSendMsgWithResponse() throws Exception {
72-
ThreadPoolExecutor workingThreads = initMessageExecutor();
73-
NettyRemotingServer nettyRemotingServer = new NettyRemotingServer(workingThreads);
74-
new Thread(() -> {
75-
SessionHolder.init(null);
76-
nettyRemotingServer.setHandler(DefaultCoordinator.getInstance(nettyRemotingServer));
77-
// set registry
78-
XID.setIpAddress(NetUtil.getLocalIp());
79-
XID.setPort(8091);
80-
// init snowflake for transactionId, branchId
81-
UUIDGenerator.init(1L);
82-
nettyRemotingServer.init();
83-
})
84-
.start();
85-
Thread.sleep(3000);
36+
int dynamicPort = getDynamicPort();
37+
ServerInstance serverInstance = startServerSimple(dynamicPort);
38+
39+
try {
40+
configureClient(dynamicPort);
8641

87-
String applicationId = "app 1";
88-
String transactionServiceGroup = "default_tx_group";
89-
TmNettyRemotingClient tmNettyRemotingClient =
90-
TmNettyRemotingClient.getInstance(applicationId, transactionServiceGroup);
91-
tmNettyRemotingClient.init();
42+
String applicationId = "app 1";
43+
String transactionServiceGroup = "default_tx_group";
44+
TmNettyRemotingClient tmNettyRemotingClient =
45+
TmNettyRemotingClient.getInstance(applicationId, transactionServiceGroup);
46+
tmNettyRemotingClient.init();
9247

93-
String serverAddress = "0.0.0.0:8091";
94-
Channel channel =
95-
TmNettyRemotingClient.getInstance().getClientChannelManager().acquireChannel(serverAddress);
48+
Channel channel = TmNettyRemotingClient.getInstance()
49+
.getClientChannelManager()
50+
.acquireChannel(serverInstance.getAddress());
9651

97-
RpcMessage rpcMessage = buildUndoLogDeleteMsg(ProtocolConstants.MSGTYPE_RESQUEST_ONEWAY);
98-
Assertions.assertFalse(MsgVersionHelper.versionNotSupport(channel, rpcMessage));
99-
TmNettyRemotingClient.getInstance().sendAsync(channel, rpcMessage);
52+
RpcMessage rpcMessage = buildUndoLogDeleteMsg(ProtocolConstants.MSGTYPE_RESQUEST_ONEWAY);
53+
Assertions.assertFalse(MsgVersionHelper.versionNotSupport(channel, rpcMessage));
54+
TmNettyRemotingClient.getInstance().sendAsync(channel, rpcMessage);
10055

101-
Version.putChannelVersion(channel, "0.7.0");
102-
Assertions.assertTrue(MsgVersionHelper.versionNotSupport(channel, rpcMessage));
103-
TmNettyRemotingClient.getInstance().sendAsync(channel, rpcMessage);
104-
Object response = TmNettyRemotingClient.getInstance().sendSync(channel, rpcMessage, 100);
105-
Assertions.assertTrue(response instanceof VersionNotSupportMessage);
56+
Version.putChannelVersion(channel, "0.7.0");
57+
Assertions.assertTrue(MsgVersionHelper.versionNotSupport(channel, rpcMessage));
58+
TmNettyRemotingClient.getInstance().sendAsync(channel, rpcMessage);
59+
Object response = TmNettyRemotingClient.getInstance().sendSync(channel, rpcMessage, 100);
60+
Assertions.assertTrue(response instanceof VersionNotSupportMessage);
10661

107-
nettyRemotingServer.destroy();
108-
tmNettyRemotingClient.destroy();
62+
tmNettyRemotingClient.destroy();
63+
} finally {
64+
serverInstance.destroy();
65+
}
10966
}
11067

11168
private RpcMessage buildUndoLogDeleteMsg(byte messageType) {

0 commit comments

Comments
 (0)