package org.ovirt.engine.core.bll.numa.vm;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import static org.ovirt.engine.core.bll.utils.NumaTestUtils.createVdsNumaNode;
import static org.ovirt.engine.core.bll.utils.NumaTestUtils.createVmNumaNode;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.function.Function;
import org.junit.Test;
import org.ovirt.engine.core.bll.ValidateTestUtils;
import org.ovirt.engine.core.common.action.VmNumaNodeOperationParameters;
import org.ovirt.engine.core.common.businessentities.MigrationSupport;
import org.ovirt.engine.core.common.errors.EngineMessage;
import org.ovirt.engine.core.compat.Guid;
public class AddVmNumaNodesCommandTest
extends AbstractVmNumaNodeCommandTestBase<AddVmNumaNodesCommand<VmNumaNodeOperationParameters>> {
@Override
protected Function<VmNumaNodeOperationParameters, AddVmNumaNodesCommand<VmNumaNodeOperationParameters>>
commandCreator() {
return p -> new AddVmNumaNodesCommand<>(p, null);
}
protected void initNumaNodes() {
vdsNumaNodes = new ArrayList<>(Arrays.asList(createVdsNumaNode(1), createVdsNumaNode(2), createVdsNumaNode(3)));
existingNumaNodes = new ArrayList<>(Arrays.asList(createVmNumaNode(0), createVmNumaNode(1)));
paramNumaNodes.addAll(Arrays.asList(createVmNumaNode(2), createVmNumaNode(3)));
}
@Test
public void canSetNumaConfigurationWithVmFromParams() {
mockCommandWithVmFromParams();
command.executeCommand();
verify(vmNumaNodeDao).massSaveNumaNode(eq(paramNumaNodes), any(Guid.class));
}
@Test
public void canSetNumaConfigurationWithVmFromDb() {
mockCommandWithVmFromDb();
command.executeCommand();
verify(vmNumaNodeDao).massSaveNumaNode(eq(paramNumaNodes), any(Guid.class));
}
@Test
public void canSetNumaPinning() {
paramNumaNodes.clear();
paramNumaNodes.add(createVmNumaNode(1, vdsNumaNodes));
mockCommandWithVmFromParams();
command.executeCommand();
verify(vmNumaNodeDao).massSaveNumaNode(eq(paramNumaNodes), any(Guid.class));
}
@Test
public void canDetectMissingVM() {
when(vmDao.get(eq(vm.getId()))).thenReturn(null);
mockCommandWithVmFromDb();
ValidateTestUtils.runAndAssertValidateFailure(command,
EngineMessage.ACTION_TYPE_FAILED_VM_NOT_FOUND);
}
@Test
public void canDetectZeroHostNodesWithVmFromParams() {
vdsNumaNodes.clear();
mockCommandWithVmFromParams();
ValidateTestUtils.runAndAssertValidateFailure(command,
EngineMessage.VM_NUMA_PINNED_VDS_NODE_EMPTY);
}
@Test
public void canDetectMissingRequiredHostNumaNodes() {
existingNumaNodes.set(0, createVmNumaNode(0, vdsNumaNodes));
vdsNumaNodes.remove(0);
mockCommandWithVmFromParams();
ValidateTestUtils.runAndAssertValidateFailure(command,
EngineMessage.VM_NUMA_NODE_HOST_NODE_INVALID_INDEX);
}
@Test
public void canDetectZeroHostNodesWithVmFromDb() {
vdsNumaNodes.clear();
mockCommandWithVmFromDb();
ValidateTestUtils.runAndAssertValidateFailure(command,
EngineMessage.VM_NUMA_PINNED_VDS_NODE_EMPTY);
}
@Test
public void validateWithPinnedHostOnVm() {
mockCommandWithVmFromDb();
assertThat(command.validate()).isTrue();
}
@Test
public void canOnlyDoWithPinnedToHostPolicy() {
mockCommandWithVmFromDb();
vm.setMigrationSupport(MigrationSupport.MIGRATABLE);
ValidateTestUtils.runAndAssertValidateFailure(command,
EngineMessage.ACTION_TYPE_FAILED_VM_NOT_PINNED_TO_HOST);
}
@Test
public void canNotDoWithoutPinnedHost() {
mockCommandWithVmFromDb();
vm.setMigrationSupport(MigrationSupport.MIGRATABLE);
vm.setDedicatedVmForVdsList(new ArrayList<>());
ValidateTestUtils.runAndAssertValidateFailure(command,
EngineMessage.ACTION_TYPE_FAILED_VM_NOT_PINNED_TO_HOST);
}
@Test
public void canNotDoWithTwoPinnedHost() {
mockCommandWithVmFromDb();
vm.setDedicatedVmForVdsList(Arrays.asList(Guid.newGuid(), Guid.newGuid()));
ValidateTestUtils.runAndAssertValidateFailure(command,
EngineMessage.ACTION_TYPE_FAILED_VM_PINNED_TO_MULTIPLE_HOSTS);
}
@Test
public void canCreateAsMuchNumaNodesAsVirtualCores() {
mockCommandWithVmFromDb();
vm.setNumOfSockets(1);
vm.setCpuPerSocket(4);
assertThat(command.validate()).isTrue();
}
@Test
public void canCreateLessNumaNodesAsVirtualCores() {
mockCommandWithVmFromDb();
vm.setNumOfSockets(1);
vm.setCpuPerSocket(5);
assertThat(command.validate()).isTrue();
}
@Test
public void failCreateMoreNumaNodesThanVirtualCoresWithVmFromDb() {
mockCommandWithVmFromDb();
vm.setNumOfSockets(1);
vm.setCpuPerSocket(3);
ValidateTestUtils.runAndAssertValidateFailure(command, EngineMessage.VM_NUMA_NODE_MORE_NODES_THAN_CPUS);
}
@Test
public void failCreateMoreNumaNodesThanVirtualCoresWithVmFromParams() {
mockCommandWithVmFromParams();
vm.setNumOfSockets(1);
vm.setCpuPerSocket(3);
ValidateTestUtils.runAndAssertValidateFailure(command, EngineMessage.VM_NUMA_NODE_MORE_NODES_THAN_CPUS);
}
@Test
public void canDetectDuplicateNumaNodes() {
paramNumaNodes.clear();
paramNumaNodes.addAll(Arrays.asList(createVmNumaNode(10), createVmNumaNode(10)));
mockCommandWithVmFromParams();
ValidateTestUtils.runAndAssertValidateFailure(command,
EngineMessage.VM_NUMA_NODE_INDEX_DUPLICATE);
}
@Test
public void canDetectNonContinuousNumaNodeIndices() {
paramNumaNodes.clear();
paramNumaNodes.addAll(Arrays.asList(createVmNumaNode(2), createVmNumaNode(4)));
mockCommandWithVmFromParams();
ValidateTestUtils.runAndAssertValidateFailure(command,
EngineMessage.VM_NUMA_NODE_NON_CONTINUOUS_INDEX);
}
}