porting tests from test_roslib into roslib package
This commit is contained in:
parent
4cde9e9262
commit
aea291debc
|
@ -561,185 +561,3 @@ def _safe_load_manifest(p):
|
|||
return roslib.manifest.load_manifest(p)
|
||||
except:
|
||||
return roslib.manifest.Manifest()
|
||||
|
||||
class ROSPackages(object):
|
||||
"""
|
||||
UNSTABLE/EXPERIMENTAL
|
||||
|
||||
Utility class for querying properties about ROS packages. This
|
||||
should be used when querying properties about multiple
|
||||
packages. ROSPackages caches information about packages, which
|
||||
enables it to have higher performance than alternatives like
|
||||
shelling out to rospack.
|
||||
|
||||
Example::
|
||||
rp = ROSPackages()
|
||||
d = rp.depends1(['roscpp', 'rospy'])
|
||||
print d['roscpp']
|
||||
d = rp.rosdeps(['roscpp', 'rospy'])
|
||||
print d['rospy']
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
self.manifests = {}
|
||||
self._depends_cache = {}
|
||||
self._rosdeps_cache = {}
|
||||
|
||||
def load_manifests(self, packages):
|
||||
"""
|
||||
Load manifests for specified packages into 'manifests' attribute.
|
||||
|
||||
|
||||
@param packages: package names
|
||||
@type packages: [str]
|
||||
"""
|
||||
|
||||
if not type(packages) in [list, tuple]:
|
||||
raise TypeError("packages must be list or tuple")
|
||||
|
||||
# load any manifests that we haven't already
|
||||
to_load = [p for p in packages if not p in self.manifests]
|
||||
if to_load:
|
||||
_update_rospack_cache()
|
||||
self.manifests.update(dict([(p, _safe_load_manifest(p)) for p in to_load]))
|
||||
|
||||
def depends1(self, packages):
|
||||
"""
|
||||
Collect all direct dependencies of specified packages into a
|
||||
dictionary.
|
||||
|
||||
@param packages: package names
|
||||
@type packages: [str]
|
||||
@return: dictionary mapping package names to list of dependent package names.
|
||||
@rtype: {str: [str]}
|
||||
"""
|
||||
self.load_manifests(packages)
|
||||
map = {}
|
||||
manifests = self.manifests
|
||||
for pkg in packages:
|
||||
map[pkg] = [d.package for d in manifests[pkg].depends]
|
||||
return map
|
||||
|
||||
def depends(self, packages):
|
||||
"""
|
||||
Collect all dependencies of specified packages into a
|
||||
dictionary.
|
||||
|
||||
@param packages: package names
|
||||
@type packages: [str]
|
||||
@return: dictionary mapping package names to list of dependent package names.
|
||||
@rtype: {str: [str]}
|
||||
"""
|
||||
|
||||
self.load_manifests(packages)
|
||||
map = {}
|
||||
for pkg in packages:
|
||||
if pkg in self._depends_cache:
|
||||
map[pkg] = self._depends_cache[pkg]
|
||||
else:
|
||||
# this will cache for future reference
|
||||
map[pkg] = self._depends(pkg)
|
||||
return map
|
||||
|
||||
def _depends(self, package):
|
||||
"""
|
||||
Compute recursive dependencies of a single package and cache
|
||||
the result in self._depends_cache.
|
||||
|
||||
This is an internal routine. It assumes that
|
||||
load_manifests() has already been invoked for package.
|
||||
|
||||
@param package: package name
|
||||
@type package: str
|
||||
@return: list of rosdeps
|
||||
@rtype: [str]
|
||||
"""
|
||||
|
||||
if package in self._depends_cache:
|
||||
return self._depends_cache[package]
|
||||
|
||||
# assign key before recursive call to prevent infinite case
|
||||
self._depends_cache[package] = s = set()
|
||||
|
||||
manifests = self.manifests
|
||||
# take the union of all dependencies
|
||||
pkgs = [p.package for p in manifests[package].depends]
|
||||
self.load_manifests(pkgs)
|
||||
for p in pkgs:
|
||||
s.update(self._depends(p))
|
||||
# add in our own deps
|
||||
s.update(pkgs)
|
||||
# cache the return value as a list
|
||||
s = list(s)
|
||||
self._depends_cache[package] = s
|
||||
return s
|
||||
|
||||
def rosdeps0(self, packages):
|
||||
"""
|
||||
Collect rosdeps of specified packages into a dictionary.
|
||||
@param packages: package names
|
||||
@type packages: [str]
|
||||
@return: dictionary mapping package names to list of rosdep names.
|
||||
@rtype: {str: [str]}
|
||||
"""
|
||||
|
||||
self.load_manifests(packages)
|
||||
map = {}
|
||||
manifests = self.manifests
|
||||
for pkg in packages:
|
||||
map[pkg] = [d.name for d in manifests[pkg].rosdeps]
|
||||
return map
|
||||
|
||||
def rosdeps(self, packages):
|
||||
"""
|
||||
Collect all (recursive) dependencies of specified packages
|
||||
into a dictionary.
|
||||
|
||||
@param packages: package names
|
||||
@type packages: [str]
|
||||
@return: dictionary mapping package names to list of dependent package names.
|
||||
@rtype: {str: [str]}
|
||||
"""
|
||||
|
||||
self.load_manifests(packages)
|
||||
map = {}
|
||||
for pkg in packages:
|
||||
if pkg in self._rosdeps_cache:
|
||||
map[pkg] = self._rosdeps_cache[pkg]
|
||||
else:
|
||||
# this will cache for future reference
|
||||
map[pkg] = self._rosdeps(pkg)
|
||||
return map
|
||||
|
||||
def _rosdeps(self, package):
|
||||
"""
|
||||
Compute recursive rosdeps of a single package and cache the
|
||||
result in self._rosdeps_cache.
|
||||
|
||||
This is an internal routine. It assumes that
|
||||
load_manifests() has already been invoked for package.
|
||||
|
||||
@param package: package name
|
||||
@type package: str
|
||||
@return: list of rosdeps
|
||||
@rtype: [str]
|
||||
"""
|
||||
|
||||
if package in self._rosdeps_cache:
|
||||
return self._rosdeps_cache[package]
|
||||
# set the key before recursive call to prevent infinite case
|
||||
self._rosdeps_cache[package] = s = set()
|
||||
|
||||
manifests = self.manifests
|
||||
# take the union of all dependencies
|
||||
pkgs = [p.package for p in manifests[package].depends]
|
||||
self.load_manifests(pkgs)
|
||||
for p in pkgs:
|
||||
s.update(self._rosdeps(p))
|
||||
# add in our own deps
|
||||
s.update([d.name for d in manifests[package].rosdeps])
|
||||
# cache the return value as a list
|
||||
s = list(s)
|
||||
self._rosdeps_cache[package] = s
|
||||
return s
|
||||
|
||||
|
|
|
@ -188,6 +188,7 @@ def expand_to_packages(names, env=None):
|
|||
if env is None:
|
||||
env = os.environ
|
||||
ros_paths = rospkg.get_ros_paths(env)
|
||||
print "ROS_PATHS", ros_paths, env['ROS_PACKAGE_PATH']
|
||||
rospack = rospkg.RosPack(ros_paths)
|
||||
rosstack = rospkg.RosStack(ros_paths)
|
||||
return rospkg.expand_to_packages(names, rospack, rosstack)
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
#!/usr/bin/env python
|
||||
# this node only exists to test find_node functionality
|
||||
|
||||
print "hello"
|
|
@ -0,0 +1,21 @@
|
|||
<package>
|
||||
<description brief="a brief description">Line 1
|
||||
Line 2
|
||||
</description>
|
||||
<version>1.2.4</version> <!-- bad -->
|
||||
<author>The authors
|
||||
go here</author>
|
||||
<license>Public Domain
|
||||
with other stuff</license>
|
||||
<url>http://pr.willowgarage.com/package/</url>
|
||||
<logo>http://www.willowgarage.com/files/willowgarage/robot10.jpg</logo>
|
||||
<depend package="pkgname" />
|
||||
<depend package="common"/>
|
||||
<export>
|
||||
<cpp cflags="-I${prefix}/include" lflags="-L${prefix}/lib -lros"/>
|
||||
<cpp os="osx" cflags="-I${prefix}/include" lflags="-L${prefix}/lib -lrosthread -framework CoreServices"/>
|
||||
</export>
|
||||
<rosdep name="python" />
|
||||
<rosdep name="bar" />
|
||||
<rosdep name="baz" />
|
||||
</package>
|
|
@ -0,0 +1 @@
|
|||
not xml
|
|
@ -0,0 +1,20 @@
|
|||
<notpackage>
|
||||
<description brief="a brief description">Line 1
|
||||
Line 2
|
||||
</description>
|
||||
<author>The authors
|
||||
go here</author>
|
||||
<license>Public Domain
|
||||
with other stuff</license>
|
||||
<url>http://pr.willowgarage.com/package/</url>
|
||||
<logo>http://www.willowgarage.com/files/willowgarage/robot10.jpg</logo>
|
||||
<depend package="pkgname" />
|
||||
<depend package="common"/>
|
||||
<export>
|
||||
<cpp cflags="-I${prefix}/include" lflags="-L${prefix}/lib -lros"/>
|
||||
<cpp os="osx" cflags="-I${prefix}/include" lflags="-L${prefix}/lib -lrosthread -framework CoreServices"/>
|
||||
</export>
|
||||
<rosdep name="python" />
|
||||
<rosdep name="bar" />
|
||||
<rosdep name="baz" />
|
||||
</notpackage>
|
|
@ -0,0 +1,11 @@
|
|||
<package>
|
||||
<description brief="a brief description">Line 1
|
||||
</description>
|
||||
<description brief="a brief second description">Second description
|
||||
</description>
|
||||
|
||||
<author>The authors
|
||||
go here</author>
|
||||
<license>Public Domain
|
||||
with other stuff</license>
|
||||
</package>
|
|
@ -0,0 +1,20 @@
|
|||
<package>
|
||||
<description brief="a brief description">Line 1
|
||||
Line 2
|
||||
</description>
|
||||
<author>The authors
|
||||
go here</author>
|
||||
<license>Public Domain
|
||||
with other stuff</license>
|
||||
<url>http://pr.willowgarage.com/package/</url>
|
||||
<logo>http://www.willowgarage.com/files/willowgarage/robot10.jpg</logo>
|
||||
<depend package="pkgname" />
|
||||
<depend package="common"/>
|
||||
<export>
|
||||
<cpp cflags="-I${prefix}/include" lflags="-L${prefix}/lib -lros"/>
|
||||
<cpp os="osx" cflags="-I${prefix}/include" lflags="-L${prefix}/lib -lrosthread -framework CoreServices"/>
|
||||
</export>
|
||||
<rosdep name="python" />
|
||||
<rosdep name="bar" />
|
||||
<rosdep name="baz" />
|
||||
</package>
|
|
@ -0,0 +1,13 @@
|
|||
<stack>
|
||||
<description brief="a brief description">Line 1
|
||||
Line 2
|
||||
</description>
|
||||
<author>The authors
|
||||
go here</author>
|
||||
<license>Public Domain
|
||||
with other stuff</license>
|
||||
<url>http://ros.org/stack/</url>
|
||||
<logo>http://www.willowgarage.com/files/willowgarage/robot10.jpg</logo>
|
||||
<depend stack="stackname" />
|
||||
<depend stack="common"/>
|
||||
</stack>
|
|
@ -0,0 +1,14 @@
|
|||
<stack>
|
||||
<description brief="a brief description">Line 1
|
||||
Line 2
|
||||
</description>
|
||||
<author>The authors
|
||||
go here</author>
|
||||
<license>Public Domain
|
||||
with other stuff</license>
|
||||
<url>http://ros.org/stack/</url>
|
||||
<version>1.2.3</version>
|
||||
<logo>http://www.willowgarage.com/files/willowgarage/robot10.jpg</logo>
|
||||
<depend stack="stackname" />
|
||||
<depend stack="common"/>
|
||||
</stack>
|
|
@ -0,0 +1,64 @@
|
|||
/*
|
||||
* Copyright (c) 2008, Willow Garage, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of Willow Garage, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
#include <ros/package.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
using namespace ros;
|
||||
|
||||
TEST(Package, getPath)
|
||||
{
|
||||
std::string path = package::getPath("roslib");
|
||||
printf("Path: %s\n", path.c_str());
|
||||
ASSERT_FALSE(path.empty());
|
||||
}
|
||||
|
||||
TEST(Package, getAll)
|
||||
{
|
||||
using package::V_string;
|
||||
V_string packages;
|
||||
ASSERT_TRUE(package::getAll(packages));
|
||||
ASSERT_FALSE(packages.empty());
|
||||
|
||||
V_string::iterator it = packages.begin();
|
||||
V_string::iterator end = packages.end();
|
||||
for (; it != end; ++it)
|
||||
{
|
||||
printf("Package: %s\n", it->c_str());
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char **argv){
|
||||
testing::InitGoogleTest(&argc, argv);
|
||||
return RUN_ALL_TESTS();
|
||||
}
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
<package>
|
||||
<description brief="bar">
|
||||
|
||||
bar
|
||||
|
||||
</description>
|
||||
<author>Ken Conley</author>
|
||||
<license>BSD</license>
|
||||
<review status="unreviewed" notes=""/>
|
||||
<url>http://ros.org/wiki/bar</url>
|
||||
|
||||
</package>
|
||||
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
<package>
|
||||
<description brief="foo">
|
||||
|
||||
foo
|
||||
|
||||
</description>
|
||||
<author>Ken Conley</author>
|
||||
<license>BSD</license>
|
||||
<review status="unreviewed" notes=""/>
|
||||
<url>http://ros.org/wiki/foo</url>
|
||||
|
||||
</package>
|
||||
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
<package>
|
||||
<description brief="foo">
|
||||
|
||||
foo
|
||||
|
||||
</description>
|
||||
<author>Ken Conley</author>
|
||||
<license>BSD</license>
|
||||
<review status="unreviewed" notes=""/>
|
||||
<url>http://ros.org/wiki/foo</url>
|
||||
|
||||
</package>
|
||||
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
<package>
|
||||
<description brief="roslib tests">
|
||||
Unit tests verifying that roslib is operating as expected.
|
||||
</description>
|
||||
<author>none</author>
|
||||
<license>BSD</license>
|
||||
<platform os="test_os" version="test_version"/>
|
||||
</package>
|
|
@ -0,0 +1,6 @@
|
|||
[nosetests]
|
||||
with-xunit=1
|
||||
with-coverage=1
|
||||
cover-package=roslib
|
||||
tests=test_roslib_manifest.py,test_roslib_names.py,test_roslib_packages.py,test_roslib_params.py, test_roslib.py, test_roslib_rosenv.py, test_roslib_stack_manifest.py, test_roslib_stacks.py, test_roslib_substitution_args.py, test_roslib_exceptions.py, test_roslib_manifestlib.py
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
cmake_minimum_required(VERSION 2.4.6)
|
||||
include($ENV{ROS_ROOT}/core/rosbuild/rosbuild.cmake)
|
||||
set(ROSPACK_MAKEDIST true)
|
||||
rosbuild_make_distribution(1.5.0-cmake)
|
|
@ -0,0 +1,9 @@
|
|||
<stack>
|
||||
<description brief="bar">
|
||||
bar
|
||||
</description>
|
||||
<author>Ken Conley</author>
|
||||
<license>BSD</license>
|
||||
</stack>
|
||||
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
cmake_minimum_required(VERSION 2.4.6)
|
||||
include($ENV{ROS_ROOT}/core/rosbuild/rosbuild.cmake)
|
||||
set(ROSPACK_MAKEDIST true)
|
||||
rosbuild_make_distribution(1.5.0-cmake)
|
|
@ -0,0 +1,14 @@
|
|||
<package>
|
||||
<description brief="foo_pkg">
|
||||
|
||||
foo_pkg
|
||||
|
||||
</description>
|
||||
<author>Ken Conley</author>
|
||||
<license>BSD</license>
|
||||
<review status="unreviewed" notes=""/>
|
||||
<url>http://ros.org/wiki/foo_pkg</url>
|
||||
|
||||
</package>
|
||||
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
<package>
|
||||
<description brief="foo_pkg_2">
|
||||
|
||||
foo_pkg_2
|
||||
|
||||
</description>
|
||||
<author>Ken Conley</author>
|
||||
<license>BSD</license>
|
||||
<review status="unreviewed" notes=""/>
|
||||
<url>http://ros.org/wiki/foo_pkg_2</url>
|
||||
|
||||
</package>
|
||||
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
<stack>
|
||||
<description brief="foo">
|
||||
foo
|
||||
</description>
|
||||
<author>Ken Conley</author>
|
||||
<version>
|
||||
1.6.0-manifest
|
||||
</version>
|
||||
<license>BSD</license>
|
||||
</stack>
|
||||
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
<package>
|
||||
<description brief="foo">
|
||||
foo
|
||||
</description>
|
||||
<author>Ken Conley</author>
|
||||
<license>BSD</license>
|
||||
</package>
|
||||
|
||||
|
|
@ -0,0 +1 @@
|
|||
../stack_tests/s1
|
|
@ -0,0 +1,11 @@
|
|||
<package>
|
||||
<description brief="roslib tests">
|
||||
Fake
|
||||
</description>
|
||||
<author>No one</author>
|
||||
<license>BSD</license>
|
||||
<review status="test" notes=""/>
|
||||
|
||||
<depend package="roslib" />
|
||||
<depend package="rosunit" />
|
||||
</package>
|
|
@ -0,0 +1,9 @@
|
|||
<stack>
|
||||
<description brief="bar">
|
||||
bar
|
||||
</description>
|
||||
<author>Ken Conley</author>
|
||||
<license>BSD</license>
|
||||
</stack>
|
||||
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
<stack>
|
||||
<description brief="bar">
|
||||
bar
|
||||
</description>
|
||||
<author>Ken Conley</author>
|
||||
<license>BSD</license>
|
||||
</stack>
|
||||
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
<package>
|
||||
<description brief="roslib tests">
|
||||
Fake
|
||||
</description>
|
||||
<author>No one</author>
|
||||
<license>BSD</license>
|
||||
<review status="test" notes=""/>
|
||||
|
||||
<depend package="roslib" />
|
||||
<depend package="rosunit" />
|
||||
</package>
|
|
@ -0,0 +1,9 @@
|
|||
<stack>
|
||||
<description brief="foo">
|
||||
foo
|
||||
</description>
|
||||
<author>Ken Conley</author>
|
||||
<license>BSD</license>
|
||||
</stack>
|
||||
|
||||
|
|
@ -0,0 +1,49 @@
|
|||
# Software License Agreement (BSD License)
|
||||
#
|
||||
# Copyright (c) 2009, Willow Garage, Inc.
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions
|
||||
# are met:
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
# * Redistributions in binary form must reproduce the above
|
||||
# copyright notice, this list of conditions and the following
|
||||
# disclaimer in the documentation and/or other materials provided
|
||||
# with the distribution.
|
||||
# * Neither the name of Willow Garage, Inc. nor the names of its
|
||||
# contributors may be used to endorse or promote products derived
|
||||
# from this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
import os
|
||||
import sys
|
||||
|
||||
def test_load_manifest():
|
||||
# this is a bit of a noop as it's a prerequisite of running with rosunit
|
||||
import roslib
|
||||
roslib.load_manifest('roslib')
|
||||
|
||||
def test_interactive():
|
||||
import roslib
|
||||
|
||||
# make sure that it's part of high-level API
|
||||
assert not roslib.is_interactive(), "interactive should be false by default"
|
||||
for v in [True, False]:
|
||||
roslib.set_interactive(v)
|
||||
assert v == roslib.is_interactive()
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
# Software License Agreement (BSD License)
|
||||
#
|
||||
# Copyright (c) 2009, Willow Garage, Inc.
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions
|
||||
# are met:
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
# * Redistributions in binary form must reproduce the above
|
||||
# copyright notice, this list of conditions and the following
|
||||
# disclaimer in the documentation and/or other materials provided
|
||||
# with the distribution.
|
||||
# * Neither the name of Willow Garage, Inc. nor the names of its
|
||||
# contributors may be used to endorse or promote products derived
|
||||
# from this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
import os
|
||||
import sys
|
||||
|
||||
def test_exceptions():
|
||||
from roslib.exceptions import ROSLibException
|
||||
assert isinstance(ROSLibException(), Exception)
|
|
@ -0,0 +1,172 @@
|
|||
# Software License Agreement (BSD License)
|
||||
#
|
||||
# Copyright (c) 2009, Willow Garage, Inc.
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions
|
||||
# are met:
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
# * Redistributions in binary form must reproduce the above
|
||||
# copyright notice, this list of conditions and the following
|
||||
# disclaimer in the documentation and/or other materials provided
|
||||
# with the distribution.
|
||||
# * Neither the name of Willow Garage, Inc. nor the names of its
|
||||
# contributors may be used to endorse or promote products derived
|
||||
# from this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
import os
|
||||
import sys
|
||||
import unittest
|
||||
|
||||
import roslib
|
||||
|
||||
def get_test_path():
|
||||
return os.path.abspath(os.path.dirname(__file__))
|
||||
|
||||
class RoslibManifestTest(unittest.TestCase):
|
||||
|
||||
def test_ManifestException(self):
|
||||
from roslib.manifest import ManifestException
|
||||
self.assert_(isinstance(ManifestException(), Exception))
|
||||
|
||||
def test_Depend(self):
|
||||
from roslib.manifestlib import Depend, ManifestException
|
||||
for bad in [None, '']:
|
||||
try:
|
||||
Depend(bad)
|
||||
self.fail("should have failed on [%s]"%bad)
|
||||
except ValueError: pass
|
||||
|
||||
d = Depend('roslib')
|
||||
self.assertEquals('roslib', str(d))
|
||||
self.assertEquals('roslib', repr(d))
|
||||
|
||||
self.assertEquals('<depend package="roslib" />',d.xml())
|
||||
self.assertEquals(d, Depend('roslib'))
|
||||
self.assertNotEquals(d, Depend('roslib2'))
|
||||
self.assertNotEquals(d, 1)
|
||||
|
||||
def test_ROSDep(self):
|
||||
from roslib.manifest import ROSDep, ManifestException
|
||||
for bad in [None, '']:
|
||||
try:
|
||||
rd = ROSDep(bad)
|
||||
self.fail("should have failed on [%s]"%bad)
|
||||
except ValueError: pass
|
||||
|
||||
rd = ROSDep('python')
|
||||
self.assertEquals('<rosdep name="python" />',rd.xml())
|
||||
|
||||
def test_VersionControl(self):
|
||||
from roslib.manifest import VersionControl, ManifestException
|
||||
ros_svn = 'https://ros.svn.sf.net/svnroot'
|
||||
|
||||
bad = [
|
||||
(None, ros_svn),
|
||||
]
|
||||
for type_, url in bad:
|
||||
try:
|
||||
VersionControl(type_,url)
|
||||
self.fail("should have failed on [%s] [%s]"%(type_, url))
|
||||
except ValueError: pass
|
||||
|
||||
tests = [
|
||||
('svn', ros_svn, '<versioncontrol type="svn" url="%s" />'%ros_svn),
|
||||
('cvs', None, '<versioncontrol type="cvs" />'),
|
||||
]
|
||||
for type_, url, xml in tests:
|
||||
vc = VersionControl(type_, url)
|
||||
self.assertEquals(type_, vc.type)
|
||||
self.assertEquals(url, vc.url)
|
||||
self.assertEquals(xml, vc.xml())
|
||||
|
||||
def _subtest_parse_example1(self, m):
|
||||
from roslib.manifest import Manifest
|
||||
self.assert_(isinstance(m, Manifest))
|
||||
self.assertEquals("a brief description", m.brief)
|
||||
self.assertEquals("Line 1\nLine 2", m.description.strip())
|
||||
self.assertEquals("The authors\ngo here", m.author.strip())
|
||||
self.assertEquals("Public Domain\nwith other stuff", m.license.strip())
|
||||
self.assertEquals("http://pr.willowgarage.com/package/", m.url)
|
||||
self.assertEquals("http://www.willowgarage.com/files/willowgarage/robot10.jpg", m.logo)
|
||||
dpkgs = [d.package for d in m.depends]
|
||||
self.assertEquals(set(['pkgname', 'common']), set(dpkgs))
|
||||
rdpkgs = [d.name for d in m.rosdeps]
|
||||
self.assertEquals(set(['python', 'bar', 'baz']), set(rdpkgs))
|
||||
|
||||
def test_parse_example1_file(self):
|
||||
from roslib.manifest import parse_file, Manifest
|
||||
p = os.path.join(get_test_path(), 'manifest_tests', 'example1.xml')
|
||||
self._subtest_parse_example1(parse_file(p))
|
||||
|
||||
def test_parse_example1_string(self):
|
||||
from roslib.manifest import parse, Manifest
|
||||
self._subtest_parse_example1(parse(EXAMPLE1))
|
||||
|
||||
def test_Manifest_str(self):
|
||||
# just make sure it doesn't crash
|
||||
from roslib.manifest import parse
|
||||
str(parse(EXAMPLE1))
|
||||
|
||||
def test_Manifest_xml(self):
|
||||
from roslib.manifest import parse
|
||||
m = parse(EXAMPLE1)
|
||||
self._subtest_parse_example1(m)
|
||||
# verify roundtrip
|
||||
m2 = parse(m.xml())
|
||||
self._subtest_parse_example1(m2)
|
||||
|
||||
|
||||
def test_parse_bad_file(self):
|
||||
from roslib.manifest import parse_file, Manifest
|
||||
# have to import from ManifestException due to weirdness when run in --cov mode
|
||||
from roslib.manifestlib import ManifestException
|
||||
base_p = os.path.join(get_test_path(), 'manifest_tests')
|
||||
for b in ['bad1.xml', 'bad2.xml', 'bad3.xml']:
|
||||
p = os.path.join(base_p, b)
|
||||
try:
|
||||
parse_file(p)
|
||||
self.fail("parse should have failed on bad manifest")
|
||||
except ManifestException, e:
|
||||
print str(e)
|
||||
self.assert_(b in str(e), "file name should be in error message: %s"%(str(e)))
|
||||
|
||||
EXAMPLE1 = """<package>
|
||||
<description brief="a brief description">Line 1
|
||||
Line 2
|
||||
</description>
|
||||
<author>The authors
|
||||
go here</author>
|
||||
<license>Public Domain
|
||||
with other stuff</license>
|
||||
<url>http://pr.willowgarage.com/package/</url>
|
||||
<logo>http://www.willowgarage.com/files/willowgarage/robot10.jpg</logo>
|
||||
<depend package="pkgname" />
|
||||
<depend package="common"/>
|
||||
<export>
|
||||
<cpp cflags="-I${prefix}/include" lflags="-L${prefix}/lib -lros"/>
|
||||
<cpp os="osx" cflags="-I${prefix}/include" lflags="-L${prefix}/lib -lrosthread -framework CoreServices"/>
|
||||
</export>
|
||||
<rosdep name="python" />
|
||||
<rosdep name="bar" />
|
||||
<rosdep name="baz" />
|
||||
<rosbuild2>
|
||||
<depend thirdparty="thisshouldbeokay"/>
|
||||
</rosbuild2>
|
||||
</package>"""
|
|
@ -0,0 +1,305 @@
|
|||
# Software License Agreement (BSD License)
|
||||
#
|
||||
# Copyright (c) 2009, Willow Garage, Inc.
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions
|
||||
# are met:
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
# * Redistributions in binary form must reproduce the above
|
||||
# copyright notice, this list of conditions and the following
|
||||
# disclaimer in the documentation and/or other materials provided
|
||||
# with the distribution.
|
||||
# * Neither the name of Willow Garage, Inc. nor the names of its
|
||||
# contributors may be used to endorse or promote products derived
|
||||
# from this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
import os
|
||||
import struct
|
||||
import sys
|
||||
import unittest
|
||||
|
||||
import roslib
|
||||
|
||||
class RoslibManifestlibTest(unittest.TestCase):
|
||||
|
||||
def test_ManifestException(self):
|
||||
from roslib.manifestlib import ManifestException
|
||||
self.assert_(isinstance(ManifestException(), Exception))
|
||||
|
||||
def test_Platform(self):
|
||||
from roslib.manifestlib import Platform, ManifestException
|
||||
for bad in [None, '']:
|
||||
try:
|
||||
Platform(bad, '1')
|
||||
self.fail("should have failed on [%s]"%bad)
|
||||
except ValueError: pass
|
||||
try:
|
||||
Platform('ubuntu', bad)
|
||||
self.fail("should have failed on [%s]"%bad)
|
||||
except ValueError: pass
|
||||
|
||||
p = Platform('ubuntu', '8.04')
|
||||
self.assertEquals('ubuntu 8.04', str(p))
|
||||
self.assertEquals('ubuntu 8.04', repr(p))
|
||||
|
||||
self.assertEquals('<platform os="ubuntu" version="8.04"/>',p.xml())
|
||||
self.assertEquals(p, Platform('ubuntu', '8.04'))
|
||||
self.assertEquals(p, Platform('ubuntu', '8.04', notes=None))
|
||||
self.assertNotEquals(p, Platform('ubuntu', '8.04', 'some notes'))
|
||||
self.assertNotEquals(p, 'foo')
|
||||
self.assertNotEquals(p, 1)
|
||||
|
||||
# note: probably actually "osx"
|
||||
p = Platform('OS X', '10.6', 'macports')
|
||||
self.assertEquals('OS X 10.6', str(p))
|
||||
self.assertEquals('OS X 10.6', repr(p))
|
||||
|
||||
self.assertEquals('<platform os="OS X" version="10.6" notes="macports"/>',p.xml())
|
||||
self.assertEquals(p, p)
|
||||
self.assertEquals(p, Platform('OS X', '10.6', 'macports'))
|
||||
self.assertNotEquals(p, Platform('OS X', '10.6'))
|
||||
self.assertNotEquals(p, 'foo')
|
||||
self.assertNotEquals(p, 1)
|
||||
|
||||
|
||||
def test_Depend(self):
|
||||
from roslib.manifestlib import Depend, StackDepend, ManifestException
|
||||
for bad in [None, '']:
|
||||
try:
|
||||
Depend(bad)
|
||||
self.fail("should have failed on [%s]"%bad)
|
||||
except ValueError: pass
|
||||
|
||||
d = Depend('roslib')
|
||||
self.assertEquals('roslib', str(d))
|
||||
self.assertEquals('roslib', repr(d))
|
||||
|
||||
self.assertEquals('<depend package="roslib" />',d.xml())
|
||||
self.assertEquals(d, Depend('roslib'))
|
||||
self.assertNotEquals(d, StackDepend('roslib'))
|
||||
self.assertNotEquals(d, Depend('roslib2'))
|
||||
self.assertNotEquals(d, 1)
|
||||
|
||||
def test_StackDepend(self):
|
||||
from roslib.manifestlib import Depend, StackDepend, ManifestException
|
||||
for bad in [None, '']:
|
||||
try:
|
||||
StackDepend(bad)
|
||||
self.fail("should have failed on [%s]"%bad)
|
||||
except ValueError: pass
|
||||
|
||||
d = StackDepend('common')
|
||||
self.assertEquals('common', str(d))
|
||||
self.assertEquals('common', repr(d))
|
||||
|
||||
self.assertEquals('<depend stack="common" />',d.xml())
|
||||
self.assertEquals(d, StackDepend('common'))
|
||||
self.assertNotEquals(d, Depend('common'))
|
||||
self.assertNotEquals(d, StackDepend('common2'))
|
||||
self.assertNotEquals(d, 1)
|
||||
|
||||
def test_ROSDep(self):
|
||||
from roslib.manifestlib import ROSDep, ManifestException
|
||||
for bad in [None, '']:
|
||||
try:
|
||||
rd = ROSDep(bad)
|
||||
self.fail("should have failed on [%s]"%bad)
|
||||
except ValueError: pass
|
||||
|
||||
rd = ROSDep('python')
|
||||
self.assertEquals('<rosdep name="python" />',rd.xml())
|
||||
|
||||
def test_VersionControl(self):
|
||||
from roslib.manifestlib import VersionControl, ManifestException
|
||||
ros_svn = 'https://ros.svn.sf.net/svnroot'
|
||||
|
||||
bad = [
|
||||
(None, ros_svn),
|
||||
]
|
||||
for type_, url in bad:
|
||||
try:
|
||||
VersionControl(type_,url)
|
||||
self.fail("should have failed on [%s] [%s]"%(type_, url))
|
||||
except ValueError: pass
|
||||
|
||||
tests = [
|
||||
('svn', ros_svn, '<versioncontrol type="svn" url="%s" />'%ros_svn),
|
||||
('cvs', None, '<versioncontrol type="cvs" />'),
|
||||
]
|
||||
for type_, url, xml in tests:
|
||||
vc = VersionControl(type_, url)
|
||||
self.assertEquals(type_, vc.type)
|
||||
self.assertEquals(url, vc.url)
|
||||
self.assertEquals(xml, vc.xml())
|
||||
|
||||
def _subtest_parse_example1(self, m):
|
||||
from roslib.manifestlib import _Manifest
|
||||
self.assert_(isinstance(m, _Manifest))
|
||||
self.assertEquals("a brief description", m.brief)
|
||||
self.assertEquals("Line 1\nLine 2", m.description.strip())
|
||||
self.assertEquals("The authors\ngo here", m.author.strip())
|
||||
self.assertEquals("Public Domain\nwith other stuff", m.license.strip())
|
||||
self.assertEquals("http://pr.willowgarage.com/package/", m.url)
|
||||
self.assertEquals("http://www.willowgarage.com/files/willowgarage/robot10.jpg", m.logo)
|
||||
dpkgs = [d.package for d in m.depends]
|
||||
self.assertEquals(set(['pkgname', 'common']), set(dpkgs))
|
||||
rdpkgs = [d.name for d in m.rosdeps]
|
||||
self.assertEquals(set(['python', 'bar', 'baz']), set(rdpkgs))
|
||||
for p in m.platforms:
|
||||
if p.os == 'ubuntu':
|
||||
self.assertEquals("8.04", p.version)
|
||||
self.assertEquals('', p.notes)
|
||||
elif p.os == 'OS X':
|
||||
self.assertEquals("10.6", p.version)
|
||||
self.assertEquals("macports", p.notes)
|
||||
else:
|
||||
self.fail("unknown platform "+str(p))
|
||||
|
||||
def _subtest_parse_stack_example1(self, m):
|
||||
from roslib.manifestlib import _Manifest
|
||||
self.assert_(isinstance(m, _Manifest))
|
||||
self.assertEquals('stack', m._type)
|
||||
self.assertEquals("a brief description", m.brief)
|
||||
self.assertEquals("Line 1\nLine 2", m.description.strip())
|
||||
self.assertEquals("The authors\ngo here", m.author.strip())
|
||||
self.assertEquals("Public Domain\nwith other stuff", m.license.strip())
|
||||
self.assertEquals("http://ros.org/stack/", m.url)
|
||||
self.assertEquals("http://www.willowgarage.com/files/willowgarage/robot10.jpg", m.logo)
|
||||
dpkgs = [d.stack for d in m.depends]
|
||||
self.assertEquals(set(['stackname', 'common']), set(dpkgs))
|
||||
self.assertEquals([], m.rosdeps)
|
||||
self.assertEquals([], m.exports)
|
||||
|
||||
def _subtest_parse_stack_version(self, m):
|
||||
self.assertEquals("1.2.3", m.version)
|
||||
|
||||
def test_parse_example1_file(self):
|
||||
from roslib.manifestlib import parse_file, _Manifest
|
||||
p = os.path.join(get_test_path(), 'manifest_tests', 'example1.xml')
|
||||
self._subtest_parse_example1(parse_file(_Manifest(), p))
|
||||
|
||||
p = os.path.join(get_test_path(), 'manifest_tests', 'stack_example1.xml')
|
||||
self._subtest_parse_stack_example1(parse_file(_Manifest('stack'), p))
|
||||
|
||||
p = os.path.join(get_test_path(), 'manifest_tests', 'stack_version.xml')
|
||||
self._subtest_parse_stack_version(parse_file(_Manifest('stack'), p))
|
||||
|
||||
def test_parse_example1_string(self):
|
||||
from roslib.manifestlib import parse, _Manifest
|
||||
self._subtest_parse_example1(parse(_Manifest(), EXAMPLE1))
|
||||
self._subtest_parse_stack_example1(parse(_Manifest('stack'), STACK_EXAMPLE1))
|
||||
|
||||
def test__Manifest(self):
|
||||
from roslib.manifestlib import _Manifest
|
||||
m = _Manifest()
|
||||
# check defaults
|
||||
self.assertEquals('package', m._type)
|
||||
m = _Manifest('stack')
|
||||
self.assertEquals('stack', m._type)
|
||||
|
||||
def test_Manifest_str(self):
|
||||
# just make sure it doesn't crash
|
||||
from roslib.manifestlib import parse, _Manifest
|
||||
str(parse(_Manifest(), EXAMPLE1))
|
||||
|
||||
def test_Manifest_xml(self):
|
||||
from roslib.manifestlib import parse, _Manifest
|
||||
m = _Manifest()
|
||||
parse(m, EXAMPLE1)
|
||||
self._subtest_parse_example1(m)
|
||||
# verify roundtrip
|
||||
m2 = _Manifest()
|
||||
parse(m2, m.xml())
|
||||
self._subtest_parse_example1(m2)
|
||||
|
||||
# bad file examples should be more like the roslaunch tests where there is just 1 thing wrong
|
||||
def test_parse_bad_file(self):
|
||||
from roslib.manifestlib import parse_file, _Manifest, ManifestException
|
||||
base_p = os.path.join(get_test_path(), 'manifest_tests')
|
||||
m = _Manifest()
|
||||
for b in ['bad1.xml', 'bad2.xml', 'bad3.xml']:
|
||||
p = os.path.join(base_p, b)
|
||||
try:
|
||||
parse_file(m, p)
|
||||
self.fail("parse should have failed on bad manifest")
|
||||
except ManifestException, e:
|
||||
print str(e)
|
||||
self.assert_(b in str(e), "file name should be in error message [%s]"%(str(e)))
|
||||
|
||||
EXAMPLE1 = """<package>
|
||||
<description brief="a brief description">Line 1
|
||||
Line 2
|
||||
</description>
|
||||
<author>The authors
|
||||
go here</author>
|
||||
<license>Public Domain
|
||||
with other stuff</license>
|
||||
<url>http://pr.willowgarage.com/package/</url>
|
||||
<logo>http://www.willowgarage.com/files/willowgarage/robot10.jpg</logo>
|
||||
<depend package="pkgname" />
|
||||
<depend package="common"/>
|
||||
<export>
|
||||
<cpp cflags="-I${prefix}/include" lflags="-L${prefix}/lib -lros"/>
|
||||
<cpp os="osx" cflags="-I${prefix}/include" lflags="-L${prefix}/lib -lrosthread -framework CoreServices"/>
|
||||
</export>
|
||||
<rosdep name="python" />
|
||||
<rosdep name="bar" />
|
||||
<rosdep name="baz" />
|
||||
<platform os="ubuntu" version="8.04" />
|
||||
<platform os="OS X" version="10.6" notes="macports" />
|
||||
<rosbuild2>
|
||||
<depend thirdparty="thisshouldbeokay"/>
|
||||
</rosbuild2>
|
||||
</package>"""
|
||||
|
||||
STACK_EXAMPLE1 = """<stack>
|
||||
<description brief="a brief description">Line 1
|
||||
Line 2
|
||||
</description>
|
||||
<author>The authors
|
||||
go here</author>
|
||||
<license>Public Domain
|
||||
with other stuff</license>
|
||||
<url>http://ros.org/stack/</url>
|
||||
<logo>http://www.willowgarage.com/files/willowgarage/robot10.jpg</logo>
|
||||
<depend stack="stackname" />
|
||||
<depend stack="common"/>
|
||||
</stack>"""
|
||||
|
||||
STACK_INVALID1 = """<stack>
|
||||
<description brief="a brief description">Line 1</description>
|
||||
<author>The authors</author>
|
||||
<license>Public Domain</license>
|
||||
<rosdep name="python" />
|
||||
</stack>"""
|
||||
|
||||
STACK_INVALID2 = """<stack>
|
||||
<description brief="a brief description">Line 1</description>
|
||||
<author>The authors</author>
|
||||
<license>Public Domain</license>
|
||||
<export>
|
||||
<cpp cflags="-I${prefix}/include" lflags="-L${prefix}/lib -lros"/>
|
||||
<cpp os="osx" cflags="-I${prefix}/include" lflags="-L${prefix}/lib -lrosthread -framework CoreServices"/>
|
||||
</export>
|
||||
</stack>"""
|
||||
|
||||
|
||||
def get_test_path():
|
||||
return os.path.abspath(os.path.dirname(__file__))
|
|
@ -0,0 +1,324 @@
|
|||
# Software License Agreement (BSD License)
|
||||
#
|
||||
# Copyright (c) 2009, Willow Garage, Inc.
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions
|
||||
# are met:
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
# * Redistributions in binary form must reproduce the above
|
||||
# copyright notice, this list of conditions and the following
|
||||
# disclaimer in the documentation and/or other materials provided
|
||||
# with the distribution.
|
||||
# * Neither the name of Willow Garage, Inc. nor the names of its
|
||||
# contributors may be used to endorse or promote products derived
|
||||
# from this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
import os
|
||||
import sys
|
||||
import unittest
|
||||
|
||||
import roslib.names
|
||||
|
||||
class NamesTest(unittest.TestCase):
|
||||
|
||||
def test_get_ros_namespace(self):
|
||||
if 'ROS_NAMESPACE' in os.environ:
|
||||
rosns = os.environ['ROS_NAMESPACE']
|
||||
del os.environ['ROS_NAMESPACE']
|
||||
else:
|
||||
rosns = None
|
||||
sysargv = sys.argv
|
||||
|
||||
try:
|
||||
sys.argv = []
|
||||
self.assertEquals('/', roslib.names.get_ros_namespace())
|
||||
self.assertEquals('/', roslib.names.get_ros_namespace(argv=[]))
|
||||
self.assertEquals('/', roslib.names.get_ros_namespace(env={}))
|
||||
self.assertEquals('/', roslib.names.get_ros_namespace(env={}, argv=[]))
|
||||
|
||||
os.environ['ROS_NAMESPACE'] = 'unresolved'
|
||||
self.assertEquals('/unresolved/', roslib.names.get_ros_namespace())
|
||||
self.assertEquals('/unresolved/', roslib.names.get_ros_namespace(env={'ROS_NAMESPACE': 'unresolved'}))
|
||||
sys.argv = ['foo', '__ns:=unresolved_override']
|
||||
self.assertEquals('/unresolved_override/', roslib.names.get_ros_namespace(env={'ROS_NAMESPACE': 'unresolved'}))
|
||||
self.assertEquals('/override2/', roslib.names.get_ros_namespace(env={'ROS_NAMESPACE': 'unresolved'}, argv=['foo', '__ns:=override2']))
|
||||
|
||||
sys.argv = []
|
||||
os.environ['ROS_NAMESPACE'] = '/resolved/'
|
||||
self.assertEquals('/resolved/', roslib.names.get_ros_namespace())
|
||||
self.assertEquals('/resolved/', roslib.names.get_ros_namespace(env={'ROS_NAMESPACE': '/resolved'}))
|
||||
|
||||
del os.environ['ROS_NAMESPACE']
|
||||
|
||||
sys.argv = ['foo', '__ns:=unresolved_ns']
|
||||
self.assertEquals('/unresolved_ns/', roslib.names.get_ros_namespace())
|
||||
self.assertEquals('/unresolved_ns2/', roslib.names.get_ros_namespace(argv=['foo', '__ns:=unresolved_ns2']))
|
||||
sys.argv = ['foo', '__ns:=/resolved_ns/']
|
||||
self.assertEquals('/resolved_ns/', roslib.names.get_ros_namespace())
|
||||
self.assertEquals('/resolved_ns2/', roslib.names.get_ros_namespace(argv=['foo', '__ns:=resolved_ns2']))
|
||||
finally:
|
||||
sys.argv = sysargv
|
||||
|
||||
# restore
|
||||
if rosns:
|
||||
os.environ['ROS_NAMESPACE'] = rosns
|
||||
|
||||
def test_make_global_ns(self):
|
||||
from roslib.names import make_global_ns
|
||||
|
||||
for n in ['~foo']:
|
||||
try:
|
||||
make_global_ns(n)
|
||||
self.fail("make_global_ns should fail on %s"%n)
|
||||
except ValueError: pass
|
||||
|
||||
self.assertEquals('/foo/', make_global_ns('foo'))
|
||||
self.assertEquals('/', make_global_ns(''))
|
||||
self.assertEquals('/foo/', make_global_ns('/foo'))
|
||||
self.assertEquals('/foo/', make_global_ns('/foo/'))
|
||||
self.assertEquals('/foo/bar/', make_global_ns('/foo/bar'))
|
||||
self.assertEquals('/foo/bar/', make_global_ns('/foo/bar/'))
|
||||
|
||||
def test_is_global(self):
|
||||
try:
|
||||
roslib.names.is_global(None)
|
||||
self.fail("is_global should raise exception on invalid param")
|
||||
except: pass
|
||||
tests = ['/', '/global', '/global2']
|
||||
for t in tests:
|
||||
self.assert_(roslib.names.is_global(t))
|
||||
fails = ['', 'not_global', 'not/global']
|
||||
for t in fails:
|
||||
self.failIf(roslib.names.is_global(t))
|
||||
|
||||
def test_is_private(self):
|
||||
try:
|
||||
roslib.names.is_private(None)
|
||||
self.fail("is_private should raise exception on invalid param")
|
||||
except: pass
|
||||
tests = ['~name', '~name/sub']
|
||||
for t in tests:
|
||||
self.assert_(roslib.names.is_private(t))
|
||||
fails = ['', 'not_private', 'not/private', 'not/~private', '/not/~private']
|
||||
for t in fails:
|
||||
self.failIf(roslib.names.is_private(t))
|
||||
|
||||
def test_namespace(self):
|
||||
from roslib.names import namespace
|
||||
try:
|
||||
namespace(1)
|
||||
self.fail("1")
|
||||
except TypeError: pass
|
||||
try:
|
||||
namespace(None)
|
||||
self.fail("None")
|
||||
except ValueError: pass
|
||||
self.assertEquals('/', namespace(''))
|
||||
self.assertEquals('/', namespace('/'))
|
||||
self.assertEquals('/', namespace('/foo'))
|
||||
self.assertEquals('/', namespace('/foo/'))
|
||||
self.assertEquals('/foo/', namespace('/foo/bar'))
|
||||
self.assertEquals('/foo/', namespace('/foo/bar/'))
|
||||
self.assertEquals('/foo/bar/', namespace('/foo/bar/baz'))
|
||||
self.assertEquals('/foo/bar/', namespace('/foo/bar/baz/'))
|
||||
|
||||
# unicode tests
|
||||
self.assertEquals(u'/', namespace(u''))
|
||||
self.assertEquals(u'/', namespace(u'/'))
|
||||
self.assertEquals(u'/foo/bar/', namespace(u'/foo/bar/baz/'))
|
||||
|
||||
def test_nsjoin(self):
|
||||
from roslib.names import ns_join
|
||||
|
||||
# private and global names cannot be joined
|
||||
self.assertEquals('~name', ns_join('/foo', '~name'))
|
||||
self.assertEquals('/name', ns_join('/foo', '/name'))
|
||||
self.assertEquals('~name', ns_join('~', '~name'))
|
||||
self.assertEquals('/name', ns_join('/', '/name'))
|
||||
|
||||
# ns can be '~' or '/'
|
||||
self.assertEquals('~name', ns_join('~', 'name'))
|
||||
self.assertEquals('/name', ns_join('/', 'name'))
|
||||
|
||||
self.assertEquals('/ns/name', ns_join('/ns', 'name'))
|
||||
self.assertEquals('/ns/name', ns_join('/ns/', 'name'))
|
||||
self.assertEquals('/ns/ns2/name', ns_join('/ns', 'ns2/name'))
|
||||
self.assertEquals('/ns/ns2/name', ns_join('/ns/', 'ns2/name'))
|
||||
|
||||
# allow ns to be empty
|
||||
self.assertEquals('name', ns_join('', 'name'))
|
||||
|
||||
|
||||
def test_load_mappings(self):
|
||||
from roslib.names import load_mappings
|
||||
self.assertEquals({}, load_mappings([]))
|
||||
self.assertEquals({}, load_mappings(['foo']))
|
||||
self.assertEquals({}, load_mappings([':=']))
|
||||
self.assertEquals({}, load_mappings([':=:=']))
|
||||
self.assertEquals({}, load_mappings(['f:=']))
|
||||
self.assertEquals({}, load_mappings([':=b']))
|
||||
self.assertEquals({}, load_mappings(['foo:=bar:=baz']))
|
||||
# should ignore node param assignments
|
||||
self.assertEquals({}, load_mappings(['_foo:=bar']))
|
||||
|
||||
self.assertEquals({'foo': 'bar'}, load_mappings(['foo:=bar']))
|
||||
# should allow double-underscore names
|
||||
self.assertEquals({'__foo': 'bar'}, load_mappings(['__foo:=bar']))
|
||||
self.assertEquals({'foo': 'bar'}, load_mappings(['./f', '-x', '--blah', 'foo:=bar']))
|
||||
self.assertEquals({'a': '1', 'b': '2', 'c': '3'}, load_mappings(['c:=3', 'c:=', ':=3', 'a:=1', 'b:=2']))
|
||||
|
||||
def test_resource_name(self):
|
||||
from roslib.names import resource_name
|
||||
self.assertEquals('foo/bar', resource_name('foo', 'bar'))
|
||||
self.assertEquals('bar', resource_name('foo', 'bar', my_pkg='foo'))
|
||||
self.assertEquals('foo/bar', resource_name('foo', 'bar', my_pkg='bar'))
|
||||
self.assertEquals('foo/bar', resource_name('foo', 'bar', my_pkg=''))
|
||||
self.assertEquals('foo/bar', resource_name('foo', 'bar', my_pkg=None))
|
||||
|
||||
def test_resource_name_base(self):
|
||||
from roslib.names import resource_name_base
|
||||
self.assertEquals('', resource_name_base(''))
|
||||
self.assertEquals('bar', resource_name_base('bar'))
|
||||
self.assertEquals('bar', resource_name_base('foo/bar'))
|
||||
self.assertEquals('bar', resource_name_base('/bar'))
|
||||
self.assertEquals('', resource_name_base('foo/'))
|
||||
|
||||
def test_resource_name_package(self):
|
||||
from roslib.names import resource_name_package
|
||||
self.assertEquals(None, resource_name_package(''))
|
||||
self.assertEquals(None, resource_name_package('foo'))
|
||||
self.assertEquals('foo', resource_name_package('foo/'))
|
||||
self.assertEquals('foo', resource_name_package('foo/bar'))
|
||||
|
||||
def test_package_resource_name(self):
|
||||
from roslib.names import package_resource_name
|
||||
self.assertEquals(('', ''), package_resource_name(''))
|
||||
self.assertEquals(('', 'foo'), package_resource_name('foo'))
|
||||
self.assertEquals(('foo', 'bar'), package_resource_name('foo/bar'))
|
||||
self.assertEquals(('foo', ''), package_resource_name('foo/'))
|
||||
try:
|
||||
# only allowed single separator
|
||||
package_resource_name("foo/bar/baz")
|
||||
self.fail("should have raised ValueError")
|
||||
except ValueError:
|
||||
pass
|
||||
|
||||
|
||||
def test_is_legal_resource_name(self):
|
||||
from roslib.names import is_legal_resource_name
|
||||
failures = [None, '', 'hello\n', '\t', 'foo++', 'foo-bar', '#foo',
|
||||
' name', 'name ',
|
||||
'~name', '/name',
|
||||
'1name', 'foo\\']
|
||||
for f in failures:
|
||||
self.failIf(is_legal_resource_name(f), f)
|
||||
tests = ['f', 'f1', 'f_', 'foo', 'foo_bar', 'foo/bar', 'roslib/Log']
|
||||
for t in tests:
|
||||
self.assert_(is_legal_resource_name(t), t)
|
||||
|
||||
def test_is_legal_name(self):
|
||||
from roslib.names import is_legal_name
|
||||
failures = [None,
|
||||
'foo++', 'foo-bar', '#foo',
|
||||
'hello\n', '\t', ' name', 'name ',
|
||||
'f//b',
|
||||
'1name', 'foo\\']
|
||||
for f in failures:
|
||||
self.failIf(is_legal_name(f), f)
|
||||
tests = ['',
|
||||
'f', 'f1', 'f_', 'f/', 'foo', 'foo_bar', 'foo/bar', 'foo/bar/baz',
|
||||
'~f', '~a/b/c',
|
||||
'~/f',
|
||||
'/a/b/c/d', '/']
|
||||
for t in tests:
|
||||
self.assert_(is_legal_name(t), "[%s]"%t)
|
||||
|
||||
def test_is_legal_base_name(self):
|
||||
from roslib.names import is_legal_base_name
|
||||
failures = [None, '', 'hello\n', '\t', 'foo++', 'foo-bar', '#foo',
|
||||
'f/', 'foo/bar', '/', '/a',
|
||||
'f//b',
|
||||
'~f', '~a/b/c',
|
||||
' name', 'name ',
|
||||
'1name', 'foo\\']
|
||||
for f in failures:
|
||||
self.failIf(is_legal_base_name(f), f)
|
||||
tests = ['f', 'f1', 'f_', 'foo', 'foo_bar']
|
||||
for t in tests:
|
||||
self.assert_(is_legal_base_name(t), "[%s]"%t)
|
||||
|
||||
def test_is_legal_resource_base_name(self):
|
||||
from roslib.names import is_legal_resource_base_name
|
||||
failures = [None, '', 'hello\n', '\t', 'foo++', 'foo-bar', '#foo',
|
||||
'f/', 'foo/bar', '/', '/a',
|
||||
'f//b',
|
||||
'~f', '~a/b/c',
|
||||
'~/f',
|
||||
' name', 'name ',
|
||||
'1name', 'foo\\']
|
||||
for f in failures:
|
||||
self.failIf(is_legal_resource_base_name(f), f)
|
||||
tests = ['f', 'f1', 'f_', 'foo', 'foo_bar']
|
||||
for t in tests:
|
||||
self.assert_(is_legal_resource_base_name(t), "[%s]"%t)
|
||||
|
||||
def test_resolve_name(self):
|
||||
from roslib.names import resolve_name
|
||||
# TODO: test with remappings
|
||||
tests = [
|
||||
('', '/', '/'),
|
||||
('', '/node', '/'),
|
||||
('', '/ns1/node', '/ns1/'),
|
||||
|
||||
('foo', '', '/foo'),
|
||||
('foo/', '', '/foo'),
|
||||
('/foo', '', '/foo'),
|
||||
('/foo/', '', '/foo'),
|
||||
('/foo', '/', '/foo'),
|
||||
('/foo/', '/', '/foo'),
|
||||
('/foo', '/bar', '/foo'),
|
||||
('/foo/', '/bar', '/foo'),
|
||||
|
||||
('foo', '/ns1/ns2', '/ns1/foo'),
|
||||
('foo', '/ns1/ns2/', '/ns1/foo'),
|
||||
('foo', '/ns1/ns2/ns3/', '/ns1/ns2/foo'),
|
||||
('foo/', '/ns1/ns2', '/ns1/foo'),
|
||||
('/foo', '/ns1/ns2', '/foo'),
|
||||
('foo/bar', '/ns1/ns2', '/ns1/foo/bar'),
|
||||
('foo//bar', '/ns1/ns2', '/ns1/foo/bar'),
|
||||
('foo/bar', '/ns1/ns2/ns3', '/ns1/ns2/foo/bar'),
|
||||
('foo//bar//', '/ns1/ns2/ns3', '/ns1/ns2/foo/bar'),
|
||||
|
||||
('~foo', '/', '/foo'),
|
||||
('~foo', '/node', '/node/foo'),
|
||||
('~foo', '/ns1/ns2', '/ns1/ns2/foo'),
|
||||
('~foo/', '/ns1/ns2', '/ns1/ns2/foo'),
|
||||
('~foo/bar', '/ns1/ns2', '/ns1/ns2/foo/bar'),
|
||||
|
||||
# #3044
|
||||
('~/foo', '/', '/foo'),
|
||||
('~/foo', '/node', '/node/foo'),
|
||||
('~/foo', '/ns1/ns2', '/ns1/ns2/foo'),
|
||||
('~/foo/', '/ns1/ns2', '/ns1/ns2/foo'),
|
||||
('~/foo/bar', '/ns1/ns2', '/ns1/ns2/foo/bar'),
|
||||
|
||||
]
|
||||
for name, node_name, v in tests:
|
||||
self.assertEquals(v, resolve_name(name, node_name))
|
|
@ -0,0 +1,93 @@
|
|||
# Software License Agreement (BSD License)
|
||||
#
|
||||
# Copyright (c) 2009, Willow Garage, Inc.
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions
|
||||
# are met:
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
# * Redistributions in binary form must reproduce the above
|
||||
# copyright notice, this list of conditions and the following
|
||||
# disclaimer in the documentation and/or other materials provided
|
||||
# with the distribution.
|
||||
# * Neither the name of Willow Garage, Inc. nor the names of its
|
||||
# contributors may be used to endorse or promote products derived
|
||||
# from this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
import os
|
||||
import struct
|
||||
import sys
|
||||
import unittest
|
||||
|
||||
import roslib.packages
|
||||
|
||||
class RoslibPackagesTest(unittest.TestCase):
|
||||
|
||||
def test_list_pkgs_by_path(self):
|
||||
from roslib.packages import list_pkgs_by_path
|
||||
# regression test for bug found where list_pkgs_by_path returns empty package name if path is a package and path is a relpath
|
||||
d = roslib.packages.get_pkg_dir('roslib')
|
||||
|
||||
os.chdir(d)
|
||||
|
||||
self.assertEquals(['roslib'], list_pkgs_by_path('.'))
|
||||
self.assertEquals(set(['bar', 'foo']), set(list_pkgs_by_path(os.path.join('test', 'package_tests'))))
|
||||
self.assertEquals(set(['bar', 'foo']), set(list_pkgs_by_path(os.path.join('test', 'package_tests', 'p1'))))
|
||||
self.assertEquals(['foo'], list_pkgs_by_path(os.path.join('test', 'package_tests', 'p1', 'foo')))
|
||||
|
||||
self.assertEquals([], list_pkgs_by_path(os.path.join('bin')))
|
||||
|
||||
|
||||
def test_find_node(self):
|
||||
import roslib.packages
|
||||
d = roslib.packages.get_pkg_dir('roslib')
|
||||
p = os.path.join(d, 'test', 'fake_node.py')
|
||||
self.assertEquals(p, roslib.packages.find_node('roslib', 'fake_node.py'))
|
||||
|
||||
self.assertEquals(None, roslib.packages.find_node('roslib', 'not_a_node'))
|
||||
|
||||
def test_get_pkg_dir(self):
|
||||
import roslib.packages
|
||||
import roslib.rospack
|
||||
path = roslib.rospack.rospackexec(['find', 'roslib'])
|
||||
self.assertEquals(path, roslib.packages.get_pkg_dir('roslib'))
|
||||
try:
|
||||
self.assertEquals(path, roslib.packages.get_pkg_dir('fake_roslib'))
|
||||
self.fail("should have raised")
|
||||
except roslib.packages.InvalidROSPkgException: pass
|
||||
|
||||
def test_get_dir_pkg(self):
|
||||
import roslib.packages
|
||||
path = get_roslib_path()
|
||||
|
||||
res = roslib.packages.get_dir_pkg(path)
|
||||
res = (os.path.realpath(res[0]), res[1])
|
||||
self.assertEquals((path, 'roslib'), res)
|
||||
res = roslib.packages.get_dir_pkg(os.path.join(path, 'test'))
|
||||
res = (os.path.realpath(res[0]), res[1])
|
||||
self.assertEquals((path, 'roslib'), res)
|
||||
|
||||
# must fail on parent of roslib
|
||||
self.assertEquals((None, None), roslib.packages.get_dir_pkg(os.path.dirname(path)))
|
||||
|
||||
def get_roslib_path():
|
||||
return os.path.abspath(os.path.join(get_test_path(), '..'))
|
||||
|
||||
def get_test_path():
|
||||
return os.path.abspath(os.path.dirname(__file__))
|
|
@ -0,0 +1,55 @@
|
|||
# Software License Agreement (BSD License)
|
||||
#
|
||||
# Copyright (c) 2009, Willow Garage, Inc.
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions
|
||||
# are met:
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
# * Redistributions in binary form must reproduce the above
|
||||
# copyright notice, this list of conditions and the following
|
||||
# disclaimer in the documentation and/or other materials provided
|
||||
# with the distribution.
|
||||
# * Neither the name of Willow Garage, Inc. nor the names of its
|
||||
# contributors may be used to endorse or promote products derived
|
||||
# from this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
import os
|
||||
import sys
|
||||
import unittest
|
||||
|
||||
import roslib.names
|
||||
|
||||
class ParamsTest(unittest.TestCase):
|
||||
|
||||
def test_load_param_mappings(self):
|
||||
from roslib.params import load_command_line_node_params
|
||||
self.assertEquals({}, load_command_line_node_params([]))
|
||||
self.assertEquals({}, load_command_line_node_params(['foo']))
|
||||
self.assertEquals({}, load_command_line_node_params(['_foo']))
|
||||
self.assertEquals({}, load_command_line_node_params([':=']))
|
||||
self.assertEquals({}, load_command_line_node_params([':=:=']))
|
||||
self.assertEquals({}, load_command_line_node_params(['_f:=']))
|
||||
self.assertEquals({}, load_command_line_node_params([':=b']))
|
||||
self.assertEquals({}, load_command_line_node_params(['_foo:=_bar:=baz']))
|
||||
|
||||
self.assertEquals({'foo': 'bar'}, load_command_line_node_params(['_foo:=bar']))
|
||||
self.assertEquals({'foo': 'bar'}, load_command_line_node_params(['./f', '-x', '--blah', '_foo:=bar']))
|
||||
self.assertEquals({'a': 'one', 'b': 2, 'c': 3.0, 'd':[1,2,3,4]}, load_command_line_node_params(['_c:=3.0', '_c:=', ':=3', '_a:=one', '_b:=2', '_d:=[1,2,3,4]']))
|
||||
|
|
@ -0,0 +1,150 @@
|
|||
# Software License Agreement (BSD License)
|
||||
#
|
||||
# Copyright (c) 2009, Willow Garage, Inc.
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions
|
||||
# are met:
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
# * Redistributions in binary form must reproduce the above
|
||||
# copyright notice, this list of conditions and the following
|
||||
# disclaimer in the documentation and/or other materials provided
|
||||
# with the distribution.
|
||||
# * Neither the name of Willow Garage, Inc. nor the names of its
|
||||
# contributors may be used to endorse or promote products derived
|
||||
# from this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
import os
|
||||
import sys
|
||||
import unittest
|
||||
|
||||
import roslib.rosenv
|
||||
|
||||
class EnvTest(unittest.TestCase):
|
||||
|
||||
def test_get_ros_root(self):
|
||||
from roslib.rosenv import get_ros_root
|
||||
self.assertEquals(None, get_ros_root(required=False, env={}))
|
||||
self.assertEquals(None, get_ros_root(False, {}))
|
||||
try:
|
||||
get_ros_root(required=True, env={})
|
||||
self.fail("get_ros_root should have failed")
|
||||
except: pass
|
||||
|
||||
env = {'ROS_ROOT': '/fake/path'}
|
||||
self.assertEquals('/fake/path', get_ros_root(required=False, env=env))
|
||||
try:
|
||||
get_ros_root(required=True, env=env)
|
||||
self.fail("get_ros_root should have failed")
|
||||
except: pass
|
||||
|
||||
real_ros_root = get_ros_root(required=True)
|
||||
|
||||
# make sure that ros root is a directory
|
||||
p = os.path.join(real_ros_root, 'Makefile')
|
||||
env = {'ROS_ROOT': p}
|
||||
self.assertEquals(p, get_ros_root(required=False, env=env))
|
||||
try:
|
||||
get_ros_root(required=True, env=env)
|
||||
self.fail("get_ros_root should have failed")
|
||||
except: pass
|
||||
|
||||
def test_get_ros_package_path(self):
|
||||
from roslib.rosenv import get_ros_package_path
|
||||
self.assertEquals(None, get_ros_package_path(required=False, env={}))
|
||||
self.assertEquals(None, get_ros_package_path(False, {}))
|
||||
try:
|
||||
get_ros_package_path(required=True, env={})
|
||||
self.fail("get_ros_package_path should have raised")
|
||||
except: pass
|
||||
env = {'ROS_PACKAGE_PATH': ':'}
|
||||
self.assertEquals(':', get_ros_package_path(True, env=env))
|
||||
self.assertEquals(':', get_ros_package_path(False, env=env))
|
||||
|
||||
# trip-wire tests. Cannot guarantee that ROS_PACKAGE_PATH is set
|
||||
# to valid value on test machine, just make sure logic doesn't crash
|
||||
self.assertEquals(os.environ.get('ROS_PACKAGE_PATH', None), get_ros_package_path(required=False))
|
||||
|
||||
def test_get_ros_master_uri(self):
|
||||
from roslib.rosenv import get_master_uri
|
||||
self.assertEquals(None, get_master_uri(required=False, env={}))
|
||||
self.assertEquals(None, get_master_uri(False, {}))
|
||||
try:
|
||||
get_master_uri(required=True, env={})
|
||||
self.fail("get_ros_package_path should have raised")
|
||||
except: pass
|
||||
env = {'ROS_MASTER_URI': 'http://localhost:1234'}
|
||||
self.assertEquals('http://localhost:1234', get_master_uri(True, env=env))
|
||||
self.assertEquals('http://localhost:1234', get_master_uri(False, env=env))
|
||||
|
||||
argv = ['__master:=http://localhost:5678']
|
||||
self.assertEquals('http://localhost:5678', get_master_uri(False, env=env, argv=argv))
|
||||
|
||||
try:
|
||||
argv = ['__master:=http://localhost:5678:=http://localhost:1234']
|
||||
get_master_uri(required=False, env=env, argv=argv)
|
||||
self.fail("should have thrown")
|
||||
except roslib.rosenv.ROSEnvException: pass
|
||||
|
||||
try:
|
||||
argv = ['__master:=']
|
||||
get_master_uri(False, env=env, argv=argv)
|
||||
self.fail("should have thrown")
|
||||
except roslib.rosenv.ROSEnvException: pass
|
||||
|
||||
# make sure test works with os.environ
|
||||
self.assertEquals(os.environ.get('ROS_MASTER_URI', None), get_master_uri(required=False))
|
||||
|
||||
def test_get_test_results_dir(self):
|
||||
from roslib.rosenv import get_ros_root, get_test_results_dir
|
||||
import tempfile, os
|
||||
base = tempfile.gettempdir()
|
||||
ros_test_results_dir = os.path.join(base, 'ros_test_results_dir')
|
||||
ros_home_dir = os.path.join(base, 'ros_home_dir')
|
||||
home_dir = os.path.expanduser('~')
|
||||
|
||||
# ROS_TEST_RESULTS_DIR has precedence
|
||||
env = {'ROS_ROOT': get_ros_root(), 'ROS_TEST_RESULTS_DIR': ros_test_results_dir, 'ROS_HOME': ros_home_dir }
|
||||
self.assertEquals(ros_test_results_dir, get_test_results_dir(env=env))
|
||||
|
||||
env = {'ROS_ROOT': get_ros_root(), 'ROS_HOME': ros_home_dir }
|
||||
self.assertEquals(os.path.join(ros_home_dir, 'test_results'), get_test_results_dir(env=env))
|
||||
|
||||
env = {'ROS_ROOT': get_ros_root()}
|
||||
self.assertEquals(os.path.join(home_dir, '.ros', 'test_results'), get_test_results_dir(env=env))
|
||||
|
||||
# test default assignment of env. Don't both checking return value as we would duplicate get_test_results_dir
|
||||
self.assert_(get_test_results_dir() is not None)
|
||||
|
||||
def test_get_ros_home(self):
|
||||
from roslib.rosenv import get_ros_root, get_ros_home
|
||||
import tempfile, os
|
||||
base = tempfile.gettempdir()
|
||||
ros_home_dir = os.path.join(base, 'ros_home_dir')
|
||||
home_dir = os.path.expanduser('~')
|
||||
|
||||
# ROS_HOME has precedence
|
||||
env = {'ROS_ROOT': get_ros_root(), 'ROS_HOME': ros_home_dir }
|
||||
self.assertEquals(ros_home_dir, get_ros_home(env=env))
|
||||
|
||||
env = {'ROS_ROOT': get_ros_root()}
|
||||
self.assertEquals(os.path.join(home_dir, '.ros'), get_ros_home(env=env))
|
||||
|
||||
# test default assignment of env. Don't both checking return value
|
||||
self.assert_(get_ros_home() is not None)
|
|
@ -0,0 +1,123 @@
|
|||
# Software License Agreement (BSD License)
|
||||
#
|
||||
# Copyright (c) 2009, Willow Garage, Inc.
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions
|
||||
# are met:
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
# * Redistributions in binary form must reproduce the above
|
||||
# copyright notice, this list of conditions and the following
|
||||
# disclaimer in the documentation and/or other materials provided
|
||||
# with the distribution.
|
||||
# * Neither the name of Willow Garage, Inc. nor the names of its
|
||||
# contributors may be used to endorse or promote products derived
|
||||
# from this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
import os
|
||||
import sys
|
||||
import unittest
|
||||
|
||||
import roslib
|
||||
|
||||
def get_test_path():
|
||||
return os.path.abspath(os.path.dirname(__file__))
|
||||
|
||||
class RoslibStackManifestTest(unittest.TestCase):
|
||||
|
||||
def _subtest_parse_stack_example1(self, m):
|
||||
from roslib.manifestlib import _Manifest
|
||||
self.assert_(isinstance(m, _Manifest))
|
||||
self.assertEquals('stack', m._type)
|
||||
self.assertEquals("a brief description", m.brief)
|
||||
self.assertEquals("Line 1\nLine 2", m.description.strip())
|
||||
self.assertEquals("The authors\ngo here", m.author.strip())
|
||||
self.assertEquals("Public Domain\nwith other stuff", m.license.strip())
|
||||
self.assertEquals("http://ros.org/stack/", m.url)
|
||||
self.assertEquals("http://www.willowgarage.com/files/willowgarage/robot10.jpg", m.logo)
|
||||
dpkgs = [d.stack for d in m.depends]
|
||||
self.assertEquals(set(['stackname', 'common']), set(dpkgs))
|
||||
self.assertEquals([], m.rosdeps)
|
||||
self.assertEquals([], m.exports)
|
||||
|
||||
def _subtest_parse_stack_version(self, m):
|
||||
self.assertEquals("1.2.3", m.version)
|
||||
|
||||
def test_parse_example1_file(self):
|
||||
from roslib.stack_manifest import parse_file, StackManifest
|
||||
|
||||
p = os.path.join(get_test_path(), 'manifest_tests', 'stack_example1.xml')
|
||||
self._subtest_parse_stack_example1(parse_file(p))
|
||||
|
||||
p = os.path.join(get_test_path(), 'manifest_tests', 'stack_version.xml')
|
||||
self._subtest_parse_stack_version(parse_file(p))
|
||||
|
||||
def test_parse_example1_string(self):
|
||||
from roslib.manifestlib import parse, _Manifest
|
||||
self._subtest_parse_stack_example1(parse(_Manifest('stack'), STACK_EXAMPLE1))
|
||||
|
||||
def test_StackManifest(self):
|
||||
from roslib.stack_manifest import StackManifest
|
||||
m = StackManifest()
|
||||
self.assertEquals('stack', m._type)
|
||||
|
||||
def test_StackManifest_str(self):
|
||||
# just make sure it doesn't crash
|
||||
from roslib.stack_manifest import parse
|
||||
str(parse(STACK_EXAMPLE1))
|
||||
|
||||
def test_StackManifest_xml(self):
|
||||
from roslib.stack_manifest import parse, StackManifest
|
||||
m = parse(STACK_EXAMPLE1)
|
||||
self._subtest_parse_stack_example1(m)
|
||||
# verify roundtrip
|
||||
m2 = parse(m.xml())
|
||||
self._subtest_parse_stack_example1(m2)
|
||||
|
||||
# bad file examples should be more like the roslaunch tests where there is just 1 thing wrong
|
||||
STACK_EXAMPLE1 = """<stack>
|
||||
<description brief="a brief description">Line 1
|
||||
Line 2
|
||||
</description>
|
||||
<author>The authors
|
||||
go here</author>
|
||||
<license>Public Domain
|
||||
with other stuff</license>
|
||||
<url>http://ros.org/stack/</url>
|
||||
<logo>http://www.willowgarage.com/files/willowgarage/robot10.jpg</logo>
|
||||
<depend stack="stackname" />
|
||||
<depend stack="common"/>
|
||||
</stack>"""
|
||||
|
||||
STACK_INVALID1 = """<stack>
|
||||
<description brief="a brief description">Line 1</description>
|
||||
<author>The authors</author>
|
||||
<license>Public Domain</license>
|
||||
<rosdep name="python" />
|
||||
</stack>"""
|
||||
|
||||
STACK_INVALID2 = """<stack>
|
||||
<description brief="a brief description">Line 1</description>
|
||||
<author>The authors</author>
|
||||
<license>Public Domain</license>
|
||||
<export>
|
||||
<cpp cflags="-I${prefix}/include" lflags="-L${prefix}/lib -lros"/>
|
||||
<cpp os="osx" cflags="-I${prefix}/include" lflags="-L${prefix}/lib -lrosthread -framework CoreServices"/>
|
||||
</export>
|
||||
</stack>"""
|
|
@ -0,0 +1,243 @@
|
|||
# Software License Agreement (BSD License)
|
||||
#
|
||||
# Copyright (c) 2009, Willow Garage, Inc.
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions
|
||||
# are met:
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
# * Redistributions in binary form must reproduce the above
|
||||
# copyright notice, this list of conditions and the following
|
||||
# disclaimer in the documentation and/or other materials provided
|
||||
# with the distribution.
|
||||
# * Neither the name of Willow Garage, Inc. nor the names of its
|
||||
# contributors may be used to endorse or promote products derived
|
||||
# from this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
import os
|
||||
import sys
|
||||
import unittest
|
||||
|
||||
import roslib
|
||||
import rospkg
|
||||
|
||||
class RoslibStacksTest(unittest.TestCase):
|
||||
|
||||
def test_stack_of(self):
|
||||
import roslib.packages
|
||||
from roslib.stacks import stack_of
|
||||
self.assertEquals('ros', stack_of('roslib'))
|
||||
# due to caching, test twice
|
||||
self.assertEquals('ros', stack_of('roslib'))
|
||||
try:
|
||||
stack_of('fake_roslib')
|
||||
self.fail("should have failed")
|
||||
except roslib.packages.InvalidROSPkgException:
|
||||
pass
|
||||
|
||||
# test unary
|
||||
test_dir = os.path.join(roslib.packages.get_pkg_dir('roslib'), 'test', 'stack_tests_unary')
|
||||
env = os.environ.copy()
|
||||
env['ROS_PACKAGE_PATH'] = test_dir
|
||||
for s in ['foo', 'bar']:
|
||||
self.assertEquals(s, stack_of(s, env=env))
|
||||
|
||||
def test_list_stacks(self):
|
||||
from roslib.stacks import list_stacks
|
||||
l = list_stacks()
|
||||
self.assert_('ros' in l)
|
||||
|
||||
# make sure it is equivalent to rosstack list
|
||||
from roslib.rospack import rosstackexec
|
||||
l2 = [x for x in rosstackexec(['list']).split('\n') if x]
|
||||
l2 = [x.split()[0] for x in l2]
|
||||
self.assertEquals(set(l), set(l2), set(l) ^ set(l2))
|
||||
|
||||
# test with env
|
||||
test_dir = os.path.join(roslib.packages.get_pkg_dir('roslib'), 'test', 'stack_tests', 's1')
|
||||
env = os.environ.copy()
|
||||
env['ROS_PACKAGE_PATH'] = test_dir
|
||||
self.assertEquals(set(['ros', 'foo', 'bar']), set(list_stacks(env=env)))
|
||||
|
||||
|
||||
def test_list_stacks_by_path(self):
|
||||
from roslib.stacks import list_stacks_by_path
|
||||
|
||||
# test with the ros stack
|
||||
rr = rospkg.get_ros_root()
|
||||
self.assertEquals(['ros'], list_stacks_by_path(rr))
|
||||
stacks = []
|
||||
self.assertEquals(['ros'], list_stacks_by_path(rr, stacks))
|
||||
self.assertEquals(['ros'], stacks)
|
||||
self.assertEquals(['ros'], list_stacks_by_path(rr, stacks))
|
||||
|
||||
stacks.extend(['fake_stack', 'fake_stack2'])
|
||||
self.assertEquals(['ros', 'fake_stack', 'fake_stack2'], list_stacks_by_path(rr, stacks))
|
||||
|
||||
cache = {}
|
||||
self.assertEquals(['ros'], list_stacks_by_path(rr, cache=cache))
|
||||
self.assertEquals({'ros': rr}, cache)
|
||||
|
||||
# test with synthetic stacks
|
||||
test_dir = os.path.join(roslib.packages.get_pkg_dir('roslib'), 'test', 'stack_tests')
|
||||
self.assertEquals(set(['bar', 'foo']), set(list_stacks_by_path(test_dir)))
|
||||
|
||||
test_dir = os.path.join(roslib.packages.get_pkg_dir('roslib'), 'test', 'stack_tests', 's1')
|
||||
self.assertEquals(set(['bar', 'foo']), set(list_stacks_by_path(test_dir)))
|
||||
|
||||
test_dir = os.path.join(roslib.packages.get_pkg_dir('roslib'), 'test', 'stack_tests', 's1', 'bar')
|
||||
self.assertEquals(['bar'], list_stacks_by_path(test_dir))
|
||||
|
||||
# test symlink following
|
||||
|
||||
test_dir = os.path.join(roslib.packages.get_pkg_dir('roslib'), 'test', 'stack_tests2')
|
||||
self.assertEquals(set(['foo', 'bar']), set(list_stacks_by_path(test_dir)))
|
||||
|
||||
def test_list_stacks_by_path_unary(self):
|
||||
from roslib.stacks import list_stacks_by_path
|
||||
# test with synthetic stacks
|
||||
test_dir = os.path.join(roslib.packages.get_pkg_dir('roslib'), 'test', 'stack_tests_unary')
|
||||
self.assertEquals(set(['bar', 'foo', 'baz']), set(list_stacks_by_path(test_dir)))
|
||||
|
||||
def test_get_stack_dir_unary(self):
|
||||
# now manipulate the environment to test precedence
|
||||
# - save original RPP as we popen rosstack in other tests
|
||||
d = roslib.packages.get_pkg_dir('roslib')
|
||||
d = os.path.join(d, 'test', 'stack_tests_unary')
|
||||
s1_d = os.path.join(d, 's1')
|
||||
rpp = rospkg.get_ros_package_path()
|
||||
try:
|
||||
paths = [d]
|
||||
os.environ[rospkg.environment.ROS_PACKAGE_PATH] = os.pathsep.join(paths)
|
||||
self.assertEquals(os.path.join(s1_d, 'foo'), roslib.stacks.get_stack_dir('foo'))
|
||||
self.assertEquals(os.path.join(s1_d, 'bar'), roslib.stacks.get_stack_dir('bar'))
|
||||
self.assertEquals(os.path.join(s1_d, 'baz'), roslib.stacks.get_stack_dir('baz'))
|
||||
finally:
|
||||
#restore rpp
|
||||
if rpp is not None:
|
||||
os.environ[rospkg.environment.ROS_PACKAGE_PATH] = rpp
|
||||
else:
|
||||
del os.environ[rospkg.environment.ROS_PACKAGE_PATH]
|
||||
|
||||
def test_get_stack_dir(self):
|
||||
import roslib.packages
|
||||
from roslib.stacks import get_stack_dir, InvalidROSStackException, list_stacks
|
||||
self.assertEquals(rospkg.get_ros_root(), get_stack_dir('ros'))
|
||||
try:
|
||||
get_stack_dir('non_existent')
|
||||
self.fail("should have raised")
|
||||
except roslib.stacks.InvalidROSStackException:
|
||||
pass
|
||||
|
||||
# now manipulate the environment to test precedence
|
||||
# - save original RPP as we popen rosstack in other tests
|
||||
rpp = os.environ.get(rospkg.environment.ROS_PACKAGE_PATH, None)
|
||||
try:
|
||||
d = roslib.packages.get_pkg_dir('roslib')
|
||||
d = os.path.join(d, 'test', 'stack_tests')
|
||||
|
||||
# - s1/s2/s3
|
||||
print "s1/s2/s3"
|
||||
paths = [os.path.join(d, p) for p in ['s1', 's2', 's3']]
|
||||
os.environ[rospkg.environment.ROS_PACKAGE_PATH] = os.pathsep.join(paths)
|
||||
# - run multiple times to test caching
|
||||
for i in xrange(2):
|
||||
stacks = roslib.stacks.list_stacks()
|
||||
self.assert_('foo' in stacks)
|
||||
self.assert_('bar' in stacks)
|
||||
|
||||
foo_p = os.path.join(d, 's1', 'foo')
|
||||
bar_p = os.path.join(d, 's1', 'bar')
|
||||
self.assertEquals(foo_p, roslib.stacks.get_stack_dir('foo'))
|
||||
self.assertEquals(bar_p, roslib.stacks.get_stack_dir('bar'))
|
||||
|
||||
# - s2/s3/s1
|
||||
print "s2/s3/s1"
|
||||
|
||||
paths = [os.path.join(d, p) for p in ['s2', 's3', 's1']]
|
||||
os.environ[rospkg.environment.ROS_PACKAGE_PATH] = os.pathsep.join(paths)
|
||||
stacks = roslib.stacks.list_stacks()
|
||||
self.assert_('foo' in stacks)
|
||||
self.assert_('bar' in stacks)
|
||||
|
||||
foo_p = os.path.join(d, 's2', 'foo')
|
||||
bar_p = os.path.join(d, 's1', 'bar')
|
||||
self.assertEquals(foo_p, roslib.stacks.get_stack_dir('foo'))
|
||||
self.assertEquals(bar_p, roslib.stacks.get_stack_dir('bar'))
|
||||
finally:
|
||||
#restore rpp
|
||||
if rpp is not None:
|
||||
os.environ[rospkg.environment.ROS_PACKAGE_PATH] = rpp
|
||||
else:
|
||||
del os.environ[rospkg.environment.ROS_PACKAGE_PATH]
|
||||
|
||||
def test_expand_to_packages_unary(self):
|
||||
# test unary
|
||||
test_dir = os.path.join(roslib.packages.get_pkg_dir('roslib'), 'test', 'stack_tests_unary')
|
||||
|
||||
env = os.environ.copy()
|
||||
env[rospkg.environment.ROS_PACKAGE_PATH] = test_dir
|
||||
|
||||
from roslib.stacks import expand_to_packages
|
||||
self.assertEquals((['foo'], []), expand_to_packages(['foo'], env=env))
|
||||
self.assertEquals((['foo', 'bar'], []), expand_to_packages(['foo', 'bar'], env=env))
|
||||
|
||||
def test_expand_to_packages(self):
|
||||
from roslib.stacks import expand_to_packages
|
||||
try:
|
||||
# it's possible to accidentally pass in a sequence type
|
||||
# like a string and get weird results, so check that we
|
||||
# don't
|
||||
self.assertEquals(([], []), expand_to_packages('ros'))
|
||||
self.fail("expand_to_packages should only take in a list of strings")
|
||||
except ValueError: pass
|
||||
|
||||
self.assertEquals(([], []), expand_to_packages([]))
|
||||
self.assertEquals((['rosmake', 'roslib', 'roslib'], []), expand_to_packages(['rosmake', 'roslib', 'roslib']))
|
||||
self.assertEquals(([], ['bogus_one', 'bogus_two']), expand_to_packages(['bogus_one', 'bogus_two']))
|
||||
|
||||
self.assertEquals(([], ['bogus_one', 'bogus_two']), expand_to_packages(['bogus_one', 'bogus_two']))
|
||||
|
||||
# TODO: setup directory tree so that this can be more precisely calculated
|
||||
valid, invalid = expand_to_packages(['ros', 'bogus_one'])
|
||||
self.assertEquals(['bogus_one'], invalid)
|
||||
check = ['rosbuild', 'rosunit', 'roslib']
|
||||
print valid
|
||||
for c in check:
|
||||
self.assert_(c in valid, "expected [%s] to be in ros expansion"%c)
|
||||
|
||||
def test_get_stack_version(self):
|
||||
from roslib.stacks import get_stack_version
|
||||
|
||||
test_dir = os.path.join(get_test_path(), 'stack_tests', 's1')
|
||||
env = os.environ.copy()
|
||||
env[rospkg.environment.ROS_PACKAGE_PATH] = test_dir
|
||||
|
||||
# REP 109: stack.xml has precedence over CMakeLists.txt, version is whitespace stripped
|
||||
self.assertEquals('1.6.0-manifest', roslib.stacks.get_stack_version('foo', env=env))
|
||||
# REP 109: test fallback to CMakeLists.txt version
|
||||
self.assertEquals('1.5.0-cmake', roslib.stacks.get_stack_version('bar', env=env))
|
||||
|
||||
if 0:
|
||||
test_dir = os.path.join(roslib.packages.get_pkg_dir('roslib'), 'test', 'stack_tests_unary')
|
||||
env = os.environ.copy()
|
||||
env[rospkg.environment.ROS_PACKAGE_PATH] = test_dir
|
||||
|
||||
def get_test_path():
|
||||
return os.path.abspath(os.path.dirname(__file__))
|
|
@ -0,0 +1,163 @@
|
|||
# Software License Agreement (BSD License)
|
||||
#
|
||||
# Copyright (c) 2009, Willow Garage, Inc.
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions
|
||||
# are met:
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
# * Redistributions in binary form must reproduce the above
|
||||
# copyright notice, this list of conditions and the following
|
||||
# disclaimer in the documentation and/or other materials provided
|
||||
# with the distribution.
|
||||
# * Neither the name of Willow Garage, Inc. nor the names of its
|
||||
# contributors may be used to endorse or promote products derived
|
||||
# from this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
import os
|
||||
import sys
|
||||
import unittest
|
||||
|
||||
class SubArgsTest(unittest.TestCase):
|
||||
|
||||
def test__arg(self):
|
||||
import random
|
||||
from roslib.substitution_args import _arg, ArgException, SubstitutionException
|
||||
|
||||
ctx = { 'arg': {
|
||||
'foo': '12345',
|
||||
'bar': 'hello world',
|
||||
'baz': 'sim',
|
||||
'empty': '',
|
||||
}
|
||||
}
|
||||
|
||||
# test invalid
|
||||
try:
|
||||
_arg('$(arg)', 'arg', [], ctx)
|
||||
self.fail("should have thrown")
|
||||
except SubstitutionException:
|
||||
pass
|
||||
|
||||
# test normal
|
||||
tests = [
|
||||
('12345', ('$(arg foo)', 'arg foo', ['foo'], ctx)),
|
||||
('', ('$(arg empty)', 'arg empty', ['empty'], ctx)),
|
||||
('sim', ('$(arg baz)', 'arg baz', ['baz'], ctx)),
|
||||
|
||||
# test with other args present, should only resolve match
|
||||
('1234512345', ('$(arg foo)$(arg foo)', 'arg foo', ['foo'], ctx)),
|
||||
('12345$(arg baz)', ('$(arg foo)$(arg baz)', 'arg foo', ['foo'], ctx)),
|
||||
('$(arg foo)sim', ('$(arg foo)$(arg baz)', 'arg baz', ['baz'], ctx)),
|
||||
|
||||
# test double-resolve safe
|
||||
('12345', ('12345', 'arg foo', ['foo'], ctx)),
|
||||
]
|
||||
|
||||
for result, test in tests:
|
||||
resolved, a, args, context = test
|
||||
self.assertEquals(result, _arg(resolved, a, args, context))
|
||||
|
||||
# - test that all fail if ctx is not set
|
||||
for result, test in tests:
|
||||
resolved, a, args, context = test
|
||||
try:
|
||||
_arg(resolved, a, args, {})
|
||||
self.fail("should have thrown")
|
||||
except ArgException, e:
|
||||
self.assertEquals(args[0], str(e))
|
||||
try:
|
||||
_arg(resolved, a, args, {'arg': {}})
|
||||
self.fail("should have thrown")
|
||||
except ArgException, e:
|
||||
self.assertEquals(args[0], str(e))
|
||||
|
||||
|
||||
def test_resolve_args(self):
|
||||
from roslib.substitution_args import resolve_args, SubstitutionException
|
||||
from roslib.packages import get_pkg_dir
|
||||
roslib_dir = get_pkg_dir('roslib', required=True)
|
||||
|
||||
anon_context = {'foo': 'bar'}
|
||||
arg_context = {'fuga': 'hoge', 'car': 'cdr'}
|
||||
context = {'anon': anon_context, 'arg': arg_context }
|
||||
|
||||
tests = [
|
||||
('$(find roslib)', roslib_dir),
|
||||
('hello$(find roslib)', 'hello'+roslib_dir),
|
||||
('$(find roslib )', roslib_dir),
|
||||
('$$(find roslib )', '$'+roslib_dir),
|
||||
('$( find roslib )', roslib_dir),
|
||||
('$(find roslib )', roslib_dir),
|
||||
('$(find roslib)$(find roslib)', roslib_dir+roslib_dir),
|
||||
('$(find roslib)/foo/bar.xml', roslib_dir+os.sep+'foo'+os.sep+'bar.xml'),
|
||||
(r'$(find roslib)\foo\bar.xml $(find roslib)\bar.xml', roslib_dir+os.sep+'foo'+os.sep+'bar.xml '+roslib_dir+os.sep+'bar.xml'),
|
||||
('$(find roslib)\\foo\\bar.xml more/stuff\\here', roslib_dir+os.sep+'foo'+os.sep+'bar.xml more/stuff\\here'),
|
||||
('$(env ROS_ROOT)', os.environ['ROS_ROOT']),
|
||||
('$(env ROS_ROOT)', os.environ['ROS_ROOT']),
|
||||
('$(env ROS_ROOT )', os.environ['ROS_ROOT']),
|
||||
('$(optenv ROS_ROOT)', os.environ['ROS_ROOT']),
|
||||
('$(optenv ROS_ROOT)$(optenv ROS_ROOT)', os.environ['ROS_ROOT']+os.environ['ROS_ROOT']),
|
||||
('$(optenv ROS_ROOT alternate text)', os.environ['ROS_ROOT']),
|
||||
('$(optenv NOT_ROS_ROOT)', ''),
|
||||
('$(optenv NOT_ROS_ROOT)more stuff', 'more stuff'),
|
||||
('$(optenv NOT_ROS_ROOT alternate)', 'alternate'),
|
||||
('$(optenv NOT_ROS_ROOT alternate text)', 'alternate text'),
|
||||
|
||||
# #1776
|
||||
('$(anon foo)', 'bar'),
|
||||
('$(anon foo)/baz', 'bar/baz'),
|
||||
('$(anon foo)/baz/$(anon foo)', 'bar/baz/bar'),
|
||||
|
||||
# arg
|
||||
('$(arg fuga)', 'hoge'),
|
||||
('$(arg fuga)$(arg fuga)', 'hogehoge'),
|
||||
('$(arg car)$(arg fuga)', 'cdrhoge'),
|
||||
('$(arg fuga)hoge', 'hogehoge'),
|
||||
]
|
||||
for arg, val in tests:
|
||||
self.assertEquals(val, resolve_args(arg, context=context))
|
||||
|
||||
# more #1776
|
||||
r = resolve_args('$(anon foo)/bar')
|
||||
self.assert_('/bar' in r)
|
||||
self.failIf('$(anon foo)' in r)
|
||||
|
||||
|
||||
# test against strings that should not match
|
||||
noop_tests = [
|
||||
'$(find roslib', '$find roslib', '', ' ', 'noop', 'find roslib', 'env ROS_ROOT', '$$', ')', '(', '()',
|
||||
None,
|
||||
]
|
||||
for t in noop_tests:
|
||||
self.assertEquals(t, resolve_args(t))
|
||||
failures = [
|
||||
'$((find roslib))', '$(find $roslib)',
|
||||
'$(find)', '$(find roslib roslib)', '$(export roslib)',
|
||||
'$(env)', '$(env ROS_ROOT alternate)',
|
||||
'$(env NOT_SET)',
|
||||
'$(optenv)',
|
||||
'$(anon)',
|
||||
'$(anon foo bar)',
|
||||
]
|
||||
for f in failures:
|
||||
try:
|
||||
resolve_args(f)
|
||||
self.fail("resolve_args(%s) should have failed"%f)
|
||||
except SubstitutionException: pass
|
|
@ -0,0 +1,142 @@
|
|||
/*
|
||||
* Copyright (c) 2008, Willow Garage, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of Willow Garage, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/* Author: Brian Gerkey */
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <boost/thread.hpp>
|
||||
#include <gtest/gtest.h>
|
||||
#include "ros/package.h"
|
||||
|
||||
void string_split(const std::string &s, std::vector<std::string> &t, const std::string &d)
|
||||
{ t.clear();
|
||||
size_t start = 0, end;
|
||||
while ((end = s.find_first_of(d, start)) != std::string::npos)
|
||||
{
|
||||
if((end-start) > 0)
|
||||
t.push_back(s.substr(start, end-start));
|
||||
start = end + 1;
|
||||
}
|
||||
if(start < s.size())
|
||||
t.push_back(s.substr(start));
|
||||
}
|
||||
|
||||
char g_rr_buf[1024];
|
||||
void set_env_vars(void)
|
||||
{
|
||||
// Point ROS_PACKAGE_PATH at the roslib directory, and point
|
||||
// ROS_ROOT into an empty directory.
|
||||
getcwd(g_rr_buf, sizeof(g_rr_buf));
|
||||
setenv("ROS_PACKAGE_PATH", g_rr_buf, 1);
|
||||
strncpy(g_rr_buf+strlen(g_rr_buf), "/tmp.XXXXXX", sizeof(g_rr_buf)-strlen(g_rr_buf)-1);
|
||||
g_rr_buf[sizeof(g_rr_buf)-1] = '\0';
|
||||
mkdtemp(g_rr_buf);
|
||||
setenv("ROS_ROOT", g_rr_buf, 1);
|
||||
}
|
||||
void cleanup_env_vars(void)
|
||||
{
|
||||
// Remove the empty directory that we created in set_env_vars().
|
||||
rmdir(g_rr_buf);
|
||||
memset(g_rr_buf, 0, sizeof(g_rr_buf));
|
||||
}
|
||||
|
||||
TEST(roslib, commandListNames)
|
||||
{
|
||||
set_env_vars();
|
||||
|
||||
std::string output = ros::package::command("list-names");
|
||||
std::vector<std::string> output_list;
|
||||
string_split(output, output_list, "\n");
|
||||
ASSERT_EQ((int)output_list.size(), 1);
|
||||
ASSERT_STREQ(output_list[0].c_str(), "roslib");
|
||||
|
||||
cleanup_env_vars();
|
||||
}
|
||||
|
||||
TEST(roslib, commandList)
|
||||
{
|
||||
set_env_vars();
|
||||
|
||||
std::string output = ros::package::command("list");
|
||||
std::vector<std::string> output_list;
|
||||
std::vector<std::string> name_path;
|
||||
string_split(output, output_list, "\n");
|
||||
ASSERT_EQ((int)output_list.size(), 1);
|
||||
string_split(output_list[0], name_path, " ");
|
||||
ASSERT_EQ((int)name_path.size(), 2);
|
||||
ASSERT_STREQ(name_path[0].c_str(), "roslib");
|
||||
|
||||
cleanup_env_vars();
|
||||
}
|
||||
|
||||
TEST(roslib, getAll)
|
||||
{
|
||||
set_env_vars();
|
||||
|
||||
std::vector<std::string> output_list;
|
||||
ASSERT_TRUE(ros::package::getAll(output_list));
|
||||
ASSERT_EQ((int)output_list.size(), 1);
|
||||
ASSERT_STREQ(output_list[0].c_str(), "roslib");
|
||||
|
||||
cleanup_env_vars();
|
||||
}
|
||||
|
||||
void
|
||||
roslib_caller()
|
||||
{
|
||||
struct timespec ts = {0, 100000};
|
||||
std::string output;
|
||||
for(int i=0;i<100;i++)
|
||||
{
|
||||
output = ros::package::command("plugins --attrib=foo roslib");
|
||||
nanosleep(&ts, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(roslib, concurrent_access)
|
||||
{
|
||||
set_env_vars();
|
||||
const int size = 10;
|
||||
boost::thread t[size];
|
||||
for(int i=0;i<size; i++)
|
||||
t[i] = boost::thread(boost::bind(roslib_caller));
|
||||
for(int i=0;i<size; i++)
|
||||
t[i].join();
|
||||
cleanup_env_vars();
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
testing::InitGoogleTest(&argc, argv);
|
||||
return RUN_ALL_TESTS();
|
||||
}
|
||||
|
Loading…
Reference in New Issue