Package org.objectweb.celtix.bus.ws.rm

Source Code of org.objectweb.celtix.bus.ws.rm.RetransmissionQueueTest$TestResender

package org.objectweb.celtix.bus.ws.rm;

import java.io.OutputStream;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.List;

import javax.xml.ws.handler.MessageContext;

import junit.framework.TestCase;

import org.easymock.IMocksControl;
import org.easymock.classextension.EasyMock;
import org.objectweb.celtix.bindings.AbstractBindingBase;
import org.objectweb.celtix.bindings.AbstractBindingImpl;
import org.objectweb.celtix.bindings.DataBindingCallback;
import org.objectweb.celtix.bindings.ServerDataBindingCallback;
import org.objectweb.celtix.bus.ws.addressing.AddressingPropertiesImpl;
import org.objectweb.celtix.context.InputStreamMessageContext;
import org.objectweb.celtix.context.ObjectMessageContext;
import org.objectweb.celtix.context.OutputStreamMessageContext;
import org.objectweb.celtix.handlers.HandlerInvoker;
import org.objectweb.celtix.transports.ClientTransport;
import org.objectweb.celtix.transports.ServerTransport;
import org.objectweb.celtix.transports.Transport;
import org.objectweb.celtix.workqueue.WorkQueue;
import org.objectweb.celtix.ws.rm.Identifier;
import org.objectweb.celtix.ws.rm.RMProperties;
import org.objectweb.celtix.ws.rm.SequenceType;
import org.objectweb.celtix.ws.rm.persistence.RMStore;

import static org.objectweb.celtix.bindings.JAXWSConstants.DATABINDING_CALLBACK_PROPERTY;
import static org.objectweb.celtix.context.ObjectMessageContext.REQUESTOR_ROLE_PROPERTY;
import static org.objectweb.celtix.ws.addressing.JAXWSAConstants.CLIENT_ADDRESSING_PROPERTIES_OUTBOUND;
import static org.objectweb.celtix.ws.addressing.JAXWSAConstants.SERVER_ADDRESSING_PROPERTIES_OUTBOUND;
import static org.objectweb.celtix.ws.rm.JAXWSRMConstants.RM_PROPERTIES_OUTBOUND;


/**
* Test resend logic.
*/
public class RetransmissionQueueTest extends TestCase {

    private IMocksControl control;
    private RMHandler handler;
    private WorkQueue workQueue;
    private RetransmissionQueue queue;
    private TestResender resender;
    private List<ObjectMessageContext> contexts =
        new ArrayList<ObjectMessageContext>();
    private List<RMProperties> properties =
        new ArrayList<RMProperties>();
    private List<SequenceType> sequences =
        new ArrayList<SequenceType>();
    private List<Identifier> identifiers =
        new ArrayList<Identifier>();
   
    public void setUp() {
        control = EasyMock.createNiceControl();
        handler = control.createMock(RMHandler.class);
        queue = new RetransmissionQueue(handler);
        resender = new TestResender();
        queue.replaceResender(resender);
        workQueue = control.createMock(WorkQueue.class);
        /*
        workQueue.schedule(queue.getResendInitiator(),
                           queue.getBaseRetransmissionInterval());       
        EasyMock.expectLastCall();
        */
    }
   
    public void tearDown() {
        control.verify();
        contexts.clear();
        properties.clear();
        sequences.clear();
    }

    public void testCtor() {
        ready();
        assertNotNull("expected unacked map", queue.getUnacknowledged());
        assertEquals("expected empty unacked map",
                     0,
                     queue.getUnacknowledged().size());
        assertEquals("unexpected base retransmission interval",
                     3000L,
                     queue.getBaseRetransmissionInterval());
        assertEquals("unexpected exponential backoff",
                     2,
                     queue.getExponentialBackoff());
    }
   
