68a665e44539d08eb8b002fb245e6aaeba602e8e
[controller.git] / opendaylight / md-sal / sal-distributed-datastore / src / test / java / org / opendaylight / controller / cluster / datastore / actors / client / SequencedQueueEntryTest.java
1 /*
2  * Copyright (c) 2016 Cisco Systems, Inc. and others.  All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8 package org.opendaylight.controller.cluster.datastore.actors.client;
9
10 import static org.junit.Assert.assertEquals;
11 import static org.junit.Assert.assertFalse;
12 import static org.junit.Assert.assertSame;
13 import static org.junit.Assert.assertTrue;
14 import static org.mockito.Matchers.any;
15 import static org.mockito.Mockito.doReturn;
16 import static org.mockito.Mockito.verify;
17 import akka.actor.ActorRef;
18 import akka.actor.ActorSystem;
19 import akka.testkit.TestProbe;
20 import java.util.concurrent.ThreadLocalRandom;
21 import java.util.concurrent.TimeUnit;
22 import org.junit.After;
23 import org.junit.AfterClass;
24 import org.junit.Before;
25 import org.junit.BeforeClass;
26 import org.junit.Test;
27 import org.mockito.ArgumentCaptor;
28 import org.mockito.Mock;
29 import org.mockito.MockitoAnnotations;
30 import org.opendaylight.controller.cluster.access.ABIVersion;
31 import org.opendaylight.controller.cluster.access.concepts.AbstractRequestFailureProxy;
32 import org.opendaylight.controller.cluster.access.concepts.AbstractRequestProxy;
33 import org.opendaylight.controller.cluster.access.concepts.Request;
34 import org.opendaylight.controller.cluster.access.concepts.RequestException;
35 import org.opendaylight.controller.cluster.access.concepts.RequestFailure;
36 import org.opendaylight.controller.cluster.access.concepts.Response;
37 import org.opendaylight.controller.cluster.common.actor.TestTicker;
38 import org.opendaylight.yangtools.concepts.WritableIdentifier;
39 import scala.concurrent.duration.Duration;
40
41 /**
42  * Test suite covering logic contained in {@link SequencedQueueEntry}.
43  *
44  * @author Robert Varga
45  */
46 public class SequencedQueueEntryTest {
47     private static class MockFailure extends RequestFailure<WritableIdentifier, MockFailure> {
48         private static final long serialVersionUID = 1L;
49
50         MockFailure(final WritableIdentifier target, final long sequence, final long retry, final RequestException cause) {
51             super(target, sequence, retry, cause);
52         }
53
54         @Override
55         protected AbstractRequestFailureProxy<WritableIdentifier, MockFailure> externalizableProxy(final ABIVersion version) {
56             return null;
57         }
58
59         @Override
60         protected MockFailure cloneAsVersion(final ABIVersion version) {
61             return this;
62         }
63     }
64
65     private static class MockRequest extends Request<WritableIdentifier, MockRequest> {
66         private static final long serialVersionUID = 1L;
67
68         MockRequest(final WritableIdentifier target, final long sequence, final ActorRef replyTo) {
69             super(target, sequence, 0, replyTo);
70         }
71
72
73         MockRequest(final MockRequest request, final long retry) {
74             super(request, retry);
75         }
76
77         @Override
78         public RequestFailure<WritableIdentifier, ?> toRequestFailure(final RequestException cause) {
79             return new MockFailure(getTarget(), getSequence(), getRetry(), cause);
80         }
81
82         @Override
83         protected AbstractRequestProxy<WritableIdentifier, MockRequest> externalizableProxy(final ABIVersion version) {
84             return null;
85         }
86
87         @Override
88         protected MockRequest cloneAsVersion(final ABIVersion version) {
89             return this;
90         }
91
92         @Override
93         protected MockRequest cloneAsRetry(final long retry) {
94             return new MockRequest(this, retry);
95         }
96     };
97
98     @Mock
99     private ActorRef mockReplyTo;
100     @Mock
101     private WritableIdentifier mockIdentifier;
102     @Mock
103     private RequestException mockCause;
104     @Mock
105     private RequestCallback mockCallback;
106     @Mock
107     private ClientActorBehavior mockBehavior;
108
109     private TestTicker ticker;
110     private BackendInfo mockBackendInfo;
111     private Request<WritableIdentifier, ?> mockRequest;
112     private Response<WritableIdentifier, ?> mockResponse;
113
114     private static ActorSystem actorSystem;
115     private TestProbe mockActor;
116
117     private SequencedQueueEntry entry;
118
119     @BeforeClass
120     public static void setupClass() {
121         actorSystem = ActorSystem.apply();
122     }
123
124     @AfterClass
125     public static void teardownClass() {
126         actorSystem.terminate();
127     }
128
129     @Before
130     public void setup() {
131         MockitoAnnotations.initMocks(this);
132
133         doReturn(mockBehavior).when(mockCallback).complete(any(MockFailure.class));
134
135         ticker = new TestTicker();
136         ticker.increment(ThreadLocalRandom.current().nextLong());
137
138         mockActor = TestProbe.apply(actorSystem);
139         mockBackendInfo = new BackendInfo(mockActor.ref(), ABIVersion.current());
140         mockRequest = new MockRequest(mockIdentifier, ThreadLocalRandom.current().nextLong(), mockReplyTo);
141         mockResponse = mockRequest.toRequestFailure(mockCause);
142
143         entry = new SequencedQueueEntry(mockRequest, mockCallback, ticker.read());
144     }
145
146     @After
147     public void teardown() {
148         actorSystem.stop(mockActor.ref());
149     }
150
151     @Test
152     public void testGetSequence() {
153         assertEquals(mockRequest.getSequence(), entry.getSequence());
154     }
155
156     @Test
157     public void testGetCurrentTry() {
158         assertEquals(0, entry.getCurrentTry());
159         entry.retransmit(mockBackendInfo, ticker.read());
160         assertEquals(0, entry.getCurrentTry());
161         entry.retransmit(mockBackendInfo, ticker.read());
162         assertEquals(1, entry.getCurrentTry());
163         entry.retransmit(mockBackendInfo, ticker.read());
164         assertEquals(2, entry.getCurrentTry());
165     }
166
167     @Test
168     public void testComplete() {
169         entry.complete(mockResponse);
170         verify(mockCallback).complete(mockResponse);
171     }
172
173     @Test
174     public void testPoison() {
175         entry.poison(mockCause);
176
177         final ArgumentCaptor<MockFailure> captor = ArgumentCaptor.forClass(MockFailure.class);
178         verify(mockCallback).complete(captor.capture());
179         assertSame(mockCause, captor.getValue().getCause());
180     }
181
182     @Test
183     public void testIsTimedOut() {
184         assertTrue(entry.isTimedOut(ticker.read(), 0));
185         assertFalse(entry.isTimedOut(ticker.read(), 1));
186
187         entry.retransmit(mockBackendInfo, ticker.read());
188         assertTrue(entry.isTimedOut(ticker.read(), 0));
189         ticker.increment(10);
190         assertTrue(entry.isTimedOut(ticker.read(), 10));
191         assertFalse(entry.isTimedOut(ticker.read(), 20));
192
193         entry.retransmit(mockBackendInfo, ticker.read());
194         assertTrue(entry.isTimedOut(ticker.read(), 0));
195         ticker.increment(10);
196         assertTrue(entry.isTimedOut(ticker.read(), 10));
197         assertFalse(entry.isTimedOut(ticker.read(), 11));
198     }
199
200     @Test
201     public void testRetransmit() {
202         assertFalse(mockActor.msgAvailable());
203         entry.retransmit(mockBackendInfo, ticker.read());
204
205         assertTrue(mockActor.msgAvailable());
206         assertRequestEquals(mockRequest, mockActor.receiveOne(Duration.apply(5, TimeUnit.SECONDS)));
207     }
208
209      private static void assertRequestEquals(final Request<?, ?> expected, final Object o) {
210          final Request<?, ?> actual = (Request<?, ?>) o;
211          assertEquals(expected.getRetry(), actual.getRetry());
212          assertEquals(expected.getSequence(), actual.getSequence());
213          assertEquals(expected.getTarget(), actual.getTarget());
214     }
215 }