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 TestContainer(unittest.TestCase):
19 # The test passes no builder.resources
20 # Hence the default resources will apply: {'cores': 1, 'ram': 1024, 'outdirSize': 1024, 'tmpdirSize': 1024}
21 @mock.patch("arvados.commands.keepdocker.list_images_in_arv")
22 def test_run(self, keepdocker):
23 for enable_reuse in (True, False):
24 runner = mock.MagicMock()
25 runner.project_uuid = "zzzzz-8i9sb-zzzzzzzzzzzzzzz"
26 runner.ignore_docker_for_reuse = False
28 keepdocker.return_value = [("zzzzz-4zz18-zzzzzzzzzzzzzz3", "")]
29 runner.api.collections().get().execute.return_value = {
30 "portable_data_hash": "99999999999999999999999999999993+99"}
32 document_loader, avsc_names, schema_metadata, metaschema_loader = cwltool.process.get_schema("v1.0")
38 "arguments": [{"valueFrom": "$(runtime.outdir)"}]
40 make_fs_access=functools.partial(arvados_cwl.CollectionFsAccess, api_client=runner.api)
41 arvtool = arvados_cwl.ArvadosCommandTool(runner, tool, work_api="containers", avsc_names=avsc_names,
42 basedir="", make_fs_access=make_fs_access, loader=Loader({}))
43 arvtool.formatgraph = None
44 for j in arvtool.job({}, mock.MagicMock(), basedir="", name="test_run_"+str(enable_reuse),
45 make_fs_access=make_fs_access, tmpdir="/tmp"):
46 j.run(enable_reuse=enable_reuse)
47 runner.api.container_requests().create.assert_called_with(
50 'HOME': '/var/spool/cwl',
53 'name': 'test_run_'+str(enable_reuse),
54 'runtime_constraints': {
58 'use_existing': enable_reuse,
61 '/var/spool/cwl': {'kind': 'tmp'}
64 'owner_uuid': 'zzzzz-8i9sb-zzzzzzzzzzzzzzz',
65 'output_path': '/var/spool/cwl',
66 'container_image': '99999999999999999999999999999993+99',
67 'command': ['ls', '/var/spool/cwl'],
68 'cwd': '/var/spool/cwl'
71 # The test passes some fields in builder.resources
72 # For the remaining fields, the defaults will apply: {'cores': 1, 'ram': 1024, 'outdirSize': 1024, 'tmpdirSize': 1024}
73 @mock.patch("arvados.commands.keepdocker.list_images_in_arv")
74 def test_resource_requirements(self, keepdocker):
75 runner = mock.MagicMock()
76 runner.project_uuid = "zzzzz-8i9sb-zzzzzzzzzzzzzzz"
77 runner.ignore_docker_for_reuse = False
78 document_loader, avsc_names, schema_metadata, metaschema_loader = cwltool.process.get_schema("v1.0")
80 keepdocker.return_value = [("zzzzz-4zz18-zzzzzzzzzzzzzz3", "")]
81 runner.api.collections().get().execute.return_value = {
82 "portable_data_hash": "99999999999999999999999999999993+99"}
88 "class": "ResourceRequirement",
93 "class": "http://arvados.org/cwl#RuntimeConstraints",
96 "class": "http://arvados.org/cwl#APIRequirement",
98 "class": "http://arvados.org/cwl#PartitionRequirement",
103 make_fs_access=functools.partial(arvados_cwl.CollectionFsAccess, api_client=runner.api)
104 arvtool = arvados_cwl.ArvadosCommandTool(runner, tool, work_api="containers",
105 avsc_names=avsc_names, make_fs_access=make_fs_access,
107 arvtool.formatgraph = None
108 for j in arvtool.job({}, mock.MagicMock(), basedir="", name="test_resource_requirements",
109 make_fs_access=make_fs_access, tmpdir="/tmp"):
112 runner.api.container_requests().create.assert_called_with(
115 'HOME': '/var/spool/cwl',
118 'name': 'test_resource_requirements',
119 'runtime_constraints': {
122 'keep_cache_ram': 512,
124 'partition': ['blurb']
126 'use_existing': True,
129 '/var/spool/cwl': {'kind': 'tmp'}
131 'state': 'Committed',
132 'owner_uuid': 'zzzzz-8i9sb-zzzzzzzzzzzzzzz',
133 'output_path': '/var/spool/cwl',
134 'container_image': '99999999999999999999999999999993+99',
136 'cwd': '/var/spool/cwl'
139 @mock.patch("arvados.collection.Collection")
140 def test_done(self, col):
141 api = mock.MagicMock()
143 runner = mock.MagicMock()
145 runner.project_uuid = "zzzzz-8i9sb-zzzzzzzzzzzzzzz"
146 runner.num_retries = 0
147 runner.ignore_docker_for_reuse = False
149 col().open.return_value = []
150 api.collections().list().execute.side_effect = ({"items": []},
151 {"items": [{"manifest_text": "XYZ"}]})
153 arvjob = arvados_cwl.ArvadosContainer(runner)
154 arvjob.name = "testjob"
155 arvjob.builder = mock.MagicMock()
156 arvjob.output_callback = mock.MagicMock()
157 arvjob.collect_outputs = mock.MagicMock()
158 arvjob.successCodes = [0]
159 arvjob.outdir = "/var/spool/cwl"
163 "output": "99999999999999999999999999999993+99",
164 "log": "99999999999999999999999999999994+99",
165 "uuid": "zzzzz-8i9sb-zzzzzzzzzzzzzzz",
169 api.collections().list.assert_has_calls([
171 mock.call(filters=[['owner_uuid', '=', 'zzzzz-8i9sb-zzzzzzzzzzzzzzz'],
172 ['portable_data_hash', '=', '99999999999999999999999999999993+99'],
173 ['name', '=', 'Output 9999999 of testjob']]),
174 mock.call().execute(num_retries=0),
175 mock.call(limit=1, filters=[['portable_data_hash', '=', '99999999999999999999999999999993+99']],
176 select=['manifest_text']),
177 mock.call().execute(num_retries=0)])
179 api.collections().create.assert_called_with(
180 ensure_unique_name=True,
181 body={'portable_data_hash': '99999999999999999999999999999993+99',
182 'manifest_text': 'XYZ',
183 'owner_uuid': 'zzzzz-8i9sb-zzzzzzzzzzzzzzz',
184 'name': 'Output 9999999 of testjob'})
186 @mock.patch("arvados.collection.Collection")
187 def test_done_use_existing_collection(self, col):
188 api = mock.MagicMock()
190 runner = mock.MagicMock()
192 runner.project_uuid = "zzzzz-8i9sb-zzzzzzzzzzzzzzz"
193 runner.num_retries = 0
195 col().open.return_value = []
196 api.collections().list().execute.side_effect = ({"items": [{"uuid": "zzzzz-4zz18-zzzzzzzzzzzzzz2"}]},)
198 arvjob = arvados_cwl.ArvadosContainer(runner)
199 arvjob.name = "testjob"
200 arvjob.builder = mock.MagicMock()
201 arvjob.output_callback = mock.MagicMock()
202 arvjob.collect_outputs = mock.MagicMock()
203 arvjob.successCodes = [0]
204 arvjob.outdir = "/var/spool/cwl"
208 "output": "99999999999999999999999999999993+99",
209 "log": "99999999999999999999999999999994+99",
210 "uuid": "zzzzz-8i9sb-zzzzzzzzzzzzzzz",
214 api.collections().list.assert_has_calls([
216 mock.call(filters=[['owner_uuid', '=', 'zzzzz-8i9sb-zzzzzzzzzzzzzzz'],
217 ['portable_data_hash', '=', '99999999999999999999999999999993+99'],
218 ['name', '=', 'Output 9999999 of testjob']]),
219 mock.call().execute(num_retries=0)])
221 self.assertFalse(api.collections().create.called)