2394ee0bb15b5a6e35e92f2607198ad7cda827b4
[controller.git] / opendaylight / md-sal / sal-distributed-datastore / src / test / java / org / opendaylight / controller / cluster / datastore / entityownership / EntityOwnershipListenerSupportTest.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.entityownership;
9
10 import static org.junit.Assert.assertEquals;
11 import static org.mockito.Mockito.mock;
12 import static org.mockito.Mockito.never;
13 import static org.mockito.Mockito.reset;
14 import static org.mockito.Mockito.timeout;
15 import static org.mockito.Mockito.verify;
16 import akka.actor.ActorContext;
17 import akka.actor.ActorRef;
18 import akka.actor.Props;
19 import akka.testkit.JavaTestKit;
20 import akka.testkit.TestActorRef;
21 import com.google.common.util.concurrent.Uninterruptibles;
22 import java.util.ArrayList;
23 import java.util.List;
24 import java.util.concurrent.TimeUnit;
25 import org.junit.After;
26 import org.junit.Before;
27 import org.junit.Test;
28 import org.opendaylight.controller.cluster.raft.TestActorFactory;
29 import org.opendaylight.controller.cluster.raft.utils.DoNothingActor;
30 import org.opendaylight.controller.md.sal.common.api.clustering.Entity;
31 import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipCandidate;
32 import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipListener;
33 import org.opendaylight.yangtools.yang.common.QName;
34 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
35 import scala.collection.Iterator;
36 import scala.collection.immutable.Iterable;
37
38 /**
39  * Unit tests for EntityOwnershipListenerSupport.
40  *
41  * @author Thomas Pantelis
42  */
43 public class EntityOwnershipListenerSupportTest extends AbstractEntityOwnershipTest {
44     private final TestActorFactory actorFactory = new TestActorFactory(getSystem());
45     private ActorContext actorContext;
46
47     @Before
48     public void setup() {
49         TestActorRef<DoNothingActor> actor = actorFactory.createTestActor(
50                 Props.create(DoNothingActor.class), actorFactory.generateActorId("test"));
51
52         actorContext = actor.underlyingActor().getContext();
53     }
54
55     @After
56     public void tearDown() {
57         actorFactory.close();
58     }
59
60     @Test
61     public void testNotifyEntityOwnershipListeners() {
62         EntityOwnershipListenerSupport support = new EntityOwnershipListenerSupport(actorContext, "test");
63
64         EntityOwnershipListener mockListener1 = mock(EntityOwnershipListener.class, "EntityOwnershipListener1");
65         EntityOwnershipListener mockListener2 = mock(EntityOwnershipListener.class, "EntityOwnershipListener2");
66         EntityOwnershipListener mockListener3 = mock(EntityOwnershipListener.class, "EntityOwnershipListener3");
67         Entity entity1 = new Entity("type1", YangInstanceIdentifier.of(QName.create("test", "id1")));
68         Entity entity2 = new Entity("type1", YangInstanceIdentifier.of(QName.create("test", "id2")));
69         Entity entity3 = new Entity("type1", YangInstanceIdentifier.of(QName.create("test", "id3")));
70         Entity entity4 = new Entity("type2", YangInstanceIdentifier.of(QName.create("test", "id4")));
71         Entity entity5 = new Entity("noListener", YangInstanceIdentifier.of(QName.create("test", "id5")));
72
73         // Add EntityOwnershipListener registrations.
74
75         support.addEntityOwnershipListener(entity1, mockListener1);
76         support.addEntityOwnershipListener(entity1, mockListener1); // register again - should be noop
77         support.addEntityOwnershipListener(entity2, mockListener1);
78         support.addEntityOwnershipListener(entity1, mockListener2);
79         support.addEntityOwnershipListener(entity1.getType(), mockListener3);
80
81         // Notify entity1 changed and verify listeners are notified.
82
83         support.notifyEntityOwnershipListeners(entity1, false, true, true);
84
85         verify(mockListener1, timeout(5000)).ownershipChanged(ownershipChange(entity1, false, true, true));
86         verify(mockListener2, timeout(5000)).ownershipChanged(ownershipChange(entity1, false, true, true));
87         verify(mockListener3, timeout(5000)).ownershipChanged(ownershipChange(entity1, false, true, true));
88         assertEquals("# of listener actors", 3, actorContext.children().size());
89
90         // Notify entity2 changed and verify only mockListener1 and mockListener3 are notified.
91
92         support.notifyEntityOwnershipListeners(entity2, false, false, false);
93
94         verify(mockListener1, timeout(5000)).ownershipChanged(ownershipChange(entity2, false, false, false));
95         verify(mockListener3, timeout(5000)).ownershipChanged(ownershipChange(entity2, false, false, false));
96         Uninterruptibles.sleepUninterruptibly(300, TimeUnit.MILLISECONDS);
97         verify(mockListener2, never()).ownershipChanged(ownershipChange(entity2));
98         assertEquals("# of listener actors", 3, actorContext.children().size());
99
100         // Notify entity3 changed and verify only mockListener3 is notified.
101
102         support.notifyEntityOwnershipListeners(entity3, false, true, true);
103
104         verify(mockListener3, timeout(5000)).ownershipChanged(ownershipChange(entity3, false, true, true));
105         Uninterruptibles.sleepUninterruptibly(300, TimeUnit.MILLISECONDS);
106         verify(mockListener1, never()).ownershipChanged(ownershipChange(entity3));
107         verify(mockListener2, never()).ownershipChanged(ownershipChange(entity3));
108
109         // Notify entity4 changed and verify no listeners are notified.
110
111         support.notifyEntityOwnershipListeners(entity4, true, false, true);
112
113         Uninterruptibles.sleepUninterruptibly(300, TimeUnit.MILLISECONDS);
114         verify(mockListener1, never()).ownershipChanged(ownershipChange(entity4));
115         verify(mockListener2, never()).ownershipChanged(ownershipChange(entity4));
116         verify(mockListener3, never()).ownershipChanged(ownershipChange(entity4));
117
118         // Notify entity5 changed and verify no listener is notified.
119
120         support.notifyEntityOwnershipListeners(entity5, true, false, true);
121
122         Uninterruptibles.sleepUninterruptibly(300, TimeUnit.MILLISECONDS);
123         verify(mockListener1, never()).ownershipChanged(ownershipChange(entity4));
124         verify(mockListener2, never()).ownershipChanged(ownershipChange(entity4));
125         verify(mockListener3, never()).ownershipChanged(ownershipChange(entity4));
126
127         reset(mockListener1, mockListener2, mockListener3);
128
129         // Unregister mockListener1 for entity1, issue a change and verify only mockListeners 2 & 3 are notified.
130
131         support.removeEntityOwnershipListener(entity1, mockListener1);
132         support.notifyEntityOwnershipListeners(entity1, true, false, true);
133
134         verify(mockListener2, timeout(5000)).ownershipChanged(ownershipChange(entity1, true, false, true));
135         verify(mockListener3, timeout(5000)).ownershipChanged(ownershipChange(entity1, true, false, true));
136         Uninterruptibles.sleepUninterruptibly(300, TimeUnit.MILLISECONDS);
137         verify(mockListener1, never()).ownershipChanged(ownershipChange(entity1));
138
139         // Unregister mockListener3, issue a change for entity1 and verify only mockListeners2 is notified.
140
141         reset(mockListener1, mockListener2, mockListener3);
142
143         support.removeEntityOwnershipListener(entity1.getType(), mockListener3);
144         support.notifyEntityOwnershipListeners(entity1, false, false, false);
145
146         verify(mockListener2, timeout(5000)).ownershipChanged(ownershipChange(entity1, false, false, false));
147         Uninterruptibles.sleepUninterruptibly(300, TimeUnit.MILLISECONDS);
148         verify(mockListener1, never()).ownershipChanged(ownershipChange(entity1));
149         verify(mockListener3, never()).ownershipChanged(ownershipChange(entity1));
150
151         // Completely unregister all listeners and verify their listener actors are destroyed.
152
153         Iterable<ActorRef> listenerActors = actorContext.children();
154         assertEquals("# of listener actors", 2, listenerActors.size());
155
156         List<JavaTestKit> watchers = new ArrayList<>();
157         for(Iterator<ActorRef> iter = listenerActors.iterator(); iter.hasNext();) {
158             JavaTestKit kit = new JavaTestKit(getSystem());
159             kit.watch(iter.next());
160             watchers.add(kit);
161         }
162
163         support.removeEntityOwnershipListener(entity2, mockListener1);
164         support.removeEntityOwnershipListener(entity2, mockListener1); // un-register again - shoild be noop
165         support.removeEntityOwnershipListener(entity1, mockListener2);
166
167         Iterator<ActorRef> iter = listenerActors.iterator();
168         for(JavaTestKit kit: watchers) {
169             kit.expectTerminated(JavaTestKit.duration("3 seconds"), iter.next());
170         }
171
172         assertEquals("# of listener actors", 0, actorContext.children().size());
173
174         // Re-register mockListener1 for entity1 and verify it is notified.
175
176         reset(mockListener1, mockListener2);
177
178         support.addEntityOwnershipListener(entity1, mockListener1);
179
180         support.notifyEntityOwnershipListeners(entity1, false, false, true);
181
182         verify(mockListener1, timeout(5000)).ownershipChanged(ownershipChange(entity1, false, false, true));
183         verify(mockListener2, never()).ownershipChanged(ownershipChange(entity1));
184         verify(mockListener3, never()).ownershipChanged(ownershipChange(entity1));
185
186         // Quickly register and unregister mockListener2 - expecting no exceptions.
187
188         support.addEntityOwnershipListener(entity1, mockListener2);
189         support.removeEntityOwnershipListener(entity1, mockListener2);
190     }
191
192     @Test
193     public void testHasCandidateForEntity() {
194         EntityOwnershipListenerSupport support = new EntityOwnershipListenerSupport(actorContext, "test");
195         Entity entity = new Entity("type", YangInstanceIdentifier.of(QName.create("test", "id")));
196
197         assertEquals("hasCandidateForEntity", false, support.hasCandidateForEntity(entity));
198
199         support.addEntityOwnershipListener(entity, mock(EntityOwnershipListener.class));
200         assertEquals("hasCandidateForEntity", false, support.hasCandidateForEntity(entity));
201
202         EntityOwnershipCandidate candidate = mock(EntityOwnershipCandidate.class);
203         support.addEntityOwnershipListener(entity, candidate);
204         assertEquals("hasCandidateForEntity", true, support.hasCandidateForEntity(entity));
205
206         support.removeEntityOwnershipListener(entity, candidate);
207         assertEquals("hasCandidateForEntity", false, support.hasCandidateForEntity(entity));
208     }
209 }