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.access.client;
10 import static org.junit.Assert.assertEquals;
11 import static org.junit.Assert.assertFalse;
12 import static org.junit.Assert.assertNull;
13 import static org.junit.Assert.assertSame;
14 import static org.junit.Assert.assertTrue;
15 import static org.mockito.Matchers.any;
16 import static org.mockito.Mockito.doReturn;
17 import static org.mockito.Mockito.verify;
18 import akka.actor.ActorRef;
19 import akka.actor.ActorSystem;
20 import akka.testkit.TestProbe;
21 import java.util.concurrent.ThreadLocalRandom;
22 import java.util.concurrent.TimeUnit;
23 import org.junit.After;
24 import org.junit.AfterClass;
25 import org.junit.Before;
26 import org.junit.BeforeClass;
27 import org.junit.Test;
28 import org.mockito.ArgumentCaptor;
29 import org.mockito.Mock;
30 import org.mockito.MockitoAnnotations;
31 import org.opendaylight.controller.cluster.access.ABIVersion;
32 import org.opendaylight.controller.cluster.access.concepts.AbstractRequestFailureProxy;
33 import org.opendaylight.controller.cluster.access.concepts.AbstractRequestProxy;
34 import org.opendaylight.controller.cluster.access.concepts.Request;
35 import org.opendaylight.controller.cluster.access.concepts.RequestEnvelope;
36 import org.opendaylight.controller.cluster.access.concepts.RequestException;
37 import org.opendaylight.controller.cluster.access.concepts.RequestFailure;
38 import org.opendaylight.controller.cluster.access.concepts.Response;
39 import org.opendaylight.controller.cluster.common.actor.TestTicker;
40 import org.opendaylight.yangtools.concepts.WritableIdentifier;
41 import scala.concurrent.duration.Duration;
44 * Test suite covering logic contained in {@link SequencedQueueEntry}.
46 * @author Robert Varga
48 public class SequencedQueueEntryTest {
49 private static class MockFailure extends RequestFailure<WritableIdentifier, MockFailure> {
50 private static final long serialVersionUID = 1L;
52 MockFailure(final WritableIdentifier target, final RequestException cause) {
53 super(target, 0, cause);
57 protected AbstractRequestFailureProxy<WritableIdentifier, MockFailure> externalizableProxy(final ABIVersion version) {
62 protected MockFailure cloneAsVersion(final ABIVersion version) {
67 private static class MockRequest extends Request<WritableIdentifier, MockRequest> {
68 private static final long serialVersionUID = 1L;
70 MockRequest(final WritableIdentifier target, final ActorRef replyTo) {
71 super(target, 0, replyTo);
75 public RequestFailure<WritableIdentifier, ?> toRequestFailure(final RequestException cause) {
76 return new MockFailure(getTarget(), cause);
80 protected AbstractRequestProxy<WritableIdentifier, MockRequest> externalizableProxy(final ABIVersion version) {
85 protected MockRequest cloneAsVersion(final ABIVersion version) {
91 private ActorRef mockReplyTo;
93 private WritableIdentifier mockIdentifier;
95 private RequestException mockCause;
97 private RequestCallback mockCallback;
99 private ClientActorBehavior mockBehavior;
101 private TestTicker ticker;
102 private BackendInfo mockBackendInfo;
103 private Request<WritableIdentifier, ?> mockRequest;
104 private Response<WritableIdentifier, ?> mockResponse;
106 private static ActorSystem actorSystem;
107 private TestProbe mockActor;
109 private SequencedQueueEntry entry;
112 public static void setupClass() {
113 actorSystem = ActorSystem.apply();
117 public static void teardownClass() {
118 actorSystem.terminate();
122 public void setup() {
123 MockitoAnnotations.initMocks(this);
125 doReturn(mockBehavior).when(mockCallback).complete(any(MockFailure.class));
127 ticker = new TestTicker();
128 ticker.increment(ThreadLocalRandom.current().nextLong());
130 mockActor = TestProbe.apply(actorSystem);
131 mockBackendInfo = new BackendInfo(mockActor.ref(), 0, ABIVersion.current(), 5);
132 mockRequest = new MockRequest(mockIdentifier, mockReplyTo);
133 mockResponse = mockRequest.toRequestFailure(mockCause);
135 entry = new SequencedQueueEntry(mockRequest, mockCallback, ticker.read());
139 public void teardown() {
140 actorSystem.stop(mockActor.ref());
144 public void testGetTxDetails() {
145 assertNull(entry.getTxDetails());
146 entry.retransmit(mockBackendInfo, 0, ticker.read());
147 assertEquals(0, entry.getTxDetails().getTxSequence());
148 entry.retransmit(mockBackendInfo, 1, ticker.read());
149 assertEquals(1, entry.getTxDetails().getTxSequence());
150 entry.retransmit(mockBackendInfo, 3, ticker.read());
151 assertEquals(3, entry.getTxDetails().getTxSequence());
155 public void testComplete() {
156 entry.complete(mockResponse);
157 verify(mockCallback).complete(mockResponse);
161 public void testPoison() {
162 entry.poison(mockCause);
164 final ArgumentCaptor<MockFailure> captor = ArgumentCaptor.forClass(MockFailure.class);
165 verify(mockCallback).complete(captor.capture());
166 assertSame(mockCause, captor.getValue().getCause());
170 public void testIsTimedOut() {
171 assertTrue(entry.isTimedOut(ticker.read(), 0));
172 assertFalse(entry.isTimedOut(ticker.read(), 1));
174 entry.retransmit(mockBackendInfo, 0, ticker.read());
175 assertTrue(entry.isTimedOut(ticker.read(), 0));
176 ticker.increment(10);
177 assertTrue(entry.isTimedOut(ticker.read(), 10));
178 assertFalse(entry.isTimedOut(ticker.read(), 20));
180 entry.retransmit(mockBackendInfo, 1, ticker.read());
181 assertTrue(entry.isTimedOut(ticker.read(), 0));
182 ticker.increment(10);
183 assertTrue(entry.isTimedOut(ticker.read(), 10));
184 assertFalse(entry.isTimedOut(ticker.read(), 11));
188 public void testRetransmit() {
189 assertFalse(mockActor.msgAvailable());
190 entry.retransmit(mockBackendInfo, 0, ticker.read());
192 assertTrue(mockActor.msgAvailable());
193 assertRequestEquals(mockRequest, mockActor.receiveOne(Duration.apply(5, TimeUnit.SECONDS)));
196 private static void assertRequestEquals(final Request<?, ?> expected, final Object o) {
197 assertTrue(o instanceof RequestEnvelope);
199 final RequestEnvelope actual = (RequestEnvelope) o;
200 assertEquals(0, actual.getSessionId());
201 assertEquals(0, actual.getTxSequence());
202 assertEquals(expected.getTarget(), actual.getMessage().getTarget());