package com.vmware.vhadoop.vhm; import java.util.Arrays; import java.util.HashSet; import java.util.PriorityQueue; import java.util.Set; import static org.junit.Assert.*; import org.junit.Test; import com.vmware.vhadoop.api.vhm.strategy.VMChooser; import com.vmware.vhadoop.api.vhm.strategy.VMChooser.RankedVM; public class VMChooserTests { private abstract class TestVMChooser implements VMChooser { abstract boolean acceptVM(String vmId, boolean powerState); abstract int rankVM(String vmId, boolean targetPowerState); @Override public Set<String> chooseVMsToEnable(String clusterId, Set<String> candidateVmIds) { Set<String> result = new HashSet<String>(); for (String vmId : candidateVmIds) { if (acceptVM(vmId, true)) { result.add(vmId); } } return result; } @Override public Set<String> chooseVMsToDisable(String clusterId, Set<String> candidateVmIds) { Set<String> result = new HashSet<String>(); for (String vmId : candidateVmIds) { if (acceptVM(vmId, false)) { result.add(vmId); } } return result; } @Override public Set<RankedVM> rankVMsToEnable(String clusterId, Set<String> candidateVmIds) { Set<RankedVM> result = new HashSet<RankedVM>(); for (String vmId : candidateVmIds) { result.add(new RankedVM(vmId, rankVM(vmId, true))); } return result; } @Override public Set<RankedVM> rankVMsToDisable(String clusterId, Set<String> candidateVmIds) { Set<RankedVM> result = new HashSet<RankedVM>(); for (String vmId : candidateVmIds) { result.add(new RankedVM(vmId, rankVM(vmId, false))); } return result; } } @Test public void testTrivial() { String clusterId = "notUsed"; TestVMChooser vmChooser = new TestVMChooser() { @Override /* Rank VMs based on the trailing character */ int rankVM(String vmId, boolean powerState) { char lastChar = vmId.charAt(vmId.length()-1); return lastChar; } @Override /* Choose VMs only if their ID is 3 chars long */ boolean acceptVM(String vmId, boolean powerState) { return (vmId.length() == 3); } }; Set<String> poweredOffVMs = new HashSet<String>(Arrays.asList(new String[]{"vm2", "vma1"})); Set<String> poweredOnVMs = new HashSet<String>(Arrays.asList(new String[]{"vm4", "vma3"})); Set<String> chosen = vmChooser.chooseVMsToEnable(clusterId, poweredOffVMs); assertEquals(1, chosen.size()); assertEquals("vm2", chosen.iterator().next()); chosen = vmChooser.chooseVMsToDisable(clusterId, poweredOnVMs); assertEquals(1, chosen.size()); assertEquals("vm4", chosen.iterator().next()); Set<RankedVM> ranked = vmChooser.rankVMsToEnable(clusterId, poweredOffVMs); assertEquals(2, ranked.size()); assertEquals("vma1", RankedVM.selectLowestRankedIds(ranked, 1).iterator().next()); ranked = vmChooser.rankVMsToDisable(clusterId, poweredOnVMs); assertEquals(2, ranked.size()); assertEquals("vma3", RankedVM.selectLowestRankedIds(ranked, 1).iterator().next()); } @Test public void testCombineRankings() { String clusterId = "notUsed"; TestVMChooser vmChooser1 = new TestVMChooser() { @Override /* Rank VMs based on the literal value of the trailing character */ int rankVM(String vmId, boolean powerState) { char lastChar = vmId.charAt(vmId.length()-1); return Integer.parseInt(""+lastChar); } @Override /* Choose VMs only if their ID is 4 chars long */ boolean acceptVM(String vmId, boolean powerState) { return (vmId.length() == 4); } }; TestVMChooser vmChooser2 = new TestVMChooser() { @Override /* Rank VMs based on the literal value of the first character */ int rankVM(String vmId, boolean powerState) { char firstChar = vmId.charAt(0); return Integer.parseInt(""+firstChar); } @Override /* Choose VMs only if their ID is not 4 chars long */ boolean acceptVM(String vmId, boolean powerState) { return (vmId.length() != 4); } }; Set<String> poweredOffVMs = new HashSet<String>(Arrays.asList(new String[]{"9vm0", "8vm1", "7vm2", "4vma5", "3vma6", "0vma9"})); Set<String> poweredOnVMs = new HashSet<String>(Arrays.asList(new String[]{"6vm3", "5vm4", "2vma7", "1vma8"})); Set<RankedVM> ranked1 = vmChooser1.rankVMsToEnable(clusterId, poweredOffVMs); assertEquals(6, ranked1.size()); assertEquals("9vm0", RankedVM.selectLowestRankedIds(ranked1, 1).iterator().next()); Set<RankedVM> ranked2 = vmChooser2.rankVMsToEnable(clusterId, poweredOffVMs); assertEquals(6, ranked2.size()); assertEquals("0vma9", RankedVM.selectLowestRankedIds(ranked2, 1).iterator().next()); Set<RankedVM> result = RankedVM.combine(ranked1, null); assertEquals(6, result.size()); result = RankedVM.combine(null, ranked2); assertEquals(6, result.size()); result = RankedVM.combine(ranked1, ranked2); for (RankedVM rankedVM : result) { assertEquals(9, rankedVM.getRank()); } } @Test public void testFlattenRankValues() { String clusterId = "notUsed"; TestVMChooser vmChooser = new TestVMChooser() { @Override /* Rank VMs based on a multiple of the value of the trailing character */ int rankVM(String vmId, boolean powerState) { char lastChar = vmId.charAt(vmId.length()-1); return Integer.parseInt(""+lastChar) * 13; } @Override /* Choose VMs only if their ID is 4 chars long */ boolean acceptVM(String vmId, boolean powerState) { return false; } }; Set<String> poweredOffVMs = new HashSet<String>(Arrays.asList(new String[]{"vm0", "vm5", "vma5", "vm7", "vma7", "vmb7", "vm9"})); Set<RankedVM> ranked = vmChooser.rankVMsToEnable(clusterId, poweredOffVMs); assertEquals(7, ranked.size()); Set<RankedVM> flattened = RankedVM.flattenRankValues(ranked); assertEquals(7, flattened.size()); int[] expected = new int[]{0, 1, 1, 2, 2, 2, 3}; PriorityQueue<RankedVM> orderedQueue = new PriorityQueue<RankedVM>(flattened); for (int cntr = 0; cntr < expected.length; cntr++) { assertEquals(expected[cntr], orderedQueue.poll().getRank()); } } }