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;
19 import akka.actor.ActorRef;
20 import akka.actor.ActorSystem;
21 import akka.testkit.TestProbe;
22 import java.util.concurrent.ThreadLocalRandom;
23 import java.util.concurrent.TimeUnit;
24 import org.junit.After;
25 import org.junit.AfterClass;
26 import org.junit.Before;
27 import org.junit.BeforeClass;
28 import org.junit.Test;
29 import org.mockito.ArgumentCaptor;
30 import org.mockito.Mock;
31 import org.mockito.MockitoAnnotations;
32 import org.opendaylight.controller.cluster.access.ABIVersion;
33 import org.opendaylight.controller.cluster.access.concepts.AbstractRequestFailureProxy;
34 import org.opendaylight.controller.cluster.access.concepts.AbstractRequestProxy;
35 import org.opendaylight.controller.cluster.access.concepts.Request;
36 import org.opendaylight.controller.cluster.access.concepts.RequestEnvelope;
37 import org.opendaylight.controller.cluster.access.concepts.RequestException;
38 import org.opendaylight.controller.cluster.access.concepts.RequestFailure;
39 import org.opendaylight.controller.cluster.access.concepts.Response;
40 import org.opendaylight.controller.cluster.common.actor.TestTicker;
41 import org.opendaylight.yangtools.concepts.WritableIdentifier;
42 import scala.concurrent.duration.Duration;
45 * Test suite covering logic contained in {@link SequencedQueueEntry}.
47 * @author Robert Varga
49 public class SequencedQueueEntryTest {
50 private static class MockFailure extends RequestFailure<WritableIdentifier, MockFailure> {
51 private static final long serialVersionUID = 1L;
53 MockFailure(final WritableIdentifier target, final RequestException cause) {
54 super(target, 0, cause);
58 protected AbstractRequestFailureProxy<WritableIdentifier, MockFailure> externalizableProxy(
59 final ABIVersion version) {
64 protected MockFailure cloneAsVersion(final ABIVersion version) {
69 private static class MockRequest extends Request<WritableIdentifier, MockRequest> {
70 private static final long serialVersionUID = 1L;
72 MockRequest(final WritableIdentifier target, final ActorRef replyTo) {
73 super(target, 0, replyTo);
77 public RequestFailure<WritableIdentifier, ?> toRequestFailure(final RequestException cause) {
78 return new MockFailure(getTarget(), cause);
82 protected AbstractRequestProxy<WritableIdentifier, MockRequest> externalizableProxy(final ABIVersion version) {
87 protected MockRequest cloneAsVersion(final ABIVersion version) {
93 private ActorRef mockReplyTo;
95 private WritableIdentifier mockIdentifier;
97 private RequestException mockCause;
99 private RequestCallback mockCallback;
101 private ClientActorBehavior mockBehavior;
103 private TestTicker ticker;
104 private BackendInfo mockBackendInfo;
105 private Request<WritableIdentifier, ?> mockRequest;
106 private Response<WritableIdentifier, ?> mockResponse;
108 private static ActorSystem actorSystem;
109 private TestProbe mockActor;
111 private SequencedQueueEntry entry;
114 public static void setupClass() {
115 actorSystem = ActorSystem.apply();
119 public static void teardownClass() {
120 actorSystem.terminate();
124 public void setup() {
125 MockitoAnnotations.initMocks(this);
127 doReturn(mockBehavior).when(mockCallback).complete(any(MockFailure.class));
129 ticker = new TestTicker();
130 ticker.increment(ThreadLocalRandom.current().nextLong());
132 mockActor = TestProbe.apply(actorSystem);
133 mockBackendInfo = new BackendInfo(mockActor.ref(), 0, ABIVersion.current(), 5);
134 mockRequest = new MockRequest(mockIdentifier, mockReplyTo);
135 mockResponse = mockRequest.toRequestFailure(mockCause);
137 entry = new SequencedQueueEntry(mockRequest, mockCallback, ticker.read());
141 public void teardown() {
142 actorSystem.stop(mockActor.ref());
146 public void testGetTxDetails() {
147 assertNull(entry.getTxDetails());
148 entry.retransmit(mockBackendInfo, 0, ticker.read());
149 assertEquals(0, entry.getTxDetails().getTxSequence());
150 entry.retransmit(mockBackendInfo, 1, ticker.read());
151 assertEquals(1, entry.getTxDetails().getTxSequence());
152 entry.retransmit(mockBackendInfo, 3, ticker.read());
153 assertEquals(3, entry.getTxDetails().getTxSequence());
157 public void testComplete() {
158 entry.complete(mockResponse);
159 verify(mockCallback).complete(mockResponse);
163 public void testPoison() {
164 entry.poison(mockCause);
166 final ArgumentCaptor<MockFailure> captor = ArgumentCaptor.forClass(MockFailure.class);
167 verify(mockCallback).complete(captor.capture());
168 assertSame(mockCause, captor.getValue().getCause());
172 public void testIsTimedOut() {
173 assertTrue(entry.isTimedOut(ticker.read(), 0));
174 assertFalse(entry.isTimedOut(ticker.read(), 1));
176 entry.retransmit(mockBackendInfo, 0, ticker.read());
177 assertTrue(entry.isTimedOut(ticker.read(), 0));
178 ticker.increment(10);
179 assertTrue(entry.isTimedOut(ticker.read(), 10));
180 assertFalse(entry.isTimedOut(ticker.read(), 20));
182 entry.retransmit(mockBackendInfo, 1, ticker.read());
183 assertTrue(entry.isTimedOut(ticker.read(), 0));
184 ticker.increment(10);
185 assertTrue(entry.isTimedOut(ticker.read(), 10));
186 assertFalse(entry.isTimedOut(ticker.read(), 11));
190 public void testRetransmit() {
191 assertFalse(mockActor.msgAvailable());
192 entry.retransmit(mockBackendInfo, 0, ticker.read());
194 assertTrue(mockActor.msgAvailable());
195 assertRequestEquals(mockRequest, mockActor.receiveOne(Duration.apply(5, TimeUnit.SECONDS)));
198 private static void assertRequestEquals(final Request<?, ?> expected, final Object obj) {
199 assertTrue(obj instanceof RequestEnvelope);
201 final RequestEnvelope actual = (RequestEnvelope) obj;
202 assertEquals(0, actual.getSessionId());
203 assertEquals(0, actual.getTxSequence());
204 assertEquals(expected.getTarget(), actual.getMessage().getTarget());