Imported Upstream version 1.13.1
Jochen Sprickerhof
7 years ago
0 | 0 | ^^^^^^^^^^^^^^^^^^^^^^^^ |
1 | 1 | Changelog for package mk |
2 | 2 | ^^^^^^^^^^^^^^^^^^^^^^^^ |
3 | ||
4 | 1.13.1 (2016-03-13) | |
5 | ------------------- | |
6 | ||
7 | 1.13.0 (2016-03-10) | |
8 | ------------------- | |
9 | ||
10 | 1.12.6 (2016-03-10) | |
11 | ------------------- | |
3 | 12 | |
4 | 13 | 1.12.5 (2015-10-13) |
5 | 14 | ------------------- |
0 | 0 | <package> |
1 | 1 | <name>mk</name> |
2 | <version>1.12.5</version> | |
2 | <version>1.13.1</version> | |
3 | 3 | <description> |
4 | 4 | A collection of .mk include files for building ROS architectural elements. |
5 | 5 | Most package authors should use cmake .mk, which calls CMake for the build of the package. |
0 | 0 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |
1 | 1 | Changelog for package rosbuild |
2 | 2 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |
3 | ||
4 | 1.13.1 (2016-03-13) | |
5 | ------------------- | |
6 | ||
7 | 1.13.0 (2016-03-10) | |
8 | ------------------- | |
9 | ||
10 | 1.12.6 (2016-03-10) | |
11 | ------------------- | |
3 | 12 | |
4 | 13 | 1.12.5 (2015-10-13) |
5 | 14 | ------------------- |
0 | 0 | <package> |
1 | 1 | <name>rosbuild</name> |
2 | <version>1.12.5</version> | |
2 | <version>1.13.1</version> | |
3 | 3 | <description> |
4 | 4 | rosbuild contains scripts for managing the CMake-based build system for ROS. |
5 | 5 | </description> |
0 | 0 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |
1 | 1 | Changelog for package roslang |
2 | 2 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |
3 | ||
4 | 1.13.1 (2016-03-13) | |
5 | ------------------- | |
6 | ||
7 | 1.13.0 (2016-03-10) | |
8 | ------------------- | |
9 | ||
10 | 1.12.6 (2016-03-10) | |
11 | ------------------- | |
3 | 12 | |
4 | 13 | 1.12.5 (2015-10-13) |
5 | 14 | ------------------- |
0 | 0 | <package> |
1 | 1 | <name>roslang</name> |
2 | <version>1.12.5</version> | |
2 | <version>1.13.1</version> | |
3 | 3 | <description> |
4 | 4 | roslang is a common package that all <a href="http://www.ros.org/wiki/Client%20Libraries">ROS client libraries</a> depend on. |
5 | 5 | This is mainly used to find client libraries (via 'rospack depends-on1 roslang'). |
0 | 0 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |
1 | 1 | Changelog for package roslib |
2 | 2 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |
3 | ||
4 | 1.13.1 (2016-03-13) | |
5 | ------------------- | |
6 | ||
7 | 1.13.0 (2016-03-10) | |
8 | ------------------- | |
9 | * update ROS_DISTRO to kinetic | |
10 | ||
11 | 1.12.6 (2016-03-10) | |
12 | ------------------- | |
13 | * expose an API (ros::package::getPlugins) which can map multiple export values to one package name (`#103 <https://github.com/ros/ros/issues/103>`_) | |
14 | * deprecate API returning incomplete information (`#103 <https://github.com/ros/ros/issues/103>`_) | |
15 | * allow caching of rospack results (`#97 <https://github.com/ros/ros/issues/97>`_) | |
3 | 16 | |
4 | 17 | 1.12.5 (2015-10-13) |
5 | 18 | ------------------- |
4 | 4 | rem Need the delims= line here to ensure that it reads with eol delimiters, not space. |
5 | 5 | for /f "delims=" %%i in ('%COMMAND%') do set PATH=%%i |
6 | 6 | |
7 | set ROS_DISTRO=jade | |
7 | set ROS_DISTRO=kinetic | |
8 | 8 | |
9 | 9 | REM python function to generate ROS package path based on all parent workspaces (prepends the separator if necessary) |
10 | 10 | REM do not use EnableDelayedExpansion here, it messes with the != symbols |
2 | 2 | # scrub old ROS bin dirs, to avoid accidentally finding the wrong executables |
3 | 3 | export PATH="`@(PYTHON_EXECUTABLE) -c \"import os; print(os.pathsep.join([x for x in \\\"$PATH\\\".split(os.pathsep) if not any([d for d in ['cturtle', 'diamondback', 'electric', 'fuerte'] if d in x])]))\"`" |
4 | 4 | |
5 | if [ -n "$ROS_DISTRO" -a "$ROS_DISTRO" != "jade" ]; then | |
5 | if [ -n "$ROS_DISTRO" -a "$ROS_DISTRO" != "kinetic" ]; then | |
6 | 6 | echo "ROS_DISTRO was set to '$ROS_DISTRO' before. Please make sure that the environment does not mix paths from different distributions." |
7 | 7 | fi |
8 | export ROS_DISTRO=jade | |
8 | export ROS_DISTRO=kinetic | |
9 | 9 | |
10 | 10 | # python function to generate ROS package path based on all workspaces |
11 | 11 | PYTHON_CODE_BUILD_ROS_PACKAGE_PATH=$(cat <<EOF |
28 | 28 | #define ROSLIB_PACKAGE_H |
29 | 29 | |
30 | 30 | #include <string> |
31 | #include <utility> | |
31 | 32 | #include <vector> |
32 | 33 | #include <map> |
33 | 34 | |
107 | 108 | ROSLIB_DECL void getPlugins(const std::string& package, const std::string& attribute, V_string& plugins, bool force_recrawl=false); |
108 | 109 | |
109 | 110 | /** |
110 | * \brief Call the "rospack plugins" command, eg. "rospack plugins --attrib=<attribute> <package>". Returns a map of package name to | |
111 | * export value. | |
111 | * \brief Call the "rospack plugins" command, eg. "rospack plugins --attrib=<attribute> <name>". | |
112 | * Return a vector of string pairs which are package names and exported values respectively. | |
113 | * Note that there can be multiple values for any single package. | |
114 | * | |
115 | * Note that while this uses the original rospack 'plugin' terminology, | |
116 | * this effectively works for any exported tag with attributes in the | |
117 | * catkin package.xml export list. Typical examples include: | |
118 | * | |
119 | \code{.xml} | |
120 | <export> | |
121 | <nav_core plugin="${prefix}/blp_plugin.xml" /> <!-- name="nav_core", attribute="plugin" --> | |
122 | <rosdoc config="rosdoc.yaml" /> <!-- name="rosdoc", attribute="config" --> | |
123 | </export> | |
124 | \endcode | |
125 | * | |
126 | * \param name : name of the package export tag (has to be a package name) [in] | |
127 | * \param attribute : name of the attribute inside the export tag with which to filter results [in] | |
128 | * \param exports : package/value export pairs resulting from the search [out] | |
129 | * \param force_recrawl : force rospack to rediscover everything on the system before running the search [in] | |
112 | 130 | */ |
113 | ROSLIB_DECL void getPlugins(const std::string& package, const std::string& attribute, M_string& plugins, bool force_recrawl=false); | |
131 | ROSLIB_DECL void getPlugins( | |
132 | const std::string& name, | |
133 | const std::string& attribute, | |
134 | std::vector<std::pair<std::string, std::string> >& exports, | |
135 | bool force_recrawl=false | |
136 | ); | |
137 | ||
138 | /** | |
139 | * \brief Call the "rospack plugins" command, eg. "rospack plugins --attrib=<attribute> <package>". | |
140 | * Return a map of package name to export value. | |
141 | * | |
142 | * \warning If there are multiple export values, only the last one is saved in the map. | |
143 | * | |
144 | * \deprecated Prefer the ::getPlugins(const std::string&, const std::string&, std::vector<std::pair<std::string, std::string>>&, bool) api instead. | |
145 | */ | |
146 | ROS_DEPRECATED ROSLIB_DECL void getPlugins(const std::string& package, const std::string& attribute, M_string& plugins, bool force_recrawl=false); | |
114 | 147 | |
115 | 148 | } // namespace package |
116 | 149 | } // namespace ros |
0 | 0 | <package> |
1 | 1 | <name>roslib</name> |
2 | <version>1.12.5</version> | |
2 | <version>1.13.1</version> | |
3 | 3 | <description> |
4 | 4 | Base dependencies and support libraries for ROS. |
5 | 5 | roslib contains many of the common data structures and tools that are shared across ROS client library implementations. |
46 | 46 | std::string command(const std::string& _cmd) |
47 | 47 | { |
48 | 48 | boost::mutex::scoped_lock lock(librospack_mutex); |
49 | ||
50 | rospack::ROSPack rp; | |
49 | // static allows caching of results in between calls (in same process) | |
50 | static rospack::ROSPack rp; | |
51 | 51 | int ret; |
52 | 52 | try |
53 | 53 | { |
133 | 133 | } |
134 | 134 | } |
135 | 135 | |
136 | void getPlugins( | |
137 | const std::string& name, | |
138 | const std::string& attribute, | |
139 | std::vector<std::pair<std::string, std::string> >& exports, | |
140 | bool force_recrawl | |
141 | ) | |
142 | { | |
143 | V_string packages, plugins; | |
144 | getPlugins(name, attribute, packages, plugins, force_recrawl); | |
145 | // works on the assumption the previous call always return equal length package/plugin lists | |
146 | for (std::size_t i = 0; i < packages.size(); ++i ) { | |
147 | exports.push_back(std::pair<std::string, std::string>(packages[i], plugins[i])); | |
148 | } | |
149 | } | |
150 | ||
136 | 151 | void getPlugins(const std::string& package, const std::string& attribute, V_string& plugins, bool force_recrawl) |
137 | 152 | { |
138 | 153 | V_string packages; |
0 | [nosetests] | |
1 | with-xunit=1 | |
2 | with-coverage=1 | |
3 | cover-package=roslib | |
4 | tests=test_roslib_manifest.py,test_roslib_names.py,test_roslib_packages.py,test_roslib.py, test_roslib_rosenv.py, test_roslib_stack_manifest.py, test_roslib_stacks.py, test_roslib_exceptions.py, test_roslib_manifestlib.py | |
5 |
0 | 0 | <package> |
1 | 1 | <name>ros</name> |
2 | <version>1.12.5</version> | |
2 | <version>1.13.1</version> | |
3 | 3 | <description>ROS packaging system</description> |
4 | 4 | <maintainer email="dthomas@osrfoundation.org">Dirk Thomas</maintainer> |
5 | 5 | <license>BSD</license> |
0 | 0 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |
1 | 1 | Changelog for package rosbash |
2 | 2 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |
3 | ||
4 | 1.13.1 (2016-03-13) | |
5 | ------------------- | |
6 | ||
7 | 1.13.0 (2016-03-10) | |
8 | ------------------- | |
9 | ||
10 | 1.12.6 (2016-03-10) | |
11 | ------------------- | |
12 | * add roscat to display file contents (`#99 <https://github.com/ros/ros/pull/99>`_) | |
13 | * roszsh: Ignore hidden files and directory in completion (`#100 <https://github.com/ros/ros/pull/100>`_) | |
3 | 14 | |
4 | 15 | 1.12.5 (2015-10-13) |
5 | 16 | ------------------- |
0 | 0 | <package> |
1 | 1 | <name>rosbash</name> |
2 | <version>1.12.5</version> | |
2 | <version>1.13.1</version> | |
3 | 3 | <description> |
4 | 4 | Assorted shell commands for using ros with bash. |
5 | 5 | </description> |
279 | 279 | fi |
280 | 280 | _roscmd ${1} ${2} |
281 | 281 | cp ${arg} ${3} |
282 | } | |
283 | ||
284 | function roscat { | |
285 | local arg | |
286 | if [[ $1 = "--help" ]] || [[ $# -ne 2 ]]; then | |
287 | echo -e "usage: roscat [package] [file]\n\nDisplay a file content within a package." | |
288 | [[ $1 = "--help" ]] && return 0 || return 1 | |
289 | fi | |
290 | _roscmd ${1} ${2} | |
291 | [ $? -eq 1 ] && return 1 | |
292 | if [[ -n ${arg} ]]; then | |
293 | if [[ -z $CATTER ]]; then | |
294 | cat ${arg} | |
295 | else | |
296 | $CATTER ${arg} | |
297 | fi | |
298 | fi | |
282 | 299 | } |
283 | 300 | |
284 | 301 | function rosawesome { |
948 | 965 | complete -F "_roscomplete_exe" "rosrun" |
949 | 966 | complete -F "_roscomplete_file" "rosed" |
950 | 967 | complete -F "_roscomplete_file" "roscp" |
968 | complete -F "_roscomplete_file" "roscat" | |
951 | 969 | complete -F "_roscomplete_launch" -o filenames "roslaunch" |
952 | 970 | complete -F "_roscomplete_test" -o filenames "rostest" |
953 | 971 | complete -F "_roscomplete_rospack" "rospack" |
0 | #alias roscat 'echo "unimplemented"' | |
0 | 1 | |
1 | 2 | function _rossed |
2 | 3 | if test (uname) = "Darwin" -o (uname) = "FreeBSD" |
3 | 3 | #alias rosd 'echo "unimplemented"' |
4 | 4 | #alias rospd 'echo "unimplemented"' |
5 | 5 | #alias rosed 'echo "unimplemented"' |
6 | #alias roscat 'echo "unimplemented"' | |
6 | 7 | #alias roscmd 'echo "unimplemented"' |
7 | 8 | #alias roscp 'echo "unimplemented"' |
8 | 9 |
262 | 262 | cp ${arg} ${3} |
263 | 263 | } |
264 | 264 | |
265 | function roscat { | |
266 | local arg | |
267 | if [[ $1 = "--help" ]] | [[ $# -ne 2 ]]; then | |
268 | echo -e "usage: roscat [package] [file]\n\nDisplay a file content within a package." | |
269 | [[ $1 = "--help" ]] && return 0 || return 1 | |
270 | fi | |
271 | _roscmd ${1} ${2} | |
272 | [ $? -eq 1 ] && return 1 | |
273 | if [[ -z $CATTER ]]; then | |
274 | cat ${arg} | |
275 | else | |
276 | $CATTER ${arg} | |
277 | fi | |
278 | } | |
279 | ||
265 | 280 | function _roscomplete { |
266 | 281 | local arg opts stack_opts |
267 | 282 | reply=() |
343 | 358 | else |
344 | 359 | perm="/111" |
345 | 360 | fi |
346 | _roscomplete_search_dir "-type f -perm $perm -regex .*/.*$" | |
361 | _roscomplete_search_dir "-type f -perm $perm -regex .*/.*$ ! -path */\.*" | |
347 | 362 | } |
348 | 363 | |
349 | 364 | function _roscomplete_file { |
729 | 744 | compctl -K "_roscomplete_rosmake" "rosmake" |
730 | 745 | |
731 | 746 | compctl -x 'p[1]' -k "(check purge)" -- "rosclean" |
732 | compctl -f -x 'p[1]' -K "_roscomplete" - 'p[2]' -K _roscomplete_file -- "rosed" "roscp" | |
747 | compctl -f -x 'p[1]' -K "_roscomplete" - 'p[2]' -K _roscomplete_file -- "rosed" "roscp" "roscat" | |
733 | 748 | compctl -f -x 'S[-]' -k '(--debug --prefix)' - 'c[-1,--prefix][-1,-p]' -h '' - 'p[1],c[-1,-d],c[-1,--debug],c[-2,-p],c[-2,--prefix]' -K "_roscomplete" - 'p[2],c[-2,-d],c[-2,--debug],c[-3,-p],c[-3,--prefix]' -K _roscomplete_exe -- "rosrun" |
734 | 749 | compctl -/g '*.(launch|test)' -x 'p[1]' -K "_roscomplete" -tx - 'p[2]' -K _roscomplete_launchfile -- + -x 'S[--]' -k "(--files --args --nodes --find-node --child --local --screen --server_uri --run_id --wait --port --core --pid --dump-params)" -- "roslaunch" |
735 | 750 | compctl -/g '*.(launch|test)' -x 'p[1]' -K "_roscomplete" -tx - 'p[2]' -K _roscomplete_launchfile -- + -x 'S[--]' -k "(--bare --bare-limit --bare-name --pkgdir --package)" -- "rostest" |
0 | 0 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |
1 | 1 | Changelog for package rosboost_cfg |
2 | 2 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |
3 | ||
4 | 1.13.1 (2016-03-13) | |
5 | ------------------- | |
6 | ||
7 | 1.13.0 (2016-03-10) | |
8 | ------------------- | |
9 | ||
10 | 1.12.6 (2016-03-10) | |
11 | ------------------- | |
3 | 12 | |
4 | 13 | 1.12.5 (2015-10-13) |
5 | 14 | ------------------- |
0 | 0 | <package> |
1 | 1 | <name>rosboost_cfg</name> |
2 | <version>1.12.5</version> | |
2 | <version>1.13.1</version> | |
3 | 3 | <description> |
4 | 4 | Contains scripts used by the rosboost-cfg tool for determining cflags/lflags/etc. of boost on your system |
5 | 5 | </description> |
0 | 0 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |
1 | 1 | Changelog for package rosclean |
2 | 2 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |
3 | ||
4 | 1.13.1 (2016-03-13) | |
5 | ------------------- | |
6 | ||
7 | 1.13.0 (2016-03-10) | |
8 | ------------------- | |
9 | ||
10 | 1.12.6 (2016-03-10) | |
11 | ------------------- | |
3 | 12 | |
4 | 13 | 1.12.5 (2015-10-13) |
5 | 14 | ------------------- |
0 | 0 | <package> |
1 | 1 | <name>rosclean</name> |
2 | <version>1.12.5</version> | |
2 | <version>1.13.1</version> | |
3 | 3 | <description> |
4 | 4 | rosclean: cleanup filesystem resources (e.g. log files). |
5 | 5 | </description> |
0 | 0 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |
1 | 1 | Changelog for package roscreate |
2 | 2 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |
3 | ||
4 | 1.13.1 (2016-03-13) | |
5 | ------------------- | |
6 | ||
7 | 1.13.0 (2016-03-10) | |
8 | ------------------- | |
9 | ||
10 | 1.12.6 (2016-03-10) | |
11 | ------------------- | |
3 | 12 | |
4 | 13 | 1.12.5 (2015-10-13) |
5 | 14 | ------------------- |
0 | 0 | <package> |
1 | 1 | <name>roscreate</name> |
2 | <version>1.12.5</version> | |
2 | <version>1.13.1</version> | |
3 | 3 | <description> |
4 | 4 | roscreate contains a tool that assists in the creation of ROS filesystem resources. |
5 | 5 | It provides: <tt>roscreate-pkg</tt>, which creates a new package directory, |
0 | 0 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |
1 | 1 | Changelog for package rosmake |
2 | 2 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |
3 | ||
4 | 1.13.1 (2016-03-13) | |
5 | ------------------- | |
6 | ||
7 | 1.13.0 (2016-03-10) | |
8 | ------------------- | |
9 | ||
10 | 1.12.6 (2016-03-10) | |
11 | ------------------- | |
3 | 12 | |
4 | 13 | 1.12.5 (2015-10-13) |
5 | 14 | ------------------- |
0 | 0 | <package> |
1 | 1 | <name>rosmake</name> |
2 | <version>1.12.5</version> | |
2 | <version>1.13.1</version> | |
3 | 3 | <description> |
4 | 4 | rosmake is a ros dependency aware build tool which can be used to |
5 | 5 | build all dependencies in the correct order. |
0 | 0 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |
1 | 1 | Changelog for package rosunit |
2 | 2 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |
3 | ||
4 | 1.13.1 (2016-03-13) | |
5 | ------------------- | |
6 | * fix a regression in XML reports introduced in 1.12.6 (`#109 <https://github.com/ros/ros/pull/109>`_) | |
7 | ||
8 | 1.13.0 (2016-03-10) | |
9 | ------------------- | |
10 | ||
11 | 1.12.6 (2016-03-10) | |
12 | ------------------- | |
13 | * remove invalid characters from XML unit test results (`#89 <https://github.com/ros/ros/pull/89>`_, `#108 <https://github.com/ros/ros/pull/108>`_) | |
14 | * add ability to load tests using dotnames in rosunit (`#101 <https://github.com/ros/ros/issues/101>`_) | |
3 | 15 | |
4 | 16 | 1.12.5 (2015-10-13) |
5 | 17 | ------------------- |
0 | 0 | <package> |
1 | 1 | <name>rosunit</name> |
2 | <version>1.12.5</version> | |
2 | <version>1.13.1</version> | |
3 | 3 | <description> |
4 | 4 | Unit-testing package for ROS. This is a lower-level library for rostest and handles unit tests, whereas rostest handles integration tests. |
5 | 5 | </description> |
48 | 48 | import codecs |
49 | 49 | import re |
50 | 50 | |
51 | import xml.etree.ElementTree as ET | |
51 | 52 | from xml.dom.minidom import parse, parseString |
52 | 53 | from xml.dom import Node as DomNode |
53 | 54 | |
54 | 55 | from functools import reduce |
55 | 56 | import rospkg |
57 | ||
58 | invalid_chars = re.compile(ur'[^\x09\x0A\x0D\x20-\x7E\x85\xA0-\xFF\u0100-\uD7FF\uE000-\uFDCF\uFDE0-\uFFFD]') | |
59 | def invalid_char_replacer(m): | |
60 | return "&#x"+('%04X' % ord(m.group(0)))+";" | |
61 | def filter_nonprintable_text(text): | |
62 | return re.sub(invalid_chars, invalid_char_replacer, text) | |
63 | ||
64 | def cdata(cdata_text): | |
65 | return '<![CDATA[\n{}\n]]>'.format(cdata_text) | |
56 | 66 | |
57 | 67 | class TestInfo(object): |
58 | 68 | """ |
74 | 84 | 'error' result container |
75 | 85 | """ |
76 | 86 | def xml(self): |
77 | data = '<error type="%s"><![CDATA[%s]]></error>' % (self.type, self.text) | |
78 | try: | |
79 | data = unicode(data) | |
80 | except NameError: | |
81 | pass | |
82 | return data | |
87 | """ | |
88 | @return XML tag representing the object, with non-XML text filtered out | |
89 | @rtype: str | |
90 | """ | |
91 | return ET.tostring(self.xml_element(), encoding='utf-8', method='xml') | |
92 | ||
93 | def xml_element(self): | |
94 | """ | |
95 | @return XML tag representing the object, with non-XML text filtered out | |
96 | @rtype: xml.etree.ElementTree.Element | |
97 | """ | |
98 | error = ET.Element('error') | |
99 | error.set('type', self.type) | |
100 | error.text = cdata(filter_nonprintable_text(self.text)) | |
101 | return error | |
83 | 102 | |
84 | 103 | class TestFailure(TestInfo): |
85 | 104 | """ |
86 | 105 | 'failure' result container |
87 | 106 | """ |
88 | 107 | def xml(self): |
89 | data = '<failure type="%s"><![CDATA[%s]]></failure>' % (self.type, self.text) | |
90 | try: | |
91 | data = unicode(data) | |
92 | except NameError: | |
93 | pass | |
94 | return data | |
95 | ||
108 | """ | |
109 | @return XML tag representing the object, with non-XML text filtered out | |
110 | @rtype: str | |
111 | """ | |
112 | return ET.tostring(self.xml_element(), encoding='utf-8', method='xml') | |
113 | ||
114 | def xml_element(self): | |
115 | """ | |
116 | @return XML tag representing the object, with non-XML text filtered out | |
117 | @rtype: xml.etree.ElementTree.Element | |
118 | """ | |
119 | error = ET.Element('failure') | |
120 | error.set('type', self.type) | |
121 | error.text = cdata(filter_nonprintable_text(self.text)) | |
122 | return error | |
96 | 123 | |
97 | 124 | class TestCaseResult(object): |
98 | 125 | """ |
168 | 195 | self.errors.append(error) |
169 | 196 | |
170 | 197 | def xml(self): |
171 | data = ' <testcase classname="%s" name="%s" time="%s">\n' % (self.classname, self.name, self.time) + \ | |
172 | '\n '.join([f.xml() for f in self.failures]) + \ | |
173 | '\n '.join([e.xml() for e in self.errors]) + \ | |
174 | ' </testcase>' | |
175 | try: | |
176 | data = unicode(data) | |
177 | except NameError: | |
178 | pass | |
179 | return data | |
198 | """ | |
199 | @return XML tag representing the object, with non-XML text filtered out | |
200 | @rtype: str | |
201 | """ | |
202 | return ET.tostring(self.xml_element(), encoding='utf-8', method='xml') | |
203 | ||
204 | def xml_element(self): | |
205 | """ | |
206 | @return XML tag representing the object, with non-XML text filtered out | |
207 | @rtype: xml.etree.ElementTree.Element | |
208 | """ | |
209 | testcase = ET.Element('testcase') | |
210 | testcase.set('classname', self.classname) | |
211 | testcase.set('name', self.name) | |
212 | testcase.set('time', str(self.time)) | |
213 | for f in self.failures: | |
214 | testcase.append(f.xml_element()) | |
215 | for e in self.errors: | |
216 | testcase.append(e.xml_element()) | |
217 | return testcase | |
180 | 218 | |
181 | 219 | class Result(object): |
182 | 220 | __slots__ = ['name', 'num_errors', 'num_failures', 'num_tests', \ |
215 | 253 | """ |
216 | 254 | self.test_case_results.append(r) |
217 | 255 | |
218 | def xml(self): | |
256 | def xml_element(self): | |
219 | 257 | """ |
220 | 258 | @return: document as unicode (UTF-8 declared) XML according to Ant JUnit spec |
221 | 259 | """ |
222 | data = '<?xml version="1.0" encoding="utf-8"?>' + \ | |
223 | '<testsuite name="%s" tests="%s" errors="%s" failures="%s" time="%s">' % \ | |
224 | (self.name, self.num_tests, self.num_errors, self.num_failures, self.time) + \ | |
225 | '\n'.join([tc.xml() for tc in self.test_case_results]) + \ | |
226 | ' <system-out><![CDATA[%s]]></system-out>' % self.system_out + \ | |
227 | ' <system-err><![CDATA[%s]]></system-err>' % self.system_err + \ | |
228 | '</testsuite>' | |
229 | try: | |
230 | data = unicode(data) | |
231 | except NameError: | |
232 | pass | |
233 | return data | |
260 | testsuite = ET.Element('testsuite') | |
261 | testsuite.set('tests', str(self.num_tests)) | |
262 | testsuite.set('failures', str(self.num_failures)) | |
263 | testsuite.set('time', str(self.time)) | |
264 | testsuite.set('errors', str(self.num_errors)) | |
265 | testsuite.set('name', self.name) | |
266 | for tc in self.test_case_results: | |
267 | tc.xml(testsuite) | |
268 | system_out = ET.SubElement(testsuite, 'system-out') | |
269 | system_out.text = cdata(filter_nonprintable_text(self.system_out)) | |
270 | system_err = ET.SubElement(testsuite, 'system-err') | |
271 | system_err.text = cdata(filter_nonprintable_text(self.system_err)) | |
272 | return ET.tostring(testsuite, encoding='utf-8', method='xml') | |
234 | 273 | |
235 | 274 | def _text(tag): |
236 | 275 | return reduce(lambda x, y: x + y, [c.data for c in tag.childNodes if c.nodeType in [DomNode.TEXT_NODE, DomNode.CDATA_SECTION_NODE]], "").strip() |
425 | 464 | @param stdout: stdout data to include in report |
426 | 465 | @type stdout: str |
427 | 466 | """ |
428 | if not stdout: | |
429 | return """<?xml version="1.0" encoding="UTF-8"?> | |
430 | <testsuite tests="1" failures="1" time="1" errors="0" name="%s"> | |
431 | <testcase name="test_ran" status="run" time="1" classname="Results"> | |
432 | <failure message="%s" type=""/> | |
433 | </testcase> | |
434 | </testsuite>"""%(test_name, message) | |
435 | else: | |
436 | return """<?xml version="1.0" encoding="UTF-8"?> | |
437 | <testsuite tests="1" failures="1" time="1" errors="0" name="%s"> | |
438 | <testcase name="test_ran" status="run" time="1" classname="Results"> | |
439 | <failure message="%s" type=""/> | |
440 | </testcase> | |
441 | <system-out><![CDATA[[ | |
442 | %s | |
443 | ]]></system-out> | |
444 | </testsuite>"""%(test_name, message, stdout) | |
467 | testsuite = ET.Element('testsuite') | |
468 | testsuite.set('tests', '1') | |
469 | testsuite.set('failures', '1') | |
470 | testsuite.set('time', '1') | |
471 | testsuite.set('errors', '0') | |
472 | testsuite.set('name', test_name) | |
473 | testcase = ET.SubElement(testsuite, 'testcase') | |
474 | testcase.set('name', 'test_ran') | |
475 | testcase.set('status', 'run') | |
476 | testcase.set('time', '1') | |
477 | testcase.set('classname', 'Results') | |
478 | failure = ET.SubElement(testcase, 'failure') | |
479 | failure.set('message', message) | |
480 | failure.set('type', '') | |
481 | if stdout: | |
482 | system_out = ET.SubElement(testsuite, 'system-out') | |
483 | system_out.text = cdata(filter_nonprintable_text(stdout)) | |
484 | return ET.tostring(testsuite, encoding='utf-8', method='xml') | |
445 | 485 | |
446 | 486 | def test_success_junit_xml(test_name): |
447 | 487 | """ |
450 | 490 | @param test_name: Name of test that passed |
451 | 491 | @type test_name: str |
452 | 492 | """ |
453 | return """<?xml version="1.0" encoding="UTF-8"?> | |
454 | <testsuite tests="1" failures="0" time="1" errors="0" name="%s"> | |
455 | <testcase name="test_ran" status="run" time="1" classname="Results"> | |
456 | </testcase> | |
457 | </testsuite>"""%(test_name) | |
493 | testsuite = ET.Element('testsuite') | |
494 | testsuite.set('tests', '1') | |
495 | testsuite.set('failures', '0') | |
496 | testsuite.set('time', '1') | |
497 | testsuite.set('errors', '0') | |
498 | testsuite.set('name', test_name) | |
499 | testcase = ET.SubElement(testsuite, 'testcase') | |
500 | testcase.set('name', 'test_ran') | |
501 | testcase.set('status', 'run') | |
502 | testcase.set('time', '1') | |
503 | testcase.set('classname', 'Results') | |
504 | return ET.tostring(testsuite, encoding='utf-8', method='xml') | |
458 | 505 | |
459 | 506 | def print_summary(junit_results, runner_name='ROSUNIT'): |
460 | 507 | """ |
56 | 56 | |
57 | 57 | @param package: name of ROS package that is running the test |
58 | 58 | @type package: str |
59 | @param test: a test case instance or a name resolving to a test case or suite | |
60 | @type test: unittest.TestCase, or string | |
59 | 61 | @param coverage_packages: list of Python package to compute coverage results for. Defaults to package |
60 | 62 | @type coverage_packages: [str] |
61 | 63 | @param sysargs: (optional) alternate sys.argv |
83 | 85 | start_coverage(coverage_packages) |
84 | 86 | |
85 | 87 | # create and run unittest suite with our xmllrunner wrapper |
86 | suite = unittest.TestLoader().loadTestsFromTestCase(test) | |
88 | suite = None | |
89 | if issubclass(test, unittest.TestCase): | |
90 | suite = unittest.TestLoader().loadTestsFromTestCase(test) | |
91 | else: | |
92 | suite = unittest.TestLoader().loadTestsFromName(test) | |
93 | ||
87 | 94 | if text_mode: |
88 | 95 | result = unittest.TextTestRunner(verbosity=2).run(suite) |
89 | 96 | else: |
19 | 19 | except ImportError: |
20 | 20 | from io import StringIO |
21 | 21 | from xml.sax.saxutils import escape |
22 | ||
22 | import xml.etree.ElementTree as ET | |
23 | ||
24 | def cdata(cdata_text): | |
25 | return '<![CDATA[\n{}\n]]>'.format(cdata_text) | |
23 | 26 | |
24 | 27 | class _TestInfo(object): |
25 | 28 | |
54 | 57 | info._error = error |
55 | 58 | return info |
56 | 59 | |
60 | def xml(self): | |
61 | """Create an XML tag with information about this test case. | |
62 | ||
63 | """ | |
64 | testcase = ET.Element("testcase") | |
65 | testcase.set('classname', self._class) | |
66 | testcase.set('name', self._method) | |
67 | testcase.set('time', '%.4f' % self._time) | |
68 | if self._failure != None: | |
69 | self._print_error(testcase, 'failure', self._failure) | |
70 | if self._error != None: | |
71 | self._print_error(testcase, 'error', self._error) | |
72 | return testcase | |
73 | ||
57 | 74 | def print_report(self, stream): |
58 | 75 | """Print information about this test case in XML format to the |
59 | 76 | supplied stream. |
60 | 77 | |
61 | 78 | """ |
62 | stream.write(' <testcase classname="%(class)s" name="%(method)s" time="%(time).4f">' % \ | |
63 | { | |
64 | "class": self._class, | |
65 | "method": self._method, | |
66 | "time": self._time, | |
67 | }) | |
68 | if self._failure != None: | |
69 | self._print_error(stream, 'failure', self._failure) | |
70 | if self._error != None: | |
71 | self._print_error(stream, 'error', self._error) | |
72 | stream.write('</testcase>\n') | |
79 | stream.write(ET.tostring(self.xml())) | |
73 | 80 | |
74 | 81 | def print_report_text(self, stream): |
75 | 82 | #stream.write(' <testcase classname="%(class)s" name="%(method)s" time="%(time).4f">' % \ |
88 | 95 | if self._failure == None and self._error == None: |
89 | 96 | stream.write(' ... ok\n') |
90 | 97 | |
91 | def _print_error(self, stream, tagname, error): | |
92 | """Print information from a failure or error to the supplied stream.""" | |
93 | text = escape(str(error[1])) | |
94 | stream.write('\n') | |
95 | stream.write(' <%s type="%s">%s\n' \ | |
96 | % (tagname, str(error[0].__name__), text)) | |
98 | def _print_error(self, testcase, tagname, error): | |
99 | """ | |
100 | Append an XML tag with information from a failure or error to the | |
101 | supplied testcase. | |
102 | """ | |
103 | tag = ET.SubElement(testcase, tagname) | |
104 | tag.set('type', str(error[0].__name__)) | |
97 | 105 | tb_stream = StringIO() |
98 | 106 | traceback.print_tb(error[2], None, tb_stream) |
99 | stream.write(escape(tb_stream.getvalue())) | |
100 | stream.write(' </%s>\n' % tagname) | |
101 | stream.write(' ') | |
107 | tag.text ='%s\n%s' % (str(error[1]), tb_stream.getvalue()) | |
102 | 108 | |
103 | 109 | def _print_error_text(self, stream, tagname, error): |
104 | 110 | """Print information from a failure or error to the supplied stream.""" |
151 | 157 | unittest.TestResult.addFailure(self, test, err) |
152 | 158 | self._failure = err |
153 | 159 | |
160 | def filter_nonprintable_text(self, text): | |
161 | invalid_chars = re.compile(ur'[^\x09\x0A\x0D\x20-\x7E\x85\xA0-\xFF\u0100-\uD7FF\uE000-\uFDCF\uFDE0-\uFFFD]') | |
162 | def invalid_char_replacer(m): | |
163 | return "&#x"+('%04X' % ord(m.group(0)))+";" | |
164 | return re.sub(invalid_chars, invalid_char_replacer, str(text)) | |
165 | ||
166 | def xml(self, time_taken, out, err): | |
167 | """ | |
168 | @return XML tag representing the object | |
169 | @rtype: xml.etree.ElementTree.Element | |
170 | """ | |
171 | test_suite = ET.Element('testsuite') | |
172 | test_suite.set('errors', str(len(self.errors))) | |
173 | test_suite.set('failures', str(len(self.failures))) | |
174 | test_suite.set('name', self._test_name) | |
175 | test_suite.set('tests', str(self.testsRun)) | |
176 | test_suite.set('time', '%.3f' % time_taken) | |
177 | for info in self._tests: | |
178 | test_suite.append(info.xml()) | |
179 | system_out = ET.SubElement(test_suite, 'system-out') | |
180 | system_out.text = cdata(self.filter_nonprintable_text(out)) | |
181 | system_err = ET.SubElement(test_suite, 'system-err') | |
182 | system_err.text = cdata(self.filter_nonprintable_text(err)) | |
183 | return ET.ElementTree(test_suite) | |
184 | ||
154 | 185 | def print_report(self, stream, time_taken, out, err): |
155 | 186 | """Prints the XML report to the supplied stream. |
156 | 187 | |
158 | 189 | output and standard error streams must be passed in.a |
159 | 190 | |
160 | 191 | """ |
161 | stream.write('<testsuite errors="%(e)d" failures="%(f)d" ' % \ | |
162 | { "e": len(self.errors), "f": len(self.failures) }) | |
163 | stream.write('name="%(n)s" tests="%(t)d" time="%(time).3f">\n' % \ | |
164 | { | |
165 | "n": self._test_name, | |
166 | "t": self.testsRun, | |
167 | "time": time_taken, | |
168 | }) | |
169 | for info in self._tests: | |
170 | info.print_report(stream) | |
171 | stream.write(' <system-out><![CDATA[%s]]></system-out>\n' % out) | |
172 | stream.write(' <system-err><![CDATA[%s]]></system-err>\n' % err) | |
173 | stream.write('</testsuite>\n') | |
192 | stream.write(ET.tostring(self.xml(time_taken, out, err).getroot(), encoding='utf-8', method='xml')) | |
174 | 193 | |
175 | 194 | def print_report_text(self, stream, time_taken, out, err): |
176 | 195 | """Prints the text report to the supplied stream. |
246 | 265 | result.print_report(stream, time_taken, out_s, err_s) |
247 | 266 | |
248 | 267 | result.print_report_text(sys.stdout, time_taken, out_s, err_s) |
249 | ||
250 | if self._stream == None: | |
251 | stream.close() | |
252 | 268 | |
253 | 269 | return result |
254 | 270 |
0 | import unittest | |
1 | ||
2 | ||
3 | class CaseA(unittest.TestCase): | |
4 | ||
5 | def runTest(self): | |
6 | self.assertTrue(True) | |
7 | ||
8 | ||
9 | class CaseB(unittest.TestCase): | |
10 | ||
11 | def runTest(self): | |
12 | self.assertTrue(True) | |
13 | ||
14 | ||
15 | class DotnameLoadingSuite(unittest.TestSuite): | |
16 | ||
17 | def __init__(self): | |
18 | super(DotnameLoadingSuite, self).__init__() | |
19 | self.addTest(CaseA()) | |
20 | self.addTest(CaseB()) | |
21 | ||
22 | ||
23 | class DotnameLoadingTest(unittest.TestCase): | |
24 | ||
25 | def test_a(self): | |
26 | self.assertTrue(True) | |
27 | ||
28 | def test_b(self): | |
29 | self.assertTrue(True) | |
30 | ||
31 | ||
32 | class NotTestCase(): | |
33 | ||
34 | def not_test(self): | |
35 | pass |
0 | #!/usr/bin/env python | |
1 | ||
2 | # This file should be run using a non-ros unit test framework such as nose using | |
3 | # nosetests test_dotname.py. Alternatively, just run with python test_dotname.py. | |
4 | # You will get the output from rostest as well. | |
5 | ||
6 | import unittest | |
7 | import rosunit | |
8 | from dotname_cases import DotnameLoadingTest, NotTestCase | |
9 | ||
10 | ||
11 | class TestDotnameLoading(unittest.TestCase): | |
12 | ||
13 | def test_class_basic(self): | |
14 | rosunit.unitrun('test_rosunit', 'test_class_basic', DotnameLoadingTest) | |
15 | ||
16 | def test_class_dotname(self): | |
17 | rosunit.unitrun('test_rosunit', 'test_class_dotname', 'test.dotname_cases.DotnameLoadingTest') | |
18 | ||
19 | def test_method_dotname(self): | |
20 | rosunit.unitrun('test_rosunit', 'test_method_dotname', 'test.dotname_cases.DotnameLoadingTest.test_a') | |
21 | ||
22 | def test_suite_dotname(self): | |
23 | rosunit.unitrun('test_rosunit', 'test_suite_dotname', 'test.dotname_cases.DotnameLoadingSuite') | |
24 | ||
25 | def test_class_basic_nottest(self): | |
26 | # class which exists but is not a TestCase | |
27 | with self.assertRaises(SystemExit): | |
28 | rosunit.unitrun('test_rosunit', 'test_class_basic_nottest', NotTestCase) | |
29 | ||
30 | def test_class_dotname_nottest(self): | |
31 | # class which exists but is not a valid test | |
32 | with self.assertRaises(TypeError): | |
33 | rosunit.unitrun('test_rosunit', 'test_class_dotname_nottest', 'test.dotname_cases.NotTestCase') | |
34 | ||
35 | def test_class_dotname_noexist(self): | |
36 | # class which does not exist in the module | |
37 | with self.assertRaises(AttributeError): | |
38 | rosunit.unitrun('test_rosunit', 'test_class_dotname_noexist', 'test.dotname_cases.DotnameLoading') | |
39 | ||
40 | def test_method_dotname_noexist(self): | |
41 | # method which does not exist in the class | |
42 | with self.assertRaises(AttributeError): | |
43 | rosunit.unitrun('test_rosunit', 'test_method_dotname_noexist', 'test.dotname_cases.DotnameLoadingTest.not_method') | |
44 | ||
45 | ||
46 | if __name__ == '__main__': | |
47 | unittest.main() |
90 | 90 | if len(result.suites) > 1 or result.noSuitesRoot == False: |
91 | 91 | f.write('</testsuites>\n') |
92 | 92 | |
93 | class XmlResultTestGeneration(unittest.TestCase): | |
94 | def setUp(self): | |
95 | global junitxml | |
96 | if junitxml is None: | |
97 | import rosunit.junitxml | |
98 | junitxml = rosunit.junitxml | |
99 | ||
100 | def tearDown(self): | |
101 | pass | |
102 | ||
103 | def testGenerateError(self): | |
104 | error = junitxml.TestError('error_type', 'error_text') | |
105 | error_str = error.xml() | |
106 | self.assertEquals('''<error type="error_type"><![CDATA[ | |
107 | error_text | |
108 | ]]></error>''', error_str) | |
109 | ||
110 | def testGenerateFailure(self): | |
111 | failure = junitxml.TestFailure('failure_type', 'failure_text') | |
112 | failure_str = failure.xml() | |
113 | self.assertEquals('''<failure type="failure_type"><![CDATA[ | |
114 | failure_text | |
115 | ]]></failure>''', failure_str) | |
116 | ||
117 | def testGenerateTestCaseResult(self): | |
118 | testcase = junitxml.TestCaseResult('test_case') | |
119 | error = junitxml.TestError('error_type', 'error_text') | |
120 | error_str = error.xml() | |
121 | failure = junitxml.TestFailure('failure_type', 'failure_text') | |
122 | failure_str = failure.xml() | |
123 | testcase.add_error(error) | |
124 | testcase.add_failure(failure) | |
125 | testcase_str = testcase.xml() | |
126 | self.assertEquals('''<testcase classname="" name="test_case" time="0.0"><failure type="failure_type"><![CDATA[ | |
127 | failure_text | |
128 | ]]></failure><error type="error_type"><![CDATA[ | |
129 | error_text | |
130 | ]]></error></testcase>''', testcase_str) | |
93 | 131 | |
94 | 132 | class XmlResultTestRead(unittest.TestCase): |
95 | 133 |