Resolve name/id using translation rules for Server
This changes OS::Nova::Server resource to use translation rules to resolve name_id properties. As most of the tests in test_server.py and test_rackspace_cloud_server.py are impacted by this change, this also changes all the tests to use mock library. Though the change is very big, it's mostly mox to mock conversion for the tests. This reduces the LOC drastically. Some of these test modules have become very big to manage. We can split them into smaller ones in the future. Change-Id: Iaa630ab3b013dfb65e9131b1f265e846c8274037 Partial-Bug: #1514680 Blueprint: mox-to-mock-conversion
This commit is contained in:
parent
5748507573
commit
9305478141
|
@ -12,13 +12,15 @@
|
|||
# under the License.
|
||||
|
||||
import mock
|
||||
import mox
|
||||
from oslo_config import cfg
|
||||
from oslo_utils import uuidutils
|
||||
import six
|
||||
|
||||
from heat.common import exception
|
||||
from heat.common import template_format
|
||||
from heat.engine.clients.os import glance
|
||||
from heat.engine.clients.os import neutron
|
||||
from heat.engine.clients.os import nova
|
||||
from heat.engine import environment
|
||||
from heat.engine import resource
|
||||
from heat.engine import rsrc_defn
|
||||
|
@ -77,16 +79,6 @@ class CloudServersTest(common.HeatTestCase):
|
|||
resource._register_class("OS::Nova::Server",
|
||||
cloud_server.CloudServer)
|
||||
|
||||
def _mock_find_image_by_name_or_id_success(self, imageId):
|
||||
self.mock_get_image = mock.Mock()
|
||||
self.ctx.clients.client_plugin(
|
||||
'glance').find_image_by_name_or_id = self.mock_get_image
|
||||
self.mock_get_image.return_value = imageId
|
||||
|
||||
def _stub_server_validate(self, server, imageId_input, image_id):
|
||||
# stub glance image validate
|
||||
self._mock_find_image_by_name_or_id_success(image_id)
|
||||
|
||||
def _setup_test_stack(self, stack_name):
|
||||
t = template_format.parse(wp_template)
|
||||
templ = template.Template(
|
||||
|
@ -97,7 +89,7 @@ class CloudServersTest(common.HeatTestCase):
|
|||
return (templ, self.stack)
|
||||
|
||||
def _setup_test_server(self, return_server, name, image_id=None,
|
||||
override_name=False, stub_create=True, exit_code=0):
|
||||
override_name=False, stub_create=True):
|
||||
stack_name = '%s_s' % name
|
||||
(tmpl, stack) = self._setup_test_stack(stack_name)
|
||||
|
||||
|
@ -105,7 +97,13 @@ class CloudServersTest(common.HeatTestCase):
|
|||
'image'] = image_id or 'CentOS 5.2'
|
||||
tmpl.t['Resources']['WebServer']['Properties'][
|
||||
'flavor'] = '256 MB Server'
|
||||
|
||||
self.patchobject(neutron.NeutronClientPlugin,
|
||||
'find_resourceid_by_name_or_id',
|
||||
return_value='aaaaaa')
|
||||
self.patchobject(nova.NovaClientPlugin, 'find_flavor_by_name_or_id',
|
||||
return_value=1)
|
||||
self.patchobject(glance.GlanceClientPlugin, 'find_image_by_name_or_id',
|
||||
return_value=1)
|
||||
server_name = '%s' % name
|
||||
if override_name:
|
||||
tmpl.t['Resources']['WebServer']['Properties'][
|
||||
|
@ -115,41 +113,23 @@ class CloudServersTest(common.HeatTestCase):
|
|||
server = cloud_server.CloudServer(server_name,
|
||||
resource_defns['WebServer'],
|
||||
stack)
|
||||
self.patchobject(nova.NovaClientPlugin, '_create',
|
||||
return_value=self.fc)
|
||||
|
||||
self.patchobject(server, 'store_external_ports')
|
||||
|
||||
self._stub_server_validate(server, image_id or 'CentOS 5.2', 1)
|
||||
if stub_create:
|
||||
self.m.StubOutWithMock(self.fc.servers, 'create')
|
||||
self.fc.servers.create(
|
||||
image=1,
|
||||
flavor=1,
|
||||
key_name='test',
|
||||
name=override_name and server.name or utils.PhysName(
|
||||
stack_name, server.name),
|
||||
security_groups=[],
|
||||
userdata=mox.IgnoreArg(),
|
||||
scheduler_hints=None,
|
||||
meta=None,
|
||||
nics=None,
|
||||
availability_zone=None,
|
||||
block_device_mapping=None,
|
||||
block_device_mapping_v2=None,
|
||||
config_drive=True,
|
||||
disk_config=None,
|
||||
reservation_id=None,
|
||||
files=mox.IgnoreArg(),
|
||||
admin_pass=None).AndReturn(return_server)
|
||||
|
||||
self.patchobject(self.fc.servers, 'create',
|
||||
return_value=return_server)
|
||||
# mock check_create_complete innards
|
||||
self.patchobject(self.fc.servers, 'get',
|
||||
return_value=return_server)
|
||||
return server
|
||||
|
||||
def _create_test_server(self, return_server, name, override_name=False,
|
||||
stub_create=True, exit_code=0):
|
||||
stub_create=True):
|
||||
server = self._setup_test_server(return_server, name,
|
||||
stub_create=stub_create,
|
||||
exit_code=exit_code)
|
||||
self.m.StubOutWithMock(self.fc.servers, 'get')
|
||||
self.fc.servers.get(server.id).AndReturn(return_server)
|
||||
self.m.ReplayAll()
|
||||
stub_create=stub_create)
|
||||
scheduler.TaskRunner(server.create)()
|
||||
return server
|
||||
|
||||
|
@ -166,14 +146,9 @@ class CloudServersTest(common.HeatTestCase):
|
|||
server = self._setup_test_server(return_server,
|
||||
'test_rackconnect_deployed')
|
||||
server.context.roles = ['rack_connect']
|
||||
self.m.StubOutWithMock(self.fc.servers, 'get')
|
||||
self.fc.servers.get(return_server.id).MultipleTimes(
|
||||
).AndReturn(return_server)
|
||||
self.m.ReplayAll()
|
||||
scheduler.TaskRunner(server.create)()
|
||||
self.assertEqual('CREATE', server.action)
|
||||
self.assertEqual('COMPLETE', server.status)
|
||||
self.m.VerifyAll()
|
||||
|
||||
def test_rackconnect_failed(self):
|
||||
return_server = self.fc.servers.list()[1]
|
||||
|
@ -181,13 +156,9 @@ class CloudServersTest(common.HeatTestCase):
|
|||
'rackconnect_automation_status': 'FAILED',
|
||||
'rax_service_level_automation': 'Complete',
|
||||
}
|
||||
self.m.StubOutWithMock(self.fc.servers, 'get')
|
||||
self.fc.servers.get(return_server.id).MultipleTimes(
|
||||
).AndReturn(return_server)
|
||||
server = self._setup_test_server(return_server,
|
||||
'test_rackconnect_failed')
|
||||
server.context.roles = ['rack_connect']
|
||||
self.m.ReplayAll()
|
||||
create = scheduler.TaskRunner(server.create)
|
||||
exc = self.assertRaises(exception.ResourceFailure, create)
|
||||
self.assertEqual('Error: resources.test_rackconnect_failed: '
|
||||
|
@ -201,17 +172,12 @@ class CloudServersTest(common.HeatTestCase):
|
|||
'rackconnect_unprocessable_reason': 'Fake reason',
|
||||
'rax_service_level_automation': 'Complete',
|
||||
}
|
||||
self.m.StubOutWithMock(self.fc.servers, 'get')
|
||||
self.fc.servers.get(return_server.id).MultipleTimes(
|
||||
).AndReturn(return_server)
|
||||
server = self._setup_test_server(return_server,
|
||||
'test_rackconnect_unprocessable')
|
||||
server.context.roles = ['rack_connect']
|
||||
self.m.ReplayAll()
|
||||
scheduler.TaskRunner(server.create)()
|
||||
self.assertEqual('CREATE', server.action)
|
||||
self.assertEqual('COMPLETE', server.status)
|
||||
self.m.VerifyAll()
|
||||
|
||||
def test_rackconnect_unknown(self):
|
||||
return_server = self.fc.servers.list()[1]
|
||||
|
@ -219,13 +185,9 @@ class CloudServersTest(common.HeatTestCase):
|
|||
'rackconnect_automation_status': 'FOO',
|
||||
'rax_service_level_automation': 'Complete',
|
||||
}
|
||||
self.m.StubOutWithMock(self.fc.servers, 'get')
|
||||
self.fc.servers.get(return_server.id).MultipleTimes(
|
||||
).AndReturn(return_server)
|
||||
server = self._setup_test_server(return_server,
|
||||
'test_rackconnect_unknown')
|
||||
server.context.roles = ['rack_connect']
|
||||
self.m.ReplayAll()
|
||||
create = scheduler.TaskRunner(server.create)
|
||||
exc = self.assertRaises(exception.ResourceFailure, create)
|
||||
self.assertEqual('Error: resources.test_rackconnect_unknown: '
|
||||
|
@ -257,13 +219,10 @@ class CloudServersTest(common.HeatTestCase):
|
|||
return return_server
|
||||
self.patchobject(self.fc.servers, 'get',
|
||||
side_effect=activate_status)
|
||||
self.m.ReplayAll()
|
||||
|
||||
scheduler.TaskRunner(server.create)()
|
||||
self.assertEqual((server.CREATE, server.COMPLETE), server.state)
|
||||
|
||||
self.m.VerifyAll()
|
||||
|
||||
def test_rackconnect_no_status(self):
|
||||
return_server = self.fc.servers.list()[0]
|
||||
server = self._setup_test_server(return_server,
|
||||
|
@ -287,13 +246,9 @@ class CloudServersTest(common.HeatTestCase):
|
|||
return return_server
|
||||
self.patchobject(self.fc.servers, 'get',
|
||||
side_effect=activate_status)
|
||||
self.m.ReplayAll()
|
||||
|
||||
scheduler.TaskRunner(server.create)()
|
||||
self.assertEqual((server.CREATE, server.COMPLETE), server.state)
|
||||
|
||||
self.m.VerifyAll()
|
||||
|
||||
def test_rax_automation_lifecycle(self):
|
||||
return_server = self.fc.servers.list()[0]
|
||||
server = self._setup_test_server(return_server,
|
||||
|
@ -322,19 +277,19 @@ class CloudServersTest(common.HeatTestCase):
|
|||
return return_server
|
||||
self.patchobject(self.fc.servers, 'get',
|
||||
side_effect=activate_status)
|
||||
self.m.ReplayAll()
|
||||
|
||||
scheduler.TaskRunner(server.create)()
|
||||
self.assertEqual((server.CREATE, server.COMPLETE), server.state)
|
||||
|
||||
self.m.VerifyAll()
|
||||
|
||||
def test_add_port_for_addresses(self):
|
||||
return_server = self.fc.servers.list()[1]
|
||||
return_server.metadata = {'rax_service_level_automation': 'Complete'}
|
||||
stack_name = 'test_stack'
|
||||
(tmpl, stack) = self._setup_test_stack(stack_name)
|
||||
resource_defns = tmpl.resource_definitions(stack)
|
||||
self.patchobject(nova.NovaClientPlugin, 'find_flavor_by_name_or_id',
|
||||
return_value=1)
|
||||
self.patchobject(glance.GlanceClientPlugin, 'find_image_by_name_or_id',
|
||||
return_value=1)
|
||||
server = cloud_server.CloudServer('WebServer',
|
||||
resource_defns['WebServer'], stack)
|
||||
self.patchobject(server, 'store_external_ports')
|
||||
|
@ -432,10 +387,6 @@ class CloudServersTest(common.HeatTestCase):
|
|||
'Build Error'}
|
||||
server = self._setup_test_server(return_server,
|
||||
'test_managed_cloud_build_error')
|
||||
self.m.StubOutWithMock(self.fc.servers, 'get')
|
||||
self.fc.servers.get(return_server.id).MultipleTimes(
|
||||
).AndReturn(return_server)
|
||||
self.m.ReplayAll()
|
||||
create = scheduler.TaskRunner(server.create)
|
||||
exc = self.assertRaises(exception.ResourceFailure, create)
|
||||
self.assertEqual('Error: resources.test_managed_cloud_build_error: '
|
||||
|
@ -447,10 +398,6 @@ class CloudServersTest(common.HeatTestCase):
|
|||
return_server.metadata = {'rax_service_level_automation': 'FOO'}
|
||||
server = self._setup_test_server(return_server,
|
||||
'test_managed_cloud_unknown')
|
||||
self.m.StubOutWithMock(self.fc.servers, 'get')
|
||||
self.fc.servers.get(return_server.id).MultipleTimes(
|
||||
).AndReturn(return_server)
|
||||
self.m.ReplayAll()
|
||||
create = scheduler.TaskRunner(server.create)
|
||||
exc = self.assertRaises(exception.ResourceFailure, create)
|
||||
self.assertEqual('Error: resources.test_managed_cloud_unknown: '
|
||||
|
@ -462,6 +409,10 @@ class CloudServersTest(common.HeatTestCase):
|
|||
return_server = self.fc.servers.list()[1]
|
||||
return_server.metadata = {'rax_service_level_automation': 'Complete'}
|
||||
stack_name = 'no_user_data'
|
||||
self.patchobject(nova.NovaClientPlugin, 'find_flavor_by_name_or_id',
|
||||
return_value=1)
|
||||
self.patchobject(glance.GlanceClientPlugin, 'find_image_by_name_or_id',
|
||||
return_value=1)
|
||||
(tmpl, stack) = self._setup_test_stack(stack_name)
|
||||
properties = tmpl.t['Resources']['WebServer']['Properties']
|
||||
properties['user_data'] = user_data
|
||||
|
@ -476,15 +427,11 @@ class CloudServersTest(common.HeatTestCase):
|
|||
self.patchobject(server, "_populate_deployments_metadata")
|
||||
mock_servers_create = mock.Mock(return_value=return_server)
|
||||
self.fc.servers.create = mock_servers_create
|
||||
image_id = mock.ANY
|
||||
self._mock_find_image_by_name_or_id_success(image_id)
|
||||
self.m.StubOutWithMock(self.fc.servers, 'get')
|
||||
self.fc.servers.get(return_server.id).MultipleTimes(
|
||||
).AndReturn(return_server)
|
||||
self.m.ReplayAll()
|
||||
self.patchobject(self.fc.servers, 'get',
|
||||
return_value=return_server)
|
||||
scheduler.TaskRunner(server.create)()
|
||||
mock_servers_create.assert_called_with(
|
||||
image=image_id,
|
||||
image=mock.ANY,
|
||||
flavor=mock.ANY,
|
||||
key_name=mock.ANY,
|
||||
name=mock.ANY,
|
||||
|
@ -543,15 +490,14 @@ class CloudServersValidationTests(common.HeatTestCase):
|
|||
"key_name": "test",
|
||||
"user_data": "wordpress",
|
||||
}
|
||||
|
||||
rsrcdef = rsrc_defn.ResourceDefinition(
|
||||
"test", cloud_server.CloudServer, properties=properties_server)
|
||||
|
||||
mock_plugin().find_flavor_by_name_or_id.return_value = 1
|
||||
server = cloud_server.CloudServer("test", rsrcdef, self.mockstack)
|
||||
|
||||
mock_boot_vol = self.patchobject(
|
||||
server, '_validate_block_device_mapping')
|
||||
mock_boot_vol.return_value = True
|
||||
|
||||
self.assertIsNone(server.validate())
|
||||
|
||||
def test_validate_no_image_bfv(self, mock_client, mock_plugin):
|
||||
|
@ -563,6 +509,7 @@ class CloudServersValidationTests(common.HeatTestCase):
|
|||
rsrcdef = rsrc_defn.ResourceDefinition(
|
||||
"test", cloud_server.CloudServer, properties=properties_server)
|
||||
|
||||
mock_plugin().find_flavor_by_name_or_id.return_value = 1
|
||||
server = cloud_server.CloudServer("test", rsrcdef, self.mockstack)
|
||||
|
||||
mock_boot_vol = self.patchobject(
|
||||
|
@ -577,7 +524,6 @@ class CloudServersValidationTests(common.HeatTestCase):
|
|||
}
|
||||
|
||||
mock_plugin().get_flavor.return_value = mock_flavor
|
||||
|
||||
error = self.assertRaises(
|
||||
exception.StackValidationFailed, server.validate)
|
||||
self.assertEqual(
|
||||
|
@ -585,6 +531,8 @@ class CloudServersValidationTests(common.HeatTestCase):
|
|||
six.text_type(error))
|
||||
|
||||
def test_validate_bfv_volume_only(self, mock_client, mock_plugin):
|
||||
mock_plugin().find_flavor_by_name_or_id.return_value = 1
|
||||
mock_plugin().find_image_by_name_or_id.return_value = 1
|
||||
server = cloud_server.CloudServer("test", self.rsrcdef, self.mockstack)
|
||||
|
||||
mock_flavor = mock.Mock(ram=4, disk=4)
|
||||
|
@ -609,6 +557,8 @@ class CloudServersValidationTests(common.HeatTestCase):
|
|||
|
||||
def test_validate_image_flavor_excluded_class(self, mock_client,
|
||||
mock_plugin):
|
||||
mock_plugin().find_flavor_by_name_or_id.return_value = 1
|
||||
mock_plugin().find_image_by_name_or_id.return_value = 1
|
||||
server = cloud_server.CloudServer("test", self.rsrcdef, self.mockstack)
|
||||
|
||||
mock_image = mock.Mock(status='ACTIVE', min_ram=2, min_disk=1)
|
||||
|
@ -631,6 +581,8 @@ class CloudServersValidationTests(common.HeatTestCase):
|
|||
six.text_type(error))
|
||||
|
||||
def test_validate_image_flavor_ok(self, mock_client, mock_plugin):
|
||||
mock_plugin().find_flavor_by_name_or_id.return_value = 1
|
||||
mock_plugin().find_image_by_name_or_id.return_value = 1
|
||||
server = cloud_server.CloudServer("test", self.rsrcdef, self.mockstack)
|
||||
|
||||
mock_image = mock.Mock(size=1, status='ACTIVE', min_ram=2, min_disk=2)
|
||||
|
|
|
@ -450,7 +450,7 @@ echo -e '%s\tALL=(ALL)\tNOPASSWD: ALL' >> /etc/sudoers
|
|||
else:
|
||||
return False
|
||||
|
||||
def check_resize(self, server_id, flavor_id, flavor):
|
||||
def check_resize(self, server_id, flavor):
|
||||
"""Verify that a resizing server is properly resized.
|
||||
|
||||
If that's the case, confirm the resize, if not raise an error.
|
||||
|
|
|
@ -630,7 +630,7 @@ class Instance(resource.Resource, sh.SchedulerHintsMixin):
|
|||
flavor = prop_diff[self.INSTANCE_TYPE]
|
||||
flavor_id = self.client_plugin().find_flavor_by_name_or_id(flavor)
|
||||
handler_args = {'args': (flavor_id,)}
|
||||
checker_args = {'args': (flavor_id, flavor)}
|
||||
checker_args = {'args': (flavor_id,)}
|
||||
|
||||
prg_resize = progress.ServerUpdateProgress(self.resource_id,
|
||||
'resize',
|
||||
|
|
|
@ -567,11 +567,57 @@ class Server(stack_user.StackUser, sh.SchedulerHintsMixin,
|
|||
entity = 'servers'
|
||||
|
||||
def translation_rules(self, props):
|
||||
return [translation.TranslationRule(
|
||||
props,
|
||||
translation.TranslationRule.REPLACE,
|
||||
source_path=[self.NETWORKS, self.NETWORK_ID],
|
||||
value_name=self.NETWORK_UUID)]
|
||||
rules = [
|
||||
translation.TranslationRule(
|
||||
props,
|
||||
translation.TranslationRule.REPLACE,
|
||||
source_path=[self.NETWORKS, self.NETWORK_ID],
|
||||
value_name=self.NETWORK_UUID),
|
||||
translation.TranslationRule(
|
||||
props,
|
||||
translation.TranslationRule.RESOLVE,
|
||||
source_path=[self.FLAVOR],
|
||||
client_plugin=self.client_plugin('nova'),
|
||||
finder='find_flavor_by_name_or_id'),
|
||||
translation.TranslationRule(
|
||||
props,
|
||||
translation.TranslationRule.RESOLVE,
|
||||
source_path=[self.IMAGE],
|
||||
client_plugin=self.client_plugin('glance'),
|
||||
finder='find_image_by_name_or_id'),
|
||||
]
|
||||
if self.is_using_neutron():
|
||||
rules.extend([
|
||||
translation.TranslationRule(
|
||||
props,
|
||||
translation.TranslationRule.RESOLVE,
|
||||
source_path=[self.NETWORKS, self.NETWORK_ID],
|
||||
client_plugin=self.client_plugin('neutron'),
|
||||
finder='find_resourceid_by_name_or_id',
|
||||
entity='network'),
|
||||
translation.TranslationRule(
|
||||
props,
|
||||
translation.TranslationRule.RESOLVE,
|
||||
source_path=[self.NETWORKS, self.NETWORK_SUBNET],
|
||||
client_plugin=self.client_plugin('neutron'),
|
||||
finder='find_resourceid_by_name_or_id',
|
||||
entity='subnet'),
|
||||
translation.TranslationRule(
|
||||
props,
|
||||
translation.TranslationRule.RESOLVE,
|
||||
source_path=[self.NETWORKS, self.NETWORK_PORT],
|
||||
client_plugin=self.client_plugin('neutron'),
|
||||
finder='find_resourceid_by_name_or_id',
|
||||
entity='port')])
|
||||
else:
|
||||
rules.extend([
|
||||
translation.TranslationRule(
|
||||
props,
|
||||
translation.TranslationRule.RESOLVE,
|
||||
source_path=[self.NETWORKS, self.NETWORK_ID],
|
||||
client_plugin=self.client_plugin('nova'),
|
||||
finder='get_nova_network_id')])
|
||||
return rules
|
||||
|
||||
def __init__(self, name, json_snippet, stack):
|
||||
super(Server, self).__init__(name, json_snippet, stack)
|
||||
|
@ -771,16 +817,7 @@ class Server(stack_user.StackUser, sh.SchedulerHintsMixin,
|
|||
instance_user=None,
|
||||
user_data_format=user_data_format)
|
||||
|
||||
flavor = self.properties[self.FLAVOR]
|
||||
availability_zone = self.properties[self.AVAILABILITY_ZONE]
|
||||
|
||||
image = self.properties[self.IMAGE]
|
||||
if image:
|
||||
image = self.client_plugin(
|
||||
'glance').find_image_by_name_or_id(image)
|
||||
|
||||
flavor_id = self.client_plugin().find_flavor_by_name_or_id(flavor)
|
||||
|
||||
instance_meta = self.properties[self.METADATA]
|
||||
if instance_meta is not None:
|
||||
instance_meta = self.client_plugin().meta_serialize(
|
||||
|
@ -799,13 +836,15 @@ class Server(stack_user.StackUser, sh.SchedulerHintsMixin,
|
|||
admin_pass = self.properties[self.ADMIN_PASS] or None
|
||||
personality_files = self.properties[self.PERSONALITY]
|
||||
key_name = self.properties[self.KEY_NAME]
|
||||
flavor = self.properties[self.FLAVOR]
|
||||
image = self.properties[self.IMAGE]
|
||||
|
||||
server = None
|
||||
try:
|
||||
server = self.client().servers.create(
|
||||
name=self._server_name(),
|
||||
image=image,
|
||||
flavor=flavor_id,
|
||||
flavor=flavor,
|
||||
key_name=key_name,
|
||||
security_groups=security_groups,
|
||||
userdata=userdata,
|
||||
|
@ -1028,10 +1067,7 @@ class Server(stack_user.StackUser, sh.SchedulerHintsMixin,
|
|||
|
||||
def _update_flavor(self, prop_diff):
|
||||
flavor = prop_diff[self.FLAVOR]
|
||||
flavor_id = self.client_plugin().find_flavor_by_name_or_id(flavor)
|
||||
handler_args = {'args': (flavor_id,)}
|
||||
checker_args = {'args': (flavor_id, flavor)}
|
||||
|
||||
handler_args = checker_args = {'args': (flavor,)}
|
||||
prg_resize = progress.ServerUpdateProgress(self.resource_id,
|
||||
'resize',
|
||||
handler_extra=handler_args,
|
||||
|
@ -1045,8 +1081,6 @@ class Server(stack_user.StackUser, sh.SchedulerHintsMixin,
|
|||
prop_diff.get(self.IMAGE_UPDATE_POLICY) or
|
||||
self.properties[self.IMAGE_UPDATE_POLICY])
|
||||
image = prop_diff[self.IMAGE]
|
||||
image_id = self.client_plugin(
|
||||
'glance').find_image_by_name_or_id(image)
|
||||
preserve_ephemeral = (
|
||||
image_update_policy == 'REBUILD_PRESERVE_EPHEMERAL')
|
||||
password = (prop_diff.get(self.ADMIN_PASS) or
|
||||
|
@ -1055,7 +1089,7 @@ class Server(stack_user.StackUser, sh.SchedulerHintsMixin,
|
|||
'preserve_ephemeral': preserve_ephemeral}
|
||||
prg = progress.ServerUpdateProgress(self.resource_id,
|
||||
'rebuild',
|
||||
handler_extra={'args': (image_id,),
|
||||
handler_extra={'args': (image,),
|
||||
'kwargs': kwargs})
|
||||
return prg
|
||||
|
||||
|
|
|
@ -66,8 +66,7 @@ class ServerNetworkMixin(object):
|
|||
subnet = network.get(self.NETWORK_SUBNET)
|
||||
if (subnet is not None and net is not None):
|
||||
subnet_net = self.client_plugin(
|
||||
'neutron').network_id_from_subnet_id(
|
||||
self._get_subnet_id(subnet))
|
||||
'neutron').network_id_from_subnet_id(subnet)
|
||||
if subnet_net != net:
|
||||
msg = _('Specified subnet %(subnet)s does not belongs to '
|
||||
'network %(network)s.') % {
|
||||
|
@ -98,7 +97,7 @@ class ServerNetworkMixin(object):
|
|||
if fixed_ip:
|
||||
body['ip_address'] = fixed_ip
|
||||
if subnet:
|
||||
body['subnet_id'] = self._get_subnet_id(subnet)
|
||||
body['subnet_id'] = subnet
|
||||
# we should add fixed_ips only if subnet or ip were provided
|
||||
if body:
|
||||
kwargs.update({'fixed_ips': [body]})
|
||||
|
@ -276,23 +275,11 @@ class ServerNetworkMixin(object):
|
|||
def _get_network_id(self, net):
|
||||
net_id = net.get(self.NETWORK_ID) or None
|
||||
subnet = net.get(self.NETWORK_SUBNET) or None
|
||||
if net_id:
|
||||
if self.is_using_neutron():
|
||||
net_id = self.client_plugin(
|
||||
'neutron').find_resourceid_by_name_or_id('network',
|
||||
net_id)
|
||||
else:
|
||||
net_id = self.client_plugin(
|
||||
'nova').get_nova_network_id(net_id)
|
||||
elif subnet:
|
||||
net_id = self.client_plugin('neutron').network_id_from_subnet_id(
|
||||
self._get_subnet_id(subnet))
|
||||
if not net_id and subnet:
|
||||
net_id = self.client_plugin(
|
||||
'neutron').network_id_from_subnet_id(subnet)
|
||||
return net_id
|
||||
|
||||
def _get_subnet_id(self, subnet):
|
||||
return self.client_plugin('neutron').find_resourceid_by_name_or_id(
|
||||
'subnet', subnet)
|
||||
|
||||
def update_networks_matching_iface_port(self, nets, interfaces):
|
||||
|
||||
def find_equal(port, net_id, ip, nets):
|
||||
|
|
|
@ -722,10 +722,17 @@ class InstancesTest(common.HeatTestCase):
|
|||
instance = self._create_test_instance(return_server,
|
||||
'ud_type')
|
||||
|
||||
self._stub_glance_for_update()
|
||||
update_template = copy.deepcopy(instance.t)
|
||||
update_template['Properties']['InstanceType'] = 'm1.small'
|
||||
|
||||
def side_effect(*args):
|
||||
return 2 if args[0] == 'm1.small' else 1
|
||||
|
||||
self.patchobject(nova.NovaClientPlugin, 'find_flavor_by_name_or_id',
|
||||
side_effect=side_effect)
|
||||
self.patchobject(glance.GlanceClientPlugin, 'find_image_by_name_or_id',
|
||||
return_value=1)
|
||||
|
||||
self.m.StubOutWithMock(self.fc.servers, 'get')
|
||||
|
||||
def status_resize(*args):
|
||||
|
@ -770,7 +777,14 @@ class InstancesTest(common.HeatTestCase):
|
|||
instance = self._create_test_instance(return_server,
|
||||
'ud_type_f')
|
||||
|
||||
self._stub_glance_for_update()
|
||||
def side_effect(*args):
|
||||
return 2 if args[0] == 'm1.small' else 1
|
||||
|
||||
self.patchobject(nova.NovaClientPlugin, 'find_flavor_by_name_or_id',
|
||||
side_effect=side_effect)
|
||||
self.patchobject(glance.GlanceClientPlugin, 'find_image_by_name_or_id',
|
||||
return_value=1)
|
||||
|
||||
update_template = copy.deepcopy(instance.t)
|
||||
update_template['Properties']['InstanceType'] = 'm1.small'
|
||||
|
||||
|
@ -797,7 +811,7 @@ class InstancesTest(common.HeatTestCase):
|
|||
error = self.assertRaises(exception.ResourceFailure, updater)
|
||||
self.assertEqual(
|
||||
"Error: resources.ud_type_f: "
|
||||
"Resizing to 'm1.small' failed, status 'ERROR'",
|
||||
"Resizing to '2' failed, status 'ERROR'",
|
||||
six.text_type(error))
|
||||
self.assertEqual((instance.UPDATE, instance.FAILED), instance.state)
|
||||
self.m.VerifyAll()
|
||||
|
|
|
@ -21,6 +21,8 @@ import six
|
|||
from heat.common import exception
|
||||
from heat.common import messaging
|
||||
from heat.common import template_format
|
||||
from heat.engine.clients.os import glance
|
||||
from heat.engine.clients.os import nova
|
||||
from heat.engine import environment
|
||||
from heat.engine import resource
|
||||
from heat.engine import service
|
||||
|
@ -853,6 +855,14 @@ resources:
|
|||
environment_files=None):
|
||||
stack_name = 'service_update_test_stack_preview'
|
||||
params = {'foo': 'bar'}
|
||||
|
||||
def side_effect(*args):
|
||||
return 2 if args[0] == 'm1.small' else 1
|
||||
|
||||
self.patchobject(nova.NovaClientPlugin, 'find_flavor_by_name_or_id',
|
||||
side_effect=side_effect)
|
||||
self.patchobject(glance.GlanceClientPlugin, 'find_image_by_name_or_id',
|
||||
return_value=1)
|
||||
old_stack = tools.get_stack(stack_name, self.ctx,
|
||||
template=orig_template)
|
||||
sid = old_stack.store()
|
||||
|
@ -947,7 +957,6 @@ resources:
|
|||
def test_stack_update_preview_updated(self):
|
||||
# new template changes to flavor of server
|
||||
new_tmpl = self.old_tmpl.replace('m1.large', 'm1.small')
|
||||
|
||||
result = self._test_stack_update_preview(self.old_tmpl, new_tmpl)
|
||||
|
||||
updated = [x for x in result['updated']][0]
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -15,6 +15,8 @@ from oslo_serialization import jsonutils
|
|||
|
||||
from heat.common import identifier
|
||||
from heat.common import template_format
|
||||
from heat.engine.clients.os import glance
|
||||
from heat.engine.clients.os import nova
|
||||
from heat.engine import environment
|
||||
from heat.engine.resources.aws.cfn.wait_condition_handle import (
|
||||
WaitConditionHandle)
|
||||
|
@ -144,11 +146,13 @@ resources:
|
|||
|
||||
class MetadataRefreshTest(common.HeatTestCase):
|
||||
|
||||
@mock.patch.object(nova.NovaClientPlugin, 'find_flavor_by_name_or_id')
|
||||
@mock.patch.object(glance.GlanceClientPlugin, 'find_image_by_name_or_id')
|
||||
@mock.patch.object(instance.Instance, 'handle_create')
|
||||
@mock.patch.object(instance.Instance, 'check_create_complete')
|
||||
@mock.patch.object(instance.Instance, 'FnGetAtt')
|
||||
def test_FnGetAtt_metadata_updated(self, mock_get,
|
||||
mock_check, mock_handle):
|
||||
def test_FnGetAtt_metadata_updated(self, mock_get, mock_check,
|
||||
mock_handle, *args):
|
||||
"""Tests that metadata gets updated when FnGetAtt return changes."""
|
||||
# Setup
|
||||
temp = template_format.parse(TEST_TEMPLATE_METADATA)
|
||||
|
@ -158,9 +162,7 @@ class MetadataRefreshTest(common.HeatTestCase):
|
|||
stack = stk.Stack(ctx, 'test_stack', template, disable_rollback=True)
|
||||
stack.store()
|
||||
|
||||
self.stub_ImageConstraint_validate()
|
||||
self.stub_KeypairConstraint_validate()
|
||||
self.stub_FlavorConstraint_validate()
|
||||
|
||||
# Configure FnGetAtt to return different values on subsequent calls
|
||||
mock_get.side_effect = [
|
||||
|
@ -208,13 +210,15 @@ class WaitConditionMetadataUpdateTest(common.HeatTestCase):
|
|||
self.man = service.EngineService('a-host', 'a-topic')
|
||||
self.man.create_periodic_tasks()
|
||||
|
||||
@mock.patch.object(nova.NovaClientPlugin, 'find_flavor_by_name_or_id')
|
||||
@mock.patch.object(glance.GlanceClientPlugin, 'find_image_by_name_or_id')
|
||||
@mock.patch.object(instance.Instance, 'handle_create')
|
||||
@mock.patch.object(instance.Instance, 'check_create_complete')
|
||||
@mock.patch.object(instance.Instance, 'is_service_available')
|
||||
@mock.patch.object(TaskRunner, '_sleep')
|
||||
@mock.patch.object(WaitConditionHandle, 'identifier')
|
||||
def test_wait_metadata(self, mock_identifier, mock_sleep, mock_available,
|
||||
mock_check, mock_handle):
|
||||
mock_check, mock_handle, *args):
|
||||
"""Tests a wait condition metadata update after a signal call."""
|
||||
|
||||
# Setup Stack
|
||||
|
@ -224,9 +228,7 @@ class WaitConditionMetadataUpdateTest(common.HeatTestCase):
|
|||
stack = stk.Stack(ctx, 'test-stack', template, disable_rollback=True)
|
||||
stack.store()
|
||||
|
||||
self.stub_ImageConstraint_validate()
|
||||
self.stub_KeypairConstraint_validate()
|
||||
self.stub_FlavorConstraint_validate()
|
||||
|
||||
res_id = identifier.ResourceIdentifier('test_tenant_id', stack.name,
|
||||
stack.id, '', 'WH')
|
||||
|
@ -288,10 +290,15 @@ class WaitConditionMetadataUpdateTest(common.HeatTestCase):
|
|||
|
||||
class MetadataRefreshServerTest(common.HeatTestCase):
|
||||
|
||||
@mock.patch.object(nova.NovaClientPlugin, 'find_flavor_by_name_or_id',
|
||||
return_value=1)
|
||||
@mock.patch.object(glance.GlanceClientPlugin, 'find_image_by_name_or_id',
|
||||
return_value=1)
|
||||
@mock.patch.object(Server, 'handle_create')
|
||||
@mock.patch.object(Server, 'check_create_complete')
|
||||
@mock.patch.object(Server, 'FnGetAtt')
|
||||
def test_FnGetAtt_metadata_update(self, mock_get, mock_check, mock_handle):
|
||||
def test_FnGetAtt_metadata_update(self, mock_get, mock_check,
|
||||
mock_handle, *args):
|
||||
temp = template_format.parse(TEST_TEMPLATE_SERVER)
|
||||
template = tmpl.Template(temp,
|
||||
env=environment.Environment({}))
|
||||
|
@ -299,9 +306,7 @@ class MetadataRefreshServerTest(common.HeatTestCase):
|
|||
stack = stk.Stack(ctx, 'test-stack', template, disable_rollback=True)
|
||||
stack.store()
|
||||
|
||||
self.stub_ImageConstraint_validate()
|
||||
self.stub_KeypairConstraint_validate()
|
||||
self.stub_FlavorConstraint_validate()
|
||||
|
||||
# Note dummy addresses are from TEST-NET-1 ref rfc5737
|
||||
mock_get.side_effect = ['192.0.2.1', '192.0.2.2', '192.0.2.2']
|
||||
|
|
Loading…
Reference in New Issue