atomic-storage: remove type dependency at segment level I/O
[controller.git] / opendaylight / md-sal / sal-distributed-datastore / src / test / java / org / opendaylight / controller / cluster / databroker / ClientBackedDataStoreTest.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;
9
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;
15
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;
40
41 @RunWith(MockitoJUnitRunner.StrictStubs.class)
42 public class ClientBackedDataStoreTest {
43
44     private static final ClientIdentifier UNKNOWN_ID = ClientIdentifier.create(
45             FrontendIdentifier.create(MemberName.forName("local"), FrontendType.forName("unknown")), 0);
46
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);
50
51     private static final TransactionIdentifier TRANSACTION_IDENTIFIER =
52         new TransactionIdentifier(new LocalHistoryIdentifier(CLIENT_IDENTIFIER, 0), 0);
53
54     @Mock
55     private DataStoreClient clientActor;
56     @Mock
57     private DatastoreContext datastoreContext;
58     @Mock
59     private Timeout shardElectionTimeout;
60     @Mock
61     private ActorUtils actorUtils;
62     @Mock
63     private ClientLocalHistory clientLocalHistory;
64     @Mock
65     private ClientTransaction clientTransaction;
66     @Mock
67     private ClientSnapshot clientSnapshot;
68
69
70     @Before
71     public void setUp() {
72         doReturn(DatastoreContext.newBuilder().build()).when(actorUtils).getDatastoreContext();
73         doReturn(TRANSACTION_IDENTIFIER).when(clientTransaction).getIdentifier();
74         doReturn(TRANSACTION_IDENTIFIER).when(clientSnapshot).getIdentifier();
75
76         doReturn(clientTransaction).when(clientActor).createTransaction();
77         doReturn(clientLocalHistory).when(clientActor).createLocalHistory();
78         doReturn(clientSnapshot).when(clientActor).createSnapshot();
79     }
80
81     @Test
82     public void testCreateTransactionChain() {
83         try (var clientBackedDataStore = new ClientBackedDataStore(actorUtils, UNKNOWN_ID, clientActor)) {
84             assertNotNull(clientBackedDataStore.createTransactionChain());
85             verify(clientActor, times(1)).createLocalHistory();
86         }
87     }
88
89     @Test
90     public void testNewReadOnlyTransaction() {
91         try (var clientBackedDataStore = new ClientBackedDataStore(actorUtils, UNKNOWN_ID, clientActor)) {
92             assertNotNull(clientBackedDataStore.newReadOnlyTransaction());
93             verify(clientActor, times(1)).createSnapshot();
94         }
95     }
96
97     @Test
98     public void testNewWriteOnlyTransaction() {
99         try (var clientBackedDataStore = new ClientBackedDataStore(actorUtils, UNKNOWN_ID, clientActor)) {
100             assertNotNull(clientBackedDataStore.newWriteOnlyTransaction());
101             verify(clientActor, times(1)).createTransaction();
102         }
103     }
104
105     @Test
106     public void testNewReadWriteTransaction() {
107         try (var clientBackedDataStore = new ClientBackedDataStore(actorUtils, UNKNOWN_ID, clientActor)) {
108             assertNotNull(clientBackedDataStore.newReadWriteTransaction());
109             verify(clientActor, times(1)).createTransaction();
110         }
111     }
112
113     @Test
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);
123
124             assertTrue("Expected to be blocked for 50 millis", elapsedMillis >= 50);
125         }
126     }
127
128     @Test
129     public void testWaitTillReadyCountDown() {
130         try (var clientBackedDataStore = new ClientBackedDataStore(actorUtils, UNKNOWN_ID, clientActor)) {
131             doReturn(datastoreContext).when(actorUtils).getDatastoreContext();
132
133             ForkJoinPool.commonPool().submit(() -> {
134                 Uninterruptibles.sleepUninterruptibly(500, TimeUnit.MILLISECONDS);
135                 clientBackedDataStore.readinessFuture().set(Empty.value());
136             });
137
138             final var sw = Stopwatch.createStarted();
139             clientBackedDataStore.waitTillReady();
140             final var elapsedMillis = sw.stop().elapsed(TimeUnit.MILLISECONDS);
141
142             assertTrue("Expected to be released in 500 millis", elapsedMillis < 5000);
143         }
144     }
145 }