package unit; import java.util.*; /** * Standalone unit test for grafana-0001: CWE-407. * * grafana-0001: dfs() visited-array Array.includes — O(n²) on time-range refresh * slow() uses a List for visited; contains() is O(V) per node visit. * DFS over N nodes with average degree d: O(N * V_avg) ≈ O(N²). * fast() uses a HashSet; contains() is O(1) per visit. * DFS over N nodes: O(N + E) where E = total edges. * Assert: slowOps > fastOps * 10x for N=200 variables in a chain graph. */ public class GrafanaTest { /** Simulate the DFS with List visited — O(V) membership test per node. */ static long slowDfs(List> adj, int start, int N) { long ops = 0; List visited = new ArrayList<>(); Deque stack = new ArrayDeque<>(); stack.push(start); while (!stack.isEmpty()) { int node = stack.pop(); // visited.includes(node) — O(V) scan boolean seen = false; for (int v : visited) { ops++; if (v == node) { seen = true; break; } } if (seen) continue; visited.add(node); // push(node.name) for (int child : adj.get(node)) { // !visited.includes(child) — another O(V) per edge boolean childSeen = false; for (int v : visited) { ops++; if (v == child) { childSeen = true; break; } } if (!childSeen) { stack.push(child); } } } return ops; } /** Simulate the DFS with Set visited — O(1) membership test per node. */ static long fastDfs(List> adj, int start, int N) { long ops = 0; Set visited = new HashSet<>(); Deque stack = new ArrayDeque<>(); stack.push(start); while (!stack.isEmpty()) { int node = stack.pop(); ops++; // O(1) hash lookup if (visited.contains(node)) continue; visited.add(node); for (int child : adj.get(node)) { ops++; // O(1) hash lookup if (!visited.contains(child)) { stack.push(child); } } } return ops; } static void testDfsVisited() { int N = 200; // variable count // Build a chain graph: 0→1→2→…→N-1 (worst-case for visited growth) List> adj = new ArrayList<>(N); for (int i = 0; i < N; i++) adj.add(new ArrayList<>()); for (int i = 0; i < N - 1; i++) adj.get(i).add(i + 1); long sOps = slowDfs(adj, 0, N); long fOps = fastDfs(adj, 0, N); int Nx = 10; boolean pass = sOps > fOps * Nx; System.out.printf("grafana-0001 [N=%d chain]: slow=%d fast=%d ratio=%.1fx — %s%n", N, sOps, fOps, (double) sOps / fOps, pass ? "PASS" : "FAIL"); if (!pass) throw new AssertionError("grafana-0001 FAIL: slow=" + sOps + " fast=" + fOps); } public static void main(String[] args) { testDfsVisited(); System.out.println("1/1 PASS"); } }