blob: 829f0c9cb2001eb6929aef292bd66d147f206d46 [file] [log] [blame]
// 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.user;
import com.cloud.api.query.dao.DiskOfferingJoinDao;
import com.cloud.api.query.dao.NetworkOfferingJoinDao;
import com.cloud.api.query.dao.ServiceOfferingJoinDao;
import com.cloud.api.query.dao.VpcOfferingJoinDao;
import com.cloud.configuration.ConfigurationManager;
import com.cloud.configuration.Resource.ResourceOwnerType;
import com.cloud.configuration.ResourceLimit;
import com.cloud.configuration.dao.ResourceCountDao;
import com.cloud.configuration.dao.ResourceLimitDao;
import com.cloud.dc.DedicatedResourceVO;
import com.cloud.dc.dao.DedicatedResourceDao;
import com.cloud.domain.Domain;
import com.cloud.domain.DomainVO;
import com.cloud.domain.dao.DomainDao;
import com.cloud.domain.dao.DomainDetailsDao;
import com.cloud.exception.InvalidParameterValueException;
import com.cloud.exception.PermissionDeniedException;
import com.cloud.network.dao.NetworkDomainDao;
import com.cloud.projects.ProjectManager;
import com.cloud.projects.dao.ProjectDao;
import com.cloud.user.dao.AccountDao;
import com.cloud.utils.UuidUtils;
import com.cloud.utils.db.Filter;
import com.cloud.utils.db.GlobalLock;
import com.cloud.utils.db.SearchCriteria;
import com.cloud.utils.exception.CloudRuntimeException;
import com.cloud.utils.net.NetUtils;
import org.apache.cloudstack.annotation.dao.AnnotationDao;
import org.apache.cloudstack.context.CallContext;
import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService;
import org.apache.cloudstack.framework.messagebus.MessageBus;
import org.apache.cloudstack.framework.messagebus.PublishScope;
import org.apache.cloudstack.region.RegionManager;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.ArgumentMatchers;
import org.mockito.Mock;
import org.mockito.MockedStatic;
import org.mockito.Mockito;
import org.mockito.Spy;
import org.mockito.junit.MockitoJUnitRunner;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.UUID;
@RunWith(MockitoJUnitRunner.class)
public class DomainManagerImplTest {
@Mock
DomainDao domainDaoMock;
@Mock
AccountManager _accountMgr;
@Mock
ResourceCountDao _resourceCountDao;
@Mock
AccountDao _accountDao;
@Mock
DiskOfferingJoinDao _diskOfferingDao;
@Mock
NetworkOfferingJoinDao networkOfferingJoinDao;
@Mock
ServiceOfferingJoinDao serviceOfferingJoinDao;
@Mock
VpcOfferingJoinDao vpcOfferingJoinDao;
@Mock
ProjectDao _projectDao;
@Mock
ProjectManager _projectMgr;
@Mock
RegionManager _regionMgr;
@Mock
ResourceLimitDao _resourceLimitDao;
@Mock
DedicatedResourceDao _dedicatedDao;
@Mock
NetworkOrchestrationService _networkMgr;
@Mock
NetworkDomainDao _networkDomainDao;
@Mock
MessageBus _messageBus;
@Mock
ConfigurationManager _configMgr;
@Mock
DomainDetailsDao _domainDetailsDao;
@Mock
AnnotationDao annotationDao;
@Spy
@InjectMocks
DomainManagerImpl domainManager = new DomainManagerImpl();
@Mock
DomainVO domain;
@Mock
Account adminAccount;
@Mock
GlobalLock lock;
List<AccountVO> domainAccountsForCleanup;
List<Long> domainNetworkIds;
List<DedicatedResourceVO> domainDedicatedResources;
private static final long DOMAIN_ID = 3l;
private static final long ACCOUNT_ID = 1l;
private static boolean testDomainCleanup = false;
@Before
public void setup() throws NoSuchFieldException, SecurityException,
IllegalArgumentException, IllegalAccessException {
Mockito.doReturn(adminAccount).when(domainManager).getCaller();
Mockito.doReturn(lock).when(domainManager).getGlobalLock("DomainCleanup");
Mockito.when(lock.lock(Mockito.anyInt())).thenReturn(true);
Mockito.when(domainDaoMock.findById(DOMAIN_ID)).thenReturn(domain);
Mockito.when(domain.getAccountId()).thenReturn(ACCOUNT_ID);
Mockito.when(domain.getId()).thenReturn(DOMAIN_ID);
Mockito.when(domainDaoMock.remove(DOMAIN_ID)).thenReturn(true);
domainAccountsForCleanup = new ArrayList<AccountVO>();
domainNetworkIds = new ArrayList<Long>();
domainDedicatedResources = new ArrayList<DedicatedResourceVO>();
Mockito.when(_accountDao.findCleanupsForRemovedAccounts(DOMAIN_ID)).thenReturn(domainAccountsForCleanup);
Mockito.when(_networkDomainDao.listNetworkIdsByDomain(DOMAIN_ID)).thenReturn(domainNetworkIds);
Mockito.when(_dedicatedDao.listByDomainId(DOMAIN_ID)).thenReturn(domainDedicatedResources);
Mockito.when(_diskOfferingDao.findByDomainId(Mockito.anyLong())).thenReturn(Collections.emptyList());
Mockito.when(networkOfferingJoinDao.findByDomainId(Mockito.anyLong(), Mockito.anyBoolean())).thenReturn(Collections.emptyList());
Mockito.when(serviceOfferingJoinDao.findByDomainId(Mockito.anyLong())).thenReturn(Collections.emptyList());
Mockito.when(vpcOfferingJoinDao.findByDomainId(Mockito.anyLong())).thenReturn(Collections.emptyList());
}
@Test
public void testFindDomainByIdOrPathNullOrEmpty() {
final DomainVO domain = new DomainVO("someDomain", 123, 1L, "network.domain");
Mockito.when(domainDaoMock.findById(1L)).thenReturn(domain);
Assert.assertEquals(domain, domainManager.findDomainByIdOrPath(null, null));
Assert.assertEquals(domain, domainManager.findDomainByIdOrPath(0L, ""));
Assert.assertEquals(domain, domainManager.findDomainByIdOrPath(-1L, " "));
Assert.assertEquals(domain, domainManager.findDomainByIdOrPath(null, " "));
}
@Test
public void testFindDomainByIdOrPathValidPathAndInvalidId() {
final DomainVO domain = new DomainVO("someDomain", 123, 1L, "network.domain");
Mockito.when(domainDaoMock.findDomainByPath(Mockito.eq("/someDomain/"))).thenReturn(domain);
Assert.assertEquals(domain, domainManager.findDomainByIdOrPath(null, "/someDomain/"));
Assert.assertEquals(domain, domainManager.findDomainByIdOrPath(0L, " /someDomain/"));
Assert.assertEquals(domain, domainManager.findDomainByIdOrPath(-1L, "/someDomain/ "));
Assert.assertEquals(domain, domainManager.findDomainByIdOrPath(null, " /someDomain/ "));
}
@Test
public void testFindDomainByIdOrPathInvalidPathAndInvalidId() {
Mockito.when(domainDaoMock.findDomainByPath(Mockito.anyString())).thenReturn(null);
Assert.assertNull(domainManager.findDomainByIdOrPath(null, "/nonExistingDomain/"));
Assert.assertNull(domainManager.findDomainByIdOrPath(0L, " /nonExistingDomain/"));
Assert.assertNull(domainManager.findDomainByIdOrPath(-1L, "/nonExistingDomain/ "));
Assert.assertNull(domainManager.findDomainByIdOrPath(null, " /nonExistingDomain/ "));
}
@Test
public void testFindDomainByIdOrPathValidId() {
final DomainVO domain = new DomainVO("someDomain", 123, 1L, "network.domain");
Mockito.when(domainDaoMock.findById(1L)).thenReturn(domain);
Mockito.lenient().when(domainDaoMock.findDomainByPath(Mockito.eq("/validDomain/"))).thenReturn(new DomainVO());
Assert.assertEquals(domain, domainManager.findDomainByIdOrPath(1L, null));
Assert.assertEquals(domain, domainManager.findDomainByIdOrPath(1L, ""));
Assert.assertEquals(domain, domainManager.findDomainByIdOrPath(1L, " "));
Assert.assertEquals(domain, domainManager.findDomainByIdOrPath(1L, " "));
Assert.assertEquals(domain, domainManager.findDomainByIdOrPath(1L, "/validDomain/"));
}
@Test(expected=InvalidParameterValueException.class)
public void testDeleteDomainNullDomain() {
Mockito.when(domainDaoMock.findById(DOMAIN_ID)).thenReturn(null);
domainManager.deleteDomain(DOMAIN_ID, testDomainCleanup);
}
@Test(expected=PermissionDeniedException.class)
public void testDeleteDomainRootDomain() {
Mockito.when(domainDaoMock.findById(Domain.ROOT_DOMAIN)).thenReturn(domain);
domainManager.deleteDomain(Domain.ROOT_DOMAIN, testDomainCleanup);
}
@Test
public void testDeleteDomainNoCleanup() {
Mockito.when(_configMgr.releaseDomainSpecificVirtualRanges(Mockito.anyLong())).thenReturn(true);
domainManager.deleteDomain(DOMAIN_ID, testDomainCleanup);
Mockito.verify(domainManager).deleteDomain(domain, testDomainCleanup);
Mockito.verify(domainManager).removeDomainWithNoAccountsForCleanupNetworksOrDedicatedResources(domain);
Mockito.verify(domainManager).cleanupDomainDetails(DOMAIN_ID);
Mockito.verify(domainManager).cleanupDomainOfferings(DOMAIN_ID);
Mockito.verify(lock).unlock();
}
@Test
public void testRemoveDomainWithNoAccountsForCleanupNetworksOrDedicatedResourcesRemoveDomain() {
domainManager.removeDomainWithNoAccountsForCleanupNetworksOrDedicatedResources(domain);
Mockito.verify(domainManager).publishRemoveEventsAndRemoveDomain(domain);
}
@Test(expected=CloudRuntimeException.class)
public void testRemoveDomainWithNoAccountsForCleanupNetworksOrDedicatedResourcesDontRemoveDomain() {
domainNetworkIds.add(2l);
domainManager.removeDomainWithNoAccountsForCleanupNetworksOrDedicatedResources(domain);
Mockito.verify(domainManager).failRemoveOperation(domain, domainAccountsForCleanup, domainNetworkIds, false);
}
@Test
public void testPublishRemoveEventsAndRemoveDomainSuccessfulDelete() {
domainManager.publishRemoveEventsAndRemoveDomain(domain);
Mockito.verify(_messageBus).publish(Mockito.anyString(), ArgumentMatchers.eq(DomainManager.MESSAGE_PRE_REMOVE_DOMAIN_EVENT),
ArgumentMatchers.eq(PublishScope.LOCAL), ArgumentMatchers.eq(domain));
Mockito.verify(_messageBus).publish(Mockito.anyString(), ArgumentMatchers.eq(DomainManager.MESSAGE_REMOVE_DOMAIN_EVENT),
ArgumentMatchers.eq(PublishScope.LOCAL), ArgumentMatchers.eq(domain));
Mockito.verify(domainDaoMock).remove(DOMAIN_ID);
}
@Test(expected=CloudRuntimeException.class)
public void testPublishRemoveEventsAndRemoveDomainExceptionDelete() {
Mockito.when(domainDaoMock.remove(DOMAIN_ID)).thenReturn(false);
domainManager.publishRemoveEventsAndRemoveDomain(domain);
Mockito.verify(_messageBus).publish(Mockito.anyString(), ArgumentMatchers.eq(DomainManager.MESSAGE_PRE_REMOVE_DOMAIN_EVENT),
ArgumentMatchers.eq(PublishScope.LOCAL), ArgumentMatchers.eq(domain));
Mockito.verify(_messageBus, Mockito.never()).publish(Mockito.anyString(), ArgumentMatchers.eq(DomainManager.MESSAGE_REMOVE_DOMAIN_EVENT),
ArgumentMatchers.eq(PublishScope.LOCAL), ArgumentMatchers.eq(domain));
Mockito.verify(domainDaoMock).remove(DOMAIN_ID);
}
@Test(expected=CloudRuntimeException.class)
public void testFailRemoveOperation() {
domainManager.failRemoveOperation(domain, domainAccountsForCleanup, domainNetworkIds, true);
}
@Test
public void deleteDomain() {
DomainVO domain = new DomainVO();
domain.setId(20l);
domain.setAccountId(30l);
Account account = new AccountVO("testaccount", 1L, "networkdomain", Account.Type.NORMAL, "uuid");
UserVO user = new UserVO(1, "testuser", "password", "firstname", "lastName", "email", "timezone", UUID.randomUUID().toString(), User.Source.UNKNOWN);
CallContext.register(user, account);
Mockito.when(domainDaoMock.findById(20l)).thenReturn(domain);
Mockito.doNothing().when(_accountMgr).checkAccess(Mockito.any(Account.class), Mockito.any(Domain.class));
Mockito.when(domainDaoMock.update(Mockito.eq(20l), Mockito.any(DomainVO.class))).thenReturn(true);
Mockito.lenient().when(_accountDao.search(Mockito.any(SearchCriteria.class), (Filter) org.mockito.ArgumentMatchers.isNull())).thenReturn(new ArrayList<AccountVO>());
Mockito.when(_networkDomainDao.listNetworkIdsByDomain(Mockito.anyLong())).thenReturn(new ArrayList<Long>());
Mockito.when(_accountDao.findCleanupsForRemovedAccounts(Mockito.anyLong())).thenReturn(new ArrayList<AccountVO>());
Mockito.when(_dedicatedDao.listByDomainId(Mockito.anyLong())).thenReturn(new ArrayList<DedicatedResourceVO>());
Mockito.when(domainDaoMock.remove(Mockito.anyLong())).thenReturn(true);
Mockito.when(_configMgr.releaseDomainSpecificVirtualRanges(Mockito.anyLong())).thenReturn(true);
try {
Assert.assertTrue(domainManager.deleteDomain(20l, false));
} finally {
CallContext.unregister();
}
}
@Test
public void deleteDomainCleanup() {
DomainVO domain = new DomainVO();
domain.setId(20l);
domain.setAccountId(30l);
Account account = new AccountVO("testaccount", 1L, "networkdomain", Account.Type.NORMAL, "uuid");
UserVO user = new UserVO(1, "testuser", "password", "firstname", "lastName", "email", "timezone", UUID.randomUUID().toString(), User.Source.UNKNOWN);
CallContext.register(user, account);
Mockito.when(domainDaoMock.findById(20l)).thenReturn(domain);
Mockito.doNothing().when(_accountMgr).checkAccess(Mockito.any(Account.class), Mockito.any(Domain.class));
Mockito.when(domainDaoMock.update(Mockito.eq(20l), Mockito.any(DomainVO.class))).thenReturn(true);
Mockito.when(domainDaoMock.createSearchCriteria()).thenReturn(Mockito.mock(SearchCriteria.class));
Mockito.when(domainDaoMock.search(Mockito.any(SearchCriteria.class), (Filter) org.mockito.ArgumentMatchers.isNull())).thenReturn(new ArrayList<DomainVO>());
Mockito.when(_accountDao.createSearchCriteria()).thenReturn(Mockito.mock(SearchCriteria.class));
Mockito.when(_accountDao.search(Mockito.any(SearchCriteria.class), (Filter) org.mockito.ArgumentMatchers.isNull())).thenReturn(new ArrayList<AccountVO>());
Mockito.when(_networkDomainDao.listNetworkIdsByDomain(Mockito.anyLong())).thenReturn(new ArrayList<Long>());
Mockito.when(_accountDao.findCleanupsForRemovedAccounts(Mockito.anyLong())).thenReturn(new ArrayList<AccountVO>());
Mockito.when(_dedicatedDao.listByDomainId(Mockito.anyLong())).thenReturn(new ArrayList<DedicatedResourceVO>());
Mockito.when(domainDaoMock.remove(Mockito.anyLong())).thenReturn(true);
Mockito.when(_resourceCountDao.removeEntriesByOwner(Mockito.anyLong(), Mockito.eq(ResourceOwnerType.Domain))).thenReturn(1l);
Mockito.when(_resourceLimitDao.removeEntriesByOwner(Mockito.anyLong(), Mockito.eq(ResourceOwnerType.Domain))).thenReturn(1l);
Mockito.when(_configMgr.releaseDomainSpecificVirtualRanges(Mockito.anyLong())).thenReturn(true);
try {
Assert.assertTrue(domainManager.deleteDomain(20l, true));
} finally {
CallContext.unregister();
}
}
@Test
public void validateNetworkDomainTestNullNetworkDomainDoesNotCallVerifyDomainName() {
try (MockedStatic<NetUtils> ignored = Mockito.mockStatic(NetUtils.class)) {
Mockito.when(NetUtils.verifyDomainName(Mockito.anyString())).thenReturn(true);
domainManager.validateNetworkDomain(null);
Mockito.verify(NetUtils.class, Mockito.never());
NetUtils.verifyDomainName(Mockito.anyString());
}
}
@Test (expected = InvalidParameterValueException.class)
public void validateNetworkDomainTestInvalidNetworkDomainThrowsException(){
domainManager.validateNetworkDomain(" t e s t");
}
@Test
public void validateNetworkDomainTestValidNetworkDomainDoesNotThrowException(){
domainManager.validateNetworkDomain("test");
}
@Test (expected = InvalidParameterValueException.class)
public void validateUniqueDomainNameTestExistingNameThrowsException() {
SearchCriteria scMock = Mockito.mock(SearchCriteria.class);
ArrayList<DomainVO> listMock = Mockito.mock(ArrayList.class);
Mockito.doReturn(scMock).when(domainDaoMock).createSearchCriteria();
Mockito.doReturn(listMock).when(domainDaoMock).search(Mockito.any(SearchCriteria.class), Mockito.any());
Mockito.doReturn(false).when(listMock).isEmpty();
domainManager.validateUniqueDomainName("test", 1L);
}
@Test
public void validateUniqueDomainNameTestUniqueNameDoesNotThrowException() {
SearchCriteria scMock = Mockito.mock(SearchCriteria.class);
ArrayList<DomainVO> listMock = Mockito.mock(ArrayList.class);
Mockito.doReturn(scMock).when(domainDaoMock).createSearchCriteria();
Mockito.doReturn(listMock).when(domainDaoMock).search(Mockito.any(SearchCriteria.class), Mockito.any());
Mockito.doReturn(true).when(listMock).isEmpty();
domainManager.validateUniqueDomainName("testUnique", 1L);
Mockito.verify(domainDaoMock).createSearchCriteria();
Mockito.verify(scMock).addAnd("name", SearchCriteria.Op.EQ, "testUnique");
Mockito.verify(scMock).addAnd("parent", SearchCriteria.Op.EQ, 1L);
Mockito.verify(domainDaoMock).search(scMock,null);
Mockito.verify(listMock).isEmpty();
}
@Test
public void createDomainVoTestCreateValidUuidIfEmptyString(){
DomainVO domainVo = domainManager.createDomainVo("test",1L,2L,"NetworkTest","");
Assert.assertTrue(UuidUtils.isUuid(domainVo.getUuid()));
}
@Test
public void createDomainVoTestCreateValidUuidIfWhiteSpace(){
DomainVO domainVo = domainManager.createDomainVo("test",1L,2L,"NetworkTest"," ");
Assert.assertTrue(UuidUtils.isUuid(domainVo.getUuid()));
}
@Test
public void createDomainVoTestCreateValidUuidIfNull(){
DomainVO domainVo = domainManager.createDomainVo("test",1L,2L,"NetworkTest",null);
Assert.assertTrue(UuidUtils.isUuid(domainVo.getUuid()));
}
@Test
public void createDomainVoTestValidInformedUuid(){
DomainVO domainVo = domainManager.createDomainVo("test",1L,2L,"NetworkTest","testUuid");
Assert.assertEquals("testUuid", domainVo.getUuid());
}
@Test
public void createDomainTest(){
Mockito.doNothing().when(domainManager).validateDomainNameAndNetworkDomain(Mockito.any(String.class), Mockito.any(Long.class), Mockito.any(String.class));
DomainVO domainVoMock = Mockito.mock(DomainVO.class);
Mockito.doReturn(domainVoMock).when(domainManager).createDomainVo("test",1L,2L,"netTest","uuidTest");
Mockito.doReturn(domainVoMock).when(domainDaoMock).create(domainVoMock);
try (MockedStatic<CallContext> ignored = Mockito.mockStatic(CallContext.class)) {
CallContext callContextMock = Mockito.mock(CallContext.class);
Mockito.when(CallContext.current()).thenReturn(callContextMock);
Domain actualDomain = domainManager.createDomain("test", 1L, 2L, "netTest", "uuidTest");
Mockito.verify(domainManager).validateDomainNameAndNetworkDomain("test", 1L, "netTest");
Mockito.verify(domainManager).createDomainVo("test", 1L, 2L, "netTest", "uuidTest");
Mockito.verify(domainDaoMock).create(domainVoMock);
Mockito.verify(_resourceCountDao).createResourceCounts(domainVoMock.getId(), ResourceLimit.ResourceOwnerType.Domain);
CallContext.current();
Mockito.verify(callContextMock).putContextParameter(Domain.class, domainVoMock.getUuid());
Mockito.verify(_messageBus).publish("DomainManagerImpl", DomainManager.MESSAGE_ADD_DOMAIN_EVENT, PublishScope.LOCAL, domainVoMock.getId());
Assert.assertEquals(domainVoMock, actualDomain);
}
}
}