Use resource methods for metadata get/set

The current approach of using the Metadata descriptor
class has some issues including:
* Unintended database queries on accessing a metadata attribute
* get/modify/set patterns since the attribute isn't backed by a real dict
* lack of control over whether to fetch metadata locally or from the db

This change creates Resource methods metadata_get and metadata_set to use
for reading and modifying resource data. This is a refactoring change only so
there should be no change in behaviour.

This change will help in the future with
Related-Bug: #1306743

Change-Id: I7cd87a071ac410a388d787f132c9aee194030714
This commit is contained in:
Steve Baker 2014-04-23 14:04:57 +12:00
parent 464d25927b
commit 96791aaa10
26 changed files with 137 additions and 166 deletions

View File

@ -118,7 +118,7 @@ def format_stack_resource(resource, detail=True):
api.RES_UPDATED_TIME: timeutils.isotime(last_updated_time),
api.RES_NAME: resource.name,
api.RES_PHYSICAL_ID: resource.resource_id or '',
api.RES_METADATA: resource.metadata,
api.RES_METADATA: resource.metadata_get(),
api.RES_ACTION: resource.action,
api.RES_STATUS: resource.status,
api.RES_STATUS_DATA: resource.status_reason,
@ -134,7 +134,6 @@ def format_stack_resource(resource, detail=True):
if detail:
res[api.RES_DESCRIPTION] = resource.parsed_template('Description', '')
res[api.RES_METADATA] = resource.metadata
return res

View File

@ -530,7 +530,7 @@ class ResourceFacade(function.Function):
attr = function.resolve(self.args)
if attr == self.METADATA:
return self.stack.parent_resource.metadata
return self.stack.parent_resource.metadata_get()
elif attr == self.UPDATE_POLICY:
up = self.stack.parent_resource.t.get('UpdatePolicy', {})
return function.resolve(up)

View File

