diff options
author | Jon Bratseth <bratseth@yahoo-inc.com> | 2016-06-15 23:09:44 +0200 |
---|---|---|
committer | Jon Bratseth <bratseth@yahoo-inc.com> | 2016-06-15 23:09:44 +0200 |
commit | 72231250ed81e10d66bfe70701e64fa5fe50f712 (patch) | |
tree | 2728bba1131a6f6e5bdf95afec7d7ff9358dac50 /jrt/tests/com/yahoo |
Publish
Diffstat (limited to 'jrt/tests/com/yahoo')
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; + } + +} |