github.com/whoyao/protocol@v0.0.0-20230519045905-2d8ace718ca5/utils/protoproxy_test.go (about) 1 package utils 2 3 import ( 4 "runtime" 5 "sync/atomic" 6 "testing" 7 "time" 8 9 "github.com/stretchr/testify/require" 10 11 "github.com/whoyao/protocol/livekit" 12 ) 13 14 func TestProtoProxy(t *testing.T) { 15 numGoRoutines := runtime.NumGoroutine() 16 proxy, numParticipants := createTestProxy() 17 18 select { 19 case <-proxy.Updated(): 20 t.Fatal("should not have received an update") 21 default: 22 } 23 24 // should not have changed, initial value should persist 25 require.EqualValues(t, 0, proxy.Get().NumParticipants) 26 require.EqualValues(t, 0, proxy.Get().NumParticipants) 27 28 // immediate change 29 proxy.MarkDirty(true) 30 time.Sleep(100 * time.Millisecond) 31 32 require.EqualValues(t, 2, numParticipants.Load()) 33 require.EqualValues(t, 1, proxy.Get().NumParticipants) 34 35 // queued updates 36 proxy.MarkDirty(false) 37 select { 38 case <-proxy.Updated(): 39 // consume previous notification 40 default: 41 } 42 require.EqualValues(t, 1, proxy.Get().NumParticipants) 43 44 select { 45 case <-proxy.Updated(): 46 case <-time.After(100 * time.Millisecond): 47 t.Fatal("should have received an update") 48 } 49 require.EqualValues(t, 2, proxy.Get().NumParticipants) 50 51 // ensure we didn't leak 52 proxy.Stop() 53 54 for i := 0; i < 10; i++ { 55 if numGoRoutines <= runtime.NumGoroutine() { 56 break 57 } 58 time.Sleep(100 * time.Millisecond) 59 } 60 require.LessOrEqual(t, runtime.NumGoroutine(), numGoRoutines) 61 } 62 63 func createTestProxy() (*ProtoProxy[*livekit.Room], *atomic.Uint32) { 64 // uses an update func that increments numParticipants each time 65 var numParticipants atomic.Uint32 66 return NewProtoProxy[*livekit.Room](10*time.Millisecond, func() *livekit.Room { 67 defer numParticipants.Add(1) 68 return &livekit.Room{ 69 NumParticipants: numParticipants.Load(), 70 } 71 }), &numParticipants 72 }