linux: full test suite — unit/integration/functional + virtme-ng bench harness

Java simulation tests (unit/):
- Linux0006Test.java: linux-0001 (headerdep 29×) + linux-0006 (btf 500×+) — 4/4 PASS
- LinuxTest.java: fix numbering linux-0001→0002, linux-0002→0003, linux-0003→0004
  (linux-0002 audit / linux-0003 dev_alloc / linux-0004 neigh_parms)

Kernel test files (tests/):
- linux-0005-component-kunit.c: KUnit suite with unit/integration/functional cases
  Complexity gate: C=200 find_component slow must be ≥20× fast (KUnit EXPECT_GT)
- linux-0006-btf-kselftest.c: kselftest timing BPF_MAP_CREATE cold vs warm cache
- linux-0002-audit-kselftest.sh: auditctl watch + open() timing, F=50 R=20
- linux-0003-0004-net-kselftest.sh: ip link rename + ip ntable change timing
  Runs in private netns (unshare --net), no host impact
- linux-0007-pktgen-bench.sh: pktgen proc read timing, 20× gate
- linux-0008-taskstats-kselftest.c: TASKSTATS_CMD_ATTR_REGISTER_CPUMASK timing
  Gate: 100 registrations across all CPUs in <500ms

Build + bench harness (bench/):
- build-and-bench.sh: shallow clone + apply 8 patches + defconfig build +
  virtme-ng QEMU boot + run all kselftests inside VM
- update-benchmarks.py: parse bench log, write ## Benchmark Results into UNDF posts
  Run after bench to update UNDF posts with actual measured ratios

License: all test code GPLv2 (in-kernel), bench scripts public domain
This commit is contained in:
russell@unturf.com 2026-04-04 12:29:56 -04:00
parent 998e2b7b0f
commit b1e7dd87a1
10 changed files with 1838 additions and 20 deletions

View file

