From 40a7a35eaa90009d47b20066f62d312b42fbdf48 Mon Sep 17 00:00:00 2001 From: Artem Titov Date: Mon, 15 Oct 2018 15:25:34 +0200 Subject: [PATCH] Extract functionality of test_main into separate library. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Extract functionality of test_main into separate library to be able to reuse it if another main will be required. Bug: webrtc:5996 Change-Id: I2925b4240bd0e4fb884b43bb16667ca2d6216bbd Reviewed-on: https://webrtc-review.googlesource.com/c/105921 Reviewed-by: Patrik Höglund Reviewed-by: Mirko Bonadei Commit-Queue: Artem Titov Cr-Commit-Position: refs/heads/master@{#25172} --- audio/BUILD.gn | 1 + call/BUILD.gn | 7 +- common_audio/BUILD.gn | 1 + common_video/BUILD.gn | 1 + modules/BUILD.gn | 1 + modules/audio_coding/BUILD.gn | 3 + modules/remote_bitrate_estimator/BUILD.gn | 1 + modules/rtp_rtcp/BUILD.gn | 1 + modules/video_capture/BUILD.gn | 1 + rtc_tools/BUILD.gn | 1 + system_wrappers/BUILD.gn | 1 + test/BUILD.gn | 21 ++- test/test_main.cc | 134 +---------------- test/test_main_lib.cc | 168 ++++++++++++++++++++++ test/test_main_lib.h | 38 +++++ 15 files changed, 245 insertions(+), 135 deletions(-) create mode 100644 test/test_main_lib.cc create mode 100644 test/test_main_lib.h diff --git a/audio/BUILD.gn b/audio/BUILD.gn index 91cece93cb..3046d619f7 100644 --- a/audio/BUILD.gn +++ b/audio/BUILD.gn @@ -265,6 +265,7 @@ if (rtc_include_tests) { "../test:single_threaded_task_queue", "../test:test_common", "../test:test_main", + "//test:test_support", "//testing/gtest", "//third_party/abseil-cpp/absl/memory", ] diff --git a/call/BUILD.gn b/call/BUILD.gn index b06dbbe696..8e026d5bf7 100644 --- a/call/BUILD.gn +++ b/call/BUILD.gn @@ -454,6 +454,9 @@ if (rtc_include_tests) { } rtc_test("fake_network_unittests") { + sources = [ + "test/fake_network_pipe_unittest.cc", + ] deps = [ ":call_interfaces", ":fake_network", @@ -463,10 +466,8 @@ if (rtc_include_tests) { "../system_wrappers", "../test:test_common", "../test:test_main", + "//test:test_support", "//testing/gtest", ] - sources = [ - "test/fake_network_pipe_unittest.cc", - ] } } diff --git a/common_audio/BUILD.gn b/common_audio/BUILD.gn index abcfe9ad16..51cb1b0d56 100644 --- a/common_audio/BUILD.gn +++ b/common_audio/BUILD.gn @@ -389,6 +389,7 @@ if (rtc_include_tests) { "../system_wrappers:cpu_features_api", "../test:fileutils", "../test:test_main", + "//test:test_support", "//testing/gtest", ] diff --git a/common_video/BUILD.gn b/common_video/BUILD.gn index 31d0c072ac..64892a2af9 100644 --- a/common_video/BUILD.gn +++ b/common_video/BUILD.gn @@ -97,6 +97,7 @@ if (rtc_include_tests) { "../test:fileutils", "../test:test_main", "../test:video_test_common", + "//test:test_support", "//testing/gtest", "//third_party/libyuv", ] diff --git a/modules/BUILD.gn b/modules/BUILD.gn index 8127244462..1df9865d45 100644 --- a/modules/BUILD.gn +++ b/modules/BUILD.gn @@ -236,6 +236,7 @@ if (rtc_include_tests) { deps = [ ":module_api", "../test:test_main", + "../test:test_support", "audio_coding:audio_coding_unittests", "audio_device:audio_device_unittests", "audio_mixer:audio_mixer_unittests", diff --git a/modules/audio_coding/BUILD.gn b/modules/audio_coding/BUILD.gn index 44f9a8b19b..9bad88c8fd 100644 --- a/modules/audio_coding/BUILD.gn +++ b/modules/audio_coding/BUILD.gn @@ -1479,6 +1479,7 @@ if (rtc_include_tests) { "../../rtc_base/system:arch", "../../test:test_main", "//testing/gtest", + "//test:test_support", ] + audio_coding_deps data = audio_decoder_unittests_resources @@ -1597,6 +1598,7 @@ if (rtc_include_tests) { "../../rtc_base:rtc_base_approved", "../../test:test_main", "../audio_processing", + "//test:test_support", "//testing/gtest", ] } @@ -1957,6 +1959,7 @@ if (rtc_include_tests) { "../../rtc_base:rtc_base_approved", "../../test:fileutils", "../../test:test_main", + "//test:test_support", "//testing/gtest", ] } diff --git a/modules/remote_bitrate_estimator/BUILD.gn b/modules/remote_bitrate_estimator/BUILD.gn index a8d6850749..1e1cadb440 100644 --- a/modules/remote_bitrate_estimator/BUILD.gn +++ b/modules/remote_bitrate_estimator/BUILD.gn @@ -227,6 +227,7 @@ if (rtc_include_tests) { "../../rtc_base:rtc_base_approved", "../../test:fileutils", "../../test:test_main", + "//test:test_support", "//testing/gtest", ] data = [ diff --git a/modules/rtp_rtcp/BUILD.gn b/modules/rtp_rtcp/BUILD.gn index a4774d8cd5..9102562974 100644 --- a/modules/rtp_rtcp/BUILD.gn +++ b/modules/rtp_rtcp/BUILD.gn @@ -321,6 +321,7 @@ if (rtc_include_tests) { ":rtp_rtcp", "../../test:fileutils", "../../test:test_main", + "//test:test_support", "//testing/gtest", ] } # test_packet_masks_metrics diff --git a/modules/video_capture/BUILD.gn b/modules/video_capture/BUILD.gn index ef6f335e49..734fcbffae 100644 --- a/modules/video_capture/BUILD.gn +++ b/modules/video_capture/BUILD.gn @@ -192,6 +192,7 @@ if (!build_with_chromium) { "../../system_wrappers:system_wrappers", "../../test:video_test_common", "../utility", + "//test:test_support", "//testing/gtest", ] deps += [ "../../test:test_main" ] diff --git a/rtc_tools/BUILD.gn b/rtc_tools/BUILD.gn index b895d11ec5..56e3a3aa80 100644 --- a/rtc_tools/BUILD.gn +++ b/rtc_tools/BUILD.gn @@ -357,6 +357,7 @@ if (rtc_include_tests) { "../rtc_base:checks", "../test:fileutils", "../test:test_main", + "//test:test_support", "//testing/gtest", "//third_party/abseil-cpp/absl/memory", ] diff --git a/system_wrappers/BUILD.gn b/system_wrappers/BUILD.gn index eb60052265..0f5dc140db 100644 --- a/system_wrappers/BUILD.gn +++ b/system_wrappers/BUILD.gn @@ -166,6 +166,7 @@ if (rtc_include_tests) { "..:webrtc_common", "../rtc_base:rtc_base_approved", "../test:test_main", + "//test:test_support", "//testing/gtest", ] diff --git a/test/BUILD.gn b/test/BUILD.gn index b38e215a78..8602bbf0f6 100644 --- a/test/BUILD.gn +++ b/test/BUILD.gn @@ -196,19 +196,18 @@ rtc_source_set("test_support") { } if (rtc_include_tests) { - rtc_source_set("test_main") { + rtc_source_set("test_main_lib") { visibility = [ "*" ] testonly = true sources = [ - "test_main.cc", + "test_main_lib.cc", + "test_main_lib.h", ] - public_deps = [ - ":test_support", - ] deps = [ ":field_trial", ":perf_test", + ":test_support", "../rtc_base:rtc_base", "../system_wrappers:field_trial", "../system_wrappers:metrics", @@ -222,6 +221,18 @@ if (rtc_include_tests) { ] } + rtc_source_set("test_main") { + visibility = [ "*" ] + testonly = true + sources = [ + "test_main.cc", + ] + + deps = [ + ":test_main_lib", + ] + } + rtc_source_set("video_test_support") { testonly = true diff --git a/test/test_main.cc b/test/test_main.cc index ec32f2d383..fb9aa2070f 100644 --- a/test/test_main.cc +++ b/test/test_main.cc @@ -8,135 +8,15 @@ * be found in the AUTHORS file in the root of the source tree. */ -#include +#include -#include "rtc_base/flags.h" -#include "rtc_base/logging.h" -#include "rtc_base/thread.h" -#include "system_wrappers/include/field_trial.h" -#include "system_wrappers/include/metrics.h" -#include "test/field_trial.h" -#include "test/gmock.h" -#include "test/gtest.h" -#include "test/testsupport/fileutils.h" -#include "test/testsupport/perf_test.h" - -#if defined(WEBRTC_WIN) -#include "rtc_base/win32socketinit.h" -#endif - -#if defined(WEBRTC_IOS) -#include "test/ios/test_support.h" - -DEFINE_string(NSTreatUnknownArgumentsAsOpen, - "", - "Intentionally ignored flag intended for iOS simulator."); -DEFINE_string(ApplePersistenceIgnoreState, - "", - "Intentionally ignored flag intended for iOS simulator."); -DEFINE_bool( - save_chartjson_result, - false, - "Store the perf results in Documents/perf_result.json in the format " - "described by " - "https://github.com/catapult-project/catapult/blob/master/dashboard/docs/" - "data-format.md."); - -#else - -DEFINE_string( - isolated_script_test_output, - "", - "Path to output an empty JSON file which Chromium infra requires."); - -DEFINE_string( - isolated_script_test_perf_output, - "", - "Path where the perf results should be stored in the JSON format described " - "by " - "https://github.com/catapult-project/catapult/blob/master/dashboard/docs/" - "data-format.md."); - -#endif - -DEFINE_bool(logs, false, "print logs to stderr"); - -DEFINE_string( - force_fieldtrials, - "", - "Field trials control experimental feature code which can be forced. " - "E.g. running with --force_fieldtrials=WebRTC-FooFeature/Enable/" - " will assign the group Enable to field trial WebRTC-FooFeature."); - -DEFINE_bool(help, false, "Print this message."); +#include "test/test_main_lib.h" int main(int argc, char* argv[]) { - ::testing::InitGoogleMock(&argc, argv); - - // Default to LS_INFO, even for release builds to provide better test logging. - // TODO(pbos): Consider adding a command-line override. - if (rtc::LogMessage::GetLogToDebug() > rtc::LS_INFO) - rtc::LogMessage::LogToDebug(rtc::LS_INFO); - - if (rtc::FlagList::SetFlagsFromCommandLine(&argc, argv, false)) { - return 1; + std::unique_ptr main = webrtc::TestMain::Create(); + int err_code = main->Init(argc, argv); + if (err_code != 0) { + return err_code; } - if (FLAG_help) { - rtc::FlagList::Print(nullptr, false); - return 0; - } - - // TODO(bugs.webrtc.org/9792): we need to reference something from fileutils.h - // so that our downstream hack where we replace fileutils.cc works. Otherwise - // the downstream flag implementation will take over and botch the flag - // introduced by the hack. Remove this awful thing once the downstream - // implementation has been eliminated. - (void)webrtc::test::JoinFilename("horrible", "hack"); - - webrtc::test::ValidateFieldTrialsStringOrDie(FLAG_force_fieldtrials); - // InitFieldTrialsFromString stores the char*, so the char array must outlive - // the application. - webrtc::field_trial::InitFieldTrialsFromString(FLAG_force_fieldtrials); - webrtc::metrics::Enable(); - -#if defined(WEBRTC_WIN) - rtc::WinsockInitializer winsock_init; -#endif - - rtc::LogMessage::SetLogToStderr(FLAG_logs); - - // Ensure that main thread gets wrapped as an rtc::Thread. - // TODO(bugs.webrt.org/9714): It might be better to avoid wrapping the main - // thread, or leave it to individual tests that need it. But as long as we - // have automatic thread wrapping, we need this to avoid that some other - // random thread (which one depending on which tests are run) gets - // automatically wrapped. - rtc::ThreadManager::Instance()->WrapCurrentThread(); - RTC_CHECK(rtc::Thread::Current()); - -#if defined(WEBRTC_IOS) - - rtc::test::InitTestSuite(RUN_ALL_TESTS, argc, argv, - FLAG_save_chartjson_result); - rtc::test::RunTestsFromIOSApp(); - -#else - - int exit_code = RUN_ALL_TESTS(); - - std::string chartjson_result_file = FLAG_isolated_script_test_perf_output; - if (!chartjson_result_file.empty()) { - webrtc::test::WritePerfResults(chartjson_result_file); - } - - std::string result_filename = FLAG_isolated_script_test_output; - if (!result_filename.empty()) { - std::ofstream result_file(result_filename); - result_file << "{\"version\": 3}"; - result_file.close(); - } - - return exit_code; - -#endif + return main->Run(argc, argv); } diff --git a/test/test_main_lib.cc b/test/test_main_lib.cc new file mode 100644 index 0000000000..bcd08576ac --- /dev/null +++ b/test/test_main_lib.cc @@ -0,0 +1,168 @@ +/* + * Copyright (c) 2018 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. + */ + +#include "test/test_main_lib.h" + +#include +#include + +#include "rtc_base/flags.h" +#include "rtc_base/logging.h" +#include "rtc_base/thread.h" +#include "system_wrappers/include/field_trial.h" +#include "system_wrappers/include/metrics.h" +#include "test/field_trial.h" +#include "test/gmock.h" +#include "test/gtest.h" +#include "test/testsupport/fileutils.h" +#include "test/testsupport/perf_test.h" + +#if defined(WEBRTC_WIN) +#include "rtc_base/win32socketinit.h" +#endif + +#if defined(WEBRTC_IOS) +#include "test/ios/test_support.h" + +DEFINE_string(NSTreatUnknownArgumentsAsOpen, + "", + "Intentionally ignored flag intended for iOS simulator."); +DEFINE_string(ApplePersistenceIgnoreState, + "", + "Intentionally ignored flag intended for iOS simulator."); +DEFINE_bool( + save_chartjson_result, + false, + "Store the perf results in Documents/perf_result.json in the format " + "described by " + "https://github.com/catapult-project/catapult/blob/master/dashboard/docs/" + "data-format.md."); + +#else + +DEFINE_string( + isolated_script_test_output, + "", + "Path to output an empty JSON file which Chromium infra requires."); + +DEFINE_string( + isolated_script_test_perf_output, + "", + "Path where the perf results should be stored in the JSON format described " + "by " + "https://github.com/catapult-project/catapult/blob/master/dashboard/docs/" + "data-format.md."); + +#endif + +DEFINE_bool(logs, false, "print logs to stderr"); + +DEFINE_string( + force_fieldtrials, + "", + "Field trials control experimental feature code which can be forced. " + "E.g. running with --force_fieldtrials=WebRTC-FooFeature/Enable/" + " will assign the group Enable to field trial WebRTC-FooFeature."); + +DEFINE_bool(help, false, "Print this message."); + +namespace webrtc { + +namespace { + +class TestMainImpl : public TestMain { + public: + int Init(int argc, char* argv[]) override { + ::testing::InitGoogleMock(&argc, argv); + + // Default to LS_INFO, even for release builds to provide better test + // logging. + // TODO(pbos): Consider adding a command-line override. + if (rtc::LogMessage::GetLogToDebug() > rtc::LS_INFO) + rtc::LogMessage::LogToDebug(rtc::LS_INFO); + + if (rtc::FlagList::SetFlagsFromCommandLine(&argc, argv, false)) { + return 1; + } + if (FLAG_help) { + rtc::FlagList::Print(nullptr, false); + return 0; + } + + // TODO(bugs.webrtc.org/9792): we need to reference something from + // fileutils.h so that our downstream hack where we replace fileutils.cc + // works. Otherwise the downstream flag implementation will take over and + // botch the flag introduced by the hack. Remove this awful thing once the + // downstream implementation has been eliminated. + (void)webrtc::test::JoinFilename("horrible", "hack"); + + webrtc::test::ValidateFieldTrialsStringOrDie(FLAG_force_fieldtrials); + // InitFieldTrialsFromString stores the char*, so the char array must + // outlive the application. + webrtc::field_trial::InitFieldTrialsFromString(FLAG_force_fieldtrials); + webrtc::metrics::Enable(); + +#if defined(WEBRTC_WIN) + winsock_init_ = absl::make_unique(); +#endif + + rtc::LogMessage::SetLogToStderr(FLAG_logs); + + // Ensure that main thread gets wrapped as an rtc::Thread. + // TODO(bugs.webrt.org/9714): It might be better to avoid wrapping the main + // thread, or leave it to individual tests that need it. But as long as we + // have automatic thread wrapping, we need this to avoid that some other + // random thread (which one depending on which tests are run) gets + // automatically wrapped. + rtc::ThreadManager::Instance()->WrapCurrentThread(); + RTC_CHECK(rtc::Thread::Current()); + return 0; + } + + int Run(int argc, char* argv[]) override { +#if defined(WEBRTC_IOS) + rtc::test::InitTestSuite(RUN_ALL_TESTS, argc, argv, + FLAG_save_chartjson_result); + rtc::test::RunTestsFromIOSApp(); + return 0; +#else + int exit_code = RUN_ALL_TESTS(); + + std::string chartjson_result_file = FLAG_isolated_script_test_perf_output; + if (!chartjson_result_file.empty()) { + webrtc::test::WritePerfResults(chartjson_result_file); + } + + std::string result_filename = FLAG_isolated_script_test_output; + if (!result_filename.empty()) { + std::ofstream result_file(result_filename); + result_file << "{\"version\": 3}"; + result_file.close(); + } + + return exit_code; +#endif + } + + ~TestMainImpl() override = default; + + private: +#if defined(WEBRTC_WIN) + std::unique_ptr winsock_init_; +#endif +}; + +} // namespace + +std::unique_ptr TestMain::Create() { + return absl::make_unique(); +} + +} // namespace webrtc diff --git a/test/test_main_lib.h b/test/test_main_lib.h new file mode 100644 index 0000000000..9e859869dd --- /dev/null +++ b/test/test_main_lib.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2018 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 TEST_TEST_MAIN_LIB_H_ +#define TEST_TEST_MAIN_LIB_H_ + +#include + +namespace webrtc { + +// Class to initialize test environment and run tests. +class TestMain { + public: + virtual ~TestMain() {} + + static std::unique_ptr Create(); + + // Initializes test environment. Clients can add their own initialization + // steps after call to this method and before running tests. + // Returns 0 if initialization was successful and non 0 otherwise. + virtual int Init(int argc, char* argv[]) = 0; + + // Runs test end return result error code. 0 - no errors. + virtual int Run(int argc, char* argv[]) = 0; + + protected: + TestMain() = default; +}; + +} // namespace webrtc + +#endif // TEST_TEST_MAIN_LIB_H_