diff --git a/lib/galaxy/tools/__init__.py b/lib/galaxy/tools/__init__.py index f363c234792..fe836bb3d74 100755 --- a/lib/galaxy/tools/__init__.py +++ b/lib/galaxy/tools/__init__.py @@ -52,7 +52,7 @@ from galaxy.tools.parameters.input_translation import ToolInputTranslator from galaxy.tools.parameters.output import ToolOutputActionGroup from galaxy.tools.parameters.validation import LateValidationError from galaxy.tools.filters import FilterFactory -from galaxy.tools.test import ToolTestBuilder +from galaxy.tools.test import parse_tests_elem from galaxy.util import listify, parse_xml, rst_to_html, string_as_bool, string_to_object, xml_text, xml_to_string from galaxy.util.bunch import Bunch from galaxy.util.expressions import ExpressionContext @@ -1222,7 +1222,7 @@ class Tool( object, Dictifiable ): tests_elem = root.find( "tests" ) if tests_elem: try: - self.parse_tests( tests_elem ) + self.tests = parse_tests_elem( self, tests_elem ) except: log.exception( "Failed to parse tool tests" ) else: @@ -1564,16 +1564,6 @@ class Tool( object, Dictifiable ): log.error( "Traceback: %s" % trace_msg ) return return_level - def parse_tests( self, tests_elem ): - """ - Parse any "" elements, create a `ToolTestBuilder` for each and - store in `self.tests`. - """ - self.tests = [] - for i, test_elem in enumerate( tests_elem.findall( 'test' ) ): - test = ToolTestBuilder( self, test_elem, i ) - self.tests.append( test ) - def parse_input_page( self, input_elem, enctypes ): """ Parse a page of inputs. This basically just calls 'parse_input_elem', diff --git a/lib/galaxy/tools/test.py b/lib/galaxy/tools/test.py index e63911a7ef6..0e2c32f966a 100644 --- a/lib/galaxy/tools/test.py +++ b/lib/galaxy/tools/test.py @@ -1,3 +1,4 @@ +import os import os.path from parameters import basic from parameters import grouping @@ -8,6 +9,21 @@ log = logging.getLogger( __name__ ) DEFAULT_FTYPE = 'auto' DEFAULT_DBKEY = 'hg17' +DEFAULT_INTERACTOR = "twill" # Default mechanism test code uses for interacting with Galaxy instance. + + +def parse_tests_elem(tool, tests_elem): + """ + Build ToolTestBuilder objects for each "" elements and + return default interactor (if any). + """ + default_interactor = os.environ.get( 'GALAXY_TEST_DEFAULT_INTERACTOR', DEFAULT_INTERACTOR ) + tests_default_interactor = tests_elem.get( 'interactor', default_interactor ) + tests = [] + for i, test_elem in enumerate( tests_elem.findall( 'test' ) ): + test = ToolTestBuilder( tool, test_elem, i, default_interactor=tests_default_interactor ) + tests.append( test ) + return tests class ToolTestBuilder( object ): @@ -17,7 +33,7 @@ class ToolTestBuilder( object ): doing dynamic tests in this way allows better integration) """ - def __init__( self, tool, test_elem, i ): + def __init__( self, tool, test_elem, i, default_interactor ): name = test_elem.get( 'name', 'Test-%d' % (i + 1) ) maxseconds = int( test_elem.get( 'maxseconds', '120' ) ) @@ -30,7 +46,7 @@ class ToolTestBuilder( object ): self.error = False self.exception = None - self.__parse_elem( test_elem, i ) + self.__parse_elem( test_elem, i, default_interactor ) def test_data( self ): """ @@ -57,12 +73,18 @@ class ToolTestBuilder( object ): yield data_dict - def __parse_elem( self, test_elem, i ): + def __parse_elem( self, test_elem, i, default_interactor ): # Composite datasets need a unique name: each test occurs in a fresh # history, but we'll keep it unique per set of tests - use i (test #) # and composite_data_names_counter (instance per test #) composite_data_names_counter = 0 try: + # Mechanism test code uses for interacting with Galaxy instance, + # until 'api' is the default switch this to API to use its new + # features. Once 'api' is the default set to 'twill' to use legacy + # features or workarounds. + self.interactor = test_elem.get( 'interactor', default_interactor ) + for param_elem in test_elem.findall( "param" ): attrib = dict( param_elem.attrib ) if 'values' in attrib: diff --git a/test/functional/test_toolbox.py b/test/functional/test_toolbox.py index ba252e71619..479d2ca6ceb 100644 --- a/test/functional/test_toolbox.py +++ b/test/functional/test_toolbox.py @@ -1,6 +1,8 @@ import sys import new +import os from galaxy.tools.parameters import grouping +from galaxy.util import string_as_bool from base.twilltestcase import TwillTestCase import galaxy.model from galaxy.model.orm import and_, desc @@ -20,7 +22,7 @@ class ToolTestCase( TwillTestCase ): self.__handle_test_def_errors( testdef ) - galaxy_interactor = GalaxyInteractorTwill( self ) + galaxy_interactor = self.__galaxy_interactor( testdef ) test_history = galaxy_interactor.new_history() @@ -38,6 +40,11 @@ class ToolTestCase( TwillTestCase ): galaxy_interactor.delete_history( test_history ) + def __galaxy_interactor( self, testdef ): + interactor_key = testdef.interactor + interactor_class = GALAXY_INTERACTORS[ interactor_key ] + return interactor_class( self ) + def __handle_test_def_errors(self, testdef): # If the test generation had an error, raise if testdef.error: @@ -68,6 +75,25 @@ class ToolTestCase( TwillTestCase ): raise +class GalaxyInteractorApi( object ): + + def __init__( self, twill_test_case ): + self.twill_test_case = twill_test_case + self.master_api_key = twill_test_case.master_api_key + + def new_history( self ): + return None + + def stage_data_async( self, test_data, shed_tool_id, async=True ): + return lambda: True + + def run_tool( self, testdef ): + return [] + + def delete_history( self, history ): + return None + + class GalaxyInteractorTwill( object ): def __init__( self, twill_test_case ): @@ -231,3 +257,9 @@ def build_tests( testing_shed_tools=False, master_api_key=None ): # from baseclasses (which should be a tuple of classes) and with namespace dict. new_class_obj = new.classobj( name, baseclasses, namespace ) G[ name ] = new_class_obj + + +GALAXY_INTERACTORS = { + 'api': GalaxyInteractorApi, + 'twill': GalaxyInteractorTwill, +}