Do not allow multi-datastore transactions
[controller.git] / opendaylight / md-sal / sal-distributed-datastore / src / test / java / org / opendaylight / controller / cluster / databroker / AbstractDOMBrokerWriteTransactionTest.java
1 /*
2  *
3  * This program and the accompanying materials are made available under the
4  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
5  * and is available at http://www.eclipse.org/legal/epl-v10.html
6  */
7 package org.opendaylight.controller.cluster.databroker;
8
9 import static org.junit.Assert.assertEquals;
10 import static org.junit.Assert.assertSame;
11 import static org.junit.Assert.assertThrows;
12 import static org.junit.Assert.assertTrue;
13 import static org.mockito.ArgumentMatchers.any;
14 import static org.mockito.Mockito.doThrow;
15 import static org.opendaylight.mdsal.common.api.LogicalDatastoreType.CONFIGURATION;
16 import static org.opendaylight.mdsal.common.api.LogicalDatastoreType.OPERATIONAL;
17
18 import com.google.common.util.concurrent.FluentFuture;
19 import java.util.Map;
20 import java.util.concurrent.ExecutionException;
21 import org.junit.Test;
22 import org.junit.runner.RunWith;
23 import org.mockito.Mock;
24 import org.mockito.junit.MockitoJUnitRunner;
25 import org.opendaylight.mdsal.common.api.CommitInfo;
26 import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
27 import org.opendaylight.mdsal.common.api.TransactionCommitFailedException;
28 import org.opendaylight.mdsal.common.api.TransactionDatastoreMismatchException;
29 import org.opendaylight.mdsal.dom.spi.store.DOMStoreTransactionFactory;
30 import org.opendaylight.mdsal.dom.spi.store.DOMStoreWriteTransaction;
31
32 @RunWith(MockitoJUnitRunner.StrictStubs.class)
33 public class AbstractDOMBrokerWriteTransactionTest {
34
35     @Mock
36     private DOMStoreTransactionFactory txFactory;
37     @Mock
38     private AbstractDOMTransactionFactory<?> abstractDOMTransactionFactory;
39     @Mock
40     private DOMStoreWriteTransaction domStoreWriteTransaction;
41
42     private class AbstractDOMBrokerWriteTransactionTestImpl
43             extends AbstractDOMBrokerWriteTransaction<DOMStoreWriteTransaction> {
44
45         AbstractDOMBrokerWriteTransactionTestImpl() {
46             this(Map.of(CONFIGURATION, txFactory));
47         }
48
49         AbstractDOMBrokerWriteTransactionTestImpl(Map<LogicalDatastoreType, DOMStoreTransactionFactory> txFactoryMap) {
50             super(new Object(), txFactoryMap, abstractDOMTransactionFactory);
51         }
52
53         @Override
54         protected DOMStoreWriteTransaction createTransaction(final LogicalDatastoreType key) {
55             return domStoreWriteTransaction;
56         }
57
58         @Override
59         protected DOMStoreWriteTransaction getSubtransaction() {
60             return domStoreWriteTransaction;
61         }
62     }
63
64     @Test
65     public void readyRuntimeExceptionAndCancel() {
66         RuntimeException thrown = new RuntimeException();
67         doThrow(thrown).when(domStoreWriteTransaction).ready();
68         AbstractDOMBrokerWriteTransactionTestImpl abstractDOMBrokerWriteTransactionTestImpl =
69                 new AbstractDOMBrokerWriteTransactionTestImpl();
70
71         FluentFuture<? extends CommitInfo> submitFuture = abstractDOMBrokerWriteTransactionTestImpl.commit();
72         final var cause = assertThrows(ExecutionException.class, submitFuture::get).getCause();
73         assertTrue(cause instanceof TransactionCommitFailedException);
74         assertSame(thrown, cause.getCause());
75         abstractDOMBrokerWriteTransactionTestImpl.cancel();
76     }
77
78     @Test
79     public void submitRuntimeExceptionAndCancel() throws InterruptedException {
80         RuntimeException thrown = new RuntimeException();
81         doThrow(thrown).when(abstractDOMTransactionFactory).commit(any(), any());
82         AbstractDOMBrokerWriteTransactionTestImpl abstractDOMBrokerWriteTransactionTestImpl
83                 = new AbstractDOMBrokerWriteTransactionTestImpl();
84
85         FluentFuture<? extends CommitInfo> submitFuture = abstractDOMBrokerWriteTransactionTestImpl.commit();
86         final var cause = assertThrows(ExecutionException.class, submitFuture::get).getCause();
87         assertTrue(cause instanceof TransactionCommitFailedException);
88         assertSame(thrown, cause.getCause());
89         abstractDOMBrokerWriteTransactionTestImpl.cancel();
90     }
91
92     @Test
93     public void getSubtransactionStoreMismatch() {
94         final var testTx = new AbstractDOMBrokerWriteTransactionTestImpl(
95                 Map.of(CONFIGURATION, txFactory, OPERATIONAL, txFactory));
96
97         assertEquals(domStoreWriteTransaction, testTx.getSubtransaction(CONFIGURATION));
98
99         final var exception = assertThrows(TransactionDatastoreMismatchException.class,
100                 () -> testTx.getSubtransaction(OPERATIONAL));
101         assertEquals(CONFIGURATION, exception.expected());
102         assertEquals(OPERATIONAL, exception.encountered());
103     }
104
105     @Test
106     public void getSubtransactionStoreUndefined() {
107         final var testTx = new AbstractDOMBrokerWriteTransactionTestImpl(Map.of(OPERATIONAL, txFactory));
108
109         final var exception = assertThrows(IllegalArgumentException.class,
110                 () -> testTx.getSubtransaction(CONFIGURATION));
111         assertEquals("CONFIGURATION is not supported", exception.getMessage());
112     }
113 }