diff options
author | Jon Bratseth <bratseth@yahoo-inc.com> | 2016-06-15 23:09:44 +0200 |
---|---|---|
committer | Jon Bratseth <bratseth@yahoo-inc.com> | 2016-06-15 23:09:44 +0200 |
commit | 72231250ed81e10d66bfe70701e64fa5fe50f712 (patch) | |
tree | 2728bba1131a6f6e5bdf95afec7d7ff9358dac50 /jrt_test |
Publish
Diffstat (limited to 'jrt_test')
87 files changed, 1881 insertions, 0 deletions
diff --git a/jrt_test/.gitignore b/jrt_test/.gitignore new file mode 100644 index 00000000000..a9b20e8992d --- /dev/null +++ b/jrt_test/.gitignore @@ -0,0 +1,2 @@ +Makefile +Testing diff --git a/jrt_test/CMakeLists.txt b/jrt_test/CMakeLists.txt new file mode 100644 index 00000000000..007611e632c --- /dev/null +++ b/jrt_test/CMakeLists.txt @@ -0,0 +1,25 @@ +# Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +vespa_define_module( + DEPENDS + fastos + vespalog + vespalib + fnet + slobrok + configdefinitions + + APPS + src/binref + src/java + src/jrt-test/simpleserver + + TESTS + src/tests/connect-close + src/tests/echo + src/tests/garbage + src/tests/hello-world + src/tests/mandatory-methods + src/tests/mockup-invoke + src/tests/rpc-error + src/tests/slobrok-api +) diff --git a/jrt_test/OWNERS b/jrt_test/OWNERS new file mode 100644 index 00000000000..efd8e309424 --- /dev/null +++ b/jrt_test/OWNERS @@ -0,0 +1,2 @@ +havardpe +arnej27959 diff --git a/jrt_test/README b/jrt_test/README new file mode 100644 index 00000000000..a6899ec6072 --- /dev/null +++ b/jrt_test/README @@ -0,0 +1 @@ +Java Remote Tools tests. Also tests C++ and Java combinations. diff --git a/jrt_test/src/.gitignore b/jrt_test/src/.gitignore new file mode 100644 index 00000000000..a39df0815b3 --- /dev/null +++ b/jrt_test/src/.gitignore @@ -0,0 +1,3 @@ +Makefile.ini +config_command.sh +project.dsw diff --git a/jrt_test/src/binref/.gitignore b/jrt_test/src/binref/.gitignore new file mode 100644 index 00000000000..bf0d7f26c94 --- /dev/null +++ b/jrt_test/src/binref/.gitignore @@ -0,0 +1,7 @@ +.depend +Makefile +compilejava +env.sh +runjava +testspeed +testspeedbig diff --git a/jrt_test/src/binref/CMakeLists.txt b/jrt_test/src/binref/CMakeLists.txt new file mode 100644 index 00000000000..20594f98d02 --- /dev/null +++ b/jrt_test/src/binref/CMakeLists.txt @@ -0,0 +1,5 @@ +# Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. + +configure_file(compilejava.in compilejava @ONLY) +configure_file(runjava.in runjava @ONLY) +configure_file(env.sh.in env.sh @ONLY) diff --git a/jrt_test/src/binref/compilejava.in b/jrt_test/src/binref/compilejava.in new file mode 100755 index 00000000000..d2751bb717d --- /dev/null +++ b/jrt_test/src/binref/compilejava.in @@ -0,0 +1,11 @@ +#!/bin/sh +unset VESPA_LOG_TARGET +CLASSPATH=@PROJECT_BINARY_DIR@/jrt/target/jrt.jar +CLASSPATH=$CLASSPATH:@PROJECT_BINARY_DIR@/vespajlib/target/vespajlib.jar +CLASSPATH=$CLASSPATH:@CMAKE_CURRENT_SOURCE_DIR@/../java/classes +CLASSPATH=$CLASSPATH:. +if [ $# -lt 1 ]; then + echo "usage: compilejava file ..." + exit 1 +fi +exec javac -classpath $CLASSPATH "$@" diff --git a/jrt_test/src/binref/env.sh.in b/jrt_test/src/binref/env.sh.in new file mode 100644 index 00000000000..86c1efbb2aa --- /dev/null +++ b/jrt_test/src/binref/env.sh.in @@ -0,0 +1,15 @@ +BINREF=@CMAKE_CURRENT_BINARY_DIR@ +export BINREF +# port numbers allocated for this module: +PORT_0=18230 +PORT_1=18231 +PORT_2=18232 +PORT_3=18233 +PORT_4=18234 +PORT_5=18235 +PORT_6=18236 +PORT_7=18237 +PORT_8=18238 +PORT_9=18239 +PORT_10=18240 +PORT_11=18241 diff --git a/jrt_test/src/binref/progctl.sh b/jrt_test/src/binref/progctl.sh new file mode 120000 index 00000000000..2c1fb1d47ce --- /dev/null +++ b/jrt_test/src/binref/progctl.sh @@ -0,0 +1 @@ +../../../vespalib/src/vespa/vespalib/testkit/progctl.sh
\ No newline at end of file diff --git a/jrt_test/src/binref/runjava.in b/jrt_test/src/binref/runjava.in new file mode 100755 index 00000000000..5cbc6ba4988 --- /dev/null +++ b/jrt_test/src/binref/runjava.in @@ -0,0 +1,13 @@ +#!/bin/sh +unset VESPA_LOG_TARGET +CLASSPATH=@PROJECT_BINARY_DIR@/jrt/target/jrt.jar +CLASSPATH=$CLASSPATH:@PROJECT_BINARY_DIR@/vespajlib/target/vespajlib.jar +CLASSPATH=$CLASSPATH:@CMAKE_CURRENT_SOURCE_DIR@/../java/classes +CLASSPATH=$CLASSPATH:. +if [ $# -lt 1 ]; then + echo "usage: runjava <class> [args]" + exit 1 +fi +CLASS=$1 +shift +exec java -cp $CLASSPATH $CLASS "$@" diff --git a/jrt_test/src/binref/sbcmd b/jrt_test/src/binref/sbcmd new file mode 120000 index 00000000000..a1cd73591a5 --- /dev/null +++ b/jrt_test/src/binref/sbcmd @@ -0,0 +1 @@ +../../../slobrok/src/apps/sbcmd/sbcmd
\ No newline at end of file diff --git a/jrt_test/src/binref/simpleserver b/jrt_test/src/binref/simpleserver new file mode 120000 index 00000000000..7f1f746f093 --- /dev/null +++ b/jrt_test/src/binref/simpleserver @@ -0,0 +1 @@ +../../../jrt_test/src/jrt-test/simpleserver/jrt_test_simpleserver_app
\ No newline at end of file diff --git a/jrt_test/src/binref/slobrok b/jrt_test/src/binref/slobrok new file mode 120000 index 00000000000..77dae12a032 --- /dev/null +++ b/jrt_test/src/binref/slobrok @@ -0,0 +1 @@ +../../../slobrok/src/apps/slobrok/slobrok
\ No newline at end of file diff --git a/jrt_test/src/binref/testrun.sh b/jrt_test/src/binref/testrun.sh new file mode 120000 index 00000000000..56c3c1186d8 --- /dev/null +++ b/jrt_test/src/binref/testrun.sh @@ -0,0 +1 @@ +../../../vespalib/src/vespa/vespalib/testkit/testrun.sh
\ No newline at end of file diff --git a/jrt_test/src/java/.gitignore b/jrt_test/src/java/.gitignore new file mode 100644 index 00000000000..c7d02fa8c22 --- /dev/null +++ b/jrt_test/src/java/.gitignore @@ -0,0 +1,3 @@ +build.inc +classes +jrt-test.jar diff --git a/jrt_test/src/java/CMakeLists.txt b/jrt_test/src/java/CMakeLists.txt new file mode 100644 index 00000000000..60ebc1b930b --- /dev/null +++ b/jrt_test/src/java/CMakeLists.txt @@ -0,0 +1,8 @@ +# Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +file(MAKE_DIRECTORY classes) +add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/java_code_compiled + COMMAND ${CMAKE_CURRENT_BINARY_DIR}/../binref/compilejava -d classes *.java + COMMAND ${CMAKE_COMMAND} -E touch ${CMAKE_CURRENT_BINARY_DIR}/java_code_compiled + DEPENDS DummySlobrokService.java HelloWorld.java PollRPCServer.java SimpleServer.java + WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}) +add_custom_target(jrt_test_java ALL DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/java_code_compiled) diff --git a/jrt_test/src/java/DummySlobrokService.java b/jrt_test/src/java/DummySlobrokService.java new file mode 100644 index 00000000000..3fcc51dcb39 --- /dev/null +++ b/jrt_test/src/java/DummySlobrokService.java @@ -0,0 +1,40 @@ +// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +import com.yahoo.jrt.*; +import com.yahoo.jrt.slobrok.api.*; + +public class DummySlobrokService { + public static void main(String args[]) { + if (args.length < 3) { + System.err.println("Usage: DummySlobrokService <myspec> " + + "<slobrokspec> <service> [service] ..."); + System.exit(1); + } + Spec mySpec = new Spec(args[0]); + String[] slobroks = new String[1]; + slobroks[0] = args[1]; + SlobrokList slist = new SlobrokList(); + slist.setup(slobroks); + int serviceCnt = args.length - 2; + String[] serviceList = new String[serviceCnt]; + for (int i = 0; i < serviceCnt; i++) { + serviceList[i] = args[i + 2]; + } + Supervisor orb = new Supervisor(new Transport()); + Spec listenSpec = new Spec(mySpec.port()); + try { + Acceptor acceptor = orb.listen(listenSpec); + System.out.println("Listening at " + listenSpec); + Register reg = new Register(orb, slist, + mySpec.host(), mySpec.port()); + for (int i = 0; i < serviceList.length; i++) { + System.out.println("trying to register " + serviceList[i]); + reg.registerName(serviceList[i]); + } + orb.transport().join(); + acceptor.shutdown().join(); + } catch (ListenFailedException e) { + System.err.println("Could not listen at " + listenSpec); + orb.transport().shutdown().join(); + } + } +} diff --git a/jrt_test/src/java/HelloWorld.java b/jrt_test/src/java/HelloWorld.java new file mode 100644 index 00000000000..d9f0e934d18 --- /dev/null +++ b/jrt_test/src/java/HelloWorld.java @@ -0,0 +1,8 @@ +// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +public class HelloWorld +{ + public static void main(String[] args) + { + System.out.println("Hello World!"); + } +} diff --git a/jrt_test/src/java/PollRPCServer.java b/jrt_test/src/java/PollRPCServer.java new file mode 100644 index 00000000000..bf47762e139 --- /dev/null +++ b/jrt_test/src/java/PollRPCServer.java @@ -0,0 +1,35 @@ +// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. + +import com.yahoo.jrt.*; + +public class PollRPCServer { + + public static void main(String[] args) { + if (args.length != 1) { + System.err.println("usage: PollRPCServer <spec>"); + System.exit(1); + } + Transport transport = new Transport(); + Supervisor orb = new Supervisor(transport); + Target target = orb.connect(new Spec(args[0])); + Request req = new Request("frt.rpc.ping"); + int retry = 0; + System.out.print("polling '" + args[0] + "' "); + while (true) { + target.invokeSync(req, 60.0); + System.out.print("."); + if (req.errorCode() != ErrorCode.CONNECTION + || ++retry == 500) { + break; + } + try { Thread.sleep(250); } catch (Exception e) {} + target = orb.connect(new Spec(args[0])); + req = new Request("frt.rpc.ping"); + } + if (req.isError()) { + System.out.println(" fail"); + System.exit(1); + } + System.out.println(" ok"); + } +} diff --git a/jrt_test/src/java/SimpleServer.java b/jrt_test/src/java/SimpleServer.java new file mode 100644 index 00000000000..b2859b65f65 --- /dev/null +++ b/jrt_test/src/java/SimpleServer.java @@ -0,0 +1,50 @@ +// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. + +import com.yahoo.jrt.*; + +public class SimpleServer { + + public void rpc_inc(Request req) { + req.returnValues().add(new Int32Value(req.parameters().get(0).asInt32() + + 1)); + } + + public void rpc_echo(Request req) { + for (int i = 0; i < req.parameters().size(); i++) { + req.returnValues().add(req.parameters().get(i)); + } + } + + public void rpc_test(Request req) { + int value = req.parameters().get(0).asInt32(); + int error = req.parameters().get(1).asInt32(); + int extra = req.parameters().get(2).asInt8(); + + req.returnValues().add(new Int32Value(value)); + if (extra != 0) { + req.returnValues().add(new Int32Value(value)); + } + if (error != 0) { + req.setError(error, "Custom error"); + } + } + + public static void main(String[] args) { + if (args.length != 1) { + System.err.println("usage: SimpleServer <spec>"); + System.exit(1); + } + Supervisor orb = new Supervisor(new Transport()); + SimpleServer handler = new SimpleServer(); + orb.addMethod(new Method("inc", "i", "i", handler, "rpc_inc")); + orb.addMethod(new Method("echo", "*", "*", handler, "rpc_echo")); + orb.addMethod(new Method("test", "iib", "i", handler, "rpc_test")); + try { + orb.listen(new Spec(args[0])); + } catch (ListenFailedException e) { + System.err.println("could not listen at " + args[0]); + System.exit(1); + } + orb.transport().join(); + } +} diff --git a/jrt_test/src/java/build.xml b/jrt_test/src/java/build.xml new file mode 100644 index 00000000000..1b9afee3d15 --- /dev/null +++ b/jrt_test/src/java/build.xml @@ -0,0 +1,62 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. --> +<project basedir="." default="all" name="jrt-test"> + <!-- Written to assume that classpath is rooted in the current directory. --> + <!-- So this should be OK if you make this script in the root of a filesystem. --> + <!-- If not, just change src.dir to be the root of your sources' package tree --> + <!-- and use e.g. View over a Filesystem to mount that subdirectory with all capabilities. --> + <!-- The idea is that both Ant and NetBeans have to know what the package root is --> + <!-- for the classes in your application. --> + + <!-- Don't worry if you don't know the Ant syntax completely or need help on some tasks! --> + <!-- The standard Ant documentation can be downloaded from AutoUpdate and --> + <!-- and then you can access the Ant manual in the online help. --> + + <property file="build.inc" /> + + <target name="init"> + <property location="classes" name="classes.dir"/> + <property location="." name="src.dir"/> + <property location="doc/api" name="javadoc.dir"/> + <property name="project.name" value="${ant.project.name}"/> + <property location="${project.name}.jar" name="jar"/> + </target> + + <target depends="init" name="compile"> + <!-- Both srcdir and destdir should be package roots. --> + <mkdir dir="${classes.dir}"/> + <javac debug="true" deprecation="true" destdir="${classes.dir}" srcdir="${src.dir}"> + <classpath> + <pathelement location="${JRT_DIR}/lib/jars/jrt.jar"/> + </classpath> + <!-- To add something to the classpath: --> + <!-- <classpath><pathelement location="${mylib}"/></classpath> --> + <!-- To exclude some files: --> + <!-- <exclude name="com/foo/SomeFile.java"/><exclude name="com/foo/somepackage/"/> --> + </javac> + </target> + + <target depends="init,compile" name="jar"> + <!-- To make a standalone app, insert into <jar>: --> + <!-- <manifest><attribute name="Main-Class" value="com.foo.Main"/></manifest> --> + <jar basedir="${classes.dir}" compress="true" jarfile="${jar}"/> + </target> + + <target depends="init,jar" description="Build everything." name="all"/> + + <target depends="init" description="Javadoc for my API." name="javadoc"> + <mkdir dir="${javadoc.dir}"/> + <javadoc destdir="${javadoc.dir}" packagenames="*"> + <sourcepath> + <pathelement location="${src.dir}"/> + </sourcepath> + </javadoc> + </target> + + <target depends="init" description="Clean all build products." name="clean"> + <delete dir="${classes.dir}"/> + <delete dir="${javadoc.dir}"/> + <delete file="${jar}"/> + </target> + +</project> diff --git a/jrt_test/src/jrt-test/simpleserver/.gitignore b/jrt_test/src/jrt-test/simpleserver/.gitignore new file mode 100644 index 00000000000..7dbb2b11ddc --- /dev/null +++ b/jrt_test/src/jrt-test/simpleserver/.gitignore @@ -0,0 +1,4 @@ +.depend +Makefile +simpleserver +jrt_test_simpleserver_app diff --git a/jrt_test/src/jrt-test/simpleserver/CMakeLists.txt b/jrt_test/src/jrt-test/simpleserver/CMakeLists.txt new file mode 100644 index 00000000000..922fa7edf49 --- /dev/null +++ b/jrt_test/src/jrt-test/simpleserver/CMakeLists.txt @@ -0,0 +1,7 @@ +# Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +vespa_add_executable(jrt_test_simpleserver_app + SOURCES + simpleserver.cpp + INSTALL bin + DEPENDS +) diff --git a/jrt_test/src/jrt-test/simpleserver/simpleserver.cpp b/jrt_test/src/jrt-test/simpleserver/simpleserver.cpp new file mode 100644 index 00000000000..ef13973c0ce --- /dev/null +++ b/jrt_test/src/jrt-test/simpleserver/simpleserver.cpp @@ -0,0 +1,102 @@ +// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +#include <vespa/log/log.h> +LOG_SETUP("simpleserver"); +#include <vespa/fastos/fastos.h> +#include <vespa/fnet/frt/frt.h> + + +class Server : public FRT_Invokable +{ +private: + Server(const Server &); + Server &operator=(const Server &); + +public: + Server(FRT_Supervisor *s) + { + FRT_ReflectionBuilder rb(s); + //--------------------------------------------------------------------- + rb.DefineMethod("inc", "i", "i", true, + FRT_METHOD(Server::rpc_inc), this); + rb.MethodDesc("Increase an integer value"); + rb.ParamDesc("value", "initial value"); + rb.ReturnDesc("result", "value + 1"); + //--------------------------------------------------------------------- + rb.DefineMethod("blob", "x", "x", true, + FRT_METHOD(Server::rpc_blob), this); + rb.MethodDesc("Send a copy of a blob back to the client"); + rb.ParamDesc("blob", "the original blob"); + rb.ReturnDesc("blob", "a copy of the original blob"); + //--------------------------------------------------------------------- + rb.DefineMethod("test", "iib", "i", true, + FRT_METHOD(Server::rpc_test), this); + rb.MethodDesc("Magic test method"); + rb.ParamDesc("value", "the value"); + rb.ParamDesc("error", "error code to set"); + rb.ParamDesc("extra", "if not 0, add an extra return value"); + rb.ReturnDesc("value", "the value"); + //--------------------------------------------------------------------- + } + + void rpc_inc(FRT_RPCRequest *req) + { + req->GetReturn()->AddInt32(req->GetParams()->GetValue(0)._intval32 + + 1); + } + + void rpc_blob(FRT_RPCRequest *req) + { + req->GetReturn()->AddData(req->GetParams()->GetValue(0)._data._buf, + req->GetParams()->GetValue(0)._data._len); + } + + void rpc_test(FRT_RPCRequest *req) + { + int value = req->GetParams()->GetValue(0)._intval32; + int error = req->GetParams()->GetValue(1)._intval32; + int extra = req->GetParams()->GetValue(2)._intval8; + + req->GetReturn()->AddInt32(value); + if (extra != 0) { + req->GetReturn()->AddInt32(value); + } + if (error != 0) { + req->SetError(error, "Custom error"); + } + } +}; + + +class App : public FastOS_Application +{ +public: + int Main(); +}; + + +int +App::Main() +{ + if (_argc < 2) { + printf("usage: %s <listenspec> [ddw]\n", _argv[0]); + printf(" ddw = disable direct write\n"); + return 1; + } + FRT_Supervisor orb; + if (_argc >= 3 && strcmp(_argv[2], "ddw") == 0) { + printf("(direct write disabled)\n"); + orb.GetTransport()->SetDirectWrite(false); + } + Server server(&orb); + orb.Listen(_argv[1]); + orb.Main(); + return 0; +} + + +int +main(int argc, char **argv) +{ + App myapp; + return myapp.Entry(argc, argv); +} diff --git a/jrt_test/src/testlist.txt b/jrt_test/src/testlist.txt new file mode 100644 index 00000000000..44524219796 --- /dev/null +++ b/jrt_test/src/testlist.txt @@ -0,0 +1,8 @@ +tests/connect-close +tests/echo +tests/garbage +tests/hello-world +tests/mandatory-methods +tests/mockup-invoke +tests/rpc-error +tests/slobrok-api diff --git a/jrt_test/src/tests/connect-close/.gitignore b/jrt_test/src/tests/connect-close/.gitignore new file mode 100644 index 00000000000..3e5691f8847 --- /dev/null +++ b/jrt_test/src/tests/connect-close/.gitignore @@ -0,0 +1,3 @@ +.depend +Makefile +Test.class diff --git a/jrt_test/src/tests/connect-close/CMakeLists.txt b/jrt_test/src/tests/connect-close/CMakeLists.txt new file mode 100644 index 00000000000..5c90dd5bfcc --- /dev/null +++ b/jrt_test/src/tests/connect-close/CMakeLists.txt @@ -0,0 +1 @@ +# Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. diff --git a/jrt_test/src/tests/connect-close/DESC b/jrt_test/src/tests/connect-close/DESC new file mode 100644 index 00000000000..d39f23bc4f2 --- /dev/null +++ b/jrt_test/src/tests/connect-close/DESC @@ -0,0 +1 @@ +Try to uncover bad behavior related to closing connections. diff --git a/jrt_test/src/tests/connect-close/FILES b/jrt_test/src/tests/connect-close/FILES new file mode 100644 index 00000000000..f24627b5d6d --- /dev/null +++ b/jrt_test/src/tests/connect-close/FILES @@ -0,0 +1 @@ +Test.java diff --git a/jrt_test/src/tests/connect-close/Test.java b/jrt_test/src/tests/connect-close/Test.java new file mode 100644 index 00000000000..8d42e821887 --- /dev/null +++ b/jrt_test/src/tests/connect-close/Test.java @@ -0,0 +1,39 @@ +// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. + +import com.yahoo.jrt.*; + +public class Test implements FatalErrorHandler { + + boolean error = false; + int port = 0; + + public void handleFailure(Throwable t, Object o) { + System.err.println("FATAL ERROR -> " + o); + t.printStackTrace(); + error = true; + } + + public void myMain() { + Supervisor server = new Supervisor(new Transport(this)); + Supervisor client = new Supervisor(new Transport(this)); + try { + port = server.listen(new Spec(0)).port(); // random port + } catch (ListenFailedException e) { + System.err.println("Listen failed"); + System.exit(1); + } + + Target a = client.connect(new Spec("localhost", port)); + + server.transport().shutdown().join(); + client.transport().shutdown().join(); + + if (error) { + System.exit(1); + } + } + + public static void main(String[] args) { + new Test().myMain(); + } +} diff --git a/jrt_test/src/tests/echo/.gitignore b/jrt_test/src/tests/echo/.gitignore new file mode 100644 index 00000000000..9a2c3782c92 --- /dev/null +++ b/jrt_test/src/tests/echo/.gitignore @@ -0,0 +1,7 @@ +.depend +EchoServer.class +Makefile +echo-client +out.javaserver.1 +out.txt +jrt_test_echo-client_app diff --git a/jrt_test/src/tests/echo/CMakeLists.txt b/jrt_test/src/tests/echo/CMakeLists.txt new file mode 100644 index 00000000000..3ac6183a27d --- /dev/null +++ b/jrt_test/src/tests/echo/CMakeLists.txt @@ -0,0 +1,7 @@ +# Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +vespa_add_executable(jrt_test_echo-client_app + SOURCES + echo-client.cpp + DEPENDS +) +vespa_add_test(NAME jrt_test_echo-client_app NO_VALGRIND COMMAND sh echo_test.sh) diff --git a/jrt_test/src/tests/echo/DESC b/jrt_test/src/tests/echo/DESC new file mode 100644 index 00000000000..20d168f6385 --- /dev/null +++ b/jrt_test/src/tests/echo/DESC @@ -0,0 +1,3 @@ +Invoke a method that returns the parameters using all different value +types. The server is written in Java while the client is written in +C++. diff --git a/jrt_test/src/tests/echo/FILES b/jrt_test/src/tests/echo/FILES new file mode 100644 index 00000000000..cc0b575f983 --- /dev/null +++ b/jrt_test/src/tests/echo/FILES @@ -0,0 +1,5 @@ +dotest.sh +out.txt +ref.txt +echo-client.cpp +out.javaserver.1 diff --git a/jrt_test/src/tests/echo/dotest.sh b/jrt_test/src/tests/echo/dotest.sh new file mode 100644 index 00000000000..a01bf1e06ef --- /dev/null +++ b/jrt_test/src/tests/echo/dotest.sh @@ -0,0 +1,15 @@ +#!/bin/sh +# Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. + +. ../../binref/env.sh +export PORT_2 +sh $BINREF/progctl.sh progdefs.sh start javaserver 1 +$BINREF/runjava PollRPCServer tcp/localhost:$PORT_2 +$VALGRIND ./jrt_test_echo-client_app tcp/localhost:$PORT_2 > out.txt +sh $BINREF/progctl.sh progdefs.sh stop javaserver 1 + +if diff -u out.txt ref.txt; then + exit 0 +else + exit 1 +fi diff --git a/jrt_test/src/tests/echo/echo-client.cpp b/jrt_test/src/tests/echo/echo-client.cpp new file mode 100644 index 00000000000..4d246431793 --- /dev/null +++ b/jrt_test/src/tests/echo/echo-client.cpp @@ -0,0 +1,91 @@ +// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +#include <vespa/log/log.h> +LOG_SETUP("echo_client"); +#include <vespa/fastos/fastos.h> +#include <vespa/fnet/frt/frt.h> + +class EchoClient : public FastOS_Application +{ +public: + int Main() + { + if (_argc < 2) { + printf("usage : echo_client <connectspec>\n"); + return 1; + } + FRT_Supervisor supervisor; + + supervisor.Start(); + FRT_Target *target = supervisor.GetTarget(_argv[1]); + FRT_RPCRequest *req = supervisor.AllocRPCRequest(); + FRT_Values *args = req->GetParams(); + req->SetMethodName("echo"); + args->EnsureFree(16); + + args->AddInt8(8); + uint8_t *pt_int8 = args->AddInt8Array(3); + pt_int8[0] = 1; + pt_int8[1] = 2; + pt_int8[2] = 3; + + args->AddInt16(16); + uint16_t *pt_int16 = args->AddInt16Array(3); + pt_int16[0] = 2; + pt_int16[1] = 4; + pt_int16[2] = 6; + + args->AddInt32(32); + uint32_t *pt_int32 = args->AddInt32Array(3); + pt_int32[0] = 4; + pt_int32[1] = 8; + pt_int32[2] = 12; + + args->AddInt64(64); + uint64_t *pt_int64 = args->AddInt64Array(3); + pt_int64[0] = 8; + pt_int64[1] = 16; + pt_int64[2] = 24; + + args->AddFloat(32.5); + float *pt_float = args->AddFloatArray(3); + pt_float[0] = 0.25; + pt_float[1] = 0.5; + pt_float[2] = 0.75; + + args->AddDouble(64.5); + double *pt_double = args->AddDoubleArray(3); + pt_double[0] = 0.1; + pt_double[1] = 0.2; + pt_double[2] = 0.3; + + args->AddString("string"); + FRT_StringValue *pt_string = args->AddStringArray(3); + args->SetString(&pt_string[0], "str1"); + args->SetString(&pt_string[1], "str2"); + args->SetString(&pt_string[2], "str3"); + + args->AddData("data", 4); + FRT_DataValue *pt_data = args->AddDataArray(3); + args->SetData(&pt_data[0], "dat1", 4); + args->SetData(&pt_data[1], "dat2", 4); + args->SetData(&pt_data[2], "dat3", 4); + + target->InvokeSync(req, 60.0); // Invoke + req->Print(); // Dump request data + if (req->GetReturn()->Equals(req->GetParams())) { + printf("Return values == parameters.\n"); + } else { + printf("Return values != parameters.\n"); + } + req->SubRef(); + supervisor.ShutDown(true); + return 0; + } +}; + +int +main(int argc, char **argv) +{ + EchoClient myapp; + return myapp.Entry(argc, argv); +} diff --git a/jrt_test/src/tests/echo/echo_test.sh b/jrt_test/src/tests/echo/echo_test.sh new file mode 100755 index 00000000000..49241e787f5 --- /dev/null +++ b/jrt_test/src/tests/echo/echo_test.sh @@ -0,0 +1,4 @@ +#!/bin/bash +. ../../binref/env.sh +sh dotest.sh || (sh $BINREF/progctl.sh progdefs.sh stop all; false) +sh $BINREF/progctl.sh progdefs.sh stop all diff --git a/jrt_test/src/tests/echo/progdefs.sh b/jrt_test/src/tests/echo/progdefs.sh new file mode 100644 index 00000000000..4a3053ad64e --- /dev/null +++ b/jrt_test/src/tests/echo/progdefs.sh @@ -0,0 +1,2 @@ +# Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +prog javaserver 1 "tcp/$PORT_2" "$BINREF/runjava SimpleServer" diff --git a/jrt_test/src/tests/echo/ref.txt b/jrt_test/src/tests/echo/ref.txt new file mode 100644 index 00000000000..c7252f5e2d6 --- /dev/null +++ b/jrt_test/src/tests/echo/ref.txt @@ -0,0 +1,109 @@ +FRT_RPCRequest { + method: echo + error(0): No error + params: + FRT_Values { + [bBhHiIlLfFdDsSxX] + int8: 8 + int8_array { + int8: 1 + int8: 2 + int8: 3 + } + int16: 16 + int16_array { + int16: 2 + int16: 4 + int16: 6 + } + int32: 32 + int32_array { + int32: 4 + int32: 8 + int32: 12 + } + int64: 64 + int64_array { + int64: 8 + int64: 16 + int64: 24 + } + float: 32.500000 + float_array { + float: 0.250000 + float: 0.500000 + float: 0.750000 + } + double: 64.500000 + double_array { + double: 0.100000 + double: 0.200000 + double: 0.300000 + } + string: string + string_array { + string: str1 + string: str2 + string: str3 + } + data: len=4 + data_array { + data: len=4 + data: len=4 + data: len=4 + } + } + return: + FRT_Values { + [bBhHiIlLfFdDsSxX] + int8: 8 + int8_array { + int8: 1 + int8: 2 + int8: 3 + } + int16: 16 + int16_array { + int16: 2 + int16: 4 + int16: 6 + } + int32: 32 + int32_array { + int32: 4 + int32: 8 + int32: 12 + } + int64: 64 + int64_array { + int64: 8 + int64: 16 + int64: 24 + } + float: 32.500000 + float_array { + float: 0.250000 + float: 0.500000 + float: 0.750000 + } + double: 64.500000 + double_array { + double: 0.100000 + double: 0.200000 + double: 0.300000 + } + string: string + string_array { + string: str1 + string: str2 + string: str3 + } + data: len=4 + data_array { + data: len=4 + data: len=4 + data: len=4 + } + } +} +Return values == parameters. diff --git a/jrt_test/src/tests/garbage/.gitignore b/jrt_test/src/tests/garbage/.gitignore new file mode 100644 index 00000000000..c73b0e5d28d --- /dev/null +++ b/jrt_test/src/tests/garbage/.gitignore @@ -0,0 +1,4 @@ +.depend +Garbage$Closer.class +Garbage.class +Makefile diff --git a/jrt_test/src/tests/garbage/CMakeLists.txt b/jrt_test/src/tests/garbage/CMakeLists.txt new file mode 100644 index 00000000000..5c90dd5bfcc --- /dev/null +++ b/jrt_test/src/tests/garbage/CMakeLists.txt @@ -0,0 +1 @@ +# Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. diff --git a/jrt_test/src/tests/garbage/DESC b/jrt_test/src/tests/garbage/DESC new file mode 100644 index 00000000000..c63c00cfc58 --- /dev/null +++ b/jrt_test/src/tests/garbage/DESC @@ -0,0 +1,4 @@ +See what happens when feeding an RPC server garbage input. This +particular test is based on Java interpreting the packet size as +negative and therefore can determine that this is garbage from the +packet header alone. diff --git a/jrt_test/src/tests/garbage/FILES b/jrt_test/src/tests/garbage/FILES new file mode 100644 index 00000000000..8767d7c6974 --- /dev/null +++ b/jrt_test/src/tests/garbage/FILES @@ -0,0 +1 @@ +Garbage.java diff --git a/jrt_test/src/tests/garbage/Garbage.java b/jrt_test/src/tests/garbage/Garbage.java new file mode 100644 index 00000000000..65d935e81a7 --- /dev/null +++ b/jrt_test/src/tests/garbage/Garbage.java @@ -0,0 +1,99 @@ +// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +import com.yahoo.jrt.*; +import java.net.Socket; +import java.io.OutputStream; +import java.io.InputStream; +import java.io.IOException; + +public class Garbage implements FatalErrorHandler { + + boolean error = false; + int port = 0; + + public void handleFailure(Throwable t, Object o) { + System.err.println("FATAL ERROR -> " + o); + t.printStackTrace(); + error = true; + } + + class Closer implements Runnable { + private boolean done = false; + private Socket socket = null; + + public Closer(Socket s) { + socket = s; + } + + public void done() { + synchronized (this) { + done = true; + notify(); + } + } + + public void run() { + long t = System.currentTimeMillis(); + long end = t + 60000; + synchronized (this) { + while (!done) { + if (t >= end) { + error = true; + try { socket.close(); } catch (IOException e) { + System.err.println("AAARGH!!"); + System.exit(1); + } + return; + } + try { wait(end - t); } catch (InterruptedException ignore) {} + t = System.currentTimeMillis(); + } + } + } + } + + public void myMain() { + Supervisor server = new Supervisor(new Transport(this)); + try { + port = server.listen(new Spec(0)).port(); // random port + } catch (ListenFailedException e) { + System.err.println("Listen failed"); + System.exit(1); + } + + try { + Socket s = new Socket("localhost", port); + InputStream in = s.getInputStream(); + OutputStream out = s.getOutputStream(); + byte[] data = {(byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, + (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, + (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff}; + out.write(data); + out.flush(); + Closer closer = new Closer(s); + new Thread(closer).start(); + try { + if (in.read() != -1) { + error = true; + } + } finally { + closer.done(); + } + } catch (IOException e) { + System.err.println(e); + error = true; + } + + server.transport().shutdown().join(); + + if (error) { + System.err.println("TEST FAILED!"); + System.exit(1); + } else { + System.err.println("test passed"); + } + } + + public static void main(String[] args) { + new Garbage().myMain(); + } +} diff --git a/jrt_test/src/tests/hello-world/.gitignore b/jrt_test/src/tests/hello-world/.gitignore new file mode 100644 index 00000000000..565c2df422c --- /dev/null +++ b/jrt_test/src/tests/hello-world/.gitignore @@ -0,0 +1,3 @@ +.depend +Makefile +out.txt diff --git a/jrt_test/src/tests/hello-world/CMakeLists.txt b/jrt_test/src/tests/hello-world/CMakeLists.txt new file mode 100644 index 00000000000..5c90dd5bfcc --- /dev/null +++ b/jrt_test/src/tests/hello-world/CMakeLists.txt @@ -0,0 +1 @@ +# Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. diff --git a/jrt_test/src/tests/hello-world/DESC b/jrt_test/src/tests/hello-world/DESC new file mode 100644 index 00000000000..de4b2bda136 --- /dev/null +++ b/jrt_test/src/tests/hello-world/DESC @@ -0,0 +1 @@ +Test running a hello world java program.
\ No newline at end of file diff --git a/jrt_test/src/tests/hello-world/FILES b/jrt_test/src/tests/hello-world/FILES new file mode 100644 index 00000000000..8bdeb70b5ed --- /dev/null +++ b/jrt_test/src/tests/hello-world/FILES @@ -0,0 +1,3 @@ +fastos.project +out.txt +ref.txt diff --git a/jrt_test/src/tests/hello-world/ref.txt b/jrt_test/src/tests/hello-world/ref.txt new file mode 100644 index 00000000000..980a0d5f19a --- /dev/null +++ b/jrt_test/src/tests/hello-world/ref.txt @@ -0,0 +1 @@ +Hello World! diff --git a/jrt_test/src/tests/mandatory-methods/.gitignore b/jrt_test/src/tests/mandatory-methods/.gitignore new file mode 100644 index 00000000000..c5d116be3c2 --- /dev/null +++ b/jrt_test/src/tests/mandatory-methods/.gitignore @@ -0,0 +1,8 @@ +.depend +Makefile +RPCServer.class +extract-reflection +out.javaserver.1 +out.txt +pid.txt +jrt_test_extract-reflection_app diff --git a/jrt_test/src/tests/mandatory-methods/CMakeLists.txt b/jrt_test/src/tests/mandatory-methods/CMakeLists.txt new file mode 100644 index 00000000000..f4496d86cbb --- /dev/null +++ b/jrt_test/src/tests/mandatory-methods/CMakeLists.txt @@ -0,0 +1,7 @@ +# Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +vespa_add_executable(jrt_test_extract-reflection_app + SOURCES + extract-reflection.cpp + DEPENDS +) +vespa_add_test(NAME jrt_test_extract-reflection_app NO_VALGRIND COMMAND sh mandatory-methods_test.sh) diff --git a/jrt_test/src/tests/mandatory-methods/DESC b/jrt_test/src/tests/mandatory-methods/DESC new file mode 100644 index 00000000000..2cb4f467a2e --- /dev/null +++ b/jrt_test/src/tests/mandatory-methods/DESC @@ -0,0 +1,10 @@ +Test the mandatory methods of a Java RPC server +(ping/reflection). This is done by using a C++ client against a +barebone Java server. The ping method is used to poll the server while +waiting for it to come up. The reflection methods are used to extract +reflection information about the mandatory methods, which is checked +against a checked-in expected result. + +This test will break easily if the documentation of the mandatory +methods is changed or if the method iteration order is changed. This +will not happen often, and the test is easily updated. diff --git a/jrt_test/src/tests/mandatory-methods/FILES b/jrt_test/src/tests/mandatory-methods/FILES new file mode 100644 index 00000000000..4bfb761c16d --- /dev/null +++ b/jrt_test/src/tests/mandatory-methods/FILES @@ -0,0 +1,6 @@ +dotest.sh +out.txt +ref.txt +RPCServer.java +extract-reflection.cpp +out.javaserver.1 diff --git a/jrt_test/src/tests/mandatory-methods/RPCServer.java b/jrt_test/src/tests/mandatory-methods/RPCServer.java new file mode 100644 index 00000000000..a9fe3bae7b0 --- /dev/null +++ b/jrt_test/src/tests/mandatory-methods/RPCServer.java @@ -0,0 +1,21 @@ +// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. + +import com.yahoo.jrt.*; + +public class RPCServer { + + public static void main(String[] args) { + if (args.length != 1) { + System.err.println("usage: RPCServer <spec>"); + System.exit(1); + } + Supervisor orb = new Supervisor(new Transport()); + try { + orb.listen(new Spec(args[0])); + } catch (ListenFailedException e) { + System.err.println("could not listen at " + args[0]); + System.exit(1); + } + orb.transport().join(); + } +} diff --git a/jrt_test/src/tests/mandatory-methods/dotest.sh b/jrt_test/src/tests/mandatory-methods/dotest.sh new file mode 100644 index 00000000000..25560a6210d --- /dev/null +++ b/jrt_test/src/tests/mandatory-methods/dotest.sh @@ -0,0 +1,14 @@ +#!/bin/sh +# Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. + +sh $BINREF/progctl.sh progdefs.sh start javaserver 1 + +./jrt_test_extract-reflection_app tcp/localhost:$PORT_1 verbose > out.txt + +sh $BINREF/progctl.sh progdefs.sh stop javaserver 1 + +if diff -u out.txt ref.txt; then + exit 0 +else + exit 1 +fi diff --git a/jrt_test/src/tests/mandatory-methods/extract-reflection.cpp b/jrt_test/src/tests/mandatory-methods/extract-reflection.cpp new file mode 100644 index 00000000000..7b92997cfdf --- /dev/null +++ b/jrt_test/src/tests/mandatory-methods/extract-reflection.cpp @@ -0,0 +1,145 @@ +// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. + +#include <vespa/fastos/fastos.h> +#include <vespa/fnet/frt/frt.h> + +class RPCInfo : public FastOS_Application +{ +public: + + void GetReq(FRT_RPCRequest **req, FRT_Supervisor *supervisor) + { + if ((*req) != NULL) + (*req)->SubRef(); + (*req) = supervisor->AllocRPCRequest(); + } + + void FreeReqs(FRT_RPCRequest *r1, FRT_RPCRequest *r2) + { + if (r1 != NULL) + r1->SubRef(); + if (r2 != NULL) + r2->SubRef(); + } + + void DumpMethodInfo(const char *indent, FRT_RPCRequest *info, + const char *name) + { + if (info->IsError()) { + printf("%sMETHOD %s\n", indent, name); + printf("%s [error(%d): %s]\n\n", indent, + info->GetErrorCode(), + info->GetErrorMessage()); + return; + } + + const char *desc = info->GetReturn()->GetValue(0)._string._str; + const char *arg = info->GetReturn()->GetValue(1)._string._str; + const char *ret = info->GetReturn()->GetValue(2)._string._str; + uint32_t argCnt = strlen(arg); + uint32_t retCnt = strlen(ret); + FRT_StringValue *argName = info->GetReturn()->GetValue(3)._string_array._pt; + FRT_StringValue *argDesc = info->GetReturn()->GetValue(4)._string_array._pt; + FRT_StringValue *retName = info->GetReturn()->GetValue(5)._string_array._pt; + FRT_StringValue *retDesc = info->GetReturn()->GetValue(6)._string_array._pt; + + printf("%sMETHOD %s\n", indent, name); + printf("%s DESCRIPTION:\n" + "%s %s\n", indent, indent, desc); + + if (argCnt > 0) { + printf("%s PARAMS:\n", indent); + for (uint32_t a = 0; a < argCnt; a++) + printf("%s [%c][%s] %s\n", indent, arg[a], argName[a]._str, + argDesc[a]._str); + } + + if (retCnt > 0) { + printf("%s RETURN:\n", indent); + for (uint32_t r = 0; r < retCnt; r++) + printf("%s [%c][%s] %s\n", indent, ret[r], retName[r]._str, + retDesc[r]._str); + } + printf("\n"); + } + + + int Main() + { + if (_argc < 2) { + printf("usage : rpc_info <connectspec> [verbose]\n"); + return 1; + } + + bool verbose = (_argc > 2 && strcmp(_argv[2], "verbose") == 0); + FRT_Supervisor supervisor; + FRT_Target *target = supervisor.GetTarget(_argv[1]); + FRT_RPCRequest *m_list = NULL; + FRT_RPCRequest *info = NULL; + supervisor.Start(); + + for (int i = 0; i < 50; i++) { + GetReq(&info, &supervisor); + info->SetMethodName("frt.rpc.ping"); + target->InvokeSync(info, 60.0); + if (info->GetErrorCode() != FRTE_RPC_CONNECTION) { + break; + } + FastOS_Thread::Sleep(1000); + target->SubRef(); + target = supervisor.GetTarget(_argv[1]); + } + if (info->IsError()) { + fprintf(stderr, "Error talking to %s\n", _argv[1]); + info->Print(); + FreeReqs(m_list, info); + supervisor.ShutDown(true); + return 1; + } + + GetReq(&m_list, &supervisor); + m_list->SetMethodName("frt.rpc.getMethodList"); + target->InvokeSync(m_list, 60.0); + + if (!m_list->IsError()) { + + uint32_t numMethods = m_list->GetReturn()->GetValue(0)._string_array._len; + FRT_StringValue *methods = m_list->GetReturn()->GetValue(0)._string_array._pt; + FRT_StringValue *arglist = m_list->GetReturn()->GetValue(1)._string_array._pt; + FRT_StringValue *retlist = m_list->GetReturn()->GetValue(2)._string_array._pt; + + for (uint32_t m = 0; m < numMethods; m++) { + + if (verbose) { + + GetReq(&info, &supervisor); + info->SetMethodName("frt.rpc.getMethodInfo"); + info->GetParams()->AddString(methods[m]._str); + target->InvokeSync(info, 60.0); + DumpMethodInfo("", info, methods[m]._str); + + } else { + + printf("METHOD [%s] <- %s <- [%s]\n", + retlist[m]._str, methods[m]._str, arglist[m]._str); + } + } + } else { + fprintf(stderr, " [error(%d): %s]\n", + m_list->GetErrorCode(), + m_list->GetErrorMessage()); + } + FreeReqs(m_list, info); + target->SubRef(); + supervisor.ShutDown(true); + return 0; + } +}; + + +int +main(int argc, char **argv) +{ + RPCInfo myapp; + return myapp.Entry(argc, argv); +} diff --git a/jrt_test/src/tests/mandatory-methods/mandatory-methods_test.sh b/jrt_test/src/tests/mandatory-methods/mandatory-methods_test.sh new file mode 100755 index 00000000000..bf86849d9c1 --- /dev/null +++ b/jrt_test/src/tests/mandatory-methods/mandatory-methods_test.sh @@ -0,0 +1,10 @@ +#!/bin/bash + +. ../../binref/env.sh +export PORT_1 + +$BINREF/compilejava RPCServer.java + +sh dotest.sh || (sh $BINREF/progctl.sh progdefs.sh stop all; false) +sh $BINREF/progctl.sh progdefs.sh stop all + diff --git a/jrt_test/src/tests/mandatory-methods/progdefs.sh b/jrt_test/src/tests/mandatory-methods/progdefs.sh new file mode 100644 index 00000000000..aa7ae4ab3ca --- /dev/null +++ b/jrt_test/src/tests/mandatory-methods/progdefs.sh @@ -0,0 +1,2 @@ +# Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +prog javaserver 1 "tcp/$PORT_1" "$BINREF/runjava RPCServer" diff --git a/jrt_test/src/tests/mandatory-methods/ref.txt b/jrt_test/src/tests/mandatory-methods/ref.txt new file mode 100644 index 00000000000..785181bca6d --- /dev/null +++ b/jrt_test/src/tests/mandatory-methods/ref.txt @@ -0,0 +1,26 @@ +METHOD frt.rpc.getMethodInfo + DESCRIPTION: + Obtain detailed information about a single method + PARAMS: + [s][methodName] The method we want information about + RETURN: + [s][desc] Description of what the method does + [s][params] Method parameter types + [s][return] Method return values + [S][paramNames] Method parameter names + [S][paramDesc] Method parameter descriptions + [S][returnNames] Method return value names + [S][returnDesc] Method return value descriptions + +METHOD frt.rpc.getMethodList + DESCRIPTION: + Obtain a list of all available methods + RETURN: + [S][names] Method names + [S][params] Method parameter types + [S][return] Method return types + +METHOD frt.rpc.ping + DESCRIPTION: + Method that may be used to check if the server is online + diff --git a/jrt_test/src/tests/mockup-invoke/.gitignore b/jrt_test/src/tests/mockup-invoke/.gitignore new file mode 100644 index 00000000000..89cd4543d46 --- /dev/null +++ b/jrt_test/src/tests/mockup-invoke/.gitignore @@ -0,0 +1,8 @@ +.depend +Makefile +MockupInvoke.class +mockup-server +out.server.1 +out.txt +pid.txt +jrt_test_mockup-server_app diff --git a/jrt_test/src/tests/mockup-invoke/CMakeLists.txt b/jrt_test/src/tests/mockup-invoke/CMakeLists.txt new file mode 100644 index 00000000000..773de6f4283 --- /dev/null +++ b/jrt_test/src/tests/mockup-invoke/CMakeLists.txt @@ -0,0 +1,7 @@ +# Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +vespa_add_executable(jrt_test_mockup-server_app + SOURCES + mockup-server.cpp + DEPENDS +) +vespa_add_test(NAME jrt_test_mockup-server_app NO_VALGRIND COMMAND sh mockup-invoke_test.sh) diff --git a/jrt_test/src/tests/mockup-invoke/DESC b/jrt_test/src/tests/mockup-invoke/DESC new file mode 100644 index 00000000000..27ad5eca58f --- /dev/null +++ b/jrt_test/src/tests/mockup-invoke/DESC @@ -0,0 +1,2 @@ +Test that the mockup invoke implementation in Java is able to invoke +methods in a C++ based RPC server. diff --git a/jrt_test/src/tests/mockup-invoke/FILES b/jrt_test/src/tests/mockup-invoke/FILES new file mode 100644 index 00000000000..da260550280 --- /dev/null +++ b/jrt_test/src/tests/mockup-invoke/FILES @@ -0,0 +1,6 @@ +dotest.sh +out.txt +ref.txt +mockup-server.cpp +MockupInvoke.java +out.server.1 diff --git a/jrt_test/src/tests/mockup-invoke/MockupInvoke.java b/jrt_test/src/tests/mockup-invoke/MockupInvoke.java new file mode 100644 index 00000000000..aa5a59c780d --- /dev/null +++ b/jrt_test/src/tests/mockup-invoke/MockupInvoke.java @@ -0,0 +1,34 @@ +// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. + +import com.yahoo.jrt.*; + +public class MockupInvoke { + + public static void main(String[] args) { + if (args.length != 3) { + System.out.println("error: Wrong number of parameters"); + System.exit(0); + } + Transport transport = new Transport(); + Supervisor orb = new Supervisor(transport); + Spec spec = new Spec(args[0]); + Request req = new Request("concat"); + req.parameters().add(new StringValue(args[1])); + req.parameters().add(new StringValue(args[2])); + orb.invokeBatch(spec, req, 60.0); + if (req.isError()) { + System.out.println("error: " + req.errorCode() + + ": " + req.errorMessage()); + System.exit(0); + } + if (req.returnValues().size() != 1 + || req.returnValues().get(0).type() != 's') { + + System.out.println("error: Wrong return values"); + System.exit(0); + } + System.out.println("result: '" + + req.returnValues().get(0).asString() + + "'"); + } +} diff --git a/jrt_test/src/tests/mockup-invoke/dotest.sh b/jrt_test/src/tests/mockup-invoke/dotest.sh new file mode 100644 index 00000000000..3bd15b6437f --- /dev/null +++ b/jrt_test/src/tests/mockup-invoke/dotest.sh @@ -0,0 +1,19 @@ +#!/bin/sh +# Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. + +sh $BINREF/progctl.sh progdefs.sh start server 1 + +$BINREF/runjava PollRPCServer tcp/localhost:$PORT_0 +$BINREF/runjava MockupInvoke tcp/localhost:$PORT_0 aaa bbb > out.txt +$BINREF/runjava MockupInvoke tcp/localhost:$PORT_0 bbb ccc >> out.txt +$BINREF/runjava MockupInvoke tcp/localhost:$PORT_0 ccc ddd >> out.txt +$BINREF/runjava MockupInvoke tcp/localhost:$PORT_0 ddd eee >> out.txt +$BINREF/runjava MockupInvoke tcp/localhost:$PORT_0 eee fff >> out.txt + +sh $BINREF/progctl.sh progdefs.sh stop server 1 + +if diff -u out.txt ref.txt; then + exit 0 +else + exit 1 +fi diff --git a/jrt_test/src/tests/mockup-invoke/mockup-invoke_test.sh b/jrt_test/src/tests/mockup-invoke/mockup-invoke_test.sh new file mode 100755 index 00000000000..56ca7079e7a --- /dev/null +++ b/jrt_test/src/tests/mockup-invoke/mockup-invoke_test.sh @@ -0,0 +1,10 @@ +#!/bin/bash + +. ../../binref/env.sh + +export PORT_0 + +$BINREF/compilejava MockupInvoke.java + +sh dotest.sh || (sh $BINREF/progctl.sh progdefs.sh stop all; false) +sh $BINREF/progctl.sh progdefs.sh stop all diff --git a/jrt_test/src/tests/mockup-invoke/mockup-server.cpp b/jrt_test/src/tests/mockup-invoke/mockup-server.cpp new file mode 100644 index 00000000000..97b2e945e57 --- /dev/null +++ b/jrt_test/src/tests/mockup-invoke/mockup-server.cpp @@ -0,0 +1,69 @@ +// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +#include <vespa/log/log.h> +LOG_SETUP("mockup_server"); +#include <vespa/fastos/fastos.h> +#include <vespa/fnet/frt/frt.h> + + +class MockupServer : public FRT_Invokable +{ +private: + MockupServer(const MockupServer &); + MockupServer &operator=(const MockupServer &); + +public: + MockupServer(FRT_Supervisor *s) + { + FRT_ReflectionBuilder rb(s); + //------------------------------------------------------------------- + rb.DefineMethod("concat", "ss", "s", true, + FRT_METHOD(MockupServer::RPC_concat), this); + rb.MethodDesc("Concatenate two strings"); + rb.ParamDesc("string1", "a string"); + rb.ParamDesc("string2", "another string"); + rb.ReturnDesc("ret", "the concatenation of string1 and string2"); + //------------------------------------------------------------------- + } + + void RPC_concat(FRT_RPCRequest *req) + { + FRT_Values ¶ms = *req->GetParams(); + FRT_Values &ret = *req->GetReturn(); + + uint32_t len = (params[0]._string._len + + params[1]._string._len); + char *tmp = ret.AddString(len); + strcpy(tmp, params[0]._string._str); + strcat(tmp, params[1]._string._str); + } +}; + + +class App : public FastOS_Application +{ +public: + int Main(); +}; + + +int +App::Main() +{ + if (_argc < 2) { + printf("usage: %s <listenspec>\n", _argv[0]); + return 1; + } + FRT_Supervisor orb; + MockupServer server(&orb); + orb.Listen(_argv[1]); + orb.Main(); + return 0; +} + + +int +main(int argc, char **argv) +{ + App myapp; + return myapp.Entry(argc, argv); +} diff --git a/jrt_test/src/tests/mockup-invoke/progdefs.sh b/jrt_test/src/tests/mockup-invoke/progdefs.sh new file mode 100644 index 00000000000..4c483b8060b --- /dev/null +++ b/jrt_test/src/tests/mockup-invoke/progdefs.sh @@ -0,0 +1,2 @@ +# Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +prog server 1 "tcp/$PORT_0" "./jrt_test_mockup-server_app" diff --git a/jrt_test/src/tests/mockup-invoke/ref.txt b/jrt_test/src/tests/mockup-invoke/ref.txt new file mode 100644 index 00000000000..41229d78bc7 --- /dev/null +++ b/jrt_test/src/tests/mockup-invoke/ref.txt @@ -0,0 +1,5 @@ +result: 'aaabbb' +result: 'bbbccc' +result: 'cccddd' +result: 'dddeee' +result: 'eeefff' diff --git a/jrt_test/src/tests/rpc-error/.gitignore b/jrt_test/src/tests/rpc-error/.gitignore new file mode 100644 index 00000000000..96e67ef3ca7 --- /dev/null +++ b/jrt_test/src/tests/rpc-error/.gitignore @@ -0,0 +1,9 @@ +.depend +Makefile +TestErrors.class +cpp_pid.txt +java_pid.txt +out.cppserver.1 +out.javaserver.1 +test-errors +jrt_test_test-errors_app diff --git a/jrt_test/src/tests/rpc-error/CMakeLists.txt b/jrt_test/src/tests/rpc-error/CMakeLists.txt new file mode 100644 index 00000000000..9d144709dfc --- /dev/null +++ b/jrt_test/src/tests/rpc-error/CMakeLists.txt @@ -0,0 +1,7 @@ +# Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +vespa_add_executable(jrt_test_test-errors_app + SOURCES + test-errors.cpp + DEPENDS +) +vespa_add_test(NAME jrt_test_test-errors_app NO_VALGRIND COMMAND sh rpc-error_test.sh) diff --git a/jrt_test/src/tests/rpc-error/DESC b/jrt_test/src/tests/rpc-error/DESC new file mode 100644 index 00000000000..a9de538edd7 --- /dev/null +++ b/jrt_test/src/tests/rpc-error/DESC @@ -0,0 +1 @@ +Test that RPC errors are handled correctly when mixing cpp and java. diff --git a/jrt_test/src/tests/rpc-error/FILES b/jrt_test/src/tests/rpc-error/FILES new file mode 100644 index 00000000000..53c47eb425d --- /dev/null +++ b/jrt_test/src/tests/rpc-error/FILES @@ -0,0 +1,5 @@ +dotest.sh +TestErrors.java +test-errors.cpp +out.cppserver.1 +out.javaserver.1 diff --git a/jrt_test/src/tests/rpc-error/TestErrors.java b/jrt_test/src/tests/rpc-error/TestErrors.java new file mode 100644 index 00000000000..cc25935141f --- /dev/null +++ b/jrt_test/src/tests/rpc-error/TestErrors.java @@ -0,0 +1,139 @@ +// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +import com.yahoo.jrt.*; + + +public class TestErrors { + + boolean error = false; + Supervisor client; + Target target; + + public void init(String spec) { + client = new Supervisor(new Transport()); + target = client.connect(new Spec(spec)); + } + + public void fini() { + target.close(); + client.transport().shutdown().join(); + if (!error) { + System.err.println("Conclusion: PASS"); + } else { + System.err.println("Conclusion: FAIL"); + System.exit(1); + } + } + + public void assertTrue(boolean value) { + if (!value) { + Throwable tmp = new Throwable(); + System.out.println("<ASSERT FAILED>"); + tmp.printStackTrace(); + error = true; + } + } + + public void assertEquals(int e, int a) { + if (e != a) { + Throwable tmp = new Throwable(); + System.out.println("<ASSERT FAILED>: expected <" + e + + ">, but was <" + a + ">"); + tmp.printStackTrace(); + error = true; + } + } + + public void testNoError() { + Request req1 = new Request("test"); + req1.parameters().add(new Int32Value(42)); + req1.parameters().add(new Int32Value(0)); + req1.parameters().add(new Int8Value((byte)0)); + target.invokeSync(req1, 60.0); + assertTrue(!req1.isError()); + assertEquals(1, req1.returnValues().size()); + assertEquals(42, req1.returnValues().get(0).asInt32()); + } + + public void testNoSuchMethod() { + Request req1 = new Request("bogus"); + target.invokeSync(req1, 60.0); + assertTrue(req1.isError()); + assertEquals(0, req1.returnValues().size()); + assertEquals(ErrorCode.NO_SUCH_METHOD, req1.errorCode()); + } + + public void testWrongParameters() { + Request req1 = new Request("test"); + req1.parameters().add(new Int32Value(42)); + req1.parameters().add(new Int32Value(0)); + req1.parameters().add(new Int32Value(0)); + target.invokeSync(req1, 60.0); + assertTrue(req1.isError()); + assertEquals(0, req1.returnValues().size()); + assertEquals(ErrorCode.WRONG_PARAMS, req1.errorCode()); + + Request req2 = new Request("test"); + req2.parameters().add(new Int32Value(42)); + req2.parameters().add(new Int32Value(0)); + target.invokeSync(req2, 60.0); + assertTrue(req2.isError()); + assertEquals(0, req2.returnValues().size()); + assertEquals(ErrorCode.WRONG_PARAMS, req2.errorCode()); + + Request req3 = new Request("test"); + req3.parameters().add(new Int32Value(42)); + req3.parameters().add(new Int32Value(0)); + req3.parameters().add(new Int8Value((byte)0)); + req3.parameters().add(new Int8Value((byte)0)); + target.invokeSync(req3, 60.0); + assertTrue(req3.isError()); + assertEquals(0, req3.returnValues().size()); + assertEquals(ErrorCode.WRONG_PARAMS, req3.errorCode()); + } + + public void testWrongReturnValues() { + Request req1 = new Request("test"); + req1.parameters().add(new Int32Value(42)); + req1.parameters().add(new Int32Value(0)); + req1.parameters().add(new Int8Value((byte)1)); + target.invokeSync(req1, 60.0); + assertTrue(req1.isError()); + assertEquals(0, req1.returnValues().size()); + assertEquals(ErrorCode.WRONG_RETURN, req1.errorCode()); + } + + public void testMethodFailed() { + Request req1 = new Request("test"); + req1.parameters().add(new Int32Value(42)); + req1.parameters().add(new Int32Value(75000)); + req1.parameters().add(new Int8Value((byte)0)); + target.invokeSync(req1, 60.0); + assertTrue(req1.isError()); + assertEquals(0, req1.returnValues().size()); + assertEquals(75000, req1.errorCode()); + + Request req2 = new Request("test"); + req2.parameters().add(new Int32Value(42)); + req2.parameters().add(new Int32Value(75000)); + req2.parameters().add(new Int8Value((byte)1)); + target.invokeSync(req2, 60.0); + assertTrue(req2.isError()); + assertEquals(0, req2.returnValues().size()); + assertEquals(75000, req2.errorCode()); + } + + public static void main(String[] args) { + if (args.length != 1) { + System.err.println("Usage: TestErrors spec"); + System.exit(1); + } + TestErrors test = new TestErrors(); + test.init(args[0]); + test.testNoError(); + test.testNoSuchMethod(); + test.testWrongParameters(); + test.testWrongReturnValues(); + test.testMethodFailed(); + test.fini(); + } +} diff --git a/jrt_test/src/tests/rpc-error/dotest.sh b/jrt_test/src/tests/rpc-error/dotest.sh new file mode 100644 index 00000000000..2e37525857f --- /dev/null +++ b/jrt_test/src/tests/rpc-error/dotest.sh @@ -0,0 +1,45 @@ +#!/bin/sh +# Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. + +. ../../binref/env.sh + +STATUS=ok +JAVA_PORT=$PORT_3 +CPP_PORT=$PORT_4 + +export JAVA_PORT +export CPP_PORT + +sh $BINREF/progctl.sh progdefs.sh start cppserver 1 + +$BINREF/runjava PollRPCServer tcp/localhost:$CPP_PORT +echo "CPP CLIENT <-> CPP SERVER" +./jrt_test_test-errors_app tcp/localhost:$CPP_PORT +if [ $? -ne 0 ]; then STATUS=fail; fi + +echo "JAVA CLIENT <-> CPP SERVER" +$BINREF/runjava TestErrors tcp/localhost:$CPP_PORT +if [ $? -ne 0 ]; then STATUS=fail; fi + +sh $BINREF/progctl.sh progdefs.sh stop cppserver 1 + + +sh $BINREF/progctl.sh progdefs.sh start javaserver 1 + +$BINREF/runjava PollRPCServer tcp/localhost:$JAVA_PORT +echo "CPP CLIENT <-> JAVA SERVER" +./jrt_test_test-errors_app tcp/localhost:$JAVA_PORT +if [ $? -ne 0 ]; then STATUS=fail; fi + +echo "JAVA CLIENT <-> JAVA SERVER" +$BINREF/runjava TestErrors tcp/localhost:$JAVA_PORT +if [ $? -ne 0 ]; then STATUS=fail; fi + +sh $BINREF/progctl.sh progdefs.sh stop javaserver 1 + +if [ $STATUS = "ok" ]; then + echo "OK" +else + echo "FAIL" + exit 1 +fi diff --git a/jrt_test/src/tests/rpc-error/progdefs.sh b/jrt_test/src/tests/rpc-error/progdefs.sh new file mode 100644 index 00000000000..815aa5a960e --- /dev/null +++ b/jrt_test/src/tests/rpc-error/progdefs.sh @@ -0,0 +1,3 @@ +# Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +prog cppserver 1 "tcp/$CPP_PORT" "$BINREF/simpleserver" +prog javaserver 1 "tcp/$JAVA_PORT" "$BINREF/runjava SimpleServer" diff --git a/jrt_test/src/tests/rpc-error/rpc-error_test.sh b/jrt_test/src/tests/rpc-error/rpc-error_test.sh new file mode 100755 index 00000000000..dc2f855acbd --- /dev/null +++ b/jrt_test/src/tests/rpc-error/rpc-error_test.sh @@ -0,0 +1,16 @@ +#!/bin/sh + +. ../../binref/env.sh + +STATUS=ok +JAVA_PORT=$PORT_3 +CPP_PORT=$PORT_4 + +export JAVA_PORT +export CPP_PORT + +$BINREF/compilejava TestErrors.java + +sh dotest.sh || (sh $BINREF/progctl.sh progdefs.sh stop all; false) +sh $BINREF/progctl.sh progdefs.sh stop all + diff --git a/jrt_test/src/tests/rpc-error/test-errors.cpp b/jrt_test/src/tests/rpc-error/test-errors.cpp new file mode 100644 index 00000000000..fd167b85085 --- /dev/null +++ b/jrt_test/src/tests/rpc-error/test-errors.cpp @@ -0,0 +1,168 @@ +// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +#include <vespa/vespalib/testkit/testapp.h> +#include <vespa/fnet/frt/frt.h> + + +class TestErrors : public vespalib::TestApp +{ +private: + FRT_Supervisor *client; + FRT_Target *target; + +public: + void init(const char *spec) { + client = new FRT_Supervisor; + target = client->GetTarget(spec); + client->Start(); + } + + void fini() { + target->SubRef(); + target = NULL; + client->ShutDown(true); + delete client; + client = NULL; + } + + void testNoError(); + void testNoSuchMethod(); + void testWrongParameters(); + void testWrongReturnValues(); + void testMethodFailed(); + int Main(); +}; + + +void +TestErrors::testNoError() +{ + FRT_RPCRequest *req1 = client->AllocRPCRequest(); + req1->SetMethodName("test"); + req1->GetParams()->AddInt32(42); + req1->GetParams()->AddInt32(0); + req1->GetParams()->AddInt8(0); + target->InvokeSync(req1, 60.0); + EXPECT_TRUE(!req1->IsError()); + if (EXPECT_TRUE(1 == req1->GetReturn()->GetNumValues())) { + EXPECT_TRUE(42 == req1->GetReturn()->GetValue(0)._intval32); + } else { + EXPECT_TRUE(false); + } + req1->SubRef(); +} + + +void +TestErrors::testNoSuchMethod() +{ + FRT_RPCRequest *req1 = client->AllocRPCRequest(); + req1->SetMethodName("bogus"); + target->InvokeSync(req1, 60.0); + EXPECT_TRUE(req1->IsError()); + EXPECT_TRUE(0 == req1->GetReturn()->GetNumValues()); + EXPECT_TRUE(FRTE_RPC_NO_SUCH_METHOD == req1->GetErrorCode()); + req1->SubRef(); +} + + +void +TestErrors::testWrongParameters() +{ + FRT_RPCRequest *req1 = client->AllocRPCRequest(); + req1->SetMethodName("test"); + req1->GetParams()->AddInt32(42); + req1->GetParams()->AddInt32(0); + req1->GetParams()->AddInt32(0); + target->InvokeSync(req1, 60.0); + EXPECT_TRUE(req1->IsError()); + EXPECT_TRUE(0 == req1->GetReturn()->GetNumValues()); + EXPECT_TRUE(FRTE_RPC_WRONG_PARAMS == req1->GetErrorCode()); + req1->SubRef(); + + FRT_RPCRequest *req2 = client->AllocRPCRequest(); + req2->SetMethodName("test"); + req2->GetParams()->AddInt32(42); + req2->GetParams()->AddInt32(0); + target->InvokeSync(req2, 60.0); + EXPECT_TRUE(req2->IsError()); + EXPECT_TRUE(0 == req2->GetReturn()->GetNumValues()); + EXPECT_TRUE(FRTE_RPC_WRONG_PARAMS == req2->GetErrorCode()); + req2->SubRef(); + + FRT_RPCRequest *req3 = client->AllocRPCRequest(); + req3->SetMethodName("test"); + req3->GetParams()->AddInt32(42); + req3->GetParams()->AddInt32(0); + req3->GetParams()->AddInt8(0); + req3->GetParams()->AddInt8(0); + target->InvokeSync(req3, 60.0); + EXPECT_TRUE(req3->IsError()); + EXPECT_TRUE(0 == req3->GetReturn()->GetNumValues()); + EXPECT_TRUE(FRTE_RPC_WRONG_PARAMS == req3->GetErrorCode()); + req3->SubRef(); +} + + +void +TestErrors::testWrongReturnValues() +{ + FRT_RPCRequest *req1 = client->AllocRPCRequest(); + req1->SetMethodName("test"); + req1->GetParams()->AddInt32(42); + req1->GetParams()->AddInt32(0); + req1->GetParams()->AddInt8(1); + target->InvokeSync(req1, 60.0); + EXPECT_TRUE(req1->IsError()); + EXPECT_TRUE(0 == req1->GetReturn()->GetNumValues()); + EXPECT_TRUE(FRTE_RPC_WRONG_RETURN == req1->GetErrorCode()); + req1->SubRef(); +} + + +void +TestErrors::testMethodFailed() +{ + FRT_RPCRequest *req1 = client->AllocRPCRequest(); + req1->SetMethodName("test"); + req1->GetParams()->AddInt32(42); + req1->GetParams()->AddInt32(75000); + req1->GetParams()->AddInt8(0); + target->InvokeSync(req1, 60.0); + EXPECT_TRUE(req1->IsError()); + EXPECT_TRUE(0 == req1->GetReturn()->GetNumValues()); + EXPECT_TRUE(75000 == req1->GetErrorCode()); + req1->SubRef(); + + FRT_RPCRequest *req2 = client->AllocRPCRequest(); + req2->SetMethodName("test"); + req2->GetParams()->AddInt32(42); + req2->GetParams()->AddInt32(75000); + req2->GetParams()->AddInt8(1); + target->InvokeSync(req2, 60.0); + EXPECT_TRUE(req2->IsError()); + EXPECT_TRUE(0 == req2->GetReturn()->GetNumValues()); + EXPECT_TRUE(75000 == req2->GetErrorCode()); + req2->SubRef(); +} + + +int +TestErrors::Main() +{ + if (_argc != 2) { + fprintf(stderr, "usage: %s spec", _argv[0]); + return 1; + } + TEST_INIT("test_errors"); + init(_argv[1]); + testNoError(); + testNoSuchMethod(); + testWrongParameters(); + testWrongReturnValues(); + testMethodFailed(); + fini(); + TEST_DONE(); +} + + +TEST_APPHOOK(TestErrors); diff --git a/jrt_test/src/tests/slobrok-api/.gitignore b/jrt_test/src/tests/slobrok-api/.gitignore new file mode 100644 index 00000000000..b4c0ce28732 --- /dev/null +++ b/jrt_test/src/tests/slobrok-api/.gitignore @@ -0,0 +1,4 @@ +*.class +.depend +Makefile +out.slobrok.1 diff --git a/jrt_test/src/tests/slobrok-api/CMakeLists.txt b/jrt_test/src/tests/slobrok-api/CMakeLists.txt new file mode 100644 index 00000000000..5c90dd5bfcc --- /dev/null +++ b/jrt_test/src/tests/slobrok-api/CMakeLists.txt @@ -0,0 +1 @@ +# Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. diff --git a/jrt_test/src/tests/slobrok-api/DESC b/jrt_test/src/tests/slobrok-api/DESC new file mode 100644 index 00000000000..b44753d7d10 --- /dev/null +++ b/jrt_test/src/tests/slobrok-api/DESC @@ -0,0 +1,2 @@ +Test java port of slobrok api classes. Currently only tests with a +single slobrok server. diff --git a/jrt_test/src/tests/slobrok-api/FILES b/jrt_test/src/tests/slobrok-api/FILES new file mode 100644 index 00000000000..cc18fdd7eb7 --- /dev/null +++ b/jrt_test/src/tests/slobrok-api/FILES @@ -0,0 +1,2 @@ +SlobrokAPITest.java +out.slobrok.1 diff --git a/jrt_test/src/tests/slobrok-api/SlobrokAPITest.java b/jrt_test/src/tests/slobrok-api/SlobrokAPITest.java new file mode 100644 index 00000000000..5fd88f27b80 --- /dev/null +++ b/jrt_test/src/tests/slobrok-api/SlobrokAPITest.java @@ -0,0 +1,223 @@ +// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. + + +import com.yahoo.jrt.*; +import com.yahoo.jrt.slobrok.api.*; +import java.util.Comparator; +import java.util.Arrays; +import java.util.ArrayList; + + +public class SlobrokAPITest { + + private static class SpecList extends ArrayList { + public SpecList add(String name, String spec) { + add(new Mirror.Entry(name, spec)); + return this; + } + } + + String[] slobroks; + SlobrokList slist = new SlobrokList(); + boolean error = false; + Supervisor server = new Supervisor(new Transport()); + Supervisor client = new Supervisor(new Transport()); + Acceptor acceptor = null; + Mirror mirror = null; + Register register = null; + String mySpec = null; + + public SlobrokAPITest(String slobrokSpec) throws ListenFailedException { + slobroks = new String[1]; + slobroks[0] = slobrokSpec; + slist.setup(slobroks); + acceptor = server.listen(new Spec(0)); + mirror = new Mirror(client, slist); + register = new Register(server, slist, + "localhost", acceptor.port()); + mySpec = new Spec("localhost", acceptor.port()).toString(); + } + + void shutdown() { + register.shutdown(); + mirror.shutdown(); + acceptor.shutdown(); + client.transport().shutdown(); + server.transport().shutdown(); + } + + void check(String pattern, ArrayList result) { + Comparator cmp = new Comparator() { + public int compare(Object a, Object b) { + Mirror.Entry x = (Mirror.Entry) a; + Mirror.Entry y = (Mirror.Entry) b; + return x.compareTo(y); + } + }; + Mirror.Entry[] expect + = (Mirror.Entry[]) result.toArray(new Mirror.Entry[result.size()]); + Arrays.sort(expect, cmp); + Mirror.Entry[] actual = new Mirror.Entry[0]; + for (int i = 0; i < 600; i++) { + actual = mirror.lookup(pattern); + Arrays.sort(actual, cmp); + if (Arrays.equals(actual, expect)) { + err("lookup successful for pattern: " + pattern); + return; + } + try { Thread.sleep(100); } catch (InterruptedException e) {} + } + error = true; + err("lookup failed for pattern: " + pattern); + err("actual values:"); + if (actual.length == 0) { + err(" { EMPTY }"); + } + for (int i = 0; i < actual.length; i++) { + err(" {" + actual[i].getName() + ", " + actual[i].getSpec() + "}"); + } + err("expected values:"); + if (expect.length == 0) { + err(" { EMPTY }"); + } + for (int i = 0; i < expect.length; i++) { + err(" {" + expect[i].getName() + ", " + expect[i].getSpec() + "}"); + } + } + + public void runTests() throws Exception { + try { + register.registerName("A/x/w"); + check("A/x/w", new SpecList().add("A/x/w", mySpec)); + check("*/*", new SpecList()); + check("*/*/*", new SpecList().add("A/x/w", mySpec)); + + register.registerName("B/x"); + check("B/x", new SpecList().add("B/x", mySpec)); + check("*/*", new SpecList().add("B/x", mySpec)); + check("*/*/*", new SpecList().add("A/x/w", mySpec)); + + register.registerName("C/x/z"); + check("C/x/z", new SpecList().add("C/x/z", mySpec)); + check("*/*", new SpecList().add("B/x", mySpec)); + check("*/*/*", new SpecList() + .add("A/x/w", mySpec) + .add("C/x/z", mySpec)); + + register.registerName("D/y/z"); + check("D/y/z", new SpecList().add("D/y/z", mySpec)); + check("*/*", new SpecList().add("B/x", mySpec)); + check("*/*/*", new SpecList() + .add("A/x/w", mySpec) + .add("C/x/z", mySpec) + .add("D/y/z", mySpec)); + + register.registerName("E/y"); + check("E/y", new SpecList().add("E/y", mySpec)); + check("*/*", new SpecList() + .add("B/x", mySpec) + .add("E/y", mySpec)); + check("*/*/*", new SpecList() + .add("A/x/w", mySpec) + .add("C/x/z", mySpec) + .add("D/y/z", mySpec)); + + register.registerName("F/y/w"); + check("F/y/w", new SpecList().add("F/y/w", mySpec)); + check("*/*", new SpecList() + .add("B/x", mySpec) + .add("E/y", mySpec)); + check("*/*/*", new SpecList() + .add("A/x/w", mySpec) + .add("C/x/z", mySpec) + .add("D/y/z", mySpec) + .add("F/y/w", mySpec)); + + check("*", new SpecList()); + + check("B/*", new SpecList() + .add("B/x", mySpec)); + + check("*/y", new SpecList() + .add("E/y", mySpec)); + + check("*/x/*", new SpecList() + .add("A/x/w", mySpec) + .add("C/x/z", mySpec)); + + check("*/*/z", new SpecList() + .add("C/x/z", mySpec) + .add("D/y/z", mySpec)); + + check("A/*/z", new SpecList()); + + check("A/*/w", new SpecList() + .add("A/x/w", mySpec)); + + register.unregisterName("E/y"); + register.unregisterName("C/x/z"); + register.unregisterName("F/y/w"); + check("*/*", new SpecList() + .add("B/x", mySpec)); + check("*/*/*", new SpecList() + .add("A/x/w", mySpec) + .add("D/y/z", mySpec)); + + register.registerName("E/y"); + register.registerName("C/x/z"); + register.registerName("F/y/w"); + check("*/*", new SpecList() + .add("B/x", mySpec) + .add("E/y", mySpec)); + check("*/*/*", new SpecList() + .add("A/x/w", mySpec) + .add("C/x/z", mySpec) + .add("D/y/z", mySpec) + .add("F/y/w", mySpec)); + + register.unregisterName("E/y"); + register.unregisterName("C/x/z"); + register.unregisterName("F/y/w"); + check("*/*", new SpecList() + .add("B/x", mySpec)); + check("*/*/*", new SpecList() + .add("A/x/w", mySpec) + .add("D/y/z", mySpec)); + + register.registerName("E/y"); + register.registerName("C/x/z"); + register.registerName("F/y/w"); + check("*/*", new SpecList() + .add("B/x", mySpec) + .add("E/y", mySpec)); + check("*/*/*", new SpecList() + .add("A/x/w", mySpec) + .add("C/x/z", mySpec) + .add("D/y/z", mySpec) + .add("F/y/w", mySpec)); + + if (error) { + throw new Exception("Test failed"); + } + } finally { + shutdown(); + } + } + + public static void main(String[] args) { + if (args.length != 1) { + err("usage: SlobrokAPITest slobrok-spec"); + System.exit(1); + } + try { + new SlobrokAPITest(args[0]).runTests(); + } catch (Exception e) { + e.printStackTrace(); + System.exit(1); + } + } + + public static void err(String msg) { + System.err.println(msg); + } +} diff --git a/jrt_test/src/tests/slobrok-api/dotest.sh b/jrt_test/src/tests/slobrok-api/dotest.sh new file mode 100755 index 00000000000..4a221e5830c --- /dev/null +++ b/jrt_test/src/tests/slobrok-api/dotest.sh @@ -0,0 +1,14 @@ +#!/bin/sh +# Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. + +. ../../binref/env.sh + +ret=true + +export PORT_8 +sh $BINREF/progctl.sh progdefs.sh start slobrok 1 +${BINREF}/runjava SlobrokAPITest tcp/localhost:${PORT_8} || ret=false +${BINREF}/sbcmd ${PORT_8} slobrok.system.stop +sh $BINREF/progctl.sh progdefs.sh stop slobrok 1 + +$ret diff --git a/jrt_test/src/tests/slobrok-api/progdefs.sh b/jrt_test/src/tests/slobrok-api/progdefs.sh new file mode 100644 index 00000000000..af694ab8ad4 --- /dev/null +++ b/jrt_test/src/tests/slobrok-api/progdefs.sh @@ -0,0 +1,2 @@ +# Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +prog slobrok 1 "-p $PORT_8" diff --git a/jrt_test/testrun/.gitignore b/jrt_test/testrun/.gitignore new file mode 100644 index 00000000000..d875378e396 --- /dev/null +++ b/jrt_test/testrun/.gitignore @@ -0,0 +1,7 @@ +test-report.html +test-report.html.* +test.*.*.file.* +test.*.*.files.html +tmp.* +xsync.log +/test.*.*.result |