10291: Check discovery document before trying to choose/use a work API.
authorTom Clegg <tom@curoverse.com>
Wed, 19 Oct 2016 15:44:12 +0000 (11:44 -0400)
committerTom Clegg <tom@curoverse.com>
Wed, 19 Oct 2016 15:44:12 +0000 (11:44 -0400)
sdk/cwl/arvados_cwl/__init__.py
sdk/cwl/tests/test_job.py
sdk/cwl/tests/test_make_output.py
sdk/cwl/tests/test_pathmapper.py
sdk/cwl/tests/test_submit.py

index 7ebb13f1bb48af456ce50f2c7d8629e03c975cb0..f5f326bde12bf17c69c5886be2ceb8a3f00ed3d7 100644 (file)
@@ -58,7 +58,6 @@ class ArvCwlRunner(object):
         self.uploaded = {}
         self.num_retries = 4
         self.uuid = None
-        self.work_api = work_api
         self.stop_polling = threading.Event()
         self.poll_api = None
         self.pipeline = None
@@ -71,12 +70,20 @@ class ArvCwlRunner(object):
         else:
             self.keep_client = arvados.keep.KeepClient(api_client=self.api, num_retries=self.num_retries)
 
-        if self.work_api is None:
-            # todo: autodetect API to use.
-            self.work_api = "jobs"
-
-        if self.work_api not in ("containers", "jobs"):
-            raise Exception("Unsupported API '%s'" % self.work_api)
+        for api in ["jobs", "containers"]:
+            try:
+                methods = self.api._rootDesc.get('resources')[api]['methods']
+                if ('httpMethod' in methods['create'] and
+                    (work_api == api or work_api is None)):
+                    self.work_api = api
+                    break
+            except KeyError:
+                pass
+        if not self.work_api:
+            if work_api is None:
+                raise Exception("No supported APIs")
+            else:
+                raise Exception("Unsupported API '%s'" % work_api)
 
     def arv_make_tool(self, toolpath_object, **kwargs):
         kwargs["work_api"] = self.work_api
index db1c494c44cb91cf8ccebeb693123583d75594c1..7abc5676cc2f04efd0a74b8bac8271b7abab8b71 100644 (file)
@@ -1,10 +1,11 @@
+import functools
+import json
 import logging
 import mock
-import unittest
 import os
-import functools
-import json
+import unittest
 
+import arvados
 import arvados_cwl
 import cwltool.process
 from schema_salad.ref_resolver import Loader
@@ -215,7 +216,10 @@ class TestWorkflow(unittest.TestCase):
     def test_run(self, mockcollection):
         arvados_cwl.add_arv_hints()
 
-        runner = arvados_cwl.ArvCwlRunner(mock.MagicMock())
+        api = mock.MagicMock()
+        api._rootDesc = arvados.api('v1')._rootDesc
+        runner = arvados_cwl.ArvCwlRunner(api)
+        self.assertEqual(runner.work_api, 'jobs')
 
         runner.project_uuid = "zzzzz-8i9sb-zzzzzzzzzzzzzzz"
         runner.ignore_docker_for_reuse = False
@@ -270,3 +274,12 @@ class TestWorkflow(unittest.TestCase):
                      ['script_version', 'in git', '9e5b98e8f5f4727856b53447191f9c06e3da2ba6'],
                      ['docker_image_locator', 'in docker', 'arvados/jobs']],
             find_or_create=True)
+
+    def test_default_work_api(self):
+        arvados_cwl.add_arv_hints()
+
+        api = mock.MagicMock()
+        api._rootDesc = arvados.api('v1')._rootDesc
+        del api._rootDesc.get('resources')['jobs']['methods']['create']
+        runner = arvados_cwl.ArvCwlRunner(api)
+        self.assertEqual(runner.work_api, 'containers')
index 267129715494b9f05bfe9a2df220e0514da5e81c..cd66eb15065059579e718150372d1f0c03247688 100644 (file)
@@ -1,20 +1,24 @@
+import functools
+import json
 import logging
 import mock
-import unittest
 import os
-import functools
-import json
 import StringIO
