2 * Copyright (c) 2015 Brocade Communications Systems, 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.controller.cluster.datastore;
10 import static org.junit.Assert.assertEquals;
11 import static org.opendaylight.controller.md.cluster.datastore.model.TestModel.INNER_LIST_QNAME;
12 import static org.opendaylight.controller.md.cluster.datastore.model.TestModel.OUTER_CONTAINER_PATH;
13 import static org.opendaylight.controller.md.cluster.datastore.model.TestModel.OUTER_CONTAINER_QNAME;
14 import static org.opendaylight.controller.md.cluster.datastore.model.TestModel.OUTER_LIST_PATH;
15 import static org.opendaylight.controller.md.cluster.datastore.model.TestModel.OUTER_LIST_QNAME;
16 import static org.opendaylight.controller.md.cluster.datastore.model.TestModel.TEST_PATH;
17 import static org.opendaylight.controller.md.cluster.datastore.model.TestModel.innerEntryPath;
18 import static org.opendaylight.controller.md.cluster.datastore.model.TestModel.innerNode;
19 import static org.opendaylight.controller.md.cluster.datastore.model.TestModel.outerEntryKey;
20 import static org.opendaylight.controller.md.cluster.datastore.model.TestModel.outerEntryPath;
21 import static org.opendaylight.controller.md.cluster.datastore.model.TestModel.outerNode;
22 import static org.opendaylight.controller.md.cluster.datastore.model.TestModel.outerNodeEntry;
23 import static org.opendaylight.controller.md.cluster.datastore.model.TestModel.testNodeWithOuter;
25 import akka.actor.ActorRef;
26 import akka.dispatch.Dispatchers;
27 import akka.testkit.TestActorRef;
28 import org.junit.Test;
29 import org.opendaylight.controller.cluster.datastore.messages.RegisterChangeListener;
30 import org.opendaylight.controller.cluster.datastore.utils.MockDataChangeListener;
31 import org.opendaylight.controller.md.cluster.datastore.model.TestModel;
32 import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker.DataChangeScope;
33 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
34 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNodes;
35 import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes;
38 * Unit tests for DataChangeListenerSupport.
40 * @author Thomas Pantelis
42 public class DataChangeListenerSupportTest extends AbstractShardTest {
45 public void testChangeListenerWithNoInitialData() throws Exception {
47 new ShardTestKit(getSystem()) {
49 final TestActorRef<Shard> actor = actorFactory.createTestActor(
50 newShardProps().withDispatcher(Dispatchers.DefaultDispatcherId()),
51 "testChangeListenerWithNoInitialData");
53 waitUntilLeader(actor);
55 final Shard shard = actor.underlyingActor();
56 final MockDataChangeListener listener = new MockDataChangeListener(0);
57 final ActorRef dclActor = actorFactory.createActor(DataChangeListener.props(listener, TEST_PATH),
58 "testChangeListenerWithNoInitialData-DataChangeListener");
59 final DataChangeListenerSupport support = new DataChangeListenerSupport(shard);
60 support.onMessage(new RegisterChangeListener(TEST_PATH, dclActor, DataChangeScope.ONE, false),
63 listener.expectNoMoreChanges("Unexpected initial change event");
69 public void testInitialChangeListenerEventWithContainerPath() throws Exception {
71 new ShardTestKit(getSystem()) {
73 final TestActorRef<Shard> actor = actorFactory.createTestActor(
74 newShardProps().withDispatcher(Dispatchers.DefaultDispatcherId()),
75 "testInitialChangeListenerEventWithContainerPath");
77 waitUntilLeader(actor);
79 final Shard shard = actor.underlyingActor();
80 writeToStore(shard.getDataStore(), TestModel.TEST_PATH,
81 ImmutableNodes.containerNode(TestModel.TEST_QNAME));
82 final MockDataChangeListener listener = new MockDataChangeListener(1);
83 final ActorRef dclActor = actorFactory.createActor(DataChangeListener.props(listener, TEST_PATH),
84 "testInitialChangeListenerEventWithContainerPath-DataChangeListener");
85 final DataChangeListenerSupport support = new DataChangeListenerSupport(shard);
86 support.onMessage(new RegisterChangeListener(TEST_PATH, dclActor, DataChangeScope.ONE, false),
89 listener.waitForChangeEvents(TEST_PATH);
95 public void testInitialChangeListenerEventWithListPath() throws Exception {
96 new ShardTestKit(getSystem()) {
98 final TestActorRef<Shard> actor = actorFactory.createTestActor(
99 newShardProps().withDispatcher(Dispatchers.DefaultDispatcherId()),
100 "testInitialChangeListenerEventWithListPath");
102 waitUntilLeader(actor);
104 final Shard shard = actor.underlyingActor();
105 mergeToStore(shard.getDataStore(), TEST_PATH, testNodeWithOuter(1, 2));
107 final MockDataChangeListener listener = new MockDataChangeListener(1);
108 final ActorRef dclActor = actorFactory.createActor(DataChangeListener.props(listener, OUTER_LIST_PATH),
109 "testInitialChangeListenerEventWithListPath-DataChangeListener");
110 final DataChangeListenerSupport support = new DataChangeListenerSupport(shard);
111 support.onMessage(new RegisterChangeListener(OUTER_LIST_PATH, dclActor, DataChangeScope.ONE, false),
114 listener.waitForChangeEvents();
115 assertEquals("Outer entry 1 present", true, NormalizedNodes
116 .findNode(listener.getCreatedData(0, OUTER_LIST_PATH), outerEntryKey(1)).isPresent());
117 assertEquals("Outer entry 2 present", true, NormalizedNodes
118 .findNode(listener.getCreatedData(0, OUTER_LIST_PATH), outerEntryKey(2)).isPresent());
124 public void testInitialChangeListenerEventWithWildcardedListPath() throws Exception {
126 new ShardTestKit(getSystem()) {
128 final TestActorRef<Shard> actor = actorFactory.createTestActor(
129 newShardProps().withDispatcher(Dispatchers.DefaultDispatcherId()),
130 "testInitialChangeListenerEventWithWildcardedListPath");
132 waitUntilLeader(actor);
134 final Shard shard = actor.underlyingActor();
136 mergeToStore(shard.getDataStore(), TEST_PATH, testNodeWithOuter(1, 2));
137 writeToStore(shard.getDataStore(), OUTER_CONTAINER_PATH,
138 ImmutableNodes.containerNode(OUTER_CONTAINER_QNAME));
140 final MockDataChangeListener listener = new MockDataChangeListener(1);
141 final YangInstanceIdentifier path = OUTER_LIST_PATH.node(OUTER_LIST_QNAME);
142 final ActorRef dclActor = actorFactory.createActor(DataChangeListener.props(listener, path),
143 "testInitialChangeListenerEventWithWildcardedListPath-DataChangeListener");
144 final DataChangeListenerSupport support = new DataChangeListenerSupport(shard);
145 support.onMessage(new RegisterChangeListener(path, dclActor, DataChangeScope.ONE, false), true, true);
147 listener.waitForChangeEvents();
148 listener.verifyCreatedData(0, outerEntryPath(1));
149 listener.verifyCreatedData(0, outerEntryPath(2));
150 listener.verifyNoCreatedData(0, OUTER_CONTAINER_PATH);
156 public void testInitialChangeListenerEventWithNestedWildcardedListsPath() throws Exception {
158 new ShardTestKit(getSystem()) {
160 final TestActorRef<Shard> actor = actorFactory.createTestActor(
161 newShardProps().withDispatcher(Dispatchers.DefaultDispatcherId()),
162 "testInitialChangeListenerEventWithNestedWildcardedListsPath");
164 waitUntilLeader(actor);
166 final Shard shard = actor.underlyingActor();
168 mergeToStore(shard.getDataStore(), TEST_PATH,
169 testNodeWithOuter(outerNode(outerNodeEntry(1, innerNode("one", "two")),
170 outerNodeEntry(2, innerNode("three", "four")))));
172 final MockDataChangeListener listener = new MockDataChangeListener(1);
173 final YangInstanceIdentifier path = OUTER_LIST_PATH.node(OUTER_LIST_QNAME)
174 .node(INNER_LIST_QNAME).node(INNER_LIST_QNAME);
175 final ActorRef dclActor = actorFactory.createActor(DataChangeListener.props(listener, path),
176 "testInitialChangeListenerEventWithNestedWildcardedListsPath-DataChangeListener");
177 final DataChangeListenerSupport support = new DataChangeListenerSupport(shard);
178 support.onMessage(new RegisterChangeListener(path, dclActor, DataChangeScope.ONE, false), true, true);
181 listener.waitForChangeEvents();
182 listener.verifyCreatedData(0, innerEntryPath(1, "one"));
183 listener.verifyCreatedData(0, innerEntryPath(1, "two"));
184 listener.verifyCreatedData(0, innerEntryPath(2, "three"));
185 listener.verifyCreatedData(0, innerEntryPath(2, "four"));
187 // Register for a specific outer list entry
188 final MockDataChangeListener listener2 = new MockDataChangeListener(1);
189 final YangInstanceIdentifier path2 = OUTER_LIST_PATH.node(outerEntryKey(1)).node(INNER_LIST_QNAME)
190 .node(INNER_LIST_QNAME);
191 final ActorRef dclActor2 = actorFactory.createActor(DataChangeListener.props(listener2, path2),
192 "testInitialChangeListenerEventWithNestedWildcardedListsPath-DataChangeListener2");
193 final DataChangeListenerSupport support2 = new DataChangeListenerSupport(shard);
194 support2.onMessage(new RegisterChangeListener(path2, dclActor2, DataChangeScope.ONE, false),
197 listener2.waitForChangeEvents();
198 listener2.verifyCreatedData(0, innerEntryPath(1, "one"));
199 listener2.verifyCreatedData(0, innerEntryPath(1, "two"));
200 listener2.verifyNoCreatedData(0, innerEntryPath(2, "three"));
201 listener2.verifyNoCreatedData(0, innerEntryPath(2, "four"));
207 public void testInitialChangeListenerEventWhenNotInitiallyLeader() throws Exception {
209 new ShardTestKit(getSystem()) {
211 final TestActorRef<Shard> actor = actorFactory.createTestActor(
212 newShardProps().withDispatcher(Dispatchers.DefaultDispatcherId()),
213 "testInitialChangeListenerEventWhenNotInitiallyLeader");
215 waitUntilLeader(actor);
217 final Shard shard = actor.underlyingActor();
219 mergeToStore(shard.getDataStore(), TEST_PATH,
220 testNodeWithOuter(outerNode(outerNodeEntry(1, innerNode("one", "two")),
221 outerNodeEntry(2, innerNode("three", "four")))));
223 final MockDataChangeListener listener = new MockDataChangeListener(0);
224 final YangInstanceIdentifier path = OUTER_LIST_PATH.node(OUTER_LIST_QNAME).node(INNER_LIST_QNAME)
225 .node(INNER_LIST_QNAME);
226 final ActorRef dclActor = actorFactory.createActor(DataChangeListener.props(listener, path),
227 "testInitialChangeListenerEventWhenNotInitiallyLeader-DataChangeListener");
228 final DataChangeListenerSupport support = new DataChangeListenerSupport(shard);
229 support.onMessage(new RegisterChangeListener(path, dclActor, DataChangeScope.ONE, false), false, true);
231 listener.expectNoMoreChanges("Unexpected initial change event");
234 support.onLeadershipChange(true, true);
236 listener.waitForChangeEvents();
237 listener.verifyCreatedData(0, innerEntryPath(1, "one"));
238 listener.verifyCreatedData(0, innerEntryPath(1, "two"));
239 listener.verifyCreatedData(0, innerEntryPath(2, "three"));
240 listener.verifyCreatedData(0, innerEntryPath(2, "four"));