Add integration tests for clouds client

This adds more integration tests for the v1 client, specifically for
/v1/clouds.

Further, this introduces a new test method for the integration tests as
it was found to be reimplemented in a few different test modules. This
replaces the pattern used in the existing tests with the new pattern.

Implements: bp testing-plan
Change-Id: Ic4e342cf01be288b7a7c453659580c57169b1022
This commit is contained in:
Ian Cordasco 2017-03-14 14:30:56 -05:00
parent 4f0b316244
commit 2e34424cda
9 changed files with 9233 additions and 5 deletions

File diff suppressed because it is too large Load Diff

@ -0,0 +1,68 @@
http_interactions:
- recorded_at: '2017-03-21T15:37:24'
request:
body:
encoding: utf-8
string: "{\n \"variables\": {\n \"cloud-var\": \"var-value\"\n },\n \"\
note\": \"This is a test cloud.\",\n \"name\": \"cloud-creation\"\n}"
headers:
Accept: '*/*'
Accept-Encoding: gzip, deflate
Connection: keep-alive
Content-Length: '100'
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 \"updated_at\": null,\n \"project_id\": \"<craton-demo-project>\"\
,\n \"note\": \"This is a test cloud.\",\n \"id\": 51,\n \"created_at\"\
: \"2017-03-21T00:27:49.238178\",\n \"variables\": {\n \"cloud-var\":\
\ \"var-value\"\n },\n \"name\": \"cloud-creation\"\n}"
headers:
Content-Length: '253'
Content-Type: application/json
Date: Tue, 21 Mar 2017 00:27:49 GMT
Location: <craton-url>/clouds/51
Server: WSGIServer/0.2 CPython/3.5.2
x-openstack-request-id: req-3bd28970-bd1a-465a-9598-d42db902336e
status:
code: 201
message: CREATED
url: <craton-url>/clouds
- recorded_at: '2017-03-21T15:37:24'
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/51
response:
body:
encoding: null
string: ''
headers:
Content-Length: '0'
Content-Type: application/json
Date: Tue, 21 Mar 2017 00:27:49 GMT
Server: WSGIServer/0.2 CPython/3.5.2
x-openstack-request-id: req-50ddeb39-ff4e-4070-8f13-f2664e27075f
status:
code: 204
message: NO CONTENT
url: <craton-url>/clouds/51
recorded_with: betamax/0.8.0

@ -0,0 +1,95 @@
http_interactions:
- recorded_at: '2017-03-21T15:37:24'
request:
body:
encoding: utf-8
string: "{\n \"name\": \"cloud-deletion\"\n}"
headers:
Accept: '*/*'
Accept-Encoding: gzip, deflate
Connection: keep-alive
Content-Length: '26'
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 \"updated_at\": null,\n \"project_id\": \"<craton-demo-project>\"\
,\n \"note\": null,\n \"id\": 54,\n \"created_at\": \"2017-03-21T00:27:49.348024\"\
,\n \"variables\": {},\n \"name\": \"cloud-deletion\"\n}"
headers:
Content-Length: '202'
Content-Type: application/json
Date: Tue, 21 Mar 2017 00:27:49 GMT
Location: <craton-url>/clouds/54
Server: WSGIServer/0.2 CPython/3.5.2
x-openstack-request-id: req-f495907c-a15f-4645-8c1b-6fe6c5364cf1
status:
code: 201
message: CREATED
url: <craton-url>/clouds
- recorded_at: '2017-03-21T15:37:24'
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/54
response:
body:
encoding: null
string: ''
headers:
Content-Length: '0'
Content-Type: application/json
Date: Tue, 21 Mar 2017 00:27:49 GMT
Server: WSGIServer/0.2 CPython/3.5.2
x-openstack-request-id: req-176a55f2-30a5-48a0-b606-66d7785e385b
status:
code: 204
message: NO CONTENT
url: <craton-url>/clouds/54
- recorded_at: '2017-03-21T15:37:24'
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>/clouds/54
response:
body:
encoding: utf-8
string: '{"status": 404, "message": "Not Found"}'
headers:
Content-Length: '46'
Content-Type: text/html; charset=utf-8
Date: Tue, 21 Mar 2017 00:27:49 GMT
Server: WSGIServer/0.2 CPython/3.5.2
x-openstack-request-id: req-247795f2-7474-49c6-8e18-5390c12deac3
status:
code: 404
message: NOT FOUND
url: <craton-url>/clouds/54
recorded_with: betamax/0.8.0

File diff suppressed because it is too large Load Diff

@ -0,0 +1,101 @@
http_interactions:
- recorded_at: '2017-03-21T15:37:23'
request:
body:
encoding: utf-8
string: "{\n \"note\": \"Original note.\",\n \"name\": \"cloud-to-update\"\
\n}"
headers:
Accept: '*/*'
Accept-Encoding: gzip, deflate
Connection: keep-alive
Content-Length: '53'
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 \"updated_at\": null,\n \"project_id\": \"<craton-demo-project>\"\
,\n \"note\": \"Original note.\",\n \"id\": 44,\n \"created_at\": \"2017-03-21T00:27:48.950481\"\
,\n \"variables\": {},\n \"name\": \"cloud-to-update\"\n}"
headers:
Content-Length: '215'
Content-Type: application/json
Date: Tue, 21 Mar 2017 00:27:48 GMT
Location: <craton-url>/clouds/44
Server: WSGIServer/0.2 CPython/3.5.2
x-openstack-request-id: req-fa3c730f-aae8-463a-90a6-eecb670dff0d
status:
code: 201
message: CREATED
url: <craton-url>/clouds
- recorded_at: '2017-03-21T15:37:23'
request:
body:
encoding: utf-8
string: "{\n \"note\": \"Updated note.\",\n \"name\": \"updated-cloud\"\n}"
headers:
Accept: '*/*'
Accept-Encoding: gzip, deflate
Connection: keep-alive
Content-Length: '50'
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>/clouds/44
response:
body:
encoding: null
string: "{\n \"updated_at\": \"2017-03-21T00:27:49.011515\",\n \"project_id\"\
: \"<craton-demo-project>\",\n \"note\": \"Updated note.\",\n \"id\": 44,\n\
\ \"created_at\": \"2017-03-21T00:27:48.000000\",\n \"name\": \"updated-cloud\"\
\n}"
headers:
Content-Length: '217'
Content-Type: application/json
Date: Tue, 21 Mar 2017 00:27:49 GMT
Server: WSGIServer/0.2 CPython/3.5.2
x-openstack-request-id: req-5acfb733-4eee-4a77-8227-97a7781227c9
status:
code: 200
message: OK
url: <craton-url>/clouds/44
- recorded_at: '2017-03-21T15:37:23'
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/44
response:
body:
encoding: null
string: ''
headers:
Content-Length: '0'
Content-Type: application/json
Date: Tue, 21 Mar 2017 00:27:49 GMT
Server: WSGIServer/0.2 CPython/3.5.2
x-openstack-request-id: req-88a3a81c-f0bc-400f-8459-322890873ba8
status:
code: 204
message: NO CONTENT
url: <craton-url>/clouds/44
recorded_with: betamax/0.8.0

@ -19,6 +19,7 @@ from betamax_matchers import json_body
from keystoneauth1.fixture import keystoneauth_betamax as ksabetamax from keystoneauth1.fixture import keystoneauth_betamax as ksabetamax
from cratonclient import auth from cratonclient import auth
from cratonclient import exceptions
from cratonclient.tests import base from cratonclient.tests import base
from cratonclient.v1 import client from cratonclient.v1 import client
@ -74,6 +75,10 @@ class BetamaxTestCase(base.TestCase):
'project': CRATON_ROOT_PROJECT, 'project': CRATON_ROOT_PROJECT,
} }
def assertNotFound(self, func, item_id):
"""Assert that the item referenced by item_id 404s."""
self.assertRaises(exceptions.NotFound, func, item_id)
def cleanupHost(self, host): def cleanupHost(self, host):
"""Add a cleanup task for the host.""" """Add a cleanup task for the host."""
self.addCleanup(self.client.hosts.delete, host.id) self.addCleanup(self.client.hosts.delete, host.id)

@ -13,7 +13,6 @@
# under the License. # under the License.
"""Module containing the cratonclient.v1.cells integration tests.""" """Module containing the cratonclient.v1.cells integration tests."""
from cratonclient import exceptions
from cratonclient.tests.integration import base from cratonclient.tests.integration import base
@ -58,7 +57,7 @@ class TestCells(base.BetamaxTestCase):
self.assertEqual('cell-to-delete', cell.name) self.assertEqual('cell-to-delete', cell.name)
self.assertTrue(self.client.cells.delete(cell.id)) self.assertTrue(self.client.cells.delete(cell.id))
self.assertRaises(exceptions.NotFound, self.client.cells.get, cell.id) self.assertNotFound(self.client.cells.get, cell.id)
def test_autopagination_when_listing(self): def test_autopagination_when_listing(self):
"""Verify the client autopaginates lists of cells.""" """Verify the client autopaginates lists of cells."""

@ -0,0 +1,103 @@
# -*- 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.clouds."""
from cratonclient.tests.integration import base
class TestClouds(base.BetamaxTestCase):
"""CloudsManager integration tests."""
def setUp(self):
"""Prepare our clouds manager test case."""
super(TestClouds, self).setUp()
self.create_demo_client()
def test_create(self):
"""Test cloud creation via the API."""
note = 'This is a test cloud.'
cloud = self.cleanupCloud(self.client.clouds.create(
name='cloud-creation',
note=note,
variables={'cloud-var': 'var-value'},
))
self.assertEqual('cloud-creation', cloud.name)
self.assertEqual(note, cloud.note)
self.assertEqual({'cloud-var': 'var-value'},
cloud.to_dict()['variables'])
def test_delete(self):
"""Verify the client can delete a cloud."""
cloud = self.client.clouds.create(name='cloud-deletion')
self.assertEqual('cloud-deletion', cloud.name)
self.assertTrue(self.client.clouds.delete(cloud.id))
self.assertNotFound(self.client.clouds.get, cloud.id)
def test_autopagination_when_listing(self):
"""Verify the client autopaginates lists of clouds."""
note_str = 'This cloud was created to test pagination. ({}/62)'
for i in range(0, 62):
self.cleanupCloud(self.client.clouds.create(
name='cloud-{}'.format(i),
note=note_str.format(i),
))
cells = list(self.client.clouds.list())
self.assertEqual(62, len(cells))
def test_manual_pagination(self):
"""Verify manual pagination of /v1/clouds."""
note_str = 'This cloud was created to test pagination. ({}/62)'
for i in range(0, 62):
self.cleanupCloud(self.client.clouds.create(
name='cloud-{}'.format(i),
note=note_str.format(i),
))
first_page = list(self.client.clouds.list(autopaginate=False))
self.assertEqual(30, len(first_page))
next_page = list(self.client.clouds.list(
autopaginate=False,
marker=first_page[-1].id,
))
self.assertEqual(30, len(next_page))
last_page = list(self.client.clouds.list(
autopaginate=False,
marker=next_page[-1].id,
))
self.assertEqual(2, len(last_page))
def test_update_existing_cloud(self):
"""Test that the client allows a cloud to be deleted."""
cloud = self.cleanupCloud(self.client.clouds.create(
name='cloud-to-update',
note='Original note.',
))
self.assertEqual('cloud-to-update', cloud.name)
self.assertEqual('Original note.', cloud.note)
updated_cloud = self.client.clouds.update(
cloud.id,
name='updated-cloud',
note='Updated note.',
)
self.assertEqual(cloud.id, updated_cloud.id)
self.assertEqual('updated-cloud', updated_cloud.name)
self.assertEqual('Updated note.', updated_cloud.note)

@ -13,7 +13,6 @@
# under the License. # under the License.
"""Module containing the cratonclient.v1.hosts integration tests.""" """Module containing the cratonclient.v1.hosts integration tests."""
from cratonclient import exceptions
from cratonclient.tests.integration import base from cratonclient.tests.integration import base
@ -55,8 +54,7 @@ class TestHosts(base.BetamaxTestCase):
) )
self.assertTrue(self.client.hosts.delete(host.id)) self.assertTrue(self.client.hosts.delete(host.id))
self.assertRaises(exceptions.NotFound, self.client.hosts.get, self.assertNotFound(self.client.hosts.get, host.id)
host.id)
def test_list_autopaginates(self): def test_list_autopaginates(self):
"""Verify listing of hosts via the Python API.""" """Verify listing of hosts via the Python API."""