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