package org.ovirt.engine.core.bll.scheduling.policyunits;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import org.junit.ClassRule;
import org.junit.Test;
import org.ovirt.engine.core.bll.scheduling.PolicyUnitParameter;
import org.ovirt.engine.core.bll.scheduling.external.BalanceResult;
import org.ovirt.engine.core.common.businessentities.BusinessEntity;
import org.ovirt.engine.core.common.businessentities.Cluster;
import org.ovirt.engine.core.common.businessentities.VDS;
import org.ovirt.engine.core.common.businessentities.VM;
import org.ovirt.engine.core.common.config.ConfigValues;
import org.ovirt.engine.core.compat.Guid;
import org.ovirt.engine.core.utils.MockConfigRule;
public class EvenDistributionBalancePolicyUnitTest extends CpuAndMemoryBalancingPolicyUnitTest {
static final Guid DESTINATION_HOST = new Guid("087fc691-de02-11e4-8830-0800200c9a66");
@ClassRule
public static MockConfigRule configRule =
new MockConfigRule(
MockConfigRule.mockConfig(ConfigValues.MaxSchedulerWeight, Integer.MAX_VALUE),
MockConfigRule.mockConfig(ConfigValues.HighUtilizationForEvenlyDistribute, 80),
MockConfigRule.mockConfig(ConfigValues.LowUtilizationForEvenlyDistribute, 20),
MockConfigRule.mockConfig(ConfigValues.CpuOverCommitDurationMinutes, 5),
MockConfigRule.mockConfig(ConfigValues.VcpuConsumptionPercentage, 20),
MockConfigRule.mockConfig(ConfigValues.UtilizationThresholdInPercent, 80)
);
@Test
public void testBalanceCpuLoad() throws Exception {
Map<Guid, BusinessEntity<Guid>> cache = newCache();
final Map<Guid, VDS> hosts = loadHosts("basic_balancing_hosts_cpu_load.csv", cache);
final Map<Guid, VM> vms = loadVMs("basic_balancing_vms.csv", cache);
Cluster cluster = new Cluster();
Map<String, String> parameters = new HashMap<>();
parameters.put(PolicyUnitParameter.HIGH_MEMORY_LIMIT_FOR_UNDER_UTILIZED.getDbName(), "900");
parameters.put(PolicyUnitParameter.LOW_MEMORY_LIMIT_FOR_OVER_UTILIZED.getDbName(), "512");
ArrayList<String> messages = new ArrayList<>();
EvenDistributionBalancePolicyUnit unit = mockUnit(EvenDistributionBalancePolicyUnit.class, cluster, hosts, vms);
Optional<BalanceResult> result = unit.balance(cluster, new ArrayList<>(hosts.values()), parameters, messages);
assertNotNull(result);
assertTrue(result.isPresent());
assertTrue(result.get().isValid());
assertNotNull(result.get().getVmToMigrate());
assertEquals(2, result.get().getCandidateHosts().size());
assertEquals(DESTINATION_HOST, result.get().getCandidateHosts().get(0));
}
@Test
public void testBalanceMemoryLoad() throws Exception {
Map<Guid, BusinessEntity<Guid>> cache = newCache();
final Map<Guid, VDS> hosts = loadHosts("basic_balancing_hosts_mem_load.csv", cache);
final Map<Guid, VM> vms = loadVMs("basic_balancing_vms.csv", cache);
Cluster cluster = new Cluster();
Map<String, String> parameters = new HashMap<>();
parameters.put(PolicyUnitParameter.HIGH_MEMORY_LIMIT_FOR_UNDER_UTILIZED.getDbName(), "900");
parameters.put(PolicyUnitParameter.LOW_MEMORY_LIMIT_FOR_OVER_UTILIZED.getDbName(), "512");
ArrayList<String> messages = new ArrayList<>();
EvenDistributionBalancePolicyUnit unit = mockUnit(EvenDistributionBalancePolicyUnit.class, cluster, hosts, vms);
Optional<BalanceResult> result = unit.balance(cluster, new ArrayList<>(hosts.values()), parameters, messages);
assertNotNull(result);
assertTrue(result.isPresent());
assertTrue(result.get().isValid());
assertNotNull(result.get().getVmToMigrate());
List<Guid> candidateHosts = validMigrationTargets(unit, result);
assertEquals(1, candidateHosts.size());
assertEquals(DESTINATION_HOST, candidateHosts.get(0));
}
/**
* Test situation where all hosts are either CPU or Memory over utilized.
*/
@Test
public void testBalanceCpuAndMemoryLoad() throws Exception {
Map<Guid, BusinessEntity<Guid>> cache = newCache();
final Map<Guid, VDS> hosts = loadHosts("basic_balancing_hosts_cpumem_load.csv", cache);
final Map<Guid, VM> vms = loadVMs("basic_balancing_vms.csv", cache);
Cluster cluster = new Cluster();
Map<String, String> parameters = new HashMap<>();
parameters.put(PolicyUnitParameter.HIGH_MEMORY_LIMIT_FOR_UNDER_UTILIZED.getDbName(), "900");
parameters.put(PolicyUnitParameter.LOW_MEMORY_LIMIT_FOR_OVER_UTILIZED.getDbName(), "512");
ArrayList<String> messages = new ArrayList<>();
EvenDistributionBalancePolicyUnit unit = mockUnit(EvenDistributionBalancePolicyUnit.class, cluster, hosts, vms);
Optional<BalanceResult> result = unit.balance(cluster, new ArrayList<>(hosts.values()), parameters, messages);
assert !result.isPresent();
}
/**
* Test a scenario where a host is CPU overloaded and the destination has some memory load but
* not too much so it is able to receive the VM.
*/
@Test
public void testBalanceCpuAndMediumMemoryLoad() throws Exception {
Map<Guid, BusinessEntity<Guid>> cache = newCache();
final Map<Guid, VDS> hosts = loadHosts("basic_balancing_hosts_cpumem_medium_load.csv", cache);
final Map<Guid, VM> vms = loadVMs("basic_balancing_vms.csv", cache);
Cluster cluster = new Cluster();
Map<String, String> parameters = new HashMap<>();
parameters.put(PolicyUnitParameter.HIGH_MEMORY_LIMIT_FOR_UNDER_UTILIZED.getDbName(), "900");
parameters.put(PolicyUnitParameter.LOW_MEMORY_LIMIT_FOR_OVER_UTILIZED.getDbName(), "300");
ArrayList<String> messages = new ArrayList<>();
EvenDistributionBalancePolicyUnit unit = mockUnit(EvenDistributionBalancePolicyUnit.class, cluster, hosts, vms);
Optional<BalanceResult> result = unit.balance(cluster, new ArrayList<>(hosts.values()), parameters, messages);
assertNotNull(result);
assertTrue(result.isPresent());
assertTrue(result.get().isValid());
assertNotNull(result.get().getVmToMigrate());
List<Guid> candidateHosts = validMigrationTargets(unit, result);
assertEquals(1, candidateHosts.size());
assertEquals(DESTINATION_HOST, candidateHosts.get(0));
}
/**
* Test a scenario where a host is CPU overloaded and the destination has some memory load but
* it is too much to receive the VM.
*/
@Test
public void testBalanceCpuAndHighMemoryLoad() throws Exception {
Map<Guid, BusinessEntity<Guid>> cache = newCache();
final Map<Guid, VDS> hosts = loadHosts("basic_balancing_hosts_cpumem_medium_load.csv", cache);
final Map<Guid, VM> vms = loadVMs("basic_balancing_vms.csv", cache);
Cluster cluster = new Cluster();
Map<String, String> parameters = new HashMap<>();
parameters.put(PolicyUnitParameter.HIGH_MEMORY_LIMIT_FOR_UNDER_UTILIZED.getDbName(), "900");
parameters.put(PolicyUnitParameter.LOW_MEMORY_LIMIT_FOR_OVER_UTILIZED.getDbName(), "512");
ArrayList<String> messages = new ArrayList<>();
EvenDistributionBalancePolicyUnit unit = mockUnit(EvenDistributionBalancePolicyUnit.class, cluster, hosts, vms);
Optional<BalanceResult> result = unit.balance(cluster, new ArrayList<>(hosts.values()), parameters, messages);
assert !result.isPresent();
}
}