Merge pull request #4387 from jmchilton/tool_unit_test_cleanup

Cleanup of Unit Test Code for Loading Tools
This commit is contained in:
Björn Grüning
2017-08-16 14:55:14 +02:00
committed by GitHub
8 changed files with 76 additions and 104 deletions
+23 -16
View File
@@ -191,6 +191,24 @@ class ToolNotFoundException( Exception ):
pass
def create_tool_from_source( app, tool_source, config_file=None, **kwds ):
# Allow specifying a different tool subclass to instantiate
tool_module = tool_source.parse_tool_module()
if tool_module is not None:
module, cls = tool_module
mod = __import__( module, globals(), locals(), [cls] )
ToolClass = getattr( mod, cls )
elif tool_source.parse_tool_type():
tool_type = tool_source.parse_tool_type()
ToolClass = tool_types.get( tool_type )
else:
# Normal tool
root = getattr( tool_source, 'root', None )
ToolClass = Tool
tool = ToolClass( config_file, tool_source, app, **kwds )
return tool
class ToolBox( BaseGalaxyToolBox ):
""" A derivative of AbstractToolBox with knowledge about Tool internals -
how to construct them, action types, dependency management, etc....
@@ -228,7 +246,7 @@ class ToolBox( BaseGalaxyToolBox ):
# Deprecated method, TODO - eliminate calls to this in test/.
return self._tools_by_id
def create_tool( self, config_file, repository_id=None, guid=None, **kwds ):
def create_tool( self, config_file, **kwds ):
try:
tool_source = get_tool_source(
config_file,
@@ -239,21 +257,10 @@ class ToolBox( BaseGalaxyToolBox ):
# capture and log parsing errors
global_tool_errors.add_error(config_file, "Tool XML parsing", e)
raise e
# Allow specifying a different tool subclass to instantiate
tool_module = tool_source.parse_tool_module()
if tool_module is not None:
module, cls = tool_module
mod = __import__( module, globals(), locals(), [cls] )
ToolClass = getattr( mod, cls )
elif tool_source.parse_tool_type():
tool_type = tool_source.parse_tool_type()
ToolClass = tool_types.get( tool_type )
else:
# Normal tool
root = getattr( tool_source, 'root', None )
ToolClass = Tool
tool = ToolClass( config_file, tool_source, self.app, guid=guid, repository_id=repository_id, **kwds )
return tool
return self._create_tool_from_source( tool_source, config_file=config_file, **kwds )
def _create_tool_from_source( self, tool_source, **kwds ):
return create_tool_from_source( self.app, tool_source, **kwds)
def get_tool_components( self, tool_id, tool_version=None, get_loaded_tools_by_lineage=False, set_selected=False ):
"""
+1 -1
View File
@@ -61,7 +61,7 @@ def test_on_text_for_names():
class DefaultToolActionTestCase( unittest.TestCase, tools_support.UsesApp, tools_support.UsesTools ):
def setUp( self ):
self.setup_app( mock_model=False )
self.setup_app( )
history = model.History()
self.history = history
self.trans = MockTrans(
@@ -17,7 +17,7 @@ DEFAULT_EXTRA_NAME = "test1"
class CollectPrimaryDatasetsTestCase( unittest.TestCase, tools_support.UsesApp, tools_support.UsesTools ):
def setUp( self ):
self.setup_app( mock_model=False )
self.setup_app( )
object_store = MockObjectStore()
self.app.object_store = object_store
self._init_tool( tools_support.SIMPLE_TOOL_CONTENTS )
+3 -2
View File
@@ -134,8 +134,9 @@ class ToolExecutionTestCase( TestCase, tools_support.UsesApp, tools_support.Uses
hda.dataset = galaxy.model.Dataset()
hda.dataset.state = 'ok'
self.trans.sa_session.model_objects[ galaxy.model.HistoryDatasetAssociation ][ id ] = hda
self.trans.sa_session.add( hda )
self.history.datasets.append( hda )
self.trans.sa_session.flush()
return hda
def __add_collection_dataset( self, id, collection_type="paired", *hdas ):
@@ -199,7 +200,7 @@ class MockTrans( object ):
self.app = app
self.history = history
self.user = None
self.history._active_datasets_and_roles = [hda for hda in self.app.model.context.model_objects[ galaxy.model.HistoryDatasetAssociation ] if hda.active and hda.history == history]
self.history._active_datasets_and_roles = [hda for hda in self.app.model.context.query( galaxy.model.HistoryDatasetAssociation ).all() if hda.active and hda.history == history]
self.workflow_building_mode = False
self.webapp = Bunch( name="galaxy" )
self.sa_session = self.app.model.context
+1 -1
View File
@@ -10,7 +10,7 @@ from galaxy.util import bunch
class BaseParameterTestCase( TestCase, tools_support.UsesApp ):
def setUp(self):
self.setup_app( mock_model=False )
self.setup_app( )
self.mock_tool = bunch.Bunch(
app=self.app,
tool_type="default",
+1 -1
View File
@@ -56,7 +56,7 @@ class BaseToolBoxTestCase( unittest.TestCase, tools_support.UsesApp, tools_supp
def setUp( self ):
self.reindexed = False
self.setup_app( mock_model=False )
self.setup_app( )
install_model = mapping.init( "sqlite:///:memory:", create_tables=True )
self.app.tool_cache = ToolCache()
self.app.install_model = install_model
+11 -82
View File
@@ -7,18 +7,18 @@ import os.path
import shutil
import string
import tempfile
from collections import defaultdict
from unittest_utils import galaxy_mock
import galaxy.datatypes.registry
import galaxy.model
from galaxy.jobs import NoopQueue
from galaxy.model import mapping
from galaxy.tools import Tool
from galaxy.tools.deps.containers import NullContainerFinder
from galaxy.tools import create_tool_from_source
from galaxy.tools.parser import get_tool_source
from galaxy.util.bunch import Bunch
from galaxy.util.dbkeys import GenomeBuilds
from galaxy.web.security import SecurityHelper
datatypes_registry = galaxy.datatypes.registry.Registry()
datatypes_registry.load_datatypes()
@@ -27,9 +27,11 @@ galaxy.model.set_datatypes_registry(datatypes_registry)
class UsesApp( object ):
def setup_app( self, mock_model=True ):
def setup_app( self ):
self.test_directory = tempfile.mkdtemp()
self.app = MockApp( self.test_directory, mock_model=mock_model )
self.app = galaxy_mock.MockApp( )
self.app.config.new_file_path = os.path.join(self.test_directory, "new_files")
self.app.config.admin_users = "mary@example.com"
def tear_down_app( self ):
shutil.rmtree( self.test_directory )
@@ -90,7 +92,7 @@ class UsesTools( object ):
def __setup_tool( self ):
tool_source = get_tool_source( self.tool_file )
try:
self.tool = Tool( self.tool_file, tool_source, self.app )
self.tool = create_tool_from_source(self.app, tool_source, config_file=self.tool_file)
except Exception:
self.tool = None
if getattr( self, "tool_action", None and self.tool):
@@ -101,79 +103,6 @@ class UsesTools( object ):
open( self.tool_file, "w" ).write( contents )
class MockApp( object ):
def __init__( self, test_directory, mock_model=True ):
# The following line is needed in order to create
# HistoryDatasetAssociations - ideally the model classes would be
# usable without the ORM infrastructure in place.
in_memomry_model = mapping.init( "/tmp", "sqlite:///:memory:", create_tables=True )
self.datatypes_registry = Bunch(
integrated_datatypes_configs='/galaxy/integrated_datatypes_configs.xml',
get_datatype_by_extension=lambda ext: Bunch(),
)
self.config = Bunch(
outputs_to_working_directory=False,
commands_in_new_shell=True,
new_file_path=os.path.join(test_directory, "new_files"),
tool_data_path=os.path.join(test_directory, "tools"),
root=os.path.join(test_directory, "galaxy"),
admin_users="mary@example.com",
len_file_path=os.path.join( 'tool-data', 'shared', 'ucsc', 'chrom' ),
builds_file_path=os.path.join( 'tool-data', 'shared', 'ucsc', 'builds.txt.sample' ),
migrated_tools_config=os.path.join(test_directory, "migrated_tools_conf.xml"),
server_name="test_server",
preserve_python_environment="always",
)
# Setup some attributes for downstream extension by specific tests.
self.job_config = Bunch(
dynamic_params=None,
)
# Two ways to handle model layer, one is to stub out some objects that
# have an interface similar to real model (mock_model) and can keep
# track of 'persisted' objects in a map. The other is to use a real
# sqlalchemy layer but target an in memory database. Depending on what
# is being tested.
if mock_model:
# Create self.model to mimic app.model.
self.model = Bunch( context=MockContext() )
for module_member_name in dir( galaxy.model ):
module_member = getattr(galaxy.model, module_member_name)
if type( module_member ) == type:
self.model[ module_member_name ] = module_member
else:
self.model = in_memomry_model
self.genome_builds = GenomeBuilds( self )
self.toolbox = None
self.object_store = None
self.security = SecurityHelper(id_secret="testing")
from galaxy.security import GalaxyRBACAgent
self.job_queue = NoopQueue()
self.security_agent = GalaxyRBACAgent( self.model )
self.tool_data_tables = {}
self.dataset_collections_service = None
self.container_finder = NullContainerFinder()
self.name = "galaxy"
self._toolbox_lock = MockLock()
def wait_for_toolbox_reload(self, toolbox):
# TODO: If the tpm test case passes, does the operation really
# need to wait.
return True
class MockLock( object ):
def __enter__(self):
pass
def __exit__(self, type, value, traceback):
pass
class MockContext(object):
def __init__(self, model_objects=None):
+35
View File
@@ -11,9 +11,12 @@ from galaxy import (
quota
)
from galaxy.datatypes import registry
from galaxy.jobs import NoopQueue
from galaxy.managers import tags
from galaxy.model import mapping
from galaxy.tools.deps.containers import NullContainerFinder
from galaxy.util.bunch import Bunch
from galaxy.util.dbkeys import GenomeBuilds
from galaxy.web import security
@@ -63,22 +66,47 @@ class MockApp( object ):
self.tag_handler = tags.GalaxyTagManager( self.model.context )
self.quota_agent = quota.QuotaAgent( self.model )
self.init_datatypes()
self.job_config = Bunch(
dynamic_params=None,
)
self.tool_data_tables = {}
self.dataset_collections_service = None
self.container_finder = NullContainerFinder()
self._toolbox_lock = MockLock()
self.genome_builds = GenomeBuilds( self )
self.job_queue = NoopQueue()
def init_datatypes( self ):
datatypes_registry = registry.Registry()
datatypes_registry.load_datatypes()
model.set_datatypes_registry( datatypes_registry )
self.datatypes_registry = datatypes_registry
def wait_for_toolbox_reload(self, toolbox):
# TODO: If the tpm test case passes, does the operation really
# need to wait.
return True
class MockLock( object ):
def __enter__(self):
pass
def __exit__(self, type, value, traceback):
pass
class MockAppConfig( Bunch ):
def __init__( self, root=None, **kwargs ):
Bunch.__init__( self, **kwargs )
root = root or '/tmp'
self.security = security.SecurityHelper( id_secret='bler' )
self.use_remote_user = kwargs.get( 'use_remote_user', False )
self.file_path = '/tmp'
self.jobs_directory = '/tmp'
self.new_file_path = '/tmp'
self.tool_data_path = '/tmp'
self.object_store_config_file = ''
self.object_store = 'disk'
@@ -93,6 +121,13 @@ class MockAppConfig( Bunch ):
self.umask = 0o77
# Follow two required by GenomeBuilds
self.len_file_path = os.path.join( 'tool-data', 'shared', 'ucsc', 'chrom' )
self.builds_file_path = os.path.join( 'tool-data', 'shared', 'ucsc', 'builds.txt.sample' )
self.migrated_tools_config = "/tmp/migrated_tools_conf.xml"
self.preserve_python_environment = "always"
# set by MockDir
self.root = root