PageRenderTime 10ms CodeModel.GetById 1ms app.highlight 6ms RepoModel.GetById 1ms app.codeStats 1ms

/test/functional/test_toolbox.py

https://bitbucket.org/cistrome/cistrome-harvard/
Python | 117 lines | 76 code | 19 blank | 22 comment | 21 complexity | 8ac68dc0f8873baf6521946d94ad611d MD5 | raw file
  1import new
  2import sys
  3from base.twilltestcase import TwillTestCase
  4from base.interactor import build_interactor, stage_data_in_history
  5from galaxy.tools import DataManagerTool
  6import logging
  7log = logging.getLogger( __name__ )
  8
  9toolbox = None
 10
 11#Do not test Data Managers as part of the standard Tool Test Framework.
 12TOOL_TYPES_NO_TEST = ( DataManagerTool, )
 13
 14class ToolTestCase( TwillTestCase ):
 15    """Abstract test case that runs tests based on a `galaxy.tools.test.ToolTest`"""
 16
 17    def do_it( self, testdef ):
 18        """
 19        Run through a tool test case.
 20        """
 21        shed_tool_id = self.shed_tool_id
 22
 23        self._handle_test_def_errors( testdef )
 24
 25        galaxy_interactor = self._galaxy_interactor( testdef )
 26
 27        test_history = galaxy_interactor.new_history()
 28
 29        stage_data_in_history( galaxy_interactor, testdef.test_data(), test_history, shed_tool_id )
 30
 31        data_list = galaxy_interactor.run_tool( testdef, test_history )
 32        self.assertTrue( data_list )
 33
 34        self._verify_outputs( testdef, test_history, shed_tool_id, data_list, galaxy_interactor )
 35
 36        galaxy_interactor.delete_history( test_history )
 37
 38    def _galaxy_interactor( self, testdef ):
 39        return build_interactor( self, testdef.interactor )
 40
 41    def _handle_test_def_errors(self, testdef):
 42        # If the test generation had an error, raise
 43        if testdef.error:
 44            if testdef.exception:
 45                raise testdef.exception
 46            else:
 47                raise Exception( "Test parse failure" )
 48
 49    def _verify_outputs( self, testdef, history, shed_tool_id, data_list, galaxy_interactor ):
 50        maxseconds = testdef.maxseconds
 51
 52        for output_index, output_tuple in enumerate(testdef.outputs):
 53            # Get the correct hid
 54            name, outfile, attributes = output_tuple
 55            try:
 56                output_data = data_list[ name ]
 57            except (TypeError, KeyError):
 58                # Legacy - fall back on ordered data list access if data_list is
 59                # just a list (case with twill variant or if output changes its
 60                # name).
 61                if hasattr(data_list, "values"):
 62                    output_data = data_list.values()[ output_index ]
 63                else:
 64                    output_data = data_list[ len(data_list) - len(testdef.outputs) + output_index ]
 65            self.assertTrue( output_data is not None )
 66            try:
 67                galaxy_interactor.verify_output( history, output_data, outfile, attributes=attributes, shed_tool_id=shed_tool_id, maxseconds=maxseconds )
 68            except Exception:
 69                for stream in ['stdout', 'stderr']:
 70                    stream_output = galaxy_interactor.get_job_stream( history, output_data, stream=stream )
 71                    print >>sys.stderr, self._format_stream( stream_output, stream=stream, format=True )
 72                raise
 73
 74
 75def build_tests( app=None, testing_shed_tools=False, master_api_key=None, user_api_key=None ):
 76    """
 77    If the module level variable `toolbox` is set, generate `ToolTestCase`
 78    classes for all of its tests and put them into this modules globals() so
 79    they can be discovered by nose.
 80    """
 81    if app is None:
 82        return
 83
 84    # Push all the toolbox tests to module level
 85    G = globals()
 86
 87    # Eliminate all previous tests from G.
 88    for key, val in G.items():
 89        if key.startswith( 'TestForTool_' ):
 90            del G[ key ]
 91    for i, tool_id in enumerate( app.toolbox.tools_by_id ):
 92        tool = app.toolbox.get_tool( tool_id )
 93        if isinstance( tool, TOOL_TYPES_NO_TEST ):
 94            #We do not test certain types of tools (e.g. Data Manager tools) as part of ToolTestCase 
 95            continue
 96        if tool.tests:
 97            shed_tool_id = None if not testing_shed_tools else tool.id
 98            # Create a new subclass of ToolTestCase, dynamically adding methods
 99            # named test_tool_XXX that run each test defined in the tool config.
100            name = "TestForTool_" + tool.id.replace( ' ', '_' )
101            baseclasses = ( ToolTestCase, )
102            namespace = dict()
103            for j, testdef in enumerate( tool.tests ):
104                def make_test_method( td ):
105                    def test_tool( self ):
106                        self.do_it( td )
107                    return test_tool
108                test_method = make_test_method( testdef )
109                test_method.__doc__ = "%s ( %s ) > %s" % ( tool.name, tool.id, testdef.name )
110                namespace[ 'test_tool_%06d' % j ] = test_method
111                namespace[ 'shed_tool_id' ] = shed_tool_id
112                namespace[ 'master_api_key' ] = master_api_key
113                namespace[ 'user_api_key' ] = user_api_key
114            # The new.classobj function returns a new class object, with name name, derived
115            # from baseclasses (which should be a tuple of classes) and with namespace dict.
116            new_class_obj = new.classobj( name, baseclasses, namespace )
117            G[ name ] = new_class_obj