| // Licensed to the Apache Software Foundation (ASF) under one |
| // or more contributor license agreements. See the NOTICE file |
| // distributed with this work for additional information |
| // regarding copyright ownership. The ASF licenses this file |
| // to you 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.cloud.network.router.deployment; |
| |
| import static junit.framework.Assert.assertEquals; |
| import static junit.framework.Assert.assertFalse; |
| import static junit.framework.Assert.assertNotNull; |
| import static junit.framework.Assert.assertNull; |
| import static junit.framework.Assert.assertTrue; |
| import static junit.framework.Assert.fail; |
| import static org.mockito.Matchers.anyLong; |
| import static org.mockito.Mockito.doNothing; |
| import static org.mockito.Mockito.doReturn; |
| import static org.mockito.Mockito.mock; |
| import static org.mockito.Mockito.spy; |
| import static org.mockito.Mockito.times; |
| import static org.mockito.Mockito.verify; |
| import static org.mockito.Mockito.when; |
| |
| import java.util.ArrayList; |
| import java.util.List; |
| |
| import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService; |
| import org.junit.Before; |
| import org.junit.Test; |
| import org.junit.runner.RunWith; |
| import org.mockito.Matchers; |
| import org.mockito.Mock; |
| import org.mockito.runners.MockitoJUnitRunner; |
| |
| import com.cloud.dc.DataCenter.NetworkType; |
| import com.cloud.dc.HostPodVO; |
| import com.cloud.deploy.DeployDestination; |
| import com.cloud.deploy.DeploymentPlan; |
| import com.cloud.exception.ConcurrentOperationException; |
| import com.cloud.exception.InsufficientAddressCapacityException; |
| import com.cloud.exception.InsufficientCapacityException; |
| import com.cloud.exception.ResourceUnavailableException; |
| import com.cloud.network.Network; |
| import com.cloud.network.Network.Provider; |
| import com.cloud.network.Network.Service; |
| import com.cloud.network.Networks.TrafficType; |
| import com.cloud.network.VirtualRouterProvider.Type; |
| import com.cloud.network.addr.PublicIp; |
| import com.cloud.network.dao.NetworkVO; |
| import com.cloud.network.dao.PhysicalNetworkServiceProviderVO; |
| import com.cloud.network.element.VirtualRouterProviderVO; |
| import com.cloud.network.router.VirtualRouter.Role; |
| import com.cloud.user.Account; |
| import com.cloud.utils.db.SearchBuilder; |
| import com.cloud.utils.db.SearchCriteria; |
| import com.cloud.utils.exception.CloudRuntimeException; |
| import com.cloud.vm.DomainRouterVO; |
| import com.cloud.vm.VMInstanceVO; |
| import com.cloud.vm.VirtualMachine; |
| |
| @RunWith(MockitoJUnitRunner.class) |
| public class RouterDeploymentDefinitionTest extends RouterDeploymentDefinitionTestBase { |
| |
| @Mock |
| protected NetworkVO mockNw; |
| |
| protected RouterDeploymentDefinition deployment; |
| |
| |
| @Override |
| protected void initMocks() { |
| when(mockDestination.getDataCenter()).thenReturn(mockDataCenter); |
| when(mockDataCenter.getId()).thenReturn(DATA_CENTER_ID); |
| when(mockPod.getId()).thenReturn(POD_ID1); |
| when(mockHostPodVO1.getId()).thenReturn(POD_ID1); |
| when(mockHostPodVO2.getId()).thenReturn(POD_ID2); |
| when(mockHostPodVO3.getId()).thenReturn(POD_ID3); |
| when(mockNw.getId()).thenReturn(NW_ID_1); |
| } |
| |
| @Before |
| public void initTest() { |
| initMocks(); |
| |
| deployment = builder.create() |
| .setGuestNetwork(mockNw) |
| .setDeployDestination(mockDestination) |
| .setAccountOwner(mockOwner) |
| .setParams(params) |
| .build(); |
| } |
| |
| @Test |
| public void testRedundancyProperty() { |
| // Set and confirm is redundant |
| when(mockNw.isRedundant()).thenReturn(true); |
| final RouterDeploymentDefinition deployment = builder.create() |
| .setGuestNetwork(mockNw) |
| .setDeployDestination(mockDestination) |
| .build(); |
| assertTrue("The builder ignored redundancy from its inner network", deployment.isRedundant()); |
| when(mockNw.isRedundant()).thenReturn(false); |
| assertFalse("The builder ignored redundancy from its inner network", deployment.isRedundant()); |
| } |
| |
| @Test |
| public void testConstructionFieldsAndFlags() { |
| // Vpc type |
| assertFalse(deployment.isVpcRouter()); |
| // Offering null |
| deployment.serviceOfferingId = null; |
| assertNull(deployment.getServiceOfferingId()); |
| deployment.serviceOfferingId = OFFERING_ID; |
| assertEquals(OFFERING_ID, deployment.getServiceOfferingId().longValue()); |
| assertNotNull(deployment.getRouters()); |
| assertNotNull(deployment.getGuestNetwork()); |
| assertNotNull(deployment.getDest()); |
| assertNotNull(deployment.getOwner()); |
| deployment.plan = mock(DeploymentPlan.class); |
| assertNotNull(deployment.getPlan()); |
| assertFalse(deployment.isPublicNetwork()); |
| deployment.isPublicNetwork = true; |
| assertTrue(deployment.isPublicNetwork()); |
| // This could never be a Vpc deployment |
| assertNull(deployment.getVpc()); |
| assertEquals(params, deployment.getParams()); |
| } |
| |
| @Test |
| public void testLock() { |
| // Prepare |
| when(mockNwDao.acquireInLockTable(NW_ID_1, NetworkOrchestrationService.NetworkLockTimeout.value())) |
| .thenReturn(mockNw); |
| |
| // Execute |
| deployment.lock(); |
| |
| // Assert |
| verify(mockNwDao, times(1)).acquireInLockTable(NW_ID_1, 600); |
| assertNotNull(LOCK_NOT_CORRECTLY_GOT, deployment.tableLockId); |
| assertEquals(LOCK_NOT_CORRECTLY_GOT, NW_ID_1, NW_ID_1, deployment.tableLockId.longValue()); |
| } |
| |
| @Test(expected = ConcurrentOperationException.class) |
| public void testLockFails() { |
| // Prepare |
| when(mockNwDao.acquireInLockTable(NW_ID_1, NetworkOrchestrationService.NetworkLockTimeout.value())) |
| .thenReturn(null); |
| |
| // Execute |
| try { |
| deployment.lock(); |
| } finally { |
| // Assert |
| verify(mockNwDao, times(1)).acquireInLockTable(NW_ID_1, 600); |
| assertNull(deployment.tableLockId); |
| } |
| |
| } |
| |
| @Test |
| public void testUnlock() { |
| // Prepare |
| deployment.tableLockId = NW_ID_1; |
| |
| // Execute |
| deployment.unlock(); |
| |
| // Assert |
| verify(mockNwDao, times(1)).releaseFromLockTable(NW_ID_1); |
| } |
| |
| @Test |
| public void testUnlockWithoutLock() { |
| // Prepare |
| deployment.tableLockId = null; |
| |
| // Execute |
| deployment.unlock(); |
| |
| // Assert |
| verify(mockNwDao, times(0)).releaseFromLockTable(anyLong()); |
| } |
| |
| /** |
| * If it's not a basic network, pod is not needed in the generated DataCenterDeployment |
| */ |
| @Test |
| public void testGenerateDeploymentPlanNoPodNeeded() { |
| // Prepare |
| when(mockDataCenter.getNetworkType()).thenReturn(NetworkType.Advanced); |
| |
| // Execute |
| deployment.generateDeploymentPlan(); |
| |
| // Assert |
| assertEquals("", DATA_CENTER_ID, (Long) deployment.plan.getDataCenterId()); |
| assertEquals("", mockDestination, deployment.dest); |
| assertEquals("", null, deployment.getPod()); |
| assertEquals("", null, deployment.getPodId()); |
| } |
| |
| /** |
| * If it's Basic, it should have pod |
| */ |
| @Test |
| public void testGenerateDeploymentPlanBasic() { |
| // Prepare |
| when(mockDestination.getPod()).thenReturn(mockPod); |
| when(mockDataCenter.getNetworkType()).thenReturn(NetworkType.Basic); |
| |
| // Execute |
| deployment.generateDeploymentPlan(); |
| |
| // Assert |
| assertEquals("", DATA_CENTER_ID, (Long) deployment.plan.getDataCenterId()); |
| assertEquals("", mockDestination, deployment.dest); |
| assertEquals("", mockPod, deployment.getPod()); |
| assertEquals("", POD_ID1, deployment.getPodId()); |
| } |
| |
| /** |
| * If it's Basic, it should have pod, otherwise fail with |
| * {@link CloudRuntimeException} |
| */ |
| @Test(expected = CloudRuntimeException.class) |
| public void testGenerateDeploymentPlanBasicFailNoPod() { |
| // Prepare |
| when(mockDestination.getPod()).thenReturn(null); |
| when(mockDataCenter.getNetworkType()).thenReturn(NetworkType.Basic); |
| |
| // Execute |
| deployment.generateDeploymentPlan(); |
| |
| // Assert |
| assertEquals("", DATA_CENTER_ID, (Long) deployment.plan.getDataCenterId()); |
| assertEquals("", mockDestination, deployment.dest); |
| } |
| |
| @Test |
| public void testCheckPreconditions() throws ResourceUnavailableException { |
| // Prepare |
| final Network.State states[] = { |
| Network.State.Implemented, |
| Network.State.Setup, |
| Network.State.Implementing |
| }; |
| when(deployment.guestNetwork.getTrafficType()).thenReturn(TrafficType.Guest); |
| |
| // Drive specific tests |
| for (final Network.State state : states) { |
| driveTestCheckPreconditionsCorrectNwState(state); |
| } |
| } |
| |
| public void driveTestCheckPreconditionsCorrectNwState(final Network.State state) throws ResourceUnavailableException { |
| // Prepare |
| when(deployment.guestNetwork.getState()).thenReturn(state); |
| |
| // Execute |
| deployment.checkPreconditions(); |
| |
| // Assert : It just should raise no exceptions |
| } |
| |
| @Test(expected = ResourceUnavailableException.class) |
| public void testCheckPreconditionsWrongTrafficType() throws ResourceUnavailableException { |
| // Prepare wrong traffic type to trigger error |
| when(deployment.guestNetwork.getTrafficType()).thenReturn(TrafficType.Public); |
| |
| // Execute |
| driveTestCheckPreconditionsCorrectNwState(Network.State.Implemented); |
| } |
| |
| @Test(expected = ResourceUnavailableException.class) |
| public void testCheckPreconditionsWrongState() throws ResourceUnavailableException { |
| // Prepare wrong traffic type to trigger error |
| when(deployment.guestNetwork.getTrafficType()).thenReturn(TrafficType.Guest); |
| |
| // Execute |
| driveTestCheckPreconditionsCorrectNwState(Network.State.Shutdown); |
| } |
| |
| @Test |
| public void testFindDestinationsNonBasicZone() { |
| // Prepare |
| when(mockDataCenter.getNetworkType()).thenReturn(NetworkType.Advanced); |
| |
| // Execute |
| final List<DeployDestination> destinations = deployment.findDestinations(); |
| |
| // Assert |
| assertEquals(ONLY_THE_PROVIDED_AS_DEFAULT_DESTINATION_WAS_EXPECTED, |
| 1, destinations.size()); |
| assertEquals(ONLY_THE_PROVIDED_AS_DEFAULT_DESTINATION_WAS_EXPECTED, |
| mockDestination, destinations.get(0)); |
| } |
| |
| @Test |
| public void testFindDestinationsPredefinedPod() { |
| // Prepare |
| when(mockDataCenter.getNetworkType()).thenReturn(NetworkType.Basic); |
| when(mockDestination.getPod()).thenReturn(mockPod); |
| |
| // Execute |
| final List<DeployDestination> destinations = deployment.findDestinations(); |
| |
| // Assert |
| assertEquals(ONLY_THE_PROVIDED_AS_DEFAULT_DESTINATION_WAS_EXPECTED, |
| 1, destinations.size()); |
| assertEquals(ONLY_THE_PROVIDED_AS_DEFAULT_DESTINATION_WAS_EXPECTED, |
| mockDestination, destinations.get(0)); |
| } |
| |
| @Test |
| public void testFindDestinations() { |
| // Prepare |
| when(mockDataCenter.getNetworkType()).thenReturn(NetworkType.Basic); |
| when(mockDestination.getPod()).thenReturn(null); |
| |
| // Stub local method listByDataCenterIdVMTypeAndStates |
| mockPods.add(mockHostPodVO1); |
| mockPods.add(mockHostPodVO2); |
| mockPods.add(mockHostPodVO3); |
| final RouterDeploymentDefinition deployment = spy(this.deployment); |
| doReturn(mockPods).when(deployment).listByDataCenterIdVMTypeAndStates( |
| DATA_CENTER_ID, VirtualMachine.Type.User, |
| VirtualMachine.State.Starting, VirtualMachine.State.Running); |
| |
| // Leave this one empty to force adding add destination for this pod |
| final List<DomainRouterVO> virtualRouters1 = new ArrayList<>(); |
| when(mockRouterDao.listByPodIdAndStates(POD_ID1, |
| VirtualMachine.State.Starting, VirtualMachine.State.Running)).thenReturn(virtualRouters1); |
| |
| // This list is not empty, so it will not add any for this pod, and continue with next pod |
| final List<DomainRouterVO> virtualRouters2 = new ArrayList<>(); |
| final DomainRouterVO domainRouterVO1 = mock(DomainRouterVO.class); |
| virtualRouters2.add(domainRouterVO1); |
| when(mockRouterDao.listByPodIdAndStates(POD_ID2, |
| VirtualMachine.State.Starting, VirtualMachine.State.Running)).thenReturn(virtualRouters2); |
| |
| // Leave this last one empty to check we finally added more than one afterwards |
| final List<DomainRouterVO> virtualRouters3 = new ArrayList<>(); |
| when(mockRouterDao.listByPodIdAndStates(POD_ID3, |
| VirtualMachine.State.Starting, VirtualMachine.State.Running)).thenReturn(virtualRouters3); |
| |
| // Execute |
| final List<DeployDestination> destinations = deployment.findDestinations(); |
| |
| // Assert that 2 were added (for the 1st and 3rd |
| assertEquals("", |
| 2, destinations.size()); |
| assertEquals("", |
| mockDataCenter, destinations.get(0).getDataCenter()); |
| assertEquals("", |
| mockHostPodVO1, destinations.get(0).getPod()); |
| assertEquals("", |
| mockDataCenter, destinations.get(1).getDataCenter()); |
| assertEquals("", |
| mockHostPodVO3, destinations.get(1).getPod()); |
| } |
| |
| @Test(expected = CloudRuntimeException.class) |
| public void testFindDestinationsMoreThan1PodPerBasicZone() { |
| // Prepare |
| when(mockDataCenter.getNetworkType()).thenReturn(NetworkType.Basic); |
| when(mockDestination.getPod()).thenReturn(null); |
| |
| // Stub local method listByDataCenterIdVMTypeAndStates |
| mockPods.add(mockHostPodVO1); |
| mockPods.add(mockHostPodVO2); |
| // Deployment under test is a Mockito spy |
| final RouterDeploymentDefinition deploymentUT = spy(deployment); |
| doReturn(mockPods).when(deploymentUT).listByDataCenterIdVMTypeAndStates( |
| DATA_CENTER_ID, VirtualMachine.Type.User, |
| VirtualMachine.State.Starting, VirtualMachine.State.Running); |
| |
| // Leave this one empty to force adding add destination for this pod |
| final List<DomainRouterVO> virtualRouters1 = new ArrayList<>(); |
| when(mockRouterDao.listByPodIdAndStates(POD_ID1, |
| VirtualMachine.State.Starting, VirtualMachine.State.Running)).thenReturn(virtualRouters1); |
| |
| // This list is not empty, so it will not add any for this pod, and continue with next pod |
| final List<DomainRouterVO> virtualRouters2 = new ArrayList<>(); |
| final DomainRouterVO domainRouterVO1 = mock(DomainRouterVO.class); |
| final DomainRouterVO domainRouterVO2 = mock(DomainRouterVO.class); |
| virtualRouters2.add(domainRouterVO1); |
| virtualRouters2.add(domainRouterVO2); |
| when(mockRouterDao.listByPodIdAndStates(POD_ID2, |
| VirtualMachine.State.Starting, VirtualMachine.State.Running)).thenReturn(virtualRouters2); |
| |
| // Execute |
| deploymentUT.findDestinations(); |
| |
| // Assert by expected exception |
| } |
| |
| @Test |
| public void testPlanDeploymentRoutersBasic() { |
| // Prepare |
| when(mockDataCenter.getNetworkType()).thenReturn(NetworkType.Basic); |
| when(mockDestination.getPod()).thenReturn(mockPod); |
| |
| // Execute |
| deployment.planDeploymentRouters(); |
| |
| // Assert |
| verify(mockRouterDao, times(1)).listByNetworkAndPodAndRole(mockNw.getId(), |
| POD_ID1, Role.VIRTUAL_ROUTER); |
| } |
| |
| @Test |
| public void testPlanDeploymentRoutersNonBasic() { |
| // Prepare |
| when(mockDataCenter.getNetworkType()).thenReturn(NetworkType.Advanced); |
| when(mockDestination.getPod()).thenReturn(mockPod); |
| |
| // Execute |
| deployment.planDeploymentRouters(); |
| |
| // Assert |
| verify(mockRouterDao, times(1)).listByNetworkAndRole( |
| mockNw.getId(), Role.VIRTUAL_ROUTER); |
| } |
| |
| @Test |
| public void testListByDataCenterIdVMTypeAndStates() { |
| // Prepare |
| final VMInstanceVO vmInstanceVO = mock(VMInstanceVO.class); |
| final SearchBuilder<VMInstanceVO> vmInstanceSearch = mock(SearchBuilder.class); |
| when(mockVmDao.createSearchBuilder()).thenReturn(vmInstanceSearch); |
| when(vmInstanceSearch.entity()).thenReturn(vmInstanceVO); |
| when(vmInstanceVO.getType()).thenReturn(VirtualMachine.Type.Instance); |
| when(vmInstanceVO.getState()).thenReturn(VirtualMachine.State.Stopped); |
| when(vmInstanceVO.getPodIdToDeployIn()).thenReturn(POD_ID1); |
| |
| final SearchBuilder<HostPodVO> podIdSearch = mock(SearchBuilder.class); |
| when(mockPodDao.createSearchBuilder()).thenReturn(podIdSearch); |
| final SearchCriteria<HostPodVO> sc = mock(SearchCriteria.class); |
| final HostPodVO hostPodVO = mock(HostPodVO.class); |
| when(podIdSearch.entity()).thenReturn(hostPodVO); |
| when(hostPodVO.getId()).thenReturn(POD_ID1); |
| when(hostPodVO.getDataCenterId()).thenReturn(DATA_CENTER_ID); |
| when(podIdSearch.create()).thenReturn(sc); |
| |
| final List<HostPodVO> expectedPods = mock(List.class); |
| when(mockPodDao.search(sc, null)).thenReturn(expectedPods); |
| |
| // Execute |
| final List<HostPodVO> pods = deployment.listByDataCenterIdVMTypeAndStates(DATA_CENTER_ID, |
| VirtualMachine.Type.User, |
| VirtualMachine.State.Starting, |
| VirtualMachine.State.Running); |
| |
| // Assert |
| assertNotNull(pods); |
| assertEquals(expectedPods, pods); |
| verify(sc, times(1)).setParameters("dc", DATA_CENTER_ID); |
| verify(sc, times(1)).setJoinParameters("vmInstanceSearch", "type", VirtualMachine.Type.User); |
| verify(sc, times(1)).setJoinParameters("vmInstanceSearch", "states", |
| VirtualMachine.State.Starting, VirtualMachine.State.Running); |
| verify(mockPodDao, times(1)).search(sc, null); |
| } |
| |
| @Test |
| public void testFindOrDeployVirtualRouter() throws ConcurrentOperationException, |
| InsufficientCapacityException, ResourceUnavailableException { |
| // Prepare |
| final RouterDeploymentDefinition deploymentUT = spy(deployment); |
| doNothing().when(deploymentUT).findOrDeployVirtualRouter(); |
| |
| // Execute |
| deploymentUT.deployVirtualRouter(); |
| |
| // Assert |
| verify(mockNetworkHelper, times(1)).startRouters(deploymentUT); |
| } |
| |
| @Test(expected = ConcurrentOperationException.class) |
| public void testDeployVirtualRouter() throws ConcurrentOperationException, |
| InsufficientCapacityException, ResourceUnavailableException { |
| |
| // Prepare |
| final List<DeployDestination> mockDestinations = new ArrayList<>(); |
| mockDestinations.add(mock(DeployDestination.class)); |
| mockDestinations.add(mock(DeployDestination.class)); |
| |
| final RouterDeploymentDefinition deploymentUT = spy(deployment); |
| doNothing().when(deploymentUT).lock(); |
| doNothing().when(deploymentUT).checkPreconditions(); |
| doReturn(mockDestinations).when(deploymentUT).findDestinations(); |
| doNothing().when(deploymentUT).planDeploymentRouters(); |
| doNothing().when(deploymentUT).generateDeploymentPlan(); |
| // Let's test that if the last step fails in the last iteration it unlocks the table |
| final ConcurrentOperationException exception = |
| new ConcurrentOperationException(null); |
| doNothing().doThrow(exception).when(deploymentUT).executeDeployment(); |
| doNothing().when(deploymentUT).unlock(); |
| |
| // Execute |
| try { |
| deploymentUT.findOrDeployVirtualRouter(); |
| } finally { |
| // Assert |
| verify(deploymentUT, times(1)).lock(); |
| verify(deploymentUT, times(2)).checkPreconditions(); |
| verify(deploymentUT, times(2)).findDestinations(); |
| verify(deploymentUT, times(3)).generateDeploymentPlan(); |
| verify(deploymentUT, times(2)).executeDeployment(); |
| //verify(deploymentUT, times(2)).planDeploymentRouters(); |
| verify(deploymentUT, times(1)).unlock(); |
| } |
| |
| fail(); |
| } |
| |
| @Test |
| public void testDeployVirtualRouterSkip() throws ConcurrentOperationException, |
| InsufficientCapacityException, ResourceUnavailableException { |
| |
| // Prepare |
| final List<DeployDestination> mockDestinations = new ArrayList<>(); |
| mockDestinations.add(mock(DeployDestination.class)); |
| mockDestinations.add(mock(DeployDestination.class)); |
| |
| final RouterDeploymentDefinition deploymentUT = spy(deployment); |
| doNothing().when(deploymentUT).checkPreconditions(); |
| doReturn(mockDestinations).when(deploymentUT).findDestinations(); |
| doNothing().when(deploymentUT).planDeploymentRouters(); |
| doNothing().when(deploymentUT).generateDeploymentPlan(); |
| doReturn(0).when(deploymentUT).getNumberOfRoutersToDeploy(); |
| |
| // Execute |
| try { |
| deploymentUT.findOrDeployVirtualRouter(); |
| } finally { |
| // Assert |
| verify(deploymentUT, times(0)).lock(); // lock shouldn't be acquired when VR already present |
| verify(deploymentUT, times(1)).checkPreconditions(); |
| verify(deploymentUT, times(1)).findDestinations(); |
| verify(deploymentUT, times(2)).generateDeploymentPlan(); |
| verify(deploymentUT, times(0)).executeDeployment(); // no need to deploy VR as already present |
| verify(deploymentUT, times(0)).unlock(); // same as lock |
| } |
| } |
| |
| @Test |
| public void testGetNumberOfRoutersToDeploy() { |
| // Prepare |
| deployment.routers = new ArrayList<>(); // Empty list |
| |
| // Execute and assert |
| assertEquals(NUMBER_OF_ROUTERS_TO_DEPLOY_IS_NOT_THE_EXPECTED, |
| 1, deployment.getNumberOfRoutersToDeploy()); |
| |
| // Execute and assert, just the same but for redundant deployment |
| when(mockNw.isRedundant()).thenReturn(true); |
| assertEquals(NUMBER_OF_ROUTERS_TO_DEPLOY_IS_NOT_THE_EXPECTED, |
| 2, deployment.getNumberOfRoutersToDeploy()); |
| |
| // Just the same, instead of an empty list, a 1 items list |
| deployment.routers.add(mock(DomainRouterVO.class)); |
| when(mockNw.isRedundant()).thenReturn(false); |
| assertEquals(NUMBER_OF_ROUTERS_TO_DEPLOY_IS_NOT_THE_EXPECTED, |
| 0, deployment.getNumberOfRoutersToDeploy()); |
| |
| when(mockNw.isRedundant()).thenReturn(true); |
| assertEquals(NUMBER_OF_ROUTERS_TO_DEPLOY_IS_NOT_THE_EXPECTED, |
| 1, deployment.getNumberOfRoutersToDeploy()); |
| } |
| |
| @Test |
| public void testFindVirtualProvider() { |
| // Prepare |
| when(mockNetworkModel.getPhysicalNetworkId(deployment.guestNetwork)).thenReturn(PHYSICAL_NW_ID); |
| final Type type = Type.VirtualRouter; |
| final PhysicalNetworkServiceProviderVO physicalNwSrvProvider = mock(PhysicalNetworkServiceProviderVO.class); |
| when(physicalProviderDao.findByServiceProvider(PHYSICAL_NW_ID, type.toString())) |
| .thenReturn(physicalNwSrvProvider); |
| when(physicalNwSrvProvider.getId()).thenReturn(PROVIDER_ID); |
| |
| final VirtualRouterProviderVO vrProvider = mock(VirtualRouterProviderVO.class); |
| when(mockVrProviderDao.findByNspIdAndType(PROVIDER_ID, type)) |
| .thenReturn(vrProvider); |
| |
| // Execute |
| deployment.findVirtualProvider(); |
| |
| // Assert |
| assertEquals("Didn't find and set the VirtualRouterProvider as expected", |
| vrProvider, deployment.getVirtualProvider()); |
| } |
| |
| @Test(expected = CloudRuntimeException.class) |
| public void testFindVirtualProviderWithNullPhyNwSrvProvider() { |
| // Prepare |
| when(mockNetworkModel.getPhysicalNetworkId(deployment.guestNetwork)).thenReturn(PHYSICAL_NW_ID); |
| final Type type = Type.VirtualRouter; |
| when(physicalProviderDao.findByServiceProvider(PHYSICAL_NW_ID, type.toString())) |
| .thenReturn(null); |
| |
| // Execute |
| deployment.findVirtualProvider(); |
| } |
| |
| @Test(expected = CloudRuntimeException.class) |
| public void testFindVirtualProviderWithNullVrProvider() { |
| // Prepare |
| when(mockNetworkModel.getPhysicalNetworkId(deployment.guestNetwork)).thenReturn(PHYSICAL_NW_ID); |
| final Type type = Type.VirtualRouter; |
| final PhysicalNetworkServiceProviderVO physicalNwSrvProvider = mock(PhysicalNetworkServiceProviderVO.class); |
| when(physicalProviderDao.findByServiceProvider(PHYSICAL_NW_ID, type.toString())) |
| .thenReturn(physicalNwSrvProvider); |
| when(physicalNwSrvProvider.getId()).thenReturn(PROVIDER_ID); |
| |
| when(mockVrProviderDao.findByNspIdAndType(PROVIDER_ID, type)) |
| .thenReturn(null); |
| |
| // Execute |
| deployment.findVirtualProvider(); |
| } |
| |
| @Test |
| public void testFindSourceNatIPPublicNw() throws InsufficientAddressCapacityException, ConcurrentOperationException { |
| // Prepare |
| final PublicIp sourceNatIp = mock(PublicIp.class); |
| when(mockIpAddrMgr.assignSourceNatIpAddressToGuestNetwork( |
| mockOwner, mockNw)).thenReturn(sourceNatIp); |
| deployment.isPublicNetwork = true; |
| |
| // It should be null until this method finds it |
| assertNull(deployment.sourceNatIp); |
| // Execute |
| deployment.findSourceNatIP(); |
| |
| // Assert |
| assertEquals("SourceNatIP was not correctly found and set", sourceNatIp, deployment.sourceNatIp); |
| } |
| |
| @Test |
| public void testFindSourceNatIPNonPublicNw() throws InsufficientAddressCapacityException, ConcurrentOperationException { |
| // Prepare |
| final PublicIp sourceNatIp = mock(PublicIp.class); |
| when(mockIpAddrMgr.assignSourceNatIpAddressToGuestNetwork( |
| mockOwner, mockNw)).thenReturn(sourceNatIp); |
| deployment.isPublicNetwork = false; |
| |
| // It should be null until this method finds it |
| assertNull(deployment.sourceNatIp); |
| // Execute |
| deployment.findSourceNatIP(); |
| |
| // Assert |
| assertEquals("SourceNatIP should remain null given a non public network", |
| null, deployment.sourceNatIp); |
| } |
| |
| @Test |
| public void testFindOfferingIdFromNetwork() { |
| // Prepare |
| deployment.serviceOfferingId = 1L; |
| when(mockNw.getNetworkOfferingId()).thenReturn(OFFERING_ID); |
| when(mockNetworkOfferingDao.findById(OFFERING_ID)).thenReturn(mockNwOfferingVO); |
| when(mockNwOfferingVO.getServiceOfferingId()).thenReturn(OFFERING_ID); |
| |
| // Execute |
| deployment.findServiceOfferingId(); |
| |
| // Assert |
| assertEquals("Service offering id not matching the one associated with network offering", |
| OFFERING_ID, deployment.serviceOfferingId.longValue()); |
| } |
| |
| @Test |
| public void testFindOfferingIdDefault() { |
| // Prepare |
| deployment.serviceOfferingId = 1L; |
| when(mockNw.getNetworkOfferingId()).thenReturn(OFFERING_ID); |
| when(mockNetworkOfferingDao.findById(OFFERING_ID)).thenReturn(mockNwOfferingVO); |
| when(mockNwOfferingVO.getServiceOfferingId()).thenReturn(null); |
| when(mockServiceOfferingDao.findDefaultSystemOffering(Matchers.anyString(), Matchers.anyBoolean())).thenReturn(mockSvcOfferingVO); |
| when(mockSvcOfferingVO.getId()).thenReturn(DEFAULT_OFFERING_ID); |
| |
| // Execute |
| deployment.findServiceOfferingId(); |
| |
| // Assert |
| assertEquals("Since there is no service offering associated with network offering, offering id should have matched default one", |
| DEFAULT_OFFERING_ID, deployment.serviceOfferingId.longValue()); |
| } |
| |
| @Test |
| public void testDeployAllVirtualRouters() |
| throws ConcurrentOperationException, InsufficientCapacityException, ResourceUnavailableException { |
| |
| // Prepare |
| deployment.routers = new ArrayList<>(); |
| when(mockNw.isRedundant()).thenReturn(true); |
| //this.deployment.routers.add(routerVO1); |
| final RouterDeploymentDefinition deploymentUT = spy(deployment); |
| doReturn(2).when(deploymentUT).getNumberOfRoutersToDeploy(); |
| |
| final DomainRouterVO routerVO1 = mock(DomainRouterVO.class); |
| final DomainRouterVO routerVO2 = mock(DomainRouterVO.class); |
| when(mockNetworkHelper.deployRouter(deploymentUT, false)) |
| .thenReturn(routerVO1).thenReturn(routerVO2); |
| when(networkDetailsDao.findById(anyLong())).thenReturn(null); |
| // Execute |
| deploymentUT.deployAllVirtualRouters(); |
| |
| // Assert |
| verify(mockRouterDao, times(1)).addRouterToGuestNetwork(routerVO1, mockNw); |
| verify(mockRouterDao, times(1)).addRouterToGuestNetwork(routerVO2, mockNw); |
| assertEquals("First router to deploy was not added to list of available routers", |
| routerVO1, deployment.routers.get(0)); |
| assertEquals("Second router to deploy was not added to list of available routers", |
| routerVO2, deployment.routers.get(1)); |
| } |
| |
| @Test |
| public void testSetupAccountOwner() { |
| // Prepare |
| when(mockNetworkModel.isNetworkSystem(mockNw)).thenReturn(true); |
| final Account newAccountOwner = mock(Account.class); |
| when(mockAccountMgr.getAccount(Account.ACCOUNT_ID_SYSTEM)).thenReturn(newAccountOwner); |
| //Execute |
| deployment.setupAccountOwner(); |
| // Assert |
| assertEquals("New account owner not properly set", newAccountOwner, deployment.owner); |
| } |
| |
| @Test |
| public void testSetupAccountOwnerNotNetworkSystem() { |
| // Prepare |
| when(mockNetworkModel.isNetworkSystem(mockNw)).thenReturn(false); |
| when(mockNw.getGuestType()).thenReturn(Network.GuestType.Shared); |
| final Account newAccountOwner = mock(Account.class); |
| when(mockAccountMgr.getAccount(Account.ACCOUNT_ID_SYSTEM)).thenReturn(newAccountOwner); |
| //Execute |
| deployment.setupAccountOwner(); |
| // Assert |
| assertEquals("New account owner not properly set", newAccountOwner, deployment.owner); |
| } |
| |
| @Test |
| public void testSetupAccountOwnerNotSharedNeitherNetworkSystem() { |
| // Prepare |
| when(mockNetworkModel.isNetworkSystem(mockNw)).thenReturn(false); |
| when(mockNw.getGuestType()).thenReturn(Network.GuestType.Isolated); |
| when(mockAccountMgr.getAccount(Account.ACCOUNT_ID_SYSTEM)).thenReturn(null); |
| //Execute |
| deployment.setupAccountOwner(); |
| // Assert |
| assertEquals("New account shouldn't have been updated", mockOwner, deployment.owner); |
| } |
| |
| |
| |
| |
| protected void driveTestPrepareDeployment(final boolean isRedundant, final boolean isPublicNw) { |
| // Prepare |
| when(mockNw.isRedundant()).thenReturn(isRedundant); |
| when(mockNetworkModel.isProviderSupportServiceInNetwork( |
| NW_ID_1, Service.SourceNat, Provider.VirtualRouter)).thenReturn(isPublicNw); |
| // Execute |
| final boolean canProceedDeployment = deployment.prepareDeployment(); |
| // Assert |
| boolean shouldProceedDeployment = true; |
| if (isRedundant && !isPublicNw) { |
| shouldProceedDeployment = false; |
| } |
| assertEquals(shouldProceedDeployment, canProceedDeployment); |
| if (!shouldProceedDeployment) { |
| assertEquals("Since deployment cannot proceed we should empty the list of routers", |
| 0, deployment.routers.size()); |
| } |
| } |
| |
| @Test |
| public void testPrepareDeploymentPublicNw() { |
| driveTestPrepareDeployment(true, true); |
| } |
| |
| @Test |
| public void testPrepareDeploymentNonRedundant() { |
| driveTestPrepareDeployment(false, true); |
| } |
| |
| @Test |
| public void testPrepareDeploymentRedundantNonPublicNw() { |
| driveTestPrepareDeployment(true, false); |
| } |
| |
| protected void driveTestExecuteDeployment(final int noOfRoutersToDeploy, final boolean passPreparation) |
| throws ConcurrentOperationException, InsufficientCapacityException, ResourceUnavailableException { |
| // Prepare |
| final RouterDeploymentDefinition deploymentUT = spy(deployment); |
| doReturn(noOfRoutersToDeploy).when(deploymentUT).getNumberOfRoutersToDeploy(); |
| doReturn(passPreparation).when(deploymentUT).prepareDeployment(); |
| doNothing().when(deploymentUT).findVirtualProvider(); |
| doNothing().when(deploymentUT).findServiceOfferingId(); |
| doNothing().when(deploymentUT).findSourceNatIP(); |
| doNothing().when(deploymentUT).deployAllVirtualRouters(); |
| |
| // Execute |
| deploymentUT.executeDeployment(); |
| |
| // Assert |
| verify(deploymentUT, times(1)).getNumberOfRoutersToDeploy(); |
| int proceedToDeployment = 0; |
| if (noOfRoutersToDeploy > 0) { |
| verify(deploymentUT, times(1)).prepareDeployment(); |
| if (passPreparation) { |
| proceedToDeployment = 1; |
| } |
| } |
| verify(deploymentUT, times(proceedToDeployment)).findVirtualProvider(); |
| verify(deploymentUT, times(proceedToDeployment)).findServiceOfferingId(); |
| verify(deploymentUT, times(proceedToDeployment)).findSourceNatIP(); |
| verify(deploymentUT, times(proceedToDeployment)).deployAllVirtualRouters(); |
| } |
| |
| @Test |
| public void testExecuteDeploymentNoRoutersToDeploy() |
| throws ConcurrentOperationException, InsufficientCapacityException, ResourceUnavailableException { |
| driveTestExecuteDeployment(0, true); |
| } |
| |
| @Test |
| public void testExecuteDeploymentFailPreparation() |
| throws ConcurrentOperationException, InsufficientCapacityException, ResourceUnavailableException { |
| driveTestExecuteDeployment(2, false); |
| } |
| |
| @Test |
| public void testExecuteDeployment() |
| throws ConcurrentOperationException, InsufficientCapacityException, ResourceUnavailableException { |
| driveTestExecuteDeployment(2, true); |
| } |
| } |