package unit; import support.Moad0009Algorithm; import support.Moad0009Algorithm.Event; import support.Moad0009Algorithm.Result; import java.util.List; /** * Unit tests for MOAD-0009: A Metered Heart. * * Proves from first principles: * 1. Defective scheduler fires on every timer tick (N firings for N ticks) * even when only M events occur — N - M firings are wasted. * 2. Fixed event-driven handler fires exactly once per event (M firings for M events). * 3. Both correctly process the same set of events (same events handled). * 4. Defective wastes fire count grows with poll interval; fixed stays constant. * 5. Zero-event scenario: defective fires N times on empty queue; fixed fires 0. * * No build tool required. Compile and run: * * cd tests * java -m jdk.compiler/com.sun.tools.javac.Main -cp . \ * support/Moad0009Algorithm.java unit/Moad0009UnitTest.java * java -cp . unit.Moad0009UnitTest */ public class Moad0009UnitTest { private static int passed = 0; private static int failed = 0; public static void main(String[] args) { System.out.println("=== Moad0009UnitTest (A Metered Heart) ===\n"); System.out.println("-- Correctness: both process the same events --"); testBothProcessSameEvents(); testBothHandleNoEvents(); System.out.println("\n-- Defect: timer fires N times regardless of M events --"); testDefectiveFiresEveryTick(); testDefectiveWastedFiresN100M3(); testDefectiveZeroEventsStillFiresN(); System.out.println("\n-- Fix: fires exactly once per event --"); testFixedFiresExactlyMTimes(); testFixedZeroEventsZeroFirings(); testFixedFireCountEqualsEventCount(); System.out.println("\n-- Comparison: defective wastes grow with poll count; fixed stays M --"); testWastedFiresGrowWithPollCount(); System.out.printf("\n%d passed, %d failed%n", passed, failed); if (failed > 0) System.exit(1); } // ── Correctness ─────────────────────────────────────────────────────────── static void testBothProcessSameEvents() { List events = Moad0009Algorithm.buildEvents(3, 10); Result def = Moad0009Algorithm.runDefectiveScheduler(20, events); Result fix = Moad0009Algorithm.runFixedEventDriven(events); assertEqual("correctness: both process same event count", def.eventsProcessed, fix.eventsProcessed); assertEqual("correctness: both process all 3 events", 3, def.eventsProcessed); } static void testBothHandleNoEvents() { List events = List.of(); Result def = Moad0009Algorithm.runDefectiveScheduler(10, events); Result fix = Moad0009Algorithm.runFixedEventDriven(events); assertEqual("correctness: both process 0 events from empty list", 0, def.eventsProcessed); assertEqual("correctness: fixed: 0 events processed", 0, fix.eventsProcessed); } // ── Defect ──────────────────────────────────────────────────────────────── static void testDefectiveFiresEveryTick() { int ticks = 50; List events = Moad0009Algorithm.buildEvents(2, ticks); Result result = Moad0009Algorithm.runDefectiveScheduler(ticks, events); // DEFECT: fires every tick regardless of events assertEqual("defective: fires exactly N=" + ticks + " times", ticks, result.firings); } static void testDefectiveWastedFiresN100M3() { int ticks = 100; int eventCount = 3; List events = Moad0009Algorithm.buildEvents(eventCount, ticks); Result result = Moad0009Algorithm.runDefectiveScheduler(ticks, events); // DEFECT: 100 firings for 3 events = 97 wasted firings (97% waste) int wasted = result.firings - result.eventsProcessed; assertEqual("defective: 97 wasted firings (100 ticks, 3 events)", 97, wasted); assertTrue("defective: waste ratio > 95%", (double) wasted / result.firings > 0.95, "wasted=" + wasted + " total=" + result.firings); } static void testDefectiveZeroEventsStillFiresN() { int ticks = 60; List events = List.of(); Result result = Moad0009Algorithm.runDefectiveScheduler(ticks, events); // DEFECT: no events exist, but timer still fires 60 times — pure waste assertEqual("defective: 0 events, fires N=" + ticks + " times (100% waste)", ticks, result.firings); assertEqual("defective: 0 events processed", 0, result.eventsProcessed); } // ── Fix ─────────────────────────────────────────────────────────────────── static void testFixedFiresExactlyMTimes() { List events = Moad0009Algorithm.buildEvents(5, 100); Result result = Moad0009Algorithm.runFixedEventDriven(events); assertEqual("fixed: fires exactly M=5 times (one per event)", 5, result.firings); } static void testFixedZeroEventsZeroFirings() { List events = List.of(); Result result = Moad0009Algorithm.runFixedEventDriven(events); assertEqual("fixed: 0 events → 0 firings (no wasted work)", 0, result.firings); } static void testFixedFireCountEqualsEventCount() { for (int m : new int[]{1, 7, 23, 100}) { List events = Moad0009Algorithm.buildEvents(m, 200); Result result = Moad0009Algorithm.runFixedEventDriven(events); assertEqual("fixed: M=" + m + " events → exactly M=" + m + " firings", m, result.firings); } } // ── Comparison ──────────────────────────────────────────────────────────── static void testWastedFiresGrowWithPollCount() { List events = Moad0009Algorithm.buildEvents(2, 200); // More ticks = more waste in defective; fixed stays at M=2 Result def50 = Moad0009Algorithm.runDefectiveScheduler(50, events); Result def200 = Moad0009Algorithm.runDefectiveScheduler(200, events); Result fix = Moad0009Algorithm.runFixedEventDriven(events); assertTrue("defective: 50 ticks → 50 firings", def50.firings == 50, "got " + def50.firings); assertTrue("defective: 200 ticks → 200 firings", def200.firings == 200, "got " + def200.firings); assertTrue("fixed: always 2 firings regardless of tick count", fix.firings == 2, "got " + fix.firings); // Wasted = defective.firings - events processed int waste50 = def50.firings - def50.eventsProcessed; int waste200 = def200.firings - def200.eventsProcessed; assertTrue("defective: waste grows with tick count (200 > 50)", waste200 > waste50, "waste50=" + waste50 + " waste200=" + waste200); } // ── Helpers ─────────────────────────────────────────────────────────────── static void assertEqual(String label, int expected, int actual) { if (expected == actual) { System.out.printf(" PASS: %s%n", label); passed++; } else { System.out.printf(" FAIL: %s — expected %d, got %d%n", label, expected, actual); failed++; } } static void assertTrue(String label, boolean condition, String detail) { if (condition) { System.out.printf(" PASS: %s%n", label); passed++; } else { System.out.printf(" FAIL: %s — %s%n", label, detail); failed++; } } }