// Licensed to the Apache Software Foundation (ASF) under one // or more contributor license agreements. See the NOTICE file // distributed with this work for additional information // regarding copyright ownership. The ASF licenses this file // to you under the Apache License, Version 2.0 (the // "License"); you may not use this file except in compliance // with the License. You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, // software distributed under the License is distributed on an // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY // KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. package casbin import ( "fmt" "testing" "github.com/casbin/casbin/v3/util" ) func BenchmarkRoleManagerSmall(b *testing.B) { e, _ := NewEnforcer("examples/rbac_model.conf") // Do not rebuild the role inheritance relations for every AddGroupingPolicy() call. e.EnableAutoBuildRoleLinks(false) // 100 roles, 10 resources. pPolicies := make([][]string, 0) for i := 0; i < 100; i++ { pPolicies = append(pPolicies, []string{fmt.Sprintf("group%d", i), fmt.Sprintf("data%d", i/10), "read"}) } _, err := e.AddPolicies(pPolicies) if err != nil { b.Fatal(err) } // 1000 users. gPolicies := make([][]string, 0) for i := 0; i < 1000; i++ { gPolicies = append(gPolicies, []string{fmt.Sprintf("user%d", i), fmt.Sprintf("group%d", i/10)}) } _, err = e.AddGroupingPolicies(gPolicies) if err != nil { b.Fatal(err) } rm := e.GetRoleManager() b.ResetTimer() for i := 0; i < b.N; i++ { for j := 0; j < 100; j++ { _, _ = rm.HasLink("user501", fmt.Sprintf("group%d", j)) } } } func BenchmarkRoleManagerMedium(b *testing.B) { e, _ := NewEnforcer("examples/rbac_model.conf") // Do not rebuild the role inheritance relations for every AddGroupingPolicy() call. e.EnableAutoBuildRoleLinks(false) // 1000 roles, 100 resources. pPolicies := make([][]string, 0) for i := 0; i < 1000; i++ { pPolicies = append(pPolicies, []string{fmt.Sprintf("group%d", i), fmt.Sprintf("data%d", i/10), "read"}) } _, err := e.AddPolicies(pPolicies) if err != nil { b.Fatal(err) } // 10000 users. gPolicies := make([][]string, 0) for i := 0; i < 10000; i++ { gPolicies = append(gPolicies, []string{fmt.Sprintf("user%d", i), fmt.Sprintf("group%d", i/10)}) } _, err = e.AddGroupingPolicies(gPolicies) if err != nil { b.Fatal(err) } err = e.BuildRoleLinks() if err != nil { b.Fatal(err) } rm := e.GetRoleManager() b.ResetTimer() for i := 0; i < b.N; i++ { for j := 0; j < 1000; j++ { _, _ = rm.HasLink("user501", fmt.Sprintf("group%d", j)) } } } func BenchmarkRoleManagerLarge(b *testing.B) { e, _ := NewEnforcer("examples/rbac_model.conf") // 10000 roles, 1000 resources. pPolicies := make([][]string, 0) for i := 0; i < 10000; i++ { pPolicies = append(pPolicies, []string{fmt.Sprintf("group%d", i), fmt.Sprintf("data%d", i/10), "read"}) } _, err := e.AddPolicies(pPolicies) if err != nil { b.Fatal(err) } // 100000 users. gPolicies := make([][]string, 0) for i := 0; i < 100000; i++ { gPolicies = append(gPolicies, []string{fmt.Sprintf("user%d", i), fmt.Sprintf("group%d", i/10)}) } _, err = e.AddGroupingPolicies(gPolicies) if err != nil { b.Fatal(err) } rm := e.GetRoleManager() b.ResetTimer() for i := 0; i < b.N; i++ { for j := 0; j < 10000; j++ { _, _ = rm.HasLink("user501", fmt.Sprintf("group%d", j)) } } } func BenchmarkBuildRoleLinksWithPatternLarge(b *testing.B) { e, _ := NewEnforcer("examples/performance/rbac_with_pattern_large_scale_model.conf", "examples/performance/rbac_with_pattern_large_scale_policy.csv") e.AddNamedMatchingFunc("g", "", util.KeyMatch4) b.ResetTimer() for i := 0; i < b.N; i++ { _ = e.BuildRoleLinks() } } func BenchmarkBuildRoleLinksWithDomainPatternLarge(b *testing.B) { e, _ := NewEnforcer("examples/performance/rbac_with_pattern_large_scale_model.conf", "examples/performance/rbac_with_pattern_large_scale_policy.csv") e.AddNamedDomainMatchingFunc("g", "", util.KeyMatch4) b.ResetTimer() for i := 0; i < b.N; i++ { _ = e.BuildRoleLinks() } } func BenchmarkBuildRoleLinksWithPatternAndDomainPatternLarge(b *testing.B) { e, _ := NewEnforcer("examples/performance/rbac_with_pattern_large_scale_model.conf", "examples/performance/rbac_with_pattern_large_scale_policy.csv") e.AddNamedMatchingFunc("g", "", util.KeyMatch4) e.AddNamedDomainMatchingFunc("g", "", util.KeyMatch4) b.ResetTimer() for i := 0; i < b.N; i++ { _ = e.BuildRoleLinks() } } func BenchmarkHasLinkWithPatternLarge(b *testing.B) { e, _ := NewEnforcer("examples/performance/rbac_with_pattern_large_scale_model.conf", "examples/performance/rbac_with_pattern_large_scale_policy.csv") e.AddNamedMatchingFunc("g", "", util.KeyMatch4) rm := e.rmMap["g"] b.ResetTimer() for i := 0; i < b.N; i++ { _, _ = rm.HasLink("staffUser1001", "staff001", "/orgs/1/sites/site001") } } func BenchmarkHasLinkWithDomainPatternLarge(b *testing.B) { e, _ := NewEnforcer("examples/performance/rbac_with_pattern_large_scale_model.conf", "examples/performance/rbac_with_pattern_large_scale_policy.csv") e.AddNamedDomainMatchingFunc("g", "", util.KeyMatch4) rm := e.rmMap["g"] b.ResetTimer() for i := 0; i < b.N; i++ { _, _ = rm.HasLink("staffUser1001", "staff001", "/orgs/1/sites/site001") } } func BenchmarkHasLinkWithPatternAndDomainPatternLarge(b *testing.B) { e, _ := NewEnforcer("examples/performance/rbac_with_pattern_large_scale_model.conf", "examples/performance/rbac_with_pattern_large_scale_policy.csv") e.AddNamedMatchingFunc("g", "", util.KeyMatch4) e.AddNamedDomainMatchingFunc("g", "", util.KeyMatch4) rm := e.rmMap["g"] b.ResetTimer() for i := 0; i < b.N; i++ { _, _ = rm.HasLink("staffUser1001", "staff001", "/orgs/1/sites/site001") } } // BenchmarkConcurrentHasLinkWithMatching benchmarks concurrent HasLink performance with matching functions. // Performance test for concurrent access with temporary role creation. func BenchmarkConcurrentHasLinkWithMatching(b *testing.B) { e, _ := NewEnforcer("examples/rbac_with_pattern_model.conf", "examples/rbac_with_pattern_policy.csv") e.AddNamedMatchingFunc("g2", "keyMatch2", util.KeyMatch2) rm := e.GetRoleManager() b.ResetTimer() b.RunParallel(func(pb *testing.PB) { for pb.Next() { _, _ = rm.HasLink("alice", "/book/123") } }) }