Fix intermittent unit test failures
[controller.git] / opendaylight / md-sal / sal-distributed-datastore / src / test / java / org / opendaylight / controller / cluster / datastore / LocalTransactionContextTest.java
1 /*
2  * Copyright (c) 2015 Cisco Systems, Inc. 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
9 package org.opendaylight.controller.cluster.datastore;
10
11 import static org.junit.Assert.assertTrue;
12 import static org.mockito.Mockito.doReturn;
13 import static org.mockito.Mockito.doThrow;
14 import static org.mockito.Mockito.mock;
15 import static org.mockito.Mockito.verify;
16 import akka.actor.ActorSelection;
17 import com.google.common.base.Optional;
18 import com.google.common.util.concurrent.Futures;
19 import com.google.common.util.concurrent.SettableFuture;
20 import org.junit.Before;
21 import org.junit.Test;
22 import org.mockito.Mock;
23 import org.mockito.MockitoAnnotations;
24 import org.opendaylight.controller.cluster.datastore.identifiers.TransactionIdentifier;
25 import org.opendaylight.controller.cluster.datastore.messages.DataExists;
26 import org.opendaylight.controller.cluster.datastore.messages.ReadData;
27 import org.opendaylight.controller.cluster.datastore.modification.DeleteModification;
28 import org.opendaylight.controller.cluster.datastore.modification.MergeModification;
29 import org.opendaylight.controller.cluster.datastore.modification.WriteModification;
30 import org.opendaylight.controller.sal.core.spi.data.DOMStoreReadTransaction;
31 import org.opendaylight.controller.sal.core.spi.data.DOMStoreReadWriteTransaction;
32 import org.opendaylight.controller.sal.core.spi.data.DOMStoreWriteTransaction;
33 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
34 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
35 import scala.concurrent.Future;
36
37 public class LocalTransactionContextTest {
38
39     @Mock
40     OperationLimiter limiter;
41
42     @Mock
43     TransactionIdentifier identifier;
44
45     @Mock
46     DOMStoreReadWriteTransaction readWriteTransaction;
47
48     @Mock
49     LocalTransactionReadySupport mockReadySupport;
50
51     LocalTransactionContext localTransactionContext;
52
53     @Before
54     public void setUp() {
55         MockitoAnnotations.initMocks(this);
56         localTransactionContext = new LocalTransactionContext(readWriteTransaction, limiter.getIdentifier(), mockReadySupport) {
57             @Override
58             protected DOMStoreWriteTransaction getWriteDelegate() {
59                 return readWriteTransaction;
60             }
61
62             @Override
63             protected DOMStoreReadTransaction getReadDelegate() {
64                 return readWriteTransaction;
65             }
66         };
67     }
68
69     @Test
70     public void testWrite() {
71         YangInstanceIdentifier yangInstanceIdentifier = YangInstanceIdentifier.builder().build();
72         NormalizedNode<?, ?> normalizedNode = mock(NormalizedNode.class);
73         localTransactionContext.executeModification(new WriteModification(yangInstanceIdentifier, normalizedNode));
74         verify(readWriteTransaction).write(yangInstanceIdentifier, normalizedNode);
75     }
76
77     @Test
78     public void testMerge() {
79         YangInstanceIdentifier yangInstanceIdentifier = YangInstanceIdentifier.builder().build();
80         NormalizedNode<?, ?> normalizedNode = mock(NormalizedNode.class);
81         localTransactionContext.executeModification(new MergeModification(yangInstanceIdentifier, normalizedNode));
82         verify(readWriteTransaction).merge(yangInstanceIdentifier, normalizedNode);
83     }
84
85     @Test
86     public void testDelete() {
87         YangInstanceIdentifier yangInstanceIdentifier = YangInstanceIdentifier.builder().build();
88         localTransactionContext.executeModification(new DeleteModification(yangInstanceIdentifier));
89         verify(readWriteTransaction).delete(yangInstanceIdentifier);
90     }
91
92
93     @Test
94     public void testRead() {
95         YangInstanceIdentifier yangInstanceIdentifier = YangInstanceIdentifier.builder().build();
96         NormalizedNode<?, ?> normalizedNode = mock(NormalizedNode.class);
97         doReturn(Futures.immediateCheckedFuture(Optional.of(normalizedNode))).when(readWriteTransaction).read(yangInstanceIdentifier);
98         localTransactionContext.executeRead(new ReadData(yangInstanceIdentifier, DataStoreVersions.CURRENT_VERSION),
99                 SettableFuture.<Optional<NormalizedNode<?,?>>>create());
100         verify(readWriteTransaction).read(yangInstanceIdentifier);
101     }
102
103     @Test
104     public void testExists() {
105         YangInstanceIdentifier yangInstanceIdentifier = YangInstanceIdentifier.builder().build();
106         doReturn(Futures.immediateCheckedFuture(true)).when(readWriteTransaction).exists(yangInstanceIdentifier);
107         localTransactionContext.executeRead(new DataExists(yangInstanceIdentifier, DataStoreVersions.CURRENT_VERSION),
108                 SettableFuture.<Boolean>create());
109         verify(readWriteTransaction).exists(yangInstanceIdentifier);
110     }
111
112     @Test
113     public void testReady() {
114         final LocalThreePhaseCommitCohort mockCohort = mock(LocalThreePhaseCommitCohort.class);
115         doReturn(akka.dispatch.Futures.successful(null)).when(mockCohort).initiateCoordinatedCommit();
116         doReturn(mockCohort).when(mockReadySupport).onTransactionReady(readWriteTransaction, null);
117
118         Future<ActorSelection> future = localTransactionContext.readyTransaction();
119         assertTrue(future.isCompleted());
120
121         verify(mockReadySupport).onTransactionReady(readWriteTransaction, null);
122     }
123
124     @Test
125     public void testReadyWithWriteError() {
126         YangInstanceIdentifier yangInstanceIdentifier = YangInstanceIdentifier.builder().build();
127         NormalizedNode<?, ?> normalizedNode = mock(NormalizedNode.class);
128         RuntimeException error = new RuntimeException("mock");
129         doThrow(error).when(readWriteTransaction).write(yangInstanceIdentifier, normalizedNode);
130
131         localTransactionContext.executeModification(new WriteModification(yangInstanceIdentifier, normalizedNode));
132         localTransactionContext.executeModification(new WriteModification(yangInstanceIdentifier, normalizedNode));
133
134         verify(readWriteTransaction).write(yangInstanceIdentifier, normalizedNode);
135
136         doReadyWithExpectedError(error);
137     }
138
139     @Test
140     public void testReadyWithMergeError() {
141         YangInstanceIdentifier yangInstanceIdentifier = YangInstanceIdentifier.builder().build();
142         NormalizedNode<?, ?> normalizedNode = mock(NormalizedNode.class);
143         RuntimeException error = new RuntimeException("mock");
144         doThrow(error).when(readWriteTransaction).merge(yangInstanceIdentifier, normalizedNode);
145
146         localTransactionContext.executeModification(new MergeModification(yangInstanceIdentifier, normalizedNode));
147         localTransactionContext.executeModification(new MergeModification(yangInstanceIdentifier, normalizedNode));
148
149         verify(readWriteTransaction).merge(yangInstanceIdentifier, normalizedNode);
150
151         doReadyWithExpectedError(error);
152     }
153
154     @Test
155     public void testReadyWithDeleteError() {
156         YangInstanceIdentifier yangInstanceIdentifier = YangInstanceIdentifier.builder().build();
157         RuntimeException error = new RuntimeException("mock");
158         doThrow(error).when(readWriteTransaction).delete(yangInstanceIdentifier);
159
160         localTransactionContext.executeModification(new DeleteModification(yangInstanceIdentifier));
161         localTransactionContext.executeModification(new DeleteModification(yangInstanceIdentifier));
162
163         verify(readWriteTransaction).delete(yangInstanceIdentifier);
164
165         doReadyWithExpectedError(error);
166     }
167
168     private void doReadyWithExpectedError(RuntimeException expError) {
169         LocalThreePhaseCommitCohort mockCohort = mock(LocalThreePhaseCommitCohort.class);
170         doReturn(akka.dispatch.Futures.successful(null)).when(mockCohort).initiateCoordinatedCommit();
171         doReturn(mockCohort).when(mockReadySupport).onTransactionReady(readWriteTransaction, expError);
172
173         localTransactionContext.readyTransaction();
174     }
175 }