From 389f3989a05e323f2c73ad219b2e9d6b115db128 Mon Sep 17 00:00:00 2001 From: John Chilton Date: Wed, 25 Sep 2024 11:24:24 -0400 Subject: [PATCH] Improvements to test format. - Allow class: File and class: Collection on file and collection test descriptions. - Allow collection_type: in collection test descriptions. Implement this. - Update test workflows to reflect these two things as best practices. --- lib/galaxy/tool_util/models.py | 23 +++++++++++++++++-- lib/galaxy/tool_util/parser/interface.py | 13 +++++++++++ .../empty_collection_sort.gxwf-tests.yml | 2 ++ .../flatten_collection.gxwf-tests.yml | 3 ++- ...n_collection_over_execution.gxwf-tests.yml | 2 ++ .../integer_into_data_column.gxwf-tests.yml | 1 + .../map_over_expression.gxwf-tests.yml | 3 ++- .../multi_select_mapping.gxwf-tests.yml | 2 ++ ...le_integer_into_data_column.gxwf-tests.yml | 1 + .../workflow/multiple_text.gxwf-tests.yml | 1 + .../workflow/multiple_versions.gxwf-tests.yml | 2 ++ ...e_based_on_input_collection.gxwf-tests.yml | 1 + ...placement_parameters_legacy.gxwf-tests.yml | 2 ++ ...placement_parameters_nested.gxwf-tests.yml | 2 ++ ...replacement_parameters_text.gxwf-tests.yml | 2 ++ lib/galaxy_test/workflow/tests.py | 5 +--- 16 files changed, 57 insertions(+), 8 deletions(-) diff --git a/lib/galaxy/tool_util/models.py b/lib/galaxy/tool_util/models.py index 4f1ea35670c6..eb76e1d711ef 100644 --- a/lib/galaxy/tool_util/models.py +++ b/lib/galaxy/tool_util/models.py @@ -13,12 +13,16 @@ ) from pydantic import ( + AfterValidator, AnyUrl, BaseModel, ConfigDict, + Field, RootModel, ) from typing_extensions import ( + Annotated, + Literal, NotRequired, TypedDict, ) @@ -113,7 +117,7 @@ class BaseTestOutputModel(StrictModel): class TestDataOutputAssertions(BaseTestOutputModel): - pass + class_: Optional[Literal["File"]] = Field("File", alias="class") class TestCollectionCollectionElementAssertions(StrictModel): @@ -131,14 +135,29 @@ class TestCollectionDatasetElementAssertions(BaseTestOutputModel): TestCollectionCollectionElementAssertions.model_rebuild() +def _check_collection_type(v: str) -> str: + if len(v) == 0: + raise ValueError("Invalid empty collection_type specified.") + collection_levels = v.split(":") + for collection_level in collection_levels: + if collection_level not in ["list", "paired"]: + raise ValueError(f"Invalid collection_type specified [{v}]") + return v + + +CollectionType = Annotated[Optional[str], AfterValidator(_check_collection_type)] + + class CollectionAttributes(StrictModel): - collection_type: Optional[str] = None + collection_type: CollectionType = None class TestCollectionOutputAssertions(StrictModel): + class_: Optional[Literal["Collection"]] = Field("Collection", alias="class") elements: Optional[Dict[str, TestCollectionElementAssertion]] = None element_tests: Optional[Dict[str, "TestCollectionElementAssertion"]] = None attributes: Optional[CollectionAttributes] = None + collection_type: CollectionType = None TestOutputLiteral = Union[bool, int, float, str] diff --git a/lib/galaxy/tool_util/parser/interface.py b/lib/galaxy/tool_util/parser/interface.py index c137955dbeb1..19c557cd53de 100644 --- a/lib/galaxy/tool_util/parser/interface.py +++ b/lib/galaxy/tool_util/parser/interface.py @@ -870,6 +870,19 @@ def from_dict(as_dict): element_tests=as_dict["element_tests"], ) + @staticmethod + def from_yaml_test_format(as_dict): + if "attributes" not in as_dict: + as_dict["attributes"] = {} + attributes = as_dict["attributes"] + # setup preferred name "elements" in accordance with work in https://github.com/galaxyproject/planemo/pull/1417 + # TODO: test this works recursively... + if "elements" in as_dict and "element_tests" not in as_dict: + as_dict["element_tests"] = as_dict["elements"] + if "collection_type" in as_dict: + attributes["type"] = as_dict["collection_type"] + return TestCollectionOutputDef.from_dict(as_dict) + def to_dict(self): return dict(name=self.name, attributes=self.attrib, element_tests=self.element_tests) diff --git a/lib/galaxy_test/workflow/empty_collection_sort.gxwf-tests.yml b/lib/galaxy_test/workflow/empty_collection_sort.gxwf-tests.yml index ad83bb676b67..d5ac9d9b15b4 100644 --- a/lib/galaxy_test/workflow/empty_collection_sort.gxwf-tests.yml +++ b/lib/galaxy_test/workflow/empty_collection_sort.gxwf-tests.yml @@ -9,6 +9,8 @@ filter_file: i1 outputs: output: + class: Collection + collection_type: list elements: i1: asserts: diff --git a/lib/galaxy_test/workflow/flatten_collection.gxwf-tests.yml b/lib/galaxy_test/workflow/flatten_collection.gxwf-tests.yml index bfd0a6a02435..7af6cff256bc 100644 --- a/lib/galaxy_test/workflow/flatten_collection.gxwf-tests.yml +++ b/lib/galaxy_test/workflow/flatten_collection.gxwf-tests.yml @@ -3,7 +3,8 @@ job: {} outputs: out: - attributes: {collection_type: 'list'} + class: Collection + collection_type: list elements: 'oe1-ie1': asserts: diff --git a/lib/galaxy_test/workflow/flatten_collection_over_execution.gxwf-tests.yml b/lib/galaxy_test/workflow/flatten_collection_over_execution.gxwf-tests.yml index 5c54212815e9..85d986adbb10 100644 --- a/lib/galaxy_test/workflow/flatten_collection_over_execution.gxwf-tests.yml +++ b/lib/galaxy_test/workflow/flatten_collection_over_execution.gxwf-tests.yml @@ -8,6 +8,8 @@ content: "0 mycoolline\n1 mysecondline\n" outputs: out: + class: Collection + collection_type: list elements: 'samp1-0': asserts: diff --git a/lib/galaxy_test/workflow/integer_into_data_column.gxwf-tests.yml b/lib/galaxy_test/workflow/integer_into_data_column.gxwf-tests.yml index 890acb144ee1..eae87aa6f314 100644 --- a/lib/galaxy_test/workflow/integer_into_data_column.gxwf-tests.yml +++ b/lib/galaxy_test/workflow/integer_into_data_column.gxwf-tests.yml @@ -10,6 +10,7 @@ type: raw outputs: output: + class: File asserts: - that: has_line line: "parameter: 2" diff --git a/lib/galaxy_test/workflow/map_over_expression.gxwf-tests.yml b/lib/galaxy_test/workflow/map_over_expression.gxwf-tests.yml index 0357ca6c53ca..7a52cb858c28 100644 --- a/lib/galaxy_test/workflow/map_over_expression.gxwf-tests.yml +++ b/lib/galaxy_test/workflow/map_over_expression.gxwf-tests.yml @@ -10,7 +10,8 @@ content: B outputs: out1: - attributes: { collection_type: list } + class: Collection + collection_type: list elements: A: asserts: diff --git a/lib/galaxy_test/workflow/multi_select_mapping.gxwf-tests.yml b/lib/galaxy_test/workflow/multi_select_mapping.gxwf-tests.yml index 065849a34082..b9857cc30642 100644 --- a/lib/galaxy_test/workflow/multi_select_mapping.gxwf-tests.yml +++ b/lib/galaxy_test/workflow/multi_select_mapping.gxwf-tests.yml @@ -16,6 +16,8 @@ ext: 'expression.json' outputs: output: + class: Collection + collection_type: list elements: the_example_2: asserts: diff --git a/lib/galaxy_test/workflow/multiple_integer_into_data_column.gxwf-tests.yml b/lib/galaxy_test/workflow/multiple_integer_into_data_column.gxwf-tests.yml index c960ea73e8ff..365bf7f6de1f 100644 --- a/lib/galaxy_test/workflow/multiple_integer_into_data_column.gxwf-tests.yml +++ b/lib/galaxy_test/workflow/multiple_integer_into_data_column.gxwf-tests.yml @@ -10,6 +10,7 @@ type: raw outputs: output: + class: File asserts: - that: has_text text: "col 1,2" diff --git a/lib/galaxy_test/workflow/multiple_text.gxwf-tests.yml b/lib/galaxy_test/workflow/multiple_text.gxwf-tests.yml index 15fd0dba0254..09a7dd89e557 100644 --- a/lib/galaxy_test/workflow/multiple_text.gxwf-tests.yml +++ b/lib/galaxy_test/workflow/multiple_text.gxwf-tests.yml @@ -9,6 +9,7 @@ type: raw outputs: output: + class: File asserts: - that: has_line line: '--ex1,ex2,--ex3' diff --git a/lib/galaxy_test/workflow/multiple_versions.gxwf-tests.yml b/lib/galaxy_test/workflow/multiple_versions.gxwf-tests.yml index 1d1db5dba980..bbe2eee671e1 100644 --- a/lib/galaxy_test/workflow/multiple_versions.gxwf-tests.yml +++ b/lib/galaxy_test/workflow/multiple_versions.gxwf-tests.yml @@ -6,12 +6,14 @@ type: raw outputs: output_1: + class: File asserts: - that: has_text text: 'Version 0.1' - that: not_has_text text: 'Version 0.2' output_2: + class: File asserts: - that: has_text text: 'Version 0.2' diff --git a/lib/galaxy_test/workflow/rename_based_on_input_collection.gxwf-tests.yml b/lib/galaxy_test/workflow/rename_based_on_input_collection.gxwf-tests.yml index a6b357635316..9f76add4f574 100644 --- a/lib/galaxy_test/workflow/rename_based_on_input_collection.gxwf-tests.yml +++ b/lib/galaxy_test/workflow/rename_based_on_input_collection.gxwf-tests.yml @@ -18,5 +18,6 @@ type: File outputs: output: + class: File metadata: name: 'the_dataset_pair suffix' diff --git a/lib/galaxy_test/workflow/replacement_parameters_legacy.gxwf-tests.yml b/lib/galaxy_test/workflow/replacement_parameters_legacy.gxwf-tests.yml index a3120f277072..b800042dc1a4 100644 --- a/lib/galaxy_test/workflow/replacement_parameters_legacy.gxwf-tests.yml +++ b/lib/galaxy_test/workflow/replacement_parameters_legacy.gxwf-tests.yml @@ -5,8 +5,10 @@ replaceme: moocow outputs: out1: + class: File metadata: name: 'moocow name' out2: + class: File metadata: name: 'moocow name 2' diff --git a/lib/galaxy_test/workflow/replacement_parameters_nested.gxwf-tests.yml b/lib/galaxy_test/workflow/replacement_parameters_nested.gxwf-tests.yml index c5152f0e4add..f9acae8274f1 100644 --- a/lib/galaxy_test/workflow/replacement_parameters_nested.gxwf-tests.yml +++ b/lib/galaxy_test/workflow/replacement_parameters_nested.gxwf-tests.yml @@ -6,8 +6,10 @@ type: raw outputs: out1: + class: File metadata: name: 'moocow name' out2: + class: File metadata: name: 'moocow name 2' diff --git a/lib/galaxy_test/workflow/replacement_parameters_text.gxwf-tests.yml b/lib/galaxy_test/workflow/replacement_parameters_text.gxwf-tests.yml index b76353ae9325..fd8dc8eb7bfc 100644 --- a/lib/galaxy_test/workflow/replacement_parameters_text.gxwf-tests.yml +++ b/lib/galaxy_test/workflow/replacement_parameters_text.gxwf-tests.yml @@ -6,8 +6,10 @@ type: raw outputs: out1: + class: File metadata: name: 'moocow name' out2: + class: File metadata: name: 'moocow name 2' diff --git a/lib/galaxy_test/workflow/tests.py b/lib/galaxy_test/workflow/tests.py index a850490740b6..d879a1f310ae 100644 --- a/lib/galaxy_test/workflow/tests.py +++ b/lib/galaxy_test/workflow/tests.py @@ -96,10 +96,7 @@ def verify_dataset(dataset: dict, test_properties: OutputChecks): if is_collection_test: assert isinstance(test_properties, dict) test_properties["name"] = output_name - # setup preferred name "elements" in accordance with work in https://github.com/galaxyproject/planemo/pull/1417 - test_properties["element_tests"] = test_properties["elements"] - output_def = TestCollectionOutputDef.from_dict(test_properties) - + output_def = TestCollectionOutputDef.from_yaml_test_format(test_properties) invocation_details = self.workflow_populator.get_invocation(run_summary.invocation_id, step_details=True) assert output_name in invocation_details["output_collections"] test_output = invocation_details["output_collections"][output_name]