package unit; import java.util.*; /** * Kubernetes0007Algorithm — CWE-407 unit test for kubernetes-0007 * * kubernetes-0007: pod_failure_policy.go:126,128 * for _, containerStatus := range containerStatuses { // O(C) containers * isOnExitCodesOperatorMatching(exitCode, requirement) → * slices.Contains(requirement.Values, exitCode) // O(V) scan * } * * Called from matchPodFailurePolicy() for every failed pod: * for _, p := range failedPods { matchPodFailurePolicy(policy, p) } * * Total complexity: O(P × R × C × V) — pods × rules × containers × values * * SLOW: slices.Contains([]int32, exitCode) — O(V) linear scan per container * FAST: map[int32]struct{} pre-built once per rule — O(1) per container * * No JUnit. Run: javac -d . Kubernetes0007Algorithm.java && java -ea unit.Kubernetes0007Algorithm */ public class Kubernetes0007Algorithm { // ------------------------------------------------------------------------- // Data model — mirrors PodFailurePolicyOnExitCodesRequirement // ------------------------------------------------------------------------- static class ExitCodeRequirement { final boolean opIn; // true=In, false=NotIn final int[] values; // requirement.Values []int32 ExitCodeRequirement(boolean opIn, int[] values) { this.opIn = opIn; this.values = values; } } static class PolicyRule { final ExitCodeRequirement requirement; PolicyRule(ExitCodeRequirement r) { this.requirement = r; } } // ------------------------------------------------------------------------- // Op counters for measuring linear vs map scans // ------------------------------------------------------------------------- static long slowOps = 0; static long fastOps = 0; // ------------------------------------------------------------------------- // SLOW: O(V) linear scan — models slices.Contains(requirement.Values, exitCode) // ------------------------------------------------------------------------- static boolean isMatchingSlow(int exitCode, ExitCodeRequirement req) { for (int v : req.values) { // O(V) linear scan slowOps++; if (v == exitCode) { return req.opIn; // In: found → match } } return !req.opIn; // In: not found → no match; NotIn: not found → match } /** * Match one pod's containers against all policy rules. * Models matchPodFailurePolicy() + getMatchingContainerFromList(). * Returns true if any rule matches any container exit code. */ static boolean matchPodSlow(int[] containerExitCodes, List rules) { for (PolicyRule rule : rules) { // O(R) rules for (int exitCode : containerExitCodes) { // O(C) containers if (exitCode != 0 && isMatchingSlow(exitCode, rule.requirement)) { return true; } } } return false; } /** * Run all failed pods through policy matching. * Models nonIgnoredFailedPodsCount() hot path. */ static int countIgnoredPodsSlow(int[][] failedPods, List rules) { int ignored = 0; for (int[] podExitCodes : failedPods) { // O(P) pods if (matchPodSlow(podExitCodes, rules)) { ignored++; } } return ignored; } // ------------------------------------------------------------------------- // FAST: pre-build map[int32]struct{} once per rule — O(1) per container // ------------------------------------------------------------------------- static boolean isMatchingFast(int exitCode, boolean opIn, Set valueSet) { fastOps++; boolean found = valueSet.contains(exitCode); // O(1) hash lookup return opIn ? found : !found; } static boolean matchPodFast(int[] containerExitCodes, List rules, List> ruleSets) { for (int i = 0; i < rules.size(); i++) { // O(R) PolicyRule rule = rules.get(i); Set valueSet = ruleSets.get(i); for (int exitCode : containerExitCodes) { // O(C) if (exitCode != 0 && isMatchingFast(exitCode, rule.requirement.opIn, valueSet)) { return true; } } } return false; } static int countIgnoredPodsFast(int[][] failedPods, List rules) { // Pre-build one set per rule — O(R × V) one-time cost List> ruleSets = new ArrayList<>(rules.size()); for (PolicyRule rule : rules) { Set set = new HashSet<>(rule.requirement.values.length * 2); for (int v : rule.requirement.values) { set.add(v); } ruleSets.add(set); } // Now match all pods — O(P × R × C × 1) int ignored = 0; for (int[] podExitCodes : failedPods) { if (matchPodFast(podExitCodes, rules, ruleSets)) { ignored++; } } return ignored; } // ------------------------------------------------------------------------- // Helpers // ------------------------------------------------------------------------- /** Build R rules each with V exit code values (some matching exitSeed) */ static List buildRules(int R, int V, int exitSeed) { List rules = new ArrayList<>(R); for (int i = 0; i < R; i++) { int[] values = new int[V]; for (int j = 0; j < V; j++) { values[j] = (exitSeed + i * V + j) % 256 + 1; } rules.add(new PolicyRule(new ExitCodeRequirement(true, values))); } return rules; } /** Build P pods each with C containers, exit codes spread to hit last rule */ static int[][] buildPods(int P, int C) { int[][] pods = new int[P][C]; for (int i = 0; i < P; i++) { for (int j = 0; j < C; j++) { // Use exit code that is unlikely to match early rules → worst case scan pods[i][j] = (i * C + j) % 200 + 50; } } return pods; } // ------------------------------------------------------------------------- // Tests // ------------------------------------------------------------------------- static void testCorrectness() { // Single rule: In [1, 2, 3] List rules = new ArrayList<>(); rules.add(new PolicyRule(new ExitCodeRequirement(true, new int[]{1, 2, 3}))); int[][] matchingPod = {{1, 0}}; // exit code 1 → should match int[][] noMatchPod = {{5, 0}}; // exit code 5 → no match List> sets = new ArrayList<>(); sets.add(new HashSet<>(Arrays.asList(1, 2, 3))); assert countIgnoredPodsSlow(matchingPod, rules) == 1 : "slow: expected match"; assert countIgnoredPodsFast(matchingPod, rules) == 1 : "fast: expected match"; assert countIgnoredPodsSlow(noMatchPod, rules) == 0 : "slow: expected no match"; assert countIgnoredPodsFast(noMatchPod, rules) == 0 : "fast: expected no match"; // NotIn rule: NotIn [1,2,3] — exit code 5 should match (5 not in set) List notInRules = new ArrayList<>(); notInRules.add(new PolicyRule(new ExitCodeRequirement(false, new int[]{1, 2, 3}))); assert countIgnoredPodsSlow(noMatchPod, notInRules) == 1 : "slow NotIn: expected match for code 5"; assert countIgnoredPodsFast(noMatchPod, notInRules) == 1 : "fast NotIn: expected match for code 5"; System.out.println("PASS correctness: In/NotIn matching verified"); } static void testOpsCount() { int P = 100, R = 10, C = 3, V = 20; List rules = buildRules(R, V, 200); // high exit codes → no early match int[][] pods = buildPods(P, C); slowOps = 0; fastOps = 0; countIgnoredPodsSlow(pods, rules); countIgnoredPodsFast(pods, rules); long expectedSlowBound = (long) P * R * C * V; long expectedFastBound = (long) P * R * C; System.out.printf("PASS ops_count P=%d R=%d C=%d V=%d: slowOps=%d fastOps=%d ratio=%.0fx%n", P, R, C, V, slowOps, fastOps, (double) slowOps / Math.max(fastOps, 1)); assert slowOps >= fastOps * 5 : "expected slowOps >> fastOps, got slowOps=" + slowOps + " fastOps=" + fastOps; } static void testPerf_P500_R15_C3_V30() { int P = 500, R = 15, C = 3, V = 30; List rules = buildRules(R, V, 210); int[][] pods = buildPods(P, C); // Warm up JVM for (int i = 0; i < 20; i++) { countIgnoredPodsSlow(pods, rules); countIgnoredPodsFast(pods, rules); } long t0 = System.nanoTime(); int slowResult = 0; for (int i = 0; i < 500; i++) { slowResult += countIgnoredPodsSlow(pods, rules); } long slowNs = System.nanoTime() - t0; long t1 = System.nanoTime(); int fastResult = 0; for (int i = 0; i < 500; i++) { fastResult += countIgnoredPodsFast(pods, rules); } long fastNs = System.nanoTime() - t1; assert slowResult == fastResult : "results differ: " + slowResult + " vs " + fastResult; double ratio = (double) slowNs / Math.max(fastNs, 1); System.out.printf("PASS perf P=%d R=%d C=%d V=%d 500x: slow=%dms fast=%dms ratio=%.1fx%n", P, R, C, V, slowNs / 1_000_000, fastNs / 1_000_000, ratio); assert ratio >= 0.5 : "ratio too low: " + ratio + " (slow=" + slowNs + "ns fast=" + fastNs + "ns)"; } static void testPerf_P2000_R20_C5_V10_stress() { int P = 2000, R = 20, C = 5, V = 10; List rules = buildRules(R, V, 220); int[][] pods = buildPods(P, C); // Warm up for (int i = 0; i < 10; i++) { countIgnoredPodsSlow(pods, rules); countIgnoredPodsFast(pods, rules); } long t0 = System.nanoTime(); int slowResult = 0; for (int i = 0; i < 100; i++) { slowResult += countIgnoredPodsSlow(pods, rules); } long slowNs = System.nanoTime() - t0; long t1 = System.nanoTime(); int fastResult = 0; for (int i = 0; i < 100; i++) { fastResult += countIgnoredPodsFast(pods, rules); } long fastNs = System.nanoTime() - t1; assert slowResult == fastResult : "results differ: " + slowResult + " vs " + fastResult; double ratio = (double) slowNs / Math.max(fastNs, 1); System.out.printf("PASS stress P=%d R=%d C=%d V=%d 100x: slow=%dms fast=%dms ratio=%.1fx%n", P, R, C, V, slowNs / 1_000_000, fastNs / 1_000_000, ratio); // ops count test already proves O(V) vs O(1) — just verify correctness here assert slowResult > 0 || fastResult == 0 : "unexpected mismatch"; } // ------------------------------------------------------------------------- // Main // ------------------------------------------------------------------------- public static void main(String[] args) { System.out.println("=== Kubernetes0007Algorithm: pod failure policy exit-code scan (kubernetes-0007) ==="); testCorrectness(); testOpsCount(); testPerf_P500_R15_C3_V30(); testPerf_P2000_R20_C5_V10_stress(); System.out.println("4/4 PASS"); } }