@ -2,23 +2,23 @@ package unit;
import java.util.*;
/**
* LinuxTest — CWE-407 benchmark for linux-0001, linux-0002, linux-0003
* LinuxTest — CWE-407 benchmark for linux-0002, linux-0003, linux-0004
*
* linux-0001 (AUDIT_FILTER_INODES_QUADRATIC):
* linux-0002 (AUDIT_FILTER_INODES_QUADRATIC):
* Models audit_filter_inodes() + audit_filter_rules():
* SLOW: for each name [O(F)]: for each rule [O(R)]: for each inode-field: scan names [O(F)]
* Total O(F * R * F) = O(F²R)
* FAST: for each name [O(F)]: hash-lookup rule by inode [O(1)]: O(1) field check
* Total O(F)
*
* linux-0002 (DEV_ALLOC_NAME_NESTED_ALTNAME):
* linux-0003 (DEV_ALLOC_NAME_NESTED_ALTNAME):
* Models __dev_alloc_name():
* SLOW: for each netdev [O(D)]: for each altname [O(A)]: sscanf+snprintf+strcmp [O(1)]
* Total O(D * A)
* FAST: maintain prefix bitmap; populate on registration; find_first_zero in O(D+A) once
* Lookup: O(1) — single bitmap load
*
* linux-0003 (NEIGH_PARMS_IFINDEX_LINEAR_SCAN):
* linux-0004 (NEIGH_PARMS_IFINDEX_LINEAR_SCAN):
* Models lookup_neigh_parms():
* SLOW: list_for_each_entry(p, &tbl->parms_list) — O(P) per command
* FAST: xarray / HashMap keyed by ifindex — O(1) per command
@ -26,7 +26,7 @@ import java.util.*;
public class LinuxTest {
// =========================================================================
// linux-0001: audit_filter_inodes quadratic names_list re-scan
// linux-0002: audit_filter_inodes quadratic names_list re-scan
// =========================================================================
/** One audit_names entry — inode + dev pair (like struct audit_names). */
@ -122,7 +122,7 @@ public class LinuxTest {
}
// =========================================================================
// linux-0002: __dev_alloc_name nested O(D * A) altname sscanf
// linux-0003: __dev_alloc_name nested O(D * A) altname sscanf
// =========================================================================
/** One net_device with primary name and alt names. */
@ -209,7 +209,7 @@ public class LinuxTest {
}
// =========================================================================
// linux-0003: lookup_neigh_parms O(P) list scan vs O(1) map lookup
// linux-0004: lookup_neigh_parms O(P) list scan vs O(1) map lookup
// =========================================================================
/** Simulates struct neigh_parms — one per registered netdev. */
@ -267,13 +267,13 @@ public class LinuxTest {
public static void main(String[] args) {
int passed = 0, total = 0;
System.out.println("LinuxTest — CWE-407 benchmark (linux-0001 / 0002 / 0003)");
System.out.println("LinuxTest — CWE-407 benchmark (linux-0002 / 0003 / 0004)");
System.out.println("=".repeat(80));
// ------------------------------------------------------------------
// linux-0001: audit_filter_inodes quadratic re-scan
// linux-0002: audit_filter_inodes quadratic re-scan
// ------------------------------------------------------------------
System.out.println("\nlinux-0001: audit_filter_inodes O(F²R) vs O(FR)");
System.out.println("\nlinux-0002: audit_filter_inodes O(F²R) vs O(FR)");
{
// F=50 files (e.g. compiler opening many headers)
// R=20 rules, 2 AUDIT_INODE fields each
@ -307,7 +307,7 @@ public class LinuxTest {
// fast does F * R * fields = 50*20*2 = 2000 per call
// ratio should be ~F = 50x
assert sOps[0] > fOps[0] * 10
: "FAIL linux-0001 F=50 R=20: slow=" + sOps[0] + " fast=" + fOps[0];
: "FAIL linux-0002 F=50 R=20: slow=" + sOps[0] + " fast=" + fOps[0];
passed++;
}
{
@ -339,14 +339,14 @@ public class LinuxTest {
bench("audit filter F=200 R=50 (2k syscalls)", slow, fast, sOps[0], fOps[0]);
total++;
assert sOps[0] > fOps[0] * 50
: "FAIL linux-0001 F=200 R=50: slow=" + sOps[0] + " fast=" + fOps[0];
: "FAIL linux-0002 F=200 R=50: slow=" + sOps[0] + " fast=" + fOps[0];
passed++;
}
// ------------------------------------------------------------------
// linux-0002: __dev_alloc_name nested altname scan
// linux-0003: __dev_alloc_name nested altname scan
// ------------------------------------------------------------------
System.out.println("\nlinux-0002: __dev_alloc_name O(D*A) vs O(1)");
System.out.println("\nlinux-0003: __dev_alloc_name O(D*A) vs O(1)");
{
// D=300 devices, A=2 alt names each (typical container node)
int D = 300, A = 2;
@ -378,7 +378,7 @@ public class LinuxTest {
// fast: 1 op per call -> 5k total
// ratio: ~900x
assert sOps[0] > fOps[0] * 50
: "FAIL linux-0002 D=300 A=2: slow=" + sOps[0] + " fast=" + fOps[0];
: "FAIL linux-0003 D=300 A=2: slow=" + sOps[0] + " fast=" + fOps[0];
passed++;
}
{
@ -409,14 +409,14 @@ public class LinuxTest {
bench("dev_alloc_name D=800 A=3 (1k renames)", slow, fast, sOps[0], fOps[0]);
total++;
assert sOps[0] > fOps[0] * 100
: "FAIL linux-0002 D=800 A=3: slow=" + sOps[0] + " fast=" + fOps[0];
: "FAIL linux-0003 D=800 A=3: slow=" + sOps[0] + " fast=" + fOps[0];
passed++;
}
// ------------------------------------------------------------------
// linux-0003: lookup_neigh_parms linear scan vs HashMap
// linux-0004: lookup_neigh_parms linear scan vs HashMap
// ------------------------------------------------------------------
System.out.println("\nlinux-0003: lookup_neigh_parms O(P) vs O(1)");
System.out.println("\nlinux-0004: lookup_neigh_parms O(P) vs O(1)");
{
// P=400 parms (VxLAN gateway with 400 VTEPs + bridge ports)
int P = 400;
@ -450,7 +450,7 @@ public class LinuxTest {
// fast: 1 op per lookup -> 100k
// ratio: ~400x
assert sOps[0] > fOps[0] * 100
: "FAIL linux-0003 P=400: slow=" + sOps[0] + " fast=" + fOps[0];
: "FAIL linux-0004 P=400: slow=" + sOps[0] + " fast=" + fOps[0];
passed++;
}
{
@ -483,7 +483,7 @@ public class LinuxTest {
bench("neigh_parms lookup P=1000 not-found (50k)", slow, fast, sOps[0], fOps[0]);
total++;
assert sOps[0] > fOps[0] * 500
: "FAIL linux-0003 P=1000 not-found: slow=" + sOps[0] + " fast=" + fOps[0];
: "FAIL linux-0004 P=1000 not-found: slow=" + sOps[0] + " fast=" + fOps[0];
passed++;
}