summaryrefslogtreecommitdiff
path: root/lib/java/test/org/apache/thrift/test/voidmethexceptions/TestVoidMethExceptions.java
diff options
context:
space:
mode:
Diffstat (limited to 'lib/java/test/org/apache/thrift/test/voidmethexceptions/TestVoidMethExceptions.java')
-rw-r--r--lib/java/test/org/apache/thrift/test/voidmethexceptions/TestVoidMethExceptions.java549
1 files changed, 549 insertions, 0 deletions
diff --git a/lib/java/test/org/apache/thrift/test/voidmethexceptions/TestVoidMethExceptions.java b/lib/java/test/org/apache/thrift/test/voidmethexceptions/TestVoidMethExceptions.java
new file mode 100644
index 000000000..af39262bb
--- /dev/null
+++ b/lib/java/test/org/apache/thrift/test/voidmethexceptions/TestVoidMethExceptions.java
@@ -0,0 +1,549 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.thrift.test.voidmethexceptions;
+
+import org.apache.commons.lang3.tuple.Pair;
+import org.apache.thrift.TApplicationException;
+import org.apache.thrift.TConfiguration;
+import org.apache.thrift.TProcessor;
+import org.apache.thrift.async.AsyncMethodCallback;
+import org.apache.thrift.async.TAsyncClientManager;
+import org.apache.thrift.protocol.TBinaryProtocol;
+import org.apache.thrift.server.TNonblockingServer;
+import org.apache.thrift.server.TServer;
+import org.apache.thrift.transport.TNonblockingServerSocket;
+import org.apache.thrift.transport.TNonblockingSocket;
+import org.apache.thrift.transport.TSocket;
+import org.apache.thrift.transport.TTransport;
+import org.apache.thrift.transport.layered.TFramedTransport;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import thrift.test.voidmethexceptions.TAppService01;
+import thrift.test.voidmethexceptions.TExampleException;
+
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.TimeUnit;
+import java.util.function.Supplier;
+
+@RunWith(Parameterized.class)
+public class TestVoidMethExceptions {
+
+ private static final Logger log = LoggerFactory.getLogger(TestVoidMethExceptions.class);
+
+ private static final int TIMEOUT_MILLIS = 5_000;
+
+ private final ServerImplementationType serverImplementationType;
+
+ private TServer server;
+ private Thread serverThread;
+ private int serverPort;
+
+
+ public TestVoidMethExceptions(ServerImplementationType serverImplementationType) {
+ Assert.assertNotNull(serverImplementationType);
+ this.serverImplementationType = serverImplementationType;
+ }
+
+
+ @Parameters(name = "serverImplementationType = {0}")
+ public static Object[][] parameters() {
+ return new Object[][]{{ServerImplementationType.SYNC_SERVER},
+ {ServerImplementationType.ASYNC_SERVER}};
+ }
+
+
+ @Before
+ public void setUp() throws Exception {
+ serverPort = -1;
+ serverImplementationType.service.setCancelled(false);
+ CompletableFuture<Void> futureServerStarted = new CompletableFuture<>();
+ TNonblockingServerSocket serverTransport = new TNonblockingServerSocket(0);
+ TNonblockingServer.Args args = new TNonblockingServer.Args(serverTransport);
+ args.processor(serverImplementationType.processor);
+ server = new TNonblockingServer(args) {
+
+ @Override
+ protected void setServing(boolean serving) {
+ super.setServing(serving);
+
+ if (serving) {
+ serverPort = serverTransport.getPort();
+ futureServerStarted.complete(null);
+ }
+ }
+
+ };
+
+ serverThread = new Thread(() -> {
+ server.serve();
+ }, "thrift-server");
+ serverThread.setDaemon(true);
+ serverThread.start();
+ futureServerStarted.get(TIMEOUT_MILLIS, TimeUnit.MILLISECONDS);
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ serverImplementationType.service.setCancelled(true);
+ server.stop();
+ serverThread.join(TIMEOUT_MILLIS);
+ }
+
+
+ @Test
+ public void testSyncClientMustReturnResultReturnString() throws Exception {
+ checkSyncClient("returnString",
+ "sent msg",
+ false,
+ "sent msg",
+ null,
+ null,
+ (client, msg, throwException) -> {
+ return client.returnString(msg, throwException);
+ });
+ }
+
+ @Test
+ public void testSyncClientMustReturnResultReturnVoidThrows() throws Exception {
+ checkSyncClient("returnVoidThrows",
+ "sent msg",
+ false,
+ null,
+ null,
+ null,
+ (client, msg, throwException) -> {
+ client.returnVoidThrows(msg, throwException);
+ return null;
+ });
+ }
+
+ @Test
+ public void testSyncClientMustReturnResultReturnVoidNoThrowsRuntimeException() throws Exception {
+ checkSyncClient("returnVoidNoThrowsRuntimeException",
+ "sent msg",
+ false,
+ null,
+ null,
+ null,
+ (client, msg, throwException) -> {
+ client.returnVoidNoThrowsRuntimeException(msg, throwException);
+ return null;
+ });
+ }
+
+ @Test
+ public void testSyncClientMustReturnResultReturnVoidNoThrowsTApplicationException() throws Exception {
+ checkSyncClient("returnVoidNoThrowsTApplicationException",
+ "sent msg",
+ false,
+ null,
+ null,
+ null,
+ (client, msg, throwException) -> {
+ client.returnVoidNoThrowsTApplicationException(msg, throwException);
+ return null;
+ });
+ }
+
+
+ @Test
+ public void testSyncClientMustThrowExceptionReturnString() throws Exception {
+ checkSyncClient("returnString",
+ "sent msg",
+ true,
+ null,
+ TExampleException.class,
+ "sent msg",
+ (client, msg, throwException) -> {
+ return client.returnString(msg, throwException);
+ });
+ }
+
+ @Test
+ public void testSyncClientMustThrowExceptionReturnVoidThrows() throws Exception {
+ checkSyncClient("returnVoidThrows",
+ "sent msg",
+ true,
+ null,
+ TExampleException.class,
+ "sent msg",
+ (client, msg, throwException) -> {
+ client.returnVoidThrows(msg, throwException);
+ return null;
+ });
+ }
+
+ @Test
+ public void testSyncClientMustThrowExceptionReturnVoidNoThrowsRuntimeException() throws Exception {
+ checkSyncClient("returnVoidNoThrowsRuntimeException",
+ "sent msg",
+ true,
+ null,
+ TApplicationException.class,
+ serverImplementationType == ServerImplementationType.ASYNC_SERVER ? "sent msg"
+ : null, // sync server return "Internal error processing returnVoidNoThrowsRuntimeException" message
+ (client, msg, throwException) -> {
+ client.returnVoidNoThrowsRuntimeException(msg, throwException);
+ return null;
+ });
+ }
+
+ @Test
+ public void testSyncClientMustThrowExceptionReturnVoidNoThrowsTApplicationException() throws Exception {
+ checkSyncClient("returnVoidNoThrowsTApplicationException",
+ "sent msg",
+ true,
+ null,
+ TApplicationException.class,
+ "sent msg",
+ (client, msg, throwException) -> {
+ client.returnVoidNoThrowsTApplicationException(msg, throwException);
+ return null;
+ });
+ }
+
+
+ @Test
+ public void testAsyncClientMustReturnResultReturnString() throws Throwable {
+ checkAsyncClient("returnString",
+ "sent msg",
+ false,
+ "sent msg",
+ null,
+ null,
+ (client, msg, throwException, resultHandler) -> {
+ client.returnString(msg, throwException, resultHandler);
+ });
+ }
+
+ @Test
+ public void testAsyncClientMustReturnResultReturnVoidThrows() throws Throwable {
+ checkAsyncClient("returnVoidThrows",
+ "sent msg",
+ false,
+ (Void) null,
+ null,
+ null,
+ (client, msg, throwException, resultHandler) -> {
+ client.returnVoidThrows(msg, throwException, resultHandler);
+ });
+ }
+
+ @Test
+ public void testAsyncClientMustReturnResultReturnVoidNoThrowsRuntimeException() throws Throwable {
+ checkAsyncClient("returnVoidNoThrowsRuntimeException",
+ "sent msg",
+ false,
+ (Void) null,
+ null,
+ null,
+ (client, msg, throwException, resultHandler) -> {
+ client.returnVoidNoThrowsRuntimeException(msg, throwException, resultHandler);
+ });
+ }
+
+ @Test
+ public void testAsyncClientMustReturnResultReturnVoidNoThrowsTApplicationException() throws Throwable {
+ checkAsyncClient("returnVoidNoThrowsTApplicationException",
+ "sent msg",
+ false,
+ (Void) null,
+ null,
+ null,
+ (client, msg, throwException, resultHandler) -> {
+ client.returnVoidNoThrowsTApplicationException(msg, throwException, resultHandler);
+ });
+ }
+
+
+ @Test
+ public void testAsyncClientMustThrowExceptionReturnString() throws Throwable {
+ checkAsyncClient("returnString",
+ "sent msg",
+ true,
+ (String) null,
+ TExampleException.class,
+ "sent msg",
+ (client, msg, throwException, resultHandler) -> {
+ client.returnString(msg, throwException, resultHandler);
+ });
+ }
+
+ @Test
+ public void testAsyncClientMustThrowExceptionReturnVoidThrows() throws Throwable {
+ checkAsyncClient("returnVoidThrows",
+ "sent msg",
+ true,
+ (Void) null,
+ TExampleException.class,
+ "sent msg",
+ (client, msg, throwException, resultHandler) -> {
+ client.returnVoidThrows(msg, throwException, resultHandler);
+ });
+ }
+
+ @Test
+ public void testAsyncClientMustThrowExceptionReturnVoidNoThrowsRuntimeException() throws Throwable {
+ checkAsyncClient("returnVoidNoThrowsRuntimeException",
+ "sent msg",
+ true,
+ (Void) null,
+ TApplicationException.class,
+ serverImplementationType == ServerImplementationType.ASYNC_SERVER ? "sent msg"
+ : null, // sync server return "Internal error processing returnVoidNoThrowsRuntimeException" message
+ (client, msg, throwException, resultHandler) -> {
+ client.returnVoidNoThrowsRuntimeException(msg, throwException, resultHandler);
+ });
+ }
+
+ @Test
+ public void testAsyncClientMustThrowExceptionReturnVoidNoThrowsTApplicationException() throws Throwable {
+ checkAsyncClient("returnVoidNoThrowsTApplicationException",
+ "sent msg",
+ true,
+ (Void) null,
+ TApplicationException.class,
+ "sent msg",
+ (client, msg, throwException, resultHandler) -> {
+ client.returnVoidNoThrowsTApplicationException(msg, throwException, resultHandler);
+ });
+ }
+
+
+ @Test
+ public void testSyncClientNoWaitForResultNoExceptionOnewayVoidNoThrows() throws Exception {
+ checkSyncClient("onewayVoidNoThrows",
+ "sent msg",
+ false,
+ null,
+ null,
+ null,
+ (client, msg, throwException) -> {
+ client.onewayVoidNoThrows(msg, throwException);
+ return null;
+ });
+ }
+
+ @Test
+ public void testSyncClientNoWaitForResultExceptionOnewayVoidNoThrows() throws Exception {
+ checkSyncClient("onewayVoidNoThrows",
+ "sent msg",
+ true,
+ null,
+ null,
+ null,
+ (client, msg, throwException) -> {
+ client.onewayVoidNoThrows(msg, throwException);
+ return null;
+ });
+ }
+
+ @Test
+ public void testAsyncClientNoWaitForResultNoExceptionOnewayVoidNoThrows() throws Throwable {
+ checkAsyncClient("onewayVoidNoThrows",
+ "sent msg",
+ false,
+ (Void) null,
+ null,
+ null,
+ (client, msg, throwException, resultHandler) -> {
+ client.onewayVoidNoThrows(msg, throwException, resultHandler);
+ });
+ }
+
+ @Test
+ public void testAsyncClientNoWaitForResultExceptionOnewayVoidNoThrows() throws Throwable {
+ checkAsyncClient("onewayVoidNoThrows",
+ "sent msg",
+ true,
+ (Void) null,
+ null,
+ null,
+ (client, msg, throwException, resultHandler) -> {
+ client.onewayVoidNoThrows(msg, throwException, resultHandler);
+ });
+ }
+
+
+ private void checkSyncClient(String desc,
+ String msg,
+ boolean throwException,
+ String expectedResult,
+ Class<?> expectedExceptionClass,
+ String expectedExceptionMsg,
+ SyncCall<TAppService01.Iface, String, Boolean, String> call) throws Exception {
+ if (log.isInfoEnabled()) {
+ log.info("start test checkSyncClient::" + desc + ", throwException: " + throwException
+ + ", serverImplementationType: "
+ + serverImplementationType);
+ }
+ Assert.assertNotEquals(-1, serverPort);
+ try (TTransport clientTransport = new TFramedTransport(new TSocket(new TConfiguration(),
+ "localhost",
+ serverPort,
+ TIMEOUT_MILLIS))) {
+ clientTransport.open();
+ TAppService01.Iface client = new TAppService01.Client(new TBinaryProtocol(clientTransport));
+
+ try {
+
+ String result = call.apply(client, msg, throwException);
+
+ if (throwException && expectedExceptionClass != null) {
+ Assert.fail("No exception, but must!!!");
+ } else {
+ // expected
+ Assert.assertEquals(expectedResult, result);
+ }
+ } catch (TExampleException | TApplicationException x) {
+ if (log.isInfoEnabled()) {
+ log.info("Exception: " + x, x);
+ }
+ if (throwException) {
+ // expected
+ Assert.assertEquals(expectedExceptionClass, x.getClass());
+ if (expectedExceptionMsg != null) {
+ Assert.assertEquals(expectedExceptionMsg, x.getMessage());
+ }
+ } else {
+ Assert.fail();
+ }
+ }
+ }
+ }
+
+ private <T> void checkAsyncClient(String desc,
+ String msg,
+ boolean throwException,
+ T expectedResult,
+ Class<?> expectedExceptionClass,
+ String expectedExceptionMsg,
+ AsyncCall<TAppService01.AsyncClient, String, Boolean, AsyncMethodCallback<T>> call) throws Throwable {
+ if (log.isInfoEnabled()) {
+ log.info("start test checkAsyncClient::" + desc + ", throwException: " + throwException
+ + ", serverImplementationType: "
+ + serverImplementationType);
+ }
+ Assert.assertNotEquals(serverPort, -1);
+ try (TNonblockingSocket clientTransportAsync = new TNonblockingSocket("localhost", serverPort, TIMEOUT_MILLIS)) {
+ TAsyncClientManager asyncClientManager = new TAsyncClientManager();
+ try {
+ TAppService01.AsyncClient asyncClient = new TAppService01.AsyncClient(new TBinaryProtocol.Factory(),
+ asyncClientManager,
+ clientTransportAsync);
+ asyncClient.setTimeout(TIMEOUT_MILLIS);
+
+ CompletableFuture<T> futureResult = new CompletableFuture<>();
+
+ call.apply(asyncClient, msg, throwException, new AsyncMethodCallback<T>() {
+
+ @Override
+ public void onError(Exception exception) {
+ futureResult.completeExceptionally(exception);
+ }
+
+ @Override
+ public void onComplete(T response) {
+ futureResult.complete(response);
+ }
+
+ });
+
+ try {
+ T result;
+ try {
+ result = futureResult.get(TIMEOUT_MILLIS, TimeUnit.MILLISECONDS);
+ } catch (ExecutionException x) {
+ throw x.getCause();
+ }
+
+ if (throwException && expectedExceptionClass != null) {
+ Assert.fail("No exception, but must!!!");
+ } else {
+ // expected
+ Assert.assertEquals(expectedResult, result);
+ }
+ } catch (TExampleException | TApplicationException x) {
+ if (log.isInfoEnabled()) {
+ log.info("Exception: " + x, x);
+ }
+ if (throwException) {
+ // expected
+ Assert.assertEquals(expectedExceptionClass, x.getClass());
+ if (expectedExceptionMsg != null) {
+ Assert.assertEquals(expectedExceptionMsg, x.getMessage());
+ }
+ } else {
+ Assert.fail();
+ }
+ }
+ } finally {
+ asyncClientManager.stop();
+ }
+ }
+ }
+
+
+ private enum ServerImplementationType {
+
+ SYNC_SERVER(() -> {
+ ServiceSyncImp service = new ServiceSyncImp();
+ return Pair.of(new TAppService01.Processor<>(service), service);
+ }),
+ ASYNC_SERVER(() -> {
+ ServiceAsyncImp service = new ServiceAsyncImp();
+ return Pair.of(new TAppService01.AsyncProcessor<>(service), service);
+ });
+
+ final TProcessor processor;
+ final ServiceBase service;
+
+ ServerImplementationType(Supplier<Pair<TProcessor, ServiceBase>> supplier) {
+ Pair<TProcessor, ServiceBase> pair = supplier.get();
+ this.processor = pair.getLeft();
+ this.service = pair.getRight();
+ }
+ }
+
+
+ @FunctionalInterface
+ private interface SyncCall<T, U, V, R> {
+
+ R apply(T t, U u, V v) throws Exception;
+
+ }
+
+
+ @FunctionalInterface
+ private interface AsyncCall<T, U, V, X> {
+
+ void apply(T t, U u, V v, X x) throws Exception;
+
+ }
+
+}