Add CLI read-only functional tests

First pass at functional tests in cinderclient.  This patch
just takes some of the basic CLI tests from tempest and moves
them into the cinderclient functional tests.

These are read-only tests, and just do simple field checks
on the tables generated by the basic list commands.

Note: to run use "tox -efunctional", this requires that you
have a full cinderclient env and credentials are set. You may
be either running this locally (say in a devstack env) or
you may have a remote cloud handy that you can just source the
credentials for and run it that way.

Change-Id: I2f09a63be265d6a74cb103d80579068b9ab66bf4
This commit is contained in:
John Griffith 2015-04-30 16:58:46 -06:00
parent 4ea65b4409
commit 4c5e5e4bba
6 changed files with 151 additions and 1 deletions

View File

@ -1,4 +1,4 @@
[DEFAULT] [DEFAULT]
test_command=OS_STDOUT_CAPTURE=${OS_STDOUT_CAPTURE:-1} OS_STDERR_CAPTURE=${OS_STDERR_CAPTURE:-1} ${PYTHON:-python} -m subunit.run discover -t ./ ${OS_TEST_PATH:-./cinderclient/tests} $LISTOPT $IDOPTION test_command=OS_STDOUT_CAPTURE=${OS_STDOUT_CAPTURE:-1} OS_STDERR_CAPTURE=${OS_STDERR_CAPTURE:-1} ${PYTHON:-python} -m subunit.run discover -t ./ ${OS_TEST_PATH:-./cinderclient/tests/unit} $LISTOPT $IDOPTION
test_id_option=--load-list $IDFILE test_id_option=--load-list $IDFILE
test_list_option=--list test_list_option=--list

View File

@ -0,0 +1,56 @@
# 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.
import os
from tempest_lib.cli import base
from tempest_lib.cli import output_parser
class ClientTestBase(base.ClientTestBase):
"""Cinder base class, issues calls to cinderclient.
"""
def setUp(self):
super(ClientTestBase, self).setUp()
self.clients = self._get_clients()
self.parser = output_parser
def _get_clients(self):
cli_dir = os.environ.get(
'OS_CINDERCLIENT_EXEC_DIR',
os.path.join(os.path.abspath('.'), '.tox/functional/bin'))
return base.CLIClient(
username=os.environ.get('OS_USERNAME'),
password=os.environ.get('OS_PASSWORD'),
tenant_name=os.environ.get('OS_TENANT_NAME'),
uri=os.environ.get('OS_AUTH_URL'),
cli_dir=cli_dir)
def cinder(self, *args, **kwargs):
return self.clients.cinder(*args,
**kwargs)
def assertTableStruct(self, items, field_names):
"""Verify that all items has keys listed in field_names.
:param items: items to assert are field names in the output table
:type items: list
:param field_names: field names from the output table of the cmd
:type field_names: list
"""
# Strip off the --- if present
for item in items:
for field in field_names:
self.assertIn(field, item)

View File

@ -0,0 +1,89 @@
# 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.
from cinderclient.tests.functional import base
class CinderClientReadOnlyTests(base.ClientTestBase):
"""Basic read-only test for cinderclient.
Simple check of base list commands, verify they
respond and include the expected headers in the
resultant table.
Not intended for testing things that require actual
resource creation/manipulation, thus the name 'read-only'.
"""
# Commands in order listed in 'cinder help'
def test_absolute_limits(self):
limits = self.parser.listing(self.cinder('absolute-limits'))
self.assertTableStruct(limits, ['Name', 'Value'])
def test_availability_zones(self):
zone_list = self.parser.listing(self.cinder('availability-zone-list'))
self.assertTableStruct(zone_list, ['Name', 'Status'])
def test_backup_list(self):
backup_list = self.parser.listing(self.cinder('backup-list'))
self.assertTableStruct(backup_list, ['ID', 'Volume ID', 'Status',
'Name', 'Size', 'Object Count',
'Container'])
def test_encryption_type_list(self):
encrypt_list = self.parser.listing(self.cinder('encryption-type-list'))
self.assertTableStruct(encrypt_list, ['Volume Type ID', 'Provider',
'Cipher', 'Key Size',
'Control Location'])
def test_endpoints(self):
out = self.cinder('endpoints')
tables = self.parser.tables(out)
for table in tables:
headers = table['headers']
self.assertTrue(2 >= len(headers))
self.assertEqual('Value', headers[1])
def test_list(self):
list = self.parser.listing(self.cinder('list'))
self.assertTableStruct(list, ['ID', 'Status', 'Name', 'Size',
'Volume Type', 'Bootable',
'Attached to'])
def test_qos_list(self):
qos_list = self.parser.listing(self.cinder('qos-list'))
self.assertTableStruct(qos_list, ['ID', 'Name', 'Consumer', 'specs'])
def test_rate_limits(self):
rate_limits = self.parser.listing(self.cinder('rate-limits'))
self.assertTableStruct(rate_limits, ['Verb', 'URI', 'Value', 'Remain',
'Unit', 'Next_Available'])
def test_service_list(self):
service_list = self.parser.listing(self.cinder('service-list'))
self.assertTableStruct(service_list, ['Binary', 'Host', 'Zone',
'Status', 'State', 'Updated_at'])
def test_snapshot_list(self):
snapshot_list = self.parser.listing(self.cinder('snapshot-list'))
self.assertTableStruct(snapshot_list, ['ID', 'Volume ID', 'Status',
'Name', 'Size'])
def test_transfer_list(self):
transfer_list = self.parser.listing(self.cinder('transfer-list'))
self.assertTableStruct(transfer_list, ['ID', 'Volume ID', 'Name'])
def test_type_list(self):
type_list = self.parser.listing(self.cinder('type-list'))
self.assertTableStruct(type_list, ['ID', 'Name'])

View File

@ -11,5 +11,6 @@ oslosphinx>=2.5.0 # Apache-2.0
python-subunit>=0.0.18 python-subunit>=0.0.18
requests-mock>=0.6.0 # Apache-2.0 requests-mock>=0.6.0 # Apache-2.0
sphinx>=1.1.2,!=1.2.0,!=1.3b1,<1.3 sphinx>=1.1.2,!=1.2.0,!=1.3b1,<1.3
tempest-lib>=0.5.0
testtools>=0.9.36,!=1.2.0 testtools>=0.9.36,!=1.2.0
testrepository>=0.0.18 testrepository>=0.0.18

View File

@ -26,6 +26,10 @@ commands = python setup.py testr --coverage --testr-args='{posargs}'
commands= commands=
python setup.py build_sphinx python setup.py build_sphinx
[testenv:functional]
setenv =
OS_TEST_PATH = ./cinderclient/tests/functional
[tox:jenkins] [tox:jenkins]
downloadcache = ~/cache/pip downloadcache = ~/cache/pip