1#!/usr/bin/env python 2# Software License Agreement (BSD License) 3# 4# Copyright (c) 2009, Willow Garage, Inc. 5# All rights reserved. 6# 7# Redistribution and use in source and binary forms, with or without 8# modification, are permitted provided that the following conditions 9# are met: 10# 11# * Redistributions of source code must retain the above copyright 12# notice, this list of conditions and the following disclaimer. 13# * Redistributions in binary form must reproduce the above 14# copyright notice, this list of conditions and the following 15# disclaimer in the documentation and/or other materials provided 16# with the distribution. 17# * Neither the name of Willow Garage, Inc. nor the names of its 18# contributors may be used to endorse or promote products derived 19# from this software without specific prior written permission. 20# 21# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 22# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 23# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 24# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 25# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 26# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 27# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 28# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 29# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 30# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 31# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 32# POSSIBILITY OF SUCH DAMAGE. 33 34import os 35import subprocess 36import shutil 37import rosinstall.rosws_cli 38from test.scm_test_base import AbstractFakeRosBasedTest, _create_yaml_file, _create_config_elt_dict 39from wstool.config_yaml import PathSpec 40import wstool.multiproject_cmd 41from rosinstall.rosws_cli import RoswsCLI 42from rosinstall.helpers import ROSInstallException 43 44 45class FakeConfig(): 46 def __init__(self, elts=[], celts=[], basepath=''): 47 self.elts = elts 48 self.celts = celts 49 self.basepath = basepath 50 51 def get_config_elements(self): 52 return self.celts 53 54 def get_source(self): 55 return self.elts 56 57 def get_base_path(self): 58 return self.basepath 59 60 61class MockConfigElement(): 62 def __init__(self, local_name='', scmtype=None, path=None, uri=None, spec=None): 63 self.scmtype = scmtype 64 self.path = path 65 self.uri = uri 66 self.local_name = local_name 67 self.spec = spec 68 69 def get_path(self): 70 return self.path 71 72 def get_local_name(self): 73 return self.local_name 74 75 def get_path_spec(self): 76 return self.spec 77 78 def is_vcs_element(self): 79 return True if self.scmtype else False 80 81 82class RosinstallCommandlineTest(AbstractFakeRosBasedTest): 83 84 def test_require_bootstrap(self): 85 config = FakeConfig() 86 self.assertFalse(rosinstall.rosinstall_cmd._ros_requires_boostrap(config)) 87 config = FakeConfig([PathSpec(self.ros_path, path=self.ros_path)]) 88 self.assertFalse(rosinstall.rosinstall_cmd._ros_requires_boostrap(config)) 89 config = FakeConfig([PathSpec(self.ros_path, 'git', 'gituri', path=self.ros_path)]) 90 self.assertTrue(rosinstall.rosinstall_cmd._ros_requires_boostrap(config)) 91 92 93class RosinstallCommandLineGenerationTest(AbstractFakeRosBasedTest): 94 95 def test_cmd_generate_ros_files_simple(self): 96 self.local_path = os.path.join(self.test_root_path, "ws") 97 os.makedirs(self.local_path) 98 99 config = FakeConfig(celts=[MockConfigElement(path=self.ros_path)], basepath=self.local_path) 100 rosinstall.rosinstall_cmd.cmd_generate_ros_files(config, self.local_path, nobuild=True, rosdep_yes=False, catkin=False, catkinpp=None) 101 self.assertTrue(os.path.exists(os.path.join(self.local_path, 'setup.sh'))) 102 self.assertTrue(os.path.exists(os.path.join(self.local_path, 'setup.bash'))) 103 self.assertTrue(os.path.exists(os.path.join(self.local_path, 'setup.zsh'))) 104 105 def test_cmd_generate_ros_files_vcs(self): 106 self.local_path = os.path.join(self.test_root_path, "ws2") 107 os.makedirs(self.local_path) 108 109 config = FakeConfig(celts=[MockConfigElement(path=self.ros_path), MockConfigElement(path='gitrepo', scmtype='git', uri=self.git_path), MockConfigElement(path='hgrepo', scmtype='hg', uri=self.hg_path)], basepath=self.local_path) 110 rosinstall.rosinstall_cmd.cmd_generate_ros_files(config, self.local_path, nobuild=True, rosdep_yes=False, catkin=False, catkinpp=None) 111 self.assertTrue(os.path.exists(os.path.join(self.local_path, 'setup.sh'))) 112 self.assertTrue(os.path.exists(os.path.join(self.local_path, 'setup.bash'))) 113 self.assertTrue(os.path.exists(os.path.join(self.local_path, 'setup.zsh'))) 114 115 def test_cmd_generate_ros_files_catkin(self): 116 self.local_path = os.path.join(self.test_root_path, "ws3") 117 os.makedirs(self.local_path) 118 119 config = FakeConfig([PathSpec(self.ros_path), PathSpec('gitrepo', 'git', uri=self.git_path)], self.local_path) 120 rosinstall.rosinstall_cmd.cmd_generate_ros_files(config, self.local_path, nobuild=True, rosdep_yes=False, catkin=True, catkinpp=False) 121 self.assertFalse(os.path.exists(os.path.join(self.local_path, 'setup.sh'))) 122 self.assertFalse(os.path.exists(os.path.join(self.local_path, 'setup.bash'))) 123 self.assertFalse(os.path.exists(os.path.join(self.local_path, 'setup.zsh'))) 124 self.assertTrue(os.path.exists(os.path.join(self.local_path, 'CMakeLists.txt'))) 125 126 def test_cmd_generate_ros_files_catkinpp(self): 127 self.local_path = os.path.join(self.test_root_path, "ws4") 128 os.makedirs(self.local_path) 129 130 config = FakeConfig([PathSpec(self.ros_path), PathSpec('gitrepo', 'git', uri=self.git_path)], self.local_path) 131 rosinstall.rosinstall_cmd.cmd_generate_ros_files(config, self.local_path, nobuild=True, rosdep_yes=False, catkin=True, catkinpp=True) 132 self.assertFalse(os.path.exists(os.path.join(self.local_path, 'setup.sh'))) 133 self.assertFalse(os.path.exists(os.path.join(self.local_path, 'setup.bash'))) 134 self.assertFalse(os.path.exists(os.path.join(self.local_path, 'setup.zsh'))) 135 self.assertTrue(os.path.exists(os.path.join(self.local_path, 'CMakeLists.txt'))) 136 self.assertTrue(os.path.exists(os.path.join(self.local_path, 'workspace-config.cmake'))) 137 138 def test_cmd_generate_ros_files_build(self): 139 self.local_path = os.path.join(self.test_root_path, "ws2b") 140 os.makedirs(self.local_path) 141 local_rosinstall = os.path.join(self.test_root_path, "local.rosinstall") 142 _create_yaml_file([_create_config_elt_dict("git", 'ros_comm', self.git_path), 143 _create_config_elt_dict("git", 'ros', self.ros_path), 144 _create_config_elt_dict("hg", 'hgrepo', self.hg_path)], local_rosinstall) 145 cli = RoswsCLI() 146 self.assertEqual(0, cli.cmd_init([self.local_path, local_rosinstall])) 147 self.assertTrue(os.path.exists(os.path.join(self.local_path, 'setup.sh'))) 148 self.assertTrue(os.path.exists(os.path.join(self.local_path, 'setup.bash'))) 149 self.assertTrue(os.path.exists(os.path.join(self.local_path, 'setup.zsh'))) 150 151 def test_cmd_init(self): 152 self.local_path = os.path.join(self.test_root_path, "ws5") 153 os.makedirs(self.local_path) 154 155 cli = RoswsCLI() 156 self.assertEqual(0, cli.cmd_init([self.local_path, self.ros_path])) 157 self.assertTrue(os.path.exists(os.path.join(self.local_path, 'setup.sh'))) 158 self.assertTrue(os.path.exists(os.path.join(self.local_path, 'setup.bash'))) 159 self.assertTrue(os.path.exists(os.path.join(self.local_path, 'setup.zsh'))) 160 self.assertTrue(os.path.exists(os.path.join(self.local_path, '.rosinstall'))) 161 self.assertEqual(0, subprocess.call(". %s" % os.path.join(self.local_path, 'setup.sh'), shell=True, env=self.new_environ)) 162 self.assertEqual(0, subprocess.call(". %s" % os.path.join(self.local_path, 'setup.bash'), shell=True, env=self.new_environ, executable='/bin/bash')) 163 164 self.assertEqual(0, cli.cmd_merge(self.local_path, [self.ros_path, "-y"])) 165 self.assertTrue(os.path.exists(os.path.join(self.local_path, 'setup.sh'))) 166 self.assertTrue(os.path.exists(os.path.join(self.local_path, 'setup.bash'))) 167 self.assertTrue(os.path.exists(os.path.join(self.local_path, 'setup.zsh'))) 168 self.assertTrue(os.path.exists(os.path.join(self.local_path, '.rosinstall'))) 169 self.assertEqual(0, subprocess.call(". %s" % os.path.join(self.local_path, 'setup.sh'), shell=True, env=self.new_environ)) 170 self.assertEqual(0, subprocess.call(". %s" % os.path.join(self.local_path, 'setup.bash'), shell=True, env=self.new_environ, executable='/bin/bash')) 171 172 def test_cmd_init_catkin(self): 173 self.local_path = os.path.join(self.test_root_path, "ws6") 174 os.makedirs(self.local_path) 175 176 cli = RoswsCLI() 177 self.assertEqual(0, cli.cmd_init([self.local_path, self.ros_path, "-c"])) 178 self.assertFalse(os.path.exists(os.path.join(self.local_path, 'setup.sh'))) 179 self.assertFalse(os.path.exists(os.path.join(self.local_path, 'setup.bash'))) 180 self.assertFalse(os.path.exists(os.path.join(self.local_path, 'setup.zsh'))) 181 self.assertTrue(os.path.exists(os.path.join(self.local_path, '.rosinstall'))) 182 self.assertTrue(os.path.exists(os.path.join(self.local_path, 'CMakeLists.txt'))) 183 184 def test_cmd_init_catkin2(self): 185 self.local_path = os.path.join(self.test_root_path, "ws7") 186 os.makedirs(self.local_path) 187 188 cli = RoswsCLI() 189 self.assertEqual(0, cli.cmd_init([self.local_path, self.ros_path, "--catkin"])) 190 self.assertFalse(os.path.exists(os.path.join(self.local_path, 'setup.sh'))) 191 self.assertFalse(os.path.exists(os.path.join(self.local_path, 'setup.bash'))) 192 self.assertFalse(os.path.exists(os.path.join(self.local_path, 'setup.zsh'))) 193 self.assertTrue(os.path.exists(os.path.join(self.local_path, '.rosinstall'))) 194 self.assertTrue(os.path.exists(os.path.join(self.local_path, 'CMakeLists.txt'))) 195 196 def test_cmd_init_catkinpp(self): 197 self.local_path = os.path.join(self.test_root_path, "ws8") 198 os.makedirs(self.local_path) 199 200 cli = RoswsCLI() 201 self.assertEqual(0, cli.cmd_init([self.local_path, self.ros_path, "--catkin", "--cmake-prefix-path=foo"])) 202 self.assertFalse(os.path.exists(os.path.join(self.local_path, 'setup.sh'))) 203 self.assertFalse(os.path.exists(os.path.join(self.local_path, 'setup.bash'))) 204 self.assertFalse(os.path.exists(os.path.join(self.local_path, 'setup.zsh'))) 205 self.assertTrue(os.path.exists(os.path.join(self.local_path, '.rosinstall'))) 206 self.assertTrue(os.path.exists(os.path.join(self.local_path, 'CMakeLists.txt'))) 207 self.assertTrue(os.path.exists(os.path.join(self.local_path, 'workspace-config.cmake'))) 208 209 def test_cmd_init_makedir(self): 210 # rosinstall to create dir 211 self.local_path = os.path.join(self.test_root_path, "ws9") 212 cli = RoswsCLI() 213 self.assertEqual(0, cli.cmd_init([self.local_path, self.ros_path])) 214 self.assertTrue(os.path.exists(os.path.join(self.local_path, 'setup.sh'))) 215 self.assertTrue(os.path.exists(os.path.join(self.local_path, 'setup.bash'))) 216 self.assertTrue(os.path.exists(os.path.join(self.local_path, 'setup.zsh'))) 217 218 def test_cmd_init_no_ros(self): 219 self.local_path = os.path.join(self.test_root_path, "ws10") 220 221 ros_root_existed = False 222 if 'ROS_ROOT' in os.environ: 223 ros_root_existed = True 224 oldros = os.environ.pop('ROS_ROOT') 225 cli = RoswsCLI() 226 self.assertEqual(0, cli.cmd_init([self.local_path])) 227 228 shutil.rmtree(self.local_path) 229 os.environ['ROS_ROOT'] = self.ros_path 230 231 self.assertEqual(0, cli.cmd_init([self.local_path])) 232 self.assertTrue(os.path.exists(os.path.join(self.local_path, 'setup.sh'))) 233 self.assertTrue(os.path.exists(os.path.join(self.local_path, 'setup.bash'))) 234 self.assertTrue(os.path.exists(os.path.join(self.local_path, 'setup.zsh'))) 235 if ros_root_existed: 236 os.environ['ROS_ROOT'] = oldros 237 else: 238 os.environ.pop('ROS_ROOT') 239 240 def test_cmd_init_main(self): 241 # rosinstall to create dir 242 ros_root_existed = False 243 244 if 'ROS_ROOT' in os.environ: 245 ros_root_existed = True 246 oldros = os.environ.pop('ROS_ROOT') 247 os.environ['ROS_ROOT'] = self.ros_path 248 self.local_path = os.path.join(self.test_root_path, "ws11") 249 self.assertEqual(0, rosinstall.rosws_cli.rosws_main(['rosws', 'help'])) 250 self.assertEqual(0, rosinstall.rosws_cli.rosws_main(['rosws', 'init', self.local_path])) 251 self.assertEqual(0, rosinstall.rosws_cli.rosws_main(['rosws', 'info', '-t', self.local_path])) 252 self.assertEqual(0, rosinstall.rosws_cli.rosws_main(['rosws', 'info', '--pkg-path-only', '-t', self.local_path])) 253 self.assertEqual(0, rosinstall.rosws_cli.rosws_main(['rosws', 'info', '--no-pkg-path', '-t', self.local_path])) 254 self.assertEqual(0, rosinstall.rosws_cli.rosws_main(['rosws', 'info', '--data-only', '-t', self.local_path])) 255 self.assertTrue(os.path.exists(os.path.join(self.local_path, 'setup.sh'))) 256 self.assertTrue(os.path.exists(os.path.join(self.local_path, 'setup.bash'))) 257 self.assertTrue(os.path.exists(os.path.join(self.local_path, 'setup.zsh'))) 258 if ros_root_existed: 259 os.environ['ROS_ROOT'] = oldros 260 else: 261 os.environ.pop('ROS_ROOT') 262 263 def test_cmd_remove(self): 264 # rosinstall to create dir 265 self.local_path = os.path.join(self.test_root_path, "ws12") 266 cli = RoswsCLI() 267 self.assertEqual(0, cli.cmd_init([self.local_path, self.ros_path])) 268 self.assertEqual(0, cli.cmd_merge(self.local_path, [self.git_path, "-y"])) 269 self.assertEqual(0, cli.cmd_merge(self.local_path, [self.hg_path, "-y"])) 270 config = wstool.multiproject_cmd.get_config(basepath=self.local_path, 271 config_filename='.rosinstall') 272 self.assertEqual(len(config.get_config_elements()), 3) 273 self.assertEqual(0, cli.cmd_remove(self.local_path, [self.git_path])) 274 config = wstool.multiproject_cmd.get_config(basepath=self.local_path, 275 config_filename='.rosinstall') 276 self.assertEqual(len(config.get_config_elements()), 2) 277 278 def execute_check_result_allshells(self, command, path, cwd=None, expect=''): 279 """sources in turn each setup.*sh and runs command""" 280 # zsh has issues with SCRIPT_PATH 281 for shell in ['sh', 'bash']: 282 cmd = ". %s ; %s" % (os.path.join(path, 'setup.%s' % shell), command) 283 p = subprocess.Popen(cmd, shell=True, cwd=cwd, stdout=subprocess.PIPE, executable='/bin/%s' % shell) 284 output = p.communicate()[0] 285 self.assertEqual(expect.encode('UTF-8'), output.strip(), ("'%s' != '%s', cmd: %s, cwd: %s" % (expect, output, cmd, cwd))) 286 self.assertEqual(0, p.returncode) 287 288 def test_init_parallel(self): 289 self.local_path = os.path.join(self.test_root_path, "ws13a") 290 cli = RoswsCLI() 291 self.assertEqual(0, cli.cmd_init([self.local_path, self.simple_rosinstall, "--parallel=5"])) 292 293 command = "echo $ROS_WORKSPACE" 294 self.execute_check_result_allshells(command, self.local_path, expect=self.local_path) 295 self.execute_check_result_allshells(command, '.', cwd=self.local_path, expect=self.local_path) 296 self.execute_check_result_allshells(command, 'ws13a', cwd=self.test_root_path, expect=self.local_path) 297 298 local_ros_path = os.path.join(self.local_path, "ros") 299 local_git_path = os.path.join(self.local_path, "gitrepo") 300 package_path = "%s:%s" % (local_git_path, local_ros_path) 301 command = "echo $ROS_PACKAGE_PATH" 302 self.execute_check_result_allshells(command, self.local_path, expect=package_path) 303 self.execute_check_result_allshells(command, '.', cwd=self.local_path, expect=package_path) 304 self.execute_check_result_allshells(command, 'ws13a', cwd=self.test_root_path, expect=package_path) 305 306 def test_setup_sh(self): 307 self.local_path = os.path.join(self.test_root_path, "ws13") 308 cli = RoswsCLI() 309 self.assertEqual(0, cli.cmd_init([self.local_path, self.simple_rosinstall])) 310 311 command = "echo $ROS_WORKSPACE" 312 self.execute_check_result_allshells(command, self.local_path, expect=self.local_path) 313 self.execute_check_result_allshells(command, '.', cwd=self.local_path, expect=self.local_path) 314 self.execute_check_result_allshells(command, 'ws13', cwd=self.test_root_path, expect=self.local_path) 315 316 local_ros_path = os.path.join(self.local_path, "ros") 317 local_git_path = os.path.join(self.local_path, "gitrepo") 318 package_path = "%s:%s" % (local_git_path, local_ros_path) 319 command = "echo $ROS_PACKAGE_PATH" 320 self.execute_check_result_allshells(command, self.local_path, expect=package_path) 321 self.execute_check_result_allshells(command, '.', cwd=self.local_path, expect=package_path) 322 self.execute_check_result_allshells(command, 'ws13', cwd=self.test_root_path, expect=package_path) 323 324 def test_setup_sh_relros(self): 325 self.local_path = os.path.join(self.test_root_path, "ws14") 326 cli = RoswsCLI() 327 simple_rel_rosinstall = os.path.join(self.test_root_path, "simple_rel.rosinstall") 328 _create_yaml_file([_create_config_elt_dict("git", "ros", "../ros")], 329 simple_rel_rosinstall) 330 self.assertEqual(0, cli.cmd_init([self.local_path, simple_rel_rosinstall])) 331 332 command = "echo $ROS_WORKSPACE" 333 self.execute_check_result_allshells(command, self.local_path, expect=self.local_path) 334 self.execute_check_result_allshells(command, '.', cwd=self.local_path, expect=self.local_path) 335 self.execute_check_result_allshells(command, 'ws14', cwd=self.test_root_path, expect=self.local_path) 336 337 package_path = os.path.join(self.local_path, "ros") 338 command = "echo $ROS_PACKAGE_PATH" 339 self.execute_check_result_allshells(command, self.local_path, expect=package_path) 340 self.execute_check_result_allshells(command, '.', cwd=self.local_path, expect=package_path) 341 self.execute_check_result_allshells(command, 'ws14', cwd=self.test_root_path, expect=package_path) 342 343 344 def test_setup_sh_relother(self): 345 self.local_path = os.path.join(self.test_root_path, "ws15") 346 cli = RoswsCLI() 347 simple_rel_rosinstall = os.path.join(self.test_root_path, "simple_rel2.rosinstall") 348 _create_yaml_file([_create_config_elt_dict("git", "ros", "../ros"), 349 _create_config_elt_dict("other", "../gitrepo")], 350 simple_rel_rosinstall) 351 self.assertEqual(0, cli.cmd_init([self.local_path, simple_rel_rosinstall])) 352 353 command = "echo $ROS_WORKSPACE" 354 self.execute_check_result_allshells(command, self.local_path, expect=self.local_path) 355 self.execute_check_result_allshells(command, '.', cwd=self.local_path, expect=self.local_path) 356 self.execute_check_result_allshells(command, 'ws15', cwd=self.test_root_path, expect=self.local_path) 357 358 local_ros_path = os.path.join(self.local_path, "ros") 359 package_path = "%s:%s" % (self.git_path, local_ros_path) 360 command = "echo $ROS_PACKAGE_PATH" 361 self.execute_check_result_allshells(command, self.local_path, expect=package_path) 362 self.execute_check_result_allshells(command, '.', cwd=self.local_path, expect=package_path) 363 self.execute_check_result_allshells(command, 'ws15', cwd=self.test_root_path, expect=package_path) 364