/** * Copyright (c) 2016 Juniper Networks, Inc. All rights reserved. */ package net.juniper.contrail.vcenter; import java.util.UUID; import java.io.IOException; import java.net.InetAddress; import java.util.List; import java.util.Map; import org.apache.log4j.Logger; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; import static org.mockito.Matchers.any; import static org.mockito.Matchers.anyShort; import static org.mockito.Matchers.anyString; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verifyNoMoreInteractions; import static org.mockito.Mockito.times; import junit.framework.TestCase; import org.junit.Test; import org.junit.Before; import org.junit.FixMethodOrder; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; import org.junit.runners.MethodSorters; import org.powermock.api.mockito.PowerMockito; import org.powermock.modules.junit4.PowerMockRunner; import org.powermock.core.classloader.annotations.PrepareForTest; import net.juniper.contrail.api.ApiConnector; import net.juniper.contrail.api.ApiConnectorMock; import net.juniper.contrail.api.ApiPropertyBase; import net.juniper.contrail.api.ObjectReference; import net.juniper.contrail.api.types.InstanceIp; import net.juniper.contrail.api.types.VirtualMachine; import net.juniper.contrail.api.types.VirtualMachineInterface; import net.juniper.contrail.api.types.VirtualNetwork; import net.juniper.contrail.api.types.Project; import net.juniper.contrail.contrail_vrouter_api.ContrailVRouterApi; @RunWith(PowerMockRunner.class) @PrepareForTest(VCenterNotify.class) @FixMethodOrder(MethodSorters.NAME_ASCENDING) public class VirtualMachineInterfaceInfoTest extends TestCase { private static final Logger s_logger = Logger.getLogger(VirtualMachineInterfaceInfoTest.class); public static VncDB vncDB; public static ApiConnector api; private static VirtualNetworkInfo vnInfo; private static VirtualMachineInfo vmInfo; private static VirtualMachineInterfaceInfo firstVmiInfo; private static InstanceIp firstInstanceIp; private static ContrailVRouterApi vrouterApi; private final static String macAddress1 = "11:11:22:33:44:11"; public static VirtualMachineInterfaceInfo VMI1 = new VirtualMachineInterfaceInfo(macAddress1); private final static String macAddress2 = "22:11:22:33:44:22"; public static VirtualMachineInterfaceInfo VMI2 = new VirtualMachineInterfaceInfo(macAddress2); private final static String macAddress3 = "33:11:FF:33:44:33"; public static VirtualMachineInterfaceInfo VMI3 = new VirtualMachineInterfaceInfo(macAddress3); public static VirtualMachineInterface verifyVirtualMachineInterfacePresent( VirtualMachineInterfaceInfo vmiInfo) throws IOException { VirtualNetwork vn = VirtualNetworkInfoTest.verifyVirtualNetworkPresent(vmiInfo.vnInfo); VirtualMachine vm = VirtualMachineInfoTest.verifyVirtualMachinePresent(vmiInfo.vmInfo); List<ObjectReference<ApiPropertyBase>> vmInterfaceRefs = vm.getVirtualMachineInterfaceBackRefs(); assertNotNull(vmInterfaceRefs); assertTrue(vmInterfaceRefs.size() >= 1); for (ObjectReference<ApiPropertyBase> vmInterfaceRef : Utils.safe(vmInterfaceRefs)) { String vmInterfaceUuid = vmInterfaceRef.getUuid(); VirtualMachineInterface vmInterface = (VirtualMachineInterface) api.findById(VirtualMachineInterface.class, vmInterfaceUuid); api.read(vmInterface); List<String> macAddresses = vmInterface.getMacAddresses().getMacAddress(); assertTrue(macAddresses.size() > 0); if (!macAddresses.get(0).equals(vmiInfo.getMacAddress())) { continue; } List<ObjectReference<ApiPropertyBase>> vnRefs = vmInterface.getVirtualNetwork(); for (ObjectReference<ApiPropertyBase> vnRef : vnRefs) { if (vnRef.getUuid().equals(vn.getUuid())) { assertNotNull(vmInterface); assertEquals(vmInterface.getUuid(), vmiInfo.getUuid()); assertEquals(vmInterface.getName(), vmiInfo.getUuid()); assertEquals(vmInterface.getIdPerms(), vncDB.getVCenterIdPerms()); assertEquals(vmInterface.getParent(), vncDB.getVCenterProject()); String vmInterfaceName = "vmi-" + vn.getName() + "-" + vmiInfo.vmInfo.getName(); assertEquals(vmInterface.getDisplayName(), vmInterfaceName); List<ObjectReference<ApiPropertyBase>> vmRefs = vmInterface.getVirtualMachine(); assertNotNull(vmRefs); assertEquals(1, vmRefs.size()); assertEquals(vm.getUuid(), vmRefs.get(0).getUuid()); List<ObjectReference<ApiPropertyBase>> vmiVnRefs = vmInterface.getVirtualNetwork(); assertNotNull(vmiVnRefs); assertEquals(1, vmiVnRefs.size()); assertEquals(vn.getUuid(), vmiVnRefs.get(0).getUuid()); return vmInterface; } } } return null; } public static void verifyVirtualMachineInterfaceAbsent(VirtualMachineInterfaceInfo vmiInfo) throws IOException { // Verify virtual-machine-interface is deleted from api-server VirtualMachineInterface vmi1 =(VirtualMachineInterface) api.findById(VirtualMachineInterface.class, vmiInfo.getUuid()); assertNull(vmi1); } public static InstanceIp verifyInstanceIpPresent(VirtualMachineInterfaceInfo vmiInfo) throws IOException { VirtualNetwork vn = VirtualNetworkInfoTest.verifyVirtualNetworkPresent(vmiInfo.vnInfo); VirtualMachineInterface vmInterface = verifyVirtualMachineInterfacePresent(vmiInfo); // find instance-ip corresponding to virtual-machine-interface List<ObjectReference<ApiPropertyBase>> instanceIpRefs = vmInterface.getInstanceIpBackRefs(); assertNotNull(instanceIpRefs); assertEquals(1, instanceIpRefs.size()); ObjectReference<ApiPropertyBase> instanceIpRef = instanceIpRefs.get(0); assertNotNull(instanceIpRef); InstanceIp instanceIp = (InstanceIp) api.findById(InstanceIp.class, instanceIpRef.getUuid()); assertNotNull(instanceIp); String instanceIpName = "ip-" + vn.getName() + "-" + vmiInfo.vmInfo.getName(); assertEquals(instanceIp.getDisplayName(), instanceIpName); assertEquals(instanceIp.getUuid(), instanceIpRef.getUuid()); assertEquals(instanceIp.getName(), instanceIpRef.getUuid()); assertEquals(instanceIp.getIdPerms(), vncDB.getVCenterIdPerms()); List<ObjectReference<ApiPropertyBase>> instIpVnRefs = instanceIp.getVirtualNetwork(); assertNotNull(instIpVnRefs); assertEquals(instIpVnRefs.size(), 1); assertEquals(instIpVnRefs.get(0).getUuid(), vn.getUuid()); List<ObjectReference<ApiPropertyBase>> vmiRefs = instanceIp.getVirtualMachineInterface(); assertNotNull(vmiRefs); assertEquals(1, vmiRefs.size()); assertEquals(vmInterface.getUuid(), vmiRefs.get(0).getUuid()); s_logger.info("Found instanceIP " + instanceIp.getAddress()); return instanceIp; } public static void verifyInstanceIpAbsent(InstanceIp instanceIp) throws IOException { InstanceIp ip1 = (InstanceIp) api.findById(InstanceIp.class, instanceIp.getUuid()); assertNull(ip1); } @Before public void globalSetUp() throws IOException { api = new ApiConnectorMock(null, 0); assertNotNull(api); // Create default-domain,default-project Project vProject = new Project(); vProject.setName("default-project"); try { if (!api.create(vProject)) { s_logger.error("Unable to create project: " + vProject.getName()); fail("default-project creation failed"); return; } } catch (IOException e) { s_logger.error("Exception : " + e); e.printStackTrace(); fail("default-project creation failed"); return; } // Setup vnc object vncDB = new VncDB(null,0, Mode.VCENTER_ONLY); vncDB.setApiConnector(api); assertNotNull(vncDB.getApiConnector()); assertTrue(vncDB.isVncApiServerAlive()); assertTrue(vncDB.Initialize()); VirtualNetworkInfoTest.api = api; VirtualNetworkInfoTest.vncDB = vncDB; VirtualMachineInfoTest.api = api; VirtualMachineInfoTest.vncDB = vncDB; MainDB.vncDB = vncDB; // Setup mock ContrailVRouterApi connection for vrouterIp = 10.84.24.45 vrouterApi = mock(ContrailVRouterApi.class); when(vrouterApi.addPort(anyString(), anyString(), anyString(), anyString(), anyString(), anyString(), anyShort(), anyShort(), anyString(), anyString())).thenReturn(true); when(vrouterApi.deletePort(anyString())).thenReturn(true); Map<String, ContrailVRouterApi> vrouterApiMap = VRouterNotifier.getVrouterApiMap(); vrouterApiMap.put("10.84.24.45", vrouterApi); PowerMockito.mockStatic(VCenterNotify.class); vnInfo = VirtualNetworkInfoTest.BLUE; try { s_logger.info("Create " + vnInfo); vnInfo.create(vncDB); } catch (Exception e) { fail("Cannot create VN " + VirtualNetworkInfoTest.BLUE); } VirtualNetworkInfoTest.verifyVirtualNetworkPresent(VirtualNetworkInfoTest.BLUE); // Create Virtual Machine and first VMI vmInfo = VirtualMachineInfoTest.VM1; firstVmiInfo = new VirtualMachineInterfaceInfo(VMI1); firstVmiInfo.setVnInfo(vnInfo); firstVmiInfo.setVmInfo(vmInfo); // add this interface to the VM vmInfo.created(firstVmiInfo); // verify VMI has been added in the VMI map of this VM assertTrue(vmInfo.contains(firstVmiInfo)); // create VM and VMI try { s_logger.info("Create " + vmInfo); vmInfo.create(vncDB); } catch (Exception e) { fail("Cannot create VM " + vmInfo); } VirtualMachineInfoTest.verifyVirtualMachinePresent(vmInfo); verifyVirtualMachineInterfacePresent(firstVmiInfo); firstInstanceIp = verifyInstanceIpPresent(firstVmiInfo); verify(vrouterApi).addPort(anyString(), anyString(), anyString(), anyString(), anyString(), anyString(), anyShort(), anyShort(), anyString(), anyString()); } @Test public void testVirtualMachineInterfaceCreateDelete() throws IOException { // Create Virtual Machine and second VMI VirtualMachineInterfaceInfo secondVmiInfo = new VirtualMachineInterfaceInfo(VMI2);; secondVmiInfo.setVnInfo(vnInfo); secondVmiInfo.setVmInfo(vmInfo); // add this interface to the VM vmInfo.created(secondVmiInfo); // verify VMI has been added in the VMI map of this VM assertTrue(vmInfo.contains(secondVmiInfo)); // create VM and VMI try { s_logger.info("Create second VMI " + secondVmiInfo); secondVmiInfo.create(vncDB); } catch (Exception e) { fail("Cannot create VMI " + secondVmiInfo); } assertTrue(vnInfo.contains(secondVmiInfo)); assertTrue(vmInfo.contains(secondVmiInfo)); verifyVirtualMachineInterfacePresent(secondVmiInfo); InstanceIp secondInstanceIp = verifyInstanceIpPresent(secondVmiInfo); verify(vrouterApi, times(2)).addPort(anyString(), anyString(), anyString(), anyString(), anyString(), anyString(), anyShort(), anyShort(),anyString(), anyString()); // update should have no effect try { s_logger.info("Update second VMI " + secondVmiInfo); secondVmiInfo.update(secondVmiInfo, vncDB); } catch (Exception e) { fail("Cannot update VMI " + secondVmiInfo); } verifyNoMoreInteractions(vrouterApi); try { s_logger.info("Delete second VMI " + secondVmiInfo); secondVmiInfo.delete(vncDB); } catch (Exception e) { fail("Cannot delete VMI " + secondVmiInfo); } verifyInstanceIpAbsent(secondInstanceIp); verifyVirtualMachineInterfaceAbsent(secondVmiInfo); verify(vrouterApi).deletePort(anyString()); try { s_logger.info("Delete first VMI " + firstVmiInfo); firstVmiInfo.delete(vncDB); } catch (Exception e) { fail("Cannot delete VMI " + secondVmiInfo); } verifyInstanceIpAbsent(firstInstanceIp); verifyVirtualMachineInterfaceAbsent(firstVmiInfo); verify(vrouterApi, times(2)).deletePort(anyString()); try { s_logger.info("Delete " + vmInfo); vmInfo.delete(vncDB); } catch (Exception e) { fail("Cannot delete VM " + vmInfo); } VirtualMachineInfoTest.verifyVirtualMachineAbsent(vmInfo); } @Test public void testVirtualMachineInterfaceStaticIpAddressing() throws IOException { VirtualNetworkInfo staticVnInfo = VirtualNetworkInfoTest.STATIC_IP; assertEquals(staticVnInfo.getExternalIpam(), true); try { s_logger.info("Create " + staticVnInfo); staticVnInfo.create(vncDB); } catch (Exception e) { fail("Cannot create VN " + VirtualNetworkInfoTest.STATIC_IP + " " + e.getMessage()); e.printStackTrace(); } VirtualNetworkInfoTest.verifyVirtualNetworkPresent(staticVnInfo); VirtualMachineInterfaceInfo vmiInfo = new VirtualMachineInterfaceInfo(VMI3);; vmiInfo.setVnInfo(staticVnInfo); vmiInfo.setVmInfo(vmInfo); // add this interface to the VM vmInfo.created(vmiInfo); // verify VMI has been added in the VMI map of this VM assertTrue(vmInfo.contains(vmiInfo)); // create VM and VMI try { s_logger.info("Create " + vmiInfo); vmiInfo.create(vncDB); } catch (Exception e) { fail("Cannot create VMI " + vmiInfo); } VirtualMachineInfoTest.verifyVirtualMachinePresent(vmInfo); verifyVirtualMachineInterfacePresent(vmiInfo); assertNull(vmiInfo.getIpAddress()); assertNull(vmiInfo.apiInstanceIp); verify(vrouterApi, times(2)).addPort(anyString(), anyString(), anyString(), anyString(), anyString(), anyString(), anyShort(), anyShort(), anyString(), anyString()); } @Test public void testNetworkChange() throws IOException { s_logger.info("testNetworkChange"); VirtualNetworkInfo redVnInfo = VirtualNetworkInfoTest.RED; try { s_logger.info("Create " + redVnInfo); redVnInfo.create(vncDB); } catch (Exception e) { fail("Cannot create VN " + redVnInfo); } VirtualNetworkInfoTest.verifyVirtualNetworkPresent(redVnInfo); s_logger.info("Change VM1 nw adapter from network BLUE (dhcp) to network RED (dhcp)"); VirtualMachineInterfaceInfo newVmiInfo = new VirtualMachineInterfaceInfo(firstVmiInfo); newVmiInfo.setVnInfo(redVnInfo); try { firstVmiInfo.update(newVmiInfo, vncDB); } catch (Exception e) { fail("Cannot update VMIs " + firstVmiInfo); } assertTrue(vmInfo.contains(firstVmiInfo)); assertTrue(redVnInfo.contains(firstVmiInfo)); verifyVirtualMachineInterfacePresent(firstVmiInfo); InstanceIp redIp = verifyInstanceIpPresent(firstVmiInfo); s_logger.info("New IP Address is " + redIp.getAddress()); verify(vrouterApi, times(2)).addPort(anyString(), anyString(), anyString(), anyString(), anyString(), anyString(), anyShort(), anyShort(), anyString(), anyString()); verify(vrouterApi).deletePort(anyString()); verifyInstanceIpAbsent(firstInstanceIp); VirtualNetworkInfo staticVnInfo = VirtualNetworkInfoTest.STATIC_IP; try { s_logger.info("Create " + staticVnInfo); staticVnInfo.create(vncDB); } catch (Exception e) { fail("Cannot create VN " + staticVnInfo); } VirtualNetworkInfoTest.verifyVirtualNetworkPresent(staticVnInfo); s_logger.info("Change VM1 nw adapter from network RED (dhcp) to network STATIC_IP (dhcp)"); newVmiInfo = new VirtualMachineInterfaceInfo(firstVmiInfo); newVmiInfo.setVnInfo(staticVnInfo); newVmiInfo.setIpAddress("192.168.3.2"); try { firstVmiInfo.update(newVmiInfo, vncDB); } catch (Exception e) { fail("Cannot update VMIs " + firstVmiInfo); } assertTrue(vmInfo.contains(firstVmiInfo)); assertTrue(staticVnInfo.contains(firstVmiInfo)); verifyVirtualMachineInterfacePresent(firstVmiInfo); InstanceIp staticIp = verifyInstanceIpPresent(firstVmiInfo); assertEquals("192.168.3.2", staticIp.getAddress()); verify(vrouterApi, times(3)).addPort(anyString(), anyString(), anyString(), anyString(), anyString(), anyString(), anyShort(), anyShort(), anyString(), anyString()); verify(vrouterApi, times(2)).deletePort(anyString()); verifyInstanceIpAbsent(redIp); VirtualNetworkInfo staticVnInfo2 = VirtualNetworkInfoTest.STATIC_IP2; try { s_logger.info("Create " + staticVnInfo2); staticVnInfo2.create(vncDB); } catch (Exception e) { fail("Cannot create VN " + staticVnInfo2); } VirtualNetworkInfoTest.verifyVirtualNetworkPresent(staticVnInfo2); s_logger.info("Change VM1 nw adapter from network STATIC_IP (static) to network STATIC_IP2 (static)"); newVmiInfo = new VirtualMachineInterfaceInfo(firstVmiInfo); newVmiInfo.setVnInfo(staticVnInfo2); newVmiInfo.setIpAddress("192.168.4.2"); try { firstVmiInfo.update(newVmiInfo, vncDB); } catch (Exception e) { fail("Cannot update VMIs " + firstVmiInfo); } assertTrue(vmInfo.contains(firstVmiInfo)); assertTrue(staticVnInfo2.contains(firstVmiInfo)); verifyVirtualMachineInterfacePresent(firstVmiInfo); InstanceIp staticIp2 = verifyInstanceIpPresent(firstVmiInfo); assertEquals("192.168.4.2", staticIp2.getAddress()); verify(vrouterApi, times(4)).addPort(anyString(), anyString(), anyString(), anyString(), anyString(), anyString(), anyShort(), anyShort(), anyString(), anyString()); verify(vrouterApi, times(3)).deletePort(anyString()); verifyInstanceIpAbsent(staticIp); s_logger.info("Change VM1 nw adapter from network STATIC_IP2 (static) to network BLUE (dhcp)"); newVmiInfo = new VirtualMachineInterfaceInfo(firstVmiInfo); newVmiInfo.setVnInfo(VirtualNetworkInfoTest.BLUE); newVmiInfo.setIpAddress(null); try { firstVmiInfo.update(newVmiInfo, vncDB); } catch (Exception e) { fail("Cannot update VMIs " + firstVmiInfo); } assertTrue(vmInfo.contains(firstVmiInfo)); assertTrue(VirtualNetworkInfoTest.BLUE.contains(firstVmiInfo)); verifyVirtualMachineInterfacePresent(firstVmiInfo); InstanceIp blueIp = verifyInstanceIpPresent(firstVmiInfo); assertNotSame(null, blueIp.getAddress()); verify(vrouterApi, times(5)).addPort(anyString(), anyString(), anyString(), anyString(), anyString(), anyString(), anyShort(), anyShort(), anyString(), anyString()); verify(vrouterApi, times(4)).deletePort(anyString()); verifyInstanceIpAbsent(staticIp2); } }