diff --git a/lib/galaxy/tools/parameters/basic.py b/lib/galaxy/tools/parameters/basic.py index c32192032d09..694fb751c3b5 100644 --- a/lib/galaxy/tools/parameters/basic.py +++ b/lib/galaxy/tools/parameters/basic.py @@ -290,7 +290,10 @@ def validate(self, value, trans=None): if value in ["", None] and self.optional: return for validator in self.validators: - validator.validate(value, trans) + try: + validator.validate(value, trans) + except ValueError as e: + raise ValueError(f"Parameter {self.name}: {e}") from None def to_dict(self, trans, other_values=None): """to_dict tool parameter. This can be overridden by subclasses.""" @@ -1988,7 +1991,10 @@ def do_validate(v): ): return else: - validator.validate(v, trans) + try: + validator.validate(v, trans) + except ValueError as e: + raise ValueError(f"Parameter {self.name}: {e}") from None dataset_count = 0 if value: diff --git a/lib/galaxy/tools/parameters/validation.py b/lib/galaxy/tools/parameters/validation.py index 6bd0ae5b1b79..49cae6053b94 100644 --- a/lib/galaxy/tools/parameters/validation.py +++ b/lib/galaxy/tools/parameters/validation.py @@ -16,13 +16,6 @@ log = logging.getLogger(__name__) -def get_test_fname(fname): - """Returns test data filename""" - path, name = os.path.split(__file__) - full_path = os.path.join(path, "test", fname) - return full_path - - class Validator(abc.ABC): """ A validator checks that a value meets some conditions OR raises ValueError @@ -88,45 +81,6 @@ def validate(self, value, trans=None, message=None, value_to_show=None): class RegexValidator(Validator): """ Validator that evaluates a regular expression - - >>> from galaxy.util import XML - >>> from galaxy.tools.parameters.basic import ToolParameter - >>> p = ToolParameter.build(None, XML(''' - ... - ... [Ff]oo - ... - ... ''')) - >>> t = p.validate("Foo") - >>> t = p.validate("foo") - >>> t = p.validate("Fop") - Traceback (most recent call last): - ... - ValueError: Value 'Fop' does not match regular expression '[Ff]oo' - >>> t = p.validate(["Foo", "foo"]) - >>> t = p.validate(["Foo", "Fop"]) - Traceback (most recent call last): - ... - ValueError: Value 'Fop' does not match regular expression '[Ff]oo' - >>> - >>> p = ToolParameter.build(None, XML(''' - ... - ... [Ff]oo - ... - ... ''')) - >>> t = p.validate("Foo") - Traceback (most recent call last): - ... - ValueError: Value 'Foo' does match regular expression '[Ff]oo' - >>> t = p.validate("foo") - Traceback (most recent call last): - ... - ValueError: Value 'foo' does match regular expression '[Ff]oo' - >>> t = p.validate("Fop") - >>> t = p.validate(["Fop", "foo"]) - Traceback (most recent call last): - ... - ValueError: Value 'foo' does match regular expression '[Ff]oo' - >>> t = p.validate(["Fop", "Fop"]) """ @classmethod @@ -177,40 +131,6 @@ def validate(self, value, trans=None): class InRangeValidator(ExpressionValidator): """ Validator that ensures a number is in a specified range - - >>> from galaxy.util import XML - >>> from galaxy.tools.parameters.basic import ToolParameter - >>> p = ToolParameter.build(None, XML(''' - ... - ... - ... - ... ''')) - >>> t = p.validate(10) - Traceback (most recent call last): - ... - ValueError: Doh!! 10 not in range - >>> t = p.validate(15) - >>> t = p.validate(20) - >>> t = p.validate(21) - Traceback (most recent call last): - ... - ValueError: Doh!! 21 not in range - >>> - >>> p = ToolParameter.build(None, XML(''' - ... - ... - ... - ... ''')) - >>> t = p.validate(10) - >>> t = p.validate(15) - Traceback (most recent call last): - ... - ValueError: Value ('15') must not fulfill float('10') < value <= float('20') - >>> t = p.validate(20) - Traceback (most recent call last): - ... - ValueError: Value ('20') must not fulfill float('10') < value <= float('20') - >>> t = p.validate(21) """ @classmethod @@ -253,40 +173,6 @@ def __init__(self, message, range_min, range_max, exclude_min=False, exclude_max class LengthValidator(InRangeValidator): """ Validator that ensures the length of the provided string (value) is in a specific range - - >>> from galaxy.util import XML - >>> from galaxy.tools.parameters.basic import ToolParameter - >>> p = ToolParameter.build(None, XML(''' - ... - ... - ... - ... ''')) - >>> t = p.validate("foo") - >>> t = p.validate("bar") - >>> t = p.validate("f") - Traceback (most recent call last): - ... - ValueError: Must have length of at least 2 and at most 8 - >>> t = p.validate("foobarbaz") - Traceback (most recent call last): - ... - ValueError: Must have length of at least 2 and at most 8 - >>> - >>> p = ToolParameter.build(None, XML(''' - ... - ... - ... - ... ''')) - >>> t = p.validate("foo") - Traceback (most recent call last): - ... - ValueError: Must not have length of at least 2 and at most 8 - >>> t = p.validate("bar") - Traceback (most recent call last): - ... - ValueError: Must not have length of at least 2 and at most 8 - >>> t = p.validate("f") - >>> t = p.validate("foobarbaz") """ @classmethod @@ -305,44 +191,6 @@ def validate(self, value, trans=None): class DatasetOkValidator(Validator): """ Validator that checks if a dataset is in an 'ok' state - - >>> from galaxy.datatypes.registry import example_datatype_registry_for_sample - >>> from galaxy.model import History, HistoryDatasetAssociation, set_datatypes_registry - >>> from galaxy.model.mapping import init - >>> from galaxy.util import XML - >>> from galaxy.tools.parameters.basic import ToolParameter - >>> - >>> sa_session = init("/tmp", "sqlite:///:memory:", create_tables=True).session - >>> hist = History() - >>> with sa_session.begin(): - ... sa_session.add(hist) - >>> set_datatypes_registry(example_datatype_registry_for_sample()) - >>> ok_hda = hist.add_dataset(HistoryDatasetAssociation(id=1, extension='interval', create_dataset=True, sa_session=sa_session)) - >>> ok_hda.set_dataset_state(model.Dataset.states.OK) - >>> notok_hda = hist.add_dataset(HistoryDatasetAssociation(id=2, extension='interval', create_dataset=True, sa_session=sa_session)) - >>> notok_hda.set_dataset_state(model.Dataset.states.EMPTY) - >>> - >>> p = ToolParameter.build(None, XML(''' - ... - ... - ... - ... ''')) - >>> t = p.validate(ok_hda) - >>> t = p.validate(notok_hda) - Traceback (most recent call last): - ... - ValueError: The selected dataset is still being generated, select another dataset or wait until it is completed - >>> - >>> p = ToolParameter.build(None, XML(''' - ... - ... - ... - ... ''')) - >>> t = p.validate(ok_hda) - Traceback (most recent call last): - ... - ValueError: The selected dataset must not be in state OK - >>> t = p.validate(notok_hda) """ @classmethod @@ -364,44 +212,6 @@ def validate(self, value, trans=None): class DatasetEmptyValidator(Validator): """ Validator that checks if a dataset has a positive file size. - - >>> from galaxy.datatypes.registry import example_datatype_registry_for_sample - >>> from galaxy.model import Dataset, History, HistoryDatasetAssociation, set_datatypes_registry - >>> from galaxy.model.mapping import init - >>> from galaxy.util import XML - >>> from galaxy.tools.parameters.basic import ToolParameter - >>> - >>> sa_session = init("/tmp", "sqlite:///:memory:", create_tables=True).session - >>> hist = History() - >>> with sa_session.begin(): - ... sa_session.add(hist) - >>> set_datatypes_registry(example_datatype_registry_for_sample()) - >>> empty_dataset = Dataset(external_filename=get_test_fname("empty.txt")) - >>> empty_hda = hist.add_dataset(HistoryDatasetAssociation(id=1, extension='interval', dataset=empty_dataset, sa_session=sa_session)) - >>> full_dataset = Dataset(external_filename=get_test_fname("1.tabular")) - >>> full_hda = hist.add_dataset(HistoryDatasetAssociation(id=2, extension='interval', dataset=full_dataset, sa_session=sa_session)) - >>> - >>> p = ToolParameter.build(None, XML(''' - ... - ... - ... - ... ''')) - >>> t = p.validate(full_hda) - >>> t = p.validate(empty_hda) - Traceback (most recent call last): - ... - ValueError: The selected dataset is empty, this tool expects non-empty files. - >>> - >>> p = ToolParameter.build(None, XML(''' - ... - ... - ... - ... ''')) - >>> t = p.validate(full_hda) - Traceback (most recent call last): - ... - ValueError: The selected dataset is non-empty, this tool expects empty files. - >>> t = p.validate(empty_hda) """ @classmethod @@ -413,6 +223,8 @@ def from_element(cls, param, elem): return cls(message, negate) def validate(self, value, trans=None): + print(f"value {value}") + print(f"value {value.get_size()}") if value: super().validate(value.get_size() != 0) @@ -420,46 +232,6 @@ def validate(self, value, trans=None): class DatasetExtraFilesPathEmptyValidator(Validator): """ Validator that checks if a dataset's extra_files_path exists and is not empty. - - >>> from galaxy.datatypes.registry import example_datatype_registry_for_sample - >>> from galaxy.model import History, HistoryDatasetAssociation, set_datatypes_registry - >>> from galaxy.model.mapping import init - >>> from galaxy.util import XML - >>> from galaxy.tools.parameters.basic import ToolParameter - >>> - >>> sa_session = init("/tmp", "sqlite:///:memory:", create_tables=True).session - >>> hist = History() - >>> with sa_session.begin(): - ... sa_session.add(hist) - >>> set_datatypes_registry(example_datatype_registry_for_sample()) - >>> has_extra_hda = hist.add_dataset(HistoryDatasetAssociation(id=1, extension='interval', create_dataset=True, sa_session=sa_session)) - >>> has_extra_hda.dataset.file_size = 10 - >>> has_extra_hda.dataset.total_size = 15 - >>> has_no_extra_hda = hist.add_dataset(HistoryDatasetAssociation(id=2, extension='interval', create_dataset=True, sa_session=sa_session)) - >>> has_no_extra_hda.dataset.file_size = 10 - >>> has_no_extra_hda.dataset.total_size = 10 - >>> - >>> p = ToolParameter.build(None, XML(''' - ... - ... - ... - ... ''')) - >>> t = p.validate(has_extra_hda) - >>> t = p.validate(has_no_extra_hda) - Traceback (most recent call last): - ... - ValueError: The selected dataset's extra_files_path directory is empty or does not exist, this tool expects non-empty extra_files_path directories associated with the selected input. - >>> - >>> p = ToolParameter.build(None, XML(''' - ... - ... - ... - ... ''')) - >>> t = p.validate(has_extra_hda) - Traceback (most recent call last): - ... - ValueError: The selected dataset's extra_files_path directory is non-empty or does exist, this tool expects empty extra_files_path directories associated with the selected input. - >>> t = p.validate(has_no_extra_hda) """ @classmethod @@ -478,58 +250,6 @@ def validate(self, value, trans=None): class MetadataValidator(Validator): """ Validator that checks for missing metadata - - >>> from galaxy.datatypes.registry import example_datatype_registry_for_sample - >>> from galaxy.model import Dataset, History, HistoryDatasetAssociation, set_datatypes_registry - >>> from galaxy.model.mapping import init - >>> from galaxy.util import XML - >>> from galaxy.tools.parameters.basic import ToolParameter - >>> - >>> sa_session = init("/tmp", "sqlite:///:memory:", create_tables=True).session - >>> hist = History() - >>> with sa_session.begin(): - ... sa_session.add(hist) - >>> set_datatypes_registry(example_datatype_registry_for_sample()) - >>> fname = get_test_fname('1.bed') - >>> bedds = Dataset(external_filename=fname) - >>> hda = hist.add_dataset(HistoryDatasetAssociation(id=1, extension='bed', create_dataset=True, sa_session=sa_session, dataset=bedds)) - >>> hda.set_dataset_state(model.Dataset.states.OK) - >>> hda.set_meta() - >>> hda.metadata.strandCol = hda.metadata.spec["strandCol"].no_value - >>> param_xml = ''' - ... - ... ''' - >>> p = ToolParameter.build(None, XML(param_xml.format(check="nameCol", skip=""))) - >>> t = p.validate(hda) - >>> p = ToolParameter.build(None, XML(param_xml.format(check="strandCol", skip=""))) - >>> t = p.validate(hda) - Traceback (most recent call last): - ... - ValueError: Metadata 'strandCol' missing, click the pencil icon in the history item to edit / save the metadata attributes - >>> p = ToolParameter.build(None, XML(param_xml.format(check="", skip="dbkey,comment_lines,column_names,strandCol"))) - >>> t = p.validate(hda) - >>> p = ToolParameter.build(None, XML(param_xml.format(check="", skip="dbkey,comment_lines,column_names,nameCol"))) - >>> t = p.validate(hda) - Traceback (most recent call last): - ... - ValueError: Metadata 'strandCol' missing, click the pencil icon in the history item to edit / save the metadata attributes - >>> param_xml_negate = ''' - ... - ... ''' - >>> p = ToolParameter.build(None, XML(param_xml_negate.format(check="strandCol", skip=""))) - >>> t = p.validate(hda) - >>> p = ToolParameter.build(None, XML(param_xml_negate.format(check="nameCol", skip=""))) - >>> t = p.validate(hda) - Traceback (most recent call last): - ... - ValueError: At least one of the checked metadata 'nameCol' is set, click the pencil icon in the history item to edit / save the metadata attributes - >>> p = ToolParameter.build(None, XML(param_xml_negate.format(check="", skip="dbkey,comment_lines,column_names,nameCol"))) - >>> t = p.validate(hda) - >>> p = ToolParameter.build(None, XML(param_xml_negate.format(check="", skip="dbkey,comment_lines,column_names,strandCol"))) - >>> t = p.validate(hda) - Traceback (most recent call last): - ... - ValueError: At least one of the non skipped metadata 'dbkey,comment_lines,column_names,strandCol' is set, click the pencil icon in the history item to edit / save the metadata attributes """ requires_dataset_metadata = True @@ -600,45 +320,6 @@ def validate(self, value, trans=None): class UnspecifiedBuildValidator(Validator): """ Validator that checks for dbkey not equal to '?' - - >>> from galaxy.datatypes.registry import example_datatype_registry_for_sample - >>> from galaxy.model import History, HistoryDatasetAssociation, set_datatypes_registry - >>> from galaxy.model.mapping import init - >>> from galaxy.util import XML - >>> from galaxy.tools.parameters.basic import ToolParameter - >>> - >>> sa_session = init("/tmp", "sqlite:///:memory:", create_tables=True).session - >>> hist = History() - >>> with sa_session.begin(): - ... sa_session.add(hist) - >>> set_datatypes_registry(example_datatype_registry_for_sample()) - >>> has_dbkey_hda = hist.add_dataset(HistoryDatasetAssociation(id=1, extension='interval', create_dataset=True, sa_session=sa_session)) - >>> has_dbkey_hda.set_dataset_state(model.Dataset.states.OK) - >>> has_dbkey_hda.metadata.dbkey = 'hg19' - >>> has_no_dbkey_hda = hist.add_dataset(HistoryDatasetAssociation(id=2, extension='interval', create_dataset=True, sa_session=sa_session)) - >>> has_no_dbkey_hda.set_dataset_state(model.Dataset.states.OK) - >>> - >>> p = ToolParameter.build(None, XML(''' - ... - ... - ... - ... ''')) - >>> t = p.validate(has_dbkey_hda) - >>> t = p.validate(has_no_dbkey_hda) - Traceback (most recent call last): - ... - ValueError: Unspecified genome build, click the pencil icon in the history item to set the genome build - >>> - >>> p = ToolParameter.build(None, XML(''' - ... - ... - ... - ... ''')) - >>> t = p.validate(has_dbkey_hda) - Traceback (most recent call last): - ... - ValueError: Specified genome build, click the pencil icon in the history item to remove the genome build - >>> t = p.validate(has_no_dbkey_hda) """ requires_dataset_metadata = True @@ -664,31 +345,6 @@ def validate(self, value, trans=None): class NoOptionsValidator(Validator): """ Validator that checks for empty select list - - >>> from galaxy.util import XML - >>> from galaxy.tools.parameters.basic import ToolParameter - >>> p = ToolParameter.build(None, XML(''' - ... - ... - ... - ... ''')) - >>> t = p.validate('foo') - >>> t = p.validate(None) - Traceback (most recent call last): - ... - ValueError: No options available for selection - >>> - >>> p = ToolParameter.build(None, XML(''' - ... - ... - ... - ... - ... ''')) - >>> t = p.validate('foo') - Traceback (most recent call last): - ... - ValueError: Options available for selection - >>> t = p.validate(None) """ @classmethod @@ -706,28 +362,6 @@ def validate(self, value, trans=None): class EmptyTextfieldValidator(Validator): """ Validator that checks for empty text field - - >>> from galaxy.util import XML - >>> from galaxy.tools.parameters.basic import ToolParameter - >>> p = ToolParameter.build(None, XML(''' - ... - ... - ... - ... ''')) - >>> t = p.validate("") - Traceback (most recent call last): - ... - ValueError: Field requires a value - >>> p = ToolParameter.build(None, XML(''' - ... - ... - ... - ... ''')) - >>> t = p.validate("foo") - Traceback (most recent call last): - ... - ValueError: Field must not set a value - >>> t = p.validate("") """ @classmethod diff --git a/test/unit/app/tools/test_parameter_validation.py b/test/unit/app/tools/test_parameter_validation.py index a1f9da021b45..8c337600944e 100644 --- a/test/unit/app/tools/test_parameter_validation.py +++ b/test/unit/app/tools/test_parameter_validation.py @@ -1,5 +1,17 @@ +from galaxy.datatypes.sniff import get_test_fname +from galaxy.model import ( + Dataset, + History, + HistoryDatasetAssociation, +) from .util import BaseParameterTestCase +# def get_test_fname(fname): +# """Returns test data filename""" +# path, name = os.path.split(__file__) +# full_path = os.path.join(path, "test", fname) +# return full_path + class TestParameterValidation(BaseParameterTestCase): def test_simple_ExpressionValidator(self): @@ -63,6 +75,373 @@ def test_ExpressionValidator_message(self): ): p.validate(1) + def test_NoOptionsValidator(self): + p = self._parameter_for( + xml=""" + + +""" + ) + p.validate("foo") + with self.assertRaisesRegex(ValueError, "Parameter index: No options available for selection"): + p.validate(None) + + p = self._parameter_for( + xml=""" + + + +""" + ) + with self.assertRaisesRegex(ValueError, "Parameter index: Options available for selection"): + p.validate("foo") + p.validate(None) + + def test_EmptyTextfieldValidator(self): + p = self._parameter_for( + xml=""" + + +""" + ) + p.validate("foo") + with self.assertRaisesRegex(ValueError, "Parameter blah: Field requires a value"): + p.validate("") + + p = self._parameter_for( + xml=""" + + +""" + ) + with self.assertRaisesRegex(ValueError, "Parameter blah: Field must not set a value"): + p.validate("foo") + p.validate("") + + def test_RegexValidator(self): + p = self._parameter_for( + xml=""" + + [Ff]oo +""" + ) + p.validate("Foo") + p.validate("foo") + with self.assertRaisesRegex( + ValueError, r"Parameter blah: Value 'Fop' does not match regular expression '\[Ff\]oo'" + ): + p.validate("Fop") + + # test also valitation of lists (for select parameters) + p.validate(["Foo", "foo"]) + with self.assertRaisesRegex( + ValueError, r"Parameter blah: Value 'Fop' does not match regular expression '\[Ff\]oo'" + ): + p.validate(["Foo", "Fop"]) + + p = self._parameter_for( + xml=""" + + [Ff]oo +""" + ) + with self.assertRaisesRegex( + ValueError, r"Parameter blah: Value 'Foo' does match regular expression '\[Ff\]oo'" + ): + p.validate("Foo") + with self.assertRaisesRegex( + ValueError, r"Parameter blah: Value 'foo' does match regular expression '\[Ff\]oo'" + ): + p.validate("foo") + p.validate("Fop") + with self.assertRaisesRegex( + ValueError, r"Parameter blah: Value 'foo' does match regular expression '\[Ff\]oo'" + ): + p.validate(["Fop", "foo"]) + p.validate(["Fop", "fop"]) + + def test_LengthValidator(self): + p = self._parameter_for( + xml=""" + + +""" + ) + p.validate("foo") + p.validate("bar") + with self.assertRaisesRegex(ValueError, "Parameter blah: Must have length of at least 2 and at most 8"): + p.validate("f") + with self.assertRaisesRegex(ValueError, "Parameter blah: Must have length of at least 2 and at most 8"): + p.validate("foobarbaz") + + p = self._parameter_for( + xml=""" + + +""" + ) + with self.assertRaisesRegex(ValueError, "Parameter blah: Must not have length of at least 2 and at most 8"): + p.validate("foo") + with self.assertRaisesRegex(ValueError, "Parameter blah: Must not have length of at least 2 and at most 8"): + p.validate("bar") + p.validate("f") + p.validate("foobarbaz") + + def test_InRangeValidator(self): + p = self._parameter_for( + xml=""" + + +""" + ) + with self.assertRaisesRegex(ValueError, "Parameter blah: Doh!! 10 not in range"): + p.validate(10) + p.validate(15) + p.validate(20) + with self.assertRaisesRegex(ValueError, "Parameter blah: Doh!! 21 not in range"): + p.validate(21) + + p = self._parameter_for( + xml=""" + + +""" + ) + p.validate(10) + with self.assertRaisesRegex( + ValueError, r"Parameter blah: Value \('15'\) must not fulfill float\('10'\) < value <= float\('20'\)" + ): + p.validate(15) + with self.assertRaisesRegex( + ValueError, r"Parameter blah: Value \('20'\) must not fulfill float\('10'\) < value <= float\('20'\)" + ): + p.validate(20) + p.validate(21) + + def test_DatasetOkValidator(self): + sa_session = self.app.model.context + hist = History() + with sa_session.begin(): + sa_session.add(hist) + ok_hda = hist.add_dataset( + HistoryDatasetAssociation(id=1, extension="interval", create_dataset=True, sa_session=sa_session) + ) + ok_hda.set_dataset_state(Dataset.states.OK) + notok_hda = hist.add_dataset( + HistoryDatasetAssociation(id=2, extension="interval", create_dataset=True, sa_session=sa_session) + ) + notok_hda.set_dataset_state(Dataset.states.EMPTY) + + p = self._parameter_for( + xml=""" + + +""" + ) + p.validate(ok_hda) + with self.assertRaisesRegex( + ValueError, + "Parameter blah: The selected dataset is still being generated, select another dataset or wait until it is completed", + ): + p.validate(notok_hda) + p = self._parameter_for( + xml=""" + + +""" + ) + with self.assertRaisesRegex(ValueError, "Parameter blah: The selected dataset must not be in state OK"): + p.validate(ok_hda) + p.validate(notok_hda) + + def test_DatasetEmptyValidator(self): + sa_session = self.app.model.context + hist = History() + with sa_session.begin(): + sa_session.add(hist) + empty_dataset = Dataset(external_filename=get_test_fname("empty.txt")) + empty_hda = hist.add_dataset( + HistoryDatasetAssociation(id=1, extension="interval", dataset=empty_dataset, sa_session=sa_session) + ) + full_dataset = Dataset(external_filename=get_test_fname("1.json")) + full_hda = hist.add_dataset( + HistoryDatasetAssociation(id=2, extension="interval", dataset=full_dataset, sa_session=sa_session) + ) + + p = self._parameter_for( + xml=""" + + +""" + ) + p.validate(full_hda) + with self.assertRaisesRegex( + ValueError, "Parameter blah: The selected dataset is empty, this tool expects non-empty files." + ): + p.validate(empty_hda) + + p = self._parameter_for( + xml=""" + + +""" + ) + with self.assertRaisesRegex( + ValueError, "Parameter blah: The selected dataset is non-empty, this tool expects empty files." + ): + p.validate(full_hda) + p.validate(empty_hda) + + def test_DatasetExtraFilesPathEmptyValidator(self): + sa_session = self.app.model.context + hist = History() + with sa_session.begin(): + sa_session.add(hist) + has_extra_hda = hist.add_dataset( + HistoryDatasetAssociation(id=1, extension="interval", create_dataset=True, sa_session=sa_session) + ) + has_extra_hda.dataset.file_size = 10 + has_extra_hda.dataset.total_size = 15 + has_no_extra_hda = hist.add_dataset( + HistoryDatasetAssociation(id=2, extension="interval", create_dataset=True, sa_session=sa_session) + ) + has_no_extra_hda.dataset.file_size = 10 + has_no_extra_hda.dataset.total_size = 10 + + p = self._parameter_for( + xml=""" + + +""" + ) + p.validate(has_extra_hda) + with self.assertRaisesRegex( + ValueError, + "Parameter blah: The selected dataset's extra_files_path directory is empty or does not exist, this tool expects non-empty extra_files_path directories associated with the selected input.", + ): + p.validate(has_no_extra_hda) + + p = self._parameter_for( + xml=""" + + +""" + ) + + with self.assertRaisesRegex( + ValueError, + "Parameter blah: The selected dataset's extra_files_path directory is non-empty or does exist, this tool expects empty extra_files_path directories associated with the selected input.", + ): + p.validate(has_extra_hda) + p.validate(has_no_extra_hda) + + def test_MetadataValidator(self): + sa_session = self.app.model.context + hist = History() + with sa_session.begin(): + sa_session.add(hist) + hda = hist.add_dataset( + HistoryDatasetAssociation( + id=1, + extension="bed", + create_dataset=True, + sa_session=sa_session, + dataset=Dataset(external_filename=get_test_fname("1.bed")), + ) + ) + hda.set_dataset_state(Dataset.states.OK) + hda.set_meta() + hda.metadata.strandCol = hda.metadata.spec["strandCol"].no_value + + param_xml = """ + + +""" + + p = self._parameter_for(xml=param_xml.format(check="nameCol", skip="")) + p.validate(hda) + + p = self._parameter_for(xml=param_xml.format(check="strandCol", skip="")) + with self.assertRaisesRegex( + ValueError, + "Parameter blah: Metadata 'strandCol' missing, click the pencil icon in the history item to edit / save the metadata attributes", + ): + p.validate(hda) + + p = self._parameter_for(xml=param_xml.format(check="", skip="dbkey,comment_lines,column_names,strandCol")) + p.validate(hda) + p = self._parameter_for(xml=param_xml.format(check="", skip="dbkey,comment_lines,column_names,nameCol")) + with self.assertRaisesRegex( + ValueError, + "Parameter blah: Metadata 'strandCol' missing, click the pencil icon in the history item to edit / save the metadata attributes", + ): + p.validate(hda) + + param_xml_negate = """ + + +""" + p = self._parameter_for(xml=param_xml_negate.format(check="strandCol", skip="")) + p.validate(hda) + p = self._parameter_for(xml=param_xml_negate.format(check="nameCol", skip="")) + with self.assertRaisesRegex( + ValueError, + "Parameter blah: At least one of the checked metadata 'nameCol' is set, click the pencil icon in the history item to edit / save the metadata attributes", + ): + p.validate(hda) + + p = self._parameter_for(xml=param_xml_negate.format(check="", skip="dbkey,comment_lines,column_names,nameCol")) + p.validate(hda) + p = self._parameter_for( + xml=param_xml_negate.format(check="", skip="dbkey,comment_lines,column_names,strandCol") + ) + with self.assertRaisesRegex( + ValueError, + "Parameter blah: At least one of the non skipped metadata 'dbkey,comment_lines,column_names,strandCol' is set, click the pencil icon in the history item to edit / save the metadata attributes", + ): + p.validate(hda) + + def test_UnspecifiedBuildValidator(self): + sa_session = self.app.model.context + hist = History() + with sa_session.begin(): + sa_session.add(hist) + has_dbkey_hda = hist.add_dataset( + HistoryDatasetAssociation(id=1, extension="interval", create_dataset=True, sa_session=sa_session) + ) + has_dbkey_hda.set_dataset_state(Dataset.states.OK) + has_dbkey_hda.metadata.dbkey = "hg19" + has_no_dbkey_hda = hist.add_dataset( + HistoryDatasetAssociation(id=2, extension="interval", create_dataset=True, sa_session=sa_session) + ) + has_no_dbkey_hda.set_dataset_state(Dataset.states.OK) + + p = self._parameter_for( + xml=""" + + +""" + ) + p.validate(has_dbkey_hda) + with self.assertRaisesRegex( + ValueError, + "Parameter blah: Unspecified genome build, click the pencil icon in the history item to set the genome build", + ): + p.validate(has_no_dbkey_hda) + + p = self._parameter_for( + xml=""" + + +""" + ) + with self.assertRaisesRegex( + ValueError, + "Parameter blah: Specified genome build, click the pencil icon in the history item to remove the genome build", + ): + p.validate(has_dbkey_hda) + p.validate(has_no_dbkey_hda) + def test_RegexValidator_global_flag_inline(self): # tests that global inline flags continue to work past python 3.10 p = self._parameter_for(