github.com/keybase/client/go@v0.0.0-20240309051027-028f7c731f8b/offline/rpc_cache_test.go (about) 1 // Copyright 2019 Keybase, Inc. All rights reserved. Use of 2 // this source code is governed by the included BSD license. 3 4 package offline 5 6 import ( 7 "testing" 8 9 "github.com/keybase/client/go/libkb" 10 "github.com/keybase/client/go/protocol/keybase1" 11 "github.com/keybase/clockwork" 12 "github.com/stretchr/testify/require" 13 ) 14 15 func TestRPCCacheBestEffort(t *testing.T) { 16 tc := libkb.SetupTest(t, "RPCCache()", 1) 17 defer tc.Cleanup() 18 19 fakeClock := clockwork.NewFakeClock() 20 tc.G.SetClock(fakeClock) 21 22 rpcCache := NewRPCCache(tc.G) 23 24 inHandlerCh := make(chan struct{}, 1) 25 handlerCh := make(chan interface{}, 1) 26 handler := func(mctx libkb.MetaContext) (interface{}, error) { 27 inHandlerCh <- struct{}{} 28 return <-handlerCh, nil 29 } 30 31 mctx := libkb.NewMetaContextBackground(tc.G) 32 33 t.Log("Populate the cache via the handler") 34 rpc := "TestRPC" 35 key := 1 36 value := 2 37 handlerCh <- value 38 var res int 39 resp := &res 40 servedRes, err := rpcCache.Serve( 41 mctx, keybase1.OfflineAvailability_BEST_EFFORT, 1, rpc, false, 42 key, resp, handler) 43 require.NoError(t, err) 44 require.Equal(t, 0, res) // `res` isn't filled in when the handler is used. 45 require.Equal(t, value, servedRes.(int)) 46 <-inHandlerCh 47 48 t.Log("Read via the handler, when the cache is populated") 49 var res2 int 50 resp2 := &res2 51 handlerCh <- value 52 servedRes2, err := rpcCache.Serve( 53 mctx, keybase1.OfflineAvailability_BEST_EFFORT, 1, rpc, false, 54 key, resp2, handler) 55 require.NoError(t, err) 56 require.Equal(t, 2, res2) // `res` is filled in by the cache, but shouldn't be used because `servedRes2` is also filled in. 57 require.Equal(t, value, servedRes2.(int)) 58 <-inHandlerCh 59 60 t.Log("Read via the cache, when connected but the handler is slow") 61 var res3 int 62 resp3 := &res3 63 var servedRes3 interface{} 64 errCh := make(chan error) 65 go func() { 66 var err error 67 servedRes3, err = rpcCache.Serve( 68 mctx, keybase1.OfflineAvailability_BEST_EFFORT, 1, rpc, false, 69 key, resp3, handler) 70 errCh <- err 71 }() 72 73 // Wait for the handler to be entered, then advance the clock. 74 <-inHandlerCh 75 fakeClock.Advance(bestEffortHandlerTimeout + 1) 76 err = <-errCh 77 require.NoError(t, err) 78 require.Equal(t, 2, res3) 79 require.Nil(t, servedRes3) // The filled-in cached value should be used. 80 }