java-topology/tests/unit/DependencyListComplexityTest.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

188 lines
8.4 KiB
Java

package unit;
import support.DependencyListAlgorithm;
import support.DependencyListAlgorithm.Result;
/**
* Unit tests for DEFECT 0004: Dependencies$Node.addDependency() List.contains().
*
* Proves:
* 1. Both implementations produce the same deduplicated list (correctness).
* 2. Defective version makes exactly M*(M-1)/2 comparisons for M unique items.
* 3. Fixed version makes exactly M comparisons for M unique items.
* 4. Doubling M quadruples defective work; doubling M doubles fixed work.
*
* No build tool required. Compile and run:
*
* cd tests
* java -m jdk.compiler/com.sun.tools.javac.Main -cp . \
* support/DependencyListAlgorithm.java unit/DependencyListComplexityTest.java
* java -cp . unit.DependencyListComplexityTest
*/
public class DependencyListComplexityTest {
private static int passed = 0;
private static int failed = 0;
public static void main(String[] args) {
System.out.println("=== DependencyListComplexityTest (DEFECT 0004) ===\n");
System.out.println("-- Correctness: both produce same deduplicated list --");
testCorrectnessUniqueItems();
testCorrectnessDuplicates();
testCorrectnessEmpty();
System.out.println("\n-- Complexity: defective comparison counts M*(M-1)/2 --");
testDefectiveExactCounts();
System.out.println("\n-- Complexity: fixed comparison counts M --");
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 testCorrectnessUniqueItems() {
int[] items = DependencyListAlgorithm.buildUniqueSequence(5);
Result def = DependencyListAlgorithm.addUniqueItemsDefective(items);
Result fix = DependencyListAlgorithm.addUniqueItemsFixed(items);
assertEqual("unique-5: defective size", 5, def.items.size());
assertEqual("unique-5: fixed size", 5, fix.items.size());
for (int i = 0; i < 5; i++) {
assertEqual("unique-5: defective[" + i + "]", (long) i, def.items.get(i).longValue());
assertEqual("unique-5: fixed[" + i + "]", (long) i, fix.items.get(i).longValue());
}
}
static void testCorrectnessDuplicates() {
// [0, 1, 0, 2, 1, 3] → unique = [0, 1, 2, 3]
int[] items = {0, 1, 0, 2, 1, 3};
Result def = DependencyListAlgorithm.addUniqueItemsDefective(items);
Result fix = DependencyListAlgorithm.addUniqueItemsFixed(items);
assertEqual("dupes: defective unique count", 4, def.items.size());
assertEqual("dupes: fixed unique count", 4, fix.items.size());
for (int i = 0; i < 4; i++) {
assertEqual("dupes: defective[" + i + "]", (long) i, def.items.get(i).longValue());
assertEqual("dupes: fixed[" + i + "]", (long) i, fix.items.get(i).longValue());
}
}
static void testCorrectnessEmpty() {
int[] items = {};
Result def = DependencyListAlgorithm.addUniqueItemsDefective(items);
Result fix = DependencyListAlgorithm.addUniqueItemsFixed(items);
assertEqual("empty: defective size", 0, def.items.size());
assertEqual("empty: fixed size", 0, fix.items.size());
assertEqual("empty: defective comparisons", 0L, def.comparisons);
assertEqual("empty: fixed comparisons", 0L, fix.comparisons);
}
// ─── Exact comparison counts ──────────────────────────────────────────────
/**
* PROVES DEFECT: adding M unique items forces exactly M*(M-1)/2 comparisons.
*
* Derivation:
* Add item 0: list=[], scan 0 elements → 0 comparisons.
* Add item 1: list=[0], scan [0] for 1 → 1 comparison (not found).
* Add item k: list has k elements → k comparisons (not found).
* Total: 0+1+2+...+(M-1) = M*(M-1)/2.
*/
static void testDefectiveExactCounts() {
System.out.println("[defective] addUnique(M) — expected M*(M-1)/2:");
int[] sizes = {5, 10, 20, 50, 100};
for (int m : sizes) {
int[] items = DependencyListAlgorithm.buildUniqueSequence(m);
Result r = DependencyListAlgorithm.addUniqueItemsDefective(items);
long expected = (long) m * (m - 1) / 2;
System.out.printf(" M=%-4d actual=%-8d expected=%-8d %s%n",
m, r.comparisons, expected,
r.comparisons == expected ? "PASS" : "FAIL expected=" + expected);
assertEqual("defective M=" + m, expected, r.comparisons);
}
}
/**
* PROVES FIX: M unique items require exactly M comparisons — one per set.add().
*/
static void testFixedExactCounts() {
System.out.println("[fixed] addUnique(M) — expected M:");
int[] sizes = {5, 10, 20, 50, 100};
for (int m : sizes) {
int[] items = DependencyListAlgorithm.buildUniqueSequence(m);
Result r = DependencyListAlgorithm.addUniqueItemsFixed(items);
long expected = m;
System.out.printf(" M=%-4d actual=%-8d expected=%-8d %s%n",
m, r.comparisons, expected,
r.comparisons == expected ? "PASS" : "FAIL");
assertEqual("fixed M=" + m, expected, r.comparisons);
}
}
// ─── Growth ratio ─────────────────────────────────────────────────────────
/**
* PROVES QUADRATIC GROWTH:
* Doubling M → defective comparisons quadruple (≈4x), fixed double (≈2x).
*
* Math:
* defective(M) = M*(M-1)/2 ≈ M²/2
* defective(2M) = 2M*(2M-1)/2 ≈ 2M² → ratio ≈ 4
* fixed(M) = M, fixed(2M) = 2M → ratio = 2 (exact)
*/
static void testGrowthRatio() {
int[][] pairs = {{10, 20}, {20, 40}, {50, 100}, {100, 200}};
for (int[] pair : pairs) {
int m1 = pair[0], m2 = pair[1];
long def1 = DependencyListAlgorithm.addUniqueItemsDefective(
DependencyListAlgorithm.buildUniqueSequence(m1)).comparisons;
long def2 = DependencyListAlgorithm.addUniqueItemsDefective(
DependencyListAlgorithm.buildUniqueSequence(m2)).comparisons;
long fix1 = DependencyListAlgorithm.addUniqueItemsFixed(
DependencyListAlgorithm.buildUniqueSequence(m1)).comparisons;
long fix2 = DependencyListAlgorithm.addUniqueItemsFixed(
DependencyListAlgorithm.buildUniqueSequence(m2)).comparisons;
double defRatio = (double) def2 / def1;
double fixRatio = (double) fix2 / fix1;
System.out.printf(" M %d→%d: defective ratio=%.2f (expect ~4.0) fixed ratio=%.2f (expect 2.0)%n",
m1, m2, defRatio, fixRatio);
assertTrue("defective M=" + m1 + "" + m2 + " ratio ≥ 3.8", defRatio >= 3.8);
// exact ratio = 2*(2M-1)/(M-1) → 4.22 at M=10, converges to 4.0
assertTrue("defective M=" + m1 + "" + m2 + " ratio ≤ 4.25", defRatio <= 4.25);
assertTrue("fixed M=" + m1 + "" + m2 + " 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 assertTrue(String name, boolean condition) {
if (condition) {
System.out.printf(" PASS %s%n", name);
passed++;
} else {
System.out.printf(" FAIL %s%n", name);
failed++;
}
}
}