2 * Copyright (c) 2015 Brocade Communications Systems, Inc. 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.datastore;
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;
20 import com.google.common.primitives.UnsignedLong;
21 import com.google.common.util.concurrent.FutureCallback;
22 import java.util.Collections;
23 import java.util.Optional;
24 import java.util.concurrent.CompletableFuture;
25 import java.util.concurrent.Future;
26 import org.junit.Before;
27 import org.junit.Test;
28 import org.mockito.Mock;
29 import org.mockito.MockitoAnnotations;
30 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
31 import org.opendaylight.yangtools.yang.data.api.schema.tree.ConflictingModificationAppliedException;
32 import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeCandidate;
33 import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeCandidateTip;
34 import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeModification;
35 import org.opendaylight.yangtools.yang.data.api.schema.tree.DataValidationFailedException;
36 import scala.concurrent.Promise;
39 * Unit tests for SimpleShardDataTreeCohort.
41 * @author Thomas Pantelis
43 public class SimpleShardDataTreeCohortTest extends AbstractTest {
45 private ShardDataTree mockShardDataTree;
48 private DataTreeModification mockModification;
51 private CompositeDataTreeCohort mockUserCohorts;
54 private FutureCallback<DataTreeCandidate> mockPreCallback;
56 private SimpleShardDataTreeCohort cohort;
59 public void setup() throws Exception {
60 MockitoAnnotations.initMocks(this);
62 doNothing().when(mockUserCohorts).commit();
63 doReturn(Optional.empty()).when(mockUserCohorts).abort();
65 cohort = new SimpleShardDataTreeCohort.Normal(mockShardDataTree, mockModification, nextTransactionId(),
70 public void testCanCommitSuccess() throws Exception {
74 private void canCommitSuccess() {
75 doAnswer(invocation -> {
76 invocation.getArgumentAt(0, SimpleShardDataTreeCohort.class).successfulCanCommit();
78 }).when(mockShardDataTree).startCanCommit(cohort);
80 @SuppressWarnings("unchecked")
81 final FutureCallback<Void> callback = mock(FutureCallback.class);
82 cohort.canCommit(callback);
84 verify(callback).onSuccess(null);
85 verifyNoMoreInteractions(callback);
88 private void testValidatationPropagates(final Exception cause) throws DataValidationFailedException {
89 doAnswer(invocation -> {
90 invocation.getArgumentAt(0, SimpleShardDataTreeCohort.class).failedCanCommit(cause);
92 }).when(mockShardDataTree).startCanCommit(cohort);
94 @SuppressWarnings("unchecked")
95 final FutureCallback<Void> callback = mock(FutureCallback.class);
96 cohort.canCommit(callback);
98 verify(callback).onFailure(cause);
99 verifyNoMoreInteractions(callback);
103 public void testCanCommitWithConflictingModEx() throws DataValidationFailedException {
104 testValidatationPropagates(new ConflictingModificationAppliedException(YangInstanceIdentifier.EMPTY, "mock"));
108 public void testCanCommitWithDataValidationEx() throws DataValidationFailedException {
109 testValidatationPropagates(new DataValidationFailedException(YangInstanceIdentifier.EMPTY, "mock"));
113 public void testCanCommitWithIllegalArgumentEx() throws DataValidationFailedException {
114 testValidatationPropagates(new IllegalArgumentException("mock"));
117 private DataTreeCandidateTip preCommitSuccess() {
118 final DataTreeCandidateTip mockCandidate = mock(DataTreeCandidateTip.class);
119 doAnswer(invocation -> {
120 invocation.getArgumentAt(0, SimpleShardDataTreeCohort.class).successfulPreCommit(mockCandidate);
122 }).when(mockShardDataTree).startPreCommit(cohort);
124 @SuppressWarnings("unchecked")
125 final FutureCallback<DataTreeCandidate> callback = mock(FutureCallback.class);
126 cohort.preCommit(callback);
128 verify(callback).onSuccess(mockCandidate);
129 verifyNoMoreInteractions(callback);
131 assertSame("getCandidate", mockCandidate, cohort.getCandidate());
133 return mockCandidate;
137 public void testPreCommitAndCommitSuccess() throws Exception {
139 final DataTreeCandidateTip candidate = preCommitSuccess();
141 doAnswer(invocation -> {
142 invocation.getArgumentAt(0, SimpleShardDataTreeCohort.class).successfulCommit(UnsignedLong.valueOf(0));
144 }).when(mockShardDataTree).startCommit(cohort, candidate);
146 @SuppressWarnings("unchecked")
147 final FutureCallback<UnsignedLong> mockCommitCallback = mock(FutureCallback.class);
148 cohort.commit(mockCommitCallback);
150 verify(mockCommitCallback).onSuccess(any(UnsignedLong.class));
151 verifyNoMoreInteractions(mockCommitCallback);
153 verify(mockUserCohorts).commit();
157 public void testPreCommitWithIllegalArgumentEx() throws Exception {
160 final Exception cause = new IllegalArgumentException("mock");
161 doAnswer(invocation -> {
162 invocation.getArgumentAt(0, SimpleShardDataTreeCohort.class).failedPreCommit(cause);
164 }).when(mockShardDataTree).startPreCommit(cohort);
166 @SuppressWarnings("unchecked")
167 final FutureCallback<DataTreeCandidate> callback = mock(FutureCallback.class);
168 cohort.preCommit(callback);
170 verify(callback).onFailure(cause);
171 verifyNoMoreInteractions(callback);
173 verify(mockUserCohorts).abort();
177 public void testPreCommitWithReportedFailure() throws Exception {
180 final Exception cause = new IllegalArgumentException("mock");
181 cohort.reportFailure(cause);
183 @SuppressWarnings("unchecked")
184 final FutureCallback<DataTreeCandidate> callback = mock(FutureCallback.class);
185 cohort.preCommit(callback);
187 verify(callback).onFailure(cause);
188 verifyNoMoreInteractions(callback);
190 verify(mockShardDataTree, never()).startPreCommit(cohort);
194 public void testCommitWithIllegalArgumentEx() {
196 final DataTreeCandidateTip candidate = preCommitSuccess();
198 final Exception cause = new IllegalArgumentException("mock");
199 doAnswer(invocation -> {
200 invocation.getArgumentAt(0, SimpleShardDataTreeCohort.class).failedCommit(cause);
202 }).when(mockShardDataTree).startCommit(cohort, candidate);
204 @SuppressWarnings("unchecked")
205 final FutureCallback<UnsignedLong> callback = mock(FutureCallback.class);
206 cohort.commit(callback);
208 verify(callback).onFailure(cause);
209 verifyNoMoreInteractions(callback);
211 verify(mockUserCohorts).abort();
214 private static Future<?> abort(final ShardDataTreeCohort cohort) {
215 final CompletableFuture<Void> f = new CompletableFuture<>();
216 cohort.abort(new FutureCallback<Void>() {
218 public void onSuccess(final Void result) {
223 public void onFailure(final Throwable failure) {
224 f.completeExceptionally(failure);
232 public void testAbort() throws Exception {
233 doReturn(true).when(mockShardDataTree).startAbort(cohort);
236 verify(mockShardDataTree).startAbort(cohort);
240 public void testAbortWithCohorts() throws Exception {
241 doReturn(true).when(mockShardDataTree).startAbort(cohort);
243 final Promise<Iterable<Object>> cohortFuture = akka.dispatch.Futures.promise();
244 doReturn(Optional.of(cohortFuture.future())).when(mockUserCohorts).abort();
246 final Future<?> abortFuture = abort(cohort);
248 cohortFuture.success(Collections.emptyList());
251 verify(mockShardDataTree).startAbort(cohort);