@@ -7,10 +7,12 @@ import (
7
7
8
8
"github.com/google/uuid"
9
9
"github.com/prometheus/client_golang/prometheus"
10
+ "github.com/stretchr/testify/assert"
10
11
"github.com/stretchr/testify/require"
11
12
12
13
"github.com/coder/coder/v2/coderd/coderdtest"
13
14
"github.com/coder/coder/v2/coderd/rbac"
15
+ "github.com/coder/coder/v2/testutil"
14
16
)
15
17
16
18
type benchmarkCase struct {
@@ -351,6 +353,47 @@ func TestCacher(t *testing.T) {
351
353
require .NoError (t , rec .AllAsserted (), "all assertions should have been made" )
352
354
})
353
355
356
+ t .Run ("DontCacheTransientErrors" , func (t * testing.T ) {
357
+ t .Parallel ()
358
+
359
+ var (
360
+ ctx = testutil .Context (t , testutil .WaitShort )
361
+ authOut = make (chan error , 1 ) // buffered to not block
362
+ authorizeFunc = func (ctx context.Context , subject rbac.Subject , action rbac.Action , object rbac.Object ) error {
363
+ // Just return what you're told.
364
+ return testutil .RequireRecvCtx (ctx , t , authOut )
365
+ }
366
+ ma = & rbac.MockAuthorizer {AuthorizeFunc : authorizeFunc }
367
+ rec = & coderdtest.RecordingAuthorizer {Wrapped : ma }
368
+ authz = rbac .Cacher (rec )
369
+ subj , obj , action = coderdtest .RandomRBACSubject (), coderdtest .RandomRBACObject (), coderdtest .RandomRBACAction ()
370
+ )
371
+
372
+ // First call will result in a transient error. This should not be cached.
373
+ testutil .RequireSendCtx (ctx , t , authOut , context .Canceled )
374
+ err := authz .Authorize (ctx , subj , action , obj )
375
+ assert .ErrorIs (t , err , context .Canceled )
376
+
377
+ // A subsequent call should still hit the authorizer.
378
+ testutil .RequireSendCtx (ctx , t , authOut , nil )
379
+ err = authz .Authorize (ctx , subj , action , obj )
380
+ assert .NoError (t , err )
381
+ // This should be cached and not hit the wrapped authorizer again.
382
+ err = authz .Authorize (ctx , subj , action , obj )
383
+ assert .NoError (t , err )
384
+
385
+ // Let's change the subject.
386
+ subj , obj , action = coderdtest .RandomRBACSubject (), coderdtest .RandomRBACObject (), coderdtest .RandomRBACAction ()
387
+
388
+ // A third will be a legit error
389
+ testutil .RequireSendCtx (ctx , t , authOut , assert .AnError )
390
+ err = authz .Authorize (ctx , subj , action , obj )
391
+ assert .EqualError (t , err , assert .AnError .Error ())
392
+ // This should be cached and not hit the wrapped authorizer again.
393
+ err = authz .Authorize (ctx , subj , action , obj )
394
+ assert .EqualError (t , err , assert .AnError .Error ())
395
+ })
396
+
354
397
t .Run ("MultipleSubjects" , func (t * testing.T ) {
355
398
t .Parallel ()
356
399
0 commit comments