Fix followerDistributedDataStore tear down
[controller.git] / opendaylight / md-sal / sal-distributed-datastore / src / test / java / org / opendaylight / controller / cluster / datastore / SimpleShardDataTreeCohortTest.java
1 /*
2  * Copyright (c) 2015 Brocade Communications 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 package org.opendaylight.controller.cluster.datastore;
9
10 import static org.junit.Assert.assertSame;
11 import static org.mockito.ArgumentMatchers.any;
12 import static org.mockito.Mockito.doAnswer;
13 import static org.mockito.Mockito.doReturn;
14 import static org.mockito.Mockito.mock;
15 import static org.mockito.Mockito.never;
16 import static org.mockito.Mockito.verify;
17 import static org.mockito.Mockito.verifyNoMoreInteractions;
18
19 import com.google.common.primitives.UnsignedLong;
20 import com.google.common.util.concurrent.FutureCallback;
21 import java.util.Optional;
22 import java.util.concurrent.CompletableFuture;
23 import java.util.concurrent.Future;
24 import org.junit.Before;
25 import org.junit.Test;
26 import org.mockito.Mock;
27 import org.mockito.MockitoAnnotations;
28 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
29 import org.opendaylight.yangtools.yang.data.api.schema.tree.ConflictingModificationAppliedException;
30 import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeCandidate;
31 import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeCandidateTip;
32 import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeModification;
33 import org.opendaylight.yangtools.yang.data.api.schema.tree.DataValidationFailedException;
34
35 /**
36  * Unit tests for SimpleShardDataTreeCohort.
37  *
38  * @author Thomas Pantelis
39  */
40 public class SimpleShardDataTreeCohortTest extends AbstractTest {
41     @Mock
42     private ShardDataTree mockShardDataTree;
43
44     @Mock
45     private DataTreeModification mockModification;
46
47     @Mock
48     private CompositeDataTreeCohort mockUserCohorts;
49
50     @Mock
51     private FutureCallback<DataTreeCandidate> mockPreCallback;
52
53     private SimpleShardDataTreeCohort cohort;
54
55     @Before
56     public void setup() {
57         MockitoAnnotations.initMocks(this);
58
59         doReturn(Optional.empty()).when(mockUserCohorts).commit();
60         doReturn(Optional.empty()).when(mockUserCohorts).abort();
61
62         cohort = new SimpleShardDataTreeCohort(mockShardDataTree, mockModification, nextTransactionId(),
63             mockUserCohorts, Optional.empty());
64     }
65
66     @Test
67     public void testCanCommitSuccess() {
68         canCommitSuccess();
69     }
70
71     private void canCommitSuccess() {
72         doAnswer(invocation -> {
73             invocation.<SimpleShardDataTreeCohort>getArgument(0).successfulCanCommit();
74             return null;
75         }).when(mockShardDataTree).startCanCommit(cohort);
76
77         @SuppressWarnings("unchecked")
78         final FutureCallback<Void> callback = mock(FutureCallback.class);
79         cohort.canCommit(callback);
80
81         verify(callback).onSuccess(null);
82         verifyNoMoreInteractions(callback);
83     }
84
85     private void testValidatationPropagates(final Exception cause) {
86         doAnswer(invocation -> {
87             invocation.<SimpleShardDataTreeCohort>getArgument(0).failedCanCommit(cause);
88             return null;
89         }).when(mockShardDataTree).startCanCommit(cohort);
90
91         @SuppressWarnings("unchecked")
92         final FutureCallback<Void> callback = mock(FutureCallback.class);
93         cohort.canCommit(callback);
94
95         verify(callback).onFailure(cause);
96         verifyNoMoreInteractions(callback);
97     }
98
99     @Test
100     public void testCanCommitWithConflictingModEx() {
101         testValidatationPropagates(new ConflictingModificationAppliedException(YangInstanceIdentifier.empty(), "mock"));
102     }
103
104     @Test
105     public void testCanCommitWithDataValidationEx() {
106         testValidatationPropagates(new DataValidationFailedException(YangInstanceIdentifier.empty(), "mock"));
107     }
108
109     @Test
110     public void testCanCommitWithIllegalArgumentEx() {
111         testValidatationPropagates(new IllegalArgumentException("mock"));
112     }
113
114     private DataTreeCandidateTip preCommitSuccess() {
115         final DataTreeCandidateTip mockCandidate = mock(DataTreeCandidateTip.class);
116         doAnswer(invocation -> {
117             invocation.<SimpleShardDataTreeCohort>getArgument(0).successfulPreCommit(mockCandidate);
118             return null;
119         }).when(mockShardDataTree).startPreCommit(cohort);
120
121         @SuppressWarnings("unchecked")
122         final FutureCallback<DataTreeCandidate> callback = mock(FutureCallback.class);
123         cohort.preCommit(callback);
124
125         verify(callback).onSuccess(mockCandidate);
126         verifyNoMoreInteractions(callback);
127
128         assertSame("getCandidate", mockCandidate, cohort.getCandidate());
129
130         return mockCandidate;
131     }
132
133     @Test
134     public void testPreCommitAndCommitSuccess() {
135         canCommitSuccess();
136         final DataTreeCandidateTip candidate = preCommitSuccess();
137
138         doAnswer(invocation -> {
139             invocation.<SimpleShardDataTreeCohort>getArgument(0).successfulCommit(UnsignedLong.valueOf(0), () -> { });
140             return null;
141         }).when(mockShardDataTree).startCommit(cohort, candidate);
142
143         @SuppressWarnings("unchecked")
144         final FutureCallback<UnsignedLong> mockCommitCallback = mock(FutureCallback.class);
145         cohort.commit(mockCommitCallback);
146
147         verify(mockCommitCallback).onSuccess(any(UnsignedLong.class));
148         verifyNoMoreInteractions(mockCommitCallback);
149
150         verify(mockUserCohorts).commit();
151     }
152
153     @Test
154     public void testPreCommitWithIllegalArgumentEx() {
155         canCommitSuccess();
156
157         final Exception cause = new IllegalArgumentException("mock");
158         doAnswer(invocation -> {
159             invocation.<SimpleShardDataTreeCohort>getArgument(0).failedPreCommit(cause);
160             return null;
161         }).when(mockShardDataTree).startPreCommit(cohort);
162
163         @SuppressWarnings("unchecked")
164         final FutureCallback<DataTreeCandidate> callback = mock(FutureCallback.class);
165         cohort.preCommit(callback);
166
167         verify(callback).onFailure(cause);
168         verifyNoMoreInteractions(callback);
169
170         verify(mockUserCohorts).abort();
171     }
172
173     @Test
174     public void testPreCommitWithReportedFailure() {
175         canCommitSuccess();
176
177         final Exception cause = new IllegalArgumentException("mock");
178         cohort.reportFailure(cause);
179
180         @SuppressWarnings("unchecked")
181         final FutureCallback<DataTreeCandidate> callback = mock(FutureCallback.class);
182         cohort.preCommit(callback);
183
184         verify(callback).onFailure(cause);
185         verifyNoMoreInteractions(callback);
186
187         verify(mockShardDataTree, never()).startPreCommit(cohort);
188     }
189
190     @Test
191     public void testCommitWithIllegalArgumentEx() {
192         canCommitSuccess();
193         final DataTreeCandidateTip candidate = preCommitSuccess();
194
195         final Exception cause = new IllegalArgumentException("mock");
196         doAnswer(invocation -> {
197             invocation.<SimpleShardDataTreeCohort>getArgument(0).failedCommit(cause);
198             return null;
199         }).when(mockShardDataTree).startCommit(cohort, candidate);
200
201         @SuppressWarnings("unchecked")
202         final FutureCallback<UnsignedLong> callback = mock(FutureCallback.class);
203         cohort.commit(callback);
204
205         verify(callback).onFailure(cause);
206         verifyNoMoreInteractions(callback);
207
208         verify(mockUserCohorts).abort();
209     }
210
211     private static Future<?> abort(final ShardDataTreeCohort cohort) {
212         final CompletableFuture<Void> f = new CompletableFuture<>();
213         cohort.abort(new FutureCallback<Void>() {
214             @Override
215             public void onSuccess(final Void result) {
216                 f.complete(null);
217             }
218
219             @Override
220             public void onFailure(final Throwable failure) {
221                 f.completeExceptionally(failure);
222             }
223         });
224
225         return f;
226     }
227
228     @Test
229     public void testAbort() throws Exception {
230         doReturn(Boolean.TRUE).when(mockShardDataTree).startAbort(cohort);
231
232         abort(cohort).get();
233         verify(mockShardDataTree).startAbort(cohort);
234     }
235
236     @Test
237     public void testAbortWithCohorts() throws Exception {
238         doReturn(true).when(mockShardDataTree).startAbort(cohort);
239
240         doReturn(Optional.of(CompletableFuture.completedFuture(null))).when(mockUserCohorts).abort();
241
242         final Future<?> abortFuture = abort(cohort);
243
244         abortFuture.get();
245         verify(mockShardDataTree).startAbort(cohort);
246     }
247 }