+import unittest
 
+import arvados
 import arvados_cwl
 
 class TestMakeOutput(unittest.TestCase):
+    def setUp(self):
+        self.api = mock.MagicMock()
+        self.api._rootDesc = arvados.api('v1')._rootDesc
+
     @mock.patch("arvados.collection.Collection")
     @mock.patch("arvados.collection.CollectionReader")
     def test_make_output_collection(self, reader, col):
-        api = mock.MagicMock()
         keep_client = mock.MagicMock()
-        runner = arvados_cwl.ArvCwlRunner(api, keep_client=keep_client)
+        runner = arvados_cwl.ArvCwlRunner(self.api, keep_client=keep_client)
         runner.project_uuid = 'zzzzz-j7d0g-zzzzzzzzzzzzzzz'
 
         final = mock.MagicMock()
index 7e13066d855a92e292420c229ba4c34f8e324e00..57958f78d0a41a97b9d5b0aa5f10a2cf10563b22 100644 (file)
@@ -21,10 +21,14 @@ def upload_mock(files, api, dry_run=False, num_retries=0, project=None, fnPatter
         c.fn = fnPattern % (pdh, os.path.basename(c.fn))
 
 class TestPathmap(unittest.TestCase):
+    def setUp(self):
+        self.api = mock.MagicMock()
+        self.api._rootDesc = arvados.api('v1')._rootDesc
+
     def test_keepref(self):
         """Test direct keep references."""
 
-        arvrunner = arvados_cwl.ArvCwlRunner(mock.MagicMock())
+        arvrunner = arvados_cwl.ArvCwlRunner(self.api)
 
         p = ArvPathMapper(arvrunner, [{
             "class": "File",
@@ -38,7 +42,7 @@ class TestPathmap(unittest.TestCase):
     def test_upload(self, upl):
         """Test pathmapper uploading files."""
 
-        arvrunner = arvados_cwl.ArvCwlRunner(mock.MagicMock())
+        arvrunner = arvados_cwl.ArvCwlRunner(self.api)
 
         upl.side_effect = upload_mock
 
@@ -54,7 +58,7 @@ class TestPathmap(unittest.TestCase):
     def test_prev_uploaded(self, upl):
         """Test pathmapper handling previously uploaded files."""
 
-        arvrunner = arvados_cwl.ArvCwlRunner(mock.MagicMock())
+        arvrunner = arvados_cwl.ArvCwlRunner(self.api)
         arvrunner.add_uploaded('tests/hw.py', MapperEnt(resolved='keep:99999999999999999999999999999991+99/hw.py', target='', type='File'))
 
         upl.side_effect = upload_mock
@@ -71,7 +75,7 @@ class TestPathmap(unittest.TestCase):
     @mock.patch("arvados.commands.run.statfile")
     def test_statfile(self, statfile, upl):
         """Test pathmapper handling ArvFile references."""
-        arvrunner = arvados_cwl.ArvCwlRunner(mock.MagicMock())
+        arvrunner = arvados_cwl.ArvCwlRunner(self.api)
 
         # An ArvFile object returned from arvados.commands.run.statfile means the file is located on a
         # keep mount, so we can construct a direct reference directly without upload.
index d3bdf8fedc30d897b323cd23fce5e74a017f3da9..0ff9da927afafb9908bc32ab747e2fb169c5a9dc 100644 (file)
@@ -1,16 +1,17 @@
-import arvados
-import arvados.keep
-import arvados.collection
-import arvados_cwl
 import copy
 import cStringIO
 import functools
 import hashlib
+import json
+import logging
 import mock
 import sys
 import unittest
-import json
-import logging
+
+import arvados
+import arvados.collection
+import arvados_cwl
+import arvados.keep
 
 from .matcher import JsonDiffMatcher
 
@@ -38,6 +39,7 @@ def stubs(func):
 
 
         stubs.api = mock.MagicMock()
+        stubs.api._rootDesc = arvados.api('v1')._rootDesc
         stubs.api.users().current().execute.return_value = {
             "uuid": stubs.fake_user_uuid,
         }