Job mapping unit tests.

A bunch of unit tests for galaxy.jobs.mapper and galaxy.jobs.rule_helper testing various aspects of static and dynamic job mapping and the utility class (RuleHelper) that can be supplied to dynamic job rules.
This commit is contained in:
John Chilton
2014-08-17 16:38:34 -04:00
parent 9a631f6cf2
commit 33bcfa173a
5 changed files with 278 additions and 0 deletions
+129
View File
@@ -0,0 +1,129 @@
import jobs.test_rules
from galaxy.jobs.mapper import JobRunnerMapper
from galaxy.jobs import JobDestination
from galaxy.util import bunch
TOOL_JOB_DESTINATION = JobDestination()
DYNAMICALLY_GENERATED_DESTINATION = JobDestination()
def test_static_mapping():
mapper = __mapper()
assert mapper.get_job_destination( {} ) is TOOL_JOB_DESTINATION
def test_caching():
mapper = __mapper()
mapper.get_job_destination( {} )
mapper.get_job_destination( {} )
assert mapper.job_wrapper.tool.call_count == 1
def test_dynamic_mapping():
mapper = __mapper( __dynamic_destination( dict( function="upload" ) ) )
assert mapper.get_job_destination( {} ) is DYNAMICALLY_GENERATED_DESTINATION
assert mapper.job_config.rule_response == "local_runner"
def test_dynamic_mapping_priorities():
mapper = __mapper( __dynamic_destination( dict( function="tophat" ) ) )
assert mapper.get_job_destination( {} ) is DYNAMICALLY_GENERATED_DESTINATION
# Next line verifies we using definition in 20_instance.py instead of
# 10_site.py.
assert mapper.job_config.rule_response == "instance_dest_id"
def test_dynamic_mapping_defaults_to_tool_id_as_rule():
mapper = __mapper( __dynamic_destination( ) )
assert mapper.get_job_destination( {} ) is DYNAMICALLY_GENERATED_DESTINATION
assert mapper.job_config.rule_response == "tool1_dest_id"
def test_dynamic_mapping_function_parameters():
mapper = __mapper( __dynamic_destination( dict( function="check_rule_params" ) ) )
assert mapper.get_job_destination( {} ) is DYNAMICALLY_GENERATED_DESTINATION
assert mapper.job_config.rule_response == "all_passed"
def test_dynamic_mapping_resource_parameters():
mapper = __mapper( __dynamic_destination( dict( function="check_resource_params" ) ) )
assert mapper.get_job_destination( {} ) is DYNAMICALLY_GENERATED_DESTINATION
assert mapper.job_config.rule_response == "have_resource_params"
def __mapper( tool_job_destination=TOOL_JOB_DESTINATION ):
job_wrapper = MockJobWrapper( tool_job_destination )
job_config = MockJobConfig()
mapper = JobRunnerMapper(
job_wrapper,
{},
job_config
)
mapper.rules_module = jobs.test_rules
return mapper
def __dynamic_destination( params={} ):
return JobDestination( runner="dynamic", params=params )
class MockJobConfig( object ):
def __init__( self ):
self.rule_response = None
def get_destination( self, rep ):
# Called to transform dynamic job destination rule response
# from destination id/runner url into a dynamic job destination.
self.rule_response = rep
return DYNAMICALLY_GENERATED_DESTINATION
class MockJobWrapper( object ):
def __init__( self, tool_job_destination ):
self.tool = MockTool( tool_job_destination )
self.job_id = 12345
self.app = object()
def is_mock_job_wrapper( self ):
return True
def get_job(self):
def get_param_values( app, ignore_errors ):
assert app == self.app
return {
"threshold": 8,
"__job_resource": {
"__job_resource__select": "True",
"memory": "8gb"
}
}
return bunch.Bunch(
user=bunch.Bunch(
id=6789,
email="test@example.com"
),
get_param_values=get_param_values
)
class MockTool( object ):
def __init__( self, tool_job_destination ):
self.id = "testtoolshed/devteam/tool1/23abcd13123"
self.call_count = 0
self.tool_job_destination = tool_job_destination
self.all_ids = [ "testtoolshed/devteam/tool1/23abcd13123", "tool1" ]
def get_job_destination( self, params ):
self.call_count += 1
return self.tool_job_destination
def is_mock_tool( self ):
return True
+98
View File
@@ -0,0 +1,98 @@
from galaxy.util import bunch
from galaxy import model
from galaxy.model import mapping
from galaxy.jobs.rule_helper import RuleHelper
USER_EMAIL_1 = "u1@example.com"
USER_EMAIL_2 = "u2@example.com"
USER_EMAIL_3 = "u3@example.com"
def test_job_count():
rule_helper = __rule_helper()
__assert_job_count_is( 0, rule_helper )
__setup_fixtures( rule_helper.app )
# Test raw counts for users...
__assert_job_count_is( 7, rule_helper, for_user_email=USER_EMAIL_1 )
__assert_job_count_is( 2, rule_helper, for_user_email=USER_EMAIL_2 )
__assert_job_count_is( 0, rule_helper, for_user_email=USER_EMAIL_3 )
# Test desitnation counts
__assert_job_count_is( 2, rule_helper, for_destination="local" )
__assert_job_count_is( 7, rule_helper, for_destination="cluster1" )
# Test per user destination counts
__assert_job_count_is( 5, rule_helper, for_destination="cluster1", for_user_email=USER_EMAIL_1 )
__assert_job_count_is( 2, rule_helper, for_destination="local", for_user_email=USER_EMAIL_1 )
__assert_job_count_is( 2, rule_helper, for_destination="cluster1", for_user_email=USER_EMAIL_2 )
__assert_job_count_is( 0, rule_helper, for_destination="local", for_user_email=USER_EMAIL_2 )
# Test per user, per state destination counts
__assert_job_count_is( 3, rule_helper, for_destination="cluster1", for_user_email=USER_EMAIL_1, for_job_states=[ "queued" ] )
__assert_job_count_is( 2, rule_helper, for_destination="cluster1", for_user_email=USER_EMAIL_1, for_job_states=[ "running" ] )
__assert_job_count_is( 0, rule_helper, for_destination="cluster1", for_user_email=USER_EMAIL_1, for_job_states=[ "error" ] )
__assert_job_count_is( 5, rule_helper, for_destination="cluster1", for_user_email=USER_EMAIL_1, for_job_states=[ "queued", "running", "error" ] )
def __assert_job_count_is( expected_count, rule_helper, **kwds ):
acutal_count = rule_helper.job_count( **kwds )
if expected_count != acutal_count:
template = "Expected job count %d, actual job count %s for params %s"
raise AssertionError( template % ( expected_count, acutal_count, kwds ) )
def __setup_fixtures( app ):
# user1 has 3 jobs queued and 2 jobs running on cluster1 and one queued and
# on running job on local. user2 has a queued and running job on the cluster.
# user3 has no jobs.
user1 = model.User( email=USER_EMAIL_1, password="pass1" )
user2 = model.User( email=USER_EMAIL_2, password="pass2" )
user3 = model.User( email=USER_EMAIL_2, password="pass2" )
app.add( user1, user2, user3 )
app.add( __new_job( user=user1, destination_id="cluster1", state="queued" ) )
app.add( __new_job( user=user1, destination_id="cluster1", state="queued" ) )
app.add( __new_job( user=user1, destination_id="cluster1", state="queued" ) )
app.add( __new_job( user=user1, destination_id="cluster1", state="running" ) )
app.add( __new_job( user=user1, destination_id="cluster1", state="running" ) )
app.add( __new_job( user=user1, destination_id="local", state="queued" ) )
app.add( __new_job( user=user1, destination_id="local", state="running" ) )
app.add( __new_job( user=user2, destination_id="cluster1", state="queued" ) )
app.add( __new_job( user=user2, destination_id="cluster1", state="running" ) )
def __rule_helper():
app = MockApp()
rule_helper = RuleHelper( app )
return rule_helper
def __new_job( **kwds ):
job = model.Job()
for key, value in kwds.items():
setattr( job, key, value )
return job
class MockApp( object ):
def __init__( self ):
self.config = bunch.Bunch( )
self.model = mapping.init(
"/tmp",
"sqlite:///:memory:",
create_tables=True
)
def add( self, *args ):
for arg in args:
self.model.context.add( arg )
self.model.context.flush()
+45
View File
@@ -0,0 +1,45 @@
def upload():
return 'local_runner'
def tophat():
return 'site_dest_id'
def tool1():
# tool1 is id to test tool mocked out in test_mapper.py, without specify
# function name in dynamic destination - this function should be used by
# default.
return 'tool1_dest_id'
def check_rule_params(
job_id,
tool,
tool_id,
job_wrapper,
rule_helper,
app,
job,
user,
user_email,
):
assert job_id == 12345
assert tool.is_mock_tool()
assert tool_id == "testtoolshed/devteam/tool1/23abcd13123"
assert job_wrapper.is_mock_job_wrapper()
assert app == job_wrapper.app
assert rule_helper is not None
assert job.user == user
assert user.id == 6789
assert user_email == "test@example.com"
return "all_passed"
def check_resource_params( resource_params ):
assert resource_params["memory"] == "8gb"
return "have_resource_params"
+6
View File
@@ -0,0 +1,6 @@
def tophat():
# This should override definition in 10_site.py
return 'instance_dest_id'