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  }