def test_create_userdata_w_profile(): randomstr = 'test-' + create_jobid() s3 = boto3.client('s3') s3.put_object(Body='haha'.encode('utf-8'), Bucket='tibanna-output', Key=randomstr) input_dict = { 'args': { 'input_files': { 'input_file': { 'bucket_name': 'tibanna-output', 'object_key': randomstr } }, 'output_S3_bucket': 'somebucket', 'app_name': 'md5', 'cwl_main_filename': 'md5.cwl', 'cwl_directory_url': 'someurl' }, 'config': { 'log_bucket': 'tibanna-output' }, 'jobid': 'myjobid' } execution = Execution(input_dict) profile = {'access_key': 'haha', 'secret_key': 'lala'} userdata = execution.create_userdata(profile=profile) print(userdata) assert userdata assert '-a haha -s lala' in userdata # cleanup afterwards s3.delete_objects(Bucket='tibanna-output', Delete={'Objects': [{ 'Key': randomstr }]})
def test_launch_args(): """test creating launch arguments - also test spot_instance""" jobid = create_jobid() log_bucket = 'tibanna-output' input_dict = { 'args': { 'output_S3_bucket': 'somebucket', 'cwl_main_filename': 'md5.cwl', 'cwl_directory_url': 'someurl' }, 'config': { 'log_bucket': log_bucket, 'mem': 1, 'cpu': 1, 'spot_instance': True }, 'jobid': jobid } execution = Execution(input_dict) # userdata is required before launch_args is created execution.userdata = execution.create_userdata() launch_args = execution.launch_args print(launch_args) assert launch_args assert 't3.micro' in str(launch_args) assert 'InstanceMarketOptions' in str(launch_args)
def test_create_run_json_dict(): randomstr = 'test-' + create_jobid() s3 = boto3.client('s3') s3.put_object(Body='haha'.encode('utf-8'), Bucket='tibanna-output', Key=randomstr) input_dict = { 'args': { 'input_files': { 'input_file': { 'bucket_name': 'tibanna-output', 'object_key': randomstr } }, 'output_S3_bucket': 'somebucket', 'app_name': 'md5', 'cwl_main_filename': 'md5.cwl', 'cwl_directory_url': 'someurl' }, 'config': { 'log_bucket': 'tibanna-output' } } execution = Execution(input_dict) runjson = execution.create_run_json_dict() assert runjson # cleanup afterwards s3.delete_objects(Bucket='tibanna-output', Delete={'Objects': [{ 'Key': randomstr }]})
def test_ec2_exception_coordinator9(): """ec2 exceptions with 'other_instance_types' with both instance_type and mem/cpu specified""" jobid = create_jobid() log_bucket = 'tibanna-output' input_dict = { 'args': { 'output_S3_bucket': 'somebucket', 'cwl_main_filename': 'md5.cwl', 'cwl_directory_url': 'someurl' }, 'config': { 'log_bucket': log_bucket, 'mem': 2, 'cpu': 1, 'behavior_on_capacity_limit': 'other_instance_types' }, 'jobid': jobid } execution = Execution(input_dict, dryrun=True) assert execution.cfg.instance_type == 't3.small' execution.userdata = execution.create_userdata() res = execution.ec2_exception_coordinator(fun)() assert res == 'continue' assert execution.cfg.instance_type == 't2.small'
def test_upload_run_json(): jobid = create_jobid() log_bucket = 'tibanna-output' input_dict = { 'args': { 'output_S3_bucket': 'somebucket', 'cwl_main_filename': 'md5.cwl', 'cwl_directory_url': 'someurl' }, 'config': { 'log_bucket': log_bucket, 'mem': 1, 'cpu': 1 }, 'jobid': jobid } somejson = {'haha': 'lala'} execution = Execution(input_dict) execution.upload_run_json(somejson) s3 = boto3.client('s3') res = s3.get_object(Bucket=log_bucket, Key=jobid + '.run.json') assert res # clean up afterwards s3.delete_objects(Bucket=log_bucket, Delete={'Objects': [{ 'Key': jobid + '.run.json' }]})
def test_check_dependency_failed(): job_statuses = {'running_jobs': ['jid1'], 'failed_jobs': ['jid2']} with mock.patch('tibanna.job.Jobs.status', return_value=job_statuses): with pytest.raises(DependencyFailedException) as exec_info: Execution.check_dependency(job_id=['jid1', 'jid2']) assert 'failed' in str(exec_info.value) assert 'jid1' not in str(exec_info.value) assert 'jid2' in str(exec_info.value)
def test_get_input_size_in_bytes_with_secondary_files(): randomstr, randomstr_1, randomstr_2 = 'test-' + create_jobid( ), 'test-' + create_jobid(), 'test-' + create_jobid() s3 = boto3.client('s3') s3.put_object(Body='haha'.encode('utf-8'), Bucket='tibanna-output', Key=randomstr) s3.put_object(Body='fooooooo'.encode('utf-8'), Bucket='tibanna-output', Key=randomstr_1) s3.put_object(Body='pippo'.encode('utf-8'), Bucket='tibanna-output', Key=randomstr_2) input_dict = { 'args': { 'input_files': { 'input_file': { 'bucket_name': 'tibanna-output', 'object_key': randomstr } }, 'secondary_files': { 'input_file': { 'bucket_name': 'tibanna-output', 'object_key': [randomstr_1, randomstr_2] } }, 'output_S3_bucket': 'somebucket', 'app_name': 'md5', 'cwl_main_filename': 'md5.cwl', 'cwl_directory_url': 'someurl' }, 'config': { 'log_bucket': 'tibanna-output' } } execution = Execution(input_dict) execution.input_size_in_bytes = execution.get_input_size_in_bytes() assert execution.total_input_size_in_gb == 1.5832483768463135E-8 # cleanup afterwards s3.delete_objects(Bucket='tibanna-output', Delete={ 'Objects': [{ 'Key': randomstr }, { 'Key': randomstr_1 }, { 'Key': randomstr_2 }] })
def test_execution_mem_cpu(): """mem and cpu are provided but not app_name or instance_type, which should be fine. language is snakemake this time""" input_dict = { 'args': { 'input_files': {}, 'language': 'snakemake', 'output_S3_bucket': 'somebucket', 'snakemake_main_filename': 'Snakefile', 'snakemake_directory_url': 'someurl', 'command': 'snakemake', 'container_image': 'quay.io/snakemake/snakemake' }, 'config': { 'log_bucket': 'tibanna-output', 'mem': 1, 'cpu': 1 } } execution = Execution(input_dict) unicorn_dict = execution.input_dict assert len(execution.instance_type_list) == 10 assert 'args' in unicorn_dict assert 'config' in unicorn_dict assert 'instance_type' in unicorn_dict['config'] assert unicorn_dict['config']['instance_type'] == 't3.micro'
def test_execution_benchmark_app_name_but_w_nonmatching_inputarg( run_task_awsem_event_wdl_md5_benchmark_error): cfg = Config(**run_task_awsem_event_wdl_md5_benchmark_error['config']) assert cfg.use_benchmark == True with pytest.raises(Exception) as exec_info: execution = Execution(run_task_awsem_event_wdl_md5_benchmark_error) assert 'Benchmarking not working' in str(exec_info.value)
def test_launch_and_get_instance_id(): """test dryrun of ec2 launch""" jobid = create_jobid() log_bucket = 'tibanna-output' input_dict = { 'args': { 'output_S3_bucket': 'somebucket', 'cwl_main_filename': 'md5.cwl', 'cwl_directory_url': 'someurl' }, 'config': { 'log_bucket': log_bucket, 'mem': 1, 'cpu': 1, 'spot_instance': True }, 'jobid': jobid } execution = Execution(input_dict, dryrun=True) # userdata is required before launch_args is created execution.userdata = execution.create_userdata() with pytest.raises(Exception) as ex: execution.launch_and_get_instance_id() assert 'Request would have succeeded, but DryRun flag is set' in str( ex.value)
def test_update_config_ebs_size2(): """ebs_size is given as the 'x' format. The total estimated ebs_size is larger than 10""" randomstr = 'test-' + create_jobid() s3 = boto3.client('s3') s3.put_object(Body='haha'.encode('utf-8'), Bucket='tibanna-output', Key=randomstr) input_dict = { 'args': { 'input_files': { 'input_file': { 'bucket_name': 'tibanna-output', 'object_key': randomstr } }, 'output_S3_bucket': 'somebucket', 'app_name': 'md5', 'cwl_main_filename': 'md5.cwl', 'cwl_directory_url': 'someurl' }, 'config': { 'log_bucket': 'tibanna-output', 'ebs_size': '5000000000x' } } execution = Execution(input_dict) execution.input_size_in_bytes = execution.get_input_size_in_bytes() execution.update_config_ebs_size() assert execution.cfg.ebs_size == 19 # cleanup afterwards s3.delete_objects(Bucket='tibanna-output', Delete={'Objects': [{ 'Key': randomstr }]})
def test_ec2_exception_coordinator6(): """ec2 exceptions with 'retry_without_spot'""" jobid = create_jobid() log_bucket = 'tibanna-output' input_dict = { 'args': { 'output_S3_bucket': 'somebucket', 'cwl_main_filename': 'md5.cwl', 'cwl_directory_url': 'someurl' }, 'config': { 'log_bucket': log_bucket, 'instance_type': 't2.micro', 'spot_instance': True, 'behavior_on_capacity_limit': 'retry_without_spot' }, 'jobid': jobid } execution = Execution(input_dict, dryrun=True) execution.userdata = execution.create_userdata() res = execution.ec2_exception_coordinator(fun)() assert res == 'continue' assert execution.cfg.spot_instance is False # changed to non-spot assert execution.cfg.behavior_on_capacity_limit == 'fail' # changed to non-spot with pytest.raises(EC2InstanceLimitException) as exec_info: res = execution.ec2_exception_coordinator(fun)() # this time, it fails assert exec_info
def test_execution_missing_field6(): """language is shell but container_image is missing""" input_dict = { 'args': { 'input_files': {}, 'language': 'shell', 'output_S3_bucket': 'somebucket', 'command': 'some command' }, 'config': { 'log_bucket': 'tibanna-output', 'mem': 1, 'cpu': 1 } } with pytest.raises(MissingFieldInInputJsonException) as ex: Execution(input_dict) assert ex assert 'container_image' in str(ex.value)
def test_execution_missing_field5(): """language is snakemake but command is missing""" input_dict = { 'args': { 'input_files': {}, 'language': 'snakemake', 'output_S3_bucket': 'somebucket', 'snakemake_main_filename': 'Snakefile', 'snakemake_directory_url': 'someurl', 'container_image': 'quay.io/snakemake/snakemake' }, 'config': { 'log_bucket': 'tibanna-output', 'mem': 1, 'cpu': 1 } } with pytest.raises(MissingFieldInInputJsonException) as ex: Execution(input_dict) assert ex assert 'command' in str(ex.value)
def test_execution_benchmark(): randomstr = 'test-' + create_jobid() s3 = boto3.client('s3') s3.put_object(Body='haha'.encode('utf-8'), Bucket='tibanna-output', Key=randomstr) input_dict = { 'args': { 'input_files': { 'input_file': { 'bucket_name': 'tibanna-output', 'object_key': randomstr } }, 'output_S3_bucket': 'somebucket', 'app_name': 'md5', 'cwl_main_filename': 'md5.cwl', 'cwl_directory_url': 'someurl' }, 'config': { 'log_bucket': 'tibanna-output' } } execution = Execution(input_dict) unicorn_dict = execution.input_dict print(unicorn_dict) assert 'args' in unicorn_dict assert 'config' in unicorn_dict assert 'instance_type' in unicorn_dict['config'] assert unicorn_dict['config']['instance_type'] == 't3.micro' assert unicorn_dict['config']['ebs_size'] == 10 # cleanup afterwards s3.delete_objects(Bucket='tibanna-output', Delete={'Objects': [{ 'Key': randomstr }]})
def test_ec2_exception_coordinator2(): """ec2 limit exceptions with 'fail'""" jobid = create_jobid() log_bucket = 'tibanna-output' input_dict = { 'args': { 'output_S3_bucket': 'somebucket', 'cwl_main_filename': 'md5.cwl', 'cwl_directory_url': 'someurl' }, 'config': { 'log_bucket': log_bucket, 'instance_type': 'c5.4xlarge', 'spot_instance': True }, 'jobid': jobid } execution = Execution(input_dict, dryrun=True) execution.userdata = execution.create_userdata() with pytest.raises(EC2InstanceLimitException) as exec_info: execution.ec2_exception_coordinator(fun)() assert exec_info
def test_ec2_exception_coordinator7(): """ec2 exceptions with 'retry_without_spot' without spot instance""" jobid = create_jobid() log_bucket = 'tibanna-output' input_dict = { 'args': { 'output_S3_bucket': 'somebucket', 'cwl_main_filename': 'md5.cwl', 'cwl_directory_url': 'someurl' }, 'config': { 'log_bucket': log_bucket, 'instance_type': 't2.micro', 'behavior_on_capacity_limit': 'retry_without_spot' }, 'jobid': jobid } execution = Execution(input_dict, dryrun=True) assert execution.cfg.spot_instance is False execution.userdata = execution.create_userdata() with pytest.raises(Exception) as exec_info: execution.ec2_exception_coordinator(fun)() assert "'retry_without_spot' works only with 'spot_instance'" in str( exec_info.value)
def test_ec2_exception_coordinator5(): """ec2 exceptions with 'other_instance_types' but had only one option""" jobid = create_jobid() log_bucket = 'tibanna-output' input_dict = { 'args': { 'output_S3_bucket': 'somebucket', 'cwl_main_filename': 'md5.cwl', 'cwl_directory_url': 'someurl' }, 'config': { 'log_bucket': log_bucket, 'instance_type': 't2.micro', 'spot_instance': True, 'behavior_on_capacity_limit': 'other_instance_types' }, 'jobid': jobid } execution = Execution(input_dict, dryrun=True) assert execution.cfg.instance_type == 't2.micro' execution.userdata = execution.create_userdata() with pytest.raises(EC2InstanceLimitException) as exec_info: execution.ec2_exception_coordinator(fun)() assert 'No more instance type available' in str(exec_info.value)
def test_execution_benchmark_app_name_but_w_instance_type_ebs( run_task_awsem_event_wdl_md5_do_not_use_benchmark): execution = Execution(run_task_awsem_event_wdl_md5_do_not_use_benchmark)