def test_pull_pip_dependencies(self): plugin = colcon.ColconPlugin("test-part", self.properties, self.project) os.makedirs(os.path.join(plugin.sourcedir, "src")) self.dependencies_mock.return_value = {"pip": {"foo", "bar", "baz"}} plugin.pull() self.assert_rosdep_setup( plugin.options.colcon_rosdistro, self.ros_version, os.path.join(plugin.sourcedir, "src"), os.path.join(plugin.partdir, "rosdep"), self.ubuntu_distro, plugin.project._get_build_base(), plugin.project._get_stage_packages_target_arch(), ) self.assert_pip_setup( "3", plugin.partdir, plugin.installdir, plugin.project.stage_dir ) # Verify that dependencies were found as expected. TODO: Would really # like to use ANY here instead of verifying explicit arguments, but # Python issue #25195 won't let me. self.assertThat(self.dependencies_mock.call_count, Equals(1)) self.assertThat(self.dependencies_mock.call_args[0][0], Equals({"my_package"})) # Verify that the pip dependencies were installed self.pip_mock.return_value.download.assert_called_once_with( {"foo", "bar", "baz"} ) self.pip_mock.return_value.install.assert_called_once_with( {"foo", "bar", "baz"} )
def test_source_setup_sh(self): plugin = colcon.ColconPlugin("test-part", self.properties, self.project) underlay = os.path.join( "test-root", "opt", "ros", plugin.options.colcon_rosdistro ) underlay_setup = os.path.join(underlay, "setup.sh") overlay = os.path.join("test-root", "opt", "ros", "snap") overlay_setup = os.path.join(overlay, "local_setup.sh") # Make sure $@ is zeroed, then setup.sh sourced, then $@ is restored lines_of_interest = [ "set --", 'if [ -f "{}" ]; then'.format(underlay_setup), '. "{}"'.format(underlay_setup), "fi", 'if [ -f "{}" ]; then'.format(overlay_setup), '. "{}"'.format(overlay_setup), "fi", 'eval "set -- $BACKUP_ARGS"', ] actual_lines = [] for line in plugin._source_setup_sh("test-root").split("\n"): line = line.strip() if line in lines_of_interest: actual_lines.append(line) self.assertThat( actual_lines, Equals(lines_of_interest), "Expected setups to be sourced after args were zeroed, followed by the " "args being restored.", )
def test_pull_local_dependencies(self): self.properties.colcon_packages.append("package_2") self.properties.source_subdir = "subdir" plugin = colcon.ColconPlugin("test-part", self.properties, self.project) os.makedirs(os.path.join(plugin.sourcedir, "subdir", "src")) # No system dependencies (only local) self.dependencies_mock.return_value = {} plugin.pull() self.assert_rosdep_setup( plugin.options.colcon_rosdistro, self.ros_version, os.path.join(plugin.sourcedir, "subdir", "src"), os.path.join(plugin.partdir, "rosdep"), self.ubuntu_distro, plugin.project._get_build_base(), plugin.project._get_stage_packages_target_arch(), ) # Verify that dependencies were found as expected. TODO: Would really # like to use ANY here instead of verifying explicit arguments, but # Python issue #25195 won't let me. self.assertThat(self.dependencies_mock.call_count, Equals(1)) self.assertThat( self.dependencies_mock.call_args[0][0], Equals({"my_package", "package_2"}) ) # Verify that no .deb packages were installed self.assertTrue( mock.call().unpack(plugin.installdir) not in self.ubuntu_mock.mock_calls )
def test_build_multiple( self, finish_build_mock, prepare_build_mock, run_output_mock, run_mock ): self.properties.colcon_packages.append("package_2") plugin = colcon.ColconPlugin("test-part", self.properties, self.project) os.makedirs(os.path.join(plugin.sourcedir, "src")) plugin.build() class check_pkg_arguments: def __init__(self, test): self.test = test def __eq__(self, args): index = args.index("--packages-select") packages = args[index + 1 : index + 3] self.test.assertIn("my_package", packages) self.test.assertIn("package_2", packages) return True run_mock.assert_called_with(check_pkg_arguments(self)) self.assertFalse( self.dependencies_mock.called, "Dependencies should have been discovered in the pull() step", ) finish_build_mock.assert_called_once_with()
def test_valid_colcon_workspace_src(self): # sourcedir is expected to be the root of the Colcon workspace. Since # it contains a 'src' directory, this is a valid Colcon workspace. plugin = colcon.ColconPlugin("test-part", self.properties, self.project) os.makedirs(os.path.join(plugin.sourcedir, "src")) # An exception will be raised if pull can't handle the valid workspace. plugin.pull()
def test_invalid_colcon_workspace_invalid_source_no_packages(self): """Test that an invalid source space is fine iff no packages.""" self.properties.colcon_source_space = "foo" self.properties.colcon_packages = [] plugin = colcon.ColconPlugin("test-part", self.properties, self.project) # Normally pulling should fail, but since there are no packages to # build, even an invalid workspace should be okay. plugin.pull()
def test_valid_colcon_workspace_source_space(self): self.properties.colcon_source_space = "foo" # sourcedir is expected to be the root of the Colcon workspace. # Normally this would mean it contained a `src` directory, but it can # be remapped via the `colcon-source-space` key. plugin = colcon.ColconPlugin("test-part", self.properties, self.project) os.makedirs(os.path.join(plugin.sourcedir, self.properties.colcon_source_space)) # An exception will be raised if pull can't handle the source space. plugin.pull()
def test_clean_pull(self): plugin = colcon.ColconPlugin("test-part", self.properties, self.project) os.makedirs(os.path.join(plugin.sourcedir, "src")) self.dependencies_mock.return_value = {"apt": {"foo", "bar", "baz"}} plugin.pull() os.makedirs(plugin._rosdep_path) plugin.clean_pull() self.assertFalse(os.path.exists(plugin._rosdep_path))
def test_eol_ros_distro_warning(self): self.properties.colcon_rosdistro = "crystal" fake_logger = fixtures.FakeLogger(level=logging.WARNING) self.useFixture(fake_logger) colcon.ColconPlugin("test-part", self.properties, self.project) self.assertThat( fake_logger.output, Contains( "The 'crystal' ROS distro has reached end-of-life and is no longer supported. Use at your own risk." ), )
def test_pull_debian_dependencies(self): plugin = colcon.ColconPlugin("test-part", self.properties, self.project) os.makedirs(os.path.join(plugin.sourcedir, "src")) self.dependencies_mock.return_value = {"apt": {"foo", "bar", "baz"}} plugin.pull() self.assert_rosdep_setup( plugin.options.colcon_rosdistro, self.ros_version, os.path.join(plugin.sourcedir, "src"), os.path.join(plugin.partdir, "rosdep"), self.ubuntu_distro, plugin.project._get_build_base(), plugin.project._get_stage_packages_target_arch(), ) # Verify that dependencies were found as expected. TODO: Would really # like to use ANY here instead of verifying explicit arguments, but # Python issue #25195 won't let me. self.assertThat(self.dependencies_mock.call_count, Equals(1)) self.assertThat(self.dependencies_mock.call_args[0][0], Equals({"my_package"})) # Verify that the dependencies were installed self.assertThat( self.ubuntu_mock.fetch_stage_packages.mock_calls, Equals( [ mock.call( stage_packages_path=plugin.stage_packages_path, package_names={"bar", "baz", "foo"}, base=plugin.project._get_build_base(), target_arch=plugin.project._get_stage_packages_target_arch(), ) ] ), ) self.assertThat( self.ubuntu_mock.unpack_stage_packages.mock_calls, Equals( [ mock.call( stage_packages_path=plugin.stage_packages_path, install_path=pathlib.Path(plugin.installdir), ) ] ), )
def test_invalid_colcon_workspace_no_src(self): # sourcedir is expected to be the root of the Colcon workspace. Since # it does not contain a `src` folder and `source-space` is 'src', this # should fail. plugin = colcon.ColconPlugin("test-part", self.properties, self.project) raised = self.assertRaises(colcon.ColconPackagePathNotFoundError, plugin.pull) self.assertThat( str(raised), Equals( "Failed to find package path: {!r}".format( os.path.join(plugin.sourcedir, "src") ) ), )
def test_invalid_colcon_workspace_invalid_source_space(self): self.properties.colcon_source_space = "foo" # sourcedir is expected to be the root of the Colcon workspace. Since # it does not contain a `src` folder and source_space wasn't # specified, this should fail. plugin = colcon.ColconPlugin("test-part", self.properties, self.project) raised = self.assertRaises(colcon.ColconPackagePathNotFoundError, plugin.pull) self.assertThat( str(raised), Equals( "Failed to find package path: {!r}".format( os.path.join(plugin.sourcedir, self.properties.colcon_source_space) ) ), )
def test_pull_invalid_dependency(self): plugin = colcon.ColconPlugin("test-part", self.properties, self.project) os.makedirs(os.path.join(plugin.sourcedir, "src")) self.dependencies_mock.return_value = {"apt": {"foo"}} self.ubuntu_mock.fetch_stage_packages.side_effect = ( repo.errors.PackageNotFoundError("foo") ) raised = self.assertRaises(colcon.ColconAptDependencyFetchError, plugin.pull) self.assertThat( str(raised), Equals( "Failed to fetch apt dependencies: The package 'foo' was not found." ), )
def test_run_environment(self, run_mock): plugin = colcon.ColconPlugin("test-part", self.properties, self.project) with mock.patch.object( plugin, "_source_setup_sh", wraps=plugin._source_setup_sh ) as sh_mock: # Joining and re-splitting to get hacked script in there as well environment = "\n".join(plugin.env(plugin.installdir)).split("\n") sh_mock.assert_called_with(plugin.installdir) underlay_setup = os.path.join(plugin.options.colcon_rosdistro, "setup.sh") overlay_setup = os.path.join("snap", "local_setup.sh") # Verify that the python executables and root are set before any setup.sh is # sourced. Also verify that the underlay setup is sourced before the overlay. ament_python_index = [ i for i, line in enumerate(environment) if "AMENT_PYTHON_EXECUTABLE" in line ][0] colcon_python_index = [ i for i, line in enumerate(environment) if "COLCON_PYTHON_EXECUTABLE" in line ][0] root_index = [ i for i, line in enumerate(environment) if "SNAP_COLCON_ROOT" in line ][0] underlay_source_setup_index = [ i for i, line in enumerate(environment) if underlay_setup in line ][0] overlay_source_setup_index = [ i for i, line in enumerate(environment) if overlay_setup in line ][0] self.assertThat(ament_python_index, LessThan(underlay_source_setup_index)) self.assertThat(colcon_python_index, LessThan(underlay_source_setup_index)) self.assertThat(root_index, LessThan(underlay_source_setup_index)) self.assertThat( underlay_source_setup_index, LessThan(overlay_source_setup_index) )
def setUp(self): super().setUp() self.plugin = colcon.ColconPlugin("test-part", self.properties, self.project)
def test_build( self, finish_build_mock, prepare_build_mock, run_output_mock, run_mock, tmp_work_path, project, options, disable_parallel, build_attributes, colcon_packages_ignore, colcon_ament_cmake_args, colcon_catkin_cmake_args, colcon_cmake_args, colcon_packages, ): options.colcon_packages = colcon_packages options.colcon_packages_ignore = colcon_packages_ignore options.build_attributes.extend(build_attributes) options.colcon_cmake_args = colcon_cmake_args options.colcon_catkin_cmake_args = colcon_catkin_cmake_args options.colcon_ament_cmake_args = colcon_ament_cmake_args options.disable_parallel = disable_parallel plugin = colcon.ColconPlugin("test-part", options, project) os.makedirs(os.path.join(plugin.sourcedir, "src")) plugin.build() prepare_build_mock.assert_called_once_with() if "debug" in build_attributes: build_type = "Debug" else: build_type = "Release" expected_command = ["colcon", "build", "--merge-install"] if colcon_packages: expected_command += ["--packages-select"] + colcon_packages if colcon_packages_ignore: expected_command += ["--packages-ignore"] + colcon_packages_ignore expected_command += [ "--build-base", plugin.builddir, "--base-paths", f"{plugin.sourcedir}/src", "--install-base", f"{plugin.installdir}/opt/ros/snap", "--parallel-workers={}".format(1 if disable_parallel else 2), "--cmake-args", f"-DCMAKE_BUILD_TYPE={build_type}", ] if colcon_cmake_args: expected_command += ["-DCMAKE"] if colcon_catkin_cmake_args: expected_command += ["--catkin-cmake-args", "-DCATKIN"] if colcon_ament_cmake_args: expected_command += ["--ament-cmake-args", "-DAMENT"] if colcon_packages or colcon_packages is None: assert run_mock.mock_calls[0][1][0] == expected_command else: run_mock.assert_not_called() finish_build_mock.assert_called_once_with()