[ONOS-6371] (vnet) mastership manager tests
Test cases for virtual network mastership manager.
Change-Id: I129dfc7510c3a75fcca0ecd48a33cc77e1a641ce
diff --git a/incubator/net/src/main/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkMastershipManager.java b/incubator/net/src/main/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkMastershipManager.java
index 7d973e0..352ae6c 100644
--- a/incubator/net/src/main/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkMastershipManager.java
+++ b/incubator/net/src/main/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkMastershipManager.java
@@ -45,9 +45,9 @@
import java.util.List;
import java.util.Set;
import java.util.concurrent.CompletableFuture;
+import java.util.stream.Collectors;
import static com.google.common.base.Preconditions.checkNotNull;
-import static com.google.common.collect.Lists.newArrayList;
import static org.onlab.metrics.MetricsUtil.startTimer;
import static org.onlab.metrics.MetricsUtil.stopTimer;
import static org.slf4j.LoggerFactory.getLogger;
@@ -176,11 +176,15 @@
@Override
public void balanceRoles() {
//FIXME: More advanced logic for balancing virtual network roles.
- List<ControllerNode> nodes = newArrayList(clusterService.getNodes());
+ List<ControllerNode> nodes = clusterService.getNodes().stream()
+ .filter(n -> clusterService.getState(n.id())
+ .equals(ControllerNode.State.ACTIVE))
+ .collect(Collectors.toList());
+
nodes.sort(Comparator.comparing(ControllerNode::id));
//Pick a node using network Id,
- NodeId masterNode = nodes.get((int) (networkId.id() % nodes.size())).id();
+ NodeId masterNode = nodes.get((int) ((networkId.id() - 1) % nodes.size())).id();
List<CompletableFuture<Void>> setRoleFutures = Lists.newLinkedList();
for (VirtualDevice device : manager.getVirtualDevices(networkId)) {
diff --git a/incubator/net/src/test/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkMastershipManagerTest.java b/incubator/net/src/test/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkMastershipManagerTest.java
new file mode 100644
index 0000000..ce9a433
--- /dev/null
+++ b/incubator/net/src/test/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkMastershipManagerTest.java
@@ -0,0 +1,312 @@
+/*
+ * Copyright 2017-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.incubator.net.virtual.impl;
+
+import com.google.common.collect.Sets;
+import com.google.common.util.concurrent.Futures;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.onlab.junit.TestUtils;
+import org.onlab.osgi.ServiceDirectory;
+import org.onlab.osgi.TestServiceDirectory;
+import org.onlab.packet.IpAddress;
+import org.onosproject.cluster.ClusterService;
+import org.onosproject.cluster.ClusterServiceAdapter;
+import org.onosproject.cluster.ControllerNode;
+import org.onosproject.cluster.DefaultControllerNode;
+import org.onosproject.cluster.NodeId;
+import org.onosproject.common.event.impl.TestEventDispatcher;
+import org.onosproject.core.CoreService;
+import org.onosproject.event.EventDeliveryService;
+import org.onosproject.incubator.net.virtual.TenantId;
+import org.onosproject.incubator.net.virtual.VirtualNetwork;
+import org.onosproject.incubator.net.virtual.VirtualNetworkMastershipStore;
+import org.onosproject.incubator.net.virtual.VirtualNetworkStore;
+import org.onosproject.incubator.store.virtual.impl.DistributedVirtualNetworkStore;
+import org.onosproject.incubator.store.virtual.impl.SimpleVirtualMastershipStore;
+import org.onosproject.mastership.MastershipService;
+import org.onosproject.mastership.MastershipTermService;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.NetTestTools;
+import org.onosproject.store.service.TestStorageService;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+import static org.onosproject.net.MastershipRole.MASTER;
+import static org.onosproject.net.MastershipRole.STANDBY;
+import static org.onosproject.net.MastershipRole.NONE;
+
+public class VirtualNetworkMastershipManagerTest {
+
+ private static final NodeId NID_LOCAL = new NodeId("local");
+ private static final NodeId NID_OTHER = new NodeId("foo");
+ private static final IpAddress LOCALHOST = IpAddress.valueOf("127.0.0.1");
+
+ private static final TenantId TID = TenantId.tenantId("1");
+
+ private static final DeviceId VDID1 = DeviceId.deviceId("foo:vd1");
+ private static final DeviceId VDID2 = DeviceId.deviceId("foo:vd2");
+ private static final DeviceId VDID3 = DeviceId.deviceId("foo:vd3");
+ private static final DeviceId VDID4 = DeviceId.deviceId("foo:vd4");
+
+ private static final NodeId NID1 = NodeId.nodeId("n1");
+ private static final NodeId NID2 = NodeId.nodeId("n2");
+ private static final NodeId NID3 = NodeId.nodeId("n3");
+ private static final NodeId NID4 = NodeId.nodeId("n4");
+
+ private static final ControllerNode CNODE1 =
+ new DefaultControllerNode(NID1, IpAddress.valueOf("127.0.1.1"));
+ private static final ControllerNode CNODE2 =
+ new DefaultControllerNode(NID2, IpAddress.valueOf("127.0.1.2"));
+ private static final ControllerNode CNODE3 =
+ new DefaultControllerNode(NID3, IpAddress.valueOf("127.0.1.3"));
+ private static final ControllerNode CNODE4 =
+ new DefaultControllerNode(NID4, IpAddress.valueOf("127.0.1.4"));
+
+ private VirtualNetworkManager manager;
+ private DistributedVirtualNetworkStore virtualNetworkManagerStore;
+
+ private VirtualNetworkMastershipManager mastershipMgr1;
+ private VirtualNetworkMastershipManager mastershipMgr2;
+ protected MastershipService service;
+ private TestClusterService testClusterService;
+ private EventDeliveryService eventDeliveryService;
+
+ private VirtualNetwork vnet1;
+ private VirtualNetwork vnet2;
+
+ @Before
+ public void setUp() throws Exception {
+ virtualNetworkManagerStore = new DistributedVirtualNetworkStore();
+
+ CoreService coreService = new TestCoreService();
+ TestUtils.setField(virtualNetworkManagerStore, "coreService", coreService);
+ TestUtils.setField(virtualNetworkManagerStore, "storageService", new TestStorageService());
+ virtualNetworkManagerStore.activate();
+
+ manager = new VirtualNetworkManager();
+ manager.store = virtualNetworkManagerStore;
+ TestUtils.setField(manager, "coreService", coreService);
+
+ eventDeliveryService = new TestEventDispatcher();
+ NetTestTools.injectEventDispatcher(manager, eventDeliveryService);
+
+ SimpleVirtualMastershipStore store = new SimpleVirtualMastershipStore();
+ TestUtils.setField(store, "coreService", coreService);
+ store.activate();
+
+ testClusterService = new TestClusterService();
+
+ ServiceDirectory testDirectory = new TestServiceDirectory()
+ .add(VirtualNetworkStore.class, virtualNetworkManagerStore)
+ .add(CoreService.class, coreService)
+ .add(EventDeliveryService.class, eventDeliveryService)
+ .add(ClusterService.class, testClusterService)
+ .add(VirtualNetworkMastershipStore.class, store);
+ TestUtils.setField(manager, "serviceDirectory", testDirectory);
+
+ manager.activate();
+
+ createVnets();
+
+ mastershipMgr1 = new VirtualNetworkMastershipManager(manager, vnet1.id());
+ mastershipMgr2 = new VirtualNetworkMastershipManager(manager, vnet2.id());
+ service = mastershipMgr1;
+ }
+
+ private void createVnets() {
+ manager.registerTenantId(TID);
+
+ vnet1 = manager.createVirtualNetwork(TID);
+ manager.createVirtualDevice(vnet1.id(), VDID1);
+ manager.createVirtualDevice(vnet1.id(), VDID2);
+
+ vnet2 = manager.createVirtualNetwork(TID);
+ manager.createVirtualDevice(vnet2.id(), VDID3);
+ manager.createVirtualDevice(vnet2.id(), VDID4);
+ }
+
+ @After
+ public void tearDown() {
+ manager.deactivate();
+ virtualNetworkManagerStore.deactivate();
+ }
+
+ @Test
+ public void setRole() {
+ mastershipMgr1.setRole(NID_OTHER, VDID1, MASTER);
+ assertEquals("wrong local role:", NONE, mastershipMgr1.getLocalRole(VDID1));
+ assertEquals("wrong obtained role:", STANDBY, Futures.getUnchecked(mastershipMgr1.requestRoleFor(VDID1)));
+
+ //set to master
+ mastershipMgr1.setRole(NID_LOCAL, VDID1, MASTER);
+ assertEquals("wrong local role:", MASTER, mastershipMgr1.getLocalRole(VDID1));
+ }
+
+ @Test
+ public void relinquishMastership() {
+ //no backups - should just turn to NONE for device.
+ mastershipMgr1.setRole(NID_LOCAL, VDID1, MASTER);
+ assertEquals("wrong role:", MASTER, mastershipMgr1.getLocalRole(VDID1));
+ mastershipMgr1.relinquishMastership(VDID1);
+ assertNull("wrong master:", mastershipMgr1.getMasterFor(VDID2));
+ assertEquals("wrong role:", NONE, mastershipMgr1.getLocalRole(VDID1));
+
+ //not master, nothing should happen
+ mastershipMgr1.setRole(NID_LOCAL, VDID2, NONE);
+ mastershipMgr1.relinquishMastership(VDID2);
+ assertNull("wrong role:", mastershipMgr1.getMasterFor(VDID2));
+
+ //provide NID_OTHER as backup and relinquish
+ mastershipMgr1.setRole(NID_LOCAL, VDID1, MASTER);
+ assertEquals("wrong master:", NID_LOCAL, mastershipMgr1.getMasterFor(VDID1));
+ mastershipMgr1.setRole(NID_OTHER, VDID1, STANDBY);
+ mastershipMgr1.relinquishMastership(VDID1);
+ assertEquals("wrong master:", NID_OTHER, mastershipMgr1.getMasterFor(VDID1));
+ }
+
+ @Test
+ public void requestRoleFor() {
+ mastershipMgr1.setRole(NID_LOCAL, VDID1, MASTER);
+ mastershipMgr1.setRole(NID_OTHER, VDID2, MASTER);
+
+ //local should be master for one but standby for other
+ assertEquals("wrong role:", MASTER, Futures.getUnchecked(mastershipMgr1.requestRoleFor(VDID1)));
+ assertEquals("wrong role:", STANDBY, Futures.getUnchecked(mastershipMgr1.requestRoleFor(VDID2)));
+ }
+
+ @Test
+ public void getMasterFor() {
+ mastershipMgr1.setRole(NID_LOCAL, VDID1, MASTER);
+ mastershipMgr1.setRole(NID_OTHER, VDID2, MASTER);
+ assertEquals("wrong master:", NID_LOCAL, mastershipMgr1.getMasterFor(VDID1));
+ assertEquals("wrong master:", NID_OTHER, mastershipMgr1.getMasterFor(VDID2));
+
+ //have NID_OTHER hand over VDID2 to NID_LOCAL
+ mastershipMgr1.setRole(NID_LOCAL, VDID2, MASTER);
+ assertEquals("wrong master:", NID_LOCAL, mastershipMgr1.getMasterFor(VDID2));
+ }
+
+ @Test
+ public void getDevicesOf() {
+ mastershipMgr1.setRole(NID_LOCAL, VDID1, MASTER);
+ mastershipMgr1.setRole(NID_LOCAL, VDID2, STANDBY);
+ assertEquals("should be one device:", 1, mastershipMgr1.getDevicesOf(NID_LOCAL).size());
+ //hand both devices to NID_LOCAL
+ mastershipMgr1.setRole(NID_LOCAL, VDID2, MASTER);
+ assertEquals("should be two devices:", 2, mastershipMgr1.getDevicesOf(NID_LOCAL).size());
+ }
+
+ @Test
+ public void termService() {
+ MastershipTermService ts = mastershipMgr1;
+
+ //term = 1 for both
+ mastershipMgr1.setRole(NID_LOCAL, VDID1, MASTER);
+ assertEquals("inconsistent term: ", 1,
+ ts.getMastershipTerm(VDID1).termNumber());
+
+ //hand devices to NID_LOCAL and back: term = 1 + 2
+ mastershipMgr1.setRole(NID_OTHER, VDID1, MASTER);
+ mastershipMgr1.setRole(NID_LOCAL, VDID1, MASTER);
+ assertEquals("inconsistent terms: ",
+ 3, ts.getMastershipTerm(VDID1).termNumber());
+ }
+
+ @Test
+ public void balanceWithVnets() {
+
+ testClusterService.put(CNODE1, ControllerNode.State.ACTIVE);
+ testClusterService.put(CNODE2, ControllerNode.State.ACTIVE);
+
+ mastershipMgr1.setRole(NID_LOCAL, VDID1, MASTER);
+ mastershipMgr1.setRole(NID_LOCAL, VDID2, MASTER);
+ assertEquals("wrong local role:", MASTER, mastershipMgr1.getLocalRole(VDID1));
+ assertEquals("wrong local role:", MASTER, mastershipMgr1.getLocalRole(VDID2));
+ assertEquals("wrong master:", NID_LOCAL, mastershipMgr1.getMasterFor(VDID1));
+ assertEquals("wrong master:", NID_LOCAL, mastershipMgr1.getMasterFor(VDID2));
+
+ //do balancing according to vnet Id.
+ mastershipMgr1.balanceRoles();
+ assertEquals("wrong master:", NID1, mastershipMgr1.getMasterFor(VDID1));
+ assertEquals("wrong master:", NID1, mastershipMgr1.getMasterFor(VDID2));
+
+ mastershipMgr2.setRole(NID_LOCAL, VDID3, MASTER);
+ mastershipMgr2.setRole(NID_LOCAL, VDID4, MASTER);
+ assertEquals("wrong local role:", MASTER, mastershipMgr2.getLocalRole(VDID3));
+ assertEquals("wrong local role:", MASTER, mastershipMgr2.getLocalRole(VDID4));
+ assertEquals("wrong master:", NID_LOCAL, mastershipMgr2.getMasterFor(VDID3));
+ assertEquals("wrong master:", NID_LOCAL, mastershipMgr2.getMasterFor(VDID4));
+
+ //do balancing according to vnet Id.
+ mastershipMgr2.balanceRoles();
+ assertEquals("wrong master:", NID2, mastershipMgr2.getMasterFor(VDID3));
+ assertEquals("wrong master:", NID2, mastershipMgr2.getMasterFor(VDID4));
+
+ // make N1 inactive
+ testClusterService.put(CNODE1, ControllerNode.State.INACTIVE);
+ mastershipMgr1.balanceRoles();
+ assertEquals("wrong master:", NID2, mastershipMgr1.getMasterFor(VDID1));
+ assertEquals("wrong master:", NID2, mastershipMgr1.getMasterFor(VDID2));
+ }
+
+ private final class TestClusterService extends ClusterServiceAdapter {
+
+ final Map<NodeId, ControllerNode> nodes = new HashMap<>();
+ final Map<NodeId, ControllerNode.State> nodeStates = new HashMap<>();
+
+ ControllerNode local = new DefaultControllerNode(NID_LOCAL, LOCALHOST);
+
+ @Override
+ public ControllerNode getLocalNode() {
+ return local;
+ }
+
+ @Override
+ public Set<ControllerNode> getNodes() {
+ return Sets.newHashSet(nodes.values());
+ }
+
+ @Override
+ public ControllerNode getNode(NodeId nodeId) {
+ return nodes.get(nodeId);
+ }
+
+ @Override
+ public ControllerNode.State getState(NodeId nodeId) {
+ return nodeStates.get(nodeId);
+ }
+
+ public void put(ControllerNode cn, ControllerNode.State state) {
+ nodes.put(cn.id(), cn);
+ nodeStates.put(cn.id(), state);
+ }
+ }
+
+ private final class TestSimpleMastershipStore extends SimpleVirtualMastershipStore
+ implements VirtualNetworkMastershipStore {
+
+ public TestSimpleMastershipStore(ClusterService clusterService) {
+ super.clusterService = clusterService;
+ }
+ }
+}
\ No newline at end of file