whitepaper: 352/169 — wave4 MEDIUM (hadoop/hbase/nova/neutron/openstack) + fix odl-0002 dup
This commit is contained in:
parent
9934133dcf
commit
835ae73b0f
82 changed files with 5931 additions and 6 deletions
164
defects/keystone/unit/KeystoneImpliedRoleAlgorithm.java
Normal file
164
defects/keystone/unit/KeystoneImpliedRoleAlgorithm.java
Normal file
|
|
@ -0,0 +1,164 @@
|
|||
package unit;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* CWE-407 unit test: keystone-0001
|
||||
* Implied-role deduplication: list comprehension vs set.
|
||||
*
|
||||
* Slow: `if imp_role_obj['id'] not in [x['id'] for x in roles]`
|
||||
* rebuilds list every check — O(n) per implied role.
|
||||
* Fast: maintain a seen_role_ids set — O(1) per check.
|
||||
*/
|
||||
public class KeystoneImpliedRoleAlgorithm {
|
||||
|
||||
// Simulates the implied-role graph: role_id -> list of implied role_ids
|
||||
static Map<String, List<String>> buildImpliedGraph(int R, int I) {
|
||||
Map<String, List<String>> graph = new HashMap<>();
|
||||
for (int i = 0; i < R; i++) {
|
||||
List<String> implied = new ArrayList<>();
|
||||
for (int j = 0; j < I; j++) {
|
||||
implied.add("implied-" + i + "-" + j);
|
||||
}
|
||||
graph.put("role-" + i, implied);
|
||||
// implied roles themselves have no further implications
|
||||
for (int j = 0; j < I; j++) {
|
||||
graph.put("implied-" + i + "-" + j, new ArrayList<>());
|
||||
}
|
||||
}
|
||||
return graph;
|
||||
}
|
||||
|
||||
// Defective: list comprehension for deduplication
|
||||
static long expandRolesSlow(List<Map<String, String>> roles,
|
||||
Map<String, List<String>> impliedGraph) {
|
||||
long ops = 0;
|
||||
// NOTE: iterating over a mutable list that grows — simulating the defect
|
||||
for (int idx = 0; idx < roles.size(); idx++) {
|
||||
Map<String, String> role = roles.get(idx);
|
||||
List<String> implied = impliedGraph.getOrDefault(role.get("id"),
|
||||
new ArrayList<>());
|
||||
for (String impId : implied) {
|
||||
ops++;
|
||||
// O(n) list scan — rebuild the id list each time
|
||||
boolean found = false;
|
||||
for (Map<String, String> r : roles) { // O(current size)
|
||||
ops++;
|
||||
if (r.get("id").equals(impId)) { found = true; break; }
|
||||
}
|
||||
if (!found) {
|
||||
Map<String, String> newRole = new HashMap<>();
|
||||
newRole.put("id", impId);
|
||||
roles.add(newRole);
|
||||
}
|
||||
}
|
||||
}
|
||||
return ops;
|
||||
}
|
||||
|
||||
// Fixed: set for deduplication
|
||||
static long expandRolesFast(List<Map<String, String>> roles,
|
||||
Map<String, List<String>> impliedGraph) {
|
||||
long ops = 0;
|
||||
Set<String> seenIds = new HashSet<>();
|
||||
for (Map<String, String> r : roles) seenIds.add(r.get("id"));
|
||||
|
||||
List<Map<String, String>> snapshot = new ArrayList<>(roles);
|
||||
for (Map<String, String> role : snapshot) {
|
||||
List<String> implied = impliedGraph.getOrDefault(role.get("id"),
|
||||
new ArrayList<>());
|
||||
for (String impId : implied) {
|
||||
ops++;
|
||||
if (!seenIds.contains(impId)) { // O(1)
|
||||
seenIds.add(impId);
|
||||
Map<String, String> newRole = new HashMap<>();
|
||||
newRole.put("id", impId);
|
||||
roles.add(newRole);
|
||||
}
|
||||
}
|
||||
}
|
||||
return ops;
|
||||
}
|
||||
|
||||
static List<Map<String, String>> makeRoles(int count) {
|
||||
List<Map<String, String>> roles = new ArrayList<>();
|
||||
for (int i = 0; i < count; i++) {
|
||||
Map<String, String> r = new HashMap<>();
|
||||
r.put("id", "role-" + i);
|
||||
roles.add(r);
|
||||
}
|
||||
return roles;
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
int R = 50; // initial roles
|
||||
int I = 10; // implied roles per role
|
||||
|
||||
int passed = 0;
|
||||
int total = 0;
|
||||
|
||||
Map<String, List<String>> graph = buildImpliedGraph(R, I);
|
||||
|
||||
// Test 1: op count slow vs fast
|
||||
List<Map<String, String>> rolesSlow = makeRoles(R);
|
||||
List<Map<String, String>> rolesFast = makeRoles(R);
|
||||
long slowOps = expandRolesSlow(rolesSlow, graph);
|
||||
long fastOps = expandRolesFast(rolesFast, graph);
|
||||
total++;
|
||||
assert slowOps > fastOps * 5 :
|
||||
"slow=" + slowOps + " fast=" + fastOps + " speedup insufficient";
|
||||
System.out.println("Test 1 PASS: implied-role expand slow=" + slowOps +
|
||||
" ops, fast=" + fastOps + " ops, speedup=" + (slowOps / Math.max(1, fastOps)) + "x");
|
||||
passed++;
|
||||
|
||||
// Test 2: correctness — same final role set
|
||||
Set<String> slowIds = new HashSet<>();
|
||||
for (Map<String, String> r : rolesSlow) slowIds.add(r.get("id"));
|
||||
Set<String> fastIds = new HashSet<>();
|
||||
for (Map<String, String> r : rolesFast) fastIds.add(r.get("id"));
|
||||
total++;
|
||||
assert slowIds.equals(fastIds) :
|
||||
"role sets differ: slow=" + slowIds.size() + " fast=" + fastIds.size();
|
||||
System.out.println("Test 2 PASS: role sets agree (" + slowIds.size() + " roles)");
|
||||
passed++;
|
||||
|
||||
// Test 3: no duplicates in fast result
|
||||
total++;
|
||||
assert rolesFast.size() == fastIds.size() :
|
||||
"fast result contains duplicates: list=" + rolesFast.size() +
|
||||
" set=" + fastIds.size();
|
||||
System.out.println("Test 3 PASS: no duplicates in fast result");
|
||||
passed++;
|
||||
|
||||
// Test 4: token_roles deduplication — list vs set
|
||||
// Simulate `token_roles = [r['id'] for r in token.roles]` + loop check
|
||||
List<String> tokenRolesListBuild = new ArrayList<>();
|
||||
for (int i = 0; i < R; i++) tokenRolesListBuild.add("role-" + i);
|
||||
Set<String> tokenRolesSet = new HashSet<>(tokenRolesListBuild);
|
||||
|
||||
long listCheckOps = 0;
|
||||
long setCheckOps = 0;
|
||||
List<Map<String, String>> allRoles = makeRoles(R * 2); // some not in token
|
||||
for (Map<String, String> role : allRoles) {
|
||||
listCheckOps += tokenRolesListBuild.size(); // O(T) list scan
|
||||
setCheckOps++; // O(1) set lookup
|
||||
@SuppressWarnings("unused") boolean listContains =
|
||||
tokenRolesListBuild.contains(role.get("id"));
|
||||
@SuppressWarnings("unused") boolean setContains =
|
||||
tokenRolesSet.contains(role.get("id"));
|
||||
}
|
||||
total++;
|
||||
assert listCheckOps > setCheckOps * 5 :
|
||||
"token_roles: list=" + listCheckOps + " set=" + setCheckOps;
|
||||
System.out.println("Test 4 PASS: token_roles list=" + listCheckOps +
|
||||
" ops, set=" + setCheckOps + " ops");
|
||||
passed++;
|
||||
|
||||
System.out.println(passed + "/" + total + " PASS");
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue