Пример #1
0
    def test_get_element_diff(self):
        self.assertEqual('', _get_element_diff(None, None))
        self.assertEqual('', _get_element_diff(None, 42))
        self.assertEqual('', _get_element_diff(42, None))

        spec = PathSpec('foolocalname',
                        scmtype='fooscm',
                        uri='foouri',
                        version='fooversion',
                        path='foopath')

        spec2 = PathSpec('foolocalname')
        element2 = MockConfigElement(local_name='foolocalname', spec=spec2)

        elements = [element2]
        config = FakeConfig(celts=elements)

        output = _get_element_diff(spec, config)
        self.assertEqual(' foolocalname', output)

        output = _get_element_diff(spec, config, extra_verbose=True)
        snippets = [
            ' foolocalname', 'version = fooversion', 'specified uri = foouri',
            'scmtype = fooscm'
        ]
        for s in snippets:
            self.assertTrue(s in output,
                            "missing snippet: '%s' in '%s'" % (s, output))
Пример #2
0
 def test_config_merging_kill_append(self):
     git1 = PathSpec('foo', 'git', 'git/uri')
     svn1 = PathSpec('foo', 'svn', 'svn/uri')
     hg1 = PathSpec('foo', 'hg', 'hg/uri')
     bzr1 = PathSpec('foo', 'bzr', 'bzr/uri')
     config = self._get_mock_config([git1, svn1, hg1, bzr1])
     self.assertEqual(1, len(config.get_config_elements()))
     self.assertEqual('bzr', config.get_source()[0].get_scmtype())
     self.assertEqual('/install/path/bzr/uri',
                      config.get_source()[0].get_uri())
     config = self._get_mock_config([git1, svn1, hg1, bzr1, git1])
     self.assertEqual(1, len(config.get_config_elements()))
     self.assertEqual('git', config.get_source()[0].get_scmtype())
     self.assertEqual('/install/path/git/uri',
                      config.get_source()[0].get_uri())
     bzr1 = PathSpec('bar', 'bzr', 'bzr/uri')
     config = self._get_mock_config([git1, svn1, hg1, bzr1])
     self.assertEqual(2, len(config.get_config_elements()))
     self.assertEqual('hg', config.get_source()[0].get_scmtype())
     self.assertEqual('/install/path/hg/uri',
                      config.get_source()[0].get_uri())
     self.assertEqual('bzr', config.get_source()[1].get_scmtype())
     self.assertEqual('/install/path/bzr/uri',
                      config.get_source()[1].get_uri())
     config = self._get_mock_config([git1, svn1, hg1, bzr1, git1])
     self.assertEqual(2, len(config.get_config_elements()))
     self.assertEqual('bzr', config.get_source()[0].get_scmtype())
     self.assertEqual('/install/path/bzr/uri',
                      config.get_source()[0].get_uri())
     self.assertEqual('git', config.get_source()[1].get_scmtype())
     self.assertEqual('/install/path/git/uri',
                      config.get_source()[1].get_uri())
Пример #3
0
 def test_mock_install(self):
     test_root = os.path.realpath(tempfile.mkdtemp())
     try:
         git1 = PathSpec('foo', 'git', 'git/uri', 'git.version')
         svn1 = PathSpec('foos', 'svn', 'svn/uri', '12345')
         hg1 = PathSpec('fooh', 'hg', 'hg/uri', 'hg.version')
         bzr1 = PathSpec('foob', 'bzr', 'bzr/uri', 'bzr.version')
         config = Config(
             [git1, svn1, hg1, bzr1], test_root, None, {
                 "svn": MockVcsConfigElement,
                 "git": MockVcsConfigElement,
                 "hg": MockVcsConfigElement,
                 "bzr": MockVcsConfigElement
             })
         wstool.multiproject_cmd.cmd_install_or_update(config)
         wstool.multiproject_cmd.cmd_install_or_update(config)
         wstool.multiproject_cmd.cmd_install_or_update(config,
                                                       num_threads=10)
         wstool.multiproject_cmd.cmd_install_or_update(config,
                                                       num_threads=10)
         wstool.multiproject_cmd.cmd_install_or_update(config,
                                                       num_threads=1)
         wstool.multiproject_cmd.cmd_install_or_update(config,
                                                       num_threads=1)
     finally:
         shutil.rmtree(test_root)
