2 * Copyright (c) 2018 ZTE, Inc. and others. All rights reserved.
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
8 package org.opendaylight.mdsal.dom.broker;
10 import static org.junit.Assert.assertEquals;
11 import static org.junit.Assert.assertNotNull;
12 import static org.mockito.ArgumentMatchers.any;
13 import static org.mockito.Mockito.doNothing;
14 import static org.mockito.Mockito.mock;
15 import static org.mockito.Mockito.timeout;
16 import static org.mockito.Mockito.times;
17 import static org.mockito.Mockito.verify;
19 import com.google.common.collect.Iterables;
20 import com.google.common.util.concurrent.MoreExecutors;
21 import java.util.List;
22 import org.junit.Before;
23 import org.junit.Test;
24 import org.mockito.ArgumentCaptor;
25 import org.opendaylight.mdsal.dom.api.DOMDataTreeChangeListener;
26 import org.opendaylight.mdsal.dom.spi.store.DOMStoreReadWriteTransaction;
27 import org.opendaylight.mdsal.dom.spi.store.DOMStoreThreePhaseCommitCohort;
28 import org.opendaylight.mdsal.dom.store.inmemory.InMemoryDOMDataStore;
29 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
30 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
31 import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
32 import org.opendaylight.yangtools.yang.data.spi.node.ImmutableNodes;
33 import org.opendaylight.yangtools.yang.data.tree.api.DataTreeCandidate;
35 public class DOMDataTreeChangeListenerTest extends AbstractDatastoreTest {
37 private InMemoryDOMDataStore domStore;
41 domStore = new InMemoryDOMDataStore("Mdsal217", MoreExecutors.newDirectExecutorService());
42 domStore.onModelContextUpdated(SCHEMA_CONTEXT);
46 public void receiveOnDataInitialEventForEmptyRoot() throws Exception {
47 final DOMDataTreeChangeListener listener = mock(DOMDataTreeChangeListener.class);
48 doNothing().when(listener).onInitialData();
50 domStore.registerTreeChangeListener(YangInstanceIdentifier.of(), listener);
51 verify(listener, timeout(1000)).onInitialData();
55 public void receiveOnDataInitialEventForNonExistingData() throws Exception {
56 final DOMDataTreeChangeListener listener = mock(DOMDataTreeChangeListener.class);
57 final var candidateCapture = ArgumentCaptor.forClass(List.class);
58 doNothing().when(listener).onInitialData();
59 doNothing().when(listener).onDataTreeChanged(any());
61 domStore.registerTreeChangeListener(TestModel.TEST_PATH, listener);
62 verify(listener, times(1)).onInitialData();
64 final var testNode = ImmutableNodes.newContainerBuilder()
65 .withNodeIdentifier(new NodeIdentifier(TestModel.TEST_QNAME))
67 DOMStoreReadWriteTransaction writeTx = domStore.newReadWriteTransaction();
68 assertNotNull(writeTx);
69 writeTx.write(TestModel.TEST_PATH, testNode);
70 DOMStoreThreePhaseCommitCohort cohort = writeTx.ready();
71 cohort.preCommit().get();
72 cohort.commit().get();
74 verify(listener, timeout(1000)).onDataTreeChanged(candidateCapture.capture());
75 final DataTreeCandidate candidate = (DataTreeCandidate) Iterables.getOnlyElement(candidateCapture.getValue());
76 assertEquals(TestModel.TEST_PATH, candidate.getRootPath());
80 public void receiveOnDataTreeChangedEventForPreExistingEmptyData() throws Exception {
81 final DOMDataTreeChangeListener listener = mock(DOMDataTreeChangeListener.class);
82 final ArgumentCaptor<List> candidateCapture = ArgumentCaptor.forClass(List.class);
83 doNothing().when(listener).onDataTreeChanged(any());
85 final var testNode = ImmutableNodes.newContainerBuilder()
86 .withNodeIdentifier(new NodeIdentifier(TestModel.TEST_QNAME))
89 DOMStoreReadWriteTransaction writeTx = domStore.newReadWriteTransaction();
90 assertNotNull(writeTx);
91 writeTx.write(TestModel.TEST_PATH, testNode);
92 DOMStoreThreePhaseCommitCohort cohort = writeTx.ready();
93 cohort.preCommit().get();
94 cohort.commit().get();
96 domStore.registerTreeChangeListener(TestModel.TEST_PATH, listener);
98 verify(listener, timeout(1000)).onDataTreeChanged(candidateCapture.capture());
99 final DataTreeCandidate candidate = (DataTreeCandidate) Iterables.getOnlyElement(candidateCapture.getValue());
100 assertEquals(TestModel.TEST_PATH, candidate.getRootPath());
104 public void receiveOnDataTreeChangeEventForPreExistingData() throws Exception {
105 final DOMDataTreeChangeListener listener = mock(DOMDataTreeChangeListener.class);
106 final ArgumentCaptor<List> candidateCapture = ArgumentCaptor.forClass(List.class);
107 doNothing().when(listener).onDataTreeChanged(any());
109 final ContainerNode testNode = ImmutableNodes.newContainerBuilder()
110 .withNodeIdentifier(new NodeIdentifier(TestModel.TEST_QNAME))
111 .addChild(ImmutableNodes.newSystemMapBuilder()
112 .withNodeIdentifier(new NodeIdentifier(TestModel.OUTER_LIST_QNAME))
113 .addChild(TestUtils.mapEntry(TestModel.OUTER_LIST_QNAME, TestModel.ID_QNAME, 1))
116 DOMStoreReadWriteTransaction writeTx = domStore.newReadWriteTransaction();
117 assertNotNull(writeTx);
118 writeTx.write(TestModel.TEST_PATH, testNode);
119 DOMStoreThreePhaseCommitCohort cohort = writeTx.ready();
120 cohort.preCommit().get();
121 cohort.commit().get();
123 domStore.registerTreeChangeListener(TestModel.TEST_PATH, listener);
125 verify(listener, timeout(1000)).onDataTreeChanged(candidateCapture.capture());
126 final DataTreeCandidate firstItem = (DataTreeCandidate) candidateCapture.getValue().iterator().next();
127 assertEquals(TestModel.TEST_PATH, firstItem.getRootPath());