package org.ovirt.engine.core.bll.validator.storage;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.anyCollection;
import static org.mockito.Mockito.when;
import static org.ovirt.engine.core.bll.validator.ValidationResultMatchers.failsWith;
import static org.ovirt.engine.core.bll.validator.ValidationResultMatchers.isValid;
import static org.ovirt.engine.core.utils.MockConfigRule.mockConfig;
import java.util.Collections;
import org.junit.Before;
import org.junit.ClassRule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;
import org.ovirt.engine.core.bll.ValidationResult;
import org.ovirt.engine.core.bll.storage.utils.BlockStorageDiscardFunctionalityHelper;
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.storage.StorageType;
import org.ovirt.engine.core.common.config.ConfigValues;
import org.ovirt.engine.core.common.errors.EngineMessage;
import org.ovirt.engine.core.compat.Version;
import org.ovirt.engine.core.di.InjectorRule;
import org.ovirt.engine.core.utils.MockConfigRule;
/**
* A test case for the {@link org.ovirt.engine.core.bll.validator.storage.StorageDomainValidator} class.
* The hasSpaceForClonedDisk() and hasSpaceForNewDisk() methods are covered separately in
* {@link org.ovirt.engine.core.bll.validator.storage.StorageDomainValidatorFreeSpaceTest}.
*/
@RunWith(MockitoJUnitRunner.class)
public class StorageDomainValidatorTest {
private StorageDomain domain;
private StorageDomainValidator validator;
private static final int CRITICAL_SPACE_THRESHOLD = 5;
@ClassRule
public static InjectorRule injectorRule = new InjectorRule();
@ClassRule
public static MockConfigRule mcr = new MockConfigRule(
mockConfig(ConfigValues.DiscardAfterDeleteSupported, Version.v4_0, false));
@Mock
private BlockStorageDiscardFunctionalityHelper discardFunctionalityHelper;
@Before
public void setUp() {
domain = new StorageDomain();
validator = new StorageDomainValidator(domain);
}
@Test
public void testIsDomainExistAndActiveDomainNotExists() {
validator = new StorageDomainValidator(null);
assertThat("Wrong failure for null domain",
validator.isDomainExistAndActive(),
failsWith(EngineMessage.ACTION_TYPE_FAILED_STORAGE_DOMAIN_NOT_EXIST));
}
@Test
public void testIsDomainExistAndActiveDomainNotUp() {
domain.setStatus(StorageDomainStatus.Inactive);
assertThat("Wrong failure for inactive domain",
validator.isDomainExistAndActive(),
failsWith(EngineMessage.ACTION_TYPE_FAILED_STORAGE_DOMAIN_STATUS_ILLEGAL2));
}
@Test
public void testIsDomainExistAndActiveDomainUp() {
domain.setStatus(StorageDomainStatus.Active);
assertThat("domain should be up", validator.isDomainExistAndActive(), isValid());
}
@Test
public void testDomainWithNotEnoughSpace() {
validator = new StorageDomainValidator(mockStorageDomain(3, 756, StorageType.NFS));
assertThat("Wrong failure for not enough space",
validator.isDomainWithinThresholds(),
failsWith(EngineMessage.ACTION_TYPE_FAILED_DISK_SPACE_LOW_ON_STORAGE_DOMAIN));
}
@Test
public void testDomainWithEnoughSpace() {
validator = new StorageDomainValidator(mockStorageDomain(6, 756, StorageType.NFS));
assertThat("Domain should have more space then threshold", validator.isDomainWithinThresholds(), isValid());
}
@Test
public void testIsDataDomainValid() {
domain.setStorageDomainType(StorageDomainType.Data);
assertThat(validator.isDataDomain(), isValid());
}
@Test
public void testIsDataDomainFails() {
domain.setStorageDomainType(StorageDomainType.ISO);
assertThat(validator.isDataDomain(),
failsWith(EngineMessage.ACTION_TYPE_FAILED_ACTION_IS_SUPPORTED_ONLY_FOR_DATA_DOMAINS));
}
@Test
public void discardAfterDeleteDisabled() {
assertDiscardAfterDeleteUpdate(false, StorageType.ISCSI, false, ValidationResult.VALID);
}
@Test
public void discardAfterDeleteNotSupportedByFileDomains() {
assertDiscardAfterDeleteUpdate(true, StorageType.NFS, false, new ValidationResult(
EngineMessage.ACTION_TYPE_FAILED_DISCARD_AFTER_DELETE_SUPPORTED_ONLY_BY_BLOCK_DOMAINS));
}
@Test
public void discardAfterDeleteNotSupportedByUnderlyingStorage() {
ValidationResult result = new ValidationResult(
EngineMessage.ACTION_TYPE_FAILED_DISCARD_AFTER_DELETE_NOT_SUPPORTED_BY_UNDERLYING_STORAGE,
String.format("$storageDomainName %s", domain.getName()));
assertDiscardAfterDeleteUpdate(true, StorageType.ISCSI, false, result);
}
@Test
public void discardAfterDeleteLegal() {
assertDiscardAfterDeleteUpdate(true, StorageType.ISCSI, true, ValidationResult.VALID);
}
@Test
public void discardAfterDeleteLegalForExistingStorageDomainPredicateTrue() {
domain.setSupportsDiscard(true);
assertTrue(validator.discardAfterDeleteLegalForExistingStorageDomainPredicate());
}
@Test
public void discardAfterDeleteLegalForExistingStorageDomainPredicateFalse() {
domain.setSupportsDiscard(false);
assertFalse(validator.discardAfterDeleteLegalForExistingStorageDomainPredicate());
}
@Test
public void discardAfterDeleteLegalForExistingStorageDomainPredicateNull() {
domain.setSupportsDiscard(null);
assertFalse(validator.discardAfterDeleteLegalForExistingStorageDomainPredicate());
}
@Test
public void getDiscardAfterDeleteLegalForNewBlockStorageDomainPredicateWithSupportiveLuns() {
assertGetDiscardAfterDeleteLegalForNewBlockStorageDomainPredicate(true);
}
@Test
public void getDiscardAfterDeleteLegalForNewBlockStorageDomainPredicateWithUnsupportiveLuns() {
assertGetDiscardAfterDeleteLegalForNewBlockStorageDomainPredicate(false);
}
@Test
public void discardAfterDeleteSupportedByDcVersion() {
domain.setDiscardAfterDelete(true);
assertThat(validator.isDiscardAfterDeleteSupportedByDcVersion(Version.v4_1), isValid());
}
@Test
public void discardAfterDeleteNotSupportedByDcVersion() {
domain.setDiscardAfterDelete(true);
assertThat(validator.isDiscardAfterDeleteSupportedByDcVersion(Version.v4_0),
failsWith(EngineMessage.ACTION_TYPE_FAILED_DISCARD_AFTER_DELETE_NOT_SUPPORTED_BY_DC_VERSION));
}
private static StorageDomain mockStorageDomain(int availableSize, int usedSize, StorageType storageType) {
StorageDomain sd = new StorageDomain();
sd.setAvailableDiskSize(availableSize);
sd.setUsedDiskSize(usedSize);
sd.setStatus(StorageDomainStatus.Active);
sd.setStorageType(storageType);
sd.setCriticalSpaceActionBlocker(CRITICAL_SPACE_THRESHOLD);
return sd;
}
private void assertDiscardAfterDeleteUpdate(boolean discardAfterDelete, StorageType storageType,
boolean supportsDiscard, ValidationResult result) {
domain.setDiscardAfterDelete(discardAfterDelete);
domain.setStorageType(storageType);
domain.setSupportsDiscard(supportsDiscard);
assertEquals(validator.isDiscardAfterDeleteLegal(() -> supportsDiscard), result);
}
private void assertGetDiscardAfterDeleteLegalForNewBlockStorageDomainPredicate(boolean allLunsSupportDiscard) {
injectorRule.bind(BlockStorageDiscardFunctionalityHelper.class, discardFunctionalityHelper);
when(discardFunctionalityHelper.allLunsSupportDiscard(anyCollection())).thenReturn(allLunsSupportDiscard);
assertEquals(
validator.getDiscardAfterDeleteLegalForNewBlockStorageDomainPredicate(Collections.emptyList()).get(),
allLunsSupportDiscard);
}
}