2 * Copyright (c) 2017 Pantheon Technologies s.r.o. 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.databroker.actors.dds;
10 import static org.mockito.Matchers.any;
11 import static org.mockito.Mockito.mock;
12 import static org.mockito.Mockito.verify;
13 import static org.mockito.Mockito.when;
14 import static org.opendaylight.controller.cluster.databroker.actors.dds.TestUtils.CLIENT_ID;
15 import static org.opendaylight.controller.cluster.databroker.actors.dds.TestUtils.TRANSACTION_ID;
17 import akka.actor.ActorRef;
18 import akka.actor.ActorSelection;
19 import akka.actor.ActorSystem;
20 import com.google.common.primitives.UnsignedLong;
21 import java.util.Optional;
22 import org.junit.Assert;
23 import org.junit.Test;
24 import org.mockito.Mock;
25 import org.mockito.Mockito;
26 import org.opendaylight.controller.cluster.access.ABIVersion;
27 import org.opendaylight.controller.cluster.access.client.AccessClientUtil;
28 import org.opendaylight.controller.cluster.access.client.ClientActorContext;
29 import org.opendaylight.controller.cluster.access.client.ConnectedClientConnection;
30 import org.opendaylight.controller.cluster.access.concepts.LocalHistoryIdentifier;
31 import org.opendaylight.controller.cluster.datastore.messages.PrimaryShardInfo;
32 import org.opendaylight.controller.cluster.datastore.utils.ActorContext;
33 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
34 import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTree;
35 import scala.concurrent.Promise;
36 import scala.concurrent.impl.Promise.DefaultPromise;
38 public abstract class AbstractClientHistoryTest<T extends AbstractClientHistory> {
39 protected static final String SHARD_NAME = "default";
40 protected static final String PERSISTENCE_ID = "per-1";
41 protected static final LocalHistoryIdentifier HISTORY_ID = new LocalHistoryIdentifier(CLIENT_ID, 1L);
44 private DataTree tree;
46 protected abstract T object();
48 protected abstract ClientActorContext clientActorContext();
51 public abstract void testDoCreateSnapshot() throws Exception;
54 public abstract void testDoCreateTransaction() throws Exception;
57 public abstract void testCreateHistoryProxy() throws Exception;
60 public abstract void testOnTransactionComplete() throws Exception;
63 public abstract void testOnTransactionAbort() throws Exception;
66 public abstract void testOnTransactionReady() throws Exception;
69 public abstract void testOnTransactionReadyDuplicate() throws Exception;
72 public void testCreateSnapshotProxy() throws Exception {
73 final AbstractProxyTransaction snapshotProxy = object().createSnapshotProxy(TRANSACTION_ID, 0L);
74 Assert.assertNotNull(snapshotProxy);
75 Assert.assertNotEquals(TRANSACTION_ID, snapshotProxy.getIdentifier());
79 public void testCreateTransactionProxy() throws Exception {
80 AbstractProxyTransaction transactionProxy = object().createTransactionProxy(TRANSACTION_ID, 0L);
81 Assert.assertNotNull(transactionProxy);
82 Assert.assertNotEquals(TRANSACTION_ID, transactionProxy.getIdentifier());
86 public void testState() throws Exception {
87 Assert.assertEquals(AbstractClientHistory.State.IDLE, object().state());
91 public void testUpdateState() throws Exception {
92 object().updateState(AbstractClientHistory.State.IDLE, AbstractClientHistory.State.CLOSED);
93 Assert.assertEquals(AbstractClientHistory.State.CLOSED, object().state());
97 public void testDoClose() throws Exception {
98 object().createTransactionProxy(TRANSACTION_ID, 0L);
100 Assert.assertEquals(AbstractClientHistory.State.CLOSED, object().state());
104 public void testGetIdentifier() throws Exception {
105 Assert.assertEquals(HISTORY_ID, object().getIdentifier());
109 public void testNextTx() throws Exception {
110 Assert.assertTrue(object().nextTx() + 1 == object().nextTx());
114 public void testResolveShardForPath() throws Exception {
115 final Long shardForPath = object().resolveShardForPath(YangInstanceIdentifier.EMPTY);
116 Assert.assertEquals(0L, shardForPath.longValue());
120 public void testLocalAbort() throws Exception {
121 object().localAbort(new Throwable());
122 Assert.assertEquals(AbstractClientHistory.State.CLOSED, object().state());
126 public void testOnProxyDestroyed() throws Exception {
127 final ProxyHistory proxyHistory = Mockito.mock(ProxyHistory.class);
128 when(proxyHistory.getIdentifier()).thenReturn(HISTORY_ID);
130 object().onProxyDestroyed(proxyHistory);
131 verify(proxyHistory).getIdentifier();
135 public void testCreateTransaction() throws Exception {
136 final ClientTransaction transaction = object().createTransaction();
137 Assert.assertNotNull(transaction);
141 public void testTakeSnapshot() throws Exception {
142 final ClientSnapshot clientSnapshot = object().takeSnapshot();
143 Assert.assertEquals(object().getIdentifier(), clientSnapshot.getIdentifier().getHistoryId());
147 @SuppressWarnings("unchecked")
148 public void testStartReconnect() throws Exception {
149 // cookie and shard are the same
150 final Long cookie = 0L;
151 final Long shard = cookie;
153 final ShardBackendInfo info = new ShardBackendInfo(clientActorContext().self(), 0L, ABIVersion.current(),
154 SHARD_NAME, UnsignedLong.ZERO, Optional.of(tree), 10);
155 final ConnectedClientConnection newConn = AccessClientUtil.createConnectedConnection(
156 clientActorContext(), cookie, info);
157 object().createSnapshotProxy(TRANSACTION_ID, shard);
159 final HistoryReconnectCohort reconnectCohort = object().startReconnect(newConn);
160 Assert.assertNotNull(reconnectCohort);
164 @SuppressWarnings("unchecked")
165 public void testStartReconnectMissingOldProxy() throws Exception {
166 // cookie and shard are different
167 final Long cookie = 1L;
168 final Long shard = 0L;
170 final ShardBackendInfo info = new ShardBackendInfo(clientActorContext().self(), 0L, ABIVersion.current(),
171 SHARD_NAME, UnsignedLong.ZERO, Optional.of(tree), 10);
172 final ConnectedClientConnection newConn = AccessClientUtil.createConnectedConnection(
173 clientActorContext(), cookie, info);
174 object().createSnapshotProxy(TRANSACTION_ID, shard);
176 final HistoryReconnectCohort reconnectCohort = object().startReconnect(newConn);
177 Assert.assertNull(reconnectCohort);
180 protected static ActorContext createActorContextMock(final ActorSystem system, final ActorRef actor) {
181 final ActorContext mock = mock(ActorContext.class);
182 final Promise<PrimaryShardInfo> promise = new DefaultPromise<>();
183 final ActorSelection selection = system.actorSelection(actor.path());
184 final PrimaryShardInfo shardInfo = new PrimaryShardInfo(selection, (short) 0);
185 promise.success(shardInfo);
186 when(mock.findPrimaryShardAsync(any())).thenReturn(promise.future());