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
This commit is contained in:
Julia Kreger 2017-09-10 16:23:00 +00:00 committed by Monty Taylor
parent dd431c3a22
commit 910fc10427
No known key found for this signature in database
GPG Key ID: 7BAE94BC7141A594
6 changed files with 804 additions and 60 deletions

View File

@ -17,81 +17,94 @@
from openstack import task_manager
class MachineCreate(task_manager.Task):
def main(self, client):
return client.ironic_client.node.create(**self.args)
class IronicTask(task_manager.Task):
def __init__(self, client, **kwargs):
super(IronicTask, self).__init__(**kwargs)
self.client = client
class MachineDelete(task_manager.Task):
def main(self, client):
return client.ironic_client.node.delete(**self.args)
class MachineCreate(IronicTask):
def main(self):
return self.client.ironic_client.node.create(*self.args, **self.kwargs)
class MachinePatch(task_manager.Task):
def main(self, client):
return client.ironic_client.node.update(**self.args)
class MachineDelete(IronicTask):
def main(self):
return self.client.ironic_client.node.delete(*self.args, **self.kwargs)
class MachinePortGet(task_manager.Task):
def main(self, client):
return client.ironic_client.port.get(**self.args)
class MachinePatch(IronicTask):
def main(self):
return self.client.ironic_client.node.update(*self.args, **self.kwargs)
class MachinePortGetByAddress(task_manager.Task):
def main(self, client):
return client.ironic_client.port.get_by_address(**self.args)
class MachinePortGet(IronicTask):
def main(self):
return self.client.ironic_client.port.get(*self.args, **self.kwargs)
class MachinePortCreate(task_manager.Task):
def main(self, client):
return client.ironic_client.port.create(**self.args)
class MachinePortGetByAddress(IronicTask):
def main(self):
return self.client.ironic_client.port.get_by_address(
*self.args, **self.kwargs)
class MachinePortDelete(task_manager.Task):
def main(self, client):
return client.ironic_client.port.delete(**self.args)
class MachinePortCreate(IronicTask):
def main(self):
return self.client.ironic_client.port.create(*self.args, **self.kwargs)
class MachinePortList(task_manager.Task):
def main(self, client):
return client.ironic_client.port.list()
class MachinePortDelete(IronicTask):
def main(self):
return self.client.ironic_client.port.delete(*self.args, **self.kwargs)
class MachineNodeGet(task_manager.Task):
def main(self, client):
return client.ironic_client.node.get(**self.args)
class MachinePortList(IronicTask):
def main(self):
return self.client.ironic_client.port.list()
class MachineNodeList(task_manager.Task):
def main(self, client):
return client.ironic_client.node.list(**self.args)
class MachineNodeGet(IronicTask):
def main(self):
return self.client.ironic_client.node.get(*self.args, **self.kwargs)
class MachineNodePortList(task_manager.Task):
def main(self, client):
return client.ironic_client.node.list_ports(**self.args)
class MachineNodeList(IronicTask):
def main(self):
return self.client.ironic_client.node.list(*self.args, **self.kwargs)
class MachineNodeUpdate(task_manager.Task):
def main(self, client):
return client.ironic_client.node.update(**self.args)
class MachineNodePortList(IronicTask):
def main(self):
return self.client.ironic_client.node.list_ports(
*self.args, **self.kwargs)
class MachineNodeValidate(task_manager.Task):
def main(self, client):
return client.ironic_client.node.validate(**self.args)
class MachineNodeUpdate(IronicTask):
def main(self):
return self.client.ironic_client.node.update(*self.args, **self.kwargs)
class MachineSetMaintenance(task_manager.Task):
def main(self, client):
return client.ironic_client.node.set_maintenance(**self.args)
class MachineNodeValidate(IronicTask):
def main(self):
return self.client.ironic_client.node.validate(
*self.args, **self.kwargs)
class MachineSetPower(task_manager.Task):
def main(self, client):
return client.ironic_client.node.set_power_state(**self.args)
class MachineSetMaintenance(IronicTask):
def main(self):
return self.client.ironic_client.node.set_maintenance(
*self.args, **self.kwargs)
class MachineSetProvision(task_manager.Task):
def main(self, client):
return client.ironic_client.node.set_provision_state(**self.args)
class MachineSetPower(IronicTask):
def main(self):
return self.client.ironic_client.node.set_power_state(
*self.args, **self.kwargs)
class MachineSetProvision(IronicTask):
def main(self):
return self.client.ironic_client.node.set_provision_state(
*self.args, **self.kwargs)

