Skip to content

Commit

Permalink
Merge pull request #4220 from mwtoews/cmake-use-network
Browse files Browse the repository at this point in the history
CMake: add TESTING_USE_NETWORK configure option
  • Loading branch information
rouault authored Aug 13, 2024
2 parents 0702d75 + 038fe34 commit 64ece97
Show file tree
Hide file tree
Showing 3 changed files with 130 additions and 45 deletions.
34 changes: 30 additions & 4 deletions docs/source/install.rst
Original file line number Diff line number Diff line change
Expand Up @@ -139,15 +139,32 @@ The following guides show how to compile and install the software using CMake.
PROJ 9.0 and later releases only support builds using CMake.


Build requirements
Requirements
--------------------------------------------------------------------------------

Build requirements
++++++++++++++++++

- C99 compiler
- C++11 compiler
- CMake >= 3.16
- SQLite3 >= 3.11: headers and library for target architecture, and sqlite3 executable for build architecture.
- SQLite3 >= 3.11: headers and library for target architecture, and sqlite3 executable for build architecture
- libtiff >= 4.0 (optional but recommended)
- curl >= 7.29.0 (optional but recommended)
- JSON for Modern C++ (nlohmann/json) >= 3.7.0; if not found as an external dependency then vendored version 3.9.1 from PROJ source tree is used

.. _test_requirements:

Test requirements
+++++++++++++++++

These are only required if testing is built (see :option:`BUILD_TESTING`, default ON)

- GoogleTest (GTest) >= 1.8.1; if not found and :option:`TESTING_USE_NETWORK` is ON, then version 1.12.1 is fetched from GitHub and locally installed
- Python >= 3.7
- `importlib_metadata <https://pypi.org/project/importlib-metadata/>`_ only needed for Python 3.7
- One of either `PyYAML <https://pypi.org/project/PyYAML/>`_ or `ruamel.yaml <https://pypi.org/project/ruamel.yaml/>`_


Build steps
--------------------------------------------------------------------------------
Expand Down Expand Up @@ -268,8 +285,9 @@ All cached entries can be viewed using ``cmake -LAH`` from a build directory.

.. option:: BUILD_TESTING=ON

CTest option to build the testing tree, which also downloads and installs
Googletest. Default is ON, but can be turned OFF if tests are not required.
CTest option to build the testing tree. Default is ON, but can be turned
OFF if tests are not required.
See :ref:`test requirements <test_requirements>` for other details.

.. versionchanged:: 7.0
Renamed from ``PROJ_TESTS``
Expand Down Expand Up @@ -414,6 +432,14 @@ All cached entries can be viewed using ``cmake -LAH`` from a build directory.
Path to an existing directory used to cache :file:`proj.db` to speed-up
subsequent builds without modifications to source SQL files.

.. option:: TESTING_USE_NETWORK=ON

.. versionadded:: 9.5

Permit use of network to fetch :ref:`test requirements
<test_requirements>` (if needed)
and run network-dependent tests. Default ON.

.. option:: EMBED_PROJ_DATA_PATH

.. versionadded:: 9.5
Expand Down
90 changes: 57 additions & 33 deletions test/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,44 +1,68 @@
set(GIE_BIN "gie")
option(TESTING_USE_NETWORK
"Permit use of network to fetch test requirements (if needed) \
and run network-dependent tests. Default ON." ON
)

if(CURL_ENABLED AND NOT DEFINED RUN_NETWORK_DEPENDENT_TESTS)
message(STATUS "Checking if network is available...")
set(HAS_NETWORK OFF) # evaluate if ON below

if(TESTING_USE_NETWORK)
if(NOT CMAKE_REQUIRED_QUIET)
# CMake 3.17+ use CHECK_START/CHECK_PASS/CHECK_FAIL
message(STATUS "Checking if network is available")
endif()
set(NO_CONNECTION 1)
find_program(HAS_CURL curl)
if(HAS_CURL)
# First try with curl as we can get an 'instant' answer if it is there
execute_process(
COMMAND curl -I https://www.google.com
OUTPUT_QUIET
ERROR_QUIET
RESULT_VARIABLE NO_CONNECTION
COMMAND ${HAS_CURL} -I https://www.google.com
OUTPUT_QUIET
ERROR_QUIET
RESULT_VARIABLE NO_CONNECTION
)
if(NOT NO_CONNECTION EQUAL 0)
# Then fallback to ping
# From https://stackoverflow.com/questions/62214621/how-to-check-for-internet-connection-with-cmake-automatically-prevent-fails-if/68376537#68376537
if(WIN32)
execute_process(
COMMAND ping www.google.com -n 2
OUTPUT_QUIET
ERROR_QUIET
RESULT_VARIABLE NO_CONNECTION
)
else()
execute_process(
COMMAND ping www.google.com -c 2
OUTPUT_QUIET
ERROR_QUIET
RESULT_VARIABLE NO_CONNECTION
)
endif()
endif()

