From 3326dd6b9838c2a87541ff2fb9e0c4a40e86ec08 Mon Sep 17 00:00:00 2001 From: xgbtxy <115146404+xgbtxy@users.noreply.github.com> Date: Wed, 21 Oct 2026 01:08:20 +0800 Subject: [PATCH 1/2] GH-47442: [C++] Use one bundled GoogleTest runtime on MSVC --- cpp/cmake_modules/ThirdpartyToolchain.cmake | 17 +++++++++++++---- cpp/src/arrow/CMakeLists.txt | 3 +++ cpp/src/arrow/scalar_test.cc | 9 --------- cpp/src/arrow/testing/gtest_util_test.cc | 10 +++++++--- 4 files changed, 23 insertions(+), 16 deletions(-) diff --git a/cpp/cmake_modules/ThirdpartyToolchain.cmake b/cpp/cmake_modules/ThirdpartyToolchain.cmake index 01e1ab147af7..b7cc1ffccbb9 100644 --- a/cpp/cmake_modules/ThirdpartyToolchain.cmake +++ b/cpp/cmake_modules/ThirdpartyToolchain.cmake @@ -2765,11 +2765,20 @@ if(ARROW_TESTING) set(ARROW_GTEST_GMOCK_MAIN GTest::gmock_main) else() string(APPEND ARROW_TESTING_PC_CFLAGS " -I\${includedir}/arrow-gtest") - string(APPEND ARROW_TESTING_PC_LIBS " -larrow_gtest") + if(MSVC) + # Google Mock DLLs embed GoogleTest on MSVC. Helpers and runners must use + # the same DLL so assertion failures reach the active test reporter. + string(APPEND ARROW_TESTING_PC_LIBS " -larrow_gmock_main") + set(ARROW_GTEST_GMOCK arrow::GTest::gmock_main) + set(ARROW_GTEST_GTEST arrow::GTest::gmock_main) + set(ARROW_GTEST_GTEST_MAIN arrow::GTest::gmock_main) + else() + string(APPEND ARROW_TESTING_PC_LIBS " -larrow_gtest") + set(ARROW_GTEST_GMOCK arrow::GTest::gmock) + set(ARROW_GTEST_GTEST arrow::GTest::gtest) + set(ARROW_GTEST_GTEST_MAIN arrow::GTest::gtest_main) + endif() set(ARROW_GTEST_GTEST_HEADERS arrow::GTest::gtest_headers) - set(ARROW_GTEST_GMOCK arrow::GTest::gmock) - set(ARROW_GTEST_GTEST arrow::GTest::gtest) - set(ARROW_GTEST_GTEST_MAIN arrow::GTest::gtest_main) set(ARROW_GTEST_GMOCK_MAIN arrow::GTest::gmock_main) endif() endif() diff --git a/cpp/src/arrow/CMakeLists.txt b/cpp/src/arrow/CMakeLists.txt index 7c6313c326b5..c45a78a82478 100644 --- a/cpp/src/arrow/CMakeLists.txt +++ b/cpp/src/arrow/CMakeLists.txt @@ -742,6 +742,9 @@ set(ARROW_TESTING_STATIC_INSTALL_INTERFACE_LIBS Arrow::arrow_static) if(GTest_SOURCE STREQUAL "SYSTEM") list(APPEND ARROW_TESTING_SHARED_INSTALL_INTERFACE_LIBS ${ARROW_GTEST_GTEST}) list(APPEND ARROW_TESTING_STATIC_INSTALL_INTERFACE_LIBS ${ARROW_GTEST_GTEST}) +elseif(MSVC) + list(APPEND ARROW_TESTING_SHARED_INSTALL_INTERFACE_LIBS ArrowTesting::gmock_main) + list(APPEND ARROW_TESTING_STATIC_INSTALL_INTERFACE_LIBS ArrowTesting::gmock_main) else() list(APPEND ARROW_TESTING_SHARED_INSTALL_INTERFACE_LIBS ArrowTesting::gtest) list(APPEND ARROW_TESTING_STATIC_INSTALL_INTERFACE_LIBS ArrowTesting::gtest) diff --git a/cpp/src/arrow/scalar_test.cc b/cpp/src/arrow/scalar_test.cc index 9594e8883b34..7e60f7b46744 100644 --- a/cpp/src/arrow/scalar_test.cc +++ b/cpp/src/arrow/scalar_test.cc @@ -585,8 +585,6 @@ TEST(TestRealScalarUlpDistance, Double) { // context. static auto options = EqualOptions::Defaults(); AssertScalarsEqual(0.9999999999999988, 1.0000000000000007, options.ulp_distance(14)); -#ifndef _WIN32 - // GH-47442 EXPECT_FATAL_FAILURE(AssertScalarsEqual(0.9999999999999988, 1.0000000000000007, options.ulp_distance(13)), ""); @@ -598,14 +596,11 @@ TEST(TestRealScalarUlpDistance, Double) { AssertScalarsEqual(0.9999999999999988, std::numeric_limits::quiet_NaN(), options.ulp_distance(14).nans_equal(false)), ""); -#endif } TEST(TestRealScalarUlpDistance, Float) { static auto options = EqualOptions::Defaults(); AssertScalarsEqual(123.456f, 123.456085f, options.ulp_distance(11)); -#ifndef _WIN32 - // GH-47442 EXPECT_FATAL_FAILURE( AssertScalarsEqual(123.456f, 123.456085f, options.ulp_distance(10)), ""); EXPECT_FATAL_FAILURE( @@ -616,14 +611,11 @@ TEST(TestRealScalarUlpDistance, Float) { AssertScalarsEqual(123.456f, std::numeric_limits::quiet_NaN(), options.ulp_distance(11).nans_equal(false)), ""); -#endif } TEST(TestRealScalarUlpDistance, HalfFloat) { static auto options = EqualOptions::Defaults(); AssertScalarsEqual(Float16(1.00097656), Float16(0.999511719f), options.ulp_distance(2)); -#ifndef _WIN32 - // GH-47442 EXPECT_FATAL_FAILURE(AssertScalarsEqual(Float16(1.00097656), Float16(0.999511719f), options.ulp_distance(1)), ""); @@ -635,7 +627,6 @@ TEST(TestRealScalarUlpDistance, HalfFloat) { AssertScalarsEqual(Float16(1.00097656), std::numeric_limits::quiet_NaN(), options.ulp_distance(2).nans_equal(false)), ""); -#endif } template diff --git a/cpp/src/arrow/testing/gtest_util_test.cc b/cpp/src/arrow/testing/gtest_util_test.cc index f8bf694f5c36..2802f28f6b34 100644 --- a/cpp/src/arrow/testing/gtest_util_test.cc +++ b/cpp/src/arrow/testing/gtest_util_test.cc @@ -38,6 +38,13 @@ namespace arrow::util { +TEST(TestAssertionReporting, ArrayEqualityFailure) { + // The exported helper must report to the same GoogleTest runtime as this test. + EXPECT_FATAL_FAILURE( + AssertArraysEqual(*ArrayFromJSON(int32(), "[1]"), *ArrayFromJSON(int32(), "[2]")), + ""); +} + // Test basic cases for contains NaN. class TestAssertContainsNaN : public ::testing::Test {}; @@ -206,14 +213,11 @@ TEST(AssertTestWithinUlp, Basics) { std::numeric_limits::quiet_NaN(), 2); AssertWithinUlp(std::numeric_limits::quiet_NaN(), std::numeric_limits::quiet_NaN(), 2); -#ifndef _WIN32 - // GH-47442 EXPECT_FATAL_FAILURE(AssertWithinUlp(123.4567, 123.45670000000015, 10), "not within 10 ulps"); EXPECT_FATAL_FAILURE(AssertWithinUlp(123.456f, 123.456085f, 10), "not within 10 ulps"); EXPECT_FATAL_FAILURE(AssertWithinUlp(Float16(123.456f), Float16(124.143501f), 10), "not within 10 ulps"); -#endif } } // namespace arrow::util From 9093000b9c85e616ed0c2b5bdd2312c3b016571a Mon Sep 17 00:00:00 2001 From: xgbtxy <115146404+xgbtxy@users.noreply.github.com> Date: Wed, 21 Oct 2026 02:18:41 +0800 Subject: [PATCH 2/2] GH-47442: Limit reporter checks for static GoogleTest on Windows Keep negative assertion capture disabled when Windows links static GoogleTest into both shared ArrowTesting and the runner. Continue checking shared GoogleTest and static ArrowTesting configurations, and explicitly skip the reporter test for separate runtimes. Generated-by: OpenAI Codex --- cpp/src/arrow/scalar_test.cc | 10 ++++++++++ cpp/src/arrow/testing/gtest_util_test.cc | 9 +++++++++ 2 files changed, 19 insertions(+) diff --git a/cpp/src/arrow/scalar_test.cc b/cpp/src/arrow/scalar_test.cc index 7e60f7b46744..d75261030521 100644 --- a/cpp/src/arrow/scalar_test.cc +++ b/cpp/src/arrow/scalar_test.cc @@ -585,6 +585,9 @@ TEST(TestRealScalarUlpDistance, Double) { // context. static auto options = EqualOptions::Defaults(); AssertScalarsEqual(0.9999999999999988, 1.0000000000000007, options.ulp_distance(14)); +#if !defined(_WIN32) || defined(ARROW_TESTING_STATIC) || \ + (defined(GTEST_LINKED_AS_SHARED_LIBRARY) && GTEST_LINKED_AS_SHARED_LIBRARY) + // GH-47442: A static GoogleTest runtime is separate in each Windows DLL. EXPECT_FATAL_FAILURE(AssertScalarsEqual(0.9999999999999988, 1.0000000000000007, options.ulp_distance(13)), ""); @@ -596,11 +599,14 @@ TEST(TestRealScalarUlpDistance, Double) { AssertScalarsEqual(0.9999999999999988, std::numeric_limits::quiet_NaN(), options.ulp_distance(14).nans_equal(false)), ""); +#endif } TEST(TestRealScalarUlpDistance, Float) { static auto options = EqualOptions::Defaults(); AssertScalarsEqual(123.456f, 123.456085f, options.ulp_distance(11)); +#if !defined(_WIN32) || defined(ARROW_TESTING_STATIC) || \ + (defined(GTEST_LINKED_AS_SHARED_LIBRARY) && GTEST_LINKED_AS_SHARED_LIBRARY) EXPECT_FATAL_FAILURE( AssertScalarsEqual(123.456f, 123.456085f, options.ulp_distance(10)), ""); EXPECT_FATAL_FAILURE( @@ -611,11 +617,14 @@ TEST(TestRealScalarUlpDistance, Float) { AssertScalarsEqual(123.456f, std::numeric_limits::quiet_NaN(), options.ulp_distance(11).nans_equal(false)), ""); +#endif } TEST(TestRealScalarUlpDistance, HalfFloat) { static auto options = EqualOptions::Defaults(); AssertScalarsEqual(Float16(1.00097656), Float16(0.999511719f), options.ulp_distance(2)); +#if !defined(_WIN32) || defined(ARROW_TESTING_STATIC) || \ + (defined(GTEST_LINKED_AS_SHARED_LIBRARY) && GTEST_LINKED_AS_SHARED_LIBRARY) EXPECT_FATAL_FAILURE(AssertScalarsEqual(Float16(1.00097656), Float16(0.999511719f), options.ulp_distance(1)), ""); @@ -627,6 +636,7 @@ TEST(TestRealScalarUlpDistance, HalfFloat) { AssertScalarsEqual(Float16(1.00097656), std::numeric_limits::quiet_NaN(), options.ulp_distance(2).nans_equal(false)), ""); +#endif } template diff --git a/cpp/src/arrow/testing/gtest_util_test.cc b/cpp/src/arrow/testing/gtest_util_test.cc index 2802f28f6b34..4359e088a1b9 100644 --- a/cpp/src/arrow/testing/gtest_util_test.cc +++ b/cpp/src/arrow/testing/gtest_util_test.cc @@ -39,10 +39,16 @@ namespace arrow::util { TEST(TestAssertionReporting, ArrayEqualityFailure) { +#if defined(_WIN32) && !defined(ARROW_TESTING_STATIC) && \ + (!defined(GTEST_LINKED_AS_SHARED_LIBRARY) || !GTEST_LINKED_AS_SHARED_LIBRARY) + GTEST_SKIP() << "Static GoogleTest and shared ArrowTesting have separate failure " + "reporters on Windows"; +#else // The exported helper must report to the same GoogleTest runtime as this test. EXPECT_FATAL_FAILURE( AssertArraysEqual(*ArrayFromJSON(int32(), "[1]"), *ArrayFromJSON(int32(), "[2]")), ""); +#endif } // Test basic cases for contains NaN. @@ -213,11 +219,14 @@ TEST(AssertTestWithinUlp, Basics) { std::numeric_limits::quiet_NaN(), 2); AssertWithinUlp(std::numeric_limits::quiet_NaN(), std::numeric_limits::quiet_NaN(), 2); +#if !defined(_WIN32) || defined(ARROW_TESTING_STATIC) || \ + (defined(GTEST_LINKED_AS_SHARED_LIBRARY) && GTEST_LINKED_AS_SHARED_LIBRARY) EXPECT_FATAL_FAILURE(AssertWithinUlp(123.4567, 123.45670000000015, 10), "not within 10 ulps"); EXPECT_FATAL_FAILURE(AssertWithinUlp(123.456f, 123.456085f, 10), "not within 10 ulps"); EXPECT_FATAL_FAILURE(AssertWithinUlp(Float16(123.456f), Float16(124.143501f), 10), "not within 10 ulps"); +#endif } } // namespace arrow::util