/**
* Abiquo community edition
* cloud management application for hybrid clouds
* Copyright (C) 2008-2010 - Abiquo Holdings S.L.
*
* This application is free software; you can redistribute it and/or
* modify it under the terms of the GNU LESSER GENERAL PUBLIC
* LICENSE as published by the Free Software Foundation under
* version 3 of the License
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* LESSER GENERAL PUBLIC LICENSE v.3 for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
/**
*
*/
package com.abiquo.api.services.cloud;
import static com.abiquo.testng.TestConfig.BASIC_UNIT_TESTS;
import static com.abiquo.testng.TestConfig.NETWORK_UNIT_TESTS;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.fail;
import java.util.Random;
import javax.persistence.EntityManager;
import org.springframework.security.context.SecurityContextHolder;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
import com.abiquo.api.common.AbstractUnitTest;
import com.abiquo.api.common.BasicUserAuthentication;
import com.abiquo.api.exceptions.BadRequestException;
import com.abiquo.api.exceptions.ConflictException;
import com.abiquo.api.exceptions.NotFoundException;
import com.abiquo.api.services.NetworkService;
import com.abiquo.model.enumerator.RemoteServiceType;
import com.abiquo.server.core.cloud.VirtualDatacenter;
import com.abiquo.server.core.enterprise.DatacenterLimits;
import com.abiquo.server.core.enterprise.Enterprise;
import com.abiquo.server.core.enterprise.Role;
import com.abiquo.server.core.enterprise.User;
import com.abiquo.server.core.infrastructure.RemoteService;
import com.abiquo.server.core.infrastructure.network.NetworkConfiguration;
import com.abiquo.server.core.infrastructure.network.VLANNetwork;
import com.abiquo.server.core.infrastructure.network.VLANNetworkGenerator;
import com.abiquo.server.core.util.network.IPNetworkRang;
/**
* @author jdevesa
*/
@Test(groups = {NETWORK_UNIT_TESTS})
public class PrivateNetworkServiceTest extends AbstractUnitTest
{
protected VirtualDatacenter vdc;
protected VLANNetwork vlan;
protected RemoteService rs;
@BeforeMethod(groups = {BASIC_UNIT_TESTS, NETWORK_UNIT_TESTS})
public void setupBasicUser()
{
Enterprise e = enterpriseGenerator.createUniqueInstance();
Role r = roleGenerator.createInstance();
User u = userGenerator.createInstance(e, r, "basicUser", "basicUser");
setup(e, r, u);
rs = remoteServiceGenerator.createInstance(RemoteServiceType.DHCP_SERVICE);
vdc = vdcGenerator.createInstance(rs.getDatacenter(), e);
DatacenterLimits dclimit = new DatacenterLimits(vdc.getEnterprise(), vdc.getDatacenter());
vlan = vlanGenerator.createInstance(vdc.getNetwork(), rs, "255.255.255.0");
vlan.setEnterprise(vdc.getEnterprise());
vdc.setDefaultVlan(vlan);
setup(vdc.getDatacenter(), rs, vdc.getNetwork(), vlan.getConfiguration(), vlan, vdc,
dclimit);
SecurityContextHolder.getContext().setAuthentication(new BasicUserAuthentication());
}
@Override
@AfterMethod(groups = {BASIC_UNIT_TESTS, NETWORK_UNIT_TESTS})
public void tearDown()
{
super.tearDown();
}
/**
* Throws a not found exception when it does not found the virtual datacenter
*/
@Test(expectedExceptions = {NotFoundException.class})
public void updateNetworkRandomVDCTest()
{
EntityManager em = getEntityManagerWithAnActiveTransaction();
NetworkService service = new NetworkService(em);
service.updatePrivateNetwork(new Random().nextInt(1000), vlan.getId(), vlan);
}
/**
* Throws a not found exception when it does not found the vLAN
*/
@Test(expectedExceptions = {NotFoundException.class})
public void updateNetworkRandomVlanTest()
{
EntityManager em = getEntityManagerWithAnActiveTransaction();
NetworkService service = new NetworkService(em);
service.updatePrivateNetwork(vdc.getId(), new Random().nextInt(1000), vlan);
}
/**
* Throws a not found exception when it does not found the vLAN with a known vdc but that does
* not belong to it
*/
@Test(expectedExceptions = {NotFoundException.class})
public void updateNetworkInvalidTupleVDCVlanTest()
{
VirtualDatacenter vdc2 = vdcGenerator.createInstance(rs.getDatacenter());
setup(vdc2.getEnterprise(), vdc2.getNetwork(), vdc2);
EntityManager em = getEntityManagerWithAnActiveTransaction();
NetworkService service = new NetworkService(em);
service.updatePrivateNetwork(vdc2.getId(), vlan.getId(), vlan);
}
/**
* Throws a {@link BadRequestException} when the ip of the path is different from the IP of the
* VLAN.
*/
@Test(expectedExceptions = {BadRequestException.class})
public void updateNetworkIncoherentIDs()
{
EntityManager em = getEntityManagerWithAnActiveTransaction();
VLANNetwork copy = performCopy(vlan);
copy.setId(new Random().nextInt(1000));
NetworkService service = new NetworkService(em);
service.updatePrivateNetwork(vdc.getId(), vlan.getId(), copy);
}
/**
* Throws a ConflictException when we try to change the address of the VLAN, it should raise a
* {@link ConflictException}
*/
@Test(expectedExceptions = {ConflictException.class})
public void updateNetworkAddressChanged()
{
EntityManager em = getEntityManagerWithAnActiveTransaction();
VLANNetwork copy = performCopy(vlan);
copy.getConfiguration().setAddress("12.12.12.12");
NetworkService service = new NetworkService(em);
service.updatePrivateNetwork(vdc.getId(), copy.getId(), copy);
}
/**
* Throws a {@link ConflictException} when we try to change the mask of the VLAN, it should
* raise a {@link ConflictException}
*/
@Test(expectedExceptions = {ConflictException.class})
public void updateNetworkMaskChanged()
{
EntityManager em = getEntityManagerWithAnActiveTransaction();
VLANNetwork copy = performCopy(vlan);
copy.getConfiguration().setMask(20);
NetworkService service = new NetworkService(em);
service.updatePrivateNetwork(vdc.getId(), copy.getId(), copy);
}
/**
* Throws a {@link ConflictException} when we try to change the tag of the VLAN, it should raise
* a {@link ConflictException}
*/
@Test(expectedExceptions = {ConflictException.class})
public void updateNetworkTagsChanged()
{
EntityManager em = getEntityManagerWithAnActiveTransaction();
VLANNetwork copy = performCopy(vlan);
copy.setTag(45);
NetworkService service = new NetworkService(em);
service.updatePrivateNetwork(vdc.getId(), copy.getId(), copy);
}
/**
* The {@link VLANNetworkGenerator} creates a network inside the range 192.168.1.0 and
* 192.168.1.255. And the default gateway is '192.168.1.1'. The 'gateway' field is an IP address
* that must be inside this range. This test checks that this process works ok.
*/
@Test
public void updateNetworkGatewayOutsideTheRange()
{
EntityManager em = getEntityManagerWithAnActiveTransaction();
NetworkService service = new NetworkService(em);
// Put an invalid gateway (out of range) and check a ConflictException is raised.
VLANNetwork copy = performCopy(vlan);
copy.getConfiguration().setGateway("24.24.24.0");
try
{
service.updatePrivateNetwork(vdc.getId(), copy.getId(), copy);
fail();
}
catch (ConflictException ce)
{
// do nothing. It is the desired behaviour
}
// Put a valid gateway and check the services updates it ok.
copy.getConfiguration().setGateway("192.168.1.45");
vlan = service.updatePrivateNetwork(vdc.getId(), copy.getId(), copy);
assertEquals(vlan.getConfiguration().getGateway(), copy.getConfiguration().getGateway());
commitActiveTransaction(em);
}
/**
* Two VLANs can not be created with the same name inside the same VDC. But two VLANs with the
* same name can be created in VDC differents. This test checks this behaviour.
*/
@Test
public void updateNetworkDuplicatedName()
{
// Create the second VLANNetwork 'vlan2' in the same VDC than 'vlan' and check
// the process doesn't allow us to update it.
VLANNetwork vlan2 = vlanGenerator.createInstance(vdc.getNetwork(), rs, "255.255.255.0");
vlan2.setEnterprise(vdc.getEnterprise());
setup(vlan2.getConfiguration(), vlan2);
// Create the third VLANNetwork 'vlan3' in other VDC than 'vlan'. The VLAN with the same
// name
// should be allowed now.
VirtualDatacenter vdc2 =
vdcGenerator.createInstance(rs.getDatacenter(), vdc.getEnterprise());
setup(vdc2.getNetwork(), vdc2);
VLANNetwork vlan3 = vlanGenerator.createInstance(vdc2.getNetwork(), rs, "255.255.255.0");
setup(vlan3.getConfiguration(), vlan3);
// STEP 1
EntityManager em = getEntityManagerWithAnActiveTransaction();
NetworkService service = new NetworkService(em);
try
{
// Set the same name.
vlan2.setName(vlan.getName());
service.updatePrivateNetwork(vdc.getId(), vlan2.getId(), vlan2);
fail();
}
catch (ConflictException ce)
{
// The conflict exception is the desired behavior, go on
}
// STEP 2
service = new NetworkService(em);
// Set the same name and update vlan3
VLANNetwork copy = performCopy(vlan3);
copy.setName(vlan.getName());
vlan3 = service.updatePrivateNetwork(vdc2.getId(), copy.getId(), copy);
commitActiveTransaction(em);
// assert the values
assertEquals(vlan3.getName(), vlan.getName());
}
/**
* Not all the fields of the VLAN can be changed. That was tested in previous test. This method
* test all the fields in the VLANNetwork can be changed are actually changed.
*/
@Test(groups = {BASIC_UNIT_TESTS})
public void updateNetworkUpdatesAllFields()
{
VLANNetwork copy = performCopy(vlan);
copy.getConfiguration().setGateway("192.168.1.44");
copy.getConfiguration().setPrimaryDNS("8.4.4.8");
copy.getConfiguration().setSecondaryDNS("56.56.56.56");
copy.getConfiguration().setSufixDNS("bcn.test.test.com");
copy.setName("newname");
EntityManager em = getEntityManagerWithAnActiveTransaction();
NetworkService service = new NetworkService(em);
vlan = service.updatePrivateNetwork(vdc.getId(), copy.getId(), copy);
commitActiveTransaction(em);
assertEquals(vlan.getConfiguration().getGateway(), "192.168.1.44");
assertEquals(vlan.getConfiguration().getPrimaryDNS(), "8.4.4.8");
assertEquals(vlan.getConfiguration().getSecondaryDNS(), "56.56.56.56");
assertEquals(vlan.getConfiguration().getSufixDNS(), "bcn.test.test.com");
assertEquals(vlan.getName(), "newname");
}
// DELETE-related methods.
/**
* Every virtual datacenter should have at least a VLAN defined there. So this test will raise a
* ConflictException because it don't let to delete it
*/
@Test(expectedExceptions = {ConflictException.class})
public void deleteNetworkUniqueRaisesExceptionTest()
{
EntityManager em = getEntityManagerWithAnActiveTransaction();
NetworkService service = new NetworkService(em);
service.deletePrivateNetwork(vdc.getId(), vlan.getId());
}
/**
* Every virtual datacenter should have at least a default VLAN defined there. So this test will
* raise a ConflictException because it won't let delete the default network.
*/
@Test(expectedExceptions = {ConflictException.class}, enabled = false)
public void deleteNetworkDefaultRaisesExceptionTest()
{
EntityManager em = getEntityManagerWithAnActiveTransaction();
NetworkService service = new NetworkService(em);
// Create the second one
VLANNetwork vlan2 = vlanGenerator.createInstance(vdc.getNetwork(), rs, "255.255.255.0");
setup(vlan2.getConfiguration(), vlan2);
// Try to delete the first one.
service.deletePrivateNetwork(vdc.getId(), vlan.getId());
}
/**
* Test when we try to delete a VLAN it works.
*/
@Test(groups = {BASIC_UNIT_TESTS})
public void deleteNetworkTest()
{
// Create the second one
VLANNetwork vlan2 = vlanGenerator.createInstance(vdc.getNetwork(), rs, "255.255.255.0");
vlan2.setEnterprise(vdc.getEnterprise());
setup(vlan2.getConfiguration(), vlan2);
EntityManager em = getEntityManagerWithAnActiveTransaction();
NetworkService service = new NetworkService(em);
// Assert here we have two vlans.
assertEquals(service.getPrivateNetworks(vdc.getId()).size(), 2);
// Try to delete the second one.
service.deletePrivateNetwork(vdc.getId(), vlan2.getId());
// Assert here we have delete one of them.
assertEquals(service.getPrivateNetworks(vdc.getId()).size(), 1);
commitActiveTransaction(em);
}
/**
* Performs a copy of a VLANNetwork object.
*
* @param original original object to be copied.
* @return a new instance of {@link VLANNetwork} object but with the same values
*/
private VLANNetwork performCopy(final VLANNetwork original)
{
VLANNetwork copy = new VLANNetwork();
copy.setId(original.getId());
copy.setName(original.getName());
copy.setTag(original.getTag());
copy.setNetwork(original.getNetwork());
copy.setConfiguration(new NetworkConfiguration(original.getConfiguration().getAddress(),
original.getConfiguration().getMask(),
IPNetworkRang.transformIntegerMaskToIPMask(original.getConfiguration().getMask())
.toString(), original.getConfiguration().getGateway(), "bridge"));
copy.getConfiguration().setPrimaryDNS(original.getConfiguration().getPrimaryDNS());
copy.getConfiguration().setSecondaryDNS(original.getConfiguration().getSecondaryDNS());
copy.getConfiguration().setSufixDNS(original.getConfiguration().getSufixDNS());
return copy;
}
}