Create a UIApplication when running tests on iOS.
Fix issue where running tests on iOS would get killed after a certain time had passed. This seems to be due to springboard killing apps that don't have a GUI running. Creating a UIApplication to wrap the test suite seems to solve this problem in chromium. This CL adds a class for this purpose. Most of the code was copied from chromium with bits taken out. Bug: webrtc:7161, webrtc:7758 Change-Id: I10f9bc8914e73f2870a9b0a2703cde496af8db2f Reviewed-on: https://chromium-review.googlesource.com/528173 Reviewed-by: Henrik Andreasson <henrika@webrtc.org> Reviewed-by: Magnus Jedvert <magjed@webrtc.org> Reviewed-by: Henrik Kjellander <kjellander@webrtc.org> Commit-Queue: Kári Tristan Helgason <kthelgason@webrtc.org> Cr-Commit-Position: refs/heads/master@{#18509}
This commit is contained in:
committed by
Commit Bot
parent
fae6d09c3b
commit
e2baffb055
@ -43,8 +43,6 @@ config("rtc_base_all_dependent_config") {
|
||||
if (is_ios) {
|
||||
libs = [
|
||||
"CFNetwork.framework",
|
||||
|
||||
#"Foundation.framework", # Already in //build/config:default_libs.
|
||||
"Security.framework",
|
||||
"SystemConfiguration.framework",
|
||||
"UIKit.framework",
|
||||
@ -731,6 +729,7 @@ if (rtc_include_tests) {
|
||||
"../test:field_trial",
|
||||
"../test:test_support",
|
||||
]
|
||||
|
||||
public_deps = [
|
||||
"//testing/gmock",
|
||||
"//testing/gtest",
|
||||
|
||||
@ -23,6 +23,10 @@
|
||||
#include "webrtc/test/field_trial.h"
|
||||
#include "webrtc/test/testsupport/fileutils.h"
|
||||
|
||||
#if defined(WEBRTC_IOS)
|
||||
#include "webrtc/test/ios/test_support.h"
|
||||
#endif
|
||||
|
||||
DEFINE_bool(help, false, "prints this message");
|
||||
DEFINE_string(log, "", "logging options to use");
|
||||
DEFINE_string(
|
||||
@ -106,7 +110,11 @@ int main(int argc, char** argv) {
|
||||
rtc::InitializeSSL();
|
||||
rtc::SSLStreamAdapter::enable_time_callback_for_testing();
|
||||
|
||||
int res = RUN_ALL_TESTS();
|
||||
#if defined(WEBRTC_IOS)
|
||||
rtc::test::InitTestSuite(RUN_ALL_TESTS, argc, argv);
|
||||
rtc::test::RunTestsFromIOSApp();
|
||||
#endif
|
||||
const int res = RUN_ALL_TESTS();
|
||||
|
||||
rtc::CleanupSSL();
|
||||
|
||||
|
||||
@ -122,6 +122,13 @@ rtc_source_set("test_support") {
|
||||
"testsupport/unittest_utils.h",
|
||||
]
|
||||
|
||||
if (is_ios) {
|
||||
sources += [
|
||||
"ios/test_support.h",
|
||||
"ios/test_support.mm",
|
||||
]
|
||||
}
|
||||
|
||||
deps = [
|
||||
"..:webrtc_common",
|
||||
"../base:gtest_prod",
|
||||
|
||||
25
webrtc/test/ios/test_support.h
Normal file
25
webrtc/test/ios/test_support.h
Normal file
@ -0,0 +1,25 @@
|
||||
/*
|
||||
* Copyright 2017 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.
|
||||
*/
|
||||
|
||||
#ifndef WEBRTC_TEST_IOS_TEST_SUPPORT_H_
|
||||
#define WEBRTC_TEST_IOS_TEST_SUPPORT_H_
|
||||
|
||||
namespace rtc {
|
||||
namespace test {
|
||||
// Launches an iOS app that serves as a host for a test suite.
|
||||
// This is necessary as iOS doesn't like processes without a gui
|
||||
// running for longer than a few seconds.
|
||||
void RunTestsFromIOSApp();
|
||||
void InitTestSuite(int (*test_suite)(void), int argc, char* argv[]);
|
||||
|
||||
} // namespace test
|
||||
} // namespace rtc
|
||||
|
||||
#endif // WEBRTC_TEST_IOS_TEST_SUPPORT_H_
|
||||
101
webrtc/test/ios/test_support.mm
Normal file
101
webrtc/test/ios/test_support.mm
Normal file
@ -0,0 +1,101 @@
|
||||
/*
|
||||
* Copyright 2017 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 <UIKit/UIKit.h>
|
||||
|
||||
#include "webrtc/test/ios/test_support.h"
|
||||
|
||||
// Springboard will kill any iOS app that fails to check in after launch within
|
||||
// a given time. Starting a UIApplication before invoking TestSuite::Run
|
||||
// prevents this from happening.
|
||||
|
||||
// InitIOSRunHook saves the TestSuite and argc/argv, then invoking
|
||||
// RunTestsFromIOSApp calls UIApplicationMain(), providing an application
|
||||
// delegate class: WebRtcUnitTestDelegate. The delegate implements
|
||||
// application:didFinishLaunchingWithOptions: to invoke the TestSuite's Run
|
||||
// method.
|
||||
|
||||
// Since the executable isn't likely to be a real iOS UI, the delegate puts up a
|
||||
// window displaying the app name. If a bunch of apps using MainHook are being
|
||||
// run in a row, this provides an indication of which one is currently running.
|
||||
|
||||
static int (*g_test_suite)(void) = NULL;
|
||||
static int g_argc;
|
||||
static char **g_argv;
|
||||
|
||||
@interface UIApplication (Testing)
|
||||
- (void)_terminateWithStatus:(int)status;
|
||||
@end
|
||||
|
||||
@interface WebRtcUnitTestDelegate : NSObject {
|
||||
UIWindow *_window;
|
||||
}
|
||||
- (void)runTests;
|
||||
@end
|
||||
|
||||
@implementation WebRtcUnitTestDelegate
|
||||
|
||||
- (BOOL)application:(UIApplication *)application
|
||||
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
|
||||
CGRect bounds = [[UIScreen mainScreen] bounds];
|
||||
|
||||
_window = [[UIWindow alloc] initWithFrame:bounds];
|
||||
[_window setBackgroundColor:[UIColor whiteColor]];
|
||||
[_window makeKeyAndVisible];
|
||||
|
||||
// Add a label with the app name.
|
||||
UILabel *label = [[UILabel alloc] initWithFrame:bounds];
|
||||
label.text = [[NSProcessInfo processInfo] processName];
|
||||
label.textAlignment = NSTextAlignmentCenter;
|
||||
[_window addSubview:label];
|
||||
|
||||
// An NSInternalInconsistencyException is thrown if the app doesn't have a
|
||||
// root view controller. Set an empty one here.
|
||||
[_window setRootViewController:[[UIViewController alloc] init]];
|
||||
|
||||
// Queue up the test run.
|
||||
[self performSelector:@selector(runTests) withObject:nil afterDelay:0.1];
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (void)runTests {
|
||||
int exitStatus = g_test_suite();
|
||||
|
||||
// If a test app is too fast, it will exit before Instruments has has a
|
||||
// a chance to initialize and no test results will be seen.
|
||||
// TODO(crbug.com/137010): Figure out how much time is actually needed, and
|
||||
// sleep only to make sure that much time has elapsed since launch.
|
||||
[NSThread sleepUntilDate:[NSDate dateWithTimeIntervalSinceNow:2.0]];
|
||||
|
||||
// Use the hidden selector to try and cleanly take down the app (otherwise
|
||||
// things can think the app crashed even on a zero exit status).
|
||||
UIApplication *application = [UIApplication sharedApplication];
|
||||
[application _terminateWithStatus:exitStatus];
|
||||
|
||||
exit(exitStatus);
|
||||
}
|
||||
|
||||
@end
|
||||
namespace rtc {
|
||||
namespace test {
|
||||
|
||||
void InitTestSuite(int (*test_suite)(void), int argc, char *argv[]) {
|
||||
g_test_suite = test_suite;
|
||||
g_argc = argc;
|
||||
g_argv = argv;
|
||||
}
|
||||
|
||||
void RunTestsFromIOSApp() {
|
||||
@autoreleasepool {
|
||||
exit(UIApplicationMain(g_argc, g_argv, nil, @"WebRtcUnitTestDelegate"));
|
||||
}
|
||||
}
|
||||
} // namespace test
|
||||
} // namespace rtc
|
||||
@ -17,6 +17,10 @@
|
||||
#include "webrtc/test/testsupport/fileutils.h"
|
||||
#include "webrtc/test/testsupport/trace_to_stderr.h"
|
||||
|
||||
#if defined(WEBRTC_IOS)
|
||||
#include "webrtc/test/ios/test_support.h"
|
||||
#endif
|
||||
|
||||
DEFINE_bool(logs, false, "print logs to stderr");
|
||||
|
||||
DEFINE_string(force_fieldtrials, "",
|
||||
@ -45,6 +49,10 @@ int main(int argc, char* argv[]) {
|
||||
std::unique_ptr<webrtc::test::TraceToStderr> trace_to_stderr;
|
||||
if (FLAGS_logs)
|
||||
trace_to_stderr.reset(new webrtc::test::TraceToStderr);
|
||||
#if defined(WEBRTC_IOS)
|
||||
rtc::test::InitTestSuite(RUN_ALL_TESTS, argc, argv);
|
||||
rtc::test::RunTestsFromIOSApp();
|
||||
#endif
|
||||
|
||||
return RUN_ALL_TESTS();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user