Each MOAD now has a synthetic defective specimen and fixed specimen proven from first principles across three test tiers: Unit (tests/unit/Moad000X*.java): - Correctness: defective and fixed produce identical functional output - Defect behavior: defective specimen exhibits the defect (measurable) - Fix behavior: fixed specimen eliminates the defect Integration (tests/integration/AllMoadsIntegrationTest.java): - All 9 MOADs proven at medium scale (N=500-2000) - MOAD-0001: O(N^2) vs O(N) list scan at N=1000 - MOAD-0002: 500 sessions trample each other (defective) vs coexist (fixed) - MOAD-0003: 250 anonymous requests leak auth identity (defective) vs zero (fixed) - MOAD-0004: 3000 credential exposures across 1000 requests (defective) vs zero (fixed) - MOAD-0005: 500 computes for 500 concurrent misses vs exactly 1 - MOAD-0006: all 500 passwords extractable from DB (defective) vs unextractable (fixed) - MOAD-0007: N=2000 spatial objects, defective visits all 2000 vs O(log N + k) - MOAD-0009: 990 wasted firings for 1000 ticks / 10 events vs zero waste - MOAD-0011: 10240 NFA steps vs 13 steps on N=12 adversarial input (788x) Functional (tests/functional/AllMoadsFunctionalTest.java): - MOAD-0005: real-thread contention proves herd (defective >1 compute, fixed exactly 1) - MOAD-0007: N=50000 spatial objects, 50M defective probes vs 516K fixed (97x speedup) - MOAD-0009: 10000 ticks / 10 events, 9990 wasted firings vs zero (1000x ratio) - MOAD-0011: N=16 adversarial, 163840 defective steps vs 17 fixed (9638x ratio) Support algorithms (tests/support/Moad000X*.java): - Moad0002Algorithm: shared mutable global state (DefectiveAudioSystem / FixedAudioSystem + Context) - Moad0003Algorithm: ThreadLocal not cleared (handleDefective / handleFixed with finally) - Moad0004Algorithm: HTTP headers logged verbatim (logDefective / logFixed with CREDENTIAL_HEADERS denylist) - Moad0005Algorithm: get+null+compute+put (DefectiveCache HashMap / FixedCache ConcurrentHashMap.computeIfAbsent) - Moad0006Algorithm: Base64 password storage (DefectiveCredentialStore / FixedCredentialStore SHA-256+salt) - Moad0007Algorithm: linear spatial scan (queryDefective list / queryFixed sorted array + binary search) - Moad0009Algorithm: timer-driven polling (runDefectiveScheduler / runFixedEventDriven) - Moad0011Algorithm: PCRE nested quantifiers (matchDefective backtracking NFA / matchFixed linear NFA) Makefile: added unit-moad-0002 through unit-moad-0011 targets, integration-all-moads, functional-all-moads. integration and functional targets now depend on all-MOADs variants.
207 lines
9.6 KiB
Java
207 lines
9.6 KiB
Java
package unit;
|
|
|
|
import support.Moad0007Algorithm;
|
|
import support.Moad0007Algorithm.SpatialObject;
|
|
import support.Moad0007Algorithm.Result;
|
|
|
|
import java.util.List;
|
|
|
|
/**
|
|
* Unit tests for MOAD-0007: CWE-407 — A Flatland Defect.
|
|
*
|
|
* Proves from first principles:
|
|
* 1. Both defective and fixed produce identical query results (same hits).
|
|
* 2. Defective: queryDefective() visits all N objects for every query —
|
|
* probeCount == N regardless of how many objects match.
|
|
* 3. Fixed: queryFixed() visits O(log N + k) objects — probeCount grows as
|
|
* log₂(N) for empty queries and log₂(N)+k for queries returning k hits.
|
|
* 4. Doubling N doubles defective probes; fixed probes grow only by 1 (log step).
|
|
* 5. Empty-range query: defective still visits all N; fixed visits O(log N).
|
|
*
|
|
* No build tool required. Compile and run:
|
|
*
|
|
* cd tests
|
|
* java -m jdk.compiler/com.sun.tools.javac.Main -cp . \
|
|
* support/Moad0007Algorithm.java unit/Moad0007UnitTest.java
|
|
* java -cp . unit.Moad0007UnitTest
|
|
*/
|
|
public class Moad0007UnitTest {
|
|
|
|
private static int passed = 0;
|
|
private static int failed = 0;
|
|
|
|
public static void main(String[] args) {
|
|
System.out.println("=== Moad0007UnitTest (A Flatland Defect) ===\n");
|
|
|
|
System.out.println("-- Correctness: same query results from both implementations --");
|
|
testSmallSceneAllMatch();
|
|
testSmallScenePartialMatch();
|
|
testSmallSceneNoMatch();
|
|
|
|
System.out.println("\n-- Defect: linear scan visits all N objects (O(N) probes) --");
|
|
testDefectiveProbesAllN100();
|
|
testDefectiveProbesAllN200();
|
|
testDefectiveEmptyQueryStillVisitsAllN();
|
|
|
|
System.out.println("\n-- Fix: binary search visits O(log N + k) objects --");
|
|
testFixedProbesLogN100();
|
|
testFixedProbesLogN200();
|
|
testFixedEmptyQueryVisitsLogN();
|
|
|
|
System.out.println("\n-- Complexity: doubling N doubles defective probes, barely changes fixed --");
|
|
testDoublingNEffect();
|
|
|
|
System.out.printf("\n%d passed, %d failed%n", passed, failed);
|
|
if (failed > 0) System.exit(1);
|
|
}
|
|
|
|
// ── Correctness ───────────────────────────────────────────────────────────
|
|
|
|
static void testSmallSceneAllMatch() {
|
|
List<SpatialObject> scene = Moad0007Algorithm.buildScene(10, 100.0);
|
|
SpatialObject[] index = Moad0007Algorithm.buildIndex(scene);
|
|
|
|
Result def = Moad0007Algorithm.queryDefective(scene, 0.0, 100.0);
|
|
Result fix = Moad0007Algorithm.queryFixed(index, 0.0, 100.0);
|
|
|
|
assertEqual("correctness: all-match hit counts equal", def.hits.size(), fix.hits.size());
|
|
assertEqual("correctness: all-match returns 10 hits", 10, def.hits.size());
|
|
}
|
|
|
|
static void testSmallScenePartialMatch() {
|
|
List<SpatialObject> scene = Moad0007Algorithm.buildScene(10, 100.0);
|
|
SpatialObject[] index = Moad0007Algorithm.buildIndex(scene);
|
|
|
|
// Middle third: positions [33, 66]
|
|
Result def = Moad0007Algorithm.queryDefective(scene, 33.0, 66.0);
|
|
Result fix = Moad0007Algorithm.queryFixed(index, 33.0, 66.0);
|
|
|
|
assertEqual("correctness: partial-match hit counts equal", def.hits.size(), fix.hits.size());
|
|
assertTrue("correctness: partial match returns some hits (>0, <10)",
|
|
def.hits.size() > 0 && def.hits.size() < 10,
|
|
"hits=" + def.hits.size());
|
|
}
|
|
|
|
static void testSmallSceneNoMatch() {
|
|
List<SpatialObject> scene = Moad0007Algorithm.buildScene(10, 100.0);
|
|
SpatialObject[] index = Moad0007Algorithm.buildIndex(scene);
|
|
|
|
// Query outside the scene bounds
|
|
Result def = Moad0007Algorithm.queryDefective(scene, 200.0, 300.0);
|
|
Result fix = Moad0007Algorithm.queryFixed(index, 200.0, 300.0);
|
|
|
|
assertEqual("correctness: no-match — both return 0 hits (defective)", 0, def.hits.size());
|
|
assertEqual("correctness: no-match — both return 0 hits (fixed)", 0, fix.hits.size());
|
|
}
|
|
|
|
// ── Defect ────────────────────────────────────────────────────────────────
|
|
|
|
static void testDefectiveProbesAllN100() {
|
|
int N = 100;
|
|
List<SpatialObject> scene = Moad0007Algorithm.buildScene(N, 1000.0);
|
|
// Even a no-match query visits all N
|
|
Result result = Moad0007Algorithm.queryDefective(scene, 2000.0, 3000.0);
|
|
assertEqual("defective N=100: probes all 100 objects (even no-match)", N, result.probeCount);
|
|
}
|
|
|
|
static void testDefectiveProbesAllN200() {
|
|
int N = 200;
|
|
List<SpatialObject> scene = Moad0007Algorithm.buildScene(N, 1000.0);
|
|
Result result = Moad0007Algorithm.queryDefective(scene, 2000.0, 3000.0);
|
|
assertEqual("defective N=200: probes all 200 objects", N, result.probeCount);
|
|
}
|
|
|
|
static void testDefectiveEmptyQueryStillVisitsAllN() {
|
|
int N = 150;
|
|
List<SpatialObject> scene = Moad0007Algorithm.buildScene(N, 500.0);
|
|
Result result = Moad0007Algorithm.queryDefective(scene, -100.0, -50.0); // no objects here
|
|
assertEqual("defective: empty-range query still visits all N=" + N, N, result.probeCount);
|
|
}
|
|
|
|
// ── Fix ───────────────────────────────────────────────────────────────────
|
|
|
|
static void testFixedProbesLogN100() {
|
|
int N = 100;
|
|
List<SpatialObject> scene = Moad0007Algorithm.buildScene(N, 1000.0);
|
|
SpatialObject[] index = Moad0007Algorithm.buildIndex(scene);
|
|
// No-match query: probes should be O(log N) = ~7 for N=100
|
|
Result result = Moad0007Algorithm.queryFixed(index, 2000.0, 3000.0);
|
|
// Binary search on 100 elements: at most ceil(log2(100)) = 7 steps, plus 1 for the exit check
|
|
int expectedMax = (int)(Math.ceil(Math.log(N) / Math.log(2))) + 2;
|
|
assertTrue("fixed N=100: no-match query probes <= " + expectedMax + " (log N)",
|
|
result.probeCount <= expectedMax,
|
|
"probeCount=" + result.probeCount);
|
|
assertTrue("fixed N=100: probes much less than N",
|
|
result.probeCount < N / 4,
|
|
"probeCount=" + result.probeCount + " N=" + N);
|
|
}
|
|
|
|
static void testFixedProbesLogN200() {
|
|
int N = 200;
|
|
List<SpatialObject> scene = Moad0007Algorithm.buildScene(N, 1000.0);
|
|
SpatialObject[] index = Moad0007Algorithm.buildIndex(scene);
|
|
Result result = Moad0007Algorithm.queryFixed(index, 2000.0, 3000.0);
|
|
int expectedMax = (int)(Math.ceil(Math.log(N) / Math.log(2))) + 2;
|
|
assertTrue("fixed N=200: no-match query probes <= " + expectedMax,
|
|
result.probeCount <= expectedMax,
|
|
"probeCount=" + result.probeCount);
|
|
}
|
|
|
|
static void testFixedEmptyQueryVisitsLogN() {
|
|
int N = 128; // power of 2 for clean log result
|
|
List<SpatialObject> scene = Moad0007Algorithm.buildScene(N, 1000.0);
|
|
SpatialObject[] index = Moad0007Algorithm.buildIndex(scene);
|
|
Result result = Moad0007Algorithm.queryFixed(index, -100.0, -1.0); // below all objects
|
|
// Binary search on 128 elements: 7 steps max (log2(128) = 7)
|
|
assertTrue("fixed N=128: out-of-range query probes at most 9 (log N + overhead)",
|
|
result.probeCount <= 9,
|
|
"probeCount=" + result.probeCount);
|
|
}
|
|
|
|
// ── Complexity ────────────────────────────────────────────────────────────
|
|
|
|
static void testDoublingNEffect() {
|
|
// Defective: doubling N doubles probes
|
|
int N1 = 100, N2 = 200;
|
|
List<SpatialObject> s1 = Moad0007Algorithm.buildScene(N1, 1000.0);
|
|
List<SpatialObject> s2 = Moad0007Algorithm.buildScene(N2, 1000.0);
|
|
SpatialObject[] i1 = Moad0007Algorithm.buildIndex(s1);
|
|
SpatialObject[] i2 = Moad0007Algorithm.buildIndex(s2);
|
|
|
|
Result def1 = Moad0007Algorithm.queryDefective(s1, 2000.0, 3000.0);
|
|
Result def2 = Moad0007Algorithm.queryDefective(s2, 2000.0, 3000.0);
|
|
Result fix1 = Moad0007Algorithm.queryFixed(i1, 2000.0, 3000.0);
|
|
Result fix2 = Moad0007Algorithm.queryFixed(i2, 2000.0, 3000.0);
|
|
|
|
// Defective: probes double exactly with N
|
|
assertEqual("defective: doubling N doubles probes (linear)", def1.probeCount * 2, def2.probeCount);
|
|
|
|
// Fixed: doubling N adds at most 1 log step
|
|
int fixDelta = fix2.probeCount - fix1.probeCount;
|
|
assertTrue("fixed: doubling N adds at most 1 probe (log growth)",
|
|
fixDelta <= 1,
|
|
"fix1.probes=" + fix1.probeCount + " fix2.probes=" + fix2.probeCount + " delta=" + fixDelta);
|
|
}
|
|
|
|
// ── 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++;
|
|
}
|
|
}
|
|
}
|