package org.ovirt.engine.core.bll; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.when; import java.util.ArrayList; import java.util.Collections; import java.util.Map; import java.util.function.Function; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.Spy; import org.mockito.junit.MockitoJUnitRunner; import org.ovirt.engine.core.common.action.VmSlaPolicyParameters; import org.ovirt.engine.core.common.businessentities.VM; import org.ovirt.engine.core.common.businessentities.VMStatus; import org.ovirt.engine.core.common.businessentities.qos.CpuQos; import org.ovirt.engine.core.common.businessentities.qos.StorageQos; import org.ovirt.engine.core.common.businessentities.storage.DiskImage; import org.ovirt.engine.core.common.errors.EngineMessage; import org.ovirt.engine.core.common.vdscommands.UpdateVmPolicyVDSParams; import org.ovirt.engine.core.common.vdscommands.VDSCommandType; import org.ovirt.engine.core.common.vdscommands.VDSParametersBase; import org.ovirt.engine.core.common.vdscommands.VDSReturnValue; import org.ovirt.engine.core.compat.Guid; import org.ovirt.engine.core.dao.VmDao; import org.ovirt.engine.core.dao.network.VmNetworkInterfaceDao; import org.ovirt.engine.core.vdsbroker.vdsbroker.VdsProperties; @RunWith(MockitoJUnitRunner.class) public class VmSlaPolicyCommandTest { static final Guid VM_ID = Guid.newGuid(); static final Guid DISK_DOMAIN_ID = Guid.newGuid(); static final Guid DISK_POOL_ID = Guid.newGuid(); static final Guid DISK_IMAGE_ID = Guid.newGuid(); static final Guid DISK_VOLUME_ID = Guid.newGuid(); @Mock private VmDao vmDao; @Mock private VmNetworkInterfaceDao vmNetworkInterfaceDao; private VM vm; private DiskImage diskImage; private VmSlaPolicyParameters parameters = new VmSlaPolicyParameters(VM_ID); @Spy @InjectMocks private VmSlaPolicyCommand<VmSlaPolicyParameters> command = new VmSlaPolicyCommand<>(parameters, null); private Function<UpdateVmPolicyVDSParams, Boolean> vdsFunction; @Before public void setUp() { doAnswer(invocation -> { VDSCommandType commandType = (VDSCommandType) invocation.getArguments()[0]; assertEquals(VDSCommandType.UpdateVmPolicy, commandType); UpdateVmPolicyVDSParams params = (UpdateVmPolicyVDSParams) invocation.getArguments()[1]; VDSReturnValue retVal = new VDSReturnValue(); retVal.setSucceeded(vdsFunction.apply(params)); return retVal; }).when(command).runVdsCommand(any(VDSCommandType.class), any(VDSParametersBase.class)); vm = new VM(); vm.setId(VM_ID); vm.setStatus(VMStatus.Up); when(vmDao.get(VM_ID)).thenReturn(vm); diskImage = new DiskImage(); diskImage.setStorageIds(new ArrayList<>()); diskImage.getStorageIds().add(DISK_DOMAIN_ID); diskImage.setStoragePoolId(DISK_POOL_ID); diskImage.setId(DISK_IMAGE_ID); diskImage.setImageId(DISK_VOLUME_ID); } @Test public void testVmDown() { vm.setStatus(VMStatus.Down); ValidateTestUtils.runAndAssertValidateFailure(command, EngineMessage.ACTION_TYPE_FAILED_VM_STATUS_ILLEGAL); } @Test public void testEmptyParams() { parameters.setCpuQos(null); parameters.setStorageQos(Collections.emptyMap()); ValidateTestUtils.runAndAssertValidateFailure(command, EngineMessage.VM_SLA_POLICY_UNCHANGED); } @Test public void testCpuQos() { CpuQos cpuQos = new CpuQos(); cpuQos.setCpuLimit(50); parameters.setCpuQos(cpuQos); vdsFunction = params -> { assertEquals(50, params.getCpuLimit().intValue()); return true; }; assertTrue(command.validate()); command.executeCommand(); assertTrue(command.getReturnValue().getSucceeded()); } @Test public void testCpuQosUnlimited() { CpuQos cpuQos = new CpuQos(); cpuQos.setCpuLimit(null); parameters.setCpuQos(cpuQos); vdsFunction = params -> { assertEquals(100, params.getCpuLimit().intValue()); return true; }; assertTrue(command.validate()); command.executeCommand(); assertTrue(command.getReturnValue().getSucceeded()); } void assertIoTune(UpdateVmPolicyVDSParams.IoTuneParams ioTuneParams, long totalBytesSec, long readBytesSec, long writeBytesSec, long totalIopsSec, long readIopsSec, long writeIopsSec) { assertEquals(ioTuneParams.getDomainId(), DISK_DOMAIN_ID.toString()); assertEquals(ioTuneParams.getPoolId(), DISK_POOL_ID.toString()); assertEquals(ioTuneParams.getImageId(), DISK_IMAGE_ID.toString()); assertEquals(ioTuneParams.getVolumeId(), DISK_VOLUME_ID.toString()); Map<String, Long> ioTune = ioTuneParams.getIoTune(); assertEquals(ioTune.get(VdsProperties.TotalBytesSec).longValue(), totalBytesSec); assertEquals(ioTune.get(VdsProperties.ReadBytesSec).longValue(), readBytesSec); assertEquals(ioTune.get(VdsProperties.WriteBytesSec).longValue(), writeBytesSec); assertEquals(ioTune.get(VdsProperties.TotalIopsSec).longValue(), totalIopsSec); assertEquals(ioTune.get(VdsProperties.ReadIopsSec).longValue(), readIopsSec); assertEquals(ioTune.get(VdsProperties.WriteIopsSec).longValue(), writeIopsSec); } @Test public void testStorageQos() { StorageQos storageQos = new StorageQos(); storageQos.setMaxThroughput(100); storageQos.setMaxIops(60000); parameters.getStorageQos().put(diskImage, storageQos); vdsFunction = params -> { assertIoTune(params.getIoTuneList().get(0), 100L * 1024L * 1024L, 0, 0, 60000, 0, 0); return true; }; assertTrue(command.validate()); command.executeCommand(); assertTrue(command.getReturnValue().getSucceeded()); } @Test public void testStorageQosUnlimited() { parameters.getStorageQos().put(diskImage, new StorageQos()); vdsFunction = params -> { assertIoTune(params.getIoTuneList().get(0), 0, 0, 0, 0, 0, 0); return true; }; assertTrue(command.validate()); command.executeCommand(); assertTrue(command.getReturnValue().getSucceeded()); } }