blob: ef595c7d9c74483353f4bd8015807dbb094ee837 [file] [log] [blame]
Artem Titov40a7a352018-10-15 15:25:34 +02001/*
2 * Copyright (c) 2018 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#include "test/test_main_lib.h"
12
13#include <fstream>
14#include <string>
15
Mirko Bonadeibc6a06c2018-10-19 08:43:53 +020016#include "absl/memory/memory.h"
Yves Gerey3e707812018-11-28 16:47:49 +010017#include "rtc_base/checks.h"
Artem Titov40a7a352018-10-15 15:25:34 +020018#include "rtc_base/flags.h"
19#include "rtc_base/logging.h"
20#include "rtc_base/thread.h"
21#include "system_wrappers/include/field_trial.h"
22#include "system_wrappers/include/metrics.h"
23#include "test/field_trial.h"
24#include "test/gmock.h"
25#include "test/gtest.h"
26#include "test/testsupport/fileutils.h"
27#include "test/testsupport/perf_test.h"
28
29#if defined(WEBRTC_WIN)
30#include "rtc_base/win32socketinit.h"
31#endif
32
33#if defined(WEBRTC_IOS)
34#include "test/ios/test_support.h"
35
Mirko Bonadei2dfa9982018-10-18 11:35:32 +020036WEBRTC_DEFINE_string(NSTreatUnknownArgumentsAsOpen,
37 "",
38 "Intentionally ignored flag intended for iOS simulator.");
39WEBRTC_DEFINE_string(ApplePersistenceIgnoreState,
40 "",
41 "Intentionally ignored flag intended for iOS simulator.");
42WEBRTC_DEFINE_bool(
Artem Titov40a7a352018-10-15 15:25:34 +020043 save_chartjson_result,
44 false,
45 "Store the perf results in Documents/perf_result.json in the format "
46 "described by "
47 "https://github.com/catapult-project/catapult/blob/master/dashboard/docs/"
48 "data-format.md.");
49
50#else
51
Mirko Bonadei2dfa9982018-10-18 11:35:32 +020052WEBRTC_DEFINE_string(
Artem Titov40a7a352018-10-15 15:25:34 +020053 isolated_script_test_output,
54 "",
55 "Path to output an empty JSON file which Chromium infra requires.");
56
Mirko Bonadei2dfa9982018-10-18 11:35:32 +020057WEBRTC_DEFINE_string(
Artem Titov40a7a352018-10-15 15:25:34 +020058 isolated_script_test_perf_output,
59 "",
60 "Path where the perf results should be stored in the JSON format described "
61 "by "
62 "https://github.com/catapult-project/catapult/blob/master/dashboard/docs/"
63 "data-format.md.");
64
65#endif
66
Mirko Bonadei2dfa9982018-10-18 11:35:32 +020067WEBRTC_DEFINE_bool(logs, false, "print logs to stderr");
Niels Möllerd0def192018-12-21 11:28:45 +010068WEBRTC_DEFINE_bool(verbose, false, "verbose logs to stderr");
Artem Titov40a7a352018-10-15 15:25:34 +020069
Mirko Bonadei2dfa9982018-10-18 11:35:32 +020070WEBRTC_DEFINE_string(
Artem Titov40a7a352018-10-15 15:25:34 +020071 force_fieldtrials,
72 "",
73 "Field trials control experimental feature code which can be forced. "
74 "E.g. running with --force_fieldtrials=WebRTC-FooFeature/Enable/"
75 " will assign the group Enable to field trial WebRTC-FooFeature.");
76
Mirko Bonadei2dfa9982018-10-18 11:35:32 +020077WEBRTC_DEFINE_bool(help, false, "Print this message.");
Artem Titov40a7a352018-10-15 15:25:34 +020078
79namespace webrtc {
80
81namespace {
82
83class TestMainImpl : public TestMain {
84 public:
Artem Titovb5541a02018-10-17 17:37:47 +020085 int Init(int* argc, char* argv[]) override {
86 ::testing::InitGoogleMock(argc, argv);
Artem Titov40a7a352018-10-15 15:25:34 +020087
88 // Default to LS_INFO, even for release builds to provide better test
89 // logging.
Artem Titov40a7a352018-10-15 15:25:34 +020090 if (rtc::LogMessage::GetLogToDebug() > rtc::LS_INFO)
91 rtc::LogMessage::LogToDebug(rtc::LS_INFO);
92
Artem Titovb5541a02018-10-17 17:37:47 +020093 if (rtc::FlagList::SetFlagsFromCommandLine(argc, argv, false)) {
Artem Titov40a7a352018-10-15 15:25:34 +020094 return 1;
95 }
96 if (FLAG_help) {
97 rtc::FlagList::Print(nullptr, false);
98 return 0;
99 }
100
Niels Möllerd0def192018-12-21 11:28:45 +0100101 if (FLAG_verbose)
102 rtc::LogMessage::LogToDebug(rtc::LS_VERBOSE);
103
104 rtc::LogMessage::SetLogToStderr(FLAG_logs || FLAG_verbose);
105
Artem Titov40a7a352018-10-15 15:25:34 +0200106 // TODO(bugs.webrtc.org/9792): we need to reference something from
107 // fileutils.h so that our downstream hack where we replace fileutils.cc
108 // works. Otherwise the downstream flag implementation will take over and
109 // botch the flag introduced by the hack. Remove this awful thing once the
110 // downstream implementation has been eliminated.
111 (void)webrtc::test::JoinFilename("horrible", "hack");
112
113 webrtc::test::ValidateFieldTrialsStringOrDie(FLAG_force_fieldtrials);
114 // InitFieldTrialsFromString stores the char*, so the char array must
115 // outlive the application.
116 webrtc::field_trial::InitFieldTrialsFromString(FLAG_force_fieldtrials);
117 webrtc::metrics::Enable();
118
119#if defined(WEBRTC_WIN)
120 winsock_init_ = absl::make_unique<rtc::WinsockInitializer>();
121#endif
122
Artem Titov40a7a352018-10-15 15:25:34 +0200123 // Ensure that main thread gets wrapped as an rtc::Thread.
124 // TODO(bugs.webrt.org/9714): It might be better to avoid wrapping the main
125 // thread, or leave it to individual tests that need it. But as long as we
126 // have automatic thread wrapping, we need this to avoid that some other
127 // random thread (which one depending on which tests are run) gets
128 // automatically wrapped.
129 rtc::ThreadManager::Instance()->WrapCurrentThread();
130 RTC_CHECK(rtc::Thread::Current());
131 return 0;
132 }
133
134 int Run(int argc, char* argv[]) override {
135#if defined(WEBRTC_IOS)
136 rtc::test::InitTestSuite(RUN_ALL_TESTS, argc, argv,
137 FLAG_save_chartjson_result);
138 rtc::test::RunTestsFromIOSApp();
139 return 0;
140#else
141 int exit_code = RUN_ALL_TESTS();
142
143 std::string chartjson_result_file = FLAG_isolated_script_test_perf_output;
144 if (!chartjson_result_file.empty()) {
145 webrtc::test::WritePerfResults(chartjson_result_file);
146 }
147
148 std::string result_filename = FLAG_isolated_script_test_output;
149 if (!result_filename.empty()) {
150 std::ofstream result_file(result_filename);
151 result_file << "{\"version\": 3}";
152 result_file.close();
153 }
154
Yves Gerey53347b72018-10-19 15:04:04 +0200155#if defined(ADDRESS_SANITIZER) || defined(LEAK_SANITIZER) || \
156 defined(MEMORY_SANITIZER) || defined(THREAD_SANITIZER) || \
157 defined(UNDEFINED_SANITIZER)
158 // We want the test flagged as failed only for sanitizer defects,
159 // in which case the sanitizer will override exit code with 66.
160 return 0;
161#endif
162
Artem Titov40a7a352018-10-15 15:25:34 +0200163 return exit_code;
164#endif
165 }
166
167 ~TestMainImpl() override = default;
168
169 private:
170#if defined(WEBRTC_WIN)
171 std::unique_ptr<rtc::WinsockInitializer> winsock_init_;
172#endif
173};
174
175} // namespace
176
177std::unique_ptr<TestMain> TestMain::Create() {
178 return absl::make_unique<TestMainImpl>();
179}
180
181} // namespace webrtc