blob: 3545d06077f567df78b7b72a0713c0c3ca9e3e59 [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.openstacknetworking.util;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import com.google.common.testing.EqualsTester;
import org.apache.commons.io.IOUtils;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.onlab.packet.Ip4Address;
import org.onlab.packet.IpAddress;
import org.onlab.packet.MacAddress;
import org.onosproject.net.DefaultAnnotations;
import org.onosproject.net.DefaultPort;
import org.onosproject.net.Device;
import org.onosproject.net.DeviceId;
import org.onosproject.net.PortNumber;
import org.onosproject.net.device.DeviceService;
import org.onosproject.net.device.DeviceServiceAdapter;
import org.onosproject.openstacknetworking.api.Constants;
import org.onosproject.openstacknetworking.api.InstancePort;
import org.onosproject.openstacknetworking.api.OpenstackNetworkService;
import org.onosproject.openstacknetworking.api.OpenstackRouterAdminService;
import org.onosproject.openstacknetworking.impl.DefaultInstancePort;
import org.onosproject.openstacknetworking.impl.OpenstackNetworkServiceAdapter;
import org.onosproject.openstacknetworking.impl.OpenstackRouterServiceAdapter;
import org.onosproject.openstacknetworking.impl.TestRouterInterface;
import org.onosproject.openstacknetworking.web.OpenstackFloatingIpWebResourceTest;
import org.onosproject.openstacknetworking.web.OpenstackNetworkWebResourceTest;
import org.onosproject.openstacknode.api.DefaultOpenstackAuth;
import org.onosproject.openstacknode.api.DefaultOpenstackNode;
import org.onosproject.openstacknode.api.NodeState;
import org.onosproject.openstacknode.api.OpenstackAuth;
import org.onosproject.openstacknode.api.OpenstackNode;
import org.onosproject.openstacknode.api.OpenstackNodeTest;
import org.openstack4j.model.network.NetFloatingIP;
import org.openstack4j.model.network.Network;
import org.openstack4j.model.network.Port;
import org.openstack4j.model.network.RouterInterface;
import org.openstack4j.openstack.networking.domain.NeutronFloatingIP;
import org.openstack4j.openstack.networking.domain.NeutronNetwork;
import org.openstack4j.openstack.networking.domain.NeutronPort;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.Map;
import java.util.Set;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.onosproject.net.AnnotationKeys.PORT_NAME;
import static org.onosproject.openstacknetworking.api.Constants.UNSUPPORTED_VENDOR;
import static org.onosproject.openstacknetworking.util.OpenstackNetworkingUtil.addRouterIface;
import static org.onosproject.openstacknetworking.util.OpenstackNetworkingUtil.associatedFloatingIp;
import static org.onosproject.openstacknetworking.util.OpenstackNetworkingUtil.checkArpMode;
import static org.onosproject.openstacknetworking.util.OpenstackNetworkingUtil.getConnectedClient;
import static org.onosproject.openstacknetworking.util.OpenstackNetworkingUtil.getGwByComputeDevId;
import static org.onosproject.openstacknetworking.util.OpenstackNetworkingUtil.getGwByInstancePort;
import static org.onosproject.openstacknetworking.util.OpenstackNetworkingUtil.getIntfNameFromPciAddress;
import static org.onosproject.openstacknetworking.util.OpenstackNetworkingUtil.isAssociatedWithVM;
import static org.onosproject.openstacknetworking.util.OpenstackNetworkingUtil.jsonToModelEntity;
import static org.onosproject.openstacknetworking.util.OpenstackNetworkingUtil.modelEntityToJson;
import static org.onosproject.openstacknetworking.util.OpenstackNetworkingUtil.prettyJson;
import static org.onosproject.openstacknetworking.util.OpenstackNetworkingUtil.routerInterfacesEquals;
import static org.onosproject.openstacknetworking.util.OpenstackNetworkingUtil.swapStaleLocation;
import static org.onosproject.openstacknetworking.util.OpenstackNetworkingUtil.vnicType;
public final class OpenstackNetworkingUtilTest {
private NetFloatingIP floatingIp1;
private NetFloatingIP floatingIp2;
private NetFloatingIP floatingIp3;
private Port openstackPort;
private Port openstackSriovPort1;
private Port openstackSriovPort2;
private Port openstackSriovPort3;
private InstancePort instancePort1;
private InstancePort instancePort2;
private InstancePort instancePort3;
private Map<String, RouterInterface> routerInterfaceMap = Maps.newHashMap();
private OpenstackNode openstackControlNodeV2;
private OpenstackNode openstackControlNodeV3;
@Before
public void setUp() {
instancePort1 = DefaultInstancePort.builder()
.networkId("net-id-1")
.portId("ce705c24-c1ef-408a-bda3-7bbd946164ab")
.deviceId(DeviceId.deviceId("of:000000000000000a"))
.portNumber(PortNumber.portNumber(1, "tap-1"))
.ipAddress(IpAddress.valueOf("10.0.0.3"))
.macAddress(MacAddress.valueOf("11:22:33:44:55:66"))
.state(InstancePort.State.valueOf("ACTIVE"))
.build();
instancePort2 = DefaultInstancePort.builder()
.networkId("net-id-2")
.portId("port-id-2")
.deviceId(DeviceId.deviceId("of:000000000000000b"))
.portNumber(PortNumber.portNumber(2, "tap-2"))
.ipAddress(IpAddress.valueOf("10.10.10.2"))
.macAddress(MacAddress.valueOf("22:33:44:55:66:11"))
.state(InstancePort.State.valueOf("ACTIVE"))
.build();
instancePort3 = DefaultInstancePort.builder()
.networkId("net-id-3")
.portId("port-id-3")
.deviceId(DeviceId.deviceId("of:000000000000000c"))
.oldDeviceId(DeviceId.deviceId("of:000000000000000d"))
.oldPortNumber(PortNumber.portNumber(4, "tap-4"))
.portNumber(PortNumber.portNumber(3, "tap-3"))
.ipAddress(IpAddress.valueOf("10.10.10.3"))
.macAddress(MacAddress.valueOf("33:44:55:66:11:22"))
.state(InstancePort.State.valueOf("ACTIVE"))
.build();
InputStream floatingIpjsonStream1 = OpenstackFloatingIpWebResourceTest.class
.getResourceAsStream("openstack-floatingip1.json");
InputStream floatingIpjsonStream2 = OpenstackFloatingIpWebResourceTest.class
.getResourceAsStream("openstack-floatingip2.json");
InputStream floatingIpjsonStream3 = OpenstackFloatingIpWebResourceTest.class
.getResourceAsStream("openstack-floatingip3.json");
floatingIp1 = (NetFloatingIP)
jsonToModelEntity(floatingIpjsonStream1, NeutronFloatingIP.class);
floatingIp2 = (NetFloatingIP)
jsonToModelEntity(floatingIpjsonStream2, NeutronFloatingIP.class);
floatingIp3 = (NetFloatingIP)
jsonToModelEntity(floatingIpjsonStream3, NeutronFloatingIP.class);
InputStream portJsonStream = OpenstackNetworkWebResourceTest.class
.getResourceAsStream("openstack-port.json");
InputStream sriovPortJsonStream1 = OpenstackNetworkWebResourceTest.class
.getResourceAsStream("openstack-port-sriov1.json");
InputStream sriovPortJsonStream2 = OpenstackNetworkWebResourceTest.class
.getResourceAsStream("openstack-port-sriov2.json");
InputStream sriovPortJsonStream3 = OpenstackNetworkWebResourceTest.class
.getResourceAsStream("openstack-port-sriov3.json");
openstackPort = (Port)
jsonToModelEntity(portJsonStream, NeutronPort.class);
openstackSriovPort1 = (Port)
jsonToModelEntity(sriovPortJsonStream1, NeutronPort.class);
openstackSriovPort2 = (Port)
jsonToModelEntity(sriovPortJsonStream2, NeutronPort.class);
openstackSriovPort3 = (Port)
jsonToModelEntity(sriovPortJsonStream3, NeutronPort.class);
}
@After
public void tearDown() {
}
/**
* Tests the floatingIp translation.
*/
@Test
public void testFloatingIp() throws IOException {
ObjectNode floatingIpNode =
modelEntityToJson(floatingIp1, NeutronFloatingIP.class);
InputStream is = IOUtils.toInputStream(floatingIpNode.toString(), StandardCharsets.UTF_8.name());
NetFloatingIP floatingIp2 = (NetFloatingIP)
jsonToModelEntity(is, NeutronFloatingIP.class);
new EqualsTester().addEqualityGroup(floatingIp1, floatingIp2).testEquals();
}
/**
* Tests the associatedFloatingIp method.
*/
@Test
public void testAsscoatedFloatingIp() throws NullPointerException {
Set<NetFloatingIP> testSet = Sets.newHashSet();
testSet.add(floatingIp1);
testSet.add(floatingIp2);
testSet.add(floatingIp3);
NetFloatingIP floatingIp1 = associatedFloatingIp(instancePort1, testSet);
NetFloatingIP floatingIp2 = associatedFloatingIp(instancePort2, testSet);
assertEquals(floatingIp1, this.floatingIp1);
assertEquals(floatingIp2, null);
}
/**
* Tests the isAssociatedWithVM method.
*/
@Test
public void testIsAssociatedWithVM() {
OpenstackNetworkService service = new TestOpenstackNetworkService();
NetFloatingIP floatingIp4 = new NeutronFloatingIP().toBuilder().portId("portId4").build();
assertFalse(isAssociatedWithVM(service, floatingIp4));
assertFalse(isAssociatedWithVM(service, floatingIp3));
assertTrue(isAssociatedWithVM(service, floatingIp1));
}
/**
* Tests the isAssociatedWithVM method in case IllegalStateException is occurred.
*/
@Test(expected = IllegalStateException.class)
public void testIsAssociatedWithVMexceptionCase() {
OpenstackNetworkService service = new TestOpenstackNetworkService();
isAssociatedWithVM(service, floatingIp2);
}
/**
* Tests the getGwByInstancePort method.
*/
@Test
public void testGetGwByInstancePort() {
Set<OpenstackNode> gws = Sets.newConcurrentHashSet();
gws.add(genGateway(1));
gws.add(genGateway(2));
gws.add(genGateway(3));
int expectedGwIndex = 2;
OpenstackNode gw = getGwByInstancePort(gws, instancePort1);
assertEquals(genGateway(expectedGwIndex), gw);
assertNull(getGwByInstancePort(gws, null));
}
/**
* Tests the getGwByComputeDevId method.
*/
@Test
public void testGetGwByComputeDevId() {
Set<OpenstackNode> gws = Sets.newConcurrentHashSet();
OpenstackNode nullGw = getGwByComputeDevId(gws, genDeviceId(1));
assertNull(nullGw);
gws.add(genGateway(1));
gws.add(genGateway(2));
gws.add(genGateway(3));
Set<OpenstackNode> cloneOfGws = ImmutableSet.copyOf(gws);
Map<String, Integer> gwCountMap = Maps.newConcurrentMap();
int numOfDev = 99;
for (int i = 1; i < 1 + numOfDev; i++) {
OpenstackNode gw = getGwByComputeDevId(gws, genDeviceId(i));
if (gwCountMap.get(gw.hostname()) == null) {
gwCountMap.put(gw.hostname(), 1);
} else {
gwCountMap.compute(gw.hostname(), (k, v) -> v + 1);
}
new EqualsTester().addEqualityGroup(
getGwByComputeDevId(gws, genDeviceId(i)),
getGwByComputeDevId(cloneOfGws, genDeviceId(i)))
.testEquals();
}
int sum = gwCountMap.values().stream().mapToInt(Integer::intValue).sum();
assertEquals(numOfDev, sum);
}
/**
* Tests getIntfNameFromPciAddress method.
*/
@Test
public void testGetIntfNameFromPciAddress() {
String expectedIntfName1 = "enp5s8";
String expectedIntfName2 = "enp5s8f3";
assertNull(getIntfNameFromPciAddress(openstackPort));
assertEquals(expectedIntfName1, getIntfNameFromPciAddress(openstackSriovPort1));
assertEquals(expectedIntfName2, getIntfNameFromPciAddress(openstackSriovPort2));
assertEquals(UNSUPPORTED_VENDOR, getIntfNameFromPciAddress(openstackSriovPort3));
}
/**
* Tests swapStaleLocation method.
*/
@Test
public void testSwapStaleLocation() {
InstancePort swappedInstancePort = swapStaleLocation(instancePort3);
assertEquals(instancePort3.oldDeviceId(), swappedInstancePort.deviceId());
assertEquals(instancePort3.oldPortNumber(), swappedInstancePort.portNumber());
}
/**
* Tests hasIntfAleadyInDevice method.
*/
@Test
public void testHasIntfAleadyInDevice() {
DeviceService deviceService = new TestDeviceService();
assertTrue(OpenstackNetworkingUtil.hasIntfAleadyInDevice(DeviceId.deviceId("deviceId"),
"port1", deviceService));
assertTrue(OpenstackNetworkingUtil.hasIntfAleadyInDevice(DeviceId.deviceId("deviceId"),
"port2", deviceService));
assertTrue(OpenstackNetworkingUtil.hasIntfAleadyInDevice(DeviceId.deviceId("deviceId"),
"port3", deviceService));
assertFalse(OpenstackNetworkingUtil.hasIntfAleadyInDevice(DeviceId.deviceId("deviceId"),
"port4", deviceService));
}
/**
* Tests addRouterIface method.
*/
@Test
public void testAddRouterIface() {
OpenstackRouterAdminService service = new TestOpenstackRouterAdminService();
addRouterIface(openstackPort, service);
RouterInterface initialRouterInterface = new TestRouterInterface(openstackPort.getDeviceId(),
openstackPort.getFixedIps().stream().findAny().get().getSubnetId(),
openstackPort.getId(),
openstackPort.getTenantId());
assertTrue(routerInterfacesEquals(initialRouterInterface, service.routerInterface(openstackPort.getId())));
addRouterIface(openstackSriovPort1, service);
RouterInterface updatedInitialRouterInterface = new TestRouterInterface(openstackSriovPort1.getDeviceId(),
openstackSriovPort1.getFixedIps().stream().findAny().get().getSubnetId(),
openstackSriovPort1.getId(),
openstackSriovPort1.getTenantId());
assertTrue(routerInterfacesEquals(
updatedInitialRouterInterface, service.routerInterface(openstackSriovPort1.getId())));
}
/**
* Util for generating dummy gateway node.
*
* @param index dummy gateway number
* @return dummy gateway node
*/
public OpenstackNode genGateway(int index) {
Device intgBrg = InternalOpenstackNodeTest.createDevice(index);
String hostname = "gateway-" + index;
IpAddress ip = Ip4Address.valueOf("10.10.10." + index);
NodeState state = NodeState.COMPLETE;
String uplinkPort = "eth0";
return InternalOpenstackNodeTest.createNode(hostname,
OpenstackNode.NodeType.GATEWAY, intgBrg, ip, uplinkPort, state);
}
/**
* Tests the testPrettyJson method.
*/
@Test
public void testPrettyJson() {
String string = prettyJson(new ObjectMapper(), "{\"json\":\"json\"}");
String prettyJsonString = "{\n \"json\" : \"json\"\n}";
assertEquals(string, prettyJsonString);
assertNull(prettyJson(new ObjectMapper(), "{\"json\":\"json\""));
assertNull(prettyJson(new ObjectMapper(), "{\"json\"\"json\"}"));
}
/**
* Tests the checkArpMode method.
*/
@Test
public void testCheckArpMode() {
assertFalse(checkArpMode(null));
assertTrue(checkArpMode("proxy"));
assertTrue(checkArpMode("broadcast"));
}
/**
* Tests the getConnectedClient method.
*/
@Test
public void testGetConnectedClient() {
OpenstackNode.Builder osNodeBuilderV2 = DefaultOpenstackNode.builder();
OpenstackAuth.Builder osNodeAuthBuilderV2 = DefaultOpenstackAuth.builder()
.version("v2.0")
.protocol(OpenstackAuth.Protocol.HTTP)
.project("admin")
.username("admin")
.password("password")
.perspective(OpenstackAuth.Perspective.PUBLIC);
openstackControlNodeV2 = osNodeBuilderV2.hostname("controllerv2")
.type(OpenstackNode.NodeType.CONTROLLER)
.managementIp(IpAddress.valueOf("1.1.1.1"))
.endpoint("1.1.1.1")
.authentication(osNodeAuthBuilderV2.build())
.state(NodeState.COMPLETE)
.build();
OpenstackNode.Builder osNodeBuilderV3 = DefaultOpenstackNode.builder();
OpenstackAuth.Builder osNodeAuthBuilderV3 = DefaultOpenstackAuth.builder()
.version("v2")
.protocol(OpenstackAuth.Protocol.HTTP)
.project("admin")
.username("admin")
.password("password")
.perspective(OpenstackAuth.Perspective.PUBLIC);
openstackControlNodeV3 = osNodeBuilderV3.hostname("controllerv3")
.type(OpenstackNode.NodeType.CONTROLLER)
.managementIp(IpAddress.valueOf("2.2.2.2"))
.endpoint("2.2.2.2")
.authentication(osNodeAuthBuilderV3.build())
.state(NodeState.COMPLETE)
.build();
getConnectedClient(openstackControlNodeV2);
getConnectedClient(openstackControlNodeV3);
}
/**
* Tests the vnicType method.
*/
@Test
public void testVnicType() {
String portNameNormalTap = "tap123456789ab";
String portNameNormalVhu = "tap123456789ab";
String portNameNormalCavium = "enp1f2s3";
String portNameUnsupported = "123456789ab";
assertEquals(vnicType(portNameNormalTap), Constants.VnicType.NORMAL);
assertEquals(vnicType(portNameNormalVhu), Constants.VnicType.NORMAL);
assertEquals(vnicType(portNameNormalCavium), Constants.VnicType.DIRECT);
assertEquals(vnicType(portNameUnsupported), Constants.VnicType.UNSUPPORTED);
}
private DeviceId genDeviceId(int index) {
return DeviceId.deviceId("of:compute-" + index);
}
protected class InternalOpenstackNodeTest extends OpenstackNodeTest {
}
/**
* Mocks the DeviceService.
*/
private class TestDeviceService extends DeviceServiceAdapter {
@Override
public List<org.onosproject.net.Port> getPorts(DeviceId deviceId) {
List<org.onosproject.net.Port> ports = Lists.newArrayList();
DefaultAnnotations.Builder annotations1 = DefaultAnnotations.builder()
.set(PORT_NAME, "port1");
DefaultAnnotations.Builder annotations2 = DefaultAnnotations.builder()
.set(PORT_NAME, "port2");
DefaultAnnotations.Builder annotations3 = DefaultAnnotations.builder()
.set(PORT_NAME, "port3");
org.onosproject.net.Port port1 = new DefaultPort(null, PortNumber.portNumber(1),
true, annotations1.build());
org.onosproject.net.Port port2 = new DefaultPort(null, PortNumber.portNumber(2),
true, annotations2.build());
org.onosproject.net.Port port3 = new DefaultPort(null, PortNumber.portNumber(3),
true, annotations3.build());
ports.add(port1);
ports.add(port2);
ports.add(port3);
return ports;
}
}
private class TestOpenstackNetworkService extends OpenstackNetworkServiceAdapter {
@Override
public Network network(String networkId) {
if (networkId.equals(openstackSriovPort1.getNetworkId())) {
return new NeutronNetwork().toBuilder().name("network").build();
} else {
return null;
}
}
@Override
public Port port(String portId) {
if (portId.equals(floatingIp1.getPortId())) {
return openstackSriovPort1;
} else if (portId.equals(floatingIp2.getPortId())) {
return openstackSriovPort2;
} else if (portId.equals("portId4")) {
return new NeutronPort().toBuilder().name("osPort4").build();
} else {
return null;
}
}
}
private class TestOpenstackRouterAdminService extends OpenstackRouterServiceAdapter {
@Override
public void addRouterInterface(RouterInterface osRouterIface) {
routerInterfaceMap.put(osRouterIface.getPortId(), osRouterIface);
}
@Override
public void updateRouterInterface(RouterInterface osRouterIface) {
routerInterfaceMap.put(osRouterIface.getPortId(), osRouterIface);
}
@Override
public RouterInterface routerInterface(String osRouterIfaceId) {
return routerInterfaceMap.get(osRouterIfaceId);
}
}
}