Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add ament_cmake_pytest package #116

Merged
merged 3 commits into from
Nov 14, 2017
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions ament_cmake_pytest/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
cmake_minimum_required(VERSION 3.5)

project(ament_cmake_pytest NONE)

find_package(ament_cmake_core REQUIRED)

ament_package(
CONFIG_EXTRAS "ament_cmake_pytest-extras.cmake"
)

install(
DIRECTORY cmake
DESTINATION share/${PROJECT_NAME}
)
20 changes: 20 additions & 0 deletions ament_cmake_pytest/ament_cmake_pytest-extras.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# Copyright 2017 Open Source Robotics Foundation, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

# copied from ament_cmake_pytest/ament_cmake_pytest-extras.cmake

find_package(ament_cmake_test QUIET REQUIRED)

include("${ament_cmake_pytest_DIR}/ament_add_pytest_test.cmake")
include("${ament_cmake_pytest_DIR}/ament_has_pytest.cmake")
128 changes: 128 additions & 0 deletions ament_cmake_pytest/cmake/ament_add_pytest_test.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
# Copyright 2017 Open Source Robotics Foundation, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

#
# Add a pytest test.
#
# :param testname: the name of the test
# :type testname: string
# :param path: the path to a file or folder where ``pytest`` should be invoked
# on
# :type path: string
# :param SKIP_TEST: if set mark the test as being skipped
# :type SKIP_TEST: option
# :param PYTHON_EXECUTABLE: absolute path to the executable used to run the test,
# default to the CMake variable with the same name returned by FindPythonInterp
# :type PYTHON_EXECUTABLE: string
# :param TIMEOUT: the test timeout in seconds,
# default defined by ``ament_add_test()``
# :type TIMEOUT: integer
# :param WORKING_DIRECTORY: the working directory for invoking the
# command in, default defined by ``ament_add_test()``
# :type WORKING_DIRECTORY: string
# :param ENV: list of env vars to set; listed as ``VAR=value``
# :type ENV: list of strings
# :param APPEND_ENV: list of env vars to append if already set, otherwise set;
# listed as ``VAR=value``
# :type APPEND_ENV: list of strings
# :param APPEND_LIBRARY_DIRS: list of library dirs to append to the appropriate
# OS specific env var, a la LD_LIBRARY_PATH
# :type APPEND_LIBRARY_DIRS: list of strings
#
# @public
#
function(ament_add_pytest_test testname path)
cmake_parse_arguments(ARG
"SKIP_TEST"
"PYTHON_EXECUTABLE;TIMEOUT;WORKING_DIRECTORY"
"APPEND_ENV;APPEND_LIBRARY_DIRS;ENV"
${ARGN})
if(ARG_UNPARSED_ARGUMENTS)
message(FATAL_ERROR "ament_add_pytest_test() called with unused arguments: "
"${ARG_UNPARSED_ARGUMENTS}")
endif()

# check arguments
if(NOT IS_ABSOLUTE "${path}")
set(path "${CMAKE_CURRENT_SOURCE_DIR}/${path}")
endif()
# only check existence of path if it doesn't contain generator expressions
string(FIND "${path}" "$<" index)
if(index EQUAL -1 AND NOT EXISTS "${path}")
message(FATAL_ERROR
"ament_add_pytest_test() the path '${path}' does not exist")
endif()
if(NOT ARG_PYTHON_EXECUTABLE)
set(ARG_PYTHON_EXECUTABLE "${PYTHON_EXECUTABLE}")
endif()

# ensure pytest is available
ament_has_pytest(has_pytest QUIET PYTHON_EXECUTABLE "${ARG_PYTHON_EXECUTABLE}")
if(NOT has_pytest)
message(WARNING
"The Python module 'pytest' was not found, pytests can not be run (e.g. "
"on Ubuntu/Debian install the package 'python3-pytest')")
return()
endif()

