
Adds support for a node's ``deploy_step`` (read-only) field. The deploy step indicates which step is being performed during the deployment/provisioning of a node. It is available starting with Bare Metal API version 1.44. Depends-On: https://review.openstack.org/#/c/579968/ Change-Id: I93ac628bca0822a9a359926389543f7db7fb3e56 Story: #1753128 Task: #22925
290 lines
11 KiB
Python
290 lines
11 KiB
Python
# 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 jsonschema
|
|
from tempest.lib.common.utils import data_utils
|
|
|
|
from ironicclient.tests.functional import base
|
|
|
|
|
|
def _validate_json(json_response, schema):
|
|
"""Verify JSON is valid.
|
|
|
|
:param json_response: JSON response from CLI
|
|
:type json_response: string
|
|
:param schema: expected schema of response
|
|
:type json_response: dictionary
|
|
"""
|
|
json_response = json.loads(json_response)
|
|
jsonschema.validate(json_response, schema)
|
|
|
|
|
|
class TestNodeJsonResponse(base.FunctionalTestBase):
|
|
"""Test JSON responses for node commands."""
|
|
|
|
node_schema = {
|
|
"type": "object",
|
|
"properties": {
|
|
"target_power_state": {"type": ["string", "null"]},
|
|
"extra": {"type": "object"},
|
|
"last_error": {"type": ["string", "null"]},
|
|
"updated_at": {"type": ["string", "null"]},
|
|
"maintenance_reason": {"type": ["string", "null"]},
|
|
"provision_state": {"type": "string"},
|
|
"clean_step": {"type": "object"},
|
|
"deploy_step": {"type": "object"},
|
|
"uuid": {"type": "string"},
|
|
"console_enabled": {"type": "boolean"},
|
|
"target_provision_state": {"type": ["string", "null"]},
|
|
"raid_config": {"type": "object"},
|
|
"provision_updated_at": {"type": ["string", "null"]},
|
|
"maintenance": {"type": "boolean"},
|
|
"target_raid_config": {"type": "object"},
|
|
"inspection_started_at": {"type": ["string", "null"]},
|
|
"inspection_finished_at": {"type": ["string", "null"]},
|
|
"power_state": {"type": ["string", "null"]},
|
|
"driver": {"type": "string"},
|
|
"reservation": {"type": ["string", "null"]},
|
|
"properties": {"type": "object"},
|
|
"instance_uuid": {"type": ["string", "null"]},
|
|
"name": {"type": ["string", "null"]},
|
|
"driver_info": {"type": "object"},
|
|
"created_at": {"type": "string"},
|
|
"driver_internal_info": {"type": "object"},
|
|
"chassis_uuid": {"type": ["string", "null"]},
|
|
"instance_info": {"type": "object"}
|
|
},
|
|
"patternProperties": {
|
|
".*_interface$": {"type": ["string", "null"]}
|
|
},
|
|
"additionalProperties": True
|
|
}
|
|
|
|
def setUp(self):
|
|
super(TestNodeJsonResponse, self).setUp()
|
|
self.node = self.create_node()
|
|
|
|
def test_node_list_json(self):
|
|
"""Test JSON response for nodes list."""
|
|
schema = {
|
|
"type": "array",
|
|
"items": {
|
|
"type": "object",
|
|
"properties": {
|
|
"instance_uuid": {"type": ["string", "null"]},
|
|
"maintenance": {"type": "boolean"},
|
|
"name": {"type": ["string", "null"]},
|
|
"power_state": {"type": ["string", "null"]},
|
|
"provision_state": {"type": "string"},
|
|
"uuid": {"type": "string"}}}
|
|
}
|
|
response = self.ironic('node-list', flags='--json',
|
|
params='', parse=False)
|
|
_validate_json(response, schema)
|
|
|
|
def test_node_show_json(self):
|
|
"""Test JSON response for node show."""
|
|
response = self.ironic('node-show', flags='--json', params='{0}'
|
|
.format(self.node['uuid']), parse=False)
|
|
_validate_json(response, self.node_schema)
|
|
|
|
def test_node_validate_json(self):
|
|
"""Test JSON response for node validation."""
|
|
schema = {
|
|
"type": "array",
|
|
"items": {
|
|
"type": "object",
|
|
"properties": {
|
|
"interface": {"type": ["string", "null"]},
|
|
"result": {"type": ["boolean", "null"]},
|
|
"reason": {"type": ["string", "null"]}}}
|
|
}
|
|
response = self.ironic('node-validate', flags='--json',
|
|
params='{0}'.format(self.node['uuid']),
|
|
parse=False)
|
|
_validate_json(response, schema)
|
|
|
|
def test_node_show_states_json(self):
|
|
"""Test JSON response for node show states."""
|
|
schema = {
|
|
"type": "object",
|
|
"properties": {
|
|
"target_power_state": {"type": ["string", "null"]},
|
|
"target_provision_state": {"type": ["string", "null"]},
|
|
"last_error": {"type": ["string", "null"]},
|
|
"console_enabled": {"type": "boolean"},
|
|
"provision_updated_at": {"type": ["string", "null"]},
|
|
"power_state": {"type": ["string", "null"]},
|
|
"provision_state": {"type": "string"}
|
|
}
|
|
}
|
|
response = self.ironic('node-show-states', flags='--json',
|
|
params='{0}'.format(self.node['uuid']),
|
|
parse=False)
|
|
_validate_json(response, schema)
|
|
|
|
def test_node_create_json(self):
|
|
"""Test JSON response for node creation."""
|
|
schema = {
|
|
"type": "object",
|
|
"properties": {
|
|
"uuid": {"type": "string"},
|
|
"driver_info": {"type": "object"},
|
|
"extra": {"type": "object"},
|
|
"driver": {"type": "string"},
|
|
"chassis_uuid": {"type": ["string", "null"]},
|
|
"properties": {"type": "object"},
|
|
"name": {"type": ["string", "null"]},
|
|
}
|
|
}
|
|
node_name = 'nodejson'
|
|
response = self.ironic(
|
|
'node-create', flags='--json',
|
|
params='-d fake-hardware -n {0}'.format(node_name),
|
|
parse=False)
|
|
self.addCleanup(self.delete_node, node_name)
|
|
_validate_json(response, schema)
|
|
|
|
def test_node_update_json(self):
|
|
"""Test JSON response for node update."""
|
|
node_name = data_utils.rand_name('test')
|
|
response = self.ironic('node-update', flags='--json',
|
|
params='{0} add name={1}'
|
|
.format(self.node['uuid'], node_name),
|
|
parse=False)
|
|
_validate_json(response, self.node_schema)
|
|
|
|
|
|
class TestDriverJsonResponse(base.FunctionalTestBase):
|
|
"""Test JSON responses for driver commands."""
|
|
|
|
def test_driver_list_json(self):
|
|
"""Test JSON response for drivers list."""
|
|
schema = {
|
|
"type": "array",
|
|
"items": {
|
|
"type": "object",
|
|
"properties": {
|
|
"name": {"type": "string"},
|
|
"hosts": {"type": "string"},
|
|
}}
|
|
}
|
|
response = self.ironic('driver-list', flags='--json', parse=False)
|
|
_validate_json(response, schema)
|
|
|
|
def test_driver_show_json(self):
|
|
"""Test JSON response for driver show."""
|
|
schema = {
|
|
"type": "object",
|
|
"properties": {
|
|
"name": {"type": "string"},
|
|
"hosts": {
|
|
"type": "array",
|
|
"items": {"type": "string"}}
|
|
}
|
|
}
|
|
drivers_names = self.get_drivers_names()
|
|
for driver in drivers_names:
|
|
response = self.ironic('driver-show', flags='--json',
|
|
params='{0}'.format(driver), parse=False)
|
|
_validate_json(response, schema)
|
|
|
|
def test_driver_properties_json(self):
|
|
"""Test JSON response for driver properties."""
|
|
schema = {
|
|
"type": "object",
|
|
"additionalProperties": {"type": "string"}
|
|
}
|
|
drivers_names = self.get_drivers_names()
|
|
for driver in drivers_names:
|
|
response = self.ironic('driver-properties', flags='--json',
|
|
params='{0}'.format(driver), parse=False)
|
|
_validate_json(response, schema)
|
|
|
|
|
|
class TestChassisJsonResponse(base.FunctionalTestBase):
|
|
"""Test JSON responses for chassis commands."""
|
|
|
|
chassis_schema = {
|
|
"type": "object",
|
|
"properties": {
|
|
"uuid": {"type": "string"},
|
|
"updated_at": {"type": ["string", "null"]},
|
|
"created_at": {"type": "string"},
|
|
"description": {"type": ["string", "null"]},
|
|
"extra": {"type": "object"}}
|
|
}
|
|
|
|
def setUp(self):
|
|
super(TestChassisJsonResponse, self).setUp()
|
|
self.chassis = self.create_chassis()
|
|
|
|
def test_chassis_list_json(self):
|
|
"""Test JSON response for chassis list."""
|
|
schema = {
|
|
"type": "array",
|
|
"items": {
|
|
"type": "object",
|
|
"properties": {
|
|
"uuid": {"type": "string"},
|
|
"description": {"type": ["string", "null"]}}
|
|
}
|
|
}
|
|
response = self.ironic('chassis-list', flags='--json', parse=False)
|
|
_validate_json(response, schema)
|
|
|
|
def test_chassis_show_json(self):
|
|
"""Test JSON response for chassis show."""
|
|
response = self.ironic('chassis-show', flags='--json',
|
|
params='{0}'.format(self.chassis['uuid']),
|
|
parse=False)
|
|
_validate_json(response, self.chassis_schema)
|
|
|
|
def test_chassis_create_json(self):
|
|
"""Test JSON response for chassis create."""
|
|
response = self.ironic('chassis-create', flags='--json', parse=False)
|
|
_validate_json(response, self.chassis_schema)
|
|
|
|
def test_chassis_update_json(self):
|
|
"""Test JSON response for chassis update."""
|
|
response = self.ironic(
|
|
'chassis-update', flags='--json', params='{0} {1} {2}'.format(
|
|
self.chassis['uuid'], 'add', 'description=test-chassis'),
|
|
parse=False)
|
|
_validate_json(response, self.chassis_schema)
|
|
|
|
def test_chassis_node_list_json(self):
|
|
"""Test JSON response for chassis-node-list command."""
|
|
schema = {
|
|
"type": "array",
|
|
"items": {
|
|
"type": "object",
|
|
"properties": {
|
|
"instance_uuid": {"type": ["string", "null"]},
|
|
"maintenance": {"type": "boolean"},
|
|
"name": {"type": ["string", "null"]},
|
|
"power_state": {"type": ["string", "null"]},
|
|
"provision_state": {"type": "string"},
|
|
"uuid": {"type": "string"}}}
|
|
}
|
|
self.node = self.create_node()
|
|
self.update_node(self.node['uuid'], 'add chassis_uuid={0}'
|
|
.format(self.chassis['uuid']))
|
|
response = self.ironic('chassis-node-list', flags='--json',
|
|
params='{0}'.format(self.chassis['uuid']),
|
|
parse=False)
|
|
_validate_json(response, schema)
|