Commit 8a563cfc authored by Andreas Schuh's avatar Andreas Schuh

Migrate unit tests to CMake/CTest. Fix preprocessor directive in gflags_unittest.cc.

parent 15bc2d6c
......@@ -29,9 +29,14 @@ version_numbers (
option (BUILD_SHARED_LIBS "Request build of shared libraries." OFF)
set (GFLAGS_SHARED_LIBS ${BUILD_SHARED_LIBS})
option (BUILD_NEGATIVE_COMPILATION_TESTS "Request addition of negative compilation tests." OFF)
mark_as_advanced(BUILD_NEGATIVE_COMPILATION_TESTS)
set (GFLAGS_NAMESPACE "gflags" CACHE STRING "C++ namespace identifier of gflags library.")
mark_as_advanced (GFLAGS_NAMESPACE)
mark_as_advanced (CLEAR CMAKE_INSTALL_PREFIX)
mark_as_advanced (CMAKE_CONFIGURATION_TYPES)
if (NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CXX_FLAGS AND NOT CMAKE_C_FLAGS)
set (
CMAKE_BUILD_TYPE "Release"
......@@ -121,7 +126,7 @@ else ()
set (__ATTRIBUTE__UNUSED)
endif ()
configure_sources (PUBLIC_HDRS ${PUBLIC_HDRS})
configure_headers (PUBLIC_HDRS ${PUBLIC_HDRS})
configure_sources (PRIVATE_HDRS ${PRIVATE_HDRS})
configure_sources (GFLAGS_SRCS ${GFLAGS_SRCS})
......@@ -133,16 +138,19 @@ set (CMAKE_ARCHIVE_OUTPUT_DIRECTORY "lib")
# ----------------------------------------------------------------------------
# add library target
if (WIN32 AND BUILD_SHARED_LIBS)
add_definitions (-DGFLAGS_DLL_EXPORT)
endif ()
include_directories ("${PROJECT_SOURCE_DIR}/src")
include_directories ("${PROJECT_BINARY_DIR}/include")
include_directories ("${PROJECT_BINARY_DIR}/include/${GFLAGS_NAMESPACE}")
add_library (gflags ${GFLAGS_SRCS} ${PRIVATE_HDRS} ${PUBLIC_HDRS})
add_library (gflags_nothreads ${GFLAGS_SRCS} ${PRIVATE_HDRS} ${PUBLIC_HDRS})
set_target_properties (gflags_nothreads PROPERTIES COMPILE_DEFINITIONS NO_THREADS)
if (WIN32 AND BUILD_SHARED_LIBS)
set_target_properties (gflags PROPERTIES COMPILE_DEFINITIONS GFLAGS_DLL_EXPORT)
set_target_properties (gflags_nothreads PROPERTIES COMPILE_DEFINITIONS "GFLAGS_DLL_EXPORT;NO_THREADS")
else ()
set_target_properties (gflags_nothreads PROPERTIES COMPILE_DEFINITIONS NO_THREADS)
endif ()
# ----------------------------------------------------------------------------
# installation
......@@ -191,14 +199,8 @@ configure_file (cmake/config.cmake.in "${PROJECT_BINARY_DIR}/${PACKAGE_NAME}-con
# ----------------------------------------------------------------------------
# testing - MUST follow the generation of the build tree config file
# TODO(andreas) Replace Bash scripts such that tests can be run on Windows (e.g., Python).
# The gflags_unittest.sh script should best be replaced by multiple
# add_test commands in the test/CMakeLists.txt file.
if (UNIX)
include (CTest)
if (BUILD_TESTING)
enable_testing ()
add_subdirectory (test)
endif ()
endif ()
include (CTest)
if (BUILD_TESTING)
enable_testing ()
add_subdirectory (test)
endif ()
\ No newline at end of file
......@@ -31,6 +31,22 @@ function (version_numbers VERSION MAJOR MINOR PATCH)
set ("${PATCH}" "${VERSION_PATCH}" PARENT_SCOPE)
endfunction ()
# ----------------------------------------------------------------------------
## Configure public header files
function (configure_headers out)
set (tmp)
foreach (src IN LISTS ARGN)
if (EXISTS "${PROJECT_SOURCE_DIR}/src/${src}.in")
configure_file ("${PROJECT_SOURCE_DIR}/src/${src}.in" "${PROJECT_BINARY_DIR}/include/${GFLAGS_NAMESPACE}/${src}" @ONLY)
list (APPEND tmp "${PROJECT_BINARY_DIR}/include/${GFLAGS_NAMESPACE}/${src}")
else ()
configure_file ("${PROJECT_SOURCE_DIR}/src/${src}" "${PROJECT_BINARY_DIR}/include/${GFLAGS_NAMESPACE}/${src}" COPYONLY)
list (APPEND tmp "${PROJECT_BINARY_DIR}/include/${GFLAGS_NAMESPACE}/${src}")
endif ()
endforeach ()
set (${out} "${tmp}" PARENT_SCOPE)
endfunction ()
# ----------------------------------------------------------------------------
## Configure source files with .in suffix
function (configure_sources out)
......@@ -45,3 +61,22 @@ function (configure_sources out)
endforeach ()
set (${out} "${tmp}" PARENT_SCOPE)
endfunction ()
# ----------------------------------------------------------------------------
## Add usage test
#
# Using PASS_REGULAR_EXPRESSION and FAIL_REGULAR_EXPRESSION would
# do as well, but CMake/CTest does not allow us to specify an
# expected exist status. Moreover, the execute_test.cmake script
# sets environment variables needed by the --fromenv/--tryfromenv tests.
macro (add_gflags_test name expected_rc expected_output unexpected_output cmd)
add_test (
NAME ${name}
COMMAND "${CMAKE_COMMAND}" "-DCOMMAND:STRING=$<TARGET_FILE:${cmd}>;${ARGN}"
"-DEXPECTED_RC:STRING=${expected_rc}"
"-DEXPECTED_OUTPUT:STRING=${expected_output}"
"-DUNEXPECTED_OUTPUT:STRING=${unexpected_output}"
-P "${PROJECT_SOURCE_DIR}/test/execute_test.cmake"
WORKING_DIRECTORY "${PROJECT_SOURCE_DIR}/test"
)
endmacro ()
## gflags tests
find_package (PythonInterp)
# ----------------------------------------------------------------------------
# output directories
set (CMAKE_RUNTIME_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/Testing/bin")
......@@ -16,47 +14,153 @@ include_directories ("${CMAKE_CURRENT_SOURCE_DIR}")
link_libraries (gflags_nothreads)
# ----------------------------------------------------------------------------
# test executables
# STRIP_FLAG_HELP: check with "strings" that help text is not in binary
if (UNIX)
add_executable (strip_flags gflags_strip_flags_test.cc)
add_test (
NAME strip_flags
COMMAND /bin/bash "${CMAKE_CURRENT_SOURCE_DIR}/gflags_strip_flags_test.sh"
"${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/strip_flags"
)
endif ()
# ----------------------------------------------------------------------------
# unit tests
configure_file (gflags_unittest.cc gflags_unittest-main.cc COPYONLY)
configure_file (gflags_unittest.cc gflags_unittest_main.cc COPYONLY)
set (SRCDIR "${CMAKE_CURRENT_SOURCE_DIR}/nc")
configure_file (gflags_nc.py.in "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/nc.py" @ONLY)
add_executable (unittest gflags_unittest.cc)
add_executable (unittest2 gflags_unittest-main.cc)
add_executable (unittest3 gflags_unittest_main.cc)
# First, just make sure the unittest works as-is
add_gflags_test(unittest 0 "" "" unittest)
# --help should show all flags, including flags from gflags_reporting
add_gflags_test(help-reporting 1 "gflags_reporting.cc" "" unittest --help)
# Make sure that --help prints even very long helpstrings.
add_gflags_test(long-helpstring 1 "end of a long helpstring" "" unittest --help)
# Make sure --help reflects flag changes made before flag-parsing
add_gflags_test(changed_bool1 1 "-changed_bool1 (changed) type: bool default: true" "" unittest --help)
add_gflags_test(changed_bool2 1 "-changed_bool2 (changed) type: bool default: false currently: true" "" unittest --help)
# And on the command-line, too
add_gflags_test(changeable_string_var 1 "-changeable_string_var () type: string default: \"1\" currently: \"2\"" "" unittest --changeable_string_var 2 --help)
# --nohelp and --help=false should be as if we didn't say anything
add_gflags_test(nohelp 0 "PASS" "" unittest --nohelp)
add_gflags_test(help=false 0 "PASS" "" unittest --help=false)
# --helpfull is the same as help
add_gflags_test(helpfull 1 "gflags_reporting.cc" "" unittest --helpfull)
# --helpshort should show only flags from the unittest itself
add_gflags_test(helpshort 1 "gflags_unittest.cc" "gflags_reporting.cc" unittest --helpshort)
# --helpshort should show the tldflag we created in the unittest dir
add_gflags_test(helpshort-tldflag1 1 "tldflag1" "google.cc" unittest --helpshort)
add_gflags_test(helpshort-tldflag2 1 "tldflag2" "google.cc" unittest --helpshort)
# --helpshort should work if the main source file is suffixed with [_-]main
add_gflags_test(helpshort-main 1 "gflags_unittest-main.cc" "gflags_reporting.cc" unittest2 --helpshort)
add_gflags_test(helpshort_main 1 "gflags_unittest_main.cc" "gflags_reporting.cc" unittest3 --helpshort)
# --helpon needs an argument
add_gflags_test(helpon 1 "'--helpon' is missing its argument; flag description: show help on" "" unittest --helpon)
if (BUILD_SHARED_LIBS)
# --helpon argument indicates what file we'll show args from
# TODO(andreas): This test fails. Why is there no help for the gflags module ?
add_gflags_test(helpon=gflags 1 "gflags.cc" "gflags_unittest.cc" unittest --helpon=gflags)
# another way of specifying the argument
# TODO(andreas): This test fails. Why is there no help for the gflags module ?
add_gflags_test(helpon_gflags 1 "gflags.cc" "gflags_unittest.cc" unittest --helpon gflags)
endif ()
add_executable (strip_flags gflags_strip_flags_test.cc)
add_executable (unittest gflags_unittest.cc)
add_executable (unittest2 gflags_unittest-main.cc)
add_executable (unittest3 gflags_unittest_main.cc)
# test another argument
add_gflags_test(helpon=gflags_unittest 1 "gflags_unittest.cc" "gflags.cc" unittest --helpon=gflags_unittest)
# helpmatch is like helpon but takes substrings
add_gflags_test(helpmatch_reporting 1 "gflags_reporting.cc" "gflags_unittest.cc" unittest -helpmatch reporting)
add_gflags_test(helpmatch=unittest 1 "gflags_unittest.cc" "gflags.cc:" unittest -helpmatch=unittest)
# if no flags are found with helpmatch or helpon, suggest --help
add_gflags_test(helpmatch=nosuchsubstring 1 "No modules matched" "gflags_unittest.cc" unittest -helpmatch=nosuchsubstring)
add_gflags_test(helpon=nosuchmodule 1 "No modules matched" "gflags_unittest.cc" unittest -helpon=nosuchmodule)
# helppackage shows all the flags in the same dir as this unittest
# --help should show all flags, including flags from google.cc
add_gflags_test(helppackage 1 "gflags_reporting.cc" "" unittest --helppackage)
# xml!
add_gflags_test(helpxml 1 "gflags_unittest.cc</file>" "gflags_unittest.cc:" unittest --helpxml)
# just print the version info and exit
add_gflags_test(version-1 0 "gflags_unittest" "gflags_unittest.cc" unittest --version)
add_gflags_test(version-2 0 "version test_version" "gflags_unittest.cc" unittest --version)
# --undefok is a fun flag...
add_gflags_test(undefok-1 1 "unknown command line flag 'foo'" "" unittest --undefok= --foo --unused_bool)
add_gflags_test(undefok-2 0 "PASS" "" unittest --undefok=foo --foo --unused_bool)
# If you say foo is ok to be undefined, we'll accept --nofoo as well
add_gflags_test(undefok-3 0 "PASS" "" unittest --undefok=foo --nofoo --unused_bool)
# It's ok if the foo is in the middle
add_gflags_test(undefok-4 0 "PASS" "" unittest --undefok=fee,fi,foo,fum --foo --unused_bool)
# But the spelling has to be just right...
add_gflags_test(undefok-5 1 "unknown command line flag 'foo'" "" unittest --undefok=fo --foo --unused_bool)
add_gflags_test(undefok-6 1 "unknown command line flag 'foo'" "" unittest --undefok=foot --foo --unused_bool)
# See if we can successfully load our flags from the flagfile
add_gflags_test(flagfile.1 0 "gflags_unittest" "gflags_unittest.cc" unittest "--flagfile=${CMAKE_CURRENT_LIST_DIR}/flagfile.1")
add_gflags_test(flagfile.2 0 "PASS" "" unittest "--flagfile=${CMAKE_CURRENT_LIST_DIR}/flagfile.2")
add_gflags_test(flagfile.3 0 "PASS" "" unittest "--flagfile=${CMAKE_CURRENT_LIST_DIR}/flagfile.3")
# Also try to load flags from the environment
add_gflags_test(fromenv=version 0 "gflags_unittest" "gflags_unittest.cc" unittest --fromenv=version)
add_gflags_test(tryfromenv=version 0 "gflags_unittest" "gflags_unittest.cc" unittest --tryfromenv=version)
add_gflags_test(fromenv=help 0 "PASS" "" unittest --fromenv=help)
add_gflags_test(tryfromenv=help 0 "PASS" "" unittest --tryfromenv=help)
add_gflags_test(fromenv=helpfull 1 "helpfull not found in environment" "" unittest --fromenv=helpfull)
add_gflags_test(tryfromenv=helpfull 0 "PASS" "" unittest --tryfromenv=helpfull)
add_gflags_test(tryfromenv=undefok 0 "PASS" "" unittest --tryfromenv=undefok --foo)
add_gflags_test(tryfromenv=weirdo 1 "unknown command line flag" "" unittest --tryfromenv=weirdo)
add_gflags_test(tryfromenv-multiple 0 "gflags_unittest" "gflags_unittest.cc" unittest --tryfromenv=test_bool,version,unused_bool)
add_gflags_test(fromenv=test_bool 1 "not found in environment" "" unittest --fromenv=test_bool)
add_gflags_test(fromenv=test_bool-ok 1 "unknown command line flag" "" unittest --fromenv=test_bool,ok)
# Here, the --version overrides the fromenv
add_gflags_test(version-overrides-fromenv 0 "gflags_unittest" "gflags_unittest.cc" unittest --fromenv=test_bool,version,ok)
# Make sure -- by itself stops argv processing
add_gflags_test(dashdash 0 "PASS" "" unittest -- --help)
# And we should die if the flag value doesn't pass the validator
add_gflags_test(always_fail 1 "ERROR: failed validation of new value 'true' for flag 'always_fail'" "" unittest --always_fail)
# And if locking in validators fails
# TODO(andreas): Worked on Windows 7 Release configuration, but causes
# debugger abort() intervention in case of Debug configuration.
#add_gflags_test(deadlock_if_cant_lock 0 "PASS" "" unittest --deadlock_if_cant_lock)
# ----------------------------------------------------------------------------
# (negative) compilation tests
if (PYTHON_EXECUTABLE)
if (BUILD_NEGATIVE_COMPILATION_TESTS)
find_package (PythonInterp)
if (NOT PYTHON_EXECUTABLE)
message (FATAL_ERROR "No Python installation found! It is required by the negative compilation tests."
" Either install Python or set NEGATIVE_COMPILATION_TESTS to FALSE and try again.")
endif ()
set (SRCDIR "${CMAKE_CURRENT_SOURCE_DIR}/nc")
configure_file (gflags_nc.py.in "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/nc.py" @ONLY)
macro (add_nc_test name)
add_test (
NAME nc_${name}
COMMAND "${PYTHON_EXECUTABLE}" "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/nc.py" ${name}
)
endmacro ()
add_nc_test (sanity)
add_nc_test (swapped_args)
add_nc_test (int_instead_of_bool)
add_nc_test (bool_in_quotes)
add_nc_test (define_string_with_0)
endif ()
# ----------------------------------------------------------------------------
# test commands
add_test (
NAME strip_flags
COMMAND /bin/bash "${CMAKE_CURRENT_SOURCE_DIR}/gflags_strip_flags_test.sh"
"${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/strip_flags"
)
add_test (
NAME unittest
COMMAND /bin/bash "${CMAKE_CURRENT_SOURCE_DIR}/gflags_unittest.sh"
"${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/unittest"
"${CMAKE_CURRENT_SOURCE_DIR}" # <srcdir>
"${TEMPDIR}/unittest" # <tempdir>
)
endif ()
\ No newline at end of file
--version
\ No newline at end of file
--foo=bar
--nounused_bool
\ No newline at end of file
--flagfile=flagfile.2
\ No newline at end of file
......@@ -39,8 +39,8 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifdef HAVE_UNISTD_H
# include <unistd.h>
#if HAVE_UNISTD_H
# include <unistd.h>
#endif // for unlink()
#include <vector>
#include <string>
......@@ -414,7 +414,7 @@ TEST(FlagFileTest, FilenamesOurfileFirst) {
-1.0);
}
#ifdef HAVE_FNMATCH_H // otherwise glob isn't supported
#if HAVE_FNMATCH_H // otherwise glob isn't supported
TEST(FlagFileTest, FilenamesOurfileGlob) {
FLAGS_test_string = "initial";
FLAGS_test_bool = false;
......@@ -1493,6 +1493,11 @@ TEST(FlagsValidator, FlagSaver) {
} // unnamed namespace
int main(int argc, char **argv) {
// Run unit tests only if called without arguments, otherwise this program
// is used by an "external" usage test
const bool run_tests = (argc == 1);
// We need to call SetArgv before parsing flags, so our "test" argv will
// win out over this executable's real argv. That makes running this
// test with a real --help flag kinda annoying, unfortunately.
......@@ -1521,7 +1526,11 @@ int main(int argc, char **argv) {
ParseCommandLineFlags(&argc, &argv, true);
MakeTmpdir(&FLAGS_test_tmpdir);
const int exit_status = RUN_ALL_TESTS();
int exit_status = 0;
if (run_tests) {
fprintf(stdout, "Running the unit tests now...\n\n"); fflush(stdout);
exit_status = RUN_ALL_TESTS();
} else fprintf(stderr, "\n\nPASS\n");
ShutDownCommandLineFlags();
return exit_status;
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment