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.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;
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.junit.runner.RunWith;
27 import org.mockito.Mock;
28 import org.mockito.junit.MockitoJUnitRunner;
29 import org.opendaylight.yangtools.yang.common.Empty;
30 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
31 import org.opendaylight.yangtools.yang.data.tree.api.ConflictingModificationAppliedException;
32 import org.opendaylight.yangtools.yang.data.tree.api.DataTreeCandidate;
33 import org.opendaylight.yangtools.yang.data.tree.api.DataTreeCandidateTip;
34 import org.opendaylight.yangtools.yang.data.tree.api.DataTreeModification;
35 import org.opendaylight.yangtools.yang.data.tree.api.DataValidationFailedException;
38 * Unit tests for SimpleShardDataTreeCohort.
40 * @author Thomas Pantelis
42 @RunWith(MockitoJUnitRunner.StrictStubs.class)
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;
60 doReturn(Optional.empty()).when(mockUserCohorts).commit();
61 doReturn(Optional.empty()).when(mockUserCohorts).abort();
63 cohort = new SimpleShardDataTreeCohort(mockShardDataTree, mockModification, nextTransactionId(),
64 mockUserCohorts, Optional.empty());
68 public void testCanCommitSuccess() {
72 private void canCommitSuccess() {
73 doAnswer(invocation -> {
74 invocation.<SimpleShardDataTreeCohort>getArgument(0).successfulCanCommit();
76 }).when(mockShardDataTree).startCanCommit(cohort);
78 @SuppressWarnings("unchecked")
79 final FutureCallback<Empty> callback = mock(FutureCallback.class);
80 cohort.canCommit(callback);
82 verify(callback).onSuccess(Empty.value());
83 verifyNoMoreInteractions(callback);
86 private void testValidatationPropagates(final Exception cause) {
87 doAnswer(invocation -> {
88 invocation.<SimpleShardDataTreeCohort>getArgument(0).failedCanCommit(cause);
90 }).when(mockShardDataTree).startCanCommit(cohort);
92 @SuppressWarnings("unchecked")
93 final FutureCallback<Empty> callback = mock(FutureCallback.class);
94 cohort.canCommit(callback);
96 verify(callback).onFailure(cause);
97 verifyNoMoreInteractions(callback);
101 public void testCanCommitWithConflictingModEx() {
102 testValidatationPropagates(new ConflictingModificationAppliedException(YangInstanceIdentifier.empty(), "mock"));
106 public void testCanCommitWithDataValidationEx() {
107 testValidatationPropagates(new DataValidationFailedException(YangInstanceIdentifier.empty(), "mock"));
111 public void testCanCommitWithIllegalArgumentEx() {
112 testValidatationPropagates(new IllegalArgumentException("mock"));
115 private DataTreeCandidateTip preCommitSuccess() {
116 final DataTreeCandidateTip mockCandidate = mock(DataTreeCandidateTip.class);
117 doAnswer(invocation -> {
118 invocation.<SimpleShardDataTreeCohort>getArgument(0).successfulPreCommit(mockCandidate);
120 }).when(mockShardDataTree).startPreCommit(cohort);
122 @SuppressWarnings("unchecked")
123 final FutureCallback<DataTreeCandidate> callback = mock(FutureCallback.class);
124 cohort.preCommit(callback);
126 verify(callback).onSuccess(mockCandidate);
127 verifyNoMoreInteractions(callback);
129 assertSame("getCandidate", mockCandidate, cohort.getCandidate());
131 return mockCandidate;
135 public void testPreCommitAndCommitSuccess() {
137 final DataTreeCandidateTip candidate = preCommitSuccess();
139 doAnswer(invocation -> {
140 invocation.<SimpleShardDataTreeCohort>getArgument(0).successfulCommit(UnsignedLong.valueOf(0), () -> { });
142 }).when(mockShardDataTree).startCommit(cohort, candidate);
144 @SuppressWarnings("unchecked")
145 final FutureCallback<UnsignedLong> mockCommitCallback = mock(FutureCallback.class);
146 cohort.commit(mockCommitCallback);
148 verify(mockCommitCallback).onSuccess(any(UnsignedLong.class));
149 verifyNoMoreInteractions(mockCommitCallback);
151 verify(mockUserCohorts).commit();
155 public void testPreCommitWithIllegalArgumentEx() {
158 final Exception cause = new IllegalArgumentException("mock");
159 doAnswer(invocation -> {
160 invocation.<SimpleShardDataTreeCohort>getArgument(0).failedPreCommit(cause);
162 }).when(mockShardDataTree).startPreCommit(cohort);
164 @SuppressWarnings("unchecked")
165 final FutureCallback<DataTreeCandidate> callback = mock(FutureCallback.class);
166 cohort.preCommit(callback);
168 verify(callback).onFailure(cause);
169 verifyNoMoreInteractions(callback);
171 verify(mockUserCohorts).abort();
175 public void testPreCommitWithReportedFailure() {
178 final Exception cause = new IllegalArgumentException("mock");
179 cohort.reportFailure(cause);
181 @SuppressWarnings("unchecked")
182 final FutureCallback<DataTreeCandidate> callback = mock(FutureCallback.class);
183 cohort.preCommit(callback);
185 verify(callback).onFailure(cause);
186 verifyNoMoreInteractions(callback);
188 verify(mockShardDataTree, never()).startPreCommit(cohort);
192 public void testCommitWithIllegalArgumentEx() {
194 final DataTreeCandidateTip candidate = preCommitSuccess();
196 final Exception cause = new IllegalArgumentException("mock");
197 doAnswer(invocation -> {
198 invocation.<SimpleShardDataTreeCohort>getArgument(0).failedCommit(cause);
200 }).when(mockShardDataTree).startCommit(cohort, candidate);
202 @SuppressWarnings("unchecked")
203 final FutureCallback<UnsignedLong> callback = mock(FutureCallback.class);
204 cohort.commit(callback);
206 verify(callback).onFailure(cause);
207 verifyNoMoreInteractions(callback);
209 verify(mockUserCohorts).abort();
212 private static Future<?> abort(final ShardDataTreeCohort cohort) {
213 final CompletableFuture<Empty> f = new CompletableFuture<>();
214 cohort.abort(new FutureCallback<>() {
216 public void onSuccess(final Empty result) {
221 public void onFailure(final Throwable failure) {
222 f.completeExceptionally(failure);
230 public void testAbort() throws Exception {
231 doReturn(Boolean.TRUE).when(mockShardDataTree).startAbort(cohort);
234 verify(mockShardDataTree).startAbort(cohort);
238 public void testAbortWithCohorts() throws Exception {
239 doReturn(true).when(mockShardDataTree).startAbort(cohort);
241 doReturn(Optional.of(CompletableFuture.completedFuture(null))).when(mockUserCohorts).abort();
243 final Future<?> abortFuture = abort(cohort);
246 verify(mockShardDataTree).startAbort(cohort);