package defects.libvirt.unit; import java.util.*; /** * Unit tests for libvirt-0002: x86ModelFromCPU x86FeatureFind O(C×F). */ public class Libvirt0002Test { 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("libvirt-0002 unit tests"); System.out.println("=".repeat(50)); testDefectiveCountsCorrectly(); testFixedCountsCorrectly(); testBothResolveToSameIndices(); testMissingFeatureHandled(); testOpRatioAbove200xAtF500(); testEmptyCpuFeatures(); System.out.println(); System.out.printf("Result: %d passed, %d failed%n", passed, failed); if (failed > 0) System.exit(1); } static void testDefectiveCountsCorrectly() { System.out.println("\n--- testDefectiveCountsCorrectly ---"); int f = 10, c = 3; List mapList = Libvirt0002CpuFeatureFindAlgorithm.buildMapFeatureList(f); // CPU features are the last 3: map-feat-7, map-feat-8, map-feat-9 List cpuFeats = Libvirt0002CpuFeatureFindAlgorithm.buildCpuFeatures(mapList, c); Libvirt0002CpuFeatureFindAlgorithm.DefectiveFeatureFind def = new Libvirt0002CpuFeatureFindAlgorithm.DefectiveFeatureFind(); def.resolveFeatures(cpuFeats, mapList); // Each of the 3 CPU features is at position 7,8,9 → 8+9+10=27 comparisons assertTrue("Defective comparisons = 27 at F=10, C=3 (worst case): " + def.comparisons, def.comparisons == 27); } static void testFixedCountsCorrectly() { System.out.println("\n--- testFixedCountsCorrectly ---"); int f = 10, c = 3; List mapList = Libvirt0002CpuFeatureFindAlgorithm.buildMapFeatureList(f); Map mapIdx = Libvirt0002CpuFeatureFindAlgorithm.buildFeatureIndex(mapList); List cpuFeats = Libvirt0002CpuFeatureFindAlgorithm.buildCpuFeatures(mapList, c); Libvirt0002CpuFeatureFindAlgorithm.FixedFeatureFind fix = new Libvirt0002CpuFeatureFindAlgorithm.FixedFeatureFind(); fix.resolveFeatures(cpuFeats, mapIdx); // Fixed: exactly C hash lookups assertTrue("Fixed comparisons = C = " + c + ": " + fix.comparisons, fix.comparisons == c); } static void testBothResolveToSameIndices() { System.out.println("\n--- testBothResolveToSameIndices ---"); int f = 50, c = 20; List mapList = Libvirt0002CpuFeatureFindAlgorithm.buildMapFeatureList(f); Map mapIdx = Libvirt0002CpuFeatureFindAlgorithm.buildFeatureIndex(mapList); List cpuFeats = Libvirt0002CpuFeatureFindAlgorithm.buildCpuFeatures(mapList, c); Libvirt0002CpuFeatureFindAlgorithm.DefectiveFeatureFind def = new Libvirt0002CpuFeatureFindAlgorithm.DefectiveFeatureFind(); List defResult = def.resolveFeatures(cpuFeats, mapList); Libvirt0002CpuFeatureFindAlgorithm.FixedFeatureFind fix = new Libvirt0002CpuFeatureFindAlgorithm.FixedFeatureFind(); List fixResult = fix.resolveFeatures(cpuFeats, mapIdx); // Sort both for comparison (HashMap ordering may differ from list) Collections.sort(defResult); Collections.sort(fixResult); assertTrue("Both resolve same indices: def=" + defResult + " fix=" + fixResult, defResult.equals(fixResult)); assertTrue("Resolved count = C = " + c, defResult.size() == c); } static void testMissingFeatureHandled() { System.out.println("\n--- testMissingFeatureHandled ---"); List mapList = List.of("feat-a", "feat-b", "feat-c"); Map mapIdx = Map.of("feat-a", 0, "feat-b", 1, "feat-c", 2); List cpuFeats = List.of("feat-a", "feat-MISSING", "feat-c"); Libvirt0002CpuFeatureFindAlgorithm.DefectiveFeatureFind def = new Libvirt0002CpuFeatureFindAlgorithm.DefectiveFeatureFind(); List defResult = def.resolveFeatures(cpuFeats, mapList); Libvirt0002CpuFeatureFindAlgorithm.FixedFeatureFind fix = new Libvirt0002CpuFeatureFindAlgorithm.FixedFeatureFind(); List fixResult = fix.resolveFeatures(cpuFeats, mapIdx); assertTrue("Missing feature skipped (defective): size=2, got=" + defResult.size(), defResult.size() == 2); assertTrue("Missing feature skipped (fixed): size=2, got=" + fixResult.size(), fixResult.size() == 2); assertTrue("Both return {0,2}", defResult.contains(0) && defResult.contains(2) && fixResult.contains(0) && fixResult.contains(2)); } static void testOpRatioAbove200xAtF500() { System.out.println("\n--- testOpRatioAbove200x at F=500, C=100 ---"); int f = 500, c = 100; List mapList = Libvirt0002CpuFeatureFindAlgorithm.buildMapFeatureList(f); Map mapIdx = Libvirt0002CpuFeatureFindAlgorithm.buildFeatureIndex(mapList); List cpuFeats = Libvirt0002CpuFeatureFindAlgorithm.buildCpuFeatures(mapList, c); Libvirt0002CpuFeatureFindAlgorithm.DefectiveFeatureFind def = new Libvirt0002CpuFeatureFindAlgorithm.DefectiveFeatureFind(); def.resolveFeatures(cpuFeats, mapList); Libvirt0002CpuFeatureFindAlgorithm.FixedFeatureFind fix = new Libvirt0002CpuFeatureFindAlgorithm.FixedFeatureFind(); fix.resolveFeatures(cpuFeats, mapIdx); 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 >= 200× at F=500, C=100: " + ratio, ratio >= 200.0); } static void testEmptyCpuFeatures() { System.out.println("\n--- testEmptyCpuFeatures ---"); List mapList = Libvirt0002CpuFeatureFindAlgorithm.buildMapFeatureList(10); Map mapIdx = Libvirt0002CpuFeatureFindAlgorithm.buildFeatureIndex(mapList); List cpuFeats = Collections.emptyList(); Libvirt0002CpuFeatureFindAlgorithm.DefectiveFeatureFind def = new Libvirt0002CpuFeatureFindAlgorithm.DefectiveFeatureFind(); List defResult = def.resolveFeatures(cpuFeats, mapList); assertTrue("Empty CPU features → empty result (defective)", defResult.isEmpty()); Libvirt0002CpuFeatureFindAlgorithm.FixedFeatureFind fix = new Libvirt0002CpuFeatureFindAlgorithm.FixedFeatureFind(); List fixResult = fix.resolveFeatures(cpuFeats, mapIdx); assertTrue("Empty CPU features → empty result (fixed)", fixResult.isEmpty()); } }