java-topology/tests/unit/FindNodeComplexityTest.java
russell@unturf.com 0a580b313d undefect. CWE-407 — 63 sites patched across 27 ecosystems
Authors: russell@unturf.com · brackishbert@gmail.com · foxhop.net · TimeHexOn.com

Patches, unit tests, benchmarks, whitepaper, and outreach briefs.
Public domain — no copyright claimed. Use freely.
2026-03-26 17:11:57 -04:00

190 lines
8 KiB
Java

package unit;
import support.FindNodeAlgorithm;
import support.FindNodeAlgorithm.Result;
/**
* Unit tests for DEFECT 0002a: InferenceGraph.findNode() O(N) ArrayList scan.
*
* Proves:
* 1. Both implementations find the same nodes (correctness).
* 2. Defective version makes exactly N*(N+1)/2 comparisons for N queries.
* 3. Fixed version makes exactly N comparisons for N queries.
* 4. Doubling N quadruples defective work; doubling N doubles fixed work.
*
* No build tool required. Compile and run:
*
* cd tests
* java -m jdk.compiler/com.sun.tools.javac.Main -cp . \
* support/FindNodeAlgorithm.java unit/FindNodeComplexityTest.java
* java -cp . unit.FindNodeComplexityTest
*/
public class FindNodeComplexityTest {
private static int passed = 0;
private static int failed = 0;
public static void main(String[] args) {
System.out.println("=== FindNodeComplexityTest (DEFECT 0002a) ===\n");
System.out.println("-- Correctness: both finders return same nodes --");
testCorrectnessSmall();
testCorrectnessMedium();
testAllFound();
System.out.println("\n-- Complexity: defective comparison counts N*(N+1)/2 --");
testDefectiveExactCounts();
System.out.println("\n-- Complexity: fixed comparison counts N --");
testFixedExactCounts();
System.out.println("\n-- Complexity: growth ratio proves quadratic vs linear --");
testGrowthRatio();
System.out.printf("\n%d passed, %d failed%n", passed, failed);
if (failed > 0) System.exit(1);
}
// ─── Correctness ─────────────────────────────────────────────────────────
static void testCorrectnessSmall() {
Result def = FindNodeAlgorithm.queryAllDefective(5);
Result fix = FindNodeAlgorithm.queryAllFixed(5);
assertEqual("small: defective found count", 5, def.found.size());
assertEqual("small: fixed found count", 5, fix.found.size());
for (int i = 0; i < 5; i++) {
assertTrue("small: defective found[" + i + "] not null", def.found.get(i) != null);
assertTrue("small: fixed found[" + i + "] not null", fix.found.get(i) != null);
assertEqual("small: defective found[" + i + "] label",
"N" + i, def.found.get(i).label);
assertEqual("small: fixed found[" + i + "] label",
"N" + i, fix.found.get(i).label);
}
}
static void testCorrectnessMedium() {
Result def = FindNodeAlgorithm.queryAllDefective(20);
Result fix = FindNodeAlgorithm.queryAllFixed(20);
assertEqual("medium: defective found count", 20, def.found.size());
assertEqual("medium: fixed found count", 20, fix.found.size());
for (int i = 0; i < 20; i++) {
assertEqual("medium: found[" + i + "] labels match",
def.found.get(i).label, fix.found.get(i).label);
}
}
static void testAllFound() {
// No null results — every query hits
Result def = FindNodeAlgorithm.queryAllDefective(10);
long nullCount = def.found.stream().filter(n -> n == null).count();
assertEqual("all-found: no nulls in defective", 0L, nullCount);
Result fix = FindNodeAlgorithm.queryAllFixed(10);
long nullCountFix = fix.found.stream().filter(n -> n == null).count();
assertEqual("all-found: no nulls in fixed", 0L, nullCountFix);
}
// ─── Exact comparison counts ──────────────────────────────────────────────
/**
* PROVES DEFECT: querying all N nodes in order 0..N-1 forces exactly
* N*(N+1)/2 element comparisons with the ArrayList scan.
*
* Derivation: query N0 finds it at index 0 (1 comparison), N1 found at
* index 1 (2 comparisons), ..., N(k) found at index k (k+1 comparisons).
* Total: sum(k+1, k=0..N-1) = N*(N+1)/2.
*/
static void testDefectiveExactCounts() {
System.out.println("[defective] queryAll(N) — expected N*(N+1)/2:");
int[] sizes = {5, 10, 20, 50, 100};
for (int n : sizes) {
Result r = FindNodeAlgorithm.queryAllDefective(n);
long expected = (long) n * (n + 1) / 2;
System.out.printf(" N=%-4d actual=%-8d expected=%-8d %s%n",
n, r.comparisons, expected,
r.comparisons == expected ? "PASS" : "FAIL expected=" + expected);
assertEqual("defective N=" + n, expected, r.comparisons);
}
}
/**
* PROVES FIX: N queries against a HashMap require exactly N comparisons — one per lookup.
*/
static void testFixedExactCounts() {
System.out.println("[fixed] queryAll(N) — expected N:");
int[] sizes = {5, 10, 20, 50, 100};
for (int n : sizes) {
Result r = FindNodeAlgorithm.queryAllFixed(n);
long expected = n;
System.out.printf(" N=%-4d actual=%-8d expected=%-8d %s%n",
n, r.comparisons, expected,
r.comparisons == expected ? "PASS" : "FAIL");
assertEqual("fixed N=" + n, expected, r.comparisons);
}
}
// ─── Growth ratio ─────────────────────────────────────────────────────────
/**
* PROVES QUADRATIC GROWTH of defect:
* Doubling N → defective comparisons quadruple (≈4x), fixed double (≈2x).
*
* Math:
* defective(N) = N*(N+1)/2 ≈ N²/2
* defective(2N) = 2N*(2N+1)/2 ≈ 2N² → ratio ≈ 4
* fixed(N) = N, fixed(2N) = 2N → ratio = 2 (exact)
*/
static void testGrowthRatio() {
int[][] pairs = {{10, 20}, {20, 40}, {50, 100}, {100, 200}};
for (int[] pair : pairs) {
int n1 = pair[0], n2 = pair[1];
long def1 = FindNodeAlgorithm.queryAllDefective(n1).comparisons;
long def2 = FindNodeAlgorithm.queryAllDefective(n2).comparisons;
long fix1 = FindNodeAlgorithm.queryAllFixed(n1).comparisons;
long fix2 = FindNodeAlgorithm.queryAllFixed(n2).comparisons;
double defRatio = (double) def2 / def1;
double fixRatio = (double) fix2 / fix1;
System.out.printf(" N %d→%d: defective ratio=%.2f (expect ~4.0) fixed ratio=%.2f (expect 2.0)%n",
n1, n2, defRatio, fixRatio);
assertTrue("defective N=" + n1 + "" + n2 + " ratio ≥ 3.8", defRatio >= 3.8);
assertTrue("defective N=" + n1 + "" + n2 + " ratio ≤ 4.2", defRatio <= 4.2);
assertTrue("fixed N=" + n1 + "" + n2 + " ratio = 2.0", fixRatio == 2.0);
}
}
// ─── Helpers ─────────────────────────────────────────────────────────────
static void assertEqual(String name, long expected, long actual) {
if (expected == actual) {
System.out.printf(" PASS %s%n", name);
passed++;
} else {
System.out.printf(" FAIL %s expected=%d actual=%d%n", name, expected, actual);
failed++;
}
}
static void assertEqual(String name, String expected, String actual) {
if (expected.equals(actual)) {
System.out.printf(" PASS %s%n", name);
passed++;
} else {
System.out.printf(" FAIL %s expected=%s actual=%s%n", name, expected, actual);
failed++;
}
}
static void assertTrue(String name, boolean condition) {
if (condition) {
System.out.printf(" PASS %s%n", name);
passed++;
} else {
System.out.printf(" FAIL %s%n", name);
failed++;
}
}
}