Skip to content

Commit d443dd8

Browse files
pblazejclaude
andcommitted
test: retry connects in the ObjC tests
`testSendFile` is the first ObjC test to connect, and it is the first `Room` in that bundle's process — the ObjC bundle runs in its own PID, separate from the Swift phase. Server logs show the SFU sending the subscriber offer and five ICE candidates within 1ms of the join while the SDK never answers; the client gives up 10.1s later and the next Room in the same process answers in 45ms. One-time WebRTC and audio-stack init exceeds the connect timeout on a simulator. `TestEnvironment.withRooms` has always retried connects, which is why no Swift test is exposed to this. `LKObjCRoomHelper.connectWithRoom:url:token:` gives the ObjC tests the same 3 attempts, disconnecting between them so a timed-out attempt doesn't leave a participant on the server. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
1 parent 38238b6 commit d443dd8

6 files changed

Lines changed: 55 additions & 22 deletions

File tree

Tests/LiveKitObjCTests/DataStreamObjCTests.m

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ - (void)testSendText {
6060

6161
// Connect room0
6262
XCTestExpectation *connect0 = [self expectationWithDescription:@"connect0"];
63-
[room0 connectWithUrl:url token:token0 connectOptions:nil roomOptions:nil completionHandler:^(NSError *err) {
63+
[LKObjCRoomHelper connectWithRoom:room0 url:url token:token0 completionHandler:^(NSError *err) {
6464
XCTAssertNil(err);
6565
[connect0 fulfill];
6666
}];
@@ -71,7 +71,7 @@ - (void)testSendText {
7171

7272
// Connect room1
7373
XCTestExpectation *connect1 = [self expectationWithDescription:@"connect1"];
74-
[room1 connectWithUrl:url token:token1 connectOptions:nil roomOptions:nil completionHandler:^(NSError *err) {
74+
[LKObjCRoomHelper connectWithRoom:room1 url:url token:token1 completionHandler:^(NSError *err) {
7575
XCTAssertNil(err);
7676
[connect1 fulfill];
7777
}];
@@ -170,7 +170,7 @@ - (void)testStreamText {
170170

171171
// Connect both rooms
172172
XCTestExpectation *connect0 = [self expectationWithDescription:@"connect0"];
173-
[room0 connectWithUrl:url token:token0 connectOptions:nil roomOptions:nil completionHandler:^(NSError *err) {
173+
[LKObjCRoomHelper connectWithRoom:room0 url:url token:token0 completionHandler:^(NSError *err) {
174174
XCTAssertNil(err);
175175
[connect0 fulfill];
176176
}];
@@ -179,7 +179,7 @@ - (void)testStreamText {
179179
self.participantJoinedExp = [self expectationWithDescription:@"participantJoined"];
180180

181181
XCTestExpectation *connect1 = [self expectationWithDescription:@"connect1"];
182-
[room1 connectWithUrl:url token:token1 connectOptions:nil roomOptions:nil completionHandler:^(NSError *err) {
182+
[LKObjCRoomHelper connectWithRoom:room1 url:url token:token1 completionHandler:^(NSError *err) {
183183
XCTAssertNil(err);
184184
[connect1 fulfill];
185185
}];
@@ -266,7 +266,7 @@ - (void)testSendFile {
266266

267267
// Connect both rooms
268268
XCTestExpectation *connect0 = [self expectationWithDescription:@"connect0"];
269-
[room0 connectWithUrl:url token:token0 connectOptions:nil roomOptions:nil completionHandler:^(NSError *err) {
269+
[LKObjCRoomHelper connectWithRoom:room0 url:url token:token0 completionHandler:^(NSError *err) {
270270
XCTAssertNil(err);
271271
[connect0 fulfill];
272272
}];
@@ -275,7 +275,7 @@ - (void)testSendFile {
275275
self.participantJoinedExp = [self expectationWithDescription:@"participantJoined"];
276276

277277
XCTestExpectation *connect1 = [self expectationWithDescription:@"connect1"];
278-
[room1 connectWithUrl:url token:token1 connectOptions:nil roomOptions:nil completionHandler:^(NSError *err) {
278+
[LKObjCRoomHelper connectWithRoom:room1 url:url token:token1 completionHandler:^(NSError *err) {
279279
XCTAssertNil(err);
280280
[connect1 fulfill];
281281
}];
@@ -374,7 +374,7 @@ - (void)testStreamBytes {
374374

375375
// Connect both rooms
376376
XCTestExpectation *connect0 = [self expectationWithDescription:@"connect0"];
377-
[room0 connectWithUrl:url token:token0 connectOptions:nil roomOptions:nil completionHandler:^(NSError *err) {
377+
[LKObjCRoomHelper connectWithRoom:room0 url:url token:token0 completionHandler:^(NSError *err) {
378378
XCTAssertNil(err);
379379
[connect0 fulfill];
380380
}];
@@ -383,7 +383,7 @@ - (void)testStreamBytes {
383383
self.participantJoinedExp = [self expectationWithDescription:@"participantJoined"];
384384

385385
XCTestExpectation *connect1 = [self expectationWithDescription:@"connect1"];
386-
[room1 connectWithUrl:url token:token1 connectOptions:nil roomOptions:nil completionHandler:^(NSError *err) {
386+
[LKObjCRoomHelper connectWithRoom:room1 url:url token:token1 completionHandler:^(NSError *err) {
387387
XCTAssertNil(err);
388388
[connect1 fulfill];
389389
}];

Tests/LiveKitObjCTests/DelegateObjCTests.m

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ - (void)testRoomDelegateCallbacks {
7070
// Verify roomDidConnect fires
7171
self.roomDidConnectExp = [self expectationWithDescription:@"roomDidConnect"];
7272
XCTestExpectation *connectExp = [self expectationWithDescription:@"connectCompletion"];
73-
[room connectWithUrl:url token:token connectOptions:nil roomOptions:nil completionHandler:^(NSError *err) {
73+
[LKObjCRoomHelper connectWithRoom:room url:url token:token completionHandler:^(NSError *err) {
7474
XCTAssertNil(err);
7575
[connectExp fulfill];
7676
}];
@@ -110,7 +110,7 @@ - (void)testParticipantDidConnect {
110110
Room *room1 = [[Room alloc] initWithDelegate:self connectOptions:nil roomOptions:nil];
111111

112112
XCTestExpectation *connect1 = [self expectationWithDescription:@"connect1"];
113-
[room1 connectWithUrl:url token:token1 connectOptions:nil roomOptions:nil completionHandler:^(NSError *err) {
113+
[LKObjCRoomHelper connectWithRoom:room1 url:url token:token1 completionHandler:^(NSError *err) {
114114
XCTAssertNil(err);
115115
[connect1 fulfill];
116116
}];
@@ -123,7 +123,7 @@ - (void)testParticipantDidConnect {
123123
Room *room2 = [[Room alloc] initWithDelegate:nil connectOptions:nil roomOptions:nil];
124124

125125
XCTestExpectation *connect2 = [self expectationWithDescription:@"connect2"];
126-
[room2 connectWithUrl:url token:token2 connectOptions:nil roomOptions:nil completionHandler:^(NSError *err) {
126+
[LKObjCRoomHelper connectWithRoom:room2 url:url token:token2 completionHandler:^(NSError *err) {
127127
XCTAssertNil(err);
128128
[connect2 fulfill];
129129
}];
@@ -166,7 +166,7 @@ - (void)testParticipantDidDisconnect {
166166
Room *room1 = [[Room alloc] initWithDelegate:self connectOptions:nil roomOptions:nil];
167167

168168
XCTestExpectation *connect1 = [self expectationWithDescription:@"connect1"];
169-
[room1 connectWithUrl:url token:token1 connectOptions:nil roomOptions:nil completionHandler:^(NSError *err) {
169+
[LKObjCRoomHelper connectWithRoom:room1 url:url token:token1 completionHandler:^(NSError *err) {
170170
XCTAssertNil(err);
171171
[connect1 fulfill];
172172
}];
@@ -179,7 +179,7 @@ - (void)testParticipantDidDisconnect {
179179
Room *room2 = [[Room alloc] initWithDelegate:nil connectOptions:nil roomOptions:nil];
180180

181181
XCTestExpectation *connect2 = [self expectationWithDescription:@"connect2"];
182-
[room2 connectWithUrl:url token:token2 connectOptions:nil roomOptions:nil completionHandler:^(NSError *err) {
182+
[LKObjCRoomHelper connectWithRoom:room2 url:url token:token2 completionHandler:^(NSError *err) {
183183
XCTAssertNil(err);
184184
[connect2 fulfill];
185185
}];

Tests/LiveKitObjCTests/ParticipantObjCTests.m

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ - (void)testRemoteParticipants {
5555
Room *room1 = [[Room alloc] initWithDelegate:self connectOptions:nil roomOptions:nil];
5656

5757
XCTestExpectation *connect1 = [self expectationWithDescription:@"connect1"];
58-
[room1 connectWithUrl:url token:token1 connectOptions:nil roomOptions:nil completionHandler:^(NSError *err) {
58+
[LKObjCRoomHelper connectWithRoom:room1 url:url token:token1 completionHandler:^(NSError *err) {
5959
XCTAssertNil(err);
6060
[connect1 fulfill];
6161
}];
@@ -68,7 +68,7 @@ - (void)testRemoteParticipants {
6868
Room *room2 = [[Room alloc] initWithDelegate:nil connectOptions:nil roomOptions:nil];
6969

7070
XCTestExpectation *connect2 = [self expectationWithDescription:@"connect2"];
71-
[room2 connectWithUrl:url token:token2 connectOptions:nil roomOptions:nil completionHandler:^(NSError *err) {
71+
[LKObjCRoomHelper connectWithRoom:room2 url:url token:token2 completionHandler:^(NSError *err) {
7272
XCTAssertNil(err);
7373
[connect2 fulfill];
7474
}];
@@ -99,7 +99,7 @@ - (void)testParticipantProperties {
9999
Room *room = [[Room alloc] initWithDelegate:nil connectOptions:nil roomOptions:nil];
100100

101101
XCTestExpectation *connectExp = [self expectationWithDescription:@"connect"];
102-
[room connectWithUrl:url token:token connectOptions:nil roomOptions:nil completionHandler:^(NSError *err) {
102+
[LKObjCRoomHelper connectWithRoom:room url:url token:token completionHandler:^(NSError *err) {
103103
XCTAssertNil(err);
104104
[connectExp fulfill];
105105
}];

Tests/LiveKitObjCTests/RoomObjCTests.m

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ - (void)testRoomConnectDisconnect {
5151

5252
// Connect
5353
XCTestExpectation *connectExp = [self expectationWithDescription:@"connect"];
54-
[room connectWithUrl:url token:token connectOptions:nil roomOptions:nil completionHandler:^(NSError *err) {
54+
[LKObjCRoomHelper connectWithRoom:room url:url token:token completionHandler:^(NSError *err) {
5555
XCTAssertNil(err);
5656
[connectExp fulfill];
5757
}];
@@ -85,7 +85,7 @@ - (void)testRoomProperties {
8585

8686
// Connect
8787
XCTestExpectation *connectExp = [self expectationWithDescription:@"connect"];
88-
[room connectWithUrl:url token:token connectOptions:nil roomOptions:nil completionHandler:^(NSError *err) {
88+
[LKObjCRoomHelper connectWithRoom:room url:url token:token completionHandler:^(NSError *err) {
8989
XCTAssertNil(err);
9090
[connectExp fulfill];
9191
}];
@@ -126,7 +126,7 @@ - (void)testLocalParticipantIdentity {
126126

127127
// Connect
128128
XCTestExpectation *connectExp = [self expectationWithDescription:@"connect"];
129-
[room connectWithUrl:url token:token connectOptions:nil roomOptions:nil completionHandler:^(NSError *err) {
129+
[LKObjCRoomHelper connectWithRoom:room url:url token:token completionHandler:^(NSError *err) {
130130
XCTAssertNil(err);
131131
[connectExp fulfill];
132132
}];

Tests/LiveKitObjCTests/RpcObjCTests.m

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ - (void)testRegisterAndCallRpc {
5858

5959
// Connect room0
6060
XCTestExpectation *connect0 = [self expectationWithDescription:@"connect0"];
61-
[room0 connectWithUrl:url token:token0 connectOptions:nil roomOptions:nil completionHandler:^(NSError *err) {
61+
[LKObjCRoomHelper connectWithRoom:room0 url:url token:token0 completionHandler:^(NSError *err) {
6262
XCTAssertNil(err);
6363
[connect0 fulfill];
6464
}];
@@ -68,7 +68,7 @@ - (void)testRegisterAndCallRpc {
6868

6969
// Connect room1
7070
XCTestExpectation *connect1 = [self expectationWithDescription:@"connect1"];
71-
[room1 connectWithUrl:url token:token1 connectOptions:nil roomOptions:nil completionHandler:^(NSError *err) {
71+
[LKObjCRoomHelper connectWithRoom:room1 url:url token:token1 completionHandler:^(NSError *err) {
7272
XCTAssertNil(err);
7373
[connect1 fulfill];
7474
}];
@@ -129,7 +129,7 @@ - (void)testUnregisterRpc {
129129
Room *room = [[Room alloc] initWithDelegate:nil connectOptions:nil roomOptions:nil];
130130

131131
XCTestExpectation *connectExp = [self expectationWithDescription:@"connect"];
132-
[room connectWithUrl:url token:token connectOptions:nil roomOptions:nil completionHandler:^(NSError *err) {
132+
[LKObjCRoomHelper connectWithRoom:room url:url token:token completionHandler:^(NSError *err) {
133133
XCTAssertNil(err);
134134
[connectExp fulfill];
135135
}];

Tests/LiveKitTestSupport/ObjCRoomHelper.swift

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,39 @@ import LiveKitUniFFI
2121
/// ObjC-compatible helper for generating tokens and reading server configuration.
2222
@objcMembers
2323
public class LKObjCRoomHelper: NSObject {
24+
private static let connectAttempts = 3
25+
private static let connectRetryDelay: UInt64 = 2_000_000_000
26+
27+
/// Connects with retries, matching `TestEnvironment.withRooms`. The first `Room`
28+
/// in a process pays one-time WebRTC and audio-stack initialization that can
29+
/// exceed the connect timeout on a simulator.
30+
@objc(connectWithRoom:url:token:completionHandler:)
31+
public static func connect(room: Room,
32+
url: String,
33+
token: String,
34+
completionHandler: @escaping @Sendable (Error?) -> Void)
35+
{
36+
Task {
37+
var lastError: Error?
38+
for attempt in 1 ... connectAttempts {
39+
do {
40+
try await room.connect(url: url, token: token)
41+
completionHandler(nil)
42+
return
43+
} catch {
44+
lastError = error
45+
// A timed-out connect can leave the signal connection live, so
46+
// reset before retrying instead of leaking a participant.
47+
await room.disconnect()
48+
if attempt < connectAttempts {
49+
try? await Task.sleep(nanoseconds: connectRetryDelay)
50+
}
51+
}
52+
}
53+
completionHandler(lastError)
54+
}
55+
}
56+
2457
public static func serverURL() -> String {
2558
if let string = ProcessInfo.processInfo.environment["LIVEKIT_TESTING_URL"]?.trimmingCharacters(in: .whitespacesAndNewlines),
2659
!string.isEmpty

0 commit comments

Comments
 (0)