diff --git a/CMakeLists.txt b/CMakeLists.txt index a2f33f4a36..40faaae8eb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -202,32 +202,15 @@ if(BUILD_TESTING) CMAKE_DEPENDENT_OPTION(BUILD_benchmark "Build benchmark" OFF "NOT BUILD_DEPS" ON) set(BUILD_protobuf_matchers ON) - # Fuzztest do not support MSVC or toolchain - if(APPLE OR MSVC OR CMAKE_CROSSCOMPILING) - set(USE_fuzztest OFF) - else() - # since no distro provide a fuzztest package disable support by default. - CMAKE_DEPENDENT_OPTION(USE_fuzztest "Enable fuzztest" ${BUILD_DEPS} "BUILD_CXX" OFF) - endif() - if(NOT USE_fuzztest) - set(BUILD_fuzztest OFF) - else() - CMAKE_DEPENDENT_OPTION(BUILD_fuzztest "Build fuzztest" OFF - "NOT BUILD_DEPS" ON) - endif() else() set(OR_TOOLS_BUILD_TESTING OFF) set(BUILD_googletest OFF) set(BUILD_protobuf_matchers OFF) set(BUILD_benchmark OFF) - set(USE_fuzztest OFF) - set(BUILD_fuzztest OFF) endif() message(STATUS "Build googletest: ${BUILD_googletest}") message(STATUS "Build protobuf_matchers: ${BUILD_protobuf_matchers}") message(STATUS "Build benchmark: ${BUILD_benchmark}") -message(STATUS "Enable fuzztest: ${USE_fuzztest}") -message(STATUS "Build fuzztest: ${BUILD_fuzztest}") # Optional third party solvers (enabled by default) ## BOP diff --git a/MODULE.bazel b/MODULE.bazel index a561ccf1f3..ceee624544 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -41,7 +41,6 @@ bazel_dep(name = "rules_shell", version = "0.6.1") bazel_dep(name = "abseil-cpp", version = "20250814.1") bazel_dep(name = "bzip2", version = "1.0.8.bcr.2") bazel_dep(name = "eigen", version = "3.4.0.bcr.3") -bazel_dep(name = "fuzztest", version = "20250805.0") bazel_dep(name = "glpk", version = "5.0.bcr.4") bazel_dep(name = "google_benchmark", version = "1.9.2") bazel_dep(name = "googletest", version = "1.17.0") diff --git a/cmake/check_deps.cmake b/cmake/check_deps.cmake index b7d5b2c018..15dd1f2b7f 100644 --- a/cmake/check_deps.cmake +++ b/cmake/check_deps.cmake @@ -121,9 +121,6 @@ if(BUILD_TESTING) if(NOT TARGET benchmark::benchmark) message(FATAL_ERROR "Target benchmark::benchmark not available.") endif() - if(USE_fuzztest AND NOT TARGET fuzztest::fuzztest) - message(FATAL_ERROR "Target fuzztest::fuzztest not available.") - endif() endif() # Check language Dependencies diff --git a/cmake/dependencies/CMakeLists.txt b/cmake/dependencies/CMakeLists.txt index ca539e46bd..265b0f63ca 100644 --- a/cmake/dependencies/CMakeLists.txt +++ b/cmake/dependencies/CMakeLists.txt @@ -573,20 +573,3 @@ if(BUILD_benchmark) list(POP_BACK CMAKE_MESSAGE_INDENT) message(CHECK_PASS "fetched") endif() - -if(BUILD_fuzztest) - message(CHECK_START "Fetching fuzztest") - list(APPEND CMAKE_MESSAGE_INDENT " ") - FetchContent_Declare( - fuzztest - GIT_REPOSITORY https://github.com/google/fuzztest.git - GIT_TAG 2025-08-05 - GIT_SHALLOW TRUE - UPDATE_COMMAND git reset --hard - PATCH_COMMAND git apply --ignore-whitespace - "${CMAKE_CURRENT_LIST_DIR}/../../patches/fuzztest-2025-08-05.patch" - ) - FetchContent_MakeAvailable(fuzztest) - list(POP_BACK CMAKE_MESSAGE_INDENT) - message(CHECK_PASS "fetched") -endif() diff --git a/cmake/system_deps.cmake b/cmake/system_deps.cmake index c1c08d41e7..617abe1df1 100644 --- a/cmake/system_deps.cmake +++ b/cmake/system_deps.cmake @@ -112,12 +112,6 @@ if(BUILD_TESTING) if(NOT BUILD_benchmark AND NOT TARGET benchmark::benchmark) find_package(benchmark REQUIRED) endif() - - if(USE_fuzztest) - if(NOT BUILD_fuzztest AND NOT TARGET fuzztest::fuzztest) - find_package(fuzztest REQUIRED) - endif() - endif() endif() # Check language Dependencies diff --git a/ortools/algorithms/BUILD.bazel b/ortools/algorithms/BUILD.bazel index 35566e85aa..74ff54de2c 100644 --- a/ortools/algorithms/BUILD.bazel +++ b/ortools/algorithms/BUILD.bazel @@ -435,3 +435,20 @@ cc_library( "@abseil-cpp//absl/time", ], ) + +cc_test( + name = "n_choose_k_test", + srcs = ["n_choose_k_test.cc"], + deps = [ + ":n_choose_k", + "//ortools/base:dump_vars", + "//ortools/base:gmock_main", + "//ortools/util:flat_matrix", + "@abseil-cpp//absl/numeric:int128", + "@abseil-cpp//absl/random", + "@abseil-cpp//absl/random:distributions", + "@abseil-cpp//absl/status", + "@abseil-cpp//absl/status:statusor", + "@google_benchmark//:benchmark", + ], +) diff --git a/ortools/algorithms/CMakeLists.txt b/ortools/algorithms/CMakeLists.txt index da84d96cc8..efa248cb91 100644 --- a/ortools/algorithms/CMakeLists.txt +++ b/ortools/algorithms/CMakeLists.txt @@ -52,20 +52,6 @@ if(BUILD_TESTING) GTest::gmock ) endforeach() - if(USE_fuzztest) - ortools_cxx_test( - NAME - algorithms_n_choose_k_test - SOURCES - "./n_choose_k_test.cc" - LINK_LIBRARIES - benchmark::benchmark - fuzztest::fuzztest - fuzztest::fuzztest_gtest_main - GTest::gmock - ) - endif() - # These tests are too long so we disable them. set_tests_properties( cxx_algorithms_radix_sort_test diff --git a/ortools/algorithms/n_choose_k_test.cc b/ortools/algorithms/n_choose_k_test.cc index 3c5c86bfe3..212e57f4c4 100644 --- a/ortools/algorithms/n_choose_k_test.cc +++ b/ortools/algorithms/n_choose_k_test.cc @@ -16,26 +16,19 @@ #include #include #include -#include -#include -#include #include "absl/numeric/int128.h" #include "absl/random/distributions.h" #include "absl/random/random.h" #include "absl/status/status.h" #include "absl/status/statusor.h" -#include "benchmark/benchmark.h" #include "gtest/gtest.h" #include "ortools/base/dump_vars.h" -//#include "ortools/base/fuzztest.h" #include "ortools/base/gmock.h" -#include "ortools/base/mathutil.h" #include "ortools/util/flat_matrix.h" namespace operations_research { namespace { -//using ::fuzztest::NonNegative; using ::testing::HasSubstr; using ::testing::status::IsOkAndHolds; using ::testing::status::StatusIs; @@ -248,74 +241,5 @@ TEST(NChooseKTest, ComparisonAgainstPascalTriangleForK5OrAbove) { } } -void MatchesLogCombinations(int n, int k) { - if (n < k) { - std::swap(k, n); - } - const auto exact = NChooseK(n, k); - const double log_approx = MathUtil::LogCombinations(n, k); - if (exact.ok()) { - // We accepted to compute the exact value, make sure that it matches the - // approximation. - ASSERT_NEAR(log(exact.value()), log_approx, 0.0001); - } else { - // We declined to compute the exact value, make sure that we had a good - // reason to, i.e. that the result did indeed overflow. - ASSERT_THAT(exact, StatusIs(absl::StatusCode::kInvalidArgument, - HasSubstr("overflows int64"))); - const double approx = exp(log_approx); - ASSERT_GE(std::nextafter(approx, std::numeric_limits::infinity()), - std::numeric_limits::max()) - << "we declined to compute the exact value of NChooseK(" << n << ", " - << k << "), but the log value is " << log_approx - << " (value: " << approx << "), which fits in int64_t"; - } -} -/* -FUZZ_TEST(NChooseKTest, MatchesLogCombinations) - // Ideally we'd test with `uint64_t`, but `LogCombinations` only accepts - // `int`. - .WithDomains(NonNegative(), NonNegative()); -*/ -template -void BM_NChooseK(benchmark::State& state) { - static constexpr int kNumInputs = 1000; - // Use deterministic random numbers to avoid noise. - std::mt19937 gen(42); - std::uniform_int_distribution random(0, kMaxN); - std::vector> inputs; - inputs.reserve(kNumInputs); - for (int i = 0; i < kNumInputs; ++i) { - int64_t n = random(gen); - int64_t k = random(gen); - if (n < k) { - std::swap(n, k); - } - inputs.emplace_back(n, k); - } - // Force the one-time, costly static initializations of NChooseK() to happen - // before the benchmark starts. - auto result = NChooseK(62, 31); - benchmark::DoNotOptimize(result); - - // Start the benchmark. - for (auto _ : state) { - for (const auto [n, k] : inputs) { - auto result = algo(n, k); - benchmark::DoNotOptimize(result); - } - } - state.SetItemsProcessed(state.iterations() * kNumInputs); -} -// int32_t domain. -BENCHMARK(BM_NChooseK<30, operations_research::NChooseK>); - -// int{32,64} domain. -BENCHMARK(BM_NChooseK<60, operations_research::NChooseK>); - -// int{32,64,128} domain. -BENCHMARK(BM_NChooseK<100, operations_research::NChooseK>); -BENCHMARK(BM_NChooseK<100, MathUtil::LogCombinations>); - } // namespace } // namespace operations_research diff --git a/ortools/base/fuzztest.h b/ortools/base/fuzztest.h deleted file mode 100644 index f6b3294f5e..0000000000 --- a/ortools/base/fuzztest.h +++ /dev/null @@ -1,51 +0,0 @@ -// Copyright 2010-2025 Google LLC -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#ifndef ORTOOLS_BASE_FUZZTEST_H_ -#define ORTOOLS_BASE_FUZZTEST_H_ - -#include -#include -#include - -// #include "fuzztest/googletest_fixture_adapter.h" -#include "fuzztest/domain.h" -#include "fuzztest/fuzztest.h" -#include "fuzztest/init_fuzztest.h" -#include "google/protobuf/text_format.h" - -namespace fuzztest { - -// Reads protos from directory and returns a vector usable by the .WithSeeds() -// function to aid in fuzz test migrations. `is_text_format` should be true iff -// the protos are in text format. -template -std::vector> ReadFilesFromDirectory( - std::string_view dir) { - std::vector> corpus; - - for (std::tuple& proto_tuple : ReadFilesFromDirectory(dir)) { - std::string text_proto = std::get<0>(proto_tuple); - ProtoType proto; - bool was_parsed = - google::protobuf::TextFormat::ParseFromString(text_proto, &proto); - if (was_parsed) { - corpus.push_back(std::make_tuple(proto)); - } - } - return corpus; -} - -} // namespace fuzztest - -#endif // ORTOOLS_BASE_FUZZTEST_H_ diff --git a/ortools/math_opt/elemental/CMakeLists.txt b/ortools/math_opt/elemental/CMakeLists.txt index dc1c3b1a13..3c65d2ef1f 100644 --- a/ortools/math_opt/elemental/CMakeLists.txt +++ b/ortools/math_opt/elemental/CMakeLists.txt @@ -50,8 +50,6 @@ if(BUILD_TESTING) file(GLOB _TEST_SRCS "*_test.cc") list(FILTER _TEST_SRCS EXCLUDE REGEX "elemental_export_model_update_test.cc$") - list(FILTER _TEST_SRCS - EXCLUDE REGEX "elemental_from_proto_fuzz_test.cc$") # need fuzztest foreach(_FULL_FILE_NAME IN LISTS _TEST_SRCS) get_filename_component(_NAME ${_FULL_FILE_NAME} NAME_WE) get_filename_component(_FILE_NAME ${_FULL_FILE_NAME} NAME) diff --git a/ortools/math_opt/elemental/elemental_from_proto_fuzz_test.cc b/ortools/math_opt/elemental/elemental_from_proto_fuzz_test.cc deleted file mode 100644 index f08160b056..0000000000 --- a/ortools/math_opt/elemental/elemental_from_proto_fuzz_test.cc +++ /dev/null @@ -1,81 +0,0 @@ -// Copyright 2010-2025 Google LLC -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include - -#include "absl/status/statusor.h" -#include "ortools/base/fuzztest.h" -#include "ortools/base/gmock.h" -#include "ortools/math_opt/elemental/elemental.h" -#include "ortools/math_opt/elemental/elemental_matcher.h" -#include "ortools/math_opt/model_update.pb.h" - -namespace operations_research::math_opt { -namespace { - -using ::testing::status::IsOkAndHolds; - -void FromProtoNeverCrashes(const ModelProto& proto) { - Elemental::FromModelProto(proto).IgnoreError(); -} - -FUZZ_TEST(ElementalFromProtoNoCrashTest, FromProtoNeverCrashes); - -void RoundTripsIfParses(const ModelProto& proto) { - absl::StatusOr e1 = Elemental::FromModelProto(proto); - if (!e1.ok()) { - return; - } - ASSERT_OK_AND_ASSIGN(ModelProto p2, e1->ExportModel()); - EXPECT_THAT(Elemental::FromModelProto(p2), - IsOkAndHolds(EquivToElemental(*e1))); -} - -FUZZ_TEST(ElementalRoundTripTest, RoundTripsIfParses); - -void ApplyUpdateProtoNoCrash(const ModelProto& proto, - const ModelUpdateProto& u1, - const ModelUpdateProto& u2) { - absl::StatusOr elemental = Elemental::FromModelProto(proto); - if (!elemental.ok()) { - return; - } - elemental->ApplyUpdateProto(u1).IgnoreError(); - elemental->ApplyUpdateProto(u2).IgnoreError(); -} - -FUZZ_TEST(ElementalApplyUpdateProtoNoCrashTest, ApplyUpdateProtoNoCrash); - -void UpdateRoundTripsIfParses(const ModelProto& proto, - const ModelUpdateProto& update) { - absl::StatusOr model = Elemental::FromModelProto(proto); - if (!model.ok()) { - return; - } - const Elemental::DiffHandle diff = model->AddDiff(); - if (!model->ApplyUpdateProto(update).ok()) { - return; - } - ASSERT_OK_AND_ASSIGN(const std::optional canonical_update, - model->ExportModelUpdate(diff)); - if (canonical_update.has_value()) { - ASSERT_OK_AND_ASSIGN(Elemental model2, Elemental::FromModelProto(proto)); - ASSERT_OK(model2.ApplyUpdateProto(*canonical_update)); - EXPECT_THAT(*model, EquivToElemental(model2)); - } -} - -FUZZ_TEST(ElementalUpdateRoundTripTest, UpdateRoundTripsIfParses); - -} // namespace -} // namespace operations_research::math_opt diff --git a/ortools/sat/BUILD.bazel b/ortools/sat/BUILD.bazel index d3aa9eb853..afbb7f7766 100644 --- a/ortools/sat/BUILD.bazel +++ b/ortools/sat/BUILD.bazel @@ -3843,6 +3843,7 @@ cc_test( ":integer_base", ":util", "//ortools/base:gmock", + "//ortools/base:gmock_main", "//ortools/base:logging", "//ortools/graph:connected_components", "//ortools/graph:strongly_connected_components", @@ -3856,7 +3857,6 @@ cc_test( "@abseil-cpp//absl/random:distributions", "@abseil-cpp//absl/strings", "@abseil-cpp//absl/types:span", - "@fuzztest//fuzztest:fuzztest_gtest_main", "@google_benchmark//:benchmark", ], ) diff --git a/ortools/sat/diffn_util_test.cc b/ortools/sat/diffn_util_test.cc index b1e64b5247..95373eb9b8 100644 --- a/ortools/sat/diffn_util_test.cc +++ b/ortools/sat/diffn_util_test.cc @@ -1105,27 +1105,6 @@ TEST(FindPartialIntersections, Random) { } } -void CheckFuzzedRectangles( - absl::Span> tuples) { - std::vector rectangles; - rectangles.reserve(tuples.size()); - for (const auto& [x_min, x_size, y_min, y_size] : tuples) { - rectangles.push_back({.x_min = x_min, - .x_max = CapAdd(x_min, x_size), - .y_min = y_min, - .y_max = CapAdd(y_min, y_size)}); - } - const std::vector> result = - FindPartialRectangleIntersections(rectangles); - for (const auto& [i, j] : result) { - CHECK(!rectangles[i].IsDisjoint(rectangles[j])) << i << " " << j; - } - const std::vector> naive_result = - GetAllIntersections(rectangles); - CHECK(GraphsDefineSameConnectedComponents(naive_result, result)) - << RenderRectGraph(std::nullopt, rectangles, result); -} - void BM_FindRectangles(benchmark::State& state) { absl::BitGen random; std::vector> problems; diff --git a/patches/fuzztest-2025-08-05.patch b/patches/fuzztest-2025-08-05.patch deleted file mode 100644 index 1245eef824..0000000000 --- a/patches/fuzztest-2025-08-05.patch +++ /dev/null @@ -1,154 +0,0 @@ -diff --git a/CMakeLists.txt b/CMakeLists.txt -index f9f71df..321caf5 100644 ---- a/CMakeLists.txt -+++ b/CMakeLists.txt -@@ -28,7 +28,7 @@ elseif (CMAKE_CXX_COMPILER_ID MATCHES "AppleClang") - elseif (CMAKE_CXX_COMPILER_ID MATCHES "Clang") - set (COMPILER_CLANG 1) - else () -- message (FATAL_ERROR "Compiler ${CMAKE_CXX_COMPILER_ID} is not supported") -+ message (WARNING "Compiler ${CMAKE_CXX_COMPILER_ID} is not supported") - endif () - - if (COMPILER_GCC AND (FUZZTEST_FUZZING_MODE OR (FUZZTEST_COMPATIBILITY_MODE STREQUAL "libfuzzer"))) -diff --git a/cmake/BuildDependencies.cmake b/cmake/BuildDependencies.cmake -index d8565c0..24b7f52 100644 ---- a/cmake/BuildDependencies.cmake -+++ b/cmake/BuildDependencies.cmake -@@ -17,20 +17,20 @@ cmake_minimum_required(VERSION 3.19) - include(FetchContent) - - set(absl_URL https://github.com/abseil/abseil-cpp.git) --set(absl_TAG d04b964d82ed5146f7e5e34701a5ba69f9514c9a) -+set(absl_TAG 20250814.1) - - set(re2_URL https://github.com/google/re2.git) - set(re2_TAG 2024-07-02) - - set(gtest_URL https://github.com/google/googletest.git) --set(gtest_TAG v1.16.0) -+set(gtest_TAG v1.17.0) - - # From https://www.antlr.org/download.html - set(antlr_cpp_URL https://www.antlr.org/download/antlr4-cpp-runtime-4.12.0-source.zip) - set(antlr_cpp_MD5 acf7371bd7562188712751266d8a7b90) - - set(proto_URL https://github.com/protocolbuffers/protobuf.git) --set(proto_TAG v30.2) -+set(proto_TAG v33.1) - - set(nlohmann_json_URL https://github.com/nlohmann/json.git) - set(nlohmann_json_TAG v3.11.3) -@@ -44,7 +44,7 @@ if(POLICY CMP0135) - endif() - - FetchContent_Declare( -- abseil-cpp -+ absl - GIT_REPOSITORY ${absl_URL} - GIT_TAG ${absl_TAG} - ) -@@ -93,7 +93,7 @@ endif () - - set(ABSL_PROPAGATE_CXX_STD ON) - set(ABSL_ENABLE_INSTALL ON) --FetchContent_MakeAvailable(abseil-cpp) -+FetchContent_MakeAvailable(absl) - - set(RE2_BUILD_TESTING OFF) - FetchContent_MakeAvailable(re2) -@@ -101,6 +101,7 @@ FetchContent_MakeAvailable(re2) - set(GTEST_HAS_ABSL ON) - FetchContent_MakeAvailable(googletest) - -+set(ANTLR_BUILD_CPP_TESTS OFF) - FetchContent_MakeAvailable(antlr_cpp) - - if (FUZZTEST_BUILD_TESTING) -diff --git a/cmake/FuzzTestHelpers.cmake b/cmake/FuzzTestHelpers.cmake -index 2869a77..8462fdd 100644 ---- a/cmake/FuzzTestHelpers.cmake -+++ b/cmake/FuzzTestHelpers.cmake -@@ -114,6 +114,13 @@ function(fuzztest_cc_library) - ${FUZZTEST_CC_LIB_LINKOPTS} - ${FUZZTEST_DEFAULT_LINKOPTS} - ) -+ if(APPLE) -+ set_target_properties(${_NAME} PROPERTIES -+ INSTALL_RPATH "@loader_path") -+ elseif(UNIX) -+ set_target_properties(${_NAME} PROPERTIES -+ INSTALL_RPATH "$ORIGIN") -+ endif() - - set_property( - TARGET ${_NAME} -diff --git a/fuzztest/internal/CMakeLists.txt b/fuzztest/internal/CMakeLists.txt -index 61f6da8..84fe3a7 100644 ---- a/fuzztest/internal/CMakeLists.txt -+++ b/fuzztest/internal/CMakeLists.txt -@@ -434,35 +434,6 @@ fuzztest_cc_library( - absl::cord - ) - --fuzztest_cc_library( -- NAME -- subprocess -- HDRS -- "subprocess.h" -- SRCS -- "subprocess.cc" -- DEPS -- fuzztest::logging -- absl::flat_hash_map -- absl::function_ref -- absl::span -- absl::strings -- absl::string_view -- absl::time --) -- --fuzztest_cc_test( -- NAME -- subprocess_test -- SRCS -- "subprocess_test.cc" -- DEPS -- fuzztest::subprocess -- absl::strings -- absl::time -- GTest::gmock_main --) -- - fuzztest_cc_library( - NAME - table_of_recent_compares -diff --git a/tools/CMakeLists.txt b/tools/CMakeLists.txt -index 79ada1a..124c76b 100644 ---- a/tools/CMakeLists.txt -+++ b/tools/CMakeLists.txt -@@ -2,11 +2,21 @@ add_executable( - grammar_domain_code_generator - grammar_domain_code_generator.cc - ) -- - target_link_libraries( - grammar_domain_code_generator - absl::flags - absl::flags_parse - fuzztest_logging - code_generation --) -\ No newline at end of file -+) -+include(GNUInstallDirs) -+if(APPLE) -+ set_target_properties(grammar_domain_code_generator PROPERTIES -+ INSTALL_RPATH "@loader_path/../${CMAKE_INSTALL_LIBDIR};@loader_path") -+elseif(UNIX) -+ cmake_path(RELATIVE_PATH CMAKE_INSTALL_FULL_LIBDIR -+ BASE_DIRECTORY ${CMAKE_INSTALL_FULL_BINDIR} -+ OUTPUT_VARIABLE libdir_relative_path) -+ set_target_properties(grammar_domain_code_generator PROPERTIES -+ INSTALL_RPATH "$ORIGIN/${libdir_relative_path}:$ORIGIN") -+endif()