Пример #4
0
    def test_cmd_generate_ros_files_catkinpp(self):
        self.local_path = os.path.join(self.test_root_path, "ws4")
        os.makedirs(self.local_path)

        config = FakeConfig([
            PathSpec(self.ros_path),
            PathSpec('gitrepo', 'git', uri=self.git_path)
        ], self.local_path)
        rosinstall.rosinstall_cmd.cmd_generate_ros_files(config,
                                                         self.local_path,
                                                         nobuild=True,
                                                         rosdep_yes=False,
                                                         catkin=True,
                                                         catkinpp=True)
        self.assertFalse(
            os.path.exists(os.path.join(self.local_path, 'setup.sh')))
        self.assertFalse(
            os.path.exists(os.path.join(self.local_path, 'setup.bash')))
        self.assertFalse(
            os.path.exists(os.path.join(self.local_path, 'setup.zsh')))
        self.assertTrue(
            os.path.exists(os.path.join(self.local_path, 'CMakeLists.txt')))
        self.assertTrue(
            os.path.exists(
                os.path.join(self.local_path, 'workspace-config.cmake')))
Пример #5
0
 def test_config_simple3(self):
     git1 = PathSpec('foo', 'git', 'git/uri', 'git.version')
     svn1 = PathSpec('foos', 'svn', 'svn/uri', '12345')
     bzr1 = PathSpec('foob', 'bzr', 'bzr/uri', 'bzr.version')
     hg1 = PathSpec('fooh', 'hg', 'hg/uri', 'hg.version')
     config = self._get_mock_config([git1, svn1, hg1, bzr1])
     self.assertEqual(4, len(config.get_config_elements()))
Пример #6
0
 def test_generate_with_vcs_only(self):
     def check_config_entries(self, lines, uuid):
         self.assertEqual(1, len(lines))
         self.assertEqual(self.git_el % self.version, lines[0])
     self.helper(check_config_entries, {'vcs_only': True},
                 [PathSpec(self.git, 'git', self.uri, self.version),
                  PathSpec(self.other)])
Пример #7
0
 def test_mock_install_fail(self):
     test_root = os.path.realpath(tempfile.mkdtemp())
     try:
         # robust
         git1 = PathSpec('foo', 'git', 'git/uri', 'git.version')
         svn1 = PathSpec('foos', 'svn', 'svn/uri', '12345')
         hg1 = PathSpec('fooh', 'hg', 'hg/uri', 'hg.version')
         bzr1 = PathSpec('foob', 'bzr', 'bzr/uri', 'bzr.version')
         config = Config(
             [git1, svn1, hg1, bzr1],
             install_path=test_root,
             config_filename=None,
             extended_types={
                 "svn": MockVcsConfigElement,
                 "git": MockVcsConfigElement,
                 "hg": MockVcsConfigElement,
                 "bzr": MockVcsConfigElement
             })
         config.get_config_elements()[1].install_success = False
         wstool.multiproject_cmd.cmd_install_or_update(config, robust=True)
         try:
             wstool.multiproject_cmd.cmd_install_or_update(config,
                                                           robust=False)
             self.fail("expected Exception")
         except MultiProjectException:
             pass
     finally:
         shutil.rmtree(test_root)
Пример #8
0
 def test_gen_python_code_python3(self):
     # requires python3 to be installed, obviously
     config = Config([
         PathSpec(os.path.join("test", "example_dirs", "ros_comm")),
         PathSpec("bar.sh", tags=['setup-file']),
         PathSpec("baz")
     ], self.directory, None)
     wstool.config_yaml.generate_config_yaml(config, '.rosinstall', '')
     filename = os.path.join(self.directory, "test_gen.py")
     _add_to_file(filename,
                  rosinstall.setupfiles.generate_embedded_python())
     sh_filename = os.path.join(self.directory, "bar.sh")
     _add_to_file(sh_filename, "#! /usr/bin/env sh")
     cmd = "python3 -W ignore %s" % filename
     p = subprocess.Popen(cmd,
                          shell=True,
                          cwd=self.directory,
                          stdout=subprocess.PIPE,
                          stderr=subprocess.PIPE)
     output, err = p.communicate()
     self.assertEqual(''.encode('UTF-8'), err, err)
     self.assertTrue(
         '/test/example_dirs/ros_comm'.encode('UTF-8') in output,
         output)
     self.assertTrue('baz'.encode('UTF-8') in output, output)
     self.assertTrue(
         'ROSINSTALL_PATH_SETUPFILE_SEPARATOR'.encode('UTF-8')
         in output, output)
     self.assertTrue(output.endswith('/bar.sh\n'.encode('UTF-8')),
                     output)