    public void testCacheUnacknowledged() {
        ObjectMessageContext context1 = setUpContext("sequence1");
        ObjectMessageContext context2 = setUpContext("sequence2");
        ObjectMessageContext context3 = setUpContext("sequence1");
       
        setupContextMAPs(context1);
        setupContextMAPs(context2);
        setupContextMAPs(context3);
       
        ready();
       
        assertNotNull("expected resend candidate",
                      queue.cacheUnacknowledged(context1));
        assertEquals("expected non-empty unacked map",
                     1,
                     queue.getUnacknowledged().size());
        List<RetransmissionQueue.ResendCandidate> sequence1List =
            queue.getUnacknowledged().get("sequence1");
        assertNotNull("expected non-null context list", sequence1List);
        assertSame("expected context list entry",
                   context1,
                   sequence1List.get(0).getContext());

        assertNotNull("expected resend candidate",
                      queue.cacheUnacknowledged(context2));
        assertEquals("unexpected unacked map size",
                     2,
                     queue.getUnacknowledged().size());
        List<RetransmissionQueue.ResendCandidate> sequence2List =
            queue.getUnacknowledged().get("sequence2");
        assertNotNull("expected non-null context list", sequence2List);
        assertSame("expected context list entry",
                   context2,
                   sequence2List.get(0).getContext());
       
        assertNotNull("expected resend candidate",
                      queue.cacheUnacknowledged(context3));
        assertEquals("un expected unacked map size",
                     2,
                     queue.getUnacknowledged().size());
        sequence1List =
            queue.getUnacknowledged().get("sequence1");
        assertNotNull("expected non-null context list", sequence1List);
        assertSame("expected context list entry",
                   context3,
                   sequence1List.get(1).getContext());
    }
   
    public void testPurgeAcknowledgedSome() {
        BigInteger[] messageNumbers = {BigInteger.TEN, BigInteger.ONE};
        SourceSequence sequence = setUpSequence("sequence1",
                                          messageNumbers,
                                          new boolean[] {true, false});
        List<RetransmissionQueue.ResendCandidate> sequenceList =
            new ArrayList<RetransmissionQueue.ResendCandidate>();
        queue.getUnacknowledged().put("sequence1", sequenceList);
        ObjectMessageContext context1 =
            setUpContext("sequence1", messageNumbers[0]);
        sequenceList.add(queue.createResendCandidate(context1));
        ObjectMessageContext context2 =
            setUpContext("sequence1", messageNumbers[1]);
        sequenceList.add(queue.createResendCandidate(context2));
        ready();

        queue.purgeAcknowledged(sequence);
        assertEquals("unexpected unacked map size",
                     1,
                     queue.getUnacknowledged().size());
        assertEquals("unexpected unacked list size",
                     1,
                     sequenceList.size());
    }
   
    public void testPurgeAcknowledgedNone() {
        BigInteger[] messageNumbers = {BigInteger.TEN, BigInteger.ONE};
        SourceSequence sequence = setUpSequence("sequence1",
                                           messageNumbers,
                                           new boolean[] {false, false});
        List<RetransmissionQueue.ResendCandidate> sequenceList =
            new ArrayList<RetransmissionQueue.ResendCandidate>();
        queue.getUnacknowledged().put("sequence1", sequenceList);
        ObjectMessageContext context1 =
            setUpContext("sequence1", messageNumbers[0]);
        sequenceList.add(queue.createResendCandidate(context1));
        ObjectMessageContext context2 =
            setUpContext("sequence1", messageNumbers[1]);
        sequenceList.add(queue.createResendCandidate(context2));
        ready();

        queue.purgeAcknowledged(sequence);
        assertEquals("unexpected unacked map size",
                     1,
                     queue.getUnacknowledged().size());
        assertEquals("unexpected unacked list size",
                     2,
                     sequenceList.size());
    }

