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