2 from arvados_cwl.arvdocker import arv_docker_clear_cache
9 from schema_salad.ref_resolver import Loader
11 from schema_salad.ref_resolver import Loader
13 if not os.getenv('ARVADOS_DEBUG'):
14 logging.getLogger('arvados.cwl-runner').setLevel(logging.WARN)
15 logging.getLogger('arvados.arv-run').setLevel(logging.WARN)
18 class TestContainer(unittest.TestCase):
20 # The test passes no builder.resources
21 # Hence the default resources will apply: {'cores': 1, 'ram': 1024, 'outdirSize': 1024, 'tmpdirSize': 1024}
22 @mock.patch("arvados.commands.keepdocker.list_images_in_arv")
23 def test_run(self, keepdocker):
24 for enable_reuse in (True, False):
25 arv_docker_clear_cache()
27 runner = mock.MagicMock()
28 runner.project_uuid = "zzzzz-8i9sb-zzzzzzzzzzzzzzz"
29 runner.ignore_docker_for_reuse = False
31 keepdocker.return_value = [("zzzzz-4zz18-zzzzzzzzzzzzzz3", "")]
32 runner.api.collections().get().execute.return_value = {
33 "portable_data_hash": "99999999999999999999999999999993+99"}
35 document_loader, avsc_names, schema_metadata, metaschema_loader = cwltool.process.get_schema("v1.0")
41 "arguments": [{"valueFrom": "$(runtime.outdir)"}]
43 make_fs_access=functools.partial(arvados_cwl.CollectionFsAccess, api_client=runner.api)
44 arvtool = arvados_cwl.ArvadosCommandTool(runner, tool, work_api="containers", avsc_names=avsc_names,
45 basedir="", make_fs_access=make_fs_access, loader=Loader({}))
46 arvtool.formatgraph = None
47 for j in arvtool.job({}, mock.MagicMock(), basedir="", name="test_run_"+str(enable_reuse),
48 make_fs_access=make_fs_access, tmpdir="/tmp"):
49 j.run(enable_reuse=enable_reuse)
50 runner.api.container_requests().create.assert_called_with(
53 'HOME': '/var/spool/cwl',
56 'name': 'test_run_'+str(enable_reuse),
57 'runtime_constraints': {
61 'use_existing': enable_reuse,
64 '/var/spool/cwl': {'kind': 'tmp'}
67 'owner_uuid': 'zzzzz-8i9sb-zzzzzzzzzzzzzzz',
68 'output_path': '/var/spool/cwl',
69 'container_image': '99999999999999999999999999999993+99',
70 'command': ['ls', '/var/spool/cwl'],
71 'cwd': '/var/spool/cwl'
74 # The test passes some fields in builder.resources
75 # For the remaining fields, the defaults will apply: {'cores': 1, 'ram': 1024, 'outdirSize': 1024, 'tmpdirSize': 1024}
76 @mock.patch("arvados.commands.keepdocker.list_images_in_arv")
77 def test_resource_requirements(self, keepdocker):
78 arv_docker_clear_cache()
79 runner = mock.MagicMock()
80 runner.project_uuid = "zzzzz-8i9sb-zzzzzzzzzzzzzzz"
81 runner.ignore_docker_for_reuse = False
82 document_loader, avsc_names, schema_metadata, metaschema_loader = cwltool.process.get_schema("v1.0")
84 keepdocker.return_value = [("zzzzz-4zz18-zzzzzzzzzzzzzz3", "")]
85 runner.api.collections().get().execute.return_value = {
86 "portable_data_hash": "99999999999999999999999999999993+99"}
92 "class": "ResourceRequirement",
97 "class": "http://arvados.org/cwl#RuntimeConstraints",
100 "class": "http://arvados.org/cwl#APIRequirement",
102 "class": "http://arvados.org/cwl#PartitionRequirement",
107 make_fs_access=functools.partial(arvados_cwl.CollectionFsAccess, api_client=runner.api)
108 arvtool = arvados_cwl.ArvadosCommandTool(runner, tool, work_api="containers",
109 avsc_names=avsc_names, make_fs_access=make_fs_access,
111 arvtool.formatgraph = None
112 for j in arvtool.job({}, mock.MagicMock(), basedir="", name="test_resource_requirements",
113 make_fs_access=make_fs_access, tmpdir="/tmp"):
116 runner.api.container_requests().create.assert_called_with(
119 'HOME': '/var/spool/cwl',
122 'name': 'test_resource_requirements',
123 'runtime_constraints': {
126 'keep_cache_ram': 512,
128 'partition': ['blurb']
130 'use_existing': True,
133 '/var/spool/cwl': {'kind': 'tmp'}
135 'state': 'Committed',
136 'owner_uuid': 'zzzzz-8i9sb-zzzzzzzzzzzzzzz',
137 'output_path': '/var/spool/cwl',
138 'container_image': '99999999999999999999999999999993+99',
140 'cwd': '/var/spool/cwl'
143 @mock.patch("arvados.collection.Collection")
144 def test_done(self, col):
145 api = mock.MagicMock()
147 runner = mock.MagicMock()
149 runner.project_uuid = "zzzzz-8i9sb-zzzzzzzzzzzzzzz"
150 runner.num_retries = 0
151 runner.ignore_docker_for_reuse = False
153 col().open.return_value = []
154 api.collections().list().execute.side_effect = ({"items": []},
155 {"items": [{"manifest_text": "XYZ"}]})
157 arvjob = arvados_cwl.ArvadosContainer(runner)
158 arvjob.name = "testjob"
159 arvjob.builder = mock.MagicMock()
160 arvjob.output_callback = mock.MagicMock()
161 arvjob.collect_outputs = mock.MagicMock()
162 arvjob.successCodes = [0]
163 arvjob.outdir = "/var/spool/cwl"
167 "output": "99999999999999999999999999999993+99",
168 "log": "99999999999999999999999999999994+99",
169 "uuid": "zzzzz-8i9sb-zzzzzzzzzzzzzzz",
173 api.collections().list.assert_has_calls([
175 mock.call(filters=[['owner_uuid', '=', 'zzzzz-8i9sb-zzzzzzzzzzzzzzz'],
176 ['portable_data_hash', '=', '99999999999999999999999999999993+99'],
177 ['name', '=', 'Output 9999999 of testjob']]),
178 mock.call().execute(num_retries=0),
179 mock.call(limit=1, filters=[['portable_data_hash', '=', '99999999999999999999999999999993+99']],
180 select=['manifest_text']),
181 mock.call().execute(num_retries=0)])
183 api.collections().create.assert_called_with(
184 ensure_unique_name=True,
185 body={'portable_data_hash': '99999999999999999999999999999993+99',
186 'manifest_text': 'XYZ',
187 'owner_uuid': 'zzzzz-8i9sb-zzzzzzzzzzzzzzz',
188 'name': 'Output 9999999 of testjob'})
190 @mock.patch("arvados.collection.Collection")
191 def test_done_use_existing_collection(self, col):
192 api = mock.MagicMock()
194 runner = mock.MagicMock()
196 runner.project_uuid = "zzzzz-8i9sb-zzzzzzzzzzzzzzz"
197 runner.num_retries = 0
199 col().open.return_value = []
200 api.collections().list().execute.side_effect = ({"items": [{"uuid": "zzzzz-4zz18-zzzzzzzzzzzzzz2"}]},)
202 arvjob = arvados_cwl.ArvadosContainer(runner)
203 arvjob.name = "testjob"
204 arvjob.builder = mock.MagicMock()
205 arvjob.output_callback = mock.MagicMock()
206 arvjob.collect_outputs = mock.MagicMock()
207 arvjob.successCodes = [0]
208 arvjob.outdir = "/var/spool/cwl"
212 "output": "99999999999999999999999999999993+99",
213 "log": "99999999999999999999999999999994+99",
214 "uuid": "zzzzz-8i9sb-zzzzzzzzzzzzzzz",
218 api.collections().list.assert_has_calls([
220 mock.call(filters=[['owner_uuid', '=', 'zzzzz-8i9sb-zzzzzzzzzzzzzzz'],
221 ['portable_data_hash', '=', '99999999999999999999999999999993+99'],
222 ['name', '=', 'Output 9999999 of testjob']]),
223 mock.call().execute(num_retries=0)])
225 self.assertFalse(api.collections().create.called)