Loading lib/galaxy/tool_util/linters/tests.py +10 −4 Original line number Diff line number Diff line Loading @@ -12,7 +12,11 @@ from packaging.version import Version from galaxy.tool_util.lint import Linter from galaxy.tool_util.parameters import validate_test_cases_for_tool_source from galaxy.tool_util.verify.assertion_models import assertion_list from galaxy.tool_util.verify.assertion_models import ( assertion_list, relaxed_assertion_list, ) from galaxy.tool_util.verify.parse import tag_structure_to_that_structure from galaxy.util import asbool from ._util import is_datasource Loading Loading @@ -148,15 +152,17 @@ class TestsAssertionValidation(Linter): lint_ctx.warn("Failed to parse test dictionaries from tool - cannot lint assertions") return assert "tests" in raw_tests_dict # This really only allows coercion from strings, the values themselves will still be validated assert_list_model = relaxed_assertion_list if tool_source.language == "xml" else assertion_list for test_idx, test in enumerate(raw_tests_dict["tests"], start=1): # TODO: validate command, command_version, element tests. What about children? for output in test["outputs"]: asserts_raw = output.get("attributes", {}).get("assert_list") or [] to_yaml_assertions = [] processed_assertions = [] for raw_assert in asserts_raw: to_yaml_assertions.append({"that": raw_assert["tag"], **raw_assert.get("attributes", {})}) processed_assertions.append(tag_structure_to_that_structure(raw_assert)) try: assertion_list.model_validate(to_yaml_assertions) assert_list_model.model_validate(processed_assertions) except Exception as e: error_str = _cleanup_pydantic_error(e) lint_ctx.warn( Loading test/unit/tool_util/test_tool_linters.py +23 −0 Original line number Diff line number Diff line Loading @@ -850,6 +850,23 @@ VALID_CENTER_OF_MASS = """ </tests> </tool> """ ASSERTS_STRING_COERCION = """ <tool id="id" name="name"> <outputs> <data name="data_name" format="ome.tiff"/> </outputs> <tests> <test> <output name="data_name"> <assert_contents> <!-- channels is defined as an integer, so coercion from string must be applied on validation --> <has_image_channels channels="3" /> </assert_contents> </output> </test> </tests> </tool> """ TESTS_VALID = """ <tool id="id" name="name"> <outputs> Loading Loading @@ -1945,6 +1962,12 @@ def test_tests_asserts(lint_ctx): assert len(lint_ctx.error_messages) == 9 def test_tests_asserts_string_coercion(lint_ctx): tool_source = get_xml_tool_source(ASSERTS_STRING_COERCION) run_lint_module(lint_ctx, tests, tool_source) assert len(lint_ctx.warn_messages) == 0, lint_ctx.warn_messages def test_tests_assertion_models_valid(lint_ctx): tool_source = get_xml_tool_source(VALID_CENTER_OF_MASS) run_lint_module(lint_ctx, tests, tool_source) Loading Loading
lib/galaxy/tool_util/linters/tests.py +10 −4 Original line number Diff line number Diff line Loading @@ -12,7 +12,11 @@ from packaging.version import Version from galaxy.tool_util.lint import Linter from galaxy.tool_util.parameters import validate_test_cases_for_tool_source from galaxy.tool_util.verify.assertion_models import assertion_list from galaxy.tool_util.verify.assertion_models import ( assertion_list, relaxed_assertion_list, ) from galaxy.tool_util.verify.parse import tag_structure_to_that_structure from galaxy.util import asbool from ._util import is_datasource Loading Loading @@ -148,15 +152,17 @@ class TestsAssertionValidation(Linter): lint_ctx.warn("Failed to parse test dictionaries from tool - cannot lint assertions") return assert "tests" in raw_tests_dict # This really only allows coercion from strings, the values themselves will still be validated assert_list_model = relaxed_assertion_list if tool_source.language == "xml" else assertion_list for test_idx, test in enumerate(raw_tests_dict["tests"], start=1): # TODO: validate command, command_version, element tests. What about children? for output in test["outputs"]: asserts_raw = output.get("attributes", {}).get("assert_list") or [] to_yaml_assertions = [] processed_assertions = [] for raw_assert in asserts_raw: to_yaml_assertions.append({"that": raw_assert["tag"], **raw_assert.get("attributes", {})}) processed_assertions.append(tag_structure_to_that_structure(raw_assert)) try: assertion_list.model_validate(to_yaml_assertions) assert_list_model.model_validate(processed_assertions) except Exception as e: error_str = _cleanup_pydantic_error(e) lint_ctx.warn( Loading
test/unit/tool_util/test_tool_linters.py +23 −0 Original line number Diff line number Diff line Loading @@ -850,6 +850,23 @@ VALID_CENTER_OF_MASS = """ </tests> </tool> """ ASSERTS_STRING_COERCION = """ <tool id="id" name="name"> <outputs> <data name="data_name" format="ome.tiff"/> </outputs> <tests> <test> <output name="data_name"> <assert_contents> <!-- channels is defined as an integer, so coercion from string must be applied on validation --> <has_image_channels channels="3" /> </assert_contents> </output> </test> </tests> </tool> """ TESTS_VALID = """ <tool id="id" name="name"> <outputs> Loading Loading @@ -1945,6 +1962,12 @@ def test_tests_asserts(lint_ctx): assert len(lint_ctx.error_messages) == 9 def test_tests_asserts_string_coercion(lint_ctx): tool_source = get_xml_tool_source(ASSERTS_STRING_COERCION) run_lint_module(lint_ctx, tests, tool_source) assert len(lint_ctx.warn_messages) == 0, lint_ctx.warn_messages def test_tests_assertion_models_valid(lint_ctx): tool_source = get_xml_tool_source(VALID_CENTER_OF_MASS) run_lint_module(lint_ctx, tests, tool_source) Loading