@ -65,30 +65,6 @@ class UpdateReplace(Exception):
super(Exception, self).__init__(msg)
class Metadata(object):
'''
A descriptor for accessing the metadata of a resource while ensuring the
most up-to-date data is always obtained from the database.
'''
def __get__(self, resource, resource_class):
'''Return the metadata for the owning resource.'''
if resource is None:
return None
if resource.id is None:
return resource.parsed_template('Metadata')
rs = db_api.resource_get(resource.stack.context, resource.id)
rs.refresh(attrs=['rsrc_metadata'])
return rs.rsrc_metadata
def __set__(self, resource, metadata):
'''Update the metadata for the owning resource.'''
if resource.id is None:
raise exception.ResourceNotAvailable(resource_name=resource.name)
rs = db_api.resource_get(resource.stack.context, resource.id)
rs.update_and_save({'rsrc_metadata': metadata})
class Resource(object):
ACTIONS = (INIT, CREATE, DELETE, UPDATE, ROLLBACK, SUSPEND, RESUME, ADOPT
) = ('INIT', 'CREATE', 'DELETE', 'UPDATE', 'ROLLBACK',
@ -100,8 +76,6 @@ class Resource(object):
# If True, this resource must be created before it can be referenced.
strict_dependency = True
_metadata = Metadata()
# Resource implementation set this to the subset of template keys
# which are supported for handle_update, used by update_template_diff
update_allowed_keys = ()
@ -207,13 +181,18 @@ class Resource(object):
return result
return not result
@property
def metadata(self):
return self._metadata
def metadata_get(self):
if self.id is None:
return self.parsed_template('Metadata')
rs = db_api.resource_get(self.stack.context, self.id)
rs.refresh(attrs=['rsrc_metadata'])
return rs.rsrc_metadata
@metadata.setter
def metadata(self, metadata):
self._metadata = metadata
def metadata_set(self, metadata):
if self.id is None:
raise exception.ResourceNotAvailable(resource_name=self.name)
rs = db_api.resource_get(self.stack.context, self.id)
rs.update_and_save({'rsrc_metadata': metadata})
def type(self):
return self.t['Type']
@ -465,7 +444,7 @@ class Resource(object):
'type': self.type(),
'action': self.action,
'status': self.status,
'metadata': self.metadata,
'metadata': self.metadata_get(),
'resource_data': self.data()
}
@ -493,7 +472,7 @@ class Resource(object):
self.data_set(key, value)
# save the resource metadata
self.metadata = metadata
self.metadata_set(metadata)
def _get_resource_info(self, resource_data):
if not resource_data:
@ -743,7 +722,7 @@ class Resource(object):
def _store(self):
'''Create the resource in the database.'''
metadata = self.metadata
metadata = self.metadata_get()
try:
rs = {'action': self.action,
'status': self.status,

View File

@ -58,7 +58,7 @@ class CooldownMixin(object):
# If not specified, it will be None, same as cooldown == 0
cooldown = 0
metadata = self.metadata
metadata = self.metadata_get()
if metadata and cooldown != 0:
last_adjust = metadata.keys()[0]
if not timeutils.is_older_than(last_adjust, cooldown):
@ -71,7 +71,7 @@ class CooldownMixin(object):
# we could maintain event history here, but since we only need
# the latest event for cooldown, just store that for now
metadata = {timeutils.strtime(): reason}
self.metadata = metadata
self.metadata_set(metadata)
class InstanceGroup(stack_resource.StackResource):

View File

@ -545,7 +545,7 @@ class Instance(resource.Resource):
def handle_update(self, json_snippet, tmpl_diff, prop_diff):
if 'Metadata' in tmpl_diff:
self.metadata = tmpl_diff['Metadata']
self.metadata_set(tmpl_diff['Metadata'])
checkers = []
server = None
if self.TAGS in prop_diff:
@ -643,7 +643,7 @@ class Instance(resource.Resource):
Refresh the metadata if new_metadata is None
'''
if new_metadata is None:
self.metadata = self.parsed_template('Metadata')
self.metadata_set(self.parsed_template('Metadata'))
def validate(self):
'''

View File

@ -474,11 +474,11 @@ class LoadBalancer(stack_resource.StackResource):
templ = self.get_parsed_template()
cfg = self._haproxy_config(templ, prop_diff[self.INSTANCES])
md = self.nested()['LB_instance'].metadata
md = self.nested()['LB_instance'].metadata_get()
files = md['AWS::CloudFormation::Init']['config']['files']
files['/etc/haproxy/haproxy.cfg']['content'] = cfg
self.nested()['LB_instance'].metadata = md
self.nested()['LB_instance'].metadata_set(md)
def handle_delete(self):
return self.delete_nested()

View File

@ -350,7 +350,7 @@ class Pool(neutron.NeutronResource):
vip_arguments['pool_id'] = pool['id']
vip = client.create_vip({'vip': vip_arguments})['vip']
self.metadata = {'vip': vip['id']}
self.metadata_set({'vip': vip['id']})
def _show_resource(self):
return self.neutron().show_pool(self.resource_id)['pool']
@ -361,7 +361,7 @@ class Pool(neutron.NeutronResource):
return False
elif attributes['status'] == 'ACTIVE':
vip_attributes = self.neutron().show_vip(
self.metadata['vip'])['vip']
self.metadata_get()['vip'])['vip']
if vip_attributes['status'] == 'PENDING_CREATE':
return False
elif vip_attributes['status'] == 'ACTIVE':
@ -395,7 +395,7 @@ class Pool(neutron.NeutronResource):
def _resolve_attribute(self, name):
if name == 'vip':
return self.neutron().show_vip(self.metadata['vip'])['vip']
return self.neutron().show_vip(self.metadata_get()['vip'])['vip']
return super(Pool, self)._resolve_attribute(name)
def _confirm_vip_delete(self):
@ -403,16 +403,16 @@ class Pool(neutron.NeutronResource):
while True:
try:
yield
client.show_vip(self.metadata['vip'])
client.show_vip(self.metadata_get()['vip'])
except NeutronClientException as ex:
self._handle_not_found_exception(ex)
break
def handle_delete(self):
checkers = []
if self.metadata:
if self.metadata_get():
try:
self.neutron().delete_vip(self.metadata['vip'])
self.neutron().delete_vip(self.metadata_get()['vip'])
except NeutronClientException as ex:
self._handle_not_found_exception(ex)
else:

View File

@ -236,7 +236,7 @@ echo -e '%s\tALL=(ALL)\tNOPASSWD: ALL' >> /etc/sudoers
attachments.append((read_cloudinit_file('loguserdata.py'),
'loguserdata.py', 'x-shellscript'))
metadata = resource.metadata
metadata = resource.metadata_get()
if metadata:
attachments.append((json.dumps(metadata),
'cfn-init-data', 'x-cfninitdata'))

View File

@ -427,17 +427,15 @@ class Server(stack_user.StackUser):
else:
self.data_set('password', password, True)
@property
def metadata(self):
def metadata_get(self):
if self.user_data_software_config():
return self._build_deployments_metadata()
else:
return self._metadata
return super(Server, self).metadata_get()
@metadata.setter
def metadata(self, metadata):
def metadata_set(self, metadata):
if not self.user_data_software_config():
self._metadata = metadata
super(Server, self).metadata_set(metadata)
def user_data_raw(self):
return self.properties.get(self.USER_DATA_FORMAT) == self.RAW
@ -713,7 +711,7 @@ class Server(stack_user.StackUser):
def handle_update(self, json_snippet, tmpl_diff, prop_diff):
if 'Metadata' in tmpl_diff:
self.metadata = tmpl_diff['Metadata']
self.metadata_set(tmpl_diff['Metadata'])
checkers = []
server = None
@ -846,7 +844,7 @@ class Server(stack_user.StackUser):
Refresh the metadata if new_metadata is None
'''
if new_metadata is None:
self.metadata = self.parsed_template('Metadata')
self.metadata_set(self.parsed_template('Metadata'))
def validate(self):
'''