if(NOT NO_CONNECTION EQUAL 0)
message(WARNING "... no. Skipping network dependent tests.")
set(RUN_NETWORK_DEPENDENT_TESTS_DEFAULT_VAL OFF)
else()
find_program(HAS_PING ping)
if(HAS_PING)
# Then fallback to ping -- https://stackoverflow.com/a/68376537/
if(WIN32)
set(PING_COUNT "-n")
else()
set(PING_COUNT "-c")
endif()
execute_process(
COMMAND ${HAS_PING} www.google.com ${PING_COUNT} 2
OUTPUT_QUIET
ERROR_QUIET
RESULT_VARIABLE NO_CONNECTION
)
else()
message(STATUS "... yes")
set(RUN_NETWORK_DEPENDENT_TESTS_DEFAULT_VAL ON)
message(WARNING
"Cannot establish if network is avalable - "
"'curl' or 'ping' not found"
)
endif()
option(RUN_NETWORK_DEPENDENT_TESTS "Whether to run tests dependent on network availability" ${RUN_NETWORK_DEPENDENT_TESTS_DEFAULT_VAL})
endif()
if(NO_CONNECTION EQUAL 0)
set(HAS_NETWORK ON)
if(NOT CMAKE_REQUIRED_QUIET)
message(STATUS "Checking if network is available - yes")
endif()
else()
if(NOT CMAKE_REQUIRED_QUIET)
message(STATUS
"Checking if network is available - no; skipping network-dependent tests."
)
endif()
endif()
else()
message(STATUS "Network access not premitted (TESTING_USE_NETWORK=OFF)")
endif()

option(RUN_NETWORK_DEPENDENT_TESTS
"Whether to run tests dependent on network availability"
${HAS_NETWORK}
)

# Regression tests
proj_add_gie_test("Builtins" "gie/builtins.gie")
proj_add_gie_test("Builtins2" "gie/more_builtins.gie")
Expand Down
51 changes: 43 additions & 8 deletions test/unit/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,17 +1,41 @@
# CMake configuration for PROJ unit tests
# External GTest provided by (e.g.) libgtest-dev

find_package(GTest 1.8.1)
set(MIN_GTest_VERSION "1.8.1")

if(NOT CMAKE_REQUIRED_QUIET)
# CMake 3.17+ use CHECK_START/CHECK_PASS/CHECK_FAIL
message(STATUS "Looking for GTest")
endif()
find_package(GTest QUIET)
set(USE_EXTERNAL_GTEST_DEFAULT OFF)
if(GTest_FOUND)
option(USE_EXTERNAL_GTEST "Compile against external GTest" ON)
if(NOT CMAKE_REQUIRED_QUIET)
message(STATUS "Looking for GTest - found (${GTest_VERSION})")
endif()
if(GTest_VERSION VERSION_LESS MIN_GTest_VERSION)
message(WARNING "External GTest version is too old")
else()
set(USE_EXTERNAL_GTEST_DEFAULT ON)
endif()
else()
option(USE_EXTERNAL_GTEST "Compile against external GTest" OFF)
if(NOT CMAKE_REQUIRED_QUIET)
message(STATUS "Looking for GTest - not found")
endif()
endif()

option(USE_EXTERNAL_GTEST
"Compile against external GTest"
${USE_EXTERNAL_GTEST_DEFAULT}
)

if(USE_EXTERNAL_GTEST)

if(NOT GTest_FOUND)
message(FATAL_ERROR "External GTest >= 1.8.1 not found")
message(SEND_ERROR "External GTest >= ${MIN_GTest_VERSION} not found, \
skipping some tests")
# exit the remainder of this file
return()
endif()
message(STATUS "Using external GTest")

Expand All @@ -24,9 +48,9 @@ if(USE_EXTERNAL_GTEST)
INTERFACE_LINK_LIBRARIES "GTest::GTest")
endif()

else()
elseif(HAS_NETWORK)

message(STATUS "Fetching GTest")
message(STATUS "Fetching GTest from GitHub ...")

# Add Google Test
#
Expand Down Expand Up @@ -56,8 +80,19 @@ else()
add_subdirectory(${googletest_SOURCE_DIR} ${googletest_BINARY_DIR} EXCLUDE_FROM_ALL)
endif()
endif()

endif() # USE_EXTERNAL_GTEST
else()
if(TESTING_USE_NETWORK)
set(_msg_detail "install GTest dependency")
else()
set(_msg_detail
"either install GTest dependency, or if possible, \
set TESTING_USE_NETWORK=ON to fetch content from GitHub"
)
endif()
message(WARNING "Tests that require GTest will be skipped; ${_msg_detail}")
# exit the remainder of this file
return()
endif()

#
# Build PROJ unit tests
Expand Down

0 comments on commit 64ece97

Please sign in to comment.