0757669af56e7da38cab6a6cbfea667551f81829
[genius.git] / mdsalutil / mdsalutil-testutils / src / test / java / org / opendaylight / genius / infra / tests / ManagedNewTransactionRunnerImplTest.java
1 /*
2  * Copyright (c) 2017 Red Hat, 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.genius.infra.tests;
9
10 import static com.google.common.truth.Truth.assertThat;
11 import static org.junit.Assert.assertEquals;
12 import static org.junit.Assert.assertTrue;
13 import static org.junit.Assert.fail;
14 import static org.opendaylight.controller.md.sal.test.model.util.ListsBindingUtils.TOP_FOO_KEY;
15 import static org.opendaylight.controller.md.sal.test.model.util.ListsBindingUtils.path;
16 import static org.opendaylight.controller.md.sal.test.model.util.ListsBindingUtils.topLevelList;
17 import static org.opendaylight.genius.infra.Datastore.OPERATIONAL;
18 import static org.opendaylight.infrautils.testutils.Asserts.assertThrows;
19
20 import com.google.common.util.concurrent.ListeningExecutorService;
21 import com.google.common.util.concurrent.MoreExecutors;
22 import java.io.IOException;
23 import java.util.concurrent.ExecutionException;
24 import java.util.concurrent.Executors;
25 import org.junit.Assert;
26 import org.junit.Before;
27 import org.junit.Rule;
28 import org.junit.Test;
29 import org.opendaylight.genius.datastoreutils.SingleTransactionDataBroker;
30 import org.opendaylight.genius.datastoreutils.testutils.DataBrokerFailuresImpl;
31 import org.opendaylight.genius.infra.ManagedNewTransactionRunner;
32 import org.opendaylight.genius.infra.ManagedNewTransactionRunnerImpl;
33 import org.opendaylight.infrautils.testutils.LogCaptureRule;
34 import org.opendaylight.infrautils.testutils.LogRule;
35 import org.opendaylight.mdsal.binding.api.DataBroker;
36 import org.opendaylight.mdsal.binding.api.WriteTransaction;
37 import org.opendaylight.mdsal.binding.dom.adapter.test.AbstractBaseDataBrokerTest;
38 import org.opendaylight.mdsal.binding.dom.adapter.test.AbstractDataBrokerTestCustomizer;
39 import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
40 import org.opendaylight.mdsal.common.api.OptimisticLockFailedException;
41 import org.opendaylight.mdsal.common.api.TransactionCommitFailedException;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.test.augment.rev140709.TreeComplexUsesAugment;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.test.augment.rev140709.TreeComplexUsesAugmentBuilder;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.test.augment.rev140709.complex.from.grouping.ContainerWithUsesBuilder;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.test.list.rev140701.two.level.list.TopLevelList;
46 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
47
48 /**
49  * Test for {@link ManagedNewTransactionRunnerImpl}.
50  *
51  * @author Michael Vorburger.ch
52  * @author Stephen Kitt
53  */
54 public class ManagedNewTransactionRunnerImplTest {
55
56     static final InstanceIdentifier<TopLevelList> TEST_PATH = path(TOP_FOO_KEY);
57
58     public @Rule LogRule logRule = new LogRule();
59     public @Rule LogCaptureRule logCaptureRule = new LogCaptureRule();
60
61     DataBrokerFailuresImpl testableDataBroker;
62     SingleTransactionDataBroker singleTransactionDataBroker;
63     ManagedNewTransactionRunner managedNewTransactionRunner;
64
65     protected ManagedNewTransactionRunner createManagedNewTransactionRunnerToTest(DataBroker dataBroker) {
66         return new ManagedNewTransactionRunnerImpl(dataBroker);
67     }
68
69     @Before
70     public void beforeTest() throws Exception {
71         AbstractBaseDataBrokerTest test = new AbstractBaseDataBrokerTest() {
72             @Override
73             protected AbstractDataBrokerTestCustomizer createDataBrokerTestCustomizer() {
74                 return new AbstractDataBrokerTestCustomizer() {
75                     @Override
76                     public ListeningExecutorService getCommitCoordinatorExecutor() {
77                         return MoreExecutors.listeningDecorator(Executors.newCachedThreadPool());
78                     }
79                 };
80             }
81         };
82         test.setup();
83         testableDataBroker = new DataBrokerFailuresImpl(test.getDataBroker());
84         managedNewTransactionRunner = createManagedNewTransactionRunnerToTest(testableDataBroker);
85         singleTransactionDataBroker = new SingleTransactionDataBroker(testableDataBroker);
86     }
87
88     @Test
89     public void testApplyWithNewReadTransactionAndCloseEmptySuccessfully() throws Exception {
90         Assert.assertEquals(Long.valueOf(1),
91             managedNewTransactionRunner.applyWithNewReadOnlyTransactionAndClose(OPERATIONAL, tx -> 1L));
92     }
93
94     @Test
95     public void testCallWithNewReadTransactionAndCloseEmptySuccessfully() throws Exception {
96         managedNewTransactionRunner.callWithNewReadOnlyTransactionAndClose(OPERATIONAL, tx -> { });
97     }
98
99     @Test
100     public void testCallWithNewWriteOnlyTransactionAndSubmitEmptySuccessfully() throws Exception {
101         managedNewTransactionRunner.callWithNewWriteOnlyTransactionAndSubmit(writeTx -> { }).get();
102     }
103
104     @Test
105     public void testCallWithNewTypedWriteOnlyTransactionAndSubmitEmptySuccessfully() throws Exception {
106         managedNewTransactionRunner.callWithNewWriteOnlyTransactionAndSubmit(OPERATIONAL, writeTx -> {
107         }).get();
108     }
109
110     @Test
111     public void testCallWithNewReadWriteTransactionAndSubmitEmptySuccessfully() throws Exception {
112         managedNewTransactionRunner.callWithNewReadWriteTransactionAndSubmit(tx -> { }).get();
113     }
114
115     @Test
116     public void testCallWithNewTypedReadWriteTransactionAndSubmitEmptySuccessfully() throws Exception {
117         managedNewTransactionRunner.callWithNewReadWriteTransactionAndSubmit(OPERATIONAL, tx -> {
118         }).get();
119     }
120
121     @Test
122     public void testApplyWithNewReadWriteTransactionAndSubmitEmptySuccessfully() throws Exception {
123         assertEquals(1,
124             (long) managedNewTransactionRunner.applyWithNewReadWriteTransactionAndSubmit(OPERATIONAL,
125                 tx -> 1).get());
126     }
127
128     @Test
129     public void testCallWithNewWriteOnlyTransactionAndSubmitPutSuccessfully() throws Exception {
130         TopLevelList data = newTestDataObject();
131         managedNewTransactionRunner.callWithNewWriteOnlyTransactionAndSubmit(
132             writeTx -> writeTx.put(LogicalDatastoreType.OPERATIONAL, TEST_PATH, data)).get();
133         assertEquals(data, singleTransactionDataBroker.syncRead(LogicalDatastoreType.OPERATIONAL, TEST_PATH));
134     }
135
136     @Test
137     public void testCallWithNewTypedWriteOnlyTransactionAndSubmitPutSuccessfully() throws Exception {
138         TopLevelList data = newTestDataObject();
139         managedNewTransactionRunner.callWithNewWriteOnlyTransactionAndSubmit(OPERATIONAL,
140             writeTx -> writeTx.put(TEST_PATH, data)).get();
141         assertEquals(data, singleTransactionDataBroker.syncRead(LogicalDatastoreType.OPERATIONAL, TEST_PATH));
142     }
143
144     @Test
145     public void testCallWithNewReadWriteTransactionAndSubmitPutSuccessfully() throws Exception {
146         TopLevelList data = newTestDataObject();
147         managedNewTransactionRunner.callWithNewReadWriteTransactionAndSubmit(
148             tx -> tx.put(LogicalDatastoreType.OPERATIONAL, TEST_PATH, data)).get();
149         assertEquals(data, singleTransactionDataBroker.syncRead(LogicalDatastoreType.OPERATIONAL, TEST_PATH));
150     }
151
152     @Test
153     public void testCallWithNewTypedReadWriteTransactionAndSubmitPutSuccessfully() throws Exception {
154         TopLevelList data = newTestDataObject();
155         managedNewTransactionRunner.callWithNewReadWriteTransactionAndSubmit(OPERATIONAL,
156             tx -> tx.put(TEST_PATH, data)).get();
157         assertEquals(data, singleTransactionDataBroker.syncRead(LogicalDatastoreType.OPERATIONAL, TEST_PATH));
158     }
159
160     @Test
161     public void testApplyWithNewReadWriteTransactionAndSubmitPutSuccessfully() throws Exception {
162         TopLevelList data = newTestDataObject();
163         assertEquals(1, (long) managedNewTransactionRunner.applyWithNewReadWriteTransactionAndSubmit(
164             OPERATIONAL,
165             tx -> {
166                 tx.put(TEST_PATH, data);
167                 return 1;
168             }).get());
169         assertEquals(data, singleTransactionDataBroker.syncRead(LogicalDatastoreType.OPERATIONAL, TEST_PATH));
170     }
171
172     @Test
173     public void testCallWithNewReadTransactionAndCloseReadSuccessfully() throws Exception {
174         TopLevelList data = newTestDataObject();
175         managedNewTransactionRunner.callWithNewWriteOnlyTransactionAndSubmit(OPERATIONAL,
176             tx -> tx.put(TEST_PATH, data)).get();
177         assertEquals(data, managedNewTransactionRunner.applyWithNewReadOnlyTransactionAndClose(OPERATIONAL,
178             tx -> tx.read(TEST_PATH)).get().get());
179     }
180
181     TopLevelList newTestDataObject() {
182         TreeComplexUsesAugment fooAugment = new TreeComplexUsesAugmentBuilder()
183                 .setContainerWithUses(new ContainerWithUsesBuilder().setLeafFromGrouping("foo").build()).build();
184         return topLevelList(TOP_FOO_KEY, fooAugment);
185     }
186
187     @Test
188     public void testCallWithNewWriteOnlyTransactionAndSubmitPutButLaterException() throws Exception {
189         assertTrue(assertThrows(ExecutionException.class,
190             () -> {
191                 managedNewTransactionRunner.callWithNewReadWriteTransactionAndSubmit(writeTx -> {
192                     writeTx.put(LogicalDatastoreType.OPERATIONAL, TEST_PATH, newTestDataObject());
193                     // We now throw an arbitrary kind of checked (not unchecked!) exception here
194                     throw new IOException("something didn't quite go as expected...");
195                 }).get();
196                 fail("This should have led to an ExecutionException!");
197             }).getCause() instanceof IOException);
198         assertThat(
199             singleTransactionDataBroker.syncReadOptional(LogicalDatastoreType.OPERATIONAL, TEST_PATH));
200     }
201
202     @Test
203     public void testCallWithNewTypedWriteOnlyTransactionAndSubmitPutButLaterException() throws Exception {
204         assertTrue(assertThrows(ExecutionException.class,
205             () -> {
206                 managedNewTransactionRunner.callWithNewWriteOnlyTransactionAndSubmit(OPERATIONAL, writeTx -> {
207                     writeTx.put(TEST_PATH, newTestDataObject());
208                     // We now throw an arbitrary kind of checked (not unchecked!) exception here
209                     throw new IOException("something didn't quite go as expected...");
210                 }).get();
211                 fail("This should have led to an ExecutionException!");
212             }).getCause() instanceof IOException);
213         assertThat(
214             singleTransactionDataBroker.syncReadOptional(LogicalDatastoreType.OPERATIONAL, TEST_PATH));
215     }
216
217     @Test
218     public void testCallWithNewReadWriteTransactionAndSubmitPutButLaterException() throws Exception {
219         assertTrue(assertThrows(ExecutionException.class,
220             () -> {
221                 managedNewTransactionRunner.callWithNewReadWriteTransactionAndSubmit(writeTx -> {
222                     writeTx.put(LogicalDatastoreType.OPERATIONAL, TEST_PATH, newTestDataObject());
223                     // We now throw an arbitrary kind of checked (not unchecked!) exception here
224                     throw new IOException("something didn't quite go as expected...");
225                 }).get();
226                 fail("This should have led to an ExecutionException!");
227             }).getCause() instanceof IOException);
228         assertThat(
229             singleTransactionDataBroker.syncReadOptional(LogicalDatastoreType.OPERATIONAL, TEST_PATH));
230     }
231
232     @Test
233     public void testCallWithNewTypedReadWriteTransactionAndSubmitPutButLaterException() throws Exception {
234         assertTrue(assertThrows(ExecutionException.class,
235             () -> {
236                 managedNewTransactionRunner.callWithNewReadWriteTransactionAndSubmit(OPERATIONAL, writeTx -> {
237                     writeTx.put(TEST_PATH, newTestDataObject());
238                     // We now throw an arbitrary kind of checked (not unchecked!) exception here
239                     throw new IOException("something didn't quite go as expected...");
240                 }).get();
241                 fail("This should have led to an ExecutionException!");
242             }).getCause() instanceof IOException);
243         assertThat(
244             singleTransactionDataBroker.syncReadOptional(LogicalDatastoreType.OPERATIONAL, TEST_PATH));
245     }
246
247     @Test
248     public void testApplyWithNewReadWriteTransactionAndSubmitPutButLaterException() throws Exception {
249         assertTrue(assertThrows(ExecutionException.class,
250             () -> {
251                 managedNewTransactionRunner.applyWithNewReadWriteTransactionAndSubmit(OPERATIONAL,
252                     writeTx -> {
253                         writeTx.put(TEST_PATH, newTestDataObject());
254                         // We now throw an arbitrary kind of checked (not unchecked!) exception here
255                         throw new IOException("something didn't quite go as expected...");
256                     }).get();
257                 fail("This should have led to an ExecutionException!");
258             }).getCause() instanceof IOException);
259         assertThat(
260             singleTransactionDataBroker.syncReadOptional(LogicalDatastoreType.OPERATIONAL, TEST_PATH));
261     }
262
263     @Test
264     public void testCallWithNewWriteOnlyTransactionCommitFailedException() throws Exception {
265         assertTrue(assertThrows(ExecutionException.class,
266             () -> {
267                 testableDataBroker.failSubmits(new TransactionCommitFailedException("bada boum bam!"));
268                 managedNewTransactionRunner.callWithNewWriteOnlyTransactionAndSubmit(
269                     writeTx -> writeTx.put(LogicalDatastoreType.OPERATIONAL, TEST_PATH, newTestDataObject())).get();
270                 fail("This should have led to an ExecutionException!");
271             }).getCause() instanceof TransactionCommitFailedException);
272         assertThat(
273             singleTransactionDataBroker.syncReadOptional(LogicalDatastoreType.OPERATIONAL, TEST_PATH));
274     }
275
276     @Test
277     public void testCallWithNewTypedWriteOnlyTransactionCommitFailedException() throws Exception {
278         assertTrue(assertThrows(ExecutionException.class,
279             () -> {
280                 testableDataBroker.failSubmits(new TransactionCommitFailedException("bada boum bam!"));
281                 managedNewTransactionRunner.callWithNewWriteOnlyTransactionAndSubmit(OPERATIONAL,
282                     writeTx -> writeTx.put(TEST_PATH, newTestDataObject())).get();
283                 fail("This should have led to an ExecutionException!");
284             }).getCause() instanceof TransactionCommitFailedException);
285         assertThat(
286             singleTransactionDataBroker.syncReadOptional(LogicalDatastoreType.OPERATIONAL, TEST_PATH));
287     }
288
289     @Test
290     public void testCallWithNewReadWriteTransactionCommitFailedException() throws Exception {
291         assertTrue(assertThrows(ExecutionException.class,
292             () -> {
293                 testableDataBroker.failSubmits(new TransactionCommitFailedException("bada boum bam!"));
294                 managedNewTransactionRunner.callWithNewReadWriteTransactionAndSubmit(
295                     writeTx -> writeTx.put(LogicalDatastoreType.OPERATIONAL, TEST_PATH, newTestDataObject())).get();
296                 fail("This should have led to an ExecutionException!");
297             }).getCause() instanceof TransactionCommitFailedException);
298         assertThat(
299             singleTransactionDataBroker.syncReadOptional(LogicalDatastoreType.OPERATIONAL, TEST_PATH));
300     }
301
302     @Test
303     public void testCallWithNewTypedReadWriteTransactionCommitFailedException() throws Exception {
304         assertTrue(assertThrows(ExecutionException.class,
305             () -> {
306                 testableDataBroker.failSubmits(new TransactionCommitFailedException("bada boum bam!"));
307                 managedNewTransactionRunner.callWithNewReadWriteTransactionAndSubmit(OPERATIONAL,
308                     writeTx -> writeTx.put(TEST_PATH, newTestDataObject())).get();
309                 fail("This should have led to an ExecutionException!");
310             }).getCause() instanceof TransactionCommitFailedException);
311         assertThat(
312             singleTransactionDataBroker.syncReadOptional(LogicalDatastoreType.OPERATIONAL, TEST_PATH));
313     }
314
315     @Test
316     public void testApplyWithNewReadWriteTransactionCommitFailedException() throws Exception {
317         assertTrue(assertThrows(ExecutionException.class,
318             () -> {
319                 testableDataBroker.failSubmits(new TransactionCommitFailedException("bada boum bam!"));
320                 managedNewTransactionRunner.applyWithNewReadWriteTransactionAndSubmit(OPERATIONAL,
321                     writeTx -> {
322                         writeTx.put(TEST_PATH, newTestDataObject());
323                         return 1;
324                     }).get();
325                 fail("This should have led to an ExecutionException!");
326             }).getCause() instanceof TransactionCommitFailedException);
327         assertThat(
328             singleTransactionDataBroker.syncReadOptional(LogicalDatastoreType.OPERATIONAL, TEST_PATH));
329     }
330
331     @Test
332     public void testCallWithNewWriteOnlyTransactionOptimisticLockFailedException() throws Exception {
333         assertTrue(assertThrows(ExecutionException.class,
334             () -> {
335                 testableDataBroker.failSubmits(2, new OptimisticLockFailedException("bada boum bam!"));
336                 managedNewTransactionRunner.callWithNewWriteOnlyTransactionAndSubmit(
337                     writeTx -> writeTx.put(LogicalDatastoreType.OPERATIONAL, TEST_PATH, newTestDataObject())).get();
338                 fail("This should have led to an ExecutionException!");
339             }).getCause() instanceof OptimisticLockFailedException);
340         assertThat(
341             singleTransactionDataBroker.syncReadOptional(LogicalDatastoreType.OPERATIONAL, TEST_PATH));
342     }
343
344     @Test
345     public void testCallWithNewTypedWriteOnlyTransactionOptimisticLockFailedException() throws Exception {
346         assertTrue(assertThrows(ExecutionException.class,
347             () -> {
348                 testableDataBroker.failSubmits(2, new OptimisticLockFailedException("bada boum bam!"));
349                 managedNewTransactionRunner.callWithNewWriteOnlyTransactionAndSubmit(OPERATIONAL,
350                     writeTx -> writeTx.put(TEST_PATH, newTestDataObject())).get();
351                 fail("This should have led to an ExecutionException!");
352             }).getCause() instanceof OptimisticLockFailedException);
353         assertThat(
354             singleTransactionDataBroker.syncReadOptional(LogicalDatastoreType.OPERATIONAL, TEST_PATH));
355     }
356
357     @Test
358     public void testCallWithNewReadWriteTransactionOptimisticLockFailedException() throws Exception {
359         assertTrue(assertThrows(ExecutionException.class,
360             () -> {
361                 testableDataBroker.failSubmits(2, new OptimisticLockFailedException("bada boum bam!"));
362                 managedNewTransactionRunner.callWithNewReadWriteTransactionAndSubmit(
363                     writeTx -> writeTx.put(LogicalDatastoreType.OPERATIONAL, TEST_PATH, newTestDataObject())).get();
364                 fail("This should have led to an ExecutionException!");
365             }).getCause() instanceof OptimisticLockFailedException);
366         assertThat(
367             singleTransactionDataBroker.syncReadOptional(LogicalDatastoreType.OPERATIONAL, TEST_PATH));
368     }
369
370     @Test
371     public void testCallWithNewTypedReadWriteTransactionOptimisticLockFailedException() throws Exception {
372         assertTrue(assertThrows(ExecutionException.class,
373             () -> {
374                 testableDataBroker.failSubmits(2, new OptimisticLockFailedException("bada boum bam!"));
375                 managedNewTransactionRunner.callWithNewReadWriteTransactionAndSubmit(OPERATIONAL,
376                     writeTx -> writeTx.put(TEST_PATH, newTestDataObject())).get();
377                 fail("This should have led to an ExecutionException!");
378             }).getCause() instanceof OptimisticLockFailedException);
379         assertThat(
380             singleTransactionDataBroker.syncReadOptional(LogicalDatastoreType.OPERATIONAL, TEST_PATH));
381     }
382
383     @Test
384     public void testApplyWithNewReadWriteTransactionOptimisticLockFailedException() throws Exception {
385         try {
386             testableDataBroker.failSubmits(2, new OptimisticLockFailedException("bada boum bam!"));
387             managedNewTransactionRunner.applyWithNewReadWriteTransactionAndSubmit(OPERATIONAL,
388                 writeTx -> {
389                     writeTx.put(TEST_PATH, newTestDataObject());
390                     return 1;
391                 }).get();
392             fail("This should have led to an ExecutionException!");
393         } catch (ExecutionException e) {
394             assertThat(e.getCause() instanceof OptimisticLockFailedException).isTrue();
395         }
396         assertThat(
397             singleTransactionDataBroker.syncReadOptional(LogicalDatastoreType.OPERATIONAL, TEST_PATH));
398     }
399
400     @Test
401     public void testCallWithNewWriteOnlyTransactionAndSubmitCannotCommit() {
402         assertThrows(ExecutionException.class,
403             () -> managedNewTransactionRunner.callWithNewWriteOnlyTransactionAndSubmit(
404                 WriteTransaction::commit).get());
405     }
406
407     @Test
408     public void testCallWithNewReadWriteTransactionAndSubmitCannotCommit() {
409         assertThrows(ExecutionException.class,
410             () -> managedNewTransactionRunner.callWithNewReadWriteTransactionAndSubmit(
411                 WriteTransaction::commit).get());
412     }
413
414     @Test
415     public void testCallWithNewWriteOnlyTransactionAndSubmitCannotCancel() {
416         assertThrows(ExecutionException.class,
417             () -> managedNewTransactionRunner.callWithNewWriteOnlyTransactionAndSubmit(
418                 WriteTransaction::cancel).get());
419     }
420
421     @Test
422     public void testCallWithNewReadWriteTransactionAndSubmitCannotCancel() {
423         assertThrows(ExecutionException.class,
424             () -> managedNewTransactionRunner.callWithNewReadWriteTransactionAndSubmit(
425                 WriteTransaction::cancel).get());
426     }
427 }