THRIFT-847 Test Framework harmonization across all languages
THRIFT-1595 Java test server should follow the documented behavior as of THRIFT-1590
Patch: Kamil Salas
diff --git a/lib/java/build.xml b/lib/java/build.xml
index 6cf489f..ddbdfda 100644
--- a/lib/java/build.xml
+++ b/lib/java/build.xml
@@ -155,7 +155,12 @@
<delete dir="${genbean}"/>
</target>
- <target name="compile-test" description="Build the test suite classes" depends="generate,dist">
+ <target name="optional-generate" unless="no-gen-thrift">
+ <antcall target="generate">
+ </antcall>
+ </target>
+
+ <target name="compile-test" description="Build the test suite classes" depends="optional-generate,dist">
<javac debug="true" srcdir="${gen}" destdir="${build.test.dir}" classpathref="test.classpath" includeantruntime="false">
<compilerarg value="-Xlint:deprecation"/>
<!--<compilerarg value="-Xlint:unchecked"/>-->
@@ -212,15 +217,19 @@
<target name="testclient" description="Run a test client" depends="compile-test">
<java classname="org.apache.thrift.test.TestClient"
- classpathref="test.classpath" failonerror="true">
+ classpathref="test.classpath" failonerror="true" fork="true">
+ <sysproperty key="javax.net.ssl.trustStore" value="${src.test}/.truststore"/>
+ <sysproperty key="javax.net.ssl.trustStorePassword" value="thrift"/>
<arg line="${testargs}"/>
</java>
</target>
<target name="testserver" description="Run a test server" depends="compile-test">
<java classname="org.apache.thrift.test.TestServer"
- classpathref="test.classpath" failonerror="true">
- <arg line="${testargs}"/>
+ classpathref="test.classpath" failonerror="true" fork="true">
+ <sysproperty key="javax.net.ssl.keyStore" value="${src.test}/.keystore"/>
+ <sysproperty key="javax.net.ssl.keyStorePassword" value="thrift"/>
+ <arg line="${testargs}"/>
</java>
</target>
diff --git a/lib/java/test/org/apache/thrift/test/TestClient.java b/lib/java/test/org/apache/thrift/test/TestClient.java
index a7d5544..4e7e507 100644
--- a/lib/java/test/org/apache/thrift/test/TestClient.java
+++ b/lib/java/test/org/apache/thrift/test/TestClient.java
@@ -29,8 +29,14 @@
import org.apache.thrift.transport.TSocket;
import org.apache.thrift.transport.THttpClient;
import org.apache.thrift.transport.TFramedTransport;
+import org.apache.thrift.transport.TFastFramedTransport;
import org.apache.thrift.transport.TTransportException;
+import org.apache.thrift.transport.TSSLTransportFactory;
+import org.apache.thrift.transport.TSSLTransportFactory.TSSLTransportParameters;
import org.apache.thrift.protocol.TBinaryProtocol;
+import org.apache.thrift.protocol.TProtocol;
+import org.apache.thrift.protocol.TJSONProtocol;
+import org.apache.thrift.protocol.TCompactProtocol;
import org.apache.thrift.protocol.TSimpleJSONProtocol;
import java.util.Map;
@@ -50,44 +56,92 @@
public static void main(String [] args) {
String host = "localhost";
int port = 9090;
- String url = null;
int numTests = 1;
- boolean framed = false;
+ String protocol_type = "binary";
+ String transport_type = "buffered";
+ boolean ssl = false;
int socketTimeout = 1000;
try {
for (int i = 0; i < args.length; ++i) {
- if (args[i].equals("-h")) {
- String[] hostport = (args[++i]).split(":");
- host = hostport[0];
- port = Integer.valueOf(hostport[1]);
- } else if (args[i].equals("-f") || args[i].equals("-framed")) {
- framed = true;
- } else if (args[i].equals("-u")) {
- url = args[++i];
- } else if (args[i].equals("-n")) {
- numTests = Integer.valueOf(args[++i]);
- } else if (args[i].equals("-timeout")) {
- socketTimeout = Integer.valueOf(args[++i]);
+ if (args[i].startsWith("--host")) {
+ host = args[i].split("=")[1];
+ host.trim();
+ } else if (args[i].startsWith("--port")) {
+ port = Integer.valueOf(args[i].split("=")[1]);
+ } else if (args[i].startsWith("--n") ||
+ args[i].startsWith("--testloops")){
+ numTests = Integer.valueOf(args[i].split("=")[1]);
+ } else if (args[i].equals("--timeout")) {
+ socketTimeout = Integer.valueOf(args[i].split("=")[1]);
+ } else if (args[i].startsWith("--protocol")) {
+ protocol_type = args[i].split("=")[1];
+ protocol_type.trim();
+ } else if (args[i].startsWith("--transport")) {
+ transport_type = args[i].split("=")[1];
+ transport_type.trim();
+ } else if (args[i].equals("--ssl")) {
+ ssl = true;
+ } else if (args[i].equals("--help")) {
+ System.out.println("Allowed options:");
+ System.out.println(" --help\t\t\tProduce help message");
+ System.out.println(" --host=arg (=" + host + ")\tHost to connect");
+ System.out.println(" --port=arg (=" + port + ")\tPort number to connect");
+ System.out.println(" --transport=arg (=" + transport_type + ")\n\t\t\t\tTransport: buffered, framed, fastframed, http");
+ System.out.println(" --protocol=arg (=" + protocol_type + ")\tProtocol: binary, json, compact");
+ System.out.println(" --ssl\t\t\tEncrypted Transport using SSL");
+ System.out.println(" --testloops[--n]=arg (=" + numTests + ")\tNumber of Tests");
+ System.exit(0);
}
}
} catch (Exception x) {
- x.printStackTrace();
+ System.err.println("Can not parse arguments! See --help");
+ System.exit(1);
+ }
+
+ try {
+ if (protocol_type.equals("binary")) {
+ } else if (protocol_type.equals("compact")) {
+ } else if (protocol_type.equals("json")) {
+ } else {
+ throw new Exception("Unknown protocol type! " + protocol_type);
+ }
+ if (transport_type.equals("buffered")) {
+ } else if (transport_type.equals("framed")) {
+ } else if (transport_type.equals("fastframed")) {
+ } else if (transport_type.equals("http")) {
+ } else {
+ throw new Exception("Unknown transport type! " + transport_type);
+ }
+ if (transport_type.equals("http") && ssl == true) {
+ throw new Exception("SSL is not supported over http.");
+ }
+ } catch (Exception e) {
+ System.err.println("Error: " + e.getMessage());
System.exit(1);
}
TTransport transport = null;
try {
- if (url != null) {
+ if (transport_type.equals("http")) {
+ String url = "http://" + host + ":" + port + "/service";
transport = new THttpClient(url);
} else {
- TSocket socket = new TSocket(host, port);
+ TSocket socket = null;
+ if (ssl == true) {
+ socket = TSSLTransportFactory.getClientSocket(host, port, 0);
+ } else {
+ socket = new TSocket(host, port);
+ }
socket.setTimeout(socketTimeout);
transport = socket;
- if (framed) {
+ if (transport_type.equals("buffered")) {
+ } else if (transport_type.equals("framed")) {
transport = new TFramedTransport(transport);
+ } else if (transport_type.equals("fastframed")) {
+ transport = new TFastFramedTransport(transport);
}
}
} catch (Exception x) {
@@ -95,10 +149,17 @@
System.exit(1);
}
- TBinaryProtocol binaryProtocol =
- new TBinaryProtocol(transport);
+ TProtocol tProtocol = null;
+ if (protocol_type.equals("json")) {
+ tProtocol = new TJSONProtocol(transport);
+ } else if (protocol_type.equals("compact")) {
+ tProtocol = new TCompactProtocol(transport);
+ } else {
+ tProtocol = new TBinaryProtocol(transport);
+ }
+
ThriftTest.Client testClient =
- new ThriftTest.Client(binaryProtocol);
+ new ThriftTest.Client(tProtocol);
Insanity insane = new Insanity();
long timeMin = 0;
@@ -113,12 +174,14 @@
*/
System.out.println("Test #" + (test+1) + ", " + "connect " + host + ":" + port);
- try {
- transport.open();
- } catch (TTransportException ttx) {
- ttx.printStackTrace();
- System.out.println("Connect failed: " + ttx.getMessage());
- System.exit(1);
+ if (transport.isOpen() == false) {
+ try {
+ transport.open();
+ } catch (TTransportException ttx) {
+ ttx.printStackTrace();
+ System.out.println("Connect failed: " + ttx.getMessage());
+ System.exit(1);
+ }
}
long start = System.nanoTime();
diff --git a/lib/java/test/org/apache/thrift/test/TestServer.java b/lib/java/test/org/apache/thrift/test/TestServer.java
index 9077882..125a773 100644
--- a/lib/java/test/org/apache/thrift/test/TestServer.java
+++ b/lib/java/test/org/apache/thrift/test/TestServer.java
@@ -26,6 +26,8 @@
import java.util.Set;
import org.apache.thrift.protocol.TBinaryProtocol;
+import org.apache.thrift.protocol.TCompactProtocol;
+import org.apache.thrift.protocol.TJSONProtocol;
import org.apache.thrift.protocol.TProtocol;
import org.apache.thrift.protocol.TProtocolFactory;
import org.apache.thrift.server.ServerContext;
@@ -33,10 +35,18 @@
import org.apache.thrift.server.TServer.Args;
import org.apache.thrift.server.TSimpleServer;
import org.apache.thrift.server.TThreadPoolServer;
-import org.apache.thrift.transport.TServerSocket;
import org.apache.thrift.server.ServerTestBase.TestHandler;
import org.apache.thrift.server.TServerEventHandler;
+import org.apache.thrift.server.TThreadedSelectorServer;
+import org.apache.thrift.server.TNonblockingServer;
+import org.apache.thrift.transport.TFramedTransport;
+import org.apache.thrift.transport.TFastFramedTransport;
+import org.apache.thrift.transport.TServerSocket;
+import org.apache.thrift.transport.TSSLTransportFactory;
import org.apache.thrift.transport.TTransport;
+import org.apache.thrift.transport.TTransportFactory;
+import org.apache.thrift.transport.TNonblockingServerSocket;
+
import thrift.test.Insanity;
import thrift.test.Numberz;
@@ -96,10 +106,74 @@
public static void main(String [] args) {
try {
int port = 9090;
- if (args.length > 1) {
- port = Integer.valueOf(args[0]);
+ boolean ssl = false;
+ String transport_type = "buffered";
+ String protocol_type = "binary";
+ String server_type = "thread-pool";
+ String domain_socket = "";
+ try {
+ for (int i = 0; i < args.length; i++) {
+ if (args[i].startsWith("--port")) {
+ port = Integer.valueOf(args[i].split("=")[1]);
+ } else if (args[i].startsWith("--server-type")) {
+ server_type = args[i].split("=")[1];
+ server_type.trim();
+ } else if (args[i].startsWith("--port")) {
+ port=Integer.parseInt(args[i].split("=")[1]);
+ } else if (args[i].startsWith("--protocol")) {
+ protocol_type = args[i].split("=")[1];
+ protocol_type.trim();
+ } else if (args[i].startsWith("--transport")) {
+ transport_type = args[i].split("=")[1];
+ transport_type.trim();
+ } else if (args[i].equals("--ssl")) {
+ ssl = true;
+ } else if (args[i].equals("--help")) {
+ System.out.println("Allowed options:");
+ System.out.println(" --help\t\t\tProduce help message");
+ System.out.println(" --port=arg (=" + port + ")\tPort number to connect");
+ System.out.println(" --transport=arg (=" + transport_type + ")\n\t\t\t\tTransport: buffered, framed, fastframed");
+ System.out.println(" --protocol=arg (=" + protocol_type + ")\tProtocol: binary, json, compact");
+ System.out.println(" --ssl\t\t\tEncrypted Transport using SSL");
+ System.out.println(" --server-type=arg (=" + server_type +")\n\t\t\t\tType of server: simple, thread-pool, nonblocking, threaded-selector");
+ System.exit(0);
+ }
+ }
+ } catch (Exception e) {
+ System.err.println("Can not parse arguments! See --help");
+ System.exit(1);
}
- //@TODO add other protocol and transport types
+
+ try {
+ if (server_type.equals("simple")) {
+ } else if (server_type.equals("thread-pool")) {
+ } else if (server_type.equals("nonblocking")) {
+ if (ssl == true) {
+ throw new Exception("SSL is not supported over nonblocking servers!");
+ }
+ } else if (server_type.equals("threaded-selector")) {
+ if (ssl == true) {
+ throw new Exception("SSL is not supported over nonblocking servers!");
+ }
+ } else {
+ throw new Exception("Unknown server type! " + server_type);
+ }
+ if (protocol_type.equals("binary")) {
+ } else if (protocol_type.equals("json")) {
+ } else if (protocol_type.equals("compact")) {
+ } else {
+ throw new Exception("Unknown protocol type! " + protocol_type);
+ }
+ if (transport_type.equals("buffered")) {
+ } else if (transport_type.equals("framed")) {
+ } else if (transport_type.equals("fastframed")) {
+ } else {
+ throw new Exception("Unknown transport type! " + transport_type);
+ }
+ } catch (Exception e) {
+ System.err.println("Error: " + e.getMessage());
+ System.exit(1);
+ }
// Processor
TestHandler testHandler =
@@ -107,21 +181,85 @@
ThriftTest.Processor testProcessor =
new ThriftTest.Processor(testHandler);
- // Transport
- TServerSocket tServerSocket =
- new TServerSocket(port);
-
// Protocol factory
- TProtocolFactory tProtocolFactory =
- new TBinaryProtocol.Factory();
+ TProtocolFactory tProtocolFactory = null;
+ if (protocol_type.equals("json")) {
+ tProtocolFactory = new TJSONProtocol.Factory();
+ } else if (protocol_type.equals("compact")) {
+ tProtocolFactory = new TCompactProtocol.Factory();
+ } else {
+ tProtocolFactory = new TBinaryProtocol.Factory();
+ }
- TServer serverEngine;
+ TTransportFactory tTransportFactory = null;
- // Simple Server
- //serverEngine = new TSimpleServer(new Args(tServerSocket).processor(testProcessor));
+ if (transport_type.equals("framed")) {
+ tTransportFactory = new TFramedTransport.Factory();
+ } else if (transport_type.equals("fastframed")) {
+ tTransportFactory = new TFastFramedTransport.Factory();
+ } else { // .equals("buffered") => default value
+ tTransportFactory = new TTransportFactory();
+ }
- // ThreadPool Server
- serverEngine = new TThreadPoolServer(new TThreadPoolServer.Args(tServerSocket).processor(testProcessor).protocolFactory(tProtocolFactory));
+ TServer serverEngine = null;
+
+
+ if (server_type.equals("nonblocking") ||
+ server_type.equals("threaded-selector")) {
+ // Nonblocking servers
+ TNonblockingServerSocket tNonblockingServerSocket =
+ new TNonblockingServerSocket(port);
+
+ if (server_type.equals("nonblocking")) {
+ // Nonblocking Server
+ TNonblockingServer.Args tNonblockingServerArgs
+ = new TNonblockingServer.Args(tNonblockingServerSocket);
+ tNonblockingServerArgs.processor(testProcessor);
+ tNonblockingServerArgs.protocolFactory(tProtocolFactory);
+ tNonblockingServerArgs.transportFactory(tTransportFactory);
+
+ serverEngine = new TNonblockingServer(tNonblockingServerArgs);
+ } else { // server_type.equals("threaded-selector")
+ // ThreadedSelector Server
+ TThreadedSelectorServer.Args tThreadedSelectorServerArgs
+ = new TThreadedSelectorServer.Args(tNonblockingServerSocket);
+ tThreadedSelectorServerArgs.processor(testProcessor);
+ tThreadedSelectorServerArgs.protocolFactory(tProtocolFactory);
+ tThreadedSelectorServerArgs.transportFactory(tTransportFactory);
+
+ serverEngine = new TThreadedSelectorServer(tThreadedSelectorServerArgs);
+ }
+ } else {
+ // Blocking servers
+
+ // SSL socket
+ TServerSocket tServerSocket = null;
+ if (ssl) {
+ tServerSocket = TSSLTransportFactory.getServerSocket(port, 0);
+ } else {
+ tServerSocket = new TServerSocket(port);
+ }
+
+ if (server_type.equals("simple")) {
+ // Simple Server
+ TServer.Args tServerArgs = new TServer.Args(tServerSocket);
+ tServerArgs.processor(testProcessor);
+ tServerArgs.protocolFactory(tProtocolFactory);
+ tServerArgs.transportFactory(tTransportFactory);
+
+ serverEngine = new TSimpleServer(tServerArgs);
+ } else { // server_type.equals("threadpool")
+ // ThreadPool Server
+ TThreadPoolServer.Args tThreadPoolServerArgs
+ = new TThreadPoolServer.Args(tServerSocket);
+ tThreadPoolServerArgs.processor(testProcessor);
+ tThreadPoolServerArgs.protocolFactory(tProtocolFactory);
+ tThreadPoolServerArgs.transportFactory(tTransportFactory);
+
+ serverEngine = new TThreadPoolServer(tThreadPoolServerArgs);
+ }
+ }
+
//Set server event handler
serverEngine.setServerEventHandler(new TestServerEventHandler());
diff --git a/test/test.sh b/test/test.sh
index 4c76d90..76301c1 100755
--- a/test/test.sh
+++ b/test/test.sh
@@ -33,6 +33,18 @@
printf "%-16s %-11s %-17s %-s\n" "client-server:" "protocol:" "transport:" "result:"
}
+intersection() {
+ return_value=""
+ for one in $1; do
+ for two in $2; do
+ if [ ${one} = ${two} ]; then
+ return_value=${return_value}" "${one}
+ fi
+ done;
+ done;
+ echo ${return_value};
+}
+
do_test () {
client_server=$1
protocol=$2
@@ -76,16 +88,39 @@
#TODO add enum for parameters
#TODO align program arguments across languages
-protocols="binary json"
-transports="buffered framed http"
-sockets="ip domain"
+cpp_protocols="binary json"
+java_protocols="binary json compact"
+cpp_transports="buffered framed http"
+java_server_transports="buffered framed fastframed"
+java_client_transports=${java_server_transports}" http"
# we need a test certificate first
-#sockets="ip ip-ssl domain"
+cpp_sockets="ip domain"
+java_sockets="ip ip-ssl"
+# TODO fastframed java transport is another implementation of framed transport
-for proto in $protocols; do
- for trans in $transports; do
- for sock in $sockets; do
+ant -f ../lib/java/build.xml compile-test 1>/dev/null
+
+######### java client - java server #############
+for proto in $java_protocols; do
+ for trans in $java_server_transports; do
+ for sock in $java_sockets; do
+ case "$sock" in
+ "ip" ) extraparam="";;
+ "ip-ssl" ) extraparam="--ssl";;
+ esac
+ do_test "java-java" "${proto}" "${trans}-${sock}" \
+ "ant -f ../lib/java/build.xml -Dno-gen-thrift=\"\" -Dtestargs \"--protocol=${proto} --transport=${trans} ${extraparam}\" testclient" \
+ "ant -f ../lib/java/build.xml -Dno-gen-thrift=\"\" -Dtestargs \"--protocol=${proto} --transport=${trans} ${extraparam}\" testserver" \
+ "15" "15"
+ done
+ done
+done
+
+######### cpp client - cpp server ###############
+for proto in $cpp_protocols; do
+ for trans in $cpp_transports; do
+ for sock in $cpp_sockets; do
case "$sock" in
"ip" ) extraparam="";;
"ip-ssl" ) extraparam="--ssl";;
@@ -94,10 +129,43 @@
do_test "cpp-cpp" "${proto}" "${trans}-${sock}" \
"cpp/TestClient --protocol=${proto} --transport=${trans} ${extraparam}" \
"cpp/TestServer --protocol=${proto} --transport=${trans} ${extraparam}" \
- "10" "5"
- done;
- done;
-done;
+ "10" "10"
+ done
+ done
+done
+
+######### java client - cpp server ##############
+# warning: ssl over http is not supported in java client!
+for proto in $(intersection "${java_protocols}" "${cpp_protocols}"); do
+ for trans in $(intersection "${java_client_transports}" "${cpp_transports}"); do
+ for sock in $(intersection "${java_sockets}" "${cpp_sockets}"); do
+ case "$sock" in
+ "ip" ) extraparam="";;
+ "ip-ssl" ) extraparam="--ssl";;
+ esac
+ do_test "java-cpp" "${proto}" "${trans}-ip" \
+ "ant -f ../lib/java/build.xml -Dno-gen-thrift=\"\" -Dtestargs \"--protocol=${proto} --transport=${trans} ${extraparam}\" testclient" \
+ "cpp/TestServer --protocol=${proto} --transport=${trans} ${extraparam}"\
+ "10" "15"
+ done
+ done
+done
+
+######### cpp client - java server ##############
+for proto in $(intersection "${cpp_protocols}" "${java_protocols}"); do
+ for trans in $(intersection "${cpp_transports}" "${java_server_transports}"); do
+ for sock in $(intersection "${java_sockets}" "${cpp_sockets}"); do
+ case "$sock" in
+ "ip" ) extraparam="";;
+ "ip-ssl" ) extraparam="--ssl";;
+ esac
+ do_test "cpp-java" "${proto}" "${trans}-ip" \
+ "cpp/TestClient --protocol=${proto} --transport=${trans}" \
+ "ant -f ../lib/java/build.xml -Dno-gen-thrift=\"\" -Dtestargs \"--protocol=${proto} --transport=${trans}\" testserver" \
+ "15" "10"
+ done
+ done
+done
# delete Unix Domain Socket used by cpp tests
rm -f /tmp/ThriftTest.thrift
@@ -128,36 +196,20 @@
"10" "10"
do_test "py-java" "binary" "buffered-ip" \
"py/TestClient.py --proto=binary --port=9090 --host=localhost --genpydir=py/gen-py" \
- "ant -f ../lib/java/build.xml testserver" \
- "120" "10"
-do_test "py-java" "json" "buffered-ip" \
+ "ant -f ../lib/java/build.xml -Dno-gen-thrift=\"\" testserver" \
+ "15" "15"
+do_test "py-java" "json" "json-ip" \
"py/TestClient.py --proto=json --port=9090 --host=localhost --genpydir=py/gen-py" \
- "ant -f ../lib/java/build.xml testserver" \
- "120" "10"
+ "ant -f ../lib/java/build.xml -Dno-gen-thrift=\"\" -Dtestargs \"--protocol=json\" testserver" \
+ "15" "10"
do_test "java-py" "binary" "buffered-ip" \
- "ant -f ../lib/java/build.xml testclient" \
+ "ant -f ../lib/java/build.xml -Dno-gen-thrift=\"\" testclient" \
"py/TestServer.py --proto=binary --port=9090 --genpydir=py/gen-py TSimpleServer" \
- "10" "35"
-do_test "java-java" "binary" "buffered-ip" \
- "ant -f ../lib/java/build.xml testclient" \
- "ant -f ../lib/java/build.xml testserver" \
- "120" "35"
-do_test "cpp-java" "binary" "buffered-ip" \
- "cpp/TestClient" \
- "ant -f ../lib/java/build.xml testserver" \
- "100" "10"
-do_test "cpp-java" "json" "buffered-ip" \
- "cpp/TestClient" \
- "ant -f ../lib/java/build.xml testserver" \
- "100" "10"
+ "10" "15"
do_test "js-java" "json " "http-ip" \
"" \
"ant -f ../lib/js/test/build.xml unittest" \
- "120" "10"
-do_test "java-cpp" "binary" "buffered-ip" \
- "ant -f ../lib/java/build.xml testclient" \
- "cpp/TestServer" \
- "10" "35"
+ "10" "15"
do_test "perl-cpp" "binary" "buffered-ip" \
"perl -I perl/gen-perl/ -I../lib/perl/lib/ perl/TestClient.pl" \
"cpp/TestServer" \