View File

@ -72,17 +72,15 @@ class WaitConditionHandle(signal_responder.SignalResponder):
return
if self._metadata_format_ok(new_metadata):
rsrc_metadata = self.metadata
rsrc_metadata = self.metadata_get()
if new_metadata['UniqueId'] in rsrc_metadata:
logger.warning(_("Overwriting Metadata item for UniqueId %s!")
% new_metadata['UniqueId'])
safe_metadata = {}
for k in ('Data', 'Reason', 'Status'):
safe_metadata[k] = new_metadata[k]
# Note we can't update self.metadata directly, as it
# is a Metadata descriptor object which only supports get/set
rsrc_metadata.update({new_metadata['UniqueId']: safe_metadata})
self.metadata = rsrc_metadata
self.metadata_set(rsrc_metadata)
else:
logger.error(_("Metadata failed validation for %s") % self.name)
raise ValueError(_("Metadata format invalid"))
@ -91,14 +89,14 @@ class WaitConditionHandle(signal_responder.SignalResponder):
'''
Return a list of the Status values for the handle signals
'''
return [v['Status'] for v in self.metadata.values()]
return [v['Status'] for v in self.metadata_get().values()]
def get_status_reason(self, status):
'''
Return a list of reasons associated with a particular status
'''
return [v['Reason']
for v in self.metadata.values()
for v in self.metadata_get().values()
if v['Status'] == status]
@ -269,14 +267,14 @@ class WaitCondition(resource.Resource):
return
handle = self.stack[self.resource_id]
handle.metadata = {}
handle.metadata_set({})
def _resolve_attribute(self, key):
res = {}
handle_res_name = self._get_handle_resource_name()
handle = self.stack[handle_res_name]
if key == 'Data':
meta = handle.metadata
meta = handle.metadata_get()
# Note, can't use a dict generator on python 2.6, hence:
res = dict([(k, meta[k]['Data']) for k in meta])
logger.debug(_('%(name)s.GetAtt(%(key)s) == %(res)s') %

View File

@ -1024,7 +1024,7 @@ class EngineService(service.Service):
if res.name != resource_name and res.id is not None:
res.metadata_update()
return resource.metadata
return resource.metadata_get()
@request_context
def create_watch_data(self, cnxt, watch_name, stats_data):

View File

@ -25,7 +25,6 @@ from heat.common import template_format
from heat.engine.notification import autoscaling as notification
from heat.engine import parser
from heat.engine import resource
from heat.engine.resource import Metadata
from heat.engine.resources import autoscaling as asc
from heat.engine.resources import image
from heat.engine.resources import instance
@ -244,12 +243,12 @@ class AutoScalingTest(HeatTestCase):
# Then set a stub to ensure the metadata update is as
# expected based on the timestamp and data
self.m.StubOutWithMock(Metadata, '__set__')
self.m.StubOutWithMock(resource.Resource, 'metadata_set')
expected = {timeutils.strtime(now): data}
# Note for ScalingPolicy, we expect to get a metadata
# update for the policy and autoscaling group, so pass nmeta=2
for x in range(nmeta):
Metadata.__set__(mox.IgnoreArg(), expected).AndReturn(None)
resource.Resource.metadata_set(expected).AndReturn(None)
def test_scaling_delete_empty(self):
t = template_format.parse(as_template)
@ -1031,7 +1030,7 @@ class AutoScalingTest(HeatTestCase):
# Now move time on 10 seconds - Cooldown in template is 60
# so this should not update the policy metadata, and the
# scaling group instances should be unchanged
# Note we have to stub Metadata.__get__ since up_policy isn't
# Note we have to stub Resource.metadata_get since up_policy isn't
# stored in the DB (because the stack hasn't really been created)
previous_meta = {timeutils.strtime(now):
'PercentChangeInCapacity : -50'}
@ -1043,9 +1042,8 @@ class AutoScalingTest(HeatTestCase):
self.m.StubOutWithMock(timeutils, 'utcnow')
timeutils.utcnow().MultipleTimes().AndReturn(now)
self.m.StubOutWithMock(Metadata, '__get__')
Metadata.__get__(mox.IgnoreArg(), rsrc, mox.IgnoreArg()
).AndReturn(previous_meta)
self.m.StubOutWithMock(resource.Resource, 'metadata_get')
rsrc.metadata_get().AndReturn(previous_meta)
self.m.ReplayAll()
@ -1091,13 +1089,12 @@ class AutoScalingTest(HeatTestCase):
now = now + datetime.timedelta(seconds=61)
self.m.StubOutWithMock(Metadata, '__get__')
Metadata.__get__(mox.IgnoreArg(), rsrc, mox.IgnoreArg()
).AndReturn(previous_meta)
self.m.StubOutWithMock(resource.Resource, 'metadata_get')
rsrc.metadata_get().AndReturn(previous_meta)
#stub for the metadata accesses while creating the two instances
Metadata.__get__(mox.IgnoreArg(), mox.IgnoreArg(), mox.IgnoreArg())
Metadata.__get__(mox.IgnoreArg(), mox.IgnoreArg(), mox.IgnoreArg())
resource.Resource.metadata_get()
resource.Resource.metadata_get()
# raise by 200%, should work
self._stub_lb_reload(3, unset=False)
@ -1141,13 +1138,12 @@ class AutoScalingTest(HeatTestCase):
self.m.VerifyAll()
self.m.UnsetStubs()
self.m.StubOutWithMock(Metadata, '__get__')
Metadata.__get__(mox.IgnoreArg(), rsrc, mox.IgnoreArg()
).AndReturn(previous_meta)
self.m.StubOutWithMock(resource.Resource, 'metadata_get')
rsrc.metadata_get().AndReturn(previous_meta)
#stub for the metadata accesses while creating the two instances
Metadata.__get__(mox.IgnoreArg(), mox.IgnoreArg(), mox.IgnoreArg())
Metadata.__get__(mox.IgnoreArg(), mox.IgnoreArg(), mox.IgnoreArg())
resource.Resource.metadata_get()
resource.Resource.metadata_get()
# raise by 200%, should work
self._stub_lb_reload(3, unset=False)
@ -1266,7 +1262,7 @@ class AutoScalingTest(HeatTestCase):
self.m.ReplayAll()
expected_meta = {'IPs': u'127.0.0.1,127.0.0.1'}
self.assertEqual(expected_meta, stack['MyCustomLB'].metadata)
self.assertEqual(expected_meta, stack['MyCustomLB'].metadata_get())
rsrc.delete()
self.m.VerifyAll()
@ -1337,7 +1333,7 @@ class AutoScalingTest(HeatTestCase):
# Now move time on 10 seconds - Cooldown in template is 60
# so this should not update the policy metadata, and the
# scaling group instances should be unchanged
# Note we have to stub Metadata.__get__ since up_policy isn't
# Note we have to stub Resource.metadata_get since up_policy isn't
# stored in the DB (because the stack hasn't really been created)
previous_meta = {timeutils.strtime(now): 'ChangeInCapacity : 1'}
@ -1348,9 +1344,8 @@ class AutoScalingTest(HeatTestCase):
self.m.StubOutWithMock(timeutils, 'utcnow')
timeutils.utcnow().MultipleTimes().AndReturn(now)
self.m.StubOutWithMock(Metadata, '__get__')
Metadata.__get__(mox.IgnoreArg(), up_policy, mox.IgnoreArg()
).AndReturn(previous_meta)
self.m.StubOutWithMock(resource.Resource, 'metadata_get')
up_policy.metadata_get().AndReturn(previous_meta)
self.m.ReplayAll()
up_policy.signal()
@ -1394,14 +1389,12 @@ class AutoScalingTest(HeatTestCase):
self.m.VerifyAll()
self.m.UnsetStubs()
self.m.StubOutWithMock(Metadata, '__get__')
Metadata.__get__(mox.IgnoreArg(), up_policy, mox.IgnoreArg()
).AndReturn(previous_meta)
Metadata.__get__(mox.IgnoreArg(), rsrc, mox.IgnoreArg()
).AndReturn(previous_meta)
self.m.StubOutWithMock(resource.Resource, 'metadata_get')
up_policy.metadata_get().AndReturn(previous_meta)
rsrc.metadata_get().AndReturn(previous_meta)
#stub for the metadata accesses while creating the additional instance
Metadata.__get__(mox.IgnoreArg(), mox.IgnoreArg(), mox.IgnoreArg())
resource.Resource.metadata_get()
now = now + datetime.timedelta(seconds=61)
self._stub_lb_reload(3, unset=False)
@ -1453,14 +1446,12 @@ class AutoScalingTest(HeatTestCase):
self.m.VerifyAll()
self.m.UnsetStubs()
self.m.StubOutWithMock(Metadata, '__get__')
Metadata.__get__(mox.IgnoreArg(), up_policy, mox.IgnoreArg()
).AndReturn(previous_meta)
Metadata.__get__(mox.IgnoreArg(), rsrc, mox.IgnoreArg()
).AndReturn(previous_meta)
self.m.StubOutWithMock(resource.Resource, 'metadata_get')
up_policy.metadata_get().AndReturn(previous_meta)
rsrc.metadata_get().AndReturn(previous_meta)
#stub for the metadata accesses while creating the additional instance
Metadata.__get__(mox.IgnoreArg(), mox.IgnoreArg(), mox.IgnoreArg())
resource.Resource.metadata_get()
self._stub_lb_reload(3, unset=False)
self._stub_meta_expected(now, 'ChangeInCapacity : 1', 2)
@ -1513,14 +1504,12 @@ class AutoScalingTest(HeatTestCase):
self.m.VerifyAll()
self.m.UnsetStubs()
self.m.StubOutWithMock(Metadata, '__get__')
Metadata.__get__(mox.IgnoreArg(), up_policy, mox.IgnoreArg()
).AndReturn(previous_meta)
Metadata.__get__(mox.IgnoreArg(), rsrc, mox.IgnoreArg()
).AndReturn(previous_meta)
self.m.StubOutWithMock(resource.Resource, 'metadata_get')
up_policy.metadata_get().AndReturn(previous_meta)
rsrc.metadata_get().AndReturn(previous_meta)
#stub for the metadata accesses while creating the additional instance
Metadata.__get__(mox.IgnoreArg(), mox.IgnoreArg(), mox.IgnoreArg())
resource.Resource.metadata_get()
self._stub_lb_reload(3, unset=False)
self._stub_meta_expected(now, 'ChangeInCapacity : 1', 2)
@ -1578,16 +1567,13 @@ class AutoScalingTest(HeatTestCase):
self.m.VerifyAll()
self.m.UnsetStubs()
self.m.StubOutWithMock(Metadata, '__get__')
Metadata.__get__(mox.IgnoreArg(), up_policy, mox.IgnoreArg()
).AndReturn(previous_meta)
Metadata.__get__(mox.IgnoreArg(), rsrc, mox.IgnoreArg()
).AndReturn(previous_meta)
self.m.StubOutWithMock(resource.Resource, 'metadata_get')
up_policy.metadata_get().AndReturn(previous_meta)
rsrc.metadata_get().AndReturn(previous_meta)
#stub for the metadata accesses while creating the two instances
Metadata.__get__(mox.IgnoreArg(), mox.IgnoreArg(), mox.IgnoreArg())
Metadata.__get__(mox.IgnoreArg(), mox.IgnoreArg(), mox.IgnoreArg())
resource.Resource.metadata_get()
resource.Resource.metadata_get()
now = now + datetime.timedelta(seconds=61)

View File

@ -2221,7 +2221,7 @@ class StackServiceTest(HeatTestCase):
@stack_context('service_metadata_test_stack')
def test_metadata(self):
test_metadata = {'foo': 'bar', 'baz': 'quux', 'blarg': 'wibble'}
pre_update_meta = self.stack['WebServer'].metadata
pre_update_meta = self.stack['WebServer'].metadata_get()
self.m.StubOutWithMock(service.EngineService, '_get_stack')
s = db_api.stack_get(self.ctx, self.stack.id)

View File

@ -368,7 +368,7 @@ class ScalingPolicyTest(HeatTestCase):
past = timeutils.strtime(timeutils.utcnow() -
datetime.timedelta(seconds=65))
policy.metadata = {past: 'ChangeInCapacity : 1'}
policy.metadata_set({past: 'ChangeInCapacity : 1'})
policy.signal()
self.assertEqual(3, len(group.get_instance_names()))

View File

@ -71,6 +71,16 @@ resources:
''')
class DummyClass(object):
metadata = None
def metadata_get(self):
return self.metadata
def metadata_set(self, metadata):
self.metadata = metadata
class HOTemplateTest(HeatTestCase):
"""Test processing of HOT templates."""
@ -545,10 +555,8 @@ class HOTemplateTest(HeatTestCase):
deletion_policy_snippet = {'resource_facade': 'deletion_policy'}
update_policy_snippet = {'resource_facade': 'update_policy'}
class DummyClass(object):
pass
parent_resource = DummyClass()
parent_resource.metadata = {"foo": "bar"}
parent_resource.metadata_set({"foo": "bar"})
parent_resource.t = {'DeletionPolicy': 'Retain',
'UpdatePolicy': {"blarg": "wibble"}}
parent_resource.stack = parser.Stack(utils.dummy_context(),
@ -567,10 +575,8 @@ class HOTemplateTest(HeatTestCase):
def test_resource_facade_function(self):
deletion_policy_snippet = {'resource_facade': 'deletion_policy'}
class DummyClass(object):
pass
parent_resource = DummyClass()
parent_resource.metadata = {"foo": "bar"}
parent_resource.metadata_set({"foo": "bar"})
parent_resource.stack = parser.Stack(utils.dummy_context(),
'toplevel_stack',
parser.Template({}))
@ -599,10 +605,8 @@ class HOTemplateTest(HeatTestCase):
def test_resource_facade_missing_deletion_policy(self):
snippet = {'resource_facade': 'deletion_policy'}
class DummyClass(object):
pass
parent_resource = DummyClass()
parent_resource.metadata = {"foo": "bar"}
parent_resource.metadata_set({"foo": "bar"})
parent_resource.t = {}
parent_resource.stack = parser.Stack(utils.dummy_context(),
'toplevel_stack',
@ -733,7 +737,8 @@ class StackTest(test_parser.StackTest):
(parser.Stack.UPDATE, parser.Stack.COMPLETE))
self.assertEqual(self.stack['AResource'].properties['Foo'], 'xyz')
self.assertEqual(self.stack['AResource'].metadata['Bar'], stack_id)
self.assertEqual(
self.stack['AResource'].metadata_get()['Bar'], stack_id)
def test_load_param_id(self):
tmpl = parser.Template(hot_tpl_empty)

View File

@ -340,7 +340,7 @@ class InstancesTest(HeatTestCase):
update_template = copy.deepcopy(instance.t)
update_template['Metadata'] = {'test': 123}
scheduler.TaskRunner(instance.update, update_template)()
self.assertEqual({'test': 123}, instance.metadata)
self.assertEqual({'test': 123}, instance.metadata_get())
def test_instance_update_instance_type(self):
"""

View File

@ -21,7 +21,7 @@ from oslo.config import cfg
from heat.common import exception
from heat.common import template_format
from heat.engine import clients
from heat.engine.resource import Metadata
from heat.engine import resource
from heat.engine.resources import instance
from heat.engine.resources import loadbalancer as lb
from heat.engine.resources import wait_condition as wc
@ -106,7 +106,7 @@ class LoadBalancerTest(HeatTestCase):
self.fc = fakes.FakeClient()
self.m.StubOutWithMock(clients.OpenStackClients, 'nova')
self.m.StubOutWithMock(self.fc.servers, 'create')
self.m.StubOutWithMock(Metadata, '__set__')
self.m.StubOutWithMock(resource.Resource, 'metadata_set')
self.fkc = test_fakes.FakeKeystoneClient(
username='test_stack.CfnLBUser')
@ -141,8 +141,7 @@ class LoadBalancerTest(HeatTestCase):
security_groups=None, availability_zone=None).AndReturn(
self.fc.servers.list()[1])
if stub_meta:
Metadata.__set__(mox.IgnoreArg(),
mox.IgnoreArg()).AndReturn(None)
resource.Resource.metadata_set(mox.IgnoreArg()).AndReturn(None)
self.m.StubOutWithMock(wc.WaitConditionHandle, 'get_status')
wc.WaitConditionHandle.get_status().AndReturn(['SUCCESS'])

View File

@ -179,14 +179,16 @@ class MetadataRefreshTest(HeatTestCase):
s1 = self.stack['S1']
s2 = self.stack['S2']
files = s1.metadata['AWS::CloudFormation::Init']['config']['files']
files = s1.metadata_get()[
'AWS::CloudFormation::Init']['config']['files']
cont = files['/tmp/random_file']['content']
self.assertEqual((s2.CREATE, s2.COMPLETE), s2.state)
self.assertEqual('s2-ip=1.2.3.5', cont)
s1.metadata_update()
s2.metadata_update()
files = s1.metadata['AWS::CloudFormation::Init']['config']['files']
files = s1.metadata_get()[
'AWS::CloudFormation::Init']['config']['files']
cont = files['/tmp/random_file']['content']
self.assertEqual('s2-ip=10.0.0.5', cont)
@ -259,7 +261,7 @@ class WaitCondMetadataUpdateTest(HeatTestCase):
def check_empty(sleep_time):
self.assertEqual('{}', watch.FnGetAtt('Data'))
self.assertIsNone(inst.metadata['test'])
self.assertIsNone(inst.metadata_get()['test'])
def update_metadata(id, data, reason):
self.man.metadata_update(utils.dummy_context(),
@ -283,12 +285,12 @@ class WaitCondMetadataUpdateTest(HeatTestCase):
self.stack.state)
self.assertEqual('{"123": "foo"}', watch.FnGetAtt('Data'))
self.assertEqual('{"123": "foo"}', inst.metadata['test'])
self.assertEqual('{"123": "foo"}', inst.metadata_get()['test'])
update_metadata('456', 'blarg', 'wibble')
self.assertEqual('{"123": "foo", "456": "blarg"}',
watch.FnGetAtt('Data'))
self.assertEqual('{"123": "foo", "456": "blarg"}',
inst.metadata['test'])
inst.metadata_get()['test'])
self.m.VerifyAll()

View File

@ -121,7 +121,7 @@ Resources:
self.assertIsNone(rsrc.validate())
self.assertEqual((rsrc.CREATE, rsrc.COMPLETE), rsrc.state)
self.assertEqual(ref_id, rsrc.FnGetRefId())
self.assertEqual(metadata, dict(rsrc.metadata))
self.assertEqual(metadata, dict(rsrc.metadata_get()))
def test_security_group(self):

View File

@ -167,7 +167,7 @@ class NovaUtilsUserdataTests(HeatTestCase):
def test_build_userdata(self):
"""Tests the build_userdata function."""
resource = self.m.CreateMockAnything()
resource.metadata = {}
resource.metadata_get().AndReturn({})
self.m.StubOutWithMock(nova_utils.cfg, 'CONF')
cnf = nova_utils.cfg.CONF
cnf.heat_metadata_server_url = 'http://server.test:123'
@ -189,7 +189,7 @@ class NovaUtilsUserdataTests(HeatTestCase):
def test_build_userdata_without_instance_user(self):
"""Don't add a custom instance user when not requested."""
resource = self.m.CreateMockAnything()
resource.metadata = {}
resource.metadata_get().AndReturn({})
self.m.StubOutWithMock(nova_utils.cfg, 'CONF')
cnf = nova_utils.cfg.CONF
cnf.instance_user = 'config_instance_user'
@ -205,7 +205,7 @@ class NovaUtilsUserdataTests(HeatTestCase):
def test_build_userdata_with_instance_user(self):
"""Add the custom instance user when requested."""
resource = self.m.CreateMockAnything()
resource.metadata = {}
resource.metadata_get().AndReturn(None)
self.m.StubOutWithMock(nova_utils.cfg, 'CONF')
cnf = nova_utils.cfg.CONF
cnf.instance_user = 'config_instance_user'

View File

@ -145,6 +145,16 @@ resource_template = template_format.parse('''{
}''')
class DummyClass(object):
metadata = None
def metadata_get(self):
return self.metadata
def metadata_set(self, metadata):
self.metadata = metadata
class TemplateTest(HeatTestCase):
def setUp(self):
@ -529,10 +539,8 @@ Mappings:
deletion_policy_snippet = {'Fn::ResourceFacade': 'DeletionPolicy'}
update_policy_snippet = {'Fn::ResourceFacade': 'UpdatePolicy'}
class DummyClass(object):
pass
parent_resource = DummyClass()
parent_resource.metadata = {"foo": "bar"}
parent_resource.metadata_set({"foo": "bar"})
parent_resource.t = {'DeletionPolicy': 'Retain',
'UpdatePolicy': {"blarg": "wibble"}}
parent_resource.stack = parser.Stack(self.ctx, 'toplevel_stack',
@ -550,10 +558,8 @@ Mappings:
def test_resource_facade_function(self):
deletion_policy_snippet = {'Fn::ResourceFacade': 'DeletionPolicy'}
class DummyClass(object):
pass
parent_resource = DummyClass()
parent_resource.metadata = {"foo": "bar"}
parent_resource.metadata_set({"foo": "bar"})
parent_resource.stack = parser.Stack(self.ctx, 'toplevel_stack',
parser.Template({}))
parent_snippet = {'DeletionPolicy': {'Fn::Join': ['eta',
@ -580,10 +586,8 @@ Mappings:
def test_resource_facade_missing_deletion_policy(self):
snippet = {'Fn::ResourceFacade': 'DeletionPolicy'}
class DummyClass(object):
pass
parent_resource = DummyClass()
parent_resource.metadata = {"foo": "bar"}
parent_resource.metadata_set({"foo": "bar"})
parent_resource.t = {}
parent_resource.stack = parser.Stack(self.ctx, 'toplevel_stack',
parser.Template({}))
@ -1107,7 +1111,8 @@ class StackTest(HeatTestCase):
self.stack.state)
self.assertEqual('xyz', self.stack['AResource'].properties['Foo'])
self.assertEqual(stack_arn, self.stack['AResource'].metadata['Bar'])
self.assertEqual(
stack_arn, self.stack['AResource'].metadata_get()['Bar'])
def test_load_param_id(self):
self.stack = parser.Stack(self.ctx, 'param_load_arn_test',

View File

@ -288,7 +288,7 @@ class ResourceTest(HeatTestCase):
def test_metadata_default(self):
tmpl = {'Type': 'Foo'}
res = generic_rsrc.GenericResource('test_resource', tmpl, self.stack)
self.assertEqual({}, res.metadata)
self.assertEqual({}, res.metadata_get())
def test_equals_different_stacks(self):
tmpl1 = {'Type': 'Foo'}
@ -767,7 +767,7 @@ class ResourceAdoptTest(HeatTestCase):
}
adopt = scheduler.TaskRunner(res.adopt, res_data)
adopt()
self.assertEqual({}, res.metadata)
self.assertEqual({}, res.metadata_get())
self.assertEqual((res.ADOPT, res.COMPLETE), res.state)
def test_adopt_with_resource_data_and_metadata(self):
@ -795,7 +795,7 @@ class ResourceAdoptTest(HeatTestCase):
adopt()
self.assertEqual("test-value",
db_api.resource_data_get(res, "test-key"))
self.assertEqual({"os_distro": "test-distro"}, res.metadata)
self.assertEqual({"os_distro": "test-distro"}, res.metadata_get())
self.assertEqual((res.ADOPT, res.COMPLETE), res.state)
def test_adopt_resource_missing(self):
@ -1300,12 +1300,12 @@ class MetadataTest(HeatTestCase):
self.addCleanup(self.stack.delete)
def test_read_initial(self):
self.assertEqual({'Test': 'Initial metadata'}, self.res.metadata)
self.assertEqual({'Test': 'Initial metadata'}, self.res.metadata_get())
def test_write(self):
test_data = {'Test': 'Newly-written data'}
self.res.metadata = test_data
self.assertEqual(test_data, self.res.metadata)
self.res.metadata_set(test_data)
self.assertEqual(test_data, self.res.metadata_get())
class ReducePhysicalResourceNameTest(HeatTestCase):

View File

@ -162,7 +162,7 @@ Resources:
self.assertIsNone(rsrc.validate())
self.assertEqual((rsrc.CREATE, rsrc.COMPLETE), rsrc.state)
self.assertEqual(ref_id, rsrc.FnGetRefId())
self.assertEqual(metadata, dict(rsrc.metadata))
self.assertEqual(metadata, dict(rsrc.metadata_get()))
def test_security_group_nova(self):
#create script

View File

@ -553,7 +553,7 @@ class ServersTest(HeatTestCase):
}
},
'deployments': {'foo': 'bar'}
}, server.metadata)
}, server.metadata_get())
created_server = servers.Server('WebServer',
t['Resources']['WebServer'], stack)
@ -623,7 +623,7 @@ class ServersTest(HeatTestCase):
}
},
'deployments': {'foo': 'bar'}
}, server.metadata)
}, server.metadata_get())
created_server = servers.Server('WebServer',
t['Resources']['WebServer'], stack)
@ -641,7 +641,7 @@ class ServersTest(HeatTestCase):
t['Resources']['WebServer'], stack)
self.m.StubOutWithMock(server, 'keystone')
self.m.ReplayAll()
deployments = server.metadata['deployments']
deployments = server.metadata_get()['deployments']
self.assertEqual([], deployments)
self.m.VerifyAll()
@ -947,11 +947,11 @@ class ServersTest(HeatTestCase):
update_template = copy.deepcopy(server.t)
update_template['Metadata'] = {'test': 123}
scheduler.TaskRunner(server.update, update_template)()
self.assertEqual({'test': 123}, server.metadata)
self.assertEqual({'test': 123}, server.metadata_get())
server.t['Metadata'] = {'test': 456}
server.metadata_update()
self.assertEqual({'test': 456}, server.metadata)
self.assertEqual({'test': 456}, server.metadata_get())
def test_server_update_nova_metadata(self):
return_server = self.fc.servers.list()[1]

View File

@ -293,4 +293,4 @@ class swiftTest(HeatTestCase):
scheduler.TaskRunner(rsrc.delete)()
self.m.VerifyAll()
self.assertEqual({}, rsrc.metadata)
self.assertEqual({}, rsrc.metadata_get())

View File

@ -455,7 +455,7 @@ class WaitConditionHandleTest(HeatTestCase):
handle_metadata = {u'123': {u'Data': u'foo',
u'Reason': u'bar',
u'Status': u'SUCCESS'}}
self.assertEqual(handle_metadata, rsrc.metadata)
self.assertEqual(handle_metadata, rsrc.metadata_get())
self.m.VerifyAll()
def test_metadata_update_invalid(self):