diff --git a/src/test/java/org/casbin/jcasbin/main/FrontendUnitTest.java b/src/test/java/org/casbin/jcasbin/main/FrontendUnitTest.java index 904a5cfc..2674864b 100644 --- a/src/test/java/org/casbin/jcasbin/main/FrontendUnitTest.java +++ b/src/test/java/org/casbin/jcasbin/main/FrontendUnitTest.java @@ -32,10 +32,11 @@ public class FrontendUnitTest { public void testCasbinJsGetPermissionForUser() throws IOException { SyncedEnforcer e = new SyncedEnforcer("examples/rbac_model.conf", "examples/rbac_with_hierarchy_policy.csv"); HashMap received = new Gson().fromJson(Frontend.casbinJsGetPermissionForUser(e, "alice"), HashMap.class); - String expectedModelStr = new String(Files.readAllBytes(Paths.get("examples/rbac_model.conf"))); - assertEquals(received.get("m"), expectedModelStr); + String receivedModelStr = ((String) received.get("m")).replace("\r\n", "\n").replace("\r", "\n"); + String expectedModelStr = new String(Files.readAllBytes(Paths.get("examples/rbac_model.conf"))).replace("\r\n", "\n").replace("\r", "\n"); + assertEquals(expectedModelStr, receivedModelStr); - String expectedPolicyStr = new String(Files.readAllBytes(Paths.get("examples/rbac_with_hierarchy_policy.csv"))); + String expectedPolicyStr = new String(Files.readAllBytes(Paths.get("examples/rbac_with_hierarchy_policy.csv"))).replace("\r\n", "\n").replace("\r", "\n"); expectedPolicyStr = Pattern.compile("\n+").matcher(expectedPolicyStr).replaceAll("\n"); String[] expectedPolicyItem = expectedPolicyStr.split(",|\n"); int i = 0; diff --git a/src/test/java/org/casbin/jcasbin/main/benchmark/BenchmarkABACModel.java b/src/test/java/org/casbin/jcasbin/main/benchmark/BenchmarkABACModel.java index ccc16629..b5070b29 100644 --- a/src/test/java/org/casbin/jcasbin/main/benchmark/BenchmarkABACModel.java +++ b/src/test/java/org/casbin/jcasbin/main/benchmark/BenchmarkABACModel.java @@ -15,7 +15,6 @@ package org.casbin.jcasbin.main.benchmark; import org.casbin.jcasbin.main.Enforcer; -import org.casbin.jcasbin.main.ModelUnitTest; import org.openjdk.jmh.annotations.*; import org.openjdk.jmh.profile.GCProfiler; import org.openjdk.jmh.runner.Runner; @@ -25,29 +24,54 @@ import java.util.concurrent.TimeUnit; -@OutputTimeUnit(TimeUnit.MILLISECONDS) +/** + * Benchmark for ABAC model. + * Data scale: 0 rules (0 user). + */ +@OutputTimeUnit(TimeUnit.NANOSECONDS) @BenchmarkMode(Mode.AverageTime) public class BenchmarkABACModel { - private static Enforcer e = new Enforcer("examples/abac_model.conf", "",false); - private static ModelUnitTest.TestResource data1 = new ModelUnitTest.TestResource("data1", "alice"); + private static Enforcer e; + private static TestResource data1; - public static void main(String args[]) throws RunnerException { + public static class TestResource { + private String Name; + private String Owner; + + public TestResource(String name, String owner) { + this.Name = name; + this.Owner = owner; + } + + public String getName() { + return Name; + } + + public String getOwner() { + return Owner; + } + } + + static { + e = new Enforcer("examples/abac_model.conf", "", false); + data1 = new TestResource("data1", "alice"); + } + + public static void main(String[] args) throws RunnerException { Options opt = new OptionsBuilder() - .include(BenchmarkABACModel.class.getName()) - .exclude("Pref") - .warmupIterations(3) - .measurementIterations(3) - .addProfiler(GCProfiler.class) - .forks(1) - .build(); + .include(BenchmarkABACModel.class.getName()) + .exclude("Pref") + .warmupIterations(3) + .measurementIterations(5) + .addProfiler(GCProfiler.class) + .forks(2) + .build(); new Runner(opt).run(); } @Threads(1) @Benchmark - public static void benchmarkABACModel() { - for (int i = 0; i < 1000; i++) { - e.enforce("alice", data1, "read"); - } + public void benchmarkABACModel() { + e.enforce("alice", data1, "read"); } } diff --git a/src/test/java/org/casbin/jcasbin/main/benchmark/BenchmarkAllModelApi.java b/src/test/java/org/casbin/jcasbin/main/benchmark/BenchmarkAllModelApi.java index 02479a22..572a986f 100644 --- a/src/test/java/org/casbin/jcasbin/main/benchmark/BenchmarkAllModelApi.java +++ b/src/test/java/org/casbin/jcasbin/main/benchmark/BenchmarkAllModelApi.java @@ -21,6 +21,7 @@ import org.openjdk.jmh.runner.options.Options; import org.openjdk.jmh.runner.options.OptionsBuilder; +import java.util.Arrays; import java.util.ArrayList; import java.util.List; import java.util.concurrent.TimeUnit; @@ -41,10 +42,11 @@ @State(value = Scope.Benchmark) @OutputTimeUnit(TimeUnit.NANOSECONDS) public class BenchmarkAllModelApi { - public static Enforcer smallEnforcer; - public static Enforcer mediumEnforcer; - public static Enforcer largeEnforcer; - public static Enforcer enforcerForAdd; + private static final String MODEL_PATH = "examples/rbac_model.conf"; + + private Enforcer smallEnforcer; + private Enforcer mediumEnforcer; + private Enforcer largeEnforcer; public static void main(String[] args) throws RunnerException { Options opt = new OptionsBuilder() @@ -55,135 +57,289 @@ public static void main(String[] args) throws RunnerException { new Runner(opt).run(); } - static { - smallEnforcer = new Enforcer("examples/rbac_model.conf", "", false); - mediumEnforcer = new Enforcer("examples/rbac_model.conf", "", false); - largeEnforcer = new Enforcer("examples/rbac_model.conf", "", false); - enforcerForAdd = new Enforcer("examples/rbac_model.conf", "", false); + @Setup(Level.Trial) + public void setup() { + smallEnforcer = new Enforcer(MODEL_PATH, "", false); + mediumEnforcer = new Enforcer(MODEL_PATH, "", false); + largeEnforcer = new Enforcer(MODEL_PATH, "", false); - // 100 roles, 10 resources. for (int i = 0; i < 100; i++) { smallEnforcer.addPolicy("user" + i, "data" + i / 10, "read"); } - // 1000 roles, 100 resources. for (int i = 0; i < 1000; i++) { mediumEnforcer.addPolicy("user" + i, "data" + i / 10, "read"); } - // 10000 roles, 1000 resources. for (int i = 0; i < 10000; i++) { largeEnforcer.addPolicy("user" + i, "data" + i / 10, "read"); } } @Benchmark - public static void addPolicySmall() { + public void addPolicySmall(AddState state) { for (int i = 0; i < 100; i++) { - enforcerForAdd.addPolicy("user" + i, "data" + (int) (Math.random() * 50), "read"); + int dataIndex = (i * 31 + state.invocationSeed) % 50; + state.enforcer.addPolicy("user" + i, "data" + dataIndex, "read"); } } @Benchmark - public static void addPolicyMedium() { + public void addPolicyMedium(AddState state) { for (int i = 0; i < 1000; i++) { - enforcerForAdd.addPolicy("user" + i, "data" + (int) (Math.random() * 500), "read"); + int dataIndex = (i * 31 + state.invocationSeed) % 500; + state.enforcer.addPolicy("user" + i, "data" + dataIndex, "read"); } } @Benchmark - public static void addPolicyLarge() { + public void addPolicyLarge(AddState state) { for (int i = 0; i < 10000; i++) { - enforcerForAdd.addPolicy("user" + i, "data" + (int) (Math.random() * 500), "read"); + int dataIndex = (i * 31 + state.invocationSeed) % 5000; + state.enforcer.addPolicy("user" + i, "data" + dataIndex, "read"); } } @Benchmark - public static void hasPolicySmall() { + public void hasPolicySmall() { for (int i = 0; i < 100; i++) { - smallEnforcer.hasPolicy("user" + (int) (Math.random() * 100), "data" + (int) (Math.random() * 10), "read"); + int userIndex = i; + smallEnforcer.hasPolicy("user" + userIndex, "data" + userIndex / 10, "read"); } } @Benchmark - public static void hasPolicyMedium() { + public void hasPolicyMedium() { for (int i = 0; i < 1000; i++) { - mediumEnforcer.hasPolicy("user" + (int) (Math.random() * 1000), "data" + (int) (Math.random() * 100), "read"); + int userIndex = i; + mediumEnforcer.hasPolicy("user" + userIndex, "data" + userIndex / 10, "read"); } } @Benchmark - public static void hasPolicyLarge() { + public void hasPolicyLarge() { for (int i = 0; i < 10000; i++) { - largeEnforcer.hasPolicy("user" + (int) (Math.random() * 10000), "data" + (int) (Math.random() * 1000), "read"); + int userIndex = i; + largeEnforcer.hasPolicy("user" + userIndex, "data" + userIndex / 10, "read"); } } @Benchmark - public static void updatePolicySmall() { - for (int i = 0; i < 100; i++) { - List oldRule = new ArrayList<>(); - List newRule = new ArrayList<>(); - oldRule.add("user" + (int) (Math.random() * 100)); - oldRule.add("data" + (int) (Math.random() * 10)); - oldRule.add("read"); - newRule.add("user" + (int) (Math.random() * 100)); - newRule.add("data" + (int) (Math.random() * 10)); - newRule.add("read"); - - smallEnforcer.updatePolicy(oldRule, newRule); + public void updatePolicySmall(UpdateStateSmall state) { + for (int i = 0; i < state.oldRules.size(); i++) { + state.enforcer.updatePolicy(state.oldRules.get(i), state.newRules.get(i)); } } @Benchmark - public static void updatePolicyMedium() { - for (int i = 0; i < 100; i++) { - List oldRule = new ArrayList<>(); - List newRule = new ArrayList<>(); - oldRule.add("user" + (int) (Math.random() * 1000)); - oldRule.add("data" + (int) (Math.random() * 100)); - oldRule.add("read"); - newRule.add("user" + (int) (Math.random() * 1000)); - newRule.add("data" + (int) (Math.random() * 100)); - newRule.add("read"); - - mediumEnforcer.updatePolicy(oldRule, newRule); + public void updatePolicyMedium(UpdateStateMedium state) { + for (int i = 0; i < state.oldRules.size(); i++) { + state.enforcer.updatePolicy(state.oldRules.get(i), state.newRules.get(i)); } } @Benchmark - public static void updatePolicyLarge() { - for (int i = 0; i < 100; i++) { - List oldRule = new ArrayList<>(); - List newRule = new ArrayList<>(); - oldRule.add("user" + (int) (Math.random() * 10000)); - oldRule.add("data" + (int) (Math.random() * 1000)); - oldRule.add("read"); - newRule.add("user" + (int) (Math.random() * 10000)); - newRule.add("data" + (int) (Math.random() * 1000)); - newRule.add("read"); - - largeEnforcer.updatePolicy(oldRule, newRule); + public void updatePolicyLarge(UpdateStateLarge state) { + for (int i = 0; i < state.oldRules.size(); i++) { + state.enforcer.updatePolicy(state.oldRules.get(i), state.newRules.get(i)); } } @Benchmark - public static void removePolicySmall() { - for (int i = 0; i < 100; i++) { - smallEnforcer.removePolicy("user" + (int) (Math.random() * 100), "data" + (int) (Math.random() * 10), "read"); + public void removePolicySmall(RemoveStateSmall state) { + for (int i = 0; i < state.users.length; i++) { + state.enforcer.removePolicy(state.users[i], state.data[i], "read"); } } @Benchmark - public static void removePolicyMedium() { - for (int i = 0; i < 1000; i++) { - mediumEnforcer.removePolicy("user" + (int) (Math.random() * 1000), "data" + (int) (Math.random() * 100), "read"); + public void removePolicyMedium(RemoveStateMedium state) { + for (int i = 0; i < state.users.length; i++) { + state.enforcer.removePolicy(state.users[i], state.data[i], "read"); } } @Benchmark - public static void removePolicyLarge() { - for (int i = 0; i < 10000; i++) { - largeEnforcer.removePolicy("user" + (int) (Math.random() * 10000), "data" + (int) (Math.random() * 1000), "read"); + public void removePolicyLarge(RemoveStateLarge state) { + for (int i = 0; i < state.users.length; i++) { + state.enforcer.removePolicy(state.users[i], state.data[i], "read"); + } + } + + @State(Scope.Thread) + public static class AddState { + private Enforcer enforcer; + private int invocationSeed; + + @Setup(Level.Trial) + public void setup() { + enforcer = new Enforcer(MODEL_PATH, "", false); + } + + @Setup(Level.Invocation) + public void reset() { + enforcer.clearPolicy(); + invocationSeed = invocationSeed * 1103515245 + 12345; + } + } + + @State(Scope.Thread) + public static class UpdateStateSmall { + private Enforcer enforcer; + private List> oldRules; + private List> newRules; + + @Setup(Level.Trial) + public void setup() { + enforcer = new Enforcer(MODEL_PATH, "", false); + } + + @Setup(Level.Invocation) + public void reset() { + enforcer.clearPolicy(); + oldRules = new ArrayList<>(100); + newRules = new ArrayList<>(100); + for (int i = 0; i < 100; i++) { + String user = "user" + i; + String oldData = "data" + i / 10; + String newData = "data" + (i / 10 + 1); + enforcer.addPolicy(user, oldData, "read"); + oldRules.add(Arrays.asList(user, oldData, "read")); + newRules.add(Arrays.asList(user, newData, "read")); + } + } + } + + @State(Scope.Thread) + public static class UpdateStateMedium { + private Enforcer enforcer; + private List> oldRules; + private List> newRules; + + @Setup(Level.Trial) + public void setup() { + enforcer = new Enforcer(MODEL_PATH, "", false); + } + + @Setup(Level.Invocation) + public void reset() { + enforcer.clearPolicy(); + oldRules = new ArrayList<>(100); + newRules = new ArrayList<>(100); + for (int i = 0; i < 100; i++) { + int userIndex = i * 10; + String user = "user" + userIndex; + String oldData = "data" + userIndex / 10; + String newData = "data" + (userIndex / 10 + 1); + enforcer.addPolicy(user, oldData, "read"); + oldRules.add(Arrays.asList(user, oldData, "read")); + newRules.add(Arrays.asList(user, newData, "read")); + } + } + } + + @State(Scope.Thread) + public static class UpdateStateLarge { + private Enforcer enforcer; + private List> oldRules; + private List> newRules; + + @Setup(Level.Trial) + public void setup() { + enforcer = new Enforcer(MODEL_PATH, "", false); + } + + @Setup(Level.Invocation) + public void reset() { + enforcer.clearPolicy(); + oldRules = new ArrayList<>(100); + newRules = new ArrayList<>(100); + for (int i = 0; i < 100; i++) { + int userIndex = i * 100; + String user = "user" + userIndex; + String oldData = "data" + userIndex / 10; + String newData = "data" + (userIndex / 10 + 1); + enforcer.addPolicy(user, oldData, "read"); + oldRules.add(Arrays.asList(user, oldData, "read")); + newRules.add(Arrays.asList(user, newData, "read")); + } + } + } + + @State(Scope.Thread) + public static class RemoveStateSmall { + private Enforcer enforcer; + private String[] users; + private String[] data; + + @Setup(Level.Trial) + public void setup() { + enforcer = new Enforcer(MODEL_PATH, "", false); + users = new String[100]; + data = new String[100]; + for (int i = 0; i < 100; i++) { + users[i] = "user" + i; + data[i] = "data" + i / 10; + } + } + + @Setup(Level.Invocation) + public void reset() { + enforcer.clearPolicy(); + for (int i = 0; i < users.length; i++) { + enforcer.addPolicy(users[i], data[i], "read"); + } + } + } + + @State(Scope.Thread) + public static class RemoveStateMedium { + private Enforcer enforcer; + private String[] users; + private String[] data; + + @Setup(Level.Trial) + public void setup() { + enforcer = new Enforcer(MODEL_PATH, "", false); + users = new String[1000]; + data = new String[1000]; + for (int i = 0; i < 1000; i++) { + users[i] = "user" + i; + data[i] = "data" + i / 10; + } + } + + @Setup(Level.Invocation) + public void reset() { + enforcer.clearPolicy(); + for (int i = 0; i < users.length; i++) { + enforcer.addPolicy(users[i], data[i], "read"); + } + } + } + + @State(Scope.Thread) + public static class RemoveStateLarge { + private Enforcer enforcer; + private String[] users; + private String[] data; + + @Setup(Level.Trial) + public void setup() { + enforcer = new Enforcer(MODEL_PATH, "", false); + users = new String[10000]; + data = new String[10000]; + for (int i = 0; i < 10000; i++) { + users[i] = "user" + i; + data[i] = "data" + i / 10; + } + } + + @Setup(Level.Invocation) + public void reset() { + enforcer.clearPolicy(); + for (int i = 0; i < users.length; i++) { + enforcer.addPolicy(users[i], data[i], "read"); + } } } } diff --git a/src/test/java/org/casbin/jcasbin/main/benchmark/BenchmarkBasicModel.java b/src/test/java/org/casbin/jcasbin/main/benchmark/BenchmarkBasicModel.java index a50e1e2e..15876c19 100644 --- a/src/test/java/org/casbin/jcasbin/main/benchmark/BenchmarkBasicModel.java +++ b/src/test/java/org/casbin/jcasbin/main/benchmark/BenchmarkBasicModel.java @@ -24,28 +24,34 @@ import java.util.concurrent.TimeUnit; -@OutputTimeUnit(TimeUnit.MILLISECONDS) +@OutputTimeUnit(TimeUnit.NANOSECONDS) @BenchmarkMode(Mode.AverageTime) public class BenchmarkBasicModel { - private static Enforcer e = new Enforcer("examples/basic_model.conf", "examples/basic_policy.csv", false); + private static Enforcer e; - public static void main(String args[]) throws RunnerException { + static { + e = new Enforcer("examples/basic_model.conf", "examples/basic_policy.csv", false); + } + + public static void main(String[] args) throws RunnerException { Options opt = new OptionsBuilder() .include(BenchmarkBasicModel.class.getName()) .exclude("Pref") .warmupIterations(3) - .measurementIterations(3) + .measurementIterations(5) .addProfiler(GCProfiler.class) - .forks(1) + .forks(getForks()) .build(); new Runner(opt).run(); } + private static int getForks() { + return Integer.getInteger("jmh.forks", 1); + } + @Threads(1) @Benchmark - public static void benchmarkBasicModel() { - for (int i = 0; i < 1000; i++) { - e.enforce("alice", "data1", "read"); - } + public void benchmarkBasicModel() { + e.enforce("alice", "data1", "read"); } } diff --git a/src/test/java/org/casbin/jcasbin/main/benchmark/BenchmarkKeyMatchModel.java b/src/test/java/org/casbin/jcasbin/main/benchmark/BenchmarkDenyOverrideModel.java similarity index 50% rename from src/test/java/org/casbin/jcasbin/main/benchmark/BenchmarkKeyMatchModel.java rename to src/test/java/org/casbin/jcasbin/main/benchmark/BenchmarkDenyOverrideModel.java index 0dfb16bd..c4f02d9e 100644 --- a/src/test/java/org/casbin/jcasbin/main/benchmark/BenchmarkKeyMatchModel.java +++ b/src/test/java/org/casbin/jcasbin/main/benchmark/BenchmarkDenyOverrideModel.java @@ -24,28 +24,42 @@ import java.util.concurrent.TimeUnit; -@OutputTimeUnit(TimeUnit.MILLISECONDS) +/** + * Benchmark for Deny-override model. + * Data scale: 6 rules (2 users, 1 role). + */ +@OutputTimeUnit(TimeUnit.NANOSECONDS) @BenchmarkMode(Mode.AverageTime) -public class BenchmarkKeyMatchModel { - private static Enforcer e = new Enforcer("examples/keymatch_model.conf", "examples/keymatch_policy.csv", false); +public class BenchmarkDenyOverrideModel { + private static Enforcer e; - public static void main(String args[]) throws RunnerException { + static { + e = new Enforcer("examples/rbac_with_deny_model.conf", "", false); + e.enableAutoBuildRoleLinks(false); + e.addPolicy("alice", "data1", "read", "allow"); + e.addPolicy("bob", "data2", "write", "allow"); + e.addPolicy("data2_admin", "data2", "read", "allow"); + e.addPolicy("data2_admin", "data2", "write", "allow"); + e.addPolicy("alice", "data2", "write", "deny"); + e.addGroupingPolicy("alice", "data2_admin"); + e.buildRoleLinks(); + } + + public static void main(String[] args) throws RunnerException { Options opt = new OptionsBuilder() - .include(BenchmarkKeyMatchModel.class.getName()) - .exclude("Pref") - .warmupIterations(3) - .measurementIterations(3) - .addProfiler(GCProfiler.class) - .forks(1) - .build(); + .include(BenchmarkDenyOverrideModel.class.getName()) + .exclude("Pref") + .warmupIterations(3) + .measurementIterations(5) + .addProfiler(GCProfiler.class) + .forks(2) + .build(); new Runner(opt).run(); } @Threads(1) @Benchmark - public static void benchmarkKeyMatchModel() { - for (int i = 0; i < 1000; i++) { - e.enforce("alice", "/alice_data/resource1", "GET"); - } + public void benchmarkDenyOverrideModel() { + e.enforce("alice", "data1", "read"); } } diff --git a/src/test/java/org/casbin/jcasbin/main/benchmark/BenchmarkPriorityModel.java b/src/test/java/org/casbin/jcasbin/main/benchmark/BenchmarkPriorityModel.java index 18129381..2a6a6b97 100644 --- a/src/test/java/org/casbin/jcasbin/main/benchmark/BenchmarkPriorityModel.java +++ b/src/test/java/org/casbin/jcasbin/main/benchmark/BenchmarkPriorityModel.java @@ -24,28 +24,46 @@ import java.util.concurrent.TimeUnit; -@OutputTimeUnit(TimeUnit.MILLISECONDS) +/** + * Benchmark for Priority model. + * Data scale: 9 rules (2 users, 2 roles). + */ +@OutputTimeUnit(TimeUnit.NANOSECONDS) @BenchmarkMode(Mode.AverageTime) public class BenchmarkPriorityModel { - private static Enforcer e = new Enforcer("examples/priority_model.conf", "examples/priority_policy.csv", false); + private static Enforcer e; - public static void main(String args[]) throws RunnerException { + static { + e = new Enforcer("examples/priority_model.conf", "", false); + e.enableAutoBuildRoleLinks(false); + e.addPolicy("alice", "data1", "read", "allow"); + e.addPolicy("data1_deny_group", "data1", "read", "deny"); + e.addPolicy("data1_deny_group", "data1", "write", "deny"); + e.addPolicy("alice", "data1", "write", "allow"); + e.addGroupingPolicy("alice", "data1_deny_group"); + + e.addPolicy("data2_allow_group", "data2", "read", "allow"); + e.addPolicy("bob", "data2", "read", "deny"); + e.addPolicy("bob", "data2", "write", "deny"); + e.addGroupingPolicy("bob", "data2_allow_group"); + e.buildRoleLinks(); + } + + public static void main(String[] args) throws RunnerException { Options opt = new OptionsBuilder() - .include(BenchmarkPriorityModel.class.getName()) - .exclude("Pref") - .warmupIterations(3) - .measurementIterations(3) - .addProfiler(GCProfiler.class) - .forks(1) - .build(); + .include(BenchmarkPriorityModel.class.getName()) + .exclude("Pref") + .warmupIterations(3) + .measurementIterations(5) + .addProfiler(GCProfiler.class) + .forks(2) + .build(); new Runner(opt).run(); } @Threads(1) @Benchmark - public static void benchmarkPriorityModel() { - for (int i = 0; i < 1000; i++) { - e.enforce("alice", "data1", "read"); - } + public void benchmarkPriorityModel() { + e.enforce("alice", "data1", "read"); } } diff --git a/src/test/java/org/casbin/jcasbin/main/benchmark/BenchmarkRBACModelLarge.java b/src/test/java/org/casbin/jcasbin/main/benchmark/BenchmarkRBACModelLarge.java index c7a9b151..bead70a0 100644 --- a/src/test/java/org/casbin/jcasbin/main/benchmark/BenchmarkRBACModelLarge.java +++ b/src/test/java/org/casbin/jcasbin/main/benchmark/BenchmarkRBACModelLarge.java @@ -24,41 +24,48 @@ import java.util.concurrent.TimeUnit; -@OutputTimeUnit(TimeUnit.MILLISECONDS) +/** + * Benchmark for RBAC model (Large). + * Data scale: 110000 rules (100000 users, 10000 roles). + */ +@OutputTimeUnit(TimeUnit.NANOSECONDS) @BenchmarkMode(Mode.AverageTime) public class BenchmarkRBACModelLarge { - private static Enforcer e = new Enforcer("examples/rbac_model.conf", "", false); + @State(Scope.Benchmark) + public static class BenchmarkState { + private Enforcer e; - public static void main(String args[]) throws RunnerException { + @Setup(Level.Trial) + public void setup() { + e = new Enforcer("examples/rbac_model.conf", "", false); + e.enableAutoBuildRoleLinks(false); + for (int i = 0; i < 10000; i++) { + e.addPolicy(String.format("group%d", i), String.format("data%d", i / 10), "read"); + } + for (int i = 0; i < 100000; i++) { + e.addGroupingPolicy(String.format("user%d", i), String.format("group%d", i / 10)); + } + e.buildRoleLinks(); + } + } + + public static void main(String[] args) throws RunnerException { Options opt = new OptionsBuilder() - .include(BenchmarkRBACModelLarge.class.getName()) - .exclude("Pref") - .warmupIterations(1) - .measurementIterations(1) - .addProfiler(GCProfiler.class) - .forks(1) - .build(); + .include(BenchmarkRBACModelLarge.class.getName()) + .exclude("Pref") + .warmupIterations(3) + .measurementIterations(5) + .addProfiler(GCProfiler.class) + .forks(2) + .build(); new Runner(opt).run(); } @Threads(1) @Benchmark - public static void benchmarkRBACModelLarge() { + public void benchmarkRBACModelLarge(BenchmarkState state) { for (int i = 0; i < 100000; i++) { - e.enforce("user50001", "data1500", "read"); - } - } - - static { - e.enableAutoBuildRoleLinks(false); - // 10000 roles, 1000 resources. - e.enableAutoBuildRoleLinks(false); - for (int i=0;i<10000;i++) { - e.addPolicy(String.format("group%d", i), String.format("data%d", i/10), "read"); - } - for (int i=0;i<100000;i++) { - e.addGroupingPolicy(String.format("user%d", i), String.format("group%d", i/10)); + state.e.enforce("user50001", "data1500", "read"); } - e.buildRoleLinks(); } } diff --git a/src/test/java/org/casbin/jcasbin/main/benchmark/BenchmarkRBACModelMedium.java b/src/test/java/org/casbin/jcasbin/main/benchmark/BenchmarkRBACModelMedium.java index 0b24bd00..b34f06a5 100644 --- a/src/test/java/org/casbin/jcasbin/main/benchmark/BenchmarkRBACModelMedium.java +++ b/src/test/java/org/casbin/jcasbin/main/benchmark/BenchmarkRBACModelMedium.java @@ -24,10 +24,22 @@ import java.util.concurrent.TimeUnit; -@OutputTimeUnit(TimeUnit.MILLISECONDS) +@OutputTimeUnit(TimeUnit.NANOSECONDS) @BenchmarkMode(Mode.AverageTime) public class BenchmarkRBACModelMedium { - private static Enforcer e = new Enforcer("examples/rbac_model.conf", "", false); + private static Enforcer e; + + static { + e = new Enforcer("examples/rbac_model.conf", "", false); + e.enableAutoBuildRoleLinks(false); + for (int i = 0; i < 1000; i++) { + e.addPolicy(String.format("group%d", i), String.format("data%d", i / 10), "read"); + } + for (int i = 0; i < 10000; i++) { + e.addGroupingPolicy(String.format("user%d", i), String.format("group%d", i / 10)); + } + e.buildRoleLinks(); + } public static void main(String args[]) throws RunnerException { Options opt = new OptionsBuilder() @@ -43,22 +55,7 @@ public static void main(String args[]) throws RunnerException { @Threads(1) @Benchmark - public static void benchmarkRBACModelMedium() { - for (int i = 0; i < 10000; i++) { - e.enforce("user5001", "data150", "read"); - } - } - - static { - e.enableAutoBuildRoleLinks(false); - // 1000 roles, 100 resources. - e.enableAutoBuildRoleLinks(false); - for (int i=0;i<1000;i++) { - e.addPolicy(String.format("group%d", i), String.format("data%d", i/10), "read"); - } - for (int i=0;i<10000;i++) { - e.addGroupingPolicy(String.format("user%d", i), String.format("group%d", i/10)); - } - e.buildRoleLinks(); + public void benchmarkRBACModelMedium() { + e.enforce("user5001", "data150", "read"); } } diff --git a/src/test/java/org/casbin/jcasbin/main/benchmark/BenchmarkRBACModelSingle.java b/src/test/java/org/casbin/jcasbin/main/benchmark/BenchmarkRBACModelSingle.java index 3d751941..9fd3c6f5 100644 --- a/src/test/java/org/casbin/jcasbin/main/benchmark/BenchmarkRBACModelSingle.java +++ b/src/test/java/org/casbin/jcasbin/main/benchmark/BenchmarkRBACModelSingle.java @@ -24,28 +24,35 @@ import java.util.concurrent.TimeUnit; -@OutputTimeUnit(TimeUnit.MILLISECONDS) +@OutputTimeUnit(TimeUnit.NANOSECONDS) @BenchmarkMode(Mode.AverageTime) public class BenchmarkRBACModelSingle { - private static Enforcer e = new Enforcer("examples/rbac_model.conf", "examples/rbac_policy.csv", false); + private static Enforcer e; - public static void main(String args[]) throws RunnerException { + static { + e = new Enforcer("examples/rbac_model.conf", "examples/rbac_policy.csv", false); + e.buildRoleLinks(); + } + + public static void main(String[] args) throws RunnerException { Options opt = new OptionsBuilder() .include(BenchmarkRBACModelSingle.class.getName()) .exclude("Pref") .warmupIterations(3) - .measurementIterations(3) + .measurementIterations(5) .addProfiler(GCProfiler.class) - .forks(1) + .forks(getForks()) .build(); new Runner(opt).run(); } + private static int getForks() { + return Integer.getInteger("jmh.forks", 1); + } + @Threads(1) @Benchmark - public static void benchmarkRBACModel() { - for (int i = 0; i < 1000; i++) { - e.enforce("alice", "data2", "read"); - } + public void benchmarkRBACModelSingle() { + e.enforce("alice", "data2", "read"); } } diff --git a/src/test/java/org/casbin/jcasbin/main/benchmark/BenchmarkRBACModelSmall.java b/src/test/java/org/casbin/jcasbin/main/benchmark/BenchmarkRBACModelSmall.java index 18f60a06..0c474159 100644 --- a/src/test/java/org/casbin/jcasbin/main/benchmark/BenchmarkRBACModelSmall.java +++ b/src/test/java/org/casbin/jcasbin/main/benchmark/BenchmarkRBACModelSmall.java @@ -24,10 +24,22 @@ import java.util.concurrent.TimeUnit; -@OutputTimeUnit(TimeUnit.MILLISECONDS) +@OutputTimeUnit(TimeUnit.NANOSECONDS) @BenchmarkMode(Mode.AverageTime) public class BenchmarkRBACModelSmall { - private static Enforcer e = new Enforcer("examples/rbac_model.conf", "", false); + private static Enforcer e; + + static { + e = new Enforcer("examples/rbac_model.conf", "", false); + e.enableAutoBuildRoleLinks(false); + for (int i = 0; i < 100; i++) { + e.addPolicy(String.format("group%d", i), String.format("data%d", i / 10), "read"); + } + for (int i = 0; i < 1000; i++) { + e.addGroupingPolicy(String.format("user%d", i), String.format("group%d", i / 10)); + } + e.buildRoleLinks(); + } public static void main(String args[]) throws RunnerException { Options opt = new OptionsBuilder() @@ -43,22 +55,7 @@ public static void main(String args[]) throws RunnerException { @Threads(1) @Benchmark - public static void benchmarkRBACModelSmall() { - for (int i = 0; i < 1000; i++) { - e.enforce("user501", "data9", "read"); - } - } - - static { - e.enableAutoBuildRoleLinks(false); - // 100 roles, 10 resources. - for (int i = 0; i < 100; i++) { - e.addPolicy(String.format("group%d", i), String.format("data%d", i/10), "read"); - } - // 1000 users. - for (int i = 0; i < 1000; i++) { - e.addGroupingPolicy(String.format("user%d", i), String.format("group%d", i/10)); - } - e.buildRoleLinks(); + public void benchmarkRBACModelSmall() { + e.enforce("user501", "data9", "read"); } } diff --git a/src/test/java/org/casbin/jcasbin/main/benchmark/BenchmarkRBACModelWithDomains.java b/src/test/java/org/casbin/jcasbin/main/benchmark/BenchmarkRBACModelWithDomains.java index d6f581f6..44fa946b 100644 --- a/src/test/java/org/casbin/jcasbin/main/benchmark/BenchmarkRBACModelWithDomains.java +++ b/src/test/java/org/casbin/jcasbin/main/benchmark/BenchmarkRBACModelWithDomains.java @@ -24,28 +24,42 @@ import java.util.concurrent.TimeUnit; -@OutputTimeUnit(TimeUnit.MILLISECONDS) +/** + * Benchmark for RBAC model with domains. + * Data scale: 6 rules (2 users, 1 role, 2 domains). + */ +@OutputTimeUnit(TimeUnit.NANOSECONDS) @BenchmarkMode(Mode.AverageTime) public class BenchmarkRBACModelWithDomains { - private static Enforcer e = new Enforcer("examples/rbac_with_domains_model.conf", "examples/rbac_with_domains_policy.csv", false); + private static Enforcer e; - public static void main(String args[]) throws RunnerException { + static { + e = new Enforcer("examples/rbac_with_domains_model.conf", "", false); + e.enableAutoBuildRoleLinks(false); + e.addPolicy("admin", "domain1", "data1", "read"); + e.addPolicy("admin", "domain1", "data1", "write"); + e.addPolicy("admin", "domain2", "data2", "read"); + e.addPolicy("admin", "domain2", "data2", "write"); + e.addGroupingPolicy("alice", "admin", "domain1"); + e.addGroupingPolicy("bob", "admin", "domain2"); + e.buildRoleLinks(); + } + + public static void main(String[] args) throws RunnerException { Options opt = new OptionsBuilder() - .include(BenchmarkRBACModelWithDomains.class.getName()) - .exclude("Pref") - .warmupIterations(3) - .measurementIterations(3) - .addProfiler(GCProfiler.class) - .forks(1) - .build(); + .include(BenchmarkRBACModelWithDomains.class.getName()) + .exclude("Pref") + .warmupIterations(3) + .measurementIterations(5) + .addProfiler(GCProfiler.class) + .forks(2) + .build(); new Runner(opt).run(); } @Threads(1) @Benchmark - public static void benchmarkRBACModelWithDomains() { - for (int i = 0; i < 1000; i++) { - e.enforce("alice", "domain1", "data1", "read"); - } + public void benchmarkRBACModelWithDomains() { + e.enforce("alice", "domain1", "data1", "read"); } } diff --git a/src/test/java/org/casbin/jcasbin/main/benchmark/BenchmarkRBACModelWithResourceRoles.java b/src/test/java/org/casbin/jcasbin/main/benchmark/BenchmarkRBACModelWithResourceRoles.java index 61414979..9188c678 100644 --- a/src/test/java/org/casbin/jcasbin/main/benchmark/BenchmarkRBACModelWithResourceRoles.java +++ b/src/test/java/org/casbin/jcasbin/main/benchmark/BenchmarkRBACModelWithResourceRoles.java @@ -24,28 +24,42 @@ import java.util.concurrent.TimeUnit; -@OutputTimeUnit(TimeUnit.MILLISECONDS) +/** + * Benchmark for RBAC model with resource roles. + * Data scale: 6 rules (2 users, 2 roles). + */ +@OutputTimeUnit(TimeUnit.NANOSECONDS) @BenchmarkMode(Mode.AverageTime) public class BenchmarkRBACModelWithResourceRoles { - private static Enforcer e = new Enforcer("examples/rbac_with_resource_roles_model.conf", "examples/rbac_with_resource_roles_policy.csv", false); + private static Enforcer e; - public static void main(String args[]) throws RunnerException { + static { + e = new Enforcer("examples/rbac_with_resource_roles_model.conf", "", false); + e.enableAutoBuildRoleLinks(false); + e.addPolicy("alice", "data1", "read"); + e.addPolicy("bob", "data2", "write"); + e.addPolicy("data_group_admin", "data_group", "write"); + e.addGroupingPolicy("alice", "data_group_admin"); + e.addNamedGroupingPolicy("g2", "data1", "data_group"); + e.addNamedGroupingPolicy("g2", "data2", "data_group"); + e.buildRoleLinks(); + } + + public static void main(String[] args) throws RunnerException { Options opt = new OptionsBuilder() - .include(BenchmarkRBACModelWithResourceRoles.class.getName()) - .exclude("Pref") - .warmupIterations(3) - .measurementIterations(3) - .addProfiler(GCProfiler.class) - .forks(1) - .build(); + .include(BenchmarkRBACModelWithResourceRoles.class.getName()) + .exclude("Pref") + .warmupIterations(3) + .measurementIterations(5) + .addProfiler(GCProfiler.class) + .forks(2) + .build(); new Runner(opt).run(); } @Threads(1) @Benchmark - public static void benchmarkRBACModelWithResourceRoles() { - for (int i = 0; i < 1000; i++) { - e.enforce("alice", "data1", "read"); - } + public void benchmarkRBACModelWithResourceRoles() { + e.enforce("alice", "data1", "read"); } } diff --git a/src/test/java/org/casbin/jcasbin/main/benchmark/BenchmarkRBACModelWithDeny.java b/src/test/java/org/casbin/jcasbin/main/benchmark/BenchmarkRestfulModel.java similarity index 52% rename from src/test/java/org/casbin/jcasbin/main/benchmark/BenchmarkRBACModelWithDeny.java rename to src/test/java/org/casbin/jcasbin/main/benchmark/BenchmarkRestfulModel.java index 5802a1b5..262e86bb 100644 --- a/src/test/java/org/casbin/jcasbin/main/benchmark/BenchmarkRBACModelWithDeny.java +++ b/src/test/java/org/casbin/jcasbin/main/benchmark/BenchmarkRestfulModel.java @@ -24,28 +24,41 @@ import java.util.concurrent.TimeUnit; -@OutputTimeUnit(TimeUnit.MILLISECONDS) +/** + * Benchmark for RESTful (KeyMatch) model. + * Data scale: 5 rules (3 users). + */ +@OutputTimeUnit(TimeUnit.NANOSECONDS) @BenchmarkMode(Mode.AverageTime) -public class BenchmarkRBACModelWithDeny { - private static Enforcer e = new Enforcer("examples/rbac_with_deny_model.conf", "examples/rbac_with_deny_policy.csv", false); +public class BenchmarkRestfulModel { + private static Enforcer e; - public static void main(String args[]) throws RunnerException { + static { + e = new Enforcer("examples/keymatch_model.conf", "", false); + e.enableAutoBuildRoleLinks(false); + e.addPolicy("alice", "/alice_data/*", "GET"); + e.addPolicy("alice", "/alice_data/resource1", "POST"); + e.addPolicy("bob", "/alice_data/resource2", "GET"); + e.addPolicy("bob", "/bob_data/*", "POST"); + e.addPolicy("cathy", "/cathy_data", "(GET)|(POST)"); + e.buildRoleLinks(); + } + + public static void main(String[] args) throws RunnerException { Options opt = new OptionsBuilder() - .include(BenchmarkRBACModelWithDeny.class.getName()) - .exclude("Pref") - .warmupIterations(3) - .measurementIterations(3) - .addProfiler(GCProfiler.class) - .forks(1) - .build(); + .include(BenchmarkRestfulModel.class.getName()) + .exclude("Pref") + .warmupIterations(3) + .measurementIterations(5) + .addProfiler(GCProfiler.class) + .forks(2) + .build(); new Runner(opt).run(); } @Threads(1) @Benchmark - public static void benchmarkRBACModelWithDeny() { - for (int i = 0; i < 1000; i++) { - e.enforce("alice", "data1", "read"); - } + public void benchmarkRestfulModel() { + e.enforce("alice", "/alice_data/resource1", "GET"); } }