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 org.apache.cloudstack.service;
  
  import com.cloud.dc.VlanDetailsVO;
  import com.cloud.dc.dao.VlanDetailsDao;
  import com.cloud.deploy.DeploymentPlan;
  import com.cloud.exception.InsufficientAddressCapacityException;
  import com.cloud.exception.InsufficientVirtualNetworkCapacityException;
  import com.cloud.network.Network;
  import com.cloud.network.NetworkModel;
  import com.cloud.network.Networks;
  import com.cloud.network.dao.IPAddressDao;
  import com.cloud.network.dao.IPAddressVO;
  import com.cloud.network.vpc.VpcOfferingVO;
  import com.cloud.network.vpc.VpcVO;
  import com.cloud.network.vpc.dao.VpcDao;
  import com.cloud.network.vpc.dao.VpcOfferingDao;
  import com.cloud.network.vpc.dao.VpcOfferingServiceMapDao;
  import com.cloud.offering.NetworkOffering;
  import com.cloud.user.Account;
  import com.cloud.utils.net.Ip;
  import com.cloud.vm.NicProfile;
  import com.cloud.vm.VirtualMachineProfile;
  import org.apache.cloudstack.NsxAnswer;
  import org.apache.cloudstack.agent.api.CreateOrUpdateNsxTier1NatRuleCommand;
  import org.apache.cloudstack.agent.api.NsxCommand;
  import org.apache.cloudstack.api.ApiConstants;
  import org.apache.cloudstack.utils.NsxControllerUtils;
  import org.junit.Assert;
  import org.junit.Before;
  import org.junit.Test;
  import org.junit.runner.RunWith;
  import org.mockito.Mock;
  import org.mockito.Mockito;
  import org.mockito.junit.MockitoJUnitRunner;
  import org.springframework.test.util.ReflectionTestUtils;
  
  import java.util.List;
  
  import static org.mockito.ArgumentMatchers.any;
  import static org.mockito.ArgumentMatchers.anyLong;
  import static org.mockito.ArgumentMatchers.anyString;
  import static org.mockito.ArgumentMatchers.anyBoolean;
  import static org.mockito.ArgumentMatchers.eq;
  import static org.mockito.Mockito.when;
  import static org.mockito.Mockito.verify;
  import static org.mockito.Mockito.times;
  
  @RunWith(MockitoJUnitRunner.class)
  public class NsxPublicNetworkGuruTest {
  
      NetworkOffering offering;
  
      NsxPublicNetworkGuru guru;
      @Mock
      NsxServiceImpl nsxService;
      @Mock
      IPAddressDao ipAddressDao;
      @Mock
      VpcDao vpcDao;
      @Mock
      VlanDetailsDao vlanDetailsDao;
      @Mock
      VpcOfferingServiceMapDao vpcOfferingServiceMapDao;
      @Mock
      VpcOfferingDao vpcOfferingDao;
      @Mock
      NsxControllerUtils nsxControllerUtils;
      @Mock
      NetworkModel networkModel;
  
      @Before
      public void setup() {
          guru = new NsxPublicNetworkGuru();
  
          ReflectionTestUtils.setField(guru, "_ipAddressDao", ipAddressDao);
          ReflectionTestUtils.setField(guru, "vpcDao", vpcDao);
          ReflectionTestUtils.setField(guru, "vlanDetailsDao", vlanDetailsDao);
          ReflectionTestUtils.setField(guru, "vpcOfferingServiceMapDao", vpcOfferingServiceMapDao);
          ReflectionTestUtils.setField(guru, "nsxService", nsxService);
          ReflectionTestUtils.setField(guru, "vpcOfferingDao", vpcOfferingDao);
          ReflectionTestUtils.setField(guru, "nsxControllerUtils", nsxControllerUtils);
          ReflectionTestUtils.setField(guru, "networkModel", networkModel);
  
          offering = Mockito.mock(NetworkOffering.class);
          when(offering.getTrafficType()).thenReturn(Networks.TrafficType.Public);
          when(offering.isSystemOnly()).thenReturn(true);
          when(networkModel.isProviderForNetworkOffering(eq(Network.Provider.Nsx), anyLong())).thenReturn(true);
      }
  
      @Test
      public void testCanHandle() {
          Assert.assertTrue(guru.canHandle(offering));
      }
  
      @Test
      public void testCannotHandle() {
          NetworkOffering offering = Mockito.mock(NetworkOffering.class);
  
          when(offering.getTrafficType()).thenReturn(Networks.TrafficType.Guest);
  
          Assert.assertFalse(guru.canHandle(offering));
      }
  
      @Test
      public void testDesign() {
          DeploymentPlan plan = Mockito.mock(DeploymentPlan.class);
          Network network = Mockito.mock(Network.class);
          Account account = Mockito.mock(Account.class);
  
  //        when(network.getTrafficType()).thenReturn(Networks.TrafficType.Public);
  
          Network designedNetwork = guru.design(offering, plan, network, "net1", 1L, account);
          Assert.assertEquals(Networks.TrafficType.Public, designedNetwork.getTrafficType());
      }
  
      @Test
      public void testDesign_whenOfferingIsForGuestTraffic() {
          DeploymentPlan plan = Mockito.mock(DeploymentPlan.class);
          Network network = Mockito.mock(Network.class);
          Account account = Mockito.mock(Account.class);
  
          when(offering.getTrafficType()).thenReturn(Networks.TrafficType.Guest);
  
          Network designedNetwork = guru.design(offering, plan, network, "net1", 1L, account);
          Assert.assertNull(designedNetwork);
      }
  
      @Test
      public void testAllocate() throws InsufficientVirtualNetworkCapacityException, InsufficientAddressCapacityException {
          String publicIpVR = "10.1.12.10";
          String publicIpNSX = "10.1.13.10";
          Network network = Mockito.mock(Network.class);
          NicProfile profile = Mockito.mock(NicProfile.class);
          VirtualMachineProfile vmProfile = Mockito.mock(VirtualMachineProfile.class);
          IPAddressVO srcNatIpOnVR = new IPAddressVO(new Ip(publicIpVR), 2L , 0xaabbccddeeffL, 2L, true);
          srcNatIpOnVR.setVpcId(12L);
          IPAddressVO srcNatIpOnNSX = new IPAddressVO(new Ip(publicIpNSX), 2L , 0xaabbccddeeffL, 3L, true);
          srcNatIpOnNSX.setVpcId(12L);
          VpcVO vpcVO = Mockito.mock(VpcVO.class);
          List<IPAddressVO> sourceNatList = List.of(srcNatIpOnNSX);
          VlanDetailsVO vlanDetailVO = new VlanDetailsVO(3L,ApiConstants.NSX_DETAIL_KEY, "true", false);
          VpcOfferingVO vpcOffering = Mockito.mock(VpcOfferingVO.class);
  
  
          when(profile.getIPv4Address()).thenReturn(publicIpVR);
          when(ipAddressDao.findByIp(anyString())).thenReturn(srcNatIpOnVR);
          when(vpcDao.findById(anyLong())).thenReturn(vpcVO);
          when(ipAddressDao.listByAssociatedVpc(12L, true)).thenReturn(sourceNatList);
          when(vlanDetailsDao.findDetail(anyLong(), anyString())).thenReturn(vlanDetailVO);
          when(vpcVO.getVpcOfferingId()).thenReturn(12L);
          when(vpcVO.getId()).thenReturn(12L);
          when(vpcVO.getName()).thenReturn("nsxVPCNet");
          when(vpcOfferingServiceMapDao.areServicesSupportedByVpcOffering(anyLong(), any())).thenReturn(true);
          when(nsxService.createVpcNetwork(anyLong(), anyLong(), anyLong(), anyLong(), anyString(), anyBoolean())).thenReturn(true);
          when(vpcOfferingDao.findById(anyLong())).thenReturn(vpcOffering);
          when(vpcOffering.getNetworkMode()).thenReturn(NetworkOffering.NetworkMode.NATTED);
          when(nsxControllerUtils.sendNsxCommand(any(CreateOrUpdateNsxTier1NatRuleCommand.class),
                  anyLong())).thenReturn(new NsxAnswer(new NsxCommand(), true, ""));
  
          guru.allocate(network, profile, vmProfile);
  
          verify(nsxControllerUtils, times(1)).sendNsxCommand(any(CreateOrUpdateNsxTier1NatRuleCommand.class),
                  anyLong());
  
      }
  }
  