Make new path for signalling v1.5 support. (#4180)

* Make new path for signalling v1.5 support.

To be able to support newer clients to interact with older servers, move
signalling v1.5 to new path (`/rtc1`). On the new path, `join_request`
is required and single peer connection is used.

With the existing path `/rtc`, single peer connection is still supported
if `join_request` is used.

Newer clients connecting to old server should follow
1. Try new path WebSocket
2. If that fails, try new path validate at `/rtc1/validate`.
3. If the above gets a 404 which will happen with older server, revert
   back to old path and signalling 1.0.

Open to suggestions on path name.

* test on both paths

* change path from /rtc1 -> /rtc/v1

* test all rtc service path combinations
This commit is contained in:
Raja Subramanian
2025-12-20 01:02:22 +05:30
committed by GitHub
parent 32cd0370c7
commit cd99fec2e7
10 changed files with 249 additions and 160 deletions
+1 -1
View File
@@ -58,7 +58,7 @@ func NewAPIKeyAuthMiddleware(provider auth.KeyProvider) *APIKeyAuthMiddleware {
}
func (m *APIKeyAuthMiddleware) ServeHTTP(w http.ResponseWriter, r *http.Request, next http.HandlerFunc) {
if r.URL != nil && r.URL.Path == "/rtc/validate" {
if r.URL != nil && (r.URL.Path == "/rtc/validate" || r.URL.Path == "/rtc/v1/validate") {
w.Header().Set("Access-Control-Allow-Origin", "*")
}
+36 -7
View File
@@ -90,13 +90,25 @@ func NewRTCService(
}
func (s *RTCService) SetupRoutes(mux *http.ServeMux) {
mux.Handle("/rtc", s)
mux.HandleFunc("/rtc/validate", s.validate)
mux.HandleFunc("/rtc", s.v0)
mux.HandleFunc("/rtc/validate", s.v0Validate)
mux.HandleFunc("/rtc/v1", s.v1)
mux.HandleFunc("/rtc/v1/validate", s.v1Validate)
}
func (s *RTCService) validate(w http.ResponseWriter, r *http.Request) {
func (s *RTCService) v0Validate(w http.ResponseWriter, r *http.Request) {
lgr := utils.GetLogger(r.Context())
_, _, code, err := s.validateInternal(lgr, r, true)
_, _, code, err := s.validateInternal(lgr, r, false, true)
if err != nil {
HandleError(w, r, code, err)
return
}
_, _ = w.Write([]byte("success"))
}
func (s *RTCService) v1Validate(w http.ResponseWriter, r *http.Request) {
lgr := utils.GetLogger(r.Context())
_, _, code, err := s.validateInternal(lgr, r, true, true)
if err != nil {
HandleError(w, r, code, err)
return
@@ -120,13 +132,22 @@ var gzipReaderPool = sync.Pool{
New: func() any { return &gzip.Reader{} },
}
func (s *RTCService) validateInternal(lgr logger.Logger, r *http.Request, strict bool) (livekit.RoomName, routing.ParticipantInit, int, error) {
func (s *RTCService) validateInternal(
lgr logger.Logger,
r *http.Request,
needsJoinRequest bool,
strict bool,
) (livekit.RoomName, routing.ParticipantInit, int, error) {
var params ValidateConnectRequestParams
useSinglePeerConnection := false
joinRequest := &livekit.JoinRequest{}
wrappedJoinRequestBase64 := r.FormValue("join_request")
if wrappedJoinRequestBase64 == "" {
if needsJoinRequest {
return "", routing.ParticipantInit{}, http.StatusBadRequest, errors.New("join_request is required")
}
params.publish = r.FormValue("publish")
attributesStrParam := r.FormValue("attributes")
@@ -244,7 +265,15 @@ func (s *RTCService) validateInternal(lgr logger.Logger, r *http.Request, strict
return res.roomName, pi, code, err
}
func (s *RTCService) ServeHTTP(w http.ResponseWriter, r *http.Request) {
func (s *RTCService) v0(w http.ResponseWriter, r *http.Request) {
s.serve(w, r, false)
}
func (s *RTCService) v1(w http.ResponseWriter, r *http.Request) {
s.serve(w, r, true)
}
func (s *RTCService) serve(w http.ResponseWriter, r *http.Request, needsJoinRequest bool) {
// reject non websocket requests
if !websocket.IsWebSocketUpgrade(r) {
w.WriteHeader(404)
@@ -295,7 +324,7 @@ func (s *RTCService) ServeHTTP(w http.ResponseWriter, r *http.Request) {
loggerResolved = false
}
roomName, pi, code, err = s.validateInternal(pLogger, r, false)
roomName, pi, code, err = s.validateInternal(pLogger, r, needsJoinRequest, false)
if err != nil {
HandleError(w, r, code, err)
return
+10 -10
View File
@@ -32,8 +32,8 @@ var (
)
func TestAgents(t *testing.T) {
for _, useSinglePeerConnection := range []bool{false, true} {
t.Run(fmt.Sprintf("singlePeerConnection=%+v", useSinglePeerConnection), func(t *testing.T) {
for _, testRTCServicePath := range testRTCServicePaths {
t.Run(fmt.Sprintf("testRTCServicePath=%s", testRTCServicePath.String()), func(t *testing.T) {
_, finish := setupSingleNodeTest("TestAgents")
defer finish()
@@ -70,8 +70,8 @@ func TestAgents(t *testing.T) {
return ""
}, RegisterTimeout)
c1 := createRTCClient("c1", defaultServerPort, useSinglePeerConnection, nil)
c2 := createRTCClient("c2", defaultServerPort, useSinglePeerConnection, nil)
c1 := createRTCClient("c1", defaultServerPort, testRTCServicePath, nil)
c2 := createRTCClient("c2", defaultServerPort, testRTCServicePath, nil)
waitUntilConnected(t, c1, c2)
// publish 2 tracks
@@ -126,8 +126,8 @@ func TestAgents(t *testing.T) {
}
func TestAgentNamespaces(t *testing.T) {
for _, useSinglePeerConnection := range []bool{false, true} {
t.Run(fmt.Sprintf("singlePeerConnection=%+v", useSinglePeerConnection), func(t *testing.T) {
for _, testRTCServicePath := range testRTCServicePaths {
t.Run(fmt.Sprintf("testRTCServicePath=%s", testRTCServicePath.String()), func(t *testing.T) {
_, finish := setupSingleNodeTest("TestAgentNamespaces")
defer finish()
@@ -158,7 +158,7 @@ func TestAgentNamespaces(t *testing.T) {
return ""
}, RegisterTimeout)
c1 := createRTCClient("c1", defaultServerPort, useSinglePeerConnection, nil)
c1 := createRTCClient("c1", defaultServerPort, testRTCServicePath, nil)
waitUntilConnected(t, c1)
testutils.WithTimeout(t, func() string {
@@ -188,8 +188,8 @@ func TestAgentNamespaces(t *testing.T) {
}
func TestAgentMultiNode(t *testing.T) {
for _, useSinglePeerConnection := range []bool{false, true} {
t.Run(fmt.Sprintf("singlePeerConnection=%+v", useSinglePeerConnection), func(t *testing.T) {
for _, testRTCServicePath := range testRTCServicePaths {
t.Run(fmt.Sprintf("testRTCServicePath=%s", testRTCServicePath.String()), func(t *testing.T) {
_, _, finish := setupMultiNodeTest("TestAgentMultiNode")
defer finish()
@@ -209,7 +209,7 @@ func TestAgentMultiNode(t *testing.T) {
return ""
}, RegisterTimeout)
c1 := createRTCClient("c1", secondServerPort, useSinglePeerConnection, nil) // Create a room on the second node
c1 := createRTCClient("c1", secondServerPort, testRTCServicePath, nil) // Create a room on the second node
waitUntilConnected(t, c1)
t1, err := c1.AddStaticTrack("audio/opus", "audio", "micro")
+8 -2
View File
@@ -135,17 +135,22 @@ type Options struct {
SignalRequestInterceptor SignalRequestInterceptor
SignalResponseInterceptor SignalResponseInterceptor
UseJoinRequestQueryParam bool
RTCServicePath string
}
func NewWebSocketConn(host, token string, opts *Options) (*websocket.Conn, error) {
u, err := url.Parse(host + "/rtc")
rtcServicePath := "/rtc"
if opts != nil && opts.RTCServicePath != "" {
rtcServicePath = opts.RTCServicePath
}
parsedURL, err := url.Parse(host + rtcServicePath)
if err != nil {
return nil, err
}
requestHeader := make(http.Header)
SetAuthorizationToken(requestHeader, token)
connectUrl := u.String()
connectUrl := parsedURL.String()
if opts != nil && opts.UseJoinRequestQueryParam {
clientInfo := &livekit.ClientInfo{
Os: runtime.GOOS,
@@ -205,6 +210,7 @@ func NewWebSocketConn(host, token string, opts *Options) (*websocket.Conn, error
connectUrl += encodeQueryParam("sdk", sdk)
}
logger.Infow("connecting to", "url", parsedURL.String())
conn, _, err := websocket.DefaultDialer.Dial(connectUrl, requestHeader)
return conn, err
}
+51 -7
View File
@@ -203,33 +203,77 @@ func createMultiNodeServer(nodeID string, port uint32) *service.LivekitServer {
return s
}
type testRTCServicePath int
const (
testRTCServicePathv0 testRTCServicePath = iota
testRTCServicePathv0SinglePeerConnection
testRTCServicePathv1
)
func (t testRTCServicePath) String() string {
switch t {
case testRTCServicePathv0:
return "v0"
case testRTCServicePathv0SinglePeerConnection:
return "v0-single-peer-connection"
case testRTCServicePathv1:
return "v1"
default:
return fmt.Sprintf("unknown: %d", t)
}
}
var testRTCServicePaths = []testRTCServicePath{
testRTCServicePathv0,
testRTCServicePathv0SinglePeerConnection,
testRTCServicePathv1,
}
func testRTCServicePathToTestClientOptions(testRTCServicePath testRTCServicePath, opts *testclient.Options) {
if opts == nil {
return
}
switch testRTCServicePath {
case testRTCServicePathv0:
opts.RTCServicePath = "/rtc"
case testRTCServicePathv0SinglePeerConnection:
opts.RTCServicePath = "/rtc"
opts.UseJoinRequestQueryParam = true
case testRTCServicePathv1:
opts.RTCServicePath = "/rtc/v1"
opts.UseJoinRequestQueryParam = true
default:
opts.RTCServicePath = "/rtc"
}
}
// creates a client and runs against server
func createRTCClient(name string, port int, useSinglePeerConnection bool, opts *testclient.Options) *testclient.RTCClient {
func createRTCClient(name string, port int, testRTCServicePath testRTCServicePath, opts *testclient.Options) *testclient.RTCClient {
var customizer func(token *auth.AccessToken, grants *auth.VideoGrant)
if opts != nil {
customizer = opts.TokenCustomizer
}
token := joinToken(testRoom, name, customizer)
return createRTCClientWithToken(token, port, useSinglePeerConnection, opts)
return createRTCClientWithToken(token, port, testRTCServicePath, opts)
}
// creates a client and runs against server
func createRTCClientWithToken(token string, port int, useSinglePeerConnection bool, opts *testclient.Options) *testclient.RTCClient {
func createRTCClientWithToken(token string, port int, testRTCServicePath testRTCServicePath, opts *testclient.Options) *testclient.RTCClient {
if opts == nil {
opts = &testclient.Options{
AutoSubscribe: true,
}
}
if useSinglePeerConnection {
opts.UseJoinRequestQueryParam = true
}
testRTCServicePathToTestClientOptions(testRTCServicePath, opts)
ws, err := testclient.NewWebSocketConn(fmt.Sprintf("ws://localhost:%d", port), token, opts)
if err != nil {
panic(err)
}
c, err := testclient.NewRTCClient(ws, useSinglePeerConnection, opts)
c, err := testclient.NewRTCClient(ws, opts.UseJoinRequestQueryParam, opts)
if err != nil {
panic(err)
}
+12 -12
View File
@@ -61,12 +61,12 @@ func TestMultiNodeUpdateRoomMetadata(t *testing.T) {
})
t.Run("when room has a participant", func(t *testing.T) {
for _, useSinglePeerConnection := range []bool{false, true} {
t.Run(fmt.Sprintf("singlePeerConnection=%+v", useSinglePeerConnection), func(t *testing.T) {
for _, testRTCServicePath := range testRTCServicePaths {
t.Run(fmt.Sprintf("testRTCServicePath=%s", testRTCServicePath.String()), func(t *testing.T) {
_, _, finish := setupMultiNodeTest("TestMultiNodeUpdateRoomMetadata_with_participant")
defer finish()
c1 := createRTCClient("c1", defaultServerPort, useSinglePeerConnection, nil)
c1 := createRTCClient("c1", defaultServerPort, testRTCServicePath, nil)
waitUntilConnected(t, c1)
defer c1.Stop()
@@ -93,12 +93,12 @@ func TestMultiNodeRemoveParticipant(t *testing.T) {
return
}
for _, useSinglePeerConnection := range []bool{false, true} {
t.Run(fmt.Sprintf("singlePeerConnection=%+v", useSinglePeerConnection), func(t *testing.T) {
for _, testRTCServicePath := range testRTCServicePaths {
t.Run(fmt.Sprintf("testRTCServicePath=%s", testRTCServicePath.String()), func(t *testing.T) {
_, _, finish := setupMultiNodeTest("TestMultiNodeRemoveParticipant")
defer finish()
c1 := createRTCClient("mn_remove_participant", defaultServerPort, useSinglePeerConnection, nil)
c1 := createRTCClient("mn_remove_participant", defaultServerPort, testRTCServicePath, nil)
defer c1.Stop()
waitUntilConnected(t, c1)
@@ -121,12 +121,12 @@ func TestMultiNodeRemoveParticipant(t *testing.T) {
// update participant metadata
func TestMultiNodeUpdateParticipantMetadata(t *testing.T) {
for _, useSinglePeerConnection := range []bool{false, true} {
t.Run(fmt.Sprintf("singlePeerConnection=%+v", useSinglePeerConnection), func(t *testing.T) {
for _, testRTCServicePath := range testRTCServicePaths {
t.Run(fmt.Sprintf("testRTCServicePath=%s", testRTCServicePath.String()), func(t *testing.T) {
_, _, finish := setupMultiNodeTest("TestMultiNodeUpdateParticipantMetadata")
defer finish()
c1 := createRTCClient("update_participant_metadata", defaultServerPort, useSinglePeerConnection, nil)
c1 := createRTCClient("update_participant_metadata", defaultServerPort, testRTCServicePath, nil)
defer c1.Stop()
waitUntilConnected(t, c1)
@@ -144,13 +144,13 @@ func TestMultiNodeUpdateParticipantMetadata(t *testing.T) {
// admin mute published track
func TestMultiNodeMutePublishedTrack(t *testing.T) {
for _, useSinglePeerConnection := range []bool{false, true} {
t.Run(fmt.Sprintf("singlePeerConnection=%+v", useSinglePeerConnection), func(t *testing.T) {
for _, testRTCServicePath := range testRTCServicePaths {
t.Run(fmt.Sprintf("testRTCServicePath=%s", testRTCServicePath.String()), func(t *testing.T) {
_, _, finish := setupMultiNodeTest("TestMultiNodeMutePublishedTrack")
defer finish()
identity := "mute_published_track"
c1 := createRTCClient(identity, defaultServerPort, useSinglePeerConnection, nil)
c1 := createRTCClient(identity, defaultServerPort, testRTCServicePath, nil)
defer c1.Stop()
waitUntilConnected(t, c1)
+27 -27
View File
@@ -44,11 +44,11 @@ func TestMultiNodeRouting(t *testing.T) {
})
require.NoError(t, err)
for _, useSinglePeerConnection := range []bool{false, true} {
t.Run(fmt.Sprintf("singlePeerConnection=%+v", useSinglePeerConnection), func(t *testing.T) {
for _, testRTCServicePath := range testRTCServicePaths {
t.Run(fmt.Sprintf("testRTCServicePath=%s", testRTCServicePath.String()), func(t *testing.T) {
// one node connecting to node 1, and another connecting to node 2
c1 := createRTCClient("c1", defaultServerPort, useSinglePeerConnection, nil)
c2 := createRTCClient("c2", secondServerPort, useSinglePeerConnection, nil)
c1 := createRTCClient("c1", defaultServerPort, testRTCServicePath, nil)
c2 := createRTCClient("c2", secondServerPort, testRTCServicePath, nil)
waitUntilConnected(t, c1, c2)
defer stopClients(c1, c2)
@@ -88,9 +88,9 @@ func TestConnectWithoutCreation(t *testing.T) {
_, _, finish := setupMultiNodeTest("TestConnectWithoutCreation")
defer finish()
for _, useSinglePeerConnection := range []bool{false, true} {
t.Run(fmt.Sprintf("singlePeerConnection=%+v", useSinglePeerConnection), func(t *testing.T) {
c1 := createRTCClient("c1", defaultServerPort, useSinglePeerConnection, nil)
for _, testRTCServicePath := range testRTCServicePaths {
t.Run(fmt.Sprintf("testRTCServicePath=%s", testRTCServicePath.String()), func(t *testing.T) {
c1 := createRTCClient("c1", defaultServerPort, testRTCServicePath, nil)
waitUntilConnected(t, c1)
c1.Stop()
@@ -127,8 +127,8 @@ func TestMultinodeReconnectAfterNodeShutdown(t *testing.T) {
return
}
for _, useSinglePeerConnection := range []bool{false, true} {
t.Run(fmt.Sprintf("singlePeerConnection=%+v", useSinglePeerConnection), func(t *testing.T) {
for _, testRTCServicePath := range testRTCServicePaths {
t.Run(fmt.Sprintf("testRTCServicePath=%s", testRTCServicePath.String()), func(t *testing.T) {
_, s2, finish := setupMultiNodeTest("TestMultinodeReconnectAfterNodeShutdown")
defer finish()
@@ -140,8 +140,8 @@ func TestMultinodeReconnectAfterNodeShutdown(t *testing.T) {
require.NoError(t, err)
// one node connecting to node 1, and another connecting to node 2
c1 := createRTCClient("c1", defaultServerPort, useSinglePeerConnection, nil)
c2 := createRTCClient("c2", secondServerPort, useSinglePeerConnection, nil)
c1 := createRTCClient("c1", defaultServerPort, testRTCServicePath, nil)
c2 := createRTCClient("c2", secondServerPort, testRTCServicePath, nil)
waitUntilConnected(t, c1, c2)
stopClients(c1, c2)
@@ -151,7 +151,7 @@ func TestMultinodeReconnectAfterNodeShutdown(t *testing.T) {
time.Sleep(syncDelay)
c3 := createRTCClient("c3", defaultServerPort, useSinglePeerConnection, nil)
c3 := createRTCClient("c3", defaultServerPort, testRTCServicePath, nil)
waitUntilConnected(t, c3)
})
}
@@ -200,10 +200,10 @@ func TestMultiNodeRefreshToken(t *testing.T) {
_, _, finish := setupMultiNodeTest("TestMultiNodeJoinAfterClose")
defer finish()
for _, useSinglePeerConnection := range []bool{false, true} {
t.Run(fmt.Sprintf("singlePeerConnection=%+v", useSinglePeerConnection), func(t *testing.T) {
for _, testRTCServicePath := range testRTCServicePaths {
t.Run(fmt.Sprintf("testRTCServicePath=%s", testRTCServicePath.String()), func(t *testing.T) {
// a participant joining with full permissions
c1 := createRTCClient("c1", defaultServerPort, useSinglePeerConnection, nil)
c1 := createRTCClient("c1", defaultServerPort, testRTCServicePath, nil)
waitUntilConnected(t, c1)
// update permissions and metadata
@@ -258,16 +258,16 @@ func TestMultiNodeUpdateAttributes(t *testing.T) {
_, _, finish := setupMultiNodeTest("TestMultiNodeUpdateAttributes")
defer finish()
for _, useSinglePeerConnection := range []bool{false, true} {
t.Run(fmt.Sprintf("singlePeerConnection=%+v", useSinglePeerConnection), func(t *testing.T) {
c1 := createRTCClient("au1", defaultServerPort, useSinglePeerConnection, &client.Options{
for _, testRTCServicePath := range testRTCServicePaths {
t.Run(fmt.Sprintf("testRTCServicePath=%s", testRTCServicePath.String()), func(t *testing.T) {
c1 := createRTCClient("au1", defaultServerPort, testRTCServicePath, &client.Options{
TokenCustomizer: func(token *auth.AccessToken, grants *auth.VideoGrant) {
token.SetAttributes(map[string]string{
"mykey": "au1",
})
},
})
c2 := createRTCClient("au2", secondServerPort, useSinglePeerConnection, &client.Options{
c2 := createRTCClient("au2", secondServerPort, testRTCServicePath, &client.Options{
TokenCustomizer: func(token *auth.AccessToken, grants *auth.VideoGrant) {
token.SetAttributes(map[string]string{
"mykey": "au2",
@@ -331,10 +331,10 @@ func TestMultiNodeRevokePublishPermission(t *testing.T) {
_, _, finish := setupMultiNodeTest("TestMultiNodeRevokePublishPermission")
defer finish()
for _, useSinglePeerConnection := range []bool{false, true} {
t.Run(fmt.Sprintf("singlePeerConnection=%+v", useSinglePeerConnection), func(t *testing.T) {
c1 := createRTCClient("c1", defaultServerPort, useSinglePeerConnection, nil)
c2 := createRTCClient("c2", secondServerPort, useSinglePeerConnection, nil)
for _, testRTCServicePath := range testRTCServicePaths {
t.Run(fmt.Sprintf("testRTCServicePath=%s", testRTCServicePath.String()), func(t *testing.T) {
c1 := createRTCClient("c1", defaultServerPort, testRTCServicePath, nil)
c2 := createRTCClient("c2", secondServerPort, testRTCServicePath, nil)
waitUntilConnected(t, c1, c2)
// c1 publishes a track for c2
@@ -383,12 +383,12 @@ func TestCloseDisconnectedParticipantOnSignalClose(t *testing.T) {
_, _, finish := setupMultiNodeTest("TestCloseDisconnectedParticipantOnSignalClose")
defer finish()
for _, useSinglePeerConnection := range []bool{false, true} {
t.Run(fmt.Sprintf("singlePeerConnection=%+v", useSinglePeerConnection), func(t *testing.T) {
c1 := createRTCClient("c1", secondServerPort, useSinglePeerConnection, nil)
for _, testRTCServicePath := range testRTCServicePaths {
t.Run(fmt.Sprintf("testRTCServicePath=%s", testRTCServicePath.String()), func(t *testing.T) {
c1 := createRTCClient("c1", secondServerPort, testRTCServicePath, nil)
waitUntilConnected(t, c1)
c2 := createRTCClient("c2", defaultServerPort, useSinglePeerConnection, &client.Options{
c2 := createRTCClient("c2", defaultServerPort, testRTCServicePath, &client.Options{
SignalRequestInterceptor: func(msg *livekit.SignalRequest, next client.SignalRequestHandler) error {
switch msg.Message.(type) {
case *livekit.SignalRequest_Offer, *livekit.SignalRequest_Answer, *livekit.SignalRequest_Leave:
+28 -28
View File
@@ -31,11 +31,11 @@ import (
// a scenario with lots of clients connecting, publishing, and leaving at random periods
func scenarioPublishingUponJoining(t *testing.T) {
for _, useSinglePeerConnection := range []bool{false, true} {
t.Run(fmt.Sprintf("singlePeerConnection=%+v", useSinglePeerConnection), func(t *testing.T) {
c1 := createRTCClient("puj_1", defaultServerPort, useSinglePeerConnection, nil)
c2 := createRTCClient("puj_2", secondServerPort, useSinglePeerConnection, &testclient.Options{AutoSubscribe: true})
c3 := createRTCClient("puj_3", defaultServerPort, useSinglePeerConnection, &testclient.Options{AutoSubscribe: true})
for _, testRTCServicePath := range testRTCServicePaths {
t.Run(fmt.Sprintf("testRTCServicePath=%s", testRTCServicePath.String()), func(t *testing.T) {
c1 := createRTCClient("puj_1", defaultServerPort, testRTCServicePath, nil)
c2 := createRTCClient("puj_2", secondServerPort, testRTCServicePath, &testclient.Options{AutoSubscribe: true})
c3 := createRTCClient("puj_3", defaultServerPort, testRTCServicePath, &testclient.Options{AutoSubscribe: true})
defer stopClients(c1, c2, c3)
waitUntilConnected(t, c1, c2, c3)
@@ -78,7 +78,7 @@ func scenarioPublishingUponJoining(t *testing.T) {
logger.Infow("c2 reconnecting")
// connect to a diff port
c2 = createRTCClient("puj_2", defaultServerPort, useSinglePeerConnection, nil)
c2 = createRTCClient("puj_2", defaultServerPort, testRTCServicePath, nil)
defer c2.Stop()
waitUntilConnected(t, c2)
writers = publishTracksForClients(t, c2)
@@ -100,10 +100,10 @@ func scenarioPublishingUponJoining(t *testing.T) {
}
func scenarioReceiveBeforePublish(t *testing.T) {
for _, useSinglePeerConnection := range []bool{false, true} {
t.Run(fmt.Sprintf("singlePeerConnection=%+v", useSinglePeerConnection), func(t *testing.T) {
c1 := createRTCClient("rbp_1", defaultServerPort, useSinglePeerConnection, nil)
c2 := createRTCClient("rbp_2", defaultServerPort, useSinglePeerConnection, nil)
for _, testRTCServicePath := range testRTCServicePaths {
t.Run(fmt.Sprintf("testRTCServicePath=%s", testRTCServicePath.String()), func(t *testing.T) {
c1 := createRTCClient("rbp_1", defaultServerPort, testRTCServicePath, nil)
c2 := createRTCClient("rbp_2", defaultServerPort, testRTCServicePath, nil)
waitUntilConnected(t, c1, c2)
defer stopClients(c1, c2)
@@ -147,10 +147,10 @@ func scenarioReceiveBeforePublish(t *testing.T) {
}
func scenarioDataPublish(t *testing.T) {
for _, useSinglePeerConnection := range []bool{false, true} {
t.Run(fmt.Sprintf("scenarioDataPublish/singlePeerConnection=%+v", useSinglePeerConnection), func(t *testing.T) {
c1 := createRTCClient("dp1", defaultServerPort, useSinglePeerConnection, nil)
c2 := createRTCClient("dp2", secondServerPort, useSinglePeerConnection, nil)
for _, testRTCServicePath := range testRTCServicePaths {
t.Run(fmt.Sprintf("scenarioDataPublish/testRTCServicePath=%s", testRTCServicePath.String()), func(t *testing.T) {
c1 := createRTCClient("dp1", defaultServerPort, testRTCServicePath, nil)
c2 := createRTCClient("dp2", secondServerPort, testRTCServicePath, nil)
waitUntilConnected(t, c1, c2)
defer stopClients(c1, c2)
@@ -177,10 +177,10 @@ func scenarioDataPublish(t *testing.T) {
}
func scenarioDataUnlabeledPublish(t *testing.T) {
for _, useSinglePeerConnection := range []bool{false, true} {
t.Run(fmt.Sprintf("scenarioDataUnlabeledPublish/singlePeerConnection=%+v", useSinglePeerConnection), func(t *testing.T) {
c1 := createRTCClient("dp1", defaultServerPort, useSinglePeerConnection, nil)
c2 := createRTCClient("dp2", secondServerPort, useSinglePeerConnection, nil)
for _, testRTCServicePath := range testRTCServicePaths {
t.Run(fmt.Sprintf("scenarioDataUnlabeledPublish/testRTCServicePath=%s", testRTCServicePath.String()), func(t *testing.T) {
c1 := createRTCClient("dp1", defaultServerPort, testRTCServicePath, nil)
c2 := createRTCClient("dp2", secondServerPort, testRTCServicePath, nil)
waitUntilConnected(t, c1, c2)
defer stopClients(c1, c2)
@@ -207,11 +207,11 @@ func scenarioDataUnlabeledPublish(t *testing.T) {
}
func scenarioDataTracksPublishingUponJoining(t *testing.T) {
for _, useSinglePeerConnection := range []bool{false, true} {
t.Run(fmt.Sprintf("scenarioDataTracksPublishingUponJoining/singlePeerConnection=%+v", useSinglePeerConnection), func(t *testing.T) {
c1 := createRTCClient("dtpuj_1", defaultServerPort, useSinglePeerConnection, nil)
c2 := createRTCClient("dtpuj_2", secondServerPort, useSinglePeerConnection, &testclient.Options{AutoSubscribe: true})
c3 := createRTCClient("dtpuj_3", defaultServerPort, useSinglePeerConnection, &testclient.Options{AutoSubscribe: true})
for _, testRTCServicePath := range testRTCServicePaths {
t.Run(fmt.Sprintf("scenarioDataTracksPublishingUponJoining/testRTCServicePath=%s", testRTCServicePath.String()), func(t *testing.T) {
c1 := createRTCClient("dtpuj_1", defaultServerPort, testRTCServicePath, nil)
c2 := createRTCClient("dtpuj_2", secondServerPort, testRTCServicePath, &testclient.Options{AutoSubscribe: true})
c3 := createRTCClient("dtpuj_3", defaultServerPort, testRTCServicePath, &testclient.Options{AutoSubscribe: true})
defer stopClients(c1, c2, c3)
waitUntilConnected(t, c1, c2, c3)
@@ -261,7 +261,7 @@ func scenarioDataTracksPublishingUponJoining(t *testing.T) {
logger.Infow("c2 reconnecting")
// connect to a diff port
c2 = createRTCClient("dtpuj_2", defaultServerPort, useSinglePeerConnection, nil)
c2 = createRTCClient("dtpuj_2", defaultServerPort, testRTCServicePath, nil)
defer c2.Stop()
waitUntilConnected(t, c2)
writers = publishDataTracksForClients(t, c2)
@@ -294,9 +294,9 @@ func scenarioDataTracksPublishingUponJoining(t *testing.T) {
}
func scenarioJoinClosedRoom(t *testing.T) {
for _, useSinglePeerConnection := range []bool{false, true} {
t.Run(fmt.Sprintf("singlePeerConnection=%+v", useSinglePeerConnection), func(t *testing.T) {
c1 := createRTCClient("jcr1", defaultServerPort, useSinglePeerConnection, nil)
for _, testRTCServicePath := range testRTCServicePaths {
t.Run(fmt.Sprintf("testRTCServicePath=%s", testRTCServicePath.String()), func(t *testing.T) {
c1 := createRTCClient("jcr1", defaultServerPort, testRTCServicePath, nil)
waitUntilConnected(t, c1)
// close room with room client
@@ -306,7 +306,7 @@ func scenarioJoinClosedRoom(t *testing.T) {
require.NoError(t, err)
// now join again
c2 := createRTCClient("jcr2", defaultServerPort, useSinglePeerConnection, nil)
c2 := createRTCClient("jcr2", defaultServerPort, testRTCServicePath, nil)
waitUntilConnected(t, c2)
stopClients(c2)
})
+72 -62
View File
@@ -58,10 +58,10 @@ func TestClientCouldConnect(t *testing.T) {
_, finish := setupSingleNodeTest("TestClientCouldConnect")
defer finish()
for _, useSinglePeerConnection := range []bool{false, true} {
t.Run(fmt.Sprintf("singlePeerConnection=%+v", useSinglePeerConnection), func(t *testing.T) {
c1 := createRTCClient("c1", defaultServerPort, useSinglePeerConnection, nil)
c2 := createRTCClient("c2", defaultServerPort, useSinglePeerConnection, nil)
for _, testRTCServicePath := range testRTCServicePaths {
t.Run(fmt.Sprintf("testRTCServicePath=%s", testRTCServicePath.String()), func(t *testing.T) {
c1 := createRTCClient("c1", defaultServerPort, testRTCServicePath, nil)
c2 := createRTCClient("c2", defaultServerPort, testRTCServicePath, nil)
waitUntilConnected(t, c1, c2)
// ensure they both see each other
@@ -87,13 +87,13 @@ func TestClientConnectDuplicate(t *testing.T) {
_, finish := setupSingleNodeTest("TestClientConnectDuplicate")
defer finish()
for _, useSinglePeerConnection := range []bool{false, true} {
t.Run(fmt.Sprintf("singlePeerConnection=%+v", useSinglePeerConnection), func(t *testing.T) {
for _, testRTCServicePath := range testRTCServicePaths {
t.Run(fmt.Sprintf("testRTCServicePath=%s", testRTCServicePath.String()), func(t *testing.T) {
grant := &auth.VideoGrant{RoomJoin: true, Room: testRoom}
grant.SetCanPublish(true)
grant.SetCanSubscribe(true)
token := joinTokenWithGrant("c1", grant)
c1 := createRTCClientWithToken(token, defaultServerPort, useSinglePeerConnection, nil)
c1 := createRTCClientWithToken(token, defaultServerPort, testRTCServicePath, nil)
// publish 2 tracks
t1, err := c1.AddStaticTrack("audio/opus", "audio", "webcam")
@@ -103,7 +103,7 @@ func TestClientConnectDuplicate(t *testing.T) {
require.NoError(t, err)
defer t2.Stop()
c2 := createRTCClient("c2", defaultServerPort, useSinglePeerConnection, nil)
c2 := createRTCClient("c2", defaultServerPort, testRTCServicePath, nil)
waitUntilConnected(t, c1, c2)
opts := &testclient.Options{
@@ -128,7 +128,7 @@ func TestClientConnectDuplicate(t *testing.T) {
return ""
})
c1Dup := createRTCClientWithToken(token, defaultServerPort, useSinglePeerConnection, opts)
c1Dup := createRTCClientWithToken(token, defaultServerPort, testRTCServicePath, opts)
waitUntilConnected(t, c1Dup)
@@ -160,10 +160,10 @@ func TestSinglePublisher(t *testing.T) {
s, finish := setupSingleNodeTest("TestSinglePublisher")
defer finish()
for _, useSinglePeerConnection := range []bool{false, true} {
t.Run(fmt.Sprintf("singlePeerConnection=%+v", useSinglePeerConnection), func(t *testing.T) {
c1 := createRTCClient("c1", defaultServerPort, useSinglePeerConnection, nil)
c2 := createRTCClient("c2", defaultServerPort, useSinglePeerConnection, nil)
for _, testRTCServicePath := range testRTCServicePaths {
t.Run(fmt.Sprintf("testRTCServicePath=%s", testRTCServicePath.String()), func(t *testing.T) {
c1 := createRTCClient("c1", defaultServerPort, testRTCServicePath, nil)
c2 := createRTCClient("c2", defaultServerPort, testRTCServicePath, nil)
waitUntilConnected(t, c1, c2)
// publish an audio and video track and ensure clients receive it ok
@@ -196,7 +196,7 @@ func TestSinglePublisher(t *testing.T) {
require.Equal(t, "audio/opus", audioTrack.MimeType)
// a new client joins and should get the initial stream
c3 := createRTCClient("c3", defaultServerPort, useSinglePeerConnection, nil)
c3 := createRTCClient("c3", defaultServerPort, testRTCServicePath, nil)
// ensure that new client that has joined also received tracks
waitUntilConnected(t, c3)
@@ -245,11 +245,11 @@ func Test_WhenAutoSubscriptionDisabled_ClientShouldNotReceiveAnyPublishedTracks(
_, finish := setupSingleNodeTest("Test_WhenAutoSubscriptionDisabled_ClientShouldNotReceiveAnyPublishedTracks")
defer finish()
for _, useSinglePeerConnection := range []bool{false, true} {
t.Run(fmt.Sprintf("singlePeerConnection=%+v", useSinglePeerConnection), func(t *testing.T) {
for _, testRTCServicePath := range testRTCServicePaths {
t.Run(fmt.Sprintf("testRTCServicePath=%s", testRTCServicePath.String()), func(t *testing.T) {
opts := testclient.Options{AutoSubscribe: false}
publisher := createRTCClient("publisher", defaultServerPort, useSinglePeerConnection, &opts)
client := createRTCClient("client", defaultServerPort, useSinglePeerConnection, &opts)
publisher := createRTCClient("publisher", defaultServerPort, testRTCServicePath, &opts)
client := createRTCClient("client", defaultServerPort, testRTCServicePath, &opts)
defer publisher.Stop()
defer client.Stop()
waitUntilConnected(t, publisher, client)
@@ -274,10 +274,10 @@ func Test_RenegotiationWithDifferentCodecs(t *testing.T) {
_, finish := setupSingleNodeTest("TestRenegotiationWithDifferentCodecs")
defer finish()
for _, useSinglePeerConnection := range []bool{false, true} {
t.Run(fmt.Sprintf("singlePeerConnection=%+v", useSinglePeerConnection), func(t *testing.T) {
c1 := createRTCClient("c1", defaultServerPort, useSinglePeerConnection, nil)
c2 := createRTCClient("c2", defaultServerPort, useSinglePeerConnection, nil)
for _, testRTCServicePath := range testRTCServicePaths {
t.Run(fmt.Sprintf("testRTCServicePath=%s", testRTCServicePath.String()), func(t *testing.T) {
c1 := createRTCClient("c1", defaultServerPort, testRTCServicePath, nil)
c2 := createRTCClient("c2", defaultServerPort, testRTCServicePath, nil)
waitUntilConnected(t, c1, c2)
// publish a vp8 video track and ensure clients receive it ok
@@ -420,9 +420,9 @@ func TestPingPong(t *testing.T) {
_, finish := setupSingleNodeTest("TestPingPong")
defer finish()
for _, useSinglePeerConnection := range []bool{false, true} {
t.Run(fmt.Sprintf("singlePeerConnection=%+v", useSinglePeerConnection), func(t *testing.T) {
c1 := createRTCClient("c1", defaultServerPort, useSinglePeerConnection, nil)
for _, testRTCServicePath := range testRTCServicePaths {
t.Run(fmt.Sprintf("testRTCServicePath=%s", testRTCServicePath.String()), func(t *testing.T) {
c1 := createRTCClient("c1", defaultServerPort, testRTCServicePath, nil)
waitUntilConnected(t, c1)
require.NoError(t, c1.SendPing())
@@ -476,15 +476,25 @@ func TestAutoCreate(t *testing.T) {
waitForServerToStart(s)
for _, useSinglePeerConnection := range []bool{false, true} {
t.Run(fmt.Sprintf("singlePeerConnection=%+v", useSinglePeerConnection), func(t *testing.T) {
for _, testRTCServicePath := range testRTCServicePaths {
t.Run(fmt.Sprintf("testRTCServicePath=%s", testRTCServicePath.String()), func(t *testing.T) {
token := joinToken(testRoom, "start-before-create", nil)
_, err := testclient.NewWebSocketConn(fmt.Sprintf("ws://localhost:%d", defaultServerPort), token, &testclient.Options{UseJoinRequestQueryParam: useSinglePeerConnection})
opts := &testclient.Options{}
testRTCServicePathToTestClientOptions(testRTCServicePath, opts)
_, err := testclient.NewWebSocketConn(
fmt.Sprintf("ws://localhost:%d", defaultServerPort),
token,
opts,
)
require.Error(t, err)
// second join should also fail
token = joinToken(testRoom, "start-before-create-2", nil)
_, err = testclient.NewWebSocketConn(fmt.Sprintf("ws://localhost:%d", defaultServerPort), token, &testclient.Options{UseJoinRequestQueryParam: useSinglePeerConnection})
_, err = testclient.NewWebSocketConn(
fmt.Sprintf("ws://localhost:%d", defaultServerPort),
token,
opts,
)
require.Error(t, err)
})
}
@@ -505,9 +515,9 @@ func TestAutoCreate(t *testing.T) {
_, err := roomClient.CreateRoom(contextWithToken(createRoomToken()), &livekit.CreateRoomRequest{Name: testRoom})
require.NoError(t, err)
for _, useSinglePeerConnection := range []bool{false, true} {
t.Run(fmt.Sprintf("singlePeerConnection=%+v", useSinglePeerConnection), func(t *testing.T) {
c1 := createRTCClient("join-after-create", defaultServerPort, useSinglePeerConnection, nil)
for _, testRTCServicePath := range testRTCServicePaths {
t.Run(fmt.Sprintf("testRTCServicePath=%s", testRTCServicePath.String()), func(t *testing.T) {
c1 := createRTCClient("join-after-create", defaultServerPort, testRTCServicePath, nil)
waitUntilConnected(t, c1)
c1.Stop()
@@ -525,9 +535,9 @@ func TestSingleNodeUpdateSubscriptionPermissions(t *testing.T) {
_, finish := setupSingleNodeTest("TestSingleNodeUpdateSubscriptionPermissions")
defer finish()
for _, useSinglePeerConnection := range []bool{false, true} {
t.Run(fmt.Sprintf("singlePeerConnection=%+v", useSinglePeerConnection), func(t *testing.T) {
pub := createRTCClient("pub", defaultServerPort, useSinglePeerConnection, nil)
for _, testRTCServicePath := range testRTCServicePaths {
t.Run(fmt.Sprintf("testRTCServicePath=%s", testRTCServicePath.String()), func(t *testing.T) {
pub := createRTCClient("pub", defaultServerPort, testRTCServicePath, nil)
grant := &auth.VideoGrant{RoomJoin: true, Room: testRoom}
grant.SetCanSubscribe(false)
@@ -536,7 +546,7 @@ func TestSingleNodeUpdateSubscriptionPermissions(t *testing.T) {
SetIdentity("sub")
token, err := at.ToJWT()
require.NoError(t, err)
sub := createRTCClientWithToken(token, defaultServerPort, useSinglePeerConnection, nil)
sub := createRTCClientWithToken(token, defaultServerPort, testRTCServicePath, nil)
waitUntilConnected(t, pub, sub)
@@ -587,9 +597,9 @@ func TestSingleNodeAttributes(t *testing.T) {
_, finish := setupSingleNodeTest("TestSingleNodeAttributes")
defer finish()
for _, useSinglePeerConnection := range []bool{false, true} {
t.Run(fmt.Sprintf("singlePeerConnection=%+v", useSinglePeerConnection), func(t *testing.T) {
pub := createRTCClient("pub", defaultServerPort, useSinglePeerConnection, &testclient.Options{
for _, testRTCServicePath := range testRTCServicePaths {
t.Run(fmt.Sprintf("testRTCServicePath=%s", testRTCServicePath.String()), func(t *testing.T) {
pub := createRTCClient("pub", defaultServerPort, testRTCServicePath, &testclient.Options{
Attributes: map[string]string{
"b": "2",
"c": "3",
@@ -611,7 +621,7 @@ func TestSingleNodeAttributes(t *testing.T) {
SetIdentity("sub")
token, err := at.ToJWT()
require.NoError(t, err)
sub := createRTCClientWithToken(token, defaultServerPort, useSinglePeerConnection, nil)
sub := createRTCClientWithToken(token, defaultServerPort, testRTCServicePath, nil)
waitUntilConnected(t, pub, sub)
@@ -646,10 +656,10 @@ func TestDeviceCodecOverride(t *testing.T) {
_, finish := setupSingleNodeTest("TestDeviceCodecOverride")
defer finish()
for _, useSinglePeerConnection := range []bool{false, true} {
t.Run(fmt.Sprintf("singlePeerConnection=%+v", useSinglePeerConnection), func(t *testing.T) {
for _, testRTCServicePath := range testRTCServicePaths {
t.Run(fmt.Sprintf("testRTCServicePath=%s", testRTCServicePath.String()), func(t *testing.T) {
// simulate device that isn't compatible with H.264
c1 := createRTCClient("c1", defaultServerPort, useSinglePeerConnection, &testclient.Options{
c1 := createRTCClient("c1", defaultServerPort, testRTCServicePath, &testclient.Options{
ClientInfo: &livekit.ClientInfo{
Os: "android",
DeviceModel: "Xiaomi 2201117TI",
@@ -714,11 +724,11 @@ func TestSubscribeToCodecUnsupported(t *testing.T) {
_, finish := setupSingleNodeTest("TestSubscribeToCodecUnsupported")
defer finish()
for _, useSinglePeerConnection := range []bool{false, true} {
t.Run(fmt.Sprintf("singlePeerConnection=%+v", useSinglePeerConnection), func(t *testing.T) {
c1 := createRTCClient("c1", defaultServerPort, useSinglePeerConnection, nil)
for _, testRTCServicePath := range testRTCServicePaths {
t.Run(fmt.Sprintf("testRTCServicePath=%s", testRTCServicePath.String()), func(t *testing.T) {
c1 := createRTCClient("c1", defaultServerPort, testRTCServicePath, nil)
// create a client that doesn't support H264
c2 := createRTCClient("c2", defaultServerPort, useSinglePeerConnection, &testclient.Options{
c2 := createRTCClient("c2", defaultServerPort, testRTCServicePath, &testclient.Options{
AutoSubscribe: true,
DisabledCodecs: []webrtc.RTPCodecCapability{
{MimeType: "video/H264"},
@@ -841,12 +851,12 @@ func TestDataPublishSlowSubscriber(t *testing.T) {
logger.Infow("----------------FINISHING TEST----------------", "test", t.Name())
}()
for _, useSinglePeerConnection := range []bool{false, true} {
t.Run(fmt.Sprintf("singlePeerConnection=%+v", useSinglePeerConnection), func(t *testing.T) {
pub := createRTCClient("pub", defaultServerPort, useSinglePeerConnection, nil)
fastSub := createRTCClient("fastSub", defaultServerPort, useSinglePeerConnection, nil)
slowSubNotDrop := createRTCClient("slowSubNotDrop", defaultServerPort, useSinglePeerConnection, nil)
slowSubDrop := createRTCClient("slowSubDrop", defaultServerPort, useSinglePeerConnection, nil)
for _, testRTCServicePath := range testRTCServicePaths {
t.Run(fmt.Sprintf("testRTCServicePath=%s", testRTCServicePath.String()), func(t *testing.T) {
pub := createRTCClient("pub", defaultServerPort, testRTCServicePath, nil)
fastSub := createRTCClient("fastSub", defaultServerPort, testRTCServicePath, nil)
slowSubNotDrop := createRTCClient("slowSubNotDrop", defaultServerPort, testRTCServicePath, nil)
slowSubDrop := createRTCClient("slowSubDrop", defaultServerPort, testRTCServicePath, nil)
waitUntilConnected(t, pub, fastSub, slowSubDrop, slowSubNotDrop)
defer func() {
pub.Stop()
@@ -967,14 +977,14 @@ func TestFireTrackBySdp(t *testing.T) {
for _, c := range cases {
codecs, sdk := c.codecs, c.pubSDK
t.Run(c.name, func(t *testing.T) {
for _, useSinglePeerConnection := range []bool{false, true} {
t.Run(fmt.Sprintf("singlePeerConnection=%+v", useSinglePeerConnection), func(t *testing.T) {
c1 := createRTCClient(c.name+"_c1", defaultServerPort, useSinglePeerConnection, &testclient.Options{
for _, testRTCServicePath := range testRTCServicePaths {
t.Run(fmt.Sprintf("testRTCServicePath=%s", testRTCServicePath.String()), func(t *testing.T) {
c1 := createRTCClient(c.name+"_c1", defaultServerPort, testRTCServicePath, &testclient.Options{
ClientInfo: &livekit.ClientInfo{
Sdk: sdk,
},
})
c2 := createRTCClient(c.name+"_c2", defaultServerPort, useSinglePeerConnection, &testclient.Options{
c2 := createRTCClient(c.name+"_c2", defaultServerPort, testRTCServicePath, &testclient.Options{
AutoSubscribe: true,
ClientInfo: &livekit.ClientInfo{
Sdk: livekit.ClientInfo_JS,
@@ -1024,10 +1034,10 @@ func TestSinglePublisherDataTrack(t *testing.T) {
s, finish := setupSingleNodeTest("TestSinglePublisherDataTrack")
defer finish()
for _, useSinglePeerConnection := range []bool{false, true} {
t.Run(fmt.Sprintf("singlePeerConnection=%+v", useSinglePeerConnection), func(t *testing.T) {
c1 := createRTCClient("c1", defaultServerPort, useSinglePeerConnection, nil)
c2 := createRTCClient("c2", defaultServerPort, useSinglePeerConnection, nil)
for _, testRTCServicePath := range testRTCServicePaths {
t.Run(fmt.Sprintf("testRTCServicePath=%s", testRTCServicePath.String()), func(t *testing.T) {
c1 := createRTCClient("c1", defaultServerPort, testRTCServicePath, nil)
c2 := createRTCClient("c2", defaultServerPort, testRTCServicePath, nil)
waitUntilConnected(t, c1, c2)
// publish a couple of data tracks and ensure clients receive it ok
@@ -1051,7 +1061,7 @@ func TestSinglePublisherDataTrack(t *testing.T) {
})
// a new client joins and should get the initial stream
c3 := createRTCClient("c3", defaultServerPort, useSinglePeerConnection, nil)
c3 := createRTCClient("c3", defaultServerPort, testRTCServicePath, nil)
// ensure that new client that has joined also received data tracks
waitUntilConnected(t, c3)
+4 -4
View File
@@ -45,9 +45,9 @@ func TestWebhooks(t *testing.T) {
require.NoError(t, err)
defer finish()
for _, useSinglePeerConnection := range []bool{false, true} {
t.Run(fmt.Sprintf("singlePeerConnection=%+v", useSinglePeerConnection), func(t *testing.T) {
c1 := createRTCClient("c1", defaultServerPort, useSinglePeerConnection, nil)
for _, testRTCServicePath := range testRTCServicePaths {
t.Run(fmt.Sprintf("testRTCServicePath=%s", testRTCServicePath.String()), func(t *testing.T) {
c1 := createRTCClient("c1", defaultServerPort, testRTCServicePath, nil)
waitUntilConnected(t, c1)
testutils.WithTimeout(t, func() string {
if ts.GetEvent(webhook.EventRoomStarted) == nil {
@@ -70,7 +70,7 @@ func TestWebhooks(t *testing.T) {
ts.ClearEvents()
// another participant joins
c2 := createRTCClient("c2", defaultServerPort, useSinglePeerConnection, nil)
c2 := createRTCClient("c2", defaultServerPort, testRTCServicePath, nil)
waitUntilConnected(t, c2)
defer c2.Stop()
testutils.WithTimeout(t, func() string {