Пример #9
0
 def test_remove(self):
     git1 = PathSpec('foo', 'git', 'git/uri', 'git.version')
     svn1 = PathSpec('foos', 'svn', 'svn/uri', '12345')
     hg1 = PathSpec('fooh', 'hg', 'hg/uri', 'hg.version')
     bzr1 = PathSpec('foob', 'bzr', 'bzr/uri', 'bzr.version')
     config = self._get_mock_config([git1, svn1, hg1, bzr1])
     self.assertEqual(4, len(config.get_config_elements()))
     self.assertFalse(config.remove_element(None))
     self.assertFalse(config.remove_element('bar'))
     self.assertEqual(4, len(config.get_config_elements()))
     self.assertTrue(config.remove_element('foo'))
     self.assertEqual(3, len(config.get_config_elements()))
     self.assertEqual('/install/path/foos',
                      config.get_config_elements()[0].get_path())
     self.assertEqual('/install/path/fooh',
                      config.get_config_elements()[1].get_path())
     self.assertEqual('/install/path/foob',
                      config.get_config_elements()[2].get_path())
     self.assertTrue(config.remove_element('fooh'))
     self.assertEqual(2, len(config.get_config_elements()))
     self.assertEqual('/install/path/foos',
                      config.get_config_elements()[0].get_path())
     self.assertEqual('/install/path/foob',
                      config.get_config_elements()[1].get_path())
     self.assertTrue(config.remove_element('foos'))
     self.assertEqual(1, len(config.get_config_elements()))
     self.assertTrue(config.remove_element('foob'))
     self.assertEqual(0, len(config.get_config_elements()))
Пример #10
0
 def test_generate_with_exact(self):
     def check_config_entries(self, lines, uuid):
         self.assertEqual(2, len(lines))
         self.assertEqual(self.git_el % uuid, lines[0])
         self.assertEqual(self.other_el, lines[1])
     self.helper(check_config_entries, {'spec': False, 'exact': True},
                 [PathSpec(self.git, 'git', self.uri, self.version),
                  PathSpec(self.other)])
 def test_get_ros_package_path(self):
     config = Config([PathSpec("foo"),
                      PathSpec("bar")],
                     ".",
                     None)
     self.assertEqual(list(map(os.path.abspath, ['bar',
                       'foo'])),
                      wstool.helpers.get_ros_package_path(config))
Пример #12
0
 def test_require_bootstrap(self):
     config = FakeConfig()
     self.assertFalse(
         rosinstall.rosinstall_cmd._ros_requires_boostrap(config))
     config = FakeConfig([PathSpec(self.ros_path, path=self.ros_path)])
     self.assertFalse(
         rosinstall.rosinstall_cmd._ros_requires_boostrap(config))
     config = FakeConfig(
         [PathSpec(self.ros_path, 'git', 'gituri', path=self.ros_path)])
     self.assertTrue(
         rosinstall.rosinstall_cmd._ros_requires_boostrap(config))
Пример #13
0
    def test_generate_sorted_with_localname(self):
        def check_config_entries(self, lines, uuid):
            self.assertEqual(2, len(lines))
            self.assertEqual('''\
- git: {local-name: git, uri: %s/some/uri2}
- svn: {local-name: ros, uri: %s/some/uri1}\
''' % (self.directory, self.directory), "\n".join(lines[:2]))

        self.helper(check_config_entries, {'sort_with_localname': True},
                    [PathSpec('ros', 'svn', 'some/uri1'),
                     PathSpec('git', 'git', 'some/uri2')])
