content: // 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 com.cloud.network.element;
  
  import com.cloud.cluster.dao.ManagementServerHostDao;
  import com.cloud.configuration.ConfigurationManager;
  import com.cloud.dc.DataCenter;
  import com.cloud.dc.DataCenter.NetworkType;
  import com.cloud.dc.DataCenterVO;
  import com.cloud.dc.dao.ClusterDao;
  import com.cloud.dc.dao.DataCenterDao;
  import com.cloud.dc.dao.HostPodDao;
  import com.cloud.dc.dao.VlanDao;
  import com.cloud.deploy.DeployDestination;
  import com.cloud.deploy.DeploymentPlan;
  import com.cloud.exception.AgentUnavailableException;
  import com.cloud.exception.ConcurrentOperationException;
  import com.cloud.exception.InsufficientCapacityException;
  import com.cloud.exception.ResourceUnavailableException;
  import com.cloud.host.dao.HostDao;
  import com.cloud.hypervisor.Hypervisor.HypervisorType;
  import com.cloud.network.Network;
  import com.cloud.network.Network.Service;
  import com.cloud.network.NetworkModel;
  import com.cloud.network.NetworkModelImpl;
  import com.cloud.network.Networks.TrafficType;
  import com.cloud.network.VirtualRouterProvider.Type;
  import com.cloud.network.as.AutoScaleCounter;
  import com.cloud.network.as.AutoScaleCounter.AutoScaleCounterType;
  import com.cloud.network.dao.FirewallRulesDao;
  import com.cloud.network.dao.IPAddressDao;
  import com.cloud.network.dao.LoadBalancerDao;
  import com.cloud.network.dao.LoadBalancerVMMapDao;
  import com.cloud.network.dao.MonitoringServiceDao;
  import com.cloud.network.dao.NetworkDao;
  import com.cloud.network.dao.NetworkDetailVO;
  import com.cloud.network.dao.NetworkDetailsDao;
  import com.cloud.network.dao.NetworkVO;
  import com.cloud.network.dao.OpRouterMonitorServiceDao;
  import com.cloud.network.dao.OvsProviderDao;
  import com.cloud.network.dao.PhysicalNetworkServiceProviderDao;
  import com.cloud.network.dao.PhysicalNetworkServiceProviderVO;
  import com.cloud.network.dao.RemoteAccessVpnDao;
  import com.cloud.network.dao.Site2SiteCustomerGatewayDao;
  import com.cloud.network.dao.Site2SiteVpnConnectionDao;
  import com.cloud.network.dao.Site2SiteVpnGatewayDao;
  import com.cloud.network.dao.UserIpv6AddressDao;
  import com.cloud.network.dao.VirtualRouterProviderDao;
  import com.cloud.network.dao.VpnUserDao;
  import com.cloud.network.router.VirtualRouter;
  import com.cloud.network.router.VirtualRouter.RedundantState;
  import com.cloud.network.router.VpcVirtualNetworkApplianceManagerImpl;
  import com.cloud.network.rules.dao.PortForwardingRulesDao;
  import com.cloud.network.vpc.VpcVO;
  import com.cloud.offering.NetworkOffering;
  import com.cloud.offerings.NetworkOfferingVO;
  import com.cloud.offerings.dao.NetworkOfferingDao;
  import com.cloud.resource.ResourceManager;
  import com.cloud.service.ServiceOfferingVO;
  import com.cloud.service.dao.ServiceOfferingDao;
  import com.cloud.storage.VMTemplateVO;
  import com.cloud.storage.dao.GuestOSDao;
  import com.cloud.storage.dao.VMTemplateDao;
  import com.cloud.storage.dao.VolumeDao;
  import com.cloud.user.Account;
  import com.cloud.user.AccountManager;
  import com.cloud.user.AccountVO;
  import com.cloud.user.dao.UserDao;
  import com.cloud.user.dao.UserStatisticsDao;
  import com.cloud.user.dao.UserStatsLogDao;
  import com.cloud.utils.exception.CloudRuntimeException;
  import com.cloud.vm.DomainRouterVO;
  import com.cloud.vm.NicProfile;
  import com.cloud.vm.ReservationContext;
  import com.cloud.vm.ReservationContextImpl;
  import com.cloud.vm.UserVmManager;
  import com.cloud.vm.VirtualMachine;
  import com.cloud.vm.VirtualMachineManager;
  import com.cloud.vm.VirtualMachineProfile;
  import com.cloud.vm.dao.DomainRouterDao;
  import com.cloud.vm.dao.NicDao;
  import com.cloud.vm.dao.NicIpAliasDao;
  import com.cloud.vm.dao.UserVmDao;
  import com.cloud.vm.dao.VMInstanceDetailsDao;
  import com.cloud.vm.dao.VMInstanceDao;
  
  import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService;
  import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
  import org.apache.cloudstack.network.BgpPeerVO;
  import org.apache.cloudstack.network.router.deployment.RouterDeploymentDefinitionBuilder;
  import org.apache.cloudstack.network.topology.NetworkTopology;
  import org.apache.cloudstack.network.topology.NetworkTopologyContext;
  import org.junit.Assert;
  import org.junit.Ignore;
  import org.junit.Test;
  import org.junit.runner.RunWith;
  import org.mockito.InjectMocks;
  import org.mockito.ArgumentMatchers;
  import org.mockito.Mock;
  import org.mockito.Mockito;
  import org.mockito.invocation.InvocationOnMock;
  import org.mockito.junit.MockitoJUnitRunner;
  import org.mockito.stubbing.Answer;
  
  import java.util.ArrayList;
  import java.util.Arrays;
  import java.util.List;
  import java.util.stream.Collectors;
  
  import static org.junit.Assert.assertEquals;
  import static org.junit.Assert.assertTrue;
  import static org.mockito.ArgumentMatchers.any;
  import static org.mockito.ArgumentMatchers.anyBoolean;
  import static org.mockito.ArgumentMatchers.anyList;
  import static org.mockito.ArgumentMatchers.anyLong;
  import static org.mockito.Mockito.doReturn;
  import static org.mockito.Mockito.lenient;
  import static org.mockito.Mockito.verify;
  import static org.mockito.Mockito.when;
  
  @RunWith(MockitoJUnitRunner.class)
  public class VirtualRouterElementTest {
      @Mock private ClusterDao _clusterDao;
      @Mock private ConfigurationDao _configDao;
      @Mock private DataCenterDao _dcDao;
      @Mock private GuestOSDao _guestOSDao;
      @Mock private HostDao _hostDao;
      @Mock private IPAddressDao _ipAddressDao;
      @Mock private UserIpv6AddressDao _ipv6Dao;
      @Mock private LoadBalancerDao _loadBalancerDao;
      @Mock private LoadBalancerVMMapDao _loadBalancerVMMapDao;
      @Mock private MonitoringServiceDao _monitorServiceDao;
      @Mock private ManagementServerHostDao _msHostDao;
      @Mock private NetworkDao _networkDao;
      @Mock private NetworkOfferingDao _networkOfferingDao;
      @Mock private NetworkDetailsDao _networkDetailsDao;
      @Mock private NicDao _nicDao;
      @Mock private NicIpAliasDao _nicIpAliasDao;
      @Mock private OpRouterMonitorServiceDao _opRouterMonitorServiceDao;
      @Mock private PortForwardingRulesDao _pfRulesDao;
      @Mock private PhysicalNetworkServiceProviderDao _physicalProviderDao;
      @Mock private HostPodDao _podDao;
      @Mock private DomainRouterDao _routerDao;
      @Mock private FirewallRulesDao _rulesDao;
      @Mock private Site2SiteCustomerGatewayDao _s2sCustomerGatewayDao;
      @Mock private Site2SiteVpnConnectionDao _s2sVpnConnectionDao;
      @Mock private Site2SiteVpnGatewayDao _s2sVpnGatewayDao;
      @Mock private ServiceOfferingDao _serviceOfferingDao;
      @Mock private VMTemplateDao _templateDao;
      @Mock private UserDao _userDao;
      @Mock private UserStatisticsDao _userStatsDao;
      @Mock private UserStatsLogDao _userStatsLogDao;
      @Mock private UserVmDao _userVmDao;
      @Mock private VlanDao _vlanDao;
      @Mock private VMInstanceDao _vmDao;
      @Mock private VMInstanceDetailsDao _vmDetailsDao;
      @Mock private VolumeDao _volumeDao;
      @Mock private RemoteAccessVpnDao _vpnDao;
      @Mock private VpnUserDao _vpnUsersDao;
      @Mock private VirtualRouterProviderDao _vrProviderDao;
      @Mock private LoadBalancerDao loadBalancerDao;
      @Mock private LoadBalancerDao _lbDao;
      @Mock private NetworkDao networkDao;
      @Mock private NetworkDao _networksDao;
      @Mock private OvsProviderDao _ovsProviderDao;
  
      @Mock private ServiceOfferingVO _offering;
      @Mock private NetworkModelImpl _networkModel;
  
      @Mock private AccountManager _accountMgr;
      @Mock private ConfigurationManager _configMgr;
      @Mock private NetworkModel networkModel;
      @Mock private NetworkModel _networkMdl;
      @Mock private NetworkOrchestrationService _networkMgr;
      @Mock private ResourceManager _resourceMgr;
      @Mock private UserVmManager _userVmMgr;
      @Mock private VirtualMachineManager _itMgr;
      @Mock private NetworkTopologyContext networkTopologyContext;
  
      @InjectMocks
      private RouterDeploymentDefinitionBuilder routerDeploymentDefinitionBuilder;
  
      @InjectMocks
      private VpcVirtualNetworkApplianceManagerImpl _routerMgr;
  
      @InjectMocks
      private VirtualRouterElement virtualRouterElement;
  
      DataCenter testDataCenter = new DataCenterVO(/* id */ 1L,
              "name",
              "description",
              "dns1",
              /* dns2 */ null,
              /* dns3 */ null,
              /* dns4 */ null,
              "cidr",
              "domain",
              /*domainid */ null,
              NetworkType.Advanced,
              "zoneToken",
              "domainSuffix");
      DeployDestination testDestination = new DeployDestination(testDataCenter,null,null,null);
      ReservationContext testContext = new ReservationContextImpl(null, null, null);
      NetworkVO testNetwork = new NetworkVO();
      NicProfile testNicProfile = new NicProfile();
      NetworkOfferingVO testOffering = new NetworkOfferingVO();
      @Mock VirtualMachineProfile testVMProfile;
  
      @Test
      @Ignore("Ignore it until it's fixed in order not to brake the build")
      public void testImplementInAdvancedZoneOnXenServer() throws Exception {
          virtualRouterElement._routerMgr = _routerMgr;
          mockDAOs(testNetwork, testOffering);
          mockMgrs();
  
          final boolean done = virtualRouterElement.implement(testNetwork, testOffering, testDestination, testContext);
          assertTrue("no cigar for network daddy",done);
      }
  
      @Test
      @Ignore("Ignore it until it's fixed in order not to brake the build")
      public void testPrepare() {
          virtualRouterElement._routerMgr = _routerMgr;
          virtualRouterElement.routerDeploymentDefinitionBuilder = routerDeploymentDefinitionBuilder;
          mockDAOs(testNetwork, testOffering);
          mockMgrs();
  
          boolean done = false;
          try {
              done = virtualRouterElement.prepare(testNetwork, testNicProfile, testVMProfile, testDestination, testContext);
          } catch (ConcurrentOperationException | InsufficientCapacityException | ResourceUnavailableException e) {
              // TODO Auto-generated catch block
              e.printStackTrace();
          }
          assertTrue("can not even start to create a router", done);
  
      }
  
      @Test
      public void testGetRouters1(){
          Network networkUpdateInprogress=new NetworkVO(1l,null,null,null,1l,1l,1l,1l,"d","d","d",null,1l,1l,null,true,null,true);
          mockDAOs((NetworkVO)networkUpdateInprogress,testOffering);
          //getRoutes should always return the router that is updating.
          List<DomainRouterVO> routers=virtualRouterElement.getRouters(networkUpdateInprogress);
          assertTrue(routers.size()==1);
          assertTrue(routers.get(0).getUpdateState()== VirtualRouter.UpdateState.UPDATE_IN_PROGRESS);
      }
  
      @Test
      public void testGetRouters2(){
          Network networkUpdateInprogress=new NetworkVO(2l,null,null,null,1l,1l,1l,1l,"d","d","d",null,1l,1l,null,true,null,true);
          mockDAOs((NetworkVO)networkUpdateInprogress,testOffering);
          //always return backup routers first when both primary and backup need update.
          List<DomainRouterVO> routers=virtualRouterElement.getRouters(networkUpdateInprogress);
          assertTrue(routers.size()==1);
          assertTrue(routers.get(0).getRedundantState()==RedundantState.BACKUP && routers.get(0).getUpdateState()==VirtualRouter.UpdateState.UPDATE_IN_PROGRESS);
      }
  
      @Test
      public void testGetRouters3(){
          Network network=new NetworkVO(3l,null,null,null,1l,1l,1l,1l,"d","d","d",null,1l,1l,null,true,null,true);
          mockDAOs((NetworkVO)network,testOffering);
          //always return backup routers first when both primary and backup need update.
          List<DomainRouterVO> routers=virtualRouterElement.getRouters(network);
          assertTrue(routers.size()==4);
      }
  
      @Test
      public void getResourceCountTest(){
          Network network=new NetworkVO(3l,null,null,null,1l,1l,1l,1l,"d","d","d",null,1l,1l,null,true,null,true);
          mockDAOs((NetworkVO)network,testOffering);
          int routers=virtualRouterElement.getResourceCount(network);
          assertTrue(routers==4);
      }
  
      @Test
      public void completeAggregationCommandTest1() throws AgentUnavailableException,ResourceUnavailableException {
          virtualRouterElement._routerMgr = Mockito.mock(VpcVirtualNetworkApplianceManagerImpl.class);
          virtualRouterElement.routerDeploymentDefinitionBuilder = routerDeploymentDefinitionBuilder;
          Network network = new NetworkVO(6l, null, null, null, 1l, 1l, 1l, 1l, "d", "d", "d", null, 1l, 1l, null, true, null, true);
          when(virtualRouterElement._routerMgr.completeAggregatedExecution(any(Network.class), anyList())).thenReturn(true);
          mockDAOs((NetworkVO) network, testOffering);
          when(virtualRouterElement._routerDao.persist(any(DomainRouterVO.class))).thenAnswer(new Answer<Object>() {
              @Override
              public Object answer(InvocationOnMock invocationOnMock) throws Throwable {
                  Object args[] = invocationOnMock.getArguments();
                  DomainRouterVO router = (DomainRouterVO) args[0];
                  if (router.getUpdateState() != VirtualRouter.UpdateState.UPDATE_COMPLETE) {
                      throw new CloudRuntimeException("TestFailed: completeAggregationCommandTest1 failed");
                  } else return null;
              }
          });
          virtualRouterElement.completeAggregatedExecution(network, testDestination);
      }
      /**
       * @param networks
       * @param offerings
       * @throws ConcurrentOperationException
       */
      private void mockMgrs() throws ConcurrentOperationException {
          final Service service = Service.Connectivity;
          testNetwork.setState(Network.State.Implementing);
          testNetwork.setTrafficType(TrafficType.Guest);
          when(_networkMdl.isProviderEnabledInPhysicalNetwork(0L, "VirtualRouter")).thenReturn(true);
          when(_networkMdl.isProviderSupportServiceInNetwork(testNetwork.getId(), service, Network.Provider.VirtualRouter)).thenReturn(true);
          when(_networkMdl.isProviderForNetwork(Network.Provider.VirtualRouter, 0L)).thenReturn(true);
          when(testVMProfile.getType()).thenReturn(VirtualMachine.Type.User);
          when(testVMProfile.getHypervisorType()).thenReturn(HypervisorType.XenServer);
          final List<NetworkVO> networks = new ArrayList<NetworkVO>(1);
          networks.add(testNetwork);
          final List<NetworkOfferingVO> offerings = new ArrayList<NetworkOfferingVO>(1);
          offerings.add(testOffering);
          doReturn(offerings).when(_networkModel).getSystemAccountNetworkOfferings(NetworkOffering.SystemControlNetwork);
          doReturn(networks).when(_networkMgr).setupNetwork(any(Account.class), any(NetworkOffering.class), any(DeploymentPlan.class), any(String.class), any(String.class), anyBoolean());
          // being anti-social and testing my own case first
          doReturn(HypervisorType.XenServer).when(_resourceMgr).getDefaultHypervisor(anyLong());
          doReturn(new AccountVO()).when(_accountMgr).getAccount(testNetwork.getAccountId());
      }
  
      /**
       * @param network
       */
      private void mockDAOs(final NetworkVO network, final NetworkOfferingVO offering) {
          lenient().when(_networkDao.acquireInLockTable(network.getId(), NetworkOrchestrationService.NetworkLockTimeout.value())).thenReturn(network);
          lenient().when(_networksDao.acquireInLockTable(network.getId(), NetworkOrchestrationService.NetworkLockTimeout.value())).thenReturn(network);
          lenient().when(_physicalProviderDao.findByServiceProvider(0L, "VirtualRouter")).thenReturn(new PhysicalNetworkServiceProviderVO());
          lenient().when(_vrProviderDao.findByNspIdAndType(0L, Type.VirtualRouter)).thenReturn(new VirtualRouterProviderVO());
          lenient().when(_networkOfferingDao.findById(0L)).thenReturn(offering);
          // watchit: (in this test) there can be only one
          when(_routerDao.getNextInSequence(Long.class, "id")).thenReturn(0L);
          final ServiceOfferingVO svcoff = new ServiceOfferingVO("name",
                  /* cpu */ 1,
                  /* ramsize */ 1024*1024,
                  /* (clock?)speed */ 1024*1024*1024,
                  /* rateMbps */ 1,
                  /* multicastRateMbps */ 0,
                  /* offerHA */ false,
                  "displayText",
                  /* systemUse */ false,
                  VirtualMachine.Type.DomainRouter,
                  /* defaultUse */ false);
          lenient().when(_serviceOfferingDao.findById(0L)).thenReturn(svcoff);
          lenient().when(_serviceOfferingDao.findByName(ArgumentMatchers.anyString())).thenReturn(svcoff);
          final DomainRouterVO router = new DomainRouterVO(/* id */ 1L,
                  /* serviceOfferingId */ 1L,
                  /* elementId */ 0L,
                  "name",
                  /* templateId */0L,
                  HypervisorType.XenServer,
                  /* guestOSId */ 0L,
                  /* domainId */ 0L,
                  /* accountId */ 1L,
                  /* userId */ 1L,
                  /* isRedundantRouter */ false,
                  RedundantState.UNKNOWN,
                  /* haEnabled */ false,
                  /* stopPending */ false,
                  /* vpcId */ null);
          final DomainRouterVO routerNeedUpdateBackup = new DomainRouterVO(/* id */ 2L,
                  /* serviceOfferingId */ 1L,
                  /* elementId */ 0L,
                  "name",
                  /* templateId */0L,
                  HypervisorType.XenServer,
                  /* guestOSId */ 0L,
                  /* domainId */ 0L,
                  /* accountId */ 1L,
                  /* userId */ 1L,
                  /* isRedundantRouter */ false,
                  RedundantState.BACKUP,
                  /* haEnabled */ false,
                  /* stopPending */ false,
                  /* vpcId */ null);
                  routerNeedUpdateBackup.setUpdateState(VirtualRouter.UpdateState.UPDATE_NEEDED);
          final DomainRouterVO routerNeedUpdatePrimary = new DomainRouterVO(/* id */ 3L,
                  /* serviceOfferingId */ 1L,
                  /* elementId */ 0L,
                  "name",
                  /* templateId */0L,
                  HypervisorType.XenServer,
                  /* guestOSId */ 0L,
                  /* domainId */ 0L,
                  /* accountId */ 1L,
                  /* userId */ 1L,
                  /* isRedundantRouter */ false,
                  RedundantState.PRIMARY,
                  /* haEnabled */ false,
                  /* stopPending */ false,
                  /* vpcId */ null);
          routerNeedUpdatePrimary.setUpdateState(VirtualRouter.UpdateState.UPDATE_NEEDED);
          final DomainRouterVO routerUpdateComplete = new DomainRouterVO(/* id */ 4L,
                  /* serviceOfferingId */ 1L,
                  /* elementId */ 0L,
                  "name",
                  /* templateId */0L,
                  HypervisorType.XenServer,
                  /* guestOSId */ 0L,
                  /* domainId */ 0L,
                  /* accountId */ 1L,
                  /* userId */ 1L,
                  /* isRedundantRouter */ false,
                  RedundantState.UNKNOWN,
                  /* haEnabled */ false,
                  /* stopPending */ false,
                  /* vpcId */ null);
                  routerUpdateComplete.setUpdateState(VirtualRouter.UpdateState.UPDATE_COMPLETE);
          final DomainRouterVO routerUpdateInProgress = new DomainRouterVO(/* id */ 5L,
                  /* serviceOfferingId */ 1L,
                  /* elementId */ 0L,
                  "name",
                  /* templateId */0L,
                  HypervisorType.XenServer,
                  /* guestOSId */ 0L,
                  /* domainId */ 0L,
                  /* accountId */ 1L,
                  /* userId */ 1L,
                  /* isRedundantRouter */ false,
                  RedundantState.UNKNOWN,
                  /* haEnabled */ false,
                  /* stopPending */ false,
                  /* vpcId */ null);
                  routerUpdateInProgress.setUpdateState(VirtualRouter.UpdateState.UPDATE_IN_PROGRESS);
          List<DomainRouterVO> routerList1=new ArrayList<>();
          routerList1.add(routerUpdateComplete);
          routerList1.add(routerNeedUpdateBackup);
          routerList1.add(routerNeedUpdatePrimary);
          routerList1.add(routerUpdateInProgress);
          List<DomainRouterVO> routerList2=new ArrayList<>();
          routerList2.add(routerUpdateComplete);
          routerList2.add(routerNeedUpdateBackup);
          routerList2.add(routerNeedUpdatePrimary);
          List<DomainRouterVO> routerList3=new ArrayList<>();
          routerList3.add(routerUpdateComplete);
          routerList3.add(routerUpdateInProgress);
          lenient().when(_routerDao.getNextInSequence(Long.class, "id")).thenReturn(1L);
          lenient().when(_templateDao.findRoutingTemplate(HypervisorType.XenServer, "SystemVM Template (XenServer)")).thenReturn(new VMTemplateVO());
          lenient().when(_routerDao.persist(any(DomainRouterVO.class))).thenReturn(router);
          lenient().when(_routerDao.findById(router.getId())).thenReturn(router);
          when(_routerDao.listByNetworkAndRole(1l, VirtualRouter.Role.VIRTUAL_ROUTER)).thenReturn(routerList1);
          when(_routerDao.listByNetworkAndRole(2l, VirtualRouter.Role.VIRTUAL_ROUTER)).thenReturn(routerList2);
          when(_routerDao.listByNetworkAndRole(3l, VirtualRouter.Role.VIRTUAL_ROUTER)).thenReturn(routerList1);
          when(_routerDao.listByNetworkAndRole(6l, VirtualRouter.Role.VIRTUAL_ROUTER)).thenReturn(routerList3);
          when(_networkDetailsDao.findDetail(1l, Network.updatingInSequence)).thenReturn(new NetworkDetailVO(1l,Network.updatingInSequence,"true",true));
          when(_networkDetailsDao.findDetail(2l, Network.updatingInSequence)).thenReturn(new NetworkDetailVO(2l,Network.updatingInSequence,"true",true));
          when(_networkDetailsDao.findDetail(6l, Network.updatingInSequence)).thenReturn(new NetworkDetailVO(2l,Network.updatingInSequence,"true",true));
          when(_routerDao.persist(any(DomainRouterVO.class))).thenReturn(router);
      }
  
      @Test
      public void testCanHandle() {
          Network network = Mockito.mock(Network.class);
  
          final long networkId = 1;
          final long physicalNetworkId = 42;
          final long networkOfferingId = 10;
          final long dataCenterId = 33;
  
          when(network.getId()).thenReturn(networkId);
          lenient().when(network.getPhysicalNetworkId()).thenReturn(physicalNetworkId);
          lenient().when(network.getTrafficType()).thenReturn(TrafficType.Guest);
          lenient().when(network.getNetworkOfferingId()).thenReturn(networkOfferingId);
          lenient().when(network.getDataCenterId()).thenReturn(dataCenterId);
          when(network.getVpcId()).thenReturn(null);
  
          when(virtualRouterElement._networkMdl.getPhysicalNetworkId(network)).thenReturn(physicalNetworkId);
          when(virtualRouterElement._networkMdl.isProviderEnabledInPhysicalNetwork(physicalNetworkId, Network.Provider.VirtualRouter.getName())).thenReturn(true);
          when(virtualRouterElement._networkMdl.isProviderForNetwork(Network.Provider.VirtualRouter, networkId)).thenReturn(true);
  
          assertTrue(virtualRouterElement.canHandle(network, null));
      }
  
      @Test
      public void testAddPasswordAndUserdata() throws Exception {
          Network network = Mockito.mock(Network.class);
          VirtualMachineProfile vm = Mockito.mock(VirtualMachineProfile.class);
          NicProfile nic = Mockito.mock(NicProfile.class);
          DeployDestination dest = Mockito.mock(DeployDestination.class);
          ReservationContext context = Mockito.mock(ReservationContext.class);
          Service service = Service.UserData;
  
          final long networkId = 1;
          final long physicalNetworkId = 42;
          final long networkOfferingId = 10;
          final long dataCenterId = 33;
  
          when(network.getId()).thenReturn(networkId);
          lenient().when(network.getPhysicalNetworkId()).thenReturn(physicalNetworkId);
          lenient().when(network.getTrafficType()).thenReturn(TrafficType.Guest);
          lenient().when(network.getNetworkOfferingId()).thenReturn(networkOfferingId);
          lenient().when(network.getDataCenterId()).thenReturn(dataCenterId);
          when(network.getVpcId()).thenReturn(null);
  
          lenient().when(vm.getType()).thenReturn(VirtualMachine.Type.User);
  
          when(virtualRouterElement._networkMdl.getPhysicalNetworkId(network)).thenReturn(physicalNetworkId);
          when(virtualRouterElement._networkMdl.isProviderEnabledInPhysicalNetwork(physicalNetworkId, Network.Provider.VirtualRouter.getName())).thenReturn(true);
          when(virtualRouterElement._networkMdl.isProviderSupportServiceInNetwork(networkId, service, Network.Provider.VirtualRouter)).thenReturn(true);
  
          lenient().when(virtualRouterElement._dcDao.findById(dataCenterId)).thenReturn(Mockito.mock(DataCenterVO.class));
  
          when(virtualRouterElement.canHandle(network, service)).thenReturn(false);
  
          assertTrue(virtualRouterElement.addPasswordAndUserdata(network, nic, vm, dest, context));
      }
  
      @Test
      public void verifyAutoScaleCounters() {
          final List<AutoScaleCounter> counterList = VirtualRouterElement.getAutoScaleCounters();
          assertEquals(3, counterList.size());
  
          List<String> counterNames = counterList.stream().map(counter -> counter.getName()).collect(Collectors.toList());
  
          assertEquals(3, counterNames.size());
          assertTrue(counterNames.contains(AutoScaleCounterType.Cpu.getName()));
          assertTrue(counterNames.contains(AutoScaleCounterType.Memory.getName()));
          assertTrue(counterNames.contains(AutoScaleCounterType.VirtualRouter.getName()));
      }
  
      @Test
      public void testApplyBgpPeersForVpc() throws ResourceUnavailableException {
          List<BgpPeerVO> bgpPeers = Mockito.mock(List.class);
          VpcVO vpc = Mockito.mock(VpcVO.class);
  
          DomainRouterVO router = Mockito.mock(DomainRouterVO.class);
          when(router.getState()).thenReturn(VirtualMachine.State.Running);
          long zoneId = 10L;
          long vpcId = 11L;
          when(vpc.getId()).thenReturn(vpcId);
          when(vpc.getZoneId()).thenReturn(zoneId);
          when(_routerDao.listByVpcId(vpcId)).thenReturn(Arrays.asList(router));
          DataCenterVO dc = Mockito.mock(DataCenterVO.class);
          when(_dcDao.findById(zoneId)).thenReturn(dc);
          NetworkTopology networkTopology = Mockito.mock(NetworkTopology.class);
          when(networkTopologyContext.retrieveNetworkTopology(dc)).thenReturn(networkTopology);
          doReturn(true).when(networkTopology).applyBgpPeers(any(), any(), any());
  
          boolean result = virtualRouterElement.applyBgpPeers(vpc, null, bgpPeers);
  
          Assert.assertTrue(result);
          verify(networkTopology).applyBgpPeers(any(), any(), any());
      }
  
      @Test
      public void testApplyBgpPeersForNetwork() throws ResourceUnavailableException {
          List<BgpPeerVO> bgpPeers = Mockito.mock(List.class);
          NetworkVO network = Mockito.mock(NetworkVO.class);
  
          DomainRouterVO router = Mockito.mock(DomainRouterVO.class);
          when(router.getState()).thenReturn(VirtualMachine.State.Running);
          long zoneId = 10L;
          long networkId = 11L;
          when(network.getId()).thenReturn(networkId);
          when(network.getDataCenterId()).thenReturn(zoneId);
          when(_routerDao.listByNetworkAndRole(networkId, VirtualRouter.Role.VIRTUAL_ROUTER)).thenReturn(Arrays.asList(router));
          DataCenterVO dc = Mockito.mock(DataCenterVO.class);
          when(_dcDao.findById(zoneId)).thenReturn(dc);
          NetworkTopology networkTopology = Mockito.mock(NetworkTopology.class);
          when(networkTopologyContext.retrieveNetworkTopology(dc)).thenReturn(networkTopology);
          doReturn(true).when(networkTopology).applyBgpPeers(any(), any(), any());
  
          boolean result = virtualRouterElement.applyBgpPeers(null, network, bgpPeers);
  
          Assert.assertTrue(result);
          verify(networkTopology).applyBgpPeers(any(), any(), any());
      }
  }
  