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