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.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;
42 * Test suite covering logic contained in {@link SequencedQueueEntry}.
44 * @author Robert Varga
46 public class SequencedQueueEntryTest {
47 private static class MockFailure extends RequestFailure<WritableIdentifier, MockFailure> {
48 private static final long serialVersionUID = 1L;
50 MockFailure(final WritableIdentifier target, final long sequence, final long retry, final RequestException cause) {
51 super(target, sequence, retry, cause);
55 protected AbstractRequestFailureProxy<WritableIdentifier, MockFailure> externalizableProxy(final ABIVersion version) {
60 protected MockFailure cloneAsVersion(final ABIVersion version) {
65 private static class MockRequest extends Request<WritableIdentifier, MockRequest> {
66 private static final long serialVersionUID = 1L;
68 MockRequest(final WritableIdentifier target, final long sequence, final ActorRef replyTo) {
69 super(target, sequence, 0, replyTo);
73 MockRequest(final MockRequest request, final long retry) {
74 super(request, retry);
78 public RequestFailure<WritableIdentifier, ?> toRequestFailure(final RequestException cause) {
79 return new MockFailure(getTarget(), getSequence(), getRetry(), cause);
83 protected AbstractRequestProxy<WritableIdentifier, MockRequest> externalizableProxy(final ABIVersion version) {
88 protected MockRequest cloneAsVersion(final ABIVersion version) {
93 protected MockRequest cloneAsRetry(final long retry) {
94 return new MockRequest(this, retry);
99 private ActorRef mockReplyTo;
101 private WritableIdentifier mockIdentifier;
103 private RequestException mockCause;
105 private RequestCallback mockCallback;
107 private ClientActorBehavior mockBehavior;
109 private TestTicker ticker;
110 private BackendInfo mockBackendInfo;
111 private Request<WritableIdentifier, ?> mockRequest;
112 private Response<WritableIdentifier, ?> mockResponse;
114 private static ActorSystem actorSystem;
115 private TestProbe mockActor;
117 private SequencedQueueEntry entry;
120 public static void setupClass() {
121 actorSystem = ActorSystem.apply();
125 public static void teardownClass() {
126 actorSystem.terminate();
130 public void setup() {
131 MockitoAnnotations.initMocks(this);
133 doReturn(mockBehavior).when(mockCallback).complete(any(MockFailure.class));
135 ticker = new TestTicker();
136 ticker.increment(ThreadLocalRandom.current().nextLong());
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);
143 entry = new SequencedQueueEntry(mockRequest, mockCallback, ticker.read());
147 public void teardown() {
148 actorSystem.stop(mockActor.ref());
152 public void testGetSequence() {
153 assertEquals(mockRequest.getSequence(), entry.getSequence());
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());
168 public void testComplete() {
169 entry.complete(mockResponse);
170 verify(mockCallback).complete(mockResponse);
174 public void testPoison() {
175 entry.poison(mockCause);
177 final ArgumentCaptor<MockFailure> captor = ArgumentCaptor.forClass(MockFailure.class);
178 verify(mockCallback).complete(captor.capture());
179 assertSame(mockCause, captor.getValue().getCause());
183 public void testIsTimedOut() {
184 assertTrue(entry.isTimedOut(ticker.read(), 0));
185 assertFalse(entry.isTimedOut(ticker.read(), 1));
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));
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));
201 public void testRetransmit() {
202 assertFalse(mockActor.msgAvailable());
203 entry.retransmit(mockBackendInfo, ticker.read());
205 assertTrue(mockActor.msgAvailable());
206 assertRequestEquals(mockRequest, mockActor.receiveOne(Duration.apply(5, TimeUnit.SECONDS)));
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());