package org.ovirt.engine.core.bll;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyList;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner.Strict;
import org.ovirt.engine.core.common.action.AddVmParameters;
import org.ovirt.engine.core.common.businessentities.ArchitectureType;
import org.ovirt.engine.core.common.businessentities.MigrationSupport;
import org.ovirt.engine.core.common.businessentities.OsType;
import org.ovirt.engine.core.common.businessentities.Quota;
import org.ovirt.engine.core.common.businessentities.VM;
import org.ovirt.engine.core.common.businessentities.VmStatic;
import org.ovirt.engine.core.common.errors.EngineMessage;
import org.ovirt.engine.core.compat.Guid;
import org.ovirt.engine.core.compat.Version;
import org.ovirt.engine.core.dao.QuotaDao;
import org.ovirt.engine.core.utils.MockConfigRule;
@RunWith(Strict.class)
public class AddVmCommandTest extends AddVmCommandTestBase<AddVmCommand<AddVmParameters>> {
@Rule
public MockConfigRule mcr = new MockConfigRule();
@Mock
private QuotaDao quotaDao;
@Override
protected AddVmCommand<AddVmParameters> createCommand() {
initVM();
return new AddVmCommand<>(new AddVmParameters(vm), null);
}
@Override
public void setUp() {
super.setUp();
generateStorageToDisksMap();
initDestSDs();
}
@Test
public void canAddVm() {
List<String> reasons = new ArrayList<>();
doNothing().when(cmd).initTemplateDisks();
initCommandMethods();
cmd.init();
doReturn(true).when(cmd).validateCustomProperties(any(VmStatic.class), anyList());
doReturn(true).when(cmd).validateSpaceRequirements();
assertTrue("vm could not be added", cmd.canAddVm(reasons, Collections.singletonList(createStorageDomain())));
}
@Test
public void isVirtioScsiEnabledDefaultedToTrue() {
cmd.getParameters().getVm().setClusterId(cluster.getId());
cmd.initEffectiveCompatibilityVersion();
when(osRepository.getDiskInterfaces(anyInt(), any(Version.class))).thenReturn(
new ArrayList<>(Collections.singletonList("VirtIO_SCSI")));
assertTrue("isVirtioScsiEnabled hasn't been defaulted to true on cluster >= 3.3.", cmd.isVirtioScsiEnabled());
}
@Test
public void validateSpaceAndThreshold() {
assertTrue(cmd.validateSpaceRequirements());
verify(storageDomainValidator, times(TOTAL_NUM_DOMAINS)).hasSpaceForNewDisks(anyList());
verify(storageDomainValidator, never()).hasSpaceForClonedDisks(anyList());
}
@Test
public void validateSpaceNotEnough() throws Exception {
doReturn(new ValidationResult(EngineMessage.ACTION_TYPE_FAILED_DISK_SPACE_LOW_ON_STORAGE_DOMAIN)).
when(storageDomainValidator).hasSpaceForNewDisks(anyList());
assertFalse(cmd.validateSpaceRequirements());
verify(storageDomainValidator).hasSpaceForNewDisks(anyList());
verify(storageDomainValidator, never()).hasSpaceForClonedDisks(anyList());
}
@Test
public void validateSpaceNotWithinThreshold() throws Exception {
doReturn(new ValidationResult(EngineMessage.ACTION_TYPE_FAILED_DISK_SPACE_LOW_ON_STORAGE_DOMAIN)).
when(storageDomainValidator).isDomainWithinThresholds();
assertFalse(cmd.validateSpaceRequirements());
}
private void initPpcCluster() {
initCluster();
cluster.setCpuName("PPC8");
cluster.setArchitecture(ArchitectureType.ppc64);
}
@Test
public void testBeanValidations() {
assertTrue(cmd.validateInputs());
}
@Test
public void testPatternBasedNameFails() {
cmd.getParameters().getVm().setName("aa-??bb");
assertFalse("Pattern-based name should not be supported for VM", cmd.validateInputs());
}
@Test
public void refuseBalloonOnPPC() {
setupCanAddPpcTest();
cmd.getParameters().setBalloonEnabled(true);
doNothing().when(cmd).initTemplateDisks();
cmd.init();
ValidateTestUtils.runAndAssertValidateFailure(cmd, EngineMessage.BALLOON_REQUESTED_ON_NOT_SUPPORTED_ARCH);
}
@Test
public void refuseSoundDeviceOnPPC() {
doNothing().when(cmd).initTemplateDisks();
setupCanAddPpcTest();
cmd.getParameters().setSoundDeviceEnabled(true);
cmd.init();
ValidateTestUtils.runAndAssertValidateFailure(cmd, EngineMessage.SOUND_DEVICE_REQUESTED_ON_NOT_SUPPORTED_ARCH);
}
private void setupCanAddPpcTest() {
doReturn(true).when(cmd).buildAndCheckDestStorageDomains();
cmd.getParameters().getVm().setClusterArch(ArchitectureType.ppc64);
cluster.setArchitecture(ArchitectureType.ppc64);
cluster.setCompatibilityVersion(Version.getLast());
}
@Test
public void testStoragePoolDoesntExist() {
doReturn(null).when(cmd).getStoragePool();
ValidateTestUtils.runAndAssertValidateFailure(cmd, EngineMessage.ACTION_TYPE_FAILED_STORAGE_POOL_NOT_EXIST);
}
@Test
public void testBlockUseHostCpuWithPPCArch() {
when(cpuFlagsManagerHandler.getCpuId(anyString(), any(Version.class))).thenReturn(CPU_ID);
when(osRepository.isCpuSupported(anyInt(), any(Version.class), anyString())).thenReturn(true);
doNothing().when(cmd).initTemplateDisks();
setupCanAddPpcTest();
cmd.setEffectiveCompatibilityVersion(Version.v4_0);
doReturn(Collections.emptyList()).when(cmd).getImagesToCheckDestinationStorageDomains();
initPpcCluster();
doReturn(true).when(cmd).validateAddVmCommand();
doReturn(true).when(cmd).isVmNameValidLength(any(VM.class));
when(osRepository.getArchitectureFromOS(anyInt())).thenReturn(ArchitectureType.ppc64);
cmd.getParameters().getVm().setClusterArch(ArchitectureType.ppc64);
cmd.getParameters().getVm().setUseHostCpuFlags(true);
cmd.getParameters().getVm().setMigrationSupport(MigrationSupport.PINNED_TO_HOST);
cmd.getParameters().getVm().setClusterId(cluster.getId());
cmd.getParameters().getVm().setVmOs(OsType.Other.ordinal());
cmd.init();
ValidateTestUtils.runAndAssertValidateFailure(cmd, EngineMessage.USE_HOST_CPU_REQUESTED_ON_UNSUPPORTED_ARCH);
}
@Test
public void testValidQuota() {
Guid quotaId = Guid.newGuid();
Quota quota = new Quota();
quota.setId(quotaId);
when(quotaDao.getById(quotaId)).thenReturn(quota);
quota.setStoragePoolId(storagePool.getId());
cmd.getParameters().getVm().setQuotaId(quotaId);
assertTrue(cmd.validateQuota(quotaId));
assertTrue(cmd.getReturnValue().getValidationMessages().isEmpty());
}
@Test
public void testNonExistingQuota() {
Guid quotaId = Guid.newGuid();
cmd.getParameters().getVm().setQuotaId(quotaId);
assertFalse(cmd.validateQuota(quotaId));
ValidateTestUtils.assertValidationMessages("", cmd, EngineMessage.ACTION_TYPE_FAILED_QUOTA_NOT_EXIST);
}
}