2 * Copyright (c) 2016 Cisco Systems, Inc. and others. All rights reserved.
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
8 package org.opendaylight.controller.cluster.datastore.actors.client;
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.RequestEnvelope;
35 import org.opendaylight.controller.cluster.access.concepts.RequestException;
36 import org.opendaylight.controller.cluster.access.concepts.RequestFailure;
37 import org.opendaylight.controller.cluster.access.concepts.Response;
38 import org.opendaylight.controller.cluster.common.actor.TestTicker;
39 import org.opendaylight.yangtools.concepts.WritableIdentifier;
40 import scala.concurrent.duration.Duration;
43 * Test suite covering logic contained in {@link SequencedQueueEntry}.
45 * @author Robert Varga
47 public class SequencedQueueEntryTest {
48 private static class MockFailure extends RequestFailure<WritableIdentifier, MockFailure> {
49 private static final long serialVersionUID = 1L;
51 MockFailure(final WritableIdentifier target, final RequestException cause) {
56 protected AbstractRequestFailureProxy<WritableIdentifier, MockFailure> externalizableProxy(final ABIVersion version) {
61 protected MockFailure cloneAsVersion(final ABIVersion version) {
66 private static class MockRequest extends Request<WritableIdentifier, MockRequest> {
67 private static final long serialVersionUID = 1L;
69 MockRequest(final WritableIdentifier target, final ActorRef replyTo) {
70 super(target, replyTo);
74 public RequestFailure<WritableIdentifier, ?> toRequestFailure(final RequestException cause) {
75 return new MockFailure(getTarget(), cause);
79 protected AbstractRequestProxy<WritableIdentifier, MockRequest> externalizableProxy(final ABIVersion version) {
84 protected MockRequest cloneAsVersion(final ABIVersion version) {
90 private ActorRef mockReplyTo;
92 private WritableIdentifier mockIdentifier;
94 private RequestException mockCause;
96 private RequestCallback mockCallback;
98 private ClientActorBehavior mockBehavior;
100 private TestTicker ticker;
101 private BackendInfo mockBackendInfo;
102 private Request<WritableIdentifier, ?> mockRequest;
103 private Response<WritableIdentifier, ?> mockResponse;
105 private static ActorSystem actorSystem;
106 private TestProbe mockActor;
108 private SequencedQueueEntry entry;
111 public static void setupClass() {
112 actorSystem = ActorSystem.apply();
116 public static void teardownClass() {
117 actorSystem.terminate();
121 public void setup() {
122 MockitoAnnotations.initMocks(this);
124 doReturn(mockBehavior).when(mockCallback).complete(any(MockFailure.class));
126 ticker = new TestTicker();
127 ticker.increment(ThreadLocalRandom.current().nextLong());
129 mockActor = TestProbe.apply(actorSystem);
130 mockBackendInfo = new BackendInfo(mockActor.ref(), ABIVersion.current());
131 mockRequest = new MockRequest(mockIdentifier, mockReplyTo);
132 mockResponse = mockRequest.toRequestFailure(mockCause);
134 entry = new SequencedQueueEntry(mockRequest, 0, mockCallback, ticker.read());
138 public void teardown() {
139 actorSystem.stop(mockActor.ref());
143 public void testGetSequence() {
144 assertEquals(0, entry.getSequence());
148 public void testGetCurrentTry() {
149 assertEquals(0, entry.getCurrentTry());
150 entry.retransmit(mockBackendInfo, ticker.read());
151 assertEquals(0, entry.getCurrentTry());
152 entry.retransmit(mockBackendInfo, ticker.read());
153 assertEquals(1, entry.getCurrentTry());
154 entry.retransmit(mockBackendInfo, ticker.read());
155 assertEquals(2, entry.getCurrentTry());
159 public void testComplete() {
160 entry.complete(mockResponse);
161 verify(mockCallback).complete(mockResponse);
165 public void testPoison() {
166 entry.poison(mockCause);
168 final ArgumentCaptor<MockFailure> captor = ArgumentCaptor.forClass(MockFailure.class);
169 verify(mockCallback).complete(captor.capture());
170 assertSame(mockCause, captor.getValue().getCause());
174 public void testIsTimedOut() {
175 assertTrue(entry.isTimedOut(ticker.read(), 0));
176 assertFalse(entry.isTimedOut(ticker.read(), 1));
178 entry.retransmit(mockBackendInfo, ticker.read());
179 assertTrue(entry.isTimedOut(ticker.read(), 0));
180 ticker.increment(10);
181 assertTrue(entry.isTimedOut(ticker.read(), 10));
182 assertFalse(entry.isTimedOut(ticker.read(), 20));
184 entry.retransmit(mockBackendInfo, ticker.read());
185 assertTrue(entry.isTimedOut(ticker.read(), 0));
186 ticker.increment(10);
187 assertTrue(entry.isTimedOut(ticker.read(), 10));
188 assertFalse(entry.isTimedOut(ticker.read(), 11));
192 public void testRetransmit() {
193 assertFalse(mockActor.msgAvailable());
194 entry.retransmit(mockBackendInfo, ticker.read());
196 assertTrue(mockActor.msgAvailable());
197 assertRequestEquals(mockRequest, mockActor.receiveOne(Duration.apply(5, TimeUnit.SECONDS)));
200 private static void assertRequestEquals(final Request<?, ?> expected, final Object o) {
201 assertTrue(o instanceof RequestEnvelope);
203 final RequestEnvelope actual = (RequestEnvelope) o;
204 assertEquals(0, actual.getRetry());
205 assertEquals(0, actual.getSequence());
206 assertEquals(expected.getTarget(), actual.getMessage().getTarget());