import os from sqlalchemy import select from galaxy.model import Dataset from galaxy_test.base import api_asserts from galaxy_test.base.populators import DatasetPopulator from galaxy_test.driver import integration_util from galaxy_test.driver.integration_setup import ( GROUP_A, GROUP_B, PosixFileSourceSetup, REQUIRED_GROUP_EXPRESSION, REQUIRED_ROLE_EXPRESSION, ) class TestPosixFileSourceIntegration(PosixFileSourceSetup, integration_util.IntegrationTestCase): dataset_populator: DatasetPopulator required_role_expression = REQUIRED_ROLE_EXPRESSION required_group_expression = REQUIRED_GROUP_EXPRESSION def setUp(self): super().setUp() self._write_file_fixtures() self.dataset_populator = DatasetPopulator(self.galaxy_interactor) def test_plugin_config(self): # Default user has required role but not required group, so cannot see plugin plugin_config_response = self.galaxy_interactor.get("remote_files/plugins") api_asserts.assert_status_code_is_ok(plugin_config_response) plugins = plugin_config_response.json() assert len(plugins) == 0 # Admins can see plugins plugin_config_response = self.galaxy_interactor.get("remote_files/plugins", admin=True) api_asserts.assert_status_code_is_ok(plugin_config_response) plugins = plugin_config_response.json() assert len(plugins) == 1 assert plugins[0]["type"] == "posix" assert plugins[0]["uri_root"] == "gxfiles://posix_test" assert plugins[0]["writable"] is True assert plugins[0]["requires_roles"] == REQUIRED_ROLE_EXPRESSION assert plugins[0]["requires_groups"] == REQUIRED_GROUP_EXPRESSION def test_allow_admin_access(self): data = {"target": "gxfiles://posix_test"} list_response = self.galaxy_interactor.get("remote_files", data, admin=True) self._assert_list_response_matches_fixtures(list_response) def test_user_access(self): data = {"target": "gxfiles://posix_test"} group_a_id = self._create_group(GROUP_A) group_b_id = self._create_group(GROUP_B) # User has role but not group list_response = self.galaxy_interactor.get("remote_files", data) self._assert_access_forbidden_response(list_response) # User has role and group A user_id = self.dataset_populator.user_id() self._add_user_to_group(group_a_id, user_id) list_response = self.galaxy_interactor.get("remote_files", data) self._assert_list_response_matches_fixtures(list_response) # Remove User from group A and add to group B self._remove_user_from_group(group_a_id, user_id) self._add_user_to_group(group_b_id, user_id) list_response = self.galaxy_interactor.get("remote_files", data) self._assert_list_response_matches_fixtures(list_response) def _create_group(self, group_name: str): payload = { "name": group_name, "user_ids": [], } response = self._post("groups", payload, admin=True, json=True) self._assert_status_code_is(response, 200) group = response.json()[0] # POST /api/groups returns a list return group["id"] def _add_user_to_group(self, group_id, user_id): update_response = self._put(f"groups/{group_id}/users/{user_id}", admin=True) self._assert_status_code_is_ok(update_response) def _remove_user_from_group(self, group_id, user_id): update_response = self._delete(f"groups/{group_id}/users/{user_id}", admin=True) self._assert_status_code_is_ok(update_response) def _assert_list_response_matches_fixtures(self, list_response): api_asserts.assert_status_code_is_ok(list_response) remote_files = list_response.json() assert len(remote_files) == 2 if remote_files[0]["class"] == "Directory": dir = remote_files[0] file = remote_files[1] else: dir = remote_files[1] file = remote_files[0] assert file["name"] == "a" assert dir["name"] == "subdir1" def _assert_access_forbidden_response(self, response): api_asserts.assert_status_code_is(response, 403) class TestPreferLinksPosixFileSourceIntegration(PosixFileSourceSetup, integration_util.IntegrationTestCase): dataset_populator: DatasetPopulator framework_tool_and_types = True prefer_links = True def setUp(self): super().setUp() self._write_file_fixtures() self.dataset_populator = DatasetPopulator(self.galaxy_interactor) def test_links_by_default(self): with self.dataset_populator.test_history() as history_id: element = dict(src="url", url="gxfiles://linking_source/a") target = { "destination": {"type": "hdas"}, "elements": [element], } targets = [target] payload = { "history_id": history_id, "targets": targets, } new_dataset = self.dataset_populator.fetch(payload, assert_ok=True).json()["outputs"][0] content = self.dataset_populator.get_history_dataset_content(history_id, dataset=new_dataset) assert content == "a\n", content stmt = select(Dataset).order_by(Dataset.create_time.desc()).limit(1) dataset = self._app.model.session.execute(stmt).unique().scalar_one() assert dataset.external_filename is not None assert dataset.external_filename.endswith("/root/a") assert os.path.exists(dataset.external_filename) assert open(dataset.external_filename).read() == "a\n" payload = self.dataset_populator.run_tool( tool_id="cat", inputs={ "input1": {"src": "hda", "id": new_dataset["id"]}, }, history_id=history_id, ) derived_dataset = payload["outputs"][0] self.dataset_populator.wait_for_history(history_id, assert_ok=True) derived_content = self.dataset_populator.get_history_dataset_content(history_id, dataset=derived_dataset) assert derived_content.strip() == "a"