Update the googletest version

We now use googletest as a git submodule instead
of the old way of converting it into a single header
and including it in the source.

This removes the dependence on googleflags for tests
to be enabled.

Change-Id: If25ea3ba7a39c2b8ba9c6effbed3e7173361b6b1
This commit is contained in:
Sameer Agarwal
2024-06-15 14:53:09 -07:00
parent 7220e1d1e8
commit 894fd6903c
13 changed files with 26 additions and 38744 deletions
+3
View File
@@ -0,0 +1,3 @@
[submodule "third_party/googletest"]
path = third_party/googletest
url = https://github.com/google/googletest.git
+15 -23
View File
@@ -263,10 +263,6 @@ endif (MINIGLOG)
include(CheckCXXCompilerFlag) include(CheckCXXCompilerFlag)
check_cxx_compiler_flag("-Wno-missing-declarations" check_cxx_compiler_flag("-Wno-missing-declarations"
CHECK_CXX_FLAG_Wno_missing_declarations) CHECK_CXX_FLAG_Wno_missing_declarations)
if (CHECK_CXX_FLAG_Wno_missing_declarations)
set_property(SOURCE gmock_gtest_all.cc
APPEND_STRING PROPERTY COMPILE_FLAGS "-Wno-missing-declarations")
endif()
add_library(ceres $<TARGET_OBJECTS:ceres_internal> ${CERES_LIBRARY_SOURCE}) add_library(ceres $<TARGET_OBJECTS:ceres_internal> ${CERES_LIBRARY_SOURCE})
@@ -393,14 +389,8 @@ install(TARGETS ceres
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}) ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR})
if (BUILD_TESTING AND GFLAGS) if (BUILD_TESTING)
add_library(gtest STATIC gmock_gtest_all.cc gmock_main.cc) add_subdirectory(${Ceres_SOURCE_DIR}/third_party/googletest ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/googletest)
target_include_directories(gtest PRIVATE ${Ceres_SOURCE_DIR}/internal/ceres)
if (CMAKE_SYSTEM_NAME MATCHES "QNX")
target_link_libraries(gtest PUBLIC regex)
endif()
target_link_libraries(gtest PRIVATE Ceres::ceres gflags)
add_library(test_util STATIC add_library(test_util STATIC
evaluator_test_utils.cc evaluator_test_utils.cc
@@ -408,22 +398,25 @@ if (BUILD_TESTING AND GFLAGS)
test_util.cc) test_util.cc)
target_include_directories(test_util PUBLIC ${Ceres_SOURCE_DIR}/internal) target_include_directories(test_util PUBLIC ${Ceres_SOURCE_DIR}/internal)
target_link_libraries (test_util PUBLIC ceres_static gflags gtest) target_link_libraries (test_util PUBLIC GTest::gmock ceres_static)
target_compile_definitions(test_util PRIVATE CERES_TEST_SRCDIR_SUFFIX="../../data")
macro (CERES_TEST NAME) macro (CERES_TEST NAME)
add_executable(${NAME}_test ${NAME}_test.cc) add_executable(${NAME}_test ${NAME}_test.cc)
# Pull in local headers from the generated test directories when ceres_test() # Pull in local headers from the generated test directories when ceres_test()
# is invoked there, as well as the private headers in this directory which # is invoked there, as well as the private headers in this directory which
# may be referenced without the 'ceres' path prefix and all private # may be referenced without the 'ceres' path prefix and all private
# dependencies that may be directly referenced. # dependencies that may be directly referenced.
target_include_directories(${NAME}_test target_include_directories(${NAME}_test
PRIVATE ${Ceres_SOURCE_DIR}/internal/ceres PRIVATE ${Ceres_SOURCE_DIR}/internal/ceres
${CERES_LIBRARY_PRIVATE_DEPENDENCIES_INCLUDE_DIRS}) ${CERES_LIBRARY_PRIVATE_DEPENDENCIES_INCLUDE_DIRS})
# Some tests include direct references/includes of private dependency # Some tests include direct references/includes of private dependency
# headers which are not propagated via the ceres targets, so link them # headers which are not propagated via the ceres targets, so link them
# explicitly. # explicitly.
target_link_libraries(${NAME}_test PRIVATE gtest test_util ceres_static target_link_libraries(${NAME}_test PRIVATE test_util ceres_static
${CERES_LIBRARY_PRIVATE_DEPENDENCIES}) ${CERES_LIBRARY_PRIVATE_DEPENDENCIES} GTest::gmock_main)
# covariance_test uses SuiteSparseQR.hpp. However, since SuiteSparse import # covariance_test uses SuiteSparseQR.hpp. However, since SuiteSparse import
# targets are private (link only) dependencies not propagated to consumers, # targets are private (link only) dependencies not propagated to consumers,
@@ -433,9 +426,7 @@ if (BUILD_TESTING AND GFLAGS)
endif (TARGET SuiteSparse::SPQR) endif (TARGET SuiteSparse::SPQR)
add_test(NAME ${NAME}_test add_test(NAME ${NAME}_test
COMMAND ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${NAME}_test COMMAND ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${NAME}_test)
--test_srcdir
${Ceres_SOURCE_DIR}/data)
endmacro (CERES_TEST) endmacro (CERES_TEST)
ceres_test(array_utils) ceres_test(array_utils)
@@ -544,16 +535,17 @@ if (BUILD_TESTING AND GFLAGS)
add_subdirectory(generated_bundle_adjustment_tests) add_subdirectory(generated_bundle_adjustment_tests)
endif (BUILD_TESTING AND GFLAGS) endif (BUILD_TESTING)
macro(add_dependencies_to_benchmark BENCHMARK_TARGET) macro(add_dependencies_to_benchmark BENCHMARK_TARGET)
target_include_directories(${BENCHMARK_TARGET} target_include_directories(${BENCHMARK_TARGET}
PRIVATE ${Ceres_SOURCE_DIR}/internal PRIVATE ${Ceres_SOURCE_DIR}/internal
${CERES_LIBRARY_PRIVATE_DEPENDENCIES_INCLUDE_DIRS}) ${CERES_LIBRARY_PRIVATE_DEPENDENCIES_INCLUDE_DIRS})
# Benchmarks include direct references/includes of private dependency headers # Benchmarks include direct references/includes of private
# which are not propagated via the ceres targets, so link them explicitly. # dependency headers which are not propagated via the ceres targets,
# so link them explicitly.
target_link_libraries(${BENCHMARK_TARGET} target_link_libraries(${BENCHMARK_TARGET}
PRIVATE benchmark::benchmark ceres_static PRIVATE test_util ceres_static benchmark::benchmark
${CERES_LIBRARY_PRIVATE_DEPENDENCIES}) ${CERES_LIBRARY_PRIVATE_DEPENDENCIES})
endmacro() endmacro()
-2
View File
@@ -1,2 +0,0 @@
DisableFormat: true
SortIncludes: false
File diff suppressed because it is too large Load Diff
-153
View File
@@ -1,153 +0,0 @@
// Copyright (c) 2007, Google Inc.
// 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.
//
// Author: Zhanyong Wan
//
// Defines the ScopedMockLog class (using Google C++ Mocking
// Framework), which is convenient for testing code that uses LOG().
//
// NOTE(keir): This is a fork until Google Log exports the scoped mock log
// class; see: http://code.google.com/p/google-glog/issues/detail?id=88
#ifndef GOOGLE_CERES_INTERNAL_MOCK_LOG_H_
#define GOOGLE_CERES_INTERNAL_MOCK_LOG_H_
#include <string>
#include <gmock/gmock.h>
#include "glog/logging.h"
namespace testing {
// A ScopedMockLog object intercepts LOG() messages issued during its
// lifespan. Using this together with Google C++ Mocking Framework,
// it's very easy to test how a piece of code calls LOG(). The
// typical usage:
//
// TEST(FooTest, LogsCorrectly) {
// ScopedMockLog log;
//
// // We expect the WARNING "Something bad!" exactly twice.
// EXPECT_CALL(log, Log(WARNING, _, "Something bad!"))
// .Times(2);
//
// // We allow foo.cc to call LOG(INFO) any number of times.
// EXPECT_CALL(log, Log(INFO, HasSubstr("/foo.cc"), _))
// .Times(AnyNumber());
//
// Foo(); // Exercises the code under test.
// }
class ScopedMockLog : public google::LogSink {
public:
// When a ScopedMockLog object is constructed, it starts to
// intercept logs.
ScopedMockLog() { AddLogSink(this); }
// When the object is destructed, it stops intercepting logs.
~ScopedMockLog() override { RemoveLogSink(this); }
// Implements the mock method:
//
// void Log(LogSeverity severity, const string& file_path,
// const string& message);
//
// The second argument to Send() is the full path of the source file
// in which the LOG() was issued.
//
// Note, that in a multi-threaded environment, all LOG() messages from a
// single thread will be handled in sequence, but that cannot be guaranteed
// for messages from different threads. In fact, if the same or multiple
// expectations are matched on two threads concurrently, their actions will
// be executed concurrently as well and may interleave.
MOCK_METHOD3(Log, void(google::LogSeverity severity,
const std::string& file_path,
const std::string& message));
private:
// Implements the send() virtual function in class LogSink.
// Whenever a LOG() statement is executed, this function will be
// invoked with information presented in the LOG().
//
// The method argument list is long and carries much information a
// test usually doesn't care about, so we trim the list before
// forwarding the call to Log(), which is much easier to use in
// tests.
//
// We still cannot call Log() directly, as it may invoke other LOG()
// messages, either due to Invoke, or due to an error logged in
// Google C++ Mocking Framework code, which would trigger a deadlock
// since a lock is held during send().
//
// Hence, we save the message for WaitTillSent() which will be called after
// the lock on send() is released, and we'll call Log() inside
// WaitTillSent(). Since while a single send() call may be running at a
// time, multiple WaitTillSent() calls (along with the one send() call) may
// be running simultaneously, we ensure thread-safety of the exchange between
// send() and WaitTillSent(), and that for each message, LOG(), send(),
// WaitTillSent() and Log() are executed in the same thread.
void send(google::LogSeverity severity,
const char* full_filename,
const char* base_filename, int line, const tm* tm_time,
const char* message, size_t message_len) override {
// We are only interested in the log severity, full file name, and
// log message.
message_info_.severity = severity;
message_info_.file_path = full_filename;
message_info_.message = std::string(message, message_len);
}
// Implements the WaitTillSent() virtual function in class LogSink.
// It will be executed after send() and after the global logging lock is
// released, so calls within it (or rather within the Log() method called
// within) may also issue LOG() statements.
//
// LOG(), send(), WaitTillSent() and Log() will occur in the same thread for
// a given log message.
void WaitTillSent() override {
// First, and very importantly, we save a copy of the message being
// processed before calling Log(), since Log() may indirectly call send()
// and WaitTillSent() in the same thread again.
MessageInfo message_info = message_info_;
Log(message_info.severity, message_info.file_path, message_info.message);
}
// All relevant information about a logged message that needs to be passed
// from send() to WaitTillSent().
struct MessageInfo {
google::LogSeverity severity;
std::string file_path;
std::string message;
};
MessageInfo message_info_;
};
} // namespace testing
#endif // GOOGLE_CERES_INTERNAL_MOCK_LOG_H_
File diff suppressed because it is too large Load Diff
-69
View File
@@ -1,69 +0,0 @@
// Copyright 2008, Google Inc.
// 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.
//
// Author: wan@google.com (Zhanyong Wan)
#include <iostream>
#include "gflags/gflags.h"
#include "glog/logging.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"
// NOTE(keir): This flag is normally part of gtest within Google but isn't in
// the open source Google Test, since it is build-system dependent. However for
// Ceres this is needed for our tests. Add the new flag here.
DEFINE_string(test_srcdir, "", "The location of the source code.");
// MS C++ compiler/linker has a bug on Windows (not on Windows CE), which
// causes a link error when _tmain is defined in a static library and UNICODE
// is enabled. For this reason instead of _tmain, main function is used on
// Windows. See the following link to track the current status of this bug:
// http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=394464 // NOLINT
#if GTEST_OS_WINDOWS_MOBILE
# include <tchar.h> // NOLINT
GTEST_API_ int _tmain(int argc, TCHAR** argv) {
#else
GTEST_API_ int main(int argc, char** argv) {
#endif // GTEST_OS_WINDOWS_MOBILE
std::cout << "Running main() from gmock_main.cc\n";
google::InitGoogleLogging(argv[0]);
// Since Google Mock depends on Google Test, InitGoogleMock() is
// also responsible for initializing Google Test. Therefore there's
// no need for calling testing::InitGoogleTest() separately.
testing::InitGoogleMock(&argc, argv);
// On Windows, gtest passes additional non-gflags command line flags to
// death-tests, specifically --gtest_filter & --gtest_internal_run_death_test
// in order that these unknown (to gflags) flags do not invoke an error in
// gflags, InitGoogleTest() (called by InitGoogleMock()) must be called
// before ParseCommandLineFlags() to handle & remove them before gflags
// parses the remaining flags.
GFLAGS_NAMESPACE::ParseCommandLineFlags(&argc, &argv, true);
return RUN_ALL_TESTS();
}
-2
View File
@@ -1,2 +0,0 @@
DisableFormat: true
SortIncludes: false
File diff suppressed because it is too large Load Diff
@@ -37,14 +37,12 @@
#include "ceres/trust_region_strategy.h" #include "ceres/trust_region_strategy.h"
#include "glog/logging.h" #include "glog/logging.h"
#include "gmock/gmock.h" #include "gmock/gmock.h"
#include "gmock/mock-log.h" #include "gtest/gtest.h
#include "gtest/gtest.h"
using testing::_; using testing::_;
using testing::AllOf; using testing::AllOf;
using testing::AnyNumber; using testing::AnyNumber;
using testing::HasSubstr; using testing::HasSubstr;
using testing::ScopedMockLog;
namespace ceres { namespace ceres {
namespace internal { namespace internal {
@@ -108,6 +106,9 @@ TEST(LevenbergMarquardtStrategy, AcceptRejectStepRadiusScaling) {
EXPECT_EQ(lms.Radius(), options.max_radius); EXPECT_EQ(lms.Radius(), options.max_radius);
} }
// TODO(sameeragarwal): Re-enable this once we move to absl, as absl provides
// absl/log/scoped_mock_log.h
/*
TEST(LevenbergMarquardtStrategy, CorrectDiagonalToLinearSolver) { TEST(LevenbergMarquardtStrategy, CorrectDiagonalToLinearSolver) {
Matrix jacobian(2, 3); Matrix jacobian(2, 3);
jacobian.setZero(); jacobian.setZero();
@@ -162,6 +163,7 @@ TEST(LevenbergMarquardtStrategy, CorrectDiagonalToLinearSolver) {
EXPECT_EQ(summary.termination_type, LinearSolverTerminationType::FAILURE); EXPECT_EQ(summary.termination_type, LinearSolverTerminationType::FAILURE);
} }
} }
*/
} // namespace internal } // namespace internal
} // namespace ceres } // namespace ceres
+1 -5
View File
@@ -39,12 +39,9 @@
#include "ceres/internal/port.h" #include "ceres/internal/port.h"
#include "ceres/stringprintf.h" #include "ceres/stringprintf.h"
#include "ceres/types.h" #include "ceres/types.h"
#include "gflags/gflags.h"
#include "glog/logging.h" #include "glog/logging.h"
#include "gtest/gtest.h" #include "gtest/gtest.h"
DECLARE_string(test_srcdir);
// This macro is used to inject additional path information specific // This macro is used to inject additional path information specific
// to the build system. // to the build system.
@@ -135,8 +132,7 @@ void ExpectArraysClose(int n, const double* p, const double* q, double tol) {
} }
std::string TestFileAbsolutePath(const std::string& filename) { std::string TestFileAbsolutePath(const std::string& filename) {
return JoinPath(CERES_GET_FLAG(FLAGS_test_srcdir) + CERES_TEST_SRCDIR_SUFFIX, return JoinPath(::testing::SrcDir() + CERES_TEST_SRCDIR_SUFFIX, filename);
filename);
} }
std::string ToString(const Solver::Options& options) { std::string ToString(const Solver::Options& options) {
+1
View File
@@ -0,0 +1 @@
This directory is used for keeping track of our third party dependencies as git submodules.
Vendored Submodule
+1
Submodule third_party/googletest added at 1d17ea141d