View File

@ -16,6 +16,7 @@ import jsonpatch
import munch
from openstack.cloud.exc import * # noqa
from openstack.cloud import meta
from openstack.cloud import openstackcloud
from openstack.cloud import _tasks
from openstack.cloud import _utils
@ -35,27 +36,28 @@ class OperatorCloud(openstackcloud.OpenStackCloud):
def list_nics(self):
with _utils.shade_exceptions("Error fetching machine port list"):
return self.manager.submit_task(_tasks.MachinePortList())
return meta.obj_list_to_munch(
self.manager.submit_task(_tasks.MachinePortList(self)))
def list_nics_for_machine(self, uuid):
with _utils.shade_exceptions(
"Error fetching port list for node {node_id}".format(
node_id=uuid)):
return self.manager.submit_task(
_tasks.MachineNodePortList(node_id=uuid))
return meta.obj_list_to_munch(self.manager.submit_task(
_tasks.MachineNodePortList(self, node_id=uuid)))
def get_nic_by_mac(self, mac):
"""Get Machine by MAC address"""
# TODO(shade) Finish porting ironic to REST/sdk
# try:
# return self.manager.submit_task(
# _tasks.MachineNodePortGet(port_id=mac))
# _tasks.MachineNodePortGet(self, port_id=mac))
# except ironic_exceptions.ClientException:
# return None
def list_machines(self):
return self._normalize_machines(
self.manager.submit_task(_tasks.MachineNodeList()))
self.manager.submit_task(_tasks.MachineNodeList(self)))
def get_machine(self, name_or_id):
"""Get Machine by name or uuid
@ -211,7 +213,7 @@ class OperatorCloud(openstackcloud.OpenStackCloud):
nic = self.manager.submit_task(
_tasks.MachinePortCreate(address=row['mac'],
node_uuid=machine['uuid']))
created_nics.append(nic.uuid)
created_nics.append(nic['uuid'])
except Exception as e:
self.log.debug("ironic NIC registration failed", exc_info=True)
@ -277,7 +279,10 @@ class OperatorCloud(openstackcloud.OpenStackCloud):
machine = self.get_machine(machine['uuid'])
if (machine['reservation'] is None and
machine['provision_state'] is not 'enroll'):
# NOTE(TheJulia): In this case, the node has
# has moved on from the previous state and is
# likely not being verified, as no lock is
# present on the node.
self.node_set_provision_state(
machine['uuid'], 'provide')
machine = self.get_machine(machine['uuid'])
@ -292,8 +297,10 @@ class OperatorCloud(openstackcloud.OpenStackCloud):
raise OpenStackCloudException(
"Machine encountered a failure: %s"
% machine['last_error'])
return machine
if not isinstance(machine, str):
return self._normalize_machine(machine)
else:
return machine
def unregister_machine(self, nics, uuid, wait=False, timeout=600):
"""Unregister Baremetal from Ironic

View File

