| /* |
| * 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.openstacknode.impl; |
| |
| import com.google.common.collect.ImmutableSet; |
| import com.google.common.collect.Lists; |
| import com.google.common.collect.Maps; |
| import com.google.common.util.concurrent.MoreExecutors; |
| import org.junit.After; |
| import org.junit.Before; |
| import org.junit.Test; |
| import org.onlab.junit.TestUtils; |
| import org.onlab.packet.ChassisId; |
| import org.onlab.packet.Ip4Address; |
| import org.onlab.packet.IpAddress; |
| import org.onlab.packet.MacAddress; |
| import org.onlab.packet.VlanId; |
| import org.onosproject.cfg.ComponentConfigAdapter; |
| import org.onosproject.cluster.ClusterServiceAdapter; |
| import org.onosproject.cluster.ControllerNode; |
| import org.onosproject.cluster.DefaultControllerNode; |
| import org.onosproject.cluster.LeadershipServiceAdapter; |
| import org.onosproject.cluster.NodeId; |
| import org.onosproject.core.ApplicationId; |
| import org.onosproject.core.CoreServiceAdapter; |
| import org.onosproject.core.DefaultApplicationId; |
| import org.onosproject.core.GroupId; |
| import org.onosproject.net.Annotations; |
| import org.onosproject.net.DefaultAnnotations; |
| import org.onosproject.net.DefaultDevice; |
| import org.onosproject.net.DefaultPort; |
| import org.onosproject.net.Device; |
| import org.onosproject.net.DeviceId; |
| import org.onosproject.net.Port; |
| import org.onosproject.net.PortNumber; |
| import org.onosproject.net.behaviour.BridgeConfig; |
| import org.onosproject.net.behaviour.BridgeDescription; |
| import org.onosproject.net.behaviour.BridgeName; |
| import org.onosproject.net.behaviour.ControllerInfo; |
| import org.onosproject.net.behaviour.DefaultBridgeDescription; |
| import org.onosproject.net.behaviour.ExtensionTreatmentResolver; |
| import org.onosproject.net.behaviour.InterfaceConfig; |
| import org.onosproject.net.behaviour.PatchDescription; |
| import org.onosproject.net.behaviour.TunnelDescription; |
| import org.onosproject.net.device.DefaultPortDescription; |
| import org.onosproject.net.device.DeviceAdminService; |
| import org.onosproject.net.device.DeviceEvent; |
| import org.onosproject.net.device.DeviceInterfaceDescription; |
| import org.onosproject.net.device.DeviceListener; |
| import org.onosproject.net.device.DeviceServiceAdapter; |
| import org.onosproject.net.device.PortDescription; |
| import org.onosproject.net.driver.Behaviour; |
| import org.onosproject.net.driver.DriverData; |
| import org.onosproject.net.driver.DriverHandler; |
| import org.onosproject.net.flow.instructions.ExtensionPropertyException; |
| import org.onosproject.net.flow.instructions.ExtensionTreatment; |
| import org.onosproject.net.flow.instructions.ExtensionTreatmentType; |
| import org.onosproject.net.group.DefaultGroup; |
| import org.onosproject.net.group.Group; |
| import org.onosproject.net.group.GroupBuckets; |
| import org.onosproject.net.group.GroupDescription; |
| import org.onosproject.net.group.GroupEvent; |
| import org.onosproject.net.group.GroupKey; |
| import org.onosproject.net.group.GroupListener; |
| import org.onosproject.net.group.GroupService; |
| import org.onosproject.net.provider.ProviderId; |
| import org.onosproject.openstacknode.api.NodeState; |
| import org.onosproject.openstacknode.api.OpenstackNode; |
| import org.onosproject.openstacknode.api.OpenstackNodeAdminService; |
| import org.onosproject.openstacknode.api.OpenstackNodeListener; |
| import org.onosproject.openstacknode.api.OpenstackNodeService; |
| import org.onosproject.ovsdb.controller.OvsdbClientService; |
| import org.onosproject.ovsdb.controller.OvsdbController; |
| |
| import java.util.Collection; |
| import java.util.List; |
| import java.util.Map; |
| import java.util.Objects; |
| import java.util.Set; |
| import java.util.stream.Collectors; |
| |
| import static org.easymock.EasyMock.*; |
| import static org.easymock.EasyMock.expect; |
| import static org.junit.Assert.assertEquals; |
| import static org.onosproject.net.AnnotationKeys.PORT_NAME; |
| import static org.onosproject.net.Device.Type.CONTROLLER; |
| import static org.onosproject.net.Device.Type.SWITCH; |
| import static org.onosproject.net.device.DeviceEvent.Type.*; |
| import static org.onosproject.openstacknode.api.Constants.*; |
| import static org.onosproject.openstacknode.api.NodeState.*; |
| import static org.onosproject.openstacknode.api.OpenstackNode.NodeType.COMPUTE; |
| import static org.onosproject.openstacknode.api.OpenstackNode.NodeType.GATEWAY; |
| |
| /** |
| * Unit test for DefaultOpenstackNodeHandler. |
| */ |
| public class DefaultOpenstackNodeHandlerTest { |
| |
| private static final ApplicationId TEST_APP_ID = new DefaultApplicationId(1, "test"); |
| private static final String ERR_STATE_NOT_MATCH = "Node state did not match"; |
| private static final NodeId LOCAL_NODE_ID = new NodeId("local"); |
| private static final ControllerNode LOCAL_CTRL = |
| new DefaultControllerNode(LOCAL_NODE_ID, IpAddress.valueOf("127.0.0.1")); |
| |
| private static final BridgeDescription ROUT_BRIDGE = DefaultBridgeDescription.builder() |
| .name(ROUTER_BRIDGE) |
| .failMode(BridgeDescription.FailMode.SECURE) |
| .disableInBand() |
| .build(); |
| |
| private static final PortDescription PATCH_ROUT = new DefaultPortDescription( |
| PortNumber.portNumber(1), |
| true, |
| DefaultAnnotations.builder() |
| .set(PORT_NAME, PATCH_ROUT_BRIDGE) |
| .build() |
| ); |
| |
| private static final String COMPUTE_1_HOSTNAME = "compute_1"; |
| private static final String COMPUTE_2_HOSTNAME = "compute_2"; |
| private static final String COMPUTE_3_HOSTNAME = "compute_3"; |
| private static final String COMPUTE_4_HOSTNAME = "compute_4"; |
| private static final String GATEWAY_1_HOSTNAME = "gateway_1"; |
| private static final String GATEWAY_2_HOSTNAME = "gateway_2"; |
| private static final String GATEWAY_3_HOSTNAME = "gateway_3"; |
| private static final String GATEWAY_4_HOSTNAME = "gateway_4"; |
| |
| private static final IpAddress COMPUTE_1_IP = IpAddress.valueOf("10.100.0.1"); |
| private static final IpAddress COMPUTE_2_IP = IpAddress.valueOf("10.100.0.2"); |
| private static final IpAddress COMPUTE_3_IP = IpAddress.valueOf("10.100.0.3"); |
| private static final IpAddress COMPUTE_4_IP = IpAddress.valueOf("10.100.0.4"); |
| private static final IpAddress GATEWAY_1_IP = IpAddress.valueOf("10.100.0.5"); |
| private static final IpAddress GATEWAY_2_IP = IpAddress.valueOf("10.100.0.6"); |
| private static final IpAddress GATEWAY_3_IP = IpAddress.valueOf("10.100.0.7"); |
| private static final IpAddress GATEWAY_4_IP = IpAddress.valueOf("10.100.0.8"); |
| |
| private static final Device COMPUTE_1_INTG_DEVICE = createOpenFlowDevice(1, INTEGRATION_BRIDGE); |
| private static final Device COMPUTE_2_INTG_DEVICE = createOpenFlowDevice(2, INTEGRATION_BRIDGE); |
| private static final Device COMPUTE_3_INTG_DEVICE = createOpenFlowDevice(3, INTEGRATION_BRIDGE); |
| private static final Device COMPUTE_4_INTG_DEVICE = createOpenFlowDevice(4, INTEGRATION_BRIDGE); |
| private static final Device GATEWAY_1_INTG_DEVICE = createOpenFlowDevice(5, INTEGRATION_BRIDGE); |
| private static final Device GATEWAY_1_ROUT_DEVICE = createOpenFlowDevice(6, ROUTER_BRIDGE); |
| private static final Device GATEWAY_2_INTG_DEVICE = createOpenFlowDevice(7, INTEGRATION_BRIDGE); |
| private static final Device GATEWAY_2_ROUT_DEVICE = createOpenFlowDevice(8, ROUTER_BRIDGE); |
| private static final Device GATEWAY_3_INTG_DEVICE = createOpenFlowDevice(9, INTEGRATION_BRIDGE); |
| private static final Device GATEWAY_3_ROUT_DEVICE = createOpenFlowDevice(10, ROUTER_BRIDGE); |
| private static final Device GATEWAY_4_INTG_DEVICE = createOpenFlowDevice(11, INTEGRATION_BRIDGE); |
| private static final Device GATEWAY_4_ROUT_DEVICE = createOpenFlowDevice(12, ROUTER_BRIDGE); |
| |
| private static final Device COMPUTE_1_OVSDB_DEVICE = createOvsdbDevice(COMPUTE_1_IP); |
| private static final Device COMPUTE_2_OVSDB_DEVICE = createOvsdbDevice(COMPUTE_2_IP); |
| private static final Device COMPUTE_3_OVSDB_DEVICE = createOvsdbDevice(COMPUTE_3_IP); |
| private static final Device COMPUTE_4_OVSDB_DEVICE = createOvsdbDevice(COMPUTE_4_IP); |
| private static final Device GATEWAY_1_OVSDB_DEVICE = createOvsdbDevice(GATEWAY_1_IP); |
| private static final Device GATEWAY_2_OVSDB_DEVICE = createOvsdbDevice(GATEWAY_2_IP); |
| |
| private static final OpenstackNode COMPUTE_1 = createNode( |
| COMPUTE_1_HOSTNAME, |
| COMPUTE, |
| COMPUTE_1_INTG_DEVICE, |
| COMPUTE_1_IP, |
| INIT |
| ); |
| |
| private static final OpenstackNode COMPUTE_2 = createNode( |
| COMPUTE_2_HOSTNAME, |
| COMPUTE, |
| COMPUTE_2_INTG_DEVICE, |
| COMPUTE_2_IP, |
| DEVICE_CREATED |
| ); |
| |
| private static final OpenstackNode COMPUTE_3 = createNode( |
| COMPUTE_3_HOSTNAME, |
| COMPUTE, |
| COMPUTE_3_INTG_DEVICE, |
| COMPUTE_3_IP, |
| PORT_CREATED |
| ); |
| |
| private static final OpenstackNode COMPUTE_4 = createNode( |
| COMPUTE_4_HOSTNAME, |
| COMPUTE, |
| COMPUTE_4_INTG_DEVICE, |
| COMPUTE_4_IP, |
| COMPLETE |
| ); |
| |
| private static final OpenstackNode GATEWAY_1 = createNode( |
| GATEWAY_1_HOSTNAME, |
| GATEWAY, |
| GATEWAY_1_INTG_DEVICE, |
| GATEWAY_1_ROUT_DEVICE, |
| GATEWAY_1_IP, |
| INIT |
| ); |
| |
| private static final OpenstackNode GATEWAY_2 = createNode( |
| GATEWAY_2_HOSTNAME, |
| GATEWAY, |
| GATEWAY_2_INTG_DEVICE, |
| GATEWAY_2_ROUT_DEVICE, |
| GATEWAY_2_IP, |
| DEVICE_CREATED |
| ); |
| |
| private static final OpenstackNode GATEWAY_3 = createNode( |
| GATEWAY_3_HOSTNAME, |
| GATEWAY, |
| GATEWAY_3_INTG_DEVICE, |
| GATEWAY_3_ROUT_DEVICE, |
| GATEWAY_3_IP, |
| PORT_CREATED |
| ); |
| |
| private static final OpenstackNode GATEWAY_4 = createNode( |
| GATEWAY_4_HOSTNAME, |
| GATEWAY, |
| GATEWAY_4_INTG_DEVICE, |
| GATEWAY_4_ROUT_DEVICE, |
| GATEWAY_4_IP, |
| COMPLETE |
| ); |
| |
| private static final TestDeviceService TEST_DEVICE_SERVICE = new TestDeviceService(); |
| |
| private TestOpenstackNodeManager testNodeManager; |
| private DefaultOpenstackNodeHandler target; |
| |
| @Before |
| public void setUp() throws Exception { |
| DeviceAdminService mockDeviceAdminService = createMock(DeviceAdminService.class); |
| mockDeviceAdminService.removeDevice(anyObject()); |
| replay(mockDeviceAdminService); |
| |
| OvsdbClientService mockOvsdbClient = createMock(OvsdbClientService.class); |
| expect(mockOvsdbClient.isConnected()) |
| .andReturn(true) |
| .anyTimes(); |
| replay(mockOvsdbClient); |
| |
| OvsdbController mockOvsdbController = createMock(OvsdbController.class); |
| expect(mockOvsdbController.getOvsdbClient(anyObject())) |
| .andReturn(mockOvsdbClient) |
| .anyTimes(); |
| replay(mockOvsdbController); |
| |
| testNodeManager = new TestOpenstackNodeManager(); |
| target = new DefaultOpenstackNodeHandler(); |
| |
| target.coreService = new TestCoreService(); |
| target.leadershipService = new TestLeadershipService(); |
| target.clusterService = new TestClusterService(); |
| target.deviceService = TEST_DEVICE_SERVICE; |
| target.deviceAdminService = mockDeviceAdminService; |
| target.ovsdbController = mockOvsdbController; |
| target.groupService = new TestGroupService(); |
| target.osNodeService = testNodeManager; |
| target.osNodeAdminService = testNodeManager; |
| target.componentConfigService = new TestComponentConfigService(); |
| TestUtils.setField(target, "eventExecutor", MoreExecutors.newDirectExecutorService()); |
| target.activate(); |
| } |
| |
| @After |
| public void tearDown() { |
| TEST_DEVICE_SERVICE.clear(); |
| target.deactivate(); |
| target = null; |
| testNodeManager = null; |
| } |
| |
| /** |
| * Checks if the compute node state changes from INIT to DEVICE_CREATED |
| * after processing INIT state. |
| */ |
| @Test |
| public void testComputeNodeProcessNodeInitState() { |
| testNodeManager.createNode(COMPUTE_1); |
| TEST_DEVICE_SERVICE.devMap.put(COMPUTE_1_OVSDB_DEVICE.id(), COMPUTE_1_OVSDB_DEVICE); |
| |
| assertEquals(ERR_STATE_NOT_MATCH, INIT, |
| testNodeManager.node(COMPUTE_1_HOSTNAME).state()); |
| target.processInitState(COMPUTE_1); |
| assertEquals(ERR_STATE_NOT_MATCH, DEVICE_CREATED, |
| testNodeManager.node(COMPUTE_1_HOSTNAME).state()); |
| } |
| |
| /** |
| * Checks if the gateway node state changes from INIT to DEVICE_CREATED |
| * after processing INIT state. |
| */ |
| @Test |
| public void testGatewayNodeProcessNodeInitState() { |
| testNodeManager.createNode(GATEWAY_1); |
| TEST_DEVICE_SERVICE.devMap.put(GATEWAY_1_OVSDB_DEVICE.id(), GATEWAY_1_OVSDB_DEVICE); |
| |
| assertEquals(ERR_STATE_NOT_MATCH, INIT, |
| testNodeManager.node(GATEWAY_1_HOSTNAME).state()); |
| target.processInitState(GATEWAY_1); |
| assertEquals(ERR_STATE_NOT_MATCH, DEVICE_CREATED, |
| testNodeManager.node(GATEWAY_1_HOSTNAME).state()); |
| } |
| |
| /** |
| * Checks if the compute node state changes from DEVICE_CREATED to |
| * PORT_CREATED after processing DEVICE_CREATED state. |
| */ |
| @Test |
| public void testComputeNodeProcessDeviceCreatedState() { |
| testNodeManager.createNode(COMPUTE_2); |
| TEST_DEVICE_SERVICE.devMap.put(COMPUTE_2_OVSDB_DEVICE.id(), COMPUTE_2_OVSDB_DEVICE); |
| TEST_DEVICE_SERVICE.devMap.put(COMPUTE_2_INTG_DEVICE.id(), COMPUTE_2_INTG_DEVICE); |
| |
| assertEquals(ERR_STATE_NOT_MATCH, DEVICE_CREATED, |
| testNodeManager.node(COMPUTE_2_HOSTNAME).state()); |
| target.processDeviceCreatedState(COMPUTE_2); |
| assertEquals(ERR_STATE_NOT_MATCH, PORT_CREATED, |
| testNodeManager.node(COMPUTE_2_HOSTNAME).state()); |
| } |
| |
| /** |
| * Checks if the gateway node state changes from DEVICE_CREATED to |
| * PORT_CREATED after processing DEVICE_CREATED state. |
| */ |
| @Test |
| public void testGatewayNodeProcessDeviceCreatedState() { |
| testNodeManager.createNode(GATEWAY_2); |
| TEST_DEVICE_SERVICE.devMap.put(GATEWAY_2_OVSDB_DEVICE.id(), GATEWAY_2_OVSDB_DEVICE); |
| TEST_DEVICE_SERVICE.devMap.put(GATEWAY_2_INTG_DEVICE.id(), GATEWAY_2_INTG_DEVICE); |
| |
| assertEquals(ERR_STATE_NOT_MATCH, DEVICE_CREATED, |
| testNodeManager.node(GATEWAY_2_HOSTNAME).state()); |
| target.processDeviceCreatedState(GATEWAY_2); |
| assertEquals(ERR_STATE_NOT_MATCH, PORT_CREATED, |
| testNodeManager.node(GATEWAY_2_HOSTNAME).state()); |
| } |
| |
| /** |
| * Checks if the compute node state changes from PORT_CREATED to |
| * COMPLETE after processing PORT_CREATED state. |
| */ |
| @Test |
| public void testComputeNodeProcessPortCreatedState() { |
| testNodeManager.createNode(COMPUTE_3); |
| TEST_DEVICE_SERVICE.devMap.put(COMPUTE_3_OVSDB_DEVICE.id(), COMPUTE_3_OVSDB_DEVICE); |
| TEST_DEVICE_SERVICE.devMap.put(COMPUTE_3_INTG_DEVICE.id(), COMPUTE_3_INTG_DEVICE); |
| TEST_DEVICE_SERVICE.portList.add(createPort(COMPUTE_3_INTG_DEVICE, DEFAULT_TUNNEL)); |
| |
| testNodeManager.createNode(GATEWAY_4); |
| TEST_DEVICE_SERVICE.devMap.put(GATEWAY_4_INTG_DEVICE.id(), GATEWAY_4_INTG_DEVICE); |
| |
| assertEquals(ERR_STATE_NOT_MATCH, PORT_CREATED, |
| testNodeManager.node(COMPUTE_3_HOSTNAME).state()); |
| target.processPortCreatedState(COMPUTE_3); |
| assertEquals(ERR_STATE_NOT_MATCH, COMPLETE, |
| testNodeManager.node(COMPUTE_3_HOSTNAME).state()); |
| } |
| |
| /** |
| * Checks if the gateway node state changes from PORT_CREATED to |
| * COMPLETE after processing PORT_CREATED state. |
| */ |
| @Test |
| public void testGatewayNodeProcessPortCreatedState() { |
| testNodeManager.createNode(COMPUTE_4); |
| TEST_DEVICE_SERVICE.devMap.put(COMPUTE_4_OVSDB_DEVICE.id(), COMPUTE_4_OVSDB_DEVICE); |
| TEST_DEVICE_SERVICE.devMap.put(COMPUTE_4_INTG_DEVICE.id(), COMPUTE_4_INTG_DEVICE); |
| TEST_DEVICE_SERVICE.portList.add(createPort(COMPUTE_4_INTG_DEVICE, DEFAULT_TUNNEL)); |
| |
| testNodeManager.createNode(GATEWAY_3); |
| TEST_DEVICE_SERVICE.devMap.put(GATEWAY_3_INTG_DEVICE.id(), GATEWAY_4_INTG_DEVICE); |
| |
| assertEquals(ERR_STATE_NOT_MATCH, PORT_CREATED, |
| testNodeManager.node(GATEWAY_3_HOSTNAME).state()); |
| target.processPortCreatedState(GATEWAY_3); |
| assertEquals(ERR_STATE_NOT_MATCH, COMPLETE, |
| testNodeManager.node(GATEWAY_3_HOSTNAME).state()); |
| } |
| |
| /** |
| * Checks if the compute node state changes from COMPLETE to INCOMPLETE |
| * when integration bridge is disconnected. |
| */ |
| @Test |
| public void testBackToIncompleteWhenBrIntDisconnected() { |
| testNodeManager.createNode(COMPUTE_4); |
| |
| assertEquals(ERR_STATE_NOT_MATCH, COMPLETE, |
| testNodeManager.node(COMPUTE_4_HOSTNAME).state()); |
| TEST_DEVICE_SERVICE.removeDevice(COMPUTE_4_INTG_DEVICE); |
| assertEquals(ERR_STATE_NOT_MATCH, INCOMPLETE, |
| testNodeManager.node(COMPUTE_4_HOSTNAME).state()); |
| } |
| |
| /** |
| * Checks if the compute node state changes from COMPLETE to INCOMPLETE |
| * when vxlan port is removed from integration bridge. |
| */ |
| @Test |
| public void testBackToIncompleteWhenVxlanRemoved() { |
| testNodeManager.createNode(COMPUTE_4); |
| |
| assertEquals(ERR_STATE_NOT_MATCH, COMPLETE, |
| testNodeManager.node(COMPUTE_4_HOSTNAME).state()); |
| TEST_DEVICE_SERVICE.removePort(COMPUTE_4_INTG_DEVICE, createPort( |
| COMPUTE_4_INTG_DEVICE, DEFAULT_TUNNEL)); |
| assertEquals(ERR_STATE_NOT_MATCH, INCOMPLETE, |
| testNodeManager.node(COMPUTE_4_HOSTNAME).state()); |
| |
| } |
| |
| private static Device createOvsdbDevice(IpAddress ovsdbIp) { |
| return new TestDevice(new ProviderId("of", "foo"), |
| DeviceId.deviceId("ovsdb:" + ovsdbIp.toString()), |
| CONTROLLER, |
| "manufacturer", |
| "hwVersion", |
| "swVersion", |
| "serialNumber", |
| new ChassisId(1)); |
| } |
| |
| private static Device createOpenFlowDevice(long devIdNum, String type) { |
| return new TestDevice(new ProviderId("of", "foo"), |
| DeviceId.deviceId(String.format("of:%016d", devIdNum)), |
| SWITCH, |
| type, |
| "hwVersion", |
| "swVersion", |
| "serialNumber", |
| new ChassisId(1)); |
| } |
| |
| private static Port createPort(Device device, String portName) { |
| return new DefaultPort(device, |
| PortNumber.portNumber(1), |
| true, |
| DefaultAnnotations.builder().set(PORT_NAME, portName).build()); |
| } |
| |
| private static OpenstackNode createNode(String hostname, |
| OpenstackNode.NodeType type, |
| Device intgBridge, |
| IpAddress ipAddr, |
| NodeState state) { |
| return new TestOpenstackNode( |
| hostname, |
| type, |
| intgBridge.id(), |
| null, |
| ipAddr, |
| ipAddr, |
| null, state); |
| } |
| |
| private static OpenstackNode createNode(String hostname, |
| OpenstackNode.NodeType type, |
| Device intgBridge, |
| Device routerBridge, |
| IpAddress ipAddr, |
| NodeState state) { |
| return new TestOpenstackNode( |
| hostname, |
| type, |
| intgBridge.id(), |
| routerBridge.id(), |
| ipAddr, |
| ipAddr, |
| null, state); |
| } |
| |
| private static final class TestDevice extends DefaultDevice { |
| private TestDevice(ProviderId providerId, |
| DeviceId id, |
| Type type, |
| String manufacturer, |
| String hwVersion, |
| String swVersion, |
| String serialNumber, |
| ChassisId chassisId, |
| Annotations... annotations) { |
| super(providerId, |
| id, |
| type, |
| manufacturer, |
| hwVersion, |
| swVersion, |
| serialNumber, |
| chassisId, |
| annotations); |
| } |
| |
| @Override |
| @SuppressWarnings("unchecked") |
| public <B extends Behaviour> B as(Class<B> projectionClass) { |
| if (projectionClass.equals(BridgeConfig.class)) { |
| return (B) new TestBridgeConfig(); |
| } else if (projectionClass.equals(InterfaceConfig.class)) { |
| return (B) new TestInterfaceConfig(); |
| } else if (projectionClass.equals(ExtensionTreatmentResolver.class)) { |
| ExtensionTreatmentResolver treatmentResolver = createMock(ExtensionTreatmentResolver.class); |
| expect(treatmentResolver.getExtensionInstruction(anyObject())) |
| .andReturn(new TestExtensionTreatment()) |
| .anyTimes(); |
| replay(treatmentResolver); |
| return (B) treatmentResolver; |
| } else { |
| return null; |
| } |
| } |
| |
| @Override |
| public <B extends Behaviour> boolean is(Class<B> projectionClass) { |
| return true; |
| } |
| } |
| |
| private static final class TestOpenstackNode extends DefaultOpenstackNode { |
| private TestOpenstackNode(String hostname, |
| NodeType type, |
| DeviceId intgBridge, |
| DeviceId routerBridge, |
| IpAddress managementIp, |
| IpAddress dataIp, |
| String vlanIntf, |
| NodeState state) { |
| super(hostname, |
| type, |
| intgBridge, |
| routerBridge, |
| managementIp, |
| dataIp, |
| vlanIntf, |
| state); |
| } |
| |
| @Override |
| public PortNumber tunnelPortNum() { |
| return PortNumber.portNumber(1); |
| } |
| |
| @Override |
| public PortNumber vlanPortNum() { |
| return PortNumber.portNumber(1); |
| } |
| |
| @Override |
| public PortNumber patchPortNum() { |
| return PortNumber.portNumber(1); |
| } |
| |
| @Override |
| public MacAddress vlanPortMac() { |
| return MacAddress.NONE; |
| } |
| } |
| |
| private static class TestOpenstackNodeManager implements OpenstackNodeService, OpenstackNodeAdminService { |
| Map<String, OpenstackNode> osNodeMap = Maps.newHashMap(); |
| List<OpenstackNodeListener> listeners = Lists.newArrayList(); |
| |
| @Override |
| public Set<OpenstackNode> nodes() { |
| return ImmutableSet.copyOf(osNodeMap.values()); |
| } |
| |
| @Override |
| public Set<OpenstackNode> nodes(OpenstackNode.NodeType type) { |
| return osNodeMap.values().stream() |
| .filter(osNode -> osNode.type() == type) |
| .collect(Collectors.toSet()); |
| } |
| |
| @Override |
| public Set<OpenstackNode> completeNodes() { |
| return osNodeMap.values().stream() |
| .filter(osNode -> osNode.state() == COMPLETE) |
| .collect(Collectors.toSet()); |
| } |
| |
| @Override |
| public Set<OpenstackNode> completeNodes(OpenstackNode.NodeType type) { |
| return osNodeMap.values().stream() |
| .filter(osNode -> osNode.type() == type && osNode.state() == COMPLETE) |
| .collect(Collectors.toSet()); |
| } |
| |
| @Override |
| public OpenstackNode node(String hostname) { |
| return osNodeMap.get(hostname); |
| } |
| |
| @Override |
| public OpenstackNode node(DeviceId deviceId) { |
| return osNodeMap.values().stream() |
| .filter(osNode -> Objects.equals(osNode.intgBridge(), deviceId) || |
| Objects.equals(osNode.ovsdb(), deviceId) || |
| Objects.equals(osNode.routerBridge(), deviceId)) |
| .findFirst().orElse(null); |
| } |
| |
| @Override |
| public void addListener(OpenstackNodeListener listener) { |
| listeners.add(listener); |
| } |
| |
| @Override |
| public void removeListener(OpenstackNodeListener listener) { |
| listeners.remove(listener); |
| } |
| |
| @Override |
| public void createNode(OpenstackNode osNode) { |
| osNodeMap.put(osNode.hostname(), osNode); |
| } |
| |
| @Override |
| public void updateNode(OpenstackNode osNode) { |
| osNodeMap.put(osNode.hostname(), osNode); |
| } |
| |
| @Override |
| public OpenstackNode removeNode(String hostname) { |
| return null; |
| } |
| } |
| |
| private static class TestDeviceService extends DeviceServiceAdapter { |
| Map<DeviceId, Device> devMap = Maps.newHashMap(); |
| List<Port> portList = Lists.newArrayList(); |
| List<DeviceListener> listeners = Lists.newArrayList(); |
| |
| @Override |
| public void addListener(DeviceListener listener) { |
| listeners.add(listener); |
| } |
| |
| @Override |
| public void removeListener(DeviceListener listener) { |
| listeners.remove(listener); |
| } |
| |
| @Override |
| public Device getDevice(DeviceId deviceId) { |
| return devMap.get(deviceId); |
| } |
| |
| @Override |
| public List<Port> getPorts(DeviceId deviceId) { |
| return this.portList.stream() |
| .filter(p -> p.element().id().equals(deviceId)) |
| .collect(Collectors.toList()); |
| } |
| |
| @Override |
| public boolean isAvailable(DeviceId deviceId) { |
| return devMap.containsKey(deviceId); |
| } |
| |
| void addDevice(Device device) { |
| devMap.put(device.id(), device); |
| DeviceEvent event = new DeviceEvent(DEVICE_ADDED, device); |
| listeners.stream().filter(l -> l.isRelevant(event)).forEach(l -> l.event(event)); |
| } |
| |
| void removeDevice(Device device) { |
| devMap.remove(device.id()); |
| DeviceEvent event = new DeviceEvent(DEVICE_AVAILABILITY_CHANGED, device); |
| listeners.stream().filter(l -> l.isRelevant(event)).forEach(l -> l.event(event)); |
| } |
| |
| void addPort(Device device, Port port) { |
| portList.add(port); |
| DeviceEvent event = new DeviceEvent(PORT_ADDED, device, port); |
| listeners.stream().filter(l -> l.isRelevant(event)).forEach(l -> l.event(event)); |
| } |
| |
| void removePort(Device device, Port port) { |
| portList.remove(port); |
| DeviceEvent event = new DeviceEvent(PORT_REMOVED, device, port); |
| listeners.stream().filter(l -> l.isRelevant(event)).forEach(l -> l.event(event)); |
| } |
| |
| void clear() { |
| this.listeners.clear(); |
| this.devMap.clear(); |
| this.portList.clear(); |
| } |
| } |
| |
| private static class TestBridgeConfig implements BridgeConfig { |
| |
| @Override |
| public DriverData data() { |
| return null; |
| } |
| |
| @Override |
| public void setData(DriverData data) { |
| |
| } |
| |
| @Override |
| public DriverHandler handler() { |
| return null; |
| } |
| |
| @Override |
| public void setHandler(DriverHandler handler) { |
| |
| } |
| |
| @Override |
| public void addBridge(BridgeName bridgeName) { |
| |
| } |
| |
| @Override |
| public void addBridge(BridgeName bridgeName, String dpid, String exPortName) { |
| |
| } |
| |
| @Override |
| public boolean addBridge(BridgeName bridgeName, String dpid, List<ControllerInfo> controllers) { |
| return false; |
| } |
| |
| @Override |
| public boolean addBridge(BridgeDescription bridge) { |
| TEST_DEVICE_SERVICE.addDevice(new DefaultDevice(new ProviderId("of", "foo"), |
| DeviceId.deviceId("of:" + bridge.datapathId().get()), |
| SWITCH, |
| bridge.name(), |
| "hwVersion", |
| "swVersion", |
| "serialNumber", |
| new ChassisId(1))); |
| return true; |
| } |
| |
| @Override |
| public void deleteBridge(BridgeName bridgeName) { |
| |
| } |
| |
| @Override |
| public Collection<BridgeDescription> getBridges() { |
| return ImmutableSet.of(ROUT_BRIDGE); |
| } |
| |
| @Override |
| public void addPort(BridgeName bridgeName, String portName) { |
| |
| } |
| |
| @Override |
| public void deletePort(BridgeName bridgeName, String portName) { |
| |
| } |
| |
| @Override |
| public Collection<PortDescription> getPorts() { |
| return ImmutableSet.of(PATCH_ROUT); |
| } |
| |
| @Override |
| public Set<PortNumber> getPortNumbers() { |
| return null; |
| } |
| |
| @Override |
| public List<PortNumber> getLocalPorts(Iterable<String> ifaceIds) { |
| return null; |
| } |
| } |
| |
| private static class TestInterfaceConfig implements InterfaceConfig { |
| |
| @Override |
| public DriverData data() { |
| return null; |
| } |
| |
| @Override |
| public void setData(DriverData data) { |
| |
| } |
| |
| @Override |
| public DriverHandler handler() { |
| return null; |
| } |
| |
| @Override |
| public void setHandler(DriverHandler handler) { |
| |
| } |
| |
| @Override |
| public boolean addAccessInterface(DeviceId deviceId, String intf, VlanId vlanId) { |
| return false; |
| } |
| |
| @Override |
| public boolean addAccessMode(String intf, VlanId vlanId) { |
| return false; |
| } |
| |
| @Override |
| public boolean removeAccessInterface(DeviceId deviceId, String intf) { |
| return false; |
| } |
| |
| @Override |
| public boolean removeAccessMode(String intf) { |
| return false; |
| } |
| |
| @Override |
| public boolean addTrunkInterface(DeviceId deviceId, String intf, List<VlanId> vlanIds) { |
| return false; |
| } |
| |
| @Override |
| public boolean addTrunkMode(String intf, List<VlanId> vlanIds) { |
| return false; |
| } |
| |
| @Override |
| public boolean removeTrunkInterface(DeviceId deviceId, String intf) { |
| return false; |
| } |
| |
| @Override |
| public boolean removeTrunkMode(String intf) { |
| return false; |
| } |
| |
| @Override |
| public boolean addRateLimit(String intf, short limit) { |
| return false; |
| } |
| |
| @Override |
| public boolean removeRateLimit(String intf) { |
| return false; |
| } |
| |
| @Override |
| public boolean addTunnelMode(String intf, TunnelDescription tunnelDesc) { |
| TEST_DEVICE_SERVICE.devMap.values().stream() |
| .filter(device -> device.type() == SWITCH && |
| device.manufacturer().equals(INTEGRATION_BRIDGE)) |
| .forEach(device -> { |
| TEST_DEVICE_SERVICE.addPort(device, createPort(device, intf)); |
| }); |
| return true; |
| } |
| |
| @Override |
| public boolean removeTunnelMode(String intf) { |
| return false; |
| } |
| |
| @Override |
| public boolean addPatchMode(String ifaceName, PatchDescription patchInterface) { |
| if (ifaceName.equals(PATCH_INTG_BRIDGE)) { |
| TEST_DEVICE_SERVICE.devMap.values().stream() |
| .filter(device -> device.type() == SWITCH && |
| device.manufacturer().equals(INTEGRATION_BRIDGE)) |
| .forEach(device -> { |
| TEST_DEVICE_SERVICE.addPort(device, createPort(device, ifaceName)); |
| }); |
| } else if (ifaceName.equals(PATCH_ROUT_BRIDGE)) { |
| TEST_DEVICE_SERVICE.devMap.values().stream() |
| .filter(device -> device.type() == SWITCH && |
| device.manufacturer().equals(ROUTER_BRIDGE)) |
| .forEach(device -> { |
| TEST_DEVICE_SERVICE.addPort(device, createPort(device, ifaceName)); |
| }); |
| } |
| return true; |
| } |
| |
| @Override |
| public boolean removePatchMode(String ifaceName) { |
| return false; |
| } |
| |
| @Override |
| public List<DeviceInterfaceDescription> getInterfaces(DeviceId deviceId) { |
| return null; |
| } |
| |
| @Override |
| public List<DeviceInterfaceDescription> getInterfaces() { |
| return null; |
| } |
| } |
| |
| private static class TestGroupService implements GroupService { |
| Map<GroupKey, Group> groupMap = Maps.newHashMap(); |
| Map<GroupKey, GroupBuckets> groupBucketsMap = Maps.newHashMap(); |
| List<GroupListener> listeners = Lists.newArrayList(); |
| |
| @Override |
| public void addListener(GroupListener listener) { |
| listeners.add(listener); |
| } |
| |
| @Override |
| public void removeListener(GroupListener listener) { |
| listeners.remove(listener); |
| } |
| |
| @Override |
| public void addGroup(GroupDescription groupDesc) { |
| DefaultGroup group = new DefaultGroup(GroupId.valueOf(groupDesc.givenGroupId()), groupDesc); |
| group.setState(Group.GroupState.ADDED); |
| groupMap.put(groupDesc.appCookie(), group); |
| groupBucketsMap.put(groupDesc.appCookie(), groupDesc.buckets()); |
| |
| GroupEvent event = new GroupEvent(GroupEvent.Type.GROUP_ADDED, group); |
| listeners.stream().filter(listener -> listener.isRelevant(event)) |
| .forEach(listener -> listener.event(event)); |
| } |
| |
| @Override |
| public Group getGroup(DeviceId deviceId, GroupKey appCookie) { |
| return groupMap.get(appCookie); |
| } |
| |
| @Override |
| public void addBucketsToGroup(DeviceId deviceId, GroupKey oldCookie, GroupBuckets buckets, |
| GroupKey newCookie, ApplicationId appId) { |
| |
| } |
| |
| @Override |
| public void removeBucketsFromGroup(DeviceId deviceId, GroupKey oldCookie, GroupBuckets buckets, |
| GroupKey newCookie, ApplicationId appId) { |
| |
| } |
| |
| @Override |
| public void purgeGroupEntries(DeviceId deviceId) { |
| |
| } |
| |
| @Override |
| public void removeGroup(DeviceId deviceId, GroupKey appCookie, ApplicationId appId) { |
| |
| } |
| |
| @Override |
| public Iterable<Group> getGroups(DeviceId deviceId, ApplicationId appId) { |
| return null; |
| } |
| |
| @Override |
| public Iterable<Group> getGroups(DeviceId deviceId) { |
| return null; |
| } |
| |
| @Override |
| public void setBucketsForGroup(DeviceId deviceId, GroupKey oldCookie, GroupBuckets buckets, |
| GroupKey newCookie, ApplicationId appId) { |
| groupBucketsMap.put(newCookie, buckets); |
| GroupEvent event = new GroupEvent(GroupEvent.Type.GROUP_UPDATED, groupMap.get(newCookie)); |
| listeners.stream().filter(listener -> listener.isRelevant(event)) |
| .forEach(listener -> listener.event(event)); |
| } |
| |
| } |
| |
| private static class TestExtensionTreatment implements ExtensionTreatment { |
| Ip4Address tunnelDst; |
| |
| @Override |
| public ExtensionTreatmentType type() { |
| return null; |
| } |
| |
| @Override |
| public <T> void setPropertyValue(String key, T value) throws ExtensionPropertyException { |
| tunnelDst = (Ip4Address) value; |
| } |
| |
| @Override |
| public <T> T getPropertyValue(String key) throws ExtensionPropertyException { |
| return null; |
| } |
| |
| @Override |
| public List<String> getProperties() { |
| return null; |
| } |
| |
| @Override |
| public byte[] serialize() { |
| return new byte[0]; |
| } |
| |
| @Override |
| public void deserialize(byte[] data) { |
| |
| } |
| |
| @Override |
| public boolean equals(Object obj) { |
| TestExtensionTreatment that = (TestExtensionTreatment) obj; |
| return Objects.equals(tunnelDst, that.tunnelDst); |
| } |
| |
| @Override |
| public int hashCode() { |
| return Objects.hash(tunnelDst); |
| } |
| } |
| |
| private static class TestCoreService extends CoreServiceAdapter { |
| |
| @Override |
| public ApplicationId getAppId(String name) { |
| return TEST_APP_ID; |
| } |
| } |
| |
| private static class TestLeadershipService extends LeadershipServiceAdapter { |
| |
| @Override |
| public NodeId getLeader(String path) { |
| return LOCAL_NODE_ID; |
| } |
| } |
| |
| private static class TestClusterService extends ClusterServiceAdapter { |
| |
| @Override |
| public ControllerNode getLocalNode() { |
| return LOCAL_CTRL; |
| } |
| } |
| |
| private class TestComponentConfigService extends ComponentConfigAdapter { |
| |
| } |
| } |