// Licensed to the Apache Software Foundation (ASF) under one // or more contributor license agreements. See the NOTICE file // distributed with this work for additional information // regarding copyright ownership. The ASF licenses this file // to you under the Apache License, Version 2.0 (the // "License"); you may not use this file except in compliance // with the License. You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, // software distributed under the License is distributed on an // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY // KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. package com.cloud.network; import com.cloud.dc.DataCenter; import com.cloud.exception.InsufficientAddressCapacityException; import com.cloud.exception.InvalidParameterValueException; import com.cloud.network.IpAddress.State; import com.cloud.network.Network.IpAddresses; import com.cloud.network.dao.IPAddressDaoImpl; import com.cloud.network.dao.IPAddressVO; import com.cloud.network.dao.UserIpv6AddressDaoImpl; import com.cloud.user.Account; import com.cloud.utils.Pair; import com.cloud.utils.net.NetUtils; import com.cloud.vm.NicProfile; import com.cloud.vm.dao.NicSecondaryIpDaoImpl; import com.cloud.vm.dao.NicSecondaryIpVO; import org.junit.After; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.mockito.InjectMocks; import org.mockito.Mockito; import org.mockito.MockitoAnnotations; import static org.mockito.Mockito.mock; public class Ipv6AddressManagerTest { @InjectMocks Ipv6AddressManagerImpl ip6Manager = Mockito.spy(new Ipv6AddressManagerImpl()); @InjectMocks NicSecondaryIpDaoImpl nicSecondaryIpDao = Mockito.spy(new NicSecondaryIpDaoImpl()); @InjectMocks UserIpv6AddressDaoImpl ipv6Dao = Mockito.spy(new UserIpv6AddressDaoImpl()); @InjectMocks IpAddressManagerImpl ipAddressManager = Mockito.spy(new IpAddressManagerImpl()); @InjectMocks NetworkModelImpl networkModel = Mockito.mock(NetworkModelImpl.class);// = Mockito.spy(new NetworkModelImpl()); @InjectMocks IPAddressDaoImpl ipAddressDao = Mockito.spy(new IPAddressDaoImpl()); private Network network = mockNetwork(); private AutoCloseable closeable; @Before public void setup() { closeable = MockitoAnnotations.openMocks(this); } @After public void tearDown() throws Exception { closeable.close(); } @Test public void isIp6TakenTestNoNull() { setIsIp6TakenTest(new UserIpv6AddressVO(), new NicSecondaryIpVO(0l, "ipaddr", 0l, 0l, 0l, 0l)); boolean result = ip6Manager.isIp6Taken(network, "requestedIpv6"); assertAndVerifyIsIp6Taken(true, result); } @Test public void isIp6TakenTestSecIpNull() { setIsIp6TakenTest(new UserIpv6AddressVO(), null); boolean result = ip6Manager.isIp6Taken(network, "requestedIpv6"); assertAndVerifyIsIp6Taken(true, result); } @Test public void isIp6TakenTestUserIpv6AddressNull() { setIsIp6TakenTest(null, new NicSecondaryIpVO(0l, "ipaddr", 0l, 0l, 0l, 0l)); boolean result = ip6Manager.isIp6Taken(network, "requestedIpv6"); assertAndVerifyIsIp6Taken(true, result); } @Test public void isIp6TakenTestAllNull() { setIsIp6TakenTest(null, null); boolean result = ip6Manager.isIp6Taken(network, "requestedIpv6"); assertAndVerifyIsIp6Taken(false, result); } private void assertAndVerifyIsIp6Taken(boolean expected, boolean result) { Assert.assertEquals(expected, result); Mockito.verify(ipv6Dao).findByNetworkIdAndIp(Mockito.anyLong(), Mockito.anyString()); Mockito.verify(nicSecondaryIpDao).findByIp6AddressAndNetworkId(Mockito.anyString(), Mockito.anyLong()); } private void setIsIp6TakenTest(UserIpv6AddressVO userIpv6, NicSecondaryIpVO nicSecondaryIp) { Mockito.doReturn(userIpv6).when(ipv6Dao).findByNetworkIdAndIp(Mockito.anyLong(), Mockito.anyString()); Mockito.doReturn(nicSecondaryIp).when(nicSecondaryIpDao).findByIp6AddressAndNetworkId(Mockito.anyString(), Mockito.anyLong()); } private Network mockNetwork() { Network network = mock(Network.class); Mockito.when(network.getId()).thenReturn(0l); Mockito.when(network.getIp6Cidr()).thenReturn("2001:db8::/32"); return network; } @Test public void allocatePublicIp6ForGuestNicTestNoException() throws InsufficientAddressCapacityException { Account owner = Mockito.mock(Account.class); String requestedIpv6 = setCheckIfCanAllocateIpv6AddresscTest("2001:db8::10", false, false); String returnedIp = ip6Manager.allocatePublicIp6ForGuestNic(network, 0l, owner, requestedIpv6); Mockito.verify(ip6Manager).checkIfCanAllocateIpv6Address(network, requestedIpv6); Assert.assertEquals(requestedIpv6, returnedIp); } @Test(expected = InsufficientAddressCapacityException.class) public void checkIfCanAllocateIpv6AddressTestIp6IsTaken() throws InsufficientAddressCapacityException { String requestedIpv6 = setCheckIfCanAllocateIpv6AddresscTest("2001:db8::10", true, false); ip6Manager.checkIfCanAllocateIpv6Address(network, requestedIpv6); verifyCheckIfCanAllocateIpv6AddressTest(network, requestedIpv6, 1, 0); } @Test(expected = InvalidParameterValueException.class) public void checkIfCanAllocateIpv6AddressTestIpIsIpEqualsGatewayOrNetworkOfferingsEmpty() throws InsufficientAddressCapacityException { String requestedIpv6 = setCheckIfCanAllocateIpv6AddresscTest("2001:db8::10", false, true); ip6Manager.checkIfCanAllocateIpv6Address(network, requestedIpv6); verifyCheckIfCanAllocateIpv6AddressTest(network, requestedIpv6, 1, 1); } @Test(expected = InvalidParameterValueException.class) public void checkIfCanAllocateIpv6AddressTestIpINotInTheNetwork() throws InsufficientAddressCapacityException { String requestedIpv6 = "2002:db8::10"; setCheckIfCanAllocateIpv6AddresscTest(requestedIpv6, false, false); ip6Manager.checkIfCanAllocateIpv6Address(network, requestedIpv6); verifyCheckIfCanAllocateIpv6AddressTest(network, requestedIpv6, 1, 1); } private void verifyCheckIfCanAllocateIpv6AddressTest(Network network, String requestedIpv6, int isIp6TakenTimes, int isIpEqualsGatewayTimes) { Mockito.verify(ip6Manager, Mockito.times(isIp6TakenTimes)).isIp6Taken(network, requestedIpv6); Mockito.verify(ipAddressManager, Mockito.times(isIpEqualsGatewayTimes)).isIpEqualsGatewayOrNetworkOfferingsEmpty(network, requestedIpv6); } private String setCheckIfCanAllocateIpv6AddresscTest(String requestedIpv6, boolean isIp6Taken, boolean isIpEqualsGatewayOrNetworkOfferingsEmpty) { Mockito.doReturn(isIp6Taken).when(ip6Manager).isIp6Taken(Mockito.eq(network), Mockito.anyString()); Mockito.doReturn(isIpEqualsGatewayOrNetworkOfferingsEmpty).when(ipAddressManager).isIpEqualsGatewayOrNetworkOfferingsEmpty(network, requestedIpv6); NetUtils.isIp6InNetwork(requestedIpv6, network.getIp6Cidr()); return requestedIpv6; } @Test public void acquireGuestIpv6AddressTest() throws InsufficientAddressCapacityException { setAcquireGuestIpv6AddressTest(true, State.Free); String requestedIpv6 = setCheckIfCanAllocateIpv6AddresscTest("2001:db8::10", false, false); ip6Manager.acquireGuestIpv6Address(network, requestedIpv6); verifyAcquireGuestIpv6AddressTest(); } private void verifyAcquireGuestIpv6AddressTest() { Mockito.verify(networkModel).areThereIPv6AddressAvailableInNetwork(Mockito.anyLong()); Mockito.verify(networkModel).checkRequestedIpAddresses(Mockito.anyLong(), Mockito.any(IpAddresses.class)); Mockito.verify(ipAddressDao).findByIpAndSourceNetworkId(Mockito.anyLong(), Mockito.anyString()); } @Test(expected = InsufficientAddressCapacityException.class) public void acquireGuestIpv6AddressTestUnavailableIp() throws InsufficientAddressCapacityException { setAcquireGuestIpv6AddressTest(false, State.Free); String requestedIpv6 = setCheckIfCanAllocateIpv6AddresscTest("2001:db8::10", false, false); ip6Manager.acquireGuestIpv6Address(network, requestedIpv6); verifyAcquireGuestIpv6AddressTest(); } @Test(expected = InsufficientAddressCapacityException.class) public void acquireGuestIpv6AddressTestStateAllocating() throws InsufficientAddressCapacityException { setAcquireGuestIpv6AddressTest(false, State.Allocating); String requestedIpv6 = setCheckIfCanAllocateIpv6AddresscTest("2001:db8::10", false, false); ip6Manager.acquireGuestIpv6Address(network, requestedIpv6); verifyAcquireGuestIpv6AddressTest(); } @Test(expected = InsufficientAddressCapacityException.class) public void acquireGuestIpv6AddressTestStateAllocated() throws InsufficientAddressCapacityException { setAcquireGuestIpv6AddressTest(false, State.Allocated); String requestedIpv6 = setCheckIfCanAllocateIpv6AddresscTest("2001:db8::10", false, false); ip6Manager.acquireGuestIpv6Address(network, requestedIpv6); verifyAcquireGuestIpv6AddressTest(); } @Test(expected = InsufficientAddressCapacityException.class) public void acquireGuestIpv6AddressTestStateReleasing() throws InsufficientAddressCapacityException { setAcquireGuestIpv6AddressTest(false, State.Releasing); String requestedIpv6 = setCheckIfCanAllocateIpv6AddresscTest("2001:db8::10", false, false); ip6Manager.acquireGuestIpv6Address(network, requestedIpv6); verifyAcquireGuestIpv6AddressTest(); } private void setAcquireGuestIpv6AddressTest(boolean isIPAvailable, State state) { mockNetwork(); IPAddressVO ipVo = Mockito.mock(IPAddressVO.class); Mockito.doReturn(isIPAvailable).when(networkModel).areThereIPv6AddressAvailableInNetwork(Mockito.anyLong()); Mockito.doReturn(ipVo).when(ipAddressDao).findByIpAndSourceNetworkId(Mockito.anyLong(), Mockito.anyString()); Mockito.when(ipVo.getState()).thenReturn(state); } @Test public void setNICIPv6AddressTest() throws InsufficientAddressCapacityException { NicProfile nic = new NicProfile(); Network network = mock(Network.class); DataCenter dc = mock(DataCenter.class); nic.setMacAddress("1e:00:b1:00:0a:f6"); Mockito.when(network.getIp6Cidr()).thenReturn("2001:db8:100::/64"); Mockito.when(network.getIp6Gateway()).thenReturn("2001:db8:100::1"); Mockito.when(network.getId()).thenReturn(1L); Mockito.when(networkModel.getNetworkIp6Dns(network, dc)).thenReturn(new Pair<>("2001:db8::53:1", "2001:db8::53:2")); Mockito.when(networkModel.isMACUnique("1e:00:b1:00:0a:f6", 1L)).thenReturn(true); String expected = "2001:db8:100:0:1c00:b1ff:fe00:af6"; ip6Manager.setNicIp6Address(nic, dc, network); Assert.assertEquals(expected, nic.getIPv6Address()); } @Test(expected = InsufficientAddressCapacityException.class) public void acquireGuestIpv6AddressEUI64Test() throws InsufficientAddressCapacityException { setAcquireGuestIpv6AddressTest(true, State.Free); String requestedIpv6 = setCheckIfCanAllocateIpv6AddresscTest("2001:db8:13f::1c00:4aff:fe00:fe", false, false); ip6Manager.acquireGuestIpv6Address(network, requestedIpv6); } }