8 from schema_salad.ref_resolver import Loader
10 from schema_salad.ref_resolver import Loader
12 if not os.getenv('ARVADOS_DEBUG'):
13 logging.getLogger('arvados.cwl-runner').setLevel(logging.WARN)
14 logging.getLogger('arvados.arv-run').setLevel(logging.WARN)
17 class TestJob(unittest.TestCase):
19 # The test passes no builder.resources
20 # Hence the default resources will apply: {'cores': 1, 'ram': 1024, 'outdirSize': 1024, 'tmpdirSize': 1024}
22 runner = mock.MagicMock()
23 runner.project_uuid = "zzzzz-8i9sb-zzzzzzzzzzzzzzz"
24 runner.ignore_docker_for_reuse = False
25 document_loader, avsc_names, schema_metadata, metaschema_loader = cwltool.process.get_schema("draft-3")
31 "arguments": [{"valueFrom": "$(runtime.outdir)"}]
33 make_fs_access=functools.partial(arvados_cwl.CollectionFsAccess, api_client=runner.api)
34 arvtool = arvados_cwl.ArvadosCommandTool(runner, tool, work_api="jobs", avsc_names=avsc_names,
35 basedir="", make_fs_access=make_fs_access, loader=Loader({}))
36 arvtool.formatgraph = None
37 for j in arvtool.job({}, mock.MagicMock(), basedir="", make_fs_access=make_fs_access):
39 runner.api.jobs().create.assert_called_with(
41 'owner_uuid': 'zzzzz-8i9sb-zzzzzzzzzzzzzzz',
42 'runtime_constraints': {},
43 'script_parameters': {
45 'task.env': {'HOME': '$(task.outdir)', 'TMPDIR': '$(task.tmpdir)'},
46 'command': ['ls', '$(task.outdir)']
49 'script_version': 'master',
50 'minimum_script_version': '9e5b98e8f5f4727856b53447191f9c06e3da2ba6',
51 'repository': 'arvados',
52 'script': 'crunchrunner',
53 'runtime_constraints': {
54 'docker_image': 'arvados/jobs',
55 'min_cores_per_node': 1,
56 'min_ram_mb_per_node': 1024,
57 'min_scratch_mb_per_node': 2048 # tmpdirSize + outdirSize
61 filters=[['repository', '=', 'arvados'],
62 ['script', '=', 'crunchrunner'],
63 ['script_version', 'in git', '9e5b98e8f5f4727856b53447191f9c06e3da2ba6'],
64 ['docker_image_locator', 'in docker', 'arvados/jobs']]
67 # The test passes some fields in builder.resources
68 # For the remaining fields, the defaults will apply: {'cores': 1, 'ram': 1024, 'outdirSize': 1024, 'tmpdirSize': 1024}
69 def test_resource_requirements(self):
70 runner = mock.MagicMock()
71 runner.project_uuid = "zzzzz-8i9sb-zzzzzzzzzzzzzzz"
72 runner.ignore_docker_for_reuse = False
73 document_loader, avsc_names, schema_metadata, metaschema_loader = cwltool.process.get_schema("draft-3")
79 "class": "ResourceRequirement",
86 make_fs_access=functools.partial(arvados_cwl.CollectionFsAccess, api_client=runner.api)
87 arvtool = arvados_cwl.ArvadosCommandTool(runner, tool, work_api="jobs", avsc_names=avsc_names,
88 make_fs_access=make_fs_access, loader=Loader({}))
89 arvtool.formatgraph = None
90 for j in arvtool.job({}, mock.MagicMock(), basedir="", make_fs_access=make_fs_access):
92 runner.api.jobs().create.assert_called_with(
94 'owner_uuid': 'zzzzz-8i9sb-zzzzzzzzzzzzzzz',
95 'runtime_constraints': {},
96 'script_parameters': {
98 'task.env': {'HOME': '$(task.outdir)', 'TMPDIR': '$(task.tmpdir)'},
102 'script_version': 'master',
103 'minimum_script_version': '9e5b98e8f5f4727856b53447191f9c06e3da2ba6',
104 'repository': 'arvados',
105 'script': 'crunchrunner',
106 'runtime_constraints': {
107 'docker_image': 'arvados/jobs',
108 'min_cores_per_node': 3,
109 'min_ram_mb_per_node': 3000,
110 'min_scratch_mb_per_node': 5024 # tmpdirSize + outdirSize
114 filters=[['repository', '=', 'arvados'],
115 ['script', '=', 'crunchrunner'],
116 ['script_version', 'in git', '9e5b98e8f5f4727856b53447191f9c06e3da2ba6'],
117 ['docker_image_locator', 'in docker', 'arvados/jobs']])
119 @mock.patch("arvados.collection.Collection")
120 def test_done(self, col):
121 api = mock.MagicMock()
123 runner = mock.MagicMock()
125 runner.project_uuid = "zzzzz-8i9sb-zzzzzzzzzzzzzzz"
126 runner.num_retries = 0
127 runner.ignore_docker_for_reuse = False
129 col().open.return_value = []
130 api.collections().list().execute.side_effect = ({"items": []},
131 {"items": [{"manifest_text": "XYZ"}]})
133 arvjob = arvados_cwl.ArvadosJob(runner)
134 arvjob.name = "testjob"
135 arvjob.builder = mock.MagicMock()
136 arvjob.output_callback = mock.MagicMock()
137 arvjob.collect_outputs = mock.MagicMock()
141 "output": "99999999999999999999999999999993+99",
142 "log": "99999999999999999999999999999994+99",
143 "uuid": "zzzzz-8i9sb-zzzzzzzzzzzzzzz"
146 api.collections().list.assert_has_calls([
148 mock.call(filters=[['owner_uuid', '=', 'zzzzz-8i9sb-zzzzzzzzzzzzzzz'],
149 ['portable_data_hash', '=', '99999999999999999999999999999993+99'],
150 ['name', '=', 'Output 9999999 of testjob']]),
151 mock.call().execute(num_retries=0),
152 mock.call(limit=1, filters=[['portable_data_hash', '=', '99999999999999999999999999999993+99']],
153 select=['manifest_text']),
154 mock.call().execute(num_retries=0)])
156 api.collections().create.assert_called_with(
157 ensure_unique_name=True,
158 body={'portable_data_hash': '99999999999999999999999999999993+99',
159 'manifest_text': 'XYZ',
160 'owner_uuid': 'zzzzz-8i9sb-zzzzzzzzzzzzzzz',
161 'name': 'Output 9999999 of testjob'})
163 @mock.patch("arvados.collection.Collection")
164 def test_done_use_existing_collection(self, col):
165 api = mock.MagicMock()
167 runner = mock.MagicMock()
169 runner.project_uuid = "zzzzz-8i9sb-zzzzzzzzzzzzzzz"
170 runner.num_retries = 0
172 col().open.return_value = []
173 api.collections().list().execute.side_effect = ({"items": [{"uuid": "zzzzz-4zz18-zzzzzzzzzzzzzz2"}]},)
175 arvjob = arvados_cwl.ArvadosJob(runner)
176 arvjob.name = "testjob"
177 arvjob.builder = mock.MagicMock()
178 arvjob.output_callback = mock.MagicMock()
179 arvjob.collect_outputs = mock.MagicMock()
183 "output": "99999999999999999999999999999993+99",
184 "log": "99999999999999999999999999999994+99",
185 "uuid": "zzzzz-8i9sb-zzzzzzzzzzzzzzz"
188 api.collections().list.assert_has_calls([
190 mock.call(filters=[['owner_uuid', '=', 'zzzzz-8i9sb-zzzzzzzzzzzzzzz'],
191 ['portable_data_hash', '=', '99999999999999999999999999999993+99'],
192 ['name', '=', 'Output 9999999 of testjob']]),
193 mock.call().execute(num_retries=0)])
195 self.assertFalse(api.collections().create.called)