Make sysrepo dependency optional
This project is useful as a standalone NETCONF client, too. Do not
require sysrepo unconditionally. If not available, just build the main
NETCONF client (and a `yang-cli`, too, because it's essentially free).
The CMake setup is a wee bit complex. CMake's OPTION statement doesn't
really support tri-state dependencies, and I like automagic stuff:
- OFF for disabling stuff unconditionally, even if the deps are there,
- ON for enabling stuff, and failing if it cannot be built,
- AUTO for trying to enable stuff if possible, and gracefully disabling
it if not available
Of course this has a potential of introducing nasty surprises to the CI,
so make sure the CI fails if the sysrepo backend gets disabled for some
reason.
Change-Id: I9c38245c3eea767ad20f42240328c483b6f80dd4
diff --git a/.zuul.public.yaml b/.zuul.public.yaml
index d03af02..f8a4675 100644
--- a/.zuul.public.yaml
+++ b/.zuul.public.yaml
@@ -1,3 +1,9 @@
+- job:
+ name: f32-gcc-netconf-cli-no-sysrepo
+ description: |
+ Build a minimal version without sysrepo or the test suite
+ parent: f32-gcc
+
- project:
check:
jobs:
@@ -7,6 +13,8 @@
requires: CzechLight-deps-f32-clang-asan-ubsan
- f32-clang-tsan:
requires: CzechLight-deps-f32-clang-tsan
+ - f32-gcc-netconf-cli-no-sysrepo:
+ requires: CzechLight-deps-f32-gcc
- f32-cpp-coverage-diff:
voting: false
- clang-format:
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 83fc93b..92ab37f 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -5,6 +5,7 @@
set(CMAKE_POSITION_INDEPENDENT_CODE TRUE)
include(GNUInstallDirs)
+include(CTest)
# Set a default build type if none was specified. This was shamelessly stolen
# from VTK's cmake setup because these guys produce both CMake and a project that
@@ -62,10 +63,70 @@
endif()
find_package(PkgConfig)
+
+set(ENABLE_SYSREPO_CLI AUTO CACHE STRING "Enable the `sysrepo-cli`")
+set_property(CACHE ENABLE_SYSREPO_CLI PROPERTY STRINGS AUTO ON OFF)
+set(ENABLE_FULL_TESTS AUTO CACHE STRING "Enable end-to-end tests via sysrepo and netopeer2")
+set_property(CACHE ENABLE_FULL_TESTS PROPERTY STRINGS AUTO ON OFF)
+if(NOT (ENABLE_SYSREPO_CLI STREQUAL ON OR ENABLE_SYSREPO_CLI STREQUAL OFF OR ENABLE_SYSREPO_CLI STREQUAL AUTO))
+ message(FATAL_ERROR "ENABLE_SYSREPO_CLI must be one of ON, OFF, AUTO")
+endif()
+if(NOT (ENABLE_FULL_TESTS STREQUAL ON OR ENABLE_FULL_TESTS STREQUAL OFF OR ENABLE_FULL_TESTS STREQUAL AUTO))
+ message(FATAL_ERROR "ENABLE_FULL_TESTS must be one of ON, OFF, AUTO")
+endif()
+if(NOT BUILD_TESTING AND ENABLE_FULL_TESTS STREQUAL ON)
+ message(FATAL_ERROR "Cannot combine ENABLE_FULL_TESTS=ON with BUILD_TESTING=OFF")
+endif()
+
pkg_check_modules(LIBYANG REQUIRED libyang-cpp>=1.0.190 IMPORTED_TARGET libyang)
-pkg_check_modules(SYSREPO REQUIRED sysrepo-cpp>=1.4.79 IMPORTED_TARGET sysrepo)
pkg_check_modules(LIBNETCONF2 REQUIRED libnetconf2>=1.1.32 IMPORTED_TARGET libnetconf2)
+if(ENABLE_FULL_TESTS STREQUAL OFF AND ENABLE_SYSREPO_CLI STREQUAL OFF)
+ message(STATUS "Skipping sysrepo per configure options")
+ set(SYSREPO_FOUND 0)
+else()
+ pkg_check_modules(SYSREPO sysrepo-cpp>=1.4.79 IMPORTED_TARGET sysrepo)
+endif()
+
+if(SYSREPO_FOUND)
+ if(ENABLE_SYSREPO_CLI STREQUAL OFF)
+ message(STATUS "Skipping the `sysrepo-cli` per config option")
+ set(DO_ENABLE_SYSREPO_CLI OFF)
+ else()
+ message(STATUS "The `sysrepo-cli` will be available")
+ set(DO_ENABLE_SYSREPO_CLI ON)
+ endif()
+
+ if(BUILD_TESTING)
+ include(cmake/DiscoverNetconfExecutables.cmake)
+ discover_netconf_executables()
+
+ if(ENABLE_FULL_TESTS STREQUAL OFF)
+ message(STATUS "End-to-end NETCONF test suite disabled per config option")
+ set(DO_ENABLE_NETCONF_TESTS OFF)
+ else()
+ message(STATUS "End-to-end NETCONF test suite enabled")
+ set(DO_ENABLE_NETCONF_TESTS ON)
+ endif()
+ endif()
+else()
+ if(ENABLE_SYSREPO_CLI STREQUAL ON)
+ message(FATAL_ERROR "Cannot find sysrepo-cpp which is required for the `sysrepo-cli`")
+ elseif(ENABLE_SYSREPO_CLI STREQUAL AUTO)
+ message(STATUS "Cannot find sysrepo-cpp, skipping the `sysrepo-cli`")
+ endif()
+ set(DO_ENABLE_SYSREPO_CLI OFF)
+
+ if(BUILD_TESTING)
+ if(ENABLE_FULL_TESTS STREQUAL ON)
+ message(FATAL_ERROR "Cannot find sysrepo-cpp which is required for the end-to-end NETCONF test suite")
+ elseif(ENABLE_FULL_TESTS STREQUAL AUTO)
+ message(STATUS "Cannot find sysrepo-cpp, skipping the end-to-end NETCONF test suite")
+ endif()
+ set(DO_ENABLE_NETCONF_TESTS OFF)
+ endif()
+endif()
+
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/src/)
add_library(ast_values STATIC
@@ -100,11 +161,13 @@
)
target_link_libraries(datastoreaccess PUBLIC Boost::boost)
-add_library(sysrepoaccess STATIC
- src/sysrepo_access.cpp
- )
+if(DO_ENABLE_SYSREPO_CLI OR DO_ENABLE_NETCONF_TESTS)
+ add_library(sysrepoaccess STATIC
+ src/sysrepo_access.cpp
+ )
-target_link_libraries(sysrepoaccess PUBLIC datastoreaccess ast_values PRIVATE PkgConfig::SYSREPO PkgConfig::LIBYANG)
+ target_link_libraries(sysrepoaccess PUBLIC datastoreaccess ast_values PRIVATE PkgConfig::SYSREPO PkgConfig::LIBYANG)
+endif()
add_library(netconfaccess STATIC
src/netconf-client.cpp
@@ -152,12 +215,15 @@
target_include_directories(${cli_target} PRIVATE ${PROJECT_BINARY_DIR})
endfunction()
-add_executable(sysrepo-cli
- src/cli.cpp
- )
-target_compile_definitions(sysrepo-cli PRIVATE SYSREPO_CLI)
-target_link_libraries(sysrepo-cli sysrepoaccess)
-cli_link_required(sysrepo-cli)
+if(DO_ENABLE_SYSREPO_CLI)
+ add_executable(sysrepo-cli
+ src/cli.cpp
+ )
+ target_compile_definitions(sysrepo-cli PRIVATE SYSREPO_CLI)
+ target_link_libraries(sysrepo-cli sysrepoaccess)
+ cli_link_required(sysrepo-cli)
+ list(APPEND cli_targets sysrepo-cli)
+endif()
add_executable(yang-cli
src/cli.cpp
@@ -165,6 +231,7 @@
target_compile_definitions(yang-cli PRIVATE YANG_CLI)
cli_link_required(yang-cli)
target_link_libraries(yang-cli yangaccess)
+list(APPEND cli_targets yang-cli)
if(CMAKE_CXX_FLAGS MATCHES "-stdlib=libc\\+\\+" AND CMAKE_CXX_COMPILER_ID STREQUAL "Clang" AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 9.0)
target_link_libraries(yang-cli c++experimental)
elseif(CMAKE_CXX_COMPILER_ID STREQUAL "GNU" AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 9.1)
@@ -179,9 +246,9 @@
target_link_libraries(netconf-cli netconfaccess Threads::Threads Boost::filesystem)
cli_link_required(netconf-cli)
+list(APPEND cli_targets netconf-cli)
-include(CTest)
if(BUILD_TESTING)
find_package(trompeloeil 33 REQUIRED)
find_package(doctest 2.3.1 REQUIRED)
@@ -195,16 +262,15 @@
target_link_libraries(DoctestIntegration doctest::doctest trompeloeil)
target_compile_definitions(DoctestIntegration PUBLIC DOCTEST_CONFIG_SUPER_FAST_ASSERTS)
- add_library(sysreposubscription STATIC
- tests/mock/sysrepo_subscription.cpp
- )
- target_link_libraries(sysreposubscription PUBLIC datastoreaccess PRIVATE PkgConfig::SYSREPO)
+ if(DO_ENABLE_NETCONF_TESTS)
+ add_library(sysreposubscription STATIC
+ tests/mock/sysrepo_subscription.cpp
+ )
+ target_link_libraries(sysreposubscription PUBLIC datastoreaccess PRIVATE PkgConfig::SYSREPO)
- include(cmake/DiscoverNetconfExecutables.cmake)
- discover_netconf_executables()
-
- file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/test_repositories)
- file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/test_sockets)
+ file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/test_repositories)
+ file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/test_sockets)
+ endif()
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/tests/yang_access_test_vars.hpp.in ${CMAKE_CURRENT_BINARY_DIR}/yang_access_test_vars.hpp @ONLY)
@@ -290,8 +356,10 @@
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/tests/cleanup_datastore.bash.in
${CMAKE_CURRENT_BINARY_DIR}/cleanup_datastore.bash @ONLY)
- datastore_test(datastore_access ${CMAKE_CURRENT_SOURCE_DIR}/tests/example-schema.yang)
- datastore_test(data_query ${CMAKE_CURRENT_SOURCE_DIR}/tests/example-schema.yang)
+ if(DO_ENABLE_NETCONF_TESTS)
+ datastore_test(datastore_access ${CMAKE_CURRENT_SOURCE_DIR}/tests/example-schema.yang)
+ datastore_test(data_query ${CMAKE_CURRENT_SOURCE_DIR}/tests/example-schema.yang)
+ endif()
endif()
option(WITH_PYTHON_BINDINGS "Create and install Python3 bindings for accessing datastores" OFF)
@@ -366,8 +434,5 @@
)
endif()
-install(TARGETS
- netconf-cli
- sysrepo-cli
- yang-cli
+install(TARGETS ${cli_targets}
RUNTIME DESTINATION ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_BINDIR}/)
diff --git a/README.md b/README.md
index db53340..7965674 100644
--- a/README.md
+++ b/README.md
@@ -12,7 +12,7 @@
* [cmake](https://cmake.org/download/) for managing the build
* [libyang](https://github.com/CESNET/libyang) for working with YANG models
* [libnetconf2](https://github.com/CESNET/libnetconf2) for connecting to NETCONF servers
-* [sysrepo](https://github.com/sysrepo/sysrepo/) **version 1.4.x** for the local sysrepo backend
+* [sysrepo](https://github.com/sysrepo/sysrepo/) **version 1.4.x** for the local sysrepo backend, and for the comprehensive test suite
* [replxx](https://github.com/AmokHuginnsson/replxx) which provides interactive line prompts
* [docopt](https://github.com/docopt/docopt.cpp) for CLI option parsing
* [pkg-config](https://www.freedesktop.org/wiki/Software/pkg-config/) for building
diff --git a/ci/build.sh b/ci/build.sh
index 1ce6c23..d6b75f4 100755
--- a/ci/build.sh
+++ b/ci/build.sh
@@ -73,7 +73,7 @@
if [[ -z "${ARTIFACT_URL}" ]]; then
# fallback to a promoted artifact
- ARTIFACT_URL="https://object-store.cloud.muni.cz/swift/v1/ci-artifacts-${ZUUL_TENANT}/${ZUUL_GERRIT_HOSTNAME}/CzechLight/dependencies/${ZUUL_JOB_NAME%%-cover?(-previous)}/${DEP_SUBMODULE_COMMIT}.tar.zst"
+ ARTIFACT_URL="https://object-store.cloud.muni.cz/swift/v1/ci-artifacts-${ZUUL_TENANT}/${ZUUL_GERRIT_HOSTNAME}/CzechLight/dependencies/${ZUUL_JOB_NAME%%+(-cover?(-previous)|-netconf-cli-no-sysrepo)}/${DEP_SUBMODULE_COMMIT}.tar.zst"
fi
ARTIFACT_FILE=$(basename ${ARTIFACT_URL})
@@ -84,11 +84,24 @@
fi
curl ${ARTIFACT_URL} | unzstd --stdout | tar -C ${PREFIX} -xf -
+if [[ ${ZUUL_JOB_NAME} =~ .*-no-sysrepo ]]; then
+ rm -rf ${PREFIX}/include/sysrepo*
+ rm ${PREFIX}/lib*/libsysrepo*
+ rm ${PREFIX}/lib*/pkgconfig/sysrepo*
+ rm ${PREFIX}/bin/sysrepo*
+fi
+
cd ${BUILD_DIR}
cmake -GNinja -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE:-Debug} -DCMAKE_INSTALL_PREFIX=${PREFIX} ${CMAKE_OPTIONS} ${ZUUL_PROJECT_SRC_DIR}
ninja-build
ctest -j${CI_PARALLEL_JOBS} --output-on-failure
+if [[ ! ${ZUUL_JOB_NAME} =~ .*-no-sysrepo ]]; then
+ # Normal builds should have the sysrepo and NETCONF tests
+ ctest --show-only=json-v1 | jq -r '.["tests"] | map(.name)' | grep -q test_datastore_access_netconf
+ ctest --show-only=json-v1 | jq -r '.["tests"] | map(.name)' | grep -q test_datastore_access_sysrepo
+fi
+
if [[ $JOB_PERFORM_EXTRA_WORK == 1 ]]; then
ninja-build doc
pushd html