blob: a6278b25997540b3f4bfb7cd998d5bf00ad464bd [file] [log] [blame]
/*
* Copyright 2018-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.segmentrouting;
import com.google.common.collect.Sets;
import org.junit.Before;
import org.junit.Test;
import org.onlab.packet.IpAddress;
import org.onosproject.cluster.ClusterService;
import org.onosproject.cluster.DefaultControllerNode;
import org.onosproject.cluster.NodeId;
import org.onosproject.mastership.MastershipService;
import org.onosproject.net.DeviceId;
import org.onosproject.net.device.DeviceService;
import org.onosproject.segmentrouting.config.DeviceConfiguration;
import org.onosproject.store.service.StorageService;
import org.onosproject.store.service.TestConsistentMap;
import org.onosproject.store.service.TestConsistentMultimap;
import java.util.Optional;
import static org.easymock.EasyMock.createMock;
import static org.easymock.EasyMock.expect;
import static org.easymock.EasyMock.replay;
import static org.easymock.EasyMock.reset;
import static org.junit.Assert.*;
public class DefaultRoutingHandlerTest {
private SegmentRoutingManager srManager;
private DefaultRoutingHandler dfh;
private static final DeviceId DEV1A = DeviceId.deviceId("of:1a");
private static final DeviceId DEV1B = DeviceId.deviceId("of:1b");
private static final DeviceId DEV2 = DeviceId.deviceId("of:2");
private static final NodeId NODE1 = NodeId.nodeId("192.168.1.1");
private static final NodeId NODE2 = NodeId.nodeId("192.168.1.2");
private static final NodeId NODE3 = NodeId.nodeId("192.168.1.3");
private static final IpAddress IP1 = IpAddress.valueOf("192.168.1.1");
private static final IpAddress IP2 = IpAddress.valueOf("192.168.1.2");
private static final IpAddress IP3 = IpAddress.valueOf("192.168.1.3");
@Before
public void setUp() {
srManager = createMock(SegmentRoutingManager.class);
srManager.storageService = createMock(StorageService.class);
expect(srManager.storageService.consistentMapBuilder()).andReturn(new TestConsistentMap.Builder<>()).anyTimes();
expect(srManager.storageService.consistentMultimapBuilder()).andReturn(
new TestConsistentMultimap.Builder<>()).anyTimes();
replay(srManager.storageService);
srManager.routingRulePopulator = createMock(RoutingRulePopulator.class);
srManager.deviceService = createMock(DeviceService.class);
srManager.deviceConfiguration = createMock(DeviceConfiguration.class);
srManager.mastershipService = createMock(MastershipService.class);
srManager.clusterService = createMock(ClusterService.class);
dfh = new DefaultRoutingHandler(srManager);
}
private void clearCache() {
dfh.invalidateShouldProgramCache(DEV1A);
dfh.invalidateShouldProgramCache(DEV1B);
dfh.invalidateShouldProgramCache(DEV2);
}
// Node 1 is the master of switch 1A, 1B, and 2
@Test
public void testShouldHandleRoutingCase1() {
expect(srManager.mastershipService.getMasterFor(DEV1A)).andReturn(NODE1).anyTimes();
expect(srManager.mastershipService.getMasterFor(DEV1B)).andReturn(NODE1).anyTimes();
expect(srManager.mastershipService.getMasterFor(DEV2)).andReturn(NODE1).anyTimes();
replay(srManager.mastershipService);
expect(srManager.getPairDeviceId(DEV1A)).andReturn(Optional.of(DEV1B)).anyTimes();
expect(srManager.getPairDeviceId(DEV1B)).andReturn(Optional.of(DEV1A)).anyTimes();
expect(srManager.getPairDeviceId(DEV2)).andReturn(Optional.empty()).anyTimes();
replay(srManager);
// Node 1 should program every device
expect(srManager.clusterService.getLocalNode()).andReturn(new DefaultControllerNode(NODE1, IP1)).anyTimes();
replay(srManager.clusterService);
assertTrue(dfh.shouldProgram(DEV1A));
assertTrue(dfh.shouldProgram(DEV1B));
assertTrue(dfh.shouldProgram(DEV2));
reset(srManager.clusterService);
clearCache();
// Node 2 should program no device
expect(srManager.clusterService.getLocalNode()).andReturn(new DefaultControllerNode(NODE2, IP2)).anyTimes();
replay(srManager.clusterService);
assertFalse(dfh.shouldProgram(DEV1A));
assertFalse(dfh.shouldProgram(DEV1B));
assertFalse(dfh.shouldProgram(DEV2));
reset(srManager.clusterService);
clearCache();
// Node 3 should program no device
expect(srManager.clusterService.getLocalNode()).andReturn(new DefaultControllerNode(NODE3, IP3)).anyTimes();
replay(srManager.clusterService);
assertFalse(dfh.shouldProgram(DEV1A));
assertFalse(dfh.shouldProgram(DEV1B));
assertFalse(dfh.shouldProgram(DEV2));
}
// Node 1 is the master of switch 1A, 1B
// Node 2 is the master of switch 2
@Test
public void testShouldHandleRoutingCase2() {
expect(srManager.mastershipService.getMasterFor(DEV1A)).andReturn(NODE1).anyTimes();
expect(srManager.mastershipService.getMasterFor(DEV1B)).andReturn(NODE1).anyTimes();
expect(srManager.mastershipService.getMasterFor(DEV2)).andReturn(NODE2).anyTimes();
replay(srManager.mastershipService);
expect(srManager.getPairDeviceId(DEV1A)).andReturn(Optional.of(DEV1B)).anyTimes();
expect(srManager.getPairDeviceId(DEV1B)).andReturn(Optional.of(DEV1A)).anyTimes();
expect(srManager.getPairDeviceId(DEV2)).andReturn(Optional.empty()).anyTimes();
replay(srManager);
// Node 1 should program 1A, 1B
expect(srManager.clusterService.getLocalNode()).andReturn(new DefaultControllerNode(NODE1, IP1)).anyTimes();
replay(srManager.clusterService);
assertTrue(dfh.shouldProgram(DEV1A));
assertTrue(dfh.shouldProgram(DEV1B));
assertFalse(dfh.shouldProgram(DEV2));
reset(srManager.clusterService);
clearCache();
// Node 2 should program 2
expect(srManager.clusterService.getLocalNode()).andReturn(new DefaultControllerNode(NODE2, IP2)).anyTimes();
replay(srManager.clusterService);
assertFalse(dfh.shouldProgram(DEV1A));
assertFalse(dfh.shouldProgram(DEV1B));
assertTrue(dfh.shouldProgram(DEV2));
reset(srManager.clusterService);
clearCache();
// Node 3 should program no device
expect(srManager.clusterService.getLocalNode()).andReturn(new DefaultControllerNode(NODE3, IP3)).anyTimes();
replay(srManager.clusterService);
assertFalse(dfh.shouldProgram(DEV1A));
assertFalse(dfh.shouldProgram(DEV1B));
assertFalse(dfh.shouldProgram(DEV2));
}
// Node 1 is the master of switch 1A
// Node 2 is the master of switch 1B
// Node 3 is the master of switch 2
@Test
public void testShouldHandleRoutingCase3() {
expect(srManager.mastershipService.getMasterFor(DEV1A)).andReturn(NODE1).anyTimes();
expect(srManager.mastershipService.getMasterFor(DEV1B)).andReturn(NODE2).anyTimes();
expect(srManager.mastershipService.getMasterFor(DEV2)).andReturn(NODE3).anyTimes();
replay(srManager.mastershipService);
expect(srManager.getPairDeviceId(DEV1A)).andReturn(Optional.of(DEV1B)).anyTimes();
expect(srManager.getPairDeviceId(DEV1B)).andReturn(Optional.of(DEV1A)).anyTimes();
expect(srManager.getPairDeviceId(DEV2)).andReturn(Optional.empty()).anyTimes();
replay(srManager);
// Node 1 should program 1A, 1B
expect(srManager.clusterService.getLocalNode()).andReturn(new DefaultControllerNode(NODE1, IP1)).anyTimes();
replay(srManager.clusterService);
assertTrue(dfh.shouldProgram(DEV1A));
assertTrue(dfh.shouldProgram(DEV1B));
assertFalse(dfh.shouldProgram(DEV2));
reset(srManager.clusterService);
clearCache();
// Node 2 should program no device
expect(srManager.clusterService.getLocalNode()).andReturn(new DefaultControllerNode(NODE2, IP2)).anyTimes();
replay(srManager.clusterService);
assertFalse(dfh.shouldProgram(DEV1A));
assertFalse(dfh.shouldProgram(DEV1B));
assertFalse(dfh.shouldProgram(DEV2));
reset(srManager.clusterService);
clearCache();
// Node 3 should program 2
expect(srManager.clusterService.getLocalNode()).andReturn(new DefaultControllerNode(NODE3, IP3)).anyTimes();
replay(srManager.clusterService);
assertFalse(dfh.shouldProgram(DEV1A));
assertFalse(dfh.shouldProgram(DEV1B));
assertTrue(dfh.shouldProgram(DEV2));
}
// Node 3 is the master of switch 1A, 1B, 2
// Later on, node 1 becomes the master of 1A; Node 2 becomes the master of 1B.
@Test
public void testShouldHandleRoutingCase4() {
expect(srManager.mastershipService.getMasterFor(DEV1A)).andReturn(NODE3).anyTimes();
expect(srManager.mastershipService.getMasterFor(DEV1B)).andReturn(NODE3).anyTimes();
expect(srManager.mastershipService.getMasterFor(DEV2)).andReturn(NODE3).anyTimes();
replay(srManager.mastershipService);
expect(srManager.getPairDeviceId(DEV1A)).andReturn(Optional.of(DEV1B)).anyTimes();
expect(srManager.getPairDeviceId(DEV1B)).andReturn(Optional.of(DEV1A)).anyTimes();
expect(srManager.getPairDeviceId(DEV2)).andReturn(Optional.empty()).anyTimes();
replay(srManager);
// Node 1 should program no device
expect(srManager.clusterService.getLocalNode()).andReturn(new DefaultControllerNode(NODE1, IP1)).anyTimes();
replay(srManager.clusterService);
assertFalse(dfh.shouldProgram(DEV1A));
assertFalse(dfh.shouldProgram(DEV1B));
assertFalse(dfh.shouldProgram(DEV2));
reset(srManager.clusterService);
clearCache();
// Node 2 should program no device
expect(srManager.clusterService.getLocalNode()).andReturn(new DefaultControllerNode(NODE2, IP2)).anyTimes();
replay(srManager.clusterService);
assertFalse(dfh.shouldProgram(DEV1A));
assertFalse(dfh.shouldProgram(DEV1B));
assertFalse(dfh.shouldProgram(DEV2));
reset(srManager.clusterService);
clearCache();
// Node 3 should program 1A, 1B and 2
expect(srManager.clusterService.getLocalNode()).andReturn(new DefaultControllerNode(NODE3, IP3)).anyTimes();
replay(srManager.clusterService);
assertTrue(dfh.shouldProgram(DEV1A));
assertTrue(dfh.shouldProgram(DEV1B));
assertTrue(dfh.shouldProgram(DEV2));
// Mastership of switch 1A moves to Node 1
reset(srManager.mastershipService);
expect(srManager.mastershipService.getMasterFor(DEV1A)).andReturn(NODE1).anyTimes();
expect(srManager.mastershipService.getMasterFor(DEV1B)).andReturn(NODE2).anyTimes();
expect(srManager.mastershipService.getMasterFor(DEV2)).andReturn(NODE3).anyTimes();
replay(srManager.mastershipService);
reset(srManager.clusterService);
clearCache();
// Node 1 should program 1A, 1B
expect(srManager.clusterService.getLocalNode()).andReturn(new DefaultControllerNode(NODE1, IP1)).anyTimes();
replay(srManager.clusterService);
assertTrue(dfh.shouldProgram(DEV1A));
assertTrue(dfh.shouldProgram(DEV1B));
assertFalse(dfh.shouldProgram(DEV2));
reset(srManager.clusterService);
clearCache();
// Node 2 should program no device
expect(srManager.clusterService.getLocalNode()).andReturn(new DefaultControllerNode(NODE2, IP2)).anyTimes();
replay(srManager.clusterService);
assertFalse(dfh.shouldProgram(DEV1A));
assertFalse(dfh.shouldProgram(DEV1B));
assertFalse(dfh.shouldProgram(DEV2));
reset(srManager.clusterService);
clearCache();
// Node 3 should program 2
expect(srManager.clusterService.getLocalNode()).andReturn(new DefaultControllerNode(NODE3, IP3)).anyTimes();
replay(srManager.clusterService);
assertFalse(dfh.shouldProgram(DEV1A));
assertFalse(dfh.shouldProgram(DEV1B));
assertTrue(dfh.shouldProgram(DEV2));
}
// Node 1 is the master of 1A. 1B has no master
// Node 2 becomes the master of 1B later
@Test
public void testShouldHandleRoutingCase5() {
expect(srManager.mastershipService.getMasterFor(DEV1A)).andReturn(NODE1).anyTimes();
expect(srManager.mastershipService.getMasterFor(DEV1B)).andReturn(null).anyTimes();
replay(srManager.mastershipService);
expect(srManager.getPairDeviceId(DEV1A)).andReturn(Optional.of(DEV1B)).anyTimes();
expect(srManager.getPairDeviceId(DEV1B)).andReturn(Optional.of(DEV1A)).anyTimes();
replay(srManager);
// Node 1 should program both 1A and 1B
expect(srManager.clusterService.getLocalNode()).andReturn(new DefaultControllerNode(NODE1, IP1)).anyTimes();
replay(srManager.clusterService);
assertTrue(dfh.shouldProgram(DEV1A));
assertTrue(dfh.shouldProgram(DEV1B));
reset(srManager.clusterService);
clearCache();
// Node 2 should program no device
expect(srManager.clusterService.getLocalNode()).andReturn(new DefaultControllerNode(NODE2, IP2)).anyTimes();
replay(srManager.clusterService);
assertFalse(dfh.shouldProgram(DEV1A));
assertFalse(dfh.shouldProgram(DEV1B));
// Mastership of switch 1B moves to Node 2
reset(srManager.mastershipService);
expect(srManager.mastershipService.getMasterFor(DEV1A)).andReturn(NODE1).anyTimes();
expect(srManager.mastershipService.getMasterFor(DEV1B)).andReturn(NODE2).anyTimes();
replay(srManager.mastershipService);
reset(srManager.clusterService);
clearCache();
// Node 1 should program 1A, 1B
expect(srManager.clusterService.getLocalNode()).andReturn(new DefaultControllerNode(NODE1, IP1)).anyTimes();
replay(srManager.clusterService);
assertTrue(dfh.shouldProgram(DEV1A));
assertTrue(dfh.shouldProgram(DEV1B));
reset(srManager.clusterService);
clearCache();
// Node 2 should program no device
expect(srManager.clusterService.getLocalNode()).andReturn(new DefaultControllerNode(NODE2, IP2)).anyTimes();
replay(srManager.clusterService);
assertFalse(dfh.shouldProgram(DEV1A));
assertFalse(dfh.shouldProgram(DEV1B));
}
// Neither 1A or 1B has master
@Test
public void testShouldHandleRoutingCase6() {
expect(srManager.mastershipService.getMasterFor(DEV1A)).andReturn(null).anyTimes();
expect(srManager.mastershipService.getMasterFor(DEV1B)).andReturn(null).anyTimes();
replay(srManager.mastershipService);
expect(srManager.getPairDeviceId(DEV1A)).andReturn(Optional.of(DEV1B)).anyTimes();
expect(srManager.getPairDeviceId(DEV1B)).andReturn(Optional.of(DEV1A)).anyTimes();
replay(srManager);
// Node 1 should program no device
expect(srManager.clusterService.getLocalNode()).andReturn(new DefaultControllerNode(NODE1, IP1)).anyTimes();
replay(srManager.clusterService);
assertFalse(dfh.shouldProgram(DEV1A));
assertFalse(dfh.shouldProgram(DEV1B));
reset(srManager.clusterService);
clearCache();
// Node 2 should program no device
expect(srManager.clusterService.getLocalNode()).andReturn(new DefaultControllerNode(NODE2, IP2)).anyTimes();
replay(srManager.clusterService);
assertFalse(dfh.shouldProgram(DEV1A));
assertFalse(dfh.shouldProgram(DEV1B));
assertFalse(dfh.shouldProgram.containsKey(Sets.newHashSet(DEV1A, DEV1B)));
}
}