set(result_file "${AMENT_TEST_RESULTS_DIR}/${PROJECT_NAME}/${testname}.xunit.xml")
set(cmd
"${ARG_PYTHON_EXECUTABLE}"
"-u" # unbuffered stdout and stderr
"-m" "pytest"
"${path}"
# store last failed tests
"-o" "cache_dir=${CMAKE_CURRENT_BINARY_DIR}/ament_cmake_pytest/${testname}/.cache"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On Xenial I'm seeing an error with this option when testing rclpy. I installed pytest from apt python3-pytest.

1: usage: pytest.py [options] [file_or_dir] [file_or_dir] [...]
1: pytest.py: error: unrecognized arguments: -o cache_dir=/workspace/ros2_ws/build_isolated/rclpy/ament_cmake_pytest/rclpytests/.cache

Full output

test 1
    Start 1: rclpytests

1: Test command: /usr/bin/python3 "-u" "/workspace/ros2_ws/install_isolated/ament_cmake_test/share/ament_cmake_test/cmake/run_test.py" "/
workspace/ros2_ws/build_isolated/rclpy/test_results/rclpy/rclpytests.xunit.xml" "--output-file" "/workspace/ros2_ws/build_isolated/rclpy/
ament_cmake_pytest/rclpytests.txt" "--append-env" "AMENT_PREFIX_PATH=/workspace/ros2_ws/build_isolated/rclpy/ament_cmake_index" "LD_LIBRA
RY_PATH=/workspace/ros2_ws/build_isolated/rclpy" "--command" "/usr/bin/python3" "-u" "-m" "pytest" "/workspace/ros2_ws/src/ros2/rclpy/rcl
py/test" "-o" "cache_dir=/workspace/ros2_ws/build_isolated/rclpy/ament_cmake_pytest/rclpytests/.cache" "--junit-xml=/workspace/ros2_ws/bu
ild_isolated/rclpy/test_results/rclpy/rclpytests.xunit.xml" "--junit-prefix=rclpy"
1: Test timeout computed to be: 90
1: -- run_test.py: extra environment variables to append:
1:  - AMENT_PREFIX_PATH+=/workspace/ros2_ws/build_isolated/rclpy/ament_cmake_index
1:  - LD_LIBRARY_PATH+=/workspace/ros2_ws/build_isolated/rclpy
1: -- run_test.py: invoking following command in '/workspace/ros2_ws/build_isolated/rclpy':
1:  - /usr/bin/python3 -u -m pytest /workspace/ros2_ws/src/ros2/rclpy/rclpy/test -o cache_dir=/workspace/ros2_ws/build_isolated/rclpy/ame
nt_cmake_pytest/rclpytests/.cache --junit-xml=/workspace/ros2_ws/build_isolated/rclpy/test_results/rclpy/rclpytests.xunit.xml --junit-pre
fix=rclpy
1: usage: pytest.py [options] [file_or_dir] [file_or_dir] [...]
1: pytest.py: error: unrecognized arguments: -o cache_dir=/workspace/ros2_ws/build_isolated/rclpy/ament_cmake_pytest/rclpytests/.cache
1:   inifile: None
1:   rootdir: /workspace/ros2_ws
1: -- run_test.py: return code 2
1: -- run_test.py: generate result file '/workspace/ros2_ws/build_isolated/rclpy/test_results/rclpy/rclpytests.xunit.xml' with failed te$
t
1: -- run_test.py: verify result file '/workspace/ros2_ws/build_isolated/rclpy/test_results/rclpy/rclpytests.xunit.xml'
1/8 Test #1: rclpytests .......................***Failed    0.51 sec

Where is -o cache_dir= supposed be handled? I haven't found any references to cache_dir in cpython, unittest, or nose. I see some references to cache_dir in an ini in pytest here.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like cache_dir was added in version 3.2, but the version in apt is 2.8.7-4. Installing via pip fixed the issue.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

# junit arguments
"--junit-xml=${result_file}"
"--junit-prefix=${PROJECT_NAME}"
)