@ -248,6 +248,16 @@ def make_fake_machine(machine_name, machine_id=None):
id=machine_id,
name=machine_name))
def make_fake_port(address, node_id=None, port_id=None):
if not node_id:
node_id = uuid.uuid4().hex
if not port_id:
port_id = uuid.uuid4().hex
return meta.obj_to_munch(FakeMachinePort(
id=port_id,
address=address,
node_id=node_id))
class FakeFloatingIP(object):
def __init__(self, id, pool, ip, fixed_ip, instance_id):
@ -346,7 +356,7 @@ class FakeVolumeSnapshot(object):
class FakeMachine(object):
def __init__(self, id, name=None, driver=None, driver_info=None,
chassis_uuid=None, instance_info=None, instance_uuid=None,
properties=None):
properties=None, reservation=None, last_error=None):
self.uuid = id
self.name = name
self.driver = driver
@ -355,6 +365,8 @@ class FakeMachine(object):
self.instance_info = instance_info
self.instance_uuid = instance_uuid
self.properties = properties
self.reservation = reservation
self.last_error = last_error
class FakeMachinePort(object):

View File

@ -34,6 +34,12 @@ class TestBaremetalNode(base.IronicTestCase):
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()))
@ -822,6 +828,542 @@ class TestBaremetalNode(base.IronicTestCase):
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',

View File

@ -374,8 +374,8 @@ class TestImage(BaseTestImage):
'X-Trans-Id': 'txbbb825960a3243b49a36f-005a0dadaedfw1',
'Content-Length': '1290170880',
'Last-Modified': 'Tue, 14 Apr 2015 18:29:01 GMT',
'X-Object-Meta-X-Shade-Sha256': fakes.NO_SHA256,
'X-Object-Meta-X-Shade-Md5': fakes.NO_MD5,
'X-Object-Meta-X-Sdk-Sha256': fakes.NO_SHA256,
'X-Object-Meta-X-Sdk-Md5': fakes.NO_MD5,
'Date': 'Thu, 16 Nov 2017 15:24:30 GMT',
'Accept-Ranges': 'bytes',
'Content-Type': 'application/octet-stream',

View File

