From b59da61ebf60252abeb0a04a43697b77ad30e319 Mon Sep 17 00:00:00 2001 From: Paul Wells Date: Thu, 13 Nov 2025 22:36:40 -0800 Subject: [PATCH 1/4] add test for client middleware options --- rpc/typed_api_test.go | 70 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) create mode 100644 rpc/typed_api_test.go diff --git a/rpc/typed_api_test.go b/rpc/typed_api_test.go new file mode 100644 index 000000000..914885e61 --- /dev/null +++ b/rpc/typed_api_test.go @@ -0,0 +1,70 @@ +package rpc + +import ( + "context" + "fmt" + reflect "reflect" + "runtime" + "slices" + "testing" + "time" + + "github.com/prometheus/client_golang/prometheus" + "github.com/stretchr/testify/require" + "google.golang.org/protobuf/proto" + + "github.com/livekit/protocol/logger" + "github.com/livekit/psrpc" + "github.com/livekit/psrpc/pkg/middleware" +) + +func TestMiddleware(t *testing.T) { + t.Run("common middleware propagate client request args", func(t *testing.T) { + InitPSRPCStats(prometheus.Labels{}) + + cases := []struct { + label string + opt psrpc.ClientOption + }{ + {"WithClientLogger", WithClientLogger(logger.GetLogger())}, + {"WithClientMetrics", middleware.WithClientMetrics(PSRPCMetricsObserver{})}, + {"WithClientObservability", WithClientObservability(logger.GetLogger())}, + } + + for _, c := range cases { + var o psrpc.ClientOpts + c.opt(&o) + t.Run(c.label, func(t *testing.T) { + for _, c := range o.RpcInterceptors { + ch := make(chan []psrpc.RequestOption, 1) + call := c(psrpc.RPCInfo{}, func(ctx context.Context, req proto.Message, opts ...psrpc.RequestOption) (proto.Message, error) { + ch <- opts + return nil, nil + }) + + expected := []psrpc.RequestOption{func(*psrpc.RequestOpts) {}, func(*psrpc.RequestOpts) {}} + call(context.Background(), nil, expected...) + + eqPtr := func(a psrpc.RequestOption) func(a psrpc.RequestOption) bool { + return func(b psrpc.RequestOption) bool { + return reflect.ValueOf(a).Pointer() == reflect.ValueOf(b).Pointer() + } + } + + select { + case res := <-ch: + fp := reflect.ValueOf(c).Pointer() + f := runtime.FuncForPC(fp) + file, line := f.FileLine(fp) + name := fmt.Sprintf("%s:%d %s", file, line, f.Name()) + + require.True(t, slices.ContainsFunc(res, eqPtr(expected[0])), "failed to receive option 0 from %s", name) + require.True(t, slices.ContainsFunc(res, eqPtr(expected[1])), "failed to receive option 0 from %s", name) + case <-time.After(time.Second): + require.FailNow(t, "timeout waiting for arguments") + } + } + }) + } + }) +} From 1631f69d6bf2456d9b345775f34f8e68280fbab3 Mon Sep 17 00:00:00 2001 From: Paul Wells Date: Thu, 13 Nov 2025 22:37:40 -0800 Subject: [PATCH 2/4] Create warm-jokes-drive.md --- .changeset/warm-jokes-drive.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/warm-jokes-drive.md diff --git a/.changeset/warm-jokes-drive.md b/.changeset/warm-jokes-drive.md new file mode 100644 index 000000000..30ec50cd7 --- /dev/null +++ b/.changeset/warm-jokes-drive.md @@ -0,0 +1,5 @@ +--- +"@livekit/protocol": patch +--- + +add test for client middleware options From 2cbb79d5dfd09371385748712ea6c922bb9ea784 Mon Sep 17 00:00:00 2001 From: Paul Wells Date: Thu, 13 Nov 2025 22:39:34 -0800 Subject: [PATCH 3/4] tidy --- rpc/typed_api_test.go | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/rpc/typed_api_test.go b/rpc/typed_api_test.go index 914885e61..cd690b9eb 100644 --- a/rpc/typed_api_test.go +++ b/rpc/typed_api_test.go @@ -43,7 +43,7 @@ func TestMiddleware(t *testing.T) { }) expected := []psrpc.RequestOption{func(*psrpc.RequestOpts) {}, func(*psrpc.RequestOpts) {}} - call(context.Background(), nil, expected...) + go call(context.Background(), nil, expected...) eqPtr := func(a psrpc.RequestOption) func(a psrpc.RequestOption) bool { return func(b psrpc.RequestOption) bool { @@ -51,13 +51,13 @@ func TestMiddleware(t *testing.T) { } } + fp := reflect.ValueOf(c).Pointer() + f := runtime.FuncForPC(fp) + file, line := f.FileLine(fp) + name := fmt.Sprintf("%s:%d %s", file, line, f.Name()) + select { case res := <-ch: - fp := reflect.ValueOf(c).Pointer() - f := runtime.FuncForPC(fp) - file, line := f.FileLine(fp) - name := fmt.Sprintf("%s:%d %s", file, line, f.Name()) - require.True(t, slices.ContainsFunc(res, eqPtr(expected[0])), "failed to receive option 0 from %s", name) require.True(t, slices.ContainsFunc(res, eqPtr(expected[1])), "failed to receive option 0 from %s", name) case <-time.After(time.Second): From 8cb42f9873164404f793b88b610d257ee1c2ae15 Mon Sep 17 00:00:00 2001 From: Paul Wells Date: Thu, 13 Nov 2025 22:40:26 -0800 Subject: [PATCH 4/4] tidy --- rpc/typed_api_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rpc/typed_api_test.go b/rpc/typed_api_test.go index cd690b9eb..08ae71909 100644 --- a/rpc/typed_api_test.go +++ b/rpc/typed_api_test.go @@ -61,7 +61,7 @@ func TestMiddleware(t *testing.T) { require.True(t, slices.ContainsFunc(res, eqPtr(expected[0])), "failed to receive option 0 from %s", name) require.True(t, slices.ContainsFunc(res, eqPtr(expected[1])), "failed to receive option 0 from %s", name) case <-time.After(time.Second): - require.FailNow(t, "timeout waiting for arguments") + require.FailNow(t, "timeout") } } })