From 9df216cc9d6fd2f27e00e5ba1e88a502d7f278c7 Mon Sep 17 00:00:00 2001 From: Derek Mauro Date: Fri, 12 Sep 2025 06:16:55 -0700 Subject: [PATCH 01/18] Update spelling of Mutex::lock and Mutex::unlock for compatibility with the standard and the latest Abseil PiperOrigin-RevId: 806260850 Change-Id: Ie973be4a3aaf7e174cd692ce6df7a82c8f261bf7 --- .../include/gmock/gmock-spec-builders.h | 4 ++-- googlemock/src/gmock-spec-builders.cc | 4 ++-- .../include/gtest/internal/gtest-port.h | 20 +++++++++---------- googletest/src/gtest-port.cc | 4 ++-- googletest/test/googletest-port-test.cc | 4 ++-- 5 files changed, 18 insertions(+), 18 deletions(-) diff --git a/googlemock/include/gmock/gmock-spec-builders.h b/googlemock/include/gmock/gmock-spec-builders.h index c4c42b7c5..445a3ed85 100644 --- a/googlemock/include/gmock/gmock-spec-builders.h +++ b/googlemock/include/gmock/gmock-spec-builders.h @@ -1530,7 +1530,7 @@ class FunctionMocker final : public UntypedFunctionMockerBase { UntypedOnCallSpecs specs_to_delete; untyped_on_call_specs_.swap(specs_to_delete); - g_gmock_mutex.Unlock(); + g_gmock_mutex.unlock(); for (UntypedOnCallSpecs::const_iterator it = specs_to_delete.begin(); it != specs_to_delete.end(); ++it) { delete static_cast*>(*it); @@ -1538,7 +1538,7 @@ class FunctionMocker final : public UntypedFunctionMockerBase { // Lock the mutex again, since the caller expects it to be locked when we // return. - g_gmock_mutex.Lock(); + g_gmock_mutex.lock(); } // Returns the result of invoking this mock function with the given diff --git a/googlemock/src/gmock-spec-builders.cc b/googlemock/src/gmock-spec-builders.cc index b681fee74..603ad7aa0 100644 --- a/googlemock/src/gmock-spec-builders.cc +++ b/googlemock/src/gmock-spec-builders.cc @@ -436,9 +436,9 @@ bool UntypedFunctionMockerBase::VerifyAndClearExpectationsLocked() UntypedExpectations expectations_to_delete; untyped_expectations_.swap(expectations_to_delete); - g_gmock_mutex.Unlock(); + g_gmock_mutex.unlock(); expectations_to_delete.clear(); - g_gmock_mutex.Lock(); + g_gmock_mutex.lock(); return expectations_met; } diff --git a/googletest/include/gtest/internal/gtest-port.h b/googletest/include/gtest/internal/gtest-port.h index 06a5a8e6f..9bd41cd62 100644 --- a/googletest/include/gtest/internal/gtest-port.h +++ b/googletest/include/gtest/internal/gtest-port.h @@ -1385,9 +1385,9 @@ class GTEST_API_ Mutex { Mutex(); ~Mutex(); - void Lock(); + void lock(); - void Unlock(); + void unlock(); // Does nothing if the current thread holds the mutex. Otherwise, crashes // with high probability. @@ -1424,9 +1424,9 @@ class GTEST_API_ Mutex { // "MutexLock l(&mu)". Hence the typedef trick below. class GTestMutexLock { public: - explicit GTestMutexLock(Mutex* mutex) : mutex_(mutex) { mutex_->Lock(); } + explicit GTestMutexLock(Mutex* mutex) : mutex_(mutex) { mutex_->lock(); } - ~GTestMutexLock() { mutex_->Unlock(); } + ~GTestMutexLock() { mutex_->unlock(); } private: Mutex* const mutex_; @@ -1641,14 +1641,14 @@ class ThreadLocal : public ThreadLocalBase { class MutexBase { public: // Acquires this mutex. - void Lock() { + void lock() { GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_lock(&mutex_)); owner_ = pthread_self(); has_owner_ = true; } // Releases this mutex. - void Unlock() { + void unlock() { // Since the lock is being released the owner_ field should no longer be // considered valid. We don't protect writing to has_owner_ here, as it's // the caller's responsibility to ensure that the current thread holds the @@ -1716,9 +1716,9 @@ class Mutex : public MutexBase { // "MutexLock l(&mu)". Hence the typedef trick below. class GTestMutexLock { public: - explicit GTestMutexLock(MutexBase* mutex) : mutex_(mutex) { mutex_->Lock(); } + explicit GTestMutexLock(MutexBase* mutex) : mutex_(mutex) { mutex_->lock(); } - ~GTestMutexLock() { mutex_->Unlock(); } + ~GTestMutexLock() { mutex_->unlock(); } private: MutexBase* const mutex_; @@ -1864,8 +1864,8 @@ class GTEST_API_ ThreadLocal { class Mutex { public: Mutex() {} - void Lock() {} - void Unlock() {} + void lock() {} + void unlock() {} void AssertHeld() const {} }; diff --git a/googletest/src/gtest-port.cc b/googletest/src/gtest-port.cc index 1038ad7bf..490dbb579 100644 --- a/googletest/src/gtest-port.cc +++ b/googletest/src/gtest-port.cc @@ -320,13 +320,13 @@ Mutex::~Mutex() { } } -void Mutex::Lock() { +void Mutex::lock() { ThreadSafeLazyInit(); ::EnterCriticalSection(critical_section_); owner_thread_id_ = ::GetCurrentThreadId(); } -void Mutex::Unlock() { +void Mutex::unlock() { ThreadSafeLazyInit(); // We don't protect writing to owner_thread_id_ here, as it's the // caller's responsibility to ensure that the current thread holds the diff --git a/googletest/test/googletest-port-test.cc b/googletest/test/googletest-port-test.cc index 9f05a0199..975b2fc33 100644 --- a/googletest/test/googletest-port-test.cc +++ b/googletest/test/googletest-port-test.cc @@ -288,8 +288,8 @@ TEST(FormatCompilerIndependentFileLocationTest, FormatsUknownFileAndLine) { defined(GTEST_OS_OPENBSD) || defined(GTEST_OS_GNU_HURD) void* ThreadFunc(void* data) { internal::Mutex* mutex = static_cast(data); - mutex->Lock(); - mutex->Unlock(); + mutex->lock(); + mutex->unlock(); return nullptr; } From 4969d0ad540da8fc9944e99457361dc7e35943c2 Mon Sep 17 00:00:00 2001 From: Abseil Team Date: Fri, 12 Sep 2025 20:44:26 -0700 Subject: [PATCH 02/18] Automated Code Change PiperOrigin-RevId: 806527439 Change-Id: I2e9aa5de44c011938e0bfc8e86af6c7d10c23ab0 --- googlemock/include/gmock/internal/gmock-internal-utils.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/googlemock/include/gmock/internal/gmock-internal-utils.h b/googlemock/include/gmock/internal/gmock-internal-utils.h index 8fc1ddc7a..487d685a2 100644 --- a/googlemock/include/gmock/internal/gmock-internal-utils.h +++ b/googlemock/include/gmock/internal/gmock-internal-utils.h @@ -298,7 +298,7 @@ GTEST_API_ void Log(LogSeverity severity, const std::string& message, // class WithoutMatchers { private: - WithoutMatchers() {} + WithoutMatchers() = default; friend GTEST_API_ WithoutMatchers GetWithoutMatchers(); }; From 0934b7e112354d609133d2c5f973c402c9efc9b9 Mon Sep 17 00:00:00 2001 From: Derek Mauro Date: Tue, 16 Sep 2025 10:38:37 -0700 Subject: [PATCH 03/18] Use an internal symbol for deprecate-and-inline that allows the use of a deprecation message PiperOrigin-RevId: 807753856 Change-Id: I34b0c7c6faf34cad11ea2aca5ccd16bca16acdec --- googlemock/include/gmock/gmock-actions.h | 8 ++++---- googlemock/include/gmock/internal/gmock-port.h | 13 ++----------- googletest/include/gtest/internal/gtest-port.h | 7 +++++++ 3 files changed, 13 insertions(+), 15 deletions(-) diff --git a/googlemock/include/gmock/gmock-actions.h b/googlemock/include/gmock/gmock-actions.h index 2746edd34..68d5cedad 100644 --- a/googlemock/include/gmock/gmock-actions.h +++ b/googlemock/include/gmock/gmock-actions.h @@ -1868,7 +1868,7 @@ typedef internal::IgnoredValue Unused; // Deprecated single-argument DoAll. template -GMOCK_DEPRECATE_AND_INLINE() +GTEST_INTERNAL_DEPRECATE_AND_INLINE("Avoid using DoAll() for single actions") typename std::decay::type DoAll(Action&& action) { return std::forward(action); } @@ -2038,11 +2038,11 @@ PolymorphicAction> SetErrnoAndReturn( // Various overloads for Invoke(). // Legacy function. -// Actions can now be implicitly constructed from callables. No need to create -// wrapper objects. // This function exists for backwards compatibility. template -GMOCK_DEPRECATE_AND_INLINE() +GTEST_INTERNAL_DEPRECATE_AND_INLINE( + "Actions can now be implicitly constructed from callables. No need to " + "create wrapper objects using Invoke().") typename std::decay::type Invoke(FunctionImpl&& function_impl) { return std::forward(function_impl); } diff --git a/googlemock/include/gmock/internal/gmock-port.h b/googlemock/include/gmock/internal/gmock-port.h index c23b69df9..42d36d2f1 100644 --- a/googlemock/include/gmock/internal/gmock-port.h +++ b/googlemock/include/gmock/internal/gmock-port.h @@ -57,19 +57,10 @@ #include "gmock/internal/custom/gmock-port.h" #include "gtest/internal/gtest-port.h" -#if defined(GTEST_HAS_ABSL) -#include "absl/base/macros.h" - -#define GMOCK_DEPRECATE_AND_INLINE() ABSL_DEPRECATE_AND_INLINE() - -#if !defined(GTEST_NO_ABSL_FLAGS) +#if defined(GTEST_HAS_ABSL) && !defined(GTEST_NO_ABSL_FLAGS) #include "absl/flags/declare.h" #include "absl/flags/flag.h" -#endif // !defined(GTEST_NO_ABSL_FLAGS) - -#else // defined(GTEST_HAS_ABSL) -#define GMOCK_DEPRECATE_AND_INLINE() -#endif // defined(GTEST_HAS_ABSL) +#endif // For MS Visual C++, check the compiler version. At least VS 2015 is // required to compile Google Mock. diff --git a/googletest/include/gtest/internal/gtest-port.h b/googletest/include/gtest/internal/gtest-port.h index 9bd41cd62..f810d0644 100644 --- a/googletest/include/gtest/internal/gtest-port.h +++ b/googletest/include/gtest/internal/gtest-port.h @@ -2322,6 +2322,13 @@ const char* StringFromGTestEnv(const char* flag, const char* default_val); } // namespace internal } // namespace testing +#if GTEST_INTERNAL_HAVE_CPP_ATTRIBUTE(clang::annotate) +#define GTEST_INTERNAL_DEPRECATE_AND_INLINE(msg) \ + [[deprecated(msg), clang::annotate("inline-me")]] +#else +#define GTEST_INTERNAL_DEPRECATE_AND_INLINE(msg) [[deprecated(msg)]] +#endif + #if defined(__cpp_lib_span) || (GTEST_INTERNAL_HAS_INCLUDE() && \ GTEST_INTERNAL_CPLUSPLUS_LANG >= 202002L) #define GTEST_INTERNAL_HAS_STD_SPAN 1 From 50b8600c63c5487e901e2845a0f64d384a65f75d Mon Sep 17 00:00:00 2001 From: Derek Mauro Date: Thu, 18 Sep 2025 11:15:32 -0700 Subject: [PATCH 04/18] Add rules_cc dependency, required by Bazel going forward This also adds the dependencies of rules_cc to WORKSPACE. bzlmod automatically pulls in dependencies. skylib is removed as it is pulled in by a deps function. PiperOrigin-RevId: 808659470 Change-Id: Idc41cad7b05019793d4a1898bdb80bc4797da5cf --- BUILD.bazel | 2 ++ MODULE.bazel | 5 +++++ WORKSPACE | 12 ++++++------ googlemock/test/BUILD.bazel | 1 + googletest/test/BUILD.bazel | 1 + googletest_deps.bzl | 16 ++++++++++++++++ 6 files changed, 31 insertions(+), 6 deletions(-) diff --git a/BUILD.bazel b/BUILD.bazel index 3ca5735db..5ab4e114f 100644 --- a/BUILD.bazel +++ b/BUILD.bazel @@ -30,6 +30,8 @@ # # Bazel Build for Google C++ Testing Framework(Google Test) +load("@rules_cc//cc:defs.bzl", "cc_library", "cc_test") + package(default_visibility = ["//visibility:public"]) licenses(["notice"]) diff --git a/MODULE.bazel b/MODULE.bazel index 5d80b462a..5b32557fc 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -52,6 +52,11 @@ bazel_dep( version = "2024-07-02.bcr.1", ) +bazel_dep( + name = "rules_cc", + version = "0.2.8" +) + bazel_dep( name = "rules_python", version = "1.3.0", diff --git a/WORKSPACE b/WORKSPACE index 0ae5dee92..f004f565d 100644 --- a/WORKSPACE +++ b/WORKSPACE @@ -45,12 +45,6 @@ http_archive( load("@rules_python//python:repositories.bzl", "py_repositories") py_repositories() -http_archive( - name = "bazel_skylib", - sha256 = "cd55a062e763b9349921f0f5db8c3933288dc8ba4f76dd9416aac68acee3cb94", - urls = ["https://github.com/bazelbuild/bazel-skylib/releases/download/1.5.0/bazel-skylib-1.5.0.tar.gz"], -) - http_archive( name = "platforms", urls = [ @@ -59,3 +53,9 @@ http_archive( ], sha256 = "29742e87275809b5e598dc2f04d86960cc7a55b3067d97221c9abbc9926bff0f", ) + +load("@bazel_features//:deps.bzl", "bazel_features_deps") +bazel_features_deps() + +load("@rules_cc//cc:extensions.bzl", "compatibility_proxy_repo") +compatibility_proxy_repo() diff --git a/googlemock/test/BUILD.bazel b/googlemock/test/BUILD.bazel index d4297c80f..27eb53511 100644 --- a/googlemock/test/BUILD.bazel +++ b/googlemock/test/BUILD.bazel @@ -30,6 +30,7 @@ # # Bazel Build for Google C++ Testing Framework(Google Test)-googlemock +load("@rules_cc//cc:defs.bzl", "cc_binary", "cc_test") load("@rules_python//python:defs.bzl", "py_library", "py_test") licenses(["notice"]) diff --git a/googletest/test/BUILD.bazel b/googletest/test/BUILD.bazel index c561ef8b9..9575ae11a 100644 --- a/googletest/test/BUILD.bazel +++ b/googletest/test/BUILD.bazel @@ -30,6 +30,7 @@ # # Bazel BUILD for The Google C++ Testing Framework (Google Test) +load("@rules_cc//cc:defs.bzl", "cc_binary", "cc_test") load("@rules_python//python:defs.bzl", "py_library", "py_test") licenses(["notice"]) diff --git a/googletest_deps.bzl b/googletest_deps.bzl index e5fc4be4f..9b5c041ea 100644 --- a/googletest_deps.bzl +++ b/googletest_deps.bzl @@ -22,6 +22,22 @@ def googletest_deps(): urls = ["https://github.com/abseil/abseil-cpp/releases/download/20250814.0/abseil-cpp-20250814.0.tar.gz"], ) + if not native.existing_rule("bazel_features"): + http_archive( + name = "bazel_features", + sha256 = "9390b391a68d3b24aef7966bce8556d28003fe3f022a5008efc7807e8acaaf1a", + strip_prefix = "bazel_features-1.36.0", + url = "https://github.com/bazel-contrib/bazel_features/releases/download/v1.36.0/bazel_features-v1.36.0.tar.gz", + ) + + if not native.existing_rule("rules_cc"): + http_archive( + name = "rules_cc", + sha256 = "207ea073dd20a705f9e8bc5ac02f5203e9621fc672774bb1a0935aefab7aebfa", + strip_prefix = "rules_cc-0.2.8", + url = "https://github.com/bazelbuild/rules_cc/releases/download/0.2.8/rules_cc-0.2.8.tar.gz", + ) + if not native.existing_rule("fuchsia_sdk"): fake_fuchsia_sdk( name = "fuchsia_sdk", From 9706f75b8f91c52a3840cf5d878a7f37ea10ef00 Mon Sep 17 00:00:00 2001 From: Abseil Team Date: Mon, 29 Sep 2025 20:04:59 -0700 Subject: [PATCH 05/18] Automated Code Change PiperOrigin-RevId: 813050069 Change-Id: I7c778db5bda5d681097af5d3569b5f4b980603e4 --- googletest/test/googletest-param-test-test.cc | 2 +- googletest/test/googletest-printers-test.cc | 2 +- googletest/test/gtest_stress_test.cc | 4 ++-- googletest/test/gtest_unittest.cc | 14 ++++++-------- 4 files changed, 10 insertions(+), 12 deletions(-) diff --git a/googletest/test/googletest-param-test-test.cc b/googletest/test/googletest-param-test-test.cc index fab977e07..10d429c9a 100644 --- a/googletest/test/googletest-param-test-test.cc +++ b/googletest/test/googletest-param-test-test.cc @@ -696,7 +696,7 @@ class TestGenerationEnvironment : public ::testing::Environment { msg << "TestsExpandedAndRun/" << i; if (UnitTestOptions::FilterMatchesTest( "TestExpansionModule/MultipleTestGenerationTest", - msg.GetString().c_str())) { + msg.GetString())) { perform_check = true; } } diff --git a/googletest/test/googletest-printers-test.cc b/googletest/test/googletest-printers-test.cc index c5d9756d5..7d7e933e2 100644 --- a/googletest/test/googletest-printers-test.cc +++ b/googletest/test/googletest-printers-test.cc @@ -1699,7 +1699,7 @@ TEST(PrintToStringTest, ContainsNonLatin) { EXPECT_PRINT_TO_STRING_(non_ascii_str, "\"\\xEC\\x98\\xA4\\xEC\\xA0\\x84 4:30\"\n" " As Text: \"오전 4:30\""); - non_ascii_str = ::std::string("From ä — ẑ"); + non_ascii_str = "From ä — ẑ"; EXPECT_PRINT_TO_STRING_(non_ascii_str, "\"From \\xC3\\xA4 \\xE2\\x80\\x94 \\xE1\\xBA\\x91\"" "\n As Text: \"From ä — ẑ\""); diff --git a/googletest/test/gtest_stress_test.cc b/googletest/test/gtest_stress_test.cc index af8e757dc..daebd4322 100644 --- a/googletest/test/gtest_stress_test.cc +++ b/googletest/test/gtest_stress_test.cc @@ -95,9 +95,9 @@ void ManyAsserts(int id) { // RecordProperty() should interact safely with other threads as well. // The shared_key forces property updates. - Test::RecordProperty(IdToKey(id, "string").c_str(), IdToString(id).c_str()); + Test::RecordProperty(IdToKey(id, "string"), IdToString(id)); Test::RecordProperty(IdToKey(id, "int").c_str(), id); - Test::RecordProperty("shared_key", IdToString(id).c_str()); + Test::RecordProperty("shared_key", IdToString(id)); // This assertion should fail kThreadCount times per thread. It // is for testing whether Google Test can handle failed assertions in a diff --git a/googletest/test/gtest_unittest.cc b/googletest/test/gtest_unittest.cc index a31b7ba0b..3680b918b 100644 --- a/googletest/test/gtest_unittest.cc +++ b/googletest/test/gtest_unittest.cc @@ -2649,8 +2649,8 @@ TEST(IsSubstringTest, GeneratesCorrectMessageForCString) { // Tests that IsSubstring returns the correct result when the input // argument type is ::std::string. TEST(IsSubstringTest, ReturnsCorrectResultsForStdString) { - EXPECT_TRUE(IsSubstring("", "", std::string("hello"), "ahellob")); - EXPECT_FALSE(IsSubstring("", "", "hello", std::string("world"))); + EXPECT_TRUE(IsSubstring("", "", "hello", "ahellob")); + EXPECT_FALSE(IsSubstring("", "", "hello", "world")); } #if GTEST_HAS_STD_WSTRING @@ -2707,8 +2707,8 @@ TEST(IsNotSubstringTest, GeneratesCorrectMessageForWideCString) { // Tests that IsNotSubstring returns the correct result when the input // argument type is ::std::string. TEST(IsNotSubstringTest, ReturnsCorrectResultsForStdString) { - EXPECT_FALSE(IsNotSubstring("", "", std::string("hello"), "ahellob")); - EXPECT_TRUE(IsNotSubstring("", "", "hello", std::string("world"))); + EXPECT_FALSE(IsNotSubstring("", "", "hello", "ahellob")); + EXPECT_TRUE(IsNotSubstring("", "", "hello", "world")); } // Tests that IsNotSubstring() generates the correct message when the input @@ -2719,8 +2719,7 @@ TEST(IsNotSubstringTest, GeneratesCorrectMessageForStdString) { " Actual: \"needle\"\n" "Expected: not a substring of haystack_expr\n" "Which is: \"two needles\"", - IsNotSubstring("needle_expr", "haystack_expr", ::std::string("needle"), - "two needles") + IsNotSubstring("needle_expr", "haystack_expr", "needle", "two needles") .failure_message()); } @@ -3655,8 +3654,7 @@ TEST(AssertionTest, EqFailure) { msg4.c_str()); const std::string msg5( - EqFailure("foo", "bar", std::string("\"x\""), std::string("\"y\""), true) - .failure_message()); + EqFailure("foo", "bar", "\"x\"", "\"y\"", true).failure_message()); EXPECT_STREQ( "Expected equality of these values:\n" " foo\n" From de1c60926218478959040ad79be8b2dbed22bd2b Mon Sep 17 00:00:00 2001 From: Abseil Team Date: Tue, 7 Oct 2025 06:38:47 -0700 Subject: [PATCH 06/18] Automated Code Change PiperOrigin-RevId: 816182689 Change-Id: Ie2aaa55be6c2e4508aaafa7a0b30fe52ec334893 --- googletest/include/gtest/gtest-matchers.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/googletest/include/gtest/gtest-matchers.h b/googletest/include/gtest/gtest-matchers.h index 93643dba1..bd8dfe999 100644 --- a/googletest/include/gtest/gtest-matchers.h +++ b/googletest/include/gtest/gtest-matchers.h @@ -296,12 +296,12 @@ class MatcherBase : private MatcherDescriberInterface { return *this; } - MatcherBase(MatcherBase&& other) + MatcherBase(MatcherBase&& other) noexcept : vtable_(other.vtable_), buffer_(other.buffer_) { other.vtable_ = nullptr; } - MatcherBase& operator=(MatcherBase&& other) { + MatcherBase& operator=(MatcherBase&& other) noexcept { if (this == &other) return *this; Destroy(); vtable_ = other.vtable_; From 279f8479469d22fa772adb454068f854472e1eb9 Mon Sep 17 00:00:00 2001 From: Abseil Team Date: Tue, 7 Oct 2025 16:02:53 -0700 Subject: [PATCH 07/18] Fix typo. PiperOrigin-RevId: 816417379 Change-Id: I4ccfe2bf291b8c2b318ac6e2d0c2d176684e42c8 --- docs/gmock_cheat_sheet.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/gmock_cheat_sheet.md b/docs/gmock_cheat_sheet.md index ddafaaa22..62159998b 100644 --- a/docs/gmock_cheat_sheet.md +++ b/docs/gmock_cheat_sheet.md @@ -130,7 +130,7 @@ TEST(BarTest, DoesThis) { ## Setting Default Actions {#OnCall} gMock has a **built-in default action** for any function that returns `void`, -`bool`, a numeric value, or a pointer. In C++11, it will additionally returns +`bool`, a numeric value, or a pointer. In C++11, it additionally returns the default-constructed value, if one exists for the given type. To customize the default action for functions with return type `T`, use From 2ce9d8f2e85550a94d6ac977c881fe3658129ac6 Mon Sep 17 00:00:00 2001 From: Abseil Team Date: Mon, 13 Oct 2025 06:50:27 -0700 Subject: [PATCH 08/18] Allow for passing non-pointers to DeleteArg and have them emit a deprecation warning instead. This allows for simpler migration of function args to smart pointers without needing all changes to tests to be atomic. PiperOrigin-RevId: 818635600 Change-Id: I9434685d9640f82b98d0b5261701b78c93d3ec1e --- googlemock/include/gmock/gmock-actions.h | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/googlemock/include/gmock/gmock-actions.h b/googlemock/include/gmock/gmock-actions.h index 68d5cedad..fe3b41ca8 100644 --- a/googlemock/include/gmock/gmock-actions.h +++ b/googlemock/include/gmock/gmock-actions.h @@ -1796,11 +1796,24 @@ struct SetArrayArgumentAction { }; template -struct DeleteArgAction { +class DeleteArgAction { + public: template void operator()(const Args&... args) const { - delete std::get(std::tie(args...)); + DoDelete(std::get(std::tie(args...))); } + + private: + template + static void DoDelete(T* ptr) { + delete ptr; + } + + template + [[deprecated( + "DeleteArg used for a non-pointer argument, it was likely migrated " + "to a smart pointer type. This action should be removed.")]] + static void DoDelete(T&) {} }; template From 8dbd60f7d5f88aca74ef76f4dd5258d35c324199 Mon Sep 17 00:00:00 2001 From: Abseil Team Date: Mon, 13 Oct 2025 13:43:39 -0700 Subject: [PATCH 09/18] Restore the documentation of `AnyWith(m)` in the matchers reference. PiperOrigin-RevId: 818813216 Change-Id: If4cb881a61a05b2c6634aa0d5ee66ea2962f168a --- docs/reference/matchers.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/reference/matchers.md b/docs/reference/matchers.md index 8b3d1405a..4c234e17c 100644 --- a/docs/reference/matchers.md +++ b/docs/reference/matchers.md @@ -49,6 +49,7 @@ Matcher | Description | `NotNull()` | `argument` is a non-null pointer (raw or smart). | | `Optional(m)` | `argument` is `optional<>` that contains a value matching `m`. (For testing whether an `optional<>` is set, check for equality with `nullopt`. You may need to use `Eq(nullopt)` if the inner type doesn't have `==`.)| | `VariantWith(m)` | `argument` is `variant<>` that holds the alternative of type T with a value matching `m`. | +| `AnyWith(m)` | `argument` is `any<>` that holds a value of type T with a value matching `m`. | | `Ref(variable)` | `argument` is a reference to `variable`. | | `TypedEq(value)` | `argument` has type `type` and is equal to `value`. You may need to use this instead of `Eq(value)` when the mock function is overloaded. | From e17e37a1151a47d6e8089f2e9a78921ac022a511 Mon Sep 17 00:00:00 2001 From: Abseil Team Date: Wed, 15 Oct 2025 21:01:25 -0700 Subject: [PATCH 10/18] Automated Code Change PiperOrigin-RevId: 820039898 Change-Id: I910d8ec41198794e7344a2d79566a19243532251 --- googlemock/test/gmock-actions_test.cc | 4 ++-- googlemock/test/gmock-matchers-arithmetic_test.cc | 6 +++--- googlemock/test/gmock-matchers-containers_test.cc | 6 +++--- googlemock/test/gmock-matchers-misc_test.cc | 8 ++++---- 4 files changed, 12 insertions(+), 12 deletions(-) diff --git a/googlemock/test/gmock-actions_test.cc b/googlemock/test/gmock-actions_test.cc index 975170539..6200611c1 100644 --- a/googlemock/test/gmock-actions_test.cc +++ b/googlemock/test/gmock-actions_test.cc @@ -1822,7 +1822,7 @@ std::vector> VectorUniquePtrSource() { TEST(MockMethodTest, CanReturnMoveOnlyValue_Return) { MockClass mock; - std::unique_ptr i(new int(19)); + std::unique_ptr i = std::make_unique(19); EXPECT_CALL(mock, MakeUnique()).WillOnce(Return(ByMove(std::move(i)))); EXPECT_CALL(mock, MakeVectorUnique()) .WillOnce(Return(ByMove(VectorUniquePtrSource()))); @@ -1845,7 +1845,7 @@ TEST(MockMethodTest, CanReturnMoveOnlyValue_Return) { TEST(MockMethodTest, CanReturnMoveOnlyValue_DoAllReturn) { testing::MockFunction mock_function; MockClass mock; - std::unique_ptr i(new int(19)); + std::unique_ptr i = std::make_unique(19); EXPECT_CALL(mock_function, Call()); EXPECT_CALL(mock, MakeUnique()) .WillOnce(DoAll(InvokeWithoutArgs(&mock_function, diff --git a/googlemock/test/gmock-matchers-arithmetic_test.cc b/googlemock/test/gmock-matchers-arithmetic_test.cc index b6c35119e..c4c91b8b3 100644 --- a/googlemock/test/gmock-matchers-arithmetic_test.cc +++ b/googlemock/test/gmock-matchers-arithmetic_test.cc @@ -1625,7 +1625,7 @@ TEST_F(DoubleNearTest, NanSensitiveDoubleNearCanMatchNaN) { } TEST(NotTest, WorksOnMoveOnlyType) { - std::unique_ptr p(new int(3)); + std::unique_ptr p = std::make_unique(3); EXPECT_THAT(p, Pointee(Eq(3))); EXPECT_THAT(p, Not(Pointee(Eq(2)))); } @@ -1681,13 +1681,13 @@ TEST(AnyOfTest, DoesNotCallAnyOfUnqualified) { } // namespace adl_test TEST(AllOfTest, WorksOnMoveOnlyType) { - std::unique_ptr p(new int(3)); + std::unique_ptr p = std::make_unique(3); EXPECT_THAT(p, AllOf(Pointee(Eq(3)), Pointee(Gt(0)), Pointee(Lt(5)))); EXPECT_THAT(p, Not(AllOf(Pointee(Eq(3)), Pointee(Gt(0)), Pointee(Lt(3))))); } TEST(AnyOfTest, WorksOnMoveOnlyType) { - std::unique_ptr p(new int(3)); + std::unique_ptr p = std::make_unique(3); EXPECT_THAT(p, AnyOf(Pointee(Eq(5)), Pointee(Lt(0)), Pointee(Lt(5)))); EXPECT_THAT(p, Not(AnyOf(Pointee(Eq(5)), Pointee(Lt(0)), Pointee(Gt(5))))); } diff --git a/googlemock/test/gmock-matchers-containers_test.cc b/googlemock/test/gmock-matchers-containers_test.cc index e9f1a02d8..c3b3ef03f 100644 --- a/googlemock/test/gmock-matchers-containers_test.cc +++ b/googlemock/test/gmock-matchers-containers_test.cc @@ -217,7 +217,7 @@ TEST(PointeeTest, ReferenceToNonConstRawPointer) { TEST(PointeeTest, SmartPointer) { const Matcher> m = Pointee(Ge(0)); - std::unique_ptr n(new int(1)); + std::unique_ptr n = std::make_unique(1); EXPECT_TRUE(m.Matches(n)); } @@ -254,7 +254,7 @@ TEST(PointerTest, RawPointerToConst) { } TEST(PointerTest, SmartPointer) { - std::unique_ptr n(new int(10)); + std::unique_ptr n = std::make_unique(10); int* raw_n = n.get(); const Matcher> m = Pointer(Eq(raw_n)); @@ -2796,7 +2796,7 @@ TEST(UnorderedPointwiseTest, WorksWithMoveOnly) { } TEST(PointeeTest, WorksOnMoveOnlyType) { - std::unique_ptr p(new int(3)); + std::unique_ptr p = std::make_unique(3); EXPECT_THAT(p, Pointee(Eq(3))); EXPECT_THAT(p, Not(Pointee(Eq(2)))); } diff --git a/googlemock/test/gmock-matchers-misc_test.cc b/googlemock/test/gmock-matchers-misc_test.cc index de8b76c69..0161169f2 100644 --- a/googlemock/test/gmock-matchers-misc_test.cc +++ b/googlemock/test/gmock-matchers-misc_test.cc @@ -79,7 +79,7 @@ TEST(AddressTest, Const) { } TEST(AddressTest, MatcherDoesntCopy) { - std::unique_ptr n(new int(1)); + std::unique_ptr n = std::make_unique(1); const Matcher> m = Address(Eq(&n)); EXPECT_TRUE(m.Matches(n)); @@ -202,7 +202,7 @@ TEST(IsTrueTest, IsTrueIsFalse) { EXPECT_THAT(nullptr, Not(IsTrue())); EXPECT_THAT(nullptr, IsFalse()); std::unique_ptr null_unique; - std::unique_ptr nonnull_unique(new int(0)); + std::unique_ptr nonnull_unique = std::make_unique(0); EXPECT_THAT(null_unique, Not(IsTrue())); EXPECT_THAT(null_unique, IsFalse()); EXPECT_THAT(nonnull_unique, IsTrue()); @@ -1665,7 +1665,7 @@ MATCHER(IsNotNull, "") { return arg != nullptr; } // Verifies that a matcher defined using MATCHER() can work on // move-only types. TEST(MatcherMacroTest, WorksOnMoveOnlyType) { - std::unique_ptr p(new int(3)); + std::unique_ptr p = std::make_unique(3); EXPECT_THAT(p, IsNotNull()); EXPECT_THAT(std::unique_ptr(), Not(IsNotNull())); } @@ -1675,7 +1675,7 @@ MATCHER_P(UniquePointee, pointee, "") { return *arg == pointee; } // Verifies that a matcher defined using MATCHER_P*() can work on // move-only types. TEST(MatcherPMacroTest, WorksOnMoveOnlyType) { - std::unique_ptr p(new int(3)); + std::unique_ptr p = std::make_unique(3); EXPECT_THAT(p, UniquePointee(3)); EXPECT_THAT(p, Not(UniquePointee(2))); } From b2b9072ecbe874f5937054653ef8f2731eb0f010 Mon Sep 17 00:00:00 2001 From: Abseil Team Date: Thu, 16 Oct 2025 06:31:04 -0700 Subject: [PATCH 11/18] Mark InternalDefaultActionSetAt as nodiscard. PiperOrigin-RevId: 820207225 Change-Id: I8e053f724c18b466bd287f80a720542a535615d2 --- googlemock/include/gmock/gmock-spec-builders.h | 8 ++++---- googlemock/test/gmock-internal-utils_test.cc | 4 ++-- googlemock/test/gmock-spec-builders_test.cc | 8 ++++---- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/googlemock/include/gmock/gmock-spec-builders.h b/googlemock/include/gmock/gmock-spec-builders.h index 445a3ed85..e861817f4 100644 --- a/googlemock/include/gmock/gmock-spec-builders.h +++ b/googlemock/include/gmock/gmock-spec-builders.h @@ -1292,10 +1292,10 @@ class MockSpec { : function_mocker_(function_mocker), matchers_(matchers) {} // Adds a new default action spec to the function mocker and returns - // the newly created spec. - internal::OnCallSpec& InternalDefaultActionSetAt(const char* file, - int line, const char* obj, - const char* call) { + // the newly created spec. .WillByDefault() must be called on the returned + // object. + [[nodiscard]] internal::OnCallSpec& InternalDefaultActionSetAt( + const char* file, int line, const char* obj, const char* call) { LogWithLocation(internal::kInfo, file, line, std::string("ON_CALL(") + obj + ", " + call + ") invoked"); return function_mocker_->AddNewOnCallSpec(file, line, matchers_); diff --git a/googlemock/test/gmock-internal-utils_test.cc b/googlemock/test/gmock-internal-utils_test.cc index 6c769a882..7cffd18a3 100644 --- a/googlemock/test/gmock-internal-utils_test.cc +++ b/googlemock/test/gmock-internal-utils_test.cc @@ -545,7 +545,7 @@ TEST(ExpectCallTest, DoesNotLogWhenVerbosityIsError) { void OnCallLogger() { DummyMock mock; - ON_CALL(mock, TestMethod()); + (void)ON_CALL(mock, TestMethod()); } // Verifies that ON_CALL logs if the --gmock_verbose flag is set to "info". @@ -568,7 +568,7 @@ TEST(OnCallTest, DoesNotLogWhenVerbosityIsError) { void OnCallAnyArgumentLogger() { DummyMock mock; - ON_CALL(mock, TestMethodArg(_)); + (void)ON_CALL(mock, TestMethodArg(_)); } // Verifies that ON_CALL prints provided _ argument. diff --git a/googlemock/test/gmock-spec-builders_test.cc b/googlemock/test/gmock-spec-builders_test.cc index 90f00c22a..287b249dc 100644 --- a/googlemock/test/gmock-spec-builders_test.cc +++ b/googlemock/test/gmock-spec-builders_test.cc @@ -160,7 +160,7 @@ class MockCC : public CC { // Tests that a method with expanded name compiles. TEST(OnCallSyntaxTest, CompilesWithMethodNameExpandedFromMacro) { MockCC cc; - ON_CALL(cc, Method()); + (void)ON_CALL(cc, Method()); } // Tests that the method with expanded name not only compiles but runs @@ -193,7 +193,7 @@ TEST(OnCallSyntaxTest, EvaluatesFirstArgumentOnce) { MockA a; MockA* pa = &a; - ON_CALL(*pa++, DoA(_)); + (void)ON_CALL(*pa++, DoA(_)); EXPECT_EQ(&a + 1, pa); } @@ -201,7 +201,7 @@ TEST(OnCallSyntaxTest, EvaluatesSecondArgumentOnce) { MockA a; int n = 0; - ON_CALL(a, DoA(n++)); + (void)ON_CALL(a, DoA(n++)); EXPECT_EQ(1, n); } @@ -232,7 +232,7 @@ TEST(OnCallSyntaxTest, WillByDefaultIsMandatory) { EXPECT_DEATH_IF_SUPPORTED( { - ON_CALL(a, DoA(5)); + (void)ON_CALL(a, DoA(5)); a.DoA(5); }, ""); From 4fe3307fb2d9f86d19777c7eb0e4809e9694dde7 Mon Sep 17 00:00:00 2001 From: Derek Mauro Date: Thu, 30 Oct 2025 10:10:42 -0700 Subject: [PATCH 12/18] macOS CI: Move the Bazel vendor_dir to ${HOME} to workaround a Bazel issue where it does not work when it is in ${TMP} and also fix the quoting which was causing it to incorrectly receive the argument https://github.com/bazelbuild/bazel/issues/27156 PiperOrigin-RevId: 826083231 Change-Id: If8f069c42c62434893db27bdaae0b0e25b67839d --- ci/macos-presubmit.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ci/macos-presubmit.sh b/ci/macos-presubmit.sh index 63cf81484..12c8d2bd9 100644 --- a/ci/macos-presubmit.sh +++ b/ci/macos-presubmit.sh @@ -66,8 +66,8 @@ fi # Use Bazel Vendor mode to reduce reliance on external dependencies. if [[ ${KOKORO_GFILE_DIR:-} ]] && [[ -f "${KOKORO_GFILE_DIR}/distdir/googletest_vendor.tar.gz" ]]; then - tar -xf "${KOKORO_GFILE_DIR}/distdir/googletest_vendor.tar.gz" -C "${TMP}/" - BAZEL_EXTRA_ARGS="--vendor_dir=\"${TMP}/googletest_vendor\" ${BAZEL_EXTRA_ARGS:-}" + tar -xf "${KOKORO_GFILE_DIR}/distdir/googletest_vendor.tar.gz" -C "${HOME}/" + BAZEL_EXTRA_ARGS="--vendor_dir=${HOME}/googletest_vendor ${BAZEL_EXTRA_ARGS:-}" fi cd ${GTEST_ROOT} From 17d335d7c7f15d989516255471c3d7f5d204308d Mon Sep 17 00:00:00 2001 From: Justin Bassett Date: Thu, 30 Oct 2025 21:51:50 -0700 Subject: [PATCH 13/18] Remove short-circuiting from AllOf, for better failure messages For `EXPECT_THAT` matcher usage, showing only the first failure meant that users would sometimes have to make a fix and run the test again only to notice that there's another failure. It's better to show more failures so that the user can fix several issues in one go. In practice, very little code actually wants the short circuiting here, only a handful of cases with custom matchers used like `AllOf(BoundsCheck(), UncheckedAccess())`. These cases are fixable by refactoring `UncheckedAccess()` to instead also apply a bounds check to fail the matcher rather than crash. Notably, this change doesn't affect `AnyOf`, so another workaround is to change `AllOf(m1, m2, ...)` into `Not(AnyOf(Not(m1), Not(m2), ...))`. PiperOrigin-RevId: 826316273 Change-Id: Ie8186f75c10443d8da35b5d07b6a8cd9ae85b451 --- googlemock/include/gmock/gmock-matchers.h | 14 +++++++++++--- googlemock/test/gmock-matchers-arithmetic_test.cc | 3 ++- googlemock/test/gmock-matchers-comparisons_test.cc | 11 ++++------- 3 files changed, 17 insertions(+), 11 deletions(-) diff --git a/googlemock/include/gmock/gmock-matchers.h b/googlemock/include/gmock/gmock-matchers.h index 236d3e5f0..666baaf79 100644 --- a/googlemock/include/gmock/gmock-matchers.h +++ b/googlemock/include/gmock/gmock-matchers.h @@ -1329,17 +1329,23 @@ class AllOfMatcherImpl : public MatcherInterface { // However, if matcher doesn't provide one, this method uses matcher's // description. std::string all_match_result; + bool success = true; for (const Matcher& matcher : matchers_) { StringMatchResultListener slistener; // Return explanation for first failed matcher. if (!matcher.MatchAndExplain(x, &slistener)) { const std::string explanation = slistener.str(); + if (!success) { + // Already had a failure. + *listener << ", and "; + } if (!explanation.empty()) { *listener << explanation; } else { *listener << "which doesn't match (" << Describe(matcher) << ")"; } - return false; + success = false; + continue; } // Keep track of explanations in case all matchers succeed. std::string explanation = slistener.str(); @@ -1356,8 +1362,10 @@ class AllOfMatcherImpl : public MatcherInterface { } } - *listener << all_match_result; - return true; + if (success) { + *listener << all_match_result; + } + return success; } private: diff --git a/googlemock/test/gmock-matchers-arithmetic_test.cc b/googlemock/test/gmock-matchers-arithmetic_test.cc index c4c91b8b3..40a170467 100644 --- a/googlemock/test/gmock-matchers-arithmetic_test.cc +++ b/googlemock/test/gmock-matchers-arithmetic_test.cc @@ -770,7 +770,8 @@ TEST_P(AllOfTestP, ExplainsResult) { // Failed match. The first matcher, which failed, needs to // explain. m = AllOf(GreaterThan(10), GreaterThan(20)); - EXPECT_EQ("which is 5 less than 10", Explain(m, 5)); + EXPECT_EQ("which is 5 less than 10, and which is 15 less than 20", + Explain(m, 5)); // Failed match. The second matcher, which failed, needs to // explain. Since it doesn't given an explanation, the matcher text is diff --git a/googlemock/test/gmock-matchers-comparisons_test.cc b/googlemock/test/gmock-matchers-comparisons_test.cc index 413c2bb0e..cd2b80a0e 100644 --- a/googlemock/test/gmock-matchers-comparisons_test.cc +++ b/googlemock/test/gmock-matchers-comparisons_test.cc @@ -2389,22 +2389,19 @@ PolymorphicMatcher DivisibleBy(int n) { return MakePolymorphicMatcher(DivisibleByImpl(n)); } -// Tests that when AllOf() fails, only the first failing matcher is -// asked to explain why. +// Tests that when AllOf() fails, all failing matchers are asked to explain why. TEST(ExplainMatchResultTest, AllOf_False_False) { const Matcher m = AllOf(DivisibleBy(4), DivisibleBy(3)); - EXPECT_EQ("which is 1 modulo 4", Explain(m, 5)); + EXPECT_EQ("which is 1 modulo 4, and which is 2 modulo 3", Explain(m, 5)); } -// Tests that when AllOf() fails, only the first failing matcher is -// asked to explain why. +// Tests that when AllOf() fails, all failing matchers are asked to explain why. TEST(ExplainMatchResultTest, AllOf_False_True) { const Matcher m = AllOf(DivisibleBy(4), DivisibleBy(3)); EXPECT_EQ("which is 2 modulo 4", Explain(m, 6)); } -// Tests that when AllOf() fails, only the first failing matcher is -// asked to explain why. +// Tests that when AllOf() fails, all failing matchers are asked to explain why. TEST(ExplainMatchResultTest, AllOf_True_False) { const Matcher m = AllOf(Ge(1), DivisibleBy(3)); EXPECT_EQ("which is 2 modulo 3", Explain(m, 5)); From 6ec14dfd8c409d05fba94e18e3a02df35b874353 Mon Sep 17 00:00:00 2001 From: Abseil Team Date: Fri, 31 Oct 2025 13:55:24 -0700 Subject: [PATCH 14/18] Modernize example of combining matchers. As of C++14 an ordinary function can have an `auto` return type. PiperOrigin-RevId: 826617761 Change-Id: I2ceecc8430643c0ac7843fb216b5a117cfe10ab3 --- docs/gmock_cook_book.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/docs/gmock_cook_book.md b/docs/gmock_cook_book.md index 9e59b4cf4..22ad02148 100644 --- a/docs/gmock_cook_book.md +++ b/docs/gmock_cook_book.md @@ -900,15 +900,16 @@ using ::testing::Not; Matchers are function objects, and parametrized matchers can be composed just like any other function. However because their types can be long and rarely -provide meaningful information, it can be easier to express them with C++14 -generic lambdas to avoid specifying types. For example, +provide meaningful information, it can be easier to express them with template +parameters and `auto`. For example, ```cpp using ::testing::Contains; using ::testing::Property; -inline constexpr auto HasFoo = [](const auto& f) { - return Property("foo", &MyClass::foo, Contains(f)); +template +inline constexpr auto HasFoo(const SubMatcher& sub_matcher) { + return Property("foo", &MyClass::foo, Contains(sub_matcher)); }; ... EXPECT_THAT(x, HasFoo("blah")); From dedab73a689243743c868748ba7f8c4b03316f89 Mon Sep 17 00:00:00 2001 From: David Pizzuto Date: Fri, 7 Nov 2025 16:02:11 -0800 Subject: [PATCH 15/18] gtest_fail_if_no_test_selected: Rephrase error message. Sharded tests interact awkwardly with --gtest_fail_if_no_test_selected, but we can't speak clearly enough to the use cases to complicate the mental model, so instead we attempt to clarify the simplest approach to debugging a single test when sharding and --gtest_fail_if_no_test_selected are both in use: unset the flag. PiperOrigin-RevId: 829609266 Change-Id: I090d5bfac979171532249e9312feef8d9aad5f16 --- googletest/src/gtest.cc | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/googletest/src/gtest.cc b/googletest/src/gtest.cc index cd218c9b0..76b49e903 100644 --- a/googletest/src/gtest.cc +++ b/googletest/src/gtest.cc @@ -6088,15 +6088,17 @@ bool UnitTestImpl::RunAllTests() { repeater->OnEnvironmentsTearDownEnd(*parent_); } } else if (GTEST_FLAG_GET(fail_if_no_test_selected)) { - // If there were no tests to run, bail if we were requested to be strict. + // If there were no tests to run, bail if we were requested to be + // strict. constexpr char kNoTestsSelectedMessage[] = - "No tests were selected to run. Please make sure at least one test " - "exists and is not disabled! If the test is sharded, you may have " - "defined more shards than test cases, which is wasteful. If you also " - "defined --gtest_filter, that filter is taken into account, so " - "shards with no matching test cases will hit this error. Either " - "disable sharding, set --gtest_fail_if_no_test_selected=false, or " - "remove the filter to resolve this error."; + "No tests ran. Check that tests exist and are not disabled or " + "filtered out.\n\n" + "For sharded runs, this error indicates an empty shard. This can " + "happen if you have more shards than tests, or if --gtest_filter " + "leaves a shard with no tests.\n\n" + "To permit empty shards (e.g., when debugging with a filter), " + "specify \n" + "--gtest_fail_if_no_test_selected=false."; ColoredPrintf(GTestColor::kRed, "%s\n", kNoTestsSelectedMessage); return false; } From 37678c92fb183b148163dd173430b4ab88586a26 Mon Sep 17 00:00:00 2001 From: Abseil Team Date: Fri, 7 Nov 2025 20:49:55 -0800 Subject: [PATCH 16/18] gtest_fail_if_no_test_selected: Rephrase error message. Sharded tests interact awkwardly with --gtest_fail_if_no_test_selected, but we can't speak clearly enough to the use cases to complicate the mental model, so instead we attempt to clarify the simplest approach to debugging a single test when sharding and --gtest_fail_if_no_test_selected are both in use: unset the flag. PiperOrigin-RevId: 829686145 Change-Id: I9ebbddc6e7537feefe2a3707fd323fc9132b99d1 --- googletest/src/gtest.cc | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/googletest/src/gtest.cc b/googletest/src/gtest.cc index 76b49e903..cd218c9b0 100644 --- a/googletest/src/gtest.cc +++ b/googletest/src/gtest.cc @@ -6088,17 +6088,15 @@ bool UnitTestImpl::RunAllTests() { repeater->OnEnvironmentsTearDownEnd(*parent_); } } else if (GTEST_FLAG_GET(fail_if_no_test_selected)) { - // If there were no tests to run, bail if we were requested to be - // strict. + // If there were no tests to run, bail if we were requested to be strict. constexpr char kNoTestsSelectedMessage[] = - "No tests ran. Check that tests exist and are not disabled or " - "filtered out.\n\n" - "For sharded runs, this error indicates an empty shard. This can " - "happen if you have more shards than tests, or if --gtest_filter " - "leaves a shard with no tests.\n\n" - "To permit empty shards (e.g., when debugging with a filter), " - "specify \n" - "--gtest_fail_if_no_test_selected=false."; + "No tests were selected to run. Please make sure at least one test " + "exists and is not disabled! If the test is sharded, you may have " + "defined more shards than test cases, which is wasteful. If you also " + "defined --gtest_filter, that filter is taken into account, so " + "shards with no matching test cases will hit this error. Either " + "disable sharding, set --gtest_fail_if_no_test_selected=false, or " + "remove the filter to resolve this error."; ColoredPrintf(GTestColor::kRed, "%s\n", kNoTestsSelectedMessage); return false; } From 085af2cc08600bdb13827ca40261abcbe5048bb5 Mon Sep 17 00:00:00 2001 From: Abseil Team Date: Sat, 8 Nov 2025 02:52:45 -0800 Subject: [PATCH 17/18] Automated rollback of commit 37678c92fb183b148163dd173430b4ab88586a26. PiperOrigin-RevId: 829765029 Change-Id: Ia5534b109e0abfd17a74d89ce58d6588a6255f94 --- googletest/src/gtest.cc | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/googletest/src/gtest.cc b/googletest/src/gtest.cc index cd218c9b0..76b49e903 100644 --- a/googletest/src/gtest.cc +++ b/googletest/src/gtest.cc @@ -6088,15 +6088,17 @@ bool UnitTestImpl::RunAllTests() { repeater->OnEnvironmentsTearDownEnd(*parent_); } } else if (GTEST_FLAG_GET(fail_if_no_test_selected)) { - // If there were no tests to run, bail if we were requested to be strict. + // If there were no tests to run, bail if we were requested to be + // strict. constexpr char kNoTestsSelectedMessage[] = - "No tests were selected to run. Please make sure at least one test " - "exists and is not disabled! If the test is sharded, you may have " - "defined more shards than test cases, which is wasteful. If you also " - "defined --gtest_filter, that filter is taken into account, so " - "shards with no matching test cases will hit this error. Either " - "disable sharding, set --gtest_fail_if_no_test_selected=false, or " - "remove the filter to resolve this error."; + "No tests ran. Check that tests exist and are not disabled or " + "filtered out.\n\n" + "For sharded runs, this error indicates an empty shard. This can " + "happen if you have more shards than tests, or if --gtest_filter " + "leaves a shard with no tests.\n\n" + "To permit empty shards (e.g., when debugging with a filter), " + "specify \n" + "--gtest_fail_if_no_test_selected=false."; ColoredPrintf(GTestColor::kRed, "%s\n", kNoTestsSelectedMessage); return false; } From 1b96fa13f549387b7549cc89e1a785cf143a1a50 Mon Sep 17 00:00:00 2001 From: Derek Mauro Date: Tue, 11 Nov 2025 18:56:19 -0800 Subject: [PATCH 18/18] Switch to referenceful lock holder for Abseil compatibility PiperOrigin-RevId: 831156684 Change-Id: I8a8b017ec2fc318a65f57e04428c030c707ee682 --- .../include/gmock/gmock-spec-builders.h | 4 +-- googlemock/src/gmock-internal-utils.cc | 2 +- googlemock/src/gmock-spec-builders.cc | 28 +++++++++---------- .../include/gtest/internal/gtest-port.h | 16 +++++------ googletest/src/gtest-port.cc | 6 ++-- googletest/src/gtest.cc | 26 ++++++++--------- googletest/test/googletest-port-test.cc | 14 ++++++---- 7 files changed, 48 insertions(+), 48 deletions(-) diff --git a/googlemock/include/gmock/gmock-spec-builders.h b/googlemock/include/gmock/gmock-spec-builders.h index e861817f4..f1c979d6f 100644 --- a/googlemock/include/gmock/gmock-spec-builders.h +++ b/googlemock/include/gmock/gmock-spec-builders.h @@ -1467,7 +1467,7 @@ class FunctionMocker final : public UntypedFunctionMockerBase { // function have been satisfied. If not, it will report Google Test // non-fatal failures for the violations. ~FunctionMocker() override GTEST_LOCK_EXCLUDED_(g_gmock_mutex) { - MutexLock l(&g_gmock_mutex); + MutexLock l(g_gmock_mutex); VerifyAndClearExpectationsLocked(); Mock::UnregisterLocked(this); ClearDefaultActionsLocked(); @@ -1646,7 +1646,7 @@ class FunctionMocker final : public UntypedFunctionMockerBase { GTEST_LOCK_EXCLUDED_(g_gmock_mutex) { const ArgumentTuple& args = *static_cast(untyped_args); - MutexLock l(&g_gmock_mutex); + MutexLock l(g_gmock_mutex); TypedExpectation* exp = this->FindMatchingExpectationLocked(args); if (exp == nullptr) { // A match wasn't found. this->FormatUnexpectedCallMessageLocked(args, what, why); diff --git a/googlemock/src/gmock-internal-utils.cc b/googlemock/src/gmock-internal-utils.cc index 96c7e306e..ceee329a8 100644 --- a/googlemock/src/gmock-internal-utils.cc +++ b/googlemock/src/gmock-internal-utils.cc @@ -156,7 +156,7 @@ GTEST_API_ void Log(LogSeverity severity, const std::string& message, if (!LogIsVisible(severity)) return; // Ensures that logs from different threads don't interleave. - MutexLock l(&g_log_mutex); + MutexLock l(g_log_mutex); if (severity == kWarning) { // Prints a GMOCK WARNING marker to make the warnings easily searchable. diff --git a/googlemock/src/gmock-spec-builders.cc b/googlemock/src/gmock-spec-builders.cc index 603ad7aa0..88e0c0200 100644 --- a/googlemock/src/gmock-spec-builders.cc +++ b/googlemock/src/gmock-spec-builders.cc @@ -212,7 +212,7 @@ void ExpectationBase::CheckActionCountIfNotDone() const GTEST_LOCK_EXCLUDED_(mutex_) { bool should_check = false; { - MutexLock l(&mutex_); + MutexLock l(mutex_); if (!action_count_checked_) { action_count_checked_ = true; should_check = true; @@ -318,7 +318,7 @@ UntypedFunctionMockerBase::~UntypedFunctionMockerBase() = default; void UntypedFunctionMockerBase::RegisterOwner(const void* mock_obj) GTEST_LOCK_EXCLUDED_(g_gmock_mutex) { { - MutexLock l(&g_gmock_mutex); + MutexLock l(g_gmock_mutex); mock_obj_ = mock_obj; } Mock::Register(mock_obj, this); @@ -332,7 +332,7 @@ void UntypedFunctionMockerBase::SetOwnerAndName(const void* mock_obj, GTEST_LOCK_EXCLUDED_(g_gmock_mutex) { // We protect name_ under g_gmock_mutex in case this mock function // is called from two threads concurrently. - MutexLock l(&g_gmock_mutex); + MutexLock l(g_gmock_mutex); mock_obj_ = mock_obj; name_ = name; } @@ -345,7 +345,7 @@ const void* UntypedFunctionMockerBase::MockObject() const { // We protect mock_obj_ under g_gmock_mutex in case this mock // function is called from two threads concurrently. - MutexLock l(&g_gmock_mutex); + MutexLock l(g_gmock_mutex); Assert(mock_obj_ != nullptr, __FILE__, __LINE__, "MockObject() must not be called before RegisterOwner() or " "SetOwnerAndName() has been called."); @@ -362,7 +362,7 @@ const char* UntypedFunctionMockerBase::Name() const { // We protect name_ under g_gmock_mutex in case this mock // function is called from two threads concurrently. - MutexLock l(&g_gmock_mutex); + MutexLock l(g_gmock_mutex); Assert(name_ != nullptr, __FILE__, __LINE__, "Name() must not be called before SetOwnerAndName() has " "been called."); @@ -490,7 +490,7 @@ class MockObjectRegistry { // failure, unless the user explicitly asked us to ignore it. ~MockObjectRegistry() { if (!GMOCK_FLAG_GET(catch_leaked_mocks)) return; - internal::MutexLock l(&internal::g_gmock_mutex); + internal::MutexLock l(internal::g_gmock_mutex); int leaked_count = 0; for (StateMap::const_iterator it = states_.begin(); it != states_.end(); @@ -559,7 +559,7 @@ UninterestingCallReactionMap() { void SetReactionOnUninterestingCalls(uintptr_t mock_obj, internal::CallReaction reaction) GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) { - internal::MutexLock l(&internal::g_gmock_mutex); + internal::MutexLock l(internal::g_gmock_mutex); UninterestingCallReactionMap()[mock_obj] = reaction; } @@ -590,7 +590,7 @@ void Mock::FailUninterestingCalls(uintptr_t mock_obj) // entry in the call-reaction table should be removed. void Mock::UnregisterCallReaction(uintptr_t mock_obj) GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) { - internal::MutexLock l(&internal::g_gmock_mutex); + internal::MutexLock l(internal::g_gmock_mutex); UninterestingCallReactionMap().erase(static_cast(mock_obj)); } @@ -598,7 +598,7 @@ void Mock::UnregisterCallReaction(uintptr_t mock_obj) // made on the given mock object. internal::CallReaction Mock::GetReactionOnUninterestingCalls( const void* mock_obj) GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) { - internal::MutexLock l(&internal::g_gmock_mutex); + internal::MutexLock l(internal::g_gmock_mutex); return (UninterestingCallReactionMap().count( reinterpret_cast(mock_obj)) == 0) ? internal::intToCallReaction( @@ -611,7 +611,7 @@ internal::CallReaction Mock::GetReactionOnUninterestingCalls( // objects. void Mock::AllowLeak(const void* mock_obj) GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) { - internal::MutexLock l(&internal::g_gmock_mutex); + internal::MutexLock l(internal::g_gmock_mutex); g_mock_object_registry.states()[mock_obj].leakable = true; } @@ -620,7 +620,7 @@ void Mock::AllowLeak(const void* mock_obj) // Test non-fatal failures and returns false. bool Mock::VerifyAndClearExpectations(void* mock_obj) GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) { - internal::MutexLock l(&internal::g_gmock_mutex); + internal::MutexLock l(internal::g_gmock_mutex); return VerifyAndClearExpectationsLocked(mock_obj); } @@ -629,7 +629,7 @@ bool Mock::VerifyAndClearExpectations(void* mock_obj) // verification was successful. bool Mock::VerifyAndClear(void* mock_obj) GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) { - internal::MutexLock l(&internal::g_gmock_mutex); + internal::MutexLock l(internal::g_gmock_mutex); ClearDefaultActionsLocked(mock_obj); return VerifyAndClearExpectationsLocked(mock_obj); } @@ -679,7 +679,7 @@ bool Mock::IsStrict(void* mock_obj) void Mock::Register(const void* mock_obj, internal::UntypedFunctionMockerBase* mocker) GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) { - internal::MutexLock l(&internal::g_gmock_mutex); + internal::MutexLock l(internal::g_gmock_mutex); g_mock_object_registry.states()[mock_obj].function_mockers.insert(mocker); } @@ -689,7 +689,7 @@ void Mock::Register(const void* mock_obj, void Mock::RegisterUseByOnCallOrExpectCall(const void* mock_obj, const char* file, int line) GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) { - internal::MutexLock l(&internal::g_gmock_mutex); + internal::MutexLock l(internal::g_gmock_mutex); MockObjectState& state = g_mock_object_registry.states()[mock_obj]; if (state.first_used_file == nullptr) { state.first_used_file = file; diff --git a/googletest/include/gtest/internal/gtest-port.h b/googletest/include/gtest/internal/gtest-port.h index f810d0644..d433f0545 100644 --- a/googletest/include/gtest/internal/gtest-port.h +++ b/googletest/include/gtest/internal/gtest-port.h @@ -1424,12 +1424,11 @@ class GTEST_API_ Mutex { // "MutexLock l(&mu)". Hence the typedef trick below. class GTestMutexLock { public: - explicit GTestMutexLock(Mutex* mutex) : mutex_(mutex) { mutex_->lock(); } - - ~GTestMutexLock() { mutex_->unlock(); } + explicit GTestMutexLock(Mutex& mutex) : mutex_(mutex) { mutex_.lock(); } + ~GTestMutexLock() { mutex_.unlock(); } private: - Mutex* const mutex_; + Mutex& mutex_; GTestMutexLock(const GTestMutexLock&) = delete; GTestMutexLock& operator=(const GTestMutexLock&) = delete; @@ -1716,12 +1715,11 @@ class Mutex : public MutexBase { // "MutexLock l(&mu)". Hence the typedef trick below. class GTestMutexLock { public: - explicit GTestMutexLock(MutexBase* mutex) : mutex_(mutex) { mutex_->lock(); } - - ~GTestMutexLock() { mutex_->unlock(); } + explicit GTestMutexLock(MutexBase& mutex) : mutex_(mutex) { mutex_.lock(); } + ~GTestMutexLock() { mutex_.unlock(); } private: - MutexBase* const mutex_; + MutexBase& mutex_; GTestMutexLock(const GTestMutexLock&) = delete; GTestMutexLock& operator=(const GTestMutexLock&) = delete; @@ -1881,7 +1879,7 @@ class Mutex { // "MutexLock l(&mu)". Hence the typedef trick below. class GTestMutexLock { public: - explicit GTestMutexLock(Mutex*) {} // NOLINT + explicit GTestMutexLock(Mutex&) {} // NOLINT }; typedef GTestMutexLock MutexLock; diff --git a/googletest/src/gtest-port.cc b/googletest/src/gtest-port.cc index 490dbb579..d50d07cdb 100644 --- a/googletest/src/gtest-port.cc +++ b/googletest/src/gtest-port.cc @@ -499,7 +499,7 @@ class ThreadLocalRegistryImpl { MemoryIsNotDeallocated memory_is_not_deallocated; #endif // _MSC_VER DWORD current_thread = ::GetCurrentThreadId(); - MutexLock lock(&mutex_); + MutexLock lock(mutex_); ThreadIdToThreadLocals* const thread_to_thread_locals = GetThreadLocalsMapLocked(); ThreadIdToThreadLocals::iterator thread_local_pos = @@ -532,7 +532,7 @@ class ThreadLocalRegistryImpl { // Clean up the ThreadLocalValues data structure while holding the lock, but // defer the destruction of the ThreadLocalValueHolderBases. { - MutexLock lock(&mutex_); + MutexLock lock(mutex_); ThreadIdToThreadLocals* const thread_to_thread_locals = GetThreadLocalsMapLocked(); for (ThreadIdToThreadLocals::iterator it = @@ -559,7 +559,7 @@ class ThreadLocalRegistryImpl { // Clean up the ThreadIdToThreadLocals data structure while holding the // lock, but defer the destruction of the ThreadLocalValueHolderBases. { - MutexLock lock(&mutex_); + MutexLock lock(mutex_); ThreadIdToThreadLocals* const thread_to_thread_locals = GetThreadLocalsMapLocked(); ThreadIdToThreadLocals::iterator thread_local_pos = diff --git a/googletest/src/gtest.cc b/googletest/src/gtest.cc index 76b49e903..80a7edad9 100644 --- a/googletest/src/gtest.cc +++ b/googletest/src/gtest.cc @@ -1086,14 +1086,14 @@ void DefaultPerThreadTestPartResultReporter::ReportTestPartResult( // Returns the global test part result reporter. TestPartResultReporterInterface* UnitTestImpl::GetGlobalTestPartResultReporter() { - internal::MutexLock lock(&global_test_part_result_reporter_mutex_); + internal::MutexLock lock(global_test_part_result_reporter_mutex_); return global_test_part_result_reporter_; } // Sets the global test part result reporter. void UnitTestImpl::SetGlobalTestPartResultReporter( TestPartResultReporterInterface* reporter) { - internal::MutexLock lock(&global_test_part_result_reporter_mutex_); + internal::MutexLock lock(global_test_part_result_reporter_mutex_); global_test_part_result_reporter_ = reporter; } @@ -2347,7 +2347,7 @@ void TestResult::RecordProperty(const std::string& xml_element, if (!ValidateTestProperty(xml_element, test_property)) { return; } - internal::MutexLock lock(&test_properties_mutex_); + internal::MutexLock lock(test_properties_mutex_); const std::vector::iterator property_with_matching_key = std::find_if(test_properties_.begin(), test_properties_.end(), internal::TestPropertyKeyIs(test_property.key())); @@ -5088,7 +5088,7 @@ std::string OsStackTraceGetter::CurrentStackTrace(int max_depth, int skip_count) void* caller_frame = nullptr; { - MutexLock lock(&mutex_); + MutexLock lock(mutex_); caller_frame = caller_frame_; } @@ -5127,7 +5127,7 @@ void OsStackTraceGetter::UponLeavingGTest() GTEST_LOCK_EXCLUDED_(mutex_) { caller_frame = nullptr; } - MutexLock lock(&mutex_); + MutexLock lock(mutex_); caller_frame_ = caller_frame; #endif // GTEST_HAS_ABSL } @@ -5390,13 +5390,13 @@ void UnitTest::UponLeavingGTest() { // Sets the TestSuite object for the test that's currently running. void UnitTest::set_current_test_suite(TestSuite* a_current_test_suite) { - internal::MutexLock lock(&mutex_); + internal::MutexLock lock(mutex_); impl_->set_current_test_suite(a_current_test_suite); } // Sets the TestInfo object for the test that's currently running. void UnitTest::set_current_test_info(TestInfo* a_current_test_info) { - internal::MutexLock lock(&mutex_); + internal::MutexLock lock(mutex_); impl_->set_current_test_info(a_current_test_info); } @@ -5435,7 +5435,7 @@ void UnitTest::AddTestPartResult(TestPartResult::Type result_type, Message msg; msg << message; - internal::MutexLock lock(&mutex_); + internal::MutexLock lock(mutex_); if (!impl_->gtest_trace_stack().empty()) { msg << "\n" << GTEST_NAME_ << " trace:"; @@ -5618,7 +5618,7 @@ const char* UnitTest::original_working_dir() const { // or NULL if no test is running. const TestSuite* UnitTest::current_test_suite() const GTEST_LOCK_EXCLUDED_(mutex_) { - internal::MutexLock lock(&mutex_); + internal::MutexLock lock(mutex_); return impl_->current_test_suite(); } @@ -5626,7 +5626,7 @@ const TestSuite* UnitTest::current_test_suite() const #ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_ const TestCase* UnitTest::current_test_case() const GTEST_LOCK_EXCLUDED_(mutex_) { - internal::MutexLock lock(&mutex_); + internal::MutexLock lock(mutex_); return impl_->current_test_suite(); } #endif @@ -5635,7 +5635,7 @@ const TestCase* UnitTest::current_test_case() const // or NULL if no test is running. const TestInfo* UnitTest::current_test_info() const GTEST_LOCK_EXCLUDED_(mutex_) { - internal::MutexLock lock(&mutex_); + internal::MutexLock lock(mutex_); return impl_->current_test_info(); } @@ -5659,13 +5659,13 @@ UnitTest::~UnitTest() { delete impl_; } // Google Test trace stack. void UnitTest::PushGTestTrace(const internal::TraceInfo& trace) GTEST_LOCK_EXCLUDED_(mutex_) { - internal::MutexLock lock(&mutex_); + internal::MutexLock lock(mutex_); impl_->gtest_trace_stack().push_back(trace); } // Pops a trace from the per-thread Google Test trace stack. void UnitTest::PopGTestTrace() GTEST_LOCK_EXCLUDED_(mutex_) { - internal::MutexLock lock(&mutex_); + internal::MutexLock lock(mutex_); impl_->gtest_trace_stack().pop_back(); } diff --git a/googletest/test/googletest-port-test.cc b/googletest/test/googletest-port-test.cc index 975b2fc33..24fcd9d93 100644 --- a/googletest/test/googletest-port-test.cc +++ b/googletest/test/googletest-port-test.cc @@ -308,7 +308,7 @@ TEST(GetThreadCountTest, ReturnsCorrectValue) { internal::Mutex mutex; { - internal::MutexLock lock(&mutex); + internal::MutexLock lock(mutex); pthread_attr_t attr; ASSERT_EQ(0, pthread_attr_init(&attr)); ASSERT_EQ(0, pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE)); @@ -1028,7 +1028,9 @@ TEST(MutexDeathTest, AssertHeldShouldAssertWhenNotLocked) { EXPECT_DEATH_IF_SUPPORTED( { Mutex m; - { MutexLock lock(&m); } + { + MutexLock lock(m); + } m.AssertHeld(); }, "thread .*hold"); @@ -1036,13 +1038,13 @@ TEST(MutexDeathTest, AssertHeldShouldAssertWhenNotLocked) { TEST(MutexTest, AssertHeldShouldNotAssertWhenLocked) { Mutex m; - MutexLock lock(&m); + MutexLock lock(m); m.AssertHeld(); } class AtomicCounterWithMutex { public: - explicit AtomicCounterWithMutex(Mutex* mutex) + explicit AtomicCounterWithMutex(Mutex& mutex) : value_(0), mutex_(mutex), random_(42) {} void Increment() { @@ -1083,7 +1085,7 @@ class AtomicCounterWithMutex { private: volatile int value_; - Mutex* const mutex_; // Protects value_. + Mutex& mutex_; // Protects value_. Random random_; }; @@ -1094,7 +1096,7 @@ void CountingThreadFunc(pair param) { // Tests that the mutex only lets one thread at a time to lock it. TEST(MutexTest, OnlyOneThreadCanLockAtATime) { Mutex mutex; - AtomicCounterWithMutex locked_counter(&mutex); + AtomicCounterWithMutex locked_counter(mutex); typedef ThreadWithParam > ThreadType; const int kCycleCount = 20;