blob: a8c99fd2a88542cb130951f1da0f36936e8e5c0b [file] [log] [blame]
Madan Jampani5e5b3d62016-02-01 16:03:33 -08001/*
Brian O'Connor5ab426f2016-04-09 01:19:45 -07002 * Copyright 2016-present Open Networking Laboratory
Madan Jampani5e5b3d62016-02-01 16:03:33 -08003 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16package org.onosproject.store.primitives.resources.impl;
17
18import java.util.LinkedList;
19import java.util.Queue;
20import java.util.concurrent.CompletableFuture;
21import java.util.function.Consumer;
22
Aaron Kruglikovb5a41e52016-06-23 15:37:41 -070023import org.junit.AfterClass;
24import org.junit.BeforeClass;
Aaron Kruglikov43d843d2016-07-01 06:39:38 -070025import org.junit.Ignore;
Madan Jampani5e5b3d62016-02-01 16:03:33 -080026import org.junit.Test;
27
28import static org.junit.Assert.*;
29
30import org.onosproject.cluster.Leadership;
31import org.onosproject.cluster.NodeId;
32import org.onosproject.event.Change;
33
34import io.atomix.Atomix;
Madan Jampani630e7ac2016-05-31 11:34:05 -070035import io.atomix.AtomixClient;
Madan Jampani5e5b3d62016-02-01 16:03:33 -080036import io.atomix.resource.ResourceType;
37
38/**
39 * Unit tests for {@link AtomixLeaderElector}.
40 */
Aaron Kruglikov43d843d2016-07-01 06:39:38 -070041@Ignore
Madan Jampani5e5b3d62016-02-01 16:03:33 -080042public class AtomixLeaderElectorTest extends AtomixTestBase {
43
44 NodeId node1 = new NodeId("node1");
45 NodeId node2 = new NodeId("node2");
46 NodeId node3 = new NodeId("node3");
47
Aaron Kruglikovb5a41e52016-06-23 15:37:41 -070048 @BeforeClass
49 public static void preTestSetup() throws Throwable {
50 createCopycatServers(3);
51 }
52
53 @AfterClass
54 public static void postTestCleanup() throws Exception {
55 clearTests();
56 }
57
Madan Jampani5e5b3d62016-02-01 16:03:33 -080058 @Override
59 protected ResourceType resourceType() {
60 return new ResourceType(AtomixLeaderElector.class);
61 }
62
63 @Test
64 public void testRun() throws Throwable {
Madan Jampani0c0cdc62016-02-22 16:54:06 -080065 leaderElectorRunTests(3);
Madan Jampani5e5b3d62016-02-01 16:03:33 -080066 }
67
68 private void leaderElectorRunTests(int numServers) throws Throwable {
Madan Jampani5e5b3d62016-02-01 16:03:33 -080069 Atomix client1 = createAtomixClient();
Aaron Kruglikovb5a41e52016-06-23 15:37:41 -070070 AtomixLeaderElector elector1 = client1.getResource("test-elector-run",
71 AtomixLeaderElector.class).join();
Madan Jampani5e5b3d62016-02-01 16:03:33 -080072 elector1.run("foo", node1).thenAccept(result -> {
73 assertEquals(node1, result.leaderNodeId());
74 assertEquals(1, result.leader().term());
75 assertEquals(1, result.candidates().size());
76 assertEquals(node1, result.candidates().get(0));
77 }).join();
78 Atomix client2 = createAtomixClient();
Aaron Kruglikovb5a41e52016-06-23 15:37:41 -070079 AtomixLeaderElector elector2 = client2.getResource("test-elector-run",
80 AtomixLeaderElector.class).join();
Madan Jampani5e5b3d62016-02-01 16:03:33 -080081 elector2.run("foo", node2).thenAccept(result -> {
82 assertEquals(node1, result.leaderNodeId());
83 assertEquals(1, result.leader().term());
84 assertEquals(2, result.candidates().size());
85 assertEquals(node1, result.candidates().get(0));
86 assertEquals(node2, result.candidates().get(1));
87 }).join();
88 }
89
90 @Test
91 public void testWithdraw() throws Throwable {
Madan Jampani5e5b3d62016-02-01 16:03:33 -080092 leaderElectorWithdrawTests(3);
Madan Jampani5e5b3d62016-02-01 16:03:33 -080093 }
94
95 private void leaderElectorWithdrawTests(int numServers) throws Throwable {
Madan Jampani5e5b3d62016-02-01 16:03:33 -080096 Atomix client1 = createAtomixClient();
Aaron Kruglikovb5a41e52016-06-23 15:37:41 -070097 AtomixLeaderElector elector1 = client1.getResource("test-elector-withdraw",
98 AtomixLeaderElector.class).join();
Madan Jampani5e5b3d62016-02-01 16:03:33 -080099 elector1.run("foo", node1).join();
100 Atomix client2 = createAtomixClient();
Aaron Kruglikovb5a41e52016-06-23 15:37:41 -0700101 AtomixLeaderElector elector2 = client2.getResource("test-elector-withdraw",
102 AtomixLeaderElector.class).join();
Madan Jampani5e5b3d62016-02-01 16:03:33 -0800103 elector2.run("foo", node2).join();
104
105 LeaderEventListener listener1 = new LeaderEventListener();
106 elector1.addChangeListener(listener1).join();
107
108 LeaderEventListener listener2 = new LeaderEventListener();
109 elector2.addChangeListener(listener2).join();
110
111 elector1.withdraw("foo").join();
112
113 listener1.nextEvent().thenAccept(result -> {
114 assertEquals(node2, result.newValue().leaderNodeId());
115 assertEquals(2, result.newValue().leader().term());
116 assertEquals(1, result.newValue().candidates().size());
117 assertEquals(node2, result.newValue().candidates().get(0));
118 }).join();
119
120 listener2.nextEvent().thenAccept(result -> {
121 assertEquals(node2, result.newValue().leaderNodeId());
122 assertEquals(2, result.newValue().leader().term());
123 assertEquals(1, result.newValue().candidates().size());
124 assertEquals(node2, result.newValue().candidates().get(0));
125 }).join();
126 }
127
128 @Test
129 public void testAnoint() throws Throwable {
Madan Jampani5e5b3d62016-02-01 16:03:33 -0800130 leaderElectorAnointTests(3);
Madan Jampani5e5b3d62016-02-01 16:03:33 -0800131 }
132
133 private void leaderElectorAnointTests(int numServers) throws Throwable {
Madan Jampani5e5b3d62016-02-01 16:03:33 -0800134 Atomix client1 = createAtomixClient();
Aaron Kruglikovb5a41e52016-06-23 15:37:41 -0700135 AtomixLeaderElector elector1 = client1.getResource("test-elector-anoint",
136 AtomixLeaderElector.class).join();
Madan Jampani5e5b3d62016-02-01 16:03:33 -0800137 Atomix client2 = createAtomixClient();
Aaron Kruglikovb5a41e52016-06-23 15:37:41 -0700138 AtomixLeaderElector elector2 = client2.getResource("test-elector-anoint",
139 AtomixLeaderElector.class).join();
Madan Jampani5e5b3d62016-02-01 16:03:33 -0800140 Atomix client3 = createAtomixClient();
Aaron Kruglikovb5a41e52016-06-23 15:37:41 -0700141 AtomixLeaderElector elector3 = client3.getResource("test-elector-anoint",
142 AtomixLeaderElector.class).join();
Madan Jampani5e5b3d62016-02-01 16:03:33 -0800143 elector1.run("foo", node1).join();
144 elector2.run("foo", node2).join();
145
146 LeaderEventListener listener1 = new LeaderEventListener();
147 elector1.addChangeListener(listener1).join();
148 LeaderEventListener listener2 = new LeaderEventListener();
149 elector2.addChangeListener(listener2);
150 LeaderEventListener listener3 = new LeaderEventListener();
151 elector3.addChangeListener(listener3).join();
152
153 elector3.anoint("foo", node3).thenAccept(result -> {
154 assertFalse(result);
155 }).join();
156 assertFalse(listener1.hasEvent());
157 assertFalse(listener2.hasEvent());
158 assertFalse(listener3.hasEvent());
159
160 elector3.anoint("foo", node2).thenAccept(result -> {
161 assertTrue(result);
162 }).join();
Madan Jampani5e5b3d62016-02-01 16:03:33 -0800163
164 listener1.nextEvent().thenAccept(result -> {
165 assertEquals(node2, result.newValue().leaderNodeId());
166 assertEquals(2, result.newValue().candidates().size());
167 assertEquals(node1, result.newValue().candidates().get(0));
168 assertEquals(node2, result.newValue().candidates().get(1));
169 }).join();
170 listener2.nextEvent().thenAccept(result -> {
171 assertEquals(node2, result.newValue().leaderNodeId());
172 assertEquals(2, result.newValue().candidates().size());
173 assertEquals(node1, result.newValue().candidates().get(0));
174 assertEquals(node2, result.newValue().candidates().get(1));
175 }).join();
176 listener3.nextEvent().thenAccept(result -> {
177 assertEquals(node2, result.newValue().leaderNodeId());
178 assertEquals(2, result.newValue().candidates().size());
179 assertEquals(node1, result.newValue().candidates().get(0));
180 assertEquals(node2, result.newValue().candidates().get(1));
181 }).join();
182 }
183
184 @Test
Madan Jampani0c0cdc62016-02-22 16:54:06 -0800185 public void testPromote() throws Throwable {
Madan Jampani0c0cdc62016-02-22 16:54:06 -0800186 leaderElectorPromoteTests(3);
Madan Jampani0c0cdc62016-02-22 16:54:06 -0800187 }
188
189 private void leaderElectorPromoteTests(int numServers) throws Throwable {
Madan Jampani630e7ac2016-05-31 11:34:05 -0700190 AtomixClient client1 = createAtomixClient();
Aaron Kruglikovb5a41e52016-06-23 15:37:41 -0700191 AtomixLeaderElector elector1 = client1.getResource("test-elector-promote",
192 AtomixLeaderElector.class).join();
Madan Jampani630e7ac2016-05-31 11:34:05 -0700193 AtomixClient client2 = createAtomixClient();
Aaron Kruglikovb5a41e52016-06-23 15:37:41 -0700194 AtomixLeaderElector elector2 = client2.getResource("test-elector-promote",
195 AtomixLeaderElector.class).join();
Madan Jampani630e7ac2016-05-31 11:34:05 -0700196 AtomixClient client3 = createAtomixClient();
Aaron Kruglikovb5a41e52016-06-23 15:37:41 -0700197 AtomixLeaderElector elector3 = client3.getResource("test-elector-promote",
198 AtomixLeaderElector.class).join();
Madan Jampani0c0cdc62016-02-22 16:54:06 -0800199 elector1.run("foo", node1).join();
200 elector2.run("foo", node2).join();
201
202 LeaderEventListener listener1 = new LeaderEventListener();
203 elector1.addChangeListener(listener1).join();
204 LeaderEventListener listener2 = new LeaderEventListener();
205 elector2.addChangeListener(listener2).join();
206 LeaderEventListener listener3 = new LeaderEventListener();
207 elector3.addChangeListener(listener3).join();
208
209 elector3.promote("foo", node3).thenAccept(result -> {
210 assertFalse(result);
211 }).join();
212
213 assertFalse(listener1.hasEvent());
214 assertFalse(listener2.hasEvent());
215 assertFalse(listener3.hasEvent());
216
217 elector3.run("foo", node3).join();
218
Madan Jampani630e7ac2016-05-31 11:34:05 -0700219 listener1.nextEvent().thenAccept(result -> {
220 assertEquals(node3, result.newValue().candidates().get(2));
221 }).join();
222 listener2.nextEvent().thenAccept(result -> {
223 assertEquals(node3, result.newValue().candidates().get(2));
224 }).join();
225 listener3.nextEvent().thenAccept(result -> {
226 assertEquals(node3, result.newValue().candidates().get(2));
227 }).join();
Madan Jampani0c0cdc62016-02-22 16:54:06 -0800228
229 elector3.promote("foo", node3).thenAccept(result -> {
230 assertTrue(result);
231 }).join();
232
233 listener1.nextEvent().thenAccept(result -> {
234 assertEquals(node3, result.newValue().candidates().get(0));
235 }).join();
236 listener2.nextEvent().thenAccept(result -> {
237 assertEquals(node3, result.newValue().candidates().get(0));
238 }).join();
239 listener3.nextEvent().thenAccept(result -> {
240 assertEquals(node3, result.newValue().candidates().get(0));
241 }).join();
242 }
243
244 @Test
Madan Jampani5e5b3d62016-02-01 16:03:33 -0800245 public void testLeaderSessionClose() throws Throwable {
Madan Jampani5e5b3d62016-02-01 16:03:33 -0800246 leaderElectorLeaderSessionCloseTests(3);
Madan Jampani5e5b3d62016-02-01 16:03:33 -0800247 }
248
249 private void leaderElectorLeaderSessionCloseTests(int numServers) throws Throwable {
Madan Jampani630e7ac2016-05-31 11:34:05 -0700250 AtomixClient client1 = createAtomixClient();
Aaron Kruglikovb5a41e52016-06-23 15:37:41 -0700251 AtomixLeaderElector elector1 = client1.getResource("test-elector-leader-session-close",
252 AtomixLeaderElector.class).join();
Madan Jampani5e5b3d62016-02-01 16:03:33 -0800253 elector1.run("foo", node1).join();
254 Atomix client2 = createAtomixClient();
Aaron Kruglikovb5a41e52016-06-23 15:37:41 -0700255 AtomixLeaderElector elector2 = client2.getResource("test-elector-leader-session-close",
256 AtomixLeaderElector.class).join();
Madan Jampani5e5b3d62016-02-01 16:03:33 -0800257 LeaderEventListener listener = new LeaderEventListener();
258 elector2.run("foo", node2).join();
259 elector2.addChangeListener(listener).join();
260 client1.close();
261 listener.nextEvent().thenAccept(result -> {
262 assertEquals(node2, result.newValue().leaderNodeId());
263 assertEquals(1, result.newValue().candidates().size());
264 assertEquals(node2, result.newValue().candidates().get(0));
265 }).join();
266 }
267
268 @Test
269 public void testNonLeaderSessionClose() throws Throwable {
Madan Jampani5e5b3d62016-02-01 16:03:33 -0800270 leaderElectorNonLeaderSessionCloseTests(3);
Madan Jampani5e5b3d62016-02-01 16:03:33 -0800271 }
272
273 private void leaderElectorNonLeaderSessionCloseTests(int numServers) throws Throwable {
Madan Jampani5e5b3d62016-02-01 16:03:33 -0800274 Atomix client1 = createAtomixClient();
Aaron Kruglikovb5a41e52016-06-23 15:37:41 -0700275 AtomixLeaderElector elector1 = client1.getResource("test-elector-non-leader-session-close",
276 AtomixLeaderElector.class).join();
Madan Jampani5e5b3d62016-02-01 16:03:33 -0800277 elector1.run("foo", node1).join();
Madan Jampani630e7ac2016-05-31 11:34:05 -0700278 AtomixClient client2 = createAtomixClient();
Aaron Kruglikovb5a41e52016-06-23 15:37:41 -0700279 AtomixLeaderElector elector2 = client2.getResource("test-elector-non-leader-session-close",
280 AtomixLeaderElector.class).join();
Madan Jampani5e5b3d62016-02-01 16:03:33 -0800281 LeaderEventListener listener = new LeaderEventListener();
282 elector2.run("foo", node2).join();
283 elector1.addChangeListener(listener).join();
284 client2.close().join();
285 listener.nextEvent().thenAccept(result -> {
286 assertEquals(node1, result.newValue().leaderNodeId());
287 assertEquals(1, result.newValue().candidates().size());
288 assertEquals(node1, result.newValue().candidates().get(0));
289 }).join();
290 }
291
292 @Test
293 public void testQueries() throws Throwable {
Madan Jampani5e5b3d62016-02-01 16:03:33 -0800294 leaderElectorQueryTests(3);
Madan Jampani5e5b3d62016-02-01 16:03:33 -0800295 }
296
297 private void leaderElectorQueryTests(int numServers) throws Throwable {
Madan Jampani5e5b3d62016-02-01 16:03:33 -0800298 Atomix client1 = createAtomixClient();
299 Atomix client2 = createAtomixClient();
Aaron Kruglikovb5a41e52016-06-23 15:37:41 -0700300 AtomixLeaderElector elector1 = client1.getResource("test-elector-query",
301 AtomixLeaderElector.class).join();
302 AtomixLeaderElector elector2 = client2.getResource("test-elector-query",
303 AtomixLeaderElector.class).join();
Madan Jampani5e5b3d62016-02-01 16:03:33 -0800304 elector1.run("foo", node1).join();
305 elector2.run("foo", node2).join();
306 elector2.run("bar", node2).join();
307 elector1.getElectedTopics(node1).thenAccept(result -> {
308 assertEquals(1, result.size());
309 assertTrue(result.contains("foo"));
310 }).join();
311 elector2.getElectedTopics(node1).thenAccept(result -> {
312 assertEquals(1, result.size());
313 assertTrue(result.contains("foo"));
314 }).join();
315 elector1.getLeadership("foo").thenAccept(result -> {
316 assertEquals(node1, result.leaderNodeId());
317 assertEquals(node1, result.candidates().get(0));
318 assertEquals(node2, result.candidates().get(1));
319 }).join();
320 elector2.getLeadership("foo").thenAccept(result -> {
321 assertEquals(node1, result.leaderNodeId());
322 assertEquals(node1, result.candidates().get(0));
323 assertEquals(node2, result.candidates().get(1));
324 }).join();
325 elector1.getLeadership("bar").thenAccept(result -> {
326 assertEquals(node2, result.leaderNodeId());
327 assertEquals(node2, result.candidates().get(0));
328 }).join();
329 elector2.getLeadership("bar").thenAccept(result -> {
330 assertEquals(node2, result.leaderNodeId());
331 assertEquals(node2, result.candidates().get(0));
332 }).join();
333 elector1.getLeaderships().thenAccept(result -> {
334 assertEquals(2, result.size());
335 Leadership fooLeadership = result.get("foo");
336 assertEquals(node1, fooLeadership.leaderNodeId());
337 assertEquals(node1, fooLeadership.candidates().get(0));
338 assertEquals(node2, fooLeadership.candidates().get(1));
339 Leadership barLeadership = result.get("bar");
340 assertEquals(node2, barLeadership.leaderNodeId());
341 assertEquals(node2, barLeadership.candidates().get(0));
342 }).join();
343 elector2.getLeaderships().thenAccept(result -> {
344 assertEquals(2, result.size());
345 Leadership fooLeadership = result.get("foo");
346 assertEquals(node1, fooLeadership.leaderNodeId());
347 assertEquals(node1, fooLeadership.candidates().get(0));
348 assertEquals(node2, fooLeadership.candidates().get(1));
349 Leadership barLeadership = result.get("bar");
350 assertEquals(node2, barLeadership.leaderNodeId());
351 assertEquals(node2, barLeadership.candidates().get(0));
352 }).join();
353 }
354
355 private static class LeaderEventListener implements Consumer<Change<Leadership>> {
356 Queue<Change<Leadership>> eventQueue = new LinkedList<>();
357 CompletableFuture<Change<Leadership>> pendingFuture;
358
359 @Override
360 public void accept(Change<Leadership> change) {
361 synchronized (this) {
362 if (pendingFuture != null) {
363 pendingFuture.complete(change);
364 pendingFuture = null;
365 } else {
366 eventQueue.add(change);
367 }
368 }
369 }
370
371 public boolean hasEvent() {
372 return !eventQueue.isEmpty();
373 }
374
Madan Jampani0c0cdc62016-02-22 16:54:06 -0800375 public void clearEvents() {
376 eventQueue.clear();
377 }
378
Madan Jampani5e5b3d62016-02-01 16:03:33 -0800379 public CompletableFuture<Change<Leadership>> nextEvent() {
380 synchronized (this) {
381 if (eventQueue.isEmpty()) {
382 if (pendingFuture == null) {
383 pendingFuture = new CompletableFuture<>();
384 }
385 return pendingFuture;
386 } else {
387 return CompletableFuture.completedFuture(eventQueue.poll());
388 }
389 }
390 }
391 }
392}