Fix followerDistributedDataStore tear down
[controller.git] / opendaylight / md-sal / sal-distributed-datastore / src / test / java / org / opendaylight / controller / cluster / databroker / actors / dds / AbstractClientHistoryTest.java
1 /*
2  * Copyright (c) 2017 Pantheon Technologies s.r.o. and others.  All rights reserved.
3  *
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
7  */
8 package org.opendaylight.controller.cluster.databroker.actors.dds;
9
10 import static org.junit.Assert.assertEquals;
11 import static org.junit.Assert.assertNotEquals;
12 import static org.junit.Assert.assertNotNull;
13 import static org.junit.Assert.assertNull;
14 import static org.mockito.ArgumentMatchers.any;
15 import static org.mockito.Mockito.doReturn;
16 import static org.mockito.Mockito.mock;
17 import static org.mockito.Mockito.verify;
18
19 import akka.actor.ActorRef;
20 import akka.actor.ActorSelection;
21 import akka.actor.ActorSystem;
22 import com.google.common.primitives.UnsignedLong;
23 import java.util.Optional;
24 import org.junit.Test;
25 import org.mockito.Mock;
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.DatastoreContext;
32 import org.opendaylight.controller.cluster.datastore.messages.PrimaryShardInfo;
33 import org.opendaylight.controller.cluster.datastore.utils.ActorUtils;
34 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
35 import org.opendaylight.yangtools.yang.data.tree.api.DataTree;
36 import scala.concurrent.Promise;
37 import scala.concurrent.impl.Promise.DefaultPromise;
38
39 public abstract class AbstractClientHistoryTest<T extends AbstractClientHistory> {
40     protected static final String SHARD_NAME = "default";
41     protected static final String PERSISTENCE_ID = "per-1";
42     protected static final LocalHistoryIdentifier HISTORY_ID = new LocalHistoryIdentifier(TestUtils.CLIENT_ID, 1L);
43
44     @Mock
45     private DataTree tree;
46     @Mock
47     private DatastoreContext datastoreContext;
48
49     protected abstract T object();
50
51     protected abstract ClientActorContext clientActorContext();
52
53     @Test
54     public abstract void testDoCreateSnapshot();
55
56     @Test
57     public abstract void testDoCreateTransaction();
58
59     @Test
60     public abstract void testCreateHistoryProxy();
61
62     @Test
63     public abstract void testOnTransactionComplete();
64
65     @Test
66     public abstract void testOnTransactionAbort();
67
68     @Test
69     public abstract void testOnTransactionReady();
70
71     @Test
72     public abstract void testOnTransactionReadyDuplicate();
73
74     @Test
75     public void testCreateSnapshotProxy() {
76         final AbstractProxyTransaction snapshotProxy = object().createSnapshotProxy(TestUtils.TRANSACTION_ID, 0L);
77         assertNotNull(snapshotProxy);
78         assertNotEquals(TestUtils.TRANSACTION_ID, snapshotProxy.getIdentifier());
79     }
80
81     @Test
82     public void testCreateTransactionProxy() {
83         AbstractProxyTransaction transactionProxy = object().createTransactionProxy(TestUtils.TRANSACTION_ID, 0L);
84         assertNotNull(transactionProxy);
85         assertNotEquals(TestUtils.TRANSACTION_ID, transactionProxy.getIdentifier());
86     }
87
88     @Test
89     public void testState() {
90         assertEquals(AbstractClientHistory.State.IDLE, object().state());
91     }
92
93     @Test
94     public void testUpdateState() {
95         object().updateState(AbstractClientHistory.State.IDLE, AbstractClientHistory.State.CLOSED);
96         assertEquals(AbstractClientHistory.State.CLOSED, object().state());
97     }
98
99     @Test
100     public void testDoClose() {
101         object().createTransactionProxy(TestUtils.TRANSACTION_ID, 0L);
102         object().doClose();
103         assertEquals(AbstractClientHistory.State.CLOSED, object().state());
104     }
105
106     @Test
107     public void testGetIdentifier() {
108         assertEquals(HISTORY_ID, object().getIdentifier());
109     }
110
111     @Test
112     public void testNextTx() {
113         assertEquals(object().nextTx() + 1, object().nextTx());
114     }
115
116     @Test
117     public void testResolveShardForPath() {
118         final Long shardForPath = object().resolveShardForPath(YangInstanceIdentifier.of());
119         assertNotNull(shardForPath);
120         assertEquals(0L, (long) shardForPath);
121     }
122
123     @Test
124     public void testLocalAbort() {
125         object().localAbort(new Throwable());
126         assertEquals(AbstractClientHistory.State.CLOSED, object().state());
127     }
128
129     @Test
130     public void testOnProxyDestroyed() {
131         final ProxyHistory proxyHistory = mock(ProxyHistory.class);
132         doReturn(HISTORY_ID).when(proxyHistory).getIdentifier();
133
134         object().onProxyDestroyed(proxyHistory);
135         verify(proxyHistory).getIdentifier();
136     }
137
138     @Test
139     public void testCreateTransaction() {
140         final ClientTransaction transaction = object().createTransaction();
141         assertNotNull(transaction);
142     }
143
144     @Test
145     public void testTakeSnapshot() {
146         final ClientSnapshot clientSnapshot = object().takeSnapshot();
147         assertEquals(object().getIdentifier(), clientSnapshot.getIdentifier().getHistoryId());
148     }
149
150     @Test
151     public void testStartReconnect() {
152         // cookie and shard are the same
153         final Long cookie = 0L;
154         final Long shard = cookie;
155
156         final ShardBackendInfo info = new ShardBackendInfo(clientActorContext().self(), 0L, ABIVersion.current(),
157                 SHARD_NAME, UnsignedLong.ZERO, Optional.of(tree), 10);
158         final ConnectedClientConnection<ShardBackendInfo> newConn = AccessClientUtil.createConnectedConnection(
159                 clientActorContext(), cookie, info);
160         object().createSnapshotProxy(TestUtils.TRANSACTION_ID, shard);
161
162         final HistoryReconnectCohort reconnectCohort = object().startReconnect(newConn);
163         assertNotNull(reconnectCohort);
164     }
165
166     @Test
167     public void testStartReconnectMissingOldProxy() {
168         // cookie and shard are different
169         final Long cookie = 1L;
170         final Long shard = 0L;
171
172         final ShardBackendInfo info = new ShardBackendInfo(clientActorContext().self(), 0L, ABIVersion.current(),
173                 SHARD_NAME, UnsignedLong.ZERO, Optional.of(tree), 10);
174         final ConnectedClientConnection<ShardBackendInfo> newConn = AccessClientUtil.createConnectedConnection(
175                 clientActorContext(), cookie, info);
176         object().createSnapshotProxy(TestUtils.TRANSACTION_ID, shard);
177
178         final HistoryReconnectCohort reconnectCohort = object().startReconnect(newConn);
179         assertNull(reconnectCohort);
180     }
181
182     protected final ActorUtils createActorUtilsMock(final ActorSystem system, final ActorRef actor) {
183         final ActorUtils mock = mock(ActorUtils.class);
184         final Promise<PrimaryShardInfo> promise = new DefaultPromise<>();
185         final ActorSelection selection = system.actorSelection(actor.path());
186         final PrimaryShardInfo shardInfo = new PrimaryShardInfo(selection, (short) 0);
187         promise.success(shardInfo);
188         doReturn(promise.future()).when(mock).findPrimaryShardAsync(any());
189         doReturn(1000).when(datastoreContext).getShardBatchedModificationCount();
190         doReturn(datastoreContext).when(mock).getDatastoreContext();
191
192         return mock;
193     }
194 }