Bug 4105: Add EntityOwnershipListenerActor and support
[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.ActorRef;
17 import akka.actor.Props;
18 import akka.actor.UntypedActorContext;
19 import akka.testkit.JavaTestKit;
20 import akka.testkit.TestActorRef;
21 import com.google.common.util.concurrent.Uninterruptibles;
22 import java.util.concurrent.TimeUnit;
23 import org.junit.After;
24 import org.junit.Test;
25 import org.opendaylight.controller.cluster.datastore.AbstractActorTest;
26 import org.opendaylight.controller.cluster.raft.TestActorFactory;
27 import org.opendaylight.controller.cluster.raft.utils.DoNothingActor;
28 import org.opendaylight.controller.md.sal.common.api.clustering.Entity;
29 import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipListener;
30 import org.opendaylight.yangtools.yang.common.QName;
31 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
32 import scala.collection.Iterator;
33 import scala.collection.immutable.Iterable;
34
35 /**
36  * Unit tests for EntityOwnershipListenerSupport.
37  *
38  * @author Thomas Pantelis
39  */
40 public class EntityOwnershipListenerSupportTest extends AbstractActorTest {
41     private final TestActorFactory actorFactory = new TestActorFactory(getSystem());
42
43     @After
44     public void tearDown() {
45         actorFactory.close();
46     }
47
48     @Test
49     public void testNotifyEntityOwnershipListeners() {
50         TestActorRef<DoNothingActor> actor = actorFactory.createTestActor(
51                 Props.create(DoNothingActor.class), actorFactory.generateActorId("test"));
52
53         UntypedActorContext actorContext = actor.underlyingActor().getContext();
54         EntityOwnershipListenerSupport support = new EntityOwnershipListenerSupport(actorContext);
55
56         EntityOwnershipListener mockListener1 = mock(EntityOwnershipListener.class, "EntityOwnershipListener1");
57         EntityOwnershipListener mockListener2 = mock(EntityOwnershipListener.class, "EntityOwnershipListener2");
58         Entity entity1 = new Entity("test", YangInstanceIdentifier.of(QName.create("test", "id1")));
59         Entity entity2 = new Entity("test", YangInstanceIdentifier.of(QName.create("test", "id2")));
60
61         // Add EntityOwnershipListener registrations.
62
63         support.addEntityOwnershipListener(entity1, mockListener1);
64         support.addEntityOwnershipListener(entity2, mockListener1);
65         support.addEntityOwnershipListener(entity1, mockListener2);
66
67         // Notify entity1 changed and verify both listeners are notified.
68
69         support.notifyEntityOwnershipListeners(entity1, false, true);
70
71         verify(mockListener1, timeout(5000)).ownershipChanged(entity1, false, true);
72         verify(mockListener2, timeout(5000)).ownershipChanged(entity1, false, true);
73         assertEquals("# of listener actors", 2, actorContext.children().size());
74
75         // Notify entity2 changed and verify only mockListener1 is notified.
76
77         support.notifyEntityOwnershipListeners(entity2, false, true);
78
79         verify(mockListener1, timeout(5000)).ownershipChanged(entity2, false, true);
80         verify(mockListener2, never()).ownershipChanged(entity2, false, true);
81         assertEquals("# of listener actors", 2, actorContext.children().size());
82
83         // Notify entity3 changed and verify neither listener is notified.
84
85         Entity entity3 = new Entity("test", YangInstanceIdentifier.of(QName.create("test", "id3")));
86         support.notifyEntityOwnershipListeners(entity3, false, true);
87
88         Uninterruptibles.sleepUninterruptibly(500, TimeUnit.MILLISECONDS);
89
90         verify(mockListener1, never()).ownershipChanged(entity3, false, true);
91         verify(mockListener2, never()).ownershipChanged(entity3, false, true);
92
93         reset(mockListener1, mockListener2);
94
95         // Unregister mockListener1 for entity1, issue a change and verify only mockListener2 is notified.
96
97         support.removeEntityOwnershipListener(entity1, mockListener1);
98
99         support.notifyEntityOwnershipListeners(entity1, false, true);
100
101         verify(mockListener2, timeout(5000)).ownershipChanged(entity1, false, true);
102         verify(mockListener1, never()).ownershipChanged(entity1, false, true);
103
104         // Completely unregister both listeners and verify their listener actors are destroyed.
105
106         Iterable<ActorRef> listenerActors = actorContext.children();
107         assertEquals("# of listener actors", 2, listenerActors.size());
108
109         Iterator<ActorRef> iter = listenerActors.iterator();
110         ActorRef listenerActor1 = iter.next();
111         ActorRef listenerActor2 = iter.next();
112
113         JavaTestKit kit1 = new JavaTestKit(getSystem());
114         kit1.watch(listenerActor1);
115
116         JavaTestKit kit2 = new JavaTestKit(getSystem());
117         kit2.watch(listenerActor2);
118
119         support.removeEntityOwnershipListener(entity2, mockListener1);
120         support.removeEntityOwnershipListener(entity1, mockListener2);
121
122         kit1.expectTerminated(JavaTestKit.duration("3 seconds"), listenerActor1);
123         kit2.expectTerminated(JavaTestKit.duration("3 seconds"), listenerActor2);
124         assertEquals("# of listener actors", 0, actorContext.children().size());
125
126         // Re-register mockListener1 for entity1 and verify it is notified.
127
128         reset(mockListener1, mockListener2);
129
130         support.addEntityOwnershipListener(entity1, mockListener1);
131
132         support.notifyEntityOwnershipListeners(entity1, false, true);
133
134         verify(mockListener1, timeout(5000)).ownershipChanged(entity1, false, true);
135         verify(mockListener2, never()).ownershipChanged(entity2, false, true);
136
137         // Quickly register and unregister mockListener2 - expecting no exceptions.
138
139         support.addEntityOwnershipListener(entity1, mockListener2);
140         support.removeEntityOwnershipListener(entity1, mockListener2);
141     }
142 }