a11fc6bb1c4ac004120540d098233c915c3ca78f
[controller.git] / opendaylight / md-sal / sal-distributed-datastore / src / test / java / org / opendaylight / controller / cluster / datastore / DataTreeChangeListenerSupportTest.java
1 /*
2  * Copyright (c) 2015 Brocade Communications Systems, Inc. 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.datastore;
9
10 import static org.opendaylight.controller.md.cluster.datastore.model.TestModel.INNER_LIST_QNAME;
11 import static org.opendaylight.controller.md.cluster.datastore.model.TestModel.OUTER_LIST_PATH;
12 import static org.opendaylight.controller.md.cluster.datastore.model.TestModel.OUTER_LIST_QNAME;
13 import static org.opendaylight.controller.md.cluster.datastore.model.TestModel.TEST_PATH;
14 import static org.opendaylight.controller.md.cluster.datastore.model.TestModel.TEST_QNAME;
15 import static org.opendaylight.controller.md.cluster.datastore.model.TestModel.innerEntryPath;
16 import static org.opendaylight.controller.md.cluster.datastore.model.TestModel.innerNode;
17 import static org.opendaylight.controller.md.cluster.datastore.model.TestModel.outerEntryKey;
18 import static org.opendaylight.controller.md.cluster.datastore.model.TestModel.outerEntryPath;
19 import static org.opendaylight.controller.md.cluster.datastore.model.TestModel.outerNode;
20 import static org.opendaylight.controller.md.cluster.datastore.model.TestModel.outerNodeEntry;
21 import static org.opendaylight.controller.md.cluster.datastore.model.TestModel.testNodeWithOuter;
22 import akka.actor.ActorRef;
23 import akka.testkit.TestActorRef;
24 import org.junit.After;
25 import org.junit.Before;
26 import org.junit.Test;
27 import org.opendaylight.controller.cluster.datastore.messages.RegisterDataTreeChangeListener;
28 import org.opendaylight.controller.cluster.datastore.utils.MockDataTreeChangeListener;
29 import org.opendaylight.controller.cluster.raft.TestActorFactory;
30 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
31 import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes;
32
33 /**
34  * Unit tests for DataTreeChangeListenerSupport.
35  *
36  * @author Thomas Pantelis
37  */
38 public class DataTreeChangeListenerSupportTest extends AbstractShardTest {
39     private final TestActorFactory actorFactory = new TestActorFactory(getSystem());
40
41     private Shard shard;
42     private DataTreeChangeListenerSupport support;
43
44     @Before
45     public void setup() {
46         shard = createShard();
47         support = new DataTreeChangeListenerSupport(shard);
48     }
49
50     @Override
51     @After
52     public void tearDown() {
53         super.tearDown();
54         actorFactory.close();
55     }
56
57     @Test
58     public void testChangeListenerWithNoInitialData() throws Exception {
59         MockDataTreeChangeListener listener = registerChangeListener(TEST_PATH, 0, true);
60
61         listener.expectNoMoreChanges("Unexpected initial change event");
62     }
63
64     @Test
65     public void testInitialChangeListenerEventWithContainerPath() throws Exception {
66         writeToStore(shard.getDataStore(), TEST_PATH, ImmutableNodes.containerNode(TEST_QNAME));
67
68         MockDataTreeChangeListener listener = registerChangeListener(TEST_PATH, 1, true);
69
70         listener.waitForChangeEvents();
71         listener.verifyNotifiedData(TEST_PATH);
72     }
73
74     @Test
75     public void testInitialChangeListenerEventWithListPath() throws Exception {
76         mergeToStore(shard.getDataStore(), TEST_PATH, testNodeWithOuter(1, 2));
77
78         MockDataTreeChangeListener listener = registerChangeListener(OUTER_LIST_PATH, 1, true);
79
80         listener.waitForChangeEvents();
81         listener.verifyNotifiedData(OUTER_LIST_PATH);
82     }
83
84     @Test
85     public void testInitialChangeListenerEventWithWildcardedListPath() throws Exception {
86         mergeToStore(shard.getDataStore(), TEST_PATH, testNodeWithOuter(1, 2));
87
88         MockDataTreeChangeListener listener = registerChangeListener(OUTER_LIST_PATH.node(OUTER_LIST_QNAME), 2, true);
89
90         listener.waitForChangeEvents();
91         listener.verifyNotifiedData(outerEntryPath(1), outerEntryPath(2));
92     }
93
94     @Test
95     public void testInitialChangeListenerEventWithNestedWildcardedListsPath() throws Exception {
96         mergeToStore(shard.getDataStore(), TEST_PATH, testNodeWithOuter(outerNode(
97                 outerNodeEntry(1, innerNode("one", "two")), outerNodeEntry(2, innerNode("three", "four")))));
98
99         MockDataTreeChangeListener listener = registerChangeListener(
100                 OUTER_LIST_PATH.node(OUTER_LIST_QNAME).node(INNER_LIST_QNAME).node(INNER_LIST_QNAME), 4, true);
101
102         listener.waitForChangeEvents();
103         listener.verifyNotifiedData(innerEntryPath(1, "one"), innerEntryPath(1, "two"), innerEntryPath(2, "three"),
104                 innerEntryPath(2, "four"));
105
106         // Register for a specific outer list entry
107
108         MockDataTreeChangeListener listener2 = registerChangeListener(
109                 OUTER_LIST_PATH.node(outerEntryKey(1)).node(INNER_LIST_QNAME).node(INNER_LIST_QNAME), 2, true);
110
111         listener2.waitForChangeEvents();
112         listener2.verifyNotifiedData(innerEntryPath(1, "one"), innerEntryPath(1, "two"));
113         listener2.verifyNoNotifiedData(innerEntryPath(2, "three"), innerEntryPath(2, "four"));
114     }
115
116     private MockDataTreeChangeListener registerChangeListener(final YangInstanceIdentifier path,
117             final int expectedEvents, final boolean isLeader) {
118         MockDataTreeChangeListener listener = new MockDataTreeChangeListener(expectedEvents);
119         ActorRef dclActor = actorFactory.createActor(DataTreeChangeListenerActor.props(listener));
120         support.onMessage(new RegisterDataTreeChangeListener(path, dclActor, false), isLeader, true);
121         return listener;
122     }
123
124     private Shard createShard() {
125         TestActorRef<Shard> actor = actorFactory.createTestActor(newShardProps());
126         ShardTestKit.waitUntilLeader(actor);
127         return actor.underlyingActor();
128     }
129 }