Пример #14
0
 def test_source_setup_sh(self):
     test_folder = os.path.join(self.test_root_path, 'workspacetest')
     os.makedirs(test_folder)
     othersetupfile = os.path.join(test_folder, 'othersetup.sh')
     testsetupfile = os.path.join(test_folder, 'testsetup.sh')
     with open(othersetupfile, 'w') as fhand:
         fhand.write('unset ROS_WORKSPACE')
     config = Config([
         PathSpec(self.ros_path),
         PathSpec(othersetupfile, scmtype=None, tags=['setup-file'])
     ],
                     install_path=test_folder,
                     config_filename=ROSINSTALL_FILENAME)
     result = rosinstall.setupfiles.generate_setup_sh_text(
         config.get_base_path())
     self.assertTrue('export ROS_WORKSPACE=%s' % test_folder in result)
     with open(testsetupfile, 'w') as fhand:
         fhand.write(result)
     # check that sourcing setup.sh raises error when .wstool is missing
     raised = False
     try:
         subprocess.check_call(". %s" % testsetupfile,
                               shell=True,
                               env=self.new_environ)
     except:
         raised = True
     self.assertTrue(raised,
                     'sourcing setup.sh with missing .wstool should fail')
     # test that our otherscript really unsets ROS_WORKSPACE, else nexttest would be invalid
     # using basename to check var is not set
     raised = False
     try:
         cmd = "export ROS_WORKSPACE=foo && . %s && basename $ROS_WORKSPACE" % othersetupfile
         subprocess.check_call(cmd, shell=True, env=self.new_environ)
     except:
         raised = True
     self.assertTrue(raised, 'unsetting-sh-file did not unset var')
     # now test that when sourcing setup.sh that contains a
     # setup-file to other sh file which unsets ROS_WORKSPACE,
     # ROS_WORKSPACE is still set in the end
     generate_config_yaml(config, ROSINSTALL_FILENAME, '')
     self.assertTrue(
         os.path.isfile(os.path.join(test_folder, ROSINSTALL_FILENAME)))
     # using basename to check var is set
     cmd = "export ROS_WORKSPACE=foo && . %s && echo $ROS_WORKSPACE" % testsetupfile
     po = subprocess.Popen(cmd,
                           shell=True,
                           cwd=test_folder,
                           stdout=subprocess.PIPE)
     workspace = po.stdout.read().decode('UTF-8').rstrip('"').lstrip(
         '"').strip()
     po.stdout.close()
     self.assertEqual(test_folder, workspace)
Пример #15
0
 def test_init(self):
     yaml = []
     install_path = '/install/path'
     config_filename = '.filename'
     config = Config(yaml, install_path, config_filename)
     self.assertEqual(install_path, config.get_base_path())
     self.assertEqual([], config.get_config_elements())
     config = Config([
         PathSpec("foo"),
         PathSpec(os.path.join(_test_root, "example_dirs", "ros_comm")),
         PathSpec(os.path.join(_test_root, "example_dirs", "ros")),
         PathSpec(os.path.join(_test_root, "example_dirs", "roscpp")),
         PathSpec("bar")
     ], ".", None)
     self.assertEqual(os.path.abspath('.'), config.get_base_path())
Пример #16
0
 def test_gen_setup_bash(self):
     config = Config([
         PathSpec(self.ros_path),
         PathSpec(os.path.join("test", "example_dirs", "ros_comm")),
         PathSpec("bar")
     ], self.test_root_path, None)
     result = rosinstall.setupfiles.generate_setup_bash_text('bash')
     self.assertTrue(result.count("#!/usr/bin/env bash") == 1)
     self.assertTrue(result.count("CATKIN_SHELL=bash") == 1)
     self.assertTrue(
         result.count("ROSSHELL_PATH=`rospack find rosbash`/rosbash") == 1)
     result = rosinstall.setupfiles.generate_setup_bash_text('zsh')
     self.assertTrue(result.count("#!/usr/bin/env zsh") == 1)
     self.assertTrue(result.count("CATKIN_SHELL=zsh") == 1)
     self.assertTrue(
         result.count("ROSSHELL_PATH=`rospack find rosbash`/roszsh") == 1)
