summaryrefslogtreecommitdiffstats
path: root/jrt/tests
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/tests
Publish
Diffstat (limited to 'jrt/tests')
-rw-r--r--jrt/tests/com/yahoo/jrt/AbortTest.java76
-rw-r--r--jrt/tests/com/yahoo/jrt/BackTargetTest.java110
-rw-r--r--jrt/tests/com/yahoo/jrt/BufferTest.java265
-rw-r--r--jrt/tests/com/yahoo/jrt/ConnectTest.java47
-rw-r--r--jrt/tests/com/yahoo/jrt/DetachTest.java136
-rw-r--r--jrt/tests/com/yahoo/jrt/EchoTest.java86
-rw-r--r--jrt/tests/com/yahoo/jrt/InvokeAsyncTest.java62
-rw-r--r--jrt/tests/com/yahoo/jrt/InvokeErrorTest.java149
-rw-r--r--jrt/tests/com/yahoo/jrt/InvokeSyncTest.java82
-rw-r--r--jrt/tests/com/yahoo/jrt/InvokeVoidTest.java74
-rw-r--r--jrt/tests/com/yahoo/jrt/ListenTest.java98
-rw-r--r--jrt/tests/com/yahoo/jrt/MandatoryMethodsTest.java97
-rw-r--r--jrt/tests/com/yahoo/jrt/PacketTest.java129
-rw-r--r--jrt/tests/com/yahoo/jrt/QueueTest.java97
-rw-r--r--jrt/tests/com/yahoo/jrt/SchedulerTest.java238
-rw-r--r--jrt/tests/com/yahoo/jrt/SessionTest.java451
-rw-r--r--jrt/tests/com/yahoo/jrt/SlobrokTest.java235
-rw-r--r--jrt/tests/com/yahoo/jrt/SpecTest.java98
-rw-r--r--jrt/tests/com/yahoo/jrt/Test.java236
-rw-r--r--jrt/tests/com/yahoo/jrt/TimeoutTest.java77
-rw-r--r--jrt/tests/com/yahoo/jrt/ValuesTest.java435
-rw-r--r--jrt/tests/com/yahoo/jrt/WatcherTest.java98
-rw-r--r--jrt/tests/com/yahoo/jrt/order.txt25
-rw-r--r--jrt/tests/com/yahoo/jrt/slobrok/api/BackOffTestCase.java52
-rw-r--r--jrt/tests/com/yahoo/jrt/slobrok/api/MirrorTest.java89
-rw-r--r--jrt/tests/com/yahoo/jrt/slobrok/api/SlobrokListTestCase.java130
-rw-r--r--jrt/tests/com/yahoo/jrt/tool/RpcInvokerTest.java59
27 files changed, 3731 insertions, 0 deletions
diff --git a/jrt/tests/com/yahoo/jrt/AbortTest.java b/jrt/tests/com/yahoo/jrt/AbortTest.java
new file mode 100644
index 00000000000..356203be4be
--- /dev/null
+++ b/jrt/tests/com/yahoo/jrt/AbortTest.java
@@ -0,0 +1,76 @@
+// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.jrt;
+
+
+public class AbortTest extends junit.framework.TestCase {
+
+ Supervisor server;
+ Acceptor acceptor;
+ Supervisor client;
+ Target target;
+ Test.Barrier barrier;
+
+ public AbortTest(String name) {
+ super(name);
+ }
+
+ public void setUp() throws ListenFailedException {
+ server = new Supervisor(new Transport());
+ client = new Supervisor(new Transport());
+ acceptor = server.listen(new Spec(Test.PORT));
+ target = client.connect(new Spec("localhost", Test.PORT));
+ server.addMethod(new Method("test", "i", "i", this, "rpc_test"));
+ barrier = new Test.Barrier();
+ }
+
+ public void tearDown() {
+ target.close();
+ acceptor.shutdown().join();
+ client.transport().shutdown().join();
+ server.transport().shutdown().join();
+ }
+
+ public void rpc_test(Request req) {
+ barrier.waitFor();
+ int value = req.parameters().get(0).asInt32();
+ req.returnValues().add(new Int32Value(value));
+ }
+
+ public void testAbort() {
+ Test.Waiter w = new Test.Waiter();
+ Request req = new Request("test");
+ req.parameters().add(new Int32Value(20));
+ target.invokeAsync(req, 5.0, w);
+ req.abort();
+ barrier.breakIt();
+ w.waitDone();
+ assertTrue(req.isError());
+ assertEquals(ErrorCode.ABORT, req.errorCode());
+ assertEquals(0, req.returnValues().size());
+
+ Request req2 = new Request("test");
+ req2.parameters().add(new Int32Value(30));
+ target.invokeSync(req2, 5.0);
+ assertTrue(!req2.isError());
+ assertEquals(1, req2.returnValues().size());
+ assertEquals(30, req2.returnValues().get(0).asInt32());
+
+ req2.abort();
+ assertTrue(!req2.isError());
+ assertEquals(1, req2.returnValues().size());
+ assertEquals(30, req2.returnValues().get(0).asInt32());
+
+ assertTrue(req.isError());
+ assertEquals(ErrorCode.ABORT, req.errorCode());
+ assertEquals(0, req.returnValues().size());
+ }
+
+ public void testBogusAbort() {
+ Request req = new Request("test");
+ req.parameters().add(new Int32Value(40));
+ try {
+ req.abort();
+ assertTrue(false);
+ } catch (IllegalStateException e) {}
+ }
+}
diff --git a/jrt/tests/com/yahoo/jrt/BackTargetTest.java b/jrt/tests/com/yahoo/jrt/BackTargetTest.java
new file mode 100644
index 00000000000..056f9ed60f0
--- /dev/null
+++ b/jrt/tests/com/yahoo/jrt/BackTargetTest.java
@@ -0,0 +1,110 @@
+// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.jrt;
+
+
+public class BackTargetTest extends junit.framework.TestCase {
+
+ Supervisor server;
+ Acceptor acceptor;
+ Supervisor client;
+ Target target;
+ int serverValue;
+ int clientValue;
+ Target serverBackTarget;
+ Target clientBackTarget;
+
+ public BackTargetTest(String name) {
+ super(name);
+ }
+
+ public void setUp() throws ListenFailedException {
+ server = new Supervisor(new Transport());
+ client = new Supervisor(new Transport());
+ acceptor = server.listen(new Spec(Test.PORT));
+ target = client.connect(new Spec("localhost", Test.PORT));
+
+ server.addMethod(new Method("inc", "", "", this, "server_inc"));
+ server.addMethod(new Method("sample_target", "", "", this,
+ "server_sample_target"));
+ server.addMethod(new Method("back_inc", "", "", this, "back_inc"));
+
+ client.addMethod(new Method("inc", "", "", this, "client_inc"));
+ client.addMethod(new Method("sample_target", "", "", this,
+ "client_sample_target"));
+ client.addMethod(new Method("back_inc", "", "", this, "back_inc"));
+
+ serverValue = 0;
+ clientValue = 0;
+ serverBackTarget = null;
+ clientBackTarget = null;
+ }
+
+ public void tearDown() {
+ target.close();
+ acceptor.shutdown().join();
+ client.transport().shutdown().join();
+ server.transport().shutdown().join();
+ }
+
+ public void server_inc(Request req) {
+ serverValue++;
+ }
+
+ public void server_sample_target(Request req) {
+ serverBackTarget = req.target();
+ }
+
+ public void client_inc(Request req) {
+ clientValue++;
+ }
+
+ public void client_sample_target(Request req) {
+ clientBackTarget = req.target();
+ }
+
+ public void back_inc(Request req) {
+ Target t = req.target();
+ t.invokeVoid(new Request("inc"));
+ }
+
+ private void checkValues(int server, int client) {
+ assertEquals(server, serverValue);
+ assertEquals(client, clientValue);
+ }
+
+ private void checkTargets(boolean server, boolean client) {
+ assertTrue(server == (serverBackTarget != null));
+ assertTrue(client == (clientBackTarget != null));
+ }
+
+ public void testBackTarget() {
+ checkTargets(false, false);
+ target.invokeSync(new Request("sample_target"), 5.0);
+ checkTargets(true, false);
+ serverBackTarget.invokeSync(new Request("sample_target"), 5.0);
+ checkTargets(true, true);
+
+ checkValues(0, 0);
+ target.invokeSync(new Request("inc"), 5.0);
+ checkValues(1, 0);
+ serverBackTarget.invokeSync(new Request("inc"), 5.0);
+ checkValues(1, 1);
+ clientBackTarget.invokeSync(new Request("inc"), 5.0);
+ checkValues(2, 1);
+
+ target.invokeSync(new Request("back_inc"), 5.0);
+ checkValues(2, 2);
+ serverBackTarget.invokeSync(new Request("back_inc"), 5.0);
+ checkValues(3, 2);
+ clientBackTarget.invokeSync(new Request("back_inc"), 5.0);
+ checkValues(3, 3);
+ }
+
+ public void testBogusBackTarget() {
+ Request req = new Request("inc");
+ try {
+ req.target();
+ assertTrue(false);
+ } catch (IllegalStateException e) {}
+ }
+}
diff --git a/jrt/tests/com/yahoo/jrt/BufferTest.java b/jrt/tests/com/yahoo/jrt/BufferTest.java
new file mode 100644
index 00000000000..a4a594b69e5
--- /dev/null
+++ b/jrt/tests/com/yahoo/jrt/BufferTest.java
@@ -0,0 +1,265 @@
+// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.jrt;
+
+
+import java.nio.ByteBuffer;
+import java.util.Arrays;
+
+
+public class BufferTest extends junit.framework.TestCase {
+
+ public BufferTest(String name) {
+ super(name);
+ }
+
+
+ public void testBuffer() {
+
+ int size = Buffer.MAX_IO + (Buffer.MAX_IO / 10);
+ Buffer buf = new Buffer(1024);
+ ByteBuffer b = null;
+
+ byte[] x = new byte[size];
+ byte[] y = new byte[size];
+
+ Arrays.fill(x, (byte) 10);
+ Arrays.fill(y, (byte) 55);
+
+ assertEquals(buf.bytes(), 0);
+ assertFalse(Arrays.equals(x, y));
+
+ b = buf.getWritable(512);
+ assertEquals(buf.bytes(), 0);
+ assertTrue(b.remaining() >= 512);
+ b.put((byte)42);
+ assertEquals(buf.bytes(), 1);
+
+ b = buf.getReadable();
+ assertEquals(buf.bytes(), 1);
+ assertEquals(b.remaining(), 1);
+ assertEquals(b.get(), 42);
+ assertEquals(buf.bytes(), 0);
+ assertEquals(b.remaining(), 0);
+
+ b = buf.getWritable(512);
+ assertTrue(b.remaining() >= 512);
+ assertEquals(buf.bytes(), 0);
+ b.put((byte)42);
+ assertEquals(buf.bytes(), 1);
+
+ b = buf.getWritable(size);
+ assertTrue(b.remaining() >= size);
+ assertEquals(buf.bytes(), 1);
+ b.put(x);
+ assertEquals(buf.bytes(), size + 1);
+
+ b = buf.getReadable();
+ assertEquals(buf.bytes(), size + 1);
+ assertEquals(b.remaining(), size + 1);
+ assertEquals(b.get(), 42);
+ assertEquals(buf.bytes(), size);
+ assertEquals(b.remaining(), size);
+ b.get(y);
+ assertEquals(buf.bytes(), 0);
+ assertEquals(b.remaining(), 0);
+ assertTrue(Arrays.equals(x, y));
+ }
+
+ public void testBufferCompact() {
+ Buffer buf = new Buffer(10);
+ buf.getWritable(3).put((byte)10).put((byte)20).put((byte)30);
+ assertEquals(10, buf.getReadable().capacity());
+ buf.getWritable(3).put((byte)11).put((byte)21).put((byte)31);
+ buf.getWritable(3).put((byte)12).put((byte)22).put((byte)32);
+ {
+ ByteBuffer bb = buf.getReadable();
+ assertEquals(10, bb.get());
+ assertEquals(20, bb.get());
+ assertEquals(30, bb.get());
+ }
+ {
+ ByteBuffer bb = buf.getReadable();
+ assertEquals(11, bb.get());
+ assertEquals(21, bb.get());
+ assertEquals(31, bb.get());
+ }
+ buf.getWritable(3).put((byte)13).put((byte)23).put((byte)33);
+ assertEquals(10, buf.getReadable().capacity());
+ {
+ ByteBuffer bb = buf.getReadable();
+ assertEquals(12, bb.get());
+ assertEquals(22, bb.get());
+ assertEquals(32, bb.get());
+ }
+ {
+ ByteBuffer bb = buf.getReadable();
+ assertEquals(13, bb.get());
+ assertEquals(23, bb.get());
+ assertEquals(33, bb.get());
+ }
+ {
+ ByteBuffer bb = buf.getReadable();
+ assertEquals(bb.position(), bb.limit());
+ }
+ }
+
+ public void testBufferMax() {
+
+ int size = Buffer.MAX_IO + (Buffer.MAX_IO / 10);
+ Buffer buf = new Buffer(1024);
+ ByteBuffer b = null;
+
+ byte[] x = new byte[size];
+ byte[] y = new byte[size];
+
+ Arrays.fill(x, (byte) 10);
+ Arrays.fill(y, (byte) 55);
+
+ assertEquals(buf.bytes(), 0);
+ assertFalse(Arrays.equals(x, y));
+
+ b = buf.getChannelWritable(size);
+ assertEquals(b.remaining(), Buffer.MAX_IO);
+ assertTrue(b.remaining() < size);
+ assertEquals(buf.bytes(), 0);
+ b.put(x, 0, Buffer.MAX_IO);
+ assertEquals(buf.bytes(), Buffer.MAX_IO);
+ assertEquals(b.remaining(), 0);
+
+ b = buf.getChannelWritable(size - Buffer.MAX_IO);
+ assertTrue(b.remaining() >= size - Buffer.MAX_IO);
+ assertEquals(buf.bytes(), Buffer.MAX_IO);
+ b.put(x, Buffer.MAX_IO, x.length - Buffer.MAX_IO);
+ assertEquals(buf.bytes(), size);
+
+ b = buf.getChannelReadable();
+ assertEquals(buf.bytes(), size);
+
+ b = buf.getChannelWritable(512);
+ assertEquals(buf.bytes(), size);
+ b.put((byte)42);
+ assertEquals(buf.bytes(), size + 1);
+
+ b = buf.getChannelReadable();
+ assertEquals(buf.bytes(), size + 1);
+ assertEquals(b.remaining(), Buffer.MAX_IO);
+ b.get(y, 0, Buffer.MAX_IO);
+ assertEquals(buf.bytes(), size - Buffer.MAX_IO + 1);
+
+ b = buf.getChannelReadable();
+ assertEquals(buf.bytes(), size - Buffer.MAX_IO + 1);
+ assertEquals(b.remaining(), size - Buffer.MAX_IO + 1);
+ b.get(y, Buffer.MAX_IO, y.length - Buffer.MAX_IO);
+ assertEquals(buf.bytes(), 1);
+ assertEquals(b.remaining(), 1);
+ assertEquals(b.get(), 42);
+ assertEquals(buf.bytes(), 0);
+ assertEquals(b.remaining(), 0);
+
+ assertTrue(Arrays.equals(x, y));
+ }
+
+ public void testBufferShrink() {
+ Buffer buf = new Buffer(500);
+ ByteBuffer b = null;
+ {
+ b = buf.getWritable(10);
+ assertEquals(500, b.capacity());
+ b.put((byte)10);
+ b.put((byte)20);
+ b.put((byte)30);
+ b.put((byte)40);
+ b.put((byte)50);
+
+ assertTrue(buf.shrink(400));
+ b = buf.getReadable();
+ assertEquals(400, b.capacity());
+ assertEquals(5, b.remaining());
+ assertEquals(10, b.get());
+ assertEquals(20, b.get());
+ assertEquals(30, b.get());
+ assertEquals(40, b.get());
+ assertEquals(50, b.get());
+ }
+ {
+ b = buf.getWritable(10);
+ assertEquals(400, b.capacity());
+ b.put((byte)10);
+ b.put((byte)20);
+ b.put((byte)30);
+ b.put((byte)40);
+ b.put((byte)50);
+
+ assertTrue(buf.shrink(300));
+ b = buf.getReadable();
+ assertEquals(300, b.capacity());
+ assertEquals(5, b.remaining());
+ assertEquals(10, b.get());
+ assertEquals(20, b.get());
+ assertEquals(30, b.get());
+ assertEquals(40, b.get());
+ assertEquals(50, b.get());
+ }
+ {
+ b = buf.getWritable(10);
+ assertEquals(300, b.capacity());
+ b.put((byte)10);
+ b.put((byte)20);
+ b.put((byte)30);
+ b.put((byte)40);
+ b.put((byte)50);
+
+ b = buf.getReadable();
+ assertTrue(buf.shrink(200));
+ b = buf.getReadable();
+ assertEquals(200, b.capacity());
+ assertEquals(5, b.remaining());
+ assertEquals(10, b.get());
+ assertEquals(20, b.get());
+ assertEquals(30, b.get());
+ assertEquals(40, b.get());
+ assertEquals(50, b.get());
+ }
+ {
+ b = buf.getWritable(10);
+ assertEquals(200, b.capacity());
+ b.put((byte)10);
+ b.put((byte)20);
+ b.put((byte)30);
+ b.put((byte)40);
+ b.put((byte)50);
+
+ b = buf.getReadable();
+ assertFalse(buf.shrink(500));
+ b = buf.getReadable();
+ assertEquals(200, b.capacity());
+ assertEquals(5, b.remaining());
+ assertEquals(10, b.get());
+ assertEquals(20, b.get());
+ assertEquals(30, b.get());
+ assertEquals(40, b.get());
+ assertEquals(50, b.get());
+ }
+ {
+ b = buf.getWritable(10);
+ assertEquals(200, b.capacity());
+ b.put((byte)10);
+ b.put((byte)20);
+ b.put((byte)30);
+ b.put((byte)40);
+ b.put((byte)50);
+
+ b = buf.getReadable();
+ assertTrue(buf.shrink(5));
+ assertFalse(buf.shrink(4));
+ b = buf.getReadable();
+ assertEquals(5, b.capacity());
+ assertEquals(5, b.remaining());
+ assertEquals(10, b.get());
+ assertEquals(20, b.get());
+ assertEquals(30, b.get());
+ assertEquals(40, b.get());
+ assertEquals(50, b.get());
+ }
+ }
+}
diff --git a/jrt/tests/com/yahoo/jrt/ConnectTest.java b/jrt/tests/com/yahoo/jrt/ConnectTest.java
new file mode 100644
index 00000000000..9597927b06a
--- /dev/null
+++ b/jrt/tests/com/yahoo/jrt/ConnectTest.java
@@ -0,0 +1,47 @@
+// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.jrt;
+
+
+public class ConnectTest extends junit.framework.TestCase {
+
+ public ConnectTest(String name) {
+ super(name);
+ }
+
+ public void testConnect() throws ListenFailedException {
+ Test.Orb server = new Test.Orb(new Transport());
+ Test.Orb client = new Test.Orb(new Transport());
+ Acceptor acceptor = server.listen(new Spec(Test.PORT));
+
+ assertTrue(server.checkLifeCounts(0, 0));
+ assertTrue(client.checkLifeCounts(0, 0));
+
+ Target target = client.connect(new Spec("localhost", Test.PORT));
+
+ for (int i = 0; i < 100; i++) {
+ if (client.initCount == 1 && server.initCount == 1) {
+ break;
+ }
+ try { Thread.sleep(100); } catch (InterruptedException e) {}
+ }
+
+ assertTrue(server.checkLifeCounts(1, 0));
+ assertTrue(client.checkLifeCounts(1, 0));
+
+ target.close();
+
+ for (int i = 0; i < 100; i++) {
+ if (client.finiCount == 1 && server.finiCount == 1) {
+ break;
+ }
+ try { Thread.sleep(100); } catch (InterruptedException e) {}
+ }
+
+ assertTrue(server.checkLifeCounts(1, 1));
+ assertTrue(client.checkLifeCounts(1, 1));
+
+ acceptor.shutdown().join();
+ client.transport().shutdown().join();
+ server.transport().shutdown().join();
+ }
+}
diff --git a/jrt/tests/com/yahoo/jrt/DetachTest.java b/jrt/tests/com/yahoo/jrt/DetachTest.java
new file mode 100644
index 00000000000..10f2485ae6d
--- /dev/null
+++ b/jrt/tests/com/yahoo/jrt/DetachTest.java
@@ -0,0 +1,136 @@
+// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.jrt;
+
+
+public class DetachTest extends junit.framework.TestCase {
+
+ Test.Orb server;
+ Acceptor acceptor;
+ Test.Orb client;
+ Target target;
+ Test.Receptor receptor;
+ Test.Barrier barrier;
+
+ public DetachTest(String name) {
+ super(name);
+ }
+
+ public void setUp() throws ListenFailedException {
+ server = new Test.Orb(new Transport());
+ client = new Test.Orb(new Transport());
+ acceptor = server.listen(new Spec(Test.PORT));
+ target = client.connect(new Spec("localhost", Test.PORT));
+
+ server.addMethod(new Method("d_inc", "i", "i", this,
+ "rpc_detach_inc"));
+ server.addMethod(new Method("d_inc_r", "i", "i", this,
+ "rpc_detach_inc_return"));
+ server.addMethod(new Method("inc_b", "i", "i", this,
+ "rpc_inc_barrier"));
+ receptor = new Test.Receptor();
+ barrier = new Test.Barrier();
+ }
+
+ public void tearDown() {
+ target.close();
+ acceptor.shutdown().join();
+ client.transport().shutdown().join();
+ server.transport().shutdown().join();
+ }
+
+ Request detached = null;
+
+ public void rpc_detach_inc(Request req) {
+ req.detach();
+ int value = req.parameters().get(0).asInt32();
+ req.returnValues().add(new Int32Value(value + 1));
+ detached = req;
+ }
+
+ public void rpc_detach_inc_return(Request req) {
+ req.detach();
+ int value = req.parameters().get(0).asInt32();
+ req.returnValues().add(new Int32Value(value + 1));
+ req.returnRequest();
+ }
+
+ public void rpc_inc_barrier(Request req) {
+ int value = req.parameters().get(0).asInt32();
+ req.returnValues().add(new Int32Value(value + 1));
+ receptor.put(req);
+ barrier.waitFor();
+ }
+
+ public void testDetach() {
+ Test.Waiter w1 = new Test.Waiter();
+ Request req1 = new Request("d_inc");
+ req1.parameters().add(new Int32Value(50));
+ target.invokeAsync(req1, 5.0, w1);
+
+ Request req2 = new Request("d_inc_r");
+ req2.parameters().add(new Int32Value(60));
+ target.invokeSync(req2, 5.0);
+
+ assertTrue(!req2.isError());
+ assertEquals(1, req2.returnValues().size());
+ assertEquals(61, req2.returnValues().get(0).asInt32());
+
+ assertTrue(detached != null);
+ assertTrue(!w1.isDone());
+ assertTrue(server.checkReadCounts(2, 0, 0));
+ assertTrue(server.checkWriteCounts(0, 1, 0));
+ assertTrue(client.checkReadCounts(0, 1, 0));
+ assertTrue(client.checkWriteCounts(2, 0, 0));
+ assertTrue(server.readBytes == client.writeBytes);
+ assertTrue(client.readBytes == server.writeBytes);
+
+ detached.returnRequest();
+ try {
+ detached.returnRequest();
+ assertTrue(false);
+ } catch (IllegalStateException e) {}
+ detached = null;
+ w1.waitDone();
+
+ assertTrue(!req1.isError());
+ assertEquals(1, req1.returnValues().size());
+ assertEquals(51, req1.returnValues().get(0).asInt32());
+ assertTrue(server.checkReadCounts(2, 0, 0));
+ assertTrue(server.checkWriteCounts(0, 2, 0));
+ assertTrue(client.checkReadCounts(0, 2, 0));
+ assertTrue(client.checkWriteCounts(2, 0, 0));
+ assertTrue(server.readBytes == client.writeBytes);
+ assertTrue(client.readBytes == server.writeBytes);
+ }
+
+ public void testBogusDetach() {
+ Request req1 = new Request("inc_b");
+ req1.parameters().add(new Int32Value(200));
+ try {
+ req1.detach();
+ assertTrue(false);
+ } catch (IllegalStateException e) {}
+
+ Request req2 = new Request("inc_b");
+ req2.parameters().add(new Int32Value(200));
+ try {
+ req2.returnRequest();
+ assertTrue(false);
+ } catch (IllegalStateException e) {}
+
+ Test.Waiter w = new Test.Waiter();
+ Request req3 = new Request("inc_b");
+ req3.parameters().add(new Int32Value(100));
+ target.invokeAsync(req3, 5.0, w);
+ Request blocked = (Request) receptor.get();
+ try {
+ blocked.returnRequest();
+ assertTrue(false);
+ } catch (IllegalStateException e) {}
+ barrier.breakIt();
+ w.waitDone();
+ assertTrue(!req3.isError());
+ assertEquals(1, req3.returnValues().size());
+ assertEquals(101, req3.returnValues().get(0).asInt32());
+ }
+}
diff --git a/jrt/tests/com/yahoo/jrt/EchoTest.java b/jrt/tests/com/yahoo/jrt/EchoTest.java
new file mode 100644
index 00000000000..a858ea76925
--- /dev/null
+++ b/jrt/tests/com/yahoo/jrt/EchoTest.java
@@ -0,0 +1,86 @@
+// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.jrt;
+
+
+public class EchoTest extends junit.framework.TestCase {
+
+ Supervisor server;
+ Acceptor acceptor;
+ Supervisor client;
+ Target target;
+ Values refValues;
+
+ public EchoTest(String name) {
+ super(name);
+ }
+
+ public void setUp() throws ListenFailedException {
+ server = new Supervisor(new Transport());
+ client = new Supervisor(new Transport());
+ acceptor = server.listen(new Spec(Test.PORT));
+ target = client.connect(new Spec("localhost", Test.PORT));
+ server.addMethod(new Method("echo", "*", "*", this, "rpc_echo"));
+ refValues = new Values();
+ byte[] dataValue = { 1, 2, 3, 4 };
+ byte[] int8Array = { 1, 2, 3, 4 };
+ short[] int16Array = { 2, 4, 6, 8 };
+ int[] int32Array = { 4, 8, 12, 16 };
+ long[] int64Array = { 8, 16, 24, 32 };
+ float[] floatArray = { 1.5f, 2.0f, 2.5f, 3.0f };
+ double[] doubleArray = { 1.25, 1.50, 1.75, 2.00 };
+ byte[][] dataArray = {{ 1, 0, 1, 0 },
+ { 0, 2, 0, 2 },
+ { 3, 0, 3, 0 },
+ { 0, 4, 0, 4 }};
+ String[] stringArray = { "one", "two", "three", "four" };
+ refValues.add(new Int8Value((byte)1));
+ refValues.add(new Int8Array(int8Array));
+ refValues.add(new Int16Value((short)2));
+ refValues.add(new Int16Array(int16Array));
+ refValues.add(new Int32Value(4));
+ refValues.add(new Int32Array(int32Array));
+ refValues.add(new Int64Value(8));
+ refValues.add(new Int64Array(int64Array));
+ refValues.add(new FloatValue(2.5f));
+ refValues.add(new FloatArray(floatArray));
+ refValues.add(new DoubleValue(3.75));
+ refValues.add(new DoubleArray(doubleArray));
+ refValues.add(new DataValue(dataValue));
+ refValues.add(new DataArray(dataArray));
+ refValues.add(new StringValue("test"));
+ refValues.add(new StringArray(stringArray));
+ }
+
+ public void tearDown() {
+ target.close();
+ acceptor.shutdown().join();
+ client.transport().shutdown().join();
+ server.transport().shutdown().join();
+ }
+
+ public void rpc_echo(Request req) {
+ if (!Test.equals(req.parameters(), refValues)) {
+ System.err.println("Parameters does not match reference values");
+ req.setError(ErrorCode.METHOD_FAILED, "parameter mismatch");
+ return;
+ }
+ Values p = req.parameters();
+ Values r = req.returnValues();
+ for (int i = 0; i < p.size(); i++) {
+ r.add(p.get(i));
+ }
+ }
+
+ public void testEcho() {
+ Request req = new Request("echo");
+ Values p = req.parameters();
+ for (int i = 0; i < refValues.size(); i++) {
+ p.add(refValues.get(i));
+ }
+ target.invokeSync(req, 60.0);
+ assertTrue(req.checkReturnTypes("bBhHiIlLfFdDxXsS"));
+ assertTrue(Test.equals(req.returnValues(), req.parameters()));
+ assertTrue(Test.equals(req.returnValues(), refValues));
+ assertTrue(Test.equals(req.parameters(), refValues));
+ }
+}
diff --git a/jrt/tests/com/yahoo/jrt/InvokeAsyncTest.java b/jrt/tests/com/yahoo/jrt/InvokeAsyncTest.java
new file mode 100644
index 00000000000..bc1f39c4a47
--- /dev/null
+++ b/jrt/tests/com/yahoo/jrt/InvokeAsyncTest.java
@@ -0,0 +1,62 @@
+// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.jrt;
+
+
+public class InvokeAsyncTest extends junit.framework.TestCase {
+
+ Supervisor server;
+ Acceptor acceptor;
+ Supervisor client;
+ Target target;
+ Test.Barrier barrier;
+
+ public InvokeAsyncTest(String name) {
+ super(name);
+ }
+
+ public void setUp() throws ListenFailedException {
+ server = new Supervisor(new Transport());
+ client = new Supervisor(new Transport());
+ acceptor = server.listen(new Spec(Test.PORT));
+ target = client.connect(new Spec("localhost", Test.PORT));
+ server.addMethod(new Method("concat", "ss", "s", this, "rpc_concat")
+ .methodDesc("Concatenate 2 strings")
+ .paramDesc(0, "str1", "a string")
+ .paramDesc(1, "str2", "another string")
+ .returnDesc(0, "ret", "str1 followed by str2"));
+ barrier = new Test.Barrier();
+ }
+
+ public void tearDown() {
+ target.close();
+ acceptor.shutdown().join();
+ client.transport().shutdown().join();
+ server.transport().shutdown().join();
+ }
+
+ public void rpc_concat(Request req) {
+ barrier.waitFor();
+ req.returnValues().add(new StringValue(req.parameters()
+ .get(0).asString() +
+ req.parameters()
+ .get(1).asString()));
+ }
+
+ public void testAsync() {
+
+ Request req = new Request("concat");
+ req.parameters().add(new StringValue("abc"));
+ req.parameters().add(new StringValue("def"));
+
+ Test.Waiter w = new Test.Waiter();
+ target.invokeAsync(req, 5.0, w);
+ assertFalse(w.isDone());
+ barrier.breakIt();
+ w.waitDone();
+ assertTrue(w.isDone());
+
+ assertTrue(!req.isError());
+ assertEquals(1, req.returnValues().size());
+ assertEquals("abcdef", req.returnValues().get(0).asString());
+ }
+}
diff --git a/jrt/tests/com/yahoo/jrt/InvokeErrorTest.java b/jrt/tests/com/yahoo/jrt/InvokeErrorTest.java
new file mode 100644
index 00000000000..8116abd5a15
--- /dev/null
+++ b/jrt/tests/com/yahoo/jrt/InvokeErrorTest.java
@@ -0,0 +1,149 @@
+// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.jrt;
+
+
+public class InvokeErrorTest extends junit.framework.TestCase {
+ final double timeout=60.0;
+ Supervisor server;
+ Acceptor acceptor;
+ Supervisor client;
+ Target target;
+ Test.Barrier barrier;
+
+ public InvokeErrorTest(String name) {
+ super(name);
+ }
+
+ public void setUp() throws ListenFailedException {
+ server = new Supervisor(new Transport());
+ client = new Supervisor(new Transport());
+ acceptor = server.listen(new Spec(Test.PORT));
+ target = client.connect(new Spec("localhost", Test.PORT));
+ server.addMethod(new Method("test", "iib", "i", this, "rpc_test"));
+ server.addMethod(new Method("test_barrier", "iib", "i", this,
+ "rpc_test_barrier"));
+ barrier = new Test.Barrier();
+ }
+
+ public void tearDown() {
+ target.close();
+ acceptor.shutdown().join();
+ client.transport().shutdown().join();
+ server.transport().shutdown().join();
+ }
+
+ 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 void rpc_test_barrier(Request req) {
+ rpc_test(req);
+ barrier.waitFor();
+ }
+
+ 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, timeout);
+ 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, timeout);
+ 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, timeout);
+ 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, timeout);
+ 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, timeout);
+ 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, timeout);
+ 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, timeout);
+ 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, timeout);
+ assertTrue(req2.isError());
+ assertEquals(0, req2.returnValues().size());
+ assertEquals(75000, req2.errorCode());
+ }
+
+ public void testConnectionError() {
+ Test.Waiter w = new Test.Waiter();
+ Request req1 = new Request("test_barrier");
+ req1.parameters().add(new Int32Value(42));
+ req1.parameters().add(new Int32Value(0));
+ req1.parameters().add(new Int8Value((byte)0));
+ target.invokeAsync(req1, timeout, w);
+ target.close();
+ client.transport().sync();
+ barrier.breakIt();
+ w.waitDone();
+ assertTrue(!target.isValid());
+ assertTrue(req1.isError());
+ assertEquals(0, req1.returnValues().size());
+ assertEquals(ErrorCode.CONNECTION, req1.errorCode());
+ }
+}
diff --git a/jrt/tests/com/yahoo/jrt/InvokeSyncTest.java b/jrt/tests/com/yahoo/jrt/InvokeSyncTest.java
new file mode 100644
index 00000000000..d8af986f588
--- /dev/null
+++ b/jrt/tests/com/yahoo/jrt/InvokeSyncTest.java
@@ -0,0 +1,82 @@
+// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.jrt;
+
+import java.io.ByteArrayOutputStream;
+import java.io.FileDescriptor;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.PrintStream;
+
+import com.yahoo.jrt.tool.RpcInvoker;
+
+
+public class InvokeSyncTest extends junit.framework.TestCase {
+
+ Supervisor server;
+ Acceptor acceptor;
+ Supervisor client;
+ Target target;
+
+ public InvokeSyncTest(String name) {
+ super(name);
+ }
+
+ public void setUp() throws ListenFailedException {
+ server = new Supervisor(new Transport());
+ client = new Supervisor(new Transport());
+ acceptor = server.listen(new Spec(Test.PORT));
+ target = client.connect(new Spec("localhost", Test.PORT));
+ server.addMethod(new Method("concat", "ss", "s", this, "rpc_concat")
+ .methodDesc("Concatenate 2 strings")
+ .paramDesc(0, "str1", "a string")
+ .paramDesc(1, "str2", "another string")
+ .returnDesc(0, "ret", "str1 followed by str2"));
+ server.addMethod(new Method("alltypes", "bhilfds", "s", this, "rpc_alltypes")
+ .methodDesc("Method taking all types of params"));
+ }
+
+ public void tearDown() {
+ System.setOut(new PrintStream(new FileOutputStream(FileDescriptor.out)));
+ target.close();
+ acceptor.shutdown().join();
+ client.transport().shutdown().join();
+ server.transport().shutdown().join();
+ }
+
+ public void rpc_concat(Request req) {
+ req.returnValues().add(new StringValue(req.parameters()
+ .get(0).asString() +
+ req.parameters()
+ .get(1).asString()));
+ }
+
+ public void rpc_alltypes(Request req) {
+ req.returnValues().add(new StringValue("This was alltypes. The string param was: "+req.parameters().get(6).asString()));
+ }
+
+ public void testSync() {
+ Request req = new Request("concat");
+ req.parameters().add(new StringValue("abc"));
+ req.parameters().add(new StringValue("def"));
+
+ target.invokeSync(req, 5.0);
+
+ assertTrue(!req.isError());
+ assertEquals(1, req.returnValues().size());
+ assertEquals("abcdef", req.returnValues().get(0).asString());
+ }
+
+ public void testRpcInvoker() throws IOException {
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ System.setOut(new PrintStream(baos));
+ RpcInvoker.main(new String[] {"-h", "localhost:"+Test.PORT, "concat", "s:foo", "s:bar"});
+ baos.flush();
+ assertEquals(baos.toString(), "foobar\n");
+ baos.reset();
+ System.setOut(new PrintStream(baos));
+ RpcInvoker.main(new String[] {"-h", "localhost:"+Test.PORT, "alltypes", "b:1", "h:2", "i:3", "l:4", "f:5.0", "d:6.0", "s:baz"});
+ baos.flush();
+ assertEquals(baos.toString(), "This was alltypes. The string param was: baz\n");
+ }
+
+}
diff --git a/jrt/tests/com/yahoo/jrt/InvokeVoidTest.java b/jrt/tests/com/yahoo/jrt/InvokeVoidTest.java
new file mode 100644
index 00000000000..4860b421146
--- /dev/null
+++ b/jrt/tests/com/yahoo/jrt/InvokeVoidTest.java
@@ -0,0 +1,74 @@
+// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.jrt;
+
+
+public class InvokeVoidTest extends junit.framework.TestCase {
+
+ Test.Orb server;
+ Acceptor acceptor;
+ Test.Orb client;
+ Target target;
+
+ public InvokeVoidTest(String name) {
+ super(name);
+ }
+
+ public void setUp() throws ListenFailedException {
+ server = new Test.Orb(new Transport());
+ client = new Test.Orb(new Transport());
+ acceptor = server.listen(new Spec(Test.PORT));
+ target = client.connect(new Spec("localhost", Test.PORT));
+
+ server.addMethod(new Method("set", "i", "", this, "rpc_set")
+ .methodDesc("Set the stored value")
+ .paramDesc(0, "value", "the new value"));
+ server.addMethod(new Method("inc", "", "", this, "rpc_inc")
+ .methodDesc("Increase the stored value"));
+ server.addMethod(new Method("get", "", "i", this, "rpc_get")
+ .methodDesc("Get the stored value")
+ .returnDesc(0, "value", "the stored value"));
+ }
+
+ public void tearDown() {
+ target.close();
+ acceptor.shutdown().join();
+ client.transport().shutdown().join();
+ server.transport().shutdown().join();
+ }
+
+ private int value = 0;
+
+ public void rpc_set(Request req) {
+ value = req.parameters().get(0).asInt32();
+ }
+ public void rpc_inc(Request req) {
+ value++;
+ }
+ public void rpc_get(Request req) {
+ req.returnValues().add(new Int32Value(value));
+ }
+
+ public void testInvokeVoid() {
+
+ Request req = new Request("set");
+ req.parameters().add(new Int32Value(40));
+ target.invokeSync(req, 5.0);
+ assertTrue(!req.isError());
+ assertEquals(0, req.returnValues().size());
+
+ target.invokeVoid(new Request("inc"));
+ target.invokeVoid(new Request("inc"));
+
+ req = new Request("get");
+ target.invokeSync(req, 5.0);
+ assertTrue(!req.isError());
+ assertEquals(42, req.returnValues().get(0).asInt32());
+
+ assertTrue(server.checkReadCounts(4, 0, 0));
+ assertTrue(server.checkWriteCounts(0, 2, 0));
+ assertTrue(client.checkReadCounts(0, 2, 0));
+ assertTrue(client.checkWriteCounts(4, 0, 0));
+ assertTrue(server.readBytes == client.writeBytes);
+ assertTrue(client.readBytes == server.writeBytes);
+ }
+}
diff --git a/jrt/tests/com/yahoo/jrt/ListenTest.java b/jrt/tests/com/yahoo/jrt/ListenTest.java
new file mode 100644
index 00000000000..d42c7dece9f
--- /dev/null
+++ b/jrt/tests/com/yahoo/jrt/ListenTest.java
@@ -0,0 +1,98 @@
+// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.jrt;
+
+
+public class ListenTest extends junit.framework.TestCase {
+
+ Supervisor server;
+
+ public ListenTest(String name) {
+ super(name);
+ }
+
+ public void setUp() {
+ server = new Supervisor(new Transport());
+ }
+
+ public void tearDown() {
+ server.transport().shutdown().join();
+ }
+
+ public void testListen() {
+ try {
+ Acceptor a = server.listen(new Spec(Test.PORT));
+ assertEquals(Test.PORT, a.port());
+ a.shutdown().join();
+ assertEquals(-1, a.port());
+ } catch (ListenFailedException e) {
+ assertTrue(false);
+ }
+ try {
+ Acceptor a = server.listen(new Spec(null, Test.PORT));
+ assertEquals(Test.PORT, a.port());
+ a.shutdown().join();
+ assertEquals(-1, a.port());
+ } catch (ListenFailedException e) {
+ assertTrue(false);
+ }
+ try {
+ Acceptor a = server.listen(new Spec("tcp/" + Test.PORT));
+ assertEquals(Test.PORT, a.port());
+ a.shutdown().join();
+ assertEquals(-1, a.port());
+ } catch (ListenFailedException e) {
+ assertTrue(false);
+ }
+ try {
+ Acceptor a = server.listen(new Spec(Test.PORT_0));
+ Acceptor b = server.listen(new Spec(Test.PORT_1));
+ Acceptor c = server.listen(new Spec(Test.PORT_2));
+ assertEquals(Test.PORT_0, a.port());
+ assertEquals(Test.PORT_1, b.port());
+ assertEquals(Test.PORT_2, c.port());
+ a.shutdown().join();
+ assertEquals(-1, a.port());
+ b.shutdown().join();
+ assertEquals(-1, b.port());
+ c.shutdown().join();
+ assertEquals(-1, c.port());
+ } catch (ListenFailedException e) {
+ assertTrue(false);
+ }
+ }
+
+ public void testBogusListen() {
+ try {
+ Acceptor a = server.listen(new Spec("bogus"));
+ assertTrue(false);
+ } catch (ListenFailedException e) {}
+
+ try {
+ Acceptor a = server.listen(new Spec(Test.PORT));
+ assertEquals(Test.PORT, a.port());
+ // try {
+ // Acceptor b = server.listen(new Spec(Test.PORT));
+ // assertTrue(false);
+ // } catch (ListenFailedException e) {}
+ a.shutdown().join();
+ assertEquals(-1, a.port());
+ } catch (ListenFailedException e) {
+ assertTrue(false);
+ }
+ }
+
+ public void testListenAnyPort() {
+ try {
+ Acceptor a = server.listen(new Spec("tcp/0"));
+ assertTrue(a.port() > 0);
+ // try {
+ // Acceptor b = server.listen(new Spec(a.port()));
+ // assertTrue(false);
+ // } catch (ListenFailedException e) {}
+ a.shutdown().join();
+ assertEquals(-1, a.port());
+ } catch (ListenFailedException e) {
+ assertTrue(false);
+ }
+ }
+}
diff --git a/jrt/tests/com/yahoo/jrt/MandatoryMethodsTest.java b/jrt/tests/com/yahoo/jrt/MandatoryMethodsTest.java
new file mode 100644
index 00000000000..7f2e073e4d8
--- /dev/null
+++ b/jrt/tests/com/yahoo/jrt/MandatoryMethodsTest.java
@@ -0,0 +1,97 @@
+// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.jrt;
+
+
+import java.util.HashSet;
+
+
+public class MandatoryMethodsTest extends junit.framework.TestCase {
+
+ Supervisor server;
+ Acceptor acceptor;
+ Supervisor client;
+ Target target;
+
+ public MandatoryMethodsTest(String name) {
+ super(name);
+ }
+
+ public void setUp() throws ListenFailedException {
+ server = new Supervisor(new Transport());
+ client = new Supervisor(new Transport());
+ acceptor = server.listen(new Spec(Test.PORT));
+ target = client.connect(new Spec("localhost", Test.PORT));
+ }
+
+ public void tearDown() {
+ target.close();
+ acceptor.shutdown().join();
+ client.transport().shutdown().join();
+ server.transport().shutdown().join();
+ }
+
+ public void testPing() {
+
+ Request req = new Request("frt.rpc.ping");
+ target.invokeSync(req, 5.0);
+
+ assertFalse(req.isError());
+ assertEquals(0, req.returnValues().size());
+ }
+
+ public void testGetMethodList() {
+
+ Request req = new Request("frt.rpc.getMethodList");
+ target.invokeSync(req, 5.0);
+
+ assertFalse(req.isError());
+ assertTrue(req.checkReturnTypes("SSS"));
+ String[] names = req.returnValues().get(0).asStringArray();
+ String[] param = req.returnValues().get(1).asStringArray();
+ String[] ret = req.returnValues().get(2).asStringArray();
+ assertEquals(3, names.length);
+ assertTrue(names.length == param.length);
+ assertTrue(names.length == ret.length);
+ HashSet<String> foundSet = new HashSet<String>();
+ for (int i = 0; i < names.length; i++) {
+ if (names[i].equals("frt.rpc.ping")) {
+ assertEquals("", param[i]);
+ assertEquals("", ret[i]);
+ } else if (names[i].equals("frt.rpc.getMethodList")) {
+ assertEquals("", param[i]);
+ assertEquals("SSS", ret[i]);
+ } else if (names[i].equals("frt.rpc.getMethodInfo")) {
+ assertEquals("s", param[i]);
+ assertEquals("sssSSSS", ret[i]);
+ }
+ foundSet.add(names[i]);
+ }
+ assertEquals(3, foundSet.size());
+ assertTrue(foundSet.contains("frt.rpc.ping"));
+ assertTrue(foundSet.contains("frt.rpc.getMethodList"));
+ assertTrue(foundSet.contains("frt.rpc.getMethodInfo"));
+ }
+
+ public void testGetMethodInfo() {
+ Request req = new Request("frt.rpc.getMethodInfo");
+ req.parameters().add(new StringValue("frt.rpc.getMethodInfo"));
+ target.invokeSync(req, 5.0);
+
+ assertFalse(req.isError());
+ assertTrue(req.checkReturnTypes("sssSSSS"));
+
+ String desc = req.returnValues().get(0).asString();
+ String param = req.returnValues().get(1).asString();
+ String ret = req.returnValues().get(2).asString();
+ String[] paramName = req.returnValues().get(3).asStringArray();
+ String[] paramDesc = req.returnValues().get(4).asStringArray();
+ String[] retName = req.returnValues().get(5).asStringArray();
+ String[] retDesc = req.returnValues().get(6).asStringArray();
+ assertEquals("s", param);
+ assertEquals("sssSSSS", ret);
+ assertEquals(1, paramName.length);
+ assertTrue(paramName.length == paramDesc.length);
+ assertEquals(7, retName.length);
+ assertTrue(retName.length == retDesc.length);
+ }
+}
diff --git a/jrt/tests/com/yahoo/jrt/PacketTest.java b/jrt/tests/com/yahoo/jrt/PacketTest.java
new file mode 100644
index 00000000000..86c05525763
--- /dev/null
+++ b/jrt/tests/com/yahoo/jrt/PacketTest.java
@@ -0,0 +1,129 @@
+// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.jrt;
+
+
+import java.nio.ByteBuffer;
+
+
+public class PacketTest extends junit.framework.TestCase {
+
+ public PacketTest(String name) {
+ super(name);
+ }
+
+
+ public void testRequestPacket() {
+
+ Values params = new Values();
+ params.add(new Int32Value(123));
+
+ Packet packet = new RequestPacket(Packet.FLAG_NOREPLY, 42,
+ "foobar", params);
+ PacketInfo info = packet.getPacketInfo();
+
+ ByteBuffer buf = ByteBuffer.allocate(info.packetLength());
+ info.encodePacket(packet, buf);
+ buf.flip();
+
+ int bytes = 12 + 4 + 6 + params.bytes();
+ ByteBuffer ref = ByteBuffer.allocate(bytes);
+ ref.putInt(bytes - 4); // plen
+ ref.putShort((short)2); // flags (no reply)
+ ref.putShort((short)100); // pcode (request)
+ ref.putInt(42); // reqId
+ ref.putInt(6); // method name length
+ ref.put((byte)'f').put((byte)'o').put((byte)'o')
+ .put((byte)'b').put((byte)'a').put((byte)'r');
+ params.encode(ref);
+ assertEquals(0, ref.remaining());
+ ref.flip();
+ assertTrue(buf.equals(ref));
+
+ PacketInfo info2 = PacketInfo.getPacketInfo(buf);
+ assertTrue(info2 != null);
+ assertEquals(info2.packetLength(), buf.remaining());
+ Packet packet2 = info2.decodePacket(buf);
+ assertEquals(0, buf.remaining());
+
+ assertEquals(packet2.requestId(), 42);
+ assertEquals(((RequestPacket)packet2).methodName(), "foobar");
+ Values params2 = ((RequestPacket)packet2).parameters();
+ assertEquals(params2.size(), 1);
+ assertEquals(params2.get(0).type(), Value.INT32);
+ assertEquals(params2.get(0).asInt32(), 123);
+ }
+
+
+ public void testReplyPacket() {
+
+ Values ret = new Values();
+ ret.add(new Int32Value(123));
+
+ Packet packet = new ReplyPacket(0, 42, ret);
+ PacketInfo info = packet.getPacketInfo();
+
+ ByteBuffer buf = ByteBuffer.allocate(info.packetLength());
+ info.encodePacket(packet, buf);
+ buf.flip();
+
+ int bytes = 12 + ret.bytes();
+ ByteBuffer ref = ByteBuffer.allocate(bytes);
+ ref.putInt(bytes - 4); // plen
+ ref.putShort((short)0); // flags
+ ref.putShort((short)101); // pcode (reply)
+ ref.putInt(42); // reqId
+ ret.encode(ref);
+ assertEquals(0, ref.remaining());
+ ref.flip();
+ assertTrue(buf.equals(ref));
+
+ PacketInfo info2 = PacketInfo.getPacketInfo(buf);
+ assertTrue(info2 != null);
+ assertEquals(info2.packetLength(), buf.remaining());
+ Packet packet2 = info2.decodePacket(buf);
+ assertEquals(0, buf.remaining());
+
+ assertEquals(packet2.requestId(), 42);
+ Values ret2 = ((ReplyPacket)packet2).returnValues();
+ assertEquals(ret2.size(), 1);
+ assertEquals(ret2.get(0).type(), Value.INT32);
+ assertEquals(ret2.get(0).asInt32(), 123);
+ }
+
+
+ public void testErrorPacket() {
+
+ String errStr = "NSM";
+ Packet packet =
+ new ErrorPacket(0, 42, ErrorCode.NO_SUCH_METHOD, errStr);
+ PacketInfo info = packet.getPacketInfo();
+
+ ByteBuffer buf = ByteBuffer.allocate(info.packetLength());
+ info.encodePacket(packet, buf);
+ buf.flip();
+
+ int bytes = 12 + 4 + 4 + 3;
+ ByteBuffer ref = ByteBuffer.allocate(bytes);
+ ref.putInt(bytes - 4); // plen
+ ref.putShort((short)0); // flags
+ ref.putShort((short)102); // pcode (error)
+ ref.putInt(42); // reqId
+ ref.putInt(ErrorCode.NO_SUCH_METHOD);
+ ref.putInt(3); // length of errorMessage
+ ref.put((byte)'N').put((byte)'S').put((byte)'M');
+ assertEquals(0, ref.remaining());
+ ref.flip();
+ assertTrue(buf.equals(ref));
+
+ PacketInfo info2 = PacketInfo.getPacketInfo(buf);
+ assertTrue(info2 != null);
+ assertEquals(info2.packetLength(), buf.remaining());
+ Packet packet2 = info2.decodePacket(buf);
+ assertEquals(0, buf.remaining());
+
+ assertEquals(packet2.requestId(), 42);
+ assertEquals(ErrorCode.NO_SUCH_METHOD,
+ ((ErrorPacket)packet2).errorCode());
+ assertEquals(errStr, ((ErrorPacket)packet2).errorMessage());
+ }
+}
diff --git a/jrt/tests/com/yahoo/jrt/QueueTest.java b/jrt/tests/com/yahoo/jrt/QueueTest.java
new file mode 100644
index 00000000000..f89d31923a5
--- /dev/null
+++ b/jrt/tests/com/yahoo/jrt/QueueTest.java
@@ -0,0 +1,97 @@
+// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.jrt;
+
+public class QueueTest extends junit.framework.TestCase {
+
+ public QueueTest(String name) {
+ super(name);
+ }
+
+ public void testEmpty() {
+ Queue queue = new Queue();
+
+ assertTrue(queue.isEmpty());
+ assertTrue(queue.size() == 0);
+ assertTrue(queue.dequeue() == null);
+ queue.enqueue(new Object());
+ assertFalse(queue.isEmpty());
+ assertFalse(queue.size() == 0);
+ assertFalse(queue.dequeue() == null);
+ }
+
+ public void testEnqueueDequeue() {
+ Queue queue = new Queue();
+ Integer int1 = new Integer(1);
+ Integer int2 = new Integer(2);
+ Integer int3 = new Integer(3);
+ Integer int4 = new Integer(4);
+ Integer int5 = new Integer(5);
+
+ assertEquals(queue.size(), 0);
+ queue.enqueue(int1);
+ assertEquals(queue.size(), 1);
+ assertTrue(queue.dequeue() == int1);
+ assertEquals(queue.size(), 0);
+
+ queue.enqueue(int1);
+ assertEquals(queue.size(), 1);
+ queue.enqueue(int2);
+ assertEquals(queue.size(), 2);
+ queue.enqueue(int3);
+ assertEquals(queue.size(), 3);
+ assertTrue(queue.dequeue() == int1);
+ assertEquals(queue.size(), 2);
+ assertTrue(queue.dequeue() == int2);
+ assertEquals(queue.size(), 1);
+ assertTrue(queue.dequeue() == int3);
+ assertEquals(queue.size(), 0);
+
+ queue.enqueue(int1);
+ assertEquals(queue.size(), 1);
+ queue.enqueue(int2);
+ assertEquals(queue.size(), 2);
+ queue.enqueue(int3);
+ assertEquals(queue.size(), 3);
+ assertTrue(queue.dequeue() == int1);
+ assertEquals(queue.size(), 2);
+ assertTrue(queue.dequeue() == int2);
+ assertEquals(queue.size(), 1);
+ queue.enqueue(int4);
+ assertEquals(queue.size(), 2);
+ queue.enqueue(int5);
+ assertEquals(queue.size(), 3);
+
+ assertTrue(queue.dequeue() == int3);
+ assertEquals(queue.size(), 2);
+ assertTrue(queue.dequeue() == int4);
+ assertEquals(queue.size(), 1);
+ assertTrue(queue.dequeue() == int5);
+ assertEquals(queue.size(), 0);
+ }
+
+ public void testFlush() {
+ Queue src = new Queue();
+ Queue dst = new Queue();
+ Integer int1 = new Integer(1);
+ Integer int2 = new Integer(2);
+ Integer int3 = new Integer(3);
+
+ assertTrue(src.flush(dst) == 0);
+ assertEquals(src.size(), 0);
+ assertEquals(dst.size(), 0);
+
+ src.enqueue(int1);
+ src.enqueue(int2);
+ src.enqueue(int3);
+
+ assertEquals(src.size(), 3);
+ assertEquals(dst.size(), 0);
+ assertTrue(src.flush(dst) == 3);
+ assertEquals(src.size(), 0);
+ assertEquals(dst.size(), 3);
+
+ assertTrue(dst.dequeue() == int1);
+ assertTrue(dst.dequeue() == int2);
+ assertTrue(dst.dequeue() == int3);
+ }
+}
diff --git a/jrt/tests/com/yahoo/jrt/SchedulerTest.java b/jrt/tests/com/yahoo/jrt/SchedulerTest.java
new file mode 100644
index 00000000000..785bc3ff719
--- /dev/null
+++ b/jrt/tests/com/yahoo/jrt/SchedulerTest.java
@@ -0,0 +1,238 @@
+// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.jrt;
+
+import java.util.Random;
+
+public class SchedulerTest extends junit.framework.TestCase {
+
+ long now; // fake time
+ Scheduler scheduler;
+
+ private class MyTask implements Runnable {
+ private Task task;
+ private long target;
+ private long actual = 0;
+ private boolean done = false;
+ private boolean multiple = false;
+
+ public MyTask(long target) {
+ task = new Task(scheduler, this);
+ this.target = target;
+ }
+
+ public void schedule() {
+ task.schedule(target / 1000.0);
+ }
+
+ public boolean unschedule() {
+ return task.unschedule();
+ }
+
+ public boolean kill() {
+ return task.kill();
+ }
+
+ public boolean done() {
+ return done;
+ }
+
+ public boolean check() {
+ if (!done || multiple) {
+ return false;
+ }
+ if (actual < target) {
+ return false;
+ }
+ // 2 * Scheduler.TICK == 200
+ return ((actual - target) <= 200);
+ }
+
+ public void run() {
+ multiple = done;
+ done = true;
+ actual = now;
+ }
+ }
+
+ private class RTTask implements Runnable {
+ private Task task;
+ private int cnt = 0;
+
+ public RTTask() {
+ task = new Task(scheduler, this);
+ }
+
+ public Task task() {
+ return task;
+ }
+
+ public void schedule() {
+ task.scheduleNow();
+ }
+
+ public boolean unschedule() {
+ return task.unschedule();
+ }
+
+ public boolean kill() {
+ return task.kill();
+ }
+
+ public int cnt() {
+ return cnt;
+ }
+
+ public void run() {
+ cnt++;
+ task.scheduleNow();
+ }
+ }
+
+ public SchedulerTest(String name) {
+ super(name);
+ }
+
+ public void setUp() {
+ now = 0;
+ scheduler = new Scheduler(now);
+ }
+
+ public void tearDown() {
+ scheduler = null;
+ }
+
+ public void testTimeliness() {
+ Random rand = new Random(73201242);
+
+ RTTask rt1 = new RTTask();
+ RTTask rt2 = new RTTask();
+ RTTask rt3 = new RTTask();
+ rt1.schedule();
+ rt2.schedule();
+ rt3.schedule();
+
+ MyTask[] tasks = new MyTask[250000];
+ for (int i = 0; i < tasks.length; i++) {
+ tasks[i] = new MyTask(rand.nextInt(131072));
+ tasks[i].schedule();
+ }
+ int iterations = 0;
+ while (now < 135000) {
+ now += 10;
+ scheduler.checkTasks(now);
+ iterations++;
+ }
+ assertEquals(iterations, rt1.cnt());
+ assertEquals(iterations, rt2.cnt());
+ assertEquals(iterations, rt3.cnt());
+ for (int i = 0; i < tasks.length; i++) {
+ assertTrue(tasks[i].check());
+ }
+ }
+
+ public void testUnschedule() {
+ MyTask t1 = new MyTask(1000);
+ MyTask t2 = new MyTask(1000);
+ MyTask t3 = new MyTask(1000);
+ MyTask t4 = new MyTask(1000);
+ MyTask t5 = new MyTask(1000);
+
+ RTTask rt1 = new RTTask();
+ RTTask rt2 = new RTTask();
+ RTTask rt3 = new RTTask();
+ RTTask rt4 = new RTTask();
+ RTTask rt5 = new RTTask();
+
+ assertFalse(t4.kill());
+
+ t1.schedule();
+ t2.schedule();
+ t3.schedule();
+ t4.schedule();
+ t5.schedule();
+
+ assertFalse(rt4.kill());
+
+ rt1.schedule();
+ rt2.schedule();
+ rt3.schedule();
+ rt4.schedule();
+ rt5.schedule();
+
+ assertTrue(t2.unschedule());
+ assertTrue(t1.unschedule());
+ assertTrue(t5.unschedule());
+
+ assertFalse(t2.unschedule());
+ assertFalse(t1.unschedule());
+ assertFalse(t5.unschedule());
+
+ t2.schedule();
+ t1.schedule();
+ assertTrue(t2.kill());
+ t2.schedule();
+ assertFalse(t2.kill());
+
+ int cnt = 0;
+ while (now < 5000) {
+ scheduler.checkTasks(now);
+ now += 10;
+ cnt++;
+ }
+ int old_cnt = cnt;
+ assertTrue(rt1.kill());
+ assertTrue(rt3.unschedule());
+ assertTrue(rt2.unschedule());
+ rt1.schedule();
+ rt2.schedule();
+ while (now < 10000) {
+ scheduler.checkTasks(now);
+ now += 10;
+ cnt++;
+ }
+
+ assertTrue(t1.check());
+ assertFalse(t2.done());
+ assertTrue(t3.check());
+ assertFalse(t4.done());
+ assertFalse(t5.done());
+
+ assertEquals(old_cnt, rt1.cnt());
+ assertEquals(cnt, rt2.cnt());
+ assertEquals(old_cnt, rt3.cnt());
+ assertEquals(0, rt4.cnt());
+ assertEquals(cnt, rt5.cnt());
+ }
+
+ public void testSlowEventLoop() {
+ scheduler.checkTasks(now);
+ now += 10000;
+ MyTask task1 = new MyTask(5000);
+ task1.schedule();
+ int cnt1 = 0;
+ while (true) {
+ scheduler.checkTasks(now);
+ if (task1.done()) {
+ break;
+ }
+ cnt1++;
+ now += 10;
+ }
+ assertTrue(cnt1 > 400 && cnt1 < 500);
+
+ scheduler.checkTasks(now);
+ now += 10000;
+ MyTask task2 = new MyTask(5000);
+ task2.schedule();
+ int cnt2 = 0;
+ while (true) {
+ scheduler.checkTasks(now);
+ if (task2.done()) {
+ break;
+ }
+ cnt2++;
+ now += 10000;
+ }
+ assertTrue(cnt2 > 10 && cnt2 < 30);
+ }
+}
diff --git a/jrt/tests/com/yahoo/jrt/SessionTest.java b/jrt/tests/com/yahoo/jrt/SessionTest.java
new file mode 100644
index 00000000000..800c28bc6ce
--- /dev/null
+++ b/jrt/tests/com/yahoo/jrt/SessionTest.java
@@ -0,0 +1,451 @@
+// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.jrt;
+
+
+public class SessionTest extends junit.framework.TestCase
+ implements SessionHandler {
+
+ private static class Session {
+ private static int cnt = 0;
+ private static boolean error = false;
+
+ private int value = 0;
+ private boolean gotInit = false;
+ private boolean gotLive = false;
+ private boolean gotDown = false;
+ private boolean gotFini = false;
+
+ private static synchronized void add() {
+ cnt++;
+ }
+
+ private static synchronized void sub() {
+ cnt--;
+ }
+
+ public Session() {
+ add();
+ }
+
+ public void init() {
+ if (gotInit || gotLive || gotDown || gotFini) {
+ setError();
+ }
+ gotInit = true;
+ }
+
+ public void live() {
+ if (!gotInit || gotLive || gotDown || gotFini) {
+ setError();
+ }
+ gotLive = true;
+ }
+
+ public void touch() {
+ if (!gotInit || gotFini) {
+ setError();
+ }
+ }
+
+ public int value() {
+ if (!gotInit || gotFini) {
+ setError();
+ }
+ return value;
+ }
+
+ public void value(int value) {
+ if (!gotInit || gotFini) {
+ setError();
+ }
+ this.value = value;
+ }
+
+ public void down() {
+ if (!gotInit || gotDown || gotFini) {
+ setError();
+ }
+ gotDown = true;
+ }
+
+ public void fini() {
+ if (!gotInit || !gotDown || gotFini) {
+ setError();
+ }
+ gotFini = true;
+ sub();
+ }
+
+ public static int cnt() {
+ return cnt;
+ }
+
+ public static void setError() {
+ error = true;
+ Throwable e = new RuntimeException("ERROR TRACE");
+ e.printStackTrace();
+ }
+
+ public static boolean getError() {
+ return error;
+ }
+
+ public static void reset() {
+ error = false;
+ cnt = 0;
+ }
+ }
+
+ Test.Orb server;
+ Acceptor acceptor;
+ Test.Orb client;
+ Target target;
+ Test.Receptor receptor;
+
+ public SessionTest(String name) {
+ super(name);
+ }
+
+ public void setUp() throws ListenFailedException {
+ Session.reset();
+ server = new Test.Orb(new Transport());
+ server.setSessionHandler(this);
+ client = new Test.Orb(new Transport());
+ client.setSessionHandler(this);
+ acceptor = server.listen(new Spec(Test.PORT));
+ target = client.connect(new Spec("localhost", Test.PORT),
+ new Session());
+
+ server.addMethod(new Method("set", "i", "", this,
+ "rpc_set"));
+ server.addMethod(new Method("get", "", "i", this,
+ "rpc_get"));
+ server.addMethod(new Method("call_detach", "", "", this,
+ "rpc_call_detach"));
+ client.addMethod(new Method("detach", "", "", this,
+ "rpc_detach"));
+ receptor = new Test.Receptor();
+ }
+
+ public void tearDown() {
+ target.close();
+ acceptor.shutdown().join();
+ client.transport().shutdown().join();
+ server.transport().shutdown().join();
+ }
+
+ public void handleSessionInit(Target t) {
+ Object ctx = t.getContext();
+ if (t.isClient()) {
+ if (ctx == null) {
+ Session.setError();
+ }
+ }
+ if (t.isServer()) {
+ if (ctx != null) {
+ Session.setError();
+ }
+ t.setContext(new Session());
+ }
+ Session s = (Session) t.getContext();
+ if (s == null) {
+ Session.setError();
+ } else {
+ s.init();
+ }
+ }
+
+ public void handleSessionLive(Target t) {
+ Session s = (Session) t.getContext();
+ if (s == null) {
+ Session.setError();
+ } else {
+ s.live();
+ }
+ }
+
+ public void handleSessionDown(Target t) {
+ Session s = (Session) t.getContext();
+ if (s == null) {
+ Session.setError();
+ } else {
+ s.down();
+ }
+ }
+
+ public void handleSessionFini(Target t) {
+ Session s = (Session) t.getContext();
+ if (s == null) {
+ Session.setError();
+ } else {
+ s.fini();
+ }
+ }
+
+ public void rpc_set(Request req) {
+ Session s = (Session) req.target().getContext();
+ s.value(req.parameters().get(0).asInt32());
+ }
+
+ public void rpc_get(Request req) {
+ Session s = (Session) req.target().getContext();
+ req.returnValues().add(new Int32Value(s.value()));
+ }
+
+ public void rpc_call_detach(Request req) {
+ Session s = (Session) req.target().getContext();
+ s.touch();
+ req.target().invokeVoid(new Request("detach"));
+ }
+
+ public void rpc_detach(Request req) {
+ Session s = (Session) req.target().getContext();
+ if (s == null) {
+ Session.setError();
+ } else {
+ s.touch();
+ }
+ req.detach();
+ receptor.put(req);
+ }
+
+ public void waitState(int sessionCount,
+ int serverInitCount,
+ int serverLiveCount,
+ int serverDownCount,
+ int serverFiniCount,
+ int clientInitCount,
+ int clientLiveCount,
+ int clientDownCount,
+ int clientFiniCount) {
+ server.transport().sync().sync();
+ client.transport().sync().sync();
+ for (int i = 0; i < 100; i++) {
+ if ((sessionCount == Session.cnt() || sessionCount < 0) &&
+ (serverInitCount == server.initCount || serverInitCount < 0) &&
+ (serverLiveCount == server.liveCount || serverLiveCount < 0) &&
+ (serverDownCount == server.downCount || serverDownCount < 0) &&
+ (serverFiniCount == server.finiCount || serverFiniCount < 0) &&
+ (clientInitCount == client.initCount || clientInitCount < 0) &&
+ (clientLiveCount == client.liveCount || clientLiveCount < 0) &&
+ (clientDownCount == client.downCount || clientDownCount < 0) &&
+ (clientFiniCount == client.finiCount || clientFiniCount < 0)) {
+ break;
+ }
+ try { Thread.sleep(100); } catch (InterruptedException e) {}
+ }
+ server.transport().sync().sync();
+ client.transport().sync().sync();
+ }
+
+ public void testConnDownLast() {
+ waitState(2, 1, 1, 0, 0, 1, 1, 0, 0);
+ assertEquals(2, Session.cnt());
+ assertEquals(1, server.initCount);
+ assertEquals(1, server.liveCount);
+ assertEquals(0, server.downCount);
+ assertEquals(0, server.finiCount);
+ assertEquals(1, client.initCount);
+ assertEquals(1, client.liveCount);
+ assertEquals(0, client.downCount);
+ assertEquals(0, client.finiCount);
+
+ Request req = new Request("get");
+ target.invokeSync(req, 5.0);
+ assertEquals(0, req.returnValues().get(0).asInt32());
+
+ req = new Request("set");
+ req.parameters().add(new Int32Value(42));
+ target.invokeSync(req, 5.0);
+ assertTrue(!req.isError());
+
+ req = new Request("get");
+ target.invokeSync(req, 5.0);
+ assertEquals(42, req.returnValues().get(0).asInt32());
+
+ assertEquals(2, Session.cnt());
+ assertEquals(1, server.initCount);
+ assertEquals(1, server.liveCount);
+ assertEquals(0, server.downCount);
+ assertEquals(0, server.finiCount);
+ assertEquals(1, client.initCount);
+ assertEquals(1, client.liveCount);
+ assertEquals(0, client.downCount);
+ assertEquals(0, client.finiCount);
+
+ target.close();
+ waitState(0, 1, 1, 1, 1, 1, 1, 1, 1);
+ assertEquals(0, Session.cnt());
+ assertEquals(1, server.initCount);
+ assertEquals(1, server.liveCount);
+ assertEquals(1, server.downCount);
+ assertEquals(1, server.finiCount);
+ assertEquals(1, client.initCount);
+ assertEquals(1, client.liveCount);
+ assertEquals(1, client.downCount);
+ assertEquals(1, client.finiCount);
+ assertFalse(Session.getError());
+ }
+
+ public void testReqDoneLast() {
+ waitState(2, 1, 1, 0, 0, 1, 1, 0, 0);
+ assertEquals(2, Session.cnt());
+ assertEquals(1, server.initCount);
+ assertEquals(1, server.liveCount);
+ assertEquals(0, server.downCount);
+ assertEquals(0, server.finiCount);
+ assertEquals(1, client.initCount);
+ assertEquals(1, client.liveCount);
+ assertEquals(0, client.downCount);
+ assertEquals(0, client.finiCount);
+
+ Request req = new Request("get");
+ target.invokeSync(req, 5.0);
+ assertEquals(0, req.returnValues().get(0).asInt32());
+
+ req = new Request("set");
+ req.parameters().add(new Int32Value(42));
+ target.invokeSync(req, 5.0);
+ assertTrue(!req.isError());
+
+ req = new Request("get");
+ target.invokeSync(req, 5.0);
+ assertEquals(42, req.returnValues().get(0).asInt32());
+
+ assertEquals(2, Session.cnt());
+ assertEquals(1, server.initCount);
+ assertEquals(1, server.liveCount);
+ assertEquals(0, server.downCount);
+ assertEquals(0, server.finiCount);
+ assertEquals(1, client.initCount);
+ assertEquals(1, client.liveCount);
+ assertEquals(0, client.downCount);
+ assertEquals(0, client.finiCount);
+
+ req = new Request("call_detach");
+ target.invokeSync(req, 5.0);
+ assertTrue(!req.isError());
+ Request detached = (Request) receptor.get();
+
+ target.close();
+ waitState(1, 1, 1, 1, 1, 1, 1, 1, 0);
+ assertEquals(1, Session.cnt());
+ assertEquals(1, server.initCount);
+ assertEquals(1, server.liveCount);
+ assertEquals(1, server.downCount);
+ assertEquals(1, server.finiCount);
+ assertEquals(1, client.initCount);
+ assertEquals(1, client.liveCount);
+ assertEquals(1, client.downCount);
+ assertEquals(0, client.finiCount);
+
+ detached.returnRequest();
+ waitState(0, 1, 1, 1, 1, 1, 1, 1, 1);
+ assertEquals(0, Session.cnt());
+ assertEquals(1, server.initCount);
+ assertEquals(1, server.liveCount);
+ assertEquals(1, server.downCount);
+ assertEquals(1, server.finiCount);
+ assertEquals(1, client.initCount);
+ assertEquals(1, client.liveCount);
+ assertEquals(1, client.downCount);
+ assertEquals(1, client.finiCount);
+ assertFalse(Session.getError());
+ }
+
+ public void testNeverLive() {
+ waitState(2, 1, 1, 0, 0, 1, 1, 0, 0);
+ assertEquals(2, Session.cnt());
+ assertEquals(1, server.initCount);
+ assertEquals(1, server.liveCount);
+ assertEquals(0, server.downCount);
+ assertEquals(0, server.finiCount);
+ assertEquals(1, client.initCount);
+ assertEquals(1, client.liveCount);
+ assertEquals(0, client.downCount);
+ assertEquals(0, client.finiCount);
+
+ target.close();
+ waitState(0, 1, 1, 1, 1, 1, 1, 1, 1);
+ assertEquals(0, Session.cnt());
+ assertEquals(1, server.initCount);
+ assertEquals(1, server.liveCount);
+ assertEquals(1, server.downCount);
+ assertEquals(1, server.finiCount);
+ assertEquals(1, client.initCount);
+ assertEquals(1, client.liveCount);
+ assertEquals(1, client.downCount);
+ assertEquals(1, client.finiCount);
+
+ Target bogus = client.connect(new Spec("bogus"),
+ new Session());
+ waitState(0, 1, 1, 1, 1, 2, 1, 2, 2);
+ assertEquals(0, Session.cnt());
+ assertEquals(1, server.initCount);
+ assertEquals(1, server.liveCount);
+ assertEquals(1, server.downCount);
+ assertEquals(1, server.finiCount);
+ assertEquals(2, client.initCount);
+ assertEquals(1, client.liveCount); // <--- NB
+ assertEquals(2, client.downCount);
+ assertEquals(2, client.finiCount);
+ assertFalse(Session.getError());
+ }
+
+ public void testTransportDown() {
+ waitState(2, 1, 1, 0, 0, 1, 1, 0, 0);
+ assertEquals(2, Session.cnt());
+ assertEquals(1, server.initCount);
+ assertEquals(1, server.liveCount);
+ assertEquals(0, server.downCount);
+ assertEquals(0, server.finiCount);
+ assertEquals(1, client.initCount);
+ assertEquals(1, client.liveCount);
+ assertEquals(0, client.downCount);
+ assertEquals(0, client.finiCount);
+
+ server.transport().shutdown().join();
+
+ waitState(0, 1, 1, 1, 1, 1, 1, 1, 1);
+ assertEquals(0, Session.cnt());
+ assertEquals(1, server.initCount);
+ assertEquals(1, server.liveCount);
+ assertEquals(1, server.downCount);
+ assertEquals(1, server.finiCount);
+ assertEquals(1, client.initCount);
+ assertEquals(1, client.liveCount);
+ assertEquals(1, client.downCount);
+ assertEquals(1, client.finiCount);
+
+ target = client.connect(new Spec("localhost", Test.PORT),
+ new Session());
+
+ waitState(0, 2, 1, 2, 2, 2, -1, 2, 2);
+ assertEquals(0, Session.cnt());
+ assertEquals(2, server.initCount);
+ assertEquals(1, server.liveCount);
+ assertEquals(2, server.downCount);
+ assertEquals(2, server.finiCount);
+ assertEquals(2, client.initCount);
+ int oldClientLive = client.liveCount;
+ assertEquals(2, client.downCount);
+ assertEquals(2, client.finiCount);
+
+ client.transport().shutdown().join();
+
+ target = client.connect(new Spec("localhost", Test.PORT),
+ new Session());
+
+ waitState(0, 2, 1, 2, 2, 3, oldClientLive, 3, 3);
+ assertEquals(0, Session.cnt());
+ assertEquals(2, server.initCount);
+ assertEquals(1, server.liveCount);
+ assertEquals(2, server.downCount);
+ assertEquals(2, server.finiCount);
+ assertEquals(3, client.initCount);
+ assertEquals(oldClientLive, client.liveCount);
+ assertEquals(3, client.downCount);
+ assertEquals(3, client.finiCount);
+ assertFalse(Session.getError());
+ }
+}
diff --git a/jrt/tests/com/yahoo/jrt/SlobrokTest.java b/jrt/tests/com/yahoo/jrt/SlobrokTest.java
new file mode 100644
index 00000000000..14c265705c4
--- /dev/null
+++ b/jrt/tests/com/yahoo/jrt/SlobrokTest.java
@@ -0,0 +1,235 @@
+// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.jrt;
+
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Comparator;
+
+import com.yahoo.jrt.slobrok.api.SlobrokList;
+import com.yahoo.jrt.slobrok.api.Mirror;
+import com.yahoo.jrt.slobrok.api.Register;
+import com.yahoo.jrt.slobrok.api.Mirror.Entry;
+import com.yahoo.jrt.slobrok.server.Slobrok;
+
+
+public class SlobrokTest extends junit.framework.TestCase {
+
+ private static class SpecList extends ArrayList<Mirror.Entry> {
+ public SpecList add(String name, String spec) {
+ add(new Mirror.Entry(name, spec));
+ return this;
+ }
+ }
+
+ String[] slobroks;
+ 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;
+ Slobrok slobrok;
+
+ public SlobrokTest(String name) {
+ super(name);
+ }
+
+ public void setUp() throws ListenFailedException {
+ slobrok = new Slobrok();
+ slobroks = new String[1];
+ slobroks[0] = new Spec("localhost", slobrok.port()).toString();
+ SlobrokList slobroklist = new SlobrokList();
+ slobroklist.setup(slobroks);
+ acceptor = server.listen(new Spec(0));
+ mirror = new Mirror(client, slobroklist);
+ register = new Register(server, slobroklist,
+ "localhost", acceptor.port());
+ mySpec = new Spec("localhost", acceptor.port()).toString();
+ }
+
+ public void tearDown() {
+ register.shutdown();
+ mirror.shutdown();
+ acceptor.shutdown();
+ client.transport().shutdown();
+ server.transport().shutdown();
+ slobrok.stop();
+ }
+
+ void check(String pattern, ArrayList<Entry> result) {
+ if (error) {
+ err("already failed, skipping test");
+ return;
+ }
+ Comparator<Entry> cmp = new Comparator<Entry>() {
+ public int compare(Entry a, Entry b) {
+ return a.compareTo(b);
+ }
+ };
+ Mirror.Entry[] expect =
+ result.toArray(new Mirror.Entry[result.size()]);
+ Arrays.sort(expect, cmp);
+ Mirror.Entry[] actual = new Mirror.Entry[0];
+ for (int i = 0; i < 1000; i++) {
+ actual = mirror.lookup(pattern);
+ Arrays.sort(actual, cmp);
+ if (Arrays.equals(actual, expect)) {
+ // err("lookup successful for pattern: " + pattern);
+ return;
+ }
+ try { Thread.sleep(10); } 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 testSlobrok() {
+ String wantName = "A/x/w";
+ register.registerName(wantName);
+ check(wantName, new SpecList().add(wantName, mySpec));
+ check("*/*", new SpecList());
+ check("*/*/*", new SpecList().add(wantName, mySpec));
+
+ assertTrue(mirror.ready());
+ assertTrue(mirror.updates() > 0);
+
+ Mirror.Entry[] oneArr = mirror.lookup("*/*/*");
+ assertTrue(oneArr.length == 1);
+ Mirror.Entry one = oneArr[0];
+ assertTrue(one.equals(new Mirror.Entry(wantName, mySpec)));
+ assertFalse(one.equals(new Mirror.Entry("B/x/w", mySpec)));
+ assertFalse(one.equals(new Mirror.Entry(wantName, "foo:99")));
+ assertFalse(one.equals(null));
+ assertFalse(one.equals(register));
+ assertTrue(one.getName().equals(wantName));
+ assertTrue(one.getSpec().equals(mySpec));
+ int wantHC = mySpec.hashCode() + wantName.hashCode();
+ assertTrue(one.hashCode() == wantHC);
+
+ 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));
+
+ assertFalse(error);
+ }
+
+ public static void err(String msg) {
+ System.err.println(msg);
+ }
+}
diff --git a/jrt/tests/com/yahoo/jrt/SpecTest.java b/jrt/tests/com/yahoo/jrt/SpecTest.java
new file mode 100644
index 00000000000..d15b8f95d30
--- /dev/null
+++ b/jrt/tests/com/yahoo/jrt/SpecTest.java
@@ -0,0 +1,98 @@
+// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.jrt;
+
+import java.net.InetSocketAddress;
+
+public class SpecTest extends junit.framework.TestCase {
+
+ public SpecTest(String name) {
+ super(name);
+ }
+
+ public void testPort() {
+ Spec spec = new Spec(457);
+ InetSocketAddress addr = new InetSocketAddress(457);
+
+ assertEquals("tcp/457", spec.toString());
+ assertFalse(spec.malformed());
+ assertEquals(457, spec.port());
+ assertNull(spec.host());
+ assertTrue(addr.equals(spec.address()));
+ }
+
+ public void testHostPort() {
+ String host = "localhost";
+ Spec spec = new Spec(host, 457);
+ InetSocketAddress addr = new InetSocketAddress(host, 457);
+
+ assertEquals("tcp/localhost:457", spec.toString());
+ assertFalse(spec.malformed());
+ assertEquals(457, spec.port());
+ assertEquals(host, spec.host());
+ assertTrue(addr.equals(spec.address()));
+ }
+
+ public void testBogusHostPort() {
+ String host = "bogus.host.name";
+ Spec spec = new Spec(host, 457);
+ InetSocketAddress addr = new InetSocketAddress(host, 457);
+
+ assertEquals("tcp/bogus.host.name:457", spec.toString());
+ assertFalse(spec.malformed());
+ assertEquals(457, spec.port());
+ assertEquals(host, spec.host());
+ assertTrue(addr.equals(spec.address()));
+ }
+
+ public void testSpec1() {
+ Spec spec = new Spec("tcp/localhost:8080");
+ InetSocketAddress addr = new InetSocketAddress("localhost", 8080);
+
+ assertEquals("tcp/localhost:8080", spec.toString());
+ assertFalse(spec.malformed());
+ assertEquals(8080, spec.port());
+ assertEquals("localhost", spec.host());
+ assertTrue(addr.equals(spec.address()));
+ }
+
+ public void testSpec2() {
+ Spec spec = new Spec("tcp/8080");
+ InetSocketAddress addr = new InetSocketAddress(8080);
+
+ assertEquals("tcp/8080", spec.toString());
+ assertFalse(spec.malformed());
+ assertEquals(8080, spec.port());
+ assertNull(spec.host());
+ assertTrue(addr.equals(spec.address()));
+ }
+
+ public void testBogusSpec1() {
+ Spec spec = new Spec("localhost:8080");
+
+ assertEquals("MALFORMED", spec.toString());
+ assertTrue(spec.malformed());
+ assertEquals(0, spec.port());
+ assertNull(spec.host());
+ assertNull(spec.address());
+ }
+
+ public void testBogusSpec2() {
+ Spec spec = new Spec("tcp/localhost:xyz");
+
+ assertEquals("MALFORMED", spec.toString());
+ assertTrue(spec.malformed());
+ assertEquals(0, spec.port());
+ assertNull(spec.host());
+ assertNull(spec.address());
+ }
+
+ public void testBogusSpec3() {
+ Spec spec = new Spec("tcp/localhost:");
+
+ assertEquals("MALFORMED", spec.toString());
+ assertTrue(spec.malformed());
+ assertEquals(0, spec.port());
+ assertNull(spec.host());
+ assertNull(spec.address());
+ }
+}
diff --git a/jrt/tests/com/yahoo/jrt/Test.java b/jrt/tests/com/yahoo/jrt/Test.java
new file mode 100644
index 00000000000..52e386ae06d
--- /dev/null
+++ b/jrt/tests/com/yahoo/jrt/Test.java
@@ -0,0 +1,236 @@
+// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.jrt;
+
+
+import java.util.Arrays;
+
+
+public class Test extends junit.framework.TestCase {
+
+ public Test(String name) { super(name); }
+ public void testNothing() {}
+
+ // www.random.org [2000, 9999]
+ public static final int PORT = 9741;
+ public static final int PORT_0 = 5069;
+ public static final int PORT_1 = 4935;
+ public static final int PORT_2 = 8862;
+ public static final int PORT_3 = 4695;
+ public static final int PORT_4 = 6975;
+ public static final int PORT_5 = 7186;
+ public static final int PORT_6 = 7694;
+ public static final int PORT_7 = 3518;
+ public static final int PORT_8 = 3542;
+ public static final int PORT_9 = 4954;
+
+ /**
+ * Supervisor extension with some extra statistics used for
+ * testing.
+ **/
+ public static class Orb extends Supervisor {
+ public int initCount = 0;
+ public int liveCount = 0;
+ public int readRequestCount = 0;
+ public int readReplyCount = 0;
+ public int readErrorCount = 0;
+ public long readBytes = 0;
+ public int writeRequestCount = 0;
+ public int writeReplyCount = 0;
+ public int writeErrorCount = 0;
+ public long writeBytes = 0;
+ public int downCount = 0;
+ public int finiCount = 0;
+
+ public Orb(Transport t) {
+ super(t);
+ }
+
+ public boolean checkReadCounts(int request, int reply, int error) {
+ return (request == readRequestCount &&
+ reply == readReplyCount &&
+ error == readErrorCount);
+ }
+
+ public boolean checkWriteCounts(int request, int reply, int error) {
+ return (request == writeRequestCount &&
+ reply == writeReplyCount &&
+ error == writeErrorCount);
+ }
+
+ public boolean checkLifeCounts(int init, int fini) {
+ return (init == initCount && fini == finiCount);
+ }
+
+ public void sessionInit(Target target) {
+ initCount++;
+ super.sessionInit(target);
+ }
+
+ public void sessionLive(Target target) {
+ liveCount++;
+ super.sessionLive(target);
+ }
+
+ public void sessionDown(Target target) {
+ downCount++;
+ super.sessionDown(target);
+ }
+
+ public void sessionFini(Target target) {
+ finiCount++;
+ super.sessionFini(target);
+ }
+
+ public void readPacket(PacketInfo info) {
+ if (info.packetCode() == Packet.PCODE_REQUEST) {
+ readRequestCount++;
+ } else if (info.packetCode() == Packet.PCODE_REPLY) {
+ readReplyCount++;
+ } else if (info.packetCode() == Packet.PCODE_ERROR) {
+ readErrorCount++;
+ }
+ readBytes += info.packetLength();
+ super.readPacket(info);
+ }
+
+ public void writePacket(PacketInfo info) {
+ if (info.packetCode() == Packet.PCODE_REQUEST) {
+ writeRequestCount++;
+ } else if (info.packetCode() == Packet.PCODE_REPLY) {
+ writeReplyCount++;
+ } else if (info.packetCode() == Packet.PCODE_ERROR) {
+ writeErrorCount++;
+ }
+ writeBytes += info.packetLength();
+ super.writePacket(info);
+ }
+ }
+
+ /**
+ * A simple object used to wait for the completion of an
+ * asynchronous request.
+ **/
+ public static class Waiter implements RequestWaiter {
+ private boolean done = false;
+ public boolean isDone() {
+ return done;
+ }
+ public synchronized void handleRequestDone(Request req) {
+ done = true;
+ notify();
+ }
+ public synchronized void waitDone() {
+ while (!isDone()) {
+ try { wait(); } catch (InterruptedException e) {}
+ }
+ }
+ }
+
+ /**
+ * A simple object used to make one thread wait until another
+ * thread tells it to continue.
+ **/
+ public static class Barrier {
+ private boolean broken = false;
+ public synchronized void reset() {
+ broken = false;
+ }
+ public synchronized void breakIt() {
+ broken = true;
+ notify();
+ }
+ public synchronized void waitFor() {
+ while (!broken) {
+ try { wait(); } catch (InterruptedException e) {}
+ }
+ }
+ }
+
+ /**
+ * A simple object used to pass a single object from one thread to
+ * another.
+ **/
+ public static class Receptor {
+ private Object obj = null;
+ public synchronized void reset() {
+ obj = null;
+ }
+ public synchronized Object get() {
+ while (obj == null) {
+ try { wait(); } catch (InterruptedException e) {}
+ }
+ return obj;
+ }
+ public synchronized void put(Object obj) {
+ this.obj = obj;
+ notify();
+ }
+ }
+
+
+ public static boolean equals(byte[][] a, byte[][] b) {
+ if (a == null || b == null) {
+ return false;
+ }
+ if (a.length != b.length) {
+ return false;
+ }
+ for (int i = 0; i < a.length; i++) {
+ if (!Arrays.equals(a[i], b[i])) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ public static boolean equals(Value a, Value b) {
+ if (a == null || b == null) {
+ return false;
+ }
+ if (a.type() != b.type()) {
+ return false;
+ }
+ switch (a.type()) {
+ case Value.INT8: return (a.asInt8() == b.asInt8());
+ case Value.INT8_ARRAY: return Arrays.equals(a.asInt8Array(),
+ b.asInt8Array());
+ case Value.INT16: return (a.asInt16() == b.asInt16());
+ case Value.INT16_ARRAY: return Arrays.equals(a.asInt16Array(),
+ b.asInt16Array());
+ case Value.INT32: return (a.asInt32() == b.asInt32());
+ case Value.INT32_ARRAY: return Arrays.equals(a.asInt32Array(),
+ b.asInt32Array());
+ case Value.INT64: return (a.asInt64() == b.asInt64());
+ case Value.INT64_ARRAY: return Arrays.equals(a.asInt64Array(),
+ b.asInt64Array());
+ case Value.FLOAT: return (a.asFloat() == b.asFloat());
+ case Value.FLOAT_ARRAY: return Arrays.equals(a.asFloatArray(),
+ b.asFloatArray());
+ case Value.DOUBLE: return (a.asDouble() == b.asDouble());
+ case Value.DOUBLE_ARRAY: return Arrays.equals(a.asDoubleArray(),
+ b.asDoubleArray());
+ case Value.DATA: return Arrays.equals(a.asData(), b.asData());
+ case Value.DATA_ARRAY: return equals(a.asDataArray(),
+ b.asDataArray());
+ case Value.STRING: return a.asString().equals(b.asString());
+ case Value.STRING_ARRAY: return Arrays.equals(a.asStringArray(),
+ b.asStringArray());
+ default: return false;
+ }
+ }
+
+ public static boolean equals(Values a, Values b) {
+ if (a == null || b == null) {
+ return false;
+ }
+ if (a.size() != b.size()) {
+ return false;
+ }
+ for (int i = 0; i < a.size(); i++) {
+ if (!equals(a.get(i), b.get(i))) {
+ return false;
+ }
+ }
+ return true;
+ }
+}
diff --git a/jrt/tests/com/yahoo/jrt/TimeoutTest.java b/jrt/tests/com/yahoo/jrt/TimeoutTest.java
new file mode 100644
index 00000000000..4b448fa29a8
--- /dev/null
+++ b/jrt/tests/com/yahoo/jrt/TimeoutTest.java
@@ -0,0 +1,77 @@
+// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.jrt;
+
+
+public class TimeoutTest extends junit.framework.TestCase {
+
+ Supervisor server;
+ Acceptor acceptor;
+ Supervisor client;
+ Target target;
+ Test.Barrier barrier;
+
+ public TimeoutTest(String name) {
+ super(name);
+ }
+
+ public void setUp() throws ListenFailedException {
+ server = new Supervisor(new Transport());
+ client = new Supervisor(new Transport());
+ acceptor = server.listen(new Spec(Test.PORT));
+ target = client.connect(new Spec("localhost", Test.PORT));
+ server.addMethod(new Method("concat", "ss", "s", this, "rpc_concat")
+ .methodDesc("Concatenate 2 strings")
+ .paramDesc(0, "str1", "a string")
+ .paramDesc(1, "str2", "another string")
+ .returnDesc(0, "ret", "str1 followed by str2"));
+ barrier = new Test.Barrier();
+ }
+
+ public void tearDown() {
+ target.close();
+ acceptor.shutdown().join();
+ client.transport().shutdown().join();
+ server.transport().shutdown().join();
+ }
+
+ public void rpc_concat(Request req) {
+ barrier.waitFor();
+ req.returnValues().add(new StringValue(req.parameters()
+ .get(0).asString() +
+ req.parameters()
+ .get(1).asString()));
+ }
+
+ public void testTimeout() {
+ Request req = new Request("concat");
+ req.parameters().add(new StringValue("abc"));
+ req.parameters().add(new StringValue("def"));
+
+ target.invokeSync(req, 0.1);
+ barrier.breakIt();
+
+ Request flush = new Request("frt.rpc.ping");
+ target.invokeSync(flush, 5.0);
+ assertTrue(!flush.isError());
+
+ assertTrue(req.isError());
+ assertEquals(ErrorCode.TIMEOUT, req.errorCode());
+ assertEquals(0, req.returnValues().size());
+ }
+
+ public void testNotTimeout() {
+ Request req = new Request("concat");
+ req.parameters().add(new StringValue("abc"));
+ req.parameters().add(new StringValue("def"));
+
+ Test.Waiter w = new Test.Waiter();
+ target.invokeAsync(req, 30.0, w);
+ try { Thread.sleep(2500); } catch (InterruptedException e) {}
+ barrier.breakIt();
+ w.waitDone();
+
+ assertTrue(!req.isError());
+ assertEquals(1, req.returnValues().size());
+ assertEquals("abcdef", req.returnValues().get(0).asString());
+ }
+}
diff --git a/jrt/tests/com/yahoo/jrt/ValuesTest.java b/jrt/tests/com/yahoo/jrt/ValuesTest.java
new file mode 100644
index 00000000000..36320b10993
--- /dev/null
+++ b/jrt/tests/com/yahoo/jrt/ValuesTest.java
@@ -0,0 +1,435 @@
+// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.jrt;
+
+import java.nio.ByteBuffer;
+import java.util.Arrays;
+
+public class ValuesTest extends junit.framework.TestCase {
+
+ public ValuesTest(String name) {
+ super(name);
+ }
+
+ public void testEmpty() {
+ Values src = new Values();
+ assertEquals(src.bytes(), 4);
+
+ ByteBuffer buf = ByteBuffer.allocate(src.bytes());
+ src.encode(buf);
+ buf.flip();
+ assertEquals(buf.remaining(), 4);
+
+ Values dst = new Values();
+ dst.decode(buf);
+ assertEquals(dst.bytes(), 4);
+ }
+
+ void checkSingleValue(Values v, byte type, int bytes) {
+ assertEquals(v.size(), 1);
+ assertEquals(v.get(0).type(), type);
+ assertEquals(v.bytes(), bytes);
+ }
+
+ public void testInt8() {
+ int byteSize = 4 + 1 + 1;
+ Values src = new Values();
+ src.add(new Int8Value((byte)1));
+ checkSingleValue(src, Value.INT8, byteSize);
+
+ ByteBuffer buf = ByteBuffer.allocate(src.bytes());
+ src.encode(buf);
+ buf.flip();
+ assertEquals(buf.remaining(), byteSize);
+
+ Values dst = new Values();
+ dst.decode(buf);
+ checkSingleValue(src, Value.INT8, byteSize);
+ assertEquals(dst.get(0).asInt8(), (byte)1);
+ }
+
+ public void testInt8Array() {
+ int byteSize = 4 + 1 + 4 + 4;
+ Values src = new Values();
+ byte[] val = { 1, 2, 3, 4 };
+ src.add(new Int8Array(val));
+ checkSingleValue(src, Value.INT8_ARRAY, byteSize);
+
+ ByteBuffer buf = ByteBuffer.allocate(src.bytes());
+ src.encode(buf);
+ buf.flip();
+ assertEquals(buf.remaining(), byteSize);
+
+ Values dst = new Values();
+ dst.decode(buf);
+ checkSingleValue(src, Value.INT8_ARRAY, byteSize);
+ assertTrue(Arrays.equals(dst.get(0).asInt8Array(), val));
+ }
+
+ public void testInt16() {
+ int byteSize = 4 + 1 + 2;
+ Values src = new Values();
+ src.add(new Int16Value((short)2));
+ checkSingleValue(src, Value.INT16, byteSize);
+
+ ByteBuffer buf = ByteBuffer.allocate(src.bytes());
+ src.encode(buf);
+ buf.flip();
+ assertEquals(buf.remaining(), byteSize);
+
+ Values dst = new Values();
+ dst.decode(buf);
+ checkSingleValue(src, Value.INT16, byteSize);
+ assertEquals(dst.get(0).asInt16(), (short)2);
+ }
+
+ public void testInt16Array() {
+ int byteSize = 4 + 1 + 4 + 4 * 2;
+ Values src = new Values();
+ short[] val = { 2, 4, 6, 8 };
+ src.add(new Int16Array(val));
+ checkSingleValue(src, Value.INT16_ARRAY, byteSize);
+
+ ByteBuffer buf = ByteBuffer.allocate(src.bytes());
+ src.encode(buf);
+ buf.flip();
+ assertEquals(buf.remaining(), byteSize);
+
+ Values dst = new Values();
+ dst.decode(buf);
+ checkSingleValue(src, Value.INT16_ARRAY, byteSize);
+ assertTrue(Arrays.equals(dst.get(0).asInt16Array(), val));
+ }
+
+ public void testInt32() {
+ int byteSize = 4 + 1 + 4;
+ Values src = new Values();
+ src.add(new Int32Value(4));
+ checkSingleValue(src, Value.INT32, byteSize);
+
+ ByteBuffer buf = ByteBuffer.allocate(src.bytes());
+ src.encode(buf);
+ buf.flip();
+ assertEquals(buf.remaining(), byteSize);
+
+ Values dst = new Values();
+ dst.decode(buf);
+ checkSingleValue(src, Value.INT32, byteSize);
+ assertEquals(dst.get(0).asInt32(), 4);
+ }
+
+ public void testInt32Array() {
+ int byteSize = 4 + 1 + 4 + 4 * 4;
+ Values src = new Values();
+ int[] val = { 4, 8, 12, 16 };
+ src.add(new Int32Array(val));
+ checkSingleValue(src, Value.INT32_ARRAY, byteSize);
+
+ ByteBuffer buf = ByteBuffer.allocate(src.bytes());
+ src.encode(buf);
+ buf.flip();
+ assertEquals(buf.remaining(), byteSize);
+
+ Values dst = new Values();
+ dst.decode(buf);
+ checkSingleValue(src, Value.INT32_ARRAY, byteSize);
+ assertTrue(Arrays.equals(dst.get(0).asInt32Array(), val));
+ }
+
+ public void testInt64() {
+ int byteSize = 4 + 1 + 8;
+ Values src = new Values();
+ src.add(new Int64Value(8));
+ checkSingleValue(src, Value.INT64, byteSize);
+
+ ByteBuffer buf = ByteBuffer.allocate(src.bytes());
+ src.encode(buf);
+ buf.flip();
+ assertEquals(buf.remaining(), byteSize);
+
+ Values dst = new Values();
+ dst.decode(buf);
+ checkSingleValue(src, Value.INT64, byteSize);
+ assertEquals(dst.get(0).asInt64(), 8);
+ }
+
+ public void testInt64Array() {
+ int byteSize = 4 + 1 + 4 + 4 * 8;
+ Values src = new Values();
+ long[] val = { 8, 16, 24, 32 };
+ src.add(new Int64Array(val));
+ checkSingleValue(src, Value.INT64_ARRAY, byteSize);
+
+ ByteBuffer buf = ByteBuffer.allocate(src.bytes());
+ src.encode(buf);
+ buf.flip();
+ assertEquals(buf.remaining(), byteSize);
+
+ Values dst = new Values();
+ dst.decode(buf);
+ checkSingleValue(src, Value.INT64_ARRAY, byteSize);
+ assertTrue(Arrays.equals(dst.get(0).asInt64Array(), val));
+ }
+
+ public void testFloat() {
+ int byteSize = 4 + 1 + 4;
+ Values src = new Values();
+ src.add(new FloatValue((float)2.5));
+ checkSingleValue(src, Value.FLOAT, byteSize);
+
+ ByteBuffer buf = ByteBuffer.allocate(src.bytes());
+ src.encode(buf);
+ buf.flip();
+ assertEquals(buf.remaining(), byteSize);
+
+ Values dst = new Values();
+ dst.decode(buf);
+ checkSingleValue(src, Value.FLOAT, byteSize);
+ assertTrue(dst.get(0).asFloat() == (float)2.5);
+ }
+
+ public void testFloatArray() {
+ int byteSize = 4 + 1 + 4 + 4 * 4;
+ Values src = new Values();
+ float[] val = { 1.5f, 2.0f, 2.5f, 3.0f };
+ src.add(new FloatArray(val));
+ checkSingleValue(src, Value.FLOAT_ARRAY, byteSize);
+
+ ByteBuffer buf = ByteBuffer.allocate(src.bytes());
+ src.encode(buf);
+ buf.flip();
+ assertEquals(buf.remaining(), byteSize);
+
+ Values dst = new Values();
+ dst.decode(buf);
+ checkSingleValue(src, Value.FLOAT_ARRAY, byteSize);
+ assertTrue(Arrays.equals(dst.get(0).asFloatArray(), val));
+ }
+
+ public void testDouble() {
+ int byteSize = 4 + 1 + 8;
+ Values src = new Values();
+ src.add(new DoubleValue(3.75));
+ checkSingleValue(src, Value.DOUBLE, byteSize);
+
+ ByteBuffer buf = ByteBuffer.allocate(src.bytes());
+ src.encode(buf);
+ buf.flip();
+ assertEquals(buf.remaining(), byteSize);
+
+ Values dst = new Values();
+ dst.decode(buf);
+ checkSingleValue(src, Value.DOUBLE, byteSize);
+ assertTrue(dst.get(0).asDouble() == 3.75);
+ }
+
+ public void testDoubleArray() {
+ int byteSize = 4 + 1 + 4 + 4 * 8;
+ Values src = new Values();
+ double[] val = { 1.25, 1.50, 1.75, 2.00 };
+ src.add(new DoubleArray(val));
+ checkSingleValue(src, Value.DOUBLE_ARRAY, byteSize);
+
+ ByteBuffer buf = ByteBuffer.allocate(src.bytes());
+ src.encode(buf);
+ buf.flip();
+ assertEquals(buf.remaining(), byteSize);
+
+ Values dst = new Values();
+ dst.decode(buf);
+ checkSingleValue(src, Value.DOUBLE_ARRAY, byteSize);
+ assertTrue(Arrays.equals(dst.get(0).asDoubleArray(), val));
+ }
+
+ public void testData() {
+ int byteSize = 4 + 1 + 4 + 4;
+ Values src = new Values();
+ byte[] val = { 1, 2, 3, 4 };
+ src.add(new DataValue(val));
+ checkSingleValue(src, Value.DATA, byteSize);
+
+ ByteBuffer buf = ByteBuffer.allocate(src.bytes());
+ src.encode(buf);
+ buf.flip();
+ assertEquals(buf.remaining(), byteSize);
+
+ Values dst = new Values();
+ dst.decode(buf);
+ checkSingleValue(src, Value.DATA, byteSize);
+ assertTrue(Arrays.equals(dst.get(0).asData(), val));
+ }
+
+ public void testDataArray() {
+ int byteSize = 4 + 1 + 4 + 4 * (4 + 4);
+ Values src = new Values();
+ byte[][] val = {{ 1, 0, 1, 0 },
+ { 0, 2, 0, 2 },
+ { 3, 0, 3, 0 },
+ { 0, 4, 0, 4 }};
+ src.add(new DataArray(val));
+ checkSingleValue(src, Value.DATA_ARRAY, byteSize);
+
+ ByteBuffer buf = ByteBuffer.allocate(src.bytes());
+ src.encode(buf);
+ buf.flip();
+ assertEquals(buf.remaining(), byteSize);
+
+ Values dst = new Values();
+ dst.decode(buf);
+ checkSingleValue(src, Value.DATA_ARRAY, byteSize);
+ assertTrue(Arrays.equals(dst.get(0).asDataArray()[0], val[0]));
+ assertTrue(Arrays.equals(dst.get(0).asDataArray()[1], val[1]));
+ assertTrue(Arrays.equals(dst.get(0).asDataArray()[2], val[2]));
+ assertTrue(Arrays.equals(dst.get(0).asDataArray()[3], val[3]));
+ }
+
+ public void testString1() {
+ int byteSize = 4 + 1 + 4 + 4;
+ Values src = new Values();
+ String val = "test";
+ src.add(new StringValue(val));
+ checkSingleValue(src, Value.STRING, byteSize);
+
+ ByteBuffer buf = ByteBuffer.allocate(src.bytes());
+ src.encode(buf);
+ buf.flip();
+ assertEquals(buf.remaining(), byteSize);
+
+ Values dst = new Values();
+ dst.decode(buf);
+ checkSingleValue(src, Value.STRING, byteSize);
+ assertTrue(dst.get(0).asString().equals("test"));
+ }
+
+ public void testString2() {
+ int byteSize = 4 + 1 + 4 + 7;
+ Values src = new Values();
+ String val = "H" + ((char)229) + "vard";
+ src.add(new StringValue(val));
+ checkSingleValue(src, Value.STRING, byteSize);
+
+ ByteBuffer buf = ByteBuffer.allocate(src.bytes());
+ src.encode(buf);
+ buf.flip();
+ assertEquals(buf.remaining(), byteSize);
+
+ byte right[] = new byte[] { 0, 0, 0, 1, 's',
+ 0, 0, 0, 7, 'H',
+ (byte)(0xC0 | (0xE5 >> 6)),
+ (byte)(0x80 | (0xE5 & 0x3F)),
+ 'v', 'a', 'r', 'd'
+ };
+ for (int ii = 0; ii < buf.remaining(); ++ii) {
+ assertEquals(buf.get(ii), right[ii]);
+ }
+
+ Values dst = new Values();
+ dst.decode(buf);
+ checkSingleValue(src, Value.STRING, byteSize);
+ assertTrue(dst.get(0).asString().equals("H\u00E5vard"));
+ }
+
+ public void testStringArray() {
+ int byteSize = 4 + 1 + 4 + 4 * 4 + 3 + 3 + 5 + 4;
+ Values src = new Values();
+ String[] val = { "one", "two", "three", "four" };
+ src.add(new StringArray(val));
+ checkSingleValue(src, Value.STRING_ARRAY, byteSize);
+
+ ByteBuffer buf = ByteBuffer.allocate(src.bytes());
+ src.encode(buf);
+ buf.flip();
+ assertEquals(buf.remaining(), byteSize);
+
+ Values dst = new Values();
+ dst.decode(buf);
+ checkSingleValue(src, Value.STRING_ARRAY, byteSize);
+ assertTrue(dst.get(0).asStringArray()[0].equals("one"));
+ assertTrue(dst.get(0).asStringArray()[1].equals("two"));
+ assertTrue(dst.get(0).asStringArray()[2].equals("three"));
+ assertTrue(dst.get(0).asStringArray()[3].equals("four"));
+ }
+
+ public void testAllValues() {
+ int byteSize =
+ 4 + 16 // typestring
+ + 1 // int8
+ + 4 + 4 // int8 array
+ + 2 // int16
+ + 4 + 4 * 2 // int16 array
+ + 4 // int32
+ + 4 + 4 * 4 // int32 array
+ + 8 // int64
+ + 4 + 4 * 8 // int64 array
+ + 4 // float
+ + 4 + 4 * 4 // float array
+ + 8 // double
+ + 4 + 4 * 8 // double array
+ + 4 + 4 // data
+ + 4 + 4 * 4 + 4 + 4 + 4 + 4 // data array
+ + 4 + 4 // string
+ + 4 + 4 * 4 + 3 + 3 + 5 + 4; // string array
+
+ byte[] dataValue = { 1, 2, 3, 4 };
+ byte[] int8Array = { 1, 2, 3, 4 };
+ short[] int16Array = { 2, 4, 6, 8 };
+ int[] int32Array = { 4, 8, 12, 16 };
+ long[] int64Array = { 8, 16, 24, 32 };
+ float[] floatArray = { 1.5f, 2.0f, 2.5f, 3.0f };
+ double[] doubleArray = { 1.25, 1.50, 1.75, 2.00 };
+ byte[][] dataArray = {{ 1, 0, 1, 0 },
+ { 0, 2, 0, 2 },
+ { 3, 0, 3, 0 },
+ { 0, 4, 0, 4 }};
+ String[] stringArray = { "one", "two", "three", "four" };
+
+ Values src = new Values();
+ src.add(new Int8Value((byte)1));
+ src.add(new Int8Array(int8Array));
+ src.add(new Int16Value((short)2));
+ src.add(new Int16Array(int16Array));
+ src.add(new Int32Value(4));
+ src.add(new Int32Array(int32Array));
+ src.add(new Int64Value(8));
+ src.add(new Int64Array(int64Array));
+ src.add(new FloatValue(2.5f));
+ src.add(new FloatArray(floatArray));
+ src.add(new DoubleValue(3.75));
+ src.add(new DoubleArray(doubleArray));
+ src.add(new DataValue(dataValue));
+ src.add(new DataArray(dataArray));
+ src.add(new StringValue("test"));
+ src.add(new StringArray(stringArray));
+ assertEquals(src.size(), 16);
+ assertEquals(src.bytes(), byteSize);
+
+ ByteBuffer buf = ByteBuffer.allocate(src.bytes());
+ src.encode(buf);
+ buf.flip();
+ assertEquals(buf.remaining(), byteSize);
+
+ Values dst = new Values();
+ dst.decode(buf);
+ assertEquals(dst.get(0).asInt8(), (byte)1);
+ assertTrue(Arrays.equals(dst.get(1).asInt8Array(), int8Array));
+ assertEquals(dst.get(2).asInt16(), (short)2);
+ assertTrue(Arrays.equals(dst.get(3).asInt16Array(), int16Array));
+ assertEquals(dst.get(4).asInt32(), 4);
+ assertTrue(Arrays.equals(dst.get(5).asInt32Array(), int32Array));
+ assertEquals(dst.get(6).asInt64(), 8);
+ assertTrue(Arrays.equals(dst.get(7).asInt64Array(), int64Array));
+ assertTrue(dst.get(8).asFloat() == (float)2.5);
+ assertTrue(Arrays.equals(dst.get(9).asFloatArray(), floatArray));
+ assertTrue(dst.get(10).asDouble() == 3.75);
+ assertTrue(Arrays.equals(dst.get(11).asDoubleArray(), doubleArray));
+ assertTrue(Arrays.equals(dst.get(12).asData(), dataValue));
+ assertTrue(Arrays.equals(dst.get(13).asDataArray()[0], dataArray[0]));
+ assertTrue(Arrays.equals(dst.get(13).asDataArray()[1], dataArray[1]));
+ assertTrue(Arrays.equals(dst.get(13).asDataArray()[2], dataArray[2]));
+ assertTrue(Arrays.equals(dst.get(13).asDataArray()[3], dataArray[3]));
+ assertTrue(dst.get(14).asString().equals("test"));
+ assertTrue(dst.get(15).asStringArray()[0].equals("one"));
+ assertTrue(dst.get(15).asStringArray()[1].equals("two"));
+ assertTrue(dst.get(15).asStringArray()[2].equals("three"));
+ assertTrue(dst.get(15).asStringArray()[3].equals("four"));
+ }
+}
diff --git a/jrt/tests/com/yahoo/jrt/WatcherTest.java b/jrt/tests/com/yahoo/jrt/WatcherTest.java
new file mode 100644
index 00000000000..5a3fae5e2bf
--- /dev/null
+++ b/jrt/tests/com/yahoo/jrt/WatcherTest.java
@@ -0,0 +1,98 @@
+// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.jrt;
+
+
+public class WatcherTest extends junit.framework.TestCase {
+
+ private static class Watcher implements TargetWatcher {
+ private int notifyCnt = 0;
+ public void notifyTargetInvalid(Target target) {
+ notifyCnt++;
+ }
+ public int cnt() {
+ return notifyCnt;
+ }
+ public boolean equals(Object rhs) {
+ return true;
+ }
+ public int hashCode() {
+ return 0;
+ }
+ }
+
+ Supervisor server;
+ Acceptor acceptor;
+ Supervisor client;
+ Target target;
+
+ public WatcherTest(String name) {
+ super(name);
+ }
+
+ public void setUp() throws ListenFailedException {
+ server = new Supervisor(new Transport());
+ client = new Supervisor(new Transport());
+ acceptor = server.listen(new Spec(Test.PORT));
+ target = client.connect(new Spec("localhost", Test.PORT));
+ }
+
+ public void tearDown() {
+ target.close();
+ acceptor.shutdown().join();
+ client.transport().shutdown().join();
+ server.transport().shutdown().join();
+ }
+
+ public void testNotify() {
+ Watcher w1 = new Watcher();
+ Watcher w2 = new Watcher();
+ Watcher w3 = new Watcher();
+ Watcher w4 = new Watcher();
+ Watcher w5 = new Watcher();
+
+ assertTrue(target.addWatcher(w1));
+ assertTrue(target.addWatcher(w1));
+ assertTrue(target.addWatcher(w1));
+
+ assertTrue(target.addWatcher(w2));
+ assertTrue(target.addWatcher(w2));
+ assertTrue(target.addWatcher(w2));
+ assertTrue(target.removeWatcher(w2));
+ assertTrue(target.removeWatcher(w2));
+ assertTrue(target.addWatcher(w2));
+
+ assertTrue(target.addWatcher(w3));
+ assertTrue(target.removeWatcher(w3));
+
+ assertTrue(target.removeWatcher(w4));
+
+ assertTrue(target.addWatcher(w5));
+ assertTrue(target.addWatcher(w5));
+ assertTrue(target.addWatcher(w5));
+ assertTrue(target.removeWatcher(w5));
+
+ target.close();
+ client.transport().sync();
+
+ assertEquals(1, w1.cnt());
+ assertEquals(1, w2.cnt());
+ assertEquals(0, w3.cnt());
+ assertEquals(0, w4.cnt());
+ assertEquals(0, w5.cnt());
+
+ assertFalse(target.removeWatcher(w1));
+ assertFalse(target.removeWatcher(w2));
+ assertFalse(target.addWatcher(w3));
+ assertFalse(target.addWatcher(w4));
+ assertFalse(target.addWatcher(w5));
+
+ target.close();
+ client.transport().sync();
+
+ assertEquals(1, w1.cnt());
+ assertEquals(1, w2.cnt());
+ assertEquals(0, w3.cnt());
+ assertEquals(0, w4.cnt());
+ assertEquals(0, w5.cnt());
+ }
+}
diff --git a/jrt/tests/com/yahoo/jrt/order.txt b/jrt/tests/com/yahoo/jrt/order.txt
new file mode 100644
index 00000000000..4e90d2635ca
--- /dev/null
+++ b/jrt/tests/com/yahoo/jrt/order.txt
@@ -0,0 +1,25 @@
+Topological sorting of test dependencies (success assumptions)
+===============================================================================
+Test.java (does no testing, but contains common stuff)
+ValuesTest.java
+SpecTest.java
+QueueTest.java
+PacketTest.java
+SchedulerTest.java
+ListenTest.java
+ConnectTest.java
+WatcherTest.java
+InvokeSyncTest.java
+InvokeAsyncTest.java
+InvokeVoidTest.java
+EchoTest.java
+InvokeErrorTest.java
+MandatoryMethodsTest.java
+DetachTest.java
+AbortTest.java
+BackTargetTest.java
+TimeoutTest.java
+SessionTest.java
+===============================================================================
+NOTE: 'ls -al | wc -l' should give the same result as 'wc -l order.txt'
+===============================================================================
diff --git a/jrt/tests/com/yahoo/jrt/slobrok/api/BackOffTestCase.java b/jrt/tests/com/yahoo/jrt/slobrok/api/BackOffTestCase.java
new file mode 100644
index 00000000000..6e3e7443e3d
--- /dev/null
+++ b/jrt/tests/com/yahoo/jrt/slobrok/api/BackOffTestCase.java
@@ -0,0 +1,52 @@
+// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.jrt.slobrok.api;
+
+import org.junit.Test;
+import static org.junit.Assert.*;
+
+/**
+ * @author arnej27959
+ */
+public class BackOffTestCase {
+
+ static final double[] expectWait = {
+ 0.5, 1.0, 1.5, 2.0, 2.5,
+ 3.0, 3.5, 4.0, 4.5,
+ 5.0, 6.0, 7.0, 8.0, 9.0,
+ 10, 15, 20, 25, 30, 30, 30
+ };
+
+ @Test
+ public void requireThatWaitTimesAreExpected() {
+ double sum = 0;
+ BackOffPolicy two = new BackOff();
+ for (int i = 0; i < expectWait.length; i++) {
+ double got = two.get();
+ sum += got;
+ assertEquals(expectWait[i], got, 0.001);
+ boolean sw = two.shouldWarn(got);
+/*
+ System.err.println("i = "+i);
+ System.err.println("got = "+got);
+ System.err.println("sum = "+sum);
+ System.err.println("sw = "+sw);
+*/
+ if (i == 13 || i > 17) {
+ assertTrue(two.shouldWarn(got));
+ } else {
+ assertFalse(two.shouldWarn(got));
+ }
+ }
+ two.reset();
+ for (int i = 0; i < expectWait.length; i++) {
+ double got = two.get();
+ assertEquals(expectWait[i], got, 0.001);
+ if (i == 13 || i > 17) {
+ assertTrue(two.shouldWarn(got));
+ } else {
+ assertFalse(two.shouldWarn(got));
+ }
+ }
+
+ }
+}
diff --git a/jrt/tests/com/yahoo/jrt/slobrok/api/MirrorTest.java b/jrt/tests/com/yahoo/jrt/slobrok/api/MirrorTest.java
new file mode 100644
index 00000000000..d0ee8abfca0
--- /dev/null
+++ b/jrt/tests/com/yahoo/jrt/slobrok/api/MirrorTest.java
@@ -0,0 +1,89 @@
+// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.jrt.slobrok.api;
+
+import org.junit.Test;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.assertFalse;
+
+public class MirrorTest {
+
+ static void mustMatch(String name, String pattern) {
+ assertTrue(Mirror.match(name.toCharArray(), pattern.toCharArray()));
+ }
+
+ static void mustNotMatch(String name, String pattern) {
+ assertFalse(Mirror.match(name.toCharArray(), pattern.toCharArray()));
+ }
+
+ @Test public void requireThatPatternMatchesSameString() {
+ String pattern = "foo/bar*zot/qux?foo**bar*/*nop*";
+ mustMatch(pattern, pattern);
+ }
+
+ @Test public void requireThatStarIsPrefixMatch() {
+ String pattern = "foo/bar.*/qux.*/bar*/nop*";
+ String matches = "foo/bar.foo/qux.bar/bar123/nop000";
+ mustMatch(matches, pattern);
+
+ matches = "foo/bar.bar/qux.qux/bar.bar/nop.nop";
+ mustMatch(matches, pattern);
+
+ matches = "foo/bar.1/qux.3/bar.4/nop.5";
+ mustMatch(matches, pattern);
+ }
+
+ @Test public void requireThatStarMatchesEmptyString() {
+ String pattern = "foo/bar.*/qux.*/bar*/nop*";
+ String matches = "foo/bar./qux./bar/nop";
+ mustMatch(matches, pattern);
+ }
+
+ @Test public void requireThatExtraBeforeSlashIsNotMatch() {
+ String pattern = "foo/*";
+ String nomatch = "foo1/bar";
+ mustNotMatch(nomatch, pattern);
+ }
+
+ @Test public void requireThatStarDoesNotMatchMultipleLevels() {
+ String pattern = "foo/*/qux";
+ String matches = "foo/bar/qux";
+ String nomatch = "foo/bar/bar/qux";
+ mustMatch(matches, pattern);
+ mustNotMatch(nomatch, pattern);
+
+ pattern = "*";
+ nomatch = "foo/bar.foo/qux.bar/bar123/nop000";
+ mustNotMatch(nomatch, pattern);
+ }
+
+ @Test public void requireThatDoubleStarMatchesMultipleLevels() {
+ String pattern = "**";
+ String matches = "foo/bar.foo/qux.bar/bar123/nop000";
+ mustMatch(matches, pattern);
+
+ pattern = "foo/**";
+ matches = "foo/bar.foo/qux.bar/bar123/nop000";
+ mustMatch(matches, pattern);
+
+ pattern = "foo**";
+ matches = "foo/bar.foo/qux.bar/bar123/nop000";
+ mustMatch(matches, pattern);
+
+ pattern = "f**";
+ matches = "foo/bar.foo/qux.bar/bar123/nop000";
+ mustMatch(matches, pattern);
+ }
+
+ @Test public void requireThatDoubleStarMatchesNothing() {
+ String pattern = "A**";
+ String matches = "A";
+ mustMatch(matches, pattern);
+ }
+
+ @Test public void requireThatDoubleStarEatsRestOfName() {
+ String pattern = "foo/**/suffix";
+ String nomatch = "foo/bar/baz/suffix";
+ mustNotMatch(nomatch, pattern);
+ }
+
+}
diff --git a/jrt/tests/com/yahoo/jrt/slobrok/api/SlobrokListTestCase.java b/jrt/tests/com/yahoo/jrt/slobrok/api/SlobrokListTestCase.java
new file mode 100644
index 00000000000..36874f0b80f
--- /dev/null
+++ b/jrt/tests/com/yahoo/jrt/slobrok/api/SlobrokListTestCase.java
@@ -0,0 +1,130 @@
+// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.jrt.slobrok.api;
+
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+
+/**
+ * @author <a href="mailto:simon@yahoo-inc.com">Simon Thoresen</a>
+ */
+public class SlobrokListTestCase {
+
+ @Test
+ public void requireThatNextSlobrokSpecReturnsNullAtEndOfList() {
+ SlobrokList lst = new SlobrokList();
+ lst.setup(new String[] { "foo", "bar" });
+ if ("[foo, bar]".equals(lst.toString())) {
+ assertEquals("foo", lst.nextSlobrokSpec());
+ assertEquals("bar", lst.nextSlobrokSpec());
+ assertNull(lst.nextSlobrokSpec());
+ assertEquals("foo", lst.nextSlobrokSpec());
+ assertEquals("bar", lst.nextSlobrokSpec());
+ assertNull(lst.nextSlobrokSpec());
+ assertEquals("[foo, bar]", lst.toString());
+ } else {
+ assertEquals("bar", lst.nextSlobrokSpec());
+ assertEquals("foo", lst.nextSlobrokSpec());
+ assertNull(lst.nextSlobrokSpec());
+ assertEquals("bar", lst.nextSlobrokSpec());
+ assertEquals("foo", lst.nextSlobrokSpec());
+ assertNull(lst.nextSlobrokSpec());
+ assertEquals("[bar, foo]", lst.toString());
+ }
+ }
+
+ @Test
+ public void requireThatSiblingsIterateIndependently() {
+ SlobrokList foo = new SlobrokList();
+ SlobrokList bar = new SlobrokList(foo);
+ foo.setup(new String[] { "foo", "bar" });
+ if ("[foo, bar]".equals(foo.toString())) {
+ assertEquals("foo", foo.nextSlobrokSpec());
+ assertEquals("foo", bar.nextSlobrokSpec());
+ assertEquals("bar", foo.nextSlobrokSpec());
+ assertEquals("bar", bar.nextSlobrokSpec());
+ assertNull(foo.nextSlobrokSpec());
+ assertNull(bar.nextSlobrokSpec());
+ } else {
+ assertEquals("bar", foo.nextSlobrokSpec());
+ assertEquals("bar", bar.nextSlobrokSpec());
+ assertEquals("foo", foo.nextSlobrokSpec());
+ assertEquals("foo", bar.nextSlobrokSpec());
+ assertNull(foo.nextSlobrokSpec());
+ assertNull(bar.nextSlobrokSpec());
+ }
+ }
+
+ @Test
+ public void requireThatLengthIsUpdatedBySetup() {
+ SlobrokList foo = new SlobrokList();
+ assertEquals(0, foo.length());
+ foo.setup(new String[69]);
+ assertEquals(69, foo.length());
+ }
+
+ @Test
+ public void requireThatIndexIsResetOnSetup() {
+ SlobrokList lst = new SlobrokList();
+ lst.setup(new String[] { "foo", "foo" });
+ assertEquals("foo", lst.nextSlobrokSpec());
+ lst.setup(new String[] { "baz" });
+ assertEquals("baz", lst.nextSlobrokSpec());
+ assertNull(lst.nextSlobrokSpec());
+ assertEquals("[baz]", lst.toString());
+ }
+
+ @Test
+ public void requireThatUpdateAffectsSiblings() {
+ SlobrokList foo = new SlobrokList();
+ SlobrokList bar = new SlobrokList(foo);
+
+ assertEquals(0, foo.length());
+ assertEquals(0, bar.length());
+
+ foo.setup(new String[] { "foo" });
+ assertEquals(1, foo.length());
+ assertEquals(1, bar.length());
+ assertEquals("foo", foo.nextSlobrokSpec());
+ assertEquals("foo", bar.nextSlobrokSpec());
+ assertEquals("[foo]", foo.toString());
+ assertEquals("[foo]", bar.toString());
+
+ foo.setup(new String[] { "baz" });
+ assertEquals(1, foo.length());
+ assertEquals(1, bar.length());
+ assertEquals("baz", bar.nextSlobrokSpec());
+ assertEquals("baz", foo.nextSlobrokSpec());
+ assertNull(foo.nextSlobrokSpec());
+ assertNull(bar.nextSlobrokSpec());
+ assertEquals("[baz]", foo.toString());
+ assertEquals("[baz]", bar.toString());
+ }
+
+ @Test
+ public void requireThatUpdateAffectsContains() {
+ SlobrokList foo = new SlobrokList();
+ foo.setup(new String[] { "foo", "bar" });
+ assertEquals(2, foo.length());
+ String one = foo.nextSlobrokSpec();
+ String two = foo.nextSlobrokSpec();
+ assertNull(foo.nextSlobrokSpec());
+ assertEquals(true, foo.contains(one));
+ assertEquals(true, foo.contains(two));
+ assertEquals(true, foo.contains("foo"));
+ assertEquals(true, foo.contains("bar"));
+ assertEquals(false, foo.contains("baz"));
+
+ foo.setup(new String[] { "foo", "baz" });
+ assertEquals(2, foo.length());
+ assertEquals(true, foo.contains("foo"));
+ assertEquals(false, foo.contains("bar"));
+ assertEquals(true, foo.contains("baz"));
+ one = foo.nextSlobrokSpec();
+ two = foo.nextSlobrokSpec();
+ assertNull(foo.nextSlobrokSpec());
+ assertEquals(true, foo.contains(one));
+ assertEquals(true, foo.contains(two));
+ }
+}
diff --git a/jrt/tests/com/yahoo/jrt/tool/RpcInvokerTest.java b/jrt/tests/com/yahoo/jrt/tool/RpcInvokerTest.java
new file mode 100644
index 00000000000..fc3a1a63699
--- /dev/null
+++ b/jrt/tests/com/yahoo/jrt/tool/RpcInvokerTest.java
@@ -0,0 +1,59 @@
+// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.jrt.tool;
+
+import com.yahoo.jrt.Request;
+
+import java.util.List;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+
+/**
+ * @author bratseth
+ */
+public class RpcInvokerTest extends junit.framework.TestCase {
+
+ public RpcInvokerTest(String name) {
+ super(name);
+ }
+
+ public void test0Args() {
+ assertCorrectArguments("");
+ }
+
+ public void test1StringShorthanArgs() {
+ assertCorrectArguments("foo");
+ }
+
+ public void test2StringArgs() {
+ assertCorrectArguments("s:foo s:bar");
+ }
+
+ public void test2StringShorthandArgs() {
+ assertCorrectArguments("foo bar");
+ }
+
+ protected void assertCorrectArguments(String argString) {
+ RpcInvoker invoker=new RpcInvoker();
+ List<String> args=toList(argString);
+ Request request=invoker.createRequest("testmethod",args);
+ for (int i=0; i<args.size(); i++) {
+ // Strip type here if present
+ String arg=args.get(i);
+ if (arg.length()>=1 && arg.charAt(1)==':')
+ arg=arg.substring(2);
+ assertEquals(arg,request.parameters().get(i).toString());
+ }
+ }
+
+ private List<String> toList(String argsString) {
+ List<String> argsList=new ArrayList<String>();
+ String[] argsArray=argsString.split(" ");
+ for (String arg : argsArray) {
+ if (arg.trim().length()==0) continue;
+ argsList.add(arg);
+ }
+ return argsList;
+ }
+
+}