diff options
author | Raffi Enficiaud <raffi.enficiaud@mines-paris.org> | 2015-04-21 20:48:37 (GMT) |
---|---|---|
committer | Brad King <brad.king@kitware.com> | 2015-04-23 13:03:10 (GMT) |
commit | 75b0e1679c39ca824a4c49d9e1a2ae2b5f04ae06 (patch) | |
tree | ad0adcba48eb69edc50c2d2c9718f1434e6e1597 /Tests | |
parent | fdfe4586a047d9b6cc64efdd22fbdc67e9f1193f (diff) | |
download | CMake-75b0e1679c39ca824a4c49d9e1a2ae2b5f04ae06.zip CMake-75b0e1679c39ca824a4c49d9e1a2ae2b5f04ae06.tar.gz CMake-75b0e1679c39ca824a4c49d9e1a2ae2b5f04ae06.tar.bz2 |
CPackDeb: Add basic package tests
Tests of generated component based deb packages with lintian and dpkg.
Also includes basic file name check.
Diffstat (limited to 'Tests')
-rw-r--r-- | Tests/CMakeLists.txt | 34 | ||||
-rw-r--r-- | Tests/CPackComponentsDEB/CMakeLists.txt | 98 | ||||
-rw-r--r-- | Tests/CPackComponentsDEB/MyLibCPackConfig-components-lintian-dpkgdeb-checks.cmake.in | 15 | ||||
-rw-r--r-- | Tests/CPackComponentsDEB/RunCPackVerifyResult-components-lintian-dpkgdeb-checks.cmake | 78 | ||||
-rw-r--r-- | Tests/CPackComponentsDEB/RunCPackVerifyResult.cmake | 192 | ||||
-rw-r--r-- | Tests/CPackComponentsDEB/license.txt | 3 | ||||
-rw-r--r-- | Tests/CPackComponentsDEB/mylib.cpp | 7 | ||||
-rw-r--r-- | Tests/CPackComponentsDEB/mylib.h | 1 | ||||
-rw-r--r-- | Tests/CPackComponentsDEB/mylibapp.cpp | 6 |
9 files changed, 434 insertions, 0 deletions
diff --git a/Tests/CMakeLists.txt b/Tests/CMakeLists.txt index 699b616..f1379e6 100644 --- a/Tests/CMakeLists.txt +++ b/Tests/CMakeLists.txt @@ -1003,6 +1003,40 @@ ${CMake_BINARY_DIR}/bin/cmake -DDIR=dev -P ${CMake_SOURCE_DIR}/Utilities/Release list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/CPackComponentsForAll/build${CPackGen}-${CPackComponentWay}") endforeach() endforeach() + + # debian specific + if(DPKG_EXECUTABLE) + unset(CPackRun_CPackDEBConfiguration_ALL_CONFIGS) + set(DEB_TEST_NAMES "CPackComponentsDEB") + set(DEB_CONFIGURATIONS_TO_TEST "components-lintian-dpkgdeb-checks") + set(CPackGen "DEB") + set(CPackRun_CPackGen "-DCPackGen=${CPackGen}") + + foreach(CPackDEBConfiguration IN LISTS DEB_CONFIGURATIONS_TO_TEST) + set(CPackRun_CPackDEBConfiguration "-DCPackDEBConfiguration=${CPackDEBConfiguration}") + add_test(${DEB_TEST_NAMES}-${CPackDEBConfiguration} + ${CMAKE_CTEST_COMMAND} -C \${CTEST_CONFIGURATION_TYPE} + --build-and-test + "${CMake_SOURCE_DIR}/Tests/${DEB_TEST_NAMES}" + "${CMake_BINARY_DIR}/Tests/${DEB_TEST_NAMES}/build${CPackGen}-${CPackDEBConfiguration}" + ${build_generator_args} + --build-project CPackComponentsDEB + --build-options ${build_options} + -DCPACK_GENERATOR:STRING=${CPackGen} + -DCPACK_BINARY_${CPackGen}:BOOL=ON + ${CPackRun_CPackDEBConfiguration} + ${CPackRun_CPackDEBConfiguration_ALL_CONFIGS} + --graphviz=${DEB_TEST_NAMES}.dot + --test-command ${CMAKE_CMAKE_COMMAND} + "-D${DEB_TEST_NAMES}_SOURCE_DIR:PATH=${CMake_SOURCE_DIR}/Tests/${DEB_TEST_NAMES}" + "-D${DEB_TEST_NAMES}_BINARY_DIR:PATH=${CMake_BINARY_DIR}/Tests/${DEB_TEST_NAMES}/build${CPackGen}-${CPackDEBConfiguration}" + "${CPackRun_CPackGen}" + "${CPackRun_CPackDEBConfiguration}" + -P "${CMake_SOURCE_DIR}/Tests/${DEB_TEST_NAMES}/RunCPackVerifyResult-${CPackDEBConfiguration}.cmake") + list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/${DEB_TEST_NAMES}/build${CPackGen}-${CPackDEBConfiguration}") + endforeach() + endif() + endif() # By default, turn this test off (because it takes a long time...) diff --git a/Tests/CPackComponentsDEB/CMakeLists.txt b/Tests/CPackComponentsDEB/CMakeLists.txt new file mode 100644 index 0000000..5c4eeab --- /dev/null +++ b/Tests/CPackComponentsDEB/CMakeLists.txt @@ -0,0 +1,98 @@ +# CPack Example: User-selectable Installation Components +# +# In this example, we have a simple library (mylib) with an example +# application (mylibapp). We create a binary installer (a CPack Generator) +# which supports CPack components. + +cmake_minimum_required(VERSION 2.8.3.20101130 FATAL_ERROR) +project(CPackComponentsDEB) + +# Use GNUInstallDirs in order to enforce lib64 if needed +include(GNUInstallDirs) + +# Create the mylib library +add_library(mylib mylib.cpp) + +# Create the mylibapp application +add_executable(mylibapp mylibapp.cpp) +target_link_libraries(mylibapp mylib) + +# Duplicate of mylibapp application +# which won't be put in any component (?mistake?) +add_executable(mylibapp2 mylibapp.cpp) +target_link_libraries(mylibapp2 mylib) + +# Create installation targets. Note that we put each kind of file +# into a different component via COMPONENT. These components will +# be used to create the installation components. +install(TARGETS mylib + ARCHIVE + DESTINATION ${CMAKE_INSTALL_LIBDIR} + COMPONENT libraries) + +install(TARGETS mylibapp + RUNTIME + DESTINATION bin + COMPONENT applications) + +install(FILES mylib.h + DESTINATION include + COMPONENT headers) + +# CPack boilerplate for this project +set(CPACK_PACKAGE_NAME "MyLib") +set(CPACK_PACKAGE_CONTACT "None") +set(CPACK_PACKAGE_VENDOR "CMake.org") +set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "MyLib - CPack Component Installation Example") +set(CPACK_PACKAGE_VERSION "1.0.2") +set(CPACK_PACKAGE_VERSION_MAJOR "1") +set(CPACK_PACKAGE_VERSION_MINOR "0") +set(CPACK_PACKAGE_VERSION_PATCH "2") +set(CPACK_PACKAGE_INSTALL_DIRECTORY "CPack Component Example") +set(CPACK_RESOURCE_FILE_LICENSE ${CMAKE_CURRENT_SOURCE_DIR}/license.txt) + +# Tell CPack all of the components to install. The "ALL" +# refers to the fact that this is the set of components that +# will be included when CPack is instructed to put everything +# into the binary installer (the default behavior). +set(CPACK_COMPONENTS_ALL applications libraries headers) + +# Set the displayed names for each of the components to install. +# These will be displayed in the list of components inside the installer. +set(CPACK_COMPONENT_APPLICATIONS_DISPLAY_NAME "MyLib Application") +set(CPACK_COMPONENT_LIBRARIES_DISPLAY_NAME "Libraries") +set(CPACK_COMPONENT_HEADERS_DISPLAY_NAME "C++ Headers") + +# Provide descriptions for each of the components to install. +# When the user hovers the mouse over the name of a component, +# the description will be shown in the "Description" box in the +# installer. If no descriptions are provided, the "Description" +# box will be removed. +set(CPACK_COMPONENT_APPLICATIONS_DESCRIPTION + "An extremely useful application that makes use of MyLib") +set(CPACK_COMPONENT_LIBRARIES_DESCRIPTION + "Static libraries used to build programs with MyLib") +set(CPACK_COMPONENT_HEADERS_DESCRIPTION + "C/C++ header files for use with MyLib") + +# It doesn't make sense to install the headers without the libraries +# (because you could never use the headers!), so make the headers component +# depend on the libraries component. +set(CPACK_COMPONENT_HEADERS_DEPENDS libraries) + +# We may use the CPack specific config file in order +# to tailor CPack behavior on a CPack generator specific way +# (Behavior would be different for RPM or TGZ or DEB ...) +if (NOT DEFINED CPackDEBConfiguration) + message(FATAL_ERROR "CPackDEBConfiguration should be defined") +endif() + +# Setup project specific CPack-time CPack Config file. +configure_file(${CPackComponentsDEB_SOURCE_DIR}/MyLibCPackConfig-${CPackDEBConfiguration}.cmake.in + ${CPackComponentsDEB_BINARY_DIR}/MyLibCPackConfig-${CPackDEBConfiguration}.cmake + @ONLY) +set(CPACK_PROJECT_CONFIG_FILE ${CPackComponentsDEB_BINARY_DIR}/MyLibCPackConfig-${CPackDEBConfiguration}.cmake) + + +# Include CPack to introduce the appropriate targets +include(CPack) diff --git a/Tests/CPackComponentsDEB/MyLibCPackConfig-components-lintian-dpkgdeb-checks.cmake.in b/Tests/CPackComponentsDEB/MyLibCPackConfig-components-lintian-dpkgdeb-checks.cmake.in new file mode 100644 index 0000000..e0a9e9d --- /dev/null +++ b/Tests/CPackComponentsDEB/MyLibCPackConfig-components-lintian-dpkgdeb-checks.cmake.in @@ -0,0 +1,15 @@ +# +# Activate component packaging +# + +if(CPACK_GENERATOR MATCHES "DEB") + set(CPACK_DEB_COMPONENT_INSTALL "ON") +endif() + +# +# Choose grouping way +# +#set(CPACK_COMPONENTS_ALL_GROUPS_IN_ONE_PACKAGE) +#set(CPACK_COMPONENTS_GROUPING) +set(CPACK_COMPONENTS_IGNORE_GROUPS 1) +#set(CPACK_COMPONENTS_ALL_IN_ONE_PACKAGE 1) diff --git a/Tests/CPackComponentsDEB/RunCPackVerifyResult-components-lintian-dpkgdeb-checks.cmake b/Tests/CPackComponentsDEB/RunCPackVerifyResult-components-lintian-dpkgdeb-checks.cmake new file mode 100644 index 0000000..5460b1a --- /dev/null +++ b/Tests/CPackComponentsDEB/RunCPackVerifyResult-components-lintian-dpkgdeb-checks.cmake @@ -0,0 +1,78 @@ +if(NOT CPackComponentsDEB_SOURCE_DIR) + message(FATAL_ERROR "CPackComponentsDEB_SOURCE_DIR not set") +endif() + +include(${CPackComponentsDEB_SOURCE_DIR}/RunCPackVerifyResult.cmake) + +# TODO: currently debian doens't produce lower cased names +set(expected_file_mask "${CPackComponentsDEB_BINARY_DIR}/MyLib-*.deb") +set(expected_count 3) + + +set(actual_output) +run_cpack(actual_output + CPack_output + CPack_error + EXPECTED_FILE_MASK "${expected_file_mask}" + CONFIG_ARGS "${config_args}" + CONFIG_VERBOSE "${config_verbose}") + +if(NOT actual_output) + message(STATUS "expected_count='${expected_count}'") + message(STATUS "expected_file_mask='${expected_file_mask}'") + message(STATUS "actual_output_files='${actual_output}'") + message(FATAL_ERROR "error: expected_files do not exist: CPackComponentsDEB test fails. (CPack_output=${CPack_output}, CPack_error=${CPack_error}") +endif() + +list(LENGTH actual_output actual_count) +if(NOT actual_count EQUAL expected_count) + message(STATUS "actual_count='${actual_count}'") + message(FATAL_ERROR "error: expected_count=${expected_count} does not match actual_count=${actual_count}: CPackComponents test fails. (CPack_output=${CPack_output}, CPack_error=${CPack_error})") +endif() + + +# lintian checks +find_program(LINTIAN_EXECUTABLE lintian) +if(LINTIAN_EXECUTABLE) + set(lintian_output_errors_all "") + foreach(_f IN LISTS actual_output) + set(STRINGS_TO_AVOID "E:([^\r\n]*)control-file-has-bad-permissions") + lintian_check_specific_errors(lintian_output_errors + FILENAME "${_f}" + ERROR_REGEX_STRINGS "${STRINGS_TO_AVOID}") + + set(lintian_output_errors_all "${lintian_output_errors_all}${lintian_output_errors}") + endforeach() + + if(NOT "${lintian_output_errors_all}" STREQUAL "") + message(FATAL_ERROR "Lintian checks failed:\n${lintian_output_errors_all}") + endif() +else() + message("lintian executable not found - skipping lintian test") +endif() + +# dpkg-deb checks +find_program(DPKGDEB_EXECUTABLE dpkg-deb) +if(DPKGDEB_EXECUTABLE) + set(dpkgdeb_output_errors_all "") + foreach(_f IN LISTS actual_output) + run_dpkgdeb(dpkg_output + FILENAME "${_f}" + ) + + dpkgdeb_return_specific_metaentry(dpkgentry + DPKGDEB_OUTPUT "${dpkg_output}" + METAENTRY "Maintainer:") + + if(NOT "${dpkgentry}" STREQUAL "None") + set(dpkgdeb_output_errors_all "${dpkgdeb_output_errors_all}" + "dpkg-deb: ${_f}: Incorrect value for Maintainer: ${dpkgentry} != None\n") + endif() + endforeach() + + if(NOT "${dpkgdeb_output_errors_all}" STREQUAL "") + message(FATAL_ERROR "dpkg-deb checks failed:\n${dpkgdeb_output_errors_all}") + endif() +else() + message("dpkg-deb executable not found - skipping dpkg-deb test") +endif() diff --git a/Tests/CPackComponentsDEB/RunCPackVerifyResult.cmake b/Tests/CPackComponentsDEB/RunCPackVerifyResult.cmake new file mode 100644 index 0000000..bd4f12a --- /dev/null +++ b/Tests/CPackComponentsDEB/RunCPackVerifyResult.cmake @@ -0,0 +1,192 @@ +# prevent older policies from interfearing with this script +cmake_policy(PUSH) +cmake_policy(VERSION ${CMAKE_VERSION}) + + +include(CMakeParseArguments) + +message(STATUS "=============================================================================") +message(STATUS "CTEST_FULL_OUTPUT (Avoid ctest truncation of output)") +message(STATUS "") + +if(NOT CPackComponentsDEB_BINARY_DIR) + message(FATAL_ERROR "CPackComponentsDEB_BINARY_DIR not set") +endif() + +if(NOT CPackGen) + message(FATAL_ERROR "CPackGen not set") +endif() + +message("CMAKE_CPACK_COMMAND = ${CMAKE_CPACK_COMMAND}") +if(NOT CMAKE_CPACK_COMMAND) + message(FATAL_ERROR "CMAKE_CPACK_COMMAND not set") +endif() + +if(NOT CPackDEBConfiguration) + message(FATAL_ERROR "CPackDEBConfiguration not set") +endif() + +# run cpack with some options and returns the list of files generated +# -output_expected_file: list of files that match the pattern +function(run_cpack output_expected_file CPack_output_parent CPack_error_parent) + set(options ) + set(oneValueArgs "EXPECTED_FILE_MASK" "CONFIG_VERBOSE") + set(multiValueArgs "CONFIG_ARGS") + cmake_parse_arguments(run_cpack_deb "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN} ) + + + # clean-up previously CPack generated files + if(${run_cpack_deb_EXPECTED_FILE_MASK}) + file(GLOB expected_file "${${run_cpack_deb_EXPECTED_FILE_MASK}}") + if (expected_file) + file(REMOVE "${expected_file}") + endif() + endif() + + message("config_args = ${run_cpack_deb_CONFIG_ARGS}") + message("config_verbose = ${run_cpack_deb_CONFIG_VERBOSE}") + execute_process(COMMAND ${CMAKE_CPACK_COMMAND} ${run_cpack_deb_CONFIG_VERBOSE} -G ${CPackGen} ${run_cpack_deb_CONFIG_ARGS} + RESULT_VARIABLE CPack_result + OUTPUT_VARIABLE CPack_output + ERROR_VARIABLE CPack_error + WORKING_DIRECTORY ${CPackComponentsDEB_BINARY_DIR}) + + set(${CPack_output_parent} ${CPack_output} PARENT_SCOPE) + set(${CPack_error_parent} ${CPack_error} PARENT_SCOPE) + + if (CPack_result) + message(FATAL_ERROR "error: CPack execution went wrong!, CPack_output=${CPack_output}, CPack_error=${CPack_error}") + else () + message(STATUS "CPack_output=${CPack_output}") + endif() + + + if(run_cpack_deb_EXPECTED_FILE_MASK) + file(GLOB _output_expected_file "${run_cpack_deb_EXPECTED_FILE_MASK}") + set(${output_expected_file} "${_output_expected_file}" PARENT_SCOPE) + endif() +endfunction() + + + +# This function runs lintian on a .deb and returns its output +function(run_lintian lintian_output) + set(${lintian_output} "" PARENT_SCOPE) + + find_program(LINTIAN_EXECUTABLE lintian) + if(LINTIAN_EXECUTABLE) + set(options "") + set(oneValueArgs "FILENAME") + set(multiValueArgs "") + cmake_parse_arguments(run_lintian_deb "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN} ) + + + if(NOT run_lintian_deb_FILENAME) + message(FATAL_ERROR "error: run_lintian needs FILENAME to be set") + endif() + + # run lintian + execute_process(COMMAND ${LINTIAN_EXECUTABLE} ${run_lintian_deb_FILENAME} + WORKING_DIRECTORY "${CPACK_TEMPORARY_DIRECTORY}" + OUTPUT_VARIABLE LINTIAN_OUTPUT + RESULT_VARIABLE LINTIAN_RESULT + ERROR_VARIABLE LINTIAN_ERROR + OUTPUT_STRIP_TRAILING_WHITESPACE ) + + set(${lintian_output} "${LINTIAN_OUTPUT}" PARENT_SCOPE) + else() + message(FATAL_ERROR "run_lintian called without lintian executable being present") + endif() +endfunction() + + +# Higher level lintian check that parse the output for errors and required strings +function(lintian_check_specific_errors output_errors) + set(${output_errors} "" PARENT_SCOPE) + set(ERROR_ACC) + + set(options "") + set(oneValueArgs "FILENAME") + set(multiValueArgs "ERROR_REGEX_STRINGS") + cmake_parse_arguments(lintian_check_specific_errors_deb "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN} ) + + set(lintian_output) + run_lintian(lintian_output FILENAME ${lintian_check_specific_errors_deb_FILENAME}) + + message(STATUS "Lintian output is ''${lintian_output}'") + + # regex to avoid + foreach(_s IN LISTS lintian_check_specific_errors_deb_ERROR_REGEX_STRINGS) + + if("${_s}" STREQUAL "") + continue() + endif() + + string(REGEX MATCHALL "${_s}" "_TMP_CHECK_ERROR" "${lintian_output}") + + if(NOT "${_TMP_CHECK_ERROR}" STREQUAL "") + set(ERROR_ACC "${ERROR_ACC}\nlintian: ${_f}: output contains an undesirable regex:\n\t${_TMP_CHECK_ERROR}") + endif() + endforeach() + + set(${output_errors} "${ERROR_ACC}" PARENT_SCOPE) +endfunction() + + + + +# This function runs dpkg-deb on a .deb and returns its output +function(run_dpkgdeb dpkg_deb_output) + set(${dpkg_deb_output} "" PARENT_SCOPE) + + find_program(DPKGDEB_EXECUTABLE dpkg-deb) + if(DPKGDEB_EXECUTABLE) + + set(options "") + set(oneValueArgs "FILENAME") + set(multiValueArgs "") + cmake_parse_arguments(run_dpkgdeb_deb "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN} ) + + + if(NOT run_dpkgdeb_deb_FILENAME) + message(FATAL_ERROR "error: run_dpkgdeb needs FILENAME to be set") + endif() + + # run lintian + execute_process(COMMAND ${DPKGDEB_EXECUTABLE} -I ${run_dpkgdeb_deb_FILENAME} + WORKING_DIRECTORY "${CPACK_TEMPORARY_DIRECTORY}" + OUTPUT_VARIABLE DPKGDEB_OUTPUT + RESULT_VARIABLE DPKGDEB_RESULT + ERROR_VARIABLE DPKGDEB_ERROR + OUTPUT_STRIP_TRAILING_WHITESPACE ) + + set(${dpkg_deb_output} "${DPKGDEB_OUTPUT}" PARENT_SCOPE) + else() + message(FATAL_ERROR "run_dpkgdeb called without dpkg-deb executable being present") + endif() +endfunction() + + +# returns a particular line of the metadata of the .deb, for checking +# a previous call to run_dpkgdeb should provide the DPKGDEB_OUTPUT entry. +function(dpkgdeb_return_specific_metaentry output) + set(${output} "" PARENT_SCOPE) + + set(options "") + set(oneValueArgs "DPKGDEB_OUTPUT" "METAENTRY") + set(multiValueArgs "") + cmake_parse_arguments(dpkgdeb_return_specific_metaentry_deb "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN} ) + + if(NOT dpkgdeb_return_specific_metaentry_deb_METAENTRY) + message(FATAL_ERROR "error: dpkgdeb_return_specific_metaentry needs METAENTRY to be set") + endif() + + string(REGEX MATCH "${dpkgdeb_return_specific_metaentry_deb_METAENTRY}([^\r\n]*)" _TMP_STR "${dpkgdeb_return_specific_metaentry_deb_DPKGDEB_OUTPUT}") + #message("################ _TMP_STR = ${CMAKE_MATCH_1} ##################") + if(NOT "${CMAKE_MATCH_1}" STREQUAL "") + string(STRIP "${CMAKE_MATCH_1}" _TMP_STR) + set(${output} "${_TMP_STR}" PARENT_SCOPE) + endif() +endfunction() + +cmake_policy(POP) diff --git a/Tests/CPackComponentsDEB/license.txt b/Tests/CPackComponentsDEB/license.txt new file mode 100644 index 0000000..ba8ba48 --- /dev/null +++ b/Tests/CPackComponentsDEB/license.txt @@ -0,0 +1,3 @@ +LICENSE +------- +This is an installer created using CPack (http://www.cmake.org). No license provided. diff --git a/Tests/CPackComponentsDEB/mylib.cpp b/Tests/CPackComponentsDEB/mylib.cpp new file mode 100644 index 0000000..8ddac19 --- /dev/null +++ b/Tests/CPackComponentsDEB/mylib.cpp @@ -0,0 +1,7 @@ +#include "mylib.h" +#include "stdio.h" + +void mylib_function() +{ + printf("This is mylib"); +} diff --git a/Tests/CPackComponentsDEB/mylib.h b/Tests/CPackComponentsDEB/mylib.h new file mode 100644 index 0000000..5d0a822 --- /dev/null +++ b/Tests/CPackComponentsDEB/mylib.h @@ -0,0 +1 @@ +void mylib_function(); diff --git a/Tests/CPackComponentsDEB/mylibapp.cpp b/Tests/CPackComponentsDEB/mylibapp.cpp new file mode 100644 index 0000000..a438ac7 --- /dev/null +++ b/Tests/CPackComponentsDEB/mylibapp.cpp @@ -0,0 +1,6 @@ +#include "mylib.h" + +int main() +{ + mylib_function(); +} |