blob: 168e94b29fba2d8d69d59941e1359b2bb5010898 [file] [log] [blame]
/*
* Copyright 2017-present Open Networking Foundation
*
* 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;
}
}
}