Пример #17
0
    def test_generate_sorted_with_localname(self):
        self.directory = tempfile.mkdtemp()
        elements = [PathSpec('ros', 'svn', 'some/uri1'),
                    PathSpec('git', 'git', 'some/uri2')]
        config = wstool.config.Config(elements, self.directory)
        wstool.config_yaml.generate_config_yaml(config, 'foo', "# Hello\n",
                                                sort_with_localname=True)
        filepath = os.path.join(self.directory, 'foo')
        self.assertTrue(os.path.exists(filepath))
        with open(filepath, 'r') as f:
            read_data = f.read()
        self.assertEqual("""\
# Hello
- git: {local-name: git, uri: %s/some/uri2}
- svn: {local-name: ros, uri: %s/some/uri1}
""" % (self.directory, self.directory), read_data)
Пример #18
0
 def get_versioned_path_spec(self, fetch=False):
     "yaml looking up current version"
     version = self.version
     if version == '':
         version = None
     revision = None
     if version is not None:
         # revision is the UID of the version spec, can be them same
         revision = self._get_vcsc().get_version(self.version)
         if revision is None:
             sys.stderr.write("Warning: version '%s' not found for '%s'\n" %
                              (self.version, self.local_name))
     currevision = self._get_vcsc().get_version()
     remote_revision = self._get_vcsc().get_remote_version(fetch=fetch)
     curr_version = self._get_vcsc().get_current_version_label()
     uri = self.uri
     curr_uri = self._get_vcsc().get_url()
     # uri might be a shorthand notation equivalent to curr_uri
     if self._get_vcsc().url_matches(curr_uri, uri):
         curr_uri = uri
     return PathSpec(local_name=self.get_local_name(),
                     path=self.get_path(),
                     scmtype=self.get_vcs_type_name(),
                     uri=self.uri,
                     version=version,
                     curr_version=curr_version,
                     revision=revision,
                     currevision=currevision,
                     remote_revision=remote_revision,
                     curr_uri=curr_uri,
                     tags=self.get_properties())
Пример #19
0
 def test_generate_with_stack(self):
     def check_config_entries(self, lines, uuid):
         self.assertEqual(1, len(lines))
         self.assertEqual("- svn: {local-name: ros, uri: %s/some/uri}"
                          % self.directory, lines[0])
     self.helper(check_config_entries, {},
                 [PathSpec('ros', 'svn', 'some/uri')])
Пример #20
0
 def test_config_simple1(self):
     mock1 = PathSpec('foo')
     config = self._get_mock_config([mock1])
     self.assertEqual(1, len(config.get_config_elements()))
     self.assertEqual('foo',
                      config.get_config_elements()[0].get_local_name())
     self.assertEqual('/install/path/foo',
                      config.get_config_elements()[0].get_path())
Пример #21
0
    def test_config_simple1_with_setupfile(self):
        mock1 = PathSpec('setup.sh', tags='setup-file')
        config = self._get_mock_config([mock1])
        self.assertEqual(1, len(config.get_config_elements()))
        self.assertEqual('setup.sh',
                         config.get_config_elements()[0].get_local_name())
        self.assertEqual('/install/path/setup.sh',
                         config.get_config_elements()[0].get_path())

        mock1 = PathSpec('/foo')
        mock2 = PathSpec('/opt/setup.sh', tags='setup-file')
        mock3 = PathSpec('/bar')
        config = self._get_mock_config([mock1, mock2, mock3])
        self.assertEqual(3, len(config.get_config_elements()))
        self.assertEqual('/opt/setup.sh',
                         config.get_config_elements()[1].get_local_name())
        self.assertEqual('/opt/setup.sh',
                         config.get_config_elements()[1].get_path())
Пример #22
0
 def test_long_localname(self):
     "Should source choose shorter local-name"
     mock1 = PathSpec("/foo/bar/boo/far/bim")
     config = self._get_mock_config([mock1], '/foo/bar/boo/far')
     self.assertEqual(1, len(config.get_config_elements()))
     self.assertEqual('/foo/bar/boo/far/bim',
                      config.get_config_elements()[0].get_local_name())
     self.assertEqual('/foo/bar/boo/far/bim',
                      config.get_config_elements()[0].get_path())
Пример #23
0
 def test_unnormalized_localname(self):
     "Should source normalize local-name"
     mock1 = PathSpec('foo/bar/..')
     config = self._get_mock_config([mock1])
     self.assertEqual(1, len(config.get_config_elements()))
     self.assertEqual('foo',
                      config.get_config_elements()[0].get_local_name())
     self.assertEqual('/install/path/foo',
                      config.get_config_elements()[0].get_path())
Пример #24
0
 def test_absolute_localname(self):
     mock1 = PathSpec('/foo/bim')
     config = self._get_mock_config([mock1],
                                    install_path='/foo/bar/ba/ra/baz/bam')
     self.assertEqual(1, len(config.get_config_elements()))
     self.assertEqual('/foo/bim',
                      config.get_config_elements()[0].get_local_name())
     self.assertEqual('/foo/bim',
                      config.get_config_elements()[0].get_path())
