Skip to content

Commit 698f599

Browse files
committed
增加单测
1 parent b1202ef commit 698f599

1 file changed

Lines changed: 164 additions & 1 deletion

File tree

trpc-proto/trpc-proto-http/src/test/java/com/tencent/trpc/proto/http/server/AbstractHttpExecutorTest.java

Lines changed: 164 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,18 +9,33 @@
99
* A copy of the Apache 2.0 License can be found in the LICENSE file.
1010
*/
1111

12+
1213
package com.tencent.trpc.proto.http.server;
1314

1415

1516
import static org.junit.Assert.assertEquals;
17+
import static org.mockito.Matchers.any;
18+
import static org.mockito.Mockito.verify;
19+
import static org.powermock.api.mockito.PowerMockito.doAnswer;
20+
import static org.powermock.api.mockito.PowerMockito.doCallRealMethod;
1621
import static org.powermock.api.mockito.PowerMockito.doReturn;
1722
import static org.powermock.api.mockito.PowerMockito.mock;
1823
import static org.powermock.api.mockito.PowerMockito.when;
1924

25+
import com.tencent.trpc.core.common.config.ProviderConfig;
26+
import com.tencent.trpc.core.exception.ErrorCode;
27+
import com.tencent.trpc.core.exception.TRpcException;
28+
import com.tencent.trpc.core.rpc.ProviderInvoker;
2029
import com.tencent.trpc.core.rpc.RpcInvocation;
2130
import com.tencent.trpc.core.rpc.common.RpcMethodInfo;
31+
import com.tencent.trpc.core.rpc.common.RpcMethodInfoAndInvoker;
32+
import com.tencent.trpc.core.worker.spi.WorkerPool;
33+
import com.tencent.trpc.core.worker.spi.WorkerPool.Task;
2234
import com.tencent.trpc.proto.http.common.HttpConstants;
35+
import java.util.concurrent.CompletableFuture;
2336
import javax.servlet.http.HttpServletRequest;
37+
import javax.servlet.http.HttpServletResponse;
38+
import org.apache.http.HttpStatus;
2439
import org.junit.Test;
2540
import org.junit.runner.RunWith;
2641
import org.powermock.core.classloader.annotations.PowerMockIgnore;
@@ -48,4 +63,152 @@ public void buildRpcInvocation_shouldSuccess() throws Exception {
4863
methodInfo);
4964
assertEquals(rpcInvocation.getFunc(), "/trpc.demo.server/hello");
5065
}
51-
}
66+
67+
@Test
68+
public void execute_shouldHandleTimeoutException() throws Exception {
69+
// 准备测试数据
70+
HttpServletRequest request = mock(HttpServletRequest.class);
71+
HttpServletResponse response = mock(HttpServletResponse.class);
72+
AbstractHttpExecutor abstractHttpExecutor = mock(AbstractHttpExecutor.class);
73+
RpcMethodInfoAndInvoker methodInfoAndInvoker = mock(RpcMethodInfoAndInvoker.class);
74+
RpcMethodInfo methodInfo = mock(RpcMethodInfo.class);
75+
ProviderInvoker<?> invoker = mock(ProviderInvoker.class);
76+
ProviderConfig providerConfig = mock(ProviderConfig.class);
77+
WorkerPool workerPool = mock(WorkerPool.class);
78+
79+
// 模拟配置和基本信息
80+
when(methodInfoAndInvoker.getMethodInfo()).thenReturn(methodInfo);
81+
doReturn(invoker).when(methodInfoAndInvoker, "getInvoker");
82+
when(invoker.getConfig()).thenReturn(providerConfig);
83+
when(providerConfig.getRequestTimeout()).thenReturn(100); // 设置100ms超时
84+
when(providerConfig.getWorkerPoolObj()).thenReturn(workerPool);
85+
86+
// 模拟请求属性
87+
when(request.getAttribute(HttpConstants.REQUEST_ATTRIBUTE_TRPC_SERVICE)).thenReturn("trpc.demo.server");
88+
when(request.getAttribute(HttpConstants.REQUEST_ATTRIBUTE_TRPC_METHOD)).thenReturn("hello");
89+
when(request.getRemoteAddr()).thenReturn("127.0.0.1");
90+
when(request.getRemotePort()).thenReturn(8080);
91+
92+
// 模拟一个永远不会完成的CompletionStage,导致超时
93+
CompletableFuture<com.tencent.trpc.core.rpc.Response> neverCompleteFuture = new CompletableFuture<>();
94+
when(invoker.invoke(any())).thenReturn(neverCompleteFuture);
95+
96+
// 模拟私有方法调用
97+
doReturn(null).when(abstractHttpExecutor, "parseRpcParams", any(), any());
98+
when(abstractHttpExecutor, "execute", request, response, methodInfoAndInvoker).thenCallRealMethod();
99+
doCallRealMethod().when(abstractHttpExecutor, "doErrorReply", any(), any(), any());
100+
doCallRealMethod().when(abstractHttpExecutor, "httpErrorReply", any(), any(), any());
101+
102+
// 执行测试
103+
Whitebox.invokeMethod(abstractHttpExecutor, "execute", request, response, methodInfoAndInvoker);
104+
105+
// 验证超时后调用了错误响应(由于异步执行,超时也通过handleError处理,返回503)
106+
verify(response).setStatus(HttpStatus.SC_SERVICE_UNAVAILABLE);
107+
}
108+
109+
@Test
110+
public void execute_shouldHandleInvokeException() throws Exception {
111+
// 准备测试数据
112+
HttpServletRequest request = mock(HttpServletRequest.class);
113+
HttpServletResponse response = mock(HttpServletResponse.class);
114+
AbstractHttpExecutor abstractHttpExecutor = mock(AbstractHttpExecutor.class);
115+
RpcMethodInfoAndInvoker methodInfoAndInvoker = mock(RpcMethodInfoAndInvoker.class);
116+
RpcMethodInfo methodInfo = mock(RpcMethodInfo.class);
117+
ProviderInvoker<?> invoker = mock(ProviderInvoker.class);
118+
ProviderConfig providerConfig = mock(ProviderConfig.class);
119+
WorkerPool workerPool = mock(WorkerPool.class);
120+
121+
// 模拟配置和基本信息
122+
when(methodInfoAndInvoker.getMethodInfo()).thenReturn(methodInfo);
123+
doReturn(invoker).when(methodInfoAndInvoker, "getInvoker");
124+
when(invoker.getConfig()).thenReturn(providerConfig);
125+
when(providerConfig.getRequestTimeout()).thenReturn(5000);
126+
when(providerConfig.getWorkerPoolObj()).thenReturn(workerPool);
127+
128+
// 模拟请求属性
129+
when(request.getAttribute(HttpConstants.REQUEST_ATTRIBUTE_TRPC_SERVICE)).thenReturn("trpc.demo.server");
130+
when(request.getAttribute(HttpConstants.REQUEST_ATTRIBUTE_TRPC_METHOD)).thenReturn("hello");
131+
when(request.getRemoteAddr()).thenReturn("127.0.0.1");
132+
when(request.getRemotePort()).thenReturn(8080);
133+
when(request.getMethod()).thenReturn("POST");
134+
when(request.getRequestURI()).thenReturn("/api/test");
135+
136+
// 模拟WorkerPool同步执行任务
137+
doAnswer(invocation -> {
138+
Task task = invocation.getArgumentAt(0, Task.class);
139+
task.run();
140+
return null;
141+
}).when(workerPool).execute(any(Task.class));
142+
143+
// 模拟invoke抛出异常
144+
CompletableFuture<com.tencent.trpc.core.rpc.Response> failedFuture = new CompletableFuture<>();
145+
failedFuture.completeExceptionally(new RuntimeException("Service invoke failed"));
146+
when(invoker.invoke(any())).thenReturn(failedFuture);
147+
148+
// 模拟私有方法调用
149+
doReturn(null).when(abstractHttpExecutor, "parseRpcParams", any(), any());
150+
when(abstractHttpExecutor, "execute", request, response, methodInfoAndInvoker).thenCallRealMethod();
151+
doCallRealMethod().when(abstractHttpExecutor, "doErrorReply", any(), any(), any());
152+
doCallRealMethod().when(abstractHttpExecutor, "httpErrorReply", any(), any(), any());
153+
154+
// 执行测试
155+
Whitebox.invokeMethod(abstractHttpExecutor, "execute", request, response, methodInfoAndInvoker);
156+
157+
// 验证调用了错误响应(invoke异常在handleError中处理,返回503)
158+
verify(response).setStatus(HttpStatus.SC_SERVICE_UNAVAILABLE);
159+
}
160+
161+
@Test
162+
public void execute_shouldHandleResponseException() throws Exception {
163+
// 准备测试数据
164+
HttpServletRequest request = mock(HttpServletRequest.class);
165+
HttpServletResponse response = mock(HttpServletResponse.class);
166+
AbstractHttpExecutor abstractHttpExecutor = mock(AbstractHttpExecutor.class);
167+
RpcMethodInfoAndInvoker methodInfoAndInvoker = mock(RpcMethodInfoAndInvoker.class);
168+
RpcMethodInfo methodInfo = mock(RpcMethodInfo.class);
169+
ProviderInvoker<?> invoker = mock(ProviderInvoker.class);
170+
ProviderConfig providerConfig = mock(ProviderConfig.class);
171+
WorkerPool workerPool = mock(WorkerPool.class);
172+
173+
// 模拟配置和基本信息
174+
when(methodInfoAndInvoker.getMethodInfo()).thenReturn(methodInfo);
175+
doReturn(invoker).when(methodInfoAndInvoker, "getInvoker");
176+
when(invoker.getConfig()).thenReturn(providerConfig);
177+
when(providerConfig.getRequestTimeout()).thenReturn(5000);
178+
when(providerConfig.getWorkerPoolObj()).thenReturn(workerPool);
179+
180+
// 模拟请求属性
181+
when(request.getAttribute(HttpConstants.REQUEST_ATTRIBUTE_TRPC_SERVICE)).thenReturn("trpc.demo.server");
182+
when(request.getAttribute(HttpConstants.REQUEST_ATTRIBUTE_TRPC_METHOD)).thenReturn("hello");
183+
when(request.getRemoteAddr()).thenReturn("127.0.0.1");
184+
when(request.getRemotePort()).thenReturn(8080);
185+
when(request.getMethod()).thenReturn("POST");
186+
when(request.getRequestURI()).thenReturn("/api/test");
187+
188+
// 模拟WorkerPool同步执行任务
189+
doAnswer(invocation -> {
190+
Task task = invocation.getArgumentAt(0, Task.class);
191+
task.run();
192+
return null;
193+
}).when(workerPool).execute(any(Task.class));
194+
195+
// 模拟Response包含异常
196+
com.tencent.trpc.core.rpc.Response rpcResponse = mock(com.tencent.trpc.core.rpc.Response.class);
197+
when(rpcResponse.getException()).thenReturn(
198+
TRpcException.newFrameException(ErrorCode.TRPC_SERVER_VALIDATE_ERR, "Validation failed"));
199+
CompletableFuture<com.tencent.trpc.core.rpc.Response> responseFuture = CompletableFuture.completedFuture(rpcResponse);
200+
when(invoker.invoke(any())).thenReturn(responseFuture);
201+
202+
// 模拟私有方法调用
203+
doReturn(null).when(abstractHttpExecutor, "parseRpcParams", any(), any());
204+
when(abstractHttpExecutor, "execute", request, response, methodInfoAndInvoker).thenCallRealMethod();
205+
doCallRealMethod().when(abstractHttpExecutor, "doErrorReply", any(), any(), any());
206+
doCallRealMethod().when(abstractHttpExecutor, "httpErrorReply", any(), any(), any());
207+
208+
// 执行测试
209+
Whitebox.invokeMethod(abstractHttpExecutor, "execute", request, response, methodInfoAndInvoker);
210+
211+
// 验证调用了错误响应(Response异常在handleError中处理,返回503)
212+
verify(response).setStatus(HttpStatus.SC_SERVICE_UNAVAILABLE);
213+
}
214+
}

0 commit comments

Comments
 (0)