summaryrefslogtreecommitdiffstats
path: root/jrt_test
diff options
context:
space:
mode:
authorJon Bratseth <bratseth@yahoo-inc.com>2016-06-15 23:09:44 +0200
committerJon Bratseth <bratseth@yahoo-inc.com>2016-06-15 23:09:44 +0200
commit72231250ed81e10d66bfe70701e64fa5fe50f712 (patch)
tree2728bba1131a6f6e5bdf95afec7d7ff9358dac50 /jrt_test
Publish
Diffstat (limited to 'jrt_test')
-rw-r--r--jrt_test/.gitignore2
-rw-r--r--jrt_test/CMakeLists.txt25
-rw-r--r--jrt_test/OWNERS2
-rw-r--r--jrt_test/README1
-rw-r--r--jrt_test/src/.gitignore3
-rw-r--r--jrt_test/src/binref/.gitignore7
-rw-r--r--jrt_test/src/binref/CMakeLists.txt5
-rwxr-xr-xjrt_test/src/binref/compilejava.in11
-rw-r--r--jrt_test/src/binref/env.sh.in15
l---------jrt_test/src/binref/progctl.sh1
-rwxr-xr-xjrt_test/src/binref/runjava.in13
l---------jrt_test/src/binref/sbcmd1
l---------jrt_test/src/binref/simpleserver1
l---------jrt_test/src/binref/slobrok1
l---------jrt_test/src/binref/testrun.sh1
-rw-r--r--jrt_test/src/java/.gitignore3
-rw-r--r--jrt_test/src/java/CMakeLists.txt8
-rw-r--r--jrt_test/src/java/DummySlobrokService.java40
-rw-r--r--jrt_test/src/java/HelloWorld.java8
-rw-r--r--jrt_test/src/java/PollRPCServer.java35
-rw-r--r--jrt_test/src/java/SimpleServer.java50
-rw-r--r--jrt_test/src/java/build.xml62
-rw-r--r--jrt_test/src/jrt-test/simpleserver/.gitignore4
-rw-r--r--jrt_test/src/jrt-test/simpleserver/CMakeLists.txt7
-rw-r--r--jrt_test/src/jrt-test/simpleserver/simpleserver.cpp102
-rw-r--r--jrt_test/src/testlist.txt8
-rw-r--r--jrt_test/src/tests/connect-close/.gitignore3
-rw-r--r--jrt_test/src/tests/connect-close/CMakeLists.txt1
-rw-r--r--jrt_test/src/tests/connect-close/DESC1
-rw-r--r--jrt_test/src/tests/connect-close/FILES1
-rw-r--r--jrt_test/src/tests/connect-close/Test.java39
-rw-r--r--jrt_test/src/tests/echo/.gitignore7
-rw-r--r--jrt_test/src/tests/echo/CMakeLists.txt7
-rw-r--r--jrt_test/src/tests/echo/DESC3
-rw-r--r--jrt_test/src/tests/echo/FILES5
-rw-r--r--jrt_test/src/tests/echo/dotest.sh15
-rw-r--r--jrt_test/src/tests/echo/echo-client.cpp91
-rwxr-xr-xjrt_test/src/tests/echo/echo_test.sh4
-rw-r--r--jrt_test/src/tests/echo/progdefs.sh2
-rw-r--r--jrt_test/src/tests/echo/ref.txt109
-rw-r--r--jrt_test/src/tests/garbage/.gitignore4
-rw-r--r--jrt_test/src/tests/garbage/CMakeLists.txt1
-rw-r--r--jrt_test/src/tests/garbage/DESC4
-rw-r--r--jrt_test/src/tests/garbage/FILES1
-rw-r--r--jrt_test/src/tests/garbage/Garbage.java99
-rw-r--r--jrt_test/src/tests/hello-world/.gitignore3
-rw-r--r--jrt_test/src/tests/hello-world/CMakeLists.txt1
-rw-r--r--jrt_test/src/tests/hello-world/DESC1
-rw-r--r--jrt_test/src/tests/hello-world/FILES3
-rw-r--r--jrt_test/src/tests/hello-world/ref.txt1
-rw-r--r--jrt_test/src/tests/mandatory-methods/.gitignore8
-rw-r--r--jrt_test/src/tests/mandatory-methods/CMakeLists.txt7
-rw-r--r--jrt_test/src/tests/mandatory-methods/DESC10
-rw-r--r--jrt_test/src/tests/mandatory-methods/FILES6
-rw-r--r--jrt_test/src/tests/mandatory-methods/RPCServer.java21
-rw-r--r--jrt_test/src/tests/mandatory-methods/dotest.sh14
-rw-r--r--jrt_test/src/tests/mandatory-methods/extract-reflection.cpp145
-rwxr-xr-xjrt_test/src/tests/mandatory-methods/mandatory-methods_test.sh10
-rw-r--r--jrt_test/src/tests/mandatory-methods/progdefs.sh2
-rw-r--r--jrt_test/src/tests/mandatory-methods/ref.txt26
-rw-r--r--jrt_test/src/tests/mockup-invoke/.gitignore8
-rw-r--r--jrt_test/src/tests/mockup-invoke/CMakeLists.txt7
-rw-r--r--jrt_test/src/tests/mockup-invoke/DESC2
-rw-r--r--jrt_test/src/tests/mockup-invoke/FILES6
-rw-r--r--jrt_test/src/tests/mockup-invoke/MockupInvoke.java34
-rw-r--r--jrt_test/src/tests/mockup-invoke/dotest.sh19
-rwxr-xr-xjrt_test/src/tests/mockup-invoke/mockup-invoke_test.sh10
-rw-r--r--jrt_test/src/tests/mockup-invoke/mockup-server.cpp69
-rw-r--r--jrt_test/src/tests/mockup-invoke/progdefs.sh2
-rw-r--r--jrt_test/src/tests/mockup-invoke/ref.txt5
-rw-r--r--jrt_test/src/tests/rpc-error/.gitignore9
-rw-r--r--jrt_test/src/tests/rpc-error/CMakeLists.txt7
-rw-r--r--jrt_test/src/tests/rpc-error/DESC1
-rw-r--r--jrt_test/src/tests/rpc-error/FILES5
-rw-r--r--jrt_test/src/tests/rpc-error/TestErrors.java139
-rw-r--r--jrt_test/src/tests/rpc-error/dotest.sh45
-rw-r--r--jrt_test/src/tests/rpc-error/progdefs.sh3
-rwxr-xr-xjrt_test/src/tests/rpc-error/rpc-error_test.sh16
-rw-r--r--jrt_test/src/tests/rpc-error/test-errors.cpp168
-rw-r--r--jrt_test/src/tests/slobrok-api/.gitignore4
-rw-r--r--jrt_test/src/tests/slobrok-api/CMakeLists.txt1
-rw-r--r--jrt_test/src/tests/slobrok-api/DESC2
-rw-r--r--jrt_test/src/tests/slobrok-api/FILES2
-rw-r--r--jrt_test/src/tests/slobrok-api/SlobrokAPITest.java223
-rwxr-xr-xjrt_test/src/tests/slobrok-api/dotest.sh14
-rw-r--r--jrt_test/src/tests/slobrok-api/progdefs.sh2
-rw-r--r--jrt_test/testrun/.gitignore7
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 &params = *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