Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(186)

Side by Side Diff: webrtc/examples/objc/AppRTCDemo/tests/ARDAppClientTest.mm

Issue 2343403002: Rename AppRTCDemo on Android and iOS to AppRTCMobile (Closed)
Patch Set: Rebase Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 /*
2 * Copyright 2014 The WebRTC Project Authors. All rights reserved.
3 *
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
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
11 #import <Foundation/Foundation.h>
12 #import <OCMock/OCMock.h>
13
14 #include "webrtc/base/gunit.h"
15 #include "webrtc/base/ssladapter.h"
16
17 #import "WebRTC/RTCMediaConstraints.h"
18 #import "WebRTC/RTCPeerConnectionFactory.h"
19 #import "WebRTC/RTCSessionDescription.h"
20
21 #import "ARDAppClient+Internal.h"
22 #import "ARDJoinResponse+Internal.h"
23 #import "ARDMessageResponse+Internal.h"
24 #import "ARDSDPUtils.h"
25
26 // These classes mimic XCTest APIs, to make eventual conversion to XCTest
27 // easier. Conversion will happen once XCTest is supported well on build bots.
28 @interface ARDTestExpectation : NSObject
29
30 @property(nonatomic, readonly) NSString *description;
31 @property(nonatomic, readonly) BOOL isFulfilled;
32
33 - (instancetype)initWithDescription:(NSString *)description;
34 - (void)fulfill;
35
36 @end
37
38 @implementation ARDTestExpectation
39
40 @synthesize description = _description;
41 @synthesize isFulfilled = _isFulfilled;
42
43 - (instancetype)initWithDescription:(NSString *)description {
44 if (self = [super init]) {
45 _description = description;
46 }
47 return self;
48 }
49
50 - (void)fulfill {
51 _isFulfilled = YES;
52 }
53
54 @end
55
56 @interface ARDTestCase : NSObject
57
58 - (ARDTestExpectation *)expectationWithDescription:(NSString *)description;
59 - (void)waitForExpectationsWithTimeout:(NSTimeInterval)timeout
60 handler:(void (^)(NSError *error))handler;
61
62 @end
63
64 @implementation ARDTestCase {
65 NSMutableArray *_expectations;
66 }
67
68 - (instancetype)init {
69 if (self = [super init]) {
70 _expectations = [NSMutableArray array];
71 }
72 return self;
73 }
74
75 - (ARDTestExpectation *)expectationWithDescription:(NSString *)description {
76 ARDTestExpectation *expectation =
77 [[ARDTestExpectation alloc] initWithDescription:description];
78 [_expectations addObject:expectation];
79 return expectation;
80 }
81
82 - (void)waitForExpectationsWithTimeout:(NSTimeInterval)timeout
83 handler:(void (^)(NSError *error))handler {
84 NSDate *startDate = [NSDate date];
85 while (![self areExpectationsFulfilled]) {
86 NSTimeInterval duration = [[NSDate date] timeIntervalSinceDate:startDate];
87 if (duration > timeout) {
88 NSAssert(NO, @"Expectation timed out.");
89 break;
90 }
91 [[NSRunLoop currentRunLoop]
92 runUntilDate:[NSDate dateWithTimeIntervalSinceNow:1]];
93 }
94 handler(nil);
95 }
96
97 - (BOOL)areExpectationsFulfilled {
98 for (ARDTestExpectation *expectation in _expectations) {
99 if (!expectation.isFulfilled) {
100 return NO;
101 }
102 }
103 return YES;
104 }
105
106 @end
107
108 @interface ARDAppClientTest : ARDTestCase
109 @end
110
111 @implementation ARDAppClientTest
112
113 #pragma mark - Mock helpers
114
115 - (id)mockRoomServerClientForRoomId:(NSString *)roomId
116 clientId:(NSString *)clientId
117 isInitiator:(BOOL)isInitiator
118 messages:(NSArray *)messages
119 messageHandler:
120 (void (^)(ARDSignalingMessage *))messageHandler {
121 id mockRoomServerClient =
122 [OCMockObject mockForProtocol:@protocol(ARDRoomServerClient)];
123
124 // Successful join response.
125 ARDJoinResponse *joinResponse = [[ARDJoinResponse alloc] init];
126 joinResponse.result = kARDJoinResultTypeSuccess;
127 joinResponse.roomId = roomId;
128 joinResponse.clientId = clientId;
129 joinResponse.isInitiator = isInitiator;
130 joinResponse.messages = messages;
131
132 // Successful message response.
133 ARDMessageResponse *messageResponse = [[ARDMessageResponse alloc] init];
134 messageResponse.result = kARDMessageResultTypeSuccess;
135
136 // Return join response from above on join.
137 [[[mockRoomServerClient stub] andDo:^(NSInvocation *invocation) {
138 __unsafe_unretained void (^completionHandler)(ARDJoinResponse *response,
139 NSError *error);
140 [invocation getArgument:&completionHandler atIndex:3];
141 completionHandler(joinResponse, nil);
142 }] joinRoomWithRoomId:roomId isLoopback:NO completionHandler:[OCMArg any]];
143
144 // Return message response from above on join.
145 [[[mockRoomServerClient stub] andDo:^(NSInvocation *invocation) {
146 __unsafe_unretained ARDSignalingMessage *message;
147 __unsafe_unretained void (^completionHandler)(ARDMessageResponse *response,
148 NSError *error);
149 [invocation getArgument:&message atIndex:2];
150 [invocation getArgument:&completionHandler atIndex:5];
151 messageHandler(message);
152 completionHandler(messageResponse, nil);
153 }] sendMessage:[OCMArg any]
154 forRoomId:roomId
155 clientId:clientId
156 completionHandler:[OCMArg any]];
157
158 // Do nothing on leave.
159 [[[mockRoomServerClient stub] andDo:^(NSInvocation *invocation) {
160 __unsafe_unretained void (^completionHandler)(NSError *error);
161 [invocation getArgument:&completionHandler atIndex:4];
162 if (completionHandler) {
163 completionHandler(nil);
164 }
165 }] leaveRoomWithRoomId:roomId
166 clientId:clientId
167 completionHandler:[OCMArg any]];
168
169 return mockRoomServerClient;
170 }
171
172 - (id)mockSignalingChannelForRoomId:(NSString *)roomId
173 clientId:(NSString *)clientId
174 messageHandler:
175 (void (^)(ARDSignalingMessage *message))messageHandler {
176 id mockSignalingChannel =
177 [OCMockObject niceMockForProtocol:@protocol(ARDSignalingChannel)];
178 [[mockSignalingChannel stub] registerForRoomId:roomId clientId:clientId];
179 [[[mockSignalingChannel stub] andDo:^(NSInvocation *invocation) {
180 __unsafe_unretained ARDSignalingMessage *message;
181 [invocation getArgument:&message atIndex:2];
182 messageHandler(message);
183 }] sendMessage:[OCMArg any]];
184 return mockSignalingChannel;
185 }
186
187 - (id)mockTURNClient {
188 id mockTURNClient =
189 [OCMockObject mockForProtocol:@protocol(ARDTURNClient)];
190 [[[mockTURNClient stub] andDo:^(NSInvocation *invocation) {
191 // Don't return anything in TURN response.
192 __unsafe_unretained void (^completionHandler)(NSArray *turnServers,
193 NSError *error);
194 [invocation getArgument:&completionHandler atIndex:2];
195 completionHandler([NSArray array], nil);
196 }] requestServersWithCompletionHandler:[OCMArg any]];
197 return mockTURNClient;
198 }
199
200 - (ARDAppClient *)createAppClientForRoomId:(NSString *)roomId
201 clientId:(NSString *)clientId
202 isInitiator:(BOOL)isInitiator
203 messages:(NSArray *)messages
204 messageHandler:
205 (void (^)(ARDSignalingMessage *message))messageHandler
206 connectedHandler:(void (^)(void))connectedHandler {
207 id turnClient = [self mockTURNClient];
208 id signalingChannel = [self mockSignalingChannelForRoomId:roomId
209 clientId:clientId
210 messageHandler:messageHandler];
211 id roomServerClient =
212 [self mockRoomServerClientForRoomId:roomId
213 clientId:clientId
214 isInitiator:isInitiator
215 messages:messages
216 messageHandler:messageHandler];
217 id delegate =
218 [OCMockObject niceMockForProtocol:@protocol(ARDAppClientDelegate)];
219 [[[delegate stub] andDo:^(NSInvocation *invocation) {
220 connectedHandler();
221 }] appClient:[OCMArg any]
222 didChangeConnectionState:RTCIceConnectionStateConnected];
223
224 return [[ARDAppClient alloc] initWithRoomServerClient:roomServerClient
225 signalingChannel:signalingChannel
226 turnClient:turnClient
227 delegate:delegate];
228 }
229
230 // 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
232 // components are mocked out and messages are relayed directly from object to
233 // object. It's expected that both clients reach the
234 // RTCIceConnectionStateConnected state within a reasonable amount of time.
235 - (void)testSession {
236 // Need block arguments here because we're setting up a callbacks before we
237 // create the clients.
238 ARDAppClient *caller = nil;
239 ARDAppClient *answerer = nil;
240 __block __weak ARDAppClient *weakCaller = nil;
241 __block __weak ARDAppClient *weakAnswerer = nil;
242 NSString *roomId = @"testRoom";
243 NSString *callerId = @"testCallerId";
244 NSString *answererId = @"testAnswererId";
245
246 ARDTestExpectation *callerConnectionExpectation =
247 [self expectationWithDescription:@"Caller PC connected."];
248 ARDTestExpectation *answererConnectionExpectation =
249 [self expectationWithDescription:@"Answerer PC connected."];
250
251 caller = [self createAppClientForRoomId:roomId
252 clientId:callerId
253 isInitiator:YES
254 messages:[NSArray array]
255 messageHandler:^(ARDSignalingMessage *message) {
256 ARDAppClient *strongAnswerer = weakAnswerer;
257 [strongAnswerer channel:strongAnswerer.channel didReceiveMessage:message];
258 } connectedHandler:^{
259 [callerConnectionExpectation fulfill];
260 }];
261 // TODO(tkchin): Figure out why DTLS-SRTP constraint causes thread assertion
262 // crash in Debug.
263 caller.defaultPeerConnectionConstraints =
264 [[RTCMediaConstraints alloc] initWithMandatoryConstraints:nil
265 optionalConstraints:nil];
266 weakCaller = caller;
267
268 answerer = [self createAppClientForRoomId:roomId
269 clientId:answererId
270 isInitiator:NO
271 messages:[NSArray array]
272 messageHandler:^(ARDSignalingMessage *message) {
273 ARDAppClient *strongCaller = weakCaller;
274 [strongCaller channel:strongCaller.channel didReceiveMessage:message];
275 } connectedHandler:^{
276 [answererConnectionExpectation fulfill];
277 }];
278 // TODO(tkchin): Figure out why DTLS-SRTP constraint causes thread assertion
279 // crash in Debug.
280 answerer.defaultPeerConnectionConstraints =
281 [[RTCMediaConstraints alloc] initWithMandatoryConstraints:nil
282 optionalConstraints:nil];
283 weakAnswerer = answerer;
284
285 // Kick off connection.
286 [caller connectToRoomWithId:roomId
287 isLoopback:NO
288 isAudioOnly:NO
289 shouldMakeAecDump:NO
290 shouldUseLevelControl:NO];
291 [answerer connectToRoomWithId:roomId
292 isLoopback:NO
293 isAudioOnly:NO
294 shouldMakeAecDump:NO
295 shouldUseLevelControl:NO];
296 [self waitForExpectationsWithTimeout:20 handler:^(NSError *error) {
297 if (error) {
298 NSLog(@"Expectations error: %@", error);
299 }
300 }];
301 }
302
303 @end
304
305 @interface ARDSDPUtilsTest : ARDTestCase
306 - (void)testPreferVideoCodec;
307 @end
308
309 @implementation ARDSDPUtilsTest
310
311 - (void)testPreferVideoCodec {
312 NSString *sdp = @("m=video 9 RTP/SAVPF 100 116 117 96 120\n"
313 "a=rtpmap:120 H264/90000\n");
314 NSString *expectedSdp = @("m=video 9 RTP/SAVPF 120 100 116 117 96\n"
315 "a=rtpmap:120 H264/90000\n");
316 RTCSessionDescription* desc =
317 [[RTCSessionDescription alloc] initWithType:RTCSdpTypeOffer sdp:sdp];
318 RTCSessionDescription *h264Desc =
319 [ARDSDPUtils descriptionForDescription:desc
320 preferredVideoCodec:@"H264"];
321 EXPECT_TRUE([h264Desc.description isEqualToString:expectedSdp]);
322 }
323
324 @end
325
326 class SignalingTest : public ::testing::Test {
327 protected:
328 static void SetUpTestCase() {
329 rtc::InitializeSSL();
330 }
331 static void TearDownTestCase() {
332 rtc::CleanupSSL();
333 }
334 };
335
336 TEST_F(SignalingTest, SessionTest) {
337 @autoreleasepool {
338 ARDAppClientTest *test = [[ARDAppClientTest alloc] init];
339 [test testSession];
340 }
341 }
342
343 TEST_F(SignalingTest, SDPTest) {
344 @autoreleasepool {
345 ARDSDPUtilsTest *test = [[ARDSDPUtilsTest alloc] init];
346 [test testPreferVideoCodec];
347 }
348 }
349
350
OLDNEW
« no previous file with comments | « webrtc/examples/objc/AppRTCDemo/mac/main.m ('k') | webrtc/examples/objc/AppRTCDemo/third_party/SocketRocket/LICENSE » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698