if(ARG_ENV)
set(ARG_ENV "ENV" ${ARG_ENV})
endif()
if(ARG_APPEND_ENV)
set(ARG_APPEND_ENV "APPEND_ENV" ${ARG_APPEND_ENV})
endif()
if(ARG_APPEND_LIBRARY_DIRS)
set(ARG_APPEND_LIBRARY_DIRS "APPEND_LIBRARY_DIRS" ${ARG_APPEND_LIBRARY_DIRS})
endif()
if(ARG_TIMEOUT)
set(ARG_TIMEOUT "TIMEOUT" "${ARG_TIMEOUT}")
endif()
if(ARG_WORKING_DIRECTORY)
set(ARG_WORKING_DIRECTORY "WORKING_DIRECTORY" "${ARG_WORKING_DIRECTORY}")
endif()
if(ARG_SKIP_TEST)
set(ARG_SKIP_TEST "SKIP_TEST")
endif()

ament_add_test(
"${testname}"
COMMAND ${cmd}
OUTPUT_FILE "${CMAKE_BINARY_DIR}/ament_cmake_pytest/${testname}.txt"
RESULT_FILE "${result_file}"
${ARG_SKIP_TEST}
${ARG_ENV}
${ARG_APPEND_ENV}
${ARG_APPEND_LIBRARY_DIRS}
${ARG_TIMEOUT}
${ARG_WORKING_DIRECTORY}
)
set_tests_properties(
"${testname}"
PROPERTIES
LABELS "pytest"
)
endfunction()
57 changes: 57 additions & 0 deletions ament_cmake_pytest/cmake/ament_has_pytest.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
# Copyright 2017 Open Source Robotics Foundation, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

#
# Check if the Python module `pytest` was found.
#
# :param var: the output variable name
# :type var: string
# :param QUIET: suppress the CMake warning if pytest is not found, if not set and pytest was not found a CMake warning is printed
# :type QUIET: option
# :param PYTHON_EXECUTABLE: absolute path to the Python interpreter to be used,
# default to the CMake variable with the same name returned by
# FindPythonInterp
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this need to be wrapped ? seems more readable if it was on the line above

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It didn't fit within 80 characters.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, in that case, is it possible to wrap the parameter description just above (QUIET) that is much longer than this one ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done in dcfedfb.

# :type PYTHON_EXECUTABLE: string
#
# @public
#
function(ament_has_pytest var)
cmake_parse_arguments(ARG "QUIET" "PYTHON_EXECUTABLE" "" ${ARGN})
if(ARG_UNPARSED_ARGUMENTS)
message(FATAL_ERROR "ament_has_pytest() called with unused arguments: "
"${ARG_UNPARSED_ARGUMENTS}")
endif()

if(NOT ARG_PYTHON_EXECUTABLE)
set(ARG_PYTHON_EXECUTABLE "${PYTHON_EXECUTABLE}")
endif()

set(cmd "${ARG_PYTHON_EXECUTABLE}" "-m" "pytest" "--version")
execute_process(
COMMAND ${cmd}
RESULT_VARIABLE res
OUTPUT_VARIABLE output
ERROR_VARIABLE error)
if(res EQUAL 0)
set(${var} TRUE PARENT_SCOPE)
else()
if(NOT ARG_QUIET)
string(REPLACE ";" " " cmd_str "${cmd}")
message(WARNING
"Failed to find Python module `pytest`: "
"'${cmd_str}' returned error code ${res}")
endif()
set(${var} FALSE PARENT_SCOPE)
endif()
endfunction()
19 changes: 19 additions & 0 deletions ament_cmake_pytest/package.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?xml version="1.0"?>
<?xml-model href="http://download.ros.org/schema/package_format2.xsd" schematypens="http://www.w3.org/2001/XMLSchema"?>
<package format="2">
<name>ament_cmake_pytest</name>
<version>0.0.3</version>
<description>The ability to run Python tests using pytest in the ament buildsystem in CMake.</description>
<maintainer email="dthomas@osrfoundation.org">Dirk Thomas</maintainer>
<license>Apache License 2.0</license>

<buildtool_depend>ament_cmake_core</buildtool_depend>

<buildtool_export_depend>ament_cmake_core</buildtool_export_depend>
<buildtool_export_depend>ament_cmake_test</buildtool_export_depend>
<buildtool_export_depend>python3-pytest</buildtool_export_depend>

<export>
<build_type>ament_cmake</build_type>
</export>
</package>