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;
10 import static org.junit.Assert.assertNotNull;
11 import static org.junit.Assert.assertTrue;
12 import static org.mockito.Mockito.doReturn;
13 import static org.mockito.Mockito.times;
14 import static org.mockito.Mockito.verify;
16 import akka.util.Timeout;
17 import com.google.common.base.Stopwatch;
18 import com.google.common.util.concurrent.Uninterruptibles;
19 import java.util.concurrent.ForkJoinPool;
20 import java.util.concurrent.TimeUnit;
21 import org.junit.Before;
22 import org.junit.Test;
23 import org.junit.runner.RunWith;
24 import org.mockito.Mock;
25 import org.mockito.junit.MockitoJUnitRunner;
26 import org.opendaylight.controller.cluster.access.concepts.ClientIdentifier;
27 import org.opendaylight.controller.cluster.access.concepts.FrontendIdentifier;
28 import org.opendaylight.controller.cluster.access.concepts.FrontendType;
29 import org.opendaylight.controller.cluster.access.concepts.LocalHistoryIdentifier;
30 import org.opendaylight.controller.cluster.access.concepts.MemberName;
31 import org.opendaylight.controller.cluster.access.concepts.TransactionIdentifier;
32 import org.opendaylight.controller.cluster.databroker.actors.dds.ClientLocalHistory;
33 import org.opendaylight.controller.cluster.databroker.actors.dds.ClientSnapshot;
34 import org.opendaylight.controller.cluster.databroker.actors.dds.ClientTransaction;
35 import org.opendaylight.controller.cluster.databroker.actors.dds.DataStoreClient;
36 import org.opendaylight.controller.cluster.datastore.DatastoreContext;
37 import org.opendaylight.controller.cluster.datastore.utils.ActorUtils;
38 import org.opendaylight.yangtools.yang.common.Empty;
39 import scala.concurrent.duration.FiniteDuration;
41 @RunWith(MockitoJUnitRunner.StrictStubs.class)
42 public class ClientBackedDataStoreTest {
44 private static final ClientIdentifier UNKNOWN_ID = ClientIdentifier.create(
45 FrontendIdentifier.create(MemberName.forName("local"), FrontendType.forName("unknown")), 0);
47 private static final FrontendIdentifier FRONTEND_IDENTIFIER = FrontendIdentifier.create(
48 MemberName.forName("member"), FrontendType.forName("frontend"));
49 private static final ClientIdentifier CLIENT_IDENTIFIER = ClientIdentifier.create(FRONTEND_IDENTIFIER, 0);
51 private static final TransactionIdentifier TRANSACTION_IDENTIFIER =
52 new TransactionIdentifier(new LocalHistoryIdentifier(CLIENT_IDENTIFIER, 0), 0);
55 private DataStoreClient clientActor;
57 private DatastoreContext datastoreContext;
59 private Timeout shardElectionTimeout;
61 private ActorUtils actorUtils;
63 private ClientLocalHistory clientLocalHistory;
65 private ClientTransaction clientTransaction;
67 private ClientSnapshot clientSnapshot;
72 doReturn(DatastoreContext.newBuilder().build()).when(actorUtils).getDatastoreContext();
73 doReturn(TRANSACTION_IDENTIFIER).when(clientTransaction).getIdentifier();
74 doReturn(TRANSACTION_IDENTIFIER).when(clientSnapshot).getIdentifier();
76 doReturn(clientTransaction).when(clientActor).createTransaction();
77 doReturn(clientLocalHistory).when(clientActor).createLocalHistory();
78 doReturn(clientSnapshot).when(clientActor).createSnapshot();
82 public void testCreateTransactionChain() {
83 try (var clientBackedDataStore = new ClientBackedDataStore(actorUtils, UNKNOWN_ID, clientActor)) {
84 assertNotNull(clientBackedDataStore.createTransactionChain());
85 verify(clientActor, times(1)).createLocalHistory();
90 public void testNewReadOnlyTransaction() {
91 try (var clientBackedDataStore = new ClientBackedDataStore(actorUtils, UNKNOWN_ID, clientActor)) {
92 assertNotNull(clientBackedDataStore.newReadOnlyTransaction());
93 verify(clientActor, times(1)).createSnapshot();
98 public void testNewWriteOnlyTransaction() {
99 try (var clientBackedDataStore = new ClientBackedDataStore(actorUtils, UNKNOWN_ID, clientActor)) {
100 assertNotNull(clientBackedDataStore.newWriteOnlyTransaction());
101 verify(clientActor, times(1)).createTransaction();
106 public void testNewReadWriteTransaction() {
107 try (var clientBackedDataStore = new ClientBackedDataStore(actorUtils, UNKNOWN_ID, clientActor)) {
108 assertNotNull(clientBackedDataStore.newReadWriteTransaction());
109 verify(clientActor, times(1)).createTransaction();
114 public void testWaitTillReadyBlocking() {
115 doReturn(datastoreContext).when(actorUtils).getDatastoreContext();
116 doReturn(shardElectionTimeout).when(datastoreContext).getShardLeaderElectionTimeout();
117 doReturn(1).when(datastoreContext).getInitialSettleTimeoutMultiplier();
118 doReturn(FiniteDuration.apply(50, TimeUnit.MILLISECONDS)).when(shardElectionTimeout).duration();
119 try (var clientBackedDataStore = new ClientBackedDataStore(actorUtils, UNKNOWN_ID, clientActor)) {
120 final var sw = Stopwatch.createStarted();
121 clientBackedDataStore.waitTillReady();
122 final var elapsedMillis = sw.stop().elapsed(TimeUnit.MILLISECONDS);
124 assertTrue("Expected to be blocked for 50 millis", elapsedMillis >= 50);
129 public void testWaitTillReadyCountDown() {
130 try (var clientBackedDataStore = new ClientBackedDataStore(actorUtils, UNKNOWN_ID, clientActor)) {
131 doReturn(datastoreContext).when(actorUtils).getDatastoreContext();
133 ForkJoinPool.commonPool().submit(() -> {
134 Uninterruptibles.sleepUninterruptibly(500, TimeUnit.MILLISECONDS);
135 clientBackedDataStore.readinessFuture().set(Empty.value());
138 final var sw = Stopwatch.createStarted();
139 clientBackedDataStore.waitTillReady();
140 final var elapsedMillis = sw.stop().elapsed(TimeUnit.MILLISECONDS);
142 assertTrue("Expected to be released in 500 millis", elapsedMillis < 5000);