Bug 5928 - Future error after OutboundQueueEntry.java failed
[openflowjava.git] / openflow-protocol-impl / src / test / java / org / opendaylight / openflowjava / protocol / impl / core / connection / OutboundQueueEntryTest.java
1 package org.opendaylight.openflowjava.protocol.impl.core.connection;
2
3 import com.google.common.util.concurrent.FutureCallback;
4 import javax.annotation.Nullable;
5 import org.junit.Assert;
6 import org.junit.Test;
7 import org.junit.runner.RunWith;
8 import org.mockito.Mock;
9 import org.mockito.Mockito;
10 import org.mockito.runners.MockitoJUnitRunner;
11 import org.opendaylight.openflowjava.protocol.api.connection.OutboundQueueException;
12 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MultipartRequestFlags;
13 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.BarrierInputBuilder;
14 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.FlowModInputBuilder;
15 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.FlowRemovedMessageBuilder;
16 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartReplyMessageBuilder;
17 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.OfHeader;
18 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PacketOutInputBuilder;
19 import org.slf4j.Logger;
20 import org.slf4j.LoggerFactory;
21
22 /**
23  * {@link OutboundQueueEntry} class test
24  */
25 @RunWith(MockitoJUnitRunner.class)
26 public class OutboundQueueEntryTest {
27
28     private static final Logger LOG = LoggerFactory.getLogger(OutboundQueueEntryTest.class);
29
30     private static final short VERSION = (short) 13;
31     private static final long VALUE = 1L;
32
33     private Integer failCounter = 0;
34
35     @Mock
36     private OfHeader ofHeader;
37     @Mock
38     private FutureCallback<OfHeader> futureCallback;
39
40     private final OutboundQueueEntry outboundQueueEntry = new OutboundQueueEntry();
41     private final OfHeader barrierInput = new BarrierInputBuilder().setVersion(VERSION).setXid(VALUE).build();
42     private final OfHeader packetOutInput = new PacketOutInputBuilder().setVersion(VERSION).setXid(VALUE).build();
43     private final OfHeader multipartReplyMessage =
44             new MultipartReplyMessageBuilder().setVersion(VERSION).setXid(VALUE).setFlags(new MultipartRequestFlags(false)).build();
45     private final OfHeader flowModInput = new FlowModInputBuilder().setVersion(VERSION).setXid(VALUE).build();
46     private final OfHeader flowRemoved = new FlowRemovedMessageBuilder().setVersion(VERSION).setXid(VALUE).build();
47
48     @Test
49     public void commit() throws Exception {
50         outboundQueueEntry.commit(ofHeader, futureCallback);
51         Assert.assertTrue(outboundQueueEntry.isCommitted());
52         Assert.assertFalse(outboundQueueEntry.isCompleted());
53         Assert.assertFalse(outboundQueueEntry.isBarrier());
54     }
55
56     @Test
57     public void reset() throws Exception {
58         outboundQueueEntry.commit(ofHeader, futureCallback);
59         Assert.assertTrue(outboundQueueEntry.isCommitted());
60
61         outboundQueueEntry.reset();
62         Assert.assertFalse(outboundQueueEntry.isCommitted());
63     }
64
65     @Test
66     public void isBarrier() throws Exception {
67         outboundQueueEntry.commit(barrierInput, futureCallback);
68         Assert.assertTrue(outboundQueueEntry.isBarrier());
69     }
70
71     @Test
72     public void takeMessage() throws Exception {
73         outboundQueueEntry.commit(packetOutInput, futureCallback);
74         outboundQueueEntry.takeMessage();
75         Mockito.verify(futureCallback).onSuccess(Mockito.<OfHeader>any());
76     }
77
78     @Test
79     public void complete() throws Exception {
80         final boolean result = outboundQueueEntry.complete(multipartReplyMessage);
81         Assert.assertTrue(result);
82         Assert.assertTrue(outboundQueueEntry.isCompleted());
83     }
84
85     @Test(expected = IllegalStateException.class)
86     public void completeTwice() throws Exception {
87         outboundQueueEntry.complete(multipartReplyMessage);
88         outboundQueueEntry.complete(multipartReplyMessage);
89     }
90
91     @Test
92     public void fail() throws Exception {
93         outboundQueueEntry.commit(ofHeader, futureCallback);
94         outboundQueueEntry.fail(null);
95         Mockito.verify(futureCallback).onFailure(Mockito.<OutboundQueueException>any());
96     }
97
98     private Integer increaseFailCounter() {
99         return ++this.failCounter;
100     }
101
102     @Test
103     public void test() throws Exception {
104
105         final FutureCallback<OfHeader> result =
106                 new FutureCallback<OfHeader>() {
107
108                     @Override
109                     public void onSuccess(@Nullable OfHeader ofHeader) {
110                         LOG.info("onSuccess: xid: {}", ofHeader.getXid());
111                     }
112
113                     @Override
114                     public void onFailure(Throwable throwable) {
115                         LOG.info("onFailure! Error: {}", throwable);
116                         LOG.info("Failure called {} time", increaseFailCounter());
117                     }
118                 };
119
120         /** This scenario creates entry with XID 1 then commit it, fail it and again commit it */
121         /** Simulates behavior when entry is committed after fail */
122         /** It shouldn't be in state completed and still have callback, it can consume all threads in thread pool */
123
124         /** Entry but no callback */
125         outboundQueueEntry.commit(flowModInput, null);
126         /** Failed entry for whatever reason */
127         outboundQueueEntry.fail(null);
128         /** Commit the same entry adding callback */
129         outboundQueueEntry.commit(flowModInput, result);
130
131         Assert.assertTrue(outboundQueueEntry.isCompleted());
132         Assert.assertTrue(outboundQueueEntry.isCommitted());
133
134         /** This is check that no callback is in entry stuck */
135         Assert.assertFalse(outboundQueueEntry.hasCallback());
136
137         Assert.assertTrue(this.failCounter == 1);
138     }
139
140 }