OLD | NEW |
---|---|
1 /* | 1 /* |
2 * Copyright 2014 The WebRTC Project Authors. All rights reserved. | 2 * Copyright 2014 The WebRTC Project Authors. All rights reserved. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license | 4 * Use of this source code is governed by a BSD-style license |
5 * that can be found in the LICENSE file in the root of the source | 5 * that can be found in the LICENSE file in the root of the source |
6 * tree. An additional intellectual property rights grant can be found | 6 * tree. An additional intellectual property rights grant can be found |
7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
9 */ | 9 */ |
10 | 10 |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
74 | 74 |
75 - (ARDTestExpectation *)expectationWithDescription:(NSString *)description { | 75 - (ARDTestExpectation *)expectationWithDescription:(NSString *)description { |
76 ARDTestExpectation *expectation = | 76 ARDTestExpectation *expectation = |
77 [[ARDTestExpectation alloc] initWithDescription:description]; | 77 [[ARDTestExpectation alloc] initWithDescription:description]; |
78 [_expectations addObject:expectation]; | 78 [_expectations addObject:expectation]; |
79 return expectation; | 79 return expectation; |
80 } | 80 } |
81 | 81 |
82 - (void)waitForExpectationsWithTimeout:(NSTimeInterval)timeout | 82 - (void)waitForExpectationsWithTimeout:(NSTimeInterval)timeout |
83 handler:(void (^)(NSError *error))handler { | 83 handler:(void (^)(NSError *error))handler { |
84 NSDate *startDate = [NSDate date]; | 84 NSDate *startDate = [NSDate date]; |
tkchin_webrtc
2016/09/29 11:14:40
Probably better to use media timing here for accur
| |
85 NSError *error = nil; | |
85 while (![self areExpectationsFulfilled]) { | 86 while (![self areExpectationsFulfilled]) { |
86 NSTimeInterval duration = [[NSDate date] timeIntervalSinceDate:startDate]; | 87 NSTimeInterval duration = [[NSDate date] timeIntervalSinceDate:startDate]; |
87 if (duration > timeout) { | 88 if (duration > timeout) { |
88 NSAssert(NO, @"Expectation timed out."); | 89 error = [NSError errorWithDomain:@"ARDAppClient" |
tkchin_webrtc
2016/09/29 11:14:40
Not sure we need this error. We'd want to just do
tkchin_webrtc
2016/09/29 11:14:40
make domain a global constant. org.webrtc.ARDAppCl
| |
90 code:101 | |
tkchin_webrtc
2016/09/29 11:14:40
likewise, global constant
kARDAppClientTestsExpect
| |
91 userInfo:@{NSLocalizedDescriptionKey : @"Expectati on timed out"}]; | |
89 break; | 92 break; |
90 } | 93 } |
91 [[NSRunLoop currentRunLoop] | 94 [[NSRunLoop currentRunLoop] |
92 runUntilDate:[NSDate dateWithTimeIntervalSinceNow:1]]; | 95 runUntilDate:[NSDate dateWithTimeIntervalSinceNow:1]]; |
93 } | 96 } |
94 handler(nil); | 97 handler(error); |
95 } | 98 } |
96 | 99 |
97 - (BOOL)areExpectationsFulfilled { | 100 - (BOOL)areExpectationsFulfilled { |
98 for (ARDTestExpectation *expectation in _expectations) { | 101 for (ARDTestExpectation *expectation in _expectations) { |
99 if (!expectation.isFulfilled) { | 102 if (!expectation.isFulfilled) { |
100 return NO; | 103 return NO; |
101 } | 104 } |
102 } | 105 } |
103 return YES; | 106 return YES; |
104 } | 107 } |
(...skipping 25 matching lines...) Expand all Loading... | |
130 joinResponse.messages = messages; | 133 joinResponse.messages = messages; |
131 | 134 |
132 // Successful message response. | 135 // Successful message response. |
133 ARDMessageResponse *messageResponse = [[ARDMessageResponse alloc] init]; | 136 ARDMessageResponse *messageResponse = [[ARDMessageResponse alloc] init]; |
134 messageResponse.result = kARDMessageResultTypeSuccess; | 137 messageResponse.result = kARDMessageResultTypeSuccess; |
135 | 138 |
136 // Return join response from above on join. | 139 // Return join response from above on join. |
137 [[[mockRoomServerClient stub] andDo:^(NSInvocation *invocation) { | 140 [[[mockRoomServerClient stub] andDo:^(NSInvocation *invocation) { |
138 __unsafe_unretained void (^completionHandler)(ARDJoinResponse *response, | 141 __unsafe_unretained void (^completionHandler)(ARDJoinResponse *response, |
139 NSError *error); | 142 NSError *error); |
140 [invocation getArgument:&completionHandler atIndex:3]; | 143 [invocation getArgument:&completionHandler atIndex:4]; |
141 completionHandler(joinResponse, nil); | 144 completionHandler(joinResponse, nil); |
142 }] joinRoomWithRoomId:roomId isLoopback:NO completionHandler:[OCMArg any]]; | 145 }] joinRoomWithRoomId:roomId isLoopback:NO completionHandler:[OCMArg any]]; |
143 | 146 |
144 // Return message response from above on join. | 147 // Return message response from above on join. |
145 [[[mockRoomServerClient stub] andDo:^(NSInvocation *invocation) { | 148 [[[mockRoomServerClient stub] andDo:^(NSInvocation *invocation) { |
146 __unsafe_unretained ARDSignalingMessage *message; | 149 __unsafe_unretained ARDSignalingMessage *message; |
147 __unsafe_unretained void (^completionHandler)(ARDMessageResponse *response, | 150 __unsafe_unretained void (^completionHandler)(ARDMessageResponse *response, |
148 NSError *error); | 151 NSError *error); |
149 [invocation getArgument:&message atIndex:2]; | 152 [invocation getArgument:&message atIndex:2]; |
150 [invocation getArgument:&completionHandler atIndex:5]; | 153 [invocation getArgument:&completionHandler atIndex:5]; |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
196 }] requestServersWithCompletionHandler:[OCMArg any]]; | 199 }] requestServersWithCompletionHandler:[OCMArg any]]; |
197 return mockTURNClient; | 200 return mockTURNClient; |
198 } | 201 } |
199 | 202 |
200 - (ARDAppClient *)createAppClientForRoomId:(NSString *)roomId | 203 - (ARDAppClient *)createAppClientForRoomId:(NSString *)roomId |
201 clientId:(NSString *)clientId | 204 clientId:(NSString *)clientId |
202 isInitiator:(BOOL)isInitiator | 205 isInitiator:(BOOL)isInitiator |
203 messages:(NSArray *)messages | 206 messages:(NSArray *)messages |
204 messageHandler: | 207 messageHandler: |
205 (void (^)(ARDSignalingMessage *message))messageHandler | 208 (void (^)(ARDSignalingMessage *message))messageHandler |
206 connectedHandler:(void (^)(void))connectedHandler { | 209 connectedHandler:(void (^)(NSInvocation *))connectedHa ndler { |
tkchin_webrtc
2016/09/29 11:14:40
would rather not be passing NSInvocation around to
afedor
2016/11/02 14:11:02
How about just passing back the selector name?
| |
207 id turnClient = [self mockTURNClient]; | 210 id turnClient = [self mockTURNClient]; |
208 id signalingChannel = [self mockSignalingChannelForRoomId:roomId | 211 id signalingChannel = [self mockSignalingChannelForRoomId:roomId |
209 clientId:clientId | 212 clientId:clientId |
210 messageHandler:messageHandler]; | 213 messageHandler:messageHandler]; |
211 id roomServerClient = | 214 id roomServerClient = |
212 [self mockRoomServerClientForRoomId:roomId | 215 [self mockRoomServerClientForRoomId:roomId |
213 clientId:clientId | 216 clientId:clientId |
214 isInitiator:isInitiator | 217 isInitiator:isInitiator |
215 messages:messages | 218 messages:messages |
216 messageHandler:messageHandler]; | 219 messageHandler:messageHandler]; |
217 id delegate = | 220 id delegate = |
218 [OCMockObject niceMockForProtocol:@protocol(ARDAppClientDelegate)]; | 221 [OCMockObject niceMockForProtocol:@protocol(ARDAppClientDelegate)]; |
219 [[[delegate stub] andDo:^(NSInvocation *invocation) { | 222 [[[delegate stub] andDo:^(NSInvocation *invocation) { |
220 connectedHandler(); | 223 connectedHandler(invocation); |
221 }] appClient:[OCMArg any] | 224 }] appClient:[OCMArg any] |
222 didChangeConnectionState:RTCIceConnectionStateConnected]; | 225 didChangeConnectionState:RTCIceConnectionStateConnected]; |
226 [[[delegate stub] andDo:^(NSInvocation *invocation) { | |
227 connectedHandler(invocation); | |
tkchin_webrtc
2016/09/29 11:14:40
I feel like this should be a different handler ins
| |
228 }] appClient:[OCMArg any] | |
229 didReceiveLocalVideoTrack:[OCMArg any]]; | |
223 | 230 |
224 return [[ARDAppClient alloc] initWithRoomServerClient:roomServerClient | 231 return [[ARDAppClient alloc] initWithRoomServerClient:roomServerClient |
225 signalingChannel:signalingChannel | 232 signalingChannel:signalingChannel |
226 turnClient:turnClient | 233 turnClient:turnClient |
227 delegate:delegate]; | 234 delegate:delegate]; |
228 } | 235 } |
229 | 236 |
230 // Tests that an ICE connection is established between two ARDAppClient objects | 237 // Tests that an ICE connection is established between two ARDAppClient objects |
231 // where one is set up as a caller and the other the answerer. Network | 238 // where one is set up as a caller and the other the answerer. Network |
232 // components are mocked out and messages are relayed directly from object to | 239 // components are mocked out and messages are relayed directly from object to |
(...skipping 15 matching lines...) Expand all Loading... | |
248 ARDTestExpectation *answererConnectionExpectation = | 255 ARDTestExpectation *answererConnectionExpectation = |
249 [self expectationWithDescription:@"Answerer PC connected."]; | 256 [self expectationWithDescription:@"Answerer PC connected."]; |
250 | 257 |
251 caller = [self createAppClientForRoomId:roomId | 258 caller = [self createAppClientForRoomId:roomId |
252 clientId:callerId | 259 clientId:callerId |
253 isInitiator:YES | 260 isInitiator:YES |
254 messages:[NSArray array] | 261 messages:[NSArray array] |
255 messageHandler:^(ARDSignalingMessage *message) { | 262 messageHandler:^(ARDSignalingMessage *message) { |
256 ARDAppClient *strongAnswerer = weakAnswerer; | 263 ARDAppClient *strongAnswerer = weakAnswerer; |
257 [strongAnswerer channel:strongAnswerer.channel didReceiveMessage:message]; | 264 [strongAnswerer channel:strongAnswerer.channel didReceiveMessage:message]; |
258 } connectedHandler:^{ | 265 } connectedHandler:^(NSInvocation *invocation){ |
259 [callerConnectionExpectation fulfill]; | 266 if ([NSStringFromSelector([invocation selector]) |
267 isEqualToString:@"appClient:didChangeConnectionState:"]) | |
268 [callerConnectionExpectation fulfill]; | |
260 }]; | 269 }]; |
261 // TODO(tkchin): Figure out why DTLS-SRTP constraint causes thread assertion | 270 // TODO(tkchin): Figure out why DTLS-SRTP constraint causes thread assertion |
262 // crash in Debug. | 271 // crash in Debug. |
263 caller.defaultPeerConnectionConstraints = | 272 caller.defaultPeerConnectionConstraints = |
264 [[RTCMediaConstraints alloc] initWithMandatoryConstraints:nil | 273 [[RTCMediaConstraints alloc] initWithMandatoryConstraints:nil |
265 optionalConstraints:nil]; | 274 optionalConstraints:nil]; |
266 weakCaller = caller; | 275 weakCaller = caller; |
267 | 276 |
268 answerer = [self createAppClientForRoomId:roomId | 277 answerer = [self createAppClientForRoomId:roomId |
269 clientId:answererId | 278 clientId:answererId |
270 isInitiator:NO | 279 isInitiator:NO |
271 messages:[NSArray array] | 280 messages:[NSArray array] |
272 messageHandler:^(ARDSignalingMessage *message) { | 281 messageHandler:^(ARDSignalingMessage *message) { |
273 ARDAppClient *strongCaller = weakCaller; | 282 ARDAppClient *strongCaller = weakCaller; |
274 [strongCaller channel:strongCaller.channel didReceiveMessage:message]; | 283 [strongCaller channel:strongCaller.channel didReceiveMessage:message]; |
275 } connectedHandler:^{ | 284 } connectedHandler:^(NSInvocation *invocation){ |
276 [answererConnectionExpectation fulfill]; | 285 if ([NSStringFromSelector([invocation selector]) |
286 isEqualToString:@"appClient:didChangeConnectionState:"]) | |
287 [answererConnectionExpectation fulfill]; | |
277 }]; | 288 }]; |
278 // TODO(tkchin): Figure out why DTLS-SRTP constraint causes thread assertion | 289 // TODO(tkchin): Figure out why DTLS-SRTP constraint causes thread assertion |
279 // crash in Debug. | 290 // crash in Debug. |
280 answerer.defaultPeerConnectionConstraints = | 291 answerer.defaultPeerConnectionConstraints = |
281 [[RTCMediaConstraints alloc] initWithMandatoryConstraints:nil | 292 [[RTCMediaConstraints alloc] initWithMandatoryConstraints:nil |
282 optionalConstraints:nil]; | 293 optionalConstraints:nil]; |
283 weakAnswerer = answerer; | 294 weakAnswerer = answerer; |
284 | 295 |
285 // Kick off connection. | 296 // Kick off connection. |
286 [caller connectToRoomWithId:roomId isLoopback:NO isAudioOnly:NO]; | 297 [caller connectToRoomWithId:roomId isLoopback:NO isAudioOnly:NO]; |
287 [answerer connectToRoomWithId:roomId isLoopback:NO isAudioOnly:NO]; | 298 [answerer connectToRoomWithId:roomId isLoopback:NO isAudioOnly:NO]; |
288 [self waitForExpectationsWithTimeout:20 handler:^(NSError *error) { | 299 [self waitForExpectationsWithTimeout:20 handler:^(NSError *error) { |
289 if (error) { | 300 if (error) { |
290 NSLog(@"Expectations error: %@", error); | 301 NSLog(@"Expectations error: %@", error); |
291 } | 302 } |
292 }]; | 303 }]; |
293 } | 304 } |
294 | 305 |
306 // Test to see that we get a local video connection | |
307 // Note this will currently pass even when no camera is connected as a local | |
308 // video track is created regardless (Perhaps there should be a test for that... ) | |
309 - (void)testSession_ShouldGetLocalVideoTrackCallback { | |
310 ARDAppClient *caller = nil; | |
311 NSString *roomId = @"testRoom"; | |
312 NSString *callerId = @"testCallerId"; | |
313 | |
314 ARDTestExpectation *callerConnectionExpectation = | |
315 [self expectationWithDescription:@"Caller PC connected."]; | |
316 | |
317 caller = [self createAppClientForRoomId:roomId | |
318 clientId:callerId | |
319 isInitiator:YES | |
320 messages:[NSArray array] | |
321 messageHandler:^(ARDSignalingMessage *message) { | |
tkchin_webrtc
2016/09/29 11:14:40
fix indentation
| |
322 } connectedHandler:^(NSInvocation *invocation){ | |
323 if ([NSStringFromSelector([invocation selector]) | |
324 isEqualToString:@"appClient:didReceiveLocalVid eoTrack:"]) | |
325 [callerConnectionExpectation fulfill]; | |
326 }]; | |
327 caller.defaultPeerConnectionConstraints = | |
328 [[RTCMediaConstraints alloc] initWithMandatoryConstraints:nil | |
329 optionalConstraints:nil]; | |
330 | |
331 // Kick off connection. | |
332 [caller connectToRoomWithId:roomId isLoopback:NO isAudioOnly:NO]; | |
333 [self waitForExpectationsWithTimeout:20 handler:^(NSError *error) { | |
334 if (error) { | |
335 EXPECT_TRUE(0); | |
336 } | |
337 }]; | |
338 } | |
339 | |
295 @end | 340 @end |
296 | 341 |
342 @interface NSString (WebRTCTests) | |
tkchin_webrtc
2016/09/29 11:14:40
I don't think we need an extra category for this s
| |
343 - (BOOL) webrtc_containsString: (NSString *)otherString; | |
344 @end | |
345 @implementation NSString (WebRTCTests) | |
346 - (BOOL) webrtc_containsString: (NSString *)otherString | |
347 { | |
348 return (otherString && [self rangeOfString: otherString].location != NSNotFoun d); | |
349 } | |
350 @end | |
351 | |
297 @interface ARDSDPUtilsTest : ARDTestCase | 352 @interface ARDSDPUtilsTest : ARDTestCase |
298 - (void)testPreferVideoCodec; | 353 - (void)testPreferVideoCodec; |
299 @end | 354 @end |
300 | 355 |
301 @implementation ARDSDPUtilsTest | 356 @implementation ARDSDPUtilsTest |
302 | 357 |
358 | |
303 - (void)testPreferVideoCodec { | 359 - (void)testPreferVideoCodec { |
304 NSString *sdp = @("m=video 9 RTP/SAVPF 100 116 117 96 120\n" | 360 NSString *sdp = @("m=video 9 RTP/SAVPF 100 116 117 96 120\n" |
305 "a=rtpmap:120 H264/90000\n"); | 361 "a=rtpmap:120 H264/90000\n"); |
306 NSString *expectedSdp = @("m=video 9 RTP/SAVPF 120 100 116 117 96\n" | 362 NSArray *expectedSdpLines = @[@"m=video 9 RTP/SAVPF 120 100 116 117 96\n", |
tkchin_webrtc
2016/09/29 11:14:40
don't know how this got here but it's intended to
| |
307 "a=rtpmap:120 H264/90000\n"); | 363 @"a=rtpmap:120 H264/90000\n"]; |
308 RTCSessionDescription* desc = | 364 RTCSessionDescription* desc = |
309 [[RTCSessionDescription alloc] initWithType:RTCSdpTypeOffer sdp:sdp]; | 365 [[RTCSessionDescription alloc] initWithType:RTCSdpTypeOffer sdp:sdp]; |
310 RTCSessionDescription *h264Desc = | 366 RTCSessionDescription *h264Desc = |
311 [ARDSDPUtils descriptionForDescription:desc | 367 [ARDSDPUtils descriptionForDescription:desc |
312 preferredVideoCodec:@"H264"]; | 368 preferredVideoCodec:@"H264"]; |
313 EXPECT_TRUE([h264Desc.description isEqualToString:expectedSdp]); | 369 EXPECT_TRUE([h264Desc.description webrtc_containsString: expectedSdpLines[0]] |
370 && [h264Desc.description webrtc_containsString: expectedSdpLines[1 ]]); | |
314 } | 371 } |
315 | 372 |
316 @end | 373 @end |
317 | 374 |
318 class SignalingTest : public ::testing::Test { | 375 class SignalingTest : public ::testing::Test { |
319 protected: | 376 protected: |
320 static void SetUpTestCase() { | 377 static void SetUpTestCase() { |
321 rtc::InitializeSSL(); | 378 rtc::InitializeSSL(); |
322 } | 379 } |
323 static void TearDownTestCase() { | 380 static void TearDownTestCase() { |
324 rtc::CleanupSSL(); | 381 rtc::CleanupSSL(); |
325 } | 382 } |
326 }; | 383 }; |
327 | 384 |
328 TEST_F(SignalingTest, SessionTest) { | 385 TEST_F(SignalingTest, SessionTest) { |
329 @autoreleasepool { | 386 @autoreleasepool { |
330 ARDAppClientTest *test = [[ARDAppClientTest alloc] init]; | 387 ARDAppClientTest *test = [[ARDAppClientTest alloc] init]; |
331 [test testSession]; | 388 [test testSession]; |
332 } | 389 } |
333 } | 390 } |
334 | 391 |
392 TEST_F(SignalingTest, SessionLocalVideoCallbackTest) { | |
393 @autoreleasepool { | |
394 ARDAppClientTest *test = [[ARDAppClientTest alloc] init]; | |
395 [test testSession_ShouldGetLocalVideoTrackCallback]; | |
396 } | |
397 } | |
398 | |
335 TEST_F(SignalingTest, SDPTest) { | 399 TEST_F(SignalingTest, SDPTest) { |
336 @autoreleasepool { | 400 @autoreleasepool { |
337 ARDSDPUtilsTest *test = [[ARDSDPUtilsTest alloc] init]; | 401 ARDSDPUtilsTest *test = [[ARDSDPUtilsTest alloc] init]; |
338 [test testPreferVideoCodec]; | 402 [test testPreferVideoCodec]; |
339 } | 403 } |
340 } | 404 } |
341 | 405 |
342 | 406 |
OLD | NEW |