    public void testCountUnacknowledged() {
        BigInteger[] messageNumbers = {BigInteger.TEN, BigInteger.ONE};
        SourceSequence sequence = setUpSequence("sequence1",
                                          messageNumbers,
                                          null);
        List<RetransmissionQueue.ResendCandidate> sequenceList =
            new ArrayList<RetransmissionQueue.ResendCandidate>();
        queue.getUnacknowledged().put("sequence1", sequenceList);
        ObjectMessageContext context1 =
            setUpContext("sequence1", messageNumbers[0], false);
        sequenceList.add(queue.createResendCandidate(context1));
        ObjectMessageContext context2 =
            setUpContext("sequence1", messageNumbers[1], false);
        sequenceList.add(queue.createResendCandidate(context2));
        ready();

        assertEquals("unexpected unacked count",
                     2,
                     queue.countUnacknowledged(sequence));
    }
   
    public void testCountUnacknowledgedUnknownSequence() {
        BigInteger[] messageNumbers = {BigInteger.TEN, BigInteger.ONE};
        SourceSequence sequence = setUpSequence("sequence1",
                                          messageNumbers,
                                          null);
        ready();

        assertEquals("unexpected unacked count",
                     0,
                     queue.countUnacknowledged(sequence));
    }
   
    public void testResendInitiatorBackoffLogic() {
        ObjectMessageContext context1 = setUpContext("sequence1");
        ObjectMessageContext context2 = setUpContext("sequence2");
        ObjectMessageContext context3 = setUpContext("sequence1");
        setupContextMAPs(context1);
        setupContextMAPs(context2);
        setupContextMAPs(context3);
        ready();
        RetransmissionQueue.ResendCandidate candidate1 =
            queue.cacheUnacknowledged(context1);
        RetransmissionQueue.ResendCandidate candidate2 =
            queue.cacheUnacknowledged(context2);
        RetransmissionQueue.ResendCandidate candidate3 =
            queue.cacheUnacknowledged(context3);
        RetransmissionQueue.ResendCandidate[] allCandidates =
        {candidate1, candidate2, candidate3};
        boolean [] expectAckRequested = {true, true, false};

        // initial run => none due
        runInitiator();

        // all 3 candidates due
        runInitiator(allCandidates);
        runCandidates(allCandidates, expectAckRequested);       
                       
        // exponential backoff => none due
        runInitiator();
       
        // all 3 candidates due
        runInitiator(allCandidates);
        runCandidates(allCandidates, expectAckRequested);

        for (int i = 0; i < 3; i++) {
            // exponential backoff => none due
            runInitiator();
        }

        // all 3 candidates due
        runInitiator(allCandidates);
        runCandidates(allCandidates, expectAckRequested);
       
        for (int i = 0; i < 7; i++) {
            // exponential backoff => none due
            runInitiator();
        }
       
        // all 3 candidates due
        runInitiator(allCandidates);
        runCandidates(allCandidates, expectAckRequested);
    }


    public void testResendInitiatorDueLogic() {
        ObjectMessageContext context1 = setUpContext("sequence1");
        ObjectMessageContext context2 = setUpContext("sequence2");
        ObjectMessageContext context3 = setUpContext("sequence1");
        setupContextMAPs(context1);
        setupContextMAPs(context2);
        setupContextMAPs(context3);
        ready();
        RetransmissionQueue.ResendCandidate candidate1 =
            queue.cacheUnacknowledged(context1);
        RetransmissionQueue.ResendCandidate candidate2 =
            queue.cacheUnacknowledged(context2);
        RetransmissionQueue.ResendCandidate candidate3 =
            queue.cacheUnacknowledged(context3);
        RetransmissionQueue.ResendCandidate[] allCandidates =
        {candidate1, candidate2, candidate3};
        boolean [] expectAckRequested = {true, true, false};

        // initial run => none due
        runInitiator();

        // all 3 candidates due
        runInitiator(allCandidates);
               
        // all still pending => none due
        runInitiator();
       
        candidate1.run();
        candidate2.run();
       
        // exponential backoff => none due
        runInitiator();
       
        // candidates 1 & 2 run => only these due
        runInitiator(new RetransmissionQueue.ResendCandidate[] {candidate1,
                                                                candidate2});

        runCandidates(allCandidates, expectAckRequested);

        // exponential backoff => none due
        runInitiator();

        // candidates 3 run belatedly => now due
        runInitiator(new RetransmissionQueue.ResendCandidate[] {candidate3});
       
        // exponential backoff => none due
        runInitiator();

        // candidates 1 & 2 now due
        runInitiator(new RetransmissionQueue.ResendCandidate[] {candidate1,
                                                                candidate2});
    }
   
