fc70e3308c4f0a965c0e8fc501a735adb4e281a1
[controller.git] / opendaylight / md-sal / sal-distributed-datastore / src / test / java / org / opendaylight / controller / cluster / datastore / DataChangeListenerSupportTest.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.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;
24
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.schema.NormalizedNodes;
34 import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes;
35
36 /**
37  * Unit tests for DataChangeListenerSupport.
38  *
39  * @author Thomas Pantelis
40  */
41 public class DataChangeListenerSupportTest extends AbstractShardTest {
42
43     @Test
44     public void testChangeListenerWithNoInitialData() throws Exception {
45
46         new ShardTestKit(getSystem()) {
47             {
48                 final TestActorRef<Shard> actor = actorFactory.createTestActor(
49                         newShardProps().withDispatcher(Dispatchers.DefaultDispatcherId()),
50                         "testChangeListenerWithNoInitialData");
51
52                 waitUntilLeader(actor);
53
54                 final Shard shard = actor.underlyingActor();
55                 final MockDataChangeListener listener = new MockDataChangeListener(0);
56                 final ActorRef dclActor = actorFactory.createActor(DataChangeListener.props(listener),
57                         "testChangeListenerWithNoInitialData-DataChangeListener");
58                 final DataChangeListenerSupport support = new DataChangeListenerSupport(shard);
59                 support.onMessage(new RegisterChangeListener(TEST_PATH, dclActor, DataChangeScope.ONE, false),
60                         true,true);
61
62                 listener.expectNoMoreChanges("Unexpected initial change event");
63             }
64         };
65     }
66
67     @Test
68     public void testInitialChangeListenerEventWithContainerPath() throws Exception {
69
70         new ShardTestKit(getSystem()) {
71             {
72                 final TestActorRef<Shard> actor = actorFactory.createTestActor(
73                         newShardProps().withDispatcher(Dispatchers.DefaultDispatcherId()),
74                         "testInitialChangeListenerEventWithContainerPath");
75
76                 waitUntilLeader(actor);
77
78                 final Shard shard = actor.underlyingActor();
79                 writeToStore(shard.getDataStore(), TestModel.TEST_PATH,
80                         ImmutableNodes.containerNode(TestModel.TEST_QNAME));
81                 final MockDataChangeListener listener = new MockDataChangeListener(1);
82                 final ActorRef dclActor = actorFactory.createActor(DataChangeListener.props(listener),
83                         "testInitialChangeListenerEventWithContainerPath-DataChangeListener");
84                 final DataChangeListenerSupport support = new DataChangeListenerSupport(shard);
85                 support.onMessage(new RegisterChangeListener(TEST_PATH, dclActor, DataChangeScope.ONE, false),
86                         true,true);
87
88                 listener.waitForChangeEvents(TEST_PATH);
89             }
90         };
91     }
92
93     @Test
94     public void testInitialChangeListenerEventWithListPath() throws Exception {
95         new ShardTestKit(getSystem()) {
96             {
97                 final TestActorRef<Shard> actor = actorFactory.createTestActor(
98                         newShardProps().withDispatcher(Dispatchers.DefaultDispatcherId()),
99                         "testInitialChangeListenerEventWithListPath");
100
101                 waitUntilLeader(actor);
102
103                 final Shard shard = actor.underlyingActor();
104                 mergeToStore(shard.getDataStore(), TEST_PATH, testNodeWithOuter(1, 2));
105
106                 final MockDataChangeListener listener = new MockDataChangeListener(1);
107                 final ActorRef dclActor = actorFactory.createActor(DataChangeListener.props(listener),
108                         "testInitialChangeListenerEventWithListPath-DataChangeListener");
109                 final DataChangeListenerSupport support = new DataChangeListenerSupport(shard);
110                 support.onMessage(new RegisterChangeListener(OUTER_LIST_PATH, dclActor, DataChangeScope.ONE, false),
111                         true, true);
112
113                 listener.waitForChangeEvents();
114                 assertEquals("Outer entry 1 present", true, NormalizedNodes
115                         .findNode(listener.getCreatedData(0, OUTER_LIST_PATH), outerEntryKey(1)).isPresent());
116                 assertEquals("Outer entry 2 present", true, NormalizedNodes
117                         .findNode(listener.getCreatedData(0, OUTER_LIST_PATH), outerEntryKey(2)).isPresent());
118             }
119         };
120     }
121
122     @Test
123     public void testInitialChangeListenerEventWithWildcardedListPath() throws Exception {
124
125         new ShardTestKit(getSystem()) {
126             {
127                 final TestActorRef<Shard> actor = actorFactory.createTestActor(
128                         newShardProps().withDispatcher(Dispatchers.DefaultDispatcherId()),
129                         "testInitialChangeListenerEventWithWildcardedListPath");
130
131                 waitUntilLeader(actor);
132
133                 final Shard shard = actor.underlyingActor();
134
135                 mergeToStore(shard.getDataStore(), TEST_PATH, testNodeWithOuter(1, 2));
136                 writeToStore(shard.getDataStore(), OUTER_CONTAINER_PATH,
137                         ImmutableNodes.containerNode(OUTER_CONTAINER_QNAME));
138
139                 final MockDataChangeListener listener = new MockDataChangeListener(1);
140                 final ActorRef dclActor = actorFactory.createActor(DataChangeListener.props(listener),
141                         "testInitialChangeListenerEventWithWildcardedListPath-DataChangeListener");
142                 final DataChangeListenerSupport support = new DataChangeListenerSupport(shard);
143                 support.onMessage(new RegisterChangeListener(OUTER_LIST_PATH.node(OUTER_LIST_QNAME), dclActor,
144                         DataChangeScope.ONE, false), true, true);
145
146                 listener.waitForChangeEvents();
147                 listener.verifyCreatedData(0, outerEntryPath(1));
148                 listener.verifyCreatedData(0, outerEntryPath(2));
149                 listener.verifyNoCreatedData(0, OUTER_CONTAINER_PATH);
150             }
151         };
152     }
153
154     @Test
155     public void testInitialChangeListenerEventWithNestedWildcardedListsPath() throws Exception {
156
157         new ShardTestKit(getSystem()) {
158             {
159                 final TestActorRef<Shard> actor = actorFactory.createTestActor(
160                         newShardProps().withDispatcher(Dispatchers.DefaultDispatcherId()),
161                         "testInitialChangeListenerEventWithNestedWildcardedListsPath");
162
163                 waitUntilLeader(actor);
164
165                 final Shard shard = actor.underlyingActor();
166
167                 mergeToStore(shard.getDataStore(), TEST_PATH,
168                         testNodeWithOuter(outerNode(outerNodeEntry(1, innerNode("one", "two")),
169                                 outerNodeEntry(2, innerNode("three", "four")))));
170
171                 final MockDataChangeListener listener = new MockDataChangeListener(1);
172                 final ActorRef dclActor = actorFactory.createActor(DataChangeListener.props(listener),
173                         "testInitialChangeListenerEventWithNestedWildcardedListsPath-DataChangeListener");
174                 final DataChangeListenerSupport support = new DataChangeListenerSupport(shard);
175                 support.onMessage(new RegisterChangeListener(OUTER_LIST_PATH.node(OUTER_LIST_QNAME)
176                         .node(INNER_LIST_QNAME).node(INNER_LIST_QNAME), dclActor, DataChangeScope.ONE, false),
177                             true, true);
178
179
180                 listener.waitForChangeEvents();
181                 listener.verifyCreatedData(0, innerEntryPath(1, "one"));
182                 listener.verifyCreatedData(0, innerEntryPath(1, "two"));
183                 listener.verifyCreatedData(0, innerEntryPath(2, "three"));
184                 listener.verifyCreatedData(0, innerEntryPath(2, "four"));
185
186                 // Register for a specific outer list entry
187                 final MockDataChangeListener listener2 = new MockDataChangeListener(1);
188                 final ActorRef dclActor2 = actorFactory.createActor(DataChangeListener.props(listener2),
189                         "testInitialChangeListenerEventWithNestedWildcardedListsPath-DataChangeListener2");
190                 final DataChangeListenerSupport support2 = new DataChangeListenerSupport(shard);
191                 support2.onMessage(new RegisterChangeListener(
192                         OUTER_LIST_PATH.node(outerEntryKey(1)).node(INNER_LIST_QNAME).node(INNER_LIST_QNAME), dclActor2,
193                         DataChangeScope.ONE, false), true, true);
194
195                 listener2.waitForChangeEvents();
196                 listener2.verifyCreatedData(0, innerEntryPath(1, "one"));
197                 listener2.verifyCreatedData(0, innerEntryPath(1, "two"));
198                 listener2.verifyNoCreatedData(0, innerEntryPath(2, "three"));
199                 listener2.verifyNoCreatedData(0, innerEntryPath(2, "four"));
200             }
201         };
202     }
203
204     @Test
205     public void testInitialChangeListenerEventWhenNotInitiallyLeader() throws Exception {
206
207         new ShardTestKit(getSystem()) {
208             {
209                 final TestActorRef<Shard> actor = actorFactory.createTestActor(
210                         newShardProps().withDispatcher(Dispatchers.DefaultDispatcherId()),
211                         "testInitialChangeListenerEventWhenNotInitiallyLeader");
212
213                 waitUntilLeader(actor);
214
215                 final Shard shard = actor.underlyingActor();
216
217                 mergeToStore(shard.getDataStore(), TEST_PATH,
218                         testNodeWithOuter(outerNode(outerNodeEntry(1, innerNode("one", "two")),
219                                 outerNodeEntry(2, innerNode("three", "four")))));
220
221                 final MockDataChangeListener listener = new MockDataChangeListener(0);
222                 final ActorRef dclActor = actorFactory.createActor(DataChangeListener.props(listener),
223                         "testInitialChangeListenerEventWhenNotInitiallyLeader-DataChangeListener");
224                 final DataChangeListenerSupport support = new DataChangeListenerSupport(shard);
225                 support.onMessage(new RegisterChangeListener(
226                         OUTER_LIST_PATH.node(OUTER_LIST_QNAME).node(INNER_LIST_QNAME).node(INNER_LIST_QNAME), dclActor,
227                         DataChangeScope.ONE, false), false, true);
228
229                 listener.expectNoMoreChanges("Unexpected initial change event");
230                 listener.reset(1);
231
232                 support.onLeadershipChange(true, true);
233
234                 listener.waitForChangeEvents();
235                 listener.verifyCreatedData(0, innerEntryPath(1, "one"));
236                 listener.verifyCreatedData(0, innerEntryPath(1, "two"));
237                 listener.verifyCreatedData(0, innerEntryPath(2, "three"));
238                 listener.verifyCreatedData(0, innerEntryPath(2, "four"));
239             }
240         };
241     }
242 }