package org.jgroups.blocks; import org.jgroups.*; import org.jgroups.stack.Protocol; import org.jgroups.util.Buffer; import org.jgroups.util.Util; import org.testng.annotations.BeforeClass; import org.testng.annotations.Test; import java.net.UnknownHostException; import java.util.concurrent.CancellationException; import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; /** * @author Bela Ban */ @Test(groups=Global.FUNCTIONAL,singleThreaded=true) public class UnicastRequestTest { protected Address a, b, c; protected static final byte[] data="bla".getBytes(); protected static final Buffer buf=new Buffer(data, 0, data.length); @BeforeClass void init() throws UnknownHostException { a=Util.createRandomAddress("A"); b=Util.createRandomAddress("B"); c=Util.createRandomAddress("C"); } public void testSimpleInvocation() throws Exception { MyCorrelator corr=new MyCorrelator(false, new Object[]{new Message(b, (long)322649)}, 0); UnicastRequest<Long> req=new UnicastRequest<>(corr, a, RequestOptions.SYNC().timeout(1000)); corr.setRequest(req); Long result=req.execute(buf, true); System.out.println("result = " + result); assert result != null && result == 322649; result=req.get(); // use the future System.out.println("result = " + result); assert result != null && result == 322649; } public void testSimpleVoidInvocation() throws Exception { MyCorrelator corr=new MyCorrelator(false, new Object[]{new Message(b, (String)null)}, 0); UnicastRequest<String> req=new UnicastRequest<>(corr, a, RequestOptions.SYNC().timeout(1000)); corr.setRequest(req); String result=req.execute(buf, true); assert req.isDone(); System.out.println("result = " + result); assert result == null; result=req.get(); System.out.println("result = " + result); assert result == null; } public void testInvocationWithException() throws Exception { MyCorrelator corr=new MyCorrelator(false, new Object[]{new Message(b, (long)322649)}, 0); UnicastRequest<Object> req=new UnicastRequest<>(corr, a, RequestOptions.SYNC().timeout(1000)); corr.setRequest(req); req.receiveResponse(new NullPointerException("booom"), b, false); Object result=req.execute(buf, true); System.out.println("result = " + result); assert result != null && result instanceof NullPointerException; result=req.get(); // use the future System.out.println("result = " + result); assert result != null && result instanceof NullPointerException; req=new UnicastRequest<>(corr, a, RequestOptions.SYNC().timeout(1000)); corr.setRequest(req); req.receiveResponse(new NullPointerException("booom"), b, true); try { req.execute(buf, true); assert false : "should have thrown NullPointerException"; } catch(NullPointerException ex) { System.out.printf("received %s as expected\n", ex); } try { req.get(); // use the future assert false : "should have thrown ExecutionException"; } catch(ExecutionException ex) { System.out.printf("received %s as expected\n", ex); assert ex.getCause() instanceof NullPointerException; } } public void testInvocationWithTimeout() throws Exception { MyCorrelator corr=new MyCorrelator(false, null, 0); UnicastRequest<Long> req=new UnicastRequest<>(corr, a, RequestOptions.SYNC().timeout(500)); corr.setRequest(req); try { req.execute(buf, true); assert false : "should have thrown TimeoutException"; } catch(TimeoutException ex) { System.out.printf("received %s as expected\n", ex); } try { req.get(500, TimeUnit.MILLISECONDS); // use the future assert false : "should have thrown ExecutionException"; } catch(TimeoutException ex) { System.out.printf("received %s as expected\n", ex); } } public void testViewChange() throws Exception { MyCorrelator corr=new MyCorrelator(false, null, 0); UnicastRequest<Long> req=new UnicastRequest<>(corr, a, RequestOptions.SYNC().timeout(5000)); corr.setRequest(req); View new_view=View.create(b, 5, b,c); req.viewChange(new_view); try { req.execute(buf, true); } catch(SuspectedException ex) { System.out.printf("received %s as expected\n", ex); } try { req.get(100, TimeUnit.MILLISECONDS); assert false : "should have thrown ExecutionException"; } catch(ExecutionException ex) { System.out.printf("received %s as expected\n", ex); assert ex.getCause() instanceof SuspectedException; } } public void testCancel() throws Exception { MyCorrelator corr=new MyCorrelator(false, null, 0); UnicastRequest<Long> req=new UnicastRequest<>(corr, a, RequestOptions.SYNC().timeout(5000)); corr.setRequest(req); req.cancel(true); try { req.execute(buf, true); assert false : "should have thrown CancellationException"; } catch(CancellationException ex) { System.out.printf("received %s as expected\n", ex); } final UnicastRequest<Long> req2=new UnicastRequest<>(corr, a, RequestOptions.SYNC().timeout(5000)); corr.setRequest(req2); new Thread(() -> {Util.sleep(1000); req2.cancel(true);}).start(); try { req2.execute(buf, true); assert false : "should have thrown CancellationException"; } catch(CancellationException ex) { System.out.printf("received %s as expected\n", ex); } assert req.isCancelled(); assert req2.isCancelled(); } protected static class MyCorrelator extends RequestCorrelator { protected UnicastRequest request; protected boolean async=true; protected Object[] responses; protected long delay; public MyCorrelator(boolean async, Object[] responses, long delay) { super(null, null, null); this.async=async; this.responses=responses; this.delay=delay; this.transport=new Protocol() { public Object down(Event evt) { return null; } }; } public void setRequest(UnicastRequest r) { request=r; } @Override public void sendUnicastRequest(Address dest, Buffer data, Request req, RequestOptions opts) throws Exception { send(); } protected void send() { if(async) { new Thread() { public void run() { sendResponses(); } }.start(); } else { sendResponses(); } } protected void sendResponses() { if(responses != null) { Object obj; for(int i=0; i < responses.length; i++) { if(delay > 0) Util.sleep(delay); obj=responses[i]; if(obj == null) { System.err.println("object was null"); continue; } if(obj instanceof Message) { Message msg=(Message)obj; Address sender=msg.getSrc(); Object retval=null; try { retval=Util.objectFromByteBuffer(msg.getBuffer()); } catch(Exception e) { e.printStackTrace(); } request.receiveResponse(retval, sender, false); } else if(obj instanceof View) request.viewChange((View)obj); } } } } }