    public void testResendInitiatorResolvedLogic() {
        ObjectMessageContext context1 = setUpContext("sequence1");
        ObjectMessageContext context2 = setUpContext("sequence2");
        ObjectMessageContext context3 = setUpContext("sequence1");
        setupContextMAPs(context1);
        setupContextMAPs(context2);
        setupContextMAPs(context3);
        ready();
        RetransmissionQueue.ResendCandidate candidate1 =
            queue.cacheUnacknowledged(context1);
        RetransmissionQueue.ResendCandidate candidate2 =
            queue.cacheUnacknowledged(context2);
        RetransmissionQueue.ResendCandidate candidate3 =
            queue.cacheUnacknowledged(context3);
        RetransmissionQueue.ResendCandidate[] allCandidates =
        {candidate1, candidate2, candidate3};
        boolean [] expectAckRequested = {true, true, false};
       
        // initial run => none due
        runInitiator();

        // all 3 candidates due
        runInitiator(allCandidates);
        runCandidates(allCandidates, expectAckRequested);

        // exponential backoff => none due
        runInitiator();
       
        candidate1.resolved();
        candidate3.resolved();
       
        // candidates 1 & 3 resolved => only candidate2 due
        runInitiator(new RetransmissionQueue.ResendCandidate[] {candidate2});
    }
   
    public void testResenderInitiatorReschedule() {
        ready();
       
        runInitiator();
    }

    public void testResenderInitiatorNoRescheduleOnShutdown() {
        ready();
       
        queue.shutdown();
        queue.getResendInitiator().run();
    }
   
    public void testDefaultResenderClient() throws Exception {
        doTestDefaultResender(true);
    }
   
    public void testDefaultResenderServer() throws Exception {
        doTestDefaultResender(false);
    }

    private void doTestDefaultResender(boolean isRequestor) throws Exception {
        ObjectMessageContext context1 = setUpContext("sequence1");
        setupContextMAPs(context1);
        queue.replaceResender(queue.getDefaultResender());
        ready();
        RetransmissionQueue.ResendCandidate candidate1 =
            queue.cacheUnacknowledged(context1);
        RetransmissionQueue.ResendCandidate[] allCandidates = {candidate1};

        // initial run => none due
        runInitiator();

        // single candidate due
        runInitiator(allCandidates);
        setUpDefaultResender(0, isRequestor);
        allCandidates[0].run();
    }

    private ObjectMessageContext setUpContext(String sid) {
        return setUpContext(sid, null);
    }

    private ObjectMessageContext setUpContext(String sid,
                                        BigInteger messageNumber) {
        return setUpContext(sid, messageNumber, true);
    }

    private ObjectMessageContext setUpContext(String sid,
                                        BigInteger messageNumber,
                                        boolean storeSequence) {
        ObjectMessageContext context =
            control.createMock(ObjectMessageContext.class);
        if (storeSequence) {
            setUpSequenceType(context, sid, messageNumber);
        }
        contexts.add(context);
       
        return context;
    }
   
    private void setupContextMAPs(ObjectMessageContext context) {
        AddressingPropertiesImpl maps = control.createMock(AddressingPropertiesImpl.class);
        context.get(CLIENT_ADDRESSING_PROPERTIES_OUTBOUND);
        EasyMock.expectLastCall().andReturn(maps);
    }
   
    private void ready() {
        control.replay();
        queue.start(workQueue);
    }
   
