package org.ovirt.engine.core.bll.storage.domain;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import static org.mockito.Mockito.withSettings;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import org.junit.Test;
import org.mockito.Answers;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.ovirt.engine.core.bll.BaseCommandTest;
import org.ovirt.engine.core.common.action.StorageDomainParametersBase;
import org.ovirt.engine.core.common.businessentities.StorageDomain;
import org.ovirt.engine.core.common.businessentities.StorageDomainStatus;
import org.ovirt.engine.core.common.businessentities.StorageDomainType;
import org.ovirt.engine.core.common.businessentities.StoragePool;
import org.ovirt.engine.core.common.businessentities.storage.LUNs;
import org.ovirt.engine.core.common.businessentities.storage.StorageType;
import org.ovirt.engine.core.common.errors.EngineMessage;
import org.ovirt.engine.core.compat.Guid;
import org.ovirt.engine.core.dao.LunDao;
import org.ovirt.engine.core.dao.StorageDomainDao;
public class StorageDomainCommandBaseTest extends BaseCommandTest {
private static final Guid[] GUIDS = new Guid[] {
new Guid("11111111-1111-1111-1111-111111111111"),
new Guid("22222222-2222-2222-2222-222222222222")
};
private final Guid HE_SD_ID = new Guid("33333333-3333-3333-3333-333333333333");
private final Guid SHARED_SD_ID = new Guid("44444444-4444-4444-4444-444444444444");
private final Guid LOCAL_SD_ID = new Guid("55555555-5555-5555-5555-555555555555");
private static final String HE_STORAGE_DOMAIN_NAME = "heStorageDomain";
@Mock
private LunDao lunDao;
@Mock
private StorageDomainDao storageDomainDao;
@InjectMocks
public StorageDomainCommandBase<StorageDomainParametersBase> cmd =
mock(StorageDomainCommandBase.class,
withSettings().defaultAnswer(Answers.CALLS_REAL_METHODS).useConstructor(new StorageDomainParametersBase(), null));
@Test
public void statusMatches() {
setStorageDomainStatus(StorageDomainStatus.Inactive);
assertTrue(cmd.checkStorageDomainStatus(StorageDomainStatus.Inactive));
assertFalse(commandHasInvalidStatusMessage());
}
@Test
public void statusIsNull() {
setStorageDomainStatus(null);
assertFalse(cmd.checkStorageDomainStatus(StorageDomainStatus.Inactive));
assertTrue(commandHasInvalidStatusMessage());
}
@Test
public void statusNotMatch() {
setStorageDomainStatus(StorageDomainStatus.Inactive);
assertFalse(cmd.checkStorageDomainStatus(StorageDomainStatus.Active));
assertTrue(commandHasInvalidStatusMessage());
}
@Test
public void statusInList() {
setStorageDomainStatus(StorageDomainStatus.Inactive);
assertTrue(cmd.checkStorageDomainStatus(StorageDomainStatus.Locked, StorageDomainStatus.Inactive,
StorageDomainStatus.Unknown));
assertFalse(commandHasInvalidStatusMessage());
}
@Test
public void statusNotInList() {
setStorageDomainStatus(StorageDomainStatus.Inactive);
assertFalse(cmd.checkStorageDomainStatus(StorageDomainStatus.Locked, StorageDomainStatus.Active,
StorageDomainStatus.Unknown));
assertTrue(commandHasInvalidStatusMessage());
}
@Test
public void canDetachInactiveDomain() {
setStorageDomainStatus(StorageDomainStatus.Inactive);
storagePoolExists();
masterDomainIsUp();
canDetachDomain();
assertTrue(cmd.canDetachDomain(false, false));
}
@Test
public void canDetachMaintenanceDomain() {
setStorageDomainStatus(StorageDomainStatus.Inactive);
storagePoolExists();
masterDomainIsUp();
canDetachDomain();
assertTrue(cmd.canDetachDomain(false, false));
}
@Test
public void checkCinderStorageDomainContainDisks() {
setCinderStorageDomainStatus(StorageDomainStatus.Inactive);
storagePoolExists();
cinderStorageDomainContainsDisks();
masterDomainIsUp();
canDetachDomain();
assertFalse(cmd.canDetachDomain(false, false));
}
@Test
public void checkStorageDomainNotEqualWithStatusActive() {
setStorageDomainStatus(StorageDomainStatus.Active);
assertFalse(cmd.checkStorageDomainStatusNotEqual(StorageDomainStatus.Active));
List<String> messages = cmd.getReturnValue().getValidationMessages();
assertEquals(2, messages.size());
assertEquals(messages.get(0), EngineMessage.ACTION_TYPE_FAILED_STORAGE_DOMAIN_STATUS_ILLEGAL2.toString());
assertEquals(messages.get(1), String.format("$status %1$s", StorageDomainStatus.Active));
}
@Test
public void checkStorageDomainNotEqualWithNonActiveStatus() {
setStorageDomainStatus(StorageDomainStatus.Maintenance);
assertTrue(cmd.checkStorageDomainStatusNotEqual(StorageDomainStatus.Active));
}
@Test
public void lunAlreadyPartOfStorageDomains() {
LUNs lun1 = new LUNs();
lun1.setLUNId(GUIDS[0].toString());
lun1.setStorageDomainId(Guid.newGuid());
LUNs lun2 = new LUNs();
lun2.setLUNId(GUIDS[1].toString());
lun2.setStorageDomainId(Guid.newGuid());
when(lunDao.getAll()).thenReturn(Arrays.asList(lun1, lun2));
List<String> specifiedLunIds = Collections.singletonList(GUIDS[0].toString());
assertTrue(cmd.isLunsAlreadyInUse(specifiedLunIds));
List<String> messages = cmd.getReturnValue().getValidationMessages();
assertEquals(2, messages.size());
assertEquals(messages.get(0), EngineMessage.ACTION_TYPE_FAILED_LUNS_ALREADY_PART_OF_STORAGE_DOMAINS.toString());
assertEquals(messages.get(1), String.format("$lunIds %1$s", cmd.getFormattedLunId(lun1, lun1.getStorageDomainName())));
}
@Test
public void shouldElectActiveDataDomain() {
final StorageDomain domain = prepareStorageDomainForElection(StorageDomainStatus.Active,
"not he domain name", false);
assertEquals(domain, cmd.electNewMaster());
}
@Test
public void shouldNotElectActiveHostedEngineDomain() {
prepareStorageDomainForElection(StorageDomainStatus.Active, HE_STORAGE_DOMAIN_NAME, true);
assertNull(cmd.electNewMaster());
}
@Test
public void shouldNotElectUnknownHostedEngineDomain() {
prepareStorageDomainForElection(StorageDomainStatus.Unknown, HE_STORAGE_DOMAIN_NAME, true);
assertNull(cmd.electNewMaster());
}
@Test
public void shouldNotElectInactiveHostedEngineDomain() {
prepareStorageDomainForElection(StorageDomainStatus.Inactive, HE_STORAGE_DOMAIN_NAME, true);
assertNull(cmd.electNewMaster(false, true, false));
}
@Test
public void shouldElectActiveSharedDataDomain() {
final StorageDomain domain =
prepareSharedStorageDomainForElection(StorageDomainStatus.Active);
assertEquals(domain, cmd.electNewMaster());
}
@Test
public void shouldElectActiveLocalDataDomain() {
StorageDomain domain = prepareLocalStorageDomainForElection(StorageDomainStatus.Active);
assertEquals(domain, cmd.electNewMaster());
}
@Test
public void shouldElectActiveSharedBeforeLocalDataDomain() {
StorageDomain localDomain =
createDataStorageDomain(StorageDomainStatus.Active, "local domain name", LOCAL_SD_ID);
localDomain.setStorageType(StorageType.LOCALFS);
StorageDomain sharedDomain =
createDataStorageDomain(StorageDomainStatus.Active, "shared domain name", SHARED_SD_ID);
when(storageDomainDao.getAllForStoragePool(any(Guid.class))).thenReturn(Arrays.asList(localDomain, sharedDomain));
cmd.setStoragePool(new StoragePool());
assertEquals(sharedDomain, cmd.electNewMaster());
}
@Test
public void shouldElectActiveSharedBeforeLocalDataDomain2() {
StorageDomain localDomain =
createDataStorageDomain(StorageDomainStatus.Active, "local domain name", LOCAL_SD_ID);
localDomain.setStorageType(StorageType.LOCALFS);
StorageDomain sharedDomain =
createDataStorageDomain(StorageDomainStatus.Active, "shared domain name", SHARED_SD_ID);
when(storageDomainDao.getAllForStoragePool(any(Guid.class))).thenReturn(Arrays.asList(sharedDomain, localDomain));
cmd.setStoragePool(new StoragePool());
assertEquals(sharedDomain, cmd.electNewMaster());
}
@Test
public void shouldElectStorageTypeAfterLastUsedAsMasterDataDomain() {
StorageDomain localDomain =
createDataStorageDomain(StorageDomainStatus.Active, "local domain name", LOCAL_SD_ID);
localDomain.setLastTimeUsedAsMaster(System.currentTimeMillis() - 1000);
localDomain.setStorageType(StorageType.LOCALFS);
StorageDomain sharedDomain =
createDataStorageDomain(StorageDomainStatus.Active, "shared domain name", SHARED_SD_ID);
sharedDomain.setLastTimeUsedAsMaster(System.currentTimeMillis());
when(storageDomainDao.getAllForStoragePool(any(Guid.class))).thenReturn(Arrays.asList(sharedDomain, localDomain));
cmd.setStoragePool(new StoragePool());
assertEquals(localDomain, cmd.electNewMaster());
}
@Test
public void shouldElectStorageTypeAfterLastUsedAsMasterDataDomain2() {
StorageDomain localDomain =
createDataStorageDomain(StorageDomainStatus.Active, "local domain name", LOCAL_SD_ID);
localDomain.setLastTimeUsedAsMaster(System.currentTimeMillis());
localDomain.setStorageType(StorageType.LOCALFS);
StorageDomain sharedDomain =
createDataStorageDomain(StorageDomainStatus.Active, "shared domain name", SHARED_SD_ID);
sharedDomain.setLastTimeUsedAsMaster(System.currentTimeMillis() - 1000);
when(storageDomainDao.getAllForStoragePool(any(Guid.class))).thenReturn(Arrays.asList(sharedDomain, localDomain));
cmd.setStoragePool(new StoragePool());
assertEquals(sharedDomain, cmd.electNewMaster());
}
private StorageDomain prepareLocalStorageDomainForElection(StorageDomainStatus status) {
final StorageDomain localDomain = createDataStorageDomain(status, "local domain name", LOCAL_SD_ID);
localDomain.setStorageType(StorageType.LOCALFS);
when(storageDomainDao.getAllForStoragePool(any(Guid.class))).thenReturn(Collections.singletonList(localDomain));
cmd.setStoragePool(new StoragePool());
return localDomain;
}
private StorageDomain prepareSharedStorageDomainForElection(StorageDomainStatus status) {
final StorageDomain sharedDomain = createDataStorageDomain(status, "shared domain name", SHARED_SD_ID);
when(storageDomainDao.getAllForStoragePool(any(Guid.class))).thenReturn(Collections.singletonList(sharedDomain));
cmd.setStoragePool(new StoragePool());
return sharedDomain;
}
private StorageDomain prepareStorageDomainForElection(StorageDomainStatus status,
String name,
boolean isHostedEngine) {
final StorageDomain domain = createDataStorageDomain(status, name, HE_SD_ID);
domain.setHostedEngineStorage(isHostedEngine);
when(storageDomainDao.getAllForStoragePool(any(Guid.class))).thenReturn(Collections.singletonList(domain));
cmd.setStoragePool(new StoragePool());
return domain;
}
private StorageDomain createDataStorageDomain(StorageDomainStatus status, String name, Guid sdId) {
final StorageDomain storageDomain = new StorageDomain();
storageDomain.setStorageName(name);
storageDomain.setStatus(status);
storageDomain.setStorageDomainType(StorageDomainType.Data);
storageDomain.setId(sdId);
storageDomain.setHostedEngineStorage(false);
return storageDomain;
}
private void storagePoolExists() {
when(cmd.checkStoragePool()).thenReturn(true);
}
private void masterDomainIsUp() {
doReturn(true).when(cmd).checkMasterDomainIsUp();
}
private void cinderStorageDomainContainsDisks() {
doReturn(false).when(cmd).isCinderStorageHasNoDisks();
}
private void canDetachDomain() {
doReturn(true).when(cmd).isDetachAllowed(anyBoolean());
}
private boolean commandHasInvalidStatusMessage() {
return cmd.getReturnValue().getValidationMessages().contains(
EngineMessage.ACTION_TYPE_FAILED_STORAGE_DOMAIN_STATUS_ILLEGAL2.toString());
}
private void setStorageDomainStatus(StorageDomainStatus status) {
StorageDomain domain = new StorageDomain();
domain.setStatus(status);
when(cmd.getStorageDomain()).thenReturn(domain);
}
private void setCinderStorageDomainStatus(StorageDomainStatus status) {
StorageDomain domain = new StorageDomain();
domain.setStatus(status);
domain.setStorageType(StorageType.CINDER);
when(cmd.getStorageDomain()).thenReturn(domain);
}
}