snapshot of https://github.com/livekit/livekit.git @ 08c5433449c106943231037d0b892895f6e92d3b (2026-09-15)
Some checks failed
Release to Docker / docker (push) Failing after 2s
Release Test Server to Docker / docker (push) Failing after 3s
Test / test (push) Failing after 16s

This commit is contained in:
upstream-mirror
2026-09-15 16:14:22 +05:00
commit 78704103fc
422 changed files with 154805 additions and 0 deletions

View File

@@ -0,0 +1,125 @@
package service
import (
"context"
"testing"
"time"
"github.com/stretchr/testify/require"
"go.uber.org/atomic"
"google.golang.org/protobuf/types/known/emptypb"
"github.com/livekit/protocol/livekit"
"github.com/livekit/protocol/rpc"
"github.com/livekit/psrpc"
"github.com/livekit/livekit-server/pkg/rtc/types/typesfakes"
)
// fakeIngressHandlerClient records WHIPRTCConnectionNotify calls. It embeds the
// interface so only the method under test needs to be implemented; any other
// call would panic (and we assert none happen).
type fakeIngressHandlerClient struct {
rpc.IngressHandlerClient
notifyCount atomic.Int32
}
func (f *fakeIngressHandlerClient) WHIPRTCConnectionNotify(
_ context.Context,
_ string,
_ *rpc.WHIPRTCConnectionNotifyRequest,
_ ...psrpc.RequestOption,
) (*emptypb.Empty, error) {
f.notifyCount.Inc()
return &emptypb.Empty{}, nil
}
// TestWhipNotifySessionStopsWhenParticipantLeaves verifies the notifier loop
// terminates once the WHIP participant leaves the room (i.e. IsClosed becomes
// true), and stops issuing further connection notifications.
func TestWhipNotifySessionStopsWhenParticipantLeaves(t *testing.T) {
origInterval := whipSessionNotifyInterval
whipSessionNotifyInterval = 5 * time.Millisecond
t.Cleanup(func() { whipSessionNotifyInterval = origInterval })
var closed atomic.Bool
participant := &typesfakes.FakeParticipant{}
participant.IsClosedStub = func() bool { return closed.Load() }
participant.IDReturns(livekit.ParticipantID("PA_test"))
participant.ToProtoReturns(&livekit.ParticipantInfo{})
cli := &fakeIngressHandlerClient{}
s := whipService{ingressRpcCli: cli}
done := make(chan error, 1)
go func() {
done <- s.notifySession(context.Background(), participant)
}()
// while the participant is connected the loop should keep notifying
require.Eventually(t, func() bool {
return cli.notifyCount.Load() > 0
}, time.Second, time.Millisecond, "expected notifications while participant is connected")
// the participant leaves the room
closed.Store(true)
select {
case err := <-done:
require.NoError(t, err)
case <-time.After(time.Second):
t.Fatal("notifySession did not stop after the participant left the room")
}
// no further notifications should be attempted after it stops
countAtStop := cli.notifyCount.Load()
time.Sleep(50 * time.Millisecond)
require.Equal(t, countAtStop, cli.notifyCount.Load(), "should not notify after the participant left")
}
// TestWhipNotifySessionStopsOnContextCancel verifies the loop exits when the
// aliveCtx (cancelled from the participant's OnClose callback) is done.
func TestWhipNotifySessionStopsOnContextCancel(t *testing.T) {
origInterval := whipSessionNotifyInterval
whipSessionNotifyInterval = 5 * time.Millisecond
t.Cleanup(func() { whipSessionNotifyInterval = origInterval })
participant := &typesfakes.FakeParticipant{}
participant.IsClosedReturns(false)
participant.IDReturns(livekit.ParticipantID("PA_test"))
participant.ToProtoReturns(&livekit.ParticipantInfo{})
cli := &fakeIngressHandlerClient{}
s := whipService{ingressRpcCli: cli}
ctx, cancel := context.WithCancel(context.Background())
done := make(chan error, 1)
go func() {
done <- s.notifySession(ctx, participant)
}()
cancel()
select {
case err := <-done:
require.NoError(t, err)
case <-time.After(time.Second):
t.Fatal("notifySession did not stop after context was cancelled")
}
}
// TestWhipSendConnectionNotifySkipsClosedParticipant verifies the guard that
// short-circuits the RPC (and drives loop termination) for a closed participant.
func TestWhipSendConnectionNotifySkipsClosedParticipant(t *testing.T) {
participant := &typesfakes.FakeParticipant{}
participant.IsClosedReturns(true)
participant.IDReturns(livekit.ParticipantID("PA_test"))
participant.ToProtoReturns(&livekit.ParticipantInfo{})
cli := &fakeIngressHandlerClient{}
s := whipService{ingressRpcCli: cli}
err := s.sendConnectionNotify(context.Background(), participant)
require.ErrorIs(t, err, ErrParticipantNotFound)
require.Zero(t, cli.notifyCount.Load(), "should not issue an RPC for a closed participant")
}