Merge "Remove Functional Tests"
This commit is contained in:
@@ -1,3 +1,2 @@
|
||||
[report]
|
||||
include = ironicclient/*
|
||||
omit = ironicclient/tests/functional/*
|
||||
|
||||
@@ -12,7 +12,6 @@ extensions = ['sphinxcontrib.apidoc',
|
||||
apidoc_module_dir = '../../ironicclient'
|
||||
apidoc_output_dir = 'reference/api'
|
||||
apidoc_excluded_paths = [
|
||||
'tests/functional/*',
|
||||
'tests']
|
||||
apidoc_separate_modules = True
|
||||
|
||||
@@ -54,7 +53,7 @@ pygments_style = 'native'
|
||||
# A list of glob-style patterns that should be excluded when looking for
|
||||
# source files. They are matched against the source file names relative to the
|
||||
# source directory, using slashes as directory separators on all platforms.
|
||||
exclude_patterns = ['api/ironicclient.tests.functional.*']
|
||||
exclude_patterns = ['']
|
||||
|
||||
# -- Options for HTML output --------------------------------------------------
|
||||
|
||||
|
||||
@@ -34,34 +34,4 @@ chosen environments after a -e flag::
|
||||
Functional Testing
|
||||
..................
|
||||
|
||||
Functional testing assumes the existence of the script run_functional.sh in the
|
||||
python-ironicclient/tools directory. The script run_functional.sh generates
|
||||
test.conf file. To run functional tests just run ./run_functional.sh.
|
||||
|
||||
Also, the test.conf file could be created manually or generated from
|
||||
environment variables. It assumes the existence of an openstack
|
||||
cloud installation along with admin credentials. The test.conf file lives in
|
||||
ironicclient/tests/functional/ directory. To run functional tests in that way
|
||||
create test.conf manually and run::
|
||||
|
||||
$ tox -e functional
|
||||
|
||||
An example test.conf file::
|
||||
|
||||
[functional]
|
||||
api_version = 1
|
||||
os_auth_url=http://192.168.0.2:5000/v2.0/
|
||||
os_username=admin
|
||||
os_password=admin
|
||||
os_project_name=admin
|
||||
|
||||
If you are testing ironic in standalone mode, only the parameters
|
||||
'auth_strategy', 'os_auth_token' and 'ironic_url' are required;
|
||||
all others will be ignored.
|
||||
|
||||
An example test.conf file for standalone host::
|
||||
|
||||
[functional]
|
||||
auth_strategy = noauth
|
||||
os_auth_token = fake
|
||||
ironic_url = http://10.0.0.2:6385
|
||||
Functional tests have been removed as of November 2024.
|
||||
|
||||
@@ -1,440 +0,0 @@
|
||||
# Copyright (c) 2016 Mirantis, Inc.
|
||||
#
|
||||
# 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 configparser
|
||||
import os
|
||||
|
||||
from tempest.lib.cli import base
|
||||
from tempest.lib.common.utils import data_utils
|
||||
from tempest.lib import exceptions
|
||||
|
||||
import ironicclient.tests.functional.utils as utils
|
||||
|
||||
DEFAULT_CONFIG_FILE = os.path.join(os.path.dirname(__file__), 'test.conf')
|
||||
|
||||
|
||||
class FunctionalTestBase(base.ClientTestBase):
|
||||
"""Ironic base class, calls to ironicclient."""
|
||||
|
||||
def setUp(self):
|
||||
super(FunctionalTestBase, self).setUp()
|
||||
if not self.auth_ref.project_scoped:
|
||||
raise Exception("Could not run functional tests, which are "
|
||||
"run based on the scope provided for "
|
||||
"authentication. Please provide a project "
|
||||
"scope information.")
|
||||
|
||||
self.client = self._get_clients()
|
||||
# NOTE(kromanenko) set ironic api version for portgroups
|
||||
self.pg_api_ver = '--ironic-api-version 1.25'
|
||||
|
||||
def _get_clients(self):
|
||||
# NOTE(aarefiev): {toxinidir} is a current working directory, so
|
||||
# the tox env path is {toxinidir}/.tox
|
||||
venv_name = os.environ.get('OS_TESTENV_NAME', 'functional')
|
||||
cli_dir = os.path.join(os.path.abspath('.'), '.tox/%s/bin' % venv_name)
|
||||
|
||||
config = self._get_config()
|
||||
if config.get('os_auth_url'):
|
||||
client = base.CLIClient(cli_dir=cli_dir,
|
||||
username=config['os_username'],
|
||||
password=config['os_password'],
|
||||
tenant_name=config.get('os_project_name'),
|
||||
uri=config['os_auth_url'])
|
||||
for keystone_object in 'user', 'project':
|
||||
domain_attr = 'os_%s_domain_id' % keystone_object
|
||||
if config.get(domain_attr):
|
||||
setattr(self, domain_attr, config.get(domain_attr))
|
||||
else:
|
||||
self.ironic_url = config['ironic_url']
|
||||
client = base.CLIClient(cli_dir=cli_dir,
|
||||
ironic_url=self.ironic_url)
|
||||
return client
|
||||
|
||||
def _get_config(self):
|
||||
config_file = os.environ.get('IRONICCLIENT_TEST_CONFIG',
|
||||
DEFAULT_CONFIG_FILE)
|
||||
config = configparser.ConfigParser()
|
||||
if not config.read(config_file):
|
||||
self.skipTest('Skipping, no test config found @ %s' % config_file)
|
||||
try:
|
||||
auth_strategy = config.get('functional', 'auth_strategy')
|
||||
except configparser.NoOptionError:
|
||||
auth_strategy = 'keystone'
|
||||
if auth_strategy not in ['keystone', 'noauth']:
|
||||
raise self.fail(
|
||||
'Invalid auth type specified: %s in functional must be '
|
||||
'one of: [keystone, noauth]' % auth_strategy)
|
||||
|
||||
conf_settings = []
|
||||
keystone_v3_conf_settings = []
|
||||
if auth_strategy == 'keystone':
|
||||
conf_settings += ['os_auth_url', 'os_username',
|
||||
'os_password', 'os_project_name']
|
||||
keystone_v3_conf_settings += ['os_user_domain_id',
|
||||
'os_project_domain_id',
|
||||
'os_identity_api_version',
|
||||
'os_system_scope']
|
||||
else:
|
||||
conf_settings += ['ironic_url']
|
||||
|
||||
cli_flags = {}
|
||||
for c in conf_settings + keystone_v3_conf_settings:
|
||||
try:
|
||||
setting_value = config.get('functional', c)
|
||||
if setting_value is not None:
|
||||
cli_flags[c] = setting_value
|
||||
except configparser.NoOptionError:
|
||||
# NOTE(TheJulia): Here we populate the options, and if we
|
||||
# don't have an option, it is okay, The keystone client will
|
||||
# do the actual validity check instead of us trying to have
|
||||
# internal check logic, as there are several different forms
|
||||
# and parameters which can be used.
|
||||
pass
|
||||
return cli_flags
|
||||
|
||||
def _cmd_no_auth(self, cmd, action, flags='', params=''):
|
||||
"""Execute given command with noauth attributes.
|
||||
|
||||
:param cmd: command to be executed
|
||||
:type cmd: string
|
||||
:param action: command on cli to run
|
||||
:type action: string
|
||||
:param flags: optional cli flags to use
|
||||
:type flags: string
|
||||
:param params: optional positional args to use
|
||||
:type params: string
|
||||
"""
|
||||
flags = ('--os-endpoint %(url)s %(flags)s'
|
||||
%
|
||||
{'url': self.ironic_url,
|
||||
'flags': flags})
|
||||
return base.execute(cmd, action, flags, params,
|
||||
cli_dir=self.client.cli_dir)
|
||||
|
||||
def _ironic(self, action, cmd='ironic', flags='', params='',
|
||||
merge_stderr=False):
|
||||
"""Execute ironic command for the given action.
|
||||
|
||||
:param action: the cli command to run using Ironic
|
||||
:type action: string
|
||||
:param cmd: the base of cli command to run
|
||||
:type action: string
|
||||
:param flags: any optional cli flags to use
|
||||
:type flags: string
|
||||
:param params: any optional positional args to use
|
||||
:type params: string
|
||||
:param merge_stderr: whether to merge stderr into the result
|
||||
:type merge_stderr: bool
|
||||
"""
|
||||
if cmd == 'openstack':
|
||||
config = self._get_config()
|
||||
id_api_version = config.get('os_identity_api_version')
|
||||
if id_api_version:
|
||||
flags += ' --os-identity-api-version {}'.format(id_api_version)
|
||||
else:
|
||||
flags += ' --os-endpoint-type publicURL'
|
||||
|
||||
if hasattr(self, 'ironic_url'):
|
||||
if cmd == 'openstack':
|
||||
flags += ' --os-auth-type none'
|
||||
return self._cmd_no_auth(cmd, action, flags, params)
|
||||
else:
|
||||
for keystone_object in 'user', 'project':
|
||||
domain_attr = 'os_%s_domain_id' % keystone_object
|
||||
if (hasattr(self, domain_attr)
|
||||
and getattr(self, domain_attr) is not None):
|
||||
flags += ' --os-%(ks_obj)s-domain-id %(value)s' % {
|
||||
'ks_obj': keystone_object,
|
||||
'value': getattr(self, domain_attr)
|
||||
}
|
||||
return self.client.cmd_with_auth(
|
||||
cmd, action, flags, params, merge_stderr=merge_stderr)
|
||||
|
||||
def ironic(self, action, flags='', params='', parse=True):
|
||||
"""Return parsed list of dicts with basic item info.
|
||||
|
||||
:param action: the cli command to run using Ironic
|
||||
:type action: string
|
||||
:param flags: any optional cli flags to use
|
||||
:type flags: string
|
||||
:param params: any optional positional args to use
|
||||
:type params: string
|
||||
:param parse: return parsed list or raw output
|
||||
:type parse: bool
|
||||
"""
|
||||
output = self._ironic(action=action, flags=flags, params=params)
|
||||
return self.parser.listing(output) if parse else output
|
||||
|
||||
def get_table_headers(self, action, flags='', params=''):
|
||||
output = self._ironic(action=action, flags=flags, params=params)
|
||||
table = self.parser.table(output)
|
||||
return table['headers']
|
||||
|
||||
def assertTableHeaders(self, field_names, table_headers):
|
||||
"""Assert that field_names and table_headers are equal.
|
||||
|
||||
:param field_names: field names from the output table of the cmd
|
||||
:param table_headers: table headers output from cmd
|
||||
"""
|
||||
self.assertEqual(sorted(field_names), sorted(table_headers))
|
||||
|
||||
def assertNodeStates(self, node_show, node_show_states):
|
||||
"""Assert that node_show_states output corresponds to node_show output.
|
||||
|
||||
:param node_show: output from node-show cmd
|
||||
:param node_show_states: output from node-show-states cmd
|
||||
"""
|
||||
for key in node_show_states.keys():
|
||||
self.assertEqual(node_show_states[key], node_show[key])
|
||||
|
||||
def assertNodeValidate(self, node_validate):
|
||||
"""Assert that all interfaces present are valid.
|
||||
|
||||
:param node_validate: output from node-validate cmd
|
||||
"""
|
||||
self.assertNotIn('False', [x['Result'] for x in node_validate])
|
||||
|
||||
def delete_node(self, node_id):
|
||||
"""Delete node method works only with fake driver.
|
||||
|
||||
:param node_id: node uuid
|
||||
:raises: CommandFailed exception when command fails to delete a node
|
||||
"""
|
||||
node_list = self.list_nodes()
|
||||
|
||||
if utils.get_object(node_list, node_id):
|
||||
node_show = self.show_node(node_id)
|
||||
if node_show['provision_state'] not in ('available',
|
||||
'manageable',
|
||||
'enroll'):
|
||||
self.ironic('node-set-provision-state',
|
||||
params='{0} deleted'.format(node_id))
|
||||
if node_show['power_state'] not in ('None', 'off'):
|
||||
self.ironic('node-set-power-state',
|
||||
params='{0} off'.format(node_id))
|
||||
self.ironic('node-delete', params=node_id)
|
||||
|
||||
node_list_uuid = self.get_nodes_uuids_from_node_list()
|
||||
if node_id in node_list_uuid:
|
||||
self.fail('Ironic node {0} has not been deleted!'
|
||||
.format(node_id))
|
||||
|
||||
def create_node(self, driver='fake-hardware', params=''):
|
||||
node = self.ironic('node-create',
|
||||
params='--driver {0} {1}'.format(driver, params))
|
||||
|
||||
if not node:
|
||||
self.fail('Ironic node has not been created!')
|
||||
|
||||
node = utils.get_dict_from_output(node)
|
||||
self.addCleanup(self.delete_node, node['uuid'])
|
||||
return node
|
||||
|
||||
def show_node(self, node_id, params=''):
|
||||
node_show = self.ironic('node-show',
|
||||
params='{0} {1}'.format(node_id, params))
|
||||
return utils.get_dict_from_output(node_show)
|
||||
|
||||
def list_nodes(self, params=''):
|
||||
return self.ironic('node-list', params=params)
|
||||
|
||||
def update_node(self, node_id, params):
|
||||
updated_node = self.ironic('node-update',
|
||||
params='{0} {1}'.format(node_id, params))
|
||||
return utils.get_dict_from_output(updated_node)
|
||||
|
||||
def get_nodes_uuids_from_node_list(self):
|
||||
node_list = self.list_nodes()
|
||||
return [x['UUID'] for x in node_list]
|
||||
|
||||
def show_node_states(self, node_id):
|
||||
show_node_states = self.ironic('node-show-states', params=node_id)
|
||||
return utils.get_dict_from_output(show_node_states)
|
||||
|
||||
def set_node_maintenance(self, node_id, maintenance_mode, params=''):
|
||||
self.ironic(
|
||||
'node-set-maintenance',
|
||||
params='{0} {1} {2}'.format(node_id, maintenance_mode, params))
|
||||
|
||||
def set_node_power_state(self, node_id, power_state, params=''):
|
||||
self.ironic('node-set-power-state',
|
||||
params='{0} {1} {2}'
|
||||
.format(node_id, power_state, params))
|
||||
|
||||
def set_node_provision_state(self, node_id, provision_state, params=''):
|
||||
self.ironic('node-set-provision-state',
|
||||
params='{0} {1} {2}'
|
||||
.format(node_id, provision_state, params))
|
||||
|
||||
def validate_node(self, node_id):
|
||||
return self.ironic('node-validate', params=node_id)
|
||||
|
||||
def list_node_chassis(self, chassis_uuid, params=''):
|
||||
return self.ironic('chassis-node-list',
|
||||
params='{0} {1}'.format(chassis_uuid, params))
|
||||
|
||||
def get_nodes_uuids_from_chassis_node_list(self, chassis_uuid):
|
||||
chassis_node_list = self.list_node_chassis(chassis_uuid)
|
||||
return [x['UUID'] for x in chassis_node_list]
|
||||
|
||||
def list_driver(self, params=''):
|
||||
return self.ironic('driver-list', params=params)
|
||||
|
||||
def show_driver(self, driver_name):
|
||||
driver_show = self.ironic('driver-show', params=driver_name)
|
||||
return utils.get_dict_from_output(driver_show)
|
||||
|
||||
def properties_driver(self, driver_name):
|
||||
return self.ironic('driver-properties', params=driver_name)
|
||||
|
||||
def get_drivers_names(self):
|
||||
driver_list = self.list_driver()
|
||||
return [x['Supported driver(s)'] for x in driver_list]
|
||||
|
||||
def delete_chassis(self, chassis_id, ignore_exceptions=False):
|
||||
try:
|
||||
self.ironic('chassis-delete', params=chassis_id)
|
||||
except exceptions.CommandFailed:
|
||||
if not ignore_exceptions:
|
||||
raise
|
||||
|
||||
def get_chassis_uuids_from_chassis_list(self):
|
||||
chassis_list = self.list_chassis()
|
||||
return [x['UUID'] for x in chassis_list]
|
||||
|
||||
def create_chassis(self, params=''):
|
||||
chassis = self.ironic('chassis-create', params=params)
|
||||
|
||||
if not chassis:
|
||||
self.fail('Ironic chassis has not been created!')
|
||||
|
||||
chassis = utils.get_dict_from_output(chassis)
|
||||
self.addCleanup(self.delete_chassis,
|
||||
chassis['uuid'],
|
||||
ignore_exceptions=True)
|
||||
return chassis
|
||||
|
||||
def list_chassis(self, params=''):
|
||||
return self.ironic('chassis-list', params=params)
|
||||
|
||||
def show_chassis(self, chassis_id, params=''):
|
||||
chassis_show = self.ironic('chassis-show',
|
||||
params='{0} {1}'.format(chassis_id, params))
|
||||
return utils.get_dict_from_output(chassis_show)
|
||||
|
||||
def update_chassis(self, chassis_id, operation, params=''):
|
||||
updated_chassis = self.ironic(
|
||||
'chassis-update',
|
||||
params='{0} {1} {2}'.format(chassis_id, operation, params))
|
||||
return utils.get_dict_from_output(updated_chassis)
|
||||
|
||||
def delete_port(self, port_id, ignore_exceptions=False):
|
||||
try:
|
||||
self.ironic('port-delete', params=port_id)
|
||||
except exceptions.CommandFailed:
|
||||
if not ignore_exceptions:
|
||||
raise
|
||||
|
||||
def create_port(self,
|
||||
node_id,
|
||||
mac_address=None,
|
||||
flags='',
|
||||
params=''):
|
||||
|
||||
if mac_address is None:
|
||||
mac_address = data_utils.rand_mac_address()
|
||||
|
||||
port = self.ironic('port-create',
|
||||
flags=flags,
|
||||
params='--address {0} --node {1} {2}'
|
||||
.format(mac_address, node_id, params))
|
||||
if not port:
|
||||
self.fail('Ironic port has not been created!')
|
||||
|
||||
return utils.get_dict_from_output(port)
|
||||
|
||||
def list_ports(self, params=''):
|
||||
return self.ironic('port-list', params=params)
|
||||
|
||||
def show_port(self, port_id, params=''):
|
||||
port_show = self.ironic('port-show', params='{0} {1}'
|
||||
.format(port_id, params))
|
||||
return utils.get_dict_from_output(port_show)
|
||||
|
||||
def get_uuids_from_port_list(self):
|
||||
port_list = self.list_ports()
|
||||
return [x['UUID'] for x in port_list]
|
||||
|
||||
def update_port(self, port_id, operation, flags='', params=''):
|
||||
updated_port = self.ironic('port-update',
|
||||
flags=flags,
|
||||
params='{0} {1} {2}'
|
||||
.format(port_id, operation, params))
|
||||
return utils.get_dict_from_output(updated_port)
|
||||
|
||||
def create_portgroup(self, node_id, params=''):
|
||||
"""Create a new portgroup."""
|
||||
portgroup = self.ironic('portgroup-create',
|
||||
flags=self.pg_api_ver,
|
||||
params='--node {0} {1}'
|
||||
.format(node_id, params))
|
||||
if not portgroup:
|
||||
self.fail('Ironic portgroup failed to create!')
|
||||
portgroup = utils.get_dict_from_output(portgroup)
|
||||
self.addCleanup(self.delete_portgroup, portgroup['uuid'],
|
||||
ignore_exceptions=True)
|
||||
return portgroup
|
||||
|
||||
def delete_portgroup(self, portgroup_id, ignore_exceptions=False):
|
||||
"""Delete a port group."""
|
||||
try:
|
||||
self.ironic('portgroup-delete',
|
||||
flags=self.pg_api_ver,
|
||||
params=portgroup_id)
|
||||
except exceptions.CommandFailed:
|
||||
if not ignore_exceptions:
|
||||
raise
|
||||
|
||||
def list_portgroups(self, params=''):
|
||||
"""List the port groups."""
|
||||
return self.ironic('portgroup-list',
|
||||
flags=self.pg_api_ver,
|
||||
params=params)
|
||||
|
||||
def show_portgroup(self, portgroup_id, params=''):
|
||||
"""Show detailed information about a port group."""
|
||||
portgroup_show = self.ironic('portgroup-show',
|
||||
flags=self.pg_api_ver,
|
||||
params='{0} {1}'
|
||||
.format(portgroup_id, params))
|
||||
return utils.get_dict_from_output(portgroup_show)
|
||||
|
||||
def update_portgroup(self, portgroup_id, op, params=''):
|
||||
"""Update information about a port group."""
|
||||
updated_portgroup = self.ironic('portgroup-update',
|
||||
flags=self.pg_api_ver,
|
||||
params='{0} {1} {2}'
|
||||
.format(portgroup_id, op, params))
|
||||
return utils.get_dict_from_output(updated_portgroup)
|
||||
|
||||
def get_portgroup_uuids_from_portgroup_list(self):
|
||||
"""Get UUIDs from list of port groups."""
|
||||
portgroup_list = self.list_portgroups()
|
||||
return [x['UUID'] for x in portgroup_list]
|
||||
|
||||
def portgroup_port_list(self, portgroup_id, params=''):
|
||||
"""List the ports associated with a port group."""
|
||||
return self.ironic('portgroup-port-list', flags=self.pg_api_ver,
|
||||
params='{0} {1}'.format(portgroup_id, params))
|
||||
@@ -1,485 +0,0 @@
|
||||
# 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 json
|
||||
|
||||
from tempest.lib.common.utils import data_utils
|
||||
from tempest.lib import exceptions
|
||||
|
||||
from ironicclient.tests.functional import base
|
||||
|
||||
|
||||
class TestCase(base.FunctionalTestBase):
|
||||
|
||||
driver_name = 'fake-hardware'
|
||||
|
||||
def openstack(self, *args, **kwargs):
|
||||
return self._ironic(cmd='openstack', *args, **kwargs)
|
||||
|
||||
def get_opts(self, fields=None, output_format='json'):
|
||||
"""Get options for OSC output fields format.
|
||||
|
||||
:param List fields: List of fields to get
|
||||
:param String output_format: Select output format
|
||||
:return: String of formatted options
|
||||
"""
|
||||
if not fields:
|
||||
return ' -f {0}'.format(output_format)
|
||||
return ' -f {0} {1}'.format(output_format,
|
||||
' '.join(['-c ' + it for it in fields]))
|
||||
|
||||
@staticmethod
|
||||
def construct_cmd(*parts):
|
||||
return ' '.join(str(x) for x in parts)
|
||||
|
||||
@staticmethod
|
||||
def generate_params(argument, params):
|
||||
"""Generate parameters string.
|
||||
|
||||
:param argument: argument
|
||||
:param params: values passed with argument
|
||||
"""
|
||||
parts = []
|
||||
for key, value in params.items():
|
||||
parts.append('{} {}={}'.format(argument, key, value))
|
||||
return ' '.join(parts)
|
||||
|
||||
def assert_dict_is_subset(self, expected, actual):
|
||||
"""Check if expected keys/values exist in actual response body.
|
||||
|
||||
Check if the expected keys and values are in the actual response body.
|
||||
|
||||
:param expected: dict of key-value pairs that are expected to be in
|
||||
'actual' dict.
|
||||
:param actual: dict of key-value pairs.
|
||||
"""
|
||||
for key, value in expected.items():
|
||||
self.assertEqual(value, actual[key])
|
||||
|
||||
def node_create(self, driver=driver_name, name=None, params=''):
|
||||
"""Create baremetal node and add cleanup.
|
||||
|
||||
:param String driver: Driver for a new node
|
||||
:param String name: Name for a new node
|
||||
:param String params: Additional args and kwargs
|
||||
:return: JSON object of created node
|
||||
"""
|
||||
if not name:
|
||||
name = data_utils.rand_name('baremetal')
|
||||
|
||||
opts = self.get_opts()
|
||||
output = self.openstack('baremetal node create {0} '
|
||||
'--driver {1} --name {2} {3}'
|
||||
.format(opts, driver, name, params))
|
||||
node = json.loads(output)
|
||||
self.addCleanup(self.node_delete, node['uuid'], True)
|
||||
if not output:
|
||||
self.fail('Baremetal node has not been created!')
|
||||
|
||||
return node
|
||||
|
||||
def node_list(self, fields=None, params=''):
|
||||
"""List baremetal nodes.
|
||||
|
||||
:param List fields: List of fields to show
|
||||
:param String params: Additional kwargs
|
||||
:return: list of JSON node objects
|
||||
"""
|
||||
opts = self.get_opts(fields=fields)
|
||||
output = self.openstack('baremetal node list {0} {1}'
|
||||
.format(opts, params))
|
||||
return json.loads(output)
|
||||
|
||||
def node_show(self, identifier, fields=None, params=''):
|
||||
"""Show specified baremetal node.
|
||||
|
||||
:param String identifier: Name or UUID of the node
|
||||
:param List fields: List of fields to show
|
||||
:param List params: Additional kwargs
|
||||
:return: JSON object of node
|
||||
"""
|
||||
opts = self.get_opts(fields)
|
||||
output = self.openstack('baremetal node show {0} {1} {2}'
|
||||
.format(opts, identifier, params))
|
||||
return json.loads(output)
|
||||
|
||||
def node_delete(self, identifier, ignore_exceptions=False):
|
||||
"""Try to delete baremetal node by name or UUID.
|
||||
|
||||
:param String identifier: Name or UUID of the node
|
||||
:param Bool ignore_exceptions: Ignore exception (needed for cleanUp)
|
||||
:return: raw values output
|
||||
:raise: CommandFailed exception when command fails to delete a node
|
||||
"""
|
||||
try:
|
||||
return self.openstack('baremetal node delete {0}'
|
||||
.format(identifier))
|
||||
except exceptions.CommandFailed:
|
||||
if not ignore_exceptions:
|
||||
raise
|
||||
|
||||
def port_create(self, node_id, mac_address=None, params=''):
|
||||
"""Create baremetal port and add cleanup.
|
||||
|
||||
:param String node_id: baremetal node UUID
|
||||
:param String mac_address: MAC address for port
|
||||
:param String params: Additional args and kwargs
|
||||
:return: JSON object of created port
|
||||
"""
|
||||
if not mac_address:
|
||||
mac_address = data_utils.rand_mac_address()
|
||||
|
||||
opts = self.get_opts()
|
||||
port = self.openstack('baremetal port create {0} '
|
||||
'--node {1} {2} {3}'
|
||||
.format(opts, node_id, mac_address, params))
|
||||
port = json.loads(port)
|
||||
if not port:
|
||||
self.fail('Baremetal port has not been created!')
|
||||
self.addCleanup(self.port_delete, port['uuid'], True)
|
||||
return port
|
||||
|
||||
def port_list(self, fields=None, params=''):
|
||||
"""List baremetal ports.
|
||||
|
||||
:param List fields: List of fields to show
|
||||
:param String params: Additional kwargs
|
||||
:return: list of JSON port objects
|
||||
"""
|
||||
opts = self.get_opts(fields=fields)
|
||||
output = self.openstack('baremetal port list {0} {1}'
|
||||
.format(opts, params))
|
||||
return json.loads(output)
|
||||
|
||||
def port_show(self, uuid, fields=None, params=''):
|
||||
"""Show specified baremetal port.
|
||||
|
||||
:param String uuid: UUID of the port
|
||||
:param List fields: List of fields to show
|
||||
:param List params: Additional kwargs
|
||||
:return: JSON object of port
|
||||
"""
|
||||
opts = self.get_opts(fields)
|
||||
output = self.openstack('baremetal port show {0} {1} {2}'
|
||||
.format(opts, uuid, params))
|
||||
return json.loads(output)
|
||||
|
||||
def port_delete(self, uuid, ignore_exceptions=False):
|
||||
"""Try to delete baremetal port by UUID.
|
||||
|
||||
:param String uuid: UUID of the port
|
||||
:param Bool ignore_exceptions: Ignore exception (needed for cleanUp)
|
||||
:return: raw values output
|
||||
:raise: CommandFailed exception when command fails to delete a port
|
||||
"""
|
||||
try:
|
||||
return self.openstack('baremetal port delete {0}'
|
||||
.format(uuid))
|
||||
except exceptions.CommandFailed:
|
||||
if not ignore_exceptions:
|
||||
raise
|
||||
|
||||
def port_group_list(self, fields=None, params=''):
|
||||
"""List baremetal port groups.
|
||||
|
||||
:param List fields: List of fields to show
|
||||
:param String params: Additional kwargs
|
||||
:return: JSON object of port group list
|
||||
"""
|
||||
opts = self.get_opts(fields=fields)
|
||||
output = self.openstack('baremetal port group list {0} {1}'
|
||||
.format(opts, params))
|
||||
return json.loads(output)
|
||||
|
||||
def port_group_create(self, node_id, name=None, params=''):
|
||||
"""Create baremetal port group.
|
||||
|
||||
:param String node_id: baremetal node UUID
|
||||
:param String name: port group name
|
||||
:param String params: Additional args and kwargs
|
||||
:return: JSON object of created port group
|
||||
"""
|
||||
if not name:
|
||||
name = data_utils.rand_name('port_group')
|
||||
|
||||
opts = self.get_opts()
|
||||
output = self.openstack(
|
||||
'baremetal port group create {0} --node {1} --name {2} {3}'
|
||||
.format(opts, node_id, name, params))
|
||||
|
||||
port_group = json.loads(output)
|
||||
if not port_group:
|
||||
self.fail('Baremetal port group has not been created!')
|
||||
|
||||
self.addCleanup(self.port_group_delete, port_group['uuid'],
|
||||
params=params, ignore_exceptions=True)
|
||||
return port_group
|
||||
|
||||
def port_group_delete(self, identifier, params='',
|
||||
ignore_exceptions=False):
|
||||
"""Try to delete baremetal port group by Name or UUID.
|
||||
|
||||
:param String identifier: Name or UUID of the port group
|
||||
:param String params: temporary arg to pass api version.
|
||||
:param Bool ignore_exceptions: Ignore exception (needed for cleanUp)
|
||||
:return: raw values output
|
||||
:raise: CommandFailed exception if not ignore_exceptions
|
||||
"""
|
||||
try:
|
||||
return self.openstack('baremetal port group delete {0} {1}'
|
||||
.format(identifier, params))
|
||||
except exceptions.CommandFailed:
|
||||
if not ignore_exceptions:
|
||||
raise
|
||||
|
||||
def port_group_show(self, identifier, fields=None, params=''):
|
||||
"""Show specified baremetal port group.
|
||||
|
||||
:param String identifier: Name or UUID of the port group
|
||||
:param List fields: List of fields to show
|
||||
:param List params: Additional kwargs
|
||||
:return: JSON object of port group
|
||||
"""
|
||||
opts = self.get_opts(fields)
|
||||
output = self.openstack('baremetal port group show {0} {1} {2}'
|
||||
.format(identifier, opts, params))
|
||||
return json.loads(output)
|
||||
|
||||
def chassis_create(self, params=''):
|
||||
"""Create baremetal chassis and add cleanup.
|
||||
|
||||
:param String params: Additional args and kwargs
|
||||
:return: JSON object of created chassis
|
||||
"""
|
||||
opts = self.get_opts()
|
||||
chassis = self.openstack('baremetal chassis create {0} {1}'
|
||||
.format(opts, params))
|
||||
|
||||
chassis = json.loads(chassis)
|
||||
if not chassis:
|
||||
self.fail('Baremetal chassis has not been created!')
|
||||
self.addCleanup(self.chassis_delete, chassis['uuid'], True)
|
||||
|
||||
return chassis
|
||||
|
||||
def chassis_delete(self, uuid, ignore_exceptions=False):
|
||||
"""Try to delete baremetal chassis by UUID.
|
||||
|
||||
:param String uuid: UUID of the chassis
|
||||
:param Bool ignore_exceptions: Ignore exception (needed for cleanUp)
|
||||
:return: raw values output
|
||||
:raise: CommandFailed exception when command fails to delete a chassis
|
||||
"""
|
||||
try:
|
||||
return self.openstack('baremetal chassis delete {0}'
|
||||
.format(uuid))
|
||||
except exceptions.CommandFailed:
|
||||
if not ignore_exceptions:
|
||||
raise
|
||||
|
||||
def chassis_list(self, fields=None, params=''):
|
||||
"""List baremetal chassis.
|
||||
|
||||
:param List fields: List of fields to show
|
||||
:param String params: Additional kwargs
|
||||
:return: list of JSON chassis objects
|
||||
"""
|
||||
opts = self.get_opts(fields=fields)
|
||||
output = self.openstack('baremetal chassis list {0} {1}'
|
||||
.format(opts, params))
|
||||
return json.loads(output)
|
||||
|
||||
def chassis_show(self, uuid, fields=None, params=''):
|
||||
"""Show specified baremetal chassis.
|
||||
|
||||
:param String uuid: UUID of the chassis
|
||||
:param List fields: List of fields to show
|
||||
:param List params: Additional kwargs
|
||||
:return: JSON object of chassis
|
||||
"""
|
||||
opts = self.get_opts(fields)
|
||||
chassis = self.openstack('baremetal chassis show {0} {1} {2}'
|
||||
.format(opts, uuid, params))
|
||||
return json.loads(chassis)
|
||||
|
||||
def driver_show(self, driver_name, fields=None, params=''):
|
||||
"""Show specified baremetal driver.
|
||||
|
||||
:param String driver_name: Name of the driver
|
||||
:param List fields: List of fields to show
|
||||
:param List params: Additional kwargs
|
||||
:return: JSON object of driver
|
||||
"""
|
||||
opts = self.get_opts(fields=fields)
|
||||
driver = self.openstack('baremetal driver show {0} {1} {2}'
|
||||
.format(opts, driver_name, params))
|
||||
return json.loads(driver)
|
||||
|
||||
def driver_list(self, fields=None, params=''):
|
||||
"""List baremetal drivers.
|
||||
|
||||
:param List fields: List of fields to show
|
||||
:param String params: Additional kwargs
|
||||
:return: list of JSON driver objects
|
||||
"""
|
||||
opts = self.get_opts(fields=fields)
|
||||
output = self.openstack('baremetal driver list {0} {1}'
|
||||
.format(opts, params))
|
||||
return json.loads(output)
|
||||
|
||||
def driver_raid_property_list(self, driver_name, fields=None, params=''):
|
||||
"""List a driver's RAID logical disk properties.
|
||||
|
||||
:param String driver_name: Name of the driver
|
||||
:param List fields: List of fields to show
|
||||
:param List params: Additional kwargs
|
||||
:return: list of JSON driver RAID properties objects
|
||||
"""
|
||||
opts = self.get_opts(fields=fields)
|
||||
output = self.openstack('baremetal driver raid property list {} {} {}'
|
||||
.format(opts, driver_name, params))
|
||||
return json.loads(output)
|
||||
|
||||
def conductor_show(self, hostname, fields=None, params=''):
|
||||
"""Show specified baremetal conductors.
|
||||
|
||||
:param String hostname: hostname of the conductor
|
||||
:param List fields: List of fields to show
|
||||
:param List params: Additional kwargs
|
||||
:return: JSON object of driver
|
||||
"""
|
||||
opts = self.get_opts(fields=fields)
|
||||
output = self.openstack('baremetal conductor show {0} {1} {2}'
|
||||
.format(opts, hostname, params))
|
||||
return json.loads(output)
|
||||
|
||||
def conductor_list(self, fields=None, params=''):
|
||||
"""List baremetal conductors.
|
||||
|
||||
:param List fields: List of fields to show
|
||||
:param String params: Additional kwargs
|
||||
:return: list of JSON driver objects
|
||||
"""
|
||||
opts = self.get_opts(fields=fields)
|
||||
output = self.openstack('baremetal conductor list {0} {1}'
|
||||
.format(opts, params))
|
||||
return json.loads(output)
|
||||
|
||||
def allocation_create(self, resource_class='allocation-test', params=''):
|
||||
opts = self.get_opts()
|
||||
output = self.openstack('baremetal allocation create {0} '
|
||||
'--resource-class {1} {2}'
|
||||
.format(opts, resource_class, params))
|
||||
allocation = json.loads(output)
|
||||
self.addCleanup(self.allocation_delete, allocation['uuid'], True)
|
||||
if not output:
|
||||
self.fail('Baremetal allocation has not been created!')
|
||||
|
||||
return allocation
|
||||
|
||||
def allocation_list(self, fields=None, params=''):
|
||||
"""List baremetal allocations.
|
||||
|
||||
:param List fields: List of fields to show
|
||||
:param String params: Additional kwargs
|
||||
:return: list of JSON allocation objects
|
||||
"""
|
||||
opts = self.get_opts(fields=fields)
|
||||
output = self.openstack('baremetal allocation list {0} {1}'
|
||||
.format(opts, params))
|
||||
return json.loads(output)
|
||||
|
||||
def allocation_show(self, identifier, fields=None, params=''):
|
||||
"""Show specified baremetal allocation.
|
||||
|
||||
:param String identifier: Name or UUID of the allocation
|
||||
:param List fields: List of fields to show
|
||||
:param List params: Additional kwargs
|
||||
:return: JSON object of allocation
|
||||
"""
|
||||
opts = self.get_opts(fields)
|
||||
output = self.openstack('baremetal allocation show {0} {1} {2}'
|
||||
.format(opts, identifier, params))
|
||||
return json.loads(output)
|
||||
|
||||
def allocation_delete(self, identifier, ignore_exceptions=False):
|
||||
"""Try to delete baremetal allocation by name or UUID.
|
||||
|
||||
:param String identifier: Name or UUID of the allocation
|
||||
:param Bool ignore_exceptions: Ignore exception (needed for cleanUp)
|
||||
:return: raw values output
|
||||
:raise: CommandFailed exception when command fails to delete
|
||||
an allocation
|
||||
"""
|
||||
try:
|
||||
return self.openstack('baremetal allocation delete {0}'
|
||||
.format(identifier))
|
||||
except exceptions.CommandFailed:
|
||||
if not ignore_exceptions:
|
||||
raise
|
||||
|
||||
def deploy_template_create(self, name, params=''):
|
||||
"""Create baremetal deploy template and add cleanup.
|
||||
|
||||
:param String name: deploy template name
|
||||
:param String params: additional parameters
|
||||
:return: JSON object of created deploy template
|
||||
"""
|
||||
opts = self.get_opts()
|
||||
template = self.openstack('baremetal deploy template create {0} {1} '
|
||||
'{2}'.format(opts, name, params))
|
||||
template = json.loads(template)
|
||||
if not template:
|
||||
self.fail('Baremetal deploy template has not been created!')
|
||||
self.addCleanup(self.deploy_template_delete, template['uuid'], True)
|
||||
return template
|
||||
|
||||
def deploy_template_list(self, fields=None, params=''):
|
||||
"""List baremetal deploy templates.
|
||||
|
||||
:param List fields: List of fields to show
|
||||
:param String params: Additional kwargs
|
||||
:return: list of JSON deploy template objects
|
||||
"""
|
||||
opts = self.get_opts(fields=fields)
|
||||
output = self.openstack('baremetal deploy template list {0} {1}'
|
||||
.format(opts, params))
|
||||
return json.loads(output)
|
||||
|
||||
def deploy_template_show(self, identifier, fields=None, params=''):
|
||||
"""Show specified baremetal deploy template.
|
||||
|
||||
:param String identifier: Name or UUID of the deploy template
|
||||
:param List fields: List of fields to show
|
||||
:param List params: Additional kwargs
|
||||
:return: JSON object of deploy template
|
||||
"""
|
||||
opts = self.get_opts(fields)
|
||||
output = self.openstack('baremetal deploy template show {0} {1} {2}'
|
||||
.format(opts, identifier, params))
|
||||
return json.loads(output)
|
||||
|
||||
def deploy_template_delete(self, identifier, ignore_exceptions=False):
|
||||
"""Try to delete baremetal deploy template by UUID.
|
||||
|
||||
:param String identifier: Name or UUID of the deploy template
|
||||
:param Bool ignore_exceptions: Ignore exception (needed for cleanUp)
|
||||
:return: raw values output
|
||||
:raise: CommandFailed exception when command fails to delete a deploy
|
||||
template
|
||||
"""
|
||||
try:
|
||||
return self.openstack('baremetal deploy template delete {0}'
|
||||
.format(identifier))
|
||||
except exceptions.CommandFailed:
|
||||
if not ignore_exceptions:
|
||||
raise
|
||||
@@ -1,187 +0,0 @@
|
||||
# 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 ddt
|
||||
from tempest.lib.common.utils import data_utils
|
||||
from tempest.lib import exceptions
|
||||
|
||||
from ironicclient.tests.functional.osc.v1 import base
|
||||
|
||||
|
||||
@ddt.ddt
|
||||
class BaremetalAllocationTests(base.TestCase):
|
||||
"""Functional tests for baremetal allocation commands."""
|
||||
|
||||
def test_create(self):
|
||||
"""Check baremetal allocation create command.
|
||||
|
||||
Test steps:
|
||||
1) Create baremetal allocation in setUp.
|
||||
2) Check that allocation successfully created.
|
||||
"""
|
||||
allocation_info = self.allocation_create()
|
||||
self.assertTrue(allocation_info['resource_class'])
|
||||
self.assertEqual(allocation_info['state'], 'allocating')
|
||||
|
||||
allocation_list = self.allocation_list()
|
||||
self.assertIn(allocation_info['uuid'],
|
||||
[x['UUID'] for x in allocation_list])
|
||||
|
||||
def test_create_name_uuid(self):
|
||||
"""Check baremetal allocation create command with name and UUID.
|
||||
|
||||
Test steps:
|
||||
1) Create baremetal allocation with specified name and UUID.
|
||||
2) Check that allocation successfully created.
|
||||
"""
|
||||
uuid = data_utils.rand_uuid()
|
||||
name = data_utils.rand_name('baremetal-allocation')
|
||||
allocation_info = self.allocation_create(
|
||||
params='--uuid {0} --name {1}'.format(uuid, name))
|
||||
self.assertEqual(allocation_info['uuid'], uuid)
|
||||
self.assertEqual(allocation_info['name'], name)
|
||||
self.assertTrue(allocation_info['resource_class'])
|
||||
self.assertEqual(allocation_info['state'], 'allocating')
|
||||
|
||||
allocation_list = self.allocation_list()
|
||||
self.assertIn(uuid, [x['UUID'] for x in allocation_list])
|
||||
self.assertIn(name, [x['Name'] for x in allocation_list])
|
||||
|
||||
def test_create_traits(self):
|
||||
"""Check baremetal allocation create command with traits.
|
||||
|
||||
Test steps:
|
||||
1) Create baremetal allocation with specified traits.
|
||||
2) Check that allocation successfully created.
|
||||
"""
|
||||
allocation_info = self.allocation_create(
|
||||
params='--trait CUSTOM_1 --trait CUSTOM_2')
|
||||
self.assertTrue(allocation_info['resource_class'])
|
||||
self.assertEqual(allocation_info['state'], 'allocating')
|
||||
self.assertIn('CUSTOM_1', allocation_info['traits'])
|
||||
self.assertIn('CUSTOM_2', allocation_info['traits'])
|
||||
|
||||
def test_create_candidate_nodes(self):
|
||||
"""Check baremetal allocation create command with candidate nodes.
|
||||
|
||||
Test steps:
|
||||
1) Create two nodes.
|
||||
2) Create baremetal allocation with specified traits.
|
||||
3) Check that allocation successfully created.
|
||||
"""
|
||||
name = data_utils.rand_name('baremetal-allocation')
|
||||
node1 = self.node_create(name=name)
|
||||
node2 = self.node_create()
|
||||
allocation_info = self.allocation_create(
|
||||
params='--candidate-node {0} --candidate-node {1}'
|
||||
.format(node1['name'], node2['uuid']))
|
||||
self.assertEqual(allocation_info['state'], 'allocating')
|
||||
# NOTE(dtantsur): names are converted to uuids in the API
|
||||
self.assertIn(node1['uuid'], allocation_info['candidate_nodes'])
|
||||
self.assertIn(node2['uuid'], allocation_info['candidate_nodes'])
|
||||
|
||||
@ddt.data('name', 'uuid')
|
||||
def test_delete(self, key):
|
||||
"""Check baremetal allocation delete command with name/UUID argument.
|
||||
|
||||
Test steps:
|
||||
1) Create baremetal allocation.
|
||||
2) Delete baremetal allocation by name/UUID.
|
||||
3) Check that allocation deleted successfully.
|
||||
"""
|
||||
name = data_utils.rand_name('baremetal-allocation')
|
||||
allocation = self.allocation_create(params='--name {}'.format(name))
|
||||
output = self.allocation_delete(allocation[key])
|
||||
self.assertIn('Deleted allocation {0}'.format(allocation[key]), output)
|
||||
|
||||
allocation_list = self.allocation_list()
|
||||
self.assertNotIn(allocation['name'],
|
||||
[x['Name'] for x in allocation_list])
|
||||
self.assertNotIn(allocation['uuid'],
|
||||
[x['UUID'] for x in allocation_list])
|
||||
|
||||
@ddt.data('name', 'uuid')
|
||||
def test_show(self, key):
|
||||
"""Check baremetal allocation show command with name and UUID.
|
||||
|
||||
Test steps:
|
||||
1) Create baremetal allocation.
|
||||
2) Show baremetal allocation calling it with name and UUID arguments.
|
||||
3) Check name, uuid and resource_class in allocation show output.
|
||||
"""
|
||||
name = data_utils.rand_name('baremetal-allocation')
|
||||
allocation = self.allocation_create(params='--name {}'.format(name))
|
||||
result = self.allocation_show(allocation[key],
|
||||
['name', 'uuid', 'resource_class'])
|
||||
self.assertEqual(allocation['name'], result['name'])
|
||||
self.assertEqual(allocation['uuid'], result['uuid'])
|
||||
self.assertTrue(result['resource_class'])
|
||||
self.assertNotIn('state', result)
|
||||
|
||||
@ddt.data(
|
||||
('--uuid', '', 'expected one argument'),
|
||||
('--uuid', '!@#$^*&%^', 'Expected UUID for uuid'),
|
||||
('--extra', '', 'expected one argument'),
|
||||
('--name', '', 'expected one argument'),
|
||||
('--name', 'not/a/name', 'invalid name'),
|
||||
('--resource-class', '', 'expected one argument'),
|
||||
('--resource-class', 'x' * 81, 'is too long'),
|
||||
('--trait', '', 'expected one argument'),
|
||||
('--trait', 'foo', 'does not match'),
|
||||
('--candidate-node', '', 'expected one argument'),
|
||||
('--candidate-node', 'banana?', 'Nodes cannot be found'),
|
||||
('--wait', 'meow', 'invalid int value'))
|
||||
@ddt.unpack
|
||||
def test_create_negative(self, argument, value, ex_text):
|
||||
"""Check errors on invalid input parameters."""
|
||||
base_cmd = 'baremetal allocation create'
|
||||
if argument != '--resource-class':
|
||||
base_cmd += ' --resource-class allocation-test'
|
||||
command = self.construct_cmd(base_cmd, argument, value)
|
||||
self.assertRaisesRegex(exceptions.CommandFailed, ex_text,
|
||||
self.openstack, command)
|
||||
|
||||
def test_create_no_resource_class(self):
|
||||
"""Check errors on missing resource class."""
|
||||
base_cmd = 'baremetal allocation create'
|
||||
self.assertRaisesRegex(exceptions.CommandFailed,
|
||||
'--resource-class',
|
||||
self.openstack, base_cmd)
|
||||
|
||||
def test_set_unset(self):
|
||||
"""Check baremetal allocation set and unset commands.
|
||||
|
||||
Test steps:
|
||||
1) Create baremetal allocation in setUp.
|
||||
2) Set extra data for allocation.
|
||||
3) Check that baremetal allocation extra data was set.
|
||||
4) Unset extra data for allocation.
|
||||
5) Check that baremetal allocation extra data was unset.
|
||||
"""
|
||||
name = data_utils.rand_name('baremetal-allocation')
|
||||
allocation = self.allocation_create(params='--name {}'.format(name))
|
||||
extra_key = 'ext'
|
||||
extra_value = 'testdata'
|
||||
self.openstack(
|
||||
'baremetal allocation set --extra {0}={1} {2}'
|
||||
.format(extra_key, extra_value, allocation['uuid']))
|
||||
|
||||
show_prop = self.allocation_show(allocation['uuid'],
|
||||
fields=['extra'])
|
||||
self.assertEqual(extra_value, show_prop['extra'][extra_key])
|
||||
|
||||
self.openstack('baremetal allocation unset --extra {0} {1}'
|
||||
.format(extra_key, allocation['uuid']))
|
||||
|
||||
show_prop = self.allocation_show(allocation['uuid'],
|
||||
fields=['extra'])
|
||||
self.assertNotIn(extra_key, show_prop['extra'])
|
||||
@@ -1,86 +0,0 @@
|
||||
# Copyright (c) 2016 Mirantis, Inc.
|
||||
#
|
||||
# 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 ironicclient.tests.functional.osc.v1 import base
|
||||
|
||||
|
||||
class BaremetalChassisTests(base.TestCase):
|
||||
"""Functional tests for baremetal chassis commands."""
|
||||
|
||||
def setUp(self):
|
||||
super(BaremetalChassisTests, self).setUp()
|
||||
self.chassis = self.chassis_create()
|
||||
|
||||
def test_list(self):
|
||||
"""Check baremetal chassis list command.
|
||||
|
||||
Test steps:
|
||||
1) Create baremetal chassis in setUp.
|
||||
2) List baremetal chassis.
|
||||
3) Check chassis description and UUID in chassis list.
|
||||
"""
|
||||
chassis_list = self.chassis_list()
|
||||
self.assertIn(self.chassis['uuid'],
|
||||
[x['UUID'] for x in chassis_list])
|
||||
self.assertIn(self.chassis['description'],
|
||||
[x['Description'] for x in chassis_list])
|
||||
|
||||
def test_show(self):
|
||||
"""Check baremetal chassis show command.
|
||||
|
||||
Test steps:
|
||||
1) Create baremetal chassis in setUp.
|
||||
2) Show baremetal chassis.
|
||||
3) Check chassis in chassis show.
|
||||
"""
|
||||
chassis = self.chassis_show(self.chassis['uuid'])
|
||||
self.assertEqual(self.chassis['uuid'], chassis['uuid'])
|
||||
self.assertEqual(self.chassis['description'], chassis['description'])
|
||||
|
||||
def test_delete(self):
|
||||
"""Check baremetal chassis delete command.
|
||||
|
||||
Test steps:
|
||||
1) Create baremetal chassis in setUp.
|
||||
2) Delete baremetal chassis by UUID.
|
||||
3) Check that chassis deleted successfully.
|
||||
"""
|
||||
output = self.chassis_delete(self.chassis['uuid'])
|
||||
self.assertIn('Deleted chassis {0}'.format(self.chassis['uuid']),
|
||||
output)
|
||||
self.assertNotIn(self.chassis['uuid'], self.chassis_list(['UUID']))
|
||||
|
||||
def test_set_unset_extra(self):
|
||||
"""Check baremetal chassis set and unset commands.
|
||||
|
||||
Test steps:
|
||||
1) Create baremetal chassis in setUp.
|
||||
2) Set extra data for chassis.
|
||||
3) Check that baremetal chassis extra data was set.
|
||||
4) Unset extra data for chassis.
|
||||
5) Check that baremetal chassis extra data was unset.
|
||||
"""
|
||||
extra_key = 'ext'
|
||||
extra_value = 'testdata'
|
||||
self.openstack('baremetal chassis set --extra {0}={1} {2}'
|
||||
.format(extra_key, extra_value, self.chassis['uuid']))
|
||||
|
||||
show_prop = self.chassis_show(self.chassis['uuid'], ['extra'])
|
||||
self.assertEqual(extra_value, show_prop['extra'][extra_key])
|
||||
|
||||
self.openstack('baremetal chassis unset --extra {0} {1}'
|
||||
.format(extra_key, self.chassis['uuid']))
|
||||
|
||||
show_prop = self.chassis_show(self.chassis['uuid'], ['extra'])
|
||||
self.assertNotIn(extra_key, show_prop['extra'])
|
||||
@@ -1,38 +0,0 @@
|
||||
# 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 ironicclient.tests.functional.osc.v1 import base
|
||||
|
||||
|
||||
class BaremetalConductorTests(base.TestCase):
|
||||
"""Functional tests for baremetal conductor commands."""
|
||||
|
||||
def test_list(self):
|
||||
"""List available conductors.
|
||||
|
||||
There is at lease one conductor in the functional tests, if not, other
|
||||
tests will fail too.
|
||||
"""
|
||||
hostnames = [c['Hostname'] for c in self.conductor_list()]
|
||||
self.assertIsNotNone(hostnames)
|
||||
|
||||
def test_show(self):
|
||||
"""Show specified conductor.
|
||||
|
||||
Conductor name varies in different environment, list first, then show
|
||||
one of them.
|
||||
"""
|
||||
conductors = self.conductor_list()
|
||||
conductor = self.conductor_show(conductors[0]['Hostname'])
|
||||
self.assertIn('conductor_group', conductor)
|
||||
self.assertIn('alive', conductor)
|
||||
self.assertIn('drivers', conductor)
|
||||
@@ -1,177 +0,0 @@
|
||||
# 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 json
|
||||
|
||||
import ddt
|
||||
from tempest.lib.common.utils import data_utils
|
||||
from tempest.lib import exceptions
|
||||
|
||||
from ironicclient.tests.functional.osc.v1 import base
|
||||
|
||||
|
||||
@ddt.ddt
|
||||
class BaremetalDeployTemplateTests(base.TestCase):
|
||||
"""Functional tests for baremetal deploy template commands."""
|
||||
|
||||
@staticmethod
|
||||
def _get_random_trait():
|
||||
return data_utils.rand_name('CUSTOM', '').replace('-', '_')
|
||||
|
||||
def setUp(self):
|
||||
super(BaremetalDeployTemplateTests, self).setUp()
|
||||
self.steps = json.dumps([{
|
||||
'interface': 'bios',
|
||||
'step': 'apply_configuration',
|
||||
'args': {},
|
||||
'priority': 10,
|
||||
}])
|
||||
name = self._get_random_trait()
|
||||
self.template = self.deploy_template_create(
|
||||
name, params="--steps '%s'" % self.steps)
|
||||
|
||||
def tearDown(self):
|
||||
if self.template is not None:
|
||||
self.deploy_template_delete(self.template['uuid'])
|
||||
super(BaremetalDeployTemplateTests, self).tearDown()
|
||||
|
||||
def test_list(self):
|
||||
"""Check baremetal deploy template list command.
|
||||
|
||||
Test steps:
|
||||
1) Create baremetal deploy template in setUp.
|
||||
2) List baremetal deploy templates.
|
||||
3) Check deploy template name and UUID in deploy templates list.
|
||||
"""
|
||||
template_list = self.deploy_template_list()
|
||||
self.assertIn(self.template['name'],
|
||||
[template['Name']
|
||||
for template in template_list])
|
||||
self.assertIn(self.template['uuid'],
|
||||
[template['UUID']
|
||||
for template in template_list])
|
||||
|
||||
def test_list_long(self):
|
||||
"""Check baremetal deploy template list --long command
|
||||
|
||||
Test steps:
|
||||
1) Create baremetal deploy template in setUp.
|
||||
2) List baremetal deploy templates with detail=True.
|
||||
3) Check deploy template fields in output.
|
||||
"""
|
||||
template_list = self.deploy_template_list(params='--long')
|
||||
template = [template for template in template_list
|
||||
if template['Name'] == self.template['name']][0]
|
||||
self.assertEqual(self.template['extra'], template['Extra'])
|
||||
self.assertEqual(self.template['name'], template['Name'])
|
||||
self.assertEqual(self.template['steps'], template['Steps'])
|
||||
self.assertEqual(self.template['uuid'], template['UUID'])
|
||||
|
||||
def test_show(self):
|
||||
"""Check baremetal deploy template show command with UUID.
|
||||
|
||||
Test steps:
|
||||
1) Create baremetal deploy template in setUp.
|
||||
2) Show baremetal deploy template calling it by UUID.
|
||||
3) Check deploy template fields in output.
|
||||
"""
|
||||
template = self.deploy_template_show(self.template['uuid'])
|
||||
self.assertEqual(self.template['extra'], template['extra'])
|
||||
self.assertEqual(self.template['name'], template['name'])
|
||||
self.assertEqual(self.template['steps'], template['steps'])
|
||||
self.assertEqual(self.template['uuid'], template['uuid'])
|
||||
|
||||
def test_delete(self):
|
||||
"""Check baremetal deploy template delete command.
|
||||
|
||||
Test steps:
|
||||
1) Create baremetal deploy template in setUp.
|
||||
2) Delete baremetal deploy template by UUID.
|
||||
3) Check that deploy template deleted successfully and not in list.
|
||||
"""
|
||||
output = self.deploy_template_delete(self.template['uuid'])
|
||||
self.assertIn('Deleted deploy template {0}'.format(
|
||||
self.template['uuid']), output)
|
||||
template_list = self.deploy_template_list()
|
||||
self.assertNotIn(self.template['name'],
|
||||
[template['Name'] for template in template_list])
|
||||
self.assertNotIn(self.template['uuid'],
|
||||
[template['UUID'] for template in template_list])
|
||||
self.template = None
|
||||
|
||||
def test_set_steps(self):
|
||||
"""Check baremetal deploy template set command for steps.
|
||||
|
||||
Test steps:
|
||||
1) Create baremetal deploy template in setUp.
|
||||
2) Set steps for deploy template.
|
||||
3) Check that baremetal deploy template steps were set.
|
||||
"""
|
||||
steps = [{
|
||||
'interface': 'bios',
|
||||
'step': 'apply_configuration',
|
||||
'args': {},
|
||||
'priority': 20,
|
||||
}]
|
||||
self.openstack("baremetal deploy template set --steps '{0}' {1}"
|
||||
.format(json.dumps(steps), self.template['uuid']))
|
||||
|
||||
show_prop = self.deploy_template_show(self.template['uuid'],
|
||||
fields=['steps'])
|
||||
self.assertEqual(steps, show_prop['steps'])
|
||||
|
||||
def test_set_unset(self):
|
||||
"""Check baremetal deploy template set and unset commands.
|
||||
|
||||
Test steps:
|
||||
1) Create baremetal deploy template in setUp.
|
||||
2) Set extra data for deploy template.
|
||||
3) Check that baremetal deploy template extra data was set.
|
||||
4) Unset extra data for deploy template.
|
||||
5) Check that baremetal deploy template extra data was unset.
|
||||
"""
|
||||
extra_key = 'ext'
|
||||
extra_value = 'testdata'
|
||||
self.openstack(
|
||||
'baremetal deploy template set --extra {0}={1} {2}'
|
||||
.format(extra_key, extra_value, self.template['uuid']))
|
||||
|
||||
show_prop = self.deploy_template_show(self.template['uuid'],
|
||||
fields=['extra'])
|
||||
self.assertEqual(extra_value, show_prop['extra'][extra_key])
|
||||
|
||||
self.openstack('baremetal deploy template unset --extra {0} {1}'
|
||||
.format(extra_key, self.template['uuid']))
|
||||
|
||||
show_prop = self.deploy_template_show(self.template['uuid'],
|
||||
fields=['extra'])
|
||||
self.assertNotIn(extra_key, show_prop['extra'])
|
||||
|
||||
@ddt.data(
|
||||
('--uuid', '', 'expected one argument'),
|
||||
('--uuid', '!@#$^*&%^', 'Expected UUID for uuid'),
|
||||
('', '', 'the following arguments are required'),
|
||||
('', 'not/a/name', 'does not match'),
|
||||
('', 'foo', 'does not match'),
|
||||
('--steps', '', 'expected one argument'),
|
||||
('--steps', '[]', 'is too short'))
|
||||
@ddt.unpack
|
||||
def test_create_negative(self, argument, value, ex_text):
|
||||
"""Check errors on invalid input parameters."""
|
||||
base_cmd = 'baremetal deploy template create'
|
||||
if argument != '':
|
||||
base_cmd += ' %s' % self._get_random_trait()
|
||||
if argument != '--steps':
|
||||
base_cmd += " --steps '%s'" % self.steps
|
||||
command = self.construct_cmd(base_cmd, argument, value)
|
||||
self.assertRaisesRegex(exceptions.CommandFailed, ex_text,
|
||||
self.openstack, command)
|
||||
@@ -1,57 +0,0 @@
|
||||
# Copyright (c) 2016 Mirantis, Inc.
|
||||
#
|
||||
# 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 ironicclient.tests.functional.osc.v1 import base
|
||||
|
||||
|
||||
class BaremetalDriverTests(base.TestCase):
|
||||
"""Functional tests for baremetal driver commands."""
|
||||
|
||||
def test_show(self):
|
||||
"""Show specified driver.
|
||||
|
||||
Test step:
|
||||
1) Check output of baremetal driver show command.
|
||||
"""
|
||||
driver = self.driver_show(self.driver_name)
|
||||
self.assertEqual(self.driver_name, driver['name'])
|
||||
|
||||
def test_list(self):
|
||||
"""List available drivers.
|
||||
|
||||
Test steps:
|
||||
1) Get list of drivers.
|
||||
2) Check that list of drivers is not empty.
|
||||
"""
|
||||
drivers = [
|
||||
driver['Supported driver(s)'] for driver in self.driver_list()
|
||||
]
|
||||
self.assertIn(self.driver_name, drivers)
|
||||
|
||||
def test_driver_raid_property_list(self):
|
||||
"""Test baremetal driver raid property list command.
|
||||
|
||||
Test steps:
|
||||
1) Get list of fake driver raid properties.
|
||||
2) Check contents of driver raid properties list.
|
||||
"""
|
||||
props = ['controller', 'disk_type', 'interface_type',
|
||||
'is_root_volume', 'number_of_physical_disks',
|
||||
'physical_disks', 'raid_level', 'share_physical_disks',
|
||||
'size_gb', 'volume_name']
|
||||
raid_props = self.driver_raid_property_list(
|
||||
self.driver_name,
|
||||
params='--os-baremetal-api-version 1.12')
|
||||
for prop in props:
|
||||
self.assertIn(prop, [i['Property'] for i in raid_props])
|
||||
@@ -1,231 +0,0 @@
|
||||
# Copyright (c) 2016 Mirantis, Inc.
|
||||
#
|
||||
# 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 json
|
||||
|
||||
import ddt
|
||||
from tempest.lib.common.utils import data_utils
|
||||
|
||||
from ironicclient.tests.functional.osc.v1 import base
|
||||
|
||||
|
||||
@ddt.ddt
|
||||
class BaremetalNodeTests(base.TestCase):
|
||||
"""Functional tests for baremetal node commands."""
|
||||
|
||||
def setUp(self):
|
||||
super(BaremetalNodeTests, self).setUp()
|
||||
self.node = self.node_create()
|
||||
|
||||
def test_create_name_uuid(self):
|
||||
"""Check baremetal node create command with name and UUID.
|
||||
|
||||
Test steps:
|
||||
1) Create baremetal node in setUp.
|
||||
2) Create one more baremetal node explicitly
|
||||
with specified name and UUID.
|
||||
3) Check that node successfully created.
|
||||
"""
|
||||
uuid = data_utils.rand_uuid()
|
||||
name = data_utils.rand_name('baremetal-node')
|
||||
node_info = self.node_create(name=name,
|
||||
params='--uuid {0}'.format(uuid))
|
||||
self.assertEqual(node_info['uuid'], uuid)
|
||||
self.assertEqual(node_info['name'], name)
|
||||
self.assertEqual(node_info['driver'], self.driver_name)
|
||||
self.assertEqual(node_info['maintenance'], False)
|
||||
self.assertEqual(node_info['provision_state'], 'enroll')
|
||||
node_list = self.node_list()
|
||||
self.assertIn(uuid, [x['UUID'] for x in node_list])
|
||||
self.assertIn(name, [x['Name'] for x in node_list])
|
||||
|
||||
def test_create_old_api_version(self):
|
||||
"""Check baremetal node create command with name and UUID.
|
||||
|
||||
Test steps:
|
||||
1) Create baremetal node in setUp.
|
||||
2) Create one more baremetal node explicitly with old API version
|
||||
3) Check that node successfully created.
|
||||
"""
|
||||
node_info = self.node_create(
|
||||
params='--os-baremetal-api-version 1.5')
|
||||
self.assertEqual(node_info['driver'], self.driver_name)
|
||||
self.assertEqual(node_info['maintenance'], False)
|
||||
self.assertEqual(node_info['provision_state'], 'available')
|
||||
|
||||
@ddt.data('name', 'uuid')
|
||||
def test_delete(self, key):
|
||||
"""Check baremetal node delete command with name/UUID argument.
|
||||
|
||||
Test steps:
|
||||
1) Create baremetal node in setUp.
|
||||
2) Delete baremetal node by name/UUID.
|
||||
3) Check that node deleted successfully.
|
||||
"""
|
||||
output = self.node_delete(self.node[key])
|
||||
self.assertIn('Deleted node {0}'.format(self.node[key]), output)
|
||||
node_list = self.node_list()
|
||||
self.assertNotIn(self.node['name'], [x['Name'] for x in node_list])
|
||||
self.assertNotIn(self.node['uuid'], [x['UUID'] for x in node_list])
|
||||
|
||||
def test_list(self):
|
||||
"""Check baremetal node list command.
|
||||
|
||||
Test steps:
|
||||
1) Create baremetal node in setUp.
|
||||
2) List baremetal nodes.
|
||||
3) Check node name in nodes list.
|
||||
"""
|
||||
node_list = self.node_list()
|
||||
self.assertIn(self.node['name'], [x['Name'] for x in node_list])
|
||||
self.assertIn(self.node['uuid'], [x['UUID'] for x in node_list])
|
||||
|
||||
@ddt.data('name', 'uuid')
|
||||
def test_set(self, key):
|
||||
"""Check baremetal node set command calling it by name/UUID.
|
||||
|
||||
Test steps:
|
||||
1) Create baremetal node in setUp.
|
||||
2) Set another name for node calling it by name/UUID.
|
||||
3) Check that baremetal node name was changed.
|
||||
"""
|
||||
new_name = data_utils.rand_name('newnodename')
|
||||
self.openstack('baremetal node set --name {0} {1}'
|
||||
.format(new_name, self.node[key]))
|
||||
show_prop = self.node_show(self.node['uuid'], ['name'])
|
||||
self.assertEqual(new_name, show_prop['name'])
|
||||
|
||||
@ddt.data('name', 'uuid')
|
||||
def test_unset(self, key):
|
||||
"""Check baremetal node unset command calling it by node name/UUID.
|
||||
|
||||
Test steps:
|
||||
1) Create baremetal node in setUp.
|
||||
2) Unset name of baremetal node calling it by node name/UUID.
|
||||
3) Check that node has no more name.
|
||||
"""
|
||||
self.openstack('baremetal node unset --name {0}'
|
||||
.format(self.node[key]))
|
||||
show_prop = self.node_show(self.node['uuid'], ['name'])
|
||||
self.assertIsNone(show_prop['name'])
|
||||
|
||||
@ddt.data('name', 'uuid')
|
||||
def test_show(self, key):
|
||||
"""Check baremetal node show command with name and UUID arguments.
|
||||
|
||||
Test steps:
|
||||
1) Create baremetal node in setUp.
|
||||
2) Show baremetal node calling it with name and UUID arguments.
|
||||
3) Check name, uuid and driver in node show output.
|
||||
"""
|
||||
node = self.node_show(self.node[key],
|
||||
['name', 'uuid', 'driver'])
|
||||
self.assertEqual(self.node['name'], node['name'])
|
||||
self.assertEqual(self.node['uuid'], node['uuid'])
|
||||
self.assertEqual(self.node['driver'], node['driver'])
|
||||
|
||||
def test_baremetal_node_maintenance_set_unset(self):
|
||||
"""Check baremetal node maintenance set command.
|
||||
|
||||
Test steps:
|
||||
1) Create baremetal node in setUp.
|
||||
2) Check maintenance status of fresh node is False.
|
||||
3) Set maintenance status for node.
|
||||
4) Check maintenance status of node is True.
|
||||
5) Unset maintenance status for node.
|
||||
6) Check maintenance status of node is False back.
|
||||
"""
|
||||
show_prop = self.node_show(self.node['name'], ['maintenance'])
|
||||
self.assertFalse(show_prop['maintenance'])
|
||||
|
||||
self.openstack('baremetal node maintenance set {0}'.
|
||||
format(self.node['name']))
|
||||
|
||||
show_prop = self.node_show(self.node['name'], ['maintenance'])
|
||||
self.assertTrue(show_prop['maintenance'])
|
||||
|
||||
self.openstack('baremetal node maintenance unset {0}'.
|
||||
format(self.node['name']))
|
||||
|
||||
show_prop = self.node_show(self.node['name'], ['maintenance'])
|
||||
self.assertFalse(show_prop['maintenance'])
|
||||
|
||||
def test_baremetal_node_maintenance_set_unset_reason(self):
|
||||
"""Check baremetal node maintenance set command.
|
||||
|
||||
Test steps:
|
||||
1) Create baremetal node in setUp.
|
||||
2) Check initial maintenance reason is None.
|
||||
3) Set maintenance status for node with reason.
|
||||
4) Check maintenance reason of node equals to expected value.
|
||||
Also check maintenance status.
|
||||
5) Unset maintenance status for node. Recheck maintenance status.
|
||||
6) Check maintenance reason is None. Recheck maintenance status.
|
||||
"""
|
||||
reason = "Hardware maintenance."
|
||||
show_prop = self.node_show(self.node['name'],
|
||||
['maintenance_reason', 'maintenance'])
|
||||
self.assertIsNone(show_prop['maintenance_reason'])
|
||||
self.assertFalse(show_prop['maintenance'])
|
||||
|
||||
self.openstack("baremetal node maintenance set --reason '{0}' {1}".
|
||||
format(reason, self.node['name']))
|
||||
|
||||
show_prop = self.node_show(self.node['name'],
|
||||
['maintenance_reason', 'maintenance'])
|
||||
self.assertEqual(reason, show_prop['maintenance_reason'])
|
||||
self.assertTrue(show_prop['maintenance'])
|
||||
|
||||
self.openstack('baremetal node maintenance unset {0}'.
|
||||
format(self.node['name']))
|
||||
|
||||
show_prop = self.node_show(self.node['name'],
|
||||
['maintenance_reason', 'maintenance'])
|
||||
self.assertIsNone(show_prop['maintenance_reason'])
|
||||
self.assertFalse(show_prop['maintenance'])
|
||||
|
||||
@ddt.data(
|
||||
(50, '1'),
|
||||
('MAX', 'JBOD'),
|
||||
(300, '6+0')
|
||||
)
|
||||
@ddt.unpack
|
||||
def test_set_unset_target_raid_config(self, size, raid_level):
|
||||
"""Set and unset node target RAID config data.
|
||||
|
||||
Test steps:
|
||||
1) Create baremetal node in setUp.
|
||||
2) Set target RAID config data for the node
|
||||
3) Check target_raid_config of node equals to expected value.
|
||||
4) Unset target_raid_config data.
|
||||
5) Check that target_raid_config data is empty.
|
||||
"""
|
||||
min_version = '--os-baremetal-api-version 1.12'
|
||||
argument_json = {"logical_disks":
|
||||
[{"size_gb": size, "raid_level": raid_level}]}
|
||||
argument_string = json.dumps(argument_json)
|
||||
self.openstack("baremetal node set --target-raid-config '{}' {} {}"
|
||||
.format(argument_string, self.node['uuid'],
|
||||
min_version))
|
||||
|
||||
show_prop = self.node_show(self.node['uuid'], ['target_raid_config'],
|
||||
min_version)
|
||||
self.assert_dict_is_subset(argument_json,
|
||||
show_prop['target_raid_config'])
|
||||
|
||||
self.openstack("baremetal node unset --target-raid-config {} {}"
|
||||
.format(self.node['uuid'], min_version))
|
||||
show_prop = self.node_show(self.node['uuid'], ['target_raid_config'],
|
||||
min_version)
|
||||
self.assertEqual({}, show_prop['target_raid_config'])
|
||||
@@ -1,47 +0,0 @@
|
||||
# Copyright (c) 2016 Mirantis, Inc.
|
||||
#
|
||||
# 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 ddt
|
||||
from tempest.lib import exceptions
|
||||
|
||||
from ironicclient.tests.functional.osc.v1 import base
|
||||
|
||||
|
||||
@ddt.ddt
|
||||
class BaremetalNodeCreateNegativeTests(base.TestCase):
|
||||
"""Negative tests for node create command."""
|
||||
|
||||
def setUp(self):
|
||||
super(BaremetalNodeCreateNegativeTests, self).setUp()
|
||||
|
||||
@ddt.data(
|
||||
('--uuid', '', 'expected one argument'),
|
||||
('--uuid', '!@#$^*&%^', 'Expected UUID for uuid'),
|
||||
('--uuid', '0000 0000', 'unrecognized arguments'),
|
||||
('--driver-info', '', 'expected one argument'),
|
||||
('--driver-info', 'some info', 'unrecognized arguments'),
|
||||
('--property', '', 'expected one argument'),
|
||||
('--property', 'some property', 'unrecognized arguments'),
|
||||
('--extra', '', 'expected one argument'),
|
||||
('--extra', 'some extra', 'unrecognized arguments'),
|
||||
('--name', '', 'expected one argument'),
|
||||
('--name', 'some name', 'unrecognized arguments'),
|
||||
('--network-interface', '', 'expected one argument'),
|
||||
('--resource-class', '', 'expected one argument'))
|
||||
@ddt.unpack
|
||||
def test_baremetal_node_create(self, argument, value, ex_text):
|
||||
base_cmd = 'baremetal node create --driver %s' % self.driver_name
|
||||
command = self.construct_cmd(base_cmd, argument, value)
|
||||
self.assertRaisesRegex(exceptions.CommandFailed, ex_text,
|
||||
self.openstack, command)
|
||||
@@ -1,136 +0,0 @@
|
||||
# Copyright (c) 2017 Mirantis, Inc.
|
||||
#
|
||||
# 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 tempest.lib import exceptions
|
||||
|
||||
from ironicclient.tests.functional.osc.v1 import base
|
||||
|
||||
|
||||
class TestNodeListFields(base.TestCase):
|
||||
"""Functional tests for "baremetal node list" with --fields."""
|
||||
|
||||
def setUp(self):
|
||||
super(TestNodeListFields, self).setUp()
|
||||
self.node = self.node_create()
|
||||
|
||||
def _get_table_headers(self, raw_output):
|
||||
table = self.parser.table(raw_output)
|
||||
return table['headers']
|
||||
|
||||
def test_list_default_fields(self):
|
||||
"""Test presence of default list table headers."""
|
||||
headers = ['UUID', 'Name', 'Instance UUID',
|
||||
'Power State', 'Provisioning State', 'Maintenance']
|
||||
|
||||
nodes_list = self.openstack('baremetal node list')
|
||||
nodes_list_headers = self._get_table_headers(nodes_list)
|
||||
|
||||
self.assertEqual(set(headers), set(nodes_list_headers))
|
||||
|
||||
def test_list_minimal_fields(self):
|
||||
headers = ['Instance UUID', 'Name', 'UUID']
|
||||
fields = ['instance_uuid', 'name', 'uuid']
|
||||
|
||||
node_list = self.openstack(
|
||||
'baremetal node list --fields {}'.format(' '.join(fields)))
|
||||
|
||||
nodes_list_headers = self._get_table_headers(node_list)
|
||||
self.assertEqual(headers, nodes_list_headers)
|
||||
|
||||
def test_list_no_fields(self):
|
||||
command = 'baremetal node list --fields'
|
||||
ex_text = 'expected at least one argument'
|
||||
self.assertRaisesRegex(exceptions.CommandFailed, ex_text,
|
||||
self.openstack, command)
|
||||
|
||||
def test_list_wrong_field(self):
|
||||
command = 'baremetal node list --fields ABC'
|
||||
ex_text = 'invalid choice'
|
||||
self.assertRaisesRegex(exceptions.CommandFailed, ex_text,
|
||||
self.openstack, command)
|
||||
|
||||
|
||||
class TestNodeShowFields(base.TestCase):
|
||||
"""Functional tests for "baremetal node show" with --fields."""
|
||||
|
||||
def setUp(self):
|
||||
super(TestNodeShowFields, self).setUp()
|
||||
self.node = self.node_create()
|
||||
self.api_version = '--os-baremetal-api-version 1.20'
|
||||
|
||||
def _get_table_rows(self, raw_output):
|
||||
table = self.parser.table(raw_output)
|
||||
rows = []
|
||||
for row in table['values']:
|
||||
rows.append(row[0])
|
||||
return rows
|
||||
|
||||
def test_show_default_fields(self):
|
||||
rows = ['console_enabled',
|
||||
'clean_step',
|
||||
'created_at',
|
||||
'deploy_step',
|
||||
'driver',
|
||||
'driver_info',
|
||||
'driver_internal_info',
|
||||
'extra',
|
||||
'inspection_finished_at',
|
||||
'inspection_started_at',
|
||||
'instance_info',
|
||||
'instance_uuid',
|
||||
'last_error',
|
||||
'maintenance',
|
||||
'maintenance_reason',
|
||||
'name',
|
||||
'power_state',
|
||||
'properties',
|
||||
'provision_state',
|
||||
'provision_updated_at',
|
||||
'reservation',
|
||||
'target_power_state',
|
||||
'target_provision_state',
|
||||
'updated_at',
|
||||
'uuid']
|
||||
node_show = self.openstack('baremetal node show {}'
|
||||
.format(self.node['uuid']))
|
||||
nodes_show_rows = self._get_table_rows(node_show)
|
||||
|
||||
self.assertTrue(set(rows).issubset(set(nodes_show_rows)))
|
||||
|
||||
def test_show_minimal_fields(self):
|
||||
rows = [
|
||||
'instance_uuid',
|
||||
'name',
|
||||
'uuid']
|
||||
|
||||
node_show = self.openstack(
|
||||
'baremetal node show {} --fields {} {}'.format(
|
||||
self.node['uuid'], ' '.join(rows), self.api_version))
|
||||
|
||||
nodes_show_rows = self._get_table_rows(node_show)
|
||||
self.assertEqual(set(rows), set(nodes_show_rows))
|
||||
|
||||
def test_show_no_fields(self):
|
||||
command = 'baremetal node show {} --fields {}'.format(
|
||||
self.node['uuid'], self.api_version)
|
||||
ex_text = 'expected at least one argument'
|
||||
self.assertRaisesRegex(exceptions.CommandFailed, ex_text,
|
||||
self.openstack, command)
|
||||
|
||||
def test_show_wrong_field(self):
|
||||
command = 'baremetal node show {} --fields ABC {}'.format(
|
||||
self.node['uuid'], self.api_version)
|
||||
ex_text = 'invalid choice'
|
||||
self.assertRaisesRegex(exceptions.CommandFailed, ex_text,
|
||||
self.openstack, command)
|
||||
@@ -1,83 +0,0 @@
|
||||
# Copyright (c) 2017 Mirantis, Inc.
|
||||
#
|
||||
# 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 ddt
|
||||
from tempest.lib import exceptions
|
||||
|
||||
from ironicclient.tests.functional.osc.v1 import base
|
||||
|
||||
|
||||
@ddt.ddt
|
||||
class BaremetalNodeNegativeTests(base.TestCase):
|
||||
"""Negative tests for baremetal node commands."""
|
||||
|
||||
def setUp(self):
|
||||
super(BaremetalNodeNegativeTests, self).setUp()
|
||||
self.node = self.node_create()
|
||||
|
||||
@ddt.data(
|
||||
('', '', 'error: the following arguments are required: --driver'),
|
||||
('--driver', 'wrongdriver',
|
||||
'No valid host was found. Reason: No conductor service '
|
||||
'registered which supports driver wrongdriver.')
|
||||
)
|
||||
@ddt.unpack
|
||||
def test_create_driver(self, argument, value, ex_text):
|
||||
"""Negative test for baremetal node driver options."""
|
||||
base_cmd = 'baremetal node create'
|
||||
command = self.construct_cmd(base_cmd, argument, value)
|
||||
self.assertRaisesRegex(exceptions.CommandFailed, ex_text,
|
||||
self.openstack, command)
|
||||
|
||||
def test_delete_no_node(self):
|
||||
"""Test for baremetal node delete without node specified."""
|
||||
command = 'baremetal node delete'
|
||||
ex_text = ''
|
||||
self.assertRaisesRegex(exceptions.CommandFailed, ex_text,
|
||||
self.openstack, command)
|
||||
|
||||
def test_list_wrong_argument(self):
|
||||
"""Test for baremetal node list with wrong argument."""
|
||||
command = 'baremetal node list --wrong_arg'
|
||||
ex_text = 'error: unrecognized arguments: --wrong_arg'
|
||||
self.assertRaisesRegex(exceptions.CommandFailed, ex_text,
|
||||
self.openstack, command)
|
||||
|
||||
@ddt.data(
|
||||
('--property', '',
|
||||
'error: the following arguments are required: <node>'),
|
||||
('--property', 'prop', 'Attributes must be a list of PATH=VALUE')
|
||||
)
|
||||
@ddt.unpack
|
||||
def test_set_property(self, argument, value, ex_text):
|
||||
"""Negative test for baremetal node set command options."""
|
||||
base_cmd = 'baremetal node set'
|
||||
command = self.construct_cmd(base_cmd, argument, value,
|
||||
self.node['uuid'])
|
||||
self.assertRaisesRegex(exceptions.CommandFailed, ex_text,
|
||||
self.openstack, command)
|
||||
|
||||
@ddt.data(
|
||||
('--property', '',
|
||||
'error: the following arguments are required: <node>'),
|
||||
('--property', 'prop', "Reason: can't remove a non-existent object")
|
||||
)
|
||||
@ddt.unpack
|
||||
def test_unset_property(self, argument, value, ex_text):
|
||||
"""Negative test for baremetal node unset command options."""
|
||||
base_cmd = 'baremetal node unset'
|
||||
command = self.construct_cmd(base_cmd, argument, value,
|
||||
self.node['uuid'])
|
||||
self.assertRaisesRegex(exceptions.CommandFailed, ex_text,
|
||||
self.openstack, command)
|
||||
@@ -1,58 +0,0 @@
|
||||
# Copyright (c) 2016 Mirantis, Inc.
|
||||
#
|
||||
# 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 ironicclient.tests.functional.osc.v1 import base
|
||||
|
||||
|
||||
class PowerStateTests(base.TestCase):
|
||||
"""Functional tests for baremetal node power state commands."""
|
||||
|
||||
def setUp(self):
|
||||
super(PowerStateTests, self).setUp()
|
||||
self.node = self.node_create()
|
||||
|
||||
def test_off_reboot_on(self):
|
||||
"""Reboot node from Power OFF state.
|
||||
|
||||
Test steps:
|
||||
1) Create baremetal node in setUp.
|
||||
2) Set node Power State OFF as precondition.
|
||||
3) Call reboot command for baremetal node.
|
||||
4) Check node Power State ON in node properties.
|
||||
"""
|
||||
self.openstack('baremetal node power off {0}'
|
||||
.format(self.node['uuid']))
|
||||
show_prop = self.node_show(self.node['uuid'], ['power_state'])
|
||||
self.assertEqual('power off', show_prop['power_state'])
|
||||
|
||||
self.openstack('baremetal node reboot {0}'.format(self.node['uuid']))
|
||||
show_prop = self.node_show(self.node['uuid'], ['power_state'])
|
||||
self.assertEqual('power on', show_prop['power_state'])
|
||||
|
||||
def test_on_reboot_on(self):
|
||||
"""Reboot node from Power ON state.
|
||||
|
||||
Test steps:
|
||||
1) Create baremetal node in setUp.
|
||||
2) Set node Power State ON as precondition.
|
||||
3) Call reboot command for baremetal node.
|
||||
4) Check node Power State ON in node properties.
|
||||
"""
|
||||
self.openstack('baremetal node power on {0}'.format(self.node['uuid']))
|
||||
show_prop = self.node_show(self.node['uuid'], ['power_state'])
|
||||
self.assertEqual('power on', show_prop['power_state'])
|
||||
|
||||
self.openstack('baremetal node reboot {0}'.format(self.node['uuid']))
|
||||
show_prop = self.node_show(self.node['uuid'], ['power_state'])
|
||||
self.assertEqual('power on', show_prop['power_state'])
|
||||
@@ -1,84 +0,0 @@
|
||||
# Copyright (c) 2016 Mirantis, Inc.
|
||||
#
|
||||
# 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 ironicclient.tests.functional.osc.v1 import base
|
||||
|
||||
|
||||
class ProvisionStateTests(base.TestCase):
|
||||
"""Functional tests for baremetal node provision state commands."""
|
||||
|
||||
def setUp(self):
|
||||
super(ProvisionStateTests, self).setUp()
|
||||
self.node = self.node_create()
|
||||
|
||||
def test_deploy_rebuild_undeploy_manage(self):
|
||||
"""Deploy, rebuild and undeploy node.
|
||||
|
||||
Test steps:
|
||||
1) Create baremetal node in setUp.
|
||||
2) Check initial "enroll" provision state.
|
||||
3) Set baremetal node "manage" provision state.
|
||||
4) Check baremetal node provision_state field value is "manageable".
|
||||
5) Set baremetal node "provide" provision state.
|
||||
6) Check baremetal node provision_state field value is "available".
|
||||
7) Set baremetal node "deploy" provision state.
|
||||
8) Check baremetal node provision_state field value is "active".
|
||||
9) Set baremetal node "rebuild" provision state.
|
||||
10) Check baremetal node provision_state field value is "active".
|
||||
11) Set baremetal node "undeploy" provision state.
|
||||
12) Check baremetal node provision_state field value is "available".
|
||||
13) Set baremetal node "manage" provision state.
|
||||
14) Check baremetal node provision_state field value is "manageable".
|
||||
15) Set baremetal node "provide" provision state.
|
||||
16) Check baremetal node provision_state field value is "available".
|
||||
"""
|
||||
show_prop = self.node_show(self.node['uuid'], ["provision_state"])
|
||||
self.assertEqual("enroll", show_prop["provision_state"])
|
||||
|
||||
# manage
|
||||
self.openstack('baremetal node manage {0}'.format(self.node['uuid']))
|
||||
show_prop = self.node_show(self.node['uuid'], ["provision_state"])
|
||||
self.assertEqual("manageable", show_prop["provision_state"])
|
||||
|
||||
# provide
|
||||
self.openstack('baremetal node provide {0}'.format(self.node['uuid']))
|
||||
show_prop = self.node_show(self.node['uuid'], ["provision_state"])
|
||||
self.assertEqual("available", show_prop["provision_state"])
|
||||
|
||||
# deploy
|
||||
self.openstack('baremetal node deploy {0}'.format(self.node['uuid']))
|
||||
show_prop = self.node_show(self.node['uuid'], ["provision_state"])
|
||||
self.assertEqual("active", show_prop["provision_state"])
|
||||
|
||||
# rebuild
|
||||
self.openstack('baremetal node rebuild {0}'.format(self.node['uuid']))
|
||||
|
||||
show_prop = self.node_show(self.node['uuid'], ["provision_state"])
|
||||
self.assertEqual("active", show_prop["provision_state"])
|
||||
|
||||
# undeploy
|
||||
self.openstack('baremetal node undeploy {0}'.format(self.node['uuid']))
|
||||
|
||||
show_prop = self.node_show(self.node['uuid'], ["provision_state"])
|
||||
self.assertEqual("available", show_prop["provision_state"])
|
||||
|
||||
# manage
|
||||
self.openstack('baremetal node manage {0}'.format(self.node['uuid']))
|
||||
show_prop = self.node_show(self.node['uuid'], ["provision_state"])
|
||||
self.assertEqual("manageable", show_prop["provision_state"])
|
||||
|
||||
# provide back
|
||||
self.openstack('baremetal node provide {0}'.format(self.node['uuid']))
|
||||
show_prop = self.node_show(self.node['uuid'], ["provision_state"])
|
||||
self.assertEqual("available", show_prop["provision_state"])
|
||||
@@ -1,124 +0,0 @@
|
||||
# Copyright (c) 2016 Mirantis, Inc.
|
||||
#
|
||||
# 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 ironicclient.tests.functional.osc.v1 import base
|
||||
|
||||
|
||||
class BaremetalPortTests(base.TestCase):
|
||||
"""Functional tests for baremetal port commands."""
|
||||
|
||||
def setUp(self):
|
||||
super(BaremetalPortTests, self).setUp()
|
||||
self.node = self.node_create()
|
||||
self.port = self.port_create(self.node['uuid'])
|
||||
|
||||
def test_list(self):
|
||||
"""Check baremetal port list command.
|
||||
|
||||
Test steps:
|
||||
1) Create baremetal port in setUp.
|
||||
2) List baremetal ports.
|
||||
3) Check port address and UUID in ports list.
|
||||
"""
|
||||
port_list = self.port_list()
|
||||
self.assertIn(self.port['address'],
|
||||
[port['Address'] for port in port_list])
|
||||
self.assertIn(self.port['uuid'],
|
||||
[port['UUID'] for port in port_list])
|
||||
|
||||
def test_show_uuid(self):
|
||||
"""Check baremetal port show command with UUID.
|
||||
|
||||
Test steps:
|
||||
1) Create baremetal port in setUp.
|
||||
2) Show baremetal port calling it by UUID.
|
||||
3) Check port fields in output.
|
||||
"""
|
||||
port = self.port_show(self.port['uuid'])
|
||||
self.assertEqual(self.port['address'], port['address'])
|
||||
self.assertEqual(self.port['uuid'], port['uuid'])
|
||||
self.assertEqual(self.port['node_uuid'], self.node['uuid'])
|
||||
|
||||
def test_show_addr(self):
|
||||
"""Check baremetal port show command with address.
|
||||
|
||||
Test steps:
|
||||
1) Create baremetal port in setUp.
|
||||
2) Show baremetal port calling it by address.
|
||||
3) Check port fields in output.
|
||||
"""
|
||||
port = self.port_show(
|
||||
uuid='', params='--address {}'.format(self.port['address']))
|
||||
self.assertEqual(self.port['address'], port['address'])
|
||||
self.assertEqual(self.port['uuid'], port['uuid'])
|
||||
self.assertEqual(self.port['node_uuid'], self.node['uuid'])
|
||||
|
||||
def test_delete(self):
|
||||
"""Check baremetal port delete command.
|
||||
|
||||
Test steps:
|
||||
1) Create baremetal port in setUp.
|
||||
2) Delete baremetal port by UUID.
|
||||
3) Check that port deleted successfully and not in list.
|
||||
"""
|
||||
output = self.port_delete(self.port['uuid'])
|
||||
self.assertIn('Deleted port {0}'.format(self.port['uuid']), output)
|
||||
port_list = self.port_list()
|
||||
self.assertNotIn(self.port['address'],
|
||||
[port['Address'] for port in port_list])
|
||||
self.assertNotIn(self.port['uuid'],
|
||||
[port['UUID'] for port in port_list])
|
||||
|
||||
def test_set_unset_extra(self):
|
||||
"""Check baremetal port set and unset commands.
|
||||
|
||||
Test steps:
|
||||
1) Create baremetal port in setUp.
|
||||
2) Set extra data for port.
|
||||
3) Check that baremetal port extra data was set.
|
||||
4) Unset extra data for port.
|
||||
5) Check that baremetal port extra data was unset.
|
||||
"""
|
||||
extra_key = 'ext'
|
||||
extra_value = 'testdata'
|
||||
self.openstack('baremetal port set --extra {0}={1} {2}'
|
||||
.format(extra_key, extra_value, self.port['uuid']))
|
||||
|
||||
show_prop = self.port_show(self.port['uuid'], ['extra'])
|
||||
self.assertEqual(extra_value, show_prop['extra'][extra_key])
|
||||
|
||||
self.openstack('baremetal port unset --extra {0} {1}'
|
||||
.format(extra_key, self.port['uuid']))
|
||||
|
||||
show_prop = self.port_show(self.port['uuid'], ['extra'])
|
||||
self.assertNotIn(extra_key, show_prop['extra'])
|
||||
|
||||
def test_port_create_with_portgroup(self):
|
||||
"""Create port with specific port group UUID.
|
||||
|
||||
Test steps:
|
||||
1) Create node in setUp().
|
||||
2) Create a port group.
|
||||
3) Create a port with specified port group.
|
||||
4) Check port properties for portgroup_uuid.
|
||||
"""
|
||||
api_version = ' --os-baremetal-api-version 1.24'
|
||||
port_group = self.port_group_create(self.node['uuid'],
|
||||
params=api_version)
|
||||
port = self.port_create(
|
||||
self.node['uuid'],
|
||||
params='--port-group {0} {1}'.format(port_group['uuid'],
|
||||
api_version))
|
||||
self.assertEqual(port_group['uuid'], port['portgroup_uuid'])
|
||||
@@ -1,75 +0,0 @@
|
||||
# Copyright (c) 2016 Mirantis, Inc.
|
||||
#
|
||||
# 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 tempest.lib.common.utils import data_utils
|
||||
|
||||
from ironicclient.tests.functional.osc.v1 import base
|
||||
|
||||
|
||||
class BaremetalPortCreate(base.TestCase):
|
||||
"""Detailed functional tests for baremetal port create command."""
|
||||
|
||||
def setUp(self):
|
||||
super(BaremetalPortCreate, self).setUp()
|
||||
self.node = self.node_create()
|
||||
|
||||
def test_extras(self):
|
||||
"""Check baremetal port create command with extra data.
|
||||
|
||||
Test steps:
|
||||
1) Create port using solitary and multiple --extra arguments.
|
||||
2) Check that port successfully created with right extras.
|
||||
"""
|
||||
extras = [{'single_extra': 'yes'},
|
||||
{'k1': 'v1', 'k2': 'v2', 'k3': 'v3'}]
|
||||
|
||||
for extra in extras:
|
||||
params = self.generate_params('--extra', extra)
|
||||
port = self.port_create(self.node['uuid'], params=params)
|
||||
self.assert_dict_is_subset(extra, port['extra'])
|
||||
|
||||
def test_pxe_1_19(self):
|
||||
"""Check baremetal port create command with PXE option.
|
||||
|
||||
Test steps:
|
||||
1) Create port using --pxe-enabled argument.
|
||||
2) Check that port successfully created with right PXE option.
|
||||
"""
|
||||
pxe_values = [True, False]
|
||||
api_version = ' --os-baremetal-api-version 1.19'
|
||||
|
||||
for value in pxe_values:
|
||||
port = self.port_create(
|
||||
self.node['uuid'],
|
||||
params='--pxe-enabled {0} {1}'.format(value, api_version))
|
||||
self.assertEqual(value, port['pxe_enabled'])
|
||||
|
||||
def test_llc_1_19(self):
|
||||
"""Check baremetal port create command with LLC option.
|
||||
|
||||
Test steps:
|
||||
1) Create port using --local-link-connection argument.
|
||||
2) Check that port successfully created with right LLC data.
|
||||
"""
|
||||
fake_port_id = data_utils.rand_name(prefix='ovs-node-')
|
||||
fake_switch_id = data_utils.rand_mac_address()
|
||||
llc_value = {"switch_info": "brbm",
|
||||
"port_id": fake_port_id,
|
||||
"switch_id": fake_switch_id}
|
||||
api_version = ' --os-baremetal-api-version 1.19'
|
||||
|
||||
params = self.generate_params('--local-link-connection', llc_value)
|
||||
port = self.port_create(self.node['uuid'],
|
||||
params='{0} {1}'.format(params, api_version))
|
||||
self.assert_dict_is_subset(llc_value, port['local_link_connection'])
|
||||
@@ -1,128 +0,0 @@
|
||||
# Copyright (c) 2016 Mirantis, Inc.
|
||||
#
|
||||
# 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 ddt
|
||||
from tempest.lib.common.utils import data_utils
|
||||
|
||||
from ironicclient.tests.functional.osc.v1 import base
|
||||
|
||||
|
||||
@ddt.ddt
|
||||
class BaremetalPortGroupTests(base.TestCase):
|
||||
"""Functional tests for baremetal port group commands."""
|
||||
|
||||
def setUp(self):
|
||||
super(BaremetalPortGroupTests, self).setUp()
|
||||
self.node = self.node_create()
|
||||
self.api_version = ' --os-baremetal-api-version 1.25'
|
||||
self.port_group = self.port_group_create(self.node['uuid'],
|
||||
params=self.api_version)
|
||||
|
||||
def test_create_with_address(self):
|
||||
"""Check baremetal port group create command with address argument.
|
||||
|
||||
Test steps:
|
||||
1) Create baremetal port group in setUp.
|
||||
2) Create baremetal port group with specific address argument.
|
||||
3) Check address of created port group.
|
||||
"""
|
||||
mac_address = data_utils.rand_mac_address()
|
||||
port_group = self.port_group_create(
|
||||
self.node['uuid'],
|
||||
params='{0} --address {1}'.format(self.api_version, mac_address))
|
||||
self.assertEqual(mac_address, port_group['address'])
|
||||
|
||||
def test_list(self):
|
||||
"""Check baremetal port group list command.
|
||||
|
||||
Test steps:
|
||||
1) Create baremetal port group in setUp.
|
||||
2) List baremetal port groups.
|
||||
3) Check port group address, UUID and name in port groups list.
|
||||
"""
|
||||
port_group_list = self.port_group_list(params=self.api_version)
|
||||
|
||||
self.assertIn(self.port_group['uuid'],
|
||||
[x['UUID'] for x in port_group_list])
|
||||
self.assertIn(self.port_group['name'],
|
||||
[x['Name'] for x in port_group_list])
|
||||
|
||||
@ddt.data('name', 'uuid')
|
||||
def test_delete(self, key):
|
||||
"""Check baremetal port group delete command.
|
||||
|
||||
Test steps:
|
||||
1) Create baremetal port group in setUp.
|
||||
2) Delete baremetal port group by UUID.
|
||||
3) Check that port group deleted successfully and not in list.
|
||||
"""
|
||||
output = self.port_group_delete(self.port_group[key],
|
||||
params=self.api_version)
|
||||
self.assertEqual('Deleted port group {0}'
|
||||
.format(self.port_group[key]), output.strip())
|
||||
|
||||
port_group_list = self.port_group_list(params=self.api_version)
|
||||
|
||||
self.assertNotIn(self.port_group['uuid'],
|
||||
[x['UUID'] for x in port_group_list])
|
||||
self.assertNotIn(self.port_group['name'],
|
||||
[x['Name'] for x in port_group_list])
|
||||
|
||||
@ddt.data('name', 'uuid')
|
||||
def test_show(self, key):
|
||||
"""Check baremetal port group show command.
|
||||
|
||||
Test steps:
|
||||
1) Create baremetal port group in setUp.
|
||||
2) Show baremetal port group.
|
||||
3) Check name, uuid and address in port group show output.
|
||||
"""
|
||||
port_group = self.port_group_show(
|
||||
self.port_group[key],
|
||||
['name', 'uuid', 'address'],
|
||||
params=self.api_version)
|
||||
|
||||
self.assertEqual(self.port_group['name'], port_group['name'])
|
||||
self.assertEqual(self.port_group['uuid'], port_group['uuid'])
|
||||
self.assertEqual(self.port_group['address'], port_group['address'])
|
||||
|
||||
@ddt.data('name', 'uuid')
|
||||
def test_set_unset(self, key):
|
||||
"""Check baremetal port group set and unset commands.
|
||||
|
||||
Test steps:
|
||||
1) Create baremetal port group in setUp.
|
||||
2) Set extra data for port group.
|
||||
3) Check that baremetal port group extra data was set.
|
||||
4) Unset extra data for port group.
|
||||
5) Check that baremetal port group extra data was unset.
|
||||
"""
|
||||
extra_key = 'ext'
|
||||
extra_value = 'testdata'
|
||||
self.openstack(
|
||||
'baremetal port group set --extra {0}={1} {2} {3}'
|
||||
.format(extra_key, extra_value, self.port_group[key],
|
||||
self.api_version))
|
||||
|
||||
show_prop = self.port_group_show(self.port_group[key], ['extra'],
|
||||
params=self.api_version)
|
||||
self.assertEqual(extra_value, show_prop['extra'][extra_key])
|
||||
|
||||
self.openstack('baremetal port group unset --extra {0} {1} {2}'
|
||||
.format(extra_key, self.port_group[key],
|
||||
self.api_version))
|
||||
|
||||
show_prop = self.port_group_show(self.port_group[key], ['extra'],
|
||||
params=self.api_version)
|
||||
self.assertNotIn(extra_key, show_prop['extra'])
|
||||
@@ -1,35 +0,0 @@
|
||||
# Copyright (c) 2015 Mirantis, Inc.
|
||||
#
|
||||
# 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.
|
||||
|
||||
|
||||
def get_dict_from_output(output):
|
||||
"""Parse list of dictionaries, return a dictionary.
|
||||
|
||||
:param output: list of dictionaries
|
||||
"""
|
||||
obj = {}
|
||||
for item in output:
|
||||
obj[item['Property']] = str(item['Value'])
|
||||
return obj
|
||||
|
||||
|
||||
def get_object(object_list, object_value):
|
||||
"""Get Ironic object by value from list of Ironic objects.
|
||||
|
||||
:param object_list: the output of the cmd
|
||||
:param object_value: value to get
|
||||
"""
|
||||
for obj in object_list:
|
||||
if object_value in obj.values():
|
||||
return obj
|
||||
@@ -1,54 +0,0 @@
|
||||
- hosts: all
|
||||
roles:
|
||||
- ensure-tox
|
||||
|
||||
tasks:
|
||||
- shell:
|
||||
cmd: |
|
||||
set -e
|
||||
set -x
|
||||
export BASE='/opt/stack'
|
||||
export IRONICCLIENT_DIR="$BASE/python-ironicclient"
|
||||
sudo chmod -R a+rw /opt/stack/
|
||||
cd $IRONICCLIENT_DIR
|
||||
set +e
|
||||
echo "Running ironicclient functional test suite"
|
||||
|
||||
# Only admin credentials needed for ironic api
|
||||
source $BASE/devstack/openrc admin admin
|
||||
|
||||
FUNC_TEST_DIR=$IRONICCLIENT_DIR/ironicclient/tests/functional
|
||||
CONFIG_FILE=$IRONICCLIENT_DIR/test.conf
|
||||
echo 'Generating configuration file for functional tests'
|
||||
|
||||
if [[ -n "$IRONIC_URL" ]]; then
|
||||
cat <<END >$CONFIG_FILE
|
||||
[functional]
|
||||
api_version = 1
|
||||
auth_strategy=noauth
|
||||
ironic_url=$IRONIC_URL
|
||||
END
|
||||
else
|
||||
cat <<END >$CONFIG_FILE
|
||||
[functional]
|
||||
api_version = 1
|
||||
os_auth_url=$OS_AUTH_URL
|
||||
os_identity_api_version=$OS_IDENTITY_API_VERSION
|
||||
os_username=$OS_USERNAME
|
||||
os_password=$OS_PASSWORD
|
||||
os_user_domain_id=$OS_USER_DOMAIN_ID
|
||||
# os_project_name=$OS_PROJECT_NAME
|
||||
# os_project_domain_id=$OS_PROJECT_DOMAIN_ID
|
||||
os_service_type=baremetal
|
||||
os_endpoint_type=public
|
||||
os_system_scope=all
|
||||
END
|
||||
fi
|
||||
echo 'Configuration file is in '$CONFIG_FILE''
|
||||
export IRONICCLIENT_TEST_CONFIG=$CONFIG_FILE
|
||||
|
||||
cd $IRONICCLIENT_DIR
|
||||
echo 'Running Functional Tests under Python3'
|
||||
{{ tox_executable }} -e functionalpy3
|
||||
executable: /bin/bash
|
||||
chdir: '/opt/stack/python-ironicclient'
|
||||
6
tox.ini
6
tox.ini
@@ -53,12 +53,6 @@ deps =
|
||||
-r{toxinidir}/doc/requirements.txt
|
||||
commands = {posargs}
|
||||
|
||||
[testenv:functionalpy3]
|
||||
passenv = *
|
||||
setenv = TESTS_DIR=./ironicclient/tests/functional
|
||||
LANGUAGE=en_US
|
||||
OS_TESTENV_NAME = {envname}
|
||||
|
||||
[testenv:docs]
|
||||
deps =
|
||||
-c{env:TOX_CONSTRAINTS_FILE:https://releases.openstack.org/constraints/upper/master}
|
||||
|
||||
@@ -1,39 +1,3 @@
|
||||
- job:
|
||||
name: ironicclient-functional
|
||||
parent: devstack-minimal
|
||||
irrelevant-files:
|
||||
- ^.*\.rst$
|
||||
- ^doc/.*$
|
||||
- ^ironicclient/locale/.*$
|
||||
- ^releasenotes/.*$
|
||||
- ^setup.cfg$
|
||||
- ^tools/.*$
|
||||
- ^tox.ini$
|
||||
required-projects:
|
||||
- openstack/ironic
|
||||
- openstack/python-ironicclient
|
||||
- openstack/keystone
|
||||
- openstack/tempest
|
||||
timeout: 4800
|
||||
post-run: playbooks/functional/run.yaml
|
||||
vars:
|
||||
tox_environment:
|
||||
PYTHONUNBUFFERED: 'true'
|
||||
tox_envlist: functionalpy3
|
||||
devstack_plugins:
|
||||
ironic: https://opendev.org/openstack/ironic
|
||||
devstack_localrc:
|
||||
USE_PYTHON3: True
|
||||
EBTABLES_RACE_FIX: True
|
||||
IRONIC_ENABLED_NETWORK_INTERFACES: noop
|
||||
IRONIC_DHCP_PROVIDER: none
|
||||
IRONIC_DEPLOY_DRIVER: fake
|
||||
INSTALL_TEMPEST: False
|
||||
devstack_services:
|
||||
key: True
|
||||
mysql: True
|
||||
rabbit: True
|
||||
|
||||
- job:
|
||||
name: ironicclient-tempest
|
||||
parent: ironic-base
|
||||
|
||||
@@ -8,14 +8,6 @@
|
||||
- release-notes-jobs-python3
|
||||
check:
|
||||
jobs:
|
||||
# NOTE(rpittau): temp non-voting until we fix it
|
||||
- ironicclient-functional:
|
||||
voting: false
|
||||
- ironicclient-tempest
|
||||
- ironicclient-tox-codespell:
|
||||
voting: false
|
||||
gate:
|
||||
jobs:
|
||||
# NOTE(rpittau): temp non-voting until we fix it
|
||||
#- ironicclient-functional
|
||||
- ironicclient-tempest
|
||||
|
||||
Reference in New Issue
Block a user