Merge "Add Betamax for testing"
This commit is contained in:
commit
37cc3e95af
|
@ -270,13 +270,23 @@ _5xx_classes = [
|
|||
_5xx_codes = {cls.status_code: cls for cls in _5xx_classes}
|
||||
|
||||
|
||||
def error_from(response):
|
||||
"""Find an error code that matches a response status_code."""
|
||||
if 400 <= response.status_code < 500:
|
||||
cls = _4xx_codes.get(response.status_code, HTTPClientError)
|
||||
elif 500 <= response.status_code < 600:
|
||||
cls = _5xx_codes.get(response.status_code, HTTPServerError)
|
||||
def _error_class_from(status_code):
|
||||
if 400 <= status_code < 500:
|
||||
cls = _4xx_codes.get(status_code, HTTPClientError)
|
||||
elif 500 <= status_code < 600:
|
||||
cls = _5xx_codes.get(status_code, HTTPServerError)
|
||||
else:
|
||||
cls = HTTPError
|
||||
return cls
|
||||
|
||||
|
||||
def error_from(response):
|
||||
"""Find an error code that matches a response status_code."""
|
||||
cls = _error_class_from(response.status_code)
|
||||
return cls(response=response)
|
||||
|
||||
|
||||
def raise_from(exception):
|
||||
"""Raise an exception from the keystoneauth1 exception."""
|
||||
cls = _error_class_from(exception.http_status)
|
||||
return cls(response=exception.response, exception=exception)
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
from itertools import chain
|
||||
import logging
|
||||
|
||||
from keystoneauth1 import exceptions as ksa_exc
|
||||
from keystoneauth1 import session as ksa_session
|
||||
from requests import exceptions as requests_exc
|
||||
|
||||
|
@ -228,6 +229,8 @@ class Session(object):
|
|||
raise exc.Timeout(exception=err)
|
||||
except requests_exc.ConnectionError as err:
|
||||
raise exc.ConnectionFailed(exception=err)
|
||||
except ksa_exc.HttpError as err:
|
||||
raise exc.raise_from(err)
|
||||
|
||||
if response.status_code >= 400:
|
||||
raise exc.error_from(response)
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
================================
|
||||
cratonclient Betamax Cassettes
|
||||
================================
|
||||
|
||||
This directory contains the cassettes that were recorded by Betamax_ for
|
||||
integration level tests of the python-cratonclient library.
|
||||
|
||||
For more information about these cassettes, please refer to the Betamax
|
||||
documentation_. For specific information about what information is stored in a
|
||||
cassette and its structure, please read `"What is a cassette?"`_
|
||||
|
||||
|
||||
.. links
|
||||
.. _Betamax:
|
||||
https://pypi.org/project/betamax
|
||||
.. _documentation:
|
||||
https://betamax.readthedocs.io/en/latest/
|
||||
.. _"What is a cassette?":
|
||||
https://betamax.readthedocs.io/en/latest/cassettes.html
|
|
@ -0,0 +1,201 @@
|
|||
http_interactions:
|
||||
- recorded_at: '2017-03-21T14:50:37'
|
||||
request:
|
||||
body:
|
||||
encoding: utf-8
|
||||
string: "{\n \"name\": \"cloud-TestHosts-test_create\"\n}"
|
||||
headers:
|
||||
Accept: '*/*'
|
||||
Accept-Encoding: gzip, deflate
|
||||
Connection: keep-alive
|
||||
Content-Length: '39'
|
||||
Content-Type: application/json
|
||||
User-Agent: python-cratonclient/0.0.1
|
||||
X-Auth-Project: <craton-demo-project>
|
||||
X-Auth-Token: <craton-demo-token>
|
||||
X-Auth-User: <craton-demo-username>
|
||||
method: POST
|
||||
uri: <craton-url>/clouds
|
||||
response:
|
||||
body:
|
||||
encoding: null
|
||||
string: "{\n \"variables\": {},\n \"id\": 6,\n \"name\": \"cloud-TestHosts-test_create\"\
|
||||
,\n \"note\": null,\n \"created_at\": \"2017-03-20T23:40:58.854217\",\n\
|
||||
\ \"updated_at\": null,\n \"project_id\": \"<craton-demo-project>\"\n}"
|
||||
headers:
|
||||
Content-Length: '214'
|
||||
Content-Type: application/json
|
||||
Date: Mon, 20 Mar 2017 23:40:58 GMT
|
||||
Location: <craton-url>/clouds/6
|
||||
Server: WSGIServer/0.2 CPython/3.5.2
|
||||
x-openstack-request-id: req-1993267c-c04e-482d-a2f7-5a3199f45fe3
|
||||
status:
|
||||
code: 201
|
||||
message: CREATED
|
||||
url: <craton-url>/clouds
|
||||
- recorded_at: '2017-03-21T14:50:37'
|
||||
request:
|
||||
body:
|
||||
encoding: utf-8
|
||||
string: "{\n \"name\": \"region-TestHosts-test_create\",\n \"cloud_id\": 6\n\
|
||||
}"
|
||||
headers:
|
||||
Accept: '*/*'
|
||||
Accept-Encoding: gzip, deflate
|
||||
Connection: keep-alive
|
||||
Content-Length: '55'
|
||||
Content-Type: application/json
|
||||
User-Agent: python-cratonclient/0.0.1
|
||||
X-Auth-Project: <craton-demo-project>
|
||||
X-Auth-Token: <craton-demo-token>
|
||||
X-Auth-User: <craton-demo-username>
|
||||
method: POST
|
||||
uri: <craton-url>/regions
|
||||
response:
|
||||
body:
|
||||
encoding: null
|
||||
string: "{\n \"variables\": {},\n \"id\": 2,\n \"name\": \"region-TestHosts-test_create\"\
|
||||
,\n \"note\": null,\n \"created_at\": \"2017-03-20T23:40:58.893218\",\n\
|
||||
\ \"updated_at\": null,\n \"cloud_id\": 6,\n \"project_id\": \"<craton-demo-project>\"\
|
||||
\n}"
|
||||
headers:
|
||||
Content-Length: '232'
|
||||
Content-Type: application/json
|
||||
Date: Mon, 20 Mar 2017 23:40:58 GMT
|
||||
Location: <craton-url>/regions/2
|
||||
Server: WSGIServer/0.2 CPython/3.5.2
|
||||
x-openstack-request-id: req-aa293966-07d6-4832-b294-68d277e7266c
|
||||
status:
|
||||
code: 201
|
||||
message: CREATED
|
||||
url: <craton-url>/regions
|
||||
- recorded_at: '2017-03-21T14:50:37'
|
||||
request:
|
||||
body:
|
||||
encoding: utf-8
|
||||
string: "{\n \"region_id\": 2,\n \"device_type\": \"server\",\n \"name\"\
|
||||
: \"host-0\",\n \"cloud_id\": 6,\n \"ip_address\": \"127.0.1.0\"\n}"
|
||||
headers:
|
||||
Accept: '*/*'
|
||||
Accept-Encoding: gzip, deflate
|
||||
Connection: keep-alive
|
||||
Content-Length: '101'
|
||||
Content-Type: application/json
|
||||
User-Agent: python-cratonclient/0.0.1
|
||||
X-Auth-Project: <craton-demo-project>
|
||||
X-Auth-Token: <craton-demo-token>
|
||||
X-Auth-User: <craton-demo-username>
|
||||
method: POST
|
||||
uri: <craton-url>/hosts
|
||||
response:
|
||||
body:
|
||||
encoding: null
|
||||
string: "{\n \"id\": 2,\n \"ip_address\": \"127.0.1.0\",\n \"region_id\"\
|
||||
: 2,\n \"active\": true,\n \"cloud_id\": 6,\n \"project_id\": \"<craton-demo-project>\"\
|
||||
,\n \"variables\": {},\n \"parent_id\": null,\n \"updated_at\": null,\n\
|
||||
\ \"name\": \"host-0\",\n \"cell_id\": null,\n \"device_type\": \"server\"\
|
||||
,\n \"note\": null,\n \"links\": [\n {\n \"href\": \"<craton-url>/regions/2\"\
|
||||
,\n \"rel\": \"up\"\n }\n ],\n \"created_at\": \"2017-03-20T23:40:58.952662\"\
|
||||
\n}"
|
||||
headers:
|
||||
Content-Length: '442'
|
||||
Content-Type: application/json
|
||||
Date: Mon, 20 Mar 2017 23:40:58 GMT
|
||||
Location: <craton-url>/hosts/2
|
||||
Server: WSGIServer/0.2 CPython/3.5.2
|
||||
x-openstack-request-id: req-98391187-c6e9-4002-936c-ba3b93ee4081
|
||||
status:
|
||||
code: 201
|
||||
message: CREATED
|
||||
url: <craton-url>/hosts
|
||||
- recorded_at: '2017-03-21T14:50:37'
|
||||
request:
|
||||
body:
|
||||
encoding: utf-8
|
||||
string: ''
|
||||
headers:
|
||||
Accept: '*/*'
|
||||
Accept-Encoding: gzip, deflate
|
||||
Connection: keep-alive
|
||||
Content-Length: '0'
|
||||
User-Agent: python-cratonclient/0.0.1
|
||||
X-Auth-Project: <craton-demo-project>
|
||||
X-Auth-Token: <craton-demo-token>
|
||||
X-Auth-User: <craton-demo-username>
|
||||
method: DELETE
|
||||
uri: <craton-url>/hosts/2
|
||||
response:
|
||||
body:
|
||||
encoding: null
|
||||
string: ''
|
||||
headers:
|
||||
Content-Length: '0'
|
||||
Content-Type: application/json
|
||||
Date: Mon, 20 Mar 2017 23:40:59 GMT
|
||||
Server: WSGIServer/0.2 CPython/3.5.2
|
||||
x-openstack-request-id: req-949fad55-ce5e-47fb-8277-13d6f88286a2
|
||||
status:
|
||||
code: 204
|
||||
message: NO CONTENT
|
||||
url: <craton-url>/hosts/2
|
||||
- recorded_at: '2017-03-21T14:50:37'
|
||||
request:
|
||||
body:
|
||||
encoding: utf-8
|
||||
string: ''
|
||||
headers:
|
||||
Accept: '*/*'
|
||||
Accept-Encoding: gzip, deflate
|
||||
Connection: keep-alive
|
||||
Content-Length: '0'
|
||||
User-Agent: python-cratonclient/0.0.1
|
||||
X-Auth-Project: <craton-demo-project>
|
||||
X-Auth-Token: <craton-demo-token>
|
||||
X-Auth-User: <craton-demo-username>
|
||||
method: DELETE
|
||||
uri: <craton-url>/regions/2
|
||||
response:
|
||||
body:
|
||||
encoding: null
|
||||
string: ''
|
||||
headers:
|
||||
Content-Length: '0'
|
||||
Content-Type: application/json
|
||||
Date: Mon, 20 Mar 2017 23:40:59 GMT
|
||||
Server: WSGIServer/0.2 CPython/3.5.2
|
||||
x-openstack-request-id: req-dbed3d00-6002-493f-84d0-40b572f500f1
|
||||
status:
|
||||
code: 204
|
||||
message: NO CONTENT
|
||||
url: <craton-url>/regions/2
|
||||
- recorded_at: '2017-03-21T14:50:37'
|
||||
request:
|
||||
body:
|
||||
encoding: utf-8
|
||||
string: ''
|
||||
headers:
|
||||
Accept: '*/*'
|
||||
Accept-Encoding: gzip, deflate
|
||||
Connection: keep-alive
|
||||
Content-Length: '0'
|
||||
User-Agent: python-cratonclient/0.0.1
|
||||
X-Auth-Project: <craton-demo-project>
|
||||
X-Auth-Token: <craton-demo-token>
|
||||
X-Auth-User: <craton-demo-username>
|
||||
method: DELETE
|
||||
uri: <craton-url>/clouds/6
|
||||
response:
|
||||
body:
|
||||
encoding: null
|
||||
string: ''
|
||||
headers:
|
||||
Content-Length: '0'
|
||||
Content-Type: application/json
|
||||
Date: Mon, 20 Mar 2017 23:40:59 GMT
|
||||
Server: WSGIServer/0.2 CPython/3.5.2
|
||||
x-openstack-request-id: req-f70acbe0-739f-4bba-9f56-707032a3211d
|
||||
status:
|
||||
code: 204
|
||||
message: NO CONTENT
|
||||
url: <craton-url>/clouds/6
|
||||
recorded_with: betamax/0.8.0
|
|
@ -0,0 +1,231 @@
|
|||
http_interactions:
|
||||
- recorded_at: '2017-03-21T14:50:37'
|
||||
request:
|
||||
body:
|
||||
encoding: utf-8
|
||||
string: "{\n \"name\": \"cloud-TestHosts-test_delete\"\n}"
|
||||
headers:
|
||||
Accept: '*/*'
|
||||
Accept-Encoding: gzip, deflate
|
||||
Connection: keep-alive
|
||||
Content-Length: '39'
|
||||
Content-Type: application/json
|
||||
User-Agent: python-cratonclient/0.0.1
|
||||
X-Auth-Project: <craton-demo-project>
|
||||
X-Auth-Token: <craton-demo-token>
|
||||
X-Auth-User: <craton-demo-username>
|
||||
method: POST
|
||||
uri: <craton-url>/clouds
|
||||
response:
|
||||
body:
|
||||
encoding: null
|
||||
string: "{\n \"variables\": {},\n \"id\": 10,\n \"name\": \"cloud-TestHosts-test_delete\"\
|
||||
,\n \"note\": null,\n \"created_at\": \"2017-03-20T23:40:59.563744\",\n\
|
||||
\ \"updated_at\": null,\n \"project_id\": \"<craton-demo-project>\"\n}"
|
||||
headers:
|
||||
Content-Length: '215'
|
||||
Content-Type: application/json
|
||||
Date: Mon, 20 Mar 2017 23:40:59 GMT
|
||||
Location: <craton-url>/clouds/10
|
||||
Server: WSGIServer/0.2 CPython/3.5.2
|
||||
x-openstack-request-id: req-8c61f8a2-83bb-466e-8cdc-b24b38e7de74
|
||||
status:
|
||||
code: 201
|
||||
message: CREATED
|
||||
url: <craton-url>/clouds
|
||||
- recorded_at: '2017-03-21T14:50:37'
|
||||
request:
|
||||
body:
|
||||
encoding: utf-8
|
||||
string: "{\n \"name\": \"region-TestHosts-test_delete\",\n \"cloud_id\": 10\n\
|
||||
}"
|
||||
headers:
|
||||
Accept: '*/*'
|
||||
Accept-Encoding: gzip, deflate
|
||||
Connection: keep-alive
|
||||
Content-Length: '56'
|
||||
Content-Type: application/json
|
||||
User-Agent: python-cratonclient/0.0.1
|
||||
X-Auth-Project: <craton-demo-project>
|
||||
X-Auth-Token: <craton-demo-token>
|
||||
X-Auth-User: <craton-demo-username>
|
||||
method: POST
|
||||
uri: <craton-url>/regions
|
||||
response:
|
||||
body:
|
||||
encoding: null
|
||||
string: "{\n \"variables\": {},\n \"id\": 6,\n \"name\": \"region-TestHosts-test_delete\"\
|
||||
,\n \"note\": null,\n \"created_at\": \"2017-03-20T23:40:59.702986\",\n\
|
||||
\ \"updated_at\": null,\n \"cloud_id\": 10,\n \"project_id\": \"<craton-demo-project>\"\
|
||||
\n}"
|
||||
headers:
|
||||
Content-Length: '233'
|
||||
Content-Type: application/json
|
||||
Date: Mon, 20 Mar 2017 23:40:59 GMT
|
||||
Location: <craton-url>/regions/6
|
||||
Server: WSGIServer/0.2 CPython/3.5.2
|
||||
x-openstack-request-id: req-6f6bf38e-9cb4-48ac-b915-e0fec77c5d98
|
||||
status:
|
||||
code: 201
|
||||
message: CREATED
|
||||
url: <craton-url>/regions
|
||||
- recorded_at: '2017-03-21T14:50:38'
|
||||
request:
|
||||
body:
|
||||
encoding: utf-8
|
||||
string: "{\n \"region_id\": 6,\n \"device_type\": \"server\",\n \"name\"\
|
||||
: \"host-to-delete\",\n \"cloud_id\": 10,\n \"ip_address\": \"127.0.1.0\"\
|
||||
\n}"
|
||||
headers:
|
||||
Accept: '*/*'
|
||||
Accept-Encoding: gzip, deflate
|
||||
Connection: keep-alive
|
||||
Content-Length: '110'
|
||||
Content-Type: application/json
|
||||
User-Agent: python-cratonclient/0.0.1
|
||||
X-Auth-Project: <craton-demo-project>
|
||||
X-Auth-Token: <craton-demo-token>
|
||||
X-Auth-User: <craton-demo-username>
|
||||
method: POST
|
||||
uri: <craton-url>/hosts
|
||||
response:
|
||||
body:
|
||||
encoding: null
|
||||
string: "{\n \"id\": 7,\n \"ip_address\": \"127.0.1.0\",\n \"region_id\"\
|
||||
: 6,\n \"active\": true,\n \"cloud_id\": 10,\n \"project_id\": \"<craton-demo-project>\"\
|
||||
,\n \"variables\": {},\n \"parent_id\": null,\n \"updated_at\": null,\n\
|
||||
\ \"name\": \"host-to-delete\",\n \"cell_id\": null,\n \"device_type\"\
|
||||
: \"server\",\n \"note\": null,\n \"links\": [\n {\n \"href\": \"\
|
||||
<craton-url>/regions/6\",\n \"rel\": \"up\"\n }\n ],\n \"created_at\"\
|
||||
: \"2017-03-20T23:40:59.817351\"\n}"
|
||||
headers:
|
||||
Content-Length: '451'
|
||||
Content-Type: application/json
|
||||
Date: Mon, 20 Mar 2017 23:40:59 GMT
|
||||
Location: <craton-url>/hosts/7
|
||||
Server: WSGIServer/0.2 CPython/3.5.2
|
||||
x-openstack-request-id: req-0a63c2bf-492e-4bc0-a49a-438bc81b7656
|
||||
status:
|
||||
code: 201
|
||||
message: CREATED
|
||||
url: <craton-url>/hosts
|
||||
- recorded_at: '2017-03-21T14:50:38'
|
||||
request:
|
||||
body:
|
||||
encoding: utf-8
|
||||
string: ''
|
||||
headers:
|
||||
Accept: '*/*'
|
||||
Accept-Encoding: gzip, deflate
|
||||
Connection: keep-alive
|
||||
Content-Length: '0'
|
||||
User-Agent: python-cratonclient/0.0.1
|
||||
X-Auth-Project: <craton-demo-project>
|
||||
X-Auth-Token: <craton-demo-token>
|
||||
X-Auth-User: <craton-demo-username>
|
||||
method: DELETE
|
||||
uri: <craton-url>/hosts/7
|
||||
response:
|
||||
body:
|
||||
encoding: null
|
||||
string: ''
|
||||
headers:
|
||||
Content-Length: '0'
|
||||
Content-Type: application/json
|
||||
Date: Mon, 20 Mar 2017 23:40:59 GMT
|
||||
Server: WSGIServer/0.2 CPython/3.5.2
|
||||
x-openstack-request-id: req-269e2521-d1d5-4312-a415-b2e8b7a91e6e
|
||||
status:
|
||||
code: 204
|
||||
message: NO CONTENT
|
||||
url: <craton-url>/hosts/7
|
||||
- recorded_at: '2017-03-21T14:50:38'
|
||||
request:
|
||||
body:
|
||||
encoding: utf-8
|
||||
string: ''
|
||||
headers:
|
||||
Accept: '*/*'
|
||||
Accept-Encoding: gzip, deflate
|
||||
Connection: keep-alive
|
||||
User-Agent: python-cratonclient/0.0.1
|
||||
X-Auth-Project: <craton-demo-project>
|
||||
X-Auth-Token: <craton-demo-token>
|
||||
X-Auth-User: <craton-demo-username>
|
||||
method: GET
|
||||
uri: <craton-url>/hosts/7
|
||||
response:
|
||||
body:
|
||||
encoding: utf-8
|
||||
string: '{"status": 404, "message": "Not Found"}'
|
||||
headers:
|
||||
Content-Length: '46'
|
||||
Content-Type: text/html; charset=utf-8
|
||||
Date: Mon, 20 Mar 2017 23:41:00 GMT
|
||||
Server: WSGIServer/0.2 CPython/3.5.2
|
||||
x-openstack-request-id: req-3ae97e93-0cca-4e97-afad-3ac4312d19b1
|
||||
status:
|
||||
code: 404
|
||||
message: NOT FOUND
|
||||
url: <craton-url>/hosts/7
|
||||
- recorded_at: '2017-03-21T14:50:38'
|
||||
request:
|
||||
body:
|
||||
encoding: utf-8
|
||||
string: ''
|
||||
headers:
|
||||
Accept: '*/*'
|
||||
Accept-Encoding: gzip, deflate
|
||||
Connection: keep-alive
|
||||
Content-Length: '0'
|
||||
User-Agent: python-cratonclient/0.0.1
|
||||
X-Auth-Project: <craton-demo-project>
|
||||
X-Auth-Token: <craton-demo-token>
|
||||
X-Auth-User: <craton-demo-username>
|
||||
method: DELETE
|
||||
uri: <craton-url>/regions/6
|
||||
response:
|
||||
body:
|
||||
encoding: null
|
||||
string: ''
|
||||
headers:
|
||||
Content-Length: '0'
|
||||
Content-Type: application/json
|
||||
Date: Mon, 20 Mar 2017 23:41:00 GMT
|
||||
Server: WSGIServer/0.2 CPython/3.5.2
|
||||
x-openstack-request-id: req-dc103d8f-ddc7-45a9-a675-2a20518b2a68
|
||||
status:
|
||||
code: 204
|
||||
message: NO CONTENT
|
||||
url: <craton-url>/regions/6
|
||||
- recorded_at: '2017-03-21T14:50:38'
|
||||
request:
|
||||
body:
|
||||
encoding: utf-8
|
||||
string: ''
|
||||
headers:
|
||||
Accept: '*/*'
|
||||
Accept-Encoding: gzip, deflate
|
||||
Connection: keep-alive
|
||||
Content-Length: '0'
|
||||
User-Agent: python-cratonclient/0.0.1
|
||||
X-Auth-Project: <craton-demo-project>
|
||||
X-Auth-Token: <craton-demo-token>
|
||||
X-Auth-User: <craton-demo-username>
|
||||
method: DELETE
|
||||
uri: <craton-url>/clouds/10
|
||||
response:
|
||||
body:
|
||||
encoding: null
|
||||
string: ''
|
||||
headers:
|
||||
Content-Length: '0'
|
||||
Content-Type: application/json
|
||||
Date: Mon, 20 Mar 2017 23:41:00 GMT
|
||||
Server: WSGIServer/0.2 CPython/3.5.2
|
||||
x-openstack-request-id: req-332fa9fc-e12f-46e9-922b-6ec1ee9bc2b3
|
||||
status:
|
||||
code: 204
|
||||
message: NO CONTENT
|
||||
url: <craton-url>/clouds/10
|
||||
recorded_with: betamax/0.8.0
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,239 @@
|
|||
http_interactions:
|
||||
- recorded_at: '2017-03-21T14:50:37'
|
||||
request:
|
||||
body:
|
||||
encoding: utf-8
|
||||
string: "{\n \"name\": \"cloud-TestHosts-test_update\"\n}"
|
||||
headers:
|
||||
Accept: '*/*'
|
||||
Accept-Encoding: gzip, deflate
|
||||
Connection: keep-alive
|
||||
Content-Length: '39'
|
||||
Content-Type: application/json
|
||||
User-Agent: python-cratonclient/0.0.1
|
||||
X-Auth-Project: <craton-demo-project>
|
||||
X-Auth-Token: <craton-demo-token>
|
||||
X-Auth-User: <craton-demo-username>
|
||||
method: POST
|
||||
uri: <craton-url>/clouds
|
||||
response:
|
||||
body:
|
||||
encoding: null
|
||||
string: "{\n \"variables\": {},\n \"id\": 9,\n \"name\": \"cloud-TestHosts-test_update\"\
|
||||
,\n \"note\": null,\n \"created_at\": \"2017-03-20T23:40:59.516122\",\n\
|
||||
\ \"updated_at\": null,\n \"project_id\": \"<craton-demo-project>\"\n}"
|
||||
headers:
|
||||
Content-Length: '214'
|
||||
Content-Type: application/json
|
||||
Date: Mon, 20 Mar 2017 23:40:59 GMT
|
||||
Location: <craton-url>/clouds/9
|
||||
Server: WSGIServer/0.2 CPython/3.5.2
|
||||
x-openstack-request-id: req-a1f5018e-9b49-4346-8f74-efee8339b882
|
||||
status:
|
||||
code: 201
|
||||
message: CREATED
|
||||
url: <craton-url>/clouds
|
||||
- recorded_at: '2017-03-21T14:50:37'
|
||||
request:
|
||||
body:
|
||||
encoding: utf-8
|
||||
string: "{\n \"name\": \"region-TestHosts-test_update\",\n \"cloud_id\": 9\n\
|
||||
}"
|
||||
headers:
|
||||
Accept: '*/*'
|
||||
Accept-Encoding: gzip, deflate
|
||||
Connection: keep-alive
|
||||
Content-Length: '55'
|
||||
Content-Type: application/json
|
||||
User-Agent: python-cratonclient/0.0.1
|
||||
X-Auth-Project: <craton-demo-project>
|
||||
X-Auth-Token: <craton-demo-token>
|
||||
X-Auth-User: <craton-demo-username>
|
||||
method: POST
|
||||
uri: <craton-url>/regions
|
||||
response:
|
||||
body:
|
||||
encoding: null
|
||||
string: "{\n \"variables\": {},\n \"id\": 5,\n \"name\": \"region-TestHosts-test_update\"\
|
||||
,\n \"note\": null,\n \"created_at\": \"2017-03-20T23:40:59.653669\",\n\
|
||||
\ \"updated_at\": null,\n \"cloud_id\": 9,\n \"project_id\": \"<craton-demo-project>\"\
|
||||
\n}"
|
||||
headers:
|
||||
Content-Length: '232'
|
||||
Content-Type: application/json
|
||||
Date: Mon, 20 Mar 2017 23:40:59 GMT
|
||||
Location: <craton-url>/regions/5
|
||||
Server: WSGIServer/0.2 CPython/3.5.2
|
||||
x-openstack-request-id: req-c89e94bc-aa5a-4622-9d53-b39dfd35af5b
|
||||
status:
|
||||
code: 201
|
||||
message: CREATED
|
||||
url: <craton-url>/regions
|
||||
- recorded_at: '2017-03-21T14:50:38'
|
||||
request:
|
||||
body:
|
||||
encoding: utf-8
|
||||
string: "{\n \"region_id\": 5,\n \"device_type\": \"server\",\n \"name\"\
|
||||
: \"host-0\",\n \"cloud_id\": 9,\n \"ip_address\": \"127.0.1.0\"\n}"
|
||||
headers:
|
||||
Accept: '*/*'
|
||||
Accept-Encoding: gzip, deflate
|
||||
Connection: keep-alive
|
||||
Content-Length: '101'
|
||||
Content-Type: application/json
|
||||
User-Agent: python-cratonclient/0.0.1
|
||||
X-Auth-Project: <craton-demo-project>
|
||||
X-Auth-Token: <craton-demo-token>
|
||||
X-Auth-User: <craton-demo-username>
|
||||
method: POST
|
||||
uri: <craton-url>/hosts
|
||||
response:
|
||||
body:
|
||||
encoding: null
|
||||
string: "{\n \"id\": 5,\n \"ip_address\": \"127.0.1.0\",\n \"region_id\"\
|
||||
: 5,\n \"active\": true,\n \"cloud_id\": 9,\n \"project_id\": \"<craton-demo-project>\"\
|
||||
,\n \"variables\": {},\n \"parent_id\": null,\n \"updated_at\": null,\n\
|
||||
\ \"name\": \"host-0\",\n \"cell_id\": null,\n \"device_type\": \"server\"\
|
||||
,\n \"note\": null,\n \"links\": [\n {\n \"href\": \"<craton-url>/regions/5\"\
|
||||
,\n \"rel\": \"up\"\n }\n ],\n \"created_at\": \"2017-03-20T23:40:59.766218\"\
|
||||
\n}"
|
||||
headers:
|
||||
Content-Length: '442'
|
||||
Content-Type: application/json
|
||||
Date: Mon, 20 Mar 2017 23:40:59 GMT
|
||||
Location: <craton-url>/hosts/5
|
||||
Server: WSGIServer/0.2 CPython/3.5.2
|
||||
x-openstack-request-id: req-2f98aecc-8f92-4ff4-9837-1b455cd36f86
|
||||
status:
|
||||
code: 201
|
||||
message: CREATED
|
||||
url: <craton-url>/hosts
|
||||
- recorded_at: '2017-03-21T14:50:38'
|
||||
request:
|
||||
body:
|
||||
encoding: utf-8
|
||||
string: "{\n \"note\": \"This is an updated note\",\n \"ip_address\": \"127.0.1.1\"\
|
||||
\n}"
|
||||
headers:
|
||||
Accept: '*/*'
|
||||
Accept-Encoding: gzip, deflate
|
||||
Connection: keep-alive
|
||||
Content-Length: '62'
|
||||
Content-Type: application/json
|
||||
User-Agent: python-cratonclient/0.0.1
|
||||
X-Auth-Project: <craton-demo-project>
|
||||
X-Auth-Token: <craton-demo-token>
|
||||
X-Auth-User: <craton-demo-username>
|
||||
method: PUT
|
||||
uri: <craton-url>/hosts/5
|
||||
response:
|
||||
body:
|
||||
encoding: null
|
||||
string: "{\n \"id\": 5,\n \"ip_address\": \"127.0.1.1\",\n \"region_id\"\
|
||||
: 5,\n \"active\": true,\n \"cloud_id\": 9,\n \"project_id\": \"<craton-demo-project>\"\
|
||||
,\n \"parent_id\": null,\n \"updated_at\": \"2017-03-20T23:40:59.877079\"\
|
||||
,\n \"name\": \"host-0\",\n \"cell_id\": null,\n \"device_type\": \"server\"\
|
||||
,\n \"note\": \"This is an updated note\",\n \"links\": [\n {\n \
|
||||
\ \"href\": \"<craton-url>/regions/5\",\n \"rel\": \"up\"\n }\n ],\n\
|
||||
\ \"created_at\": \"2017-03-20T23:40:59.000000\"\n}"
|
||||
headers:
|
||||
Content-Length: '468'
|
||||
Content-Type: application/json
|
||||
Date: Mon, 20 Mar 2017 23:40:59 GMT
|
||||
Server: WSGIServer/0.2 CPython/3.5.2
|
||||
x-openstack-request-id: req-38ce18bc-7de7-436f-a6a4-944b906effe3
|
||||
status:
|
||||
code: 200
|
||||
message: OK
|
||||
url: <craton-url>/hosts/5
|
||||
- recorded_at: '2017-03-21T14:50:38'
|
||||
request:
|
||||
body:
|
||||
encoding: utf-8
|
||||
string: ''
|
||||
headers:
|
||||
Accept: '*/*'
|
||||
Accept-Encoding: gzip, deflate
|
||||
Connection: keep-alive
|
||||
Content-Length: '0'
|
||||
User-Agent: python-cratonclient/0.0.1
|
||||
X-Auth-Project: <craton-demo-project>
|
||||
X-Auth-Token: <craton-demo-token>
|
||||
X-Auth-User: <craton-demo-username>
|
||||
method: DELETE
|
||||
uri: <craton-url>/hosts/5
|
||||
response:
|
||||
body:
|
||||
encoding: null
|
||||
string: ''
|
||||
headers:
|
||||
Content-Length: '0'
|
||||
Content-Type: application/json
|
||||
Date: Mon, 20 Mar 2017 23:40:59 GMT
|
||||
Server: WSGIServer/0.2 CPython/3.5.2
|
||||
x-openstack-request-id: req-e2c4967f-aca1-4065-8e66-42efb79e6754
|
||||
status:
|
||||
code: 204
|
||||
message: NO CONTENT
|
||||
url: <craton-url>/hosts/5
|
||||
- recorded_at: '2017-03-21T14:50:38'
|
||||
request:
|
||||
body:
|
||||
encoding: utf-8
|
||||
string: ''
|
||||
headers:
|
||||
Accept: '*/*'
|
||||
Accept-Encoding: gzip, deflate
|
||||
Connection: keep-alive
|
||||
Content-Length: '0'
|
||||
User-Agent: python-cratonclient/0.0.1
|
||||
X-Auth-Project: <craton-demo-project>
|
||||
X-Auth-Token: <craton-demo-token>
|
||||
X-Auth-User: <craton-demo-username>
|
||||
method: DELETE
|
||||
uri: <craton-url>/regions/5
|
||||
response:
|
||||
body:
|
||||
encoding: null
|
||||
string: ''
|
||||
headers:
|
||||
Content-Length: '0'
|
||||
Content-Type: application/json
|
||||
Date: Mon, 20 Mar 2017 23:41:00 GMT
|
||||
Server: WSGIServer/0.2 CPython/3.5.2
|
||||
x-openstack-request-id: req-6bca4f72-9c55-4bf8-affd-25492391be45
|
||||
status:
|
||||
code: 204
|
||||
message: NO CONTENT
|
||||
url: <craton-url>/regions/5
|
||||
- recorded_at: '2017-03-21T14:50:38'
|
||||
request:
|
||||
body:
|
||||
encoding: utf-8
|
||||
string: ''
|
||||
headers:
|
||||
Accept: '*/*'
|
||||
Accept-Encoding: gzip, deflate
|
||||
Connection: keep-alive
|
||||
Content-Length: '0'
|
||||
User-Agent: python-cratonclient/0.0.1
|
||||
X-Auth-Project: <craton-demo-project>
|
||||
X-Auth-Token: <craton-demo-token>
|
||||
X-Auth-User: <craton-demo-username>
|
||||
method: DELETE
|
||||
uri: <craton-url>/clouds/9
|
||||
response:
|
||||
body:
|
||||
encoding: null
|
||||
string: ''
|
||||
headers:
|
||||
Content-Length: '0'
|
||||
Content-Type: application/json
|
||||
Date: Mon, 20 Mar 2017 23:41:00 GMT
|
||||
Server: WSGIServer/0.2 CPython/3.5.2
|
||||
x-openstack-request-id: req-de348783-f7ce-488b-a1b1-28ee8b7f3f37
|
||||
status:
|
||||
code: 204
|
||||
message: NO CONTENT
|
||||
url: <craton-url>/clouds/9
|
||||
recorded_with: betamax/0.8.0
|
|
@ -0,0 +1,112 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
"""Module containing the base logic for cratonclient integration tests."""
|
||||
import os
|
||||
|
||||
import betamax
|
||||
from betamax_matchers import json_body
|
||||
from keystoneauth1.fixture import keystoneauth_betamax as ksabetamax
|
||||
|
||||
from cratonclient import auth
|
||||
from cratonclient.tests import base
|
||||
from cratonclient.v1 import client
|
||||
|
||||
# NOTE(sigmavirus24): This allows us to use ``'json-body'`` as a matcher below
|
||||
betamax.Betamax.register_request_matcher(json_body.JSONBodyMatcher)
|
||||
envget = os.environ.get
|
||||
|
||||
CRATON_DEMO_USERNAME = envget('CRATON_DEMO_USERNAME', 'demo')
|
||||
CRATON_DEMO_TOKEN = envget('CRATON_DEMO_TOKEN', 'demo')
|
||||
CRATON_DEMO_PROJECT = envget('CRATON_DEMO_PROJECT',
|
||||
'b9f10eca66ac4c279c139d01e65f96b5')
|
||||
CRATON_ROOT_USERNAME = envget('CRATON_ROOT_USERNAME', 'root')
|
||||
CRATON_ROOT_TOKEN = envget('CRATON_ROOT_TOKEN', 'root')
|
||||
CRATON_ROOT_PROJECT = envget('CRATON_ROOT_PROJECT',
|
||||
'b9f10eca66ac4c279c139d01e65f96b5')
|
||||
CRATON_URL = envget('CRATON_URL', 'http://127.0.0.1:8080/v1')
|
||||
|
||||
|
||||
class BetamaxTestCase(base.TestCase):
|
||||
"""This sets up Betamax with Keystoneauth1 fixture for integration tests.
|
||||
|
||||
This relies on existing keystoneauth1 integration with the Betamax library
|
||||
to make recording integration tests easier.
|
||||
"""
|
||||
|
||||
CASSETTE_LIBRARY_DIR = 'cratonclient/tests/cassettes/'
|
||||
|
||||
def generate_cassette_name(self):
|
||||
"""Generate a cassette name for the current test."""
|
||||
full_test_name = self.id()
|
||||
module, test_class, test_method = full_test_name.rsplit('.', 2)
|
||||
return test_class + '-' + test_method
|
||||
|
||||
def setUp(self):
|
||||
"""Set up betamax fixture for cratonclient."""
|
||||
super(BetamaxTestCase, self).setUp()
|
||||
self.cassette_name = self.generate_cassette_name()
|
||||
self.record_mode = envget('BETAMAX_RECORD_MODE', 'once')
|
||||
self.url = CRATON_URL
|
||||
self.betamax_fixture = self.useFixture(ksabetamax.BetamaxFixture(
|
||||
cassette_name=self.cassette_name,
|
||||
cassette_library_dir=self.CASSETTE_LIBRARY_DIR,
|
||||
record=self.record_mode,
|
||||
))
|
||||
self.demo_credentials = {
|
||||
'username': CRATON_DEMO_USERNAME,
|
||||
'token': CRATON_DEMO_TOKEN,
|
||||
'project': CRATON_DEMO_PROJECT,
|
||||
}
|
||||
self.root_credentials = {
|
||||
'username': CRATON_ROOT_USERNAME,
|
||||
'token': CRATON_ROOT_TOKEN,
|
||||
'project': CRATON_ROOT_PROJECT,
|
||||
}
|
||||
|
||||
def create_client(self, username, token, project):
|
||||
"""Create a Craton client using Craton Auth."""
|
||||
self.session = auth.craton_auth(
|
||||
username=username,
|
||||
token=token,
|
||||
project_id=project,
|
||||
)
|
||||
self.client = client.Client(self.session, self.url)
|
||||
|
||||
def create_demo_client(self):
|
||||
"""Set up cratonclient with the demo user."""
|
||||
self.create_client(**self.demo_credentials)
|
||||
|
||||
|
||||
with betamax.Betamax.configure() as config:
|
||||
config.define_cassette_placeholder(
|
||||
'<craton-demo-username>', CRATON_DEMO_USERNAME,
|
||||
)
|
||||
config.define_cassette_placeholder(
|
||||
'<craton-demo-token>', CRATON_DEMO_TOKEN,
|
||||
)
|
||||
config.define_cassette_placeholder(
|
||||
'<craton-demo-project>', CRATON_DEMO_PROJECT,
|
||||
)
|
||||
config.define_cassette_placeholder(
|
||||
'<craton-root-username>', CRATON_ROOT_USERNAME,
|
||||
)
|
||||
config.define_cassette_placeholder(
|
||||
'<craton-root-token>', CRATON_ROOT_TOKEN,
|
||||
)
|
||||
config.define_cassette_placeholder(
|
||||
'<craton-root-project>', CRATON_ROOT_PROJECT,
|
||||
)
|
||||
config.define_cassette_placeholder(
|
||||
'<craton-url>', CRATON_URL,
|
||||
)
|
|
@ -0,0 +1 @@
|
|||
"""Integration tests for Python API client for v1 API."""
|
|
@ -0,0 +1,79 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
"""The integration tests for the cratonclient.v1.devices."""
|
||||
|
||||
from cratonclient.tests.integration import base
|
||||
|
||||
|
||||
class TestDevices(base.BetamaxTestCase):
|
||||
"""DevicesManager integration tests."""
|
||||
|
||||
def cleanupCloud(self, cloud):
|
||||
"""Add a cleanup task for this cloud."""
|
||||
self.addCleanup(self.client.clouds.delete, cloud.id)
|
||||
return cloud
|
||||
|
||||
def cleanupRegion(self, region):
|
||||
"""Add a cleanup task for this region."""
|
||||
self.addCleanup(self.client.regions.delete, region.id)
|
||||
return region
|
||||
|
||||
def cleanupCell(self, cell):
|
||||
"""Add a cleanup task for this cell."""
|
||||
self.addCleanup(self.client.cells.delete, cell.id)
|
||||
return cell
|
||||
|
||||
def cleanupHost(self, host):
|
||||
"""Add a cleanup task for this host."""
|
||||
self.addCleanup(self.client.hosts.delete, host.id)
|
||||
return host
|
||||
|
||||
def setUp(self):
|
||||
"""Set up our demo user client."""
|
||||
super(TestDevices, self).setUp()
|
||||
self.create_demo_client()
|
||||
test_name = self.cassette_name.split('-', 1)[-1]
|
||||
self.cloud = self.cleanupCloud(self.client.clouds.create(
|
||||
name='cloud_{}'.format(test_name),
|
||||
))
|
||||
self.region = self.cleanupRegion(self.client.regions.create(
|
||||
name='region_{}'.format(test_name),
|
||||
cloud_id=self.cloud.id,
|
||||
))
|
||||
self.cells = [
|
||||
self.cleanupCell(self.client.cells.create(
|
||||
name='cell_{}_{}'.format(test_name, i),
|
||||
region_id=self.region.id,
|
||||
cloud_id=self.cloud.id,
|
||||
))
|
||||
for i in range(4)
|
||||
]
|
||||
self.hosts = [
|
||||
self.cleanupHost(self.client.hosts.create(
|
||||
name='host_{}_{}'.format(test_name, i),
|
||||
cell_id=self.cells[i % 4].id,
|
||||
region_id=self.region.id,
|
||||
cloud_id=self.cloud.id,
|
||||
device_type='server',
|
||||
ip_address='127.0.1.{}'.format(i),
|
||||
))
|
||||
for i in range(35)
|
||||
]
|
||||
# NOTE(sigmavirus24): The API does not presently support
|
||||
# /v1/network-devices
|
||||
# self.network_devices = [
|
||||
# self.cleanupNetworkDevice(self.client.network_devices.create(
|
||||
# ))
|
||||
# for i in range(35)
|
||||
# ]
|
|
@ -0,0 +1,116 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
"""Module containing the cratonclient.v1.hosts integration tests."""
|
||||
|
||||
from cratonclient import exceptions
|
||||
from cratonclient.tests.integration import base
|
||||
|
||||
|
||||
class TestHosts(base.BetamaxTestCase):
|
||||
"""HostsManager integration tests."""
|
||||
|
||||
def setUp(self):
|
||||
"""Prepare our hosts test case."""
|
||||
super(TestHosts, self).setUp()
|
||||
self.create_demo_client()
|
||||
self.cloud = self.client.clouds.create(
|
||||
name='cloud-{}'.format(self.cassette_name),
|
||||
)
|
||||
self.addCleanup(self.client.clouds.delete, self.cloud.id)
|
||||
self.region = self.client.regions.create(
|
||||
name='region-{}'.format(self.cassette_name),
|
||||
cloud_id=self.cloud.id,
|
||||
)
|
||||
self.addCleanup(self.client.regions.delete, self.region.id)
|
||||
|
||||
def cleanupHost(self, host):
|
||||
"""Add a cleanup task for this host."""
|
||||
self.addCleanup(self.client.hosts.delete, host.id)
|
||||
return host
|
||||
|
||||
def test_create(self):
|
||||
"""Test creation of hosts via the Python API."""
|
||||
host = self.cleanupHost(self.client.hosts.create(
|
||||
name='host-0',
|
||||
ip_address='127.0.1.0',
|
||||
device_type='server',
|
||||
region_id=self.region.id,
|
||||
cloud_id=self.cloud.id,
|
||||
))
|
||||
|
||||
self.assertEqual('host-0', host.name)
|
||||
|
||||
def test_delete(self):
|
||||
"""Test deletion of a host via the Python API."""
|
||||
host = self.client.hosts.create(
|
||||
name='host-to-delete',
|
||||
ip_address='127.0.1.0',
|
||||
device_type='server',
|
||||
region_id=self.region.id,
|
||||
cloud_id=self.cloud.id,
|
||||
)
|
||||
|
||||
self.assertTrue(self.client.hosts.delete(host.id))
|
||||
self.assertRaises(exceptions.NotFound, self.client.hosts.get,
|
||||
host.id)
|
||||
|
||||
def test_list_autopaginates(self):
|
||||
"""Verify listing of hosts via the Python API."""
|
||||
for i in range(0, 62):
|
||||
self.cleanupHost(self.client.hosts.create(
|
||||
name='host-{}'.format(i),
|
||||
ip_address='127.0.1.{}'.format(i),
|
||||
device_type='server',
|
||||
region_id=self.region.id,
|
||||
cloud_id=self.cloud.id,
|
||||
))
|
||||
|
||||
hosts = list(self.client.hosts.list())
|
||||
self.assertEqual(62, len(hosts))
|
||||
|
||||
def test_list_only_retrieves_first_page(self):
|
||||
"""Verify the behaviour of not auto-paginating listing."""
|
||||
for i in range(0, 32):
|
||||
self.cleanupHost(self.client.hosts.create(
|
||||
name='host-{}'.format(i),
|
||||
ip_address='127.0.1.{}'.format(i),
|
||||
device_type='server',
|
||||
region_id=self.region.id,
|
||||
cloud_id=self.cloud.id,
|
||||
))
|
||||
|
||||
hosts = list(self.client.hosts.list(autopaginate=False))
|
||||
self.assertEqual(30, len(hosts))
|
||||
|
||||
def test_update(self):
|
||||
"""Verify the ability to update a host."""
|
||||
host = self.cleanupHost(self.client.hosts.create(
|
||||
name='host-0',
|
||||
ip_address='127.0.1.0',
|
||||
device_type='server',
|
||||
region_id=self.region.id,
|
||||
cloud_id=self.cloud.id,
|
||||
))
|
||||
|
||||
self.assertTrue(host.active)
|
||||
|
||||
updated_host = self.client.hosts.update(
|
||||
item_id=host.id,
|
||||
note='This is an updated note',
|
||||
ip_address='127.0.1.1',
|
||||
)
|
||||
|
||||
self.assertEqual('host-0', updated_host.name)
|
||||
self.assertEqual(host.id, updated_host.id)
|
||||
self.assertEqual('This is an updated note', updated_host.note)
|
|
@ -0,0 +1,67 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
"""Unit tests for cratonclient.exceptions."""
|
||||
|
||||
from cratonclient import exceptions as exc
|
||||
from cratonclient.tests import base
|
||||
|
||||
import mock
|
||||
|
||||
|
||||
class TestExceptions(base.TestCase):
|
||||
"""Tests for our exception handling convenience functions."""
|
||||
|
||||
client_error_statuses = [
|
||||
400, 401, 403, 404, 405, 406, 407, 409, 410, 411, 412, 413, 414, 415,
|
||||
416, 422,
|
||||
]
|
||||
|
||||
server_error_statuses = [
|
||||
500,
|
||||
]
|
||||
|
||||
def mock_keystoneauth_exception_from(self, status_code):
|
||||
"""Create a fake keystoneauth1 exception with a response attribute."""
|
||||
exception = mock.Mock()
|
||||
exception.response = self.mock_response_from(status_code)
|
||||
exception.http_status = status_code
|
||||
return exception
|
||||
|
||||
def mock_response_from(self, status_code):
|
||||
"""Create a mock requests.Response object."""
|
||||
response = mock.Mock()
|
||||
response.status_code = status_code
|
||||
return response
|
||||
|
||||
def test_error_from_4xx(self):
|
||||
"""Verify error_from's behvaiour for 4xx status codes."""
|
||||
for status in self.client_error_statuses:
|
||||
response = self.mock_response_from(status)
|
||||
self.assertIsInstance(exc.error_from(response),
|
||||
exc.HTTPClientError)
|
||||
|
||||
def test_error_from_5xx(self):
|
||||
"""Verify error_from's behvaiour for 5xx status codes."""
|
||||
for status in self.server_error_statuses:
|
||||
response = self.mock_response_from(status)
|
||||
self.assertIsInstance(exc.error_from(response),
|
||||
exc.HTTPServerError)
|
||||
|
||||
def test_raise_from(self):
|
||||
"""Verify raise_from handles keystoneauth1 exceptions."""
|
||||
for status in (self.client_error_statuses +
|
||||
self.server_error_statuses):
|
||||
ksaexception = self.mock_keystoneauth_exception_from(status)
|
||||
exception = exc.raise_from(ksaexception)
|
||||
self.assertIs(ksaexception, exception.original_exception)
|
|
@ -2,6 +2,8 @@
|
|||
# of appearance. Changing the order has an impact on the overall integration
|
||||
# process, which may cause wedges in the gate later.
|
||||
|
||||
betamax>=0.7.0 # Apache-2.0
|
||||
betamax-matchers>=0.4.0 # Apache-2.0
|
||||
doc8 # Apache-2.0
|
||||
hacking<0.12,>=0.10.0
|
||||
flake8-docstrings==0.2.1.post1 # MIT
|
||||
|
|
Loading…
Reference in New Issue