2 * Copyright (c) 2021 PANTHEON.tech, s.r.o. 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.eos.akka;
10 import akka.actor.testkit.typed.javadsl.ActorTestKit;
11 import akka.cluster.Member;
12 import akka.cluster.MemberStatus;
13 import akka.cluster.typed.Cluster;
14 import com.google.common.collect.ImmutableList;
15 import java.time.Duration;
16 import java.util.List;
17 import org.awaitility.Awaitility;
18 import org.junit.After;
19 import org.junit.Before;
20 import org.junit.Test;
21 import org.opendaylight.mdsal.eos.dom.api.DOMEntity;
23 public class ThreeNodeBaseTest extends AbstractNativeEosTest {
24 public static final DOMEntity ENTITY_1 = new DOMEntity("test-type", "entity-1");
25 public static final DOMEntity ENTITY_2 = new DOMEntity("test-type-2", "entity-2");
27 private ClusterNode node1;
28 private ClusterNode node2;
29 private ClusterNode node3;
32 public void setUp() throws Exception {
33 node1 = startupRemote(2550, List.of("member-1"));
34 node2 = startupRemote(2551, List.of("member-2"));
35 node3 = startupRemote(2552, List.of("member-3"));
37 // need to wait until all nodes are ready
38 final Cluster cluster = Cluster.get(node3.getActorSystem());
39 // need a longer timeout with classic remoting, artery.tcp doesnt need to wait as long for init
40 Awaitility.await().atMost(Duration.ofSeconds(20)).until(() -> {
41 final List<Member> members = ImmutableList.copyOf(cluster.state().getMembers());
42 if (members.size() != 3) {
46 for (final Member member : members) {
47 if (!member.status().equals(MemberStatus.up())) {
57 public void tearDown() {
58 // same issue with classic remoting as in setup
59 ActorTestKit.shutdown(node1.getActorSystem(), Duration.ofSeconds(20));
60 ActorTestKit.shutdown(node2.getActorSystem(), Duration.ofSeconds(20));
61 ActorTestKit.shutdown(node3.getActorSystem(), Duration.ofSeconds(20));
65 public void testInitialNotificationsWithoutOwner() throws Exception {
66 final MockEntityOwnershipListener listener1 = registerListener(node1, ENTITY_1);
67 verifyNoNotifications(listener1);
69 final MockEntityOwnershipListener listener2 = registerListener(node2, ENTITY_1);
70 verifyNoNotifications(listener2);
72 final MockEntityOwnershipListener listener3 = registerListener(node3, ENTITY_1);
73 verifyNoNotifications(listener3);
77 public void testInitialNotificationsWithOwner() {
78 registerCandidates(node1, ENTITY_1, "member-1");
79 // make sure we register other candidates after the first is seen everywhere to prevent different results due
81 waitUntillOwnerPresent(node3, ENTITY_1);
83 registerCandidates(node2, ENTITY_1, "member-2");
84 registerCandidates(node3, ENTITY_1, "member-3");
86 final MockEntityOwnershipListener listener1 = registerListener(node1, ENTITY_1);
87 verifyListenerState(listener1, ENTITY_1, true, true, false);
89 final MockEntityOwnershipListener listener2 = registerListener(node2, ENTITY_1);
90 verifyListenerState(listener2, ENTITY_1, true, false, false);
92 final MockEntityOwnershipListener listener3 = registerListener(node3, ENTITY_1);
93 verifyListenerState(listener3, ENTITY_1, true, false, false);
97 public void testMultipleEntities() {
98 registerCandidates(node1, ENTITY_1, "member-1");
99 registerCandidates(node2, ENTITY_1, "member-2");
100 registerCandidates(node3, ENTITY_1, "member-3");
102 waitUntillOwnerPresent(node3, ENTITY_1);
104 registerCandidates(node2, ENTITY_2, "member-2");
105 waitUntillOwnerPresent(node2, ENTITY_2);
106 registerCandidates(node1, ENTITY_2, "member-1");
108 final MockEntityOwnershipListener firstEntityListener1 = registerListener(node1, ENTITY_1);
109 final MockEntityOwnershipListener firstEntityListener2 = registerListener(node2, ENTITY_1);
110 final MockEntityOwnershipListener firstEntityListener3 = registerListener(node3, ENTITY_1);
112 verifyListenerState(firstEntityListener1, ENTITY_1, true, true, false);
113 verifyListenerState(firstEntityListener2, ENTITY_1, true, false, false);
114 verifyListenerState(firstEntityListener3, ENTITY_1, true, false, false);
116 final MockEntityOwnershipListener secondEntityListener1 = registerListener(node1, ENTITY_2);
117 final MockEntityOwnershipListener secondEntityListener2 = registerListener(node2, ENTITY_2);
118 final MockEntityOwnershipListener secondEntityListener3 = registerListener(node3, ENTITY_2);
120 verifyListenerState(secondEntityListener1, ENTITY_2, true, false, false);
121 verifyListenerState(secondEntityListener2, ENTITY_2, true, true, false);
122 verifyListenerState(secondEntityListener3, ENTITY_2, true, false, false);
124 unregisterCandidates(node1, ENTITY_1, "member-1");
126 verifyListenerState(firstEntityListener1, ENTITY_1, true, false, true);
127 verifyListenerState(firstEntityListener2, ENTITY_1, true, true, false);
128 verifyListenerState(firstEntityListener3, ENTITY_1, true, false, false);
130 unregisterCandidates(node2, ENTITY_1, "member-2");
132 verifyListenerState(firstEntityListener1, ENTITY_1, true, false, false);
133 verifyListenerState(firstEntityListener2, ENTITY_1, true, false, true);
134 verifyListenerState(firstEntityListener3, ENTITY_1, true, true, false);
136 unregisterCandidates(node3, ENTITY_1, "member-3");
138 verifyListenerState(firstEntityListener1, ENTITY_1, false, false, false);
139 verifyListenerState(firstEntityListener2, ENTITY_1, false, false, false);
140 verifyListenerState(firstEntityListener3, ENTITY_1, false, false, true);
142 // check second listener hasnt moved
143 verifyListenerState(secondEntityListener1, ENTITY_2, true, false, false);
144 verifyListenerState(secondEntityListener2, ENTITY_2, true, true, false);
145 verifyListenerState(secondEntityListener3, ENTITY_2, true, false, false);
147 registerCandidates(node1, ENTITY_1, "member-1");
149 verifyListenerState(firstEntityListener1, ENTITY_1, true, true, false);
150 verifyListenerState(firstEntityListener2, ENTITY_1, true, false, false);
151 verifyListenerState(firstEntityListener3, ENTITY_1, true, false, false);