package org.jgroups.tests; import org.jgroups.*; import org.jgroups.protocols.pbcast.*; import org.jgroups.stack.Protocol; import org.jgroups.stack.ProtocolStack; import org.jgroups.util.Util; import org.testng.annotations.DataProvider; import org.testng.annotations.Test; import java.io.*; import java.util.Iterator; import java.util.NoSuchElementException; /** * Tests state transfer API (including exception handling) * @author Bela Ban */ @Test(groups=Global.STACK_DEPENDENT,sequential=true) public class StateTransferTest2 extends ChannelTestBase { JChannel c1, c2; @DataProvider(name="createChannels") protected Iterator<Class<?>[]> createChannels() { return new MyIterator(new Class<?>[]{STATE_TRANSFER.class, STATE.class, STATE_SOCK.class}); } @Test(dataProvider="createChannels") public void testSuccessfulStateTransfer(final Class<?> state_transfer_class) throws Exception { try { createStateProviderAndRequesterChannels(state_transfer_class); StateHandler sh1=new StateHandler("Bela", false, false), sh2=new StateHandler(null, false, false); c1.setReceiver(sh1); c2.setReceiver(sh2); c2.getState(null, 0); Object state=sh2.getReceivedState(); System.out.println("state = " + state); assert state != null && state.equals("Bela"); } finally { Util.close(c2, c1); } } @Test(dataProvider="createChannels") public void testUnsuccessfulStateTransferFailureAtStateProvider(final Class<?> state_transfer_class) throws Exception { try { createStateProviderAndRequesterChannels(state_transfer_class); StateHandler sh1=new StateHandler("Bela", true, false), sh2=new StateHandler(null, false, false); c1.setReceiver(sh1); c2.setReceiver(sh2); try { c2.getState(null, 0); assert false : "we shouldn't get here; getState() should have thrown an exception"; } catch(StateTransferException ex) { System.out.println("getState() threw an exception - as expected: " + ex); } Object state=sh2.getReceivedState(); System.out.println("state = " + state); assert state == null; } finally { Util.close(c2, c1); } } @Test(dataProvider="createChannels") public void testUnsuccessfulStateTransferFailureAtStateRequester(final Class<?> state_transfer_class) throws Exception { createStateProviderAndRequesterChannels(state_transfer_class); StateHandler sh1=new StateHandler("Bela", false, false), sh2=new StateHandler(null, false, true); c1.setReceiver(sh1); c2.setReceiver(sh2); try { c2.getState(null, 0); assert false : "we shouldn't get here; getState() should have thrown an exception"; } catch(StateTransferException ste) { System.out.println("getState() threw an exception - as expected: " + ste); } finally { Util.close(c2, c1); } } protected void createStateProviderAndRequesterChannels(Class state_transfer_class) throws Exception { c1=createChannel(true, 2, "Provider"); replaceStateTransferProtocolWith(c1, state_transfer_class); c2=createChannel(c1, "Requester"); c1.connect("StateTransferTest2"); c2.connect("StateTransferTest2"); } protected void replaceStateTransferProtocolWith(JChannel ch, Class<?> state_transfer_class) throws Exception { ProtocolStack stack=ch.getProtocolStack(); if(stack.findProtocol(state_transfer_class) != null) return; // protocol of the right class is already in stack Protocol prot=stack.findProtocol(STATE_TRANSFER.class, StreamingStateTransfer.class); Protocol new_state_transfer_protcol=(Protocol)state_transfer_class.newInstance(); if(prot != null) { stack.replaceProtocol(prot, new_state_transfer_protcol); } else { // no state transfer protocol found in stack Protocol flush=stack.findProtocol(FLUSH.class); if(flush != null) stack.insertProtocol(new_state_transfer_protcol, ProtocolStack.BELOW, FLUSH.class); else stack.insertProtocolAtTop(new_state_transfer_protcol); } } protected static class MyIterator implements Iterator<Class<?>[]> { protected final Class<?>[] stream_transfer_prots; protected int index=0; public MyIterator(Class<?>[] stream_transfer_prots) { this.stream_transfer_prots=stream_transfer_prots; } public boolean hasNext() {return index < stream_transfer_prots.length;} public Class<?>[] next() { if(index+1 > stream_transfer_prots.length) throw new NoSuchElementException(); return new Class<?>[]{stream_transfer_prots[index++]}; } public void remove() {} } protected static class StateHandler extends ReceiverAdapter { protected final boolean get_error; protected final boolean set_error; protected final Object state_to_send; protected Object received_state=null; public StateHandler(Object state_to_send, boolean get_error, boolean set_error) { this.state_to_send=state_to_send; this.get_error=get_error; this.set_error=set_error; } public Object getReceivedState() { return received_state; } public void getState(OutputStream ostream) throws Exception { if(get_error) throw new RuntimeException("[dummy failure] state could not be serialized"); DataOutputStream out=new DataOutputStream(new BufferedOutputStream(ostream, 200)); Util.objectToStream(state_to_send, out); out.flush(); } public void setState(InputStream istream) throws Exception { if(set_error) throw new RuntimeException("[dummy failure] state could not be set"); DataInputStream in=new DataInputStream(istream); try { received_state=Util.objectFromStream(in); } finally { Util.close(in); } } } }