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

Unified Diff: webrtc/examples/objc/AppRTCDemo/tests/ARDAppClientTest.mm

Issue 2358133003: Revert of Rename AppRTCDemo on Android and iOS to AppRTCMobile (Closed)
Patch Set: Created 4 years, 3 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 side-by-side diff with in-line comments
Download patch
Index: webrtc/examples/objc/AppRTCDemo/tests/ARDAppClientTest.mm
diff --git a/webrtc/examples/objc/AppRTCDemo/tests/ARDAppClientTest.mm b/webrtc/examples/objc/AppRTCDemo/tests/ARDAppClientTest.mm
new file mode 100644
index 0000000000000000000000000000000000000000..c1fc08ca8e94e5b5ae7a6500711e45658165cdae
--- /dev/null
+++ b/webrtc/examples/objc/AppRTCDemo/tests/ARDAppClientTest.mm
@@ -0,0 +1,350 @@
+/*
+ * Copyright 2014 The WebRTC Project Authors. All rights reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#import <Foundation/Foundation.h>
+#import <OCMock/OCMock.h>
+
+#include "webrtc/base/gunit.h"
+#include "webrtc/base/ssladapter.h"
+
+#import "WebRTC/RTCMediaConstraints.h"
+#import "WebRTC/RTCPeerConnectionFactory.h"
+#import "WebRTC/RTCSessionDescription.h"
+
+#import "ARDAppClient+Internal.h"
+#import "ARDJoinResponse+Internal.h"
+#import "ARDMessageResponse+Internal.h"
+#import "ARDSDPUtils.h"
+
+// These classes mimic XCTest APIs, to make eventual conversion to XCTest
+// easier. Conversion will happen once XCTest is supported well on build bots.
+@interface ARDTestExpectation : NSObject
+
+@property(nonatomic, readonly) NSString *description;
+@property(nonatomic, readonly) BOOL isFulfilled;
+
+- (instancetype)initWithDescription:(NSString *)description;
+- (void)fulfill;
+
+@end
+
+@implementation ARDTestExpectation
+
+@synthesize description = _description;
+@synthesize isFulfilled = _isFulfilled;
+
+- (instancetype)initWithDescription:(NSString *)description {
+ if (self = [super init]) {
+ _description = description;
+ }
+ return self;
+}
+
+- (void)fulfill {
+ _isFulfilled = YES;
+}
+
+@end
+
+@interface ARDTestCase : NSObject
+
+- (ARDTestExpectation *)expectationWithDescription:(NSString *)description;
+- (void)waitForExpectationsWithTimeout:(NSTimeInterval)timeout
+ handler:(void (^)(NSError *error))handler;
+
+@end
+
+@implementation ARDTestCase {
+ NSMutableArray *_expectations;
+}
+
+- (instancetype)init {
+ if (self = [super init]) {
+ _expectations = [NSMutableArray array];
+ }
+ return self;
+}
+
+- (ARDTestExpectation *)expectationWithDescription:(NSString *)description {
+ ARDTestExpectation *expectation =
+ [[ARDTestExpectation alloc] initWithDescription:description];
+ [_expectations addObject:expectation];
+ return expectation;
+}
+
+- (void)waitForExpectationsWithTimeout:(NSTimeInterval)timeout
+ handler:(void (^)(NSError *error))handler {
+ NSDate *startDate = [NSDate date];
+ while (![self areExpectationsFulfilled]) {
+ NSTimeInterval duration = [[NSDate date] timeIntervalSinceDate:startDate];
+ if (duration > timeout) {
+ NSAssert(NO, @"Expectation timed out.");
+ break;
+ }
+ [[NSRunLoop currentRunLoop]
+ runUntilDate:[NSDate dateWithTimeIntervalSinceNow:1]];
+ }
+ handler(nil);
+}
+
+- (BOOL)areExpectationsFulfilled {
+ for (ARDTestExpectation *expectation in _expectations) {
+ if (!expectation.isFulfilled) {
+ return NO;
+ }
+ }
+ return YES;
+}
+
+@end
+
+@interface ARDAppClientTest : ARDTestCase
+@end
+
+@implementation ARDAppClientTest
+
+#pragma mark - Mock helpers
+
+- (id)mockRoomServerClientForRoomId:(NSString *)roomId
+ clientId:(NSString *)clientId
+ isInitiator:(BOOL)isInitiator
+ messages:(NSArray *)messages
+ messageHandler:
+ (void (^)(ARDSignalingMessage *))messageHandler {
+ id mockRoomServerClient =
+ [OCMockObject mockForProtocol:@protocol(ARDRoomServerClient)];
+
+ // Successful join response.
+ ARDJoinResponse *joinResponse = [[ARDJoinResponse alloc] init];
+ joinResponse.result = kARDJoinResultTypeSuccess;
+ joinResponse.roomId = roomId;
+ joinResponse.clientId = clientId;
+ joinResponse.isInitiator = isInitiator;
+ joinResponse.messages = messages;
+
+ // Successful message response.
+ ARDMessageResponse *messageResponse = [[ARDMessageResponse alloc] init];
+ messageResponse.result = kARDMessageResultTypeSuccess;
+
+ // Return join response from above on join.
+ [[[mockRoomServerClient stub] andDo:^(NSInvocation *invocation) {
+ __unsafe_unretained void (^completionHandler)(ARDJoinResponse *response,
+ NSError *error);
+ [invocation getArgument:&completionHandler atIndex:3];
+ completionHandler(joinResponse, nil);
+ }] joinRoomWithRoomId:roomId isLoopback:NO completionHandler:[OCMArg any]];
+
+ // Return message response from above on join.
+ [[[mockRoomServerClient stub] andDo:^(NSInvocation *invocation) {
+ __unsafe_unretained ARDSignalingMessage *message;
+ __unsafe_unretained void (^completionHandler)(ARDMessageResponse *response,
+ NSError *error);
+ [invocation getArgument:&message atIndex:2];
+ [invocation getArgument:&completionHandler atIndex:5];
+ messageHandler(message);
+ completionHandler(messageResponse, nil);
+ }] sendMessage:[OCMArg any]
+ forRoomId:roomId
+ clientId:clientId
+ completionHandler:[OCMArg any]];
+
+ // Do nothing on leave.
+ [[[mockRoomServerClient stub] andDo:^(NSInvocation *invocation) {
+ __unsafe_unretained void (^completionHandler)(NSError *error);
+ [invocation getArgument:&completionHandler atIndex:4];
+ if (completionHandler) {
+ completionHandler(nil);
+ }
+ }] leaveRoomWithRoomId:roomId
+ clientId:clientId
+ completionHandler:[OCMArg any]];
+
+ return mockRoomServerClient;
+}
+
+- (id)mockSignalingChannelForRoomId:(NSString *)roomId
+ clientId:(NSString *)clientId
+ messageHandler:
+ (void (^)(ARDSignalingMessage *message))messageHandler {
+ id mockSignalingChannel =
+ [OCMockObject niceMockForProtocol:@protocol(ARDSignalingChannel)];
+ [[mockSignalingChannel stub] registerForRoomId:roomId clientId:clientId];
+ [[[mockSignalingChannel stub] andDo:^(NSInvocation *invocation) {
+ __unsafe_unretained ARDSignalingMessage *message;
+ [invocation getArgument:&message atIndex:2];
+ messageHandler(message);
+ }] sendMessage:[OCMArg any]];
+ return mockSignalingChannel;
+}
+
+- (id)mockTURNClient {
+ id mockTURNClient =
+ [OCMockObject mockForProtocol:@protocol(ARDTURNClient)];
+ [[[mockTURNClient stub] andDo:^(NSInvocation *invocation) {
+ // Don't return anything in TURN response.
+ __unsafe_unretained void (^completionHandler)(NSArray *turnServers,
+ NSError *error);
+ [invocation getArgument:&completionHandler atIndex:2];
+ completionHandler([NSArray array], nil);
+ }] requestServersWithCompletionHandler:[OCMArg any]];
+ return mockTURNClient;
+}
+
+- (ARDAppClient *)createAppClientForRoomId:(NSString *)roomId
+ clientId:(NSString *)clientId
+ isInitiator:(BOOL)isInitiator
+ messages:(NSArray *)messages
+ messageHandler:
+ (void (^)(ARDSignalingMessage *message))messageHandler
+ connectedHandler:(void (^)(void))connectedHandler {
+ id turnClient = [self mockTURNClient];
+ id signalingChannel = [self mockSignalingChannelForRoomId:roomId
+ clientId:clientId
+ messageHandler:messageHandler];
+ id roomServerClient =
+ [self mockRoomServerClientForRoomId:roomId
+ clientId:clientId
+ isInitiator:isInitiator
+ messages:messages
+ messageHandler:messageHandler];
+ id delegate =
+ [OCMockObject niceMockForProtocol:@protocol(ARDAppClientDelegate)];
+ [[[delegate stub] andDo:^(NSInvocation *invocation) {
+ connectedHandler();
+ }] appClient:[OCMArg any]
+ didChangeConnectionState:RTCIceConnectionStateConnected];
+
+ return [[ARDAppClient alloc] initWithRoomServerClient:roomServerClient
+ signalingChannel:signalingChannel
+ turnClient:turnClient
+ delegate:delegate];
+}
+
+// Tests that an ICE connection is established between two ARDAppClient objects
+// where one is set up as a caller and the other the answerer. Network
+// components are mocked out and messages are relayed directly from object to
+// object. It's expected that both clients reach the
+// RTCIceConnectionStateConnected state within a reasonable amount of time.
+- (void)testSession {
+ // Need block arguments here because we're setting up a callbacks before we
+ // create the clients.
+ ARDAppClient *caller = nil;
+ ARDAppClient *answerer = nil;
+ __block __weak ARDAppClient *weakCaller = nil;
+ __block __weak ARDAppClient *weakAnswerer = nil;
+ NSString *roomId = @"testRoom";
+ NSString *callerId = @"testCallerId";
+ NSString *answererId = @"testAnswererId";
+
+ ARDTestExpectation *callerConnectionExpectation =
+ [self expectationWithDescription:@"Caller PC connected."];
+ ARDTestExpectation *answererConnectionExpectation =
+ [self expectationWithDescription:@"Answerer PC connected."];
+
+ caller = [self createAppClientForRoomId:roomId
+ clientId:callerId
+ isInitiator:YES
+ messages:[NSArray array]
+ messageHandler:^(ARDSignalingMessage *message) {
+ ARDAppClient *strongAnswerer = weakAnswerer;
+ [strongAnswerer channel:strongAnswerer.channel didReceiveMessage:message];
+ } connectedHandler:^{
+ [callerConnectionExpectation fulfill];
+ }];
+ // TODO(tkchin): Figure out why DTLS-SRTP constraint causes thread assertion
+ // crash in Debug.
+ caller.defaultPeerConnectionConstraints =
+ [[RTCMediaConstraints alloc] initWithMandatoryConstraints:nil
+ optionalConstraints:nil];
+ weakCaller = caller;
+
+ answerer = [self createAppClientForRoomId:roomId
+ clientId:answererId
+ isInitiator:NO
+ messages:[NSArray array]
+ messageHandler:^(ARDSignalingMessage *message) {
+ ARDAppClient *strongCaller = weakCaller;
+ [strongCaller channel:strongCaller.channel didReceiveMessage:message];
+ } connectedHandler:^{
+ [answererConnectionExpectation fulfill];
+ }];
+ // TODO(tkchin): Figure out why DTLS-SRTP constraint causes thread assertion
+ // crash in Debug.
+ answerer.defaultPeerConnectionConstraints =
+ [[RTCMediaConstraints alloc] initWithMandatoryConstraints:nil
+ optionalConstraints:nil];
+ weakAnswerer = answerer;
+
+ // Kick off connection.
+ [caller connectToRoomWithId:roomId
+ isLoopback:NO
+ isAudioOnly:NO
+ shouldMakeAecDump:NO
+ shouldUseLevelControl:NO];
+ [answerer connectToRoomWithId:roomId
+ isLoopback:NO
+ isAudioOnly:NO
+ shouldMakeAecDump:NO
+ shouldUseLevelControl:NO];
+ [self waitForExpectationsWithTimeout:20 handler:^(NSError *error) {
+ if (error) {
+ NSLog(@"Expectations error: %@", error);
+ }
+ }];
+}
+
+@end
+
+@interface ARDSDPUtilsTest : ARDTestCase
+- (void)testPreferVideoCodec;
+@end
+
+@implementation ARDSDPUtilsTest
+
+- (void)testPreferVideoCodec {
+ NSString *sdp = @("m=video 9 RTP/SAVPF 100 116 117 96 120\n"
+ "a=rtpmap:120 H264/90000\n");
+ NSString *expectedSdp = @("m=video 9 RTP/SAVPF 120 100 116 117 96\n"
+ "a=rtpmap:120 H264/90000\n");
+ RTCSessionDescription* desc =
+ [[RTCSessionDescription alloc] initWithType:RTCSdpTypeOffer sdp:sdp];
+ RTCSessionDescription *h264Desc =
+ [ARDSDPUtils descriptionForDescription:desc
+ preferredVideoCodec:@"H264"];
+ EXPECT_TRUE([h264Desc.description isEqualToString:expectedSdp]);
+}
+
+@end
+
+class SignalingTest : public ::testing::Test {
+ protected:
+ static void SetUpTestCase() {
+ rtc::InitializeSSL();
+ }
+ static void TearDownTestCase() {
+ rtc::CleanupSSL();
+ }
+};
+
+TEST_F(SignalingTest, SessionTest) {
+ @autoreleasepool {
+ ARDAppClientTest *test = [[ARDAppClientTest alloc] init];
+ [test testSession];
+ }
+}
+
+TEST_F(SignalingTest, SDPTest) {
+ @autoreleasepool {
+ ARDSDPUtilsTest *test = [[ARDSDPUtilsTest alloc] init];
+ [test testPreferVideoCodec];
+ }
+}
+
+
« 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