package org.dcache.oncrpc4j.rpcgen; import org.dcache.xdr.RpcReply; import org.dcache.xdr.XdrLong; import org.dcache.xdr.XdrTransport; import org.junit.Assert; import org.junit.Test; import java.nio.channels.CompletionHandler; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; import java.util.concurrent.atomic.AtomicLong; import java.util.concurrent.atomic.AtomicReference; public class CallbackCalculatorTest extends AbstractCalculatorTest { @Test public void testCallbackAdd() throws Exception { final AtomicLong callbackTimeRef = new AtomicLong(); final AtomicReference<CalculationResult> resultRef = new AtomicReference<>(); final CountDownLatch latch = new CountDownLatch(1); long callTime = System.currentTimeMillis(); client.add_1_callback(1, 2, new CompletionHandler<RpcReply, XdrTransport>() { @Override public void completed(RpcReply result, XdrTransport attachment) { callbackTimeRef.set(System.currentTimeMillis()); CalculationResult calculationResult = new CalculationResult(); try { result.getReplyResult(calculationResult); } catch (Exception e) { throw new IllegalStateException(e); } resultRef.set(calculationResult); latch.countDown(); } @Override public void failed(Throwable exc, XdrTransport attachment) { throw new IllegalStateException(exc); } }, 0, null, null); long retTime = System.currentTimeMillis(); latch.await(3, TimeUnit.SECONDS); long resTime = System.currentTimeMillis(); CalculationResult result = resultRef.get(); Assert.assertNotNull(result); Assert.assertEquals(3, result.getResult()); long callbackTime = callbackTimeRef.get(); //to prove async operation (there's a sleep() server-side) //call <= start < finish <= callback <= res //ret < finish Assert.assertTrue(callTime <= result.startMillis); Assert.assertTrue(result.startMillis < result.finishMillis); Assert.assertTrue(result.finishMillis <= callbackTime); Assert.assertTrue(callbackTime <= resTime); Assert.assertTrue(retTime < result.finishMillis); } @Test public void testCallbackAddSimple() throws Exception { final AtomicLong callbackTimeRef = new AtomicLong(); final AtomicReference<XdrLong> resultRef = new AtomicReference<>(); final CountDownLatch latch = new CountDownLatch(1); long callTime = System.currentTimeMillis(); client.addSimple_1_callback(1, 2, new CompletionHandler<RpcReply, XdrTransport>() { @Override public void completed(RpcReply result, XdrTransport attachment) { callbackTimeRef.set(System.currentTimeMillis()); XdrLong calculationResult = new XdrLong(); try { result.getReplyResult(calculationResult); } catch (Exception e) { throw new IllegalStateException(e); } resultRef.set(calculationResult); latch.countDown(); } @Override public void failed(Throwable exc, XdrTransport attachment) { throw new IllegalStateException(exc); } }, 0, null, null); long retTime = System.currentTimeMillis(); latch.await(3, TimeUnit.SECONDS); long resTime = System.currentTimeMillis(); XdrLong result = resultRef.get(); Assert.assertNotNull(result); Assert.assertEquals(3, result.longValue()); long callbackTime = callbackTimeRef.get(); //to prove async operation (there's a sleep() server-side) //call < callback <= res //call <= ret < callback Assert.assertTrue(callTime < callbackTime); Assert.assertTrue(callbackTime <= resTime); Assert.assertTrue(callTime <= retTime); Assert.assertTrue(retTime < callbackTime); } @Test public void testCallbackAddTimeout() throws Exception { final AtomicReference<String> failureMsgRef = new AtomicReference<>(); final CountDownLatch latch = new CountDownLatch(1); client.addSimple_1_callback(1, 2, new CompletionHandler<RpcReply, XdrTransport>() { @Override public void completed(RpcReply result, XdrTransport attachment) { failureMsgRef.set("call should have timed out"); latch.countDown(); } @Override public void failed(Throwable exc, XdrTransport attachment) { if (!(exc instanceof TimeoutException)) { exc.printStackTrace(); failureMsgRef.set("expected TimeoutException. got "+exc); } latch.countDown(); } }, CalculatorServerImpl.SLEEP_MILLIS/10, TimeUnit.MILLISECONDS, null); latch.await(1, TimeUnit.SECONDS); Assert.assertNull(failureMsgRef.get()); } }