Files
openstacksdk/openstack/tests/unit/cloud/test_baremetal_node.py
Julia Kreger 910fc10427 Complete move of baremetal machine tests
Migrating tests to wrap up machine actions.

Ports will be migrated separately as there
will also need to be portgroups, which could
be wrapped into the same file/class depending
on how that ends up being implemented.

Change-Id: I239bbc134f42a47e8df75531dbd50916a97a6068
2017-12-01 09:49:48 -06:00

1458 lines
55 KiB
Python

# 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.
"""
test_baremetal_node
----------------------------------
Tests for baremetal node related operations
"""
import uuid
from testscenarios import load_tests_apply_scenarios as load_tests # noqa
from openstack.cloud import exc
from openstack.tests import fakes
from openstack.tests.unit import base
class TestBaremetalNode(base.IronicTestCase):
def setUp(self):
super(TestBaremetalNode, self).setUp()
# TODO(shade) Fix this when we get ironic update to REST
self.skipTest("Ironic operations not supported yet")
self.fake_baremetal_node = fakes.make_fake_machine(
self.name, self.uuid)
# TODO(TheJulia): Some tests below have fake ports,
# since they are required in some processes. Lets refactor
# them at some point to use self.fake_baremetal_port.
self.fake_baremetal_port = fakes.make_fake_port(
'00:01:02:03:04:05',
node_id=self.uuid)
def test_list_machines(self):
fake_baremetal_two = fakes.make_fake_machine('two', str(uuid.uuid4()))
self.register_uris([
dict(method='GET',
uri=self.get_mock_url(resource='nodes'),
json={'nodes': [self.fake_baremetal_node,
fake_baremetal_two]}),
])
machines = self.op_cloud.list_machines()
self.assertEqual(2, len(machines))
self.assertEqual(self.fake_baremetal_node, machines[0])
self.assert_calls()
def test_get_machine(self):
self.register_uris([
dict(method='GET',
uri=self.get_mock_url(
resource='nodes',
append=[self.fake_baremetal_node['uuid']]),
json=self.fake_baremetal_node),
])
machine = self.op_cloud.get_machine(self.fake_baremetal_node['uuid'])
self.assertEqual(machine['uuid'],
self.fake_baremetal_node['uuid'])
self.assert_calls()
def test_get_machine_by_mac(self):
mac_address = '00:01:02:03:04:05'
url_address = 'detail?address=%s' % mac_address
node_uuid = self.fake_baremetal_node['uuid']
self.register_uris([
dict(method='GET',
uri=self.get_mock_url(
resource='ports',
append=[url_address]),
json={'ports': [{'address': mac_address,
'node_uuid': node_uuid}]}),
dict(method='GET',
uri=self.get_mock_url(
resource='nodes',
append=[self.fake_baremetal_node['uuid']]),
json=self.fake_baremetal_node),
])
machine = self.op_cloud.get_machine_by_mac(mac_address)
self.assertEqual(machine['uuid'],
self.fake_baremetal_node['uuid'])
self.assert_calls()
def test_validate_node(self):
# NOTE(TheJulia): Note: These are only the interfaces
# that are validated, and both must be true for an
# exception to not be raised.
# This should be fixed at some point, as some interfaces
# are important in some cases and should be validated,
# such as storage.
validate_return = {
'deploy': {
'result': True,
},
'power': {
'result': True,
},
'foo': {
'result': False,
}}
self.register_uris([
dict(method='GET',
uri=self.get_mock_url(
resource='nodes',
append=[self.fake_baremetal_node['uuid'],
'validate']),
json=validate_return),
])
self.op_cloud.validate_node(self.fake_baremetal_node['uuid'])
self.assert_calls()
# FIXME(TheJulia): So, this doesn't presently fail, but should fail.
# Placing the test here, so we can sort out the issue in the actual
# method later.
# def test_validate_node_raises_exception(self):
# validate_return = {
# 'deploy': {
# 'result': False,
# 'reason': 'error!',
# },
# 'power': {
# 'result': False,
# 'reason': 'meow!',
# },
# 'foo': {
# 'result': True
# }}
# self.register_uris([
# dict(method='GET',
# uri=self.get_mock_url(
# resource='nodes',
# append=[self.fake_baremetal_node['uuid'],
# 'validate']),
# json=validate_return),
# ])
# self.assertRaises(
# Exception,
# self.op_cloud.validate_node,
# self.fake_baremetal_node['uuid'])
#
# self.assert_calls()
def test_patch_machine(self):
test_patch = [{
'op': 'remove',
'path': '/instance_info'}]
self.fake_baremetal_node['instance_info'] = {}
self.register_uris([
dict(method='PATCH',
uri=self.get_mock_url(
resource='nodes',
append=[self.fake_baremetal_node['uuid']]),
json=self.fake_baremetal_node,
validate=dict(json=test_patch)),
])
self.op_cloud.patch_machine(self.fake_baremetal_node['uuid'],
test_patch)
self.assert_calls()
def test_set_node_instance_info(self):
test_patch = [{
'op': 'add',
'path': '/foo',
'value': 'bar'}]
self.register_uris([
dict(method='PATCH',
uri=self.get_mock_url(
resource='nodes',
append=[self.fake_baremetal_node['uuid']]),
json=self.fake_baremetal_node,
validate=dict(json=test_patch)),
])
self.op_cloud.set_node_instance_info(
self.fake_baremetal_node['uuid'], test_patch)
self.assert_calls()
def test_purge_node_instance_info(self):
test_patch = [{
'op': 'remove',
'path': '/instance_info'}]
self.fake_baremetal_node['instance_info'] = {}
self.register_uris([
dict(method='PATCH',
uri=self.get_mock_url(
resource='nodes',
append=[self.fake_baremetal_node['uuid']]),
json=self.fake_baremetal_node,
validate=dict(json=test_patch)),
])
self.op_cloud.purge_node_instance_info(
self.fake_baremetal_node['uuid'])
self.assert_calls()
def test_inspect_machine_fail_active(self):
self.fake_baremetal_node['provision_state'] = 'active'
self.register_uris([
dict(method='GET',
uri=self.get_mock_url(
resource='nodes',
append=[self.fake_baremetal_node['uuid']]),
json=self.fake_baremetal_node),
])
self.assertRaises(
exc.OpenStackCloudException,
self.op_cloud.inspect_machine,
self.fake_baremetal_node['uuid'],
wait=True,
timeout=1)
self.assert_calls()
def test_inspect_machine_failed(self):
inspecting_node = self.fake_baremetal_node.copy()
self.fake_baremetal_node['provision_state'] = 'inspect failed'
self.fake_baremetal_node['last_error'] = 'kaboom!'
inspecting_node['provision_state'] = 'inspecting'
self.register_uris([
dict(
method='GET',
uri=self.get_mock_url(
resource='nodes',
append=[self.fake_baremetal_node['uuid']]),
json=self.fake_baremetal_node),
dict(
method='PUT',
uri=self.get_mock_url(
resource='nodes',
append=[self.fake_baremetal_node['uuid'],
'states', 'provision']),
validate=dict(json={'target': 'inspect'})),
dict(
method='GET',
uri=self.get_mock_url(
resource='nodes',
append=[self.fake_baremetal_node['uuid']]),
json=inspecting_node)
])
self.op_cloud.inspect_machine(self.fake_baremetal_node['uuid'])
self.assert_calls()
def test_inspect_machine_manageable(self):
self.fake_baremetal_node['provision_state'] = 'manageable'
inspecting_node = self.fake_baremetal_node.copy()
inspecting_node['provision_state'] = 'inspecting'
self.register_uris([
dict(
method='GET',
uri=self.get_mock_url(
resource='nodes',
append=[self.fake_baremetal_node['uuid']]),
json=self.fake_baremetal_node),
dict(
method='PUT',
uri=self.get_mock_url(
resource='nodes',
append=[self.fake_baremetal_node['uuid'],
'states', 'provision']),
validate=dict(json={'target': 'inspect'})),
dict(
method='GET',
uri=self.get_mock_url(
resource='nodes',
append=[self.fake_baremetal_node['uuid']]),
json=inspecting_node),
])
self.op_cloud.inspect_machine(self.fake_baremetal_node['uuid'])
self.assert_calls()
def test_inspect_machine_available(self):
available_node = self.fake_baremetal_node.copy()
available_node['provision_state'] = 'available'
manageable_node = self.fake_baremetal_node.copy()
manageable_node['provision_state'] = 'manageable'
self.register_uris([
dict(
method='GET',
uri=self.get_mock_url(
resource='nodes',
append=[self.fake_baremetal_node['uuid']]),
json=available_node),
dict(
method='PUT',
uri=self.get_mock_url(
resource='nodes',
append=[self.fake_baremetal_node['uuid'],
'states', 'provision']),
validate=dict(json={'target': 'manage'})),
dict(
method='GET',
uri=self.get_mock_url(
resource='nodes',
append=[self.fake_baremetal_node['uuid']]),
json=manageable_node),
dict(
method='PUT',
uri=self.get_mock_url(
resource='nodes',
append=[self.fake_baremetal_node['uuid'],
'states', 'provision']),
validate=dict(json={'target': 'inspect'})),
dict(
method='GET',
uri=self.get_mock_url(
resource='nodes',
append=[self.fake_baremetal_node['uuid']]),
json=manageable_node),
dict(
method='PUT',
uri=self.get_mock_url(
resource='nodes',
append=[self.fake_baremetal_node['uuid'],
'states', 'provision']),
validate=dict(json={'target': 'provide'})),
dict(
method='GET',
uri=self.get_mock_url(
resource='nodes',
append=[self.fake_baremetal_node['uuid']]),
json=available_node),
])
self.op_cloud.inspect_machine(self.fake_baremetal_node['uuid'])
self.assert_calls()
def test_inspect_machine_available_wait(self):
available_node = self.fake_baremetal_node.copy()
available_node['provision_state'] = 'available'
manageable_node = self.fake_baremetal_node.copy()
manageable_node['provision_state'] = 'manageable'
inspecting_node = self.fake_baremetal_node.copy()
inspecting_node['provision_state'] = 'inspecting'
self.register_uris([
dict(
method='GET',
uri=self.get_mock_url(
resource='nodes',
append=[self.fake_baremetal_node['uuid']]),
json=available_node),
dict(
method='PUT',
uri=self.get_mock_url(
resource='nodes',
append=[self.fake_baremetal_node['uuid'],
'states', 'provision']),
validate=dict(json={'target': 'manage'})),
dict(
method='GET',
uri=self.get_mock_url(
resource='nodes',
append=[self.fake_baremetal_node['uuid']]),
json=available_node),
dict(
method='GET',
uri=self.get_mock_url(
resource='nodes',
append=[self.fake_baremetal_node['uuid']]),
json=manageable_node),
dict(
method='PUT',
uri=self.get_mock_url(
resource='nodes',
append=[self.fake_baremetal_node['uuid'],
'states', 'provision']),
validate=dict(json={'target': 'inspect'})),
dict(
method='GET',
uri=self.get_mock_url(
resource='nodes',
append=[self.fake_baremetal_node['uuid']]),
json=inspecting_node),
dict(
method='GET',
uri=self.get_mock_url(
resource='nodes',
append=[self.fake_baremetal_node['uuid']]),
json=manageable_node),
dict(
method='PUT',
uri=self.get_mock_url(
resource='nodes',
append=[self.fake_baremetal_node['uuid'],
'states', 'provision']),
validate=dict(json={'target': 'provide'})),
dict(
method='GET',
uri=self.get_mock_url(
resource='nodes',
append=[self.fake_baremetal_node['uuid']]),
json=available_node),
])
self.op_cloud.inspect_machine(self.fake_baremetal_node['uuid'],
wait=True, timeout=1)
self.assert_calls()
def test_inspect_machine_wait(self):
self.fake_baremetal_node['provision_state'] = 'manageable'
inspecting_node = self.fake_baremetal_node.copy()
inspecting_node['provision_state'] = 'inspecting'
self.register_uris([
dict(
method='GET',
uri=self.get_mock_url(
resource='nodes',
append=[self.fake_baremetal_node['uuid']]),
json=self.fake_baremetal_node),
dict(
method='PUT',
uri=self.get_mock_url(
resource='nodes',
append=[self.fake_baremetal_node['uuid'],
'states', 'provision']),
validate=dict(json={'target': 'inspect'})),
dict(
method='GET',
uri=self.get_mock_url(
resource='nodes',
append=[self.fake_baremetal_node['uuid']]),
json=inspecting_node),
dict(
method='GET',
uri=self.get_mock_url(
resource='nodes',
append=[self.fake_baremetal_node['uuid']]),
json=inspecting_node),
dict(
method='GET',
uri=self.get_mock_url(
resource='nodes',
append=[self.fake_baremetal_node['uuid']]),
json=self.fake_baremetal_node),
])
self.op_cloud.inspect_machine(self.fake_baremetal_node['uuid'],
wait=True, timeout=1)
self.assert_calls()
def test_inspect_machine_inspect_failed(self):
self.fake_baremetal_node['provision_state'] = 'manageable'
inspecting_node = self.fake_baremetal_node.copy()
inspecting_node['provision_state'] = 'inspecting'
inspect_fail_node = self.fake_baremetal_node.copy()
inspect_fail_node['provision_state'] = 'inspect failed'
inspect_fail_node['last_error'] = 'Earth Imploded'
self.register_uris([
dict(
method='GET',
uri=self.get_mock_url(
resource='nodes',
append=[self.fake_baremetal_node['uuid']]),
json=self.fake_baremetal_node),
dict(
method='PUT',
uri=self.get_mock_url(
resource='nodes',
append=[self.fake_baremetal_node['uuid'],
'states', 'provision']),
validate=dict(json={'target': 'inspect'})),
dict(
method='GET',
uri=self.get_mock_url(
resource='nodes',
append=[self.fake_baremetal_node['uuid']]),
json=inspecting_node),
dict(
method='GET',
uri=self.get_mock_url(
resource='nodes',
append=[self.fake_baremetal_node['uuid']]),
json=inspect_fail_node),
])
self.assertRaises(exc.OpenStackCloudException,
self.op_cloud.inspect_machine,
self.fake_baremetal_node['uuid'],
wait=True, timeout=1)
self.assert_calls()
def test_set_machine_maintenace_state(self):
self.register_uris([
dict(
method='PUT',
uri=self.get_mock_url(
resource='nodes',
append=[self.fake_baremetal_node['uuid'],
'maintenance']),
validate=dict(json={'reason': 'no reason'})),
])
self.op_cloud.set_machine_maintenance_state(
self.fake_baremetal_node['uuid'], True, reason='no reason')
self.assert_calls()
def test_set_machine_maintenace_state_false(self):
self.register_uris([
dict(
method='DELETE',
uri=self.get_mock_url(
resource='nodes',
append=[self.fake_baremetal_node['uuid'],
'maintenance'])),
])
self.op_cloud.set_machine_maintenance_state(
self.fake_baremetal_node['uuid'], False)
self.assert_calls
def test_remove_machine_from_maintenance(self):
self.register_uris([
dict(
method='DELETE',
uri=self.get_mock_url(
resource='nodes',
append=[self.fake_baremetal_node['uuid'],
'maintenance'])),
])
self.op_cloud.remove_machine_from_maintenance(
self.fake_baremetal_node['uuid'])
self.assert_calls()
def test_set_machine_power_on(self):
self.register_uris([
dict(
method='PUT',
uri=self.get_mock_url(
resource='nodes',
append=[self.fake_baremetal_node['uuid'],
'states', 'power']),
validate=dict(json={'target': 'power on'})),
])
return_value = self.op_cloud.set_machine_power_on(
self.fake_baremetal_node['uuid'])
self.assertIsNone(return_value)
self.assert_calls()
def test_set_machine_power_off(self):
self.register_uris([
dict(
method='PUT',
uri=self.get_mock_url(
resource='nodes',
append=[self.fake_baremetal_node['uuid'],
'states', 'power']),
validate=dict(json={'target': 'power off'})),
])
return_value = self.op_cloud.set_machine_power_off(
self.fake_baremetal_node['uuid'])
self.assertIsNone(return_value)
self.assert_calls()
def test_set_machine_power_reboot(self):
self.register_uris([
dict(
method='PUT',
uri=self.get_mock_url(
resource='nodes',
append=[self.fake_baremetal_node['uuid'],
'states', 'power']),
validate=dict(json={'target': 'rebooting'})),
])
return_value = self.op_cloud.set_machine_power_reboot(
self.fake_baremetal_node['uuid'])
self.assertIsNone(return_value)
self.assert_calls()
def test_set_machine_power_reboot_failure(self):
self.register_uris([
dict(
method='PUT',
uri=self.get_mock_url(
resource='nodes',
append=[self.fake_baremetal_node['uuid'],
'states', 'power']),
status_code=400,
json={'error': 'invalid'},
validate=dict(json={'target': 'rebooting'})),
])
self.assertRaises(exc.OpenStackCloudException,
self.op_cloud.set_machine_power_reboot,
self.fake_baremetal_node['uuid'])
self.assert_calls()
def test_node_set_provision_state(self):
deploy_node = self.fake_baremetal_node.copy()
deploy_node['provision_state'] = 'deploying'
active_node = self.fake_baremetal_node.copy()
active_node['provision_state'] = 'active'
self.register_uris([
dict(
method='PUT',
uri=self.get_mock_url(
resource='nodes',
append=[self.fake_baremetal_node['uuid'],
'states', 'provision']),
validate=dict(json={'target': 'active',
'configdrive': 'http://host/file'})),
dict(method='GET',
uri=self.get_mock_url(
resource='nodes',
append=[self.fake_baremetal_node['uuid']]),
json=self.fake_baremetal_node),
])
self.op_cloud.node_set_provision_state(
self.fake_baremetal_node['uuid'],
'active',
configdrive='http://host/file')
self.assert_calls()
def test_node_set_provision_state_wait_timeout(self):
deploy_node = self.fake_baremetal_node.copy()
deploy_node['provision_state'] = 'deploying'
active_node = self.fake_baremetal_node.copy()
active_node['provision_state'] = 'active'
self.fake_baremetal_node['provision_state'] = 'available'
self.register_uris([
dict(
method='PUT',
uri=self.get_mock_url(
resource='nodes',
append=[self.fake_baremetal_node['uuid'],
'states', 'provision']),
validate=dict(json={'target': 'active'})),
dict(method='GET',
uri=self.get_mock_url(
resource='nodes',
append=[self.fake_baremetal_node['uuid']]),
json=self.fake_baremetal_node),
dict(method='GET',
uri=self.get_mock_url(
resource='nodes',
append=[self.fake_baremetal_node['uuid']]),
json=deploy_node),
dict(method='GET',
uri=self.get_mock_url(
resource='nodes',
append=[self.fake_baremetal_node['uuid']]),
json=active_node),
])
return_value = self.op_cloud.node_set_provision_state(
self.fake_baremetal_node['uuid'],
'active',
wait=True)
self.assertEqual(active_node, return_value)
self.assert_calls()
def test_node_set_provision_state_wait_timeout_fails(self):
# Intentionally time out.
self.register_uris([
dict(
method='PUT',
uri=self.get_mock_url(
resource='nodes',
append=[self.fake_baremetal_node['uuid'],
'states', 'provision']),
validate=dict(json={'target': 'active'})),
dict(method='GET',
uri=self.get_mock_url(
resource='nodes',
append=[self.fake_baremetal_node['uuid']]),
json=self.fake_baremetal_node),
])
self.assertRaises(
exc.OpenStackCloudException,
self.op_cloud.node_set_provision_state,
self.fake_baremetal_node['uuid'],
'active',
wait=True,
timeout=0.001)
self.assert_calls()
def test_node_set_provision_state_wait_success(self):
self.fake_baremetal_node['provision_state'] = 'active'
self.register_uris([
dict(
method='PUT',
uri=self.get_mock_url(
resource='nodes',
append=[self.fake_baremetal_node['uuid'],
'states', 'provision']),
validate=dict(json={'target': 'active'})),
dict(method='GET',
uri=self.get_mock_url(
resource='nodes',
append=[self.fake_baremetal_node['uuid']]),
json=self.fake_baremetal_node),
])
return_value = self.op_cloud.node_set_provision_state(
self.fake_baremetal_node['uuid'],
'active',
wait=True)
self.assertEqual(self.fake_baremetal_node, return_value)
self.assert_calls()
def test_node_set_provision_state_wait_failure_cases(self):
self.fake_baremetal_node['provision_state'] = 'foo failed'
self.register_uris([
dict(
method='PUT',
uri=self.get_mock_url(
resource='nodes',
append=[self.fake_baremetal_node['uuid'],
'states', 'provision']),
validate=dict(json={'target': 'active'})),
dict(method='GET',
uri=self.get_mock_url(
resource='nodes',
append=[self.fake_baremetal_node['uuid']]),
json=self.fake_baremetal_node),
])
self.assertRaises(
exc.OpenStackCloudException,
self.op_cloud.node_set_provision_state,
self.fake_baremetal_node['uuid'],
'active',
wait=True,
timeout=300)
self.assert_calls()
def test_node_set_provision_state_wait_provide(self):
self.fake_baremetal_node['provision_state'] = 'manageable'
available_node = self.fake_baremetal_node.copy()
available_node['provision_state'] = 'available'
self.register_uris([
dict(
method='PUT',
uri=self.get_mock_url(
resource='nodes',
append=[self.fake_baremetal_node['uuid'],
'states', 'provision']),
validate=dict(json={'target': 'provide'})),
dict(method='GET',
uri=self.get_mock_url(
resource='nodes',
append=[self.fake_baremetal_node['uuid']]),
json=self.fake_baremetal_node),
dict(method='GET',
uri=self.get_mock_url(
resource='nodes',
append=[self.fake_baremetal_node['uuid']]),
json=available_node),
])
return_value = self.op_cloud.node_set_provision_state(
self.fake_baremetal_node['uuid'],
'provide',
wait=True)
self.assertEqual(available_node, return_value)
self.assert_calls()
def test_activate_node(self):
self.fake_baremetal_node['provision_state'] = 'active'
self.register_uris([
dict(
method='PUT',
uri=self.get_mock_url(
resource='nodes',
append=[self.fake_baremetal_node['uuid'],
'states', 'provision']),
validate=dict(json={'target': 'active',
'configdrive': 'http://host/file'})),
dict(method='GET',
uri=self.get_mock_url(
resource='nodes',
append=[self.fake_baremetal_node['uuid']]),
json=self.fake_baremetal_node),
])
return_value = self.op_cloud.activate_node(
self.fake_baremetal_node['uuid'],
configdrive='http://host/file',
wait=True)
self.assertIsNone(return_value)
self.assert_calls()
def test_deactivate_node(self):
self.fake_baremetal_node['provision_state'] = 'available'
self.register_uris([
dict(
method='PUT',
uri=self.get_mock_url(
resource='nodes',
append=[self.fake_baremetal_node['uuid'],
'states', 'provision']),
validate=dict(json={'target': 'deleted'})),
dict(method='GET',
uri=self.get_mock_url(
resource='nodes',
append=[self.fake_baremetal_node['uuid']]),
json=self.fake_baremetal_node),
])
return_value = self.op_cloud.deactivate_node(
self.fake_baremetal_node['uuid'],
wait=True)
self.assertIsNone(return_value)
self.assert_calls()
def test_register_machine(self):
mac_address = '00:01:02:03:04:05'
nics = [{'mac': mac_address}]
node_uuid = self.fake_baremetal_node['uuid']
# TODO(TheJulia): There is a lot of duplication
# in testing creation. Surely this hsould be a helper
# or something. We should fix this, after we have
# ironicclient removed, as in the mean time visibility
# will be helpful.
node_to_post = {
'chassis_uuid': None,
'driver': None,
'driver_info': None,
'name': self.fake_baremetal_node['name'],
'properties': None,
'uuid': node_uuid}
self.fake_baremetal_node['provision_state'] = 'available'
if 'provision_state' in node_to_post:
node_to_post.pop('provision_state')
self.register_uris([
dict(
method='POST',
uri=self.get_mock_url(
resource='nodes'),
json=self.fake_baremetal_node,
validate=dict(json=node_to_post)),
dict(
method='POST',
uri=self.get_mock_url(
resource='ports'),
validate=dict(json={'address': mac_address,
'node_uuid': node_uuid}),
json=self.fake_baremetal_port),
])
return_value = self.op_cloud.register_machine(nics, **node_to_post)
self.assertDictEqual(self.fake_baremetal_node, return_value)
self.assert_calls()
# TODO(TheJulia): After we remove ironicclient,
# we need to de-duplicate these tests. Possibly
# a dedicated class, although we should do it then
# as we may find differences that need to be accounted
# for newer microversions.
def test_register_machine_enroll(self):
mac_address = '00:01:02:03:04:05'
nics = [{'mac': mac_address}]
node_uuid = self.fake_baremetal_node['uuid']
node_to_post = {
'chassis_uuid': None,
'driver': None,
'driver_info': None,
'name': self.fake_baremetal_node['name'],
'properties': None,
'uuid': node_uuid}
self.fake_baremetal_node['provision_state'] = 'enroll'
manageable_node = self.fake_baremetal_node.copy()
manageable_node['provision_state'] = 'manageable'
available_node = self.fake_baremetal_node.copy()
available_node['provision_state'] = 'available'
self.register_uris([
dict(
method='POST',
uri=self.get_mock_url(
resource='nodes'),
validate=dict(json=node_to_post),
json=self.fake_baremetal_node),
dict(
method='POST',
uri=self.get_mock_url(
resource='ports'),
validate=dict(json={'address': mac_address,
'node_uuid': node_uuid}),
json=self.fake_baremetal_port),
dict(
method='PUT',
uri=self.get_mock_url(
resource='nodes',
append=[self.fake_baremetal_node['uuid'],
'states', 'provision']),
validate=dict(json={'target': 'manage'})),
dict(
method='GET',
uri=self.get_mock_url(
resource='nodes',
append=[self.fake_baremetal_node['uuid']]),
json=manageable_node),
dict(
method='GET',
uri=self.get_mock_url(
resource='nodes',
append=[self.fake_baremetal_node['uuid']]),
json=manageable_node),
dict(
method='PUT',
uri=self.get_mock_url(
resource='nodes',
append=[self.fake_baremetal_node['uuid'],
'states', 'provision']),
validate=dict(json={'target': 'provide'})),
dict(
method='GET',
uri=self.get_mock_url(
resource='nodes',
append=[self.fake_baremetal_node['uuid']]),
json=available_node),
dict(
method='GET',
uri=self.get_mock_url(
resource='nodes',
append=[self.fake_baremetal_node['uuid']]),
json=available_node),
])
# NOTE(When we migrate to a newer microversion, this test
# may require revision. It was written for microversion
# ?1.13?, which accidently got reverted to 1.6 at one
# point during code being refactored soon after the
# change landed. Presently, with the lock at 1.6,
# this code is never used in the current code path.
return_value = self.op_cloud.register_machine(nics, **node_to_post)
self.assertDictEqual(available_node, return_value)
self.assert_calls()
def test_register_machine_enroll_wait(self):
mac_address = self.fake_baremetal_port
nics = [{'mac': mac_address}]
node_uuid = self.fake_baremetal_node['uuid']
node_to_post = {
'chassis_uuid': None,
'driver': None,
'driver_info': None,
'name': self.fake_baremetal_node['name'],
'properties': None,
'uuid': node_uuid}
self.fake_baremetal_node['provision_state'] = 'enroll'
manageable_node = self.fake_baremetal_node.copy()
manageable_node['provision_state'] = 'manageable'
available_node = self.fake_baremetal_node.copy()
available_node['provision_state'] = 'available'
self.register_uris([
dict(
method='POST',
uri=self.get_mock_url(
resource='nodes'),
validate=dict(json=node_to_post),
json=self.fake_baremetal_node),
dict(
method='POST',
uri=self.get_mock_url(
resource='ports'),
validate=dict(json={'address': mac_address,
'node_uuid': node_uuid}),
json=self.fake_baremetal_port),
dict(
method='GET',
uri=self.get_mock_url(
resource='nodes',
append=[self.fake_baremetal_node['uuid']]),
json=self.fake_baremetal_node),
dict(
method='PUT',
uri=self.get_mock_url(
resource='nodes',
append=[self.fake_baremetal_node['uuid'],
'states', 'provision']),
validate=dict(json={'target': 'manage'})),
dict(
method='GET',
uri=self.get_mock_url(
resource='nodes',
append=[self.fake_baremetal_node['uuid']]),
json=self.fake_baremetal_node),
dict(
method='GET',
uri=self.get_mock_url(
resource='nodes',
append=[self.fake_baremetal_node['uuid']]),
json=manageable_node),
dict(
method='PUT',
uri=self.get_mock_url(
resource='nodes',
append=[self.fake_baremetal_node['uuid'],
'states', 'provision']),
validate=dict(json={'target': 'provide'})),
dict(
method='GET',
uri=self.get_mock_url(
resource='nodes',
append=[self.fake_baremetal_node['uuid']]),
json=available_node),
dict(
method='GET',
uri=self.get_mock_url(
resource='nodes',
append=[self.fake_baremetal_node['uuid']]),
json=available_node),
])
return_value = self.op_cloud.register_machine(nics, wait=True,
**node_to_post)
self.assertDictEqual(available_node, return_value)
self.assert_calls()
def test_register_machine_enroll_failure(self):
mac_address = '00:01:02:03:04:05'
nics = [{'mac': mac_address}]
node_uuid = self.fake_baremetal_node['uuid']
node_to_post = {
'chassis_uuid': None,
'driver': None,
'driver_info': None,
'name': self.fake_baremetal_node['name'],
'properties': None,
'uuid': node_uuid}
self.fake_baremetal_node['provision_state'] = 'enroll'
failed_node = self.fake_baremetal_node.copy()
failed_node['reservation'] = 'conductor0'
failed_node['provision_state'] = 'verifying'
failed_node['last_error'] = 'kaboom!'
self.register_uris([
dict(
method='POST',
uri=self.get_mock_url(
resource='nodes'),
json=self.fake_baremetal_node,
validate=dict(json=node_to_post)),
dict(
method='POST',
uri=self.get_mock_url(
resource='ports'),
validate=dict(json={'address': mac_address,
'node_uuid': node_uuid}),
json=self.fake_baremetal_port),
dict(
method='PUT',
uri=self.get_mock_url(
resource='nodes',
append=[self.fake_baremetal_node['uuid'],
'states', 'provision']),
validate=dict(json={'target': 'manage'})),
dict(
method='GET',
uri=self.get_mock_url(
resource='nodes',
append=[self.fake_baremetal_node['uuid']]),
json=failed_node),
dict(
method='GET',
uri=self.get_mock_url(
resource='nodes',
append=[self.fake_baremetal_node['uuid']]),
json=failed_node),
])
self.assertRaises(
exc.OpenStackCloudException,
self.op_cloud.register_machine,
nics,
**node_to_post)
self.assert_calls()
def test_register_machine_enroll_timeout(self):
mac_address = '00:01:02:03:04:05'
nics = [{'mac': mac_address}]
node_uuid = self.fake_baremetal_node['uuid']
node_to_post = {
'chassis_uuid': None,
'driver': None,
'driver_info': None,
'name': self.fake_baremetal_node['name'],
'properties': None,
'uuid': node_uuid}
self.fake_baremetal_node['provision_state'] = 'enroll'
busy_node = self.fake_baremetal_node.copy()
busy_node['reservation'] = 'conductor0'
busy_node['provision_state'] = 'verifying'
self.register_uris([
dict(
method='POST',
uri=self.get_mock_url(
resource='nodes'),
json=self.fake_baremetal_node,
validate=dict(json=node_to_post)),
dict(
method='POST',
uri=self.get_mock_url(
resource='ports'),
validate=dict(json={'address': mac_address,
'node_uuid': node_uuid}),
json=self.fake_baremetal_port),
dict(
method='PUT',
uri=self.get_mock_url(
resource='nodes',
append=[self.fake_baremetal_node['uuid'],
'states', 'provision']),
validate=dict(json={'target': 'manage'})),
dict(
method='GET',
uri=self.get_mock_url(
resource='nodes',
append=[self.fake_baremetal_node['uuid']]),
json=self.fake_baremetal_node),
dict(
method='GET',
uri=self.get_mock_url(
resource='nodes',
append=[self.fake_baremetal_node['uuid']]),
json=busy_node),
])
# NOTE(TheJulia): This test shortcircuits the timeout loop
# such that it executes only once. The very last returned
# state to the API is essentially a busy state that we
# want to block on until it has cleared.
self.assertRaises(
exc.OpenStackCloudException,
self.op_cloud.register_machine,
nics,
timeout=0.001,
lock_timeout=0.001,
**node_to_post)
self.assert_calls()
def test_register_machine_enroll_timeout_wait(self):
mac_address = '00:01:02:03:04:05'
nics = [{'mac': mac_address}]
node_uuid = self.fake_baremetal_node['uuid']
node_to_post = {
'chassis_uuid': None,
'driver': None,
'driver_info': None,
'name': self.fake_baremetal_node['name'],
'properties': None,
'uuid': node_uuid}
self.fake_baremetal_node['provision_state'] = 'enroll'
self.register_uris([
dict(
method='POST',
uri=self.get_mock_url(
resource='nodes'),
json=self.fake_baremetal_node,
validate=dict(json=node_to_post)),
dict(
method='POST',
uri=self.get_mock_url(
resource='ports'),
validate=dict(json={'address': mac_address,
'node_uuid': node_uuid}),
json=self.fake_baremetal_port),
dict(
method='GET',
uri=self.get_mock_url(
resource='nodes',
append=[self.fake_baremetal_node['uuid']]),
json=self.fake_baremetal_node),
dict(
method='PUT',
uri=self.get_mock_url(
resource='nodes',
append=[self.fake_baremetal_node['uuid'],
'states', 'provision']),
validate=dict(json={'target': 'manage'})),
dict(
method='GET',
uri=self.get_mock_url(
resource='nodes',
append=[self.fake_baremetal_node['uuid']]),
json=self.fake_baremetal_node),
])
self.assertRaises(
exc.OpenStackCloudException,
self.op_cloud.register_machine,
nics,
wait=True,
timeout=0.001,
**node_to_post)
self.assert_calls()
def test_register_machine_port_create_failed(self):
mac_address = '00:01:02:03:04:05'
nics = [{'mac': mac_address}]
node_uuid = self.fake_baremetal_node['uuid']
node_to_post = {
'chassis_uuid': None,
'driver': None,
'driver_info': None,
'name': self.fake_baremetal_node['name'],
'properties': None,
'uuid': node_uuid}
self.fake_baremetal_node['provision_state'] = 'available'
self.register_uris([
dict(
method='POST',
uri=self.get_mock_url(
resource='nodes'),
json=self.fake_baremetal_node,
validate=dict(json=node_to_post)),
dict(
method='POST',
uri=self.get_mock_url(
resource='ports'),
status_code=400,
json={'error': 'invalid'},
validate=dict(json={'address': mac_address,
'node_uuid': node_uuid})),
dict(
method='DELETE',
uri=self.get_mock_url(
resource='nodes',
append=[self.fake_baremetal_node['uuid']])),
])
self.assertRaises(exc.OpenStackCloudException,
self.op_cloud.register_machine,
nics, **node_to_post)
self.assert_calls()
def test_unregister_machine(self):
mac_address = self.fake_baremetal_port['address']
nics = [{'mac': mac_address}]
port_uuid = self.fake_baremetal_port['uuid']
# NOTE(TheJulia): The two values below should be the same.
port_node_uuid = self.fake_baremetal_port['node_uuid']
port_url_address = 'detail?address=%s' % mac_address
self.fake_baremetal_node['provision_state'] = 'available'
self.register_uris([
dict(
method='GET',
uri=self.get_mock_url(
resource='nodes',
append=[self.fake_baremetal_node['uuid']]),
json=self.fake_baremetal_node),
dict(
method='GET',
uri=self.get_mock_url(
resource='ports',
append=[port_url_address]),
json={'ports': [{'address': mac_address,
'node_uuid': port_node_uuid,
'uuid': port_uuid}]}),
dict(
method='DELETE',
uri=self.get_mock_url(
resource='ports',
append=[self.fake_baremetal_port['uuid']])),
dict(
method='DELETE',
uri=self.get_mock_url(
resource='nodes',
append=[self.fake_baremetal_node['uuid']])),
])
self.op_cloud.unregister_machine(nics,
self.fake_baremetal_node['uuid'])
self.assert_calls()
def test_unregister_machine_timeout(self):
mac_address = self.fake_baremetal_port['address']
nics = [{'mac': mac_address}]
port_uuid = self.fake_baremetal_port['uuid']
port_node_uuid = self.fake_baremetal_port['node_uuid']
port_url_address = 'detail?address=%s' % mac_address
self.fake_baremetal_node['provision_state'] = 'available'
self.register_uris([
dict(
method='GET',
uri=self.get_mock_url(
resource='nodes',
append=[self.fake_baremetal_node['uuid']]),
json=self.fake_baremetal_node),
dict(
method='GET',
uri=self.get_mock_url(
resource='ports',
append=[port_url_address]),
json={'ports': [{'address': mac_address,
'node_uuid': port_node_uuid,
'uuid': port_uuid}]}),
dict(
method='DELETE',
uri=self.get_mock_url(
resource='ports',
append=[self.fake_baremetal_port['uuid']])),
dict(
method='DELETE',
uri=self.get_mock_url(
resource='nodes',
append=[self.fake_baremetal_node['uuid']])),
dict(
method='GET',
uri=self.get_mock_url(
resource='nodes',
append=[self.fake_baremetal_node['uuid']]),
json=self.fake_baremetal_node),
])
self.assertRaises(
exc.OpenStackCloudException,
self.op_cloud.unregister_machine,
nics,
self.fake_baremetal_node['uuid'],
wait=True,
timeout=0.001)
self.assert_calls()
def test_unregister_machine_unavailable(self):
# This is a list of invalid states that the method
# should fail on.
invalid_states = ['active', 'cleaning', 'clean wait', 'clean failed']
mac_address = self.fake_baremetal_port['address']
nics = [{'mac': mac_address}]
url_list = []
for state in invalid_states:
self.fake_baremetal_node['provision_state'] = state
url_list.append(
dict(
method='GET',
uri=self.get_mock_url(
resource='nodes',
append=[self.fake_baremetal_node['uuid']]),
json=self.fake_baremetal_node))
self.register_uris(url_list)
for state in invalid_states:
self.assertRaises(
exc.OpenStackCloudException,
self.op_cloud.unregister_machine,
nics,
self.fake_baremetal_node['uuid'])
self.assert_calls()
def test_update_machine_patch_no_action(self):
self.register_uris([dict(
method='GET',
uri=self.get_mock_url(
resource='nodes',
append=[self.fake_baremetal_node['uuid']]),
json=self.fake_baremetal_node),
])
# NOTE(TheJulia): This is just testing mechanics.
update_dict = self.op_cloud.update_machine(
self.fake_baremetal_node['uuid'])
self.assertIsNone(update_dict['changes'])
self.assertDictEqual(self.fake_baremetal_node, update_dict['node'])
self.assert_calls()
class TestUpdateMachinePatch(base.IronicTestCase):
# NOTE(TheJulia): As appears, and mordred describes,
# this class utilizes black magic, which ultimately
# results in additional test runs being executed with
# the scenario name appended. Useful for lots of
# variables that need to be tested.
def setUp(self):
super(TestUpdateMachinePatch, self).setUp()
# TODO(shade) Fix this when we get ironic update to REST
self.skipTest("Ironic operations not supported yet")
self.fake_baremetal_node = fakes.make_fake_machine(
self.name, self.uuid)
def test_update_machine_patch(self):
# The model has evolved over time, create the field if
# we don't already have it.
if self.field_name not in self.fake_baremetal_node:
self.fake_baremetal_node[self.field_name] = None
value_to_send = self.fake_baremetal_node[self.field_name]
if self.changed:
value_to_send = 'meow'
uris = [dict(
method='GET',
uri=self.get_mock_url(
resource='nodes',
append=[self.fake_baremetal_node['uuid']]),
json=self.fake_baremetal_node),
]
if self.changed:
test_patch = [{
'op': 'replace',
'path': '/' + self.field_name,
'value': 'meow'}]
uris.append(
dict(
method='PATCH',
uri=self.get_mock_url(
resource='nodes',
append=[self.fake_baremetal_node['uuid']]),
json=self.fake_baremetal_node,
validate=dict(json=test_patch)))
self.register_uris(uris)
call_args = {self.field_name: value_to_send}
update_dict = self.op_cloud.update_machine(
self.fake_baremetal_node['uuid'], **call_args)
if not self.changed:
self.assertIsNone(update_dict['changes'])
self.assertDictEqual(self.fake_baremetal_node, update_dict['node'])
self.assert_calls()
scenarios = [
('chassis_uuid', dict(field_name='chassis_uuid', changed=False)),
('chassis_uuid_changed',
dict(field_name='chassis_uuid', changed=True)),
('driver', dict(field_name='driver', changed=False)),
('driver_changed', dict(field_name='driver', changed=True)),
('driver_info', dict(field_name='driver_info', changed=False)),
('driver_info_changed', dict(field_name='driver_info', changed=True)),
('instance_info', dict(field_name='instance_info', changed=False)),
('instance_info_changed',
dict(field_name='instance_info', changed=True)),
('instance_uuid', dict(field_name='instance_uuid', changed=False)),
('instance_uuid_changed',
dict(field_name='instance_uuid', changed=True)),
('name', dict(field_name='name', changed=False)),
('name_changed', dict(field_name='name', changed=True)),
('properties', dict(field_name='properties', changed=False)),
('properties_changed', dict(field_name='properties', changed=True))
]