blob: 2666910ac5befbc86be3883b75f4aff76c8dfc7c [file] [log] [blame]
Thomas Vachuska4f1a60c2014-10-28 13:39:07 -07001/*
Brian O'Connora09fe5b2017-08-03 21:12:30 -07002 * Copyright 2014-present Open Networking Foundation
Thomas Vachuska4f1a60c2014-10-28 13:39:07 -07003 *
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 */
Brian O'Connorabafb502014-12-02 22:26:20 -080016package org.onosproject.cluster.impl;
Ayaka Koshibe406d0102014-09-24 16:08:12 -070017
Claudine Chiudce08152016-03-09 18:19:28 +000018import java.util.List;
Ayaka Koshibe406d0102014-09-24 16:08:12 -070019import java.util.Set;
Claudine Chiudce08152016-03-09 18:19:28 +000020import java.util.function.Consumer;
Ayaka Koshibe406d0102014-09-24 16:08:12 -070021
Claudine Chiudce08152016-03-09 18:19:28 +000022import com.google.common.collect.ImmutableList;
23import com.google.common.collect.ImmutableSet;
pierventrecdcd91c2021-05-06 09:27:00 +020024import com.google.common.collect.Lists;
Victor Silvaf2b9d032016-09-19 19:43:20 -030025import org.easymock.EasyMock;
Ayaka Koshibe406d0102014-09-24 16:08:12 -070026import org.junit.After;
27import org.junit.Before;
28import org.junit.Test;
Claudine Chiudce08152016-03-09 18:19:28 +000029import org.onlab.junit.TestUtils;
Ray Milkeycc53abd2015-02-19 12:31:33 -080030import org.onlab.packet.IpAddress;
Victor Silvaf2b9d032016-09-19 19:43:20 -030031import org.onosproject.cfg.ComponentConfigService;
Brian O'Connorabafb502014-12-02 22:26:20 -080032import org.onosproject.cluster.ClusterService;
33import org.onosproject.cluster.ControllerNode;
Brian O'Connorabafb502014-12-02 22:26:20 -080034import org.onosproject.cluster.DefaultControllerNode;
35import org.onosproject.cluster.NodeId;
Thomas Vachuska36002e62015-05-19 16:12:29 -070036import org.onosproject.common.event.impl.TestEventDispatcher;
pierventrecdcd91c2021-05-06 09:27:00 +020037import org.onosproject.mastership.MastershipInfo;
Brian O'Connorabafb502014-12-02 22:26:20 -080038import org.onosproject.mastership.MastershipService;
39import org.onosproject.mastership.MastershipStore;
40import org.onosproject.mastership.MastershipTermService;
41import org.onosproject.net.DeviceId;
Simon Hunt53612212016-12-04 17:19:52 -080042import org.onosproject.net.config.NetworkConfigServiceAdapter;
Claudine Chiudce08152016-03-09 18:19:28 +000043import org.onosproject.net.region.Region;
44import org.onosproject.net.region.RegionId;
45import org.onosproject.net.region.RegionStore;
46import org.onosproject.net.region.impl.RegionManager;
47import org.onosproject.store.cluster.StaticClusterService;
48import org.onosproject.store.region.impl.DistributedRegionStore;
49import org.onosproject.store.service.TestStorageService;
Thomas Vachuskac97aa612015-06-23 16:00:18 -070050import org.onosproject.store.trivial.SimpleMastershipStore;
Ayaka Koshibe406d0102014-09-24 16:08:12 -070051
Ayaka Koshibeea5b4ce2014-10-11 14:17:17 -070052import com.google.common.collect.Sets;
Madan Jampanide003d92015-05-11 17:14:20 -070053import com.google.common.util.concurrent.Futures;
Jordan Halterman61aeb352017-10-18 16:22:17 -070054import org.onosproject.upgrade.impl.UpgradeServiceAdapter;
Ayaka Koshibeea5b4ce2014-10-11 14:17:17 -070055
Victor Silvaf2b9d032016-09-19 19:43:20 -030056import static org.easymock.EasyMock.anyObject;
57import static org.easymock.EasyMock.expect;
58import static org.easymock.EasyMock.expectLastCall;
59import static org.easymock.EasyMock.replay;
Claudine Chiudce08152016-03-09 18:19:28 +000060import static org.junit.Assert.*;
Ray Milkeycc53abd2015-02-19 12:31:33 -080061import static org.onosproject.net.MastershipRole.MASTER;
62import static org.onosproject.net.MastershipRole.NONE;
63import static org.onosproject.net.MastershipRole.STANDBY;
Thomas Vachuska42e8cce2015-07-29 19:25:18 -070064import static org.onosproject.net.NetTestTools.injectEventDispatcher;
Claudine Chiudce08152016-03-09 18:19:28 +000065import static org.onosproject.net.region.Region.Type.METRO;
Ayaka Koshibe406d0102014-09-24 16:08:12 -070066
67/**
68 * Test codifying the mastership service contracts.
69 */
70public class MastershipManagerTest {
71
72 private static final NodeId NID_LOCAL = new NodeId("local");
73 private static final NodeId NID_OTHER = new NodeId("foo");
Pavlin Radoslavov444b5192014-10-28 10:45:19 -070074 private static final IpAddress LOCALHOST = IpAddress.valueOf("127.0.0.1");
Ayaka Koshibe406d0102014-09-24 16:08:12 -070075 private static final DeviceId DEV_MASTER = DeviceId.deviceId("of:1");
76 private static final DeviceId DEV_OTHER = DeviceId.deviceId("of:2");
77
Claudine Chiudce08152016-03-09 18:19:28 +000078 private static final RegionId RID1 = RegionId.regionId("r1");
79 private static final RegionId RID2 = RegionId.regionId("r2");
80 private static final DeviceId DID1 = DeviceId.deviceId("foo:d1");
81 private static final DeviceId DID2 = DeviceId.deviceId("foo:d2");
82 private static final DeviceId DID3 = DeviceId.deviceId("foo:d3");
Thomas Vachuskaf2e09cb2017-11-06 15:17:06 -080083 private static final DeviceId DID4 = DeviceId.deviceId("foo:d4");
84 private static final DeviceId DID5 = DeviceId.deviceId("foo:d5");
85 private static final DeviceId DID6 = DeviceId.deviceId("foo:d6");
Claudine Chiudce08152016-03-09 18:19:28 +000086 private static final NodeId NID1 = NodeId.nodeId("n1");
87 private static final NodeId NID2 = NodeId.nodeId("n2");
88 private static final NodeId NID3 = NodeId.nodeId("n3");
89 private static final NodeId NID4 = NodeId.nodeId("n4");
90 private static final ControllerNode CNODE1 =
91 new DefaultControllerNode(NID1, IpAddress.valueOf("127.0.1.1"));
92 private static final ControllerNode CNODE2 =
93 new DefaultControllerNode(NID2, IpAddress.valueOf("127.0.1.2"));
94 private static final ControllerNode CNODE3 =
95 new DefaultControllerNode(NID3, IpAddress.valueOf("127.0.1.3"));
96 private static final ControllerNode CNODE4 =
97 new DefaultControllerNode(NID4, IpAddress.valueOf("127.0.1.4"));
98
99
Ayaka Koshibe406d0102014-09-24 16:08:12 -0700100 private MastershipManager mgr;
101 protected MastershipService service;
Claudine Chiudce08152016-03-09 18:19:28 +0000102 private TestRegionManager regionManager;
103 private RegionStore regionStore;
104 private TestClusterService testClusterService;
Ayaka Koshibe406d0102014-09-24 16:08:12 -0700105
106 @Before
Claudine Chiudce08152016-03-09 18:19:28 +0000107 public void setUp() throws Exception {
Ayaka Koshibe406d0102014-09-24 16:08:12 -0700108 mgr = new MastershipManager();
109 service = mgr;
Thomas Vachuska42e8cce2015-07-29 19:25:18 -0700110 injectEventDispatcher(mgr, new TestEventDispatcher());
Claudine Chiudce08152016-03-09 18:19:28 +0000111 testClusterService = new TestClusterService();
112 mgr.clusterService = testClusterService;
Jordan Halterman61aeb352017-10-18 16:22:17 -0700113 mgr.upgradeService = new UpgradeServiceAdapter();
Yuta HIGUCHI0c6e1842014-11-05 22:34:23 -0800114 mgr.store = new TestSimpleMastershipStore(mgr.clusterService);
Claudine Chiudce08152016-03-09 18:19:28 +0000115 regionStore = new DistributedRegionStore();
116 TestUtils.setField(regionStore, "storageService", new TestStorageService());
117 TestUtils.callMethod(regionStore, "activate",
118 new Class<?>[] {});
119 regionManager = new TestRegionManager();
120 TestUtils.setField(regionManager, "store", regionStore);
121 regionManager.activate();
122 mgr.regionService = regionManager;
Victor Silvaf2b9d032016-09-19 19:43:20 -0300123
124 ComponentConfigService mockConfigService =
125 EasyMock.createMock(ComponentConfigService.class);
126 expect(mockConfigService.getProperties(anyObject())).andReturn(ImmutableSet.of());
127 mockConfigService.registerProperties(mgr.getClass());
128 expectLastCall();
129 mockConfigService.unregisterProperties(mgr.getClass(), false);
130 expectLastCall();
131 expect(mockConfigService.getProperties(anyObject())).andReturn(ImmutableSet.of());
132 mgr.cfgService = mockConfigService;
133 replay(mockConfigService);
134
Ayaka Koshibe406d0102014-09-24 16:08:12 -0700135 mgr.activate();
136 }
137
138 @After
139 public void tearDown() {
140 mgr.deactivate();
141 mgr.clusterService = null;
Thomas Vachuska42e8cce2015-07-29 19:25:18 -0700142 injectEventDispatcher(mgr, null);
Claudine Chiudce08152016-03-09 18:19:28 +0000143 regionManager.deactivate();
144 mgr.regionService = null;
Ayaka Koshibe406d0102014-09-24 16:08:12 -0700145 mgr.store = null;
146 }
147
148 @Test
149 public void setRole() {
150 mgr.setRole(NID_OTHER, DEV_MASTER, MASTER);
Yuta HIGUCHI0c6e1842014-11-05 22:34:23 -0800151 assertEquals("wrong local role:", NONE, mgr.getLocalRole(DEV_MASTER));
Madan Jampanide003d92015-05-11 17:14:20 -0700152 assertEquals("wrong obtained role:", STANDBY, Futures.getUnchecked(mgr.requestRoleFor(DEV_MASTER)));
Ayaka Koshibe406d0102014-09-24 16:08:12 -0700153
154 //set to master
155 mgr.setRole(NID_LOCAL, DEV_MASTER, MASTER);
156 assertEquals("wrong local role:", MASTER, mgr.getLocalRole(DEV_MASTER));
157 }
158
159 @Test
160 public void relinquishMastership() {
Ayaka Koshibeb62aab52014-10-24 13:15:25 -0700161 //no backups - should just turn to NONE for device.
Ayaka Koshibed9f693e2014-09-29 18:04:54 -0700162 mgr.setRole(NID_LOCAL, DEV_MASTER, MASTER);
163 assertEquals("wrong role:", MASTER, mgr.getLocalRole(DEV_MASTER));
164 mgr.relinquishMastership(DEV_MASTER);
165 assertNull("wrong master:", mgr.getMasterFor(DEV_OTHER));
Ayaka Koshibeb62aab52014-10-24 13:15:25 -0700166 assertEquals("wrong role:", NONE, mgr.getLocalRole(DEV_MASTER));
Ayaka Koshibed9f693e2014-09-29 18:04:54 -0700167
168 //not master, nothing should happen
Ayaka Koshibeb62aab52014-10-24 13:15:25 -0700169 mgr.setRole(NID_LOCAL, DEV_OTHER, NONE);
Ayaka Koshibed9f693e2014-09-29 18:04:54 -0700170 mgr.relinquishMastership(DEV_OTHER);
171 assertNull("wrong role:", mgr.getMasterFor(DEV_OTHER));
172
173 //provide NID_OTHER as backup and relinquish
174 mgr.setRole(NID_LOCAL, DEV_MASTER, MASTER);
175 assertEquals("wrong master:", NID_LOCAL, mgr.getMasterFor(DEV_MASTER));
176 mgr.setRole(NID_OTHER, DEV_MASTER, STANDBY);
177 mgr.relinquishMastership(DEV_MASTER);
178 assertEquals("wrong master:", NID_OTHER, mgr.getMasterFor(DEV_MASTER));
Ayaka Koshibe406d0102014-09-24 16:08:12 -0700179 }
180
181 @Test
182 public void requestRoleFor() {
183 mgr.setRole(NID_LOCAL, DEV_MASTER, MASTER);
184 mgr.setRole(NID_OTHER, DEV_OTHER, MASTER);
185
186 //local should be master for one but standby for other
Madan Jampanide003d92015-05-11 17:14:20 -0700187 assertEquals("wrong role:", MASTER, Futures.getUnchecked(mgr.requestRoleFor(DEV_MASTER)));
188 assertEquals("wrong role:", STANDBY, Futures.getUnchecked(mgr.requestRoleFor(DEV_OTHER)));
Ayaka Koshibe406d0102014-09-24 16:08:12 -0700189 }
190
191 @Test
192 public void getMasterFor() {
193 mgr.setRole(NID_LOCAL, DEV_MASTER, MASTER);
194 mgr.setRole(NID_OTHER, DEV_OTHER, MASTER);
195 assertEquals("wrong master:", NID_LOCAL, mgr.getMasterFor(DEV_MASTER));
196 assertEquals("wrong master:", NID_OTHER, mgr.getMasterFor(DEV_OTHER));
197
198 //have NID_OTHER hand over DEV_OTHER to NID_LOCAL
199 mgr.setRole(NID_LOCAL, DEV_OTHER, MASTER);
200 assertEquals("wrong master:", NID_LOCAL, mgr.getMasterFor(DEV_OTHER));
201 }
202
203 @Test
204 public void getDevicesOf() {
205 mgr.setRole(NID_LOCAL, DEV_MASTER, MASTER);
206 mgr.setRole(NID_LOCAL, DEV_OTHER, STANDBY);
207 assertEquals("should be one device:", 1, mgr.getDevicesOf(NID_LOCAL).size());
Ayaka Koshibe406d0102014-09-24 16:08:12 -0700208 //hand both devices to NID_LOCAL
209 mgr.setRole(NID_LOCAL, DEV_OTHER, MASTER);
210 assertEquals("should be two devices:", 2, mgr.getDevicesOf(NID_LOCAL).size());
211 }
212
Ayaka Koshibe48239b02014-09-25 17:12:31 -0700213 @Test
214 public void termService() {
Yuta HIGUCHIbcac4992014-11-22 19:27:57 -0800215 MastershipTermService ts = mgr;
Ayaka Koshibe48239b02014-09-25 17:12:31 -0700216
Yuta HIGUCHIdfe6e3b2014-10-30 11:31:51 -0700217 //term = 1 for both
Ayaka Koshibe48239b02014-09-25 17:12:31 -0700218 mgr.setRole(NID_LOCAL, DEV_MASTER, MASTER);
Yuta HIGUCHIdfe6e3b2014-10-30 11:31:51 -0700219 assertEquals("inconsistent term: ", 1, ts.getMastershipTerm(DEV_MASTER).termNumber());
Ayaka Koshibe48239b02014-09-25 17:12:31 -0700220
Yuta HIGUCHIdfe6e3b2014-10-30 11:31:51 -0700221 //hand devices to NID_LOCAL and back: term = 1 + 2
Ayaka Koshibe48239b02014-09-25 17:12:31 -0700222 mgr.setRole(NID_OTHER, DEV_MASTER, MASTER);
223 mgr.setRole(NID_LOCAL, DEV_MASTER, MASTER);
Yuta HIGUCHIdfe6e3b2014-10-30 11:31:51 -0700224 assertEquals("inconsistent terms: ", 3, ts.getMastershipTerm(DEV_MASTER).termNumber());
Ayaka Koshibe48239b02014-09-25 17:12:31 -0700225 }
226
Claudine Chiudce08152016-03-09 18:19:28 +0000227 @Test
Thomas Vachuskaf2e09cb2017-11-06 15:17:06 -0800228 public void balanceWithOrphans() {
229 // Setup cluster of three nodes
230 testClusterService.put(CNODE1, ControllerNode.State.ACTIVE);
231 testClusterService.put(CNODE2, ControllerNode.State.INACTIVE);
232 testClusterService.put(CNODE3, ControllerNode.State.ACTIVE);
233
234 // Pre-assign some devices to each of the node
235 // Leave some devices as orphans assigned to a downed node
236 assignRoles(NID1, ImmutableSet.of(DID1, DID2, DID3, DID4));
237 assignRoles(NID2, ImmutableSet.of(DID5));
238 assignRoles(NID3, ImmutableSet.of(DID6));
239
240 // Trigger load balancing
241 mgr.balanceRoles();
242
243 // Make sure we have a balanced load
244 // Make sure that we no longer have any orphans
245 assertEquals("incorrect balance for node 1", 3, mgr.getDevicesOf(NID1).size());
246 assertEquals("incorrect balance for node 2", 0, mgr.getDevicesOf(NID2).size());
247 assertEquals("incorrect balance for node 3", 3, mgr.getDevicesOf(NID3).size());
248 }
249
250 private void assignRoles(NodeId nid, Set<DeviceId> deviceIds) {
251 Set<DeviceId> all = ImmutableSet.of(DID1, DID2, DID3, DID4, DID5, DID6);
252 for (DeviceId did : all) {
253 mgr.setRole(nid, did, deviceIds.contains(did) ? MASTER : STANDBY);
254 }
255 }
256
257 @Test
Claudine Chiudce08152016-03-09 18:19:28 +0000258 public void balanceWithRegion1() {
259 //set up region - 2 sets of masters with 1 node in each
260 Set<NodeId> masterSet1 = ImmutableSet.of(NID1);
261 Set<NodeId> masterSet2 = ImmutableSet.of(NID2);
262 List<Set<NodeId>> masters = ImmutableList.of(masterSet1, masterSet2);
263 Region r = regionManager.createRegion(RID1, "R1", METRO, masters);
264 regionManager.addDevices(RID1, ImmutableSet.of(DID1, DID2));
265 Set<DeviceId> deviceIds = regionManager.getRegionDevices(RID1);
266 assertEquals("incorrect device count", 2, deviceIds.size());
267
268 testClusterService.put(CNODE1, ControllerNode.State.ACTIVE);
269 testClusterService.put(CNODE2, ControllerNode.State.ACTIVE);
270
271 //set master to non region nodes
272 mgr.setRole(NID_LOCAL, DID1, MASTER);
273 mgr.setRole(NID_LOCAL, DID2, MASTER);
274 assertEquals("wrong local role:", MASTER, mgr.getLocalRole(DID1));
275 assertEquals("wrong local role:", MASTER, mgr.getLocalRole(DID2));
276 assertEquals("wrong master:", NID_LOCAL, mgr.getMasterFor(DID1));
277 assertEquals("wrong master:", NID_LOCAL, mgr.getMasterFor(DID2));
278
279 //do region balancing
280 mgr.useRegionForBalanceRoles = true;
281 mgr.balanceRoles();
282 assertEquals("wrong master:", NID1, mgr.getMasterFor(DID1));
283 assertEquals("wrong master:", NID1, mgr.getMasterFor(DID2));
284
285 // make N1 inactive
286 testClusterService.put(CNODE1, ControllerNode.State.INACTIVE);
287 mgr.balanceRoles();
288 assertEquals("wrong master:", NID2, mgr.getMasterFor(DID1));
289 assertEquals("wrong master:", NID2, mgr.getMasterFor(DID2));
290
291 }
292
293 @Test
294 public void balanceWithRegion2() {
295 //set up region - 2 sets of masters with (3 nodes, 1 node)
296 Set<NodeId> masterSet1 = ImmutableSet.of(NID1, NID3, NID4);
297 Set<NodeId> masterSet2 = ImmutableSet.of(NID2);
298 List<Set<NodeId>> masters = ImmutableList.of(masterSet1, masterSet2);
299 Region r = regionManager.createRegion(RID1, "R1", METRO, masters);
300 Set<DeviceId> deviceIdsOrig = ImmutableSet.of(DID1, DID2, DID3, DEV_OTHER);
301 regionManager.addDevices(RID1, deviceIdsOrig);
302 Set<DeviceId> deviceIds = regionManager.getRegionDevices(RID1);
303 assertEquals("incorrect device count", deviceIdsOrig.size(), deviceIds.size());
304 assertEquals("incorrect devices in region", deviceIdsOrig, deviceIds);
305
306 testClusterService.put(CNODE1, ControllerNode.State.ACTIVE);
307 testClusterService.put(CNODE2, ControllerNode.State.ACTIVE);
308 testClusterService.put(CNODE3, ControllerNode.State.ACTIVE);
309 testClusterService.put(CNODE4, ControllerNode.State.ACTIVE);
310
311 //set master to non region nodes
312 deviceIdsOrig.forEach(deviceId1 -> mgr.setRole(NID_LOCAL, deviceId1, MASTER));
313 checkDeviceMasters(deviceIds, Sets.newHashSet(NID_LOCAL), deviceId ->
314 assertEquals("wrong local role:", MASTER, mgr.getLocalRole(deviceId)));
315
316 //do region balancing
317 mgr.useRegionForBalanceRoles = true;
318 mgr.balanceRoles();
319 Set<NodeId> expectedMasters = Sets.newHashSet(NID1, NID3, NID4);
320 checkDeviceMasters(deviceIds, expectedMasters);
321
322 // make N1 inactive
323 testClusterService.put(CNODE1, ControllerNode.State.INACTIVE);
324 expectedMasters.remove(NID1);
325 mgr.balanceRoles();
326 checkDeviceMasters(deviceIds, expectedMasters);
327
328 // make N4 inactive
329 testClusterService.put(CNODE4, ControllerNode.State.INACTIVE);
330 expectedMasters.remove(NID4);
331 mgr.balanceRoles();
332 checkDeviceMasters(deviceIds, expectedMasters);
333
334 // make N3 inactive
335 testClusterService.put(CNODE3, ControllerNode.State.INACTIVE);
336 expectedMasters = Sets.newHashSet(NID2);
337 mgr.balanceRoles();
338 checkDeviceMasters(deviceIds, expectedMasters);
339
340 // make N3 active
341 testClusterService.put(CNODE3, ControllerNode.State.ACTIVE);
342 expectedMasters = Sets.newHashSet(NID3);
343 mgr.balanceRoles();
344 checkDeviceMasters(deviceIds, expectedMasters);
345
346 // make N4 active
347 testClusterService.put(CNODE4, ControllerNode.State.ACTIVE);
348 expectedMasters.add(NID4);
349 mgr.balanceRoles();
350 checkDeviceMasters(deviceIds, expectedMasters);
351
352 // make N1 active
353 testClusterService.put(CNODE1, ControllerNode.State.ACTIVE);
354 expectedMasters.add(NID1);
355 mgr.balanceRoles();
356 checkDeviceMasters(deviceIds, expectedMasters);
357 }
358
pierventrecdcd91c2021-05-06 09:27:00 +0200359 @Test
360 public void demote() {
361 mgr.setRole(NID1, DID1, MASTER);
362 mgr.setRole(NID2, DID1, STANDBY);
363 mgr.setRole(NID3, DID1, STANDBY);
364 List<NodeId> stdbys = Lists.newArrayList(NID2, NID3);
365 MastershipInfo mastershipInfo = mgr.getMastershipFor(DID1);
366 assertTrue(mastershipInfo.master().isPresent());
367 assertEquals("wrong role", NID1, mastershipInfo.master().get());
368 assertEquals("wrong backups", stdbys, mastershipInfo.backups());
369 // No effect, it is the master
370 mgr.demote(NID1, DID1);
371 assertEquals("wrong role", NID1, mastershipInfo.master().get());
372 assertEquals("wrong backups", stdbys, mastershipInfo.backups());
373 // No effect, it is not part of the mastership
374 mgr.demote(NID4, DID1);
375 assertEquals("wrong role", NID1, mastershipInfo.master().get());
376 assertEquals("wrong backups", stdbys, mastershipInfo.backups());
377 // Demote N2
378 mgr.demote(NID2, DID1);
379 stdbys = Lists.newArrayList(NID3, NID2);
380 mastershipInfo = mgr.getMastershipFor(DID1);
381 assertEquals("wrong role", NID1, mastershipInfo.master().get());
382 assertEquals("wrong backups", stdbys, mastershipInfo.backups());
383 }
384
Claudine Chiudce08152016-03-09 18:19:28 +0000385 private void checkDeviceMasters(Set<DeviceId> deviceIds, Set<NodeId> expectedMasters) {
386 checkDeviceMasters(deviceIds, expectedMasters, null);
387 }
388
389 private void checkDeviceMasters(Set<DeviceId> deviceIds, Set<NodeId> expectedMasters,
390 Consumer<DeviceId> checkRole) {
391 // each device's master must be contained in the list of expectedMasters
Sho SHIMIZUa09e1bb2016-08-01 14:25:25 -0700392 deviceIds.forEach(deviceId -> {
Claudine Chiudce08152016-03-09 18:19:28 +0000393 assertTrue("wrong master:", expectedMasters.contains(mgr.getMasterFor(deviceId)));
394 if (checkRole != null) {
395 checkRole.accept(deviceId);
396 }
397 });
398 // each node in expectedMasters must have approximately the same number of devices
399 if (expectedMasters.size() > 1) {
400 int minValue = Integer.MAX_VALUE;
401 int maxDevices = -1;
402 for (NodeId nodeId: expectedMasters) {
403 int numDevicesManagedByNode = mgr.getDevicesOf(nodeId).size();
404 if (numDevicesManagedByNode < minValue) {
405 minValue = numDevicesManagedByNode;
406 }
407 if (numDevicesManagedByNode > maxDevices) {
408 maxDevices = numDevicesManagedByNode;
409 }
410 assertTrue("not balanced:", maxDevices - minValue <= 1);
411 }
412 }
413 }
414
415 private final class TestClusterService extends StaticClusterService {
Ayaka Koshibe406d0102014-09-24 16:08:12 -0700416
417 ControllerNode local = new DefaultControllerNode(NID_LOCAL, LOCALHOST);
418
419 @Override
420 public ControllerNode getLocalNode() {
421 return local;
422 }
423
Claudine Chiudce08152016-03-09 18:19:28 +0000424 public void put(ControllerNode cn, ControllerNode.State state) {
425 nodes.put(cn.id(), cn);
426 nodeStates.put(cn.id(), state);
Ayaka Koshibe406d0102014-09-24 16:08:12 -0700427 }
Ayaka Koshibe406d0102014-09-24 16:08:12 -0700428 }
Yuta HIGUCHI0c6e1842014-11-05 22:34:23 -0800429
430 private final class TestSimpleMastershipStore extends SimpleMastershipStore
431 implements MastershipStore {
432
433 public TestSimpleMastershipStore(ClusterService clusterService) {
434 super.clusterService = clusterService;
435 }
436 }
Claudine Chiudce08152016-03-09 18:19:28 +0000437
438 private class TestRegionManager extends RegionManager {
439 TestRegionManager() {
440 eventDispatcher = new TestEventDispatcher();
Simon Hunt53612212016-12-04 17:19:52 -0800441 networkConfigService = new NetworkConfigServiceAdapter();
Claudine Chiudce08152016-03-09 18:19:28 +0000442 }
443 }
Ayaka Koshibe406d0102014-09-24 16:08:12 -0700444}