Increase code coverage (#54)

* Increase code coverage

* More unit tests

* Remove credentials and mock api client

* NetrisResource tests

* Fix unit test
This commit is contained in:
Nicolas Vazquez 2025-02-28 10:04:10 -03:00 committed by GitHub
parent f5a96e77a5
commit af27e88c82
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 836 additions and 32 deletions

View File

@ -362,7 +362,7 @@ public class NetrisResource implements ServerResource {
boolean result = netrisApiClient.createOrUpdateLbRule(cmd);
if (!result) {
return new NetrisAnswer(cmd, false, String.format("Failed to create Netris LB rule for %s: %s, " +
"for private port: %s and public port: %s", getNetworkType(cmd.isVpc()), cmd.getName(), cmd.getPrivatePort(), cmd.getPublicPort(), cmd.getPublicPort()));
"for private port: %s and public port: %s", getNetworkType(cmd.isVpc()), cmd.getName(), cmd.getPrivatePort(), cmd.getPublicPort()));
}
return new NetrisAnswer(cmd, true, "OK");
}
@ -370,8 +370,7 @@ public class NetrisResource implements ServerResource {
private Answer executeRequest(DeleteNetrisLoadBalancerRuleCommand cmd) {
boolean result = netrisApiClient.deleteLbRule(cmd);
if (!result) {
return new NetrisAnswer(cmd, false, String.format("Failed to delete Netris LB rule for %s: %s, " +
"for private port: %s and public port: %s", getNetworkType(cmd.isVpc()), cmd.getName()));
return new NetrisAnswer(cmd, false, String.format("Failed to delete Netris LB rule for %s: %s", getNetworkType(cmd.isVpc()), cmd.getName()));
}
return new NetrisAnswer(cmd, true, "OK");
}

View File

@ -139,11 +139,11 @@ public class NetrisApiClientImpl implements NetrisApiClient {
private static final String ANY_IP = "0.0.0.0/0";
private static final String[] PROTOCOL_LIST = new String[]{"TCP", "UDP", "ICMP", "ALL"};
private static ApiClient apiClient;
protected ApiClient apiClient;
private final int siteId;
protected final int siteId;
private final String siteName;
private final int tenantId;
protected final int tenantId;
private final String tenantName;
public NetrisApiClientImpl(String endpointBaseUrl, String username, String password, String siteName, String adminTenantName) {

View File

@ -159,7 +159,7 @@ public class NetrisElement extends AdapterBase implements DhcpServiceProvider, D
return counterList;
}
private static Map<Network.Service, Map<Network.Capability, String>> initCapabilities() {
protected static Map<Network.Service, Map<Network.Capability, String>> initCapabilities() {
Map<Network.Service, Map<Network.Capability, String>> capabilities = new HashMap<>();
Map<Network.Capability, String> dhcpCapabilities = Map.of(Network.Capability.DhcpAccrossMultipleSubnets, "true");

View File

@ -16,6 +16,7 @@
// under the License.
package org.apache.cloudstack.resource;
import org.apache.cloudstack.agent.api.CreateNetrisVnetCommand;
import org.apache.cloudstack.agent.api.CreateNetrisVpcCommand;
import org.apache.cloudstack.agent.api.CreateOrUpdateNetrisNatCommand;
import org.apache.cloudstack.agent.api.DeleteNetrisVpcCommand;
@ -28,7 +29,7 @@ public class NetrisResourceObjectUtilsTest {
private static final long accountId = 2;
private static final long domainId = 2;
private static final long vpcId = 10;
private static final long vpcId = 8;
private static final String vpcName = "testVpc";
private static final String vpcCidr = "10.10.0.0/16";
@ -40,6 +41,14 @@ public class NetrisResourceObjectUtilsTest {
Assert.assertEquals(expectedNetrisVpcName, netrisVpcName);
}
@Test
public void testCreateVpcNameWithSuffix() {
CreateNetrisVpcCommand cmd = new CreateNetrisVpcCommand(zoneId, accountId, domainId, vpcName, vpcCidr, vpcId, true);
String netrisVpcName = NetrisResourceObjectUtils.retrieveNetrisResourceObjectName(cmd, NetrisResourceObjectUtils.NetrisObjectType.VPC, String.valueOf(vpcId));
String expectedNetrisVpcName = String.format("D%s-A%s-Z%s-V%s", domainId, accountId, zoneId, vpcId);
Assert.assertEquals(expectedNetrisVpcName, netrisVpcName);
}
@Test
public void testCreateVpcIpamAllocationName() {
CreateNetrisVpcCommand cmd = new CreateNetrisVpcCommand(zoneId, accountId, domainId, vpcName, vpcCidr, vpcId, true);
@ -66,4 +75,24 @@ public class NetrisResourceObjectUtilsTest {
String expectedNetrisRuleName = String.format("D%s-A%s-Z%s-V%s-DNAT-R%s", domainId, accountId, zoneId, vpcId, ruleId);
Assert.assertEquals(expectedNetrisRuleName, ruleName);
}
@Test
public void testSubnetName() {
String vNetName = "<NETRIS_VNET_NAME>";
Long vpcTierNetworkId = 240L;
String vpcTierNetworkCidr = "10.10.30.0/24";
String vpcTierNetworkGateway = "10.10.30.1";
CreateNetrisVnetCommand cmd = new CreateNetrisVnetCommand(zoneId, accountId, domainId, vpcName, vpcId, vNetName, vpcTierNetworkId, vpcTierNetworkCidr, vpcTierNetworkGateway, true);
String subnetName = NetrisResourceObjectUtils.retrieveNetrisResourceObjectName(cmd, NetrisResourceObjectUtils.NetrisObjectType.IPAM_SUBNET, String.valueOf(vpcId), vpcTierNetworkCidr);
String expectedName = String.format("D%s-A%s-Z%s-V%s-%s", domainId, accountId, zoneId, vpcId, vpcTierNetworkCidr);
Assert.assertEquals(expectedName, subnetName);
}
@Test
public void testSourceNatName() {
CreateOrUpdateNetrisNatCommand cmd = new CreateOrUpdateNetrisNatCommand(zoneId, accountId, domainId, vpcName, vpcId, null, null, true, vpcCidr);
String snatRuleName = NetrisResourceObjectUtils.retrieveNetrisResourceObjectName(cmd, NetrisResourceObjectUtils.NetrisObjectType.SNAT, String.valueOf(vpcId));
String expectedName = String.format("D%s-A%s-Z%s-V%s-SNAT", domainId, accountId, zoneId, vpcId);
Assert.assertEquals(expectedName, snatRuleName);
}
}

View File

@ -0,0 +1,141 @@
// 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.resource;
import com.cloud.agent.api.Answer;
import com.cloud.agent.api.Command;
import org.apache.cloudstack.agent.api.AddOrUpdateNetrisStaticRouteCommand;
import org.apache.cloudstack.agent.api.CreateNetrisACLCommand;
import org.apache.cloudstack.agent.api.CreateNetrisVnetCommand;
import org.apache.cloudstack.agent.api.CreateNetrisVpcCommand;
import org.apache.cloudstack.agent.api.CreateOrUpdateNetrisLoadBalancerRuleCommand;
import org.apache.cloudstack.agent.api.DeleteNetrisACLCommand;
import org.apache.cloudstack.agent.api.DeleteNetrisLoadBalancerRuleCommand;
import org.apache.cloudstack.agent.api.DeleteNetrisNatRuleCommand;
import org.apache.cloudstack.agent.api.DeleteNetrisStaticRouteCommand;
import org.apache.cloudstack.agent.api.DeleteNetrisVnetCommand;
import org.apache.cloudstack.agent.api.DeleteNetrisVpcCommand;
import org.apache.cloudstack.agent.api.ReleaseNatIpCommand;
import org.apache.cloudstack.agent.api.SetupNetrisPublicRangeCommand;
import org.apache.cloudstack.service.NetrisApiClient;
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 java.util.Arrays;
import java.util.List;
public class NetrisResourceTest {
@Mock
private NetrisApiClient netrisApiClient;
@Spy
@InjectMocks
private NetrisResource netrisResource = new NetrisResource();
private AutoCloseable closeable;
@Mock
private CreateNetrisVpcCommand createNetrisVpcCommand;
@Mock
private CreateNetrisVnetCommand createNetrisVnetCommand;
@Mock
private DeleteNetrisVnetCommand deleteNetrisVnetCommand;
@Mock
private DeleteNetrisVpcCommand deleteNetrisVpcCommand;
@Mock
private SetupNetrisPublicRangeCommand setupNetrisPublicRangeCommand;
@Mock
private DeleteNetrisNatRuleCommand deleteNetrisNatRuleCommand;
@Mock
private CreateNetrisACLCommand createNetrisACLCommand;
@Mock
private DeleteNetrisACLCommand deleteNetrisACLCommand;
@Mock
private AddOrUpdateNetrisStaticRouteCommand addOrUpdateNetrisStaticRouteCommand;
@Mock
private DeleteNetrisStaticRouteCommand deleteNetrisStaticRouteCommand;
@Mock
private ReleaseNatIpCommand releaseNatIpCommand;
@Mock
private CreateOrUpdateNetrisLoadBalancerRuleCommand createOrUpdateNetrisLoadBalancerRuleCommand;
@Mock
private DeleteNetrisLoadBalancerRuleCommand deleteNetrisLoadBalancerRuleCommand;
@Before
public void setup() {
closeable = MockitoAnnotations.openMocks(this);
}
@After
public void tearDown() throws Exception {
closeable.close();
}
@Test
public void testExecuteRequest() {
List<Command> commands = Arrays.asList(createNetrisVpcCommand, createNetrisVnetCommand, deleteNetrisVnetCommand,
deleteNetrisVpcCommand, setupNetrisPublicRangeCommand, deleteNetrisNatRuleCommand, createNetrisACLCommand,
deleteNetrisACLCommand, addOrUpdateNetrisStaticRouteCommand, deleteNetrisStaticRouteCommand,
releaseNatIpCommand, createOrUpdateNetrisLoadBalancerRuleCommand, deleteNetrisLoadBalancerRuleCommand);
for (boolean res : new boolean[]{true, false}) {
setMocksToValue(res);
for (Command command : commands) {
Answer answer = netrisResource.executeRequest(command);
Assert.assertEquals(res, answer.getResult());
}
}
Mockito.verify(netrisApiClient, Mockito.times(2)).createVpc(createNetrisVpcCommand);
Mockito.verify(netrisApiClient, Mockito.times(2)).createVnet(createNetrisVnetCommand);
Mockito.verify(netrisApiClient, Mockito.times(2)).deleteVnet(deleteNetrisVnetCommand);
Mockito.verify(netrisApiClient, Mockito.times(2)).deleteVpc(deleteNetrisVpcCommand);
Mockito.verify(netrisApiClient, Mockito.times(2)).setupZoneLevelPublicRange(setupNetrisPublicRangeCommand);
Mockito.verify(netrisApiClient, Mockito.times(2)).deleteNatRule(deleteNetrisNatRuleCommand);
Mockito.verify(netrisApiClient, Mockito.times(2)).addAclRule(createNetrisACLCommand);
Mockito.verify(netrisApiClient, Mockito.times(2)).deleteAclRule(deleteNetrisACLCommand);
Mockito.verify(netrisApiClient, Mockito.times(2)).addOrUpdateStaticRoute(addOrUpdateNetrisStaticRouteCommand);
Mockito.verify(netrisApiClient, Mockito.times(2)).deleteStaticRoute(deleteNetrisStaticRouteCommand);
Mockito.verify(netrisApiClient, Mockito.times(2)).releaseNatIp(releaseNatIpCommand);
Mockito.verify(netrisApiClient, Mockito.times(2)).createOrUpdateLbRule(createOrUpdateNetrisLoadBalancerRuleCommand);
Mockito.verify(netrisApiClient, Mockito.times(2)).deleteLbRule(deleteNetrisLoadBalancerRuleCommand);
}
private void setMocksToValue(boolean value) {
Mockito.when(netrisApiClient.createVpc(createNetrisVpcCommand)).thenReturn(value);
Mockito.when(netrisApiClient.createVnet(createNetrisVnetCommand)).thenReturn(value);
Mockito.when(netrisApiClient.deleteVnet(deleteNetrisVnetCommand)).thenReturn(value);
Mockito.when(netrisApiClient.deleteVpc(deleteNetrisVpcCommand)).thenReturn(value);
Mockito.when(netrisApiClient.setupZoneLevelPublicRange(setupNetrisPublicRangeCommand)).thenReturn(value);
Mockito.when(netrisApiClient.deleteNatRule(deleteNetrisNatRuleCommand)).thenReturn(value);
Mockito.when(netrisApiClient.addAclRule(createNetrisACLCommand)).thenReturn(value);
Mockito.when(netrisApiClient.deleteAclRule(deleteNetrisACLCommand)).thenReturn(value);
Mockito.when(netrisApiClient.addOrUpdateStaticRoute(addOrUpdateNetrisStaticRouteCommand)).thenReturn(value);
Mockito.when(netrisApiClient.deleteStaticRoute(deleteNetrisStaticRouteCommand)).thenReturn(value);
Mockito.when(netrisApiClient.releaseNatIp(releaseNatIpCommand)).thenReturn(value);
Mockito.when(netrisApiClient.createOrUpdateLbRule(createOrUpdateNetrisLoadBalancerRuleCommand)).thenReturn(value);
Mockito.when(netrisApiClient.deleteLbRule(deleteNetrisLoadBalancerRuleCommand)).thenReturn(value);
}
}

View File

@ -16,45 +16,88 @@
// under the License.
package org.apache.cloudstack.service;
import io.netris.ApiException;
import io.netris.ApiClient;
import io.netris.ApiResponse;
import io.netris.api.v1.AuthenticationApi;
import io.netris.api.v1.SitesApi;
import io.netris.api.v1.TenantsApi;
import io.netris.model.GetSiteBody;
import io.netris.model.VPCListing;
import io.netris.model.SitesResponseOK;
import io.netris.model.response.AuthResponse;
import io.netris.model.response.TenantResponse;
import io.netris.model.response.TenantsResponse;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.mockito.InjectMocks;
import org.mockito.MockedConstruction;
import org.mockito.Mockito;
import org.mockito.Spy;
import java.math.BigDecimal;
import java.util.List;
public class NetrisApiClientImplTest {
private static final String endpointUrl = "https://shapeblue-ctl.netris.dev";
private static final String username = "netris";
private static final String password = "qHHa$CZ2oJv*@!7mwoSR";
private static final String endpointUrl = "https://my-netris-controller.localdomain";
private static final String username = "user";
private static final String password = "password";
private static final String siteName = "Datacenter-1";
private static final String adminTenantName = "Admin";
private static final int siteId = 1;
private static final int adminTenantId = 1;
private static final NetrisApiClientImpl client = new NetrisApiClientImpl(endpointUrl, username, password, siteName, adminTenantName);
private MockedConstruction<ApiClient> apiClientMockedConstruction;
@Spy
@InjectMocks
private NetrisApiClientImpl client;
@Before
public void setUp() {
GetSiteBody site = Mockito.mock(GetSiteBody.class);
SitesApi sitesApiMock = Mockito.mock(SitesApi.class);
Mockito.when(site.getName()).thenReturn(siteName);
Mockito.when(site.getId()).thenReturn(siteId);
TenantsApi tenantsApi = Mockito.mock(TenantsApi.class);
TenantResponse tenant = Mockito.mock(TenantResponse.class);
Mockito.when(tenant.getName()).thenReturn(adminTenantName);
Mockito.when(tenant.getId()).thenReturn(new BigDecimal(adminTenantId));
apiClientMockedConstruction = Mockito.mockConstruction(ApiClient.class, (mock, context) -> {
SitesResponseOK sitesResponse = Mockito.mock(SitesResponseOK.class);
Mockito.when(sitesResponse.getData()).thenReturn(List.of(site));
Mockito.when(sitesApiMock.apiSitesGet()).thenReturn(sitesResponse);
Mockito.when(mock.getApiStubForMethod(SitesApi.class)).thenReturn(sitesApiMock);
Mockito.when(mock.getApiStubForMethod(TenantsApi.class)).thenReturn(tenantsApi);
ApiResponse<TenantsResponse> tenantsResponse = Mockito.mock(ApiResponse.class);
Mockito.when(tenantsApi.apiTenantsGet()).thenReturn(tenantsResponse);
TenantsResponse tenantsResponseData = Mockito.mock(TenantsResponse.class);
Mockito.when(tenantsResponseData.getData()).thenReturn(List.of(tenant));
Mockito.when(tenantsResponse.getData()).thenReturn(tenantsResponseData);
AuthenticationApi authenticationApi = Mockito.mock(AuthenticationApi.class);
Mockito.when(mock.getApiStubForMethod(AuthenticationApi.class)).thenReturn(authenticationApi);
ApiResponse<AuthResponse> authResponseApiResponse = Mockito.mock(ApiResponse.class);
Mockito.when(authenticationApi.apiAuthGet()).thenReturn(authResponseApiResponse);
Mockito.when(authResponseApiResponse.getStatusCode()).thenReturn(200);
});
client = new NetrisApiClientImpl(endpointUrl, username, password, siteName, adminTenantName);
}
@After
public void tearDown() {
apiClientMockedConstruction.close();
}
@Test
public void testConstructor() {
Assert.assertEquals(siteId, client.siteId);
Assert.assertEquals(adminTenantId, client.tenantId);
}
@Test
public void testNetrisAuthStatus() {
Assert.assertTrue(client.isSessionAlive());
}
@Test
public void testListSites() {
List<GetSiteBody> sites = client.listSites();
Assert.assertTrue(sites.size() > 0);
}
@Test
public void testListVpcs() {
List<VPCListing> vpcs = client.listVPCs();
Assert.assertTrue(vpcs.size() > 0);
}
@Test
public void testListTenants() throws ApiException {
List<TenantResponse> tenants = client.listTenants();
Assert.assertTrue(tenants.size() > 0);
}
}

View File

@ -0,0 +1,141 @@
// 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.DataCenterVO;
import com.cloud.dc.dao.DataCenterDao;
import com.cloud.domain.DomainVO;
import com.cloud.domain.dao.DomainDao;
import com.cloud.exception.ResourceUnavailableException;
import com.cloud.network.Network;
import com.cloud.network.as.AutoScaleCounter;
import com.cloud.network.as.Counter;
import com.cloud.network.dao.NetworkDao;
import com.cloud.network.dao.NetworkVO;
import com.cloud.network.netris.NetrisService;
import com.cloud.network.vpc.VpcVO;
import com.cloud.network.vpc.dao.VpcDao;
import com.cloud.user.Account;
import com.cloud.user.AccountManager;
import com.cloud.vm.ReservationContext;
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 java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
public class NetrisElementTest {
@Spy
@InjectMocks
private NetrisElement netrisElement = new NetrisElement();;
@Mock
private NetrisService netrisService;
@Mock
private AccountManager accountManager;
@Mock
private NetworkDao networkDao;
@Mock
private DataCenterDao dataCenterDao;
@Mock
private DomainDao domainDao;
@Mock
private VpcDao vpcDao;
private AutoCloseable closeable;
private static long accountId = 2L;
private static long zoneId = 1L;
@Before
public void setup() {
closeable = MockitoAnnotations.openMocks(this);
}
@After
public void tearDown() throws Exception {
closeable.close();
}
@Test
public void testAutoscalingCounterList() {
List<AutoScaleCounter> counters = NetrisElement.getNetrisAutoScaleCounters();
Assert.assertEquals(2, counters.size());
Set<String> counterNamesSet = counters.stream().map(AutoScaleCounter::getName).collect(Collectors.toSet());
Set<String> expected = Set.of(Counter.Source.CPU.name(), Counter.Source.MEMORY.name());
Assert.assertEquals(expected, counterNamesSet);
}
@Test
public void testInitCapabilities() {
Map<Network.Service, Map<Network.Capability, String>> capabilities = NetrisElement.initCapabilities();
Assert.assertTrue(capabilities.containsKey(Network.Service.Dns));
Assert.assertTrue(capabilities.containsKey(Network.Service.Dhcp));
Assert.assertTrue(capabilities.containsKey(Network.Service.SourceNat));
Assert.assertTrue(capabilities.containsKey(Network.Service.StaticNat));
Assert.assertTrue(capabilities.containsKey(Network.Service.Lb));
Assert.assertTrue(capabilities.containsKey(Network.Service.PortForwarding));
Assert.assertTrue(capabilities.containsKey(Network.Service.NetworkACL));
}
@Test
public void testDeleteNetwork() throws ResourceUnavailableException {
long networkId = 210L;
long domainId = 2L;
long vpcId = 8L;
String vpcName = "testVpc";
String networkName = "testVpcTier";
String networkCidr = "10.10.30.0/24";
VpcVO vpc = Mockito.mock(VpcVO.class);
Mockito.when(vpc.getName()).thenReturn(vpcName);
Network network = Mockito.mock(Network.class);
Mockito.when(network.getAccountId()).thenReturn(accountId);
Mockito.when(network.getId()).thenReturn(networkId);
Mockito.when(network.getDataCenterId()).thenReturn(zoneId);
Mockito.when(network.getName()).thenReturn(networkName);
Mockito.when(network.getCidr()).thenReturn(networkCidr);
Mockito.when(network.getVpcId()).thenReturn(vpcId);
Account account = Mockito.mock(Account.class);
Mockito.when(account.getId()).thenReturn(accountId);
Mockito.when(account.getDomainId()).thenReturn(domainId);
NetworkVO networkVO = Mockito.mock(NetworkVO.class);
Mockito.when(networkVO.getName()).thenReturn(networkName);
DataCenterVO dataCenterVO = Mockito.mock(DataCenterVO.class);
Mockito.when(dataCenterVO.getId()).thenReturn(zoneId);
DomainVO domain = Mockito.mock(DomainVO.class);
Mockito.when(domain.getId()).thenReturn(domainId);
Mockito.when(accountManager.getAccount(accountId)).thenReturn(account);
Mockito.when(networkDao.findById(networkId)).thenReturn(networkVO);
Mockito.when(dataCenterDao.findById(zoneId)).thenReturn(dataCenterVO);
Mockito.when(domainDao.findById(domainId)).thenReturn(domain);
Mockito.when(vpcDao.findById(vpcId)).thenReturn(vpc);
ReservationContext context = Mockito.mock(ReservationContext.class);
netrisElement.destroy(network, context);
Mockito.verify(netrisService).deleteVnetResource(zoneId, accountId, domainId, vpcName, vpcId,
networkName, networkId, networkCidr);
}
}

View File

@ -0,0 +1,226 @@
// 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.DataCenter;
import com.cloud.dc.DataCenterVO;
import com.cloud.dc.dao.DataCenterDao;
import com.cloud.deploy.DeployDestination;
import com.cloud.deploy.DeploymentPlan;
import com.cloud.domain.DomainVO;
import com.cloud.domain.dao.DomainDao;
import com.cloud.event.ActionEventUtils;
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.NetworkVO;
import com.cloud.network.dao.PhysicalNetworkDao;
import com.cloud.network.dao.PhysicalNetworkVO;
import com.cloud.network.netris.NetrisService;
import com.cloud.network.vpc.VpcVO;
import com.cloud.network.vpc.dao.VpcDao;
import com.cloud.offering.NetworkOffering;
import com.cloud.offerings.NetworkOfferingVO;
import com.cloud.offerings.dao.NetworkOfferingDao;
import com.cloud.offerings.dao.NetworkOfferingServiceMapDao;
import com.cloud.user.AccountVO;
import com.cloud.user.dao.AccountDao;
import com.cloud.vm.ReservationContext;
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.MockedStatic;
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
import org.mockito.Spy;
import java.util.Arrays;
import java.util.List;
import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.ArgumentMatchers.anyString;
public class NetrisGuestNetworkGuruTest {
@Mock
private NetworkOfferingServiceMapDao networkOfferingServiceMapDao;
@Mock
private PhysicalNetworkDao physicalNetworkDao;
@Mock
private DataCenterDao dataCenterDao;
@Mock
private NetworkModel networkModel;
@Mock
private AccountDao accountDao;
@Mock
private DomainDao domainDao;
@Mock
private NetworkOfferingDao networkOfferingDao;
@Mock
private VpcDao vpcDao;
@Mock
private NetrisService netrisService;
@Spy
@InjectMocks
private NetrisGuestNetworkGuru guru = new NetrisGuestNetworkGuru();
@Mock
private NetworkOfferingVO networkOffering;
@Mock
private PhysicalNetworkVO physicalNetwork;
@Mock
private DeploymentPlan plan;
@Mock
private NetworkVO network;
@Mock
private AccountVO account;
@Mock
private DomainVO domain;
@Mock
private DataCenterVO zone;
@Mock
private VpcVO vpc;
private AutoCloseable closeable;
private MockedStatic<ActionEventUtils> actionEventUtilsMocked;
private static final long networkOfferingId = 10L;
private static final long physicalNetworkId = 2L;
private static final long zoneId = 1L;
private static final long accountId = 2L;
private static final long domainId = 7L;
private static final long vpcId = 12L;
private static final long networkId = 210L;
private static final String networkName = "test-network";
private static final String vpcName = "test-vpc";
private static final String networkCidr = "172.20.10.0/24";
@Before
public void setup() {
closeable = MockitoAnnotations.openMocks(this);
Mockito.when(networkOffering.getId()).thenReturn(networkOfferingId);
Mockito.when(networkOffering.getTrafficType()).thenReturn(Networks.TrafficType.Guest);
Mockito.when(networkOffering.getNetworkMode()).thenReturn(NetworkOffering.NetworkMode.NATTED);
Mockito.when(networkOffering.isRedundantRouter()).thenReturn(false);
Mockito.when(networkOfferingDao.findById(networkOfferingId)).thenReturn(networkOffering);
Mockito.when(physicalNetwork.getIsolationMethods()).thenReturn(List.of("netris"));
Mockito.when(physicalNetworkDao.findById(physicalNetworkId)).thenReturn(physicalNetwork);
Mockito.when(networkOfferingServiceMapDao.isProviderForNetworkOffering(networkOfferingId, Network.Provider.Netris)).thenReturn(true);
Mockito.when(plan.getPhysicalNetworkId()).thenReturn(physicalNetworkId);
Mockito.when(plan.getDataCenterId()).thenReturn(zoneId);
Mockito.when(dataCenterDao.findById(zoneId)).thenReturn(zone);
Mockito.when(zone.getNetworkType()).thenReturn(DataCenter.NetworkType.Advanced);
Mockito.when(zone.getGuestNetworkCidr()).thenReturn("172.20.0.0/16");
Mockito.when(zone.getId()).thenReturn(zoneId);
List<Network.Service> offeringServices = Arrays.asList(Network.Service.Dns, Network.Service.Dhcp,
Network.Service.SourceNat, Network.Service.StaticNat, Network.Service.PortForwarding,
Network.Service.NetworkACL, Network.Service.Vpn);
Mockito.when(networkModel.listNetworkOfferingServices(networkOfferingId)).thenReturn(offeringServices);
Mockito.when(accountDao.findById(accountId)).thenReturn(account);
Mockito.when(account.getDomainId()).thenReturn(domainId);
Mockito.when(account.getId()).thenReturn(accountId);
Mockito.when(domain.getId()).thenReturn(domainId);
Mockito.when(domainDao.findById(domainId)).thenReturn(domain);
Mockito.when(network.getAccountId()).thenReturn(accountId);
Mockito.when(network.getNetworkOfferingId()).thenReturn(networkOfferingId);
Mockito.when(network.getVpcId()).thenReturn(vpcId);
Mockito.when(network.getName()).thenReturn(networkName);
Mockito.when(network.getId()).thenReturn(networkId);
Mockito.when(network.getCidr()).thenReturn(networkCidr);
Mockito.when(network.getGateway()).thenReturn("172.20.10.1");
Mockito.when(network.getDataCenterId()).thenReturn(zoneId);
Mockito.when(network.getPhysicalNetworkId()).thenReturn(physicalNetworkId);
Mockito.when(network.getTrafficType()).thenReturn(Networks.TrafficType.Guest);
Mockito.when(network.getBroadcastDomainType()).thenReturn(Networks.BroadcastDomainType.Netris);
Mockito.when(vpcDao.findById(vpcId)).thenReturn(vpc);
Mockito.when(vpc.getName()).thenReturn(vpcName);
Mockito.when(vpc.getId()).thenReturn(vpcId);
actionEventUtilsMocked = Mockito.mockStatic(ActionEventUtils.class);
Mockito.when(ActionEventUtils.onCompletedActionEvent(anyLong(), anyLong(), anyString(), anyString(), anyString(), anyLong(), anyString(), anyLong())).thenReturn(1L);
}
@After
public void tearDown() throws Exception {
closeable.close();
actionEventUtilsMocked.close();
}
@Test
public void testCanHandleNetrisOfferingNatted() {
Assert.assertTrue(guru.canHandle(networkOffering, DataCenter.NetworkType.Advanced, physicalNetwork));
}
@Test
public void testCanHandleNetrisOfferingRouted() {
Mockito.when(networkOffering.getNetworkMode()).thenReturn(NetworkOffering.NetworkMode.ROUTED);
Assert.assertTrue(guru.canHandle(networkOffering, DataCenter.NetworkType.Advanced, physicalNetwork));
}
@Test
public void testCannotHandleBasicNetwork() {
Assert.assertFalse(guru.canHandle(networkOffering, DataCenter.NetworkType.Basic, physicalNetwork));
}
@Test
public void testCannotHandleVlanIsolation() {
Mockito.when(physicalNetwork.getIsolationMethods()).thenReturn(List.of("vlan"));
Assert.assertFalse(guru.canHandle(networkOffering, DataCenter.NetworkType.Advanced, physicalNetwork));
}
@Test
public void testCannotHandleDifferentOfferingProvider() {
Mockito.when(networkOfferingServiceMapDao.isProviderForNetworkOffering(networkOfferingId, Network.Provider.Netris)).thenReturn(false);
Assert.assertFalse(guru.canHandle(networkOffering, DataCenter.NetworkType.Advanced, physicalNetwork));
}
@Test
public void testDesignNetrisNetwork() {
Network designedNetwork = guru.design(networkOffering, plan, network, networkName, 1L, account);
Assert.assertEquals(Networks.BroadcastDomainType.Netris, designedNetwork.getBroadcastDomainType());
Assert.assertEquals(Network.State.Allocated, designedNetwork.getState());
Assert.assertEquals(Networks.TrafficType.Guest, designedNetwork.getTrafficType());
}
@Test
public void testCreateNetrisVnetVpcNetworkRoutedMode() {
Mockito.when(networkOffering.getNetworkMode()).thenReturn(NetworkOffering.NetworkMode.ROUTED);
Mockito.when(netrisService.createVnetResource(Mockito.anyLong(), Mockito.anyLong(), Mockito.anyLong(),
Mockito.anyString(), Mockito.anyLong(), Mockito.anyString(), Mockito.anyLong(), Mockito.anyString(),
Mockito.anyBoolean())).thenReturn(true);
guru.createNetrisVnet(network, zone);
Mockito.verify(netrisService).createVnetResource(zoneId, accountId, domainId, vpcName, vpcId,
networkName, networkId, networkCidr, true);
}
@Test
public void testImplementNetrisVpcNetwork() throws InsufficientVirtualNetworkCapacityException {
DeployDestination destination = Mockito.mock(DeployDestination.class);
ReservationContext context = Mockito.mock(ReservationContext.class);
String vnet = "1234";
Mockito.when(dataCenterDao.allocateVnet(Mockito.eq(zoneId), Mockito.eq(physicalNetworkId),
Mockito.eq(accountId), Mockito.nullable(String.class), Mockito.anyBoolean())).thenReturn(vnet);
actionEventUtilsMocked.when(() -> ActionEventUtils.onCompletedActionEvent(Mockito.anyLong(), Mockito.anyLong(), Mockito.anyString(), Mockito.anyString(), Mockito.anyString(), Mockito.anyLong(), Mockito.anyString(), Mockito.anyLong())).thenReturn(1L);
Network implemented = guru.implement(network, networkOffering, destination, context);
Assert.assertEquals(String.format("netris://%s", vnet), implemented.getBroadcastUri().toString());
Assert.assertEquals(Network.State.Implemented, implemented.getState());
}
}

View File

@ -0,0 +1,225 @@
// 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.dao.NetworkVO;
import com.cloud.network.netris.NetrisService;
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.offerings.NetworkOfferingVO;
import com.cloud.user.AccountVO;
import com.cloud.utils.exception.CloudRuntimeException;
import com.cloud.utils.net.Ip;
import com.cloud.vm.NicProfile;
import com.cloud.vm.VirtualMachineProfile;
import org.apache.cloudstack.api.ApiConstants;
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 java.util.Arrays;
public class NetrisPublicNetworkGuruTest {
@Mock
private NetworkModel networkModel;
@Mock
private IPAddressDao ipAddressDao;
@Mock
private VpcDao vpcDao;
@Mock
private VlanDetailsDao vlanDetailsDao;
@Mock
private VpcOfferingDao vpcOfferingDao;
@Mock
private VpcOfferingServiceMapDao vpcOfferingServiceMapDao;
@Mock
private NetrisService netrisService;
@Spy
@InjectMocks
private NetrisPublicNetworkGuru guru = new NetrisPublicNetworkGuru();
@Mock
private NetworkOfferingVO networkOffering;
@Mock
private DeploymentPlan deploymentPlan;
@Mock
private NetworkVO network;
@Mock
private AccountVO account;
@Mock
private NicProfile nicProfile;
@Mock
private VirtualMachineProfile virtualMachineProfile;
@Mock
private IPAddressVO ipAddressVpcVR;
@Mock
private IPAddressVO ipAddressVpcSourceNat;
@Mock
private VpcVO vpc;
private AutoCloseable closeable;
private static final long networkOfferingId = 10L;
private static final long physicalNetworkId = 2L;
private static final long zoneId = 1L;
private static final long vpcId = 12L;
private static final String vrNicIp = "10.10.10.10";
private static final String vpcSourceNatIp = "10.10.20.20";
@Before
public void setup() {
closeable = MockitoAnnotations.openMocks(this);
Mockito.when(networkOffering.getId()).thenReturn(networkOfferingId);
Mockito.when(networkOffering.getTrafficType()).thenReturn(Networks.TrafficType.Public);
Mockito.when(networkOffering.isSystemOnly()).thenReturn(true);
Mockito.when(networkModel.isProviderForNetworkOffering(Network.Provider.Netris, networkOfferingId)).thenReturn(true);
Mockito.when(network.getBroadcastDomainType()).thenReturn(Networks.BroadcastDomainType.Netris);
Mockito.when(deploymentPlan.getDataCenterId()).thenReturn(zoneId);
Mockito.when(deploymentPlan.getPhysicalNetworkId()).thenReturn(physicalNetworkId);
Mockito.when(networkOffering.isRedundantRouter()).thenReturn(false);
Mockito.when(nicProfile.getIPv4Address()).thenReturn(vrNicIp);
Mockito.when(ipAddressDao.findByIp(vrNicIp)).thenReturn(ipAddressVpcVR);
Mockito.when(ipAddressVpcVR.getVpcId()).thenReturn(vpcId);
Mockito.when(vpcDao.findById(vpcId)).thenReturn(vpc);
Mockito.when(vpc.getId()).thenReturn(vpcId);
Mockito.when(ipAddressDao.listByAssociatedVpc(vpcId, true))
.thenReturn(Arrays.asList(ipAddressVpcVR, ipAddressVpcSourceNat));
Ip ipMock = Mockito.mock(Ip.class);
Mockito.when(ipMock.addr()).thenReturn(vrNicIp);
Mockito.when(ipAddressVpcVR.getAddress()).thenReturn(ipMock);
Ip ipVrMock = Mockito.mock(Ip.class);
Mockito.when(ipVrMock.addr()).thenReturn(vpcSourceNatIp);
Mockito.when(ipAddressVpcSourceNat.getAddress()).thenReturn(ipVrMock);
Mockito.when(ipAddressVpcSourceNat.isSourceNat()).thenReturn(true);
Mockito.when(ipAddressVpcSourceNat.isForSystemVms()).thenReturn(false);
Mockito.when(ipAddressVpcSourceNat.getVlanId()).thenReturn(4L);
VlanDetailsVO vlanDetailsVO = Mockito.mock(VlanDetailsVO.class);
Mockito.when(vlanDetailsVO.getValue()).thenReturn("true");
Mockito.when(vlanDetailsDao.findDetail(4L, ApiConstants.NETRIS_DETAIL_KEY)).thenReturn(vlanDetailsVO);
}
@After
public void tearDown() throws Exception {
closeable.close();
}
@Test
public void testCanHandleNetrisPublic() {
Assert.assertTrue(guru.canHandle(networkOffering));
}
@Test
public void testCannotHandleNonNetrisPublic() {
Mockito.when(networkModel.isProviderForNetworkOffering(Network.Provider.Netris, networkOfferingId)).thenReturn(false);
Assert.assertFalse(guru.canHandle(networkOffering));
}
@Test
public void testCannotHandleNonPublicTraffic() {
Mockito.when(networkOffering.getTrafficType()).thenReturn(Networks.TrafficType.Guest);
Assert.assertFalse(guru.canHandle(networkOffering));
}
@Test
public void testDesignNetrisNetwork() {
String name = "test-network";
long vpcId = 10L;
Network design = guru.design(networkOffering, deploymentPlan, network, name, vpcId, account);
Assert.assertEquals(Network.State.Setup, design.getState());
Assert.assertEquals(Networks.BroadcastDomainType.Netris, design.getBroadcastDomainType());
}
@Test(expected = CloudRuntimeException.class)
public void testAllocateNetrisNetworkMissingIpAddress() throws InsufficientVirtualNetworkCapacityException, InsufficientAddressCapacityException {
Mockito.when(ipAddressDao.findByIp(vrNicIp)).thenReturn(null);
guru.allocate(network, nicProfile, virtualMachineProfile);
}
@Test(expected = CloudRuntimeException.class)
public void testAllocateNetrisNetworkMissingVpc() throws InsufficientVirtualNetworkCapacityException, InsufficientAddressCapacityException {
Mockito.when(vpcDao.findById(vpcId)).thenReturn(null);
guru.allocate(network, nicProfile, virtualMachineProfile);
}
@Test(expected = CloudRuntimeException.class)
public void testAllocateNetrisNetworkSourceNatIps() throws InsufficientVirtualNetworkCapacityException, InsufficientAddressCapacityException {
Mockito.when(vpcDao.findById(vpcId)).thenReturn(null);
guru.allocate(network, nicProfile, virtualMachineProfile);
}
@Test(expected = CloudRuntimeException.class)
public void testAllocateNetrisNetworkMissingIps() throws InsufficientVirtualNetworkCapacityException, InsufficientAddressCapacityException {
Mockito.when(ipAddressDao.listByAssociatedVpc(vpcId, true)).thenReturn(null);
guru.allocate(network, nicProfile, virtualMachineProfile);
}
@Test
public void testAllocateNetrisNetwork() throws InsufficientVirtualNetworkCapacityException, InsufficientAddressCapacityException {
long vpcOfferingId = 20L;
long accountId = 2L;
long domainId = 8L;
long networkId = 210L;
String vpcName = "test-vpc";
String vpcCidr = "172.20.10.1/28";
String networkName = "vpc-tier";
Mockito.when(vpc.getAccountId()).thenReturn(accountId);
Mockito.when(vpc.getZoneId()).thenReturn(zoneId);
Mockito.when(vpc.getDomainId()).thenReturn(domainId);
Mockito.when(vpc.getVpcOfferingId()).thenReturn(vpcOfferingId);
Mockito.when(vpc.getName()).thenReturn(vpcName);
Mockito.when(vpc.getCidr()).thenReturn(vpcCidr);
Mockito.when(network.getName()).thenReturn(networkName);
Mockito.when(network.getId()).thenReturn(networkId);
VpcOfferingVO vpcOffering = Mockito.mock(VpcOfferingVO.class);
Mockito.when(vpcOfferingDao.findById(vpcOfferingId)).thenReturn(vpcOffering);
Mockito.when(vpcOffering.getNetworkMode()).thenReturn(NetworkOffering.NetworkMode.NATTED);
Mockito.when(vpcOfferingServiceMapDao.areServicesSupportedByVpcOffering(
vpcOfferingId, new Network.Service[]{Network.Service.SourceNat})).thenReturn(true);
Mockito.when(netrisService.createVpcResource(Mockito.anyLong(), Mockito.anyLong(), Mockito.anyLong(),
Mockito.anyLong(), Mockito.anyString(), Mockito.anyBoolean(), Mockito.anyString(),
Mockito.anyBoolean())).thenReturn(true);
Mockito.when(netrisService.createSnatRule(Mockito.anyLong(), Mockito.anyLong(), Mockito.anyLong(),
Mockito.anyString(), Mockito.anyLong(), Mockito.anyString(), Mockito.anyLong(),
Mockito.anyBoolean(), Mockito.anyString(), Mockito.anyString())).thenReturn(true);
guru.allocate(network, nicProfile, virtualMachineProfile);
Mockito.verify(netrisService).createVpcResource(zoneId, accountId, domainId, vpcId, vpcName, true,
vpcCidr, true);
Mockito.verify(netrisService).createSnatRule(zoneId, accountId, domainId, vpcName, vpcId, networkName,
networkId, true, vpcCidr, vpcSourceNatIp);
}
}