import os
import os.path
import shutil
import tempfile
from math import isinf
from typing import (
Optional,
Sequence,
Type,
TypeVar,
)
from galaxy.tool_util.parser.factory import get_tool_source
from galaxy.tool_util.parser.output_objects import from_tool_source
from galaxy.tool_util.unittest_utils import functional_test_tool_path
from galaxy.tool_util_models.tool_outputs import (
ToolOutput,
ToolOutputCollection,
ToolOutputDataset,
)
from galaxy.util import galaxy_directory
from galaxy.util.resources import (
as_file,
resource_path,
)
from galaxy.util.unittest import TestCase
TOOL_XML_1 = """
The BWA Mapper
bwa
bwa.py --version
bwa.py --arg1=42
mycool/bwa
bwa
1
10.2
6.1
4042
1
2
67108864
60
This is HELP TEXT1!!!
"""
TOOL_WITH_TOKEN = r"""
@NESTED_TOKEN@
"""
TOOL_WTIH_TOKEN_FROM_MACRO_FILE = r"""
macros.xml
"""
MACRO_CONTENTS = r"""
cat
"""
TOOL_WITH_RECURSIVE_TOKEN = r"""
@NESTED_TOKEN@
"""
TOOL_YAML_1 = """
name: "Bowtie Mapper"
class: GalaxyTool
id: bowtie
version: 1.0.2
description: "The Bowtie Mapper"
xrefs:
- type: bio.tools
value: bwa
command: "bowtie_wrapper.pl --map-the-stuff"
interpreter: "perl"
runtime_version:
command: "bowtie --version"
requirements:
- type: package
name: bwa
version: 1.0.1
- type: resource
cores_min: 1
- type: resource
cuda_version_min: 10.2
- type: resource
cuda_compute_capability: 6.1
- type: resource
gpu_memory_min: 4042
- type: resource
cuda_device_count_min: 1
- type: resource
cuda_device_count_max: 2
- type: resource
shm_size: 67108864
- type: resource
timelimit: 60
containers:
- type: docker
identifier: "awesome/bowtie"
credentials:
- name: Apollo
version: gmod.org/apollo
secrets:
- name: username
label: Your Apollo username
description: Username for Apollo
inject_as_env: apollo_user
optional: true
- name: password
label: Your Apollo password
description: Password for Apollo
inject_as_env: apollo_pass
optional: true
variables:
- name: server
label: Your Apollo server
description: URL of your Apollo server
inject_as_env: apollo_url
optional: true
outputs:
out1:
format: bam
from_work_dir: out1.bam
inputs:
- name: input1
type: integer
min: 7
max: 8
- name: moo
label: cow
type: repeat
blocks:
- name: nestinput
type: data
- name: nestsample
type: text
help:
|
This is HELP TEXT2!!!
tests:
- inputs:
input1: 7
outputs:
out1: moo.txt
- inputs:
input1: 8
outputs:
out1:
lines_diff: 4
compare: sim_size
"""
TOOL_EXPRESSION_XML_1 = """
Parse Int
{return {'output': parseInt($job.input1)};}
Parse an integer from text.
"""
TOOL_EXPRESSION_YAML_1 = """
class: GalaxyExpressionTool
name: "parse_int"
id: parse_int
version: 1.0.2
expression: "{return {'output': parseInt($job.input1)};}"
inputs:
- name: input1
label: Text to parse
type: text
outputs:
out1:
type: integer
from: "#output"
"""
def get_test_tool_source(source_file_name=None, source_contents=None, macro_contents=None, temp_directory=None):
source_directory = temp_directory or tempfile.mkdtemp()
macro_paths = []
if not os.path.isabs(source_file_name):
path = os.path.join(source_directory, source_file_name)
with open(path, "w") as out:
out.write(source_contents)
if macro_contents:
macro_path = os.path.join(source_directory, "macros.xml")
with open(macro_path, "w") as out:
out.write(macro_contents)
macro_paths = [macro_path]
else:
path = source_file_name
tool_source = get_tool_source(path, macro_paths=macro_paths)
if temp_directory is None:
shutil.rmtree(source_directory)
return tool_source
class BaseLoaderTestCase(TestCase):
source_file_name: Optional[str] = None
source_contents: Optional[str] = None
def setUp(self):
self.temp_directory = tempfile.mkdtemp()
def tearDown(self):
shutil.rmtree(self.temp_directory)
@property
def _tool_source(self):
return self._get_tool_source()
@property
def _output_models(self) -> Sequence[ToolOutput]:
return from_tool_source(self._tool_source)
def _get_tool_source(self, source_file_name=None, source_contents=None, macro_contents=None):
if source_file_name is None:
source_file_name = self._get_source_file_name()
if source_contents is None:
source_contents = self.source_contents
return get_test_tool_source(
source_file_name,
source_contents,
macro_contents,
self.temp_directory,
)
def _get_source_file_name(self) -> str:
assert self.source_file_name
return self.source_file_name
class TestXmlExpressionLoader(BaseLoaderTestCase):
source_file_name = "expression.xml"
source_contents = TOOL_EXPRESSION_XML_1
def test_expression(self):
assert self._tool_source.parse_expression().strip() == "{return {'output': parseInt($job.input1)};}"
def test_tool_type(self):
assert self._tool_source.parse_tool_type() == "expression"
class TestXmlLoader(BaseLoaderTestCase):
source_file_name = "bwa.xml"
source_contents = TOOL_XML_1
def test_tool_source_to_string(self):
# Previously this threw an Exception - test for regression.
str(self._tool_source)
def test_version(self):
assert self._tool_source.parse_version() == "1.0.1"
def test_id(self):
assert self._tool_source.parse_id() == "bwa"
def test_module_and_type(self):
assert self._tool_source.parse_tool_module() is None
assert self._tool_source.parse_tool_type() is None
def test_name(self):
assert self._tool_source.parse_name() == "BWA Mapper"
def test_display_interface(self):
assert self._tool_source.parse_display_interface(False)
def test_require_login(self):
assert self._tool_source.parse_require_login(False)
def test_parse_request_param_translation_elem(self):
assert self._tool_source.parse_request_param_translation_elem() is None
def test_command_parsing(self):
assert self._tool_source.parse_command() == "bwa.py --arg1=42"
assert self._tool_source.parse_interpreter() == "python"
def test_descripting_parsing(self):
assert self._tool_source.parse_description() == "The BWA Mapper"
def test_version_command(self):
assert self._tool_source.parse_version_command() == "bwa.py --version"
assert self._tool_source.parse_version_command_interpreter() == "python"
def test_parallelism(self):
parallelism_info = self._tool_source.parse_parallelism()
assert parallelism_info.method == "multi"
assert parallelism_info.attributes["split_inputs"] == "input1"
def test_hidden(self):
assert self._tool_source.parse_hidden()
def test_action(self):
assert self._tool_source.parse_action_module() is None
def test_requirements(self):
requirements, containers, resource_requirements, _, credentials = self._tool_source.parse_requirements()
assert requirements[0].type == "package"
assert list(containers)[0].identifier == "mycool/bwa"
assert resource_requirements[0].resource_type == "cores_min"
assert resource_requirements[1].resource_type == "cuda_version_min"
assert resource_requirements[2].resource_type == "cuda_compute_capability"
assert resource_requirements[3].resource_type == "gpu_memory_min"
assert resource_requirements[4].resource_type == "cuda_device_count_min"
assert resource_requirements[5].resource_type == "cuda_device_count_max"
assert resource_requirements[6].resource_type == "shm_size"
assert resource_requirements[7].resource_type == "timelimit"
assert not resource_requirements[0].runtime_required
assert credentials[0].name == "Apollo"
assert credentials[0].version == "gmod.org/apollo"
assert len(credentials[0].secrets) == 2
assert len(credentials[0].variables) == 1
def test_outputs(self):
outputs, output_collections = self._tool_source.parse_outputs(object())
assert len(outputs) == 1, outputs
assert len(output_collections) == 0
def test_stdio(self):
exit, regexes = self._tool_source.parse_stdio()
assert len(exit) == 1
assert len(regexes) == 0
assert exit[0].range_start == 1
assert isinf(exit[0].range_end)
def test_help(self):
help_text = self._tool_source.parse_help().content
assert help_text.strip() == "This is HELP TEXT1!!!"
def test_tests(self):
tests_dict = self._tool_source.parse_tests_to_dict()
tests = tests_dict["tests"]
assert len(tests) == 2
test_dict = tests[0]
inputs = test_dict["inputs"]
assert len(inputs) == 1, test_dict
input1 = inputs[0]
assert input1["name"] == "foo", input1
assert input1["value"] == "5"
outputs = test_dict["outputs"]
assert len(outputs) == 1
output1 = outputs[0]
assert output1["name"] == "out1"
assert output1["value"] == "moo.txt"
attributes1 = output1["attributes"]
assert attributes1["compare"] == "diff"
assert attributes1["lines_diff"] == 0
test2 = tests[1]
outputs = test2["outputs"]
assert len(outputs) == 1
output2 = outputs[0]
assert output2["name"] == "out1"
assert output2["value"] is None
attributes1 = output2["attributes"]
assert attributes1["compare"] == "sim_size"
assert attributes1["lines_diff"] == 4
def test_output_models(self):
output_models = self._output_models
assert len(output_models) == 1
output_model = output_models[0]
assert output_model.name == "out1"
assert not output_model.hidden
assert output_model.label is None
output_dataset_model = assert_output_model_of_type(output_model, ToolOutputDataset)
assert output_dataset_model.metadata_source is None
def test_xrefs(self):
xrefs = self._tool_source.parse_xrefs()
assert xrefs == [{"value": "bwa", "type": "bio.tools"}]
def test_exit_code(self):
tool_source = self._get_tool_source(source_contents="""
ls
""")
exit, regexes = tool_source.parse_stdio()
assert len(exit) == 2, exit
assert len(regexes) == 0, regexes
tool_source = self._get_tool_source(source_contents="""
ls
""")
exit, regexes = tool_source.parse_stdio()
assert len(exit) == 2, exit
# error:, exception: various memory exception...
assert len(regexes) > 2, regexes
def test_sanitize_option(self):
assert self._tool_source.parse_sanitize() is True
def test_refresh_option(self):
assert self._tool_source.parse_refresh() is False
def test_nested_token(self):
tool_source = self._get_tool_source(source_contents=TOOL_WITH_TOKEN)
command = tool_source.parse_command()
assert command
assert "@" not in command
def test_token_significant_whitespace(self):
tool_source = self._get_tool_source(
source_contents=TOOL_WTIH_TOKEN_FROM_MACRO_FILE, macro_contents=MACRO_CONTENTS
)
command = tool_source.parse_command()
assert command == "cat "
assert "@" not in command
def test_recursive_token(self):
with self.assertRaisesRegex(Exception, "^Token '@NESTED_TOKEN@' cannot contain itself$"):
self._get_tool_source(source_contents=TOOL_WITH_RECURSIVE_TOKEN)
def test_creator(self):
creators = self._tool_source.parse_creator()
assert len(creators) == 2
creator1 = creators[0]
assert creator1["class"] == "Person"
assert creator1["identifier"] == "http://orcid.org/0000-0002-3079-6586"
creator2 = creators[1]
assert creator2["class"] == "Organization"
assert creator2["name"] == "Galaxy IUC"
class TestYamlLoader(BaseLoaderTestCase):
source_file_name = "bwa.yml"
source_contents = TOOL_YAML_1
def test_version(self):
assert self._tool_source.parse_version() == "1.0.2"
def test_id(self):
assert self._tool_source.parse_id() == "bowtie"
def test_module_and_type(self):
# These just rely on defaults
assert self._tool_source.parse_tool_module() is None
assert self._tool_source.parse_tool_type() is None
def test_name(self):
assert self._tool_source.parse_name() == "Bowtie Mapper"
def test_display_interface(self):
assert not self._tool_source.parse_display_interface(False)
assert self._tool_source.parse_display_interface(True)
def test_require_login(self):
assert not self._tool_source.parse_require_login(False)
def test_parse_request_param_translation_elem(self):
assert self._tool_source.parse_request_param_translation_elem() is None
def test_command_parsing(self):
assert self._tool_source.parse_command() == "bowtie_wrapper.pl --map-the-stuff"
assert self._tool_source.parse_interpreter() == "perl"
def test_parse_redirect_url_params_elem(self):
assert self._tool_source.parse_redirect_url_params_elem() is None
def test_descripting_parsing(self):
assert self._tool_source.parse_description() == "The Bowtie Mapper"
def test_version_command(self):
assert self._tool_source.parse_version_command() == "bowtie --version"
assert self._tool_source.parse_version_command_interpreter() is None
def test_parallelism(self):
assert self._tool_source.parse_parallelism() is None
def test_hidden(self):
assert not self._tool_source.parse_hidden()
def test_action(self):
assert self._tool_source.parse_action_module() is None
def test_requirements(self):
software_requirements, containers, resource_requirements, _, credentials = (
self._tool_source.parse_requirements()
)
assert software_requirements.to_dict() == [{"name": "bwa", "type": "package", "version": "1.0.1", "specs": []}]
assert len(containers) == 1
assert containers[0].to_dict() == {
"identifier": "awesome/bowtie",
"type": "docker",
"resolve_dependencies": False,
"shell": "/bin/sh",
}
assert len(resource_requirements) == 8
assert resource_requirements[0].to_dict() == {"resource_type": "cores_min", "value_or_expression": 1}
assert resource_requirements[1].to_dict() == {"resource_type": "cuda_version_min", "value_or_expression": 10.2}
assert resource_requirements[2].to_dict() == {
"resource_type": "cuda_compute_capability",
"value_or_expression": 6.1,
}
assert resource_requirements[3].to_dict() == {"resource_type": "gpu_memory_min", "value_or_expression": 4042}
assert resource_requirements[4].to_dict() == {
"resource_type": "cuda_device_count_min",
"value_or_expression": 1,
}
assert resource_requirements[5].to_dict() == {
"resource_type": "cuda_device_count_max",
"value_or_expression": 2,
}
assert resource_requirements[6].to_dict() == {
"resource_type": "shm_size",
"value_or_expression": 67108864,
}
assert resource_requirements[7].to_dict() == {
"resource_type": "timelimit",
"value_or_expression": 60,
}
assert len(credentials) == 1
assert len(credentials[0].secrets) == 2
assert len(credentials[0].variables) == 1
def test_outputs(self):
outputs, output_collections = self._tool_source.parse_outputs(object())
assert len(outputs) == 1
assert len(output_collections) == 0
def test_stdio(self):
exit, regexes = self._tool_source.parse_stdio()
assert len(exit) == 2
assert isinf(exit[0].range_start)
assert exit[0].range_start == float("-inf")
assert exit[1].range_start == 1
assert isinf(exit[1].range_end)
def test_help(self):
help_text = self._tool_source.parse_help().content
assert help_text.strip() == "This is HELP TEXT2!!!"
def test_inputs(self):
input_pages = self._tool_source.parse_input_pages()
assert input_pages.inputs_defined
page_sources = input_pages.page_sources
assert len(page_sources) == 1
page_source = page_sources[0]
input_sources = page_source.parse_input_sources()
assert len(input_sources) == 2
def test_tests(self):
tests_dict = self._tool_source.parse_tests_to_dict()
tests = tests_dict["tests"]
assert len(tests) == 2
test_dict = tests[0]
inputs = test_dict["inputs"]
assert len(inputs) == 1
input1 = inputs[0]
assert input1["name"] == "input1"
assert input1["value"] == 7
outputs = test_dict["outputs"]
assert len(outputs) == 1
output1 = outputs[0]
assert output1["name"] == "out1"
assert output1["value"] == "moo.txt"
attributes1 = output1["attributes"]
assert attributes1["compare"] == "diff"
assert attributes1["lines_diff"] == 0
test2 = tests[1]
outputs = test2["outputs"]
assert len(outputs) == 1
output2 = outputs[0]
assert output2["name"] == "out1"
assert output2["value"] is None
attributes1 = output2["attributes"]
assert attributes1["compare"] == "sim_size"
assert attributes1["lines_diff"] == 4
def test_xrefs(self):
xrefs = self._tool_source.parse_xrefs()
assert xrefs == [{"value": "bwa", "type": "bio.tools"}]
def test_sanitize(self):
assert self._tool_source.parse_sanitize() is True
class TestDataSourceLoader(BaseLoaderTestCase):
source_file_name = "ds.xml"
source_contents = """
server
data_source.py $output $__app__.config.output_size_limit
go to yeastMine server $GALAXY_URL
cow
"""
def test_sanitize_option(self):
assert self._tool_source.parse_sanitize() is False
def test_refresh_option(self):
assert self._tool_source.parse_refresh() is True
def test_tool_type(self):
assert self._tool_source.parse_tool_type() == "data_source"
def test_parse_request_param_translation_elem(self):
assert self._tool_source.parse_request_param_translation_elem() is not None
def test_redirect_url_params_elem(self):
assert self._tool_source.parse_redirect_url_params_elem() is not None
def test_parallelism(self):
assert self._tool_source.parse_parallelism() is None
def test_hidden(self):
assert not self._tool_source.parse_hidden()
class TestApplyRulesToolLoader(BaseLoaderTestCase):
source_file_name = os.path.join(galaxy_directory(), "lib/galaxy/tools/apply_rules.xml")
source_contents = None
def test_tool_type(self):
tool_module = self._tool_source.parse_tool_module()
assert tool_module[0] == "galaxy.tools"
assert tool_module[1] == "ApplyRulesTool"
assert self._tool_source.parse_tool_type() == "apply_rules_to_collection"
def test_outputs(self):
outputs, output_collections = self._tool_source.parse_outputs(object())
assert len(outputs) == 1
assert len(output_collections) == 1
def test_output_models(self):
output_models = self._output_models
assert len(output_models) == 1
output_model = output_models[0]
assert output_model.name == "output"
assert not output_model.hidden
assert output_model.label == "${input.name} (re-organized)"
output_collection_model = assert_output_model_of_type(output_model, ToolOutputCollection)
structure = output_collection_model.structure
assert structure.collection_type_from_rules == "rules"
class TestBuildListToolLoader(BaseLoaderTestCase):
source_file_name = os.path.join(galaxy_directory(), "lib/galaxy/tools/build_list.xml")
source_contents = None
def test_tool_type(self):
tool_module = self._tool_source.parse_tool_module()
assert tool_module[0] == "galaxy.tools"
assert tool_module[1] == "BuildListCollectionTool"
class FunctionalTestToolTestCase(BaseLoaderTestCase):
test_path: str
source_contents: None
def _get_source_file_name(self) -> str:
return functional_test_tool_path(self.test_path)
class TestExpressionTestToolLoader(FunctionalTestToolTestCase):
test_path = "expression_null_handling_boolean.xml"
def test_test(self):
test_dicts = self._tool_source.parse_tests_to_dict()["tests"]
assert len(test_dicts) == 3
test_dict_0 = test_dicts[0]
assert "outputs" in test_dict_0, test_dict_0
outputs = test_dict_0["outputs"]
output0 = outputs[0]
assert "object" in output0["attributes"]
assert output0["attributes"]["object"] is True
test_dict_1 = test_dicts[1]
assert "outputs" in test_dict_1, test_dict_1
outputs = test_dict_1["outputs"]
output0 = outputs[0]
assert "object" in output0["attributes"]
assert output0["attributes"]["object"] is False
test_dict_2 = test_dicts[2]
assert "outputs" in test_dict_2, test_dict_2
outputs = test_dict_2["outputs"]
output0 = outputs[0]
assert "object" in output0["attributes"]
assert output0["attributes"]["object"] is None
def test_output_models(self):
output_models = self._output_models
assert len(output_models) == 1
output_model = output_models[0]
assert output_model.name == "bool_out"
assert not output_model.hidden
assert output_model.label is None
class TestDefaultDataTestToolLoader(FunctionalTestToolTestCase):
test_path = "for_workflows/cat_default.xml"
def test_input_parsing(self):
input_pages = self._tool_source.parse_input_pages()
assert input_pages.inputs_defined
page_sources = input_pages.page_sources
assert len(page_sources) == 1
page_source = page_sources[0]
input_sources = page_source.parse_input_sources()
assert len(input_sources) == 1
data_input = input_sources[0]
default_dict = data_input.parse_default()
assert default_dict
assert default_dict["location"] == "https://raw.githubusercontent.com/galaxyproject/galaxy/dev/test-data/1.bed"
class TestDefaultCollectionDataTestToolLoader(FunctionalTestToolTestCase):
test_path = "collection_paired_default.xml"
def test_input_parsing(self):
input_pages = self._tool_source.parse_input_pages()
assert input_pages.inputs_defined
page_sources = input_pages.page_sources
assert len(page_sources) == 1
page_source = page_sources[0]
input_sources = page_source.parse_input_sources()
assert len(input_sources) == 1
data_input = input_sources[0]
default_dict = data_input.parse_default()
assert default_dict
assert default_dict["collection_type"] == "paired"
elements = default_dict["elements"]
assert len(elements) == 2
element0 = elements[0]
assert element0["identifier"] == "forward"
assert element0["location"] == "https://raw.githubusercontent.com/galaxyproject/galaxy/dev/test-data/1.bed"
element1 = elements[1]
assert element1["identifier"] == "reverse"
assert element1["location"] == "https://raw.githubusercontent.com/galaxyproject/galaxy/dev/test-data/1.fasta"
class TestDefaultNestedCollectionDataTestToolLoader(FunctionalTestToolTestCase):
test_path = "collection_nested_default.xml"
def test_input_parsing(self):
input_pages = self._tool_source.parse_input_pages()
assert input_pages.inputs_defined
page_sources = input_pages.page_sources
assert len(page_sources) == 1
page_source = page_sources[0]
input_sources = page_source.parse_input_sources()
assert len(input_sources) == 1
data_input = input_sources[0]
default_dict = data_input.parse_default()
assert default_dict
assert default_dict["collection_type"] == "list:paired"
elements = default_dict["elements"]
assert len(elements) == 1
element0 = elements[0]
assert element0["identifier"] == "i1"
elements0 = element0["elements"]
assert len(elements0) == 2
elements00 = elements0[0]
assert elements00["identifier"] == "forward"
elements01 = elements0[1]
assert elements01["identifier"] == "reverse"
class TestExpressionOutputDataToolLoader(FunctionalTestToolTestCase):
test_path = "expression_pick_larger_file.xml"
def test_output_parsing(self):
outputs, _ = self._tool_source.parse_outputs(None)
assert "larger_file" in outputs
tool_output = outputs["larger_file"]
assert tool_output.format == "data"
assert tool_output.from_expression == "output"
class TestSpecialToolLoader(BaseLoaderTestCase):
source_file_name = os.path.join(galaxy_directory(), "lib/galaxy/tools/imp_exp/exp_history_to_archive.xml")
source_contents = None
def test_tool_type(self):
tool_module = self._tool_source.parse_tool_module()
# Probably we don't parse_tool_module any more? -
# tool_type seems sufficient.
assert tool_module[0] == "galaxy.tools"
assert tool_module[1] == "ExportHistoryTool"
assert self._tool_source.parse_tool_type() == "export_history"
def test_version_command(self):
assert self._tool_source.parse_version_command() is None
assert self._tool_source.parse_version_command_interpreter() is None
def test_action(self):
action = self._tool_source.parse_action_module()
assert action[0] == "galaxy.tools.actions.history_imp_exp"
assert action[1] == "ExportHistoryToolAction"
class TestCollection(FunctionalTestToolTestCase):
test_path = "collection_two_paired.xml"
def test_tests(self):
tests_dict = self._tool_source.parse_tests_to_dict()
tests = tests_dict["tests"]
assert len(tests) == 2
assert len(tests[0]["inputs"]) == 3, tests[0]
outputs, output_collections = self._tool_source.parse_outputs(None)
assert len(output_collections) == 0
class TestCollectionOutputXml(FunctionalTestToolTestCase):
test_path = "collection_creates_pair.xml"
def test_tests(self):
outputs, output_collections = self._tool_source.parse_outputs(None)
assert len(output_collections) == 1
class TestCollectionOutputYaml(FunctionalTestToolTestCase):
test_path = "collection_creates_pair_y.yml"
def test_tests(self):
outputs, output_collections = self._tool_source.parse_outputs(None)
assert len(output_collections) == 1
class TestEnvironmentVariables(FunctionalTestToolTestCase):
test_path = "environment_variables.xml"
def test_tests(self):
tests_dict = self._tool_source.parse_tests_to_dict()
tests = tests_dict["tests"]
assert len(tests) == 1
class TestExpectations(FunctionalTestToolTestCase):
test_path = "detect_errors.xml"
def test_tests(self):
tests_dict = self._tool_source.parse_tests_to_dict()
tests = tests_dict["tests"]
assert len(tests) == 10
test_0 = tests[0]
assert len(test_0["stderr"]) == 1
assert len(test_0["stdout"]) == 2
class TestExpectationsCommandVersion(FunctionalTestToolTestCase):
test_path = "job_properties.xml"
def test_tests(self):
tests_dict = self._tool_source.parse_tests_to_dict()
tests = tests_dict["tests"]
assert len(tests) > 0
test_0 = tests[0]
assert len(test_0["command_version"]) == 1
class TestQcStdio(FunctionalTestToolTestCase):
test_path = "qc_stdout.xml"
def test_tests(self):
exit, regexes = self._tool_source.parse_stdio()
assert len(exit) == 2
assert len(regexes) == 2
regex = regexes[0]
assert regex.error_level == 1.1
class TestCollectionCatGroupTag(FunctionalTestToolTestCase):
test_path = "collection_cat_group_tag.xml"
def test_output_models(self):
output_models = self._output_models
assert len(output_models) == 1
output_model = output_models[0]
assert output_model.name == "out_file1"
assert not output_model.hidden
assert output_model.label is None
output_dataset_model = assert_output_model_of_type(output_model, ToolOutputDataset)
assert output_dataset_model.metadata_source == "input1"
def test_old_invalid_citation_dont_cause_failure_to_load():
with as_file(resource_path(__name__, "invalid_citation.xml")) as tool_path:
tool_source = get_tool_source(tool_path)
assert tool_source.parse_citations() == []
def test_invalid_citation_not_allowed_in_modern_tools():
with as_file(resource_path(__name__, "invalid_citation_24.2.xml")) as tool_path:
tool_source = get_tool_source(tool_path)
exc = None
try:
tool_source.parse_citations()
except Exception as e:
exc = e
assert exc is not None
class TestToolProvidedMetadata2(FunctionalTestToolTestCase):
test_path = "tool_provided_metadata_2.xml"
def test_output_models(self):
output_models = self._output_models
assert len(output_models) == 1
output_model = output_models[0]
assert output_model.name == "sample"
assert not output_model.hidden
assert output_model.label is None
output_dataset_model = assert_output_model_of_type(output_model, ToolOutputDataset)
assert output_dataset_model.metadata_source is None
discover_datasets = output_dataset_model.discover_datasets or []
assert len(discover_datasets) == 1
discover_datasets_0 = discover_datasets[0]
assert discover_datasets_0.discover_via == "pattern"
T = TypeVar("T")
def assert_output_model_of_type(obj, clazz: Type[T]) -> T:
assert isinstance(obj, clazz)
return obj