Convert DCL tests to use DTCL
[controller.git] / opendaylight / md-sal / sal-distributed-datastore / src / test / java / org / opendaylight / controller / cluster / databroker / compat / LegacyDOMDataBrokerAdapterTest.java
1 /*
2  * Copyright (c) 2017 Inocybe Technologies 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.databroker.compat;
9
10 import static org.junit.Assert.assertEquals;
11 import static org.junit.Assert.assertNotNull;
12 import static org.junit.Assert.assertTrue;
13 import static org.junit.Assert.fail;
14 import static org.mockito.Matchers.any;
15 import static org.mockito.Matchers.anyObject;
16 import static org.mockito.Matchers.eq;
17 import static org.mockito.Mockito.doAnswer;
18 import static org.mockito.Mockito.doNothing;
19 import static org.mockito.Mockito.doReturn;
20 import static org.mockito.Mockito.inOrder;
21 import static org.mockito.Mockito.mock;
22 import static org.mockito.Mockito.verify;
23
24 import com.google.common.base.Optional;
25 import com.google.common.collect.ImmutableMap;
26 import com.google.common.util.concurrent.CheckedFuture;
27 import com.google.common.util.concurrent.Futures;
28 import com.google.common.util.concurrent.MoreExecutors;
29 import java.util.Arrays;
30 import java.util.Collection;
31 import java.util.concurrent.ExecutionException;
32 import java.util.concurrent.TimeUnit;
33 import java.util.concurrent.TimeoutException;
34 import org.junit.Before;
35 import org.junit.Test;
36 import org.mockito.ArgumentCaptor;
37 import org.mockito.InOrder;
38 import org.mockito.Mock;
39 import org.mockito.MockitoAnnotations;
40 import org.opendaylight.controller.cluster.databroker.ConcurrentDOMDataBroker;
41 import org.opendaylight.controller.cluster.datastore.DistributedDataStoreInterface;
42 import org.opendaylight.controller.cluster.datastore.exceptions.NoShardLeaderException;
43 import org.opendaylight.controller.md.cluster.datastore.model.TestModel;
44 import org.opendaylight.controller.md.sal.common.api.data.AsyncTransaction;
45 import org.opendaylight.controller.md.sal.common.api.data.DataStoreUnavailableException;
46 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
47 import org.opendaylight.controller.md.sal.common.api.data.OptimisticLockFailedException;
48 import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
49 import org.opendaylight.controller.md.sal.common.api.data.TransactionChainListener;
50 import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
51 import org.opendaylight.controller.md.sal.dom.api.ClusteredDOMDataTreeChangeListener;
52 import org.opendaylight.controller.md.sal.dom.api.DOMDataReadOnlyTransaction;
53 import org.opendaylight.controller.md.sal.dom.api.DOMDataReadWriteTransaction;
54 import org.opendaylight.controller.md.sal.dom.api.DOMDataTreeChangeListener;
55 import org.opendaylight.controller.md.sal.dom.api.DOMDataTreeChangeService;
56 import org.opendaylight.controller.md.sal.dom.api.DOMDataTreeCommitCohortRegistry;
57 import org.opendaylight.controller.md.sal.dom.api.DOMDataTreeIdentifier;
58 import org.opendaylight.controller.md.sal.dom.api.DOMDataWriteTransaction;
59 import org.opendaylight.controller.md.sal.dom.api.DOMTransactionChain;
60 import org.opendaylight.mdsal.dom.api.DOMDataTreeCommitCohort;
61 import org.opendaylight.mdsal.dom.api.DOMDataTreeCommitCohortRegistration;
62 import org.opendaylight.mdsal.dom.spi.store.DOMStoreReadTransaction;
63 import org.opendaylight.mdsal.dom.spi.store.DOMStoreReadWriteTransaction;
64 import org.opendaylight.mdsal.dom.spi.store.DOMStoreThreePhaseCommitCohort;
65 import org.opendaylight.mdsal.dom.spi.store.DOMStoreTransactionChain;
66 import org.opendaylight.mdsal.dom.spi.store.DOMStoreTreeChangePublisher;
67 import org.opendaylight.mdsal.dom.spi.store.DOMStoreWriteTransaction;
68 import org.opendaylight.yangtools.concepts.ListenerRegistration;
69 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
70 import org.opendaylight.yangtools.yang.data.api.schema.tree.ConflictingModificationAppliedException;
71 import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeCandidate;
72 import org.opendaylight.yangtools.yang.data.api.schema.tree.DataValidationFailedException;
73 import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes;
74
75 /**
76  * Unit tests for LegacyDOMDataBrokerAdapter.
77  *
78  * @author Thomas Pantelis
79  */
80 public class LegacyDOMDataBrokerAdapterTest {
81     @Mock
82     private TestDOMStore mockOperStore;
83
84     @Mock
85     private TestDOMStore mockConfigStore;
86
87     @Mock
88     private DOMStoreReadTransaction mockReadTx;
89
90     @Mock
91     private DOMStoreWriteTransaction mockWriteTx;
92
93     @Mock
94     private DOMStoreReadWriteTransaction mockReadWriteTx;
95
96     @Mock
97     private DOMStoreThreePhaseCommitCohort mockCommitCohort;
98
99     private LegacyDOMDataBrokerAdapter adapter;
100     private NormalizedNode<?,?> dataNode;
101
102     @Before
103     public void setup() {
104         MockitoAnnotations.initMocks(this);
105
106         ConcurrentDOMDataBroker backendBroker = new ConcurrentDOMDataBroker(ImmutableMap.of(
107                 org.opendaylight.mdsal.common.api.LogicalDatastoreType.OPERATIONAL, mockOperStore,
108                 org.opendaylight.mdsal.common.api.LogicalDatastoreType.CONFIGURATION, mockConfigStore),
109                 MoreExecutors.newDirectExecutorService());
110
111         adapter = new LegacyDOMDataBrokerAdapter(backendBroker);
112
113         doReturn(Futures.immediateFuture(Boolean.TRUE)).when(mockCommitCohort).canCommit();
114         doReturn(Futures.immediateFuture(null)).when(mockCommitCohort).preCommit();
115         doReturn(Futures.immediateFuture(null)).when(mockCommitCohort).commit();
116         doReturn(Futures.immediateFuture(null)).when(mockCommitCohort).abort();
117
118         dataNode = ImmutableNodes.containerNode(TestModel.TEST_QNAME);
119
120         doReturn(mockWriteTx).when(mockConfigStore).newWriteOnlyTransaction();
121         doNothing().when(mockWriteTx).write(TestModel.TEST_PATH, dataNode);
122         doNothing().when(mockWriteTx).merge(TestModel.TEST_PATH, dataNode);
123         doNothing().when(mockWriteTx).delete(TestModel.TEST_PATH);
124         doNothing().when(mockWriteTx).close();
125         doReturn(mockCommitCohort).when(mockWriteTx).ready();
126
127         doReturn(mockReadTx).when(mockConfigStore).newReadOnlyTransaction();
128         doReturn(Futures.immediateCheckedFuture(Optional.of(dataNode))).when(mockReadTx).read(TestModel.TEST_PATH);
129         doReturn(Futures.immediateCheckedFuture(Boolean.TRUE)).when(mockReadTx).exists(TestModel.TEST_PATH);
130
131         doReturn(mockReadWriteTx).when(mockConfigStore).newReadWriteTransaction();
132         doNothing().when(mockReadWriteTx).write(TestModel.TEST_PATH, dataNode);
133         doReturn(mockCommitCohort).when(mockReadWriteTx).ready();
134         doReturn(Futures.immediateCheckedFuture(Optional.of(dataNode))).when(mockReadWriteTx).read(TestModel.TEST_PATH);
135
136         DOMStoreTransactionChain mockTxChain = mock(DOMStoreTransactionChain.class);
137         doReturn(mockReadTx).when(mockTxChain).newReadOnlyTransaction();
138         doReturn(mockWriteTx).when(mockTxChain).newWriteOnlyTransaction();
139         doReturn(mockReadWriteTx).when(mockTxChain).newReadWriteTransaction();
140         doReturn(mockTxChain).when(mockConfigStore).createTransactionChain();
141
142         doReturn(mock(DOMStoreTransactionChain.class)).when(mockOperStore).createTransactionChain();
143     }
144
145     @Test
146     public void testReadOnlyTransaction() throws Exception {
147         DOMDataReadOnlyTransaction tx = adapter.newReadOnlyTransaction();
148
149         // Test successful read
150
151         CheckedFuture<Optional<NormalizedNode<?, ?>>, ReadFailedException> readFuture =
152                 tx.read(LogicalDatastoreType.CONFIGURATION, TestModel.TEST_PATH);
153         Optional<NormalizedNode<?, ?>> readOptional = readFuture.get();
154         assertEquals("isPresent", true, readOptional.isPresent());
155         assertEquals("NormalizedNode", dataNode, readOptional.get());
156
157         // Test successful exists
158
159         CheckedFuture<Boolean, ReadFailedException> existsFuture =
160                 tx.exists(LogicalDatastoreType.CONFIGURATION, TestModel.TEST_PATH);
161         assertEquals("exists", Boolean.TRUE, existsFuture.get());
162
163         // Test failed read
164
165         String errorMsg = "mock read error";
166         Throwable cause = new RuntimeException();
167         doReturn(Futures.immediateFailedCheckedFuture(new org.opendaylight.mdsal.common.api.ReadFailedException(
168                 errorMsg, cause))).when(mockReadTx).read(TestModel.TEST_PATH);
169
170         try {
171             tx.read(LogicalDatastoreType.CONFIGURATION, TestModel.TEST_PATH).checkedGet();
172             fail("Expected ReadFailedException");
173         } catch (ReadFailedException e) {
174             assertEquals("getMessage", errorMsg, e.getMessage());
175             assertEquals("getCause", cause, e.getCause());
176         }
177
178         // Test close
179         tx.close();
180         verify(mockReadTx).close();
181     }
182
183     @Test
184     public void testWriteOnlyTransaction() throws Exception {
185         // Test successful write operations and submit
186
187         DOMDataWriteTransaction tx = adapter.newWriteOnlyTransaction();
188
189         tx.put(LogicalDatastoreType.CONFIGURATION, TestModel.TEST_PATH, dataNode);
190         verify(mockWriteTx).write(TestModel.TEST_PATH, dataNode);
191
192         tx.merge(LogicalDatastoreType.CONFIGURATION, TestModel.TEST_PATH, dataNode);
193         verify(mockWriteTx).merge(TestModel.TEST_PATH, dataNode);
194
195         tx.delete(LogicalDatastoreType.CONFIGURATION, TestModel.TEST_PATH);
196         verify(mockWriteTx).delete(TestModel.TEST_PATH);
197
198         tx.commit().get(5, TimeUnit.SECONDS);
199
200         InOrder inOrder = inOrder(mockCommitCohort);
201         inOrder.verify(mockCommitCohort).canCommit();
202         inOrder.verify(mockCommitCohort).preCommit();
203         inOrder.verify(mockCommitCohort).commit();
204
205         // Test cancel
206
207         tx = adapter.newWriteOnlyTransaction();
208         tx.put(LogicalDatastoreType.CONFIGURATION, TestModel.TEST_PATH, dataNode);
209         tx.cancel();
210         verify(mockWriteTx).close();
211
212         // Test submit with OptimisticLockFailedException
213
214         String errorMsg = "mock OptimisticLockFailedException";
215         Throwable cause = new ConflictingModificationAppliedException(TestModel.TEST_PATH, "mock");
216         doReturn(Futures.immediateFailedFuture(new org.opendaylight.mdsal.common.api.OptimisticLockFailedException(
217                 errorMsg, cause))).when(mockCommitCohort).canCommit();
218
219         try {
220             tx = adapter.newWriteOnlyTransaction();
221             tx.put(LogicalDatastoreType.CONFIGURATION, TestModel.TEST_PATH, dataNode);
222             commit(tx);
223             fail("Expected OptimisticLockFailedException");
224         } catch (OptimisticLockFailedException e) {
225             assertEquals("getMessage", errorMsg, e.getMessage());
226             assertEquals("getCause", cause, e.getCause());
227         }
228
229         // Test submit with TransactionCommitFailedException
230
231         errorMsg = "mock TransactionCommitFailedException";
232         cause = new DataValidationFailedException(TestModel.TEST_PATH, "mock");
233         doReturn(Futures.immediateFailedFuture(new org.opendaylight.mdsal.common.api.TransactionCommitFailedException(
234                 errorMsg, cause))).when(mockCommitCohort).canCommit();
235
236         try {
237             tx = adapter.newWriteOnlyTransaction();
238             tx.put(LogicalDatastoreType.CONFIGURATION, TestModel.TEST_PATH, dataNode);
239             commit(tx);
240             fail("Expected TransactionCommitFailedException");
241         } catch (TransactionCommitFailedException e) {
242             assertEquals("getMessage", errorMsg, e.getMessage());
243             assertEquals("getCause", cause, e.getCause());
244         }
245
246         // Test submit with DataStoreUnavailableException
247
248         errorMsg = "mock NoShardLeaderException";
249         cause = new NoShardLeaderException("mock");
250         doReturn(Futures.immediateFailedFuture(cause)).when(mockCommitCohort).canCommit();
251
252         try {
253             tx = adapter.newWriteOnlyTransaction();
254             tx.put(LogicalDatastoreType.CONFIGURATION, TestModel.TEST_PATH, dataNode);
255             commit(tx);
256             fail("Expected TransactionCommitFailedException");
257         } catch (TransactionCommitFailedException e) {
258             assertEquals("getCause type", DataStoreUnavailableException.class, e.getCause().getClass());
259             assertEquals("Root cause", cause, e.getCause().getCause());
260         }
261
262         // Test submit with RuntimeException
263
264         errorMsg = "mock RuntimeException";
265         cause = new RuntimeException(errorMsg);
266         doReturn(Futures.immediateFailedFuture(cause)).when(mockCommitCohort).canCommit();
267
268         try {
269             tx = adapter.newWriteOnlyTransaction();
270             tx.put(LogicalDatastoreType.CONFIGURATION, TestModel.TEST_PATH, dataNode);
271             commit(tx);
272             fail("Expected TransactionCommitFailedException");
273         } catch (TransactionCommitFailedException e) {
274             assertEquals("getCause", cause, e.getCause());
275         }
276     }
277
278     @Test
279     public void testReadWriteTransaction() throws Exception {
280         DOMDataReadWriteTransaction tx = adapter.newReadWriteTransaction();
281
282         CheckedFuture<Optional<NormalizedNode<?, ?>>, ReadFailedException> readFuture =
283                 tx.read(LogicalDatastoreType.CONFIGURATION, TestModel.TEST_PATH);
284         Optional<NormalizedNode<?, ?>> readOptional = readFuture.get();
285         assertEquals("isPresent", true, readOptional.isPresent());
286         assertEquals("NormalizedNode", dataNode, readOptional.get());
287
288         tx.put(LogicalDatastoreType.CONFIGURATION, TestModel.TEST_PATH, dataNode);
289         verify(mockReadWriteTx).write(TestModel.TEST_PATH, dataNode);
290
291         tx.commit().get(5, TimeUnit.SECONDS);
292
293         InOrder inOrder = inOrder(mockCommitCohort);
294         inOrder.verify(mockCommitCohort).canCommit();
295         inOrder.verify(mockCommitCohort).preCommit();
296         inOrder.verify(mockCommitCohort).commit();
297     }
298
299     @SuppressWarnings("rawtypes")
300     @Test
301     public void testTransactionChain() throws Exception {
302         TransactionChainListener mockListener = mock(TransactionChainListener.class);
303         doNothing().when(mockListener).onTransactionChainSuccessful(anyObject());
304         doNothing().when(mockListener).onTransactionChainFailed(anyObject(), anyObject(), anyObject());
305
306         DOMTransactionChain chain = adapter.createTransactionChain(mockListener);
307
308         // Test read-only tx
309
310         DOMDataReadOnlyTransaction readTx = chain.newReadOnlyTransaction();
311
312         CheckedFuture<Optional<NormalizedNode<?, ?>>, ReadFailedException> readFuture =
313                 readTx.read(LogicalDatastoreType.CONFIGURATION, TestModel.TEST_PATH);
314         Optional<NormalizedNode<?, ?>> readOptional = readFuture.get();
315         assertEquals("isPresent", true, readOptional.isPresent());
316         assertEquals("NormalizedNode", dataNode, readOptional.get());
317
318         // Test write-only tx
319
320         DOMDataWriteTransaction writeTx = chain.newWriteOnlyTransaction();
321
322         writeTx.put(LogicalDatastoreType.CONFIGURATION, TestModel.TEST_PATH, dataNode);
323         verify(mockWriteTx).write(TestModel.TEST_PATH, dataNode);
324         writeTx.commit().get(5, TimeUnit.SECONDS);
325
326         InOrder inOrder = inOrder(mockCommitCohort);
327         inOrder.verify(mockCommitCohort).canCommit();
328         inOrder.verify(mockCommitCohort).preCommit();
329         inOrder.verify(mockCommitCohort).commit();
330
331         // Test read-write tx
332
333         DOMDataReadWriteTransaction readWriteTx = chain.newReadWriteTransaction();
334
335         readFuture = readWriteTx.read(LogicalDatastoreType.CONFIGURATION, TestModel.TEST_PATH);
336         readOptional = readFuture.get();
337         assertEquals("isPresent", true, readOptional.isPresent());
338         assertEquals("NormalizedNode", dataNode, readOptional.get());
339
340         chain.close();
341         verify(mockListener).onTransactionChainSuccessful(chain);
342
343         // Test failed chain
344
345         doReturn(Futures.immediateFailedFuture(new org.opendaylight.mdsal.common.api.TransactionCommitFailedException(
346                 "mock", (Throwable)null))).when(mockCommitCohort).canCommit();
347
348         chain = adapter.createTransactionChain(mockListener);
349
350         writeTx = chain.newWriteOnlyTransaction();
351
352         try {
353             writeTx.put(LogicalDatastoreType.CONFIGURATION, TestModel.TEST_PATH, dataNode);
354             commit(writeTx);
355             fail("Expected TransactionCommitFailedException");
356         } catch (TransactionCommitFailedException e) {
357             // expected
358         }
359
360         ArgumentCaptor<AsyncTransaction> failedTx = ArgumentCaptor.forClass(AsyncTransaction.class);
361         verify(mockListener).onTransactionChainFailed(eq(chain), failedTx.capture(),
362                 any(TransactionCommitFailedException.class));
363     }
364
365     @SuppressWarnings("unchecked")
366     @Test
367     public void testDataTreeChangeListener() {
368         DOMDataTreeChangeService domDTCLService =
369                 (DOMDataTreeChangeService) adapter.getSupportedExtensions().get(DOMDataTreeChangeService.class);
370         assertNotNull("DOMDataTreeChangeService not found", domDTCLService);
371
372         ArgumentCaptor<org.opendaylight.mdsal.dom.api.DOMDataTreeChangeListener> storeDTCL =
373                 ArgumentCaptor.forClass(org.opendaylight.mdsal.dom.api.DOMDataTreeChangeListener.class);
374         ListenerRegistration<org.opendaylight.mdsal.dom.api.DOMDataTreeChangeListener> mockReg =
375                 mock(ListenerRegistration.class);
376         doNothing().when(mockReg).close();
377         doAnswer(invocation -> storeDTCL.getValue()).when(mockReg).getInstance();
378         doReturn(mockReg).when(mockConfigStore).registerTreeChangeListener(eq(TestModel.TEST_PATH),
379                 storeDTCL.capture());
380
381         DOMDataTreeChangeListener brokerDTCL = mock(DOMDataTreeChangeListener.class);
382         ListenerRegistration<DOMDataTreeChangeListener> reg = domDTCLService.registerDataTreeChangeListener(
383                 new DOMDataTreeIdentifier(LogicalDatastoreType.CONFIGURATION, TestModel.TEST_PATH), brokerDTCL);
384         assertEquals("getInstance", brokerDTCL, reg.getInstance());
385
386         Collection<DataTreeCandidate> changes = Arrays.asList(mock(DataTreeCandidate.class));
387         storeDTCL.getValue().onDataTreeChanged(changes);
388         verify(brokerDTCL).onDataTreeChanged(changes);
389
390         reg.close();
391         verify(mockReg).close();
392
393         // Test ClusteredDOMDataTreeChangeListener
394
395         ArgumentCaptor<org.opendaylight.mdsal.dom.api.DOMDataTreeChangeListener> storeClusteredDTCL =
396                 ArgumentCaptor.forClass(org.opendaylight.mdsal.dom.api.DOMDataTreeChangeListener.class);
397         mockReg = mock(ListenerRegistration.class);
398         doReturn(mockReg).when(mockConfigStore).registerTreeChangeListener(eq(TestModel.TEST_PATH),
399                 storeClusteredDTCL.capture());
400
401         final ClusteredDOMDataTreeChangeListener brokerClusteredDTCL = mock(ClusteredDOMDataTreeChangeListener.class);
402         domDTCLService.registerDataTreeChangeListener(new DOMDataTreeIdentifier(LogicalDatastoreType.CONFIGURATION,
403                 TestModel.TEST_PATH), brokerClusteredDTCL);
404
405         assertTrue("Expected ClusteredDOMDataTreeChangeListener: " + storeClusteredDTCL.getValue(),
406                 storeClusteredDTCL.getValue()
407                     instanceof org.opendaylight.mdsal.dom.api.ClusteredDOMDataTreeChangeListener);
408         storeClusteredDTCL.getValue().onDataTreeChanged(changes);
409         verify(brokerClusteredDTCL).onDataTreeChanged(changes);
410     }
411
412     @SuppressWarnings("unchecked")
413     @Test
414     public void testDataTreeCommitCohortRegistry() {
415         DOMDataTreeCommitCohortRegistry domCohortRegistry = (DOMDataTreeCommitCohortRegistry)
416                 adapter.getSupportedExtensions().get(DOMDataTreeCommitCohortRegistry.class);
417         assertNotNull("DOMDataTreeCommitCohortRegistry not found", domCohortRegistry);
418
419         DOMDataTreeCommitCohort mockCohort = mock(DOMDataTreeCommitCohort.class);
420         org.opendaylight.mdsal.dom.api.DOMDataTreeIdentifier treeId =
421                 new org.opendaylight.mdsal.dom.api.DOMDataTreeIdentifier(
422                     org.opendaylight.mdsal.common.api.LogicalDatastoreType.CONFIGURATION, TestModel.TEST_PATH);
423         DOMDataTreeCommitCohortRegistration<DOMDataTreeCommitCohort> mockReg =
424                 mock(DOMDataTreeCommitCohortRegistration.class);
425         doReturn(mockReg).when(mockConfigStore).registerCommitCohort(treeId, mockCohort);
426
427         DOMDataTreeCommitCohortRegistration<DOMDataTreeCommitCohort> reg = domCohortRegistry.registerCommitCohort(
428                 treeId, mockCohort);
429         assertEquals("DOMDataTreeCommitCohortRegistration", mockReg, reg);
430
431         verify(mockConfigStore).registerCommitCohort(treeId, mockCohort);
432     }
433
434     @Test
435     @Deprecated
436     public void testSubmit() throws Exception {
437         DOMDataWriteTransaction tx = adapter.newWriteOnlyTransaction();
438
439         tx.put(LogicalDatastoreType.CONFIGURATION, TestModel.TEST_PATH, dataNode);
440         verify(mockWriteTx).write(TestModel.TEST_PATH, dataNode);
441
442         tx.submit().get(5, TimeUnit.SECONDS);
443
444         InOrder inOrder = inOrder(mockCommitCohort);
445         inOrder.verify(mockCommitCohort).canCommit();
446         inOrder.verify(mockCommitCohort).preCommit();
447         inOrder.verify(mockCommitCohort).commit();
448
449         String errorMsg = "mock OptimisticLockFailedException";
450         Throwable cause = new ConflictingModificationAppliedException(TestModel.TEST_PATH, "mock");
451         doReturn(Futures.immediateFailedFuture(new org.opendaylight.mdsal.common.api.TransactionCommitFailedException(
452                 errorMsg, cause))).when(mockCommitCohort).canCommit();
453
454         try {
455             tx = adapter.newWriteOnlyTransaction();
456             tx.put(LogicalDatastoreType.CONFIGURATION, TestModel.TEST_PATH, dataNode);
457             commit(tx);
458             fail("Expected TransactionCommitFailedException");
459         } catch (TransactionCommitFailedException e) {
460             assertEquals("getMessage", errorMsg, e.getMessage());
461             assertEquals("getCause", cause, e.getCause());
462         }
463     }
464
465     @SuppressWarnings("checkstyle:AvoidHidingCauseException")
466     private static void commit(DOMDataWriteTransaction tx)
467             throws TransactionCommitFailedException, InterruptedException, TimeoutException {
468         try {
469             tx.commit().get(5, TimeUnit.SECONDS);
470         } catch (ExecutionException e) {
471             assertTrue("Expected TransactionCommitFailedException. Actual: " + e.getCause(),
472                     e.getCause() instanceof TransactionCommitFailedException);
473             throw (TransactionCommitFailedException)e.getCause();
474         }
475     }
476
477     private interface TestDOMStore extends DistributedDataStoreInterface, DOMStoreTreeChangePublisher,
478             org.opendaylight.mdsal.dom.api.DOMDataTreeCommitCohortRegistry {
479     }
480 }