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.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;
37 * Unit tests for SimpleShardDataTreeCohort.
39 * @author Thomas Pantelis
41 @RunWith(MockitoJUnitRunner.StrictStubs.class)
42 public class SimpleShardDataTreeCohortTest extends AbstractTest {
44 private ShardDataTree mockShardDataTree;
47 private DataTreeModification mockModification;
50 private CompositeDataTreeCohort mockUserCohorts;
53 private FutureCallback<DataTreeCandidate> mockPreCallback;
55 private SimpleShardDataTreeCohort cohort;
59 doReturn(Optional.empty()).when(mockUserCohorts).commit();
60 doReturn(Optional.empty()).when(mockUserCohorts).abort();
62 cohort = new SimpleShardDataTreeCohort(mockShardDataTree, mockModification, nextTransactionId(),
63 mockUserCohorts, Optional.empty());
67 public void testCanCommitSuccess() {
71 private void canCommitSuccess() {
72 doAnswer(invocation -> {
73 invocation.<SimpleShardDataTreeCohort>getArgument(0).successfulCanCommit();
75 }).when(mockShardDataTree).startCanCommit(cohort);
77 @SuppressWarnings("unchecked")
78 final FutureCallback<Void> callback = mock(FutureCallback.class);
79 cohort.canCommit(callback);
81 verify(callback).onSuccess(null);
82 verifyNoMoreInteractions(callback);
85 private void testValidatationPropagates(final Exception cause) {
86 doAnswer(invocation -> {
87 invocation.<SimpleShardDataTreeCohort>getArgument(0).failedCanCommit(cause);
89 }).when(mockShardDataTree).startCanCommit(cohort);
91 @SuppressWarnings("unchecked")
92 final FutureCallback<Void> callback = mock(FutureCallback.class);
93 cohort.canCommit(callback);
95 verify(callback).onFailure(cause);
96 verifyNoMoreInteractions(callback);
100 public void testCanCommitWithConflictingModEx() {
101 testValidatationPropagates(new ConflictingModificationAppliedException(YangInstanceIdentifier.empty(), "mock"));
105 public void testCanCommitWithDataValidationEx() {
106 testValidatationPropagates(new DataValidationFailedException(YangInstanceIdentifier.empty(), "mock"));
110 public void testCanCommitWithIllegalArgumentEx() {
111 testValidatationPropagates(new IllegalArgumentException("mock"));
114 private DataTreeCandidateTip preCommitSuccess() {
115 final DataTreeCandidateTip mockCandidate = mock(DataTreeCandidateTip.class);
116 doAnswer(invocation -> {
117 invocation.<SimpleShardDataTreeCohort>getArgument(0).successfulPreCommit(mockCandidate);
119 }).when(mockShardDataTree).startPreCommit(cohort);
121 @SuppressWarnings("unchecked")
122 final FutureCallback<DataTreeCandidate> callback = mock(FutureCallback.class);
123 cohort.preCommit(callback);
125 verify(callback).onSuccess(mockCandidate);
126 verifyNoMoreInteractions(callback);
128 assertSame("getCandidate", mockCandidate, cohort.getCandidate());
130 return mockCandidate;
134 public void testPreCommitAndCommitSuccess() {
136 final DataTreeCandidateTip candidate = preCommitSuccess();
138 doAnswer(invocation -> {
139 invocation.<SimpleShardDataTreeCohort>getArgument(0).successfulCommit(UnsignedLong.valueOf(0), () -> { });
141 }).when(mockShardDataTree).startCommit(cohort, candidate);
143 @SuppressWarnings("unchecked")
144 final FutureCallback<UnsignedLong> mockCommitCallback = mock(FutureCallback.class);
145 cohort.commit(mockCommitCallback);
147 verify(mockCommitCallback).onSuccess(any(UnsignedLong.class));
148 verifyNoMoreInteractions(mockCommitCallback);
150 verify(mockUserCohorts).commit();
154 public void testPreCommitWithIllegalArgumentEx() {
157 final Exception cause = new IllegalArgumentException("mock");
158 doAnswer(invocation -> {
159 invocation.<SimpleShardDataTreeCohort>getArgument(0).failedPreCommit(cause);
161 }).when(mockShardDataTree).startPreCommit(cohort);
163 @SuppressWarnings("unchecked")
164 final FutureCallback<DataTreeCandidate> callback = mock(FutureCallback.class);
165 cohort.preCommit(callback);
167 verify(callback).onFailure(cause);
168 verifyNoMoreInteractions(callback);
170 verify(mockUserCohorts).abort();
174 public void testPreCommitWithReportedFailure() {
177 final Exception cause = new IllegalArgumentException("mock");
178 cohort.reportFailure(cause);
180 @SuppressWarnings("unchecked")
181 final FutureCallback<DataTreeCandidate> callback = mock(FutureCallback.class);
182 cohort.preCommit(callback);
184 verify(callback).onFailure(cause);
185 verifyNoMoreInteractions(callback);
187 verify(mockShardDataTree, never()).startPreCommit(cohort);
191 public void testCommitWithIllegalArgumentEx() {
193 final DataTreeCandidateTip candidate = preCommitSuccess();
195 final Exception cause = new IllegalArgumentException("mock");
196 doAnswer(invocation -> {
197 invocation.<SimpleShardDataTreeCohort>getArgument(0).failedCommit(cause);
199 }).when(mockShardDataTree).startCommit(cohort, candidate);
201 @SuppressWarnings("unchecked")
202 final FutureCallback<UnsignedLong> callback = mock(FutureCallback.class);
203 cohort.commit(callback);
205 verify(callback).onFailure(cause);
206 verifyNoMoreInteractions(callback);
208 verify(mockUserCohorts).abort();
211 private static Future<?> abort(final ShardDataTreeCohort cohort) {
212 final CompletableFuture<Void> f = new CompletableFuture<>();
213 cohort.abort(new FutureCallback<Void>() {
215 public void onSuccess(final Void result) {
220 public void onFailure(final Throwable failure) {
221 f.completeExceptionally(failure);
229 public void testAbort() throws Exception {
230 doReturn(Boolean.TRUE).when(mockShardDataTree).startAbort(cohort);
233 verify(mockShardDataTree).startAbort(cohort);
237 public void testAbortWithCohorts() throws Exception {
238 doReturn(true).when(mockShardDataTree).startAbort(cohort);
240 doReturn(Optional.of(CompletableFuture.completedFuture(null))).when(mockUserCohorts).abort();
242 final Future<?> abortFuture = abort(cohort);
245 verify(mockShardDataTree).startAbort(cohort);