Пример #25
0
    def test_generate_with_pretty_format(self):
        def check_config_entries(self, lines, uuid):
            self.assertEqual(3, len(lines))
            self.assertEqual('''\
- git:
    local-name: %s
    uri: %s\
''' % (self.git, self.uri), '\n'.join(lines))
        self.helper(check_config_entries, {'pretty': True},
                    [PathSpec(self.git, 'git', self.uri)])
Пример #26
0
    def test_config_realfolders(self):
        try:
            root_path = tempfile.mkdtemp()
            share_path = os.path.join(root_path, "share")
            os.makedirs(share_path)
            ros_path = os.path.join(share_path, "ros")
            os.makedirs(ros_path)

            p1 = PathSpec('share')
            p2 = PathSpec('share/ros')
            config = self._get_mock_config([p1, p2])
            self.assertEqual(2, len(config.get_config_elements()))
            try:
                p1 = PathSpec('share', 'git', 'git/uri', 'git.version')
                p2 = PathSpec('share/ros', 'hg', 'hg/uri', 'hg.version')
                config = self._get_mock_config([p1, p2])
                self.fail("expected overlap Exception")
            except MultiProjectException:
                pass
            try:
                p1 = PathSpec('share', 'git', 'git/uri', 'git.version')
                p2 = PathSpec('share/ros', 'hg', 'hg/uri', 'hg.version')
                config = self._get_mock_config([p2, p1])
                self.fail("expected overlap Exception")
            except MultiProjectException:
                pass
            try:
                p1 = PathSpec('share', 'git', 'git/uri', 'git.version')
                p2 = PathSpec('share/ros')
                config = self._get_mock_config([p2, p1])
                self.fail("expected overlap Exception")
            except MultiProjectException:
                pass
            try:
                p1 = PathSpec('share', 'git', 'git/uri', 'git.version')
                p2 = PathSpec('share/ros')
                config = self._get_mock_config([p1, p2])
                self.fail("expected overlap Exception")
            except MultiProjectException:
                pass
        finally:
            shutil.rmtree(root_path)
Пример #27
0
 def get_path_spec(self):
     "yaml as from source"
     version = self.version
     if version == '':
         version = None
     return PathSpec(local_name=self.get_local_name(),
                     path=self.get_path(),
                     scmtype=self.get_vcs_type_name(),
                     uri=self.uri,
                     version=version,
                     tags=self.get_properties())
Пример #28
0
 def test_generate_with_stack(self):
     self.directory = tempfile.mkdtemp()
     config = wstool.config.Config([PathSpec('ros', 'svn', 'some/uri')], self.directory)
     wstool.config_yaml.generate_config_yaml(config, 'foo', "# Hello\n")
     filepath = os.path.join(self.directory, 'foo')
     self.assertTrue(os.path.exists(filepath))
     with open(filepath, 'r') as f:
         read_data = f.read()
     lines = read_data.splitlines()
     self.assertEqual("# Hello", lines[0])
     self.assertEqual("- svn: {local-name: ros, uri: %s/some/uri}" % self.directory, lines[1])
Пример #29
0
 def test_init_fail(self):
     try:
         Config(None, "path", None)
         self.fail("expected Exception")
     except MultiProjectException:
         pass
     try:
         Config([PathSpec('foo', 'bar')], "path", None)
         self.fail("expected Exception")
     except MultiProjectException:
         pass
 def test_get_ros_stack_path(self):
     config = Config([
         PathSpec("foo"),
         PathSpec(os.path.join("test", "example_dirs", "ros_comm")),
         PathSpec(os.path.join("test", "example_dirs", "roscpp")),
         PathSpec("bar")
     ], ".", None)
     self.assertEqual(None, rosinstall.helpers.get_ros_stack_path(config))
     config = Config([
         PathSpec("foo"),
         PathSpec(os.path.join("test", "example_dirs", "ros_comm")),
         PathSpec(os.path.join("test", "example_dirs", "ros")),
         PathSpec(os.path.join("test", "example_dirs", "roscpp")),
         PathSpec("bar")
     ], ".", None)
     self.assertEqual(os.path.abspath("test/example_dirs/ros"),
                      rosinstall.helpers.get_ros_stack_path(config))