    private void setUpDefaultResender(int i, boolean isRequestor)
        throws Exception {
        assertTrue("too few contexts", i < contexts.size());
        assertTrue("too few properties", i < properties.size());
        assertTrue("too few sequences", i < sequences.size());
        control.verify();
        control.reset();
       
        contexts.get(i).get(RM_PROPERTIES_OUTBOUND);
        EasyMock.expectLastCall().andReturn(properties.get(i)).times(2);
        properties.get(i).getSequence();
        EasyMock.expectLastCall().andReturn(sequences.get(i)).times(2);
        AddressingPropertiesImpl maps =
            control.createMock(AddressingPropertiesImpl.class);
        contexts.get(i).get(REQUESTOR_ROLE_PROPERTY);
        EasyMock.expectLastCall().andReturn(Boolean.valueOf(isRequestor)).times(2);
        contexts.get(i).get(SERVER_ADDRESSING_PROPERTIES_OUTBOUND);
        EasyMock.expectLastCall().andReturn(maps);
        sequences.get(i).getIdentifier();
        EasyMock.expectLastCall().andReturn(identifiers.get(i));
        Transport transport = isRequestor
                              ? control.createMock(ClientTransport.class)
                              : control.createMock(ServerTransport.class);
        if (isRequestor) {
            handler.getClientTransport();
            EasyMock.expectLastCall().andReturn(transport).times(2);
        } else {
            handler.getServerTransport();
            EasyMock.expectLastCall().andReturn(transport).times(1);
        }
        AbstractBindingBase binding =
            control.createMock(AbstractBindingBase.class);
        handler.getBinding();
        EasyMock.expectLastCall().andReturn(binding);
        HandlerInvoker handlerInvoker =
            control.createMock(HandlerInvoker.class);
        binding.createHandlerInvoker();
        EasyMock.expectLastCall().andReturn(handlerInvoker);
        AbstractBindingImpl bindingImpl =
            control.createMock(AbstractBindingImpl.class);
        binding.getBindingImpl();
        EasyMock.expectLastCall().andReturn(bindingImpl).times(isRequestor
                                                               ? 6
                                                               : 5);
        bindingImpl.createBindingMessageContext(contexts.get(i));
        MessageContext bindingContext =
            control.createMock(MessageContext.class);
        EasyMock.expectLastCall().andReturn(bindingContext);
        OutputStreamMessageContext outputStreamContext =
            control.createMock(OutputStreamMessageContext.class);
        transport.createOutputStreamContext(bindingContext);
        EasyMock.expectLastCall().andReturn(outputStreamContext);
       
        if (isRequestor) {
            setUpClientDispatch(handlerInvoker,
                                contexts.get(i),
                                bindingContext,
                                outputStreamContext,
                                bindingImpl,
                                transport);
        } else {
            setUpServerDispatch(bindingContext, outputStreamContext);
        }
       
        control.replay();
    }

    private void setUpClientDispatch(
                              HandlerInvoker handlerInvoker,
                              ObjectMessageContext objectContext,
                              MessageContext bindingContext,
                              OutputStreamMessageContext outputStreamContext,
                              AbstractBindingImpl bindingImpl,
                              Transport transport) throws Exception {
        handlerInvoker.invokeProtocolHandlers(true, bindingContext);
        EasyMock.expectLastCall().andReturn(Boolean.TRUE);
        InputStreamMessageContext inputStreamContext =
            control.createMock(InputStreamMessageContext.class);
        ((ClientTransport)transport).invoke(outputStreamContext);
        EasyMock.expectLastCall().andReturn(inputStreamContext);
        bindingImpl.read(inputStreamContext, bindingContext);
        EasyMock.expectLastCall();
        bindingImpl.hasFault(bindingContext);
        EasyMock.expectLastCall().andReturn(false);
        bindingImpl.unmarshal(bindingContext, objectContext, null);
        EasyMock.expectLastCall();
    }

