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.configuration;
  
  import com.cloud.agent.AgentManager;
  import com.cloud.api.query.dao.NetworkOfferingJoinDao;
  import com.cloud.api.query.vo.NetworkOfferingJoinVO;
  import com.cloud.configuration.Resource.ResourceType;
  import com.cloud.dc.AccountVlanMapVO;
  import com.cloud.dc.ClusterVO;
  import com.cloud.dc.DataCenter;
  import com.cloud.dc.DataCenter.NetworkType;
  import com.cloud.dc.DataCenterGuestIpv6Prefix;
  import com.cloud.dc.DataCenterGuestIpv6PrefixVO;
  import com.cloud.dc.DataCenterVO;
  import com.cloud.dc.HostPodVO;
  import com.cloud.dc.Vlan;
  import com.cloud.dc.VlanVO;
  import com.cloud.dc.dao.AccountVlanMapDao;
  import com.cloud.dc.dao.ClusterDao;
  import com.cloud.dc.dao.DataCenterDao;
  import com.cloud.dc.dao.DataCenterGuestIpv6PrefixDao;
  import com.cloud.dc.dao.DataCenterIpAddressDao;
  import com.cloud.dc.dao.DomainVlanMapDao;
  import com.cloud.dc.dao.HostPodDao;
  import com.cloud.dc.dao.VlanDao;
  import com.cloud.exception.InsufficientCapacityException;
  import com.cloud.exception.InvalidParameterValueException;
  import com.cloud.exception.ResourceAllocationException;
  import com.cloud.exception.ResourceUnavailableException;
  import com.cloud.host.HostVO;
  import com.cloud.host.dao.HostDao;
  import com.cloud.network.IpAddressManager;
  import com.cloud.network.Ipv6GuestPrefixSubnetNetworkMapVO;
  import com.cloud.network.Network;
  import com.cloud.network.Network.Capability;
  import com.cloud.network.NetworkModel;
  import com.cloud.network.Networks;
  import com.cloud.network.dao.FirewallRulesDao;
  import com.cloud.network.dao.IPAddressDao;
  import com.cloud.network.dao.IPAddressVO;
  import com.cloud.network.dao.Ipv6GuestPrefixSubnetNetworkMapDao;
  import com.cloud.network.dao.NetworkDao;
  import com.cloud.network.dao.NetworkVO;
  import com.cloud.network.dao.PhysicalNetworkDao;
  import com.cloud.network.dao.PhysicalNetworkVO;
  import com.cloud.offering.DiskOffering;
  import com.cloud.projects.ProjectManager;
  import com.cloud.storage.DiskOfferingVO;
  import com.cloud.storage.StoragePoolTagVO;
  import com.cloud.storage.VolumeVO;
  import com.cloud.storage.dao.DiskOfferingDao;
  import com.cloud.storage.dao.StoragePoolTagsDao;
  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.ResourceLimitService;
  import com.cloud.user.User;
  import com.cloud.user.UserVO;
  import com.cloud.user.dao.AccountDao;
  import com.cloud.utils.Pair;
  import com.cloud.utils.db.Filter;
  import com.cloud.utils.db.SearchCriteria;
  import com.cloud.utils.db.TransactionLegacy;
  import com.cloud.utils.exception.CloudRuntimeException;
  import com.cloud.utils.net.Ip;
  import com.cloud.utils.net.NetUtils;
  import com.cloud.vm.VMInstanceVO;
  import com.cloud.vm.dao.VMInstanceDao;
  import org.apache.cloudstack.api.command.admin.network.CreateGuestNetworkIpv6PrefixCmd;
  import org.apache.cloudstack.api.command.admin.network.CreateNetworkOfferingCmd;
  import org.apache.cloudstack.api.command.admin.network.DeleteGuestNetworkIpv6PrefixCmd;
  import org.apache.cloudstack.api.command.admin.network.ListGuestNetworkIpv6PrefixesCmd;
  import org.apache.cloudstack.api.command.admin.vlan.CreateVlanIpRangeCmd;
  import org.apache.cloudstack.api.command.admin.vlan.DedicatePublicIpRangeCmd;
  import org.apache.cloudstack.api.command.admin.vlan.ReleasePublicIpRangeCmd;
  import org.apache.cloudstack.api.command.admin.zone.CreateZoneCmd;
  import org.apache.cloudstack.api.command.admin.zone.UpdateZoneCmd;
  import org.apache.cloudstack.api.command.user.network.ListNetworkOfferingsCmd;
  import org.apache.cloudstack.context.CallContext;
  import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService;
  import org.apache.cloudstack.engine.subsystem.api.storage.ZoneScope;
  import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
  import org.apache.cloudstack.framework.messagebus.MessageBusBase;
  import org.apache.cloudstack.storage.datastore.db.ImageStoreDao;
  import org.apache.cloudstack.storage.datastore.db.ImageStoreVO;
  import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
  import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
  import org.apache.logging.log4j.LogManager;
  import org.apache.logging.log4j.Logger;
  import org.junit.After;
  import org.junit.Assert;
  import org.junit.Before;
  import org.junit.Test;
  import org.mockito.InjectMocks;
  import org.mockito.Mock;
  import org.mockito.Mockito;
  import org.mockito.MockitoAnnotations;
  import org.mockito.Spy;
  import org.mockito.stubbing.Answer;
  import org.springframework.test.util.ReflectionTestUtils;
  
  import java.lang.reflect.Field;
  import java.util.ArrayList;
  import java.util.Arrays;
  import java.util.HashMap;
  import java.util.HashSet;
  import java.util.List;
  import java.util.Map;
  import java.util.Random;
  import java.util.Set;
  import java.util.UUID;
  
  import static org.hamcrest.CoreMatchers.is;
  import static org.junit.Assert.assertEquals;
  import static org.junit.Assert.assertFalse;
  import static org.junit.Assert.assertThat;
  import static org.junit.Assert.assertTrue;
  import static org.mockito.ArgumentMatchers.any;
  import static org.mockito.ArgumentMatchers.anyBoolean;
  import static org.mockito.ArgumentMatchers.anyInt;
  import static org.mockito.ArgumentMatchers.anyLong;
  import static org.mockito.ArgumentMatchers.anyString;
  import static org.mockito.ArgumentMatchers.nullable;
  import static org.mockito.Mockito.doNothing;
  import static org.mockito.Mockito.doThrow;
  import static org.mockito.Mockito.mock;
  import static org.mockito.Mockito.when;
  
  public class ConfigurationManagerTest {
  
      private Logger logger = LogManager.getLogger(ConfigurationManagerTest.class);
  
      @Spy
      @InjectMocks
      ConfigurationManagerImpl configurationMgr = new ConfigurationManagerImpl();
  
      DedicatePublicIpRangeCmd dedicatePublicIpRangesCmd = new DedicatePublicIpRangeCmdExtn();
      Class<?> _dedicatePublicIpRangeClass = dedicatePublicIpRangesCmd.getClass().getSuperclass();
  
      ReleasePublicIpRangeCmd releasePublicIpRangesCmd = new ReleasePublicIpRangeCmdExtn();
      Class<?> _releasePublicIpRangeClass = releasePublicIpRangesCmd.getClass().getSuperclass();
  
      @Mock
      AccountManager _accountMgr;
      @Mock
      ProjectManager _projectMgr;
      @Mock
      ResourceLimitService _resourceLimitMgr;
      @Mock
      NetworkOrchestrationService _networkMgr;
      @Mock
      NetworkOfferingJoinDao networkOfferingJoinDao;
      @Mock
      AccountDao _accountDao;
      @Mock
      VlanDao _vlanDao;
      @Mock
      AccountVlanMapDao _accountVlanMapDao;
      @Mock
      DomainVlanMapDao _domainVlanMapDao;
      @Mock
      IPAddressDao _publicIpAddressDao;
      @Mock
      DataCenterDao _zoneDao;
      @Mock
      FirewallRulesDao _firewallDao;
      @Mock
      IpAddressManager _ipAddrMgr;
      @Mock
      NetworkModel _networkModel;
      @Mock
      DataCenterIpAddressDao _privateIpAddressDao;
      @Mock
      VolumeDao _volumeDao;
      @Mock
      HostDao _hostDao;
      @Mock
      VMInstanceDao _vmInstanceDao;
      @Mock
      ClusterDao _clusterDao;
      @Mock
      HostPodDao _podDao;
      @Mock
      NetworkDao _networkDao;
      @Mock
      PhysicalNetworkDao _physicalNetworkDao;
      @Mock
      ImageStoreDao _imageStoreDao;
      @Mock
      ConfigurationDao _configDao;
      @Mock
      DiskOfferingVO diskOfferingVOMock;
      @Mock
      PrimaryDataStoreDao primaryDataStoreDao;
      @Mock
      StoragePoolTagsDao storagePoolTagsDao;
      @Mock
      DiskOfferingDao diskOfferingDao;
      @Mock
      VolumeVO volumeVO;
      @Mock
      StoragePoolVO storagePoolVO;
      @Mock
      DataCenterGuestIpv6PrefixDao dataCenterGuestIpv6PrefixDao;
      @Mock
      Ipv6GuestPrefixSubnetNetworkMapDao ipv6GuestPrefixSubnetNetworkMapDao;
      @Mock
      MessageBusBase messageBus;
  
      VlanVO vlan = new VlanVO(Vlan.VlanType.VirtualNetwork, "vlantag", "vlangateway", "vlannetmask", 1L, "iprange", 1L, 1L, null, null, null);
  
      private static final String MAXIMUM_DURATION_ALLOWED = "3600";
      @Mock
      Network network;
      @Mock
      Account account;
  
      private AutoCloseable closeable;
  
      @Before
      public void setup() throws Exception {
          closeable = MockitoAnnotations.openMocks(this);
  
          Account account = new AccountVO("testaccount", 1, "networkdomain", Account.Type.NORMAL, UUID.randomUUID().toString());
          when(configurationMgr._accountMgr.getAccount(anyLong())).thenReturn(account);
          when(configurationMgr._accountDao.findActiveAccount(anyString(), anyLong())).thenReturn(account);
          when(configurationMgr._accountMgr.getActiveAccountById(anyLong())).thenReturn(account);
  
          UserVO user = new UserVO(1, "testuser", "password", "firstname", "lastName", "email", "timezone", UUID.randomUUID().toString(), User.Source.UNKNOWN);
          CallContext.register(user, account);
  
          when(configurationMgr._publicIpAddressDao.countIPs(anyLong(), anyLong(), anyBoolean())).thenReturn(1);
  
          doNothing().when(configurationMgr._resourceLimitMgr).checkResourceLimit(any(Account.class), any(ResourceType.class), anyLong());
  
          when(configurationMgr._accountVlanMapDao.persist(any(AccountVlanMapVO.class))).thenReturn(new AccountVlanMapVO());
  
          when(configurationMgr._vlanDao.acquireInLockTable(anyLong(), anyInt())).thenReturn(vlan);
  
          Field dedicateIdField = _dedicatePublicIpRangeClass.getDeclaredField("id");
          dedicateIdField.setAccessible(true);
          dedicateIdField.set(dedicatePublicIpRangesCmd, 1L);
  
          Field accountNameField = _dedicatePublicIpRangeClass.getDeclaredField("accountName");
          accountNameField.setAccessible(true);
          accountNameField.set(dedicatePublicIpRangesCmd, "accountname");
  
          Field projectIdField = _dedicatePublicIpRangeClass.getDeclaredField("projectId");
          projectIdField.setAccessible(true);
          projectIdField.set(dedicatePublicIpRangesCmd, null);
  
          Field domainIdField = _dedicatePublicIpRangeClass.getDeclaredField("domainId");
          domainIdField.setAccessible(true);
          domainIdField.set(dedicatePublicIpRangesCmd, 1L);
  
          Field releaseIdField = _releasePublicIpRangeClass.getDeclaredField("id");
          releaseIdField.setAccessible(true);
          releaseIdField.set(releasePublicIpRangesCmd, 1L);
      }
  
      @After
      public void tearDown() throws Exception {
          CallContext.unregister();
          closeable.close();
      }
  
      @Test
      public void testDedicatePublicIpRange() throws Exception {
  
          logger.info("Running tests for DedicatePublicIpRange API");
  
          /*
           * TEST 1: given valid parameters DedicatePublicIpRange should succeed
           */
          runDedicatePublicIpRangePostiveTest();
  
          /*
           * TEST 2: given invalid public ip range DedicatePublicIpRange should fail
           */
          runDedicatePublicIpRangeInvalidRange();
          /*
          * TEST 3: given public IP range that is already dedicated to a different account DedicatePublicIpRange should fail
          */
          runDedicatePublicIpRangeDedicatedRange();
  
          /*
          * TEST 4: given zone is of type Basic DedicatePublicIpRange should fail
          */
          runDedicatePublicIpRangeInvalidZone();
  
          /*
           * TEST 5: given range is already allocated to a different account DedicatePublicIpRange should fail
           */
          runDedicatePublicIpRangeIPAddressAllocated();
      }
  
      @Test
      public void testReleasePublicIpRange() throws Exception {
  
          logger.info("Running tests for DedicatePublicIpRange API");
  
          /*
           * TEST 1: given valid parameters and no allocated public ip's in the range ReleasePublicIpRange should succeed
           */
          runReleasePublicIpRangePostiveTest1();
  
          /*
           * TEST 2: given valid parameters ReleasePublicIpRange should succeed
           */
          runReleasePublicIpRangePostiveTest2();
  
          /*
           * TEST 3: given range doesn't exist
           */
          runReleasePublicIpRangeInvalidIpRange();
  
          /*
           * TEST 4: given range is not dedicated to any account
           */
          runReleaseNonDedicatedPublicIpRange();
      }
  
      void runDedicatePublicIpRangePostiveTest() throws Exception {
          TransactionLegacy txn = TransactionLegacy.open("runDedicatePublicIpRangePostiveTest");
  
          when(configurationMgr._vlanDao.findById(anyLong())).thenReturn(vlan);
  
          when(configurationMgr._accountVlanMapDao.listAccountVlanMapsByAccount(anyLong())).thenReturn(null);
  
          DataCenterVO dc = new DataCenterVO(UUID.randomUUID().toString(), "test", "8.8.8.8", null, "10.0.0.1", null, "10.0.0.1/24", null, null, NetworkType.Advanced, null, null,
                  true, true, null, null);
          when(configurationMgr._zoneDao.findById(anyLong())).thenReturn(dc);
  
          List<IPAddressVO> ipAddressList = new ArrayList<IPAddressVO>();
          IPAddressVO ipAddress = new IPAddressVO(new Ip("75.75.75.75"), 1, 0xaabbccddeeffL, 10, false);
          ipAddressList.add(ipAddress);
          when(configurationMgr._publicIpAddressDao.listByVlanId(anyLong())).thenReturn(ipAddressList);
  
          try {
              Vlan result = configurationMgr.dedicatePublicIpRange(dedicatePublicIpRangesCmd);
              Assert.assertNotNull(result);
          } catch (Exception e) {
              logger.info("exception in testing runDedicatePublicIpRangePostiveTest message: " + e.toString());
          } finally {
              txn.close("runDedicatePublicIpRangePostiveTest");
          }
      }
  
      void runDedicatePublicIpRangeInvalidRange() throws Exception {
          TransactionLegacy txn = TransactionLegacy.open("runDedicatePublicIpRangeInvalidRange");
  
          when(configurationMgr._vlanDao.findById(anyLong())).thenReturn(null);
          try {
              configurationMgr.dedicatePublicIpRange(dedicatePublicIpRangesCmd);
          } catch (Exception e) {
              assertTrue(e.getMessage().contains("Unable to find vlan by id"));
          } finally {
              txn.close("runDedicatePublicIpRangeInvalidRange");
          }
      }
  
      void runDedicatePublicIpRangeDedicatedRange() throws Exception {
          TransactionLegacy txn = TransactionLegacy.open("runDedicatePublicIpRangeDedicatedRange");
  
          when(configurationMgr._vlanDao.findById(anyLong())).thenReturn(vlan);
  
          // public ip range is already dedicated
          List<AccountVlanMapVO> accountVlanMaps = new ArrayList<AccountVlanMapVO>();
          AccountVlanMapVO accountVlanMap = new AccountVlanMapVO(1, 1);
          accountVlanMaps.add(accountVlanMap);
          when(configurationMgr._accountVlanMapDao.listAccountVlanMapsByVlan(anyLong())).thenReturn(accountVlanMaps);
  
          DataCenterVO dc = new DataCenterVO(UUID.randomUUID().toString(), "test", "8.8.8.8", null, "10.0.0.1", null, "10.0.0.1/24", null, null, NetworkType.Advanced, null, null,
                  true, true, null, null);
          when(configurationMgr._zoneDao.findById(anyLong())).thenReturn(dc);
  
          List<IPAddressVO> ipAddressList = new ArrayList<IPAddressVO>();
          IPAddressVO ipAddress = new IPAddressVO(new Ip("75.75.75.75"), 1, 0xaabbccddeeffL, 10, false);
          ipAddressList.add(ipAddress);
          when(configurationMgr._publicIpAddressDao.listByVlanId(anyLong())).thenReturn(ipAddressList);
  
          try {
              configurationMgr.dedicatePublicIpRange(dedicatePublicIpRangesCmd);
          } catch (Exception e) {
              assertTrue(e.getMessage().contains("Public IP range has already been dedicated"));
          } finally {
              txn.close("runDedicatePublicIpRangePublicIpRangeDedicated");
          }
      }
  
      void runDedicatePublicIpRangeInvalidZone() throws Exception {
          TransactionLegacy txn = TransactionLegacy.open("runDedicatePublicIpRangeInvalidZone");
  
          when(configurationMgr._vlanDao.findById(anyLong())).thenReturn(vlan);
  
          when(configurationMgr._accountVlanMapDao.listAccountVlanMapsByVlan(anyLong())).thenReturn(null);
  
          // public ip range belongs to zone of type basic
          DataCenterVO dc = new DataCenterVO(UUID.randomUUID().toString(), "test", "8.8.8.8", null, "10.0.0.1", null, "10.0.0.1/24", null, null, NetworkType.Basic, null, null, true,
                  true, null, null);
          when(configurationMgr._zoneDao.findById(anyLong())).thenReturn(dc);
  
          List<IPAddressVO> ipAddressList = new ArrayList<IPAddressVO>();
          IPAddressVO ipAddress = new IPAddressVO(new Ip("75.75.75.75"), 1, 0xaabbccddeeffL, 10, false);
          ipAddressList.add(ipAddress);
          when(configurationMgr._publicIpAddressDao.listByVlanId(anyLong())).thenReturn(ipAddressList);
  
          try {
              configurationMgr.dedicatePublicIpRange(dedicatePublicIpRangesCmd);
          } catch (Exception e) {
              assertTrue(e.getMessage().contains("Public IP range can be dedicated to an account only in the zone of type Advanced"));
          } finally {
              txn.close("runDedicatePublicIpRangeInvalidZone");
          }
      }
  
      void runDedicatePublicIpRangeIPAddressAllocated() throws Exception {
          TransactionLegacy txn = TransactionLegacy.open("runDedicatePublicIpRangeIPAddressAllocated");
  
          when(configurationMgr._vlanDao.findById(anyLong())).thenReturn(vlan);
  
          when(configurationMgr._accountVlanMapDao.listAccountVlanMapsByAccount(anyLong())).thenReturn(null);
  
          DataCenterVO dc = new DataCenterVO(UUID.randomUUID().toString(), "test", "8.8.8.8", null, "10.0.0.1", null, "10.0.0.1/24", null, null, NetworkType.Advanced, null, null,
                  true, true, null, null);
          when(configurationMgr._zoneDao.findById(anyLong())).thenReturn(dc);
  
          // one of the ip addresses of the range is allocated to different account
          List<IPAddressVO> ipAddressList = new ArrayList<IPAddressVO>();
          IPAddressVO ipAddress = new IPAddressVO(new Ip("75.75.75.75"), 1, 0xaabbccddeeffL, 10, false);
          ipAddress.setAllocatedToAccountId(1L);
          ipAddressList.add(ipAddress);
          when(configurationMgr._publicIpAddressDao.listByVlanId(anyLong())).thenReturn(ipAddressList);
  
          try {
              configurationMgr.dedicatePublicIpRange(dedicatePublicIpRangesCmd);
          } catch (Exception e) {
              assertTrue(e.getMessage().contains("Public IP address in range is allocated to another account"));
          } finally {
              txn.close("runDedicatePublicIpRangeIPAddressAllocated");
          }
      }
  
      void runReleasePublicIpRangePostiveTest1() throws Exception {
          TransactionLegacy txn = TransactionLegacy.open("runReleasePublicIpRangePostiveTest1");
  
          when(configurationMgr._vlanDao.findById(anyLong())).thenReturn(vlan);
  
          List<AccountVlanMapVO> accountVlanMaps = new ArrayList<AccountVlanMapVO>();
          AccountVlanMapVO accountVlanMap = new AccountVlanMapVO(1, 1);
          accountVlanMaps.add(accountVlanMap);
          when(configurationMgr._accountVlanMapDao.listAccountVlanMapsByVlan(anyLong())).thenReturn(accountVlanMaps);
  
          // no allocated ip's
          when(configurationMgr._publicIpAddressDao.countIPs(anyLong(), anyLong(), anyBoolean())).thenReturn(0);
  
          when(configurationMgr._accountVlanMapDao.remove(anyLong())).thenReturn(true);
          try {
              Boolean result = configurationMgr.releasePublicIpRange(releasePublicIpRangesCmd);
              assertTrue(result);
          } catch (Exception e) {
              logger.info("exception in testing runReleasePublicIpRangePostiveTest1 message: " + e.toString());
          } finally {
              txn.close("runReleasePublicIpRangePostiveTest1");
          }
      }
  
      void runReleasePublicIpRangePostiveTest2() throws Exception {
          TransactionLegacy txn = TransactionLegacy.open("runReleasePublicIpRangePostiveTest2");
  
          when(configurationMgr._vlanDao.findById(anyLong())).thenReturn(vlan);
  
          List<AccountVlanMapVO> accountVlanMaps = new ArrayList<AccountVlanMapVO>();
          AccountVlanMapVO accountVlanMap = new AccountVlanMapVO(1, 1);
          accountVlanMaps.add(accountVlanMap);
          when(configurationMgr._accountVlanMapDao.listAccountVlanMapsByVlan(anyLong())).thenReturn(accountVlanMaps);
  
          when(configurationMgr._publicIpAddressDao.countIPs(anyLong(), anyLong(), anyBoolean())).thenReturn(1);
  
          List<IPAddressVO> ipAddressList = new ArrayList<IPAddressVO>();
          IPAddressVO ipAddress = new IPAddressVO(new Ip("75.75.75.75"), 1, 0xaabbccddeeffL, 10, false);
          ipAddressList.add(ipAddress);
          when(configurationMgr._publicIpAddressDao.listByVlanId(anyLong())).thenReturn(ipAddressList);
  
          when(configurationMgr._firewallDao.countRulesByIpId(anyLong())).thenReturn(0L);
  
          when(configurationMgr._ipAddrMgr.disassociatePublicIpAddress(any(), anyLong(), any(Account.class))).thenReturn(true);
  
          when(configurationMgr._vlanDao.releaseFromLockTable(anyLong())).thenReturn(true);
  
          when(configurationMgr._accountVlanMapDao.remove(anyLong())).thenReturn(true);
          try {
              Boolean result = configurationMgr.releasePublicIpRange(releasePublicIpRangesCmd);
              assertTrue(result);
          } catch (Exception e) {
              logger.info("exception in testing runReleasePublicIpRangePostiveTest2 message: " + e.toString());
          } finally {
              txn.close("runReleasePublicIpRangePostiveTest2");
          }
      }
  
      void runReleasePublicIpRangeInvalidIpRange() throws Exception {
          TransactionLegacy txn = TransactionLegacy.open("runReleasePublicIpRangeInvalidIpRange");
  
          when(configurationMgr._vlanDao.findById(anyLong())).thenReturn(null);
          try {
              configurationMgr.releasePublicIpRange(releasePublicIpRangesCmd);
          } catch (Exception e) {
              assertTrue(e.getMessage().contains("Please specify a valid IP range id"));
          } finally {
              txn.close("runReleasePublicIpRangeInvalidIpRange");
          }
      }
  
      void runReleaseNonDedicatedPublicIpRange() throws Exception {
          TransactionLegacy txn = TransactionLegacy.open("runReleaseNonDedicatedPublicIpRange");
  
          when(configurationMgr._vlanDao.findById(anyLong())).thenReturn(vlan);
  
          when(configurationMgr._accountVlanMapDao.listAccountVlanMapsByVlan(anyLong())).thenReturn(null);
          when(configurationMgr._domainVlanMapDao.listDomainVlanMapsByVlan(anyLong())).thenReturn(null);
          try {
              configurationMgr.releasePublicIpRange(releasePublicIpRangesCmd);
          } catch (Exception e) {
              assertTrue(e.getMessage().contains("as it not dedicated to any domain and any account"));
          } finally {
              txn.close("runReleaseNonDedicatedPublicIpRange");
          }
      }
  
      @Test
      public void searchForNetworkOfferingsTest() {
          NetworkOfferingJoinVO forVpcOfferingJoinVO = new NetworkOfferingJoinVO();
          forVpcOfferingJoinVO.setForVpc(true);
          List<NetworkOfferingJoinVO> offerings = Arrays.asList(new NetworkOfferingJoinVO(), new NetworkOfferingJoinVO(), forVpcOfferingJoinVO);
  
          Mockito.when(networkOfferingJoinDao.createSearchCriteria()).thenReturn(Mockito.mock(SearchCriteria.class));
          Mockito.when(networkOfferingJoinDao.search(Mockito.any(SearchCriteria.class), Mockito.any(Filter.class))).thenReturn(offerings);
  
          ListNetworkOfferingsCmd cmd = Mockito.spy(ListNetworkOfferingsCmd.class);
          Mockito.when(cmd.getPageSize()).thenReturn(10);
  
          assertThat(configurationMgr.searchForNetworkOfferings(cmd).second(), is(3));
  
          Mockito.when(cmd.getForVpc()).thenReturn(Boolean.FALSE);
          assertThat(configurationMgr.searchForNetworkOfferings(cmd).second(), is(2));
      }
  
      @Test
      public void validateEmptySourceNatServiceCapablitiesTest() {
          Map<Capability, String> sourceNatServiceCapabilityMap = new HashMap<>();
  
          configurationMgr.validateSourceNatServiceCapablities(sourceNatServiceCapabilityMap);
      }
  
      @Test
      public void validateInvalidSourceNatTypeForSourceNatServiceCapablitiesTest() {
          Map<Capability, String> sourceNatServiceCapabilityMap = new HashMap<>();
          sourceNatServiceCapabilityMap.put(Capability.SupportedSourceNatTypes, "perDomain");
  
          boolean caught = false;
          try {
              configurationMgr.validateSourceNatServiceCapablities(sourceNatServiceCapabilityMap);
          } catch (InvalidParameterValueException e) {
              assertTrue(e.getMessage(), e.getMessage().contains("Either peraccount or perzone source NAT type can be specified for SupportedSourceNatTypes"));
              caught = true;
          }
          assertTrue("should not be accepted", caught);
      }
  
      @Test
      public void validateInvalidBooleanValueForSourceNatServiceCapablitiesTest() {
          Map<Capability, String> sourceNatServiceCapabilityMap = new HashMap<>();
          sourceNatServiceCapabilityMap.put(Capability.RedundantRouter, "maybe");
  
          boolean caught = false;
          try {
              configurationMgr.validateSourceNatServiceCapablities(sourceNatServiceCapabilityMap);
          } catch (InvalidParameterValueException e) {
              assertTrue(e.getMessage(), e.getMessage().contains("Unknown specified value for RedundantRouter"));
              caught = true;
          }
          assertTrue("should not be accepted", caught);
      }
  
      @Test
      public void validateInvalidCapabilityForSourceNatServiceCapablitiesTest() {
          Map<Capability, String> sourceNatServiceCapabilityMap = new HashMap<>();
          sourceNatServiceCapabilityMap.put(Capability.ElasticIp, "perDomain");
  
          boolean caught = false;
          try {
              configurationMgr.validateSourceNatServiceCapablities(sourceNatServiceCapabilityMap);
          } catch (InvalidParameterValueException e) {
              assertTrue(e.getMessage(), e.getMessage().contains("Only SupportedSourceNatTypes, Network.Capability[name=RedundantRouter] capabilities can be specified for source nat service"));
              caught = true;
          }
          assertTrue("should not be accepted", caught);
      }
  
      @Test
      public void validateEmptyStaticNatServiceCapablitiesTest() {
          Map<Capability, String> staticNatServiceCapabilityMap = new HashMap<>();
  
          configurationMgr.validateStaticNatServiceCapablities(staticNatServiceCapabilityMap);
      }
  
      @Test
      public void validateInvalidStaticNatServiceCapablitiesTest() {
          Map<Capability, String> staticNatServiceCapabilityMap = new HashMap<>();
          staticNatServiceCapabilityMap.put(Capability.AssociatePublicIP, "Frue and Talse");
  
          boolean caught = false;
          try {
              configurationMgr.validateStaticNatServiceCapablities(staticNatServiceCapabilityMap);
          } catch (InvalidParameterValueException e) {
              assertTrue(e.getMessage(), e.getMessage().contains("(frue and talse)"));
              caught = true;
          }
          assertTrue("should not be accepted", caught);
      }
  
      @Test
      public void isRedundantRouter() {
          Set<Network.Provider> providers = new HashSet<>();
          Map<Capability, String> sourceNatServiceCapabilityMap = new HashMap<>();
          sourceNatServiceCapabilityMap.put(Capability.SupportedSourceNatTypes, "peraccount");
          sourceNatServiceCapabilityMap.put(Capability.RedundantRouter, "true");
          assertTrue(configurationMgr.isRedundantRouter(providers, Network.Service.SourceNat, sourceNatServiceCapabilityMap));
      }
  
      @Test
      public void isSharedSourceNat() {
          Map<Network.Service, Set<Network.Provider>> serviceCapabilityMap = new HashMap<>();
          Map<Capability, String> sourceNatServiceCapabilityMap = new HashMap<>();
          sourceNatServiceCapabilityMap.put(Capability.SupportedSourceNatTypes, "perzone");
          assertTrue(configurationMgr.isSharedSourceNat(serviceCapabilityMap, sourceNatServiceCapabilityMap));
      }
  
      @Test
      public void isNotSharedSourceNat() {
          Map<Network.Service, Set<Network.Provider>> serviceCapabilityMap = new HashMap<>();
          Map<Capability, String> sourceNatServiceCapabilityMap = new HashMap<>();
          sourceNatServiceCapabilityMap.put(Capability.SupportedSourceNatTypes, "peraccount");
          assertFalse(configurationMgr.isSharedSourceNat(serviceCapabilityMap, sourceNatServiceCapabilityMap));
      }
  
      @Test
      public void sourceNatCapabilitiesContainValidValues() {
          Map<Capability, String> sourceNatServiceCapabilityMap = new HashMap<>();
          sourceNatServiceCapabilityMap.put(Capability.SupportedSourceNatTypes, "peraccount");
          sourceNatServiceCapabilityMap.put(Capability.RedundantRouter, "True");
  
          assertTrue(configurationMgr.sourceNatCapabilitiesContainValidValues(sourceNatServiceCapabilityMap));
      }
  
      @Test
      public void validateTTStaticNatServiceCapablitiesTest() {
          Map<Capability, String> staticNatServiceCapabilityMap = new HashMap<>();
          staticNatServiceCapabilityMap.put(Capability.AssociatePublicIP, "true and Talse");
          staticNatServiceCapabilityMap.put(Capability.ElasticIp, "True");
  
          configurationMgr.validateStaticNatServiceCapablities(staticNatServiceCapabilityMap);
      }
  
      @Test
      public void validateFTStaticNatServiceCapablitiesTest() {
          Map<Capability, String> staticNatServiceCapabilityMap = new HashMap<>();
          staticNatServiceCapabilityMap.put(Capability.AssociatePublicIP, "false");
          staticNatServiceCapabilityMap.put(Capability.ElasticIp, "True");
  
          configurationMgr.validateStaticNatServiceCapablities(staticNatServiceCapabilityMap);
      }
  
      @Test
      public void validateTFStaticNatServiceCapablitiesTest() {
          Map<Capability, String> staticNatServiceCapabilityMap = new HashMap<>();
          staticNatServiceCapabilityMap.put(Capability.AssociatePublicIP, "true and Talse");
          staticNatServiceCapabilityMap.put(Capability.ElasticIp, "false");
  
          boolean caught = false;
          try {
              configurationMgr.validateStaticNatServiceCapablities(staticNatServiceCapabilityMap);
          } catch (InvalidParameterValueException e) {
              assertTrue(
                      e.getMessage(),
                      e.getMessage().contains(
                          "Capability " + Capability.AssociatePublicIP.getName() + " can only be set when capability " + Capability.ElasticIp.getName() + " is true"));
              caught = true;
          }
          assertTrue("should not be accepted", caught);
      }
  
      @Test
      public void validateFFStaticNatServiceCapablitiesTest() {
          Map<Capability, String> staticNatServiceCapabilityMap = new HashMap<>();
          staticNatServiceCapabilityMap.put(Capability.AssociatePublicIP, "false");
          staticNatServiceCapabilityMap.put(Capability.ElasticIp, "False");
  
          configurationMgr.validateStaticNatServiceCapablities(staticNatServiceCapabilityMap);
      }
  
      public class DedicatePublicIpRangeCmdExtn extends DedicatePublicIpRangeCmd {
          @Override
          public long getEntityOwnerId() {
              return 1;
          }
      }
  
      public class ReleasePublicIpRangeCmdExtn extends ReleasePublicIpRangeCmd {
          @Override
          public long getEntityOwnerId() {
              return 1;
          }
      }
  
      @Test
      public void checkIfPodIsDeletableSuccessTest() {
          HostPodVO hostPodVO = Mockito.mock(HostPodVO.class);
          Mockito.when(hostPodVO.getDataCenterId()).thenReturn(new Random().nextLong());
          Mockito.when(_podDao.findById(anyLong())).thenReturn(hostPodVO);
  
          Mockito.when(_privateIpAddressDao.countIPs(anyLong(), anyLong(), anyBoolean())).thenReturn(0);
          Mockito.when(_volumeDao.findByPod(anyLong())).thenReturn(new ArrayList<VolumeVO>());
          Mockito.when(_hostDao.findByPodId(anyLong())).thenReturn(new ArrayList<HostVO>());
          Mockito.when(_vmInstanceDao.listByPodId(anyLong())).thenReturn(new ArrayList<VMInstanceVO>());
          Mockito.when(_clusterDao.listByPodId(anyLong())).thenReturn(new ArrayList<ClusterVO>());
  
          configurationMgr.checkIfPodIsDeletable(new Random().nextLong());
      }
  
      @Test(expected = CloudRuntimeException.class)
      public void checkIfPodIsDeletableFailureOnPrivateIpAddressTest() {
          HostPodVO hostPodVO = Mockito.mock(HostPodVO.class);
          Mockito.when(hostPodVO.getDataCenterId()).thenReturn(new Random().nextLong());
          Mockito.when(_podDao.findById(anyLong())).thenReturn(hostPodVO);
  
          Mockito.when(_privateIpAddressDao.countIPs(anyLong(), anyLong(), anyBoolean())).thenReturn(1);
          Mockito.when(_volumeDao.findByPod(anyLong())).thenReturn(new ArrayList<VolumeVO>());
          Mockito.when(_hostDao.findByPodId(anyLong())).thenReturn(new ArrayList<HostVO>());
          Mockito.when(_vmInstanceDao.listByPodId(anyLong())).thenReturn(new ArrayList<VMInstanceVO>());
          Mockito.when(_clusterDao.listByPodId(anyLong())).thenReturn(new ArrayList<ClusterVO>());
  
          configurationMgr.checkIfPodIsDeletable(new Random().nextLong());
      }
  
      @Test(expected = CloudRuntimeException.class)
      public void checkIfPodIsDeletableFailureOnVolumeTest() {
          HostPodVO hostPodVO = Mockito.mock(HostPodVO.class);
          Mockito.when(hostPodVO.getDataCenterId()).thenReturn(new Random().nextLong());
          Mockito.when(_podDao.findById(anyLong())).thenReturn(hostPodVO);
  
          VolumeVO volumeVO = Mockito.mock(VolumeVO.class);
          ArrayList<VolumeVO> arrayList = new ArrayList<VolumeVO>();
          arrayList.add(volumeVO);
          Mockito.when(_privateIpAddressDao.countIPs(anyLong(), anyLong(), anyBoolean())).thenReturn(0);
          Mockito.when(_volumeDao.findByPod(anyLong())).thenReturn(arrayList);
          Mockito.when(_hostDao.findByPodId(anyLong())).thenReturn(new ArrayList<HostVO>());
          Mockito.when(_vmInstanceDao.listByPodId(anyLong())).thenReturn(new ArrayList<VMInstanceVO>());
          Mockito.when(_clusterDao.listByPodId(anyLong())).thenReturn(new ArrayList<ClusterVO>());
  
          configurationMgr.checkIfPodIsDeletable(new Random().nextLong());
      }
  
      @Test(expected = CloudRuntimeException.class)
      public void checkIfPodIsDeletableFailureOnHostTest() {
          HostPodVO hostPodVO = Mockito.mock(HostPodVO.class);
          Mockito.when(hostPodVO.getDataCenterId()).thenReturn(new Random().nextLong());
          Mockito.when(_podDao.findById(anyLong())).thenReturn(hostPodVO);
  
          HostVO hostVO = Mockito.mock(HostVO.class);
          ArrayList<HostVO> arrayList = new ArrayList<HostVO>();
          arrayList.add(hostVO);
          Mockito.when(_privateIpAddressDao.countIPs(anyLong(), anyLong(), anyBoolean())).thenReturn(0);
          Mockito.when(_volumeDao.findByPod(anyLong())).thenReturn(new ArrayList<VolumeVO>());
          Mockito.when(_hostDao.findByPodId(anyLong())).thenReturn(arrayList);
          Mockito.when(_vmInstanceDao.listByPodId(anyLong())).thenReturn(new ArrayList<VMInstanceVO>());
          Mockito.when(_clusterDao.listByPodId(anyLong())).thenReturn(new ArrayList<ClusterVO>());
  
          configurationMgr.checkIfPodIsDeletable(new Random().nextLong());
      }
  
      @Test(expected = CloudRuntimeException.class)
      public void checkIfPodIsDeletableFailureOnVmInstanceTest() {
          HostPodVO hostPodVO = Mockito.mock(HostPodVO.class);
          Mockito.when(hostPodVO.getDataCenterId()).thenReturn(new Random().nextLong());
          Mockito.when(_podDao.findById(anyLong())).thenReturn(hostPodVO);
  
          VMInstanceVO vMInstanceVO = Mockito.mock(VMInstanceVO.class);
          ArrayList<VMInstanceVO> arrayList = new ArrayList<VMInstanceVO>();
          arrayList.add(vMInstanceVO);
          Mockito.when(_privateIpAddressDao.countIPs(anyLong(), anyLong(), anyBoolean())).thenReturn(0);
          Mockito.when(_volumeDao.findByPod(anyLong())).thenReturn(new ArrayList<VolumeVO>());
          Mockito.when(_hostDao.findByPodId(anyLong())).thenReturn(new ArrayList<HostVO>());
          Mockito.when(_vmInstanceDao.listByPodId(anyLong())).thenReturn(arrayList);
          Mockito.when(_clusterDao.listByPodId(anyLong())).thenReturn(new ArrayList<ClusterVO>());
  
          configurationMgr.checkIfPodIsDeletable(new Random().nextLong());
      }
  
      @Test(expected = CloudRuntimeException.class)
      public void checkIfPodIsDeletableFailureOnClusterTest() {
          HostPodVO hostPodVO = Mockito.mock(HostPodVO.class);
          Mockito.when(hostPodVO.getDataCenterId()).thenReturn(new Random().nextLong());
          Mockito.when(_podDao.findById(anyLong())).thenReturn(hostPodVO);
  
          ClusterVO clusterVO = Mockito.mock(ClusterVO.class);
          ArrayList<ClusterVO> arrayList = new ArrayList<ClusterVO>();
          arrayList.add(clusterVO);
          Mockito.when(_privateIpAddressDao.countIPs(anyLong(), anyLong(), anyBoolean())).thenReturn(0);
          Mockito.when(_volumeDao.findByPod(anyLong())).thenReturn(new ArrayList<VolumeVO>());
          Mockito.when(_hostDao.findByPodId(anyLong())).thenReturn(new ArrayList<HostVO>());
          Mockito.when(_vmInstanceDao.listByPodId(anyLong())).thenReturn(new ArrayList<VMInstanceVO>());
          Mockito.when(_clusterDao.listByPodId(anyLong())).thenReturn(arrayList);
  
          configurationMgr.checkIfPodIsDeletable(new Random().nextLong());
      }
  
      @Test
      public void checkIfZoneIsDeletableSuccessTest() {
          Mockito.when(_hostDao.listEnabledIdsByDataCenterId(anyLong())).thenReturn(new ArrayList<>());
          Mockito.when(_podDao.listByDataCenterId(anyLong())).thenReturn(new ArrayList<HostPodVO>());
          Mockito.when(_privateIpAddressDao.countIPs(anyLong(), anyBoolean())).thenReturn(0);
          Mockito.when(_publicIpAddressDao.countIPs(anyLong(), anyBoolean())).thenReturn(0);
          Mockito.when(_vmInstanceDao.listByZoneId(anyLong())).thenReturn(new ArrayList<VMInstanceVO>());
          Mockito.when(_volumeDao.findByDc(anyLong())).thenReturn(new ArrayList<VolumeVO>());
          Mockito.when(_physicalNetworkDao.listByZone(anyLong())).thenReturn(new ArrayList<PhysicalNetworkVO>());
          Mockito.when(_imageStoreDao.findByZone(any(ZoneScope.class), anyBoolean())).thenReturn(new ArrayList<ImageStoreVO>());
  
          configurationMgr.checkIfZoneIsDeletable(new Random().nextLong());
      }
  
      @Test(expected = CloudRuntimeException.class)
      public void checkIfZoneIsDeletableFailureOnHostTest() {
          Mockito.when(_hostDao.listEnabledIdsByDataCenterId(anyLong())).thenReturn(List.of(1L));
          Mockito.when(_podDao.listByDataCenterId(anyLong())).thenReturn(new ArrayList<HostPodVO>());
          Mockito.when(_privateIpAddressDao.countIPs(anyLong(), anyBoolean())).thenReturn(0);
          Mockito.when(_publicIpAddressDao.countIPs(anyLong(), anyBoolean())).thenReturn(0);
          Mockito.when(_vmInstanceDao.listByZoneId(anyLong())).thenReturn(new ArrayList<VMInstanceVO>());
          Mockito.when(_volumeDao.findByDc(anyLong())).thenReturn(new ArrayList<VolumeVO>());
          Mockito.when(_physicalNetworkDao.listByZone(anyLong())).thenReturn(new ArrayList<PhysicalNetworkVO>());
          Mockito.when(_imageStoreDao.findByZone(any(ZoneScope.class), anyBoolean())).thenReturn(new ArrayList<ImageStoreVO>());
  
          configurationMgr.checkIfZoneIsDeletable(new Random().nextLong());
      }
  
      @Test(expected = CloudRuntimeException.class)
      public void checkIfZoneIsDeletableFailureOnPodTest() {
          HostPodVO hostPodVO = Mockito.mock(HostPodVO.class);
          ArrayList<HostPodVO> arrayList = new ArrayList<HostPodVO>();
          arrayList.add(hostPodVO);
  
          Mockito.when(_hostDao.listEnabledIdsByDataCenterId(anyLong())).thenReturn(new ArrayList<>());
          Mockito.when(_podDao.listByDataCenterId(anyLong())).thenReturn(arrayList);
          Mockito.when(_privateIpAddressDao.countIPs(anyLong(), anyBoolean())).thenReturn(0);
          Mockito.when(_publicIpAddressDao.countIPs(anyLong(), anyBoolean())).thenReturn(0);
          Mockito.when(_vmInstanceDao.listByZoneId(anyLong())).thenReturn(new ArrayList<VMInstanceVO>());
          Mockito.when(_volumeDao.findByDc(anyLong())).thenReturn(new ArrayList<VolumeVO>());
          Mockito.when(_physicalNetworkDao.listByZone(anyLong())).thenReturn(new ArrayList<PhysicalNetworkVO>());
          Mockito.when(_imageStoreDao.findByZone(any(ZoneScope.class), anyBoolean())).thenReturn(new ArrayList<ImageStoreVO>());
  
          configurationMgr.checkIfZoneIsDeletable(new Random().nextLong());
      }
  
      @Test(expected = CloudRuntimeException.class)
      public void checkIfZoneIsDeletableFailureOnPrivateIpAddressTest() {
          Mockito.when(_hostDao.listEnabledIdsByDataCenterId(anyLong())).thenReturn(new ArrayList<>());
          Mockito.when(_podDao.listByDataCenterId(anyLong())).thenReturn(new ArrayList<HostPodVO>());
          Mockito.when(_privateIpAddressDao.countIPs(anyLong(), anyBoolean())).thenReturn(1);
          Mockito.when(_publicIpAddressDao.countIPs(anyLong(), anyBoolean())).thenReturn(0);
          Mockito.when(_vmInstanceDao.listByZoneId(anyLong())).thenReturn(new ArrayList<VMInstanceVO>());
          Mockito.when(_volumeDao.findByDc(anyLong())).thenReturn(new ArrayList<VolumeVO>());
          Mockito.when(_physicalNetworkDao.listByZone(anyLong())).thenReturn(new ArrayList<PhysicalNetworkVO>());
          Mockito.when(_imageStoreDao.findByZone(any(ZoneScope.class), anyBoolean())).thenReturn(new ArrayList<ImageStoreVO>());
  
          configurationMgr.checkIfZoneIsDeletable(new Random().nextLong());
      }
  
      @Test(expected = CloudRuntimeException.class)
      public void checkIfZoneIsDeletableFailureOnPublicIpAddressTest() {
          Mockito.when(_hostDao.listEnabledIdsByDataCenterId(anyLong())).thenReturn(new ArrayList<>());
          Mockito.when(_podDao.listByDataCenterId(anyLong())).thenReturn(new ArrayList<HostPodVO>());
          Mockito.when(_privateIpAddressDao.countIPs(anyLong(), anyBoolean())).thenReturn(0);
          Mockito.when(_publicIpAddressDao.countIPs(anyLong(), anyBoolean())).thenReturn(1);
          Mockito.when(_vmInstanceDao.listByZoneId(anyLong())).thenReturn(new ArrayList<VMInstanceVO>());
          Mockito.when(_volumeDao.findByDc(anyLong())).thenReturn(new ArrayList<VolumeVO>());
          Mockito.when(_physicalNetworkDao.listByZone(anyLong())).thenReturn(new ArrayList<PhysicalNetworkVO>());
          Mockito.when(_imageStoreDao.findByZone(any(ZoneScope.class), anyBoolean())).thenReturn(new ArrayList<ImageStoreVO>());
  
          configurationMgr.checkIfZoneIsDeletable(new Random().nextLong());
      }
  
      @Test(expected = CloudRuntimeException.class)
      public void checkIfZoneIsDeletableFailureOnVmInstanceTest() {
          VMInstanceVO vMInstanceVO = Mockito.mock(VMInstanceVO.class);
          ArrayList<VMInstanceVO> arrayList = new ArrayList<VMInstanceVO>();
          arrayList.add(vMInstanceVO);
  
          Mockito.when(_hostDao.listEnabledIdsByDataCenterId(anyLong())).thenReturn(new ArrayList<>());
          Mockito.when(_podDao.listByDataCenterId(anyLong())).thenReturn(new ArrayList<HostPodVO>());
          Mockito.when(_privateIpAddressDao.countIPs(anyLong(), anyBoolean())).thenReturn(0);
          Mockito.when(_publicIpAddressDao.countIPs(anyLong(), anyBoolean())).thenReturn(0);
          Mockito.when(_vmInstanceDao.listByZoneId(anyLong())).thenReturn(arrayList);
          Mockito.when(_volumeDao.findByDc(anyLong())).thenReturn(new ArrayList<VolumeVO>());
          Mockito.when(_physicalNetworkDao.listByZone(anyLong())).thenReturn(new ArrayList<PhysicalNetworkVO>());
          Mockito.when(_imageStoreDao.findByZone(any(ZoneScope.class), anyBoolean())).thenReturn(new ArrayList<ImageStoreVO>());
  
          configurationMgr.checkIfZoneIsDeletable(new Random().nextLong());
      }
  
      @Test(expected = CloudRuntimeException.class)
      public void checkIfZoneIsDeletableFailureOnVolumeTest() {
          VolumeVO volumeVO = Mockito.mock(VolumeVO.class);
          ArrayList<VolumeVO> arrayList = new ArrayList<VolumeVO>();
          arrayList.add(volumeVO);
  
          Mockito.when(_hostDao.listEnabledIdsByDataCenterId(anyLong())).thenReturn(new ArrayList<>());
          Mockito.when(_podDao.listByDataCenterId(anyLong())).thenReturn(new ArrayList<HostPodVO>());
          Mockito.when(_privateIpAddressDao.countIPs(anyLong(), anyBoolean())).thenReturn(0);
          Mockito.when(_publicIpAddressDao.countIPs(anyLong(), anyBoolean())).thenReturn(0);
          Mockito.when(_vmInstanceDao.listByZoneId(anyLong())).thenReturn(new ArrayList<VMInstanceVO>());
          Mockito.when(_volumeDao.findByDc(anyLong())).thenReturn(arrayList);
          Mockito.when(_physicalNetworkDao.listByZone(anyLong())).thenReturn(new ArrayList<PhysicalNetworkVO>());
          Mockito.when(_imageStoreDao.findByZone(any(ZoneScope.class), anyBoolean())).thenReturn(new ArrayList<ImageStoreVO>());
  
          configurationMgr.checkIfZoneIsDeletable(new Random().nextLong());
      }
  
      @Test(expected = CloudRuntimeException.class)
      public void checkIfZoneIsDeletableFailureOnPhysicalNetworkTest() {
          PhysicalNetworkVO physicalNetworkVO = Mockito.mock(PhysicalNetworkVO.class);
          ArrayList<PhysicalNetworkVO> arrayList = new ArrayList<PhysicalNetworkVO>();
          arrayList.add(physicalNetworkVO);
  
          Mockito.when(_hostDao.listEnabledIdsByDataCenterId(anyLong())).thenReturn(new ArrayList<>());
          Mockito.when(_podDao.listByDataCenterId(anyLong())).thenReturn(new ArrayList<HostPodVO>());
          Mockito.when(_privateIpAddressDao.countIPs(anyLong(), anyBoolean())).thenReturn(0);
          Mockito.when(_publicIpAddressDao.countIPs(anyLong(), anyBoolean())).thenReturn(0);
          Mockito.when(_vmInstanceDao.listByZoneId(anyLong())).thenReturn(new ArrayList<VMInstanceVO>());
          Mockito.when(_volumeDao.findByDc(anyLong())).thenReturn(new ArrayList<VolumeVO>());
          Mockito.when(_physicalNetworkDao.listByZone(anyLong())).thenReturn(arrayList);
          Mockito.when(_imageStoreDao.findByZone(any(ZoneScope.class), anyBoolean())).thenReturn(new ArrayList<ImageStoreVO>());
  
          configurationMgr.checkIfZoneIsDeletable(new Random().nextLong());
      }
  
      @Test
      public void hasSameSubnetTest() {
          //Ipv4 Test
          boolean result;
          result = configurationMgr.hasSameSubnet(false, null, null, null, null, null, null, false, null, null, null, null, null);
          assertFalse(result);
          try {
              configurationMgr.hasSameSubnet(true, "10.0.0.1", "255.255.255.0", "10.0.0.2", "255.255.255.0", "10.0.0.2", "10.0.0.10", false, null, null, null, null, null);
              Assert.fail();
          } catch (InvalidParameterValueException e) {
              assertEquals(e.getMessage(), "The gateway of the subnet should be unique. The subnet already has a gateway 10.0.0.1");
          }
          try {
              configurationMgr.hasSameSubnet(true, "10.0.0.1", "255.255.0.0", "10.0.0.2", "255.255.255.0", "10.0.0.2", "10.0.0.10", false, null, null, null, null, null);
              Assert.fail();
          } catch (InvalidParameterValueException e){
              assertEquals(e.getMessage(), "The subnet you are trying to add is a subset of the existing subnet having gateway 10.0.0.1 and netmask 255.255.0.0");
          }
          try {
              configurationMgr.hasSameSubnet(true, "10.0.0.1", "255.255.255.0", "10.0.0.2", "255.255.0.0", "10.0.0.2", "10.0.0.10", false, null, null, null, null, null);
              Assert.fail();
          } catch (InvalidParameterValueException e) {
              assertEquals(e.getMessage(), "The subnet you are trying to add is a superset of the existing subnet having gateway 10.0.0.1 and netmask 255.255.255.0");
          }
          result = configurationMgr.hasSameSubnet(true, "10.0.0.1", "255.255.255.0", "10.0.0.1", "255.255.255.0", "10.0.0.2", "10.0.0.10", false, null, null, null, null, null);
          assertTrue(result);
  
          //Ipv6 Test
          Network ipV6Network = mock(Network.class);
          when(ipV6Network.getIp6Gateway()).thenReturn("2001:db8:0:f101::1");
          when(ipV6Network.getIp6Cidr()).thenReturn("2001:db8:0:f101::0/64");
          doThrow(new InvalidParameterValueException("Exception from Mock: startIPv6 is not in ip6cidr indicated network!")).when(configurationMgr._networkModel).checkIp6Parameters("2001:db9:0:f101::2", "2001:db9:0:f101::a", "2001:db8:0:f101::1", "2001:db8:0:f101::0/64");
          doThrow(new InvalidParameterValueException("Exception from Mock: endIPv6 is not in ip6cidr indicated network!")).when(configurationMgr._networkModel).checkIp6Parameters("2001:db8:0:f101::a", "2001:db9:0:f101::2", "2001:db8:0:f101::1", "2001:db8:0:f101::0/64");
          doThrow(new InvalidParameterValueException("ip6Gateway and ip6Cidr should be defined when startIPv6/endIPv6 are passed in")).when(configurationMgr._networkModel).checkIp6Parameters(Mockito.anyString(), Mockito.anyString(), Mockito.isNull(String.class), Mockito.isNull(String.class));
  
          configurationMgr.hasSameSubnet(false, null, null, null, null, null, null, true, "2001:db8:0:f101::1", "2001:db8:0:f101::0/64", "2001:db8:0:f101::2", "2001:db8:0:f101::a", ipV6Network);
          assertTrue(result);
          try {
              configurationMgr.hasSameSubnet(false, null, null, null, null, null, null, true, "2001:db8:0:f101::2", "2001:db8:0:f101::0/64", "2001:db8:0:f101::2", "2001:db8:0:f101::a", ipV6Network);
              Assert.fail();
          } catch (InvalidParameterValueException e){
              assertEquals(e.getMessage(), "The input gateway 2001:db8:0:f101::2 is not same as network gateway 2001:db8:0:f101::1");
          }
          try {
              configurationMgr.hasSameSubnet(false, null, null, null, null, null, null, true, "2001:db8:0:f101::1", "2001:db8:0:f101::0/63", "2001:db8:0:f101::2", "2001:db8:0:f101::a", ipV6Network);
              Assert.fail();
          } catch (InvalidParameterValueException e){
              assertEquals(e.getMessage(), "The input cidr 2001:db8:0:f101::0/63 is not same as network cidr 2001:db8:0:f101::0/64");
          }
  
          try {
              configurationMgr.hasSameSubnet(false, null, null, null, null, null, null, true, "2001:db8:0:f101::1", "2001:db8:0:f101::0/64", "2001:db9:0:f101::2", "2001:db9:0:f101::a", ipV6Network);
              Assert.fail();
          } catch (InvalidParameterValueException e) {
              assertEquals(e.getMessage(), "Exception from Mock: startIPv6 is not in ip6cidr indicated network!");
          }
          try {
              configurationMgr.hasSameSubnet(false, null, null, null, null, null, null, true, "2001:db8:0:f101::1", "2001:db8:0:f101::0/64", "2001:db8:0:f101::a", "2001:db9:0:f101::2", ipV6Network);
              Assert.fail();
          } catch(InvalidParameterValueException e) {
              assertEquals(e.getMessage(), "Exception from Mock: endIPv6 is not in ip6cidr indicated network!");
          }
  
          result = configurationMgr.hasSameSubnet(false, null, null, null, null, null, null, true, null, null, "2001:db8:0:f101::2", "2001:db8:0:f101::a", ipV6Network);
          assertTrue(result);
      }
  
      @Test(expected = CloudRuntimeException.class)
      public void testGetVlanNumberFromUriInvalidParameter() {
          configurationMgr.getVlanNumberFromUri("vlan");
      }
  
      @Test(expected = CloudRuntimeException.class)
      public void testGetVlanNumberFromUriInvalidSintax() {
          configurationMgr.getVlanNumberFromUri("xxx://7");
      }
  
      @Test
      public void testGetVlanNumberFromUriVlan() {
          assertEquals("7", configurationMgr.getVlanNumberFromUri("vlan://7"));
      }
  
      @Test
      public void testGetVlanNumberFromUriUntagged() {
          assertEquals("untagged", configurationMgr.getVlanNumberFromUri("vlan://untagged"));
      }
  
      @Test
      public void validateMaxRateEqualsOrGreaterTestAllGood() {
          configurationMgr.validateMaxRateEqualsOrGreater(1l, 2l, "IOPS Read");
      }
  
      @Test(expected = InvalidParameterValueException.class)
      public void validateMaxRateEqualsOrGreaterTestNormalRateGreaterThanMax() {
          configurationMgr.validateMaxRateEqualsOrGreater(3l, 2l, "IOPS Read");
      }
  
      @Test
      public void validateMaxRateNull() {
          configurationMgr.validateMaxRateEqualsOrGreater(3l, null, "IOPS Read");
      }
  
      @Test
      public void validateNormalRateNull() {
          configurationMgr.validateMaxRateEqualsOrGreater(null, 3l, "IOPS Read");
      }
  
      @Test
      public void validateAllNull() {
          configurationMgr.validateMaxRateEqualsOrGreater(null, 3l, "IOPS Read");
      }
  
      @Test
      public void validateMaximumIopsAndBytesLengthTestAllNull() {
          configurationMgr.validateMaximumIopsAndBytesLength(null, null, null, null);
      }
  
      @Test
      public void validateMaximumIopsAndBytesLengthTestDefaultLengthConfigs() {
          configurationMgr.validateMaximumIopsAndBytesLength(36000l, 36000l, 36000l, 36000l);
      }
  
      @Test
      public void shouldUpdateDiskOfferingTests(){
          assertTrue(configurationMgr.shouldUpdateDiskOffering(Mockito.anyString(), Mockito.anyString(), Mockito.anyInt(), Mockito.anyBoolean(), Mockito.anyString(), Mockito.anyString(), Mockito.any(DiskOffering.State.class)));
          assertTrue(configurationMgr.shouldUpdateDiskOffering(Mockito.anyString(), nullable(String.class), nullable(Integer.class), nullable(Boolean.class), nullable(String.class), nullable(String.class), nullable(DiskOffering.State.class)));
          assertTrue(configurationMgr.shouldUpdateDiskOffering(nullable(String.class), nullable(String.class), nullable(Integer.class), nullable(Boolean.class), nullable(String.class), nullable(String.class), Mockito.any(DiskOffering.State.class)));
          assertTrue(configurationMgr.shouldUpdateDiskOffering(nullable(String.class), Mockito.anyString(), nullable(Integer.class), nullable(Boolean.class), nullable(String.class), nullable(String.class), nullable(DiskOffering.State.class)));
          assertTrue(configurationMgr.shouldUpdateDiskOffering(nullable(String.class), nullable(String.class), Mockito.anyInt(), nullable(Boolean.class), nullable(String.class), nullable(String.class), nullable(DiskOffering.State.class)));
          assertTrue(configurationMgr.shouldUpdateDiskOffering(nullable(String.class), nullable(String.class), nullable(int.class), Mockito.anyBoolean(), nullable(String.class), nullable(String.class), nullable(DiskOffering.State.class)));
          assertTrue(configurationMgr.shouldUpdateDiskOffering(nullable(String.class), nullable(String.class), nullable(int.class), nullable(Boolean.class), Mockito.anyString(), Mockito.anyString(), nullable(DiskOffering.State.class)));
      }
  
      @Test
      public void shouldUpdateDiskOfferingTestFalse(){
          assertFalse(configurationMgr.shouldUpdateDiskOffering(null, null, null, null, null, null, null));
      }
  
      @Test
      public void shouldUpdateIopsRateParametersTestFalse() {
          assertFalse(configurationMgr.shouldUpdateIopsRateParameters(null, null, null, null, null, null));
      }
  
      @Test
      public void shouldUpdateIopsRateParametersTests(){
          assertTrue(configurationMgr.shouldUpdateIopsRateParameters(Mockito.anyLong(), Mockito.anyLong(), Mockito.anyLong(), Mockito.anyLong(), Mockito.anyLong(), Mockito.anyLong()));
          assertTrue(configurationMgr.shouldUpdateIopsRateParameters(nullable(Long.class), Mockito.anyLong(), nullable(Long.class), nullable(Long.class), nullable(Long.class), nullable(Long.class)));
          assertTrue(configurationMgr.shouldUpdateIopsRateParameters(nullable(Long.class), nullable(Long.class), Mockito.anyLong(), nullable(Long.class), nullable(Long.class), nullable(Long.class)));
          assertTrue(configurationMgr.shouldUpdateIopsRateParameters(nullable(Long.class), nullable(Long.class), nullable(Long.class), Mockito.anyLong(), nullable(Long.class), nullable(Long.class)));
          assertTrue(configurationMgr.shouldUpdateIopsRateParameters(nullable(Long.class), nullable(Long.class), nullable(Long.class), nullable(Long.class), Mockito.anyLong(), nullable(Long.class)));
          assertTrue(configurationMgr.shouldUpdateIopsRateParameters(nullable(Long.class), nullable(Long.class), nullable(Long.class), nullable(Long.class), nullable(Long.class), Mockito.anyLong()));
      }
  
      @Test
      public void shouldUpdateBytesRateParametersTestFalse() {
          assertFalse(configurationMgr.shouldUpdateBytesRateParameters(null, null, null, null, null, null));
      }
  
      @Test
      public void shouldUpdateBytesRateParametersTests(){
          assertTrue(configurationMgr.shouldUpdateBytesRateParameters(Mockito.anyLong(), Mockito.anyLong(), Mockito.anyLong(), Mockito.anyLong(), Mockito.anyLong(), Mockito.anyLong()));
          assertTrue(configurationMgr.shouldUpdateBytesRateParameters(nullable(Long.class), Mockito.anyLong(), nullable(Long.class), nullable(Long.class), nullable(Long.class), nullable(Long.class)));
          assertTrue(configurationMgr.shouldUpdateBytesRateParameters(nullable(Long.class), nullable(Long.class), Mockito.anyLong(), nullable(Long.class), nullable(Long.class), nullable(Long.class)));
          assertTrue(configurationMgr.shouldUpdateBytesRateParameters(nullable(Long.class), nullable(Long.class), nullable(Long.class), Mockito.anyLong(), nullable(Long.class), nullable(Long.class)));
          assertTrue(configurationMgr.shouldUpdateBytesRateParameters(nullable(Long.class), nullable(Long.class), nullable(Long.class), nullable(Long.class), Mockito.anyLong(), nullable(Long.class)));
          assertTrue(configurationMgr.shouldUpdateBytesRateParameters(nullable(Long.class), nullable(Long.class), nullable(Long.class), nullable(Long.class), nullable(Long.class), Mockito.anyLong()));
      }
  
      @Test
      public void updateDiskOfferingTagsIfIsNotNullTestWhenTagsIsNull(){
          Mockito.doNothing().when(configurationMgr).updateOfferingTagsIfIsNotNull(null, diskOfferingVOMock);
          this.configurationMgr.updateOfferingTagsIfIsNotNull(null, diskOfferingVOMock);
          Mockito.verify(configurationMgr, Mockito.times(1)).updateOfferingTagsIfIsNotNull(null, diskOfferingVOMock);
      }
      @Test
      public void updateDiskOfferingTagsIfIsNotNullTestWhenTagsIsNotNull(){
          String tags = "tags";
          Mockito.doNothing().when(configurationMgr).updateOfferingTagsIfIsNotNull(tags, diskOfferingVOMock);
          this.configurationMgr.updateOfferingTagsIfIsNotNull(tags, diskOfferingVOMock);
          Mockito.verify(configurationMgr, Mockito.times(1)).updateOfferingTagsIfIsNotNull(tags, diskOfferingVOMock);
      }
  
      @Test (expected = InvalidParameterValueException.class)
      public void updateDiskOfferingTagsWithPrimaryStorageTagsEqualNullTestThrowException(){
          String tags = "tags";
          List<String> storageTagsNull = new ArrayList<>();
          List<StoragePoolVO> pools = new ArrayList<>(Arrays.asList(storagePoolVO));
          List<VolumeVO> volumes = new ArrayList<>(Arrays.asList(volumeVO));
  
          Mockito.when(primaryDataStoreDao.listStoragePoolsWithActiveVolumesByOfferingId(anyLong())).thenReturn(pools);
          Mockito.when(storagePoolTagsDao.getStoragePoolTags(anyLong())).thenReturn(storageTagsNull);
          Mockito.when(diskOfferingDao.findById(anyLong())).thenReturn(diskOfferingVOMock);
          Mockito.when(_volumeDao.findByDiskOfferingId(anyLong())).thenReturn(volumes);
  
          this.configurationMgr.updateOfferingTagsIfIsNotNull(tags, diskOfferingVOMock);
      }
  
      @Test (expected = InvalidParameterValueException.class)
      public void updateDiskOfferingTagsWithPrimaryStorageMissingTagsTestThrowException(){
          String tags = "tag1,tag2";
          List<String> storageTagsWithMissingTag = new ArrayList<>(Arrays.asList("tag1"));
          List<StoragePoolVO> pools = new ArrayList<>(Arrays.asList(storagePoolVO));
          List<VolumeVO> volumes = new ArrayList<>(Arrays.asList(volumeVO));
  
          Mockito.when(primaryDataStoreDao.listStoragePoolsWithActiveVolumesByOfferingId(anyLong())).thenReturn(pools);
          Mockito.when(storagePoolTagsDao.getStoragePoolTags(anyLong())).thenReturn(storageTagsWithMissingTag);
          Mockito.when(diskOfferingDao.findById(anyLong())).thenReturn(diskOfferingVOMock);
          Mockito.when(_volumeDao.findByDiskOfferingId(anyLong())).thenReturn(volumes);
  
          this.configurationMgr.updateOfferingTagsIfIsNotNull(tags, diskOfferingVOMock);
      }
  
      @Test
      public void updateDiskOfferingTagsWithPrimaryStorageWithCorrectTagsTestSuccess(){
          String tags = "tag1,tag2";
          List<StoragePoolVO> pools = new ArrayList<>(Arrays.asList(storagePoolVO));
          List<VolumeVO> volumes = new ArrayList<>(Arrays.asList(volumeVO));
  
          StoragePoolTagVO poolTagMock1 = Mockito.mock(StoragePoolTagVO.class);
          StoragePoolTagVO poolTagMock2 = Mockito.mock(StoragePoolTagVO.class);
          List<StoragePoolTagVO> poolTags = List.of(poolTagMock1, poolTagMock2);
          Mockito.doReturn("tag1").when(poolTagMock1).getTag();
          Mockito.doReturn("tag2").when(poolTagMock2).getTag();
  
          Mockito.when(primaryDataStoreDao.listStoragePoolsWithActiveVolumesByOfferingId(anyLong())).thenReturn(pools);
          Mockito.when(storagePoolTagsDao.findStoragePoolTags(anyLong())).thenReturn(poolTags);
          Mockito.when(diskOfferingDao.findById(anyLong())).thenReturn(diskOfferingVOMock);
          Mockito.when(_volumeDao.findByDiskOfferingId(anyLong())).thenReturn(volumes);
  
          this.configurationMgr.updateOfferingTagsIfIsNotNull(tags, diskOfferingVOMock);
          Mockito.verify(diskOfferingVOMock, Mockito.times(1)).setTags(tags);
      }
  
      @Test(expected = IllegalArgumentException.class)
      public void testInvalidCreateDataCenterGuestIpv6Prefix() {
          CreateGuestNetworkIpv6PrefixCmd cmd = Mockito.mock(CreateGuestNetworkIpv6PrefixCmd.class);
          Mockito.when(cmd.getZoneId()).thenReturn(1L);
          Mockito.when(cmd.getPrefix()).thenReturn("Invalid");
          Mockito.when(_zoneDao.findById(Mockito.anyLong())).thenReturn(Mockito.mock(DataCenterVO.class));
          configurationMgr.createDataCenterGuestIpv6Prefix(cmd);
      }
  
      @Test(expected = InvalidParameterValueException.class)
      public void testWrongCreateDataCenterGuestIpv6Prefix() {
          CreateGuestNetworkIpv6PrefixCmd cmd = Mockito.mock(CreateGuestNetworkIpv6PrefixCmd.class);
          Mockito.when(cmd.getZoneId()).thenReturn(1L);
          Mockito.when(cmd.getPrefix()).thenReturn("fd17:5:8a43:e2a4:c000::/66");
          Mockito.when(_zoneDao.findById(Mockito.anyLong())).thenReturn(Mockito.mock(DataCenterVO.class));
          configurationMgr.createDataCenterGuestIpv6Prefix(cmd);
      }
  
      @Test(expected = InvalidParameterValueException.class)
      public void testConflictingCreateDataCenterGuestIpv6Prefix() {
          CreateGuestNetworkIpv6PrefixCmd cmd = Mockito.mock(CreateGuestNetworkIpv6PrefixCmd.class);
          Mockito.when(cmd.getZoneId()).thenReturn(1L);
          Mockito.when(cmd.getPrefix()).thenReturn("fd17:5:8a43:e2a5::/64");
          Mockito.when(_zoneDao.findById(Mockito.anyLong())).thenReturn(Mockito.mock(DataCenterVO.class));
          DataCenterGuestIpv6PrefixVO prefix = Mockito.mock(DataCenterGuestIpv6PrefixVO.class);
          Mockito.when(prefix.getPrefix()).thenReturn("fd17:5:8a43:e2a4::/62");
          Mockito.when(dataCenterGuestIpv6PrefixDao.listByDataCenterId(Mockito.anyLong())).thenReturn(List.of(prefix));
          configurationMgr.createDataCenterGuestIpv6Prefix(cmd);
      }
  
      @Test
      public void testCreateDataCenterGuestIpv6Prefix() {
          final Long zoneId = 1L;
          final String prefix = "fd17:5:8a43:e2a5::/64";
          CreateGuestNetworkIpv6PrefixCmd cmd = Mockito.mock(CreateGuestNetworkIpv6PrefixCmd.class);
          Mockito.when(cmd.getZoneId()).thenReturn(zoneId);
          Mockito.when(cmd.getPrefix()).thenReturn(prefix);
          Mockito.when(_zoneDao.findById(Mockito.anyLong())).thenReturn(Mockito.mock(DataCenterVO.class));
          Mockito.when(dataCenterGuestIpv6PrefixDao.listByDataCenterId(Mockito.anyLong())).thenReturn(new ArrayList<>());
          final List<DataCenterGuestIpv6PrefixVO> persistedPrefix = new ArrayList<>();
          Mockito.when(dataCenterGuestIpv6PrefixDao.persist(Mockito.any(DataCenterGuestIpv6PrefixVO.class))).thenAnswer((Answer<DataCenterGuestIpv6PrefixVO>) invocation -> {
              DataCenterGuestIpv6PrefixVO prefixVO = (DataCenterGuestIpv6PrefixVO)invocation.getArgument(0);
              persistedPrefix.add(prefixVO);
              return prefixVO;
          });
          configurationMgr.createDataCenterGuestIpv6Prefix(cmd);
          assertEquals(1, persistedPrefix.size());
          DataCenterGuestIpv6PrefixVO prefixVO = persistedPrefix.get(0);
          assertEquals(zoneId, prefixVO.getDataCenterId());
          assertEquals(prefix, prefixVO.getPrefix());
      }
  
      @Test
      public void testListDataCenterGuestIpv6Prefixes() {
          ListGuestNetworkIpv6PrefixesCmd cmd = Mockito.mock(ListGuestNetworkIpv6PrefixesCmd.class);
          Mockito.when(cmd.getId()).thenReturn(1L);
          Mockito.when(cmd.getZoneId()).thenReturn(1L);
          Mockito.when(_zoneDao.findById(Mockito.anyLong())).thenReturn(Mockito.mock(DataCenterVO.class));
          Mockito.when(dataCenterGuestIpv6PrefixDao.findById(Mockito.anyLong())).thenReturn(Mockito.mock(DataCenterGuestIpv6PrefixVO.class));
          Mockito.when(dataCenterGuestIpv6PrefixDao.listByDataCenterId(Mockito.anyLong()))
                  .thenReturn(List.of(Mockito.mock(DataCenterGuestIpv6PrefixVO.class), Mockito.mock(DataCenterGuestIpv6PrefixVO.class)));
          Mockito.when(dataCenterGuestIpv6PrefixDao.listAll())
                  .thenReturn(List.of(Mockito.mock(DataCenterGuestIpv6PrefixVO.class),
                          Mockito.mock(DataCenterGuestIpv6PrefixVO.class),
                          Mockito.mock(DataCenterGuestIpv6PrefixVO.class)));
          List<? extends DataCenterGuestIpv6Prefix> prefixes = configurationMgr.listDataCenterGuestIpv6Prefixes(cmd);
          assertEquals(1, prefixes.size());
          ListGuestNetworkIpv6PrefixesCmd cmd1 = Mockito.mock(ListGuestNetworkIpv6PrefixesCmd.class);
          Mockito.when(cmd1.getId()).thenReturn(null);
          Mockito.when(cmd1.getZoneId()).thenReturn(1L);
          prefixes = configurationMgr.listDataCenterGuestIpv6Prefixes(cmd1);
          assertEquals(2, prefixes.size());
          ListGuestNetworkIpv6PrefixesCmd cmd2 = Mockito.mock(ListGuestNetworkIpv6PrefixesCmd.class);
          Mockito.when(cmd2.getId()).thenReturn(null);
          Mockito.when(cmd2.getZoneId()).thenReturn(null);
          prefixes = configurationMgr.listDataCenterGuestIpv6Prefixes(cmd2);
          assertEquals(3, prefixes.size());
      }
  
      @Test(expected = InvalidParameterValueException.class)
      public void testInvalidDeleteDataCenterGuestIpv6Prefix() {
          DeleteGuestNetworkIpv6PrefixCmd cmd = Mockito.mock(DeleteGuestNetworkIpv6PrefixCmd.class);
          Mockito.when(cmd.getId()).thenReturn(1L);
          Mockito.when(dataCenterGuestIpv6PrefixDao.findById(Mockito.anyLong())).thenReturn(null);
          configurationMgr.deleteDataCenterGuestIpv6Prefix(cmd);
      }
  
      @Test(expected = CloudRuntimeException.class)
      public void testUsedDeleteDataCenterGuestIpv6Prefix() {
          final Long prefixId = 1L;
          DeleteGuestNetworkIpv6PrefixCmd cmd = Mockito.mock(DeleteGuestNetworkIpv6PrefixCmd.class);
          Mockito.when(cmd.getId()).thenReturn(prefixId);
          DataCenterGuestIpv6PrefixVO prefixVO = Mockito.mock(DataCenterGuestIpv6PrefixVO.class);
          Mockito.when(prefixVO.getId()).thenReturn(prefixId);
          Mockito.when(dataCenterGuestIpv6PrefixDao.findById(Mockito.anyLong())).thenReturn(prefixVO);
          Mockito.when(ipv6GuestPrefixSubnetNetworkMapDao.listUsedByPrefix(Mockito.anyLong()))
                  .thenReturn(List.of(Mockito.mock(Ipv6GuestPrefixSubnetNetworkMapVO.class)));
          configurationMgr.deleteDataCenterGuestIpv6Prefix(cmd);
      }
  
      @Test
      public void testDeleteDataCenterGuestIpv6Prefix() {
          final Long prefixId = 1L;
          DeleteGuestNetworkIpv6PrefixCmd cmd = Mockito.mock(DeleteGuestNetworkIpv6PrefixCmd.class);
          Mockito.when(cmd.getId()).thenReturn(prefixId);
          DataCenterGuestIpv6PrefixVO prefixVO = Mockito.mock(DataCenterGuestIpv6PrefixVO.class);
          Mockito.when(prefixVO.getId()).thenReturn(prefixId);
          Mockito.when(dataCenterGuestIpv6PrefixDao.findById(Mockito.anyLong())).thenReturn(prefixVO);
          Mockito.when(ipv6GuestPrefixSubnetNetworkMapDao.listUsedByPrefix(Mockito.anyLong())).thenReturn(new ArrayList<>());
          final List<Long> removedPrefix = new ArrayList<>();
          Mockito.when(dataCenterGuestIpv6PrefixDao.remove(Mockito.anyLong())).thenAnswer((Answer<Boolean>) invocation -> {
              removedPrefix.add(invocation.getArgument(0));
              return true;
          });
          configurationMgr.deleteDataCenterGuestIpv6Prefix(cmd);
          assertEquals(1, removedPrefix.size());
          assertEquals(prefixId, removedPrefix.get(0));
      }
  
      @Test(expected = InvalidParameterValueException.class)
      public void testInvalidNetworkTypeCreateIpv6NetworkOffering() {
          CreateNetworkOfferingCmd cmd = Mockito.mock(CreateNetworkOfferingCmd.class);
          Mockito.when(cmd.getTraffictype()).thenReturn(Networks.TrafficType.Guest.toString());
          Mockito.when(cmd.getGuestIpType()).thenReturn(Network.GuestType.L2.toString());
          Mockito.when(cmd.getInternetProtocol()).thenReturn(NetUtils.InternetProtocol.DualStack.toString());
          configurationMgr.createNetworkOffering(cmd);
      }
  
      @Test(expected = InvalidParameterValueException.class)
      public void testDisabledConfigCreateIpv6NetworkOffering() {
          CreateNetworkOfferingCmd cmd = Mockito.mock(CreateNetworkOfferingCmd.class);
          Mockito.when(cmd.getTraffictype()).thenReturn(Networks.TrafficType.Guest.toString());
          Mockito.when(cmd.getGuestIpType()).thenReturn(Network.GuestType.Isolated.toString());
          Mockito.when(cmd.getInternetProtocol()).thenReturn(NetUtils.InternetProtocol.DualStack.toString());
          configurationMgr.createNetworkOffering(cmd);
      }
  
      @Test(expected = InvalidParameterValueException.class)
      public void testWrongIpv6CreateVlanAndPublicIpRange() {
          CreateVlanIpRangeCmd cmd = Mockito.mock(CreateVlanIpRangeCmd.class);
          Mockito.when(cmd.getIp6Cidr()).thenReturn("fd17:5:8a43:e2a4:c000::/66");
          NetworkVO network = Mockito.mock(NetworkVO.class);
          Mockito.when(_networkDao.findById(Mockito.anyLong())).thenReturn(network);
          try {
              configurationMgr.createVlanAndPublicIpRange(cmd);
          } catch (InsufficientCapacityException | ResourceUnavailableException | ResourceAllocationException e) {
              throw new RuntimeException(e);
          }
      }
  
      private void mockPersistDatacenterForCreateZone() {
          Mockito.when(_zoneDao.persist(Mockito.any(DataCenterVO.class))).thenAnswer((Answer<DataCenterVO>) invocation -> {
              DataCenterVO zone = (DataCenterVO)invocation.getArguments()[0];
              ReflectionTestUtils.setField(zone, "uuid", UUID.randomUUID().toString());
              ReflectionTestUtils.setField(zone, "id", 1L);
              return zone;
          });
      }
  
      @Test
      public void testCreateEdgeZone() {
          CreateZoneCmd cmd = Mockito.mock(CreateZoneCmd.class);
          Mockito.when(cmd.isEdge()).thenReturn(true);
          Mockito.when(cmd.getNetworkType()).thenReturn(NetworkType.Advanced.toString());
          Mockito.when(cmd.getDomainId()).thenReturn(null);
          mockPersistDatacenterForCreateZone();
          DataCenter zone = configurationMgr.createZone(cmd);
          Assert.assertNotNull(zone);
          assertEquals(NetworkType.Advanced, zone.getNetworkType());
          assertEquals(DataCenter.Type.Edge, zone.getType());
      }
  
      @Test
      public void testCreateCoreZone() {
          CreateZoneCmd cmd = Mockito.mock(CreateZoneCmd.class);
          Mockito.when(cmd.isEdge()).thenReturn(false);
          Mockito.when(cmd.getNetworkType()).thenReturn(NetworkType.Advanced.toString());
          Mockito.when(cmd.getDomainId()).thenReturn(null);
          mockPersistDatacenterForCreateZone();
          DataCenter zone = configurationMgr.createZone(cmd);
          Assert.assertNotNull(zone);
          assertEquals(NetworkType.Advanced, zone.getNetworkType());
          assertEquals(DataCenter.Type.Core, zone.getType());
      }
  
      @Test
      public void testCreateBasicZone() {
          CreateZoneCmd cmd = Mockito.mock(CreateZoneCmd.class);
          Mockito.when(cmd.isEdge()).thenReturn(false);
          Mockito.when(cmd.getNetworkType()).thenReturn(NetworkType.Basic.toString());
          Mockito.when(cmd.getDomainId()).thenReturn(null);
          mockPersistDatacenterForCreateZone();
          DataCenter zone = configurationMgr.createZone(cmd);
          Assert.assertNotNull(zone);
          assertEquals(NetworkType.Basic, zone.getNetworkType());
      }
  
      @Test(expected = InvalidParameterValueException.class)
      public void testCreateBasicEdgeZoneFailure() {
          CreateZoneCmd cmd = Mockito.mock(CreateZoneCmd.class);
          Mockito.when(cmd.isEdge()).thenReturn(true);
          Mockito.when(cmd.getNetworkType()).thenReturn(NetworkType.Basic.toString());
          Mockito.when(cmd.getDomainId()).thenReturn(null);
          configurationMgr.createZone(cmd);
      }
  
      @Test
      public void testEditEdgeZone() {
          // editZone should be successful despite no Public network
          final Long zoneId = 1L;
          UpdateZoneCmd cmd = Mockito.mock(UpdateZoneCmd.class);
          Mockito.when(cmd.getId()).thenReturn(zoneId);
          Mockito.when(cmd.getZoneName()).thenReturn("NewName");
          DataCenterVO zone = Mockito.mock(DataCenterVO.class);
          Mockito.when(zone.getNetworkType()).thenReturn(NetworkType.Advanced);
          Mockito.when(zone.getType()).thenReturn(DataCenter.Type.Edge);
          Mockito.when(zone.getId()).thenReturn(zoneId);
          Mockito.when(_zoneDao.findById(Mockito.anyLong())).thenReturn(zone);
          Mockito.when(_networkModel.getDefaultPhysicalNetworkByZoneAndTrafficType(zoneId, Networks.TrafficType.Public)).thenReturn(null);
          Mockito.when(_zoneDao.update(Mockito.anyLong(), Mockito.any(DataCenterVO.class))).thenReturn(true);
          configurationMgr.editZone(cmd);
      }
  
      @Test
      public void testEdgeZoneCreatePod() {
          final long zoneId = 1L;
          DataCenterVO zone = Mockito.mock(DataCenterVO.class);
          Mockito.when(zone.getNetworkType()).thenReturn(NetworkType.Advanced);
          Mockito.when(zone.getType()).thenReturn(DataCenter.Type.Edge);
          Mockito.when(zone.getId()).thenReturn(1L);
          Mockito.when(_zoneDao.findById(Mockito.anyLong())).thenReturn(zone);
          Mockito.when(_configDao.getValue(Config.ControlCidr.key())).thenReturn(Config.ControlCidr.getDefaultValue());
          Mockito.when(_podDao.persist(Mockito.any(HostPodVO.class))).thenAnswer((Answer<HostPodVO>) invocation -> {
              HostPodVO pod = (HostPodVO)invocation.getArguments()[0];
              ReflectionTestUtils.setField(pod, "uuid", UUID.randomUUID().toString());
              ReflectionTestUtils.setField(pod, "id", 1L);
              return pod;
          });
          Mockito.doNothing().when(messageBus).publish(Mockito.any(), Mockito.any(), Mockito.any(), Mockito.any());
          configurationMgr.createPod(zoneId, "TestPod", null, null, null, null, null, null);
      }
  
      @Test
      public void testValidateSpecificConfigurationValues_ValidFormatWithPositiveIntegers() {
          String name = AgentManager.GranularWaitTimeForCommands.toString();
          String validValue = "CopyCommand=120, DeleteCommand= 60";
  
          try {
              configurationMgr.validateSpecificConfigurationValues(name, validValue, String.class);
          } catch (InvalidParameterValueException e) {
              Assert.fail("Exception should not be thrown for a valid command string with positive integers, but there is an error " + e);
          }
      }
  
      @Test
      public void testValidateSpecificConfigurationValues_InvalidFormat() {
          String name = AgentManager.GranularWaitTimeForCommands.toString();
          String invalidValue = "{\"CopyCommand\": 120}";
  
          try {
              configurationMgr.validateSpecificConfigurationValues(name, invalidValue, String.class);
              Assert.fail("Exception should be thrown for an invalid command string.");
          } catch (InvalidParameterValueException e) {
              assertTrue(e.getMessage().contains("does not contain '='."));
          }
      }
  
      @Test
      public void testValidCommandString() {
          final String input = "DhcpEntryCommand=600, SavePasswordCommand=300, VmDataCommand=300";
          final Pair<Boolean, String> result = configurationMgr.validateCommaSeparatedKeyValueConfigWithPositiveIntegerValues(input);
          assertTrue("Expected validation to pass", result.first());
          assertEquals("Expected no error message", "", result.second());
      }
  
      @Test
      public void testInvalidCommandValue() {
          final String input = "DhcpEntryCommand=600, SavePasswordCommand=300, VmDataCommand=invalid";
          final Pair<Boolean, String> result = configurationMgr.validateCommaSeparatedKeyValueConfigWithPositiveIntegerValues(input);
          assertFalse("Expected validation to fail", result.first());
          assertEquals("Expected specific error message",
                  "Validation failed: The value for command 'VmDataCommand' is not a valid integer. Invalid value: invalid",
                  result.second());
      }
  
      @Test
      public void testCommandWithZeroValue() {
          final String input = "DhcpEntryCommand=600, SavePasswordCommand=0, VmDataCommand=300";
          final Pair<Boolean, String> result = configurationMgr.validateCommaSeparatedKeyValueConfigWithPositiveIntegerValues(input);
          assertFalse("Expected validation to fail", result.first());
          assertEquals("Expected specific error message",
                  "Validation failed: The value for command 'SavePasswordCommand' is not greater than 0. Invalid value: 0",
                  result.second());
      }
  
      @Test
      public void testCommandWithNegativeValue() {
          final String input = "DhcpEntryCommand=-100, SavePasswordCommand=300, VmDataCommand=300";
          final Pair<Boolean, String> result = configurationMgr.validateCommaSeparatedKeyValueConfigWithPositiveIntegerValues(input);
          assertFalse("Expected validation to fail", result.first());
          assertEquals("Expected specific error message",
                  "Validation failed: The value for command 'DhcpEntryCommand' is not greater than 0. Invalid value: -100",
                  result.second());
      }
  
      @Test
      public void testInvalidCommandStructure() {
          final String input = "DhcpEntryCommand600, SavePasswordCommand=300, VmDataCommand=300";
          final Pair<Boolean, String> result = configurationMgr.validateCommaSeparatedKeyValueConfigWithPositiveIntegerValues(input);
          assertFalse("Expected validation to fail", result.first());
          assertEquals("Expected specific error message",
                  "Validation failed: Command 'DhcpEntryCommand600' does not contain '='.",
                  result.second());
      }
  }
  