github.com/authzed/spicedb@v1.32.1-0.20240520085336-ebda56537386/pkg/datastore/test/transactions.go (about) 1 package test 2 3 import ( 4 "context" 5 "errors" 6 "testing" 7 "time" 8 9 "github.com/stretchr/testify/require" 10 11 "github.com/authzed/spicedb/pkg/datastore" 12 "github.com/authzed/spicedb/pkg/datastore/options" 13 ) 14 15 func RetryTest(t *testing.T, tester DatastoreTester) { 16 disableRetriesOptions := []options.RWTOptionsOption{options.WithDisableRetries(true)} 17 18 testCases := []struct { 19 name string 20 returnRetryableError bool 21 txOptions []options.RWTOptionsOption 22 countAssertion func(require.TestingT, interface{}, ...interface{}) 23 }{ 24 {"retryable with retries", true, nil, require.Positive}, 25 {"non-retryable with retries", false, nil, require.Zero}, 26 {"retryable retries disabled", true, disableRetriesOptions, require.Zero}, 27 {"non-retryable retries disabled", false, disableRetriesOptions, require.Zero}, 28 } 29 30 for _, tc := range testCases { 31 t.Run(tc.name, func(t *testing.T) { 32 require := require.New(t) 33 34 rawDS, err := tester.New(0, veryLargeGCInterval, veryLargeGCWindow, 1) 35 require.NoError(err) 36 37 ds := rawDS.(TestableDatastore) 38 39 ctx, cancel := context.WithTimeout(context.Background(), 1500*time.Millisecond) 40 defer cancel() 41 42 var attempts int 43 _, err = ds.ReadWriteTx(ctx, func(ctx context.Context, rwt datastore.ReadWriteTransaction) error { 44 attempts++ 45 46 if tc.returnRetryableError { 47 return ds.ExampleRetryableError() 48 } 49 return errors.New("not retryable") 50 }, tc.txOptions...) 51 52 require.GreaterOrEqual(attempts, 1) 53 require.Error(err) 54 55 retries := attempts - 1 56 tc.countAssertion(t, retries) 57 }) 58 } 59 }