    private void setUpServerDispatch(
                            MessageContext bindingContext,
                            OutputStreamMessageContext outputStreamContext) {
        DataBindingCallback callback =
            control.createMock(ServerDataBindingCallback.class);
        bindingContext.get(DATABINDING_CALLBACK_PROPERTY);
        EasyMock.expectLastCall().andReturn(callback);
        OutputStream outputStream = control.createMock(OutputStream.class);
        outputStreamContext.getOutputStream();
        EasyMock.expectLastCall().andReturn(outputStream);
    }

    private void runInitiator() {
        runInitiator(null);
    }
   
    private void runInitiator(
                       RetransmissionQueue.ResendCandidate[] dueCandidates) {
        control.verify();
        control.reset();
       
        for (int i = 0;
             dueCandidates != null && i < dueCandidates.length;
             i++) {
            workQueue.execute(dueCandidates[i]);
            EasyMock.expectLastCall();
        }
        /*
        workQueue.schedule(queue.getResendInitiator(),
                           queue.getBaseRetransmissionInterval());        
        EasyMock.expectLastCall();
        */
        control.replay();
        queue.getResendInitiator().run();
    }
   
    private void runCandidates(
                          RetransmissionQueue.ResendCandidate[] candidates,
                          boolean[] expectAckRequested) {
        for (int i = 0; i < candidates.length; i++) {
            candidates[i].run();
            assertEquals("unexpected request acknowledge",
                         expectAckRequested[i],
                         resender.includeAckRequested);
            assertSame("unexpected context",
                       candidates[i].getContext(),
                       resender.context);
            resender.clear();
        }
    }
   
    private SequenceType setUpSequenceType(ObjectMessageContext context,
                                           String sid,
                                           BigInteger messageNumber) {
        RMProperties rmps = control.createMock(RMProperties.class);
        if (context != null) {
            context.get(RM_PROPERTIES_OUTBOUND);
            EasyMock.expectLastCall().andReturn(rmps);
        }
        properties.add(rmps);
        SequenceType sequence = control.createMock(SequenceType.class);
        if (context != null) {
            rmps.getSequence();
            EasyMock.expectLastCall().andReturn(sequence);
        }
        if (messageNumber != null) {
            sequence.getMessageNumber();
            EasyMock.expectLastCall().andReturn(messageNumber);
        } else {
            Identifier id = control.createMock(Identifier.class);
            sequence.getIdentifier();
            EasyMock.expectLastCall().andReturn(id);
            id.getValue();
            EasyMock.expectLastCall().andReturn(sid);
            identifiers.add(id);
        }
        sequences.add(sequence);
        return sequence;
    }
   
    @SuppressWarnings("unchecked")
    private SourceSequence setUpSequence(String sid,
                                   BigInteger[] messageNumbers,
                                   boolean[] isAcked) {
        SourceSequence sequence = control.createMock(SourceSequence.class);
        Identifier id = control.createMock(Identifier.class);
        sequence.getIdentifier();
        EasyMock.expectLastCall().andReturn(id);
        id.getValue();
        EasyMock.expectLastCall().andReturn(sid);
        identifiers.add(id);
        boolean includesAcked = false;
        for (int i = 0; isAcked != null && i < isAcked.length; i++) {
            sequence.isAcknowledged(messageNumbers[i]);
            EasyMock.expectLastCall().andReturn(isAcked[i]);
            if (isAcked[i]) {
                includesAcked = true;
            }
        }
        if (includesAcked) {
            sequence.getIdentifier();
            EasyMock.expectLastCall().andReturn(id);
            RMStore store = control.createMock(RMStore.class);
            handler.getStore();
            EasyMock.expectLastCall().andReturn(store);
        }
        return sequence;
    }
   
    private static class TestResender implements RetransmissionQueue.Resender {
        ObjectMessageContext context;
        boolean includeAckRequested;
       
        public void resend(ObjectMessageContext ctx, boolean requestAcknowledge) {
            context = ctx;
            includeAckRequested = requestAcknowledge;
        }
       
        void clear() {
            context = null;
            includeAckRequested = false;           
        }
    };
}
TOP

Related Classes of org.objectweb.celtix.bus.ws.rm.RetransmissionQueueTest$TestResender

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.