3415: API exceptions from Python SDK include more error information.
[arvados.git] / sdk / python / tests / test_api.py
1 #!/usr/bin/env python
2
3 import apiclient.errors
4 import arvados
5 import httplib2
6 import json
7 import mimetypes
8 import unittest
9
10 from apiclient.http import RequestMockBuilder
11 from httplib import responses as HTTP_RESPONSES
12
13 if not mimetypes.inited:
14     mimetypes.init()
15
16 class ArvadosApiClientTest(unittest.TestCase):
17     @classmethod
18     def response_from_code(cls, code):
19         return httplib2.Response(
20             {'status': code,
21              'reason': HTTP_RESPONSES.get(code, "Unknown Response"),
22              'Content-Type': mimetypes.types_map['.json']})
23
24     @classmethod
25     def api_error_response(cls, code, *errors):
26         return (cls.response_from_code(code),
27                 json.dumps({'errors': errors,
28                             'error_token': '1234567890+12345678'}))
29
30     @classmethod
31     def setUpClass(cls):
32         # The apiclient library has support for mocking requests for
33         # testing, but it doesn't extend to the discovery document
34         # itself.  Point it at a known stable discovery document for now.
35         # FIXME: Figure out a better way to stub this out.
36         cls.orig_api_host = arvados.config.get('ARVADOS_API_HOST')
37         arvados.config.settings()['ARVADOS_API_HOST'] = 'qr1hi.arvadosapi.com'
38         mock_responses = {
39             'arvados.humans.delete': (cls.response_from_code(500), ""),
40             'arvados.humans.get': cls.api_error_response(
41                 422, "Bad UUID format", "Bad output format"),
42             'arvados.humans.list': (None, json.dumps(
43                     {'items_available': 0, 'items': []})),
44             }
45         req_builder = RequestMockBuilder(mock_responses)
46         cls.api = arvados.api('v1', False, requestBuilder=req_builder)
47
48     @classmethod
49     def tearDownClass(cls):
50         if cls.orig_api_host is None:
51             del arvados.config.settings()['ARVADOS_API_HOST']
52         else:
53             arvados.config.settings()['ARVADOS_API_HOST'] = cls.orig_api_host
54         # Prevent other tests from using our mocked API client.
55         arvados.uncache_api('v1')
56
57     def test_basic_list(self):
58         answer = self.api.humans().list(
59             filters=[['uuid', 'is', None]]).execute()
60         self.assertEqual(answer['items_available'], len(answer['items']))
61
62     def test_exceptions_include_errors(self):
63         with self.assertRaises(apiclient.errors.HttpError) as err_ctx:
64             self.api.humans().get(uuid='xyz-xyz-abcdef').execute()
65         err_s = str(err_ctx.exception)
66         for msg in ["Bad UUID format", "Bad output format"]:
67             self.assertIn(msg, err_s)
68
69     def test_exceptions_without_errors_have_basic_info(self):
70         with self.assertRaises(apiclient.errors.HttpError) as err_ctx:
71             self.api.humans().delete(uuid='xyz-xyz-abcdef').execute()
72         self.assertIn("500", str(err_ctx.exception))
73
74
75 if __name__ == '__main__':
76     unittest.main()