@ -0,0 +1,170 @@
# 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 mock
import munch
import testtools
import openstack
from openstack.cloud import exc
from openstack.cloud import meta
from openstack.config import cloud_config
from openstack.tests import fakes
from openstack.tests.unit import base
class TestOperatorCloud(base.RequestsMockTestCase):
def setUp(self):
super(TestOperatorCloud, self).setUp()
def test_operator_cloud(self):
self.assertIsInstance(self.op_cloud, openstack.OperatorCloud)
@mock.patch.object(openstack.OperatorCloud, 'ironic_client')
def test_list_nics(self, mock_client):
port1 = fakes.FakeMachinePort(1, "aa:bb:cc:dd", "node1")
port2 = fakes.FakeMachinePort(2, "dd:cc:bb:aa", "node2")
port_list = [port1, port2]
port_dict_list = meta.obj_list_to_munch(port_list)
mock_client.port.list.return_value = port_list
nics = self.op_cloud.list_nics()
self.assertTrue(mock_client.port.list.called)
self.assertEqual(port_dict_list, nics)
@mock.patch.object(openstack.OperatorCloud, 'ironic_client')
def test_list_nics_failure(self, mock_client):
mock_client.port.list.side_effect = Exception()
self.assertRaises(exc.OpenStackCloudException,
self.op_cloud.list_nics)
@mock.patch.object(openstack.OperatorCloud, 'ironic_client')
def test_list_nics_for_machine(self, mock_client):
mock_client.node.list_ports.return_value = []
self.op_cloud.list_nics_for_machine("123")
mock_client.node.list_ports.assert_called_with(node_id="123")
@mock.patch.object(openstack.OperatorCloud, 'ironic_client')
def test_list_nics_for_machine_failure(self, mock_client):
mock_client.node.list_ports.side_effect = Exception()
self.assertRaises(exc.OpenStackCloudException,
self.op_cloud.list_nics_for_machine, None)
@mock.patch.object(openstack.OpenStackCloud, '_image_client')
def test_get_image_name(self, mock_client):
fake_image = munch.Munch(
id='22',
name='22 name',
status='success')
mock_client.get.return_value = [fake_image]
self.assertEqual('22 name', self.op_cloud.get_image_name('22'))
self.assertEqual('22 name', self.op_cloud.get_image_name('22 name'))
@mock.patch.object(openstack.OpenStackCloud, '_image_client')
def test_get_image_id(self, mock_client):
fake_image = munch.Munch(
id='22',
name='22 name',
status='success')
mock_client.get.return_value = [fake_image]
self.assertEqual('22', self.op_cloud.get_image_id('22'))
self.assertEqual('22', self.op_cloud.get_image_id('22 name'))
@mock.patch.object(cloud_config.CloudConfig, 'get_endpoint')
def test_get_session_endpoint_provided(self, fake_get_endpoint):
fake_get_endpoint.return_value = 'http://fake.url'
self.assertEqual(
'http://fake.url', self.op_cloud.get_session_endpoint('image'))
@mock.patch.object(cloud_config.CloudConfig, 'get_session')
def test_get_session_endpoint_session(self, get_session_mock):
session_mock = mock.Mock()
session_mock.get_endpoint.return_value = 'http://fake.url'
get_session_mock.return_value = session_mock
self.assertEqual(
'http://fake.url', self.op_cloud.get_session_endpoint('image'))
@mock.patch.object(cloud_config.CloudConfig, 'get_session')
def test_get_session_endpoint_exception(self, get_session_mock):
class FakeException(Exception):
pass
def side_effect(*args, **kwargs):
raise FakeException("No service")
session_mock = mock.Mock()
session_mock.get_endpoint.side_effect = side_effect
get_session_mock.return_value = session_mock
self.op_cloud.name = 'testcloud'
self.op_cloud.region_name = 'testregion'
with testtools.ExpectedException(
exc.OpenStackCloudException,
"Error getting image endpoint on testcloud:testregion:"
" No service"):
self.op_cloud.get_session_endpoint("image")
@mock.patch.object(cloud_config.CloudConfig, 'get_session')
def test_get_session_endpoint_unavailable(self, get_session_mock):
session_mock = mock.Mock()
session_mock.get_endpoint.return_value = None
get_session_mock.return_value = session_mock
image_endpoint = self.op_cloud.get_session_endpoint("image")
self.assertIsNone(image_endpoint)
@mock.patch.object(cloud_config.CloudConfig, 'get_session')
def test_get_session_endpoint_identity(self, get_session_mock):
session_mock = mock.Mock()
get_session_mock.return_value = session_mock
self.op_cloud.get_session_endpoint('identity')
kwargs = dict(
interface='public', region_name='RegionOne',
service_name=None, service_type='identity')
session_mock.get_endpoint.assert_called_with(**kwargs)
@mock.patch.object(cloud_config.CloudConfig, 'get_session')
def test_has_service_no(self, get_session_mock):
session_mock = mock.Mock()
session_mock.get_endpoint.return_value = None
get_session_mock.return_value = session_mock
self.assertFalse(self.op_cloud.has_service("image"))
@mock.patch.object(cloud_config.CloudConfig, 'get_session')
def test_has_service_yes(self, get_session_mock):
session_mock = mock.Mock()
session_mock.get_endpoint.return_value = 'http://fake.url'
get_session_mock.return_value = session_mock
self.assertTrue(self.op_cloud.has_service("image"))
def test_list_hypervisors(self):
'''This test verifies that calling list_hypervisors results in a call
to nova client.'''
self.register_uris([
dict(method='GET',
uri=self.get_mock_url(
'compute', 'public', append=['os-hypervisors', 'detail']),
json={'hypervisors': [
fakes.make_fake_hypervisor('1', 'testserver1'),
fakes.make_fake_hypervisor('2', 'testserver2'),
]}),
])
r = self.op_cloud.list_hypervisors()
self.assertEqual(2, len(r))
self.assertEqual('testserver1', r[0]['hypervisor_hostname'])
self.assertEqual('testserver2', r[1]['hypervisor_hostname'])
self.assert_calls()