8857: Add --ignore-docker-for-reuse option to assist workflow development.
[arvados.git] / sdk / cwl / tests / test_job.py
index 0b38db2059c28e3beada820c8797656bffa1a659..bb15e60f1f31faebd7f901f34d0cd264822d5aed 100644 (file)
@@ -8,6 +8,9 @@ class TestJob(unittest.TestCase):
     # Hence the default resources will apply: {'cores': 1, 'ram': 1024, 'outdirSize': 1024, 'tmpdirSize': 1024}
     def test_run(self):
         runner = mock.MagicMock()
+        runner.project_uuid = "zzzzz-8i9sb-zzzzzzzzzzzzzzz"
+        runner.ignore_docker_for_reuse = False
+
         tool = {
             "inputs": [],
             "outputs": [],
@@ -17,30 +20,41 @@ class TestJob(unittest.TestCase):
         arvtool.formatgraph = None
         for j in arvtool.job({}, "", mock.MagicMock()):
             j.run()
-        runner.api.jobs().create.assert_called_with(body={
-            'runtime_constraints': {},
-            'script_parameters': {
-                'tasks': [{
-                    'task.env': {'TMPDIR': '$(task.tmpdir)'},
-                    'command': ['ls']
-                }],
-                'crunchrunner': '83db29f08544e1c319572a6bd971088a+140/crunchrunner'
+            runner.api.jobs().create.assert_called_with(
+                body={
+                    'owner_uuid': 'zzzzz-8i9sb-zzzzzzzzzzzzzzz',
+                    'runtime_constraints': {},
+                    'script_parameters': {
+                        'tasks': [{
+                            'task.env': {'TMPDIR': '$(task.tmpdir)'},
+                            'command': ['ls']
+                        }]
             },
             'script_version': 'master',
-            'minimum_script_version': '9e5b98e8f5f4727856b53447191f9c06e3da2ba6',
-            'repository': 'arvados',
-            'script': 'crunchrunner',
-            'runtime_constraints': {
-                'min_cores_per_node': 1,
-                'min_ram_mb_per_node': 1024,
-                'min_scratch_mb_per_node': 2048 # tmpdirSize + outdirSize
-            }
-        }, find_or_create=True)
+                    'minimum_script_version': '9e5b98e8f5f4727856b53447191f9c06e3da2ba6',
+                    'repository': 'arvados',
+                    'script': 'crunchrunner',
+                    'runtime_constraints': {
+                        'docker_image': 'arvados/jobs',
+                        'min_cores_per_node': 1,
+                        'min_ram_mb_per_node': 1024,
+                        'min_scratch_mb_per_node': 2048 # tmpdirSize + outdirSize
+                    }
+        },
+                                                    find_or_create=True,
+                filters=[['repository', '=', 'arvados'],
+                         ['script', '=', 'crunchrunner'],
+                         ['script_version', 'in git', '9e5b98e8f5f4727856b53447191f9c06e3da2ba6'],
+                         ['docker_image_locator', 'in docker', 'arvados/jobs']]
+            )
 
     # The test passes some fields in builder.resources
     # For the remaining fields, the defaults will apply: {'cores': 1, 'ram': 1024, 'outdirSize': 1024, 'tmpdirSize': 1024}
     def test_resource_requirements(self):
         runner = mock.MagicMock()
+        runner.project_uuid = "zzzzz-8i9sb-zzzzzzzzzzzzzzz"
+        runner.ignore_docker_for_reuse = False
+
         tool = {
             "inputs": [],
             "outputs": [],
@@ -56,22 +70,107 @@ class TestJob(unittest.TestCase):
         arvtool.formatgraph = None
         for j in arvtool.job({}, "", mock.MagicMock()):
             j.run()
-        runner.api.jobs().create.assert_called_with(body={
-            'runtime_constraints': {},
-            'script_parameters': {
-                'tasks': [{
-                    'task.env': {'TMPDIR': '$(task.tmpdir)'},
-                    'command': ['ls']
-                }],
-                'crunchrunner': '83db29f08544e1c319572a6bd971088a+140/crunchrunner'
+        runner.api.jobs().create.assert_called_with(
+            body={
+                'owner_uuid': 'zzzzz-8i9sb-zzzzzzzzzzzzzzz',
+                'runtime_constraints': {},
+                'script_parameters': {
+                    'tasks': [{
+                        'task.env': {'TMPDIR': '$(task.tmpdir)'},
+                        'command': ['ls']
+                    }]
             },
             'script_version': 'master',
-            'minimum_script_version': '9e5b98e8f5f4727856b53447191f9c06e3da2ba6',
-            'repository': 'arvados',
-            'script': 'crunchrunner',
-            'runtime_constraints': {
-                'min_cores_per_node': 3,
-                'min_ram_mb_per_node': 3000,
-                'min_scratch_mb_per_node': 5024 # tmpdirSize + outdirSize
-            }
-        }, find_or_create=True)
+                'minimum_script_version': '9e5b98e8f5f4727856b53447191f9c06e3da2ba6',
+                'repository': 'arvados',
+                'script': 'crunchrunner',
+                'runtime_constraints': {
+                    'docker_image': 'arvados/jobs',
+                    'min_cores_per_node': 3,
+                    'min_ram_mb_per_node': 3000,
+                    'min_scratch_mb_per_node': 5024 # tmpdirSize + outdirSize
+                }
+        },
+            find_or_create=True,
+            filters=[['repository', '=', 'arvados'],
+                     ['script', '=', 'crunchrunner'],
+                     ['script_version', 'in git', '9e5b98e8f5f4727856b53447191f9c06e3da2ba6'],
+                     ['docker_image_locator', 'in docker', 'arvados/jobs']])
+
+    @mock.patch("arvados.collection.Collection")
+    def test_done(self, col):
+        api = mock.MagicMock()
+
+        runner = mock.MagicMock()
+        runner.api = api
+        runner.project_uuid = "zzzzz-8i9sb-zzzzzzzzzzzzzzz"
+        runner.num_retries = 0
+        runner.ignore_docker_for_reuse = False
+
+        col().open.return_value = []
+        api.collections().list().execute.side_effect = ({"items": []},
+                                                        {"items": [{"manifest_text": "XYZ"}]})
+
+        arvjob = arvados_cwl.ArvadosJob(runner)
+        arvjob.name = "testjob"
+        arvjob.builder = mock.MagicMock()
+        arvjob.output_callback = mock.MagicMock()
+        arvjob.collect_outputs = mock.MagicMock()
+
+        arvjob.done({
+            "state": "Complete",
+            "output": "99999999999999999999999999999993+99",
+            "log": "99999999999999999999999999999994+99",
+            "uuid": "zzzzz-8i9sb-zzzzzzzzzzzzzzz"
+        })
+
+        api.collections().list.assert_has_calls([
+            mock.call(),
+            mock.call(filters=[['owner_uuid', '=', 'zzzzz-8i9sb-zzzzzzzzzzzzzzz'],
+                          ['portable_data_hash', '=', '99999999999999999999999999999993+99'],
+                          ['name', '=', 'Output 9999999 of testjob']]),
+            mock.call().execute(num_retries=0),
+            mock.call(limit=1, filters=[['portable_data_hash', '=', '99999999999999999999999999999993+99']],
+                 select=['manifest_text']),
+            mock.call().execute(num_retries=0)])
+
+        api.collections().create.assert_called_with(
+            ensure_unique_name=True,
+            body={'portable_data_hash': '99999999999999999999999999999993+99',
+                  'manifest_text': 'XYZ',
+                  'owner_uuid': 'zzzzz-8i9sb-zzzzzzzzzzzzzzz',
+                  'name': 'Output 9999999 of testjob'})
+
+    @mock.patch("arvados.collection.Collection")
+    def test_done_use_existing_collection(self, col):
+        api = mock.MagicMock()
+
+        runner = mock.MagicMock()
+        runner.api = api
+        runner.project_uuid = "zzzzz-8i9sb-zzzzzzzzzzzzzzz"
+        runner.num_retries = 0
+
+        col().open.return_value = []
+        api.collections().list().execute.side_effect = ({"items": [{"uuid": "zzzzz-4zz18-zzzzzzzzzzzzzz2"}]},)
+
+        arvjob = arvados_cwl.ArvadosJob(runner)
+        arvjob.name = "testjob"
+        arvjob.builder = mock.MagicMock()
+        arvjob.output_callback = mock.MagicMock()
+        arvjob.collect_outputs = mock.MagicMock()
+
+        arvjob.done({
+            "state": "Complete",
+            "output": "99999999999999999999999999999993+99",
+            "log": "99999999999999999999999999999994+99",
+            "uuid": "zzzzz-8i9sb-zzzzzzzzzzzzzzz"
+        })
+
+        api.collections().list.assert_has_calls([
+            mock.call(),
+            mock.call(filters=[['owner_uuid', '=', 'zzzzz-8i9sb-zzzzzzzzzzzzzzz'],
+                               ['portable_data_hash', '=', '99999999999999999999999999999993+99'],
+                               ['name', '=', 'Output 9999999 of testjob']]),
+            mock.call().execute(num_retries=0)])
+
+        self.assertFalse(api.collections().create.called)