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:
parent
4ea65b4409
commit
4c5e5e4bba
@ -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
|
||||||
|
0
cinderclient/tests/functional/__init__.py
Normal file
0
cinderclient/tests/functional/__init__.py
Normal file
56
cinderclient/tests/functional/base.py
Normal file
56
cinderclient/tests/functional/base.py
Normal 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)
|
89
cinderclient/tests/functional/test_readonly_cli.py
Normal file
89
cinderclient/tests/functional/test_readonly_cli.py
Normal 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'])
|
@ -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
|
||||||
|
4
tox.ini
4
tox.ini
@ -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
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user