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