github.com/authzed/spicedb@v1.32.1-0.20240520085336-ebda56537386/internal/services/integrationtesting/benchmark_test.go (about) 1 //go:build docker && !skipintegrationtests 2 // +build docker,!skipintegrationtests 3 4 package integrationtesting_test 5 6 import ( 7 "context" 8 "embed" 9 "testing" 10 "time" 11 12 "github.com/stretchr/testify/require" 13 14 v1 "github.com/authzed/authzed-go/proto/authzed/api/v1" 15 datastoremw "github.com/authzed/spicedb/internal/middleware/datastore" 16 "github.com/authzed/spicedb/internal/services/integrationtesting/consistencytestutil" 17 "github.com/authzed/spicedb/internal/testserver" 18 testdatastore "github.com/authzed/spicedb/internal/testserver/datastore" 19 "github.com/authzed/spicedb/internal/testserver/datastore/config" 20 dsconfig "github.com/authzed/spicedb/pkg/cmd/datastore" 21 "github.com/authzed/spicedb/pkg/datastore" 22 core "github.com/authzed/spicedb/pkg/proto/core/v1" 23 "github.com/authzed/spicedb/pkg/tuple" 24 "github.com/authzed/spicedb/pkg/validationfile" 25 ) 26 27 //go:embed benchconfigs/*.yaml testconfigs/*.yaml 28 var testFiles embed.FS 29 30 func BenchmarkServices(b *testing.B) { 31 bts := []struct { 32 title string 33 fileName string 34 runner func(ctx context.Context, b *testing.B, tester consistencytestutil.ServiceTester, revision datastore.Revision) error 35 }{ 36 { 37 "basic lookup of view for a user", 38 "testconfigs/basicrbac.yaml", 39 func(ctx context.Context, b *testing.B, tester consistencytestutil.ServiceTester, revision datastore.Revision) error { 40 results, _, err := tester.LookupResources(ctx, &core.RelationReference{ 41 Namespace: "example/document", 42 Relation: "view", 43 }, &core.ObjectAndRelation{ 44 Namespace: "example/user", 45 ObjectId: "tom", 46 Relation: tuple.Ellipsis, 47 }, revision, nil, 0) 48 require.GreaterOrEqual(b, len(results), 0) 49 return err 50 }, 51 }, 52 { 53 "recursively through groups", 54 "testconfigs/simplerecursive.yaml", 55 func(ctx context.Context, b *testing.B, tester consistencytestutil.ServiceTester, revision datastore.Revision) error { 56 results, _, err := tester.LookupResources(ctx, &core.RelationReference{ 57 Namespace: "srrr/resource", 58 Relation: "viewer", 59 }, &core.ObjectAndRelation{ 60 Namespace: "srrr/user", 61 ObjectId: "someguy", 62 Relation: tuple.Ellipsis, 63 }, revision, nil, 0) 64 require.GreaterOrEqual(b, len(results), 0) 65 return err 66 }, 67 }, 68 { 69 "recursively through wide groups", 70 "benchconfigs/widegroups.yaml", 71 func(ctx context.Context, b *testing.B, tester consistencytestutil.ServiceTester, revision datastore.Revision) error { 72 results, _, err := tester.LookupResources(ctx, &core.RelationReference{ 73 Namespace: "resource", 74 Relation: "view", 75 }, &core.ObjectAndRelation{ 76 Namespace: "user", 77 ObjectId: "tom", 78 Relation: tuple.Ellipsis, 79 }, revision, nil, 0) 80 require.GreaterOrEqual(b, len(results), 0) 81 return err 82 }, 83 }, 84 { 85 "lookup with intersection", 86 "benchconfigs/lookupintersection.yaml", 87 func(ctx context.Context, b *testing.B, tester consistencytestutil.ServiceTester, revision datastore.Revision) error { 88 results, _, err := tester.LookupResources(ctx, &core.RelationReference{ 89 Namespace: "resource", 90 Relation: "view", 91 }, &core.ObjectAndRelation{ 92 Namespace: "user", 93 ObjectId: "tom", 94 Relation: tuple.Ellipsis, 95 }, revision, nil, 0) 96 require.Equal(b, len(results), 499) 97 return err 98 }, 99 }, 100 { 101 "basic check for a user", 102 "testconfigs/basicrbac.yaml", 103 func(ctx context.Context, b *testing.B, tester consistencytestutil.ServiceTester, revision datastore.Revision) error { 104 result, err := tester.Check(ctx, &core.ObjectAndRelation{ 105 Namespace: "example/document", 106 ObjectId: "firstdoc", 107 Relation: "view", 108 }, &core.ObjectAndRelation{ 109 Namespace: "example/user", 110 ObjectId: "tom", 111 Relation: tuple.Ellipsis, 112 }, revision, nil) 113 require.Equal(b, v1.CheckPermissionResponse_PERMISSIONSHIP_HAS_PERMISSION, result) 114 return err 115 }, 116 }, 117 { 118 "recursive check for a user", 119 "testconfigs/quay.yaml", 120 func(ctx context.Context, b *testing.B, tester consistencytestutil.ServiceTester, revision datastore.Revision) error { 121 result, err := tester.Check(ctx, &core.ObjectAndRelation{ 122 Namespace: "quay/repo", 123 ObjectId: "buynlarge/orgrepo", 124 Relation: "view", 125 }, &core.ObjectAndRelation{ 126 Namespace: "quay/user", 127 ObjectId: "cto", 128 Relation: tuple.Ellipsis, 129 }, revision, nil) 130 require.Equal(b, v1.CheckPermissionResponse_PERMISSIONSHIP_HAS_PERMISSION, result) 131 return err 132 }, 133 }, 134 { 135 "wide groups check for a user", 136 "benchconfigs/checkwidegroups.yaml", 137 func(ctx context.Context, b *testing.B, tester consistencytestutil.ServiceTester, revision datastore.Revision) error { 138 result, err := tester.Check(ctx, &core.ObjectAndRelation{ 139 Namespace: "resource", 140 ObjectId: "someresource", 141 Relation: "view", 142 }, &core.ObjectAndRelation{ 143 Namespace: "user", 144 ObjectId: "tom", 145 Relation: tuple.Ellipsis, 146 }, revision, nil) 147 require.Equal(b, v1.CheckPermissionResponse_PERMISSIONSHIP_HAS_PERMISSION, result) 148 return err 149 }, 150 }, 151 { 152 "wide direct relation check", 153 "benchconfigs/checkwidedirect.yaml", 154 func(ctx context.Context, b *testing.B, tester consistencytestutil.ServiceTester, revision datastore.Revision) error { 155 result, err := tester.Check(ctx, &core.ObjectAndRelation{ 156 Namespace: "resource", 157 ObjectId: "someresource", 158 Relation: "view", 159 }, &core.ObjectAndRelation{ 160 Namespace: "user", 161 ObjectId: "tom", 162 Relation: tuple.Ellipsis, 163 }, revision, nil) 164 require.Equal(b, v1.CheckPermissionResponse_PERMISSIONSHIP_HAS_PERMISSION, result) 165 return err 166 }, 167 }, 168 } 169 170 for _, bt := range bts { 171 b.Run(bt.title, func(b *testing.B) { 172 for _, engineID := range datastore.Engines { 173 b.Run(engineID, func(b *testing.B) { 174 brequire := require.New(b) 175 176 rde := testdatastore.RunDatastoreEngine(b, engineID) 177 ds := rde.NewDatastore(b, config.DatastoreConfigInitFunc(b, 178 dsconfig.WithWatchBufferLength(0), 179 dsconfig.WithGCWindow(time.Duration(90_000_000_000_000)), 180 dsconfig.WithRevisionQuantization(10), 181 dsconfig.WithMaxRetries(50), 182 dsconfig.WithRequestHedgingEnabled(false), 183 )) 184 185 contents, err := testFiles.ReadFile(bt.fileName) 186 require.NoError(b, err) 187 188 _, revision, err := validationfile.PopulateFromFilesContents(context.Background(), ds, map[string][]byte{ 189 "testfile": contents, 190 }) 191 brequire.NoError(err) 192 193 conn, cleanup := testserver.TestClusterWithDispatchAndCacheConfig(b, 1, ds) 194 b.Cleanup(cleanup) 195 196 dsCtx := datastoremw.ContextWithHandle(context.Background()) 197 brequire.NoError(datastoremw.SetInContext(dsCtx, ds)) 198 199 testers := consistencytestutil.ServiceTesters(conn[0]) 200 201 for _, tester := range testers { 202 b.Run(tester.Name(), func(b *testing.B) { 203 require := require.New(b) 204 for n := 0; n < b.N; n++ { 205 require.NoError(bt.runner(dsCtx, b, tester, revision)) 206 } 207 }) 208 } 209 }) 210 } 211 }) 212 } 213 }