Merge pull request #117 from jmchilton/detect_errors

Implement ``detect_errors`` attribute on tool XML.
This commit is contained in:
Nate Coraor
2015-04-15 16:43:33 -04:00
6 changed files with 140 additions and 17 deletions
+38
View File
@@ -0,0 +1,38 @@
from .interface import ToolStdioExitCode
from .interface import ToolStdioRegex
def error_on_exit_code():
exit_code_lower = ToolStdioExitCode()
exit_code_lower.range_start = float("-inf")
exit_code_lower.range_end = -1
_set_fatal(exit_code_lower)
exit_code_high = ToolStdioExitCode()
exit_code_high.range_start = 1
exit_code_high.range_end = float("inf")
_set_fatal(exit_code_high)
return [exit_code_lower, exit_code_high], []
def aggressive_error_checks():
exit_codes, _ = error_on_exit_code()
# these regexes are processed as case insensitive by default
regexes = [
_error_regex("exception:"),
_error_regex("error:")
]
return exit_codes, regexes
def _error_regex(match):
regex = ToolStdioRegex()
_set_fatal(regex)
regex.match = match
regex.stdout_match = True
regex.stderr_match = True
return regex
def _set_fatal(obj):
from galaxy.jobs.error_level import StdioErrorLevel
obj.error_level = StdioErrorLevel.FATAL
+18 -2
View File
@@ -15,6 +15,10 @@ from .interface import (
TestCollectionDef,
TestCollectionOutputDef,
)
from .util import (
error_on_exit_code,
aggressive_error_checks,
)
from galaxy.util import string_as_bool, xml_text, xml_to_string
from galaxy.util.odict import odict
from galaxy.tools.deps import requirements
@@ -229,8 +233,20 @@ class XmlToolSource(ToolSource):
return output
def parse_stdio(self):
parser = StdioParser(self.root)
return parser.stdio_exit_codes, parser.stdio_regexes
command_el = self._command_el
detect_errors = None
if command_el is not None:
detect_errors = command_el.get("detect_errors")
if detect_errors and detect_errors != "default":
if detect_errors == "exit_code":
return error_on_exit_code()
elif detect_errors == "aggressive":
return aggressive_error_checks()
else:
raise ValueError("Unknown detect_errors value encountered [%s]" % detect_errors)
else:
parser = StdioParser(self.root)
return parser.stdio_exit_codes, parser.stdio_regexes
def parse_help(self):
help_elem = self.root.find( 'help' )
+2 -13
View File
@@ -2,7 +2,7 @@ from .interface import ToolSource
from .interface import PagesSource
from .interface import PageSource
from .interface import InputSource
from .interface import ToolStdioExitCode
from .util import error_on_exit_code
from galaxy.tools.deps import requirements
from galaxy.tools.parameters import output_collect
@@ -57,18 +57,7 @@ class YamlToolSource(ToolSource):
return PagesSource([page_source])
def parse_stdio(self):
from galaxy.jobs.error_level import StdioErrorLevel
# New format - starting out just using exit code.
exit_code_lower = ToolStdioExitCode()
exit_code_lower.range_start = float("-inf")
exit_code_lower.range_end = -1
exit_code_lower.error_level = StdioErrorLevel.FATAL
exit_code_high = ToolStdioExitCode()
exit_code_high.range_start = 1
exit_code_high.range_end = float("inf")
exit_code_lower.error_level = StdioErrorLevel.FATAL
return [exit_code_lower, exit_code_high], []
return error_on_exit_code()
def parse_help(self):
return self.root_dict.get("help", None)
@@ -0,0 +1,51 @@
<tool id="detect_errors_aggressive" name="detect_errors_aggressive" version="1.0.0">
<command detect_errors="aggressive">
#if $error_bool
echo "ERROR: Problem...."
#elif $exception_bool
echo "Exception: Problem..."
#else
echo "Everything is OK."
#end if
; sh -c "exit $exit_code"
</command>
<inputs>
<param name="error_bool" type="boolean" label="error bool" />
<param name="exception_bool" type="boolean" label="exception bool" checked="false" />
<param name="exit_code" type="integer" value="0" label="exit code"/>
</inputs>
<outputs>
<data name="out_file1" />
</outputs>
<tests>
<test expect_exit_code="0" expect_failure="false">
<param name="error_bool" value="false" />
<param name="exception_bool" value="false" />
<param name="exit_code" value="0" />
<assert_stdout>
<has_line line="Everything is OK." />
</assert_stdout>
</test>
<test expect_exit_code="1" expect_failure="true">
<param name="error_bool" value="false" />
<param name="exception_bool" value="false" />
<param name="exit_code" value="1" />
<assert_stdout>
<has_line line="Everything is OK." />
</assert_stdout>
</test>
<test expect_exit_code="0" expect_failure="true">
<param name="error_bool" value="true" />
<param name="exception_bool" value="false" />
<param name="exit_code" value="0" />
</test>
<test expect_exit_code="0" expect_failure="true">
<param name="error_bool" value="false" />
<param name="exception_bool" value="true" />
<param name="exit_code" value="0" />
</test>
</tests>
<help>
</help>
</tool>
@@ -16,6 +16,7 @@
<tool file="composite_output.xml" />
<tool file="metadata.xml" />
<tool file="metadata_bam.xml" />
<tool file="detect_errors_aggressive.xml" />
<tool file="job_properties.xml" />
<tool file="gzipped_inputs.xml" />
<tool file="output_order.xml" />
+30 -2
View File
@@ -104,8 +104,15 @@ class BaseLoaderTestCase(unittest.TestCase):
@property
def _tool_source(self):
path = os.path.join(self.temp_directory, self.source_file_name)
open(path, "w").write(self.source_contents)
return self._get_tool_source()
def _get_tool_source(self, source_file_name=None, source_contents=None):
if source_file_name is None:
source_file_name = self.source_file_name
if source_contents is None:
source_contents = self.source_contents
path = os.path.join(self.temp_directory, source_file_name)
open(path, "w").write(source_contents)
tool_source = get_tool_source(path)
return tool_source
@@ -212,6 +219,27 @@ class XmlLoaderTestCase(BaseLoaderTestCase):
assert attributes1["compare"] == "sim_size"
assert attributes1["lines_diff"] == 4
def test_exit_code(self):
tool_source = self._get_tool_source(source_contents="""<tool id="bwa" name="bwa">
<command detect_errors="exit_code">
ls
</command>
</tool>
""")
exit, regexes = tool_source.parse_stdio()
assert len(exit) == 2, exit
assert len(regexes) == 0, regexes
tool_source = self._get_tool_source(source_contents="""<tool id="bwa" name="bwa">
<command detect_errors="aggressive">
ls
</command>
</tool>
""")
exit, regexes = tool_source.parse_stdio()
assert len(exit) == 2, exit
assert len(regexes) == 2, regexes
class YamlLoaderTestCase(BaseLoaderTestCase):
source_file_name = "bwa.yml"