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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -19,6 +19,7 @@ from betamax_matchers import json_body
from keystoneauth1.fixture import keystoneauth_betamax as ksabetamax
from cratonclient import auth
from cratonclient import exceptions
from cratonclient.tests import base
from cratonclient.v1 import client
@ -74,6 +75,10 @@ class BetamaxTestCase(base.TestCase):
'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):
"""Add a cleanup task for the host."""
self.addCleanup(self.client.hosts.delete, host.id)

View File

@ -13,7 +13,6 @@
# under the License.
"""Module containing the cratonclient.v1.cells integration tests."""
from cratonclient import exceptions
from cratonclient.tests.integration import base
@ -58,7 +57,7 @@ class TestCells(base.BetamaxTestCase):
self.assertEqual('cell-to-delete', cell.name)
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):
"""Verify the client autopaginates lists of cells."""

View File

@ -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)

View File

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