java-topology/defects/jitsi-meet-0003/unit/AvModerationPendingTest.java
russell@unturf.com 5575f6cd9c jitsi-meet+solvespace: 5-MOAD scan; 3 new CWE-407 defects
jitsi-meet-0003: av-moderation pendingAudio/Video/Desktop Array.find()
dedup O(P^2) in large moderated meetings — 249.5x op-count at P=500,
138.5x measured at P=2000. Fix: Map<id, participant> for O(1) dedup.

jitsi-meet-0004: visitors middleware delta Array.findIndex() per update
O(U*V) in large broadcast events — 15x at V=5000 U=1000. Fix: Map-based
apply-delta O(1) per join/leave.

solvespace-0002: VRML export colours_present std::vector + find_if
O(T*C) per triangle — 250x op-count at T=50k C=500. Fix: unordered_map
keyed by ToPackedInt() RGBA uint32.

MOAD-0002/0003/0004/0005: CLEAN for both targets.
All 13 unit tests PASS.
2026-03-31 22:42:46 -04:00

171 lines
6.8 KiB
Java

import java.util.*;
/**
* Unit test for jitsi-meet-0003: AV moderation pending participant dedup.
*
* Models the TypeScript reducer logic in Java to verify O(1) Map-based dedup
* vs O(P) Array.find() dedup.
*
* Defect location:
* react/features/av-moderation/reducer.ts line 210 (PARTICIPANT_PENDING_AUDIO)
* react/features/av-moderation/functions.ts line 129 (isParticipantPending)
*
* Compile and run:
* javac defects/jitsi-meet-0003/unit/AvModerationPendingTest.java
* java -cp defects/jitsi-meet-0003/unit AvModerationPendingTest
*/
public class AvModerationPendingTest {
// --- Defective implementation: Array.find() for dedup ---
static List<Map<String, String>> pendingArrayAdd(
List<Map<String, String>> pending, Map<String, String> participant) {
// O(P) linear scan — mirrors reducer.ts line 210
boolean alreadyPresent = false;
for (Map<String, String> p : pending) {
if (p.get("id").equals(participant.get("id"))) {
alreadyPresent = true;
break;
}
}
if (!alreadyPresent) {
List<Map<String, String>> updated = new ArrayList<>(pending);
updated.add(participant);
return updated;
}
return pending;
}
static boolean isPendingArray(List<Map<String, String>> pending, String id) {
// O(P) — mirrors functions.ts line 129
for (Map<String, String> p : pending) {
if (p.get("id").equals(id)) return true;
}
return false;
}
// --- Fixed implementation: Map for O(1) dedup ---
static Map<String, Map<String, String>> pendingMapAdd(
Map<String, Map<String, String>> pending, Map<String, String> participant) {
String id = participant.get("id");
if (!pending.containsKey(id)) {
Map<String, Map<String, String>> updated = new LinkedHashMap<>(pending);
updated.put(id, participant);
return updated;
}
return pending;
}
static boolean isPendingMap(Map<String, Map<String, String>> pending, String id) {
return pending.containsKey(id); // O(1)
}
// --- Helpers ---
static Map<String, String> participant(String id) {
Map<String, String> p = new HashMap<>();
p.put("id", id);
p.put("name", "Participant " + id);
return p;
}
static void check(boolean condition, String msg) {
if (!condition) throw new AssertionError("FAIL: " + msg);
}
public static void main(String[] args) {
System.out.println("jitsi-meet-0003: AvModerationPendingTest");
// Test 1: Array dedup correctness
{
List<Map<String, String>> pending = new ArrayList<>();
pending = pendingArrayAdd(pending, participant("p1"));
pending = pendingArrayAdd(pending, participant("p1")); // duplicate
pending = pendingArrayAdd(pending, participant("p2"));
check(pending.size() == 2, "Array: duplicate must be rejected, got " + pending.size());
check(isPendingArray(pending, "p1"), "Array: p1 must be present");
check(isPendingArray(pending, "p2"), "Array: p2 must be present");
check(!isPendingArray(pending, "p3"), "Array: p3 must be absent");
System.out.println(" PASS test-1: array dedup correctness");
}
// Test 2: Map dedup correctness
{
Map<String, Map<String, String>> pending = new LinkedHashMap<>();
pending = pendingMapAdd(pending, participant("p1"));
pending = pendingMapAdd(pending, participant("p1")); // duplicate
pending = pendingMapAdd(pending, participant("p2"));
check(pending.size() == 2, "Map: duplicate must be rejected, got " + pending.size());
check(isPendingMap(pending, "p1"), "Map: p1 must be present");
check(isPendingMap(pending, "p2"), "Map: p2 must be present");
check(!isPendingMap(pending, "p3"), "Map: p3 must be absent");
System.out.println(" PASS test-2: map dedup correctness");
}
// Test 3: Performance — count total comparisons (algorithmic, not timing)
// Defective: adding P unique participants costs O(1)+O(2)+...+O(P) = O(P^2/2) comparisons
// Fixed: O(P) hash lookups regardless of order
{
int P = 500;
// Count comparison ops for array: each add scans the current list
long arrayOps = 0;
for (int size = 0; size < P; size++) {
arrayOps += size; // scan from 0..size-1 before confirming absent
}
// Count comparison ops for map: O(1) per add (hash)
long mapOps = P; // one hash + compare per add
check(arrayOps > mapOps * 10,
"Array O(P^2) ops=" + arrayOps + " must be >> map O(P) ops=" + mapOps);
double ratio = (double) arrayOps / mapOps;
System.out.printf(" PASS test-3: op-count P=%d | array %,d ops | map %,d ops | %.1fx%n",
P, arrayOps, mapOps, ratio);
}
// Test 4: isParticipantPending lookup performance
// Use a large enough list to make timing differences measurable
{
int P = 2000;
int REPEATS = 500;
List<Map<String, String>> arrayPending = new ArrayList<>();
Map<String, Map<String, String>> mapPending = new LinkedHashMap<>();
for (int i = 0; i < P; i++) {
Map<String, String> p = participant("p" + i);
arrayPending.add(p);
mapPending.put(p.get("id"), p);
}
// warm-up
for (int i = 0; i < P; i++) {
isPendingArray(arrayPending, "p" + i);
isPendingMap(mapPending, "p" + i);
}
long arrayStart = System.nanoTime();
for (int r = 0; r < REPEATS; r++) {
for (int i = 0; i < P; i++) {
isPendingArray(arrayPending, "p" + i);
}
}
long arrayLookupTime = System.nanoTime() - arrayStart;
long mapStart = System.nanoTime();
for (int r = 0; r < REPEATS; r++) {
for (int i = 0; i < P; i++) {
isPendingMap(mapPending, "p" + i);
}
}
long mapLookupTime = System.nanoTime() - mapStart;
double ratio = (double) arrayLookupTime / mapLookupTime;
System.out.printf(" PASS test-4: lookup P=%d x%d | array %,d ns | map %,d ns | %.1fx%n",
P, REPEATS, arrayLookupTime, mapLookupTime, ratio);
check(mapLookupTime < arrayLookupTime, "Map lookup must be faster than array scan P=" + P);
}
System.out.println("ALL 4 PASS");
}
}