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