java-topology/defects/xen/unit/Xen0001Test.java

209 lines
9.3 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package defects.xen.unit;
import java.util.*;
/**
* Unit tests for xen-0001: credit2 balance_load O(V²) VCPU swap-search.
*/
public class Xen0001Test {
static int passed = 0;
static int failed = 0;
static void assertTrue(String label, boolean condition) {
if (condition) {
System.out.println(" PASS: " + label);
passed++;
} else {
System.out.println(" FAIL: " + label);
failed++;
}
}
public static void main(String[] args) {
System.out.println("xen-0001 unit tests");
System.out.println("=".repeat(50));
testDefectiveIsQuadratic();
testFixedIsLinear();
testBothFindSameWinner();
testNoMigratable();
testSingleVcpu();
testLoadRatioAbove50x();
System.out.println();
System.out.printf("Result: %d passed, %d failed%n", passed, failed);
if (failed > 0) System.exit(1);
}
static void testDefectiveIsQuadratic() {
System.out.println("\n--- testDefectiveIsQuadratic ---");
Xen0001CreditBalanceLoadAlgorithm.DefectiveBalanceLoad d =
new Xen0001CreditBalanceLoadAlgorithm.DefectiveBalanceLoad();
int v1 = 10, v2 = 20;
List<Xen0001CreditBalanceLoadAlgorithm.Vcpu> l1 =
Xen0001CreditBalanceLoadAlgorithm.buildSvcList(v1, 100, false);
List<Xen0001CreditBalanceLoadAlgorithm.Vcpu> o1 =
Xen0001CreditBalanceLoadAlgorithm.buildSvcList(v1, 50, false);
d.findBestSwap(l1, o1,
Xen0001CreditBalanceLoadAlgorithm.totalLoad(l1),
Xen0001CreditBalanceLoadAlgorithm.totalLoad(o1));
int ops1 = d.comparisons;
List<Xen0001CreditBalanceLoadAlgorithm.Vcpu> l2 =
Xen0001CreditBalanceLoadAlgorithm.buildSvcList(v2, 100, false);
List<Xen0001CreditBalanceLoadAlgorithm.Vcpu> o2 =
Xen0001CreditBalanceLoadAlgorithm.buildSvcList(v2, 50, false);
d.findBestSwap(l2, o2,
Xen0001CreditBalanceLoadAlgorithm.totalLoad(l2),
Xen0001CreditBalanceLoadAlgorithm.totalLoad(o2));
int ops2 = d.comparisons;
// Doubling V should roughly quadruple ops
double ratio = (double) ops2 / ops1;
assertTrue("Defective ops grows quadratically (ratio ≈ 4×): " + ratio,
ratio >= 3.5 && ratio <= 4.5);
}
static void testFixedIsLinear() {
System.out.println("\n--- testFixedIsLinear ---");
Xen0001CreditBalanceLoadAlgorithm.FixedBalanceLoad f =
new Xen0001CreditBalanceLoadAlgorithm.FixedBalanceLoad();
int v1 = 50, v2 = 100;
List<Xen0001CreditBalanceLoadAlgorithm.Vcpu> l1 =
Xen0001CreditBalanceLoadAlgorithm.buildSvcList(v1, 100, true);
List<Xen0001CreditBalanceLoadAlgorithm.Vcpu> o1 =
Xen0001CreditBalanceLoadAlgorithm.buildSvcList(v1, 50, true);
f.findBestSwap(l1, o1,
Xen0001CreditBalanceLoadAlgorithm.totalLoad(l1),
Xen0001CreditBalanceLoadAlgorithm.totalLoad(o1));
int ops1 = f.comparisons;
List<Xen0001CreditBalanceLoadAlgorithm.Vcpu> l2 =
Xen0001CreditBalanceLoadAlgorithm.buildSvcList(v2, 100, true);
List<Xen0001CreditBalanceLoadAlgorithm.Vcpu> o2 =
Xen0001CreditBalanceLoadAlgorithm.buildSvcList(v2, 50, true);
f.findBestSwap(l2, o2,
Xen0001CreditBalanceLoadAlgorithm.totalLoad(l2),
Xen0001CreditBalanceLoadAlgorithm.totalLoad(o2));
int ops2 = f.comparisons;
// Fixed ops should be O(1) or at most O(V) — not O(V²)
assertTrue("Fixed ops does not grow quadratically (ops1=" + ops1 + " ops2=" + ops2 + ")",
ops2 <= ops1 * 4); // generous bound: well below V² ratio of 4
assertTrue("Fixed ops is bounded (ops1 <= 4): " + ops1, ops1 <= 4);
assertTrue("Fixed ops is bounded (ops2 <= 4): " + ops2, ops2 <= 4);
}
static void testBothFindSameWinner() {
System.out.println("\n--- testBothFindSameWinner ---");
// Imbalanced runqueues: lrqd very heavy, orqd light
List<Xen0001CreditBalanceLoadAlgorithm.Vcpu> lrqd = new ArrayList<>();
lrqd.add(new Xen0001CreditBalanceLoadAlgorithm.Vcpu(1, 1000, true));
lrqd.add(new Xen0001CreditBalanceLoadAlgorithm.Vcpu(2, 500, true));
lrqd.add(new Xen0001CreditBalanceLoadAlgorithm.Vcpu(3, 200, false));
List<Xen0001CreditBalanceLoadAlgorithm.Vcpu> orqd = new ArrayList<>();
orqd.add(new Xen0001CreditBalanceLoadAlgorithm.Vcpu(10, 100, true));
orqd.add(new Xen0001CreditBalanceLoadAlgorithm.Vcpu(11, 50, true));
long lLoad = 1700, oLoad = 150;
Xen0001CreditBalanceLoadAlgorithm.DefectiveBalanceLoad def =
new Xen0001CreditBalanceLoadAlgorithm.DefectiveBalanceLoad();
Xen0001CreditBalanceLoadAlgorithm.SwapPair defPair =
def.findBestSwap(lrqd, orqd, lLoad, oLoad);
// Sorted descending by avgload for fixed
List<Xen0001CreditBalanceLoadAlgorithm.Vcpu> lrqdS = new ArrayList<>(lrqd);
List<Xen0001CreditBalanceLoadAlgorithm.Vcpu> orqdS = new ArrayList<>(orqd);
lrqdS.sort((a, b) -> Long.compare(b.avgload, a.avgload));
orqdS.sort((a, b) -> Long.compare(b.avgload, a.avgload));
Xen0001CreditBalanceLoadAlgorithm.FixedBalanceLoad fix =
new Xen0001CreditBalanceLoadAlgorithm.FixedBalanceLoad();
Xen0001CreditBalanceLoadAlgorithm.SwapPair fixPair =
fix.findBestSwap(lrqdS, orqdS, lLoad, oLoad);
assertTrue("Both defective and fixed find a swap pair",
defPair != null && fixPair != null);
// Both should choose the heaviest push (id=1, load=1000)
assertTrue("Both push the heaviest VCPU (id=1)",
defPair != null && defPair.push.id == 1 &&
fixPair != null && fixPair.push.id == 1);
}
static void testNoMigratable() {
System.out.println("\n--- testNoMigratable ---");
List<Xen0001CreditBalanceLoadAlgorithm.Vcpu> lrqd = new ArrayList<>();
lrqd.add(new Xen0001CreditBalanceLoadAlgorithm.Vcpu(1, 500, false));
lrqd.add(new Xen0001CreditBalanceLoadAlgorithm.Vcpu(2, 300, false));
List<Xen0001CreditBalanceLoadAlgorithm.Vcpu> orqd = new ArrayList<>();
orqd.add(new Xen0001CreditBalanceLoadAlgorithm.Vcpu(10, 100, false));
Xen0001CreditBalanceLoadAlgorithm.DefectiveBalanceLoad def =
new Xen0001CreditBalanceLoadAlgorithm.DefectiveBalanceLoad();
Xen0001CreditBalanceLoadAlgorithm.SwapPair defPair =
def.findBestSwap(lrqd, orqd, 800, 100);
assertTrue("No swap when no VCPUs are migratable (defective): pair=null",
defPair == null);
Xen0001CreditBalanceLoadAlgorithm.FixedBalanceLoad fix =
new Xen0001CreditBalanceLoadAlgorithm.FixedBalanceLoad();
Xen0001CreditBalanceLoadAlgorithm.SwapPair fixPair =
fix.findBestSwap(lrqd, orqd, 800, 100);
assertTrue("No swap when no VCPUs are migratable (fixed): pair=null",
fixPair == null);
}
static void testSingleVcpu() {
System.out.println("\n--- testSingleVcpu ---");
List<Xen0001CreditBalanceLoadAlgorithm.Vcpu> lrqd = List.of(
new Xen0001CreditBalanceLoadAlgorithm.Vcpu(1, 200, true));
List<Xen0001CreditBalanceLoadAlgorithm.Vcpu> orqd = List.of(
new Xen0001CreditBalanceLoadAlgorithm.Vcpu(2, 50, true));
Xen0001CreditBalanceLoadAlgorithm.DefectiveBalanceLoad def =
new Xen0001CreditBalanceLoadAlgorithm.DefectiveBalanceLoad();
def.findBestSwap(lrqd, orqd, 200, 50);
assertTrue("Single VCPU: defective comparisons=1", def.comparisons == 1);
Xen0001CreditBalanceLoadAlgorithm.FixedBalanceLoad fix =
new Xen0001CreditBalanceLoadAlgorithm.FixedBalanceLoad();
fix.findBestSwap(lrqd, orqd, 200, 50);
assertTrue("Single VCPU: fixed comparisons <= 2", fix.comparisons <= 2);
}
static void testLoadRatioAbove50x() {
System.out.println("\n--- testLoadRatioAbove50x (V=100) ---");
int v = 100;
Xen0001CreditBalanceLoadAlgorithm.DefectiveBalanceLoad def =
new Xen0001CreditBalanceLoadAlgorithm.DefectiveBalanceLoad();
Xen0001CreditBalanceLoadAlgorithm.FixedBalanceLoad fix =
new Xen0001CreditBalanceLoadAlgorithm.FixedBalanceLoad();
List<Xen0001CreditBalanceLoadAlgorithm.Vcpu> lrqd =
Xen0001CreditBalanceLoadAlgorithm.buildSvcList(v, 100, false);
List<Xen0001CreditBalanceLoadAlgorithm.Vcpu> orqd =
Xen0001CreditBalanceLoadAlgorithm.buildSvcList(v, 50, false);
long lLoad = Xen0001CreditBalanceLoadAlgorithm.totalLoad(lrqd);
long oLoad = Xen0001CreditBalanceLoadAlgorithm.totalLoad(orqd);
def.findBestSwap(lrqd, orqd, lLoad, oLoad);
List<Xen0001CreditBalanceLoadAlgorithm.Vcpu> lS =
Xen0001CreditBalanceLoadAlgorithm.buildSvcList(v, 100, true);
List<Xen0001CreditBalanceLoadAlgorithm.Vcpu> oS =
Xen0001CreditBalanceLoadAlgorithm.buildSvcList(v, 50, true);
fix.findBestSwap(lS, oS, lLoad, oLoad);
double ratio = (double) def.comparisons / Math.max(fix.comparisons, 1);
System.out.printf(" defective=%d, fixed=%d, ratio=%.1f×%n",
def.comparisons, fix.comparisons, ratio);
assertTrue("Op-count ratio >= 50× at V=100: " + ratio, ratio >= 50.0);
}
}