diff options
Diffstat (limited to '')
-rw-r--r-- | third_party/libwebrtc/test/test_main_lib.cc | 267 |
1 files changed, 267 insertions, 0 deletions
diff --git a/third_party/libwebrtc/test/test_main_lib.cc b/third_party/libwebrtc/test/test_main_lib.cc new file mode 100644 index 0000000000..4c80315ac5 --- /dev/null +++ b/third_party/libwebrtc/test/test_main_lib.cc @@ -0,0 +1,267 @@ +/* + * 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 <fstream> +#include <memory> +#include <string> +#include <vector> + +#include "absl/flags/flag.h" +#include "absl/memory/memory.h" +#include "absl/strings/match.h" +#include "absl/types/optional.h" +#include "api/test/metrics/chrome_perf_dashboard_metrics_exporter.h" +#include "api/test/metrics/global_metrics_logger_and_exporter.h" +#include "api/test/metrics/metrics_exporter.h" +#include "api/test/metrics/metrics_set_proto_file_exporter.h" +#include "api/test/metrics/print_result_proxy_metrics_exporter.h" +#include "api/test/metrics/stdout_metrics_exporter.h" +#include "rtc_base/checks.h" +#include "rtc_base/event_tracer.h" +#include "rtc_base/logging.h" +#include "rtc_base/ssl_adapter.h" +#include "rtc_base/ssl_stream_adapter.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/gtest.h" +#include "test/test_flags.h" +#include "test/testsupport/perf_test.h" +#include "test/testsupport/resources_dir_flag.h" + +#if defined(WEBRTC_WIN) +#include "rtc_base/win32_socket_init.h" +#endif + +#if defined(WEBRTC_IOS) +#include "test/ios/test_support.h" + +ABSL_FLAG(std::string, + NSTreatUnknownArgumentsAsOpen, + "", + "Intentionally ignored flag intended for iOS test runner."); +ABSL_FLAG(std::string, + ApplePersistenceIgnoreState, + "", + "Intentionally ignored flag intended for iOS test runner."); +ABSL_FLAG(bool, + enable_run_ios_unittests_with_xctest, + false, + "Intentionally ignored flag intended for iOS test runner."); +ABSL_FLAG(bool, + write_compiled_tests_json_to_writable_path, + false, + "Intentionally ignored flag intended for iOS test runner."); + +// This is the cousin of isolated_script_test_perf_output, but we can't dictate +// where to write on iOS so the semantics of this flag are a bit different. +ABSL_FLAG( + bool, + write_perf_output_on_ios, + false, + "Store the perf results in Documents/perftest_result.pb in the format " + "described by histogram.proto in " + "https://chromium.googlesource.com/catapult/."); + +#elif defined(WEBRTC_FUCHSIA) +ABSL_FLAG(std::string, use_vulkan, "", "Intentionally ignored flag."); +#else +// TODO(bugs.webrtc.org/8115): Remove workaround when fixed. +ABSL_FLAG(bool, no_sandbox, false, "Intentionally ignored flag."); +ABSL_FLAG(bool, test_launcher_bot_mode, false, "Intentionally ignored flag."); +#endif + +ABSL_FLAG(std::string, + isolated_script_test_output, + "", + "Path to output an empty JSON file which Chromium infra requires."); + +ABSL_FLAG(bool, logs, true, "print logs to stderr"); +ABSL_FLAG(bool, verbose, false, "verbose logs to stderr"); + +ABSL_FLAG(std::string, + trace_event, + "", + "Path to collect trace events (json file) for chrome://tracing. " + "If not set, events aren't captured."); + +ABSL_FLAG(std::string, + test_launcher_shard_index, + "", + "Index of the test shard to run, from 0 to " + "the value specified with --test_launcher_total_shards."); + +ABSL_FLAG(std::string, + test_launcher_total_shards, + "", + "Total number of shards."); + +namespace webrtc { + +namespace { + +constexpr char kPlotAllMetrics[] = "all"; + +class TestMainImpl : public TestMain { + public: + int Init(int* argc, char* argv[]) override { return Init(); } + + int Init() override { + // Make sure we always pull in the --resources_dir flag, even if the test + // binary doesn't link with fileutils (downstream expects all test mains to + // have this flag). + (void)absl::GetFlag(FLAGS_resources_dir); + + // Default to LS_INFO, even for release builds to provide better test + // logging. + if (rtc::LogMessage::GetLogToDebug() > rtc::LS_INFO) + rtc::LogMessage::LogToDebug(rtc::LS_INFO); + + if (absl::GetFlag(FLAGS_verbose)) + rtc::LogMessage::LogToDebug(rtc::LS_VERBOSE); + + rtc::LogMessage::SetLogToStderr(absl::GetFlag(FLAGS_logs) || + absl::GetFlag(FLAGS_verbose)); + + // The sharding arguments take precedence over the sharding environment + // variables. + if (!absl::GetFlag(FLAGS_test_launcher_shard_index).empty() && + !absl::GetFlag(FLAGS_test_launcher_total_shards).empty()) { + std::string shard_index = + "GTEST_SHARD_INDEX=" + absl::GetFlag(FLAGS_test_launcher_shard_index); + std::string total_shards = + "GTEST_TOTAL_SHARDS=" + + absl::GetFlag(FLAGS_test_launcher_total_shards); + putenv(shard_index.data()); + putenv(total_shards.data()); + } + + // InitFieldTrialsFromString stores the char*, so the char array must + // outlive the application. + field_trials_ = absl::GetFlag(FLAGS_force_fieldtrials); + webrtc::field_trial::InitFieldTrialsFromString(field_trials_.c_str()); + webrtc::metrics::Enable(); + +#if defined(WEBRTC_WIN) + winsock_init_ = std::make_unique<rtc::WinsockInitializer>(); +#endif + + // Initialize SSL which are used by several tests. + rtc::InitializeSSL(); + rtc::SSLStreamAdapter::EnableTimeCallbackForTesting(); + + return 0; + } + + int Run(int argc, char* argv[]) override { + std::string trace_event_path = absl::GetFlag(FLAGS_trace_event); + const bool capture_events = !trace_event_path.empty(); + if (capture_events) { + rtc::tracing::SetupInternalTracer(); + rtc::tracing::StartInternalCapture(trace_event_path); + } + + absl::optional<std::vector<std::string>> metrics_to_plot = + absl::GetFlag(FLAGS_plot); + + if (metrics_to_plot->empty()) { + metrics_to_plot = absl::nullopt; + } else { + if (metrics_to_plot->size() == 1 && + (*metrics_to_plot)[0] == kPlotAllMetrics) { + metrics_to_plot->clear(); + } + } + +#if defined(WEBRTC_IOS) + rtc::test::InitTestSuite( + RUN_ALL_TESTS, argc, argv, + absl::GetFlag(FLAGS_write_perf_output_on_ios), + absl::GetFlag(FLAGS_export_perf_results_new_api), + absl::GetFlag(FLAGS_webrtc_test_metrics_output_path), metrics_to_plot); + rtc::test::RunTestsFromIOSApp(); + int exit_code = 0; +#else + int exit_code = RUN_ALL_TESTS(); + + std::vector<std::unique_ptr<test::MetricsExporter>> exporters; + if (absl::GetFlag(FLAGS_export_perf_results_new_api)) { + exporters.push_back(std::make_unique<test::StdoutMetricsExporter>()); + if (!absl::GetFlag(FLAGS_webrtc_test_metrics_output_path).empty()) { + exporters.push_back( + std::make_unique<webrtc::test::MetricsSetProtoFileExporter>( + webrtc::test::MetricsSetProtoFileExporter::Options( + absl::GetFlag(FLAGS_webrtc_test_metrics_output_path)))); + } + if (!absl::GetFlag(FLAGS_isolated_script_test_perf_output).empty()) { + exporters.push_back( + std::make_unique<test::ChromePerfDashboardMetricsExporter>( + absl::GetFlag(FLAGS_isolated_script_test_perf_output))); + } + } else { + exporters.push_back( + std::make_unique<test::PrintResultProxyMetricsExporter>()); + } + test::ExportPerfMetric(*test::GetGlobalMetricsLogger(), + std::move(exporters)); + if (!absl::GetFlag(FLAGS_export_perf_results_new_api)) { + std::string perf_output_file = + absl::GetFlag(FLAGS_isolated_script_test_perf_output); + if (!perf_output_file.empty()) { + if (!webrtc::test::WritePerfResults(perf_output_file)) { + return 1; + } + } + if (metrics_to_plot) { + webrtc::test::PrintPlottableResults(*metrics_to_plot); + } + } + + std::string result_filename = + absl::GetFlag(FLAGS_isolated_script_test_output); + if (!result_filename.empty()) { + std::ofstream result_file(result_filename); + result_file << "{\"version\": 3}"; + } +#endif + + if (capture_events) { + rtc::tracing::StopInternalCapture(); + } + +#if defined(ADDRESS_SANITIZER) || defined(LEAK_SANITIZER) || \ + defined(MEMORY_SANITIZER) || defined(THREAD_SANITIZER) || \ + defined(UNDEFINED_SANITIZER) + // We want the test flagged as failed only for sanitizer defects, + // in which case the sanitizer will override exit code with 66. + exit_code = 0; +#endif + + return exit_code; + } + + ~TestMainImpl() override = default; + + private: +#if defined(WEBRTC_WIN) + std::unique_ptr<rtc::WinsockInitializer> winsock_init_; +#endif +}; + +} // namespace + +std::unique_ptr<TestMain> TestMain::Create() { + return std::make_unique<TestMainImpl>(); +} + +} // namespace webrtc |