package org.ovirt.engine.core.vdsbroker.vdsbroker;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.assertj.core.api.Assertions;
import org.junit.Before;
import org.junit.Test;
import org.ovirt.engine.core.common.businessentities.NumaNodeStatistics;
import org.ovirt.engine.core.common.businessentities.NumaTuneMode;
import org.ovirt.engine.core.common.businessentities.VdsNumaNode;
import org.ovirt.engine.core.common.businessentities.VmNumaNode;
import org.ovirt.engine.core.compat.Guid;
public class NumaSettingFactoryTest {
private static NumaTuneMode numaTuneMode;
private static List<VdsNumaNode> vdsNumaNodes;
private static List<VmNumaNode> vmNumaNodes;
@Before
public void setUp() throws Exception {
numaTuneMode = NumaTuneMode.INTERLEAVE;
vdsNumaNodes = createTestVdsNumaNodes();
vmNumaNodes = createTestVmNumaNodes();
}
@Test
public void testBuildVmNumaNodeSetting() throws Exception {
List<Map<String, Object>> vmNumaNodesSetting =
NumaSettingFactory.buildVmNumaNodeSetting(vmNumaNodes);
assertEquals(2, vmNumaNodesSetting.size());
assertTrue(vmNumaNodesSetting.get(0).containsKey(VdsProperties.NUMA_NODE_INDEX));
assertEquals(0, vmNumaNodesSetting.get(0).get(VdsProperties.NUMA_NODE_INDEX));
assertTrue(vmNumaNodesSetting.get(0).containsKey(VdsProperties.NUMA_NODE_CPU_LIST));
assertEquals("0,1,2,3", vmNumaNodesSetting.get(0).get(VdsProperties.NUMA_NODE_CPU_LIST));
assertTrue(vmNumaNodesSetting.get(1).containsKey(VdsProperties.VM_NUMA_NODE_MEM));
assertEquals("1024", vmNumaNodesSetting.get(1).get(VdsProperties.VM_NUMA_NODE_MEM));
}
@Test
public void testBuildCpuPinningWithNumaSetting() throws Exception {
Map<String, Object> cpuPinning =
NumaSettingFactory.buildCpuPinningWithNumaSetting(vmNumaNodes, vdsNumaNodes);
assertEquals(8, cpuPinning.size());
assertTrue(cpuPinning.containsKey("3"));
assertEquals("0,1,2,3", cpuPinning.get("3"));
assertTrue(cpuPinning.containsKey("7"));
assertEquals("4,5,6,7", cpuPinning.get("7"));
}
@Test
public void shouldNotCreateCpuPinningForVirtualNumaNodes() {
for (VmNumaNode numaNode : vmNumaNodes) {
numaNode.getVdsNumaNodeList().clear();
}
Map<String, Object> cpuPinning =
NumaSettingFactory.buildCpuPinningWithNumaSetting(vmNumaNodes, vdsNumaNodes);
Assertions.assertThat(cpuPinning).isEmpty();
Map<String, Object> mapping =
NumaSettingFactory.buildVmNumatuneSetting(NumaTuneMode.INTERLEAVE, vmNumaNodes);
Assertions.assertThat(mapping).doesNotContainKeys(VdsProperties.NUMA_TUNE_MODE, VdsProperties.NUMA_TUNE_NODESET);
}
@Test
public void testBuildVmNumatuneSetting() throws Exception {
Map<String, Object> numaTune =
NumaSettingFactory.buildVmNumatuneSetting(numaTuneMode, vmNumaNodes);
assertEquals(2, numaTune.size());
assertTrue(numaTune.containsKey(VdsProperties.NUMA_TUNE_MODE));
assertEquals(NumaTuneMode.INTERLEAVE.getValue(), numaTune.get(VdsProperties.NUMA_TUNE_MODE));
assertTrue(numaTune.containsKey(VdsProperties.NUMA_TUNE_MEMNODES));
List<Map<String, String>> memNodes =
(List<Map<String, String>>) numaTune.get(VdsProperties.NUMA_TUNE_MEMNODES);
assertEquals("0", memNodes.get(0).get(VdsProperties.NUMA_TUNE_VM_NODE_INDEX));
assertEquals("0", memNodes.get(0).get(VdsProperties.NUMA_TUNE_NODESET));
assertEquals("1", memNodes.get(1).get(VdsProperties.NUMA_TUNE_VM_NODE_INDEX));
assertEquals("1", memNodes.get(1).get(VdsProperties.NUMA_TUNE_NODESET));
}
private static List<VmNumaNode> createTestVmNumaNodes() {
List<VmNumaNode> newVmNodes = new ArrayList<>();
VmNumaNode newVmNumaNode = new VmNumaNode();
newVmNumaNode.setCpuIds(generateCpuList(0, 4));
newVmNumaNode.setId(Guid.newGuid());
newVmNumaNode.setIndex(0);
newVmNumaNode.setMemTotal(1024);
newVmNumaNode.getVdsNumaNodeList().add(0);
newVmNodes.add(newVmNumaNode);
newVmNumaNode = new VmNumaNode();
newVmNumaNode.setCpuIds(generateCpuList(4, 4));
newVmNumaNode.setId(Guid.newGuid());
newVmNumaNode.setIndex(1);
newVmNumaNode.setMemTotal(1024);
newVmNumaNode.getVdsNumaNodeList().add(1);
newVmNodes.add(newVmNumaNode);
return newVmNodes;
}
private static List<VdsNumaNode> createTestVdsNumaNodes() {
NumaNodeStatistics newNodeStatistics = new NumaNodeStatistics();
newNodeStatistics.setCpuUsagePercent(20);
newNodeStatistics.setMemUsagePercent(50);
List<VdsNumaNode> newVdsNodes = new ArrayList<>();
VdsNumaNode newVdsNumaNode= new VdsNumaNode();
newVdsNumaNode.setCpuIds(generateCpuList(0, 4));
newVdsNumaNode.setId(Guid.newGuid());
newVdsNumaNode.setIndex(0);
newVdsNumaNode.setNumaNodeDistances(generateDistance(2, 0));
newVdsNumaNode.setNumaNodeStatistics(newNodeStatistics);
newVdsNodes.add(newVdsNumaNode);
newVdsNumaNode= new VdsNumaNode();
newVdsNumaNode.setCpuIds(generateCpuList(4, 4));
newVdsNumaNode.setId(Guid.newGuid());
newVdsNumaNode.setIndex(1);
newVdsNumaNode.setNumaNodeDistances(generateDistance(2, 1));
newVdsNumaNode.setNumaNodeStatistics(newNodeStatistics);
newVdsNodes.add(newVdsNumaNode);
return newVdsNodes;
}
private static List<Integer> generateCpuList(int fromIndex, int count) {
List<Integer> cpuList = new ArrayList<>(count);
for (int i = fromIndex; i < (fromIndex + count); i++) {
cpuList.add(i);
}
return cpuList;
}
private static Map<Integer, Integer> generateDistance(int nodeCount, int selfNodeIndex) {
Map<Integer, Integer> distance = new HashMap<>(nodeCount);
for (int i = 0; i < nodeCount; i++) {
distance.put(i, (Math.abs(selfNodeIndex - i) + 1) * 10);
}
return distance;
}
}