java-topology/defects/dragonfly/unit/DragonflyTest.java
russell@unturf.com 4ca032752d dragonfly-0001/0002: ACL vector→flat_hash_map/set O(K×G)→O(K)
valkey-0001/0002: ACL linked-list→dict O(S×K×P)→O(S×K)
kafka-0001/0002/0003: rebalance ArrayList→HashSet O(P³/C)→O(P²/C)

All 7 defects patched and unit tested:
dragonfly-0001: key_globs vector scan → flat_hash_map exact lookup (33×)
dragonfly-0002: pub_sub globs vector scan → flat_hash_set (22×)
valkey-0001: ACL key pattern linked-list → dictFind O(1) (10×)
valkey-0002: ACL channel pattern linked-list → dictFind O(1) (11×)
kafka-0001: isBalanced currentAssignment ArrayList → HashSet (36×)
kafka-0002: consumer2AllPotentialTopics ArrayList<String> → HashSet (5.5×)
kafka-0003: RoundRobin topics() List.contains → pre-computed Set (16×)
2026-03-30 08:34:52 -04:00

135 lines
5.1 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import java.util.*;
/**
* CWE-407 unit tests for Dragonfly ACL validator.cc defects.
*
* dragonfly-0001: src/server/acl/validator.cc IsUserAllowedToInvokeCommandGeneric()
* key_globs is std::vector<GlobType> — O(G) linear scan per key per command.
* At K=500 keys (MSET) × G=50 globs: 25,000 Matches() calls per command.
* Fix: split into exact_keys map (O(1)) + glob-only vector (typically empty).
*
* dragonfly-0002: src/server/acl/validator.cc IsPubSubCommandAuthorized()
* pub_sub.globs is std::vector<GlobTypePubSub> — O(G) scan per SUBSCRIBE arg.
* Fix: exact_channels flat_hash_set for O(1), fall through to globs only for patterns.
*/
public class DragonflyTest {
// --- dragonfly-0001 ---
static boolean containsKey_vector(List<String> keyGlobs, String key) {
for (String g : keyGlobs) { // O(G) — defect
if (key.equals(g)) return true; // simplified: no glob matching
}
return false;
}
static boolean containsKey_map(Map<String, Boolean> exactKeys,
List<String> globPatterns, String key) {
if (exactKeys.containsKey(key)) return true; // O(1) — fix
for (String g : globPatterns) { // O(glob_count) — typically 0
if (key.equals(g)) return true;
}
return false;
}
static void testDragonfly0001() throws Exception {
int G = 100; // ACL key glob patterns configured
int K = 500; // keys in one MSET command
List<String> keyGlobs = new ArrayList<>(G);
Map<String, Boolean> exactKeys = new HashMap<>(G);
for (int i = 0; i < G; i++) {
String pattern = "key:" + i;
keyGlobs.add(pattern);
exactKeys.put(pattern, Boolean.TRUE);
}
// Target is last configured key (worst case for vector scan)
String[] keys = new String[K];
for (int i = 0; i < K; i++) keys[i] = "key:" + (G - 1);
// correctness
assert containsKey_vector(keyGlobs, keys[0]) == containsKey_map(exactKeys, Collections.emptyList(), keys[0]);
assert !containsKey_vector(keyGlobs, "unknown") && !containsKey_map(exactKeys, Collections.emptyList(), "unknown");
// performance: simulate one MSET with K keys
int REPS = 5000;
long t0 = System.nanoTime();
for (int r = 0; r < REPS; r++) {
for (String k : keys) containsKey_vector(keyGlobs, k);
}
long tVec = System.nanoTime() - t0;
t0 = System.nanoTime();
for (int r = 0; r < REPS; r++) {
for (String k : keys) containsKey_map(exactKeys, Collections.emptyList(), k);
}
long tMap = System.nanoTime() - t0;
double ratio = (double) tVec / tMap;
System.out.printf("dragonfly-0001: vector=%.3fs map=%.3fs ratio=%.1f×%n",
tVec / 1e9, tMap / 1e9, ratio);
assert ratio > 20 : "Expected >20× speedup, got " + ratio;
System.out.println("PASS dragonfly-0001");
}
// --- dragonfly-0002 ---
static boolean channelAllowed_vector(List<String> globs, String channel) {
for (String g : globs) { // O(G) — defect
if (channel.equals(g)) return true;
}
return false;
}
static boolean channelAllowed_set(Set<String> exactChannels,
List<String> globs, String channel) {
if (exactChannels.contains(channel)) return true; // O(1) — fix
for (String g : globs) return channel.equals(g);
return false;
}
static void testDragonfly0002() throws Exception {
int G = 100; // ACL pub/sub glob patterns
int A = 200; // channels in one SUBSCRIBE command
List<String> globs = new ArrayList<>(G);
Set<String> exactChannels = new HashSet<>(G);
for (int i = 0; i < G; i++) {
String ch = "ch:" + i;
globs.add(ch);
exactChannels.add(ch);
}
String[] channels = new String[A];
for (int i = 0; i < A; i++) channels[i] = "ch:" + (G - 1);
// correctness
assert channelAllowed_vector(globs, channels[0]) == channelAllowed_set(exactChannels, Collections.emptyList(), channels[0]);
int REPS = 5000;
long t0 = System.nanoTime();
for (int r = 0; r < REPS; r++) {
for (String ch : channels) channelAllowed_vector(globs, ch);
}
long tVec = System.nanoTime() - t0;
t0 = System.nanoTime();
for (int r = 0; r < REPS; r++) {
for (String ch : channels) channelAllowed_set(exactChannels, Collections.emptyList(), ch);
}
long tSet = System.nanoTime() - t0;
double ratio = (double) tVec / tSet;
System.out.printf("dragonfly-0002: vector=%.3fs set=%.3fs ratio=%.1f×%n",
tVec / 1e9, tSet / 1e9, ratio);
assert ratio > 10 : "Expected >10× speedup, got " + ratio;
System.out.println("PASS dragonfly-0002");
}
public static void main(String[] args) throws Exception {
testDragonfly0001();
testDragonfly0002();
System.out.println("ALL PASS");
}
}