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

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

Issue 1235563006: Move talk/examples/* to webrtc/examples. (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: 201508051337 Created 5 years, 4 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 * libjingle
3 * Copyright 2014 Google Inc.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright notice,
9 * this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright notice,
11 * this list of conditions and the following disclaimer in the documentation
12 * and/or other materials provided with the distribution.
13 * 3. The name of the author may not be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
19 * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
22 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
23 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
24 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
25 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28 #import <Foundation/Foundation.h>
29 #import <OCMock/OCMock.h>
30
31 #import "ARDAppClient+Internal.h"
32 #import "ARDJoinResponse+Internal.h"
33 #import "ARDMessageResponse+Internal.h"
34 #import "ARDSDPUtils.h"
35 #import "RTCMediaConstraints.h"
36 #import "RTCPeerConnectionFactory.h"
37 #import "RTCSessionDescription.h"
38
39 #include "webrtc/base/gunit.h"
40 #include "webrtc/base/ssladapter.h"
41
42 // These classes mimic XCTest APIs, to make eventual conversion to XCTest
43 // easier. Conversion will happen once XCTest is supported well on build bots.
44 @interface ARDTestExpectation : NSObject
45
46 @property(nonatomic, readonly) NSString *description;
47 @property(nonatomic, readonly) BOOL isFulfilled;
48
49 - (instancetype)initWithDescription:(NSString *)description;
50 - (void)fulfill;
51
52 @end
53
54 @implementation ARDTestExpectation
55
56 @synthesize description = _description;
57 @synthesize isFulfilled = _isFulfilled;
58
59 - (instancetype)initWithDescription:(NSString *)description {
60 if (self = [super init]) {
61 _description = description;
62 }
63 return self;
64 }
65
66 - (void)fulfill {
67 _isFulfilled = YES;
68 }
69
70 @end
71
72 @interface ARDTestCase : NSObject
73
74 - (ARDTestExpectation *)expectationWithDescription:(NSString *)description;
75 - (void)waitForExpectationsWithTimeout:(NSTimeInterval)timeout
76 handler:(void (^)(NSError *error))handler;
77
78 @end
79
80 @implementation ARDTestCase {
81 NSMutableArray *_expectations;
82 }
83
84 - (instancetype)init {
85 if (self = [super init]) {
86 _expectations = [NSMutableArray array];
87 }
88 return self;
89 }
90
91 - (ARDTestExpectation *)expectationWithDescription:(NSString *)description {
92 ARDTestExpectation *expectation =
93 [[ARDTestExpectation alloc] initWithDescription:description];
94 [_expectations addObject:expectation];
95 return expectation;
96 }
97
98 - (void)waitForExpectationsWithTimeout:(NSTimeInterval)timeout
99 handler:(void (^)(NSError *error))handler {
100 NSDate *startDate = [NSDate date];
101 while (![self areExpectationsFulfilled]) {
102 NSTimeInterval duration = [[NSDate date] timeIntervalSinceDate:startDate];
103 if (duration > timeout) {
104 NSAssert(NO, @"Expectation timed out.");
105 break;
106 }
107 [[NSRunLoop currentRunLoop]
108 runUntilDate:[NSDate dateWithTimeIntervalSinceNow:1]];
109 }
110 handler(nil);
111 }
112
113 - (BOOL)areExpectationsFulfilled {
114 for (ARDTestExpectation *expectation in _expectations) {
115 if (!expectation.isFulfilled) {
116 return NO;
117 }
118 }
119 return YES;
120 }
121
122 @end
123
124 @interface ARDAppClientTest : ARDTestCase
125 @end
126
127 @implementation ARDAppClientTest
128
129 #pragma mark - Mock helpers
130
131 - (id)mockRoomServerClientForRoomId:(NSString *)roomId
132 clientId:(NSString *)clientId
133 isInitiator:(BOOL)isInitiator
134 messages:(NSArray *)messages
135 messageHandler:
136 (void (^)(ARDSignalingMessage *))messageHandler {
137 id mockRoomServerClient =
138 [OCMockObject mockForProtocol:@protocol(ARDRoomServerClient)];
139
140 // Successful join response.
141 ARDJoinResponse *joinResponse = [[ARDJoinResponse alloc] init];
142 joinResponse.result = kARDJoinResultTypeSuccess;
143 joinResponse.roomId = roomId;
144 joinResponse.clientId = clientId;
145 joinResponse.isInitiator = isInitiator;
146 joinResponse.messages = messages;
147
148 // Successful message response.
149 ARDMessageResponse *messageResponse = [[ARDMessageResponse alloc] init];
150 messageResponse.result = kARDMessageResultTypeSuccess;
151
152 // Return join response from above on join.
153 [[[mockRoomServerClient stub] andDo:^(NSInvocation *invocation) {
154 __unsafe_unretained void (^completionHandler)(ARDJoinResponse *response,
155 NSError *error);
156 [invocation getArgument:&completionHandler atIndex:3];
157 completionHandler(joinResponse, nil);
158 }] joinRoomWithRoomId:roomId completionHandler:[OCMArg any]];
159
160 // Return message response from above on join.
161 [[[mockRoomServerClient stub] andDo:^(NSInvocation *invocation) {
162 __unsafe_unretained ARDSignalingMessage *message;
163 __unsafe_unretained void (^completionHandler)(ARDMessageResponse *response,
164 NSError *error);
165 [invocation getArgument:&message atIndex:2];
166 [invocation getArgument:&completionHandler atIndex:5];
167 messageHandler(message);
168 completionHandler(messageResponse, nil);
169 }] sendMessage:[OCMArg any]
170 forRoomId:roomId
171 clientId:clientId
172 completionHandler:[OCMArg any]];
173
174 // Do nothing on leave.
175 [[[mockRoomServerClient stub] andDo:^(NSInvocation *invocation) {
176 __unsafe_unretained void (^completionHandler)(NSError *error);
177 [invocation getArgument:&completionHandler atIndex:4];
178 if (completionHandler) {
179 completionHandler(nil);
180 }
181 }] leaveRoomWithRoomId:roomId
182 clientId:clientId
183 completionHandler:[OCMArg any]];
184
185 return mockRoomServerClient;
186 }
187
188 - (id)mockSignalingChannelForRoomId:(NSString *)roomId
189 clientId:(NSString *)clientId
190 messageHandler:
191 (void (^)(ARDSignalingMessage *message))messageHandler {
192 id mockSignalingChannel =
193 [OCMockObject niceMockForProtocol:@protocol(ARDSignalingChannel)];
194 [[mockSignalingChannel stub] registerForRoomId:roomId clientId:clientId];
195 [[[mockSignalingChannel stub] andDo:^(NSInvocation *invocation) {
196 __unsafe_unretained ARDSignalingMessage *message;
197 [invocation getArgument:&message atIndex:2];
198 messageHandler(message);
199 }] sendMessage:[OCMArg any]];
200 return mockSignalingChannel;
201 }
202
203 - (id)mockTURNClient {
204 id mockTURNClient =
205 [OCMockObject mockForProtocol:@protocol(ARDTURNClient)];
206 [[[mockTURNClient stub] andDo:^(NSInvocation *invocation) {
207 // Don't return anything in TURN response.
208 __unsafe_unretained void (^completionHandler)(NSArray *turnServers,
209 NSError *error);
210 [invocation getArgument:&completionHandler atIndex:2];
211 completionHandler([NSArray array], nil);
212 }] requestServersWithCompletionHandler:[OCMArg any]];
213 return mockTURNClient;
214 }
215
216 - (ARDAppClient *)createAppClientForRoomId:(NSString *)roomId
217 clientId:(NSString *)clientId
218 isInitiator:(BOOL)isInitiator
219 messages:(NSArray *)messages
220 messageHandler:
221 (void (^)(ARDSignalingMessage *message))messageHandler
222 connectedHandler:(void (^)(void))connectedHandler {
223 id turnClient = [self mockTURNClient];
224 id signalingChannel = [self mockSignalingChannelForRoomId:roomId
225 clientId:clientId
226 messageHandler:messageHandler];
227 id roomServerClient =
228 [self mockRoomServerClientForRoomId:roomId
229 clientId:clientId
230 isInitiator:isInitiator
231 messages:messages
232 messageHandler:messageHandler];
233 id delegate =
234 [OCMockObject niceMockForProtocol:@protocol(ARDAppClientDelegate)];
235 [[[delegate stub] andDo:^(NSInvocation *invocation) {
236 connectedHandler();
237 }] appClient:[OCMArg any] didChangeConnectionState:RTCICEConnectionConnected];
238
239 return [[ARDAppClient alloc] initWithRoomServerClient:roomServerClient
240 signalingChannel:signalingChannel
241 turnClient:turnClient
242 delegate:delegate];
243 }
244
245 // Tests that an ICE connection is established between two ARDAppClient objects
246 // where one is set up as a caller and the other the answerer. Network
247 // components are mocked out and messages are relayed directly from object to
248 // object. It's expected that both clients reach the RTCICEConnectionConnected
249 // state within a reasonable amount of time.
250 - (void)testSession {
251 // Need block arguments here because we're setting up a callbacks before we
252 // create the clients.
253 ARDAppClient *caller = nil;
254 ARDAppClient *answerer = nil;
255 __block __weak ARDAppClient *weakCaller = nil;
256 __block __weak ARDAppClient *weakAnswerer = nil;
257 NSString *roomId = @"testRoom";
258 NSString *callerId = @"testCallerId";
259 NSString *answererId = @"testAnswererId";
260
261 ARDTestExpectation *callerConnectionExpectation =
262 [self expectationWithDescription:@"Caller PC connected."];
263 ARDTestExpectation *answererConnectionExpectation =
264 [self expectationWithDescription:@"Answerer PC connected."];
265
266 caller = [self createAppClientForRoomId:roomId
267 clientId:callerId
268 isInitiator:YES
269 messages:[NSArray array]
270 messageHandler:^(ARDSignalingMessage *message) {
271 ARDAppClient *strongAnswerer = weakAnswerer;
272 [strongAnswerer channel:strongAnswerer.channel didReceiveMessage:message];
273 } connectedHandler:^{
274 [callerConnectionExpectation fulfill];
275 }];
276 // TODO(tkchin): Figure out why DTLS-SRTP constraint causes thread assertion
277 // crash in Debug.
278 caller.defaultPeerConnectionConstraints = [[RTCMediaConstraints alloc] init];
279 weakCaller = caller;
280
281 answerer = [self createAppClientForRoomId:roomId
282 clientId:answererId
283 isInitiator:NO
284 messages:[NSArray array]
285 messageHandler:^(ARDSignalingMessage *message) {
286 ARDAppClient *strongCaller = weakCaller;
287 [strongCaller channel:strongCaller.channel didReceiveMessage:message];
288 } connectedHandler:^{
289 [answererConnectionExpectation fulfill];
290 }];
291 // TODO(tkchin): Figure out why DTLS-SRTP constraint causes thread assertion
292 // crash in Debug.
293 answerer.defaultPeerConnectionConstraints =
294 [[RTCMediaConstraints alloc] init];
295 weakAnswerer = answerer;
296
297 // Kick off connection.
298 [caller connectToRoomWithId:roomId options:nil];
299 [answerer connectToRoomWithId:roomId options:nil];
300 [self waitForExpectationsWithTimeout:20 handler:^(NSError *error) {
301 if (error) {
302 NSLog(@"Expectations error: %@", error);
303 }
304 }];
305 }
306
307 @end
308
309 @interface ARDSDPUtilsTest : ARDTestCase
310 - (void)testPreferVideoCodec;
311 @end
312
313 @implementation ARDSDPUtilsTest
314
315 - (void)testPreferVideoCodec {
316 NSString *sdp = @("m=video 9 RTP/SAVPF 100 116 117 96 120\n"
317 "a=rtpmap:120 H264/90000\n");
318 NSString *expectedSdp = @("m=video 9 RTP/SAVPF 120 100 116 117 96\n"
319 "a=rtpmap:120 H264/90000\n");
320 RTCSessionDescription* desc =
321 [[RTCSessionDescription alloc] initWithType:@"offer" sdp:sdp];
322 RTCSessionDescription *h264Desc =
323 [ARDSDPUtils descriptionForDescription:desc
324 preferredVideoCodec:@"H264"];
325 EXPECT_TRUE([h264Desc.description isEqualToString:expectedSdp]);
326 }
327
328 @end
329
330 class SignalingTest : public ::testing::Test {
331 protected:
332 static void SetUpTestCase() {
333 rtc::InitializeSSL();
334 }
335 static void TearDownTestCase() {
336 rtc::CleanupSSL();
337 }
338 };
339
340 TEST_F(SignalingTest, SessionTest) {
341 @autoreleasepool {
342 ARDAppClientTest *test = [[ARDAppClientTest alloc] init];
343 [test testSession];
344 }
345 }
346
347 TEST_F(SignalingTest, SDPTest) {
348 @autoreleasepool {
349 ARDSDPUtilsTest *test = [[ARDSDPUtilsTest alloc] init];
350 [test testPreferVideoCodec];
351 }
352 }
353
354
OLDNEW
« no previous file with comments | « talk/examples/objc/AppRTCDemo/mac/main.m ('k') | talk/examples/objc/AppRTCDemo/third_party/SocketRocket/LICENSE » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698