From f42ce2a8f49cf09e695974e6cd3c434b8dda61ab Mon Sep 17 00:00:00 2001 From: Roger Meier Date: Wed, 16 Jan 2013 22:12:14 +0100 Subject: [PATCH] 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 --- lib/java/build.xml | 17 +- .../org/apache/thrift/test/TestClient.java | 117 +++++++++--- .../org/apache/thrift/test/TestServer.java | 168 ++++++++++++++++-- test/test.sh | 122 +++++++++---- 4 files changed, 343 insertions(+), 81 deletions(-) diff --git a/lib/java/build.xml b/lib/java/build.xml index 6cf489f0..ddbdfda9 100644 --- a/lib/java/build.xml +++ b/lib/java/build.xml @@ -155,7 +155,12 @@ - + + + + + + @@ -212,15 +217,19 @@ + classpathref="test.classpath" failonerror="true" fork="true"> + + - + classpathref="test.classpath" failonerror="true" fork="true"> + + + diff --git a/lib/java/test/org/apache/thrift/test/TestClient.java b/lib/java/test/org/apache/thrift/test/TestClient.java index a7d5544b..4e7e507c 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.TTransport; 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 class TestClient { 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 @@ public class TestClient { 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 @@ public class TestClient { */ 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 90778824..125a7736 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.Map; 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; 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 class TestServer { 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); + } + + 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); } - //@TODO add other protocol and transport types // Processor TestHandler testHandler = @@ -107,21 +181,85 @@ public class TestServer { 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(); + } + + TTransportFactory tTransportFactory = null; - TServer serverEngine; + 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(); + } - // Simple Server - //serverEngine = new TSimpleServer(new Args(tServerSocket).processor(testProcessor)); + 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); + } + } - // ThreadPool Server - serverEngine = new TThreadPoolServer(new TThreadPoolServer.Args(tServerSocket).processor(testProcessor).protocolFactory(tProtocolFactory)); //Set server event handler serverEngine.setServerEventHandler(new TestServerEventHandler()); diff --git a/test/test.sh b/test/test.sh index 4c76d90f..76301c11 100755 --- a/test/test.sh +++ b/test/test.sh @@ -33,6 +33,18 @@ print_header() { 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 @@ print_header #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 + +ant -f ../lib/java/build.xml compile-test 1>/dev/null -for proto in $protocols; do - for trans in $transports; do - for sock in $sockets; do +######### 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 @@ for proto in $protocols; do 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 @@ do_test "cpp-py" "json" "buffered-ip" \ "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" \ -- 2.17.1