diff --git a/.ci/autopep8.sh b/.ci/autopep8.sh deleted file mode 100755 index 22c385c425b..00000000000 --- a/.ci/autopep8.sh +++ /dev/null @@ -1,2 +0,0 @@ -exclude=$(sed -e 's|^|./|' -e 's|/$||' .ci/flake8_ignorelist.txt | paste -s -d ',' - ) -autopep8 -i -r --exclude $exclude --select E11,E101,E127,E201,E202,E22,E301,E302,E303,E304,E306,E711,W291,W292,W293,W391 ./lib/ ./test/ diff --git a/.ci/check_py3_compatibility.sh b/.ci/check_py3_compatibility.sh deleted file mode 100755 index e275c0d1b68..00000000000 --- a/.ci/check_py3_compatibility.sh +++ /dev/null @@ -1,35 +0,0 @@ -#!/bin/sh - -if command -v ack-grep >/dev/null; then - ACK=ack-grep -else - ACK=ack -fi - - -PYTHON2_ONLY_MODULES="__builtin__ _winreg BaseHTTPServer CGIHTTPServer \ -ConfigParser Cookie cookielib copy_reg cPickle cStringIO Dialog dummy_thread \ -FileDialog gdbm htmlentitydefs HTMLParser httplib Queue robotparser \ -ScrolledText SimpleDialog SimpleHTTPServer SimpleXMLRPCServer SocketServer \ -StringIO thread Tix tkColorChooser tkCommonDialog Tkconstants Tkdnd tkFont \ -Tkinter tkFileDialog tkMessageBox tkSimpleDialog ttk urllib urllib2 urlparse \ -xmlrpclib" - -ret=0 -for mod in $PYTHON2_ONLY_MODULES; do - $ACK --type python \ - --ignore-dir=.git \ - --ignore-dir=.tox \ - --ignore-dir=.venv \ - --ignore-dir=.venv3 \ - --ignore-dir=client/node_modules \ - --ignore-dir=database \ - --ignore-dir=doc/build \ - --ignore-dir=eggs \ - --ignore-dir=static/maps \ - --ignore-dir=static/scripts \ - "^import $mod(\n|\.)|^from $mod import " - if [ $? -eq 0 ]; then ret=1; fi -done - -exit $ret diff --git a/.ci/check_test_class_names.sh b/.ci/check_test_class_names.sh new file mode 100755 index 00000000000..76bf70057a3 --- /dev/null +++ b/.ci/check_test_class_names.sh @@ -0,0 +1,7 @@ +#!/bin/sh +n_tests=$(pytest --collect-only --ignore=test/functional lib/galaxy_test/ test/ | grep 'tests collected' | sed -e 's/[^0-9]*\([0-9]*\) tests collected.*/\1/') +n_tests_extra_classes=$(pytest -o python_classes='Test* *Test *TestCase' --collect-only --ignore=test/functional lib/galaxy_test/ test/ | grep 'tests collected' | sed -e 's/[^0-9]*\([0-9]*\) tests collected.*/\1/') +if [ "$n_tests_extra_classes" -gt "$n_tests" ]; then + echo "New test class with name not starting with Test introduced, change it to have tests collected by pytest" + exit 1 +fi diff --git a/.github/workflows/check_test_class_names.yaml b/.github/workflows/check_test_class_names.yaml new file mode 100644 index 00000000000..92db607c7bd --- /dev/null +++ b/.github/workflows/check_test_class_names.yaml @@ -0,0 +1,28 @@ +name: Check test class names +on: + pull_request: + paths: + - '.ci/check_test_class_names.sh' + - 'lib/galaxy_test/**' + - 'test/**' +jobs: + test: + name: Test + runs-on: ubuntu-latest + strategy: + matrix: + python-version: ['3.7'] + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-python@v4 + with: + python-version: ${{ matrix.python-version }} + - name: Cache pip dir + uses: actions/cache@v3 + with: + path: ~/.cache/pip + key: pip-cache-${{ matrix.python-version }}-${{ hashFiles('requirements.txt') }} + - name: Install Python dependencies + run: pip install -r requirements.txt -r lib/galaxy/dependencies/dev-requirements.txt + - name: Run tests + run: .ci/check_test_class_names.sh diff --git a/Makefile b/Makefile index 1d953e0a959..f50dbf59886 100644 --- a/Makefile +++ b/Makefile @@ -47,9 +47,6 @@ format: ## Format Python code base remove-unused-imports: ## Remove unused imports in Python code base $(IN_VENV) autoflake --in-place --remove-all-unused-imports --recursive --verbose lib/ test/ -list-dependency-updates: setup-venv - $(IN_VENV) pip list --outdated --format=columns - docs-slides-ready: test -f plantuml.jar || wget http://jaist.dl.sourceforge.net/project/plantuml/plantuml.jar java -jar plantuml.jar -c $(DOC_SOURCE_DIR)/slideshow/architecture/images/plantuml_options.txt -tsvg $(SLIDESHOW_DIR)/architecture/images/ *.plantuml.txt diff --git a/doc/source/dev/run_tests_help.txt b/doc/source/dev/run_tests_help.txt index 2b6f28c4704..4e002913339 100644 --- a/doc/source/dev/run_tests_help.txt +++ b/doc/source/dev/run_tests_help.txt @@ -233,9 +233,6 @@ GALAXY_TEST_TOOL_PATH Path defaulting to 'tools'. GALAXY_TEST_SHED_TOOL_CONF Shed toolbox conf (defaults to config/shed_tool_conf.xml) used when testing installed to tools with -installed. -GALAXY_TEST_HISTORY_ID Some tests can target existing history ids, this option - is fairly limited and not compatible with parrallel testing - so should be limited to debugging one off tests. TOOL_SHED_TEST_HOST Host to use for shed server setup for testing. TOOL_SHED_TEST_PORT Port to use for shed server setup for testing. TOOL_SHED_TEST_FILE_DIR Defaults to lib/tool_shed/test/test_data. diff --git a/lib/galaxy_test/api/_framework.py b/lib/galaxy_test/api/_framework.py index ca11b660573..83f899088da 100644 --- a/lib/galaxy_test/api/_framework.py +++ b/lib/galaxy_test/api/_framework.py @@ -1,10 +1,16 @@ -from typing import Optional +from typing import ( + Iterator, + Optional, +) from unittest import SkipTest +import pytest + from galaxy_test.base.api import ( UsesApiTestCaseMixin, UsesCeleryTasks, ) +from galaxy_test.base.populators import DatasetPopulator from galaxy_test.base.testcase import FunctionalTestCase try: @@ -18,6 +24,7 @@ except ImportError: class ApiTestCase(FunctionalTestCase, UsesApiTestCaseMixin, UsesCeleryTasks): galaxy_driver_class = GalaxyTestDriver _test_driver: Optional[GalaxyTestDriver] + dataset_populator: Optional[DatasetPopulator] def setUp(self): super().setUp() @@ -28,5 +35,11 @@ class ApiTestCase(FunctionalTestCase, UsesApiTestCaseMixin, UsesCeleryTasks): raise SkipTest("This test does not work with remote Galaxy instances.") return self._test_driver + @pytest.fixture + def history_id(self) -> Iterator[str]: + assert self.dataset_populator + with self.dataset_populator.test_history() as history_id: + yield history_id + __all__ = ("ApiTestCase",) diff --git a/lib/galaxy_test/api/test_dataset_collections.py b/lib/galaxy_test/api/test_dataset_collections.py index e8b66a41583..1a92862e595 100644 --- a/lib/galaxy_test/api/test_dataset_collections.py +++ b/lib/galaxy_test/api/test_dataset_collections.py @@ -12,17 +12,16 @@ from ._framework import ApiTestCase class TestDatasetCollectionsApi(ApiTestCase): - history_id: str + dataset_populator: DatasetPopulator def setUp(self): super().setUp() self.dataset_populator = DatasetPopulator(self.galaxy_interactor) self.dataset_collection_populator = DatasetCollectionPopulator(self.galaxy_interactor) - self.history_id = self.dataset_populator.new_history() - def test_create_pair_from_history(self): + def test_create_pair_from_history(self, history_id): payload = self.dataset_collection_populator.create_pair_payload( - self.history_id, + history_id, instance_type="history", ) create_response = self.dataset_populator.fetch(payload, wait=True) @@ -30,12 +29,12 @@ class TestDatasetCollectionsApi(ApiTestCase): returned_datasets = dataset_collection["elements"] assert len(returned_datasets) == 2, dataset_collection - def test_create_list_from_history(self): - element_identifiers = self.dataset_collection_populator.list_identifiers(self.history_id) + def test_create_list_from_history(self, history_id): + element_identifiers = self.dataset_collection_populator.list_identifiers(history_id) payload = dict( instance_type="history", - history_id=self.history_id, + history_id=history_id, element_identifiers=element_identifiers, collection_type="list", ) @@ -45,9 +44,9 @@ class TestDatasetCollectionsApi(ApiTestCase): returned_datasets = dataset_collection["elements"] assert len(returned_datasets) == 3, dataset_collection - def test_create_list_of_existing_pairs(self): + def test_create_list_of_existing_pairs(self, history_id): pair_payload = self.dataset_collection_populator.create_pair_payload( - self.history_id, + history_id, instance_type="history", ) pair_create_response = self._post("tools/fetch", pair_payload, json=True) @@ -58,7 +57,7 @@ class TestDatasetCollectionsApi(ApiTestCase): payload = dict( instance_type="history", - history_id=self.history_id, + history_id=history_id, element_identifiers=element_identifiers, collection_type="list", ) @@ -67,12 +66,12 @@ class TestDatasetCollectionsApi(ApiTestCase): returned_collections = dataset_collection["elements"] assert len(returned_collections) == 1, dataset_collection - def test_create_list_of_new_pairs(self): - identifiers = self.dataset_collection_populator.nested_collection_identifiers(self.history_id, "list:paired") + def test_create_list_of_new_pairs(self, history_id): + identifiers = self.dataset_collection_populator.nested_collection_identifiers(history_id, "list:paired") payload = dict( collection_type="list:paired", instance_type="history", - history_id=self.history_id, + history_id=history_id, name="a nested collection", element_identifiers=identifiers, ) @@ -95,16 +94,12 @@ class TestDatasetCollectionsApi(ApiTestCase): pair_1_element_1 = pair_elements[0] assert pair_1_element_1["element_index"] == 0 - def test_list_download(self): - fetch_response = self.dataset_collection_populator.create_list_in_history( - self.history_id, direct_upload=True - ).json() + def test_list_download(self, history_id): + fetch_response = self.dataset_collection_populator.create_list_in_history(history_id, direct_upload=True).json() dataset_collection = self.dataset_collection_populator.wait_for_fetched_collection(fetch_response) returned_dce = dataset_collection["elements"] assert len(returned_dce) == 3, dataset_collection - create_response = self._download_dataset_collection( - history_id=self.history_id, hdca_id=dataset_collection["id"] - ) + create_response = self._download_dataset_collection(history_id=history_id, hdca_id=dataset_collection["id"]) self._assert_status_code_is(create_response, 200) archive = zipfile.ZipFile(BytesIO(create_response.content)) namelist = archive.namelist() @@ -113,15 +108,13 @@ class TestDatasetCollectionsApi(ApiTestCase): for element, zip_path in zip(returned_dce, namelist): assert f"{collection_name}/{element['element_identifier']}.{element['object']['file_ext']}" == zip_path - def test_pair_download(self): - fetch_response = self.dataset_collection_populator.create_pair_in_history( - self.history_id, direct_upload=True - ).json() + def test_pair_download(self, history_id): + fetch_response = self.dataset_collection_populator.create_pair_in_history(history_id, direct_upload=True).json() dataset_collection = self.dataset_collection_populator.wait_for_fetched_collection(fetch_response) returned_dce = dataset_collection["elements"] assert len(returned_dce) == 2, dataset_collection hdca_id = dataset_collection["id"] - create_response = self._download_dataset_collection(history_id=self.history_id, hdca_id=hdca_id) + create_response = self._download_dataset_collection(history_id=history_id, hdca_id=hdca_id) self._assert_status_code_is(create_response, 200) archive = zipfile.ZipFile(BytesIO(create_response.content)) namelist = archive.namelist() @@ -130,16 +123,14 @@ class TestDatasetCollectionsApi(ApiTestCase): for element, zip_path in zip(returned_dce, namelist): assert f"{collection_name}/{element['element_identifier']}.{element['object']['file_ext']}" == zip_path - def test_list_pair_download(self): - fetch_response = self.dataset_collection_populator.create_list_of_pairs_in_history(self.history_id).json() + def test_list_pair_download(self, history_id): + fetch_response = self.dataset_collection_populator.create_list_of_pairs_in_history(history_id).json() dataset_collection = self.dataset_collection_populator.wait_for_fetched_collection(fetch_response) returned_dce = dataset_collection["elements"] assert len(returned_dce) == 1, dataset_collection list_collection_name = dataset_collection["name"] pair = returned_dce[0] - create_response = self._download_dataset_collection( - history_id=self.history_id, hdca_id=dataset_collection["id"] - ) + create_response = self._download_dataset_collection(history_id=history_id, hdca_id=dataset_collection["id"]) self._assert_status_code_is(create_response, 200) archive = zipfile.ZipFile(BytesIO(create_response.content)) namelist = archive.namelist() @@ -151,39 +142,35 @@ class TestDatasetCollectionsApi(ApiTestCase): == zip_path ) - def test_list_list_download(self): + def test_list_list_download(self, history_id): dataset_collection = self.dataset_collection_populator.create_list_of_list_in_history( - self.history_id, wait=True + history_id, wait=True ).json() returned_dce = dataset_collection["elements"] assert len(returned_dce) == 1, dataset_collection - create_response = self._download_dataset_collection( - history_id=self.history_id, hdca_id=dataset_collection["id"] - ) + create_response = self._download_dataset_collection(history_id=history_id, hdca_id=dataset_collection["id"]) self._assert_status_code_is(create_response, 200) archive = zipfile.ZipFile(BytesIO(create_response.content)) namelist = archive.namelist() assert len(namelist) == 3, f"Expected 3 elements in [{namelist}]" - def test_list_list_list_download(self): + def test_list_list_list_download(self, history_id): dataset_collection = self.dataset_collection_populator.create_list_of_list_in_history( - self.history_id, + history_id, collection_type="list:list:list", wait=True, ).json() returned_dce = dataset_collection["elements"] assert len(returned_dce) == 1, dataset_collection - create_response = self._download_dataset_collection( - history_id=self.history_id, hdca_id=dataset_collection["id"] - ) + create_response = self._download_dataset_collection(history_id=history_id, hdca_id=dataset_collection["id"]) self._assert_status_code_is(create_response, 200) archive = zipfile.ZipFile(BytesIO(create_response.content)) namelist = archive.namelist() assert len(namelist) == 3, f"Expected 3 elements in [{namelist}]" - def test_hda_security(self): - element_identifiers = self.dataset_collection_populator.pair_identifiers(self.history_id) - self.dataset_populator.make_private(self.history_id, element_identifiers[0]["id"]) + def test_hda_security(self, history_id): + element_identifiers = self.dataset_collection_populator.pair_identifiers(history_id) + self.dataset_populator.make_private(history_id, element_identifiers[0]["id"]) with self._different_user(): history_id = self.dataset_populator.new_history() payload = dict( @@ -195,12 +182,12 @@ class TestDatasetCollectionsApi(ApiTestCase): create_response = self._post("dataset_collections", payload, json=True) self._assert_status_code_is(create_response, 403) - def test_enforces_unique_names(self): - element_identifiers = self.dataset_collection_populator.list_identifiers(self.history_id) + def test_enforces_unique_names(self, history_id): + element_identifiers = self.dataset_collection_populator.list_identifiers(history_id) element_identifiers[2]["name"] = element_identifiers[0]["name"] payload = dict( instance_type="history", - history_id=self.history_id, + history_id=history_id, element_identifiers=element_identifiers, collection_type="list", ) @@ -208,7 +195,7 @@ class TestDatasetCollectionsApi(ApiTestCase): create_response = self._post("dataset_collections", payload, json=True) self._assert_status_code_is(create_response, 400) - def test_upload_collection(self): + def test_upload_collection(self, history_id): elements = [ { "src": "files", @@ -227,12 +214,12 @@ class TestDatasetCollectionsApi(ApiTestCase): } ] payload = { - "history_id": self.history_id, + "history_id": history_id, "targets": targets, "__files": {"files_0|file_data": open(self.test_data_resolver.get_filename("4.bed"))}, } self.dataset_populator.fetch(payload) - hdca = self._assert_one_collection_created_in_history() + hdca = self._assert_one_collection_created_in_history(history_id) assert hdca["name"] == "Test upload" hdca_tags = hdca["tags"] assert len(hdca_tags) == 1 @@ -245,7 +232,7 @@ class TestDatasetCollectionsApi(ApiTestCase): dataset_tags = dataset0["tags"] assert len(dataset_tags) == 3, dataset0 - def test_upload_nested(self): + def test_upload_nested(self, history_id): elements = [{"name": "samp1", "elements": [{"src": "files", "dbkey": "hg19", "info": "my cool bed"}]}] targets = [ { @@ -256,19 +243,19 @@ class TestDatasetCollectionsApi(ApiTestCase): } ] payload = { - "history_id": self.history_id, + "history_id": history_id, "targets": targets, "__files": {"files_0|file_data": open(self.test_data_resolver.get_filename("4.bed"))}, } self.dataset_populator.fetch(payload) - hdca = self._assert_one_collection_created_in_history() + hdca = self._assert_one_collection_created_in_history(history_id) assert hdca["name"] == "Test upload" assert len(hdca["elements"]) == 1, hdca element0 = hdca["elements"][0] assert element0["element_identifier"] == "samp1" @skip_if_github_down - def test_upload_collection_from_url(self): + def test_upload_collection_from_url(self, history_id): elements = [ { "src": "url", @@ -284,17 +271,17 @@ class TestDatasetCollectionsApi(ApiTestCase): } ] payload = { - "history_id": self.history_id, + "history_id": history_id, "targets": targets, } self.dataset_populator.fetch(payload) - hdca = self._assert_one_collection_created_in_history() + hdca = self._assert_one_collection_created_in_history(history_id) assert len(hdca["elements"]) == 1, hdca element0 = hdca["elements"][0] assert element0["element_identifier"] == "4.bed" assert element0["object"]["file_size"] == 61 - def test_upload_collection_deferred(self): + def test_upload_collection_deferred(self, history_id): elements = [ { "src": "url", @@ -311,11 +298,11 @@ class TestDatasetCollectionsApi(ApiTestCase): } ] payload = { - "history_id": self.history_id, + "history_id": history_id, "targets": targets, } self.dataset_populator.fetch(payload) - hdca = self._assert_one_collection_created_in_history() + hdca = self._assert_one_collection_created_in_history(history_id) assert len(hdca["elements"]) == 1, hdca element0 = hdca["elements"][0] assert element0["element_identifier"] == "4.bed" @@ -323,7 +310,7 @@ class TestDatasetCollectionsApi(ApiTestCase): assert object0["state"] == "deferred" @skip_if_github_down - def test_upload_collection_failed_expansion_url(self): + def test_upload_collection_failed_expansion_url(self, history_id): targets = [ { "destination": {"type": "hdca"}, @@ -334,23 +321,23 @@ class TestDatasetCollectionsApi(ApiTestCase): } ] payload = { - "history_id": self.history_id, + "history_id": history_id, "targets": targets, } self.dataset_populator.fetch(payload, assert_ok=False, wait=True) - hdca = self._assert_one_collection_created_in_history() + hdca = self._assert_one_collection_created_in_history(history_id) assert hdca["populated"] is False assert "bagit.txt" in hdca["populated_state_message"], hdca - def _assert_one_collection_created_in_history(self): - contents_response = self._get(f"histories/{self.history_id}/contents/dataset_collections") + def _assert_one_collection_created_in_history(self, history_id: str): + contents_response = self._get(f"histories/{history_id}/contents/dataset_collections") self._assert_status_code_is(contents_response, 200) contents = contents_response.json() assert len(contents) == 1 hdca = contents[0] assert hdca["history_content_type"] == "dataset_collection" hdca_id = hdca["id"] - collection_response = self._get(f"histories/{self.history_id}/contents/dataset_collections/{hdca_id}") + collection_response = self._get(f"histories/{history_id}/contents/dataset_collections/{hdca_id}") self._assert_status_code_is(collection_response, 200) return collection_response.json() @@ -364,19 +351,19 @@ class TestDatasetCollectionsApi(ApiTestCase): self._assert_has_keys(dataset_collection, "elements", "url", "name", "collection_type", "element_count") return dataset_collection - def _download_dataset_collection(self, history_id, hdca_id): + def _download_dataset_collection(self, history_id: str, hdca_id: str): return self._get(f"histories/{history_id}/contents/dataset_collections/{hdca_id}/download") - def test_collection_contents_security(self): + def test_collection_contents_security(self, history_id): # request contents on an hdca that doesn't belong to user - hdca, contents_url = self._create_collection_contents_pair() + hdca, contents_url = self._create_collection_contents_pair(history_id) with self._different_user(): contents_response = self._get(contents_url) self._assert_status_code_is(contents_response, 403) - def test_collection_contents_invalid_collection(self): + def test_collection_contents_invalid_collection(self, history_id): # request an invalid collection from a valid hdca, should get 404 - hdca, contents_url = self._create_collection_contents_pair() + hdca, contents_url = self._create_collection_contents_pair(history_id) response = self._get(contents_url) self._assert_status_code_is(response, 200) fake_collection_id = "5d7db0757a2eb7ef" @@ -384,10 +371,8 @@ class TestDatasetCollectionsApi(ApiTestCase): error_response = self._get(fake_contents_url) assert_object_id_error(error_response) - def test_show_dataset_collection(self): - fetch_response = self.dataset_collection_populator.create_list_in_history( - self.history_id, direct_upload=True - ).json() + def test_show_dataset_collection(self, history_id): + fetch_response = self.dataset_collection_populator.create_list_in_history(history_id, direct_upload=True).json() dataset_collection = self.dataset_collection_populator.wait_for_fetched_collection(fetch_response) returned_dce = dataset_collection["elements"] assert len(returned_dce) == 3, dataset_collection @@ -397,12 +382,12 @@ class TestDatasetCollectionsApi(ApiTestCase): assert dataset_collection["id"] == hdca_id assert dataset_collection["collection_type"] == "list" - def test_show_dataset_collection_contents(self): + def test_show_dataset_collection_contents(self, history_id): # Get contents_url from history contents, use it to show the first level # of collection contents in the created HDCA, then use it again to drill # down into the nested collection contents - hdca = self.dataset_collection_populator.create_list_of_list_in_history(self.history_id).json() - root_contents_url = self._get_contents_url_for_hdca(hdca) + hdca = self.dataset_collection_populator.create_list_of_list_in_history(history_id).json() + root_contents_url = self._get_contents_url_for_hdca(history_id, hdca) # check root contents for this collection root_contents = self._get(root_contents_url).json() @@ -417,9 +402,9 @@ class TestDatasetCollectionsApi(ApiTestCase): assert len(drill_contents) == len(hdca["elements"][0]["object"]["elements"]) self._compare_collection_contents_elements(drill_contents, hdca["elements"][0]["object"]["elements"]) - def test_collection_contents_limit_offset(self): + def test_collection_contents_limit_offset(self, history_id): # check limit/offset params for collection contents endpoint - hdca, root_contents_url = self._create_collection_contents_pair() + hdca, root_contents_url = self._create_collection_contents_pair(history_id) # check limit limited_contents = self._get(f"{root_contents_url}?limit=1").json() @@ -431,9 +416,9 @@ class TestDatasetCollectionsApi(ApiTestCase): assert len(offset_contents) == 1 assert offset_contents[0]["element_index"] == 1 - def test_collection_contents_empty_root(self): + def test_collection_contents_empty_root(self, history_id): create_response = self.dataset_collection_populator.create_list_in_history( - self.history_id, contents=[], wait=True + history_id, contents=[], wait=True ).json() hdca = create_response["output_collections"][0] assert hdca["elements"] == [] @@ -442,9 +427,9 @@ class TestDatasetCollectionsApi(ApiTestCase): response.raise_for_status() assert response.json() == [] - def test_get_suitable_converters_single_datatype(self): + def test_get_suitable_converters_single_datatype(self, history_id): response = self.dataset_collection_populator.upload_collection( - self.history_id, + history_id, "list:paired", elements=[ { @@ -486,9 +471,9 @@ class TestDatasetCollectionsApi(ApiTestCase): not missing_expected_converters ), f"Expected converter(s) {', '.join(missing_expected_converters)} missing from response" - def test_get_suitable_converters_different_datatypes_matches(self): + def test_get_suitable_converters_different_datatypes_matches(self, history_id): response = self.dataset_collection_populator.upload_collection( - self.history_id, + history_id, "list:paired", elements=[ { @@ -517,9 +502,9 @@ class TestDatasetCollectionsApi(ApiTestCase): actual.append(converter["tool_id"]) assert expected in actual - def test_get_suitable_converters_different_datatypes_no_matches(self): + def test_get_suitable_converters_different_datatypes_no_matches(self, history_id): response = self.dataset_collection_populator.upload_collection( - self.history_id, + history_id, "list:paired", elements=[ { @@ -547,7 +532,7 @@ class TestDatasetCollectionsApi(ApiTestCase): actual.append(converter["tool_id"]) assert actual == [] - def test_collection_tools_tag_propagation(self): + def test_collection_tools_tag_propagation(self, history_id): elements = [{"src": "files", "tags": ["name:element_tag"]}] targets = [ { @@ -559,7 +544,7 @@ class TestDatasetCollectionsApi(ApiTestCase): } ] payload = { - "history_id": self.history_id, + "history_id": history_id, "targets": targets, "__files": {"files_0|file_data": open(self.test_data_resolver.get_filename("4.bed"))}, } @@ -570,11 +555,11 @@ class TestDatasetCollectionsApi(ApiTestCase): payload = self.dataset_populator.run_tool_payload( tool_id="__FILTER_FAILED_DATASETS__", inputs=inputs, - history_id=self.history_id, + history_id=history_id, input_format="legacy", ) response = self._post("tools", payload).json() - self.dataset_populator.wait_for_history(self.history_id, assert_ok=False) + self.dataset_populator.wait_for_history(history_id, assert_ok=False) output_collection = response["output_collections"][0] # collection should not inherit tags from input collection elements, only parent collection assert output_collection["tags"] == ["name:collection_tag"] @@ -589,17 +574,17 @@ class TestDatasetCollectionsApi(ApiTestCase): for f in fields: assert content_element[f] == hdca_element[f] - def _create_collection_contents_pair(self): + def _create_collection_contents_pair(self, history_id: str): # Create a simple collection, return hdca and contents_url - payload = self.dataset_collection_populator.create_pair_payload(self.history_id, instance_type="history") + payload = self.dataset_collection_populator.create_pair_payload(history_id, instance_type="history") create_response = self.dataset_populator.fetch(payload=payload, wait=True) hdca = self._check_create_response(create_response) - root_contents_url = self._get_contents_url_for_hdca(hdca) + root_contents_url = self._get_contents_url_for_hdca(history_id, hdca) return hdca, root_contents_url - def _get_contents_url_for_hdca(self, hdca): + def _get_contents_url_for_hdca(self, history_id: str, hdca): # look up the history contents using optional serialization key - history_contents_url = f"histories/{self.history_id}/contents?v=dev&view=summary&keys=contents_url" + history_contents_url = f"histories/{history_id}/contents?v=dev&view=summary&keys=contents_url" json = self._get(history_contents_url).json() # filter out the collection we just made id = hdca.id diff --git a/lib/galaxy_test/api/test_datasets.py b/lib/galaxy_test/api/test_datasets.py index 6f8988dd55b..affc5f64eb9 100644 --- a/lib/galaxy_test/api/test_datasets.py +++ b/lib/galaxy_test/api/test_datasets.py @@ -35,21 +35,20 @@ COMPOSITE_DATA_FETCH_REQUEST_1 = { class TestDatasetsApi(ApiTestCase): - history_id: str + dataset_populator: DatasetPopulator def setUp(self): super().setUp() self.dataset_populator = DatasetPopulator(self.galaxy_interactor) self.dataset_collection_populator = DatasetCollectionPopulator(self.galaxy_interactor) - self.history_id = self.dataset_populator.new_history() def test_index(self): index_response = self._get("datasets") self._assert_status_code_is(index_response, 200) - def test_index_using_keys(self): + def test_index_using_keys(self, history_id): expected_keys = "id" - self.dataset_populator.new_dataset(self.history_id) + self.dataset_populator.new_dataset(history_id) index_response = self._get(f"datasets?keys={expected_keys}") self._assert_status_code_is(index_response, 200) datasets = index_response.json() @@ -83,17 +82,17 @@ class TestDatasetsApi(ApiTestCase): for index, dataset in enumerate(datasets): assert dataset["id"] == expected_ids_order[index] - def test_search_datasets(self): - hda_id = self.dataset_populator.new_dataset(self.history_id)["id"] - payload = {"limit": 1, "offset": 0, "history_id": self.history_id} + def test_search_datasets(self, history_id): + hda_id = self.dataset_populator.new_dataset(history_id)["id"] + payload = {"limit": 1, "offset": 0, "history_id": history_id} index_response = self._get("datasets", payload).json() assert len(index_response) == 1 assert index_response[0]["id"] == hda_id fetch_response = self.dataset_collection_populator.create_list_in_history( - self.history_id, contents=["1\n2\n3"] + history_id, contents=["1\n2\n3"] ).json() hdca_id = self.dataset_collection_populator.wait_for_fetched_collection(fetch_response)["id"] - index_payload_1 = {"limit": 3, "offset": 0, "order": "hid", "history_id": self.history_id} + index_payload_1 = {"limit": 3, "offset": 0, "order": "hid", "history_id": history_id} index_response = self._get("datasets", index_payload_1).json() assert len(index_response) == 3 assert index_response[0]["hid"] == 3 @@ -107,12 +106,12 @@ class TestDatasetsApi(ApiTestCase): index_response = self._get("datasets", index_payload_2).json() assert index_response[1]["id"] == hda_id - def test_search_by_tag(self): - hda_id = self.dataset_populator.new_dataset(self.history_id)["id"] + def test_search_by_tag(self, history_id): + hda_id = self.dataset_populator.new_dataset(history_id)["id"] update_payload = { "tags": ["cool:new_tag", "cool:another_tag"], } - updated_hda = self._put(f"histories/{self.history_id}/contents/{hda_id}", update_payload, json=True).json() + updated_hda = self._put(f"histories/{history_id}/contents/{hda_id}", update_payload, json=True).json() assert "cool:new_tag" in updated_hda["tags"] assert "cool:another_tag" in updated_hda["tags"] payload = { @@ -120,7 +119,7 @@ class TestDatasetsApi(ApiTestCase): "offset": 0, "q": ["history_content_type", "tag"], "qv": ["dataset", "cool:new_tag"], - "history_id": self.history_id, + "history_id": history_id, } index_response = self._get("datasets", payload).json() assert len(index_response) == 1 @@ -129,7 +128,7 @@ class TestDatasetsApi(ApiTestCase): "offset": 0, "q": ["history_content_type", "tag-contains"], "qv": ["dataset", "new_tag"], - "history_id": self.history_id, + "history_id": history_id, } index_response = self._get("datasets", payload).json() assert len(index_response) == 1 @@ -138,7 +137,7 @@ class TestDatasetsApi(ApiTestCase): "offset": 0, "q": ["history_content_type", "tag-contains"], "qv": ["dataset", "notag"], - "history_id": self.history_id, + "history_id": history_id, } index_response = self._get("datasets", payload).json() assert len(index_response) == 0 @@ -180,14 +179,14 @@ class TestDatasetsApi(ApiTestCase): index_response = self._get("datasets", payload).json() assert len(index_response) == 0 - def test_search_by_tool_id(self): - self.dataset_populator.new_dataset(self.history_id) + def test_search_by_tool_id(self, history_id): + self.dataset_populator.new_dataset(history_id) payload = { "limit": 1, "offset": 0, "q": ["history_content_type", "tool_id"], "qv": ["dataset", "__DATA_FETCH__"], - "history_id": self.history_id, + "history_id": history_id, } assert len(self._get("datasets", payload).json()) == 1 payload = { @@ -195,7 +194,7 @@ class TestDatasetsApi(ApiTestCase): "offset": 0, "q": ["history_content_type", "tool_id"], "qv": ["dataset", "__DATA_FETCH__X"], - "history_id": self.history_id, + "history_id": history_id, } assert len(self._get("datasets", payload).json()) == 0 payload = { @@ -203,18 +202,18 @@ class TestDatasetsApi(ApiTestCase): "offset": 0, "q": ["history_content_type", "tool_id-contains"], "qv": ["dataset", "ATA_FETCH"], - "history_id": self.history_id, + "history_id": history_id, } assert len(self._get("datasets", payload).json()) == 1 self.dataset_collection_populator.create_list_in_history( - self.history_id, name="search by tool id", contents=["1\n2\n3"], wait=True + history_id, name="search by tool id", contents=["1\n2\n3"], wait=True ) payload = { "limit": 10, "offset": 0, "q": ["name", "tool_id"], "qv": ["search by tool id", "__DATA_FETCH__"], - "history_id": self.history_id, + "history_id": history_id, } result = self._get("datasets", payload).json() assert result[0]["name"] == "search by tool id", result @@ -223,41 +222,41 @@ class TestDatasetsApi(ApiTestCase): "offset": 0, "q": ["history_content_type", "tool_id"], "qv": ["dataset_collection", "uploadX"], - "history_id": self.history_id, + "history_id": history_id, } result = self._get("datasets", payload).json() assert len(result) == 0 - def test_search_by_extension(self): - self.dataset_populator.new_dataset(self.history_id, wait=True) + def test_search_by_extension(self, history_id): + self.dataset_populator.new_dataset(history_id, wait=True) payload = { "q": ["extension"], "qv": ["txt"], - "history_id": self.history_id, + "history_id": history_id, } assert len(self._get("datasets", payload).json()) == 1 payload = { "q": ["extension"], "qv": ["bam"], - "history_id": self.history_id, + "history_id": history_id, } assert len(self._get("datasets", payload).json()) == 0 payload = { "q": ["extension-in"], "qv": ["bam,txt"], - "history_id": self.history_id, + "history_id": history_id, } assert len(self._get("datasets", payload).json()) == 1 payload = { "q": ["extension-like"], "qv": ["t%t"], - "history_id": self.history_id, + "history_id": history_id, } assert len(self._get("datasets", payload).json()) == 1 payload = { "q": ["extension-like"], "qv": ["b%m"], - "history_id": self.history_id, + "history_id": history_id, } assert len(self._get("datasets", payload).json()) == 0 @@ -272,32 +271,32 @@ class TestDatasetsApi(ApiTestCase): self._assert_status_code_is(index_response, 400) assert index_response.json()["err_msg"] == "bad op in filter" - def test_search_returns_only_accessible(self): - hda_id = self.dataset_populator.new_dataset(self.history_id)["id"] + def test_search_returns_only_accessible(self, history_id): + hda_id = self.dataset_populator.new_dataset(history_id)["id"] with self._different_user(): payload = {"limit": 10, "offset": 0, "q": ["history_content_type"], "qv": ["dataset"]} index_response = self._get("datasets", payload).json() for item in index_response: assert hda_id != item["id"] - def test_show(self): - hda1 = self.dataset_populator.new_dataset(self.history_id) + def test_show(self, history_id): + hda1 = self.dataset_populator.new_dataset(history_id) show_response = self._get(f"datasets/{hda1['id']}") self._assert_status_code_is(show_response, 200) self.__assert_matches_hda(hda1, show_response.json()) - def test_show_permission_denied(self): - hda = self.dataset_populator.new_dataset(self.history_id) - self.dataset_populator.make_private(history_id=self.history_id, dataset_id=hda["id"]) + def test_show_permission_denied(self, history_id): + hda = self.dataset_populator.new_dataset(history_id) + self.dataset_populator.make_private(history_id=history_id, dataset_id=hda["id"]) with self._different_user(): show_response = self._get(f"datasets/{hda['id']}") self._assert_status_code_is(show_response, 403) - def test_admin_can_update_permissions(self): + def test_admin_can_update_permissions(self, history_id): # Create private dataset - hda = self.dataset_populator.new_dataset(self.history_id) + hda = self.dataset_populator.new_dataset(history_id) dataset_id = hda["id"] - self.dataset_populator.make_private(history_id=self.history_id, dataset_id=dataset_id) + self.dataset_populator.make_private(history_id=history_id, dataset_id=dataset_id) # Admin removes restrictions payload = {"action": "remove_restrictions"} @@ -314,7 +313,7 @@ class TestDatasetsApi(ApiTestCase): assert input_hda["name"] == query_hda["name"] assert input_hda["id"] == query_hda["id"] - def test_display(self): + def test_display(self, history_id): contents = textwrap.dedent( """\ 1 2 3 4 @@ -322,14 +321,14 @@ class TestDatasetsApi(ApiTestCase): 10 20 30 40 """ ) - hda1 = self.dataset_populator.new_dataset(self.history_id, content=contents) - self.dataset_populator.wait_for_history(self.history_id) - display_response = self._get(f"histories/{self.history_id}/contents/{hda1['id']}/display", {"raw": "True"}) + hda1 = self.dataset_populator.new_dataset(history_id, content=contents) + self.dataset_populator.wait_for_history(history_id) + display_response = self._get(f"histories/{history_id}/contents/{hda1['id']}/display", {"raw": "True"}) self._assert_status_code_is(display_response, 200) assert display_response.text == contents - def test_tag_change(self): - hda_id = self.dataset_populator.new_dataset(self.history_id)["id"] + def test_tag_change(self, history_id): + hda_id = self.dataset_populator.new_dataset(history_id)["id"] payload = { "item_id": hda_id, "item_class": "HistoryDatasetAssociation", @@ -338,7 +337,7 @@ class TestDatasetsApi(ApiTestCase): put_response = self._put("tags", data=payload, json=True) self._assert_status_code_is_ok(put_response) - updated_hda = self._get(f"histories/{self.history_id}/contents/{hda_id}").json() + updated_hda = self._get(f"histories/{history_id}/contents/{hda_id}").json() assert "cool:tag_a" in updated_hda["tags"] assert "cool:tag_b" in updated_hda["tags"] assert "tag_c" in updated_hda["tags"] @@ -346,9 +345,9 @@ class TestDatasetsApi(ApiTestCase): assert "name:tag_e" in updated_hda["tags"] @skip_without_tool("cat_data_and_sleep") - def test_update_datatype(self): - hda_id = self.dataset_populator.new_dataset(self.history_id)["id"] - original_hda = self._get(f"histories/{self.history_id}/contents/{hda_id}").json() + def test_update_datatype(self, history_id): + hda_id = self.dataset_populator.new_dataset(history_id)["id"] + original_hda = self._get(f"histories/{history_id}/contents/{hda_id}").json() assert original_hda["extension"] == "txt" assert original_hda["data_type"] == "galaxy.datatypes.data.Text" @@ -359,38 +358,38 @@ class TestDatasetsApi(ApiTestCase): run_response = self.dataset_populator.run_tool_raw( "cat_data_and_sleep", inputs, - self.history_id, + history_id, ) queued_id = run_response.json()["outputs"][0]["id"] update_while_incomplete_response = self._put( # try updating datatype while used as output of a running job - f"histories/{self.history_id}/contents/{queued_id}", data={"datatype": "tabular"}, json=True + f"histories/{history_id}/contents/{queued_id}", data={"datatype": "tabular"}, json=True ) self._assert_status_code_is(update_while_incomplete_response, 400) - self.dataset_populator.wait_for_history_jobs(self.history_id) # now wait for upload to complete + self.dataset_populator.wait_for_history_jobs(history_id) # now wait for upload to complete successful_updated_hda_response = self._put( - f"histories/{self.history_id}/contents/{hda_id}", data={"datatype": "tabular"}, json=True + f"histories/{history_id}/contents/{hda_id}", data={"datatype": "tabular"}, json=True ).json() assert successful_updated_hda_response["extension"] == "tabular" assert successful_updated_hda_response["data_type"] == "galaxy.datatypes.tabular.Tabular" invalidly_updated_hda_response = self._put( # try updating with invalid datatype - f"histories/{self.history_id}/contents/{hda_id}", data={"datatype": "invalid"}, json=True + f"histories/{history_id}/contents/{hda_id}", data={"datatype": "invalid"}, json=True ) self._assert_status_code_is(invalidly_updated_hda_response, 400) @skip_without_tool("cat_data_and_sleep") - def test_delete_cancels_job(self): - self._run_cancel_job(use_query_params=False) + def test_delete_cancels_job(self, history_id): + self._run_cancel_job(history_id, use_query_params=False) @skip_without_tool("cat_data_and_sleep") - def test_delete_cancels_job_with_query_params(self): - self._run_cancel_job(use_query_params=True) + def test_delete_cancels_job_with_query_params(self, history_id): + self._run_cancel_job(history_id, use_query_params=True) - def _run_cancel_job(self, use_query_params=False): - hda_id = self.dataset_populator.new_dataset(self.history_id)["id"] + def _run_cancel_job(self, history_id: str, use_query_params: bool = False): + hda_id = self.dataset_populator.new_dataset(history_id)["id"] inputs = { "input1": {"src": "hda", "id": hda_id}, "sleep_time": 10, @@ -398,7 +397,7 @@ class TestDatasetsApi(ApiTestCase): run_response = self.dataset_populator.run_tool_raw( "cat_data_and_sleep", inputs, - self.history_id, + history_id, ).json() output_hda_id = run_response["outputs"][0]["id"] job_id = run_response["jobs"][0]["id"] @@ -408,7 +407,7 @@ class TestDatasetsApi(ApiTestCase): # Use stop_job to cancel the creating job delete_response = self.dataset_populator.delete_dataset( - self.history_id, output_hda_id, stop_job=True, use_query_params=use_query_params + history_id, output_hda_id, stop_job=True, use_query_params=use_query_params ) self._assert_status_code_is_ok(delete_response) deleted_hda = delete_response.json() @@ -492,34 +491,34 @@ class TestDatasetsApi(ApiTestCase): return deleted_result @skip_without_datatype("velvet") - def test_composite_datatype_download(self): - output = self.dataset_populator.fetch_hda(self.history_id, COMPOSITE_DATA_FETCH_REQUEST_1, wait=True) - response = self._get(f"histories/{self.history_id}/contents/{output['id']}/display?to_ext=zip") + def test_composite_datatype_download(self, history_id): + output = self.dataset_populator.fetch_hda(history_id, COMPOSITE_DATA_FETCH_REQUEST_1, wait=True) + response = self._get(f"histories/{history_id}/contents/{output['id']}/display?to_ext=zip") self._assert_status_code_is(response, 200) archive = zipfile.ZipFile(BytesIO(response.content)) namelist = archive.namelist() assert len(namelist) == 4, f"Expected 3 elements in [{namelist}]" - def test_compute_md5_on_primary_dataset(self): - hda = self.dataset_populator.new_dataset(self.history_id, wait=True) - hda_details = self.dataset_populator.get_history_dataset_details(self.history_id, dataset=hda) + def test_compute_md5_on_primary_dataset(self, history_id): + hda = self.dataset_populator.new_dataset(history_id, wait=True) + hda_details = self.dataset_populator.get_history_dataset_details(history_id, dataset=hda) assert "hashes" in hda_details, str(hda_details.keys()) hashes = hda_details["hashes"] assert len(hashes) == 0 self.dataset_populator.compute_hash(hda["id"]) - hda_details = self.dataset_populator.get_history_dataset_details(self.history_id, dataset=hda) + hda_details = self.dataset_populator.get_history_dataset_details(history_id, dataset=hda) self.assert_hash_value(hda_details, "940cbe15c94d7e339dc15550f6bdcf4d", "MD5") - def test_compute_sha1_on_composite_dataset(self): - output = self.dataset_populator.fetch_hda(self.history_id, COMPOSITE_DATA_FETCH_REQUEST_1, wait=True) - hda_details = self.dataset_populator.get_history_dataset_details(self.history_id, dataset=output) + def test_compute_sha1_on_composite_dataset(self, history_id): + output = self.dataset_populator.fetch_hda(history_id, COMPOSITE_DATA_FETCH_REQUEST_1, wait=True) + hda_details = self.dataset_populator.get_history_dataset_details(history_id, dataset=output) assert "hashes" in hda_details, str(hda_details.keys()) hashes = hda_details["hashes"] assert len(hashes) == 0 self.dataset_populator.compute_hash(hda_details["id"], hash_function="SHA-256", extra_files_path="Roadmaps") - hda_details = self.dataset_populator.get_history_dataset_details(self.history_id, dataset=output) + hda_details = self.dataset_populator.get_history_dataset_details(history_id, dataset=output) self.assert_hash_value( hda_details, "3cbd311889963528954fe03b28b68a09685ea7a75660bd2268d5b44cafbe0d22", @@ -527,21 +526,21 @@ class TestDatasetsApi(ApiTestCase): extra_files_path="Roadmaps", ) - def test_duplicated_hash_requests_on_primary(self): - hda = self.dataset_populator.new_dataset(self.history_id, wait=True) - hda_details = self.dataset_populator.get_history_dataset_details(self.history_id, dataset=hda) + def test_duplicated_hash_requests_on_primary(self, history_id): + hda = self.dataset_populator.new_dataset(history_id, wait=True) + hda_details = self.dataset_populator.get_history_dataset_details(history_id, dataset=hda) assert "hashes" in hda_details, str(hda_details.keys()) hashes = hda_details["hashes"] assert len(hashes) == 0 self.dataset_populator.compute_hash(hda["id"]) self.dataset_populator.compute_hash(hda["id"]) - hda_details = self.dataset_populator.get_history_dataset_details(self.history_id, dataset=hda) + hda_details = self.dataset_populator.get_history_dataset_details(history_id, dataset=hda) self.assert_hash_value(hda_details, "940cbe15c94d7e339dc15550f6bdcf4d", "MD5") - def test_duplicated_hash_requests_on_extra_files(self): - output = self.dataset_populator.fetch_hda(self.history_id, COMPOSITE_DATA_FETCH_REQUEST_1, wait=True) - hda_details = self.dataset_populator.get_history_dataset_details(self.history_id, dataset=output) + def test_duplicated_hash_requests_on_extra_files(self, history_id): + output = self.dataset_populator.fetch_hda(history_id, COMPOSITE_DATA_FETCH_REQUEST_1, wait=True) + hda_details = self.dataset_populator.get_history_dataset_details(history_id, dataset=output) assert "hashes" in hda_details, str(hda_details.keys()) hashes = hda_details["hashes"] assert len(hashes) == 0 @@ -555,7 +554,7 @@ class TestDatasetsApi(ApiTestCase): hda_details["id"], hash_function="SHA-256", extra_files_path="Sequences" ) - hda_details = self.dataset_populator.get_history_dataset_details(self.history_id, dataset=output) + hda_details = self.dataset_populator.get_history_dataset_details(history_id, dataset=output) self.assert_hash_value(hda_details, "ce0c0ef1073317ff96c896c249b002dc", "MD5", extra_files_path="Roadmaps") self.assert_hash_value( hda_details, "fe2e06cdd03922a1ddf3fe6c7e0d299c8044fc8e", "SHA-1", extra_files_path="Roadmaps" @@ -583,16 +582,16 @@ class TestDatasetsApi(ApiTestCase): hash_value = matching_hashes[0]["hash_value"] assert expected_hash_value == hash_value - def test_storage_show(self): - hda = self.dataset_populator.new_dataset(self.history_id, wait=True) - hda_details = self.dataset_populator.get_history_dataset_details(self.history_id, dataset=hda) + def test_storage_show(self, history_id): + hda = self.dataset_populator.new_dataset(history_id, wait=True) + hda_details = self.dataset_populator.get_history_dataset_details(history_id, dataset=hda) dataset_id = hda_details["dataset_id"] storage_info_dict = self.dataset_populator.dataset_storage_info(dataset_id) assert_has_keys(storage_info_dict, "object_store_id", "name", "description") - def test_storage_show_on_discarded(self): + def test_storage_show_on_discarded(self, history_id): as_list = self.dataset_populator.create_contents_from_store( - self.history_id, + history_id, store_dict=one_hda_model_store_dict(), ) assert len(as_list) == 1 @@ -605,9 +604,9 @@ class TestDatasetsApi(ApiTestCase): assert len(sources) == 1 assert sources[0]["source_uri"] == TEST_SOURCE_URI - def test_storage_show_on_deferred(self): + def test_storage_show_on_deferred(self, history_id): as_list = self.dataset_populator.create_contents_from_store( - self.history_id, + history_id, store_dict=deferred_hda_model_store_dict(), ) assert len(as_list) == 1 @@ -621,14 +620,12 @@ class TestDatasetsApi(ApiTestCase): assert sources[0]["source_uri"] == TEST_SOURCE_URI @skip_if_github_down - def test_display_application_link(self): + def test_display_application_link(self, history_id): item = { "src": "url", "url": "https://raw.githubusercontent.com/galaxyproject/galaxy/dev/test-data/1.bam", "ext": "bam", } - output = self.dataset_populator.fetch_hda(self.history_id, item) - dataset_details = self.dataset_populator.get_history_dataset_details( - self.history_id, dataset=output, assert_ok=True - ) + output = self.dataset_populator.fetch_hda(history_id, item) + dataset_details = self.dataset_populator.get_history_dataset_details(history_id, dataset=output, assert_ok=True) assert "display_application/" in dataset_details["display_apps"][0]["links"][0]["href"] diff --git a/lib/galaxy_test/api/test_folder_contents.py b/lib/galaxy_test/api/test_folder_contents.py index f1047d976ee..117ce0277be 100644 --- a/lib/galaxy_test/api/test_folder_contents.py +++ b/lib/galaxy_test/api/test_folder_contents.py @@ -14,18 +14,19 @@ from ._framework import ApiTestCase class TestFolderContentsApi(ApiTestCase): + dataset_populator: DatasetPopulator + def setUp(self): super().setUp() self.dataset_populator = DatasetPopulator(self.galaxy_interactor) self.dataset_collection_populator = DatasetCollectionPopulator(self.galaxy_interactor) self.library_populator = LibraryPopulator(self.galaxy_interactor) - self.history_id = self.dataset_populator.new_history() self.library = self.library_populator.new_private_library("FolderContentsTestsLibrary") self.root_folder_id = self._create_folder_in_library("Test Folder Contents") - def test_create_hda_with_ldda_message(self): - hda_id = self._create_hda() + def test_create_hda_with_ldda_message(self, history_id): + hda_id = self._create_hda(history_id) ldda_message = "Test message" data = { "from_hda_id": hda_id, @@ -34,9 +35,9 @@ class TestFolderContentsApi(ApiTestCase): ldda = self._create_content_in_folder_with_payload(self.root_folder_id, data) self._assert_has_keys(ldda, "name", "id") - def test_create_hdca_with_ldda_message(self): + def test_create_hdca_with_ldda_message(self, history_id): contents = ["dataset01", "dataset02"] - hdca_id = self._create_hdca_with_contents(contents) + hdca_id = self._create_hdca_with_contents(history_id, contents) ldda_message = "Test message" data = { "from_hdca_id": hdca_id, @@ -45,21 +46,21 @@ class TestFolderContentsApi(ApiTestCase): lddas = self._create_content_in_folder_with_payload(self.root_folder_id, data) assert len(contents) == len(lddas) - def test_index(self): + def test_index(self, history_id): folder_id = self._create_folder_in_library("Test Folder Contents Index") self._create_subfolder_in(folder_id) - self._create_dataset_in_folder(folder_id) + self._create_dataset_in_folder(history_id, folder_id) response = self._get(f"folders/{folder_id}/contents") self._assert_index_count_is_correct(response, expected_contents_count=2) - def test_index_include_deleted(self): + def test_index_include_deleted(self, history_id): folder_name = "Test Folder Contents Index include deleted" folder_id = self._create_folder_in_library(folder_name) sub_folder_id = self._create_subfolder_in(folder_id) - ldda_id, _ = self._create_dataset_in_folder(folder_id) + ldda_id, _ = self._create_dataset_in_folder(history_id, folder_id) self._delete_library_dataset(ldda_id) self._delete_subfolder(sub_folder_id) @@ -72,7 +73,7 @@ class TestFolderContentsApi(ApiTestCase): for content in index_response["folder_contents"]: assert content["deleted"] is True - def test_index_pagination(self): + def test_index_pagination(self, history_id): folder_name = "Test Folder Contents Pagination" folder_id = self._create_folder_in_library(folder_name) @@ -82,7 +83,7 @@ class TestFolderContentsApi(ApiTestCase): num_datasets = 5 for _ in range(num_datasets): - self._create_dataset_in_folder(folder_id) + self._create_dataset_in_folder(history_id, folder_id) total_items = num_datasets + num_subfolders @@ -135,13 +136,13 @@ class TestFolderContentsApi(ApiTestCase): for index in range(actual_limit): assert contents[index]["id"] == expected_query_result[index]["id"] - def test_index_search_text(self): + def test_index_search_text(self, history_id): folder_name = "Test Folder Contents Index search text" folder_id = self._create_folder_in_library(folder_name) dataset_names = ["AB", "BX", "abx"] for name in dataset_names: - self._create_dataset_in_folder(folder_id, name) + self._create_dataset_in_folder(history_id, folder_id, name) subfolder_names = ["Folder_a", "Folder_X"] for name in subfolder_names: @@ -158,10 +159,10 @@ class TestFolderContentsApi(ApiTestCase): for content in contents: assert search_text.casefold() in content["name"].casefold() - def test_index_permissions(self): + def test_index_permissions(self, history_id): folder_name = "Test Folder Contents Index permissions" folder_id = self._create_folder_in_library(folder_name) - _, hda_id = self._create_dataset_in_folder(folder_id) + _, hda_id = self._create_dataset_in_folder(history_id, folder_id) self._make_dataset_private(hda_id) @@ -192,7 +193,7 @@ class TestFolderContentsApi(ApiTestCase): response = self._get(f"folders/{folder_id}/contents") self._assert_index_count_is_correct(response, expected_contents_count=1) - def test_index_permissions_include_deleted(self): + def test_index_permissions_include_deleted(self, history_id): folder_name = "Test Folder Contents Index permissions include deleted" folder_id = self._create_folder_in_library(folder_name) @@ -212,7 +213,7 @@ class TestFolderContentsApi(ApiTestCase): ldda_ids: List[str] = [] deleted_ldda_ids: List[str] = [] for _ in range(num_datasets): - ldda_id, _ = self._create_dataset_in_folder(folder_id) + ldda_id, _ = self._create_dataset_in_folder(history_id, folder_id) ldda_ids.append(ldda_id) for index, ldda_id in enumerate(ldda_ids): @@ -246,7 +247,7 @@ class TestFolderContentsApi(ApiTestCase): response = self._get(f"folders/{folder_id}/contents?include_deleted={include_deleted}") self._assert_index_count_is_correct(response, expected_contents_count=num_non_deleted) - def test_index_order_by(self): + def test_index_order_by(self, history_id): folder_name = "Test Folder Contents Index Order By" folder_id = self._create_folder_in_library(folder_name) @@ -261,6 +262,7 @@ class TestFolderContentsApi(ApiTestCase): file_types = ["txt", "csv", "txt"] for index, name in enumerate(dataset_names): self._create_dataset_in_folder( + history_id, folder_id, name, content=f"{'0'*dataset_sizes[index]}", @@ -269,7 +271,7 @@ class TestFolderContentsApi(ApiTestCase): ) # Wait for datasets to finish upload - self.dataset_populator.wait_for_history(self.history_id) + self.dataset_populator.wait_for_history(history_id) # Folders always have priority (they show-up before any dataset regardless of the sorting) and they # can only be sorted by name, description and update_time, the other sorting attributes are ignored @@ -356,6 +358,7 @@ class TestFolderContentsApi(ApiTestCase): def _create_dataset_in_folder( self, + history_id: str, folder_id: str, name: Optional[str] = None, content: Optional[str] = None, @@ -363,7 +366,7 @@ class TestFolderContentsApi(ApiTestCase): **kwds, ) -> Tuple[str, str]: """Returns a tuple with the LDDA ID and the underlying HDA ID""" - hda_id = self._create_hda(name, content, **kwds) + hda_id = self._create_hda(history_id, name, content, **kwds) data = { "from_hda_id": hda_id, "ldda_message": ldda_message or "Test msg", @@ -376,14 +379,14 @@ class TestFolderContentsApi(ApiTestCase): self._assert_status_code_is(create_response, 200) return create_response.json() - def _create_hda(self, name: Optional[str] = None, content: Optional[str] = None, **kwds) -> str: - hda = self.dataset_populator.new_dataset(self.history_id, name=name, content=content, **kwds) + def _create_hda(self, history_id: str, name: Optional[str] = None, content: Optional[str] = None, **kwds) -> str: + hda = self.dataset_populator.new_dataset(history_id, name=name, content=content, **kwds) hda_id = hda["id"] return hda_id - def _create_hdca_with_contents(self, contents: List[str]) -> str: + def _create_hdca_with_contents(self, history_id: str, contents: List[str]) -> str: hdca = self.dataset_collection_populator.create_list_in_history( - self.history_id, contents=contents, direct_upload=True, wait=True + history_id, contents=contents, direct_upload=True, wait=True ).json()["outputs"][0] hdca_id = hdca["id"] return hdca_id diff --git a/lib/galaxy_test/api/test_history_contents.py b/lib/galaxy_test/api/test_history_contents.py index 48383cd36af..0ece275b3ed 100644 --- a/lib/galaxy_test/api/test_history_contents.py +++ b/lib/galaxy_test/api/test_history_contents.py @@ -31,17 +31,16 @@ class TestHistoryContentsApi(ApiTestCase): self.dataset_populator = DatasetPopulator(self.galaxy_interactor) self.dataset_collection_populator = DatasetCollectionPopulator(self.galaxy_interactor) self.library_populator = LibraryPopulator(self.galaxy_interactor) - self.history_id = self.dataset_populator.new_history() - def test_index_hda_summary(self): - hda1 = self.dataset_populator.new_dataset(self.history_id) - contents_response = self._get(f"histories/{self.history_id}/contents") + def test_index_hda_summary(self, history_id): + hda1 = self.dataset_populator.new_dataset(history_id) + contents_response = self._get(f"histories/{history_id}/contents") hda_summary = self.__check_for_hda(contents_response, hda1) assert "display_types" not in hda_summary # Quick summary, not full details - def test_make_private_and_public(self): - hda1 = self._wait_for_new_hda() - update_url = f"histories/{self.history_id}/contents/{hda1['id']}/permissions" + def test_make_private_and_public(self, history_id): + hda1 = self._wait_for_new_hda(history_id) + update_url = f"histories/{history_id}/contents/{hda1['id']}/permissions" role_id = self.dataset_populator.user_private_role_id() # Give manage permission to the user. @@ -51,14 +50,14 @@ class TestHistoryContentsApi(ApiTestCase): } update_response = self._update_permissions(update_url, payload, admin=True) self._assert_status_code_is(update_response, 200) - self._assert_other_user_can_access(hda1["id"]) + self._assert_other_user_can_access(history_id, hda1["id"]) # Then we restrict access. payload = { "action": "make_private", } update_response = self._update_permissions(update_url, payload) self._assert_status_code_is(update_response, 200) - self._assert_other_user_cannot_access(hda1["id"]) + self._assert_other_user_cannot_access(history_id, hda1["id"]) # Then we restrict access. payload = { @@ -66,19 +65,19 @@ class TestHistoryContentsApi(ApiTestCase): } update_response = self._update_permissions(update_url, payload) self._assert_status_code_is(update_response, 200) - self._assert_other_user_can_access(hda1["id"]) + self._assert_other_user_can_access(history_id, hda1["id"]) - def test_set_permissions_add_admin_history_contents(self): - self._verify_dataset_permissions("history_contents") + def test_set_permissions_add_admin_history_contents(self, history_id): + self._verify_dataset_permissions(history_id, "history_contents") - def test_set_permissions_add_admin_datasets(self): - self._verify_dataset_permissions("dataset") + def test_set_permissions_add_admin_datasets(self, history_id): + self._verify_dataset_permissions(history_id, "dataset") - def _verify_dataset_permissions(self, api_endpoint): - hda1 = self._wait_for_new_hda() + def _verify_dataset_permissions(self, history_id: str, api_endpoint): + hda1 = self._wait_for_new_hda(history_id) hda_id = hda1["id"] if api_endpoint == "history_contents": - update_url = f"histories/{self.history_id}/contents/{hda_id}/permissions" + update_url = f"histories/{history_id}/contents/{hda_id}/permissions" else: update_url = f"datasets/{hda_id}/permissions" @@ -95,17 +94,17 @@ class TestHistoryContentsApi(ApiTestCase): self._assert_status_code_is(update_response, 403) # First the details render for another user. - self._assert_other_user_can_access(hda_id) + self._assert_other_user_can_access(history_id, hda_id) # Then we restrict access. update_response = self._update_permissions(update_url, payload, admin=True) self._assert_status_code_is(update_response, 200) # Finally the details don't render. - self._assert_other_user_cannot_access(hda_id) + self._assert_other_user_cannot_access(history_id, hda_id) # But they do for the original user. - contents_response = self._get(f"histories/{self.history_id}/contents/{hda_id}").json() + contents_response = self._get(f"histories/{history_id}/contents/{hda_id}").json() assert "name" in contents_response update_response = self._update_permissions(update_url, payload) @@ -117,7 +116,7 @@ class TestHistoryContentsApi(ApiTestCase): } update_response = self._update_permissions(update_url, payload) self._assert_status_code_is(update_response, 200) - self._assert_other_user_cannot_access(hda_id) + self._assert_other_user_cannot_access(history_id, hda_id) user_id = self.dataset_populator.user_id() with self._different_user(): @@ -133,60 +132,60 @@ class TestHistoryContentsApi(ApiTestCase): update_response = self._update_permissions(update_url, payload) self._assert_status_code_is(update_response, 200) # Now other user can see dataset again with access permission. - self._assert_other_user_can_access(hda_id) + self._assert_other_user_can_access(history_id, hda_id) # access doesn't imply management though... with self._different_user(): update_response = self._update_permissions(update_url, payload) self._assert_status_code_is(update_response, 403) - def _assert_other_user_cannot_access(self, history_content_id): + def _assert_other_user_cannot_access(self, history_id: str, history_content_id: str): with self._different_user(): contents_response = self.dataset_populator.get_history_dataset_details_raw( - history_id=self.history_id, dataset_id=history_content_id + history_id=history_id, dataset_id=history_content_id ) assert contents_response.status_code == 403 - def _assert_other_user_can_access(self, history_content_id): + def _assert_other_user_can_access(self, history_id: str, history_content_id: str): with self._different_user(): contents_response = self.dataset_populator.get_history_dataset_details_raw( - history_id=self.history_id, dataset_id=history_content_id + history_id=history_id, dataset_id=history_content_id ) contents_response.raise_for_status() assert "name" in contents_response.json() - def test_index_hda_all_details(self): - hda1 = self.dataset_populator.new_dataset(self.history_id) - contents_response = self._get(f"histories/{self.history_id}/contents?details=all") + def test_index_hda_all_details(self, history_id): + hda1 = self.dataset_populator.new_dataset(history_id) + contents_response = self._get(f"histories/{history_id}/contents?details=all") hda_details = self.__check_for_hda(contents_response, hda1) self.__assert_hda_has_full_details(hda_details) - def test_index_hda_detail_by_id(self): - hda1 = self.dataset_populator.new_dataset(self.history_id) - contents_response = self._get(f"histories/{self.history_id}/contents?details={hda1['id']}") + def test_index_hda_detail_by_id(self, history_id): + hda1 = self.dataset_populator.new_dataset(history_id) + contents_response = self._get(f"histories/{history_id}/contents?details={hda1['id']}") hda_details = self.__check_for_hda(contents_response, hda1) self.__assert_hda_has_full_details(hda_details) - def test_index_detail_parameter_error(self): - hda1 = self.dataset_populator.new_dataset(self.history_id) + def test_index_detail_parameter_error(self, history_id): + hda1 = self.dataset_populator.new_dataset(history_id) # Invalid details should return 400 - contents_response = self._get(f"histories/{self.history_id}/contents?v=dev&details= ") + contents_response = self._get(f"histories/{history_id}/contents?v=dev&details= ") self._assert_status_code_is(contents_response, 400) # Empty IDs should return 400 - contents_response = self._get(f"histories/{self.history_id}/contents?v=dev&details=,,{hda1['id']}") + contents_response = self._get(f"histories/{history_id}/contents?v=dev&details=,,{hda1['id']}") self._assert_status_code_is(contents_response, 400) # Invalid IDs should return 400 - contents_response = self._get(f"histories/{self.history_id}/contents?v=dev&details={hda1['id']}, ,{hda1['id']}") + contents_response = self._get(f"histories/{history_id}/contents?v=dev&details={hda1['id']}, ,{hda1['id']}") self._assert_status_code_is(contents_response, 400) - def test_show_hda(self): - hda1 = self.dataset_populator.new_dataset(self.history_id) - show_response = self.__show(hda1) + def test_show_hda(self, history_id): + hda1 = self.dataset_populator.new_dataset(history_id) + show_response = self.__show(history_id, hda1) self._assert_status_code_is(show_response, 200) self.__assert_matches_hda(hda1, show_response.json()) - def _create_copy(self): - hda1 = self.dataset_populator.new_dataset(self.history_id) + def _create_copy(self, history_id: str): + hda1 = self.dataset_populator.new_dataset(history_id) create_data = dict( source="hda", content=hda1["id"], @@ -197,50 +196,50 @@ class TestHistoryContentsApi(ApiTestCase): self._assert_status_code_is(create_response, 200) return create_response.json() - def test_hda_copy(self): - response = self._create_copy() + def test_hda_copy(self, history_id): + response = self._create_copy(history_id) assert self.__count_contents(response["history_id"]) == 1 - def test_inheritance_chain(self): - response = self._create_copy() + def test_inheritance_chain(self, history_id): + response = self._create_copy(history_id) inheritance_chain_response = self._get(f"datasets/{response['id']}/inheritance_chain") self._assert_status_code_is_ok(inheritance_chain_response) inheritance_chain = inheritance_chain_response.json() assert len(inheritance_chain) == 1 - def test_library_copy(self): + def test_library_copy(self, history_id): ld = self.library_populator.new_library_dataset("lda_test_library") create_data = dict( source="library", content=ld["id"], ) - assert self.__count_contents(self.history_id) == 0 - create_response = self._post(f"histories/{self.history_id}/contents", create_data, json=True) + assert self.__count_contents(history_id) == 0 + create_response = self._post(f"histories/{history_id}/contents", create_data, json=True) self._assert_status_code_is(create_response, 200) - assert self.__count_contents(self.history_id) == 1 + assert self.__count_contents(history_id) == 1 - def test_update(self): - hda1 = self._wait_for_new_hda() + def test_update(self, history_id): + hda1 = self._wait_for_new_hda(history_id) assert str(hda1["deleted"]).lower() == "false" - update_response = self._update(hda1["id"], dict(deleted=True)) + update_response = self._update(history_id, hda1["id"], dict(deleted=True)) self._assert_status_code_is(update_response, 200) - show_response = self.__show(hda1) + show_response = self.__show(history_id, hda1) assert str(show_response.json()["deleted"]).lower() == "true" - update_response = self._update(hda1["id"], dict(name="Updated Name")) - assert self.__show(hda1).json()["name"] == "Updated Name" + update_response = self._update(history_id, hda1["id"], dict(name="Updated Name")) + assert self.__show(history_id, hda1).json()["name"] == "Updated Name" - update_response = self._update(hda1["id"], dict(name="Updated Name")) - assert self.__show(hda1).json()["name"] == "Updated Name" + update_response = self._update(history_id, hda1["id"], dict(name="Updated Name")) + assert self.__show(history_id, hda1).json()["name"] == "Updated Name" unicode_name = "ржевский сапоги" - update_response = self._update(hda1["id"], dict(name=unicode_name)) - updated_hda = self.__show(hda1).json() + update_response = self._update(history_id, hda1["id"], dict(name=unicode_name)) + updated_hda = self.__show(history_id, hda1).json() assert updated_hda["name"] == unicode_name, updated_hda quoted_name = '"Mooo"' - update_response = self._update(hda1["id"], dict(name=quoted_name)) - updated_hda = self.__show(hda1).json() + update_response = self._update(history_id, hda1["id"], dict(name=quoted_name)) + updated_hda = self.__show(history_id, hda1).json() assert updated_hda["name"] == quoted_name, quoted_name data = { @@ -258,47 +257,47 @@ class TestHistoryContentsApi(ApiTestCase): # and this is an invalid ID. assert update_response.status_code == 400, update_response.content - def test_update_batch(self): - hda1 = self._wait_for_new_hda() + def test_update_batch(self, history_id): + hda1 = self._wait_for_new_hda(history_id) assert str(hda1["deleted"]).lower() == "false" assert str(hda1["visible"]).lower() == "true" # update deleted flag => true payload = dict(items=[{"history_content_type": "dataset", "id": hda1["id"]}], deleted=True) - update_response = self._update_batch(payload) + update_response = self._update_batch(history_id, payload) objects = update_response.json() assert objects[0]["deleted"] is True assert objects[0]["visible"] is True # update visibility flag => false payload = dict(items=[{"history_content_type": "dataset", "id": hda1["id"]}], visible=False) - update_response = self._update_batch(payload) + update_response = self._update_batch(history_id, payload) objects = update_response.json() assert objects[0]["deleted"] is True assert objects[0]["visible"] is False # update both flags payload = dict(items=[{"history_content_type": "dataset", "id": hda1["id"]}], deleted=False, visible=True) - update_response = self._update_batch(payload) + update_response = self._update_batch(history_id, payload) objects = update_response.json() assert objects[0]["deleted"] is False assert objects[0]["visible"] is True - def test_update_batch_collections(self): - hdca = self._create_pair_collection() + def test_update_batch_collections(self, history_id): + hdca = self._create_pair_collection(history_id) assert hdca["deleted"] is False assert hdca["visible"] is True # update deleted flag => true payload = dict(items=[{"history_content_type": "dataset_collection", "id": hdca["id"]}], deleted=True) - update_response = self._update_batch(payload) + update_response = self._update_batch(history_id, payload) objects = update_response.json() assert objects[0]["deleted"] is True assert objects[0]["visible"] is True # update visibility flag => false payload = dict(items=[{"history_content_type": "dataset_collection", "id": hdca["id"]}], visible=False) - update_response = self._update_batch(payload) + update_response = self._update_batch(history_id, payload) objects = update_response.json() assert objects[0]["deleted"] is True assert objects[0]["visible"] is False @@ -307,27 +306,26 @@ class TestHistoryContentsApi(ApiTestCase): payload = dict( items=[{"history_content_type": "dataset_collection", "id": hdca["id"]}], deleted=False, visible=True ) - update_response = self._update_batch(payload) + update_response = self._update_batch(history_id, payload) objects = update_response.json() assert objects[0]["deleted"] is False assert objects[0]["visible"] is True - def test_update_type_failures(self): - hda1 = self._wait_for_new_hda() - update_response = self._update(hda1["id"], dict(deleted="not valid")) + def test_update_type_failures(self, history_id): + hda1 = self._wait_for_new_hda(history_id) + update_response = self._update(history_id, hda1["id"], dict(deleted="not valid")) self._assert_status_code_is(update_response, 400) - def _wait_for_new_hda(self): - hda1 = self.dataset_populator.new_dataset(self.history_id) - self.dataset_populator.wait_for_history(self.history_id) + def _wait_for_new_hda(self, history_id: str): + hda1 = self.dataset_populator.new_dataset(history_id) + self.dataset_populator.wait_for_history(history_id) return hda1 def _set_edit_update(self, data): update_response = self._put(urllib.parse.urljoin(self.url, "dataset/set_edit"), data=data, json=True) return update_response - def _update(self, item_id, data, admin=False, history_id=None): - history_id = history_id or self.history_id + def _update(self, history_id: str, item_id, data, admin=False): update_response = self._put(f"histories/{history_id}/contents/{item_id}", data=data, json=True, admin=admin) return update_response @@ -335,68 +333,68 @@ class TestHistoryContentsApi(ApiTestCase): update_response = self._put(url, data=data, json=True, admin=admin) return update_response - def _update_batch(self, data): - update_response = self._put(f"histories/{self.history_id}/contents", data=data, json=True) + def _update_batch(self, history_id: str, data): + update_response = self._put(f"histories/{history_id}/contents", data=data, json=True) return update_response - def test_delete(self): - hda1 = self.dataset_populator.new_dataset(self.history_id) - self.dataset_populator.wait_for_history(self.history_id) - assert str(self.__show(hda1).json()["deleted"]).lower() == "false" - delete_response = self._delete(f"histories/{self.history_id}/contents/{hda1['id']}") + def test_delete(self, history_id): + hda1 = self.dataset_populator.new_dataset(history_id) + self.dataset_populator.wait_for_history(history_id) + assert str(self.__show(history_id, hda1).json()["deleted"]).lower() == "false" + delete_response = self._delete(f"histories/{history_id}/contents/{hda1['id']}") assert delete_response.status_code < 300 # Something in the 200s :). - assert str(self.__show(hda1).json()["deleted"]).lower() == "true" + assert str(self.__show(history_id, hda1).json()["deleted"]).lower() == "true" def test_delete_anon(self): with self._different_user(anon=True): history_id = self._get(urllib.parse.urljoin(self.url, "history/current_history_json")).json()["id"] hda1 = self.dataset_populator.new_dataset(history_id) self.dataset_populator.wait_for_history(history_id) - assert str(self.__show(hda1).json()["deleted"]).lower() == "false" + assert str(self.__show(history_id, hda1).json()["deleted"]).lower() == "false" delete_response = self._delete(f"histories/{history_id}/contents/{hda1['id']}") assert delete_response.status_code < 300 # Something in the 200s :). - assert str(self.__show(hda1).json()["deleted"]).lower() == "true" + assert str(self.__show(history_id, hda1).json()["deleted"]).lower() == "true" - def test_delete_permission_denied(self): - hda1 = self.dataset_populator.new_dataset(self.history_id) + def test_delete_permission_denied(self, history_id): + hda1 = self.dataset_populator.new_dataset(history_id) with self._different_user(anon=True): - delete_response = self._delete(f"histories/{self.history_id}/contents/{hda1['id']}") + delete_response = self._delete(f"histories/{history_id}/contents/{hda1['id']}") assert delete_response.status_code == 403 assert delete_response.json()["err_msg"] == "HistoryDatasetAssociation is not owned by user" - def test_purge(self): - hda1 = self.dataset_populator.new_dataset(self.history_id) - self.dataset_populator.wait_for_history(self.history_id) - assert str(self.__show(hda1).json()["deleted"]).lower() == "false" - assert str(self.__show(hda1).json()["purged"]).lower() == "false" + def test_purge(self, history_id): + hda1 = self.dataset_populator.new_dataset(history_id) + self.dataset_populator.wait_for_history(history_id) + assert str(self.__show(history_id, hda1).json()["deleted"]).lower() == "false" + assert str(self.__show(history_id, hda1).json()["purged"]).lower() == "false" data = {"purge": True} - delete_response = self._delete(f"histories/{self.history_id}/contents/{hda1['id']}", data=data, json=True) + delete_response = self._delete(f"histories/{history_id}/contents/{hda1['id']}", data=data, json=True) assert delete_response.status_code < 300 # Something in the 200s :). # Purging and deleting the dataset may or may not happen asynchronously. # On 202 the request was accepted and purging will happen later. if delete_response.status_code == 202: - self.dataset_populator.wait_for_purge(self.history_id, hda1["id"]) + self.dataset_populator.wait_for_purge(history_id, hda1["id"]) else: - assert self.__show(hda1).json()["deleted"] - assert self.__show(hda1).json()["purged"] + assert self.__show(history_id, hda1).json()["deleted"] + assert self.__show(history_id, hda1).json()["purged"] - def test_dataset_collection_creation_on_contents(self): + def test_dataset_collection_creation_on_contents(self, history_id): payload = self.dataset_collection_populator.create_pair_payload( - self.history_id, type="dataset_collection", wait=True + history_id, type="dataset_collection", wait=True ) endpoint = "tools/fetch" - self._check_pair_creation(endpoint, payload) + self._check_pair_creation(history_id, endpoint, payload) - def test_dataset_collection_creation_on_typed_contents(self): - payload = self.dataset_collection_populator.create_pair_payload(self.history_id, wait=True) + def test_dataset_collection_creation_on_typed_contents(self, history_id): + payload = self.dataset_collection_populator.create_pair_payload(history_id, wait=True) endpoint = "tools/fetch" - self._check_pair_creation(endpoint, payload) + self._check_pair_creation(history_id, endpoint, payload) def test_dataset_collection_create_from_exisiting_datasets_with_new_tags(self): with self.dataset_populator.test_history() as history_id: hda_id = self.dataset_populator.new_dataset(history_id, content="1 2 3")["id"] hda2_id = self.dataset_populator.new_dataset(history_id, content="1 2 3")["id"] - update_response = self._update(hda2_id, dict(tags=["existing:tag"]), history_id=history_id).json() + update_response = self._update(history_id, hda2_id, dict(tags=["existing:tag"])).json() assert update_response["tags"] == ["existing:tag"] creation_payload = { "collection_type": "list", @@ -408,7 +406,7 @@ class TestHistoryContentsApi(ApiTestCase): "type": "dataset_collection", "copy_elements": True, } - r = self._post(f"histories/{self.history_id}/contents", creation_payload, json=True).json() + r = self._post(f"histories/{history_id}/contents", creation_payload, json=True).json() assert r["elements"][0]["object"]["id"] != hda_id, "HDA has not been copied" assert len(r["elements"][0]["object"]["tags"]) == 1 assert r["elements"][0]["object"]["tags"][0] == "my_new_tag" @@ -416,18 +414,18 @@ class TestHistoryContentsApi(ApiTestCase): original_hda = self.dataset_populator.get_history_dataset_details(history_id=history_id, dataset_id=hda_id) assert len(original_hda["tags"]) == 0, original_hda["tags"] - def _check_pair_creation(self, endpoint, payload): - pre_collection_count = self.__count_contents(type="dataset_collection") - pre_dataset_count = self.__count_contents(type="dataset") - pre_combined_count = self.__count_contents(type="dataset,dataset_collection") + def _check_pair_creation(self, history_id: str, endpoint, payload): + pre_collection_count = self.__count_contents(history_id, type="dataset_collection") + pre_dataset_count = self.__count_contents(history_id, type="dataset") + pre_combined_count = self.__count_contents(history_id, type="dataset,dataset_collection") dataset_collection_response = self._post(endpoint, payload, json=True) dataset_collection = self.__check_create_collection_response(dataset_collection_response) - post_collection_count = self.__count_contents(type="dataset_collection") - post_dataset_count = self.__count_contents(type="dataset") - post_combined_count = self.__count_contents(type="dataset,dataset_collection") + post_collection_count = self.__count_contents(history_id, type="dataset_collection") + post_dataset_count = self.__count_contents(history_id, type="dataset") + post_combined_count = self.__count_contents(history_id, type="dataset,dataset_collection") # Test filtering types with index. assert pre_collection_count == 0 @@ -437,7 +435,7 @@ class TestHistoryContentsApi(ApiTestCase): assert pre_dataset_count == post_dataset_count # Test show dataset collection. - collection_url = f"histories/{self.history_id}/contents/dataset_collections/{dataset_collection['id']}" + collection_url = f"histories/{history_id}/contents/dataset_collections/{dataset_collection['id']}" show_response = self._get(collection_url) self._assert_status_code_is(show_response, 200) dataset_collection = show_response.json() @@ -453,34 +451,34 @@ class TestHistoryContentsApi(ApiTestCase): assert dataset_collection["deleted"] @skip_without_tool("collection_creates_list") - def test_jobs_summary_simple_hdca(self): + def test_jobs_summary_simple_hdca(self, history_id): fetch_response = self.dataset_collection_populator.create_list_in_history( - self.history_id, contents=["a\nb\nc\nd", "e\nf\ng\nh"] + history_id, contents=["a\nb\nc\nd", "e\nf\ng\nh"] ).json() hdca_id = self.dataset_collection_populator.wait_for_fetched_collection(fetch_response)["id"] - run = self.dataset_populator.run_collection_creates_list(self.history_id, hdca_id) + run = self.dataset_populator.run_collection_creates_list(history_id, hdca_id) collections = run["output_collections"] collection = collections[0] - jobs_summary_url = f"histories/{self.history_id}/contents/dataset_collections/{collection['id']}/jobs_summary" + jobs_summary_url = f"histories/{history_id}/contents/dataset_collections/{collection['id']}/jobs_summary" jobs_summary_response = self._get(jobs_summary_url) self._assert_status_code_is(jobs_summary_response, 200) jobs_summary = jobs_summary_response.json() self._assert_has_keys(jobs_summary, "populated_state", "states") @skip_without_tool("cat1") - def test_jobs_summary_implicit_hdca(self): + def test_jobs_summary_implicit_hdca(self, history_id): create_response = self.dataset_collection_populator.create_pair_in_history( - self.history_id, contents=["123", "456"], wait=True + history_id, contents=["123", "456"], wait=True ) hdca_id = create_response.json()["outputs"][0]["id"] inputs = { "input1": {"batch": True, "values": [{"src": "hdca", "id": hdca_id}]}, } - run = self.dataset_populator.run_tool("cat1", inputs=inputs, history_id=self.history_id) - self.dataset_populator.wait_for_history_jobs(self.history_id) + run = self.dataset_populator.run_tool("cat1", inputs=inputs, history_id=history_id) + self.dataset_populator.wait_for_history_jobs(history_id) collections = run["implicit_collections"] collection = collections[0] - jobs_summary_url = f"histories/{self.history_id}/contents/dataset_collections/{collection['id']}/jobs_summary" + jobs_summary_url = f"histories/{history_id}/contents/dataset_collections/{collection['id']}/jobs_summary" jobs_summary_response = self._get(jobs_summary_url) self._assert_status_code_is(jobs_summary_response, 200) jobs_summary = jobs_summary_response.json() @@ -488,16 +486,16 @@ class TestHistoryContentsApi(ApiTestCase): states = jobs_summary["states"] assert states.get("ok") == 2, states - def test_dataset_collection_hide_originals(self): + def test_dataset_collection_hide_originals(self, history_id): payload = self.dataset_collection_populator.create_pair_payload( - self.history_id, type="dataset_collection", direct_upload=False + history_id, type="dataset_collection", direct_upload=False ) payload["hide_source_items"] = True - dataset_collection_response = self._post(f"histories/{self.history_id}/contents", payload, json=True) + dataset_collection_response = self._post(f"histories/{history_id}/contents", payload, json=True) self.__check_create_collection_response(dataset_collection_response) - contents_response = self._get(f"histories/{self.history_id}/contents") + contents_response = self._get(f"histories/{history_id}/contents") datasets = [ d for d in contents_response.json() if d["history_content_type"] == "dataset" and d["hid"] in [1, 2] ] @@ -506,33 +504,33 @@ class TestHistoryContentsApi(ApiTestCase): assert not datasets[0]["visible"] assert not datasets[1]["visible"] - def test_update_dataset_collection(self): - hdca = self._create_pair_collection() + def test_update_dataset_collection(self, history_id): + hdca = self._create_pair_collection(history_id) body = dict(name="newnameforpair") update_response = self._put( - f"histories/{self.history_id}/contents/dataset_collections/{hdca['id']}", data=body, json=True + f"histories/{history_id}/contents/dataset_collections/{hdca['id']}", data=body, json=True ) self._assert_status_code_is(update_response, 200) - show_response = self.__show(hdca) + show_response = self.__show(history_id, hdca) assert str(show_response.json()["name"]) == "newnameforpair" - def test_update_batch_dataset_collection(self): - hdca = self._create_pair_collection() + def test_update_batch_dataset_collection(self, history_id): + hdca = self._create_pair_collection(history_id) body = {"items": [{"history_content_type": "dataset_collection", "id": hdca["id"]}], "name": "newnameforpair"} - update_response = self._put(f"histories/{self.history_id}/contents", data=body, json=True) + update_response = self._put(f"histories/{history_id}/contents", data=body, json=True) self._assert_status_code_is(update_response, 200) - show_response = self.__show(hdca) + show_response = self.__show(history_id, hdca) assert str(show_response.json()["name"]) == "newnameforpair" - def _create_pair_collection(self): - payload = self.dataset_collection_populator.create_pair_payload(self.history_id, type="dataset_collection") + def _create_pair_collection(self, history_id: str): + payload = self.dataset_collection_populator.create_pair_payload(history_id, type="dataset_collection") dataset_collection_response = self._post("tools/fetch", payload, json=True) self._assert_status_code_is(dataset_collection_response, 200) hdca = dataset_collection_response.json()["output_collections"][0] return hdca - def test_hdca_copy(self): - hdca = self.dataset_collection_populator.create_pair_in_history(self.history_id, wait=True).json() + def test_hdca_copy(self, history_id): + hdca = self.dataset_collection_populator.create_pair_in_history(history_id, wait=True).json() hdca_id = hdca["outputs"][0]["id"] second_history_id = self.dataset_populator.new_history() create_data = dict( @@ -546,27 +544,25 @@ class TestHistoryContentsApi(ApiTestCase): self.__check_create_collection_response(create_response) contents = self._get(f"histories/{second_history_id}/contents/dataset_collections").json() assert len(contents) == 1 - new_forward, _ = self.__get_paired_response_elements(contents[0]) + new_forward, _ = self.__get_paired_response_elements(history_id, contents[0]) self._assert_has_keys(new_forward, "history_id") - assert new_forward["history_id"] == self.history_id + assert new_forward["history_id"] == history_id - def test_hdca_copy_with_new_dbkey(self): - fetch_response = self.dataset_collection_populator.create_pair_in_history(self.history_id, wait=True).json() + def test_hdca_copy_with_new_dbkey(self, history_id): + fetch_response = self.dataset_collection_populator.create_pair_in_history(history_id, wait=True).json() hdca = self.dataset_collection_populator.wait_for_fetched_collection(fetch_response) hdca_id = hdca["id"] assert hdca["elements"][0]["object"]["metadata_dbkey"] == "?" assert hdca["elements"][0]["object"]["genome_build"] == "?" create_data = {"source": "hdca", "content": hdca_id, "dbkey": "hg19"} - create_response = self._post( - f"histories/{self.history_id}/contents/dataset_collections", create_data, json=True - ) + create_response = self._post(f"histories/{history_id}/contents/dataset_collections", create_data, json=True) collection = self.__check_create_collection_response(create_response) new_forward = collection["elements"][0]["object"] assert new_forward["metadata_dbkey"] == "hg19" assert new_forward["genome_build"] == "hg19" - def test_hdca_copy_and_elements(self): - hdca = self.dataset_collection_populator.create_pair_in_history(self.history_id, wait=True).json()["outputs"][0] + def test_hdca_copy_and_elements(self, history_id): + hdca = self.dataset_collection_populator.create_pair_in_history(history_id, wait=True).json()["outputs"][0] hdca_id = hdca["id"] second_history_id = self.dataset_populator.new_history() create_data = dict( @@ -582,12 +578,12 @@ class TestHistoryContentsApi(ApiTestCase): contents = self._get(f"histories/{second_history_id}/contents/dataset_collections").json() assert len(contents) == 1 - new_forward, _ = self.__get_paired_response_elements(contents[0]) + new_forward, _ = self.__get_paired_response_elements(history_id, contents[0]) self._assert_has_keys(new_forward, "history_id") assert new_forward["history_id"] == second_history_id - def __get_paired_response_elements(self, contents): - hdca = self.__show(contents).json() + def __get_paired_response_elements(self, history_id: str, contents): + hdca = self.__show(history_id, contents).json() self._assert_has_keys(hdca, "name", "deleted", "visible", "elements") elements = hdca["elements"] assert len(elements) == 2 @@ -598,11 +594,10 @@ class TestHistoryContentsApi(ApiTestCase): return element0["object"], element1["object"] - def test_hdca_from_library_datasets(self): + def test_hdca_from_library_datasets(self, history_id): ld = self.library_populator.new_library_dataset("el1") ldda_id = ld["ldda_id"] element_identifiers = [{"name": "el1", "src": "ldda", "id": ldda_id}] - history_id = self.dataset_populator.new_history() create_data = dict( history_id=history_id, type="dataset_collection", @@ -620,14 +615,14 @@ class TestHistoryContentsApi(ApiTestCase): assert hda["copied_from_ldda_id"] == ldda_id assert hda["history_id"] == history_id - def test_hdca_from_inaccessible_library_datasets(self): + def test_hdca_from_inaccessible_library_datasets(self, history_id): library, library_dataset = self.library_populator.new_library_dataset_in_private_library( "HDCACreateInaccesibleLibrary" ) ldda_id = library_dataset["id"] element_identifiers = [{"name": "el1", "src": "ldda", "id": ldda_id}] create_data = dict( - history_id=self.history_id, + history_id=history_id, type="dataset_collection", name="Test From Library", element_identifiers=element_identifiers, @@ -648,15 +643,13 @@ class TestHistoryContentsApi(ApiTestCase): self._assert_has_keys(dataset_collection, "url", "name", "deleted", "visible", "elements") return dataset_collection - def __show(self, contents): + def __show(self, history_id, contents): show_response = self._get( - f"histories/{self.history_id}/contents/{contents['history_content_type']}s/{contents['id']}" + f"histories/{history_id}/contents/{contents['history_content_type']}s/{contents['id']}" ) return show_response - def __count_contents(self, history_id=None, **kwds): - if history_id is None: - history_id = self.history_id + def __count_contents(self, history_id: str, **kwds): contents_response = self._get(f"histories/{history_id}/contents", kwds) return len(contents_response.json()) @@ -676,13 +669,13 @@ class TestHistoryContentsApi(ApiTestCase): assert input_hda["name"] == query_hda["name"] assert input_hda["id"] == query_hda["id"] - def test_job_state_summary_field(self): + def test_job_state_summary_field(self, history_id): create_response = self.dataset_collection_populator.create_pair_in_history( - self.history_id, + history_id, contents=["123", "456"], ) self._assert_status_code_is(create_response, 200) - contents_response = self._get(f"histories/{self.history_id}/contents?v=dev&keys=job_state_summary&view=summary") + contents_response = self._get(f"histories/{history_id}/contents?v=dev&keys=job_state_summary&view=summary") self._assert_status_code_is(contents_response, 200) contents = contents_response.json() for c in contents: @@ -821,8 +814,7 @@ class TestHistoryContentsApi(ApiTestCase): f"History content update time query did not include populated_state update for dynamic nested collection {collection_id}" ) - def test_index_filter_by_type(self): - history_id = self.dataset_populator.new_history() + def test_index_filter_by_type(self, history_id): self.dataset_populator.new_dataset(history_id) self.dataset_collection_populator.create_list_in_history(history_id=history_id, wait=True) @@ -840,8 +832,7 @@ class TestHistoryContentsApi(ApiTestCase): contents_response = self._get(f"histories/{history_id}/contents?types=dataset&types=dataset_collection").json() assert len(contents_response) == expected_num_datasets + expected_num_collections - def test_index_filter_by_name_ignores_case(self): - history_id = self.dataset_populator.new_history() + def test_index_filter_by_name_ignores_case(self, history_id): self.dataset_populator.new_dataset(history_id, name="AC") self.dataset_populator.new_dataset(history_id, name="ac") self.dataset_populator.new_dataset(history_id, name="Bc") @@ -867,8 +858,7 @@ class TestHistoryContentsApi(ApiTestCase): ).json() assert len(contents_response) == 0 - def test_elements_datatypes_field(self): - history_id = self.dataset_populator.new_history() + def test_elements_datatypes_field(self, history_id): collection_name = "homogeneous" expected_datatypes = ["txt"] elements = [ # List with all elements of txt datatype (homogeneous) diff --git a/lib/galaxy_test/api/test_jobs.py b/lib/galaxy_test/api/test_jobs.py index 126a4a11a89..5ac8b0c690f 100644 --- a/lib/galaxy_test/api/test_jobs.py +++ b/lib/galaxy_test/api/test_jobs.py @@ -6,6 +6,7 @@ import urllib.parse from operator import itemgetter from unittest import SkipTest +import pytest import requests from dateutil.parser import isoparse @@ -15,7 +16,6 @@ from galaxy_test.base.populators import ( DatasetCollectionPopulator, DatasetPopulator, skip_without_tool, - uses_test_history, wait_on, wait_on_state, WorkflowPopulator, @@ -32,14 +32,14 @@ class TestJobsApi(ApiTestCase, TestsTools): self.dataset_populator = DatasetPopulator(self.galaxy_interactor) self.dataset_collection_populator = DatasetCollectionPopulator(self.galaxy_interactor) - @uses_test_history(require_new=True) + @pytest.mark.require_new_history def test_index(self, history_id): # Create HDA to ensure at least one job exists... self.__history_with_new_dataset(history_id) jobs = self.__jobs_index() assert "__DATA_FETCH__" in map(itemgetter("tool_id"), jobs) - @uses_test_history(require_new=True) + @pytest.mark.require_new_history def test_system_details_admin_only(self, history_id): self.__history_with_new_dataset(history_id) jobs = self.__jobs_index(admin=False) @@ -50,7 +50,7 @@ class TestJobsApi(ApiTestCase, TestsTools): job = jobs[0] self._assert_has_keys(job, "command_line", "external_id") - @uses_test_history(require_new=True) + @pytest.mark.require_new_history def test_admin_job_list(self, history_id): self.__history_with_new_dataset(history_id) jobs_response = self._get("jobs?view=admin_job_list", admin=False) @@ -61,7 +61,7 @@ class TestJobsApi(ApiTestCase, TestsTools): job = jobs[0] self._assert_has_keys(job, "command_line", "external_id", "handler") - @uses_test_history(require_new=True) + @pytest.mark.require_new_history def test_index_state_filter(self, history_id): # Initial number of ok jobs original_count = len(self.__uploads_with_state("ok")) @@ -83,7 +83,7 @@ class TestJobsApi(ApiTestCase, TestsTools): message = template % (original_count, new_count) raise AssertionError(message) - @uses_test_history(require_new=True) + @pytest.mark.require_new_history def test_index_date_filter(self, history_id): two_weeks_ago = (datetime.datetime.utcnow() - datetime.timedelta(14)).isoformat() last_week = (datetime.datetime.utcnow() - datetime.timedelta(7)).isoformat() @@ -106,7 +106,7 @@ class TestJobsApi(ApiTestCase, TestsTools): jobs = self.__jobs_index(data={"date_range_min": two_weeks_ago, "date_range_max": last_week}) assert today_job_id not in map(itemgetter("id"), jobs) - @uses_test_history(require_new=True) + @pytest.mark.require_new_history def test_index_history(self, history_id): self.__history_with_new_dataset(history_id) jobs = self.__jobs_index(data={"history_id": history_id}) @@ -116,7 +116,7 @@ class TestJobsApi(ApiTestCase, TestsTools): jobs = self.__jobs_index(data={"history_id": other_history_id}) assert len(jobs) == 0 - @uses_test_history(require_new=True) + @pytest.mark.require_new_history @skip_without_tool("cat1") def test_index_workflow_and_invocation_filter(self, history_id): workflow_simple = """ @@ -145,7 +145,7 @@ steps: assert len(jobs2) == 1 assert jobs1 == jobs2 - @uses_test_history(require_new=True) + @pytest.mark.require_new_history @skip_without_tool("multi_data_optional") def test_index_workflow_filter_implicit_jobs(self, history_id): workflow_id = self.workflow_populator.upload_yaml_workflow( @@ -179,7 +179,7 @@ steps: assert len(workflow_jobs) == 2 assert len(second_invocation_jobs) == 1 - @uses_test_history(require_new=True) + @pytest.mark.require_new_history def test_index_limit_and_offset_filter(self, history_id): self.__history_with_new_dataset(history_id) jobs = self.__jobs_index(data={"history_id": history_id}) @@ -190,7 +190,7 @@ steps: jobs = self.__jobs_index(data={"history_id": history_id, "limit": 0}) assert len(jobs) == 0 - @uses_test_history(require_new=True) + @pytest.mark.require_new_history def test_index_search_filter_tool_id(self, history_id): self.__history_with_new_dataset(history_id) jobs = self.__jobs_index(data={"history_id": history_id}) @@ -203,7 +203,7 @@ steps: jobs = self.__jobs_index(data={"history_id": history_id, "search": "tool:'FETCH'"}) assert len(jobs) == 0 - @uses_test_history(require_new=True) + @pytest.mark.require_new_history def test_index_search_filter_email(self, history_id): self.__history_with_new_dataset(history_id) jobs = self.__jobs_index(data={"history_id": history_id, "search": "FETCH"}) @@ -236,7 +236,7 @@ steps: self._assert_status_code_is(jobs_response, 403) assert jobs_response.json() == {"err_msg": "Only admins can index the jobs of others", "err_code": 403006} - @uses_test_history(require_new=True) + @pytest.mark.require_new_history def test_index_handler_runner_filters(self, history_id): self.__history_with_new_dataset(history_id) @@ -281,7 +281,7 @@ steps: ).json() assert not jobs - @uses_test_history(require_new=True) + @pytest.mark.require_new_history def test_index_multiple_states_filter(self, history_id): # Initial number of ok jobs original_count = len(self.__uploads_with_state("ok", "new")) @@ -294,7 +294,7 @@ steps: new_count = len(self.__uploads_with_state("new", "ok")) assert original_count < new_count, new_count - @uses_test_history(require_new=True) + @pytest.mark.require_new_history def test_show(self, history_id): job_properties_tool_run = self.dataset_populator.run_tool( tool_id="job_properties", @@ -341,7 +341,7 @@ steps: assert "The bool is not true\n" in job_details["stdout"] assert "The bool is very not true\n" in job_details["stderr"] - @uses_test_history(require_new=True) + @pytest.mark.require_new_history def test_show_security(self, history_id): self.__history_with_new_dataset(history_id) jobs_response = self._get("jobs", data={"history_id": history_id}) @@ -502,8 +502,8 @@ steps: run_response = self._post("tools", data=payload, key=self.master_api_key) self._assert_status_code_is(run_response, 400) + @pytest.mark.require_new_history @skip_without_tool("create_2") - @uses_test_history(require_new=True) def test_deleting_output_keep_running_until_all_deleted(self, history_id): job_state, outputs = self._setup_running_two_output_job(history_id, 120) @@ -526,8 +526,8 @@ steps: final_state = wait_on_state(job_state, assert_ok=False, timeout=15) assert final_state in ["deleting", "deleted"], final_state + @pytest.mark.require_new_history @skip_without_tool("create_2") - @uses_test_history(require_new=True) def test_purging_output_keep_running_until_all_purged(self, history_id): job_state, outputs = self._setup_running_two_output_job(history_id, 120) @@ -569,8 +569,8 @@ steps: if output_dataset_paths_exist: wait_on(paths_deleted, "path deletion") + @pytest.mark.require_new_history @skip_without_tool("create_2") - @uses_test_history(require_new=True) def test_purging_output_cleaned_after_ok_run(self, history_id): job_state, outputs = self._setup_running_two_output_job(history_id, 10) @@ -640,8 +640,8 @@ steps: assert_status_code_is_ok(update_response) return update_response + @pytest.mark.require_new_history @skip_without_tool("cat_data_and_sleep") - @uses_test_history(require_new=True) def test_resume_job(self, history_id): hda1 = self.dataset_populator.new_dataset(history_id, content="samp1\t10.0\nsamp2\t20.0\n") hda2 = self.dataset_populator.new_dataset(history_id, content="samp1\t30.0\nsamp2\t40.0\n") @@ -688,7 +688,7 @@ steps: assert_status_code_is_ok(response) return response.json() - @uses_test_history(require_new=True) + @pytest.mark.require_new_history def test_search(self, history_id): dataset_id = self.__history_with_ok_dataset(history_id) # We first copy the datasets, so that the update time is lower than the job creation time @@ -712,7 +712,7 @@ steps: self._assert_status_code_is(delete_respone, 200) self._search(search_payload, expected_search_count=0) - @uses_test_history(require_new=True) + @pytest.mark.require_new_history def test_search_handle_identifiers(self, history_id): # Test that input name and element identifier of a jobs' output must match for a job to be returned. dataset_id = self.__history_with_ok_dataset(history_id) @@ -728,7 +728,7 @@ steps: search_payload = self._search_payload(history_id=history_id, tool_id="identifier_single", inputs=inputs) self._search(search_payload, expected_search_count=0) - @uses_test_history(require_new=True) + @pytest.mark.require_new_history def test_search_delete_outputs(self, history_id): dataset_id = self.__history_with_ok_dataset(history_id) inputs = json.dumps({"input1": {"src": "hda", "id": dataset_id}}) @@ -739,7 +739,7 @@ steps: search_payload = self._search_payload(history_id=history_id, tool_id="cat1", inputs=inputs) self._search(search_payload, expected_search_count=0) - @uses_test_history(require_new=True) + @pytest.mark.require_new_history def test_search_with_hdca_list_input(self, history_id): list_id_a = self.__history_with_ok_collection(collection_type="list", history_id=history_id) list_id_b = self.__history_with_ok_collection(collection_type="list", history_id=history_id) @@ -767,7 +767,7 @@ steps: search_payload = self._search_payload(history_id=history_id, tool_id="multi_data_param", inputs=inputs) self._search(search_payload, expected_search_count=0) - @uses_test_history(require_new=True) + @pytest.mark.require_new_history def test_search_delete_hdca_output(self, history_id): list_id_a = self.__history_with_ok_collection(collection_type="list", history_id=history_id) inputs = json.dumps( @@ -790,7 +790,7 @@ steps: search_payload = self._search_payload(history_id=history_id, tool_id="collection_creates_list", inputs=inputs) self._search(search_payload, expected_search_count=0) - @uses_test_history(require_new=True) + @pytest.mark.require_new_history def test_search_with_hdca_pair_input(self, history_id): list_id_a = self.__history_with_ok_collection(collection_type="pair", history_id=history_id) inputs = json.dumps( @@ -825,7 +825,7 @@ steps: self._assert_status_code_is(delete_respone, 200) self._search(search_payload, expected_search_count=0) - @uses_test_history(require_new=True) + @pytest.mark.require_new_history def test_search_with_hdca_list_pair_input(self, history_id): list_id_a = self.__history_with_ok_collection(collection_type="list:pair", history_id=history_id) inputs = json.dumps( @@ -836,7 +836,7 @@ steps: ) self._job_search(tool_id="multi_data_param", history_id=history_id, inputs=inputs) - @uses_test_history(require_new=True) + @pytest.mark.require_new_history def test_search_with_hdca_list_pair_collection_mapped_over_pair_input(self, history_id): list_id_a = self.__history_with_ok_collection(collection_type="list:pair", history_id=history_id) inputs = json.dumps( @@ -868,7 +868,6 @@ steps: return rerun_params @skip_without_tool("collection_paired_test") - @uses_test_history(require_new=False) def test_job_build_for_rerun(self, history_id): rerun_params = self._get_simple_rerun_params(history_id) self._run( @@ -880,7 +879,6 @@ steps: ) @skip_without_tool("collection_paired_test") - @uses_test_history(require_new=False) def test_dce_submission_security(self, history_id): rerun_params = self._get_simple_rerun_params(history_id, private=True) with self._different_user(): @@ -895,7 +893,6 @@ steps: assert response.status_code == 403 @skip_without_tool("identifier_collection") - @uses_test_history(require_new=False) def test_job_build_for_rerun_list_list(self, history_id): list_id_a = self.__history_with_ok_collection(collection_type="list", history_id=history_id) list_id_b = self.__history_with_ok_collection(collection_type="list", history_id=history_id) diff --git a/lib/galaxy_test/api/test_roles.py b/lib/galaxy_test/api/test_roles.py index 5e77a442435..99298d3157e 100644 --- a/lib/galaxy_test/api/test_roles.py +++ b/lib/galaxy_test/api/test_roles.py @@ -143,7 +143,7 @@ class TestRolesApi(ApiTestCase): assert "administrator" in response_err["err_msg"] @staticmethod - def check_role_dict(role_dict: Dict[str, Any], assert_id: Optional[str] = None): + def check_role_dict(role_dict: Dict[str, Any], assert_id: Optional[str] = None) -> None: assert_has_keys(role_dict, "id", "name", "model_class", "url") assert role_dict["model_class"] == "Role" if assert_id is not None: diff --git a/lib/galaxy_test/api/test_tools.py b/lib/galaxy_test/api/test_tools.py index 4bba1c9b9f9..444e8b49779 100644 --- a/lib/galaxy_test/api/test_tools.py +++ b/lib/galaxy_test/api/test_tools.py @@ -25,7 +25,6 @@ from galaxy_test.base.populators import ( LibraryPopulator, skip_without_tool, stage_rules_example, - uses_test_history, ) from ._framework import ApiTestCase @@ -337,7 +336,6 @@ class TestToolsApi(ApiTestCase, TestsTools): return tool_info @skip_without_tool("model_attributes") - @uses_test_history(require_new=False) def test_model_attributes_sanitization(self, history_id): cool_name_with_quote = 'cool name with a quo"te' cool_name_without_quote = "cool name with a quo__dq__te" @@ -472,7 +470,6 @@ class TestToolsApi(ApiTestCase, TestsTools): } assert set(namelist) == expected_names - @uses_test_history(require_new=False) def test_convert_dataset_explicit_history(self, history_id): fasta1_contents = open(self.get_filename("1.fasta")).read() hda1 = self.dataset_populator.new_dataset(history_id, content=fasta1_contents) @@ -491,7 +488,6 @@ class TestToolsApi(ApiTestCase, TestsTools): for output in create_response.json()["outputs"]: assert output["file_ext"] == "tabular" - @uses_test_history(require_new=False) def test_convert_dataset_implicit_history(self, history_id): fasta1_contents = open(self.get_filename("1.fasta")).read() hda1 = self.dataset_populator.new_dataset(history_id, content=fasta1_contents) @@ -504,7 +500,6 @@ class TestToolsApi(ApiTestCase, TestsTools): for output in create_response.json()["outputs"]: assert output["file_ext"] == "tabular" - @uses_test_history(require_new=False) def test_convert_hdca(self, history_id): data = [ { @@ -631,7 +626,6 @@ class TestToolsApi(ApiTestCase, TestsTools): assert zipped_hdca["collection_type"] == "paired" @skip_without_tool("__ZIP_COLLECTION__") - @uses_test_history(require_new=False) def test_collection_operation_dataset_input_permissions(self, history_id): hda1 = dataset_to_param(self.dataset_populator.new_dataset(history_id, content="1\t2\t3")) self.dataset_populator.wait_for_history(history_id, assert_ok=True) @@ -645,7 +639,6 @@ class TestToolsApi(ApiTestCase, TestsTools): self._assert_dataset_permission_denied_response(response) @skip_without_tool("__UNZIP_COLLECTION__") - @uses_test_history(require_new=False) def test_collection_operation_collection_input_permissions(self, history_id): create_response = self.dataset_collection_populator.create_pair_in_history( history_id, direct_upload=True, wait=True @@ -867,7 +860,6 @@ class TestToolsApi(ApiTestCase, TestsTools): assert output2_content == "4\t5\t6\n1\t2\t3\n", output2_content @skip_without_tool("cat1") - @uses_test_history(require_new=False) def test_run_cat1(self, history_id): # Run simple non-upload tool with an input data parameter. new_dataset = self.dataset_populator.new_dataset(history_id, content="Cat1Test") @@ -880,8 +872,8 @@ class TestToolsApi(ApiTestCase, TestsTools): output1_content = self.dataset_populator.get_history_dataset_content(history_id, dataset=output1) assert output1_content.strip() == "Cat1Test" + @pytest.mark.require_new_history @skip_without_tool("cat1") - @uses_test_history(require_new=True) def test_run_cat1_use_cached_job(self, history_id): # Run simple non-upload tool with an input data parameter. new_dataset = self.dataset_populator.new_dataset(history_id, content="Cat1Test") @@ -902,7 +894,6 @@ class TestToolsApi(ApiTestCase, TestsTools): assert len(set(filenames)) <= 2, filenames @skip_without_tool("cat1") - @uses_test_history(require_new=False) def test_run_cat1_listified_param(self, history_id): # Run simple non-upload tool with an input data parameter. new_dataset = self.dataset_populator.new_dataset(history_id, content="Cat1Testlistified") @@ -916,7 +907,6 @@ class TestToolsApi(ApiTestCase, TestsTools): assert output1_content.strip() == "Cat1Testlistified" @skip_without_tool("multiple_versions") - @uses_test_history(require_new=False) def test_run_by_versions(self, history_id): for version in ["0.1", "0.2"]: # Run simple non-upload tool with an input data parameter. @@ -929,7 +919,6 @@ class TestToolsApi(ApiTestCase, TestsTools): assert output1_content.strip() == f"Version {version}" @skip_without_tool("multiple_versions") - @uses_test_history(require_new=False) def test_test_by_versions(self, history_id): test_data_response = self._get(f"tools/{'multiple_versions'}/test_data") test_data_response.raise_for_status() @@ -943,14 +932,12 @@ class TestToolsApi(ApiTestCase, TestsTools): assert len(test_data_dicts) == 3 @skip_without_tool("multiple_versions") - @uses_test_history(require_new=False) def test_show_with_wrong_tool_version_in_tool_id(self, history_id): tool_info = self._show_valid_tool("multiple_versions", tool_version="0.01") # Return last version assert tool_info["version"] == "0.2" @skip_without_tool("cat1") - @uses_test_history(require_new=False) def test_run_cat1_single_meta_wrapper(self, history_id): # Wrap input in a no-op meta parameter wrapper like Sam is planning to # use for all UI API submissions. @@ -965,7 +952,6 @@ class TestToolsApi(ApiTestCase, TestsTools): assert output1_content.strip() == "123" @skip_without_tool("cat1") - @uses_test_history(require_new=False) def test_guess_derived_permissions(self, history_id): def assert_inputs(inputs, can_be_used=True): # Until we make the dataset private, _different_user() can use it: @@ -997,7 +983,6 @@ class TestToolsApi(ApiTestCase, TestsTools): assert_inputs(inputs_2, can_be_used=False) @skip_without_tool("collection_creates_list") - @uses_test_history(require_new=False) def test_guess_derived_permissions_collections(self, history_id): def first_element_dataset_id(hdca): # Fetch full and updated details for HDCA @@ -1039,7 +1024,6 @@ class TestToolsApi(ApiTestCase, TestsTools): assert not _dataset_accessible(private_element_id) @skip_without_tool("validation_default") - @uses_test_history(require_new=False) def test_validation(self, history_id): inputs = { "select_param": '" ; echo "moo', @@ -1048,7 +1032,6 @@ class TestToolsApi(ApiTestCase, TestsTools): self._assert_status_code_is(response, 400) @skip_without_tool("validation_empty_dataset") - @uses_test_history(require_new=False) def test_validation_empty_dataset(self, history_id): outputs = self._run_and_get_outputs("empty_output", history_id) empty_dataset = outputs[0] @@ -1060,7 +1043,6 @@ class TestToolsApi(ApiTestCase, TestsTools): self._assert_status_code_is(response, 400) @skip_without_tool("validation_repeat") - @uses_test_history(require_new=False) def test_validation_in_repeat(self, history_id): inputs = { "r1_0|text": "123", @@ -1070,7 +1052,6 @@ class TestToolsApi(ApiTestCase, TestsTools): self._assert_status_code_is(response, 400) @skip_without_tool("multi_select") - @uses_test_history(require_new=False) def test_select_legal_values(self, history_id): inputs = { "select_ex": "not_option", @@ -1079,7 +1060,6 @@ class TestToolsApi(ApiTestCase, TestsTools): self._assert_status_code_is(response, 400) @skip_without_tool("column_param") - @uses_test_history(require_new=False) def test_column_legal_values(self, history_id): new_dataset1 = self.dataset_populator.new_dataset(history_id, content="#col1\tcol2") inputs = { @@ -1094,8 +1074,8 @@ class TestToolsApi(ApiTestCase, TestsTools): final_job_state = self.dataset_populator.wait_for_job(job["id"]) assert final_job_state == "error" + @pytest.mark.require_new_history @skip_without_tool("collection_paired_test") - @uses_test_history(require_new=True) def test_collection_parameter(self, history_id): hdca_id = self._build_pair(history_id, ["123\n", "456\n"]) inputs = { @@ -1109,7 +1089,6 @@ class TestToolsApi(ApiTestCase, TestsTools): assert contents.strip() == "123\n456", contents @skip_without_tool("collection_creates_pair") - @uses_test_history(require_new=False) def test_paired_collection_output(self, history_id): new_dataset1 = self.dataset_populator.new_dataset(history_id, content="123\n456\n789\n0ab") inputs = { @@ -1125,7 +1104,6 @@ class TestToolsApi(ApiTestCase, TestsTools): self._verify_element(history_id, element1, contents="456\n0ab\n", file_ext="txt", visible=False) @skip_without_tool("collection_creates_list") - @uses_test_history(require_new=False) def test_list_collection_output(self, history_id): create_response = self.dataset_collection_populator.create_list_in_history( history_id, contents=["a\nb\nc\nd", "e\nf\ng\nh"], wait=True @@ -1139,7 +1117,6 @@ class TestToolsApi(ApiTestCase, TestsTools): self._verify_element(history_id, element1, contents="identifier is data1\n", file_ext="txt") @skip_without_tool("collection_creates_list_2") - @uses_test_history(require_new=False) def test_list_collection_output_format_source(self, history_id): # test using format_source with a tool new_dataset1 = self.dataset_populator.new_dataset(history_id, content="#col1\tcol2") @@ -1161,7 +1138,6 @@ class TestToolsApi(ApiTestCase, TestsTools): self._verify_element(history_id, element1, contents="#col1\tcol2\ne\tf\ng\th\n", file_ext="txt") @skip_without_tool("collection_split_on_column") - @uses_test_history(require_new=False) def test_dynamic_list_output(self, history_id): new_dataset1 = self.dataset_populator.new_dataset( history_id, content="samp1\t1\nsamp1\t3\nsamp2\t2\nsamp2\t4\n" @@ -1197,7 +1173,6 @@ class TestToolsApi(ApiTestCase, TestsTools): assert output_element_hda_0["metadata_column_types"] is not None @skip_without_tool("collection_creates_dynamic_nested") - @uses_test_history(require_new=False) def test_dynamic_list_output_datasets_in_failed_state(self, history_id): inputs = {"fail_bool": True} create = self._run("collection_creates_dynamic_nested", history_id, inputs, assert_ok=False, wait_for_job=True) @@ -1310,7 +1285,6 @@ class TestToolsApi(ApiTestCase, TestsTools): self._assert_status_code_is(response, 404) @skip_without_tool("cat1") - @uses_test_history(require_new=False) def test_run_cat1_with_two_inputs(self, history_id): # Run tool with an multiple data parameter and grouping (repeat) new_dataset1 = self.dataset_populator.new_dataset(history_id, content="Cat1Test") @@ -1323,7 +1297,6 @@ class TestToolsApi(ApiTestCase, TestsTools): assert output1_content.strip() == "Cat1Test\nCat2Test" @skip_without_tool("mapper_two") - @uses_test_history(require_new=False) def test_bam_state_regression(self, history_id): # Test regression of https://github.com/galaxyproject/galaxy/issues/6856. With changes # to metadata file flushing to optimize creating bam outputs and copying bam datasets @@ -1342,7 +1315,6 @@ class TestToolsApi(ApiTestCase, TestsTools): assert details["state"] == "ok" @skip_without_tool("qc_stdout") - @uses_test_history(require_new=False) def test_qc_messages(self, history_id): new_dataset1 = self.dataset_populator.new_dataset(history_id, content="123\n456\n789") inputs = { @@ -1361,7 +1333,6 @@ class TestToolsApi(ApiTestCase, TestsTools): assert qc_message["error_level"] == 1.1 @skip_without_tool("cat1") - @uses_test_history(require_new=False) def test_multirun_cat1(self, history_id): new_dataset1 = self.dataset_populator.new_dataset(history_id, content="123") new_dataset2 = self.dataset_populator.new_dataset(history_id, content="456") @@ -1385,7 +1356,6 @@ class TestToolsApi(ApiTestCase, TestsTools): assert output2_content.strip() == "456" @skip_without_tool("random_lines1") - @uses_test_history(require_new=False) def test_multirun_non_data_parameter(self, history_id): new_dataset1 = self.dataset_populator.new_dataset(history_id, content="123\n456\n789") inputs = {"input": dataset_to_param(new_dataset1), "num_lines": {"batch": True, "values": [1, 2, 3]}} @@ -1599,7 +1569,6 @@ class TestToolsApi(ApiTestCase, TestsTools): ) @skip_without_tool("cat") - @uses_test_history(require_new=False) def test_map_over_collection(self, history_id): hdca_id = self._build_pair(history_id, ["123", "456"]) inputs = { @@ -1608,7 +1577,6 @@ class TestToolsApi(ApiTestCase, TestsTools): self._run_and_check_simple_collection_mapping(history_id, inputs) @skip_without_tool("cat1") - @uses_test_history(require_new=False) def test_map_over_empty_collection(self, history_id): hdca_id = self.dataset_collection_populator.create_list_in_history(history_id, contents=[]).json()["outputs"][ 0 @@ -1628,7 +1596,6 @@ class TestToolsApi(ApiTestCase, TestsTools): assert empty_output["name"] == "Concatenate datasets on collection 1", empty_output @skip_without_tool("output_action_change_format") - @uses_test_history(require_new=False) def test_map_over_with_output_format_actions(self, history_id): for use_action in ["do", "dont"]: hdca_id = self._build_pair(history_id, ["123", "456"]) @@ -1651,7 +1618,6 @@ class TestToolsApi(ApiTestCase, TestsTools): assert output2_details["file_ext"] == "txt" if (use_action == "do") else "data" @skip_without_tool("output_action_change_format_paired") - @uses_test_history(require_new=False) def test_map_over_with_nested_paired_output_format_actions(self, history_id): hdca_id = self.__build_nested_list(history_id) inputs = {"input": {"batch": True, "values": [dict(map_over_type="paired", src="hdca", id=hdca_id)]}} @@ -1666,7 +1632,6 @@ class TestToolsApi(ApiTestCase, TestsTools): assert output["file_ext"] == "txt", output @skip_without_tool("output_filter_with_input") - @uses_test_history(require_new=False) def test_map_over_with_output_filter_no_filtering(self, history_id): hdca_id = self.dataset_collection_populator.create_list_in_history(history_id, wait=True).json()["outputs"][0][ "id" @@ -1684,7 +1649,6 @@ class TestToolsApi(ApiTestCase, TestsTools): self._check_implicit_collection_populated(create) @skip_without_tool("output_filter_with_input_optional") - @uses_test_history(require_new=False) def test_map_over_with_output_filter_on_optional_input(self, history_id): hdca_id = self.dataset_collection_populator.create_list_in_history( history_id, contents=["myinputs"], wait=True @@ -1701,7 +1665,6 @@ class TestToolsApi(ApiTestCase, TestsTools): self._check_implicit_collection_populated(create) @skip_without_tool("output_filter_with_input") - @uses_test_history(require_new=False) def test_map_over_with_output_filter_one_filtered(self, history_id): hdca_id = self.dataset_collection_populator.create_list_in_history(history_id, wait=True).json()["outputs"][0][ "id" @@ -1719,7 +1682,6 @@ class TestToolsApi(ApiTestCase, TestsTools): self._check_implicit_collection_populated(create) @skip_without_tool("Cut1") - @uses_test_history(require_new=False) def test_map_over_with_complex_output_actions(self, history_id): hdca_id = self._bed_list(history_id) inputs = { @@ -1742,7 +1704,6 @@ class TestToolsApi(ApiTestCase, TestsTools): assert output2_content.startswith("chr1") @skip_without_tool("collection_creates_dynamic_list_of_pairs") - @uses_test_history(require_new=False) def test_map_over_with_discovered_output_collection_elements(self, history_id): hdca_id = self.dataset_collection_populator.create_list_in_history(history_id, wait=True).json()["outputs"][0][ "id" @@ -1765,7 +1726,6 @@ class TestToolsApi(ApiTestCase, TestsTools): return hdca["outputs"][0]["id"] @skip_without_tool("identifier_single") - @uses_test_history(require_new=False) def test_identifier_in_map(self, history_id): hdca_id = self._build_pair(history_id, ["123", "456"]) inputs = { @@ -1788,7 +1748,6 @@ class TestToolsApi(ApiTestCase, TestsTools): assert output2_content.strip() == "reverse" @skip_without_tool("identifier_single") - @uses_test_history(require_new=False) def test_identifier_outside_map(self, history_id): new_dataset1 = self.dataset_populator.new_dataset(history_id, content="123", name="Plain HDA") inputs = { @@ -1808,14 +1767,12 @@ class TestToolsApi(ApiTestCase, TestsTools): assert output1_content.strip() == "Plain HDA" @skip_without_tool("identifier_multiple") - @uses_test_history(require_new=False) def test_list_selectable_in_multidata_input(self, history_id): self.dataset_collection_populator.create_list_in_history(history_id, contents=["123", "456"], wait=True) build = self.dataset_populator.build_tool_state("identifier_multiple", history_id) assert len(build["inputs"][0]["options"]["hdca"]) == 1 @skip_without_tool("identifier_multiple") - @uses_test_history(require_new=False) def test_identifier_in_multiple_reduce(self, history_id): hdca_id = self._build_pair(history_id, ["123", "456"]) inputs = { @@ -1835,7 +1792,6 @@ class TestToolsApi(ApiTestCase, TestsTools): assert output1_content.strip() == "forward\nreverse" @skip_without_tool("identifier_in_conditional") - @uses_test_history(require_new=False) def test_identifier_map_over_multiple_input_in_conditional(self, history_id): hdca_id = self._build_pair(history_id, ["123", "456"]) inputs = { @@ -1855,7 +1811,6 @@ class TestToolsApi(ApiTestCase, TestsTools): assert output1_content.strip() == "forward\nreverse" @skip_without_tool("identifier_in_conditional") - @uses_test_history(require_new=False) def test_identifier_map_over_multiple_input_in_conditional_new_payload_form(self, history_id): hdca_id = self._build_pair(history_id, ["123", "456"]) inputs = { @@ -1878,7 +1833,6 @@ class TestToolsApi(ApiTestCase, TestsTools): assert output1_content.strip() == "forward\nreverse" @skip_without_tool("identifier_multiple_in_repeat") - @uses_test_history(require_new=False) def test_identifier_multiple_reduce_in_repeat_new_payload_form(self, history_id): hdca_id = self._build_pair(history_id, ["123", "456"]) inputs = { @@ -1898,7 +1852,6 @@ class TestToolsApi(ApiTestCase, TestsTools): assert output1_content.strip() == "forward\nreverse" @skip_without_tool("identifier_in_conditional") - @uses_test_history(require_new=False) def test_identifier_map_over_input_in_conditional(self, history_id): # Run cat tool, so HDA names are different from element identifiers hdca_id = self._build_pair(history_id, ["123", "456"], run_cat=True) @@ -1923,7 +1876,6 @@ class TestToolsApi(ApiTestCase, TestsTools): assert output2_content.strip() == "reverse" @skip_without_tool("identifier_multiple_in_conditional") - @uses_test_history(require_new=False) def test_identifier_multiple_reduce_in_conditional(self, history_id): hdca_id = self._build_pair(history_id, ["123", "456"]) inputs = { @@ -1943,7 +1895,6 @@ class TestToolsApi(ApiTestCase, TestsTools): assert output1_content.strip() == "forward\nreverse" @skip_without_tool("identifier_multiple_in_repeat") - @uses_test_history(require_new=False) def test_identifier_multiple_reduce_in_repeat(self, history_id): hdca_id = self._build_pair(history_id, ["123", "456"]) inputs = { @@ -1963,7 +1914,6 @@ class TestToolsApi(ApiTestCase, TestsTools): assert output1_content.strip() == "forward\nreverse" @skip_without_tool("identifier_single_in_repeat") - @uses_test_history(require_new=False) def test_identifier_single_in_repeat(self, history_id): hdca_id = self._build_pair(history_id, ["123", "456"]) inputs = {"the_repeat_0|the_data|input1": {"batch": True, "values": [{"src": "hdca", "id": hdca_id}]}} @@ -1982,7 +1932,6 @@ class TestToolsApi(ApiTestCase, TestsTools): assert output1_content.strip() == "forward", output1_content @skip_without_tool("identifier_multiple_in_conditional") - @uses_test_history(require_new=False) def test_identifier_multiple_in_conditional(self, history_id): new_dataset1 = self.dataset_populator.new_dataset(history_id, content="123", name="Normal HDA1") inputs = { @@ -2002,7 +1951,6 @@ class TestToolsApi(ApiTestCase, TestsTools): assert output1_content.strip() == "Normal HDA1" @skip_without_tool("identifier_multiple") - @uses_test_history(require_new=False) def test_identifier_with_multiple_normal_datasets(self, history_id): new_dataset1 = self.dataset_populator.new_dataset(history_id, content="123", name="Normal HDA1") new_dataset2 = self.dataset_populator.new_dataset(history_id, content="456", name="Normal HDA2") @@ -2021,7 +1969,6 @@ class TestToolsApi(ApiTestCase, TestsTools): assert output1_content.strip() == "Normal HDA1\nNormal HDA2" @skip_without_tool("identifier_collection") - @uses_test_history(require_new=False) def test_identifier_with_data_collection(self, history_id): element_identifiers = self.dataset_collection_populator.list_identifiers(history_id) @@ -2052,7 +1999,6 @@ class TestToolsApi(ApiTestCase, TestsTools): assert output1_content.strip() == "\n".join(d["name"] for d in element_identifiers) @skip_without_tool("identifier_in_actions") - @uses_test_history(require_new=False) def test_identifier_in_actions(self, history_id): element_identifiers = self.dataset_collection_populator.list_identifiers(history_id, contents=["1\t2"]) @@ -2081,7 +2027,6 @@ class TestToolsApi(ApiTestCase, TestsTools): assert output_details["metadata_column_names"][1] == "data1", output_details @skip_without_tool("cat1") - @uses_test_history(require_new=False) def test_map_over_nested_collections(self, history_id): hdca_id = self.__build_nested_list(history_id) inputs = { @@ -2090,7 +2035,6 @@ class TestToolsApi(ApiTestCase, TestsTools): self._check_simple_cat1_over_nested_collections(history_id, inputs) @skip_without_tool("collection_paired_structured_like") - @uses_test_history(require_new=False) def test_paired_input_map_over_nested_collections(self, history_id): hdca_id = self.__build_nested_list(history_id) inputs = { @@ -2108,7 +2052,6 @@ class TestToolsApi(ApiTestCase, TestsTools): assert len(outer_elements) == 2 @skip_without_tool("collection_paired_conditional_structured_like") - @uses_test_history(require_new=False) def test_paired_input_conditional_map_over_nested_collections(self, history_id): hdca_id = self.__build_nested_list(history_id) inputs = { @@ -2149,7 +2092,6 @@ class TestToolsApi(ApiTestCase, TestsTools): assert outputs[0]["id"] == first_object_forward_element["object"]["id"] @skip_without_tool("cat1") - @uses_test_history(require_new=False) def test_map_over_two_collections(self, history_id): hdca1_id = self._build_pair(history_id, ["123\n", "456\n"]) hdca2_id = self._build_pair(history_id, ["789\n", "0ab\n"]) @@ -2177,7 +2119,6 @@ class TestToolsApi(ApiTestCase, TestsTools): assert len(response_object["implicit_collections"]) == 1 @skip_without_tool("cat1") - @uses_test_history(require_new=False) def test_map_over_two_collections_unlinked(self, history_id): hdca1_id = self._build_pair(history_id, ["123\n", "456\n"]) hdca2_id = self._build_pair(history_id, ["789\n", "0ab\n"]) @@ -2229,7 +2170,6 @@ class TestToolsApi(ApiTestCase, TestsTools): assert expected_contents == contents @skip_without_tool("cat1") - @uses_test_history(require_new=False) def test_map_over_collected_and_individual_datasets(self, history_id): hdca1_id = self._build_pair(history_id, ["123\n", "456\n"]) new_dataset1 = self.dataset_populator.new_dataset(history_id, content="789") @@ -2643,7 +2583,6 @@ class TestToolsApi(ApiTestCase, TestsTools): return tool_ids @skip_without_tool("collection_cat_group_tag_multiple") - @uses_test_history(require_new=False) def test_group_tag_selection(self, history_id): input_hdca_id = self.__build_group_list(history_id) inputs = { @@ -2659,7 +2598,6 @@ class TestToolsApi(ApiTestCase, TestsTools): assert output_content.strip() == "123\n456" @skip_without_tool("collection_cat_group_tag_multiple") - @uses_test_history(require_new=False) def test_group_tag_selection_multiple(self, history_id): input_hdca_id = self.__build_group_list(history_id) inputs = { @@ -2711,7 +2649,6 @@ class TestToolsApi(ApiTestCase, TestsTools): assert output_content == "3" @skip_without_tool("cat1") - @uses_test_history(require_new=False) def test_run_deferred_dataset(self, history_id): details = self.dataset_populator.create_deferred_hda( history_id, "https://raw.githubusercontent.com/galaxyproject/galaxy/dev/test-data/1.bed", ext="bed" @@ -2729,7 +2666,6 @@ class TestToolsApi(ApiTestCase, TestsTools): assert output_content.startswith("chr1 147962192 147962580 CCDS989.1_cds_0_0_chr1_147962193_r 0 -") @skip_without_tool("metadata_bam") - @uses_test_history(require_new=False) def test_run_deferred_dataset_with_metadata_options_filter(self, history_id): details = self.dataset_populator.create_deferred_hda( history_id, "https://raw.githubusercontent.com/galaxyproject/galaxy/dev/test-data/1.bam", ext="bam" @@ -2745,7 +2681,6 @@ class TestToolsApi(ApiTestCase, TestsTools): assert output_content.startswith("chrM") @skip_without_tool("pileup") - @uses_test_history(require_new=False) def test_metadata_validator_on_deferred_input(self, history_id): deferred_bam_details = self.dataset_populator.create_deferred_hda( history_id, "https://raw.githubusercontent.com/galaxyproject/galaxy/dev/test-data/1.bam", ext="bam" @@ -2758,7 +2693,6 @@ class TestToolsApi(ApiTestCase, TestsTools): @pytest.mark.xfail @skip_without_tool("pileup") - @uses_test_history(require_new=False) def test_metadata_validator_can_fail_on_deferred_input(self, history_id): # This test fails because we just skip the validator # Fixing this is a TODO @@ -2777,7 +2711,6 @@ class TestToolsApi(ApiTestCase, TestsTools): assert job_details["state"] == "failed" @skip_without_tool("cat1") - @uses_test_history(require_new=False) def test_run_deferred_mapping(self, history_id: str): elements = [ { @@ -2818,7 +2751,6 @@ class TestToolsApi(ApiTestCase, TestsTools): assert output_content.startswith("chr22 30128507 31828507 uc003bnx.1_cds_2_0_chr22_29227_f 0 +") @skip_without_tool("cat_list") - @uses_test_history(require_new=False) def test_run_deferred_list_multi_data_reduction(self, history_id: str): elements = [ { @@ -2853,7 +2785,6 @@ class TestToolsApi(ApiTestCase, TestsTools): assert output_content.startswith("chr22 30128507 31828507 uc003bnx.1_cds_2_0_chr22_29227_f 0 +") @skip_without_tool("cat_list") - @uses_test_history(require_new=False) def test_run_deferred_nested_list_input(self, history_id: str): elements = [ { @@ -2912,7 +2843,6 @@ class TestToolsApi(ApiTestCase, TestsTools): assert output_content.startswith("chr22 30128507 31828507 uc003bnx.1_cds_2_0_chr22_29227_f 0 +") @skip_without_tool("collection_paired_structured_like") - @uses_test_history(require_new=False) def test_deferred_map_over_nested_collections(self, history_id): elements = [ { diff --git a/lib/galaxy_test/api/test_tools_upload.py b/lib/galaxy_test/api/test_tools_upload.py index 31151bed3e2..6c3922e67b8 100644 --- a/lib/galaxy_test/api/test_tools_upload.py +++ b/lib/galaxy_test/api/test_tools_upload.py @@ -21,7 +21,6 @@ from galaxy_test.base.populators import ( DatasetPopulator, skip_without_datatype, stage_inputs, - uses_test_history, ) from ._framework import ApiTestCase @@ -135,7 +134,7 @@ class TestToolsUpload(ApiTestCase): assert details["state"] == "ok" assert details["file_ext"] == "fastqsanger.gz", details - @uses_test_history(require_new=True) + @pytest.mark.require_new_history def test_fetch_compressed_auto_decompress_target(self, history_id): # TODO: this should definitely be fixed to allow auto decompression via that API. fastqgz_path = TestDataResolver().get_filename("1.fastqsanger.gz") @@ -177,7 +176,7 @@ class TestToolsUpload(ApiTestCase): details = self._upload_and_get_details(fh, file_type="auto", assert_ok=False, auto_decompress=False) assert details["file_ext"] == "binary", details - @uses_test_history(require_new=True) + @pytest.mark.require_new_history def test_fetch_compressed_with_auto(self, history_id): # UNSTABLE_FLAG: This might default to a bed.gz datatype in the future. # TODO: this should definitely be fixed to allow auto decompression via that API. @@ -232,7 +231,6 @@ class TestToolsUpload(ApiTestCase): tiff_metadata = self._upload_and_get_details(fh, file_type="auto") assert tiff_metadata["file_ext"] == "tiff" - @uses_test_history(require_new=False) def test_newlines_stage_fetch(self, history_id): job = { "input1": { @@ -247,7 +245,6 @@ class TestToolsUpload(ApiTestCase): # By default this appends the newline. assert content == "This is a line of text.\n" - @uses_test_history(require_new=False) def test_stage_object(self, history_id): job = {"input1": "randomstr"} inputs, datasets = stage_inputs( @@ -257,7 +254,6 @@ class TestToolsUpload(ApiTestCase): content = self.dataset_populator.get_history_dataset_content(history_id=history_id, dataset=dataset) assert content.strip() == '"randomstr"' - @uses_test_history(require_new=False) def test_stage_object_fetch(self, history_id): job = {"input1": "randomstr"} inputs, datasets = stage_inputs(self.galaxy_interactor, history_id, job, use_path_paste=False) @@ -265,7 +261,6 @@ class TestToolsUpload(ApiTestCase): content = self.dataset_populator.get_history_dataset_content(history_id=history_id, dataset=dataset) assert content == '"randomstr"' - @uses_test_history(require_new=False) def test_newlines_stage_fetch_configured(self, history_id): job = { "input1": { @@ -285,7 +280,6 @@ class TestToolsUpload(ApiTestCase): details = self.dataset_populator.get_history_dataset_details(history_id=history_id, dataset=dataset) assert details["genome_build"] == "hg19" - @uses_test_history(require_new=False) @skip_if_github_down def test_upload_multiple_mixed_success(self, history_id): destination = {"type": "hdas"} @@ -316,7 +310,6 @@ class TestToolsUpload(ApiTestCase): assert output0["state"] == "ok" assert output1["state"] == "error" - @uses_test_history(require_new=False) @skip_if_github_down def test_fetch_bam_file_from_url_with_extension_set(self, history_id): item = { @@ -327,7 +320,6 @@ class TestToolsUpload(ApiTestCase): output = self.dataset_populator.fetch_hda(history_id, item) self.dataset_populator.get_history_dataset_details(history_id, dataset=output, assert_ok=True) - @uses_test_history(require_new=False) @skip_if_github_down def test_fetch_html_from_url(self, history_id): destination = {"type": "hdas"} @@ -356,7 +348,6 @@ class TestToolsUpload(ApiTestCase): assert dataset["state"] == "error" assert dataset["name"] == "html_file.txt" - @uses_test_history(require_new=False) def test_abort_fetch_job(self, history_id): # This should probably be an integration test that also verifies # that the celery chord is properly canceled. @@ -407,7 +398,6 @@ class TestToolsUpload(ApiTestCase): assert roadmaps_content.strip() == "roadmaps content", roadmaps_content @skip_without_datatype("velvet") - @uses_test_history(require_new=False) def test_composite_datatype_fetch(self, history_id): item = { "src": "composite", @@ -425,7 +415,6 @@ class TestToolsUpload(ApiTestCase): assert roadmaps_content.strip() == "roadmaps content", roadmaps_content @skip_without_datatype("velvet") - @uses_test_history(require_new=False) def test_composite_datatype_stage_fetch(self, history_id): job = { "input1": { @@ -442,7 +431,6 @@ class TestToolsUpload(ApiTestCase): self.dataset_populator.wait_for_history(history_id, assert_ok=True) @skip_without_datatype("velvet") - @uses_test_history(require_new=False) def test_composite_datatype_pbed_stage_fetch(self, history_id): job = { "input1": { @@ -459,7 +447,6 @@ class TestToolsUpload(ApiTestCase): self.dataset_populator.wait_for_history(history_id, assert_ok=True) @skip_without_datatype("velvet") - @uses_test_history(require_new=False) def test_composite_datatype_stage_upload1(self, history_id): job = { "input1": { @@ -478,7 +465,6 @@ class TestToolsUpload(ApiTestCase): self.dataset_populator.wait_for_history(history_id, assert_ok=True) @skip_without_datatype("velvet") - @uses_test_history(require_new=False) def test_composite_datatype_space_to_tab(self, history_id): # Like previous test but set one upload with space_to_tab to True to # verify that works. @@ -523,7 +509,6 @@ class TestToolsUpload(ApiTestCase): assert details["file_ext"] == "isa-tab", details assert details["file_size"] == 85, details - @uses_test_history(require_new=False) def test_upload_composite_as_tar(self, history_id): tar_path = self.test_data_resolver.get_filename("testdir.tar") with open(tar_path, "rb") as tar_f: @@ -542,7 +527,6 @@ class TestToolsUpload(ApiTestCase): dataset = run_response.json()["outputs"][0] self._check_testdir_composite(dataset, history_id) - @uses_test_history(require_new=False) def test_upload_composite_as_tar_fetch(self, history_id): tar_path = self.test_data_resolver.get_filename("testdir.tar") with open(tar_path, "rb") as tar_f: @@ -599,7 +583,6 @@ class TestToolsUpload(ApiTestCase): assert len(found_files) == 5, found_files - @uses_test_history(require_new=False) def test_upload_composite_from_bad_tar(self, history_id): tar_path = self.test_data_resolver.get_filename("unsafe.tar") with open(tar_path, "rb") as tar_f: @@ -627,7 +610,6 @@ class TestToolsUpload(ApiTestCase): datasets = run_response.json()["outputs"] assert datasets[0].get("genome_build") == "hg19", datasets[0] - @uses_test_history(require_new=False) def test_fetch_bam_file(self, history_id): bam_path = TestDataResolver().get_filename("1.bam") with open(bam_path, "rb") as fh: @@ -994,7 +976,6 @@ class TestToolsUpload(ApiTestCase): assert hda["file_ext"] == "fastqsanger.gz" assert hda["state"] == "ok" - @uses_test_history(require_new=False) def test_upload_deferred(self, history_id): details = self.dataset_populator.create_deferred_hda( history_id, "https://raw.githubusercontent.com/galaxyproject/galaxy/dev/test-data/1.bam", ext="bam" diff --git a/lib/galaxy_test/api/test_workflow_extraction.py b/lib/galaxy_test/api/test_workflow_extraction.py index dc9420ab822..c3327c0f32b 100644 --- a/lib/galaxy_test/api/test_workflow_extraction.py +++ b/lib/galaxy_test/api/test_workflow_extraction.py @@ -14,20 +14,15 @@ from .test_workflows import BaseWorkflowsApiTestCase class TestWorkflowExtractionApi(BaseWorkflowsApiTestCase): - history_id: str - - def setUp(self): - super().setUp() - self.history_id = self.dataset_populator.new_history() - @skip_without_tool("cat1") @summarize_instance_history_on_error - def test_extract_from_history(self): + def test_extract_from_history(self, history_id): # Run the simple test workflow and extract it back out from history - cat1_job_id = self.__setup_and_run_cat1_workflow(history_id=self.history_id) - contents = self._history_contents() + cat1_job_id = self.__setup_and_run_cat1_workflow(history_id=history_id) + contents = self._history_contents(history_id) input_hids = [c["hid"] for c in contents[0:2]] downloaded_workflow = self._extract_and_download_workflow( + history_id, reimport_as="extract_from_history_basic", dataset_ids=input_hids, job_ids=[cat1_job_id], @@ -36,7 +31,7 @@ class TestWorkflowExtractionApi(BaseWorkflowsApiTestCase): self.__assert_looks_like_cat1_example_workflow(downloaded_workflow) @summarize_instance_history_on_error - def test_extract_with_copied_inputs(self): + def test_extract_with_copied_inputs(self, history_id): old_history_id = self.dataset_populator.new_history() # Run the simple test workflow and extract it back out from history self.__setup_and_run_cat1_workflow(history_id=old_history_id) @@ -50,22 +45,23 @@ class TestWorkflowExtractionApi(BaseWorkflowsApiTestCase): offset = 0 old_contents = self._history_contents(old_history_id) for old_dataset in old_contents: - self.__copy_content_to_history(self.history_id, old_dataset) - new_contents = self._history_contents() + self.__copy_content_to_history(history_id, old_dataset) + new_contents = self._history_contents(history_id) input_hids = [c["hid"] for c in new_contents[(offset + 0) : (offset + 2)]] - cat1_job_id = self.__job_id(self.history_id, new_contents[(offset + 2)]["id"]) + cat1_job_id = self.__job_id(history_id, new_contents[(offset + 2)]["id"]) def reimport_jobs_ids(new_history_id): return [j["id"] for j in self.dataset_populator.history_jobs(new_history_id) if j["tool_id"] == "cat1"] downloaded_workflow = self._extract_and_download_workflow( + history_id, dataset_ids=input_hids, job_ids=[cat1_job_id], ) self.__assert_looks_like_cat1_example_workflow(downloaded_workflow) @summarize_instance_history_on_error - def test_extract_with_copied_inputs_reimported(self): + def test_extract_with_copied_inputs_reimported(self, history_id): old_history_id = self.dataset_populator.new_history() # Run the simple test workflow and extract it back out from history self.__setup_and_run_cat1_workflow(history_id=old_history_id) @@ -73,14 +69,15 @@ class TestWorkflowExtractionApi(BaseWorkflowsApiTestCase): offset = 0 old_contents = self._history_contents(old_history_id) for old_dataset in old_contents: - self.__copy_content_to_history(self.history_id, old_dataset) - new_contents = self._history_contents() + self.__copy_content_to_history(history_id, old_dataset) + new_contents = self._history_contents(history_id) input_hids = [c["hid"] for c in new_contents[(offset + 0) : (offset + 2)]] def reimport_jobs_ids(new_history_id): return [j["id"] for j in self.dataset_populator.history_jobs(new_history_id) if j["tool_id"] == "cat1"] downloaded_workflow = self._extract_and_download_workflow( + history_id, reimport_as="test_extract_with_copied_inputs", reimport_jobs_ids=reimport_jobs_ids, dataset_ids=input_hids, @@ -89,32 +86,34 @@ class TestWorkflowExtractionApi(BaseWorkflowsApiTestCase): @skip_without_tool("random_lines1") @summarize_instance_history_on_error - def test_extract_mapping_workflow_from_history(self): - hdca, job_id1, job_id2 = self.__run_random_lines_mapped_over_pair(self.history_id) + def test_extract_mapping_workflow_from_history(self, history_id): + hdca, job_id1, job_id2 = self.__run_random_lines_mapped_over_pair(history_id) downloaded_workflow = self._extract_and_download_workflow( + history_id, reimport_as="extract_from_history_with_mapping", dataset_collection_ids=[hdca["hid"]], job_ids=[job_id1, job_id2], ) self.__assert_looks_like_randomlines_mapping_workflow(downloaded_workflow) - def test_extract_copied_mapping_from_history(self): + def test_extract_copied_mapping_from_history(self, history_id): old_history_id = self.dataset_populator.new_history() hdca, job_id1, job_id2 = self.__run_random_lines_mapped_over_pair(old_history_id) old_contents = self._history_contents(old_history_id) for old_content in old_contents: - self.__copy_content_to_history(self.history_id, old_content) + self.__copy_content_to_history(history_id, old_content) # API test is somewhat contrived since there is no good way # to retrieve job_id1, job_id2 like this for copied dataset # collections I don't think. downloaded_workflow = self._extract_and_download_workflow( + history_id, dataset_collection_ids=[hdca["hid"]], job_ids=[job_id1, job_id2], ) self.__assert_looks_like_randomlines_mapping_workflow(downloaded_workflow) - def test_extract_copied_mapping_from_history_reimported(self): + def test_extract_copied_mapping_from_history_reimported(self, history_id): import unittest raise unittest.SkipTest( @@ -126,7 +125,7 @@ class TestWorkflowExtractionApi(BaseWorkflowsApiTestCase): old_contents = self._history_contents(old_history_id) for old_content in old_contents: - self.__copy_content_to_history(self.history_id, old_content) + self.__copy_content_to_history(history_id, old_content) def reimport_jobs_ids(new_history_id): rval = [ @@ -140,6 +139,7 @@ class TestWorkflowExtractionApi(BaseWorkflowsApiTestCase): # to retrieve job_id1, job_id2 like this for copied dataset # collections I don't think. downloaded_workflow = self._extract_and_download_workflow( + history_id, reimport_as="test_extract_from_history_with_mapped_collection_reimport", reimport_jobs_ids=reimport_jobs_ids, reimport_wait_on_history_length=9, # see comments in _extract about eliminating this magic constant. @@ -149,13 +149,13 @@ class TestWorkflowExtractionApi(BaseWorkflowsApiTestCase): @skip_without_tool("random_lines1") @skip_without_tool("multi_data_param") - def test_extract_reduction_from_history(self): + def test_extract_reduction_from_history(self, history_id): hdca = self.dataset_collection_populator.create_pair_in_history( - self.history_id, contents=["1 2 3\n4 5 6", "7 8 9\n10 11 10"], wait=True + history_id, contents=["1 2 3\n4 5 6", "7 8 9\n10 11 10"], wait=True ).json()["outputs"][0] hdca_id = hdca["id"] inputs1 = {"input": {"batch": True, "values": [{"src": "hdca", "id": hdca_id}]}, "num_lines": 2} - implicit_hdca1, job_id1 = self._run_tool_get_collection_and_job_id(self.history_id, "random_lines1", inputs1) + implicit_hdca1, job_id1 = self._run_tool_get_collection_and_job_id(history_id, "random_lines1", inputs1) inputs2 = { "f1": {"src": "hdca", "id": implicit_hdca1["id"]}, "f2": {"src": "hdca", "id": implicit_hdca1["id"]}, @@ -163,12 +163,13 @@ class TestWorkflowExtractionApi(BaseWorkflowsApiTestCase): reduction_run_output = self.dataset_populator.run_tool( tool_id="multi_data_param", inputs=inputs2, - history_id=self.history_id, + history_id=history_id, ) job_id2 = reduction_run_output["jobs"][0]["id"] self.dataset_populator.wait_for_job(job_id2, assert_ok=True) - self.dataset_populator.wait_for_history(self.history_id, assert_ok=True) + self.dataset_populator.wait_for_history(history_id, assert_ok=True) downloaded_workflow = self._extract_and_download_workflow( + history_id, reimport_as="extract_from_history_with_reduction", dataset_collection_ids=[hdca["hid"]], job_ids=[job_id1, job_id2], @@ -189,7 +190,7 @@ class TestWorkflowExtractionApi(BaseWorkflowsApiTestCase): assert reduction_step_input["id"] == random_lines_map_step["id"] @skip_without_tool("collection_paired_test") - def test_extract_workflows_with_dataset_collections(self): + def test_extract_workflows_with_dataset_collections(self, history_id): jobs_summary = self._run_workflow( """ class: GalaxyWorkflow @@ -203,10 +204,12 @@ steps: test_data: text_input1: collection_type: paired -""" +""", + history_id, ) job_id = self._job_id_for_tool(jobs_summary.jobs, "collection_paired_test") downloaded_workflow = self._extract_and_download_workflow( + history_id, reimport_as="extract_from_history_with_basic_collections", dataset_collection_ids=["1"], job_ids=[job_id], @@ -225,7 +228,7 @@ test_data: assert collection_step_state["collection_type"] == "paired" @skip_without_tool("cat_collection") - def test_subcollection_mapping(self): + def test_subcollection_mapping(self, history_id): jobs_summary = self._run_workflow( """ class: GalaxyWorkflow @@ -244,11 +247,13 @@ steps: test_data: text_input1: collection_type: "list:paired" - """ + """, + history_id, ) job1_id = self._job_id_for_tool(jobs_summary.jobs, "cat1") job2_id = self._job_id_for_tool(jobs_summary.jobs, "cat_collection") downloaded_workflow = self._extract_and_download_workflow( + history_id, reimport_as="test_extract_workflows_with_subcollection_mapping", dataset_collection_ids=["1"], job_ids=[job1_id, job2_id], @@ -268,7 +273,7 @@ test_data: @skip_without_tool("cat_list") @skip_without_tool("collection_creates_dynamic_nested") - def test_subcollection_reduction(self): + def test_subcollection_reduction(self, history_id): jobs_summary = self._run_workflow( """ class: GalaxyWorkflow @@ -279,11 +284,13 @@ steps: tool_id: cat_list in: input1: creates_nested_list/list_output -""" +""", + history_id, ) job1_id = self._job_id_for_tool(jobs_summary.jobs, "cat_list") job2_id = self._job_id_for_tool(jobs_summary.jobs, "collection_creates_dynamic_nested") self._extract_and_download_workflow( + history_id, reimport_as="test_extract_workflows_with_subcollection_reduction", dataset_collection_ids=["1"], job_ids=[job1_id, job2_id], @@ -292,7 +299,7 @@ steps: # this workflow @skip_without_tool("collection_split_on_column") - def test_extract_workflow_with_output_collections(self): + def test_extract_workflow_with_output_collections(self, history_id): jobs_summary = self._run_workflow( """ class: GalaxyWorkflow @@ -321,11 +328,13 @@ steps: test_data: text_input1: "samp1\t10.0\nsamp2\t20.0\n" text_input2: "samp1\t30.0\nsamp2\t40.0\n" -""" +""", + history_id, ) tool_ids = ["cat1", "collection_split_on_column", "cat_list"] job_ids = [functools.partial(self._job_id_for_tool, jobs_summary.jobs)(_) for _ in tool_ids] downloaded_workflow = self._extract_and_download_workflow( + history_id, reimport_as="test_extract_workflows_with_output_collections", dataset_ids=["1", "2"], job_ids=job_ids, @@ -341,7 +350,7 @@ test_data: @skip_without_tool("collection_creates_pair") @summarize_instance_history_on_error - def test_extract_with_mapped_output_collections(self): + def test_extract_with_mapped_output_collections(self, history_id): jobs_summary = self._run_workflow( """ class: GalaxyWorkflow @@ -375,11 +384,13 @@ test_data: content: "samp1\t10.0\nsamp2\t20.0\n" - identifier: samp2 content: "samp1\t30.0\nsamp2\t40.0\n" -""" +""", + history_id, ) tool_ids = ["cat1", "collection_creates_pair", "cat_collection", "cat_list"] job_ids = [functools.partial(self._job_id_for_tool, jobs_summary.jobs)(_) for _ in tool_ids] downloaded_workflow = self._extract_and_download_workflow( + history_id, reimport_as="test_extract_workflows_with_mapped_output_collections", dataset_collection_ids=["1"], job_ids=job_ids, @@ -453,9 +464,7 @@ test_data: assert input_steps[0]["id"] == input1["id"] assert input_steps[1]["id"] == input2["id"] - def _history_contents(self, history_id=None): - if history_id is None: - history_id = self.history_id + def _history_contents(self, history_id: str): return self._get(f"histories/{history_id}/contents").json() def __copy_content_to_history(self, history_id, content): @@ -488,12 +497,11 @@ test_data: collect_step_idx = collection_step["id"] return collect_step_idx - def _extract_and_download_workflow(self, **extract_payload): + def _extract_and_download_workflow(self, history_id: str, **extract_payload): reimport_as = extract_payload.get("reimport_as") if reimport_as: history_name = reimport_as - history_id = self.history_id self.dataset_populator.wait_for_history(history_id) self.dataset_populator.rename_history(history_id, history_name) @@ -545,10 +553,10 @@ test_data: extract_payload["job_ids"] = new_job_ids - self.history_id = new_history_id + history_id = new_history_id if "from_history_id" not in extract_payload: - extract_payload["from_history_id"] = self.history_id + extract_payload["from_history_id"] = history_id if "workflow_name" not in extract_payload: extract_payload["workflow_name"] = "test import from history" diff --git a/lib/galaxy_test/api/test_workflows.py b/lib/galaxy_test/api/test_workflows.py index 4dde07b2796..05219b82f6e 100644 --- a/lib/galaxy_test/api/test_workflows.py +++ b/lib/galaxy_test/api/test_workflows.py @@ -209,15 +209,10 @@ class BaseWorkflowsApiTestCase(ApiTestCase, RunsWorkflowFixtures): invocation_details = invocation_details_response.json() return invocation_details - def _run_jobs(self, has_workflow, history_id=None, **kwds) -> Union[Dict[str, Any], RunJobsSummary]: - if history_id is None: - history_id = self.history_id - + def _run_jobs(self, has_workflow, history_id: str, **kwds) -> Union[Dict[str, Any], RunJobsSummary]: return self.workflow_populator.run_workflow(has_workflow, history_id=history_id, **kwds) - def _run_workflow(self, has_workflow, history_id=None, **kwds) -> RunJobsSummary: - if history_id is None: - history_id = self.history_id + def _run_workflow(self, has_workflow, history_id: str, **kwds) -> RunJobsSummary: assert "expected_response" not in kwds run_summary = self.workflow_populator.run_workflow(has_workflow, history_id=history_id, **kwds) return cast(RunJobsSummary, run_summary) @@ -241,7 +236,7 @@ class BaseWorkflowsApiTestCase(ApiTestCase, RunsWorkflowFixtures): assert tool_state_value["__class__"] == "RuntimeValue" -class ChangeDatatypeTestCase: +class ChangeDatatypeTests: dataset_populator: DatasetPopulator workflow_populator: WorkflowPopulator @@ -310,7 +305,7 @@ class TestWorkflowSharingApi(ApiTestCase, SharingApiTests): # - Allow post to workflows//run in addition to posting to # /workflows with id in payload. # - Much more testing obviously, always more testing. -class TestWorkflowsApi(BaseWorkflowsApiTestCase, ChangeDatatypeTestCase): +class TestWorkflowsApi(BaseWorkflowsApiTestCase, ChangeDatatypeTests): dataset_populator: DatasetPopulator def test_show_valid(self): @@ -3461,8 +3456,7 @@ text_input: content = self.dataset_populator.get_history_dataset_content(history_id) assert "chrX\t152691446\t152691471\tCCDS14735.1_cds_0_0_chrX_152691447_f\t0\t+\n" == content - def test_run_with_numeric_input_connection(self): - history_id = self.dataset_populator.new_history() + def test_run_with_numeric_input_connection(self, history_id): self._run_jobs( """ class: GalaxyWorkflow @@ -3492,8 +3486,7 @@ test_data: {} assert abs(float(str_4point14) - 4.14) < 0.0001 @skip_without_tool("param_value_from_file") - def test_expression_tool_map_over(self): - history_id = self.dataset_populator.new_history() + def test_expression_tool_map_over(self, history_id): self._run_jobs( """ class: GalaxyWorkflow @@ -5200,6 +5193,7 @@ input: def test_invocation_filtering(self): with self._different_user(email=f"{uuid4()}@test.com"): + history_id = self.dataset_populator.new_history() # new user, start with no invocations assert not self._assert_invocation_for_url_is("invocations") self._run_jobs( @@ -5211,6 +5205,7 @@ inputs: optional: true steps: [] """, + history_id=history_id, wait=False, ) first_invocation = self._assert_invocation_for_url_is("invocations") @@ -5647,7 +5642,7 @@ class TestAdminWorkflowsApi(BaseWorkflowsApiTestCase): require_admin_user = True - def test_import_export_dynamic_tools(self): + def test_import_export_dynamic_tools(self, history_id): workflow_id = self._upload_yaml_workflow( """ class: GalaxyWorkflow @@ -5680,7 +5675,6 @@ test_data: downloaded_workflow = self._download_workflow(workflow_id) response = self.workflow_populator.create_workflow_response(downloaded_workflow) workflow_id = response.json()["id"] - history_id = self.dataset_populator.new_history() hda1 = self.dataset_populator.new_dataset(history_id, content="Hello World Second!") workflow_request = dict( inputs_by="name", diff --git a/lib/galaxy_test/api/test_workflows_from_yaml.py b/lib/galaxy_test/api/test_workflows_from_yaml.py index 3ae353db093..770e2c6625b 100644 --- a/lib/galaxy_test/api/test_workflows_from_yaml.py +++ b/lib/galaxy_test/api/test_workflows_from_yaml.py @@ -1,7 +1,6 @@ import json import os -from galaxy_test.base.populators import uses_test_history from galaxy_test.base.workflow_fixtures import ( WORKFLOW_PARAMETER_INPUT_INTEGER_DEFAULT, WORKFLOW_RUNTIME_PARAMETER_SIMPLE, @@ -262,7 +261,6 @@ steps: ) self.workflow_populator.dump_workflow(workflow_id) - @uses_test_history() def test_conditional_ints(self, history_id): self._run_jobs( """ diff --git a/lib/galaxy_test/base/populators.py b/lib/galaxy_test/base/populators.py index b82898bf5d1..7f2fdf2ee2b 100644 --- a/lib/galaxy_test/base/populators.py +++ b/lib/galaxy_test/base/populators.py @@ -209,20 +209,6 @@ def summarize_instance_history_on_error(method): return wrapped_method -def uses_test_history(**test_history_kwd): - """Can override require_new and cancel_executions using kwds to decorator.""" - - def method_wrapper(method): - @wraps(method) - def wrapped_method(api_test_case, *args, **kwds): - with api_test_case.dataset_populator.test_history(**test_history_kwd) as history_id: - method(api_test_case, history_id, *args, **kwds) - - return wrapped_method - - return method_wrapper - - def _raise_skip_if(check, *args): if check: raise unittest.SkipTest(*args) @@ -743,7 +729,7 @@ class BaseDatasetPopulator(BasePopulator): """Abstract method for summarizing a target history - override to provide details.""" @contextlib.contextmanager - def test_history(self, cancel_executions: bool = True, require_new: bool = True, **kwds): + def test_history(self, cancel_executions: bool = True, **kwds): cleanup = "GALAXY_TEST_NO_CLEANUP" not in os.environ history_id = None @@ -752,10 +738,7 @@ class BaseDatasetPopulator(BasePopulator): self.cancel_history_jobs(history_id) try: - if not require_new: - history_id = kwds.get("GALAXY_TEST_HISTORY_ID", None) - - history_id = history_id or self.new_history() + history_id = self.new_history() yield history_id wrap_up() except Exception: diff --git a/lib/galaxy_test/base/testcase.py b/lib/galaxy_test/base/testcase.py index f74bec3312a..4b14e6da2bf 100644 --- a/lib/galaxy_test/base/testcase.py +++ b/lib/galaxy_test/base/testcase.py @@ -1,12 +1,12 @@ import logging import os -import unittest from typing import ( Any, Optional, ) from galaxy.tool_util.verify.test_data import TestDataResolver +from galaxy.util.unittest import TestCase from galaxy_test.base.env import ( setup_keep_outdir, target_url_parts, @@ -15,7 +15,7 @@ from galaxy_test.base.env import ( log = logging.getLogger(__name__) -class FunctionalTestCase(unittest.TestCase): +class FunctionalTestCase(TestCase): """Base class for tests targetting actual Galaxy servers. Subclass should override galaxy_driver_class if a Galaxy server @@ -24,7 +24,6 @@ class FunctionalTestCase(unittest.TestCase): """ galaxy_driver_class: Optional[type] = None - history_id: Optional[str] host: str port: Optional[str] url: str @@ -33,7 +32,6 @@ class FunctionalTestCase(unittest.TestCase): _test_driver: Optional[Any] def setUp(self) -> None: - self.history_id = os.environ.get("GALAXY_TEST_HISTORY_ID", None) self.host, self.port, self.url = target_url_parts() server_wrapper = ( self._test_driver and self._test_driver.server_wrappers and self._test_driver.server_wrappers[0] diff --git a/lib/galaxy_test/selenium/test_personal_information.py b/lib/galaxy_test/selenium/test_personal_information.py index 46aa4cb5989..4e5985814fc 100644 --- a/lib/galaxy_test/selenium/test_personal_information.py +++ b/lib/galaxy_test/selenium/test_personal_information.py @@ -23,11 +23,11 @@ class TestManageInformation(SeleniumTestCase): api_key_input = self.components.preferences.api_key_input.wait_for_visible() new_api_key = self.get_api_key() input_value = api_key_input.get_property("value") - self.assertEqual(new_api_key, input_value) + assert new_api_key == input_value # Hover the input to view the key self.action_chains().move_to_element(api_key_input).perform() hover_value = api_key_input.get_property("value") - self.assertEqual(new_api_key, hover_value) + assert new_api_key == hover_value @selenium_test def test_change_email(self): diff --git a/run_tests.sh b/run_tests.sh index 3293160735b..30387db6ab4 100755 --- a/run_tests.sh +++ b/run_tests.sh @@ -239,9 +239,6 @@ GALAXY_TEST_TOOL_PATH Path defaulting to 'tools'. GALAXY_TEST_SHED_TOOL_CONF Shed toolbox conf (defaults to config/shed_tool_conf.xml) used when testing installed to tools with -installed. -GALAXY_TEST_HISTORY_ID Some tests can target existing history ids, this option - is fairly limited and not compatible with parrallel testing - so should be limited to debugging one off tests. TOOL_SHED_TEST_HOST Host to use for shed server setup for testing. TOOL_SHED_TEST_PORT Port to use for shed server setup for testing. TOOL_SHED_TEST_FILE_DIR Defaults to lib/tool_shed/test/test_data. diff --git a/test/integration/test_async_downloads.py b/test/integration/test_async_downloads.py index 3b2a951b26d..2c854a8bc6c 100644 --- a/test/integration/test_async_downloads.py +++ b/test/integration/test_async_downloads.py @@ -1,6 +1,8 @@ import zipfile from io import BytesIO +import pytest + from galaxy_test.base.populators import ( DatasetCollectionPopulator, DatasetPopulator, @@ -16,6 +18,7 @@ class TestAsyncDownloadsIntegration(IntegrationTestCase): self.dataset_populator = DatasetPopulator(self.galaxy_interactor) self.dataset_collection_populator = DatasetCollectionPopulator(self.galaxy_interactor) + @pytest.mark.require_new_history def test_async_collection_download(self, history_id): fetch_response = self.dataset_collection_populator.create_list_in_history(history_id, direct_upload=True).json() dataset_collection = self.dataset_collection_populator.wait_for_fetched_collection(fetch_response) diff --git a/test/integration/test_change_datatype_with_store_by_id.py b/test/integration/test_change_datatype_with_store_by_id.py index 0560e9903d4..a7c2c0afd3a 100644 --- a/test/integration/test_change_datatype_with_store_by_id.py +++ b/test/integration/test_change_datatype_with_store_by_id.py @@ -1,4 +1,4 @@ -from galaxy_test.api import test_workflows +from galaxy_test.api.test_workflows import ChangeDatatypeTests from galaxy_test.base.populators import ( DatasetPopulator, WorkflowPopulator, @@ -6,9 +6,7 @@ from galaxy_test.base.populators import ( from galaxy_test.driver import integration_util -class TestChangeDatatypeStoreByIdIntegration( - integration_util.IntegrationTestCase, test_workflows.ChangeDatatypeTestCase -): +class TestChangeDatatypeStoreByIdIntegration(integration_util.IntegrationTestCase, ChangeDatatypeTests): """Test changing datatype with object_store_store_by: id.""" dataset_populator: DatasetPopulator diff --git a/test/integration/test_materialize_dataset_instance_tasks.py b/test/integration/test_materialize_dataset_instance_tasks.py index d006d88d01b..c756078857a 100644 --- a/test/integration/test_materialize_dataset_instance_tasks.py +++ b/test/integration/test_materialize_dataset_instance_tasks.py @@ -1,5 +1,7 @@ import os +import pytest + from galaxy.model.unittest_utils.store_fixtures import ( deferred_hda_model_store_dict, deferred_hda_model_store_dict_bam, @@ -35,6 +37,7 @@ class TestMaterializeDatasetInstanceTasaksIntegration(IntegrationTestCase, UsesC self.library_populator = LibraryPopulator(self.galaxy_interactor) self.dataset_populator = DatasetPopulator(self.galaxy_interactor) + @pytest.mark.require_new_history def test_materialize_history_dataset(self, history_id: str): as_list = self.dataset_populator.create_contents_from_store( history_id, @@ -54,6 +57,7 @@ class TestMaterializeDatasetInstanceTasaksIntegration(IntegrationTestCase, UsesC assert new_hda_details["state"] == "ok" assert not new_hda_details["deleted"] + @pytest.mark.require_new_history def test_materialize_gxfiles_uri(self, history_id: str): as_list = self.dataset_populator.create_contents_from_store( history_id, @@ -74,6 +78,7 @@ class TestMaterializeDatasetInstanceTasaksIntegration(IntegrationTestCase, UsesC assert new_hda_details["state"] == "ok" assert not new_hda_details["deleted"] + @pytest.mark.require_new_history def test_materialize_history_dataset_bam(self, history_id: str): as_list = self.dataset_populator.create_contents_from_store( history_id, @@ -105,6 +110,7 @@ class TestMaterializeDatasetInstanceTasaksIntegration(IntegrationTestCase, UsesC assert ">chrM" in new_hda_details["metadata_reference_names"] assert "metadata_bam_index" in new_hda_details + @pytest.mark.require_new_history def test_materialize_library_dataset(self, history_id: str): response = self.library_populator.create_from_store(store_dict=one_ld_library_deferred_model_store_dict()) assert isinstance(response, list) @@ -123,6 +129,7 @@ class TestMaterializeDatasetInstanceTasaksIntegration(IntegrationTestCase, UsesC assert new_hda_details["state"] == "ok" assert not new_hda_details["deleted"] + @pytest.mark.require_new_history def test_upload_vs_materialize_simplest_upload(self, history_id: str): item = {"src": "url", "url": "gxfiles://testdatafiles//simple_line_no_newline.txt", "ext": "txt"} output = self.dataset_populator.fetch_hda(history_id, item) @@ -137,6 +144,7 @@ class TestMaterializeDatasetInstanceTasaksIntegration(IntegrationTestCase, UsesC content = self.dataset_populator.get_history_dataset_content(new_history_id, hid=2, assert_ok=False) assert content == "This is a line of text." + @pytest.mark.require_new_history def test_upload_vs_materialize_to_posix_lines(self, history_id: str): item = { "src": "url", @@ -162,6 +170,7 @@ class TestMaterializeDatasetInstanceTasaksIntegration(IntegrationTestCase, UsesC content = self.dataset_populator.get_history_dataset_content(new_history_id, hid=2, assert_ok=False) assert content == "This is a line of text.\n" + @pytest.mark.require_new_history def test_upload_vs_materialize_space_to_tab(self, history_id: str): item = { "src": "url", @@ -187,6 +196,7 @@ class TestMaterializeDatasetInstanceTasaksIntegration(IntegrationTestCase, UsesC content = self.dataset_populator.get_history_dataset_content(new_history_id, hid=2, assert_ok=False) assert content == "This\tis\ta\tline\tof\ttext." + @pytest.mark.require_new_history def test_upload_vs_materialize_to_posix_and_space_to_tab(self, history_id: str): item = { "src": "url", @@ -213,6 +223,7 @@ class TestMaterializeDatasetInstanceTasaksIntegration(IntegrationTestCase, UsesC content = self.dataset_populator.get_history_dataset_content(new_history_id, hid=2, assert_ok=False) assert content == "This\tis\ta\tline\tof\ttext.\n" + @pytest.mark.require_new_history def test_upload_vs_materialize_grooming(self, history_id: str): item = { "src": "url", diff --git a/tox.ini b/tox.ini index 27cc84c9047..14030c6a210 100644 --- a/tox.ini +++ b/tox.ini @@ -40,12 +40,6 @@ deps = test_galaxy_packages: pyyaml unit: mock-ssh-server -[testenv:check_py3_compatibility] -commands = bash .ci/check_py3_compatibility.sh - -[testenv:check_python_dependencies] -commands = make list-dependency-updates # someday change exit code on this. - [testenv:mako_count] commands = bash .ci/check_mako.sh