From cd5d502611e42a58226546a4ee93eb7e6ba49a07 Mon Sep 17 00:00:00 2001 From: Cheng Date: Thu, 19 Dec 2024 19:12:27 +0900 Subject: [PATCH] Ship abseil and re2 as required by googletest --- .gitmodules | 6 + scripts/create_dist.js | 4 +- testing | 2 +- third_party/abseil-cpp | 1 + third_party/googletest/BUILD.gn | 136 +++++++++++---- third_party/googletest/DEPS | 18 ++ third_party/googletest/DIR_METADATA | 6 + third_party/googletest/OWNERS | 1 + third_party/googletest/README.chromium | 156 +++++++++++++++++ .../custom/gtest/internal/custom/DEPS | 5 + .../internal/custom/chrome_custom_temp_dir.cc | 104 +++++++++++ .../internal/custom/chrome_custom_temp_dir.h | 15 ++ .../custom/gtest/internal/custom/gtest.h | 23 +++ .../internal/custom/gtest_port_wrapper.cc | 161 ++++++++++++++++++ .../internal/custom/stack_trace_getter.cc | 68 ++++++++ .../internal/custom/stack_trace_getter.h | 31 ++++ third_party/re2/BUILD.gn | 62 +++++++ third_party/re2/DEPS | 7 + third_party/re2/DIR_METADATA | 6 + third_party/re2/LICENSE | 27 +++ third_party/re2/OWNERS | 2 + third_party/re2/README.chromium | 13 ++ third_party/re2/src | 1 + tools/gn | 2 +- 24 files changed, 820 insertions(+), 37 deletions(-) create mode 160000 third_party/abseil-cpp create mode 100644 third_party/googletest/DEPS create mode 100644 third_party/googletest/DIR_METADATA create mode 100644 third_party/googletest/OWNERS create mode 100644 third_party/googletest/README.chromium create mode 100644 third_party/googletest/custom/gtest/internal/custom/DEPS create mode 100644 third_party/googletest/custom/gtest/internal/custom/chrome_custom_temp_dir.cc create mode 100644 third_party/googletest/custom/gtest/internal/custom/chrome_custom_temp_dir.h create mode 100644 third_party/googletest/custom/gtest/internal/custom/gtest.h create mode 100644 third_party/googletest/custom/gtest/internal/custom/gtest_port_wrapper.cc create mode 100644 third_party/googletest/custom/gtest/internal/custom/stack_trace_getter.cc create mode 100644 third_party/googletest/custom/gtest/internal/custom/stack_trace_getter.h create mode 100644 third_party/re2/BUILD.gn create mode 100644 third_party/re2/DEPS create mode 100644 third_party/re2/DIR_METADATA create mode 100644 third_party/re2/LICENSE create mode 100644 third_party/re2/OWNERS create mode 100644 third_party/re2/README.chromium create mode 160000 third_party/re2/src diff --git a/.gitmodules b/.gitmodules index f9792f6..21354bc 100644 --- a/.gitmodules +++ b/.gitmodules @@ -16,3 +16,9 @@ [submodule "third_party/libunwind/src"] path = third_party/libunwind/src url = https://chromium.googlesource.com/external/github.com/llvm/llvm-project/libunwind +[submodule "third_party/abseil-cpp"] + path = third_party/abseil-cpp + url = https://chromium.googlesource.com/chromium/src/third_party/abseil-cpp +[submodule "third_party/re2/src"] + path = third_party/re2/src + url = https://github.com/google/re2 diff --git a/scripts/create_dist.js b/scripts/create_dist.js index bb924e9..5d8f1f8 100755 --- a/scripts/create_dist.js +++ b/scripts/create_dist.js @@ -36,6 +36,7 @@ const files = searchFiles('tools/cfi')).concat( searchFiles('tools/clang/scripts')).concat( searchFiles('tools/win')).concat( + searchFiles('third_party/abseil-cpp')).concat( searchFiles('third_party/catapult')).concat( searchFiles('third_party/depot_tools')).concat( searchFiles('third_party/googletest')).concat( @@ -44,7 +45,8 @@ const files = searchFiles('third_party/libc++abi/src/src')).concat( searchFiles('third_party/libc++abi/src/include')).concat( searchFiles('third_party/libunwind/src/src')).concat( - searchFiles('third_party/libunwind/src/include')) + searchFiles('third_party/libunwind/src/include')).concat( + searchFiles('third_party/re2')) addFileToZip(gnzip, 'buildtools/deps_revisions.gni', '.') addFileToZip(gnzip, 'buildtools/third_party/eu-strip/bin/eu-strip', '.') addFileToZip(gnzip, 'buildtools/third_party/libc++/__assertion_handler', '.') diff --git a/testing b/testing index ea5668e..0305a85 160000 --- a/testing +++ b/testing @@ -1 +1 @@ -Subproject commit ea5668efef36a14b6a0b7060524a30249d983662 +Subproject commit 0305a85a20b28da1ad923de7987b218fd3ed2ecb diff --git a/third_party/abseil-cpp b/third_party/abseil-cpp new file mode 160000 index 0000000..79b08c2 --- /dev/null +++ b/third_party/abseil-cpp @@ -0,0 +1 @@ +Subproject commit 79b08c29b362c4fecc3f1a1f9f204dd7693e87c2 diff --git a/third_party/googletest/BUILD.gn b/third_party/googletest/BUILD.gn index 09ed92e..74c9eb6 100644 --- a/third_party/googletest/BUILD.gn +++ b/third_party/googletest/BUILD.gn @@ -1,10 +1,17 @@ -# Copyright 2014 The Chromium Authors. All rights reserved. +# Copyright 2014 The Chromium Authors # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. +import("//build_overrides/build.gni") + config("gtest_config") { - # PATCH(build-gn): Causes problems when using gmock. - # visibility = [ ":*" ] # gmock also shares this config. + # webrtc wants to push this config without a public_dep chain + # TODO(crbug.com/1249254): figure out what to do with this + visibility = [ + ":*", # gmock also shares this config. + "//test:*", # webrts standalone setup + "//third_party/webrtc/test:*", + ] defines = [ # Chromium always links googletest statically, so no API qualifier is @@ -15,15 +22,34 @@ config("gtest_config") { # In order to allow regex matches in gtest to be shared between Windows # and other systems, we tell gtest to always use its internal engine. "GTEST_HAS_POSIX_RE=0", + + # Enables C++11 features. "GTEST_LANG_CXX11=1", + + # Prevents gtest from including both and . + "GTEST_HAS_TR1_TUPLE=0", + + # Use Abseil, but without flags support: Abseil flags uses the + # `FastTypeId()` pattern internally, which is known to be broken in + # subtle ways in the component build. + "GTEST_HAS_ABSL", + "GTEST_NO_ABSL_FLAGS", ] # Gtest headers need to be able to find themselves. - include_dirs = [ "src/googletest/include" ] + include_dirs = [ + "custom", + "src/googletest/include", + ] if (is_win) { cflags = [ "/wd4800" ] # Unused variable warning. } + + configs = [ + "//third_party/abseil-cpp:absl_include_config", + "//third_party/re2:re2_config", + ] } config("gmock_config") { @@ -32,6 +58,13 @@ config("gmock_config") { "custom", "src/googlemock/include", ] + + if (is_clang) { + # TODO(crbug.com/40616204): remove this when we migrated to new MOCK_METHOD + # macro. + # ref: https://google.github.io/googletest/gmock_cook_book.html#old-style-mock_methodn-macros + cflags = [ "-Wno-inconsistent-missing-override" ] + } } # Do NOT depend on this directly. Use //testing/gtest instead. @@ -39,7 +72,18 @@ config("gmock_config") { source_set("gtest") { testonly = true sources = [ + "custom/gtest/internal/custom/gtest.h", + "custom/gtest/internal/custom/stack_trace_getter.cc", + "custom/gtest/internal/custom/stack_trace_getter.h", + + # TODO(crbug.com/1009553): Remove this wrapper and custom temp dir + # after plumbing a workable temporary path into googletest on Android. + "custom/gtest/internal/custom/chrome_custom_temp_dir.cc", + "custom/gtest/internal/custom/chrome_custom_temp_dir.h", + "custom/gtest/internal/custom/gtest_port_wrapper.cc", + "src/googletest/include/gtest/gtest-assertion-result.h", "src/googletest/include/gtest/gtest-death-test.h", + "src/googletest/include/gtest/gtest-matchers.h", "src/googletest/include/gtest/gtest-message.h", "src/googletest/include/gtest/gtest-param-test.h", "src/googletest/include/gtest/gtest-printers.h", @@ -48,22 +92,31 @@ source_set("gtest") { "src/googletest/include/gtest/gtest-typed-test.h", "src/googletest/include/gtest/gtest.h", "src/googletest/include/gtest/gtest_pred_impl.h", + "src/googletest/include/gtest/gtest_prod.h", + + #"src/googletest/include/gtest/internal/custom/gtest.h", # Superseded. + "src/googletest/include/gtest/internal/custom/gtest-port.h", + "src/googletest/include/gtest/internal/custom/gtest-printers.h", "src/googletest/include/gtest/internal/gtest-death-test-internal.h", "src/googletest/include/gtest/internal/gtest-filepath.h", "src/googletest/include/gtest/internal/gtest-internal.h", - "src/googletest/include/gtest/internal/gtest-linked_ptr.h", - "src/googletest/include/gtest/internal/gtest-param-util-generated.h", "src/googletest/include/gtest/internal/gtest-param-util.h", + "src/googletest/include/gtest/internal/gtest-port-arch.h", "src/googletest/include/gtest/internal/gtest-port.h", "src/googletest/include/gtest/internal/gtest-string.h", - "src/googletest/include/gtest/internal/gtest-tuple.h", "src/googletest/include/gtest/internal/gtest-type-util.h", #"src/googletest/src/gtest-all.cc", # Not needed by our build. + "src/googletest/src/gtest-assertion-result.cc", "src/googletest/src/gtest-death-test.cc", "src/googletest/src/gtest-filepath.cc", "src/googletest/src/gtest-internal-inl.h", - "src/googletest/src/gtest-port.cc", + "src/googletest/src/gtest-matchers.cc", + + # gtest_port_wrapper.cc is used instead of gtest-port.cc. + # TODO(crbug.com/1009553): Re-enable this file after plumbing a workable + # temporary path into googletest on Android. + #"src/googletest/src/gtest-port.cc", "src/googletest/src/gtest-printers.cc", "src/googletest/src/gtest-test-part.cc", "src/googletest/src/gtest-typed-test.cc", @@ -73,44 +126,62 @@ source_set("gtest") { # Some files include "src/gtest-internal-inl.h". include_dirs = [ "src/googletest" ] - all_dependent_configs = [ ":gtest_config" ] + public_configs = [ ":gtest_config" ] configs -= [ "//build/config/compiler:chromium_code" ] configs += [ "//build/config/compiler:no_chromium_code" ] + + defines = [] + + # googletest only needs `absl`, but this makes gn check happier. + deps = [ "//third_party/abseil-cpp:absl_full" ] + public_deps = [ "//third_party/re2" ] + if (is_nacl || !build_with_chromium) { + defines += [ "GTEST_DISABLE_PRINT_STACK_TRACE" ] + sources -= [ + "custom/gtest/internal/custom/stack_trace_getter.cc", + "custom/gtest/internal/custom/stack_trace_getter.h", + ] + } else { + deps += [ "//base" ] + } + + if (is_fuchsia) { + deps += [ + "//third_party/fuchsia-sdk/sdk/pkg/fdio", + "//third_party/fuchsia-sdk/sdk/pkg/zx", + ] + } } # Do NOT depend on this directly. Use //testing/gtest:gtest_main instead. # See README.chromium for details. source_set("gtest_main") { testonly = true - sources = [ - "src/googletest/src/gtest_main.cc", - ] - deps = [ - ":gtest", - ] + sources = [ "src/googletest/src/gtest_main.cc" ] + deps = [ ":gtest" ] } -# Do NOT depend on this directly. Use //testing/gmock:gmock_main instead. +# Do NOT depend on this directly. Use //testing/gmock instead. # See README.chromium for details. source_set("gmock") { testonly = true sources = [ "src/googlemock/include/gmock/gmock-actions.h", "src/googlemock/include/gmock/gmock-cardinalities.h", - "src/googlemock/include/gmock/gmock-generated-actions.h", - "src/googlemock/include/gmock/gmock-generated-function-mockers.h", - "src/googlemock/include/gmock/gmock-generated-matchers.h", - "src/googlemock/include/gmock/gmock-generated-nice-strict.h", + "src/googlemock/include/gmock/gmock-function-mocker.h", "src/googlemock/include/gmock/gmock-matchers.h", + "src/googlemock/include/gmock/gmock-more-matchers.h", + "src/googlemock/include/gmock/gmock-nice-strict.h", "src/googlemock/include/gmock/gmock-spec-builders.h", "src/googlemock/include/gmock/gmock.h", - "src/googlemock/include/gmock/internal/gmock-generated-internal-utils.h", + + #"src/googlemock/include/gmock/internal/custom/gmock-port.h", # Superseded. + "src/googlemock/include/gmock/internal/custom/gmock-generated-actions.h", + "src/googlemock/include/gmock/internal/custom/gmock-matchers.h", "src/googlemock/include/gmock/internal/gmock-internal-utils.h", "src/googlemock/include/gmock/internal/gmock-port.h", - - # gmock helpers. - "custom/gmock/internal/custom/gmock-port.h", + "src/googlemock/include/gmock/internal/gmock-pp.h", #"src/googlemock/src/gmock-all.cc", # Not needed by our build. "src/googlemock/src/gmock-cardinalities.cc", @@ -120,20 +191,17 @@ source_set("gmock") { "src/googlemock/src/gmock.cc", ] - public_configs = [ - ":gmock_config", - ":gtest_config", - ] + # googlemock only needs `absl`, but this makes gn check happier. + deps = [ "//third_party/abseil-cpp:absl_full" ] + + public_deps = [ ":gtest" ] + public_configs = [ ":gmock_config" ] } # Do NOT depend on this directly. Use //testing/gmock:gmock_main instead. # See README.chromium for details. static_library("gmock_main") { testonly = true - sources = [ - "src/googlemock/src/gmock_main.cc", - ] - deps = [ - ":gmock", - ] + sources = [ "src/googlemock/src/gmock_main.cc" ] + deps = [ ":gmock" ] } diff --git a/third_party/googletest/DEPS b/third_party/googletest/DEPS new file mode 100644 index 0000000..f23dccc --- /dev/null +++ b/third_party/googletest/DEPS @@ -0,0 +1,18 @@ +# This file is a dummy used so that non-Chromium clients can specify +# recursive DEPS. Otherwise the clients would need to nest DEPS inside +# each other. Nested DEPS are not supported by gclient. +# +# Clients *must* specify googletest_revision when using this DEPS file. + +use_relative_paths = True + +vars = { + 'chromium_git': 'https://chromium.googlesource.com', + + # We must specify a dummy variable here for recursedeps to work. + 'googletest_revision': 'master', +} + +deps = { + 'src': '{chromium_git}/external/github.com/google/googletest.git@{googletest_revision}' +} diff --git a/third_party/googletest/DIR_METADATA b/third_party/googletest/DIR_METADATA new file mode 100644 index 0000000..67e6af8 --- /dev/null +++ b/third_party/googletest/DIR_METADATA @@ -0,0 +1,6 @@ +monorail: { + component: "Test>gTest" +} +buganizer_public: { + component_id: 1457072 +} diff --git a/third_party/googletest/OWNERS b/third_party/googletest/OWNERS new file mode 100644 index 0000000..1878806 --- /dev/null +++ b/third_party/googletest/OWNERS @@ -0,0 +1 @@ +file://testing/gtest/OWNERS diff --git a/third_party/googletest/README.chromium b/third_party/googletest/README.chromium new file mode 100644 index 0000000..5d7ec95 --- /dev/null +++ b/third_party/googletest/README.chromium @@ -0,0 +1,156 @@ +Name: Google Test: Google's C++ Testing Framework +Short Name: googletest +URL: https://github.com/google/googletest.git +Version: N/A +Revision: DEPS +License: BSD-3-Clause +License File: src/LICENSE +Shipped: no +Security critical: no + +Google Test is imported as-is, to facilitate version bumping. However, the +file/directory layout of Google Test is not yet considered stable. Therefore, +until Google Test's layout stabilizes, Chromium code MUST NOT depend on it +directly. Instead, Chromium code MUST: + +* #include the headers in testing/gtest and testing/gmock +* use //testing/gtest(:gtest_main) and //testing/gmock(:gmock_main) in BUILD.gn + deps + +This will allow us to adapt to Google Test changes with minimal disruption. + + +## Resources for Rolling Googletest in Chrome + +### What is Googletest + +Googletest is an open source C++ testing framework developed by Google and used +by Chromium. See the [User Guide](https://google.github.io/googletest/). + +### Where is Googletest + +Googletest is developed in google3 and uses +[copybara](https://github.com/google/copybara) to sync with the public GitHub +repository. + +* Development (Googler only): [google3/third\_party/googletest](http://google3/third_party/googletest/) +* GitHub: https://github.com/google/googletest +* Chromium mirror: https://chromium.googlesource.com/external/github.com/google/googletest/ +* Locally, [third\_party/googletest/src/](https://source.chromium.org/chromium/chromium/src/+/master:third_party/googletest/src/) + is a copy of Googletest which is updated via `gclient sync` according to the + `googletest revision` commit hash in the + [DEPS file](https://source.chromium.org/chromium/chromium/src/+/master:DEPS;l=244?q=DEPS%20googletest) + +### Unblocking Googletest Rolls + +1. Roll Googletest to include the breaking change +* Find the hash (on GitHub) of the offending commit + * If the change came from google3, the CL number can be found in the + `PiperOrigin-RevId` footer of Copybara commits +* On a fresh checkout, pull in the relevant change. Either: + * Sync using the DEPS file +``` +roll-dep --roll-to=commitish src/third_party/googletest/src/ +gclient sync +``` + * Check out the commit directly +``` +cd third_party/googletest/src +git remote add up https://github.com/google/googletest.git +git checkout commitish +``` + +2. Observe errors +* Ideally, this can be done by building locally. + If the build is successful, this means the change does not affect your OS or + your compiler flags differ from the trybots +* Upload a CL with the added trybots from + [Testing Changes to Chromium in Chromium](#testing-changes-to-chromium-in-chromium) + +3. Make changes +* To Chromium: create a CL including both the roll and other changes +* To Googletest: + * Make changes to [third\_party/googletest/src/](https://source.chromium.org/chromium/chromium/src/+/master:third_party/googletest/src/) + and try building locally. If the fix is successful and you’re confident + this change will work across all the trybots, create a PR on GitHub or a + CL to google3 (Googler only) of the changes you made locally to + [third\_party/googletest/src/](https://source.chromium.org/chromium/chromium/src/+/master:third_party/googletest/src/). + See [Testing Changes to Googletest in Googletest](#testing-changes-to-googletest-in-googletest) + * What if I need to make a change to Googletest, but I’m not confident it + will work with Chromium? Maybe it has to do with a tricky compiler error + that only affects a specific OS. See + [Testing Changes to Googletest in Chromium](#testing-changes-to-googletest-in-chromium) + * Once your Googletest change lands, create a roll which includes both the + offending commit and your change + +### Testing Changes to Chromium in Chromium + +Most changes should only require testing via the trybots, +with the following added: + +`Cq-Include-Trybots: luci.chromium.try:android_optional_gpu_tests_rel;luci.chromium.try:mac_optional_gpu_tests_rel;luci.chromium.try:linux_chromium_cfi_rel_ng;luci.chrome.try:win-chrome` + +### Testing Changes to Googletest in Googletest + +External: Upload a PR with your proposed changes to GitHub. +This will trigger automated testing. + +Googlers: See the [Googletest Developer’s Guide](http://go/gunitdev). + +### Testing Changes to Googletest in Chromium + +In most cases, testing locally with changes to +[third\_party/googletest/src/](https://source.chromium.org/chromium/chromium/src/+/master:third_party/googletest/src/) +should be enough. But how can you make sure the changes to Googletest actually +work in Chromium? Sometimes it’s not possible to test these changes locally +(different compiler flags, error that only affects a specific OS, etc). +Insert the pwnall repo: + +* Development: https://github.com/pwnall/googletest +* Chromium mirror: https://chromium.googlesource.com/external/github.com/pwnall/googletest/ + +The pwnall repo allows you to make speculative changes to Googletest and run +them against the Chromium trybots. The flow is as follows: + +* Create a local remote to the pwnall repo (alternatively, clone it elsewhere): +``` +cd third_party/googletest/src +git remote +git remote add up https://github.com/google/googletest.git +git remote add pwnall git@github.com:pwnall/googletest.git +``` +* Sync the pwnall repo: +``` +git checkout master +git pull up master +git push pwnall master +``` +* Make changes on a new branch +* `git push pwnall branch-name` +* Update the `googletest revision` in the + [DEPS file](https://source.chromium.org/chromium/chromium/src/+/master:DEPS) + with the commit hash and `/external/github.com/google/googletest.git` to + `/external/github.com/pwnall/googletest.git` +* Upload the CL to run the change against the Chromium trybots + +### Common Problems + +* Differences in C++ version and clang compiler flags between Chromium and Googletest + * Chromium is on C++14, though its dependencies, + which may use Googletest, may be further behind + * Look for NACL in build errors. You may need to update your GN args with + `enable_nacl=true` to reproduce these errors locally +* [A Googletest interface is changed](https://github.com/google/googletest/pull/2718/) + * Rolling past the commit will fail, since Chromium still uses the old interface + * Roll past the affecting commit and update uses in Chromium [in one CL](https://crrev.com/c/2709263) +* [A Googletest header is removed](https://github.com/google/googletest/commit/df6b75949b1efab7606ba60c0f0a0125ac95c5af) + * Rolling past the commit will fail, since Chromium still expects the header to exist + * Roll past the affecting commit and updates uses in Chromium [in one CL](https://crrev.com/c/2713029) +* [A new Googletest feature](https://github.com/google/googletest/commit/ec94d9f24c92a5090fda5567156d6dde99cdbf31) + requires [updating tests in Chromium](https://crbug.com/1163396#c8) + +### Other Resources + +* [AutoRoller](https://autoroll.skia.org/r/googletest-chromium-autoroll) and + accompanying [configuration file](https://skia.googlesource.com/skia-autoroll-internal-config.git/+/main/skia-public/googletest-chromium.cfg) +* [Bug tracking substantial roll](https://crbug.com/1163396) diff --git a/third_party/googletest/custom/gtest/internal/custom/DEPS b/third_party/googletest/custom/gtest/internal/custom/DEPS new file mode 100644 index 0000000..943f2bb --- /dev/null +++ b/third_party/googletest/custom/gtest/internal/custom/DEPS @@ -0,0 +1,5 @@ +# This directory contains Google Test glue that depends on //base. +include_rules = [ + '+base', + '+build', +] diff --git a/third_party/googletest/custom/gtest/internal/custom/chrome_custom_temp_dir.cc b/third_party/googletest/custom/gtest/internal/custom/chrome_custom_temp_dir.cc new file mode 100644 index 0000000..931c18d --- /dev/null +++ b/third_party/googletest/custom/gtest/internal/custom/chrome_custom_temp_dir.cc @@ -0,0 +1,104 @@ +// Copyright 2020 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "third_party/googletest/custom/gtest/internal/custom/chrome_custom_temp_dir.h" +#include "third_party/googletest/src/googletest/include/gtest/internal/gtest-port.h" +#if GTEST_OS_WINDOWS +#include +#endif // GTEST_OS_WINDOWS + +namespace testing { + +namespace { + +// The temporary directory read from the OS canonical environment variable. +// +// Returns an empty string if the environment variable is not set. The returned +// string may or may not end with the OS-specific path separator. The path is +// not guaranteed to point to an existing directory. The directory it points to +// is not guaranteed to be writable by the application. +std::string ChromeGetEnvTempDir() { +#if GTEST_OS_WINDOWS_MOBILE + const char* env_result = internal::posix::GetEnv("TEMP"); +#elif GTEST_OS_WINDOWS + char temp_dir_path[_MAX_PATH + 1] = {'\0'}; // NOLINT + if (::GetTempPathA(sizeof(temp_dir_path), temp_dir_path) != 0) + return temp_dir_path; + const char* env_result = internal::posix::GetEnv("TEMP"); +#else + const char* env_result = internal::posix::GetEnv("TMPDIR"); +#endif // GETST_OS_WINDOWS + + if (env_result == nullptr) + return std::string(); + return env_result; +} + +} // namespace + +// returns temp directory for tests. +std::string ChromeCustomTempDir() { + std::string temp_dir = ChromeGetEnvTempDir(); + if (!temp_dir.empty()) { + if (temp_dir.back() != GTEST_PATH_SEP_[0]) + temp_dir.push_back(GTEST_PATH_SEP_[0]); + return temp_dir; + } + +#if GTEST_OS_WINDOWS_MOBILE || GTEST_OS_WINDOWS + return "\\temp\\"; +#elif GTEST_OS_LINUX_ANDROID + // Android applications are expected to call the framework's + // Context.getExternalStorageDirectory() method through JNI to get the + // location of the world-writable SD Card directory. However, this requires a + // Context handle, which cannot be retrieved globally from native code. Doing + // so also precludes running the code as part of a regular standalone + // executable, which doesn't run in a Dalvik process (e.g. when running it + // through 'adb shell'). + // + // Starting from Android O, the recommended generic temporary directory is + // '/data/local/tmp'. The recommended fallback is the current directory, + // which is usually accessible in app context. + if (::access("/data/local/tmp", R_OK | W_OK | X_OK) == 0) + return "/data/local/tmp/"; + const char* current_dir = ::getcwd(nullptr, 0); + if (current_dir != nullptr && + ::access(current_dir, R_OK | W_OK | X_OK) == 0) { + temp_dir = current_dir; + temp_dir.push_back(GTEST_PATH_SEP_[0]); + return temp_dir; + } + // Before Android O, /sdcard is usually available. + if (::access("/sdcard", R_OK | W_OK | X_OK) == 0) + return "/sdcard/"; + // Generic POSIX fallback. + return "/tmp/"; +#elif GTEST_OS_IOS + char name_template[PATH_MAX + 1]; + + // Documented alternative to NSTemporaryDirectory() (for obtaining creating + // a temporary directory) at + // https://developer.apple.com/library/archive/documentation/Security/Conceptual/SecureCodingGuide/Articles/RaceConditions.html#//apple_ref/doc/uid/TP40002585-SW10 + // + // _CS_DARWIN_USER_TEMP_DIR (as well as _CS_DARWIN_USER_CACHE_DIR) is not + // documented in the confstr() man page at + // https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man3/confstr.3.html#//apple_ref/doc/man/3/confstr + // but are still available, according to the WebKit patches at + // https://trac.webkit.org/changeset/262004/webkit + // https://trac.webkit.org/changeset/263705/webkit + // + // The confstr() implementation falls back to getenv("TMPDIR"). See + // https://opensource.apple.com/source/Libc/Libc-1439.100.3/gen/confstr.c.auto.html + ::confstr(_CS_DARWIN_USER_TEMP_DIR, name_template, sizeof(name_template)); + + temp_dir = name_template; + if (temp_dir.back() != GTEST_PATH_SEP_[0]) + temp_dir.push_back(GTEST_PATH_SEP_[0]); + return temp_dir; +#else + return "/tmp/"; +#endif // GTEST_OS_WINDOWS_MOBILE || GTEST_OS_WINDOWS +} + +} // namespace testing diff --git a/third_party/googletest/custom/gtest/internal/custom/chrome_custom_temp_dir.h b/third_party/googletest/custom/gtest/internal/custom/chrome_custom_temp_dir.h new file mode 100644 index 0000000..2bc907c --- /dev/null +++ b/third_party/googletest/custom/gtest/internal/custom/chrome_custom_temp_dir.h @@ -0,0 +1,15 @@ +// Copyright 2020 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef THIRD_PARTY_GOOGLETEST_CUSTOM_GTEST_INTERNAL_CUSTOM_CHROME_CUSTOM_TEMP_DIR_H_ +#define THIRD_PARTY_GOOGLETEST_CUSTOM_GTEST_INTERNAL_CUSTOM_CHROME_CUSTOM_TEMP_DIR_H_ + +#include + +namespace testing { +// Returns alternate temp directory for gtest. +std::string ChromeCustomTempDir(); +} // namespace testing + +#endif // THIRD_PARTY_GOOGLETEST_CUSTOM_GTEST_INTERNAL_CUSTOM_CHROME_CUSTOM_TEMP_DIR_H_ diff --git a/third_party/googletest/custom/gtest/internal/custom/gtest.h b/third_party/googletest/custom/gtest/internal/custom/gtest.h new file mode 100644 index 0000000..2605358 --- /dev/null +++ b/third_party/googletest/custom/gtest/internal/custom/gtest.h @@ -0,0 +1,23 @@ +// Copyright 2018 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef THIRD_PARTY_GOOGLETEST_CUSTOM_GTEST_INTERNAL_CUSTOM_GTEST_H_ +#define THIRD_PARTY_GOOGLETEST_CUSTOM_GTEST_INTERNAL_CUSTOM_GTEST_H_ + +#include "build/build_config.h" +#include "third_party/googletest/custom/gtest/internal/custom/chrome_custom_temp_dir.h" + +#if !defined(GTEST_DISABLE_PRINT_STACK_TRACE) +#include "third_party/googletest/custom/gtest/internal/custom/stack_trace_getter.h" + +// Tell Google Test to use a stack trace getter based on Chromium's +// base::debug::StackTrace. +#define GTEST_OS_STACK_TRACE_GETTER_ StackTraceGetter +#endif // defined(GTEST_DISABLE_PRINT_STACK_TRACE) + +// TODO(crbug.com/1009553): Remove once googletest android temporary path is +// fixed. +#define GTEST_CUSTOM_TEMPDIR_FUNCTION_ ChromeCustomTempDir + +#endif // THIRD_PARTY_GOOGLETEST_CUSTOM_GTEST_INTERNAL_CUSTOM_GTEST_H_ diff --git a/third_party/googletest/custom/gtest/internal/custom/gtest_port_wrapper.cc b/third_party/googletest/custom/gtest/internal/custom/gtest_port_wrapper.cc new file mode 100644 index 0000000..7cc3ab7 --- /dev/null +++ b/third_party/googletest/custom/gtest/internal/custom/gtest_port_wrapper.cc @@ -0,0 +1,161 @@ +// Copyright 2019 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// TODO(crbug.com/1009553): Remove this wrapper after finding a way to plumb a +// workable temporary path into googletest on Android. + +// This wrapper lets us compile gtest-port.cc without its stream redirection +// code. We replace this code with a variant that works on all Chrome platforms. +// This is a temporary workaround until we get good code upstream. +// +// Stream redirection requires the ability to create files in a temporary +// directory. Traditionally, this directory has been /sdcard on Android. +// Commit bf0fe874a27bd6c9a4a35b98e662d2d02f8879a2 changed the Android +// directory to /data/local/tmp, which is not writable in Chrome's testing +// setup. We work around this problem by using the old code for now. +// +// It is tempting to consider disabling the stream redirection code altogether, +// by setting GTEST_HAS_STREAM_REDIRECTION to 0 in googletest's BUILD.gn. +// This breaks gtest-death-test.cc, which assumes the existence of +// testing::internal::{GetCapturedStderr,CaptureStderr} without any macro +// checking. + +#define GTEST_HAS_STREAM_REDIRECTION 0 +#include "third_party/googletest/src/googletest/src/gtest-port.cc" + +namespace testing { +namespace internal { + +// Verbatim copy from gtest-port.cc, since it only provides these constants when +// GTEST_HAS_STREAM_REDIRECTION is true. +#if defined(_MSC_VER) || defined(__BORLANDC__) +// MSVC and C++Builder do not provide a definition of STDERR_FILENO. +const int kStdOutFileno = 1; +const int kStdErrFileno = 2; +#else +const int kStdOutFileno = STDOUT_FILENO; +const int kStdErrFileno = STDERR_FILENO; +#endif // defined(_MSC_VER) || defined(__BORLANDC__) + +// Object that captures an output stream (stdout/stderr). +class CapturedStream { + public: + // The ctor redirects the stream to a temporary file. + explicit CapturedStream(int fd) : fd_(fd), uncaptured_fd_(dup(fd)) { + std::string temp_dir = ::testing::TempDir(); + + // testing::TempDir() should return a directory with a path separator. + // However, this rule was documented fairly recently, so we normalize across + // implementations with and without a trailing path separator. + if (temp_dir.back() != GTEST_PATH_SEP_[0]) + temp_dir.push_back(GTEST_PATH_SEP_[0]); + +#if GTEST_OS_WINDOWS + char temp_file_path[MAX_PATH + 1] = {'\0'}; // NOLINT + const UINT success = ::GetTempFileNameA(temp_dir.c_str(), "gtest_redir", + 0, // Generate unique file name. + temp_file_path); + GTEST_CHECK_(success != 0) + << "Unable to create a temporary file in " << temp_dir; + const int captured_fd = creat(temp_file_path, _S_IREAD | _S_IWRITE); + GTEST_CHECK_(captured_fd != -1) + << "Unable to open temporary file " << temp_file_path; + filename_ = temp_file_path; +#else + std::string name_template = temp_dir + "gtest_captured_stream.XXXXXX"; + + // mkstemp() modifies the string bytes in place, and does not go beyond the + // string's length. This results in well-defined behavior in C++17. + // + // The const_cast is needed below C++17. The constraints on std::string + // implementations in C++11 and above make assumption behind the const_cast + // fairly safe. + const int captured_fd = ::mkstemp(const_cast(name_template.data())); + GTEST_CHECK_(captured_fd != -1) + << "Failed to create tmp file " << name_template + << " for test; does the test have write access to the directory?"; + filename_ = std::move(name_template); +#endif // GTEST_OS_WINDOWS + fflush(nullptr); + dup2(captured_fd, fd_); + close(captured_fd); + } + + CapturedStream(const CapturedStream&) = delete; + CapturedStream& operator=(const CapturedStream&) = delete; + + ~CapturedStream() { remove(filename_.c_str()); } + + std::string GetCapturedString() { + if (uncaptured_fd_ != -1) { + // Restores the original stream. + fflush(nullptr); + dup2(uncaptured_fd_, fd_); + close(uncaptured_fd_); + uncaptured_fd_ = -1; + } + + FILE* const file = posix::FOpen(filename_.c_str(), "r"); + if (file == nullptr) { + GTEST_LOG_(FATAL) << "Failed to open tmp file " << filename_ + << " for capturing stream."; + } + const std::string content = ReadEntireFile(file); + posix::FClose(file); + return content; + } + + private: + const int fd_; // A stream to capture. + int uncaptured_fd_; + // Name of the temporary file holding the stderr output. + ::std::string filename_; +}; + +static CapturedStream* g_captured_stderr = nullptr; +static CapturedStream* g_captured_stdout = nullptr; + +// Starts capturing an output stream (stdout/stderr). +static void CaptureStream(int fd, + const char* stream_name, + CapturedStream** stream) { + if (*stream != nullptr) { + GTEST_LOG_(FATAL) << "Only one " << stream_name + << " capturer can exist at a time."; + } + *stream = new CapturedStream(fd); +} + +// Stops capturing the output stream and returns the captured string. +static std::string GetCapturedStream(CapturedStream** captured_stream) { + const std::string content = (*captured_stream)->GetCapturedString(); + + delete *captured_stream; + *captured_stream = nullptr; + + return content; +} + +// Starts capturing stdout. +void CaptureStdout() { + CaptureStream(kStdOutFileno, "stdout", &g_captured_stdout); +} + +// Starts capturing stderr. +void CaptureStderr() { + CaptureStream(kStdErrFileno, "stderr", &g_captured_stderr); +} + +// Stops capturing stdout and returns the captured string. +std::string GetCapturedStdout() { + return GetCapturedStream(&g_captured_stdout); +} + +// Stops capturing stderr and returns the captured string. +std::string GetCapturedStderr() { + return GetCapturedStream(&g_captured_stderr); +} + +} // namespace internal +} // namespace testing diff --git a/third_party/googletest/custom/gtest/internal/custom/stack_trace_getter.cc b/third_party/googletest/custom/gtest/internal/custom/stack_trace_getter.cc new file mode 100644 index 0000000..58f6f81 --- /dev/null +++ b/third_party/googletest/custom/gtest/internal/custom/stack_trace_getter.cc @@ -0,0 +1,68 @@ +// Copyright 2018 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "third_party/googletest/custom/gtest/internal/custom/stack_trace_getter.h" + +#include +#include + +#include "base/containers/adapters.h" +#include "base/containers/span.h" +#include "base/ranges/algorithm.h" + +std::string StackTraceGetter::CurrentStackTrace(int max_depth, int skip_count) { + base::debug::StackTrace stack_trace; + + base::span departure; + if (stack_trace_upon_leaving_gtest_.has_value()) { + departure = stack_trace_upon_leaving_gtest_->addresses(); + } + + base::span current = stack_trace.addresses(); + + // Ignore the frames at the root of the current trace that match those of the + // point of departure from GTest. These frames all relate to thread start and + // test setup, and are irrelevant for diagnosing a failure in a given test. + // Also ignore the very first mismatch, as this identifies two instructions + // within the GTest function that called UponLeavingGTest, and is irrelevant + // as well. + { + const auto r_current = base::Reversed(current); + const size_t remaining = + r_current.end() - + std::ranges::mismatch(base::Reversed(departure), r_current).in2; + if (remaining) { + current = current.first(remaining - 1); + } + } + + // Ignore the frames at the leaf of the current trace that match those of the + // point of departure from GTest. These frames are the call(s) into + // StackTrace's constructor, which are irrelevant. Also ignore the very first + // mismatch, as it identifies two instructions within current function. + { + const size_t remaining = + current.end() - std::ranges::mismatch(departure, current).in2; + if (remaining) { + current = current.last(remaining - 1); + } + } + + // Ignore frames that the caller wishes to skip. + if (skip_count >= 0 && static_cast(skip_count) < current.size()) { + current = current.subspan(static_cast(skip_count)); + } + + // Only return as many as requested. + if (max_depth >= 0 && static_cast(max_depth) < current.size()) { + current = current.first(static_cast(max_depth)); + } + + return base::debug::StackTrace(current).ToString(); +} + +void StackTraceGetter::UponLeavingGTest() { + // Remember the callstack as GTest is left. + stack_trace_upon_leaving_gtest_.emplace(); +} diff --git a/third_party/googletest/custom/gtest/internal/custom/stack_trace_getter.h b/third_party/googletest/custom/gtest/internal/custom/stack_trace_getter.h new file mode 100644 index 0000000..a869c6b --- /dev/null +++ b/third_party/googletest/custom/gtest/internal/custom/stack_trace_getter.h @@ -0,0 +1,31 @@ +// Copyright 2018 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef THIRD_PARTY_GOOGLETEST_CUSTOM_GTEST_INTERNAL_CUSTOM_STACK_TRACE_GETTER_H_ +#define THIRD_PARTY_GOOGLETEST_CUSTOM_GTEST_INTERNAL_CUSTOM_STACK_TRACE_GETTER_H_ + +#include + +#include "base/debug/stack_trace.h" +#include "third_party/googletest/src/googletest/src/gtest-internal-inl.h" + +// An implementation of Google Test's OsStackTraceGetterInterface that uses +// Chromium's base::debug::StackTrace to obtain stringified stack traces. +class StackTraceGetter + : public ::testing::internal::OsStackTraceGetterInterface { + public: + StackTraceGetter() = default; + ~StackTraceGetter() override = default; + StackTraceGetter(const StackTraceGetter&) = delete; + StackTraceGetter& operator=(const StackTraceGetter&) = delete; + + // ::testing::internal::OsStackTraceGetterInterface: + std::string CurrentStackTrace(int max_depth, int skip_count) override; + void UponLeavingGTest() override; + + private: + std::optional stack_trace_upon_leaving_gtest_; +}; + +#endif // THIRD_PARTY_GOOGLETEST_CUSTOM_GTEST_INTERNAL_CUSTOM_STACK_TRACE_GETTER_H_ diff --git a/third_party/re2/BUILD.gn b/third_party/re2/BUILD.gn new file mode 100644 index 0000000..da39856 --- /dev/null +++ b/third_party/re2/BUILD.gn @@ -0,0 +1,62 @@ +# Copyright 2014 The Chromium Authors +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +import("//testing/libfuzzer/fuzzer_test.gni") + +config("re2_config") { + include_dirs = [ "src" ] +} + +static_library("re2") { + sources = [ + "src/re2/bitmap256.cc", + "src/re2/bitmap256.h", + "src/re2/bitstate.cc", + "src/re2/compile.cc", + "src/re2/dfa.cc", + "src/re2/filtered_re2.cc", + "src/re2/filtered_re2.h", + "src/re2/mimics_pcre.cc", + "src/re2/nfa.cc", + "src/re2/onepass.cc", + "src/re2/parse.cc", + "src/re2/perl_groups.cc", + "src/re2/prefilter.cc", + "src/re2/prefilter.h", + "src/re2/prefilter_tree.cc", + "src/re2/prefilter_tree.h", + "src/re2/prog.cc", + "src/re2/prog.h", + "src/re2/re2.cc", + "src/re2/re2.h", + "src/re2/regexp.cc", + "src/re2/regexp.h", + "src/re2/set.cc", + "src/re2/set.h", + "src/re2/simplify.cc", + "src/re2/sparse_array.h", + "src/re2/sparse_set.h", + "src/re2/stringpiece.h", + "src/re2/tostring.cc", + "src/re2/unicode_casefold.cc", + "src/re2/unicode_casefold.h", + "src/re2/unicode_groups.cc", + "src/re2/unicode_groups.h", + "src/re2/walker-inl.h", + "src/util/rune.cc", + "src/util/strutil.cc", + "src/util/strutil.h", + "src/util/utf.h", + ] + + configs -= [ "//build/config/compiler:chromium_code" ] + configs += [ "//build/config/compiler:no_chromium_code" ] + public_configs = [ ":re2_config" ] + public_deps = [ "//third_party/abseil-cpp:absl" ] +} + +fuzzer_test("third_party_re2_fuzzer") { + sources = [ "src/re2/fuzzing/re2_fuzzer.cc" ] + deps = [ ":re2" ] +} diff --git a/third_party/re2/DEPS b/third_party/re2/DEPS new file mode 100644 index 0000000..82c266c --- /dev/null +++ b/third_party/re2/DEPS @@ -0,0 +1,7 @@ +include_rules = [ + '+base', + '+build', + '+re2', + '+utest', + '+util', +] diff --git a/third_party/re2/DIR_METADATA b/third_party/re2/DIR_METADATA new file mode 100644 index 0000000..45f7798 --- /dev/null +++ b/third_party/re2/DIR_METADATA @@ -0,0 +1,6 @@ +monorail: { + component: "Internals" +} +buganizer_public: { + component_id: 1456292 +} diff --git a/third_party/re2/LICENSE b/third_party/re2/LICENSE new file mode 100644 index 0000000..09e5ec1 --- /dev/null +++ b/third_party/re2/LICENSE @@ -0,0 +1,27 @@ +// Copyright (c) 2009 The RE2 Authors. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/third_party/re2/OWNERS b/third_party/re2/OWNERS new file mode 100644 index 0000000..e542f4a --- /dev/null +++ b/third_party/re2/OWNERS @@ -0,0 +1,2 @@ +junyer@chromium.org +thakis@chromium.org diff --git a/third_party/re2/README.chromium b/third_party/re2/README.chromium new file mode 100644 index 0000000..e4e6ef7 --- /dev/null +++ b/third_party/re2/README.chromium @@ -0,0 +1,13 @@ +Name: re2 - an efficient, principled regular expression library +Short Name: re2 +URL: https://github.com/google/re2 +Version: 1e44e72d31ddc66b783a545e9d9fcaa876a146b7 +Date: 2023-05-31 +License: BSD-3-Clause +License File: LICENSE +Security Critical: yes +Shipped: yes + +Description: +RE2 is a fast, safe, thread-friendly alternative to backtracking regular +expression engines like those used in PCRE, Perl, and Python. diff --git a/third_party/re2/src b/third_party/re2/src new file mode 160000 index 0000000..6dcd83d --- /dev/null +++ b/third_party/re2/src @@ -0,0 +1 @@ +Subproject commit 6dcd83d60f7944926bfd308cc13979fc53dd69ca diff --git a/tools/gn b/tools/gn index 6c4c1e2..bc68702 160000 --- a/tools/gn +++ b/tools/gn @@ -1 +1 @@ -Subproject commit 6c4c1e2f931b64a0bedc048d1acafef72f32c5af +Subproject commit bc687020094d2b4897468337c94dd6e773cc9fc4