PageRenderTime 48ms CodeModel.GetById 19ms RepoModel.GetById 1ms app.codeStats 0ms

/java/src/test/java/com/googlecode/protobuf/socketrpc/RpcChannelImplTest.java

http://protobuf-socket-rpc.googlecode.com/
Java | 354 lines | 213 code | 59 blank | 82 comment | 9 complexity | 51c39e5b48e1c9e8e73f0170dba1bdbf MD5 | raw file
  1. // Copyright (c) 2010 Shardul Deo
  2. //
  3. // Permission is hereby granted, free of charge, to any person obtaining a copy
  4. // of this software and associated documentation files (the "Software"), to deal
  5. // in the Software without restriction, including without limitation the rights
  6. // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  7. // copies of the Software, and to permit persons to whom the Software is
  8. // furnished to do so, subject to the following conditions:
  9. //
  10. // The above copyright notice and this permission notice shall be included in
  11. // all copies or substantial portions of the Software.
  12. //
  13. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  14. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  15. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  16. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  17. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  18. // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  19. // THE SOFTWARE.
  20. package com.googlecode.protobuf.socketrpc;
  21. import java.io.IOException;
  22. import java.util.concurrent.Executor;
  23. import junit.framework.TestCase;
  24. import com.google.protobuf.ByteString;
  25. import com.google.protobuf.RpcCallback;
  26. import com.google.protobuf.ServiceException;
  27. import com.googlecode.protobuf.socketrpc.SocketRpcProtos.ErrorReason;
  28. import com.googlecode.protobuf.socketrpc.TestProtos.Request;
  29. import com.googlecode.protobuf.socketrpc.TestProtos.Response;
  30. import com.googlecode.protobuf.socketrpc.TestProtos.TestService;
  31. import com.googlecode.protobuf.socketrpc.TestProtos.TestService.BlockingInterface;
  32. /**
  33. * Tests for {@link RpcChannelImpl}.
  34. *
  35. * @author Shardul Deo
  36. */
  37. public class RpcChannelImplTest extends TestCase {
  38. private FakeSocket socket;
  39. private RpcConnectionFactory connectionFactory;
  40. private RpcChannelImpl rpcChannel;
  41. @Override
  42. protected void setUp() throws Exception {
  43. super.setUp();
  44. socket = new FakeSocket(true);
  45. connectionFactory = new SocketRpcConnectionFactory("host", 8080,
  46. new FakeSocketFactory().returnsSocket(socket), true /* delimited */);
  47. rpcChannel = new RpcChannelImpl(connectionFactory,
  48. RpcChannels.SAME_THREAD_EXECUTOR);
  49. }
  50. private static class FakeCallback implements RpcCallback<Response> {
  51. private Response response;
  52. private boolean invoked = false;
  53. @Override
  54. public void run(Response response) {
  55. this.response = response;
  56. invoked = true;
  57. }
  58. };
  59. public void testGoodRpc() throws IOException {
  60. // Create data
  61. String reqdata = "Request Data";
  62. String resdata = "Response Data";
  63. Request request = Request.newBuilder().setStrData(reqdata).build();
  64. Response response = Response.newBuilder().setStrData(resdata).build();
  65. socket.withResponseProto(response);
  66. // Call non-blocking method
  67. FakeCallback callback = callRpc(request, null);
  68. verifyRequestToSocket(request);
  69. // Verify response
  70. assertTrue(callback.invoked);
  71. assertEquals(resdata, callback.response.getStrData());
  72. // Call blocking method
  73. assertEquals(resdata, callBlockingRpc(request, null).getStrData());
  74. verifyRequestToSocket(request);
  75. // Call method asynchronously
  76. callback = callAsyncRpc(request, null);
  77. verifyRequestToSocket(request);
  78. // Verify response
  79. assertTrue(callback.invoked);
  80. assertEquals(resdata, callback.response.getStrData());
  81. }
  82. /**
  83. * Rpc called with incomplete request proto
  84. */
  85. public void testIncompleteRequest() throws IOException {
  86. // Create data
  87. String resdata = "Response Data";
  88. Request request = Request.newBuilder().buildPartial(); // required missing
  89. Response response = Response.newBuilder().setStrData(resdata).build();
  90. socket.withResponseProto(response);
  91. // Call non-blocking method
  92. callRpc(request, ErrorReason.INVALID_REQUEST_PROTO);
  93. // Call blocking method
  94. assertNull(callBlockingRpc(request, ErrorReason.INVALID_REQUEST_PROTO));
  95. // Call method asynchronously
  96. callAsyncRpc(request, ErrorReason.INVALID_REQUEST_PROTO,
  97. false /* no listener */);
  98. }
  99. /**
  100. * RPC doesn't invoke callback.
  101. */
  102. public void testNoCallBack() throws IOException {
  103. // Create data
  104. String reqdata = "Request Data";
  105. Request request = Request.newBuilder().setStrData(reqdata).build();
  106. socket.withNoResponse(false /* callback */);
  107. // Call non-blocking method
  108. FakeCallback callback = callRpc(request, null);
  109. verifyRequestToSocket(request);
  110. // Verify callback not called
  111. assertFalse(callback.invoked);
  112. // Call blocking method
  113. assertNull(callBlockingRpc(request, null));
  114. verifyRequestToSocket(request);
  115. // Call method asynchronously
  116. callback = callAsyncRpc(request, null);
  117. verifyRequestToSocket(request);
  118. // Verify callback not called
  119. assertFalse(callback.invoked);
  120. }
  121. /**
  122. * RPC invokes callback with null.
  123. */
  124. public void testNullCallBack() throws IOException {
  125. // Create data
  126. String reqdata = "Request Data";
  127. Request request = Request.newBuilder().setStrData(reqdata).build();
  128. socket.withNoResponse(true /* callback */);
  129. // Call non-blocking method
  130. FakeCallback callback = callRpc(request, null);
  131. verifyRequestToSocket(request);
  132. // Verify callback was called with null
  133. assertTrue(callback.invoked);
  134. assertNull(callback.response);
  135. // Call blocking method
  136. assertNull(callBlockingRpc(request, null));
  137. verifyRequestToSocket(request);
  138. // Call method asynchronously
  139. callback = callAsyncRpc(request, null);
  140. verifyRequestToSocket(request);
  141. // Verify callback was called with null
  142. assertTrue(callback.invoked);
  143. assertNull(callback.response);
  144. }
  145. /**
  146. * Server responds with bad data
  147. */
  148. public void testBadResponse() throws IOException {
  149. // Create data
  150. String reqdata = "Request Data";
  151. Request request = Request.newBuilder().setStrData(reqdata).build();
  152. socket.withInputBytes("bad response".getBytes());
  153. // Call non-blocking method
  154. callRpc(request, ErrorReason.IO_ERROR);
  155. verifyRequestToSocket(request);
  156. // Call blocking method
  157. assertNull(callBlockingRpc(request, ErrorReason.IO_ERROR));
  158. verifyRequestToSocket(request);
  159. // Call method asynchronously
  160. callAsyncRpc(request, ErrorReason.IO_ERROR);
  161. verifyRequestToSocket(request);
  162. }
  163. /**
  164. * RPC responds with bad response proto
  165. */
  166. public void testBadResponseProto() throws IOException {
  167. // Create data
  168. String reqdata = "Request Data";
  169. Request request = Request.newBuilder().setStrData(reqdata).build();
  170. socket.withResponseProto(ByteString.copyFrom("bad response".getBytes()));
  171. callRpc(request, ErrorReason.BAD_RESPONSE_PROTO);
  172. verifyRequestToSocket(request);
  173. // Call blocking method
  174. assertNull(callBlockingRpc(request, ErrorReason.BAD_RESPONSE_PROTO));
  175. verifyRequestToSocket(request);
  176. callAsyncRpc(request, ErrorReason.BAD_RESPONSE_PROTO);
  177. verifyRequestToSocket(request);
  178. }
  179. /**
  180. * RPC responds with incomplete response.
  181. */
  182. public void testIncompleteResponse() throws IOException {
  183. // Create data
  184. String reqdata = "Request Data";
  185. Request request = Request.newBuilder().setStrData(reqdata).build();
  186. // incomplete response
  187. Response response = Response.newBuilder().setIntData(5).buildPartial();
  188. socket.withResponseProto(response);
  189. callRpc(request, ErrorReason.BAD_RESPONSE_PROTO);
  190. verifyRequestToSocket(request);
  191. // Call blocking method
  192. assertNull(callBlockingRpc(request, ErrorReason.BAD_RESPONSE_PROTO));
  193. verifyRequestToSocket(request);
  194. callAsyncRpc(request, ErrorReason.BAD_RESPONSE_PROTO);
  195. verifyRequestToSocket(request);
  196. }
  197. /**
  198. * Error on server side.
  199. */
  200. public void testErrorResponse() throws IOException {
  201. checkResponseWithError(ErrorReason.BAD_REQUEST_DATA);
  202. checkResponseWithError(ErrorReason.BAD_REQUEST_PROTO);
  203. checkResponseWithError(ErrorReason.SERVICE_NOT_FOUND);
  204. checkResponseWithError(ErrorReason.METHOD_NOT_FOUND);
  205. checkResponseWithError(ErrorReason.RPC_ERROR);
  206. checkResponseWithError(ErrorReason.RPC_FAILED);
  207. }
  208. private void checkResponseWithError(ErrorReason reason) throws IOException {
  209. // Create data
  210. String reqdata = "Request Data";
  211. Request request = Request.newBuilder().setStrData(reqdata).build();
  212. String error = "Error String";
  213. socket.withErrorResponseProto(error, reason);
  214. callRpc(request, reason);
  215. verifyRequestToSocket(request);
  216. // Call blocking method
  217. assertNull(callBlockingRpc(request, reason));
  218. verifyRequestToSocket(request);
  219. callAsyncRpc(request, reason);
  220. verifyRequestToSocket(request);
  221. }
  222. private FakeCallback callRpc(Request request, ErrorReason reason) {
  223. SocketRpcController controller = new SocketRpcController();
  224. TestService service = TestService.newStub(rpcChannel);
  225. FakeCallback callback = new FakeCallback();
  226. service.testMethod(controller, request, callback);
  227. if (reason != null) {
  228. assertTrue(controller.failed());
  229. assertEquals(reason, controller.errorReason());
  230. assertTrue(callback.invoked);
  231. assertNull(callback.response);
  232. } else {
  233. assertFalse(controller.failed());
  234. }
  235. return callback;
  236. }
  237. /**
  238. * Executor that just stores commands to be executed later.
  239. */
  240. private static class DelayedExecutor implements Executor {
  241. private Runnable listener = null;
  242. @Override
  243. public void execute(Runnable command) {
  244. listener = command;
  245. }
  246. }
  247. private FakeCallback callAsyncRpc(Request request, ErrorReason reason) {
  248. return callAsyncRpc(request, reason, true);
  249. }
  250. private FakeCallback callAsyncRpc(Request request, ErrorReason reason,
  251. boolean hasListener) {
  252. SocketRpcController controller = new SocketRpcController();
  253. DelayedExecutor executor = new DelayedExecutor();
  254. TestService service = TestService.newStub(
  255. new RpcChannelImpl(connectionFactory, executor));
  256. FakeCallback callback = new FakeCallback();
  257. service.testMethod(controller, request, callback);
  258. assertEquals(hasListener, executor.listener != null);
  259. if (hasListener) {
  260. // Callback should not be called yet since it is async
  261. assertFalse(callback.invoked);
  262. executor.listener.run();
  263. }
  264. if (reason != null) {
  265. assertTrue(controller.failed());
  266. assertEquals(reason, controller.errorReason());
  267. assertTrue(callback.invoked);
  268. assertNull(callback.response);
  269. } else {
  270. assertFalse(controller.failed());
  271. }
  272. return callback;
  273. }
  274. private Response callBlockingRpc(Request request, ErrorReason reason) {
  275. SocketRpcController controller = new SocketRpcController();
  276. BlockingInterface service = TestService.newBlockingStub(rpcChannel);
  277. try {
  278. Response response = service.testMethod(controller, request);
  279. assertNull(reason);
  280. return response;
  281. } catch (ServiceException e) {
  282. assertEquals(reason, controller.errorReason());
  283. return null;
  284. } finally {
  285. assertEquals(reason != null, controller.failed());
  286. }
  287. }
  288. private void verifyRequestToSocket(Request request) throws IOException {
  289. assertEquals(request.toByteString(), socket.getRequest().getRequestProto());
  290. assertEquals(TestService.getDescriptor().getFullName(), socket.getRequest()
  291. .getServiceName());
  292. assertEquals(TestService.getDescriptor().getMethods().get(0).getName(),
  293. socket.getRequest().getMethodName());
  294. }
  295. }