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(