Use StackDefinition in intrinsic functions for resolving data

This unifies the 'lightweight stack' used in convergence with the how
things work the rest of the time: we now always obtain resource data from
the StackDefinition's ResourceProxy objects. This means that when we are
checking an individual resource, we will never create all of the other
Resource objects for the stack in memory (although we already avoided
loading data for them from the database) - now we will only create
ResourceProxy objects as needed.

Change-Id: Id7472557e26d172df88841ff7f20afdd7f5bfada
Implements: blueprint stack-definition
This commit is contained in:
Zane Bitter 2017-07-19 17:35:40 -04:00
parent c889f08ab5
commit 764b8fb251
39 changed files with 221 additions and 375 deletions

View File

@ -45,7 +45,8 @@ class Function(object):
return None return None
stack = ref() stack = ref()
assert stack is not None, "Need a reference to the Stack object" assert stack is not None, ("Need a reference to the "
"StackDefinition object")
return stack return stack
def validate(self): def validate(self):

View File

@ -222,9 +222,7 @@ class GetAttThenSelect(function.Function):
return return
attr = function.resolve(self._attribute) attr = function.resolve(self._attribute)
from heat.engine import resource if attr not in res.attributes_schema:
if (type(res).get_attribute == resource.Resource.get_attribute and
attr not in res.attributes_schema):
raise exception.InvalidTemplateAttribute( raise exception.InvalidTemplateAttribute(
resource=self._resource_name, key=attr) resource=self._resource_name, key=attr)

View File

@ -340,8 +340,7 @@ class Resource(status.ResourceStatus):
# Load only the resource in question; don't load all resources # Load only the resource in question; don't load all resources
# by invoking stack.resources. Maintain light-weight stack. # by invoking stack.resources. Maintain light-weight stack.
res_defn = resource_owning_stack.t.resource_definitions( res_defn = resource_owning_stack.defn.resource_definition(db_res.name)
resource_owning_stack)[db_res.name]
resource = cls(db_res.name, res_defn, resource_owning_stack) resource = cls(db_res.name, res_defn, resource_owning_stack)
resource._load_data(db_res) resource._load_data(db_res)
@ -1343,8 +1342,7 @@ class Resource(status.ResourceStatus):
self._calling_engine_id = engine_id self._calling_engine_id = engine_id
registry = new_stack.env.registry registry = new_stack.env.registry
new_res_def = new_stack.t.resource_definitions( new_res_def = new_stack.defn.resource_definition(self.name)
new_stack)[self.name]
new_res_type = registry.get_class_to_instantiate( new_res_type = registry.get_class_to_instantiate(
new_res_def.resource_type, resource_name=self.name) new_res_def.resource_type, resource_name=self.name)
restricted_actions = registry.get_rsrc_restricted_actions( restricted_actions = registry.get_rsrc_restricted_actions(

View File

@ -309,7 +309,7 @@ class InstanceGroup(stack_resource.StackResource):
def changing_instances(tmpl): def changing_instances(tmpl):
instances = grouputils.get_members(self) instances = grouputils.get_members(self)
current = set((i.name, i.t) for i in instances) current = set((i.name, i.t) for i in instances)
updated = set(tmpl.resource_definitions(self.nested()).items()) updated = set(tmpl.resource_definitions(None).items())
# includes instances to be updated and deleted # includes instances to be updated and deleted
affected = set(k for k, v in current ^ updated) affected = set(k for k, v in current ^ updated)
return set(i.FnGetRefId() for i in instances if i.name in affected) return set(i.FnGetRefId() for i in instances if i.name in affected)

View File

@ -283,8 +283,7 @@ class ResourceGroup(stack_resource.StackResource):
first_name = next(self._resource_names(update_rsrc_data=False)) first_name = next(self._resource_names(update_rsrc_data=False))
test_tmpl = self._assemble_nested([first_name], test_tmpl = self._assemble_nested([first_name],
include_all=True) include_all=True)
res_def = next(six.itervalues( res_def = next(six.itervalues(test_tmpl.resource_definitions(None)))
test_tmpl.resource_definitions(self.stack)))
# make sure we can resolve the nested resource type # make sure we can resolve the nested resource type
self.stack.env.get_class_to_instantiate(res_def.resource_type) self.stack.env.get_class_to_instantiate(res_def.resource_type)

View File

@ -298,18 +298,18 @@ class Stack(collections.Mapping):
@property @property
def outputs(self): def outputs(self):
if self._outputs is None: return {n: self.defn.output_definition(n)
self._outputs = self.t.outputs(self) for n in self.defn.enabled_output_names()}
return self._outputs
@property @property
def resources(self): def resources(self):
if self._resources is None: if self._resources is None:
res_defns = self.t.resource_definitions(self) self._resources = {
name: resource.Resource(name,
self._resources = dict((name, self.defn.resource_definition(name),
resource.Resource(name, data, self)) self)
for (name, data) in res_defns.items()) for name in self.defn.enabled_rsrc_names()
}
return self._resources return self._resources
@ -320,7 +320,6 @@ class Stack(collections.Mapping):
stk_defn.update_resource_data(self.defn, rsrc.name, node_data) stk_defn.update_resource_data(self.defn, rsrc.name, node_data)
def _find_filtered_resources(self, filters=None): def _find_filtered_resources(self, filters=None):
rsrc_def_cache = {self.t.id: self.t.resource_definitions(self)}
if filters: if filters:
assert self.cache_data is None, \ assert self.cache_data is None, \
"Resources should not be loaded from the DB" "Resources should not be loaded from the DB"
@ -328,8 +327,10 @@ class Stack(collections.Mapping):
self.context, self.id, filters) self.context, self.id, filters)
else: else:
resources = self._db_resources_get() resources = self._db_resources_get()
stk_def_cache = {}
for rsc in six.itervalues(resources): for rsc in six.itervalues(resources):
loaded_res = self._resource_from_db_resource(rsc, rsrc_def_cache) loaded_res = self._resource_from_db_resource(rsc, stk_def_cache)
if loaded_res is not None: if loaded_res is not None:
yield loaded_res yield loaded_res
@ -374,7 +375,7 @@ class Stack(collections.Mapping):
self._db_resources = _db_resources self._db_resources = _db_resources
return self._db_resources return self._db_resources
def _resource_from_db_resource(self, db_res, rsrc_def_cache=None): def _resource_from_db_resource(self, db_res, stk_def_cache=None):
tid = db_res.current_template_id tid = db_res.current_template_id
if tid is None: if tid is None:
tid = self.t.id tid = self.t.id
@ -384,19 +385,19 @@ class Stack(collections.Mapping):
if cur_res is not None and (cur_res.id == db_res.id): if cur_res is not None and (cur_res.id == db_res.id):
return cur_res return cur_res
if rsrc_def_cache and tid in rsrc_def_cache: stk_def = self.defn
rsrc_def = rsrc_def_cache[tid] elif stk_def_cache and tid in stk_def_cache:
stk_def = stk_def_cache[tid]
else: else:
if tid == self.t.id: t = tmpl.Template.load(self.context, tid)
rsrc_def = self.t.resource_definitions(self) stk_def = self.defn.clone_with_new_template(t,
else: self.identifier())
t = tmpl.Template.load(self.context, tid) if stk_def_cache is not None:
rsrc_def = t.resource_definitions(self) stk_def_cache[tid] = stk_def
if rsrc_def_cache:
rsrc_def_cache[tid] = rsrc_def
defn = rsrc_def.get(db_res.name)
if defn is None: try:
defn = stk_def.resource_definition(db_res.name)
except KeyError:
return None return None
return resource.Resource(db_res.name, defn, self) return resource.Resource(db_res.name, defn, self)
@ -724,7 +725,7 @@ class Stack(collections.Mapping):
"""Insert the given resource into the stack.""" """Insert the given resource into the stack."""
template = resource.stack.t template = resource.stack.t
resource.stack = self resource.stack = self
definition = resource.t.reparse(self, template) definition = resource.t.reparse(self.defn, template)
resource.t = definition resource.t = definition
resource.reparse() resource.reparse()
self.resources[resource.name] = resource self.resources[resource.name] = resource
@ -769,16 +770,23 @@ class Stack(collections.Mapping):
not found. not found.
""" """
for r in six.itervalues(self): for r in six.itervalues(self):
if (r.state in ( if r.state not in ((r.INIT, r.COMPLETE),
(r.INIT, r.COMPLETE), (r.CREATE, r.IN_PROGRESS),
(r.CREATE, r.IN_PROGRESS), (r.CREATE, r.COMPLETE),
(r.CREATE, r.COMPLETE), (r.RESUME, r.IN_PROGRESS),
(r.RESUME, r.IN_PROGRESS), (r.RESUME, r.COMPLETE),
(r.RESUME, r.COMPLETE), (r.UPDATE, r.IN_PROGRESS),
(r.UPDATE, r.IN_PROGRESS), (r.UPDATE, r.COMPLETE),
(r.UPDATE, r.COMPLETE), (r.CHECK, r.COMPLETE)):
(r.CHECK, r.COMPLETE)) and continue
(r.FnGetRefId() == refid or r.name == refid)):
proxy = self.defn[r.name]
if proxy._resource_data is None:
matches = r.FnGetRefId() == refid or r.name == refid
else:
matches = proxy.FnGetRefId() == refid
if matches:
if self.cache_data is not None and r.id is not None: if self.cache_data is not None and r.id is not None:
# We don't have resources loaded from the database at this # We don't have resources loaded from the database at this
# point, so load the data for just this one from the DB. # point, so load the data for just this one from the DB.
@ -786,7 +794,6 @@ class Stack(collections.Mapping):
r.id) r.id)
if db_res is not None: if db_res is not None:
r._load_data(db_res) r._load_data(db_res)
return r return r
def register_access_allowed_handler(self, credential_id, handler): def register_access_allowed_handler(self, credential_id, handler):
@ -852,6 +859,8 @@ class Stack(collections.Mapping):
raise exception.StackValidationFailed( raise exception.StackValidationFailed(
message=_("Duplicate names %s") % dup_names) message=_("Duplicate names %s") % dup_names)
self._update_all_resource_data(for_resources=True, for_outputs=True)
if self.strict_validate: if self.strict_validate:
iter_rsc = self.dependencies iter_rsc = self.dependencies
else: else:
@ -1252,7 +1261,9 @@ class Stack(collections.Mapping):
self.prev_raw_template_id = getattr(self.t, 'id', None) self.prev_raw_template_id = getattr(self.t, 'id', None)
# switch template and reset dependencies # switch template and reset dependencies
self.t = template self.defn = self.defn.clone_with_new_template(template,
self.identifier(),
clear_resource_data=True)
self.reset_dependencies() self.reset_dependencies()
self._resources = None self._resources = None
self.cache_data = None self.cache_data = None
@ -1937,8 +1948,8 @@ class Stack(collections.Mapping):
timeout_mins=self.timeout_mins, timeout_mins=self.timeout_mins,
disable_rollback=self.disable_rollback) disable_rollback=self.disable_rollback)
for name, defn in six.iteritems( for name in newstack.defn.enabled_rsrc_names():
template.resource_definitions(newstack)): defn = newstack.defn.resource_definition(name)
rsrc = resource.Resource(name, defn, self) rsrc = resource.Resource(name, defn, self)
data = snapshot.data['resources'].get(name) data = snapshot.data['resources'].get(name)
handle_restore = getattr(rsrc, 'handle_restore', None) handle_restore = getattr(rsrc, 'handle_restore', None)

View File

@ -205,7 +205,7 @@ class StackUpdate(object):
# of the existing stack (which is the stack being updated) # of the existing stack (which is the stack being updated)
# but with the template of the new stack (in case the update # but with the template of the new stack (in case the update
# is switching template implementations) # is switching template implementations)
new_snippet = new_res.t.reparse(self.existing_stack, new_snippet = new_res.t.reparse(self.existing_stack.defn,
self.new_stack.t) self.new_stack.t)
if is_substituted: if is_substituted:
substitute = type(new_res)(existing_res.name, substitute = type(new_res)(existing_res.name,

View File

@ -166,7 +166,7 @@ class TestAutoScalingPolicy(common.HeatTestCase):
'reference_id': 'convg_xyz' 'reference_id': 'convg_xyz'
})} })}
stack = utils.parse_stack(t, cache_data=cache_data) stack = utils.parse_stack(t, cache_data=cache_data)
rsrc = stack['my-policy'] rsrc = stack.defn['my-policy']
self.assertEqual('convg_xyz', rsrc.FnGetRefId()) self.assertEqual('convg_xyz', rsrc.FnGetRefId())

View File

@ -70,7 +70,7 @@ class LaunchConfigurationTest(common.HeatTestCase):
})} })}
stack = utils.parse_stack(t, params=inline_templates.as_params, stack = utils.parse_stack(t, params=inline_templates.as_params,
cache_data=cache_data) cache_data=cache_data)
rsrc = stack['LaunchConfig'] rsrc = stack.defn['LaunchConfig']
self.assertEqual('convg_xyz', rsrc.FnGetRefId()) self.assertEqual('convg_xyz', rsrc.FnGetRefId())
def test_launch_config_create_with_instanceid(self): def test_launch_config_create_with_instanceid(self):

View File

@ -166,7 +166,7 @@ class TestAutoScalingPolicy(common.HeatTestCase):
'reference_id': 'http://convg_signed_url' 'reference_id': 'http://convg_signed_url'
})} })}
stack = utils.parse_stack(t, cache_data=cache_data) stack = utils.parse_stack(t, cache_data=cache_data)
rsrc = stack['WebServerScaleUpPolicy'] rsrc = stack.defn['WebServerScaleUpPolicy']
self.assertEqual('http://convg_signed_url', rsrc.FnGetRefId()) self.assertEqual('http://convg_signed_url', rsrc.FnGetRefId())

View File

@ -405,7 +405,7 @@ class EIPTest(common.HeatTestCase):
'status': 'COMPLETE', 'status': 'COMPLETE',
'reference_id': '1.1.1.1'})}) 'reference_id': '1.1.1.1'})})
rsrc = stack['eip'] rsrc = stack.defn['eip']
self.assertEqual('1.1.1.1', rsrc.FnGetRefId()) self.assertEqual('1.1.1.1', rsrc.FnGetRefId())
@ -480,9 +480,8 @@ class AllocTest(common.HeatTestCase):
self.fc.servers.get(server).AndReturn(mock_server) self.fc.servers.get(server).AndReturn(mock_server)
def create_eip(self, t, stack, resource_name): def create_eip(self, t, stack, resource_name):
resource_defns = stack.t.resource_definitions(stack)
rsrc = eip.ElasticIp(resource_name, rsrc = eip.ElasticIp(resource_name,
resource_defns[resource_name], stack.defn.resource_definition(resource_name),
stack) stack)
self.assertIsNone(rsrc.validate()) self.assertIsNone(rsrc.validate())
scheduler.TaskRunner(rsrc.create)() scheduler.TaskRunner(rsrc.create)()
@ -492,9 +491,9 @@ class AllocTest(common.HeatTestCase):
return rsrc return rsrc
def create_association(self, t, stack, resource_name): def create_association(self, t, stack, resource_name):
resource_defns = stack.t.resource_definitions(stack) resource_defn = stack.defn.resource_definition(resource_name)
rsrc = eip.ElasticIpAssociation(resource_name, rsrc = eip.ElasticIpAssociation(resource_name,
resource_defns[resource_name], resource_defn,
stack) stack)
self.assertIsNone(rsrc.validate()) self.assertIsNone(rsrc.validate())
scheduler.TaskRunner(rsrc.create)() scheduler.TaskRunner(rsrc.create)()
@ -530,7 +529,7 @@ class AllocTest(common.HeatTestCase):
}).AndReturn({'floatingip': { }).AndReturn({'floatingip': {
"status": "ACTIVE", "status": "ACTIVE",
"id": "fc68ea2c-b60b-4b4f-bd82-94ec81110766", "id": "fc68ea2c-b60b-4b4f-bd82-94ec81110766",
"floating_ip_address": "192.168.9.3" "floating_ip_address": "11.0.0.1"
}}) }})
def mock_show_floatingip(self, refid): def mock_show_floatingip(self, refid):
@ -766,7 +765,6 @@ class AllocTest(common.HeatTestCase):
mock_again=True) mock_again=True)
self.mock_create_floatingip() self.mock_create_floatingip()
self.mock_show_floatingip('fc68ea2c-b60b-4b4f-bd82-94ec81110766')
self.m.ReplayAll() self.m.ReplayAll()
t = template_format.parse(eip_template_ipassoc) t = template_format.parse(eip_template_ipassoc)
@ -780,7 +778,7 @@ class AllocTest(common.HeatTestCase):
update_server_id = '5678' update_server_id = '5678'
props['InstanceId'] = update_server_id props['InstanceId'] = update_server_id
update_snippet = rsrc_defn.ResourceDefinition(ass.name, ass.type(), update_snippet = rsrc_defn.ResourceDefinition(ass.name, ass.type(),
stack.t.parse(stack, stack.t.parse(stack.defn,
props)) props))
scheduler.TaskRunner(ass.update, update_snippet)() scheduler.TaskRunner(ass.update, update_snippet)()
self.assertEqual((ass.UPDATE, ass.COMPLETE), ass.state) self.assertEqual((ass.UPDATE, ass.COMPLETE), ass.state)
@ -791,7 +789,6 @@ class AllocTest(common.HeatTestCase):
server = self.fc.servers.list()[0] server = self.fc.servers.list()[0]
self._mock_server_get(mock_server=server, multiple=True) self._mock_server_get(mock_server=server, multiple=True)
self.mock_create_floatingip() self.mock_create_floatingip()
self.mock_show_floatingip('fc68ea2c-b60b-4b4f-bd82-94ec81110766')
self.m.ReplayAll() self.m.ReplayAll()
t = template_format.parse(eip_template_ipassoc) t = template_format.parse(eip_template_ipassoc)
@ -804,7 +801,7 @@ class AllocTest(common.HeatTestCase):
update_eip = '11.0.0.2' update_eip = '11.0.0.2'
props['EIP'] = update_eip props['EIP'] = update_eip
update_snippet = rsrc_defn.ResourceDefinition(ass.name, ass.type(), update_snippet = rsrc_defn.ResourceDefinition(ass.name, ass.type(),
stack.t.parse(stack, stack.t.parse(stack.defn,
props)) props))
scheduler.TaskRunner(ass.update, update_snippet)() scheduler.TaskRunner(ass.update, update_snippet)()
self.assertEqual((ass.UPDATE, ass.COMPLETE), ass.state) self.assertEqual((ass.UPDATE, ass.COMPLETE), ass.state)
@ -815,7 +812,6 @@ class AllocTest(common.HeatTestCase):
server = self.fc.servers.list()[0] server = self.fc.servers.list()[0]
self._mock_server_get(mock_server=server, multiple=True) self._mock_server_get(mock_server=server, multiple=True)
self.mock_create_floatingip() self.mock_create_floatingip()
self.mock_show_floatingip('fc68ea2c-b60b-4b4f-bd82-94ec81110766')
self.mock_list_instance_ports('WebServer') self.mock_list_instance_ports('WebServer')
self.mock_show_network() self.mock_show_network()
@ -838,7 +834,7 @@ class AllocTest(common.HeatTestCase):
props['AllocationId'] = update_allocationId props['AllocationId'] = update_allocationId
props.pop('EIP') props.pop('EIP')
update_snippet = rsrc_defn.ResourceDefinition(ass.name, ass.type(), update_snippet = rsrc_defn.ResourceDefinition(ass.name, ass.type(),
stack.t.parse(stack, stack.t.parse(stack.defn,
props)) props))
scheduler.TaskRunner(ass.update, update_snippet)() scheduler.TaskRunner(ass.update, update_snippet)()
self.assertEqual((ass.UPDATE, ass.COMPLETE), ass.state) self.assertEqual((ass.UPDATE, ass.COMPLETE), ass.state)
@ -850,7 +846,7 @@ class AllocTest(common.HeatTestCase):
props['EIP'] = update_eip props['EIP'] = update_eip
props.pop('AllocationId') props.pop('AllocationId')
update_snippet = rsrc_defn.ResourceDefinition(ass.name, ass.type(), update_snippet = rsrc_defn.ResourceDefinition(ass.name, ass.type(),
stack.t.parse(stack, stack.t.parse(stack.defn,
props)) props))
scheduler.TaskRunner(ass.update, update_snippet)() scheduler.TaskRunner(ass.update, update_snippet)()
self.assertEqual((ass.UPDATE, ass.COMPLETE), ass.state) self.assertEqual((ass.UPDATE, ass.COMPLETE), ass.state)
@ -944,7 +940,7 @@ class AllocTest(common.HeatTestCase):
props['NetworkInterfaceId'] = update_networkInterfaceId props['NetworkInterfaceId'] = update_networkInterfaceId
update_snippet = rsrc_defn.ResourceDefinition(ass.name, ass.type(), update_snippet = rsrc_defn.ResourceDefinition(ass.name, ass.type(),
stack.t.parse(stack, stack.t.parse(stack.defn,
props)) props))
scheduler.TaskRunner(ass.update, update_snippet)() scheduler.TaskRunner(ass.update, update_snippet)()
self.assertEqual((ass.UPDATE, ass.COMPLETE), ass.state) self.assertEqual((ass.UPDATE, ass.COMPLETE), ass.state)
@ -956,7 +952,7 @@ class AllocTest(common.HeatTestCase):
props['InstanceId'] = instance_id props['InstanceId'] = instance_id
update_snippet = rsrc_defn.ResourceDefinition(ass.name, ass.type(), update_snippet = rsrc_defn.ResourceDefinition(ass.name, ass.type(),
stack.t.parse(stack, stack.t.parse(stack.defn,
props)) props))
scheduler.TaskRunner(ass.update, update_snippet)() scheduler.TaskRunner(ass.update, update_snippet)()
self.assertEqual((ass.UPDATE, ass.COMPLETE), ass.state) self.assertEqual((ass.UPDATE, ass.COMPLETE), ass.state)
@ -992,5 +988,5 @@ class AllocTest(common.HeatTestCase):
'reference_id': 'convg_xyz' 'reference_id': 'convg_xyz'
})} })}
stack = utils.parse_stack(t, cache_data=cache_data) stack = utils.parse_stack(t, cache_data=cache_data)
rsrc = stack['IPAssoc'] rsrc = stack.defn['IPAssoc']
self.assertEqual('convg_xyz', rsrc.FnGetRefId()) self.assertEqual('convg_xyz', rsrc.FnGetRefId())

View File

@ -169,7 +169,7 @@ class LoadBalancerTest(common.HeatTestCase):
self.stack = utils.parse_stack(template, cache_data=cache_data) self.stack = utils.parse_stack(template, cache_data=cache_data)
resource_name = 'LoadBalancer' resource_name = 'LoadBalancer'
lb_defn = self.stack.t.resource_definitions(self.stack)[resource_name] lb_defn = self.stack.defn.resource_definition(resource_name)
return lb.LoadBalancer(resource_name, lb_defn, self.stack) return lb.LoadBalancer(resource_name, lb_defn, self.stack)
def test_loadbalancer_refid(self): def test_loadbalancer_refid(self):
@ -185,7 +185,8 @@ class LoadBalancerTest(common.HeatTestCase):
'reference_id': 'LoadBalancer_convg_mock' 'reference_id': 'LoadBalancer_convg_mock'
})} })}
rsrc = self.setup_loadbalancer(cache_data=cache_data) rsrc = self.setup_loadbalancer(cache_data=cache_data)
self.assertEqual('LoadBalancer_convg_mock', rsrc.FnGetRefId()) self.assertEqual('LoadBalancer_convg_mock',
self.stack.defn[rsrc.name].FnGetRefId())
def test_loadbalancer_attr_dnsname(self): def test_loadbalancer_attr_dnsname(self):
rsrc = self.setup_loadbalancer() rsrc = self.setup_loadbalancer()

View File

@ -292,7 +292,7 @@ class UserTest(common.HeatTestCase):
'reference_id': 'convg_xyz' 'reference_id': 'convg_xyz'
})} })}
stack = utils.parse_stack(t, cache_data=cache_data) stack = utils.parse_stack(t, cache_data=cache_data)
rsrc = stack['CfnUser'] rsrc = stack.defn['CfnUser']
self.assertEqual('convg_xyz', rsrc.FnGetRefId()) self.assertEqual('convg_xyz', rsrc.FnGetRefId())

View File

@ -282,7 +282,7 @@ class WaitConditionTest(common.HeatTestCase):
'reference_id': 'http://convg_signed_url' 'reference_id': 'http://convg_signed_url'
})}) })})
rsrc = stack['WaitHandle'] rsrc = stack.defn['WaitHandle']
self.assertEqual('http://convg_signed_url', rsrc.FnGetRefId()) self.assertEqual('http://convg_signed_url', rsrc.FnGetRefId())
def test_validate_handle_url_bad_stackid(self): def test_validate_handle_url_bad_stackid(self):

View File

@ -73,7 +73,7 @@ class BaseVolumeTest(common.HeatTestCase):
data['Properties']['AvailabilityZone'] = 'nova' data['Properties']['AvailabilityZone'] = 'nova'
Volume = aws_vol.Volume Volume = aws_vol.Volume
vol = Volume(resource_name, vol = Volume(resource_name,
stack.t.resource_definitions(stack)[resource_name], stack.defn.resource_definition(resource_name),
stack) stack)
return vol return vol
@ -94,9 +94,8 @@ class BaseVolumeTest(common.HeatTestCase):
Attachment = os_vol.CinderVolumeAttachment Attachment = os_vol.CinderVolumeAttachment
else: else:
Attachment = aws_vol.VolumeAttachment Attachment = aws_vol.VolumeAttachment
resource_defns = stack.t.resource_definitions(stack)
rsrc = Attachment(resource_name, rsrc = Attachment(resource_name,
resource_defns[resource_name], stack.defn.resource_definition(resource_name),
stack) stack)
self.assertIsNone(rsrc.validate()) self.assertIsNone(rsrc.validate())
scheduler.TaskRunner(rsrc.create)() scheduler.TaskRunner(rsrc.create)()

View File

@ -25,7 +25,7 @@ from heat.engine import resource
from heat.engine.resources.openstack.heat import instance_group as instgrp from heat.engine.resources.openstack.heat import instance_group as instgrp
from heat.engine import rsrc_defn from heat.engine import rsrc_defn
from heat.engine import scheduler from heat.engine import scheduler
from heat.engine import stack as parser from heat.engine import stk_defn
from heat.tests.autoscaling import inline_templates from heat.tests.autoscaling import inline_templates
from heat.tests import common from heat.tests import common
from heat.tests import utils from heat.tests import utils
@ -320,7 +320,7 @@ class LoadbalancerReloadTest(common.HeatTestCase):
properties = t['Resources']['ElasticLoadBalancer']['Properties'] properties = t['Resources']['ElasticLoadBalancer']['Properties']
properties['AvailabilityZones'] = {'Fn::GetAZs': ''} properties['AvailabilityZones'] = {'Fn::GetAZs': ''}
self.patchobject(parser.Stack, 'get_availability_zones', self.patchobject(stk_defn.StackDefinition, 'get_availability_zones',
return_value=['abc', 'xyz']) return_value=['abc', 'xyz'])
mock_members = self.patchobject(grouputils, 'get_member_refids') mock_members = self.patchobject(grouputils, 'get_member_refids')

View File

@ -171,7 +171,7 @@ Resources:
'reference_id': 'xyz' 'reference_id': 'xyz'
})} })}
stack = utils.parse_stack(t, cache_data=cache_data) stack = utils.parse_stack(t, cache_data=cache_data)
rsrc = stack['secret1'] rsrc = stack.defn['secret1']
self.assertEqual('xyz', rsrc.FnGetRefId()) self.assertEqual('xyz', rsrc.FnGetRefId())
def test_invalid_length(self): def test_invalid_length(self):

View File

@ -677,7 +677,7 @@ class RemoteStackTest(tests_common.HeatTestCase):
'reference_id': 'convg_xyz' 'reference_id': 'convg_xyz'
})} })}
stack = utils.parse_stack(t, cache_data=cache_data) stack = utils.parse_stack(t, cache_data=cache_data)
rsrc = stack['remote_stack'] rsrc = stack.defn['remote_stack']
self.assertEqual('convg_xyz', rsrc.FnGetRefId()) self.assertEqual('convg_xyz', rsrc.FnGetRefId())
def test_update_in_check_failed_state(self): def test_update_in_check_failed_state(self):

View File

@ -228,5 +228,5 @@ class ResourceChainTest(common.HeatTestCase):
'attrs': {'refs': ['rsrc1', 'rsrc2']} 'attrs': {'refs': ['rsrc1', 'rsrc2']}
})} })}
stack = utils.parse_stack(TEMPLATE, cache_data=cache_data) stack = utils.parse_stack(TEMPLATE, cache_data=cache_data)
rsrc = stack['test-chain'] rsrc = stack.defn['test-chain']
self.assertEqual(['rsrc1', 'rsrc2'], rsrc.FnGetAtt(rsrc.REFS)) self.assertEqual(['rsrc1', 'rsrc2'], rsrc.FnGetAtt('refs'))

View File

@ -884,8 +884,8 @@ class ResourceGroupAttrTest(common.HeatTestCase):
'attrs': {'refs': ['rsrc1', 'rsrc2']} 'attrs': {'refs': ['rsrc1', 'rsrc2']}
})} })}
stack = utils.parse_stack(template, cache_data=cache_data) stack = utils.parse_stack(template, cache_data=cache_data)
rsrc = stack['group1'] rsrc = stack.defn['group1']
self.assertEqual(['rsrc1', 'rsrc2'], rsrc.FnGetAtt(rsrc.REFS)) self.assertEqual(['rsrc1', 'rsrc2'], rsrc.FnGetAtt('refs'))
def test_get_attribute_blacklist(self): def test_get_attribute_blacklist(self):
resg = self._create_dummy_stack() resg = self._create_dummy_stack()

View File

@ -1104,7 +1104,8 @@ class SoftwareDeploymentTest(common.HeatTestCase):
'attrs': {'foo': 'bar'} 'attrs': {'foo': 'bar'}
})} })}
self._create_stack(self.template, cache_data=cache_data) self._create_stack(self.template, cache_data=cache_data)
self.assertEqual('bar', self.deployment.FnGetAtt('foo')) self.assertEqual('bar',
self.stack.defn[self.deployment.name].FnGetAtt('foo'))
def test_fn_get_att_error(self): def test_fn_get_att_error(self):
self._create_stack(self.template) self._create_stack(self.template)

View File

@ -291,7 +291,7 @@ class SwiftSignalHandleTest(common.HeatTestCase):
}) })
} }
st = create_stack(swiftsignalhandle_template, cache_data=cache_data) st = create_stack(swiftsignalhandle_template, cache_data=cache_data)
rsrc = st['test_wait_condition_handle'] rsrc = st.defn['test_wait_condition_handle']
self.assertEqual('convg_xyz', rsrc.FnGetRefId()) self.assertEqual('convg_xyz', rsrc.FnGetRefId())

View File

@ -821,7 +821,7 @@ class TestMistralWorkflow(common.HeatTestCase):
return [FakeWorkflow('create_vm')] return [FakeWorkflow('create_vm')]
def test_mistal_workflow_refid(self): def test_mistral_workflow_refid(self):
tmpl = template_format.parse(workflow_template) tmpl = template_format.parse(workflow_template)
stack = utils.parse_stack(tmpl, stack_name='test') stack = utils.parse_stack(tmpl, stack_name='test')
rsrc = stack['workflow'] rsrc = stack['workflow']
@ -830,7 +830,7 @@ class TestMistralWorkflow(common.HeatTestCase):
rsrc.action = 'CREATE' rsrc.action = 'CREATE'
self.assertEqual('test-workflow-owevpzgiqw66', rsrc.FnGetRefId()) self.assertEqual('test-workflow-owevpzgiqw66', rsrc.FnGetRefId())
def test_mistal_workflow_refid_convergence_cache_data(self): def test_mistral_workflow_refid_convergence_cache_data(self):
tmpl = template_format.parse(workflow_template) tmpl = template_format.parse(workflow_template)
cache_data = {'workflow': node_data.NodeData.from_dict({ cache_data = {'workflow': node_data.NodeData.from_dict({
'uuid': mock.ANY, 'uuid': mock.ANY,
@ -841,7 +841,7 @@ class TestMistralWorkflow(common.HeatTestCase):
})} })}
stack = utils.parse_stack(tmpl, stack_name='test', stack = utils.parse_stack(tmpl, stack_name='test',
cache_data=cache_data) cache_data=cache_data)
rsrc = stack['workflow'] rsrc = stack.defn['workflow']
self.assertEqual('convg_xyz', rsrc.FnGetRefId()) self.assertEqual('convg_xyz', rsrc.FnGetRefId())
def test_policies_translation_successful(self): def test_policies_translation_successful(self):

View File

@ -296,7 +296,7 @@ class NeutronFloatingIPTest(common.HeatTestCase):
'status': 'COMPLETE', 'status': 'COMPLETE',
'reference_id': 'abc'})}) 'reference_id': 'abc'})})
rsrc = stack['floating_ip'] rsrc = stack.defn['floating_ip']
self.assertEqual('abc', rsrc.FnGetRefId()) self.assertEqual('abc', rsrc.FnGetRefId())
def test_floatip_association_port(self): def test_floatip_association_port(self):
@ -449,7 +449,7 @@ class NeutronFloatingIPTest(common.HeatTestCase):
update_port_id = '2146dfbf-ba77-4083-8e86-d052f671ece5' update_port_id = '2146dfbf-ba77-4083-8e86-d052f671ece5'
props['port_id'] = update_port_id props['port_id'] = update_port_id
update_snippet = rsrc_defn.ResourceDefinition(fipa.name, fipa.type(), update_snippet = rsrc_defn.ResourceDefinition(fipa.name, fipa.type(),
stack.t.parse(stack, stack.t.parse(stack.defn,
props)) props))
scheduler.TaskRunner(fipa.update, update_snippet)() scheduler.TaskRunner(fipa.update, update_snippet)()
@ -708,7 +708,7 @@ class NeutronFloatingIPTest(common.HeatTestCase):
update_port_id = '2146dfbf-ba77-4083-8e86-d052f671ece5' update_port_id = '2146dfbf-ba77-4083-8e86-d052f671ece5'
props['port_id'] = update_port_id props['port_id'] = update_port_id
update_snippet = rsrc_defn.ResourceDefinition(fip.name, fip.type(), update_snippet = rsrc_defn.ResourceDefinition(fip.name, fip.type(),
stack.t.parse(stack, stack.t.parse(stack.defn,
props)) props))
scheduler.TaskRunner(fip.update, update_snippet)() scheduler.TaskRunner(fip.update, update_snippet)()
self.assertEqual((fip.UPDATE, fip.COMPLETE), fip.state) self.assertEqual((fip.UPDATE, fip.COMPLETE), fip.state)
@ -718,7 +718,7 @@ class NeutronFloatingIPTest(common.HeatTestCase):
props = copy.deepcopy(fip.properties.data) props = copy.deepcopy(fip.properties.data)
del(props['port_id']) del(props['port_id'])
update_snippet = rsrc_defn.ResourceDefinition(fip.name, fip.type(), update_snippet = rsrc_defn.ResourceDefinition(fip.name, fip.type(),
stack.t.parse(stack, stack.t.parse(stack.defn,
props)) props))
scheduler.TaskRunner(fip.update, update_snippet)() scheduler.TaskRunner(fip.update, update_snippet)()
self.assertEqual((fip.UPDATE, fip.COMPLETE), fip.state) self.assertEqual((fip.UPDATE, fip.COMPLETE), fip.state)

View File

@ -22,10 +22,12 @@ from heat.common import template_format
from heat.engine.clients.os import neutron from heat.engine.clients.os import neutron
from heat.engine.clients.os import openstacksdk from heat.engine.clients.os import openstacksdk
from heat.engine.hot import functions as hot_funcs from heat.engine.hot import functions as hot_funcs
from heat.engine import node_data
from heat.engine import resource from heat.engine import resource
from heat.engine.resources.openstack.neutron import subnet from heat.engine.resources.openstack.neutron import subnet
from heat.engine import rsrc_defn from heat.engine import rsrc_defn
from heat.engine import scheduler from heat.engine import scheduler
from heat.engine import stk_defn
from heat.tests import common from heat.tests import common
from heat.tests import utils from heat.tests import utils
@ -682,9 +684,10 @@ class NeutronSubnetTest(common.HeatTestCase):
""" """
t = template_format.parse(template) t = template_format.parse(template)
stack = utils.parse_stack(t) stack = utils.parse_stack(t)
self.patchobject(stack['net'], 'FnGetRefId',
return_value='fc68ea2c-b60b-4b4f-bd82-94ec81110766')
rsrc = stack['subnet'] rsrc = stack['subnet']
nd = {'reference_id': 'fc68ea2c-b60b-4b4f-bd82-94ec81110766'}
stk_defn.update_resource_data(stack.defn, 'net',
node_data.NodeData.from_dict(nd))
self.create_mock.return_value = { self.create_mock.return_value = {
"subnet": { "subnet": {
"id": "91e47a57-7508-46fe-afc9-fc454e8580e1", "id": "91e47a57-7508-46fe-afc9-fc454e8580e1",
@ -696,6 +699,7 @@ class NeutronSubnetTest(common.HeatTestCase):
} }
stack.create() stack.create()
self.assertEqual(hot_funcs.GetResource(stack, 'get_resource', 'net'), self.assertEqual(hot_funcs.GetResource(stack.defn, 'get_resource',
'net'),
rsrc.properties.get('network')) rsrc.properties.get('network'))
self.assertIsNone(rsrc.properties.get('network_id')) self.assertIsNone(rsrc.properties.get('network_id'))

View File

@ -369,7 +369,7 @@ class NeutronTrunkTest(common.HeatTestCase):
t = template_format.parse(update_template) t = template_format.parse(update_template)
stack = utils.parse_stack(t) stack = utils.parse_stack(t)
rsrc_defn = stack.t.resource_definitions(stack)['trunk'] rsrc_defn = stack.defn.resource_definition('trunk')
rsrc = trunk.Trunk('trunk', rsrc_defn, stack) rsrc = trunk.Trunk('trunk', rsrc_defn, stack)
scheduler.TaskRunner(rsrc.create)() scheduler.TaskRunner(rsrc.create)()
self.assertEqual((rsrc.CREATE, rsrc.COMPLETE), rsrc.state) self.assertEqual((rsrc.CREATE, rsrc.COMPLETE), rsrc.state)
@ -390,7 +390,7 @@ class NeutronTrunkTest(common.HeatTestCase):
t = template_format.parse(update_template) t = template_format.parse(update_template)
stack = utils.parse_stack(t) stack = utils.parse_stack(t)
rsrc_defn = stack.t.resource_definitions(stack)['trunk'] rsrc_defn = stack.defn.resource_definition('trunk')
rsrc = trunk.Trunk('trunk', rsrc_defn, stack) rsrc = trunk.Trunk('trunk', rsrc_defn, stack)
scheduler.TaskRunner(rsrc.create)() scheduler.TaskRunner(rsrc.create)()
self.assertEqual((rsrc.CREATE, rsrc.COMPLETE), rsrc.state) self.assertEqual((rsrc.CREATE, rsrc.COMPLETE), rsrc.state)
@ -411,7 +411,7 @@ class NeutronTrunkTest(common.HeatTestCase):
t = template_format.parse(update_template) t = template_format.parse(update_template)
stack = utils.parse_stack(t) stack = utils.parse_stack(t)
rsrc_defn = stack.t.resource_definitions(stack)['trunk'] rsrc_defn = stack.defn.resource_definition('trunk')
rsrc = trunk.Trunk('trunk', rsrc_defn, stack) rsrc = trunk.Trunk('trunk', rsrc_defn, stack)
scheduler.TaskRunner(rsrc.create)() scheduler.TaskRunner(rsrc.create)()
self.assertEqual((rsrc.CREATE, rsrc.COMPLETE), rsrc.state) self.assertEqual((rsrc.CREATE, rsrc.COMPLETE), rsrc.state)
@ -440,7 +440,7 @@ class NeutronTrunkTest(common.HeatTestCase):
t = template_format.parse(update_template) t = template_format.parse(update_template)
stack = utils.parse_stack(t) stack = utils.parse_stack(t)
rsrc_defn = stack.t.resource_definitions(stack)['trunk'] rsrc_defn = stack.defn.resource_definition('trunk')
rsrc = trunk.Trunk('trunk', rsrc_defn, stack) rsrc = trunk.Trunk('trunk', rsrc_defn, stack)
scheduler.TaskRunner(rsrc.create)() scheduler.TaskRunner(rsrc.create)()
self.assertEqual((rsrc.CREATE, rsrc.COMPLETE), rsrc.state) self.assertEqual((rsrc.CREATE, rsrc.COMPLETE), rsrc.state)

View File

@ -357,5 +357,5 @@ class NovaFloatingIPTest(common.HeatTestCase):
'reference_id': 'convg_xyz' 'reference_id': 'convg_xyz'
})} })}
stack = utils.parse_stack(t, cache_data=cache_data) stack = utils.parse_stack(t, cache_data=cache_data)
rsrc = stack['MyFloatingIPAssociation'] rsrc = stack.defn['MyFloatingIPAssociation']
self.assertEqual('convg_xyz', rsrc.FnGetRefId()) self.assertEqual('convg_xyz', rsrc.FnGetRefId())

View File

@ -286,5 +286,5 @@ class NovaKeyPairTest(common.HeatTestCase):
'reference_id': 'convg_xyz' 'reference_id': 'convg_xyz'
}} }}
stack = utils.parse_stack(self.kp_template, cache_data=cache_data) stack = utils.parse_stack(self.kp_template, cache_data=cache_data)
rsrc = stack['kp'] rsrc = stack.defn['kp']
self.assertEqual('convg_xyz', rsrc.FnGetRefId()) self.assertEqual('convg_xyz', rsrc.FnGetRefId())

View File

@ -472,7 +472,7 @@ class SwiftTest(common.HeatTestCase):
'reference_id': 'xyz_convg' 'reference_id': 'xyz_convg'
})} })}
stack = utils.parse_stack(self.t, cache_data=cache_data) stack = utils.parse_stack(self.t, cache_data=cache_data)
rsrc = stack['SwiftContainer'] rsrc = stack.defn['SwiftContainer']
self.assertEqual('xyz_convg', rsrc.FnGetRefId()) self.assertEqual('xyz_convg', rsrc.FnGetRefId())
@mock.patch('swiftclient.client.Connection.head_account') @mock.patch('swiftclient.client.Connection.head_account')

View File

@ -24,6 +24,7 @@ from heat.engine import function
from heat.engine import resource from heat.engine import resource
from heat.engine import rsrc_defn from heat.engine import rsrc_defn
from heat.engine import stack from heat.engine import stack
from heat.engine import stk_defn
from heat.engine import template from heat.engine import template
from heat.tests import common from heat.tests import common
from heat.tests import utils from heat.tests import utils
@ -241,25 +242,38 @@ class ValidateGetAttTest(common.HeatTestCase):
env.load({u'resource_registry': env.load({u'resource_registry':
{u'OS::Test::FakeResource': u'OverwrittenFnGetAttType'}}) {u'OS::Test::FakeResource': u'OverwrittenFnGetAttType'}})
tmpl = template.Template({"HeatTemplateFormatVersion": "2012-12-12",
"Resources": {
"test_rsrc": {
"Type": "OS::Test::GenericResource"
},
"get_att_rsrc": {
"Type": "OS::Heat::Value",
"Properties": {
"value": {
"Fn::GetAtt": ["test_rsrc",
"Foo"]
}
}
}
}},
env=env)
self.stack = stack.Stack( self.stack = stack.Stack(
utils.dummy_context(), 'test_stack', utils.dummy_context(), 'test_stack',
template.Template({"HeatTemplateFormatVersion": "2012-12-12"}, tmpl,
env=env),
stack_id=str(uuid.uuid4())) stack_id=str(uuid.uuid4()))
res_defn = rsrc_defn.ResourceDefinition('test_rsrc', self.rsrc = self.stack['test_rsrc']
'OS::Test::GenericResource') self.stack.validate()
self.rsrc = resource.Resource('test_rsrc', res_defn, self.stack)
self.stack.add_resource(self.rsrc)
def test_resource_is_appear_in_stack(self): def test_resource_is_appear_in_stack(self):
func = functions.GetAtt(self.stack, 'Fn::GetAtt', func = functions.GetAtt(self.stack.defn, 'Fn::GetAtt',
[self.rsrc.name, 'Foo']) [self.rsrc.name, 'Foo'])
self.assertIsNone(func.validate()) self.assertIsNone(func.validate())
def test_resource_is_not_appear_in_stack(self): def test_resource_is_not_appear_in_stack(self):
self.stack.remove_resource(self.rsrc.name) self.stack.remove_resource(self.rsrc.name)
func = functions.GetAtt(self.stack, 'Fn::GetAtt', func = functions.GetAtt(self.stack.defn, 'Fn::GetAtt',
[self.rsrc.name, 'Foo']) [self.rsrc.name, 'Foo'])
ex = self.assertRaises(exception.InvalidTemplateReference, ex = self.assertRaises(exception.InvalidTemplateReference,
func.validate) func.validate)
@ -267,7 +281,15 @@ class ValidateGetAttTest(common.HeatTestCase):
'is incorrect.', six.text_type(ex)) 'is incorrect.', six.text_type(ex))
def test_resource_no_attribute_with_default_fn_get_att(self): def test_resource_no_attribute_with_default_fn_get_att(self):
func = functions.GetAtt(self.stack, 'Fn::GetAtt', res_defn = rsrc_defn.ResourceDefinition('test_rsrc',
'ResWithStringPropAndAttr')
self.rsrc = resource.Resource('test_rsrc', res_defn, self.stack)
self.stack.add_resource(self.rsrc)
stk_defn.update_resource_data(self.stack.defn, self.rsrc.name,
self.rsrc.node_data())
self.stack.validate()
func = functions.GetAtt(self.stack.defn, 'Fn::GetAtt',
[self.rsrc.name, 'Bar']) [self.rsrc.name, 'Bar'])
ex = self.assertRaises(exception.InvalidTemplateAttribute, ex = self.assertRaises(exception.InvalidTemplateAttribute,
func.validate) func.validate)
@ -278,16 +300,19 @@ class ValidateGetAttTest(common.HeatTestCase):
res_defn = rsrc_defn.ResourceDefinition('test_rsrc', res_defn = rsrc_defn.ResourceDefinition('test_rsrc',
'OS::Test::FakeResource') 'OS::Test::FakeResource')
self.rsrc = resource.Resource('test_rsrc', res_defn, self.stack) self.rsrc = resource.Resource('test_rsrc', res_defn, self.stack)
self.stack.add_resource(self.rsrc)
self.rsrc.attributes_schema = {} self.rsrc.attributes_schema = {}
self.stack.add_resource(self.rsrc)
stk_defn.update_resource_data(self.stack.defn, self.rsrc.name,
self.rsrc.node_data())
self.stack.validate()
func = functions.GetAtt(self.stack, 'Fn::GetAtt', func = functions.GetAtt(self.stack.defn, 'Fn::GetAtt',
[self.rsrc.name, 'Foo']) [self.rsrc.name, 'Foo'])
self.assertIsNone(func.validate()) self.assertIsNone(func.validate())
def test_get_attr_without_attribute_name(self): def test_get_attr_without_attribute_name(self):
ex = self.assertRaises(ValueError, functions.GetAtt, ex = self.assertRaises(ValueError, functions.GetAtt,
self.stack, 'Fn::GetAtt', [self.rsrc.name]) self.stack.defn, 'Fn::GetAtt', [self.rsrc.name])
self.assertEqual('Arguments to "Fn::GetAtt" must be ' self.assertEqual('Arguments to "Fn::GetAtt" must be '
'of the form [resource_name, attribute]', 'of the form [resource_name, attribute]',
six.text_type(ex)) six.text_type(ex))

View File

@ -30,6 +30,7 @@ from heat.engine import resource
from heat.engine import resources from heat.engine import resources
from heat.engine import rsrc_defn from heat.engine import rsrc_defn
from heat.engine import stack as parser from heat.engine import stack as parser
from heat.engine import stk_defn
from heat.engine import template from heat.engine import template
from heat.tests import common from heat.tests import common
from heat.tests import generic_resource as generic_rsrc from heat.tests import generic_resource as generic_rsrc
@ -162,11 +163,12 @@ class HOTemplateTest(common.HeatTestCase):
@staticmethod @staticmethod
def resolve(snippet, template, stack=None): def resolve(snippet, template, stack=None):
return function.resolve(template.parse(stack, snippet)) return function.resolve(template.parse(stack and stack.defn, snippet))
@staticmethod @staticmethod
def resolve_condition(snippet, template, stack=None): def resolve_condition(snippet, template, stack=None):
return function.resolve(template.parse_condition(stack, snippet)) return function.resolve(template.parse_condition(stack and stack.defn,
snippet))
def test_defaults(self): def test_defaults(self):
"""Test default content behavior of HOT template.""" """Test default content behavior of HOT template."""
@ -1913,7 +1915,7 @@ conditions:
self.assertRaisesRegex(exception.StackValidationFailed, self.assertRaisesRegex(exception.StackValidationFailed,
regxp, regxp,
function.validate, function.validate,
stack.t.parse(stack, snippet)) stack.t.parse(stack.defn, snippet))
def test_add_resource(self): def test_add_resource(self):
hot_tpl = template_format.parse(''' hot_tpl = template_format.parse('''
@ -2349,7 +2351,7 @@ class HotStackTest(common.HeatTestCase):
self.ctx = utils.dummy_context() self.ctx = utils.dummy_context()
def resolve(self, snippet): def resolve(self, snippet):
return function.resolve(self.stack.t.parse(self.stack, snippet)) return function.resolve(self.stack.t.parse(self.stack.defn, snippet))
def test_repeat_get_attr(self): def test_repeat_get_attr(self):
"""Test repeat function with get_attr function as an argument.""" """Test repeat function with get_attr function as an argument."""
@ -2358,7 +2360,7 @@ class HotStackTest(common.HeatTestCase):
snippet = {'repeat': {'template': 'this is %var%', snippet = {'repeat': {'template': 'this is %var%',
'for_each': {'%var%': {'get_attr': ['resource1', 'list']}}}} 'for_each': {'%var%': {'get_attr': ['resource1', 'list']}}}}
repeat = self.stack.t.parse(self.stack, snippet) repeat = self.stack.t.parse(self.stack.defn, snippet)
self.stack.store() self.stack.store()
with mock.patch.object(rsrc_defn.ResourceDefinition, with mock.patch.object(rsrc_defn.ResourceDefinition,
@ -2724,7 +2726,8 @@ class StackAttributesTest(common.HeatTestCase):
template.Template(self.hot_tpl)) template.Template(self.hot_tpl))
self.stack.store() self.stack.store()
parsed = self.stack.t.parse(self.stack, self.snippet) parsed = self.stack.t.parse(self.stack.defn, self.snippet)
dep_attrs = list(function.dep_attrs(parsed, self.resource_name))
self.stack.create() self.stack.create()
self.assertEqual((parser.Stack.CREATE, parser.Stack.COMPLETE), self.assertEqual((parser.Stack.CREATE, parser.Stack.COMPLETE),
@ -2748,177 +2751,16 @@ class StackAttributesTest(common.HeatTestCase):
(rsrc.ADOPT, rsrc.COMPLETE)): (rsrc.ADOPT, rsrc.COMPLETE)):
rsrc.state_set(action, status) rsrc.state_set(action, status)
with mock.patch.object(rsrc_defn.ResourceDefinition,
'dep_attrs') as mock_da:
mock_da.return_value = dep_attrs
node_data = rsrc.node_data()
stk_defn.update_resource_data(self.stack.defn, rsrc.name,
node_data)
self.assertEqual(self.expected, function.resolve(parsed)) self.assertEqual(self.expected, function.resolve(parsed))
class StackGetAttributesTestConvergence(common.HeatTestCase):
def setUp(self):
super(StackGetAttributesTestConvergence, self).setUp()
self.ctx = utils.dummy_context()
self.m.ReplayAll()
scenarios = [
# for hot template 2013-05-23, get_attr: hot_funcs.GetAttThenSelect
('get_flat_attr',
dict(hot_tpl=hot_tpl_generic_resource,
snippet={'Value': {'get_attr': ['resource1', 'foo']}},
resource_name='resource1',
expected={'Value': 'resource1'})),
('get_list_attr',
dict(hot_tpl=hot_tpl_complex_attrs,
snippet={'Value': {'get_attr': ['resource1', 'list', 0]}},
resource_name='resource1',
expected={
'Value':
generic_rsrc.ResourceWithComplexAttributes.list[0]})),
('get_flat_dict_attr',
dict(hot_tpl=hot_tpl_complex_attrs,
snippet={'Value': {'get_attr': ['resource1',
'flat_dict',
'key2']}},
resource_name='resource1',
expected={
'Value':
generic_rsrc.ResourceWithComplexAttributes.
flat_dict['key2']})),
('get_nested_attr_list',
dict(hot_tpl=hot_tpl_complex_attrs,
snippet={'Value': {'get_attr': ['resource1',
'nested_dict',
'list',
0]}},
resource_name='resource1',
expected={
'Value':
generic_rsrc.ResourceWithComplexAttributes.
nested_dict['list'][0]})),
('get_nested_attr_dict',
dict(hot_tpl=hot_tpl_complex_attrs,
snippet={'Value': {'get_attr': ['resource1',
'nested_dict',
'dict',
'a']}},
resource_name='resource1',
expected={
'Value':
generic_rsrc.ResourceWithComplexAttributes.
nested_dict['dict']['a']})),
('get_attr_none',
dict(hot_tpl=hot_tpl_complex_attrs,
snippet={'Value': {'get_attr': ['resource1',
'none',
'who_cares']}},
resource_name='resource1',
expected={'Value': None})),
# for hot template version 2014-10-16 and 2015-04-30,
# get_attr: hot_funcs.GetAtt
('get_flat_attr',
dict(hot_tpl=hot_tpl_generic_resource_20141016,
snippet={'Value': {'get_attr': ['resource1', 'foo']}},
resource_name='resource1',
expected={'Value': 'resource1'})),
('get_list_attr',
dict(hot_tpl=hot_tpl_complex_attrs_20141016,
snippet={'Value': {'get_attr': ['resource1', 'list', 0]}},
resource_name='resource1',
expected={
'Value':
generic_rsrc.ResourceWithComplexAttributes.list[0]})),
('get_flat_dict_attr',
dict(hot_tpl=hot_tpl_complex_attrs_20141016,
snippet={'Value': {'get_attr': ['resource1',
'flat_dict',
'key2']}},
resource_name='resource1',
expected={
'Value':
generic_rsrc.ResourceWithComplexAttributes.
flat_dict['key2']})),
('get_nested_attr_list',
dict(hot_tpl=hot_tpl_complex_attrs_20141016,
snippet={'Value': {'get_attr': ['resource1',
'nested_dict',
'list',
0]}},
resource_name='resource1',
expected={
'Value':
generic_rsrc.ResourceWithComplexAttributes.
nested_dict['list'][0]})),
('get_nested_attr_dict',
dict(hot_tpl=hot_tpl_complex_attrs_20141016,
snippet={'Value': {'get_attr': ['resource1',
'nested_dict',
'dict',
'a']}},
resource_name='resource1',
expected={
'Value':
generic_rsrc.ResourceWithComplexAttributes.
nested_dict['dict']['a']})),
('get_attr_none',
dict(hot_tpl=hot_tpl_complex_attrs_20141016,
snippet={'Value': {'get_attr': ['resource1',
'none',
'who_cares']}},
resource_name='resource1',
expected={'Value': None}))
]
def _prepare_cache_data(self, rsrc):
dep_attrs = function.dep_attrs(
self.stack.t.parse(self.stack, self.snippet),
self.resource_name)
with mock.patch.object(rsrc_defn.ResourceDefinition,
'dep_attrs') as mock_da:
mock_da.return_value = dep_attrs
rsrc_data = rsrc.node_data()
# store as cache data
self.stack.cache_data = {
rsrc.name: rsrc_data
}
def test_get_attr_convergence(self):
"""Test resolution of get_attr occurrences with convergence."""
self.stack = parser.Stack(self.ctx, 'test_get_attr',
template.Template(self.hot_tpl))
self.stack.store()
self.stack.create()
self.assertEqual((parser.Stack.CREATE, parser.Stack.COMPLETE),
self.stack.state)
rsrc = self.stack[self.resource_name]
self._prepare_cache_data(rsrc)
with mock.patch.object(resource.Resource, 'get_attribute') as mock_ga:
for action, status in (
(rsrc.CREATE, rsrc.IN_PROGRESS),
(rsrc.CREATE, rsrc.COMPLETE),
(rsrc.RESUME, rsrc.IN_PROGRESS),
(rsrc.RESUME, rsrc.COMPLETE),
(rsrc.SUSPEND, rsrc.IN_PROGRESS),
(rsrc.SUSPEND, rsrc.COMPLETE),
(rsrc.UPDATE, rsrc.IN_PROGRESS),
(rsrc.UPDATE, rsrc.COMPLETE),
(rsrc.SNAPSHOT, rsrc.IN_PROGRESS),
(rsrc.SNAPSHOT, rsrc.COMPLETE),
(rsrc.CHECK, rsrc.IN_PROGRESS),
(rsrc.CHECK, rsrc.COMPLETE),
(rsrc.ADOPT, rsrc.IN_PROGRESS),
(rsrc.ADOPT, rsrc.COMPLETE)):
rsrc.state_set(action, status)
resolved = function.resolve(self.stack.t.parse(self.stack,
self.snippet))
self.assertEqual(self.expected, resolved)
# get_attribute should never be called, everything
# should be resolved from cache data
self.assertFalse(mock_ga.called)
class StackGetAttrValidationTest(common.HeatTestCase): class StackGetAttrValidationTest(common.HeatTestCase):
def setUp(self): def setUp(self):
@ -3067,7 +2909,8 @@ class StackParametersTest(common.HeatTestCase):
stack_id='1ba8c334-2297-4312-8c7c-43763a988ced', stack_id='1ba8c334-2297-4312-8c7c-43763a988ced',
tenant_id='9913ef0a-b8be-4b33-b574-9061441bd373') tenant_id='9913ef0a-b8be-4b33-b574-9061441bd373')
self.assertEqual(self.expected, self.assertEqual(self.expected,
function.resolve(tmpl.parse(stack, self.snippet))) function.resolve(tmpl.parse(stack.defn,
self.snippet)))
class HOTParamValidatorTest(common.HeatTestCase): class HOTParamValidatorTest(common.HeatTestCase):
@ -3598,13 +3441,20 @@ class TestGetAttAllAttributes(common.HeatTestCase):
] ]
@staticmethod @staticmethod
def resolve(snippet, template, stack=None): def resolve(snippet, template, stack):
return function.resolve(template.parse(stack, snippet)) return function.resolve(template.parse(stack.defn, snippet))
def test_get_attr_all_attributes(self): def test_get_attr_all_attributes(self):
tmpl = template.Template(self.hot_tpl) tmpl = template.Template(self.hot_tpl)
stack = parser.Stack(utils.dummy_context(), 'test_get_attr', tmpl) stack = parser.Stack(utils.dummy_context(), 'test_get_attr', tmpl)
stack.store() stack.store()
if self.raises is None:
dep_attrs = list(function.dep_attrs(tmpl.parse(stack.defn,
self.snippet),
'resource1'))
else:
dep_attrs = []
stack.create() stack.create()
self.assertEqual((parser.Stack.CREATE, parser.Stack.COMPLETE), self.assertEqual((parser.Stack.CREATE, parser.Stack.COMPLETE),
@ -3628,6 +3478,12 @@ class TestGetAttAllAttributes(common.HeatTestCase):
(rsrc.ADOPT, rsrc.COMPLETE)): (rsrc.ADOPT, rsrc.COMPLETE)):
rsrc.state_set(action, status) rsrc.state_set(action, status)
with mock.patch.object(rsrc_defn.ResourceDefinition,
'dep_attrs') as mock_da:
mock_da.return_value = dep_attrs
node_data = rsrc.node_data()
stk_defn.update_resource_data(stack.defn, rsrc.name, node_data)
if self.raises is not None: if self.raises is not None:
ex = self.assertRaises(self.raises, ex = self.assertRaises(self.raises,
self.resolve, self.snippet, tmpl, stack) self.resolve, self.snippet, tmpl, stack)

View File

@ -269,7 +269,10 @@ class WaitConditionMetadataUpdateTest(common.HeatTestCase):
update_metadata('123', 'foo', 'bar') update_metadata('123', 'foo', 'bar')
def side_effect_popper(sleep_time): def side_effect_popper(sleep_time):
if self.run_empty: wh = stack['WH']
if wh.status == wh.IN_PROGRESS:
return
elif self.run_empty:
self.run_empty = False self.run_empty = False
check_empty(sleep_time) check_empty(sleep_time)
else: else:
@ -308,7 +311,7 @@ class MetadataRefreshServerTest(common.HeatTestCase):
return_value=1) return_value=1)
@mock.patch.object(server.Server, 'handle_create') @mock.patch.object(server.Server, 'handle_create')
@mock.patch.object(server.Server, 'check_create_complete') @mock.patch.object(server.Server, 'check_create_complete')
@mock.patch.object(server.Server, 'FnGetAtt') @mock.patch.object(server.Server, 'get_attribute', new_callable=mock.Mock)
def test_FnGetAtt_metadata_update(self, mock_get, mock_check, def test_FnGetAtt_metadata_update(self, mock_get, mock_check,
mock_handle, *args): mock_handle, *args):
temp = template_format.parse(TEST_TEMPLATE_SERVER) temp = template_format.parse(TEST_TEMPLATE_SERVER)
@ -321,7 +324,7 @@ class MetadataRefreshServerTest(common.HeatTestCase):
self.stub_KeypairConstraint_validate() self.stub_KeypairConstraint_validate()
# Note dummy addresses are from TEST-NET-1 ref rfc5737 # 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'] mock_get.side_effect = ['192.0.2.1', '192.0.2.2']
# Test # Test
stack.create() stack.create()

View File

@ -286,7 +286,7 @@ Resources:
'reference_id': 'the_nested_convg_mock' 'reference_id': 'the_nested_convg_mock'
})} })}
stack = parser.Stack(ctx, 'test_stack', tmpl, cache_data=cache_data) stack = parser.Stack(ctx, 'test_stack', tmpl, cache_data=cache_data)
nested_stack = stack['the_nested'] nested_stack = stack.defn['the_nested']
self.assertEqual('the_nested_convg_mock', nested_stack.FnGetRefId()) self.assertEqual('the_nested_convg_mock', nested_stack.FnGetRefId())
def test_get_attribute(self): def test_get_attribute(self):

View File

@ -1910,7 +1910,7 @@ class ResourceTest(common.HeatTestCase):
'action': 'CREATE', 'action': 'CREATE',
'status': 'COMPLETE'})}) 'status': 'COMPLETE'})})
res = stack['res'] res = stack.defn['res']
self.assertEqual('Res', res.FnGetAtt('Foo')) self.assertEqual('Res', res.FnGetAtt('Foo'))
def test_getatt_with_path_cache_data(self): def test_getatt_with_path_cache_data(self):
@ -1932,50 +1932,9 @@ class ResourceTest(common.HeatTestCase):
'action': 'CREATE', 'action': 'CREATE',
'status': 'COMPLETE'})}) 'status': 'COMPLETE'})})
res = stack['res'] res = stack.defn['res']
self.assertEqual('abc', res.FnGetAtt('nested', 'string')) self.assertEqual('abc', res.FnGetAtt('nested', 'string'))
def test_getatts(self):
tmpl = template.Template({
'heat_template_version': '2013-05-23',
'resources': {
'res': {
'type': 'ResourceWithComplexAttributesType'
}
}
})
stack = parser.Stack(utils.dummy_context(), 'test', tmpl)
res = stack['res']
self.assertEqual({'list': ['foo', 'bar'],
'flat_dict': {'key1': 'val1',
'key2': 'val2',
'key3': 'val3'},
'nested_dict': {'list': [1, 2, 3],
'string': 'abc',
'dict': {'a': 1, 'b': 2, 'c': 3}},
'none': None}, res.FnGetAtts())
def test_getatts_with_cache_data(self):
tmpl = template.Template({
'heat_template_version': '2013-05-23',
'resources': {
'res': {
'type': 'ResourceWithPropsType'
}
}
})
stack = parser.Stack(utils.dummy_context(), 'test', tmpl,
cache_data={
'res': node_data.NodeData.from_dict({
'attrs': {'Foo': 'res',
'foo': 'res'},
'uuid': mock.ANY,
'id': mock.ANY,
'action': 'CREATE',
'status': 'COMPLETE'})})
res = stack['res']
self.assertEqual({'foo': 'res', 'Foo': 'res'}, res.FnGetAtts())
def test_properties_data_stored_encrypted_decrypted_on_load(self): def test_properties_data_stored_encrypted_decrypted_on_load(self):
cfg.CONF.set_override('encrypt_parameters_and_properties', True) cfg.CONF.set_override('encrypt_parameters_and_properties', True)

View File

@ -1328,12 +1328,7 @@ class StackTest(common.HeatTestCase):
(rsrc.RESUME, rsrc.COMPLETE), (rsrc.RESUME, rsrc.COMPLETE),
(rsrc.UPDATE, rsrc.IN_PROGRESS), (rsrc.UPDATE, rsrc.IN_PROGRESS),
(rsrc.UPDATE, rsrc.FAILED), (rsrc.UPDATE, rsrc.FAILED),
(rsrc.UPDATE, rsrc.COMPLETE)): (rsrc.UPDATE, rsrc.COMPLETE),
rsrc.state_set(action, status)
self.stack._update_all_resource_data(False, True)
self.assertEqual('AResource',
self.stack.outputs['TestOutput'].get_value())
for action, status in (
(rsrc.DELETE, rsrc.IN_PROGRESS), (rsrc.DELETE, rsrc.IN_PROGRESS),
(rsrc.DELETE, rsrc.FAILED), (rsrc.DELETE, rsrc.FAILED),
(rsrc.DELETE, rsrc.COMPLETE)): (rsrc.DELETE, rsrc.COMPLETE)):
@ -2387,11 +2382,14 @@ class StackTest(common.HeatTestCase):
cache_data=cache_data) cache_data=cache_data)
# Check if the property has the appropriate resolved value. # Check if the property has the appropriate resolved value.
cached_property = lightweight_stack['bar'].properties['Foo'] bar = resource.Resource(
self.assertEqual(cached_property, 'baz') 'bar',
lightweight_stack.defn.resource_definition('bar'),
lightweight_stack)
self.assertEqual('baz', bar.properties['Foo'])
# Make sure FnGetAtt returns the cached value. # Make sure FnGetAtt returns the cached value.
attr_value = lightweight_stack['foo'].FnGetAtt('bar') attr_value = lightweight_stack.defn['foo'].FnGetAtt('bar')
self.assertEqual('baz', attr_value) self.assertEqual('baz', attr_value)
# Make sure calls are not made to the database to retrieve the # Make sure calls are not made to the database to retrieve the
@ -2427,11 +2425,14 @@ class StackTest(common.HeatTestCase):
cache_data=cache_data) cache_data=cache_data)
# Check if the property has the appropriate resolved value. # Check if the property has the appropriate resolved value.
cached_property = lightweight_stack['bar'].properties['Foo'] bar = resource.Resource(
self.assertEqual(cached_property, 'physical-resource-id') 'bar',
lightweight_stack.defn.resource_definition('bar'),
lightweight_stack)
self.assertEqual('physical-resource-id', bar.properties['Foo'])
# Make sure FnGetRefId returns the cached value. # Make sure FnGetRefId returns the cached value.
resource_id = lightweight_stack['foo'].FnGetRefId() resource_id = lightweight_stack.defn['foo'].FnGetRefId()
self.assertEqual('physical-resource-id', resource_id) self.assertEqual('physical-resource-id', resource_id)
# Make sure calls are not made to the database to retrieve the # Make sure calls are not made to the database to retrieve the

View File

@ -230,10 +230,11 @@ class DepAttrsTest(common.HeatTestCase):
template.Template(parsed_tmpl)) template.Template(parsed_tmpl))
for res in six.itervalues(self.stack): for res in six.itervalues(self.stack):
resources = six.itervalues(self.stack.resources) definitions = (self.stack.defn.resource_definition(n)
for n in parsed_tmpl['resources'])
self.assertEqual(self.expected[res.name], self.assertEqual(self.expected[res.name],
set(itertools.chain.from_iterable( set(itertools.chain.from_iterable(
r.t.dep_attrs(res.name) for r in resources))) d.dep_attrs(res.name) for d in definitions)))
class ReferencedAttrsTest(common.HeatTestCase): class ReferencedAttrsTest(common.HeatTestCase):

View File

@ -470,8 +470,8 @@ class StackResourceTest(StackResourceBaseTest):
})} })}
stack = parser.Stack(utils.dummy_context(), 'test_att', tmpl, stack = parser.Stack(utils.dummy_context(), 'test_att', tmpl,
cache_data=cache_data) cache_data=cache_data)
rsrc = stack['my_autoscaling_group'] rsrc = stack.defn['my_autoscaling_group']
self.assertEqual(4, rsrc.FnGetAtt(rsrc.CURRENT_SIZE)) self.assertEqual(4, rsrc.FnGetAtt('current_size'))
def test__validate_nested_resources_checks_num_of_resources(self): def test__validate_nested_resources_checks_num_of_resources(self):
stack_resource.cfg.CONF.set_override('max_resources_per_stack', 2) stack_resource.cfg.CONF.set_override('max_resources_per_stack', 2)

View File

@ -1269,17 +1269,9 @@ class StackUpdateTest(common.HeatTestCase):
'AResource', 'AResource',
self.stack['BResource']._stored_properties_data['Foo']) self.stack['BResource']._stored_properties_data['Foo'])
self.ref_id_called = False
def get_ref_id(*args):
ref_id = 'inst-007' if self.ref_id_called else 'AResource'
if self.ref_id_called is False:
self.ref_id_called = True
return ref_id
mock_id = self.patchobject(generic_rsrc.ResourceWithProps, mock_id = self.patchobject(generic_rsrc.ResourceWithProps,
'FnGetRefId', 'get_reference_id',
side_effect=get_ref_id) return_value='inst-007')
updated_stack = stack.Stack(self.ctx, 'updated_stack', updated_stack = stack.Stack(self.ctx, 'updated_stack',
template.Template(tmpl2)) template.Template(tmpl2))
@ -1293,7 +1285,6 @@ class StackUpdateTest(common.HeatTestCase):
'inst-007', 'inst-007',
self.stack['BResource']._stored_properties_data['Foo']) self.stack['BResource']._stored_properties_data['Foo'])
# Note: mock_id is called 14 times!!!
mock_id.assert_called_with() mock_id.assert_called_with()
def test_update_with_new_resources_with_reference(self): def test_update_with_new_resources_with_reference(self):
@ -1383,7 +1374,8 @@ class StackUpdateTest(common.HeatTestCase):
self.stack['BResource']._stored_properties_data['Foo']) self.stack['BResource']._stored_properties_data['Foo'])
mock_id = self.patchobject(generic_rsrc.ResourceWithProps, mock_id = self.patchobject(generic_rsrc.ResourceWithProps,
'FnGetRefId', return_value='AResource') 'get_reference_id',
return_value='AResource')
# mock to make the replace fail when creating the replacement resource # mock to make the replace fail when creating the replacement resource
mock_create = self.patchobject(generic_rsrc.ResourceWithProps, mock_create = self.patchobject(generic_rsrc.ResourceWithProps,

View File

@ -28,8 +28,10 @@ from heat.engine.clients.os import nova
from heat.engine import environment from heat.engine import environment
from heat.engine import function from heat.engine import function
from heat.engine.hot import template as hot_t from heat.engine.hot import template as hot_t
from heat.engine import node_data
from heat.engine import rsrc_defn from heat.engine import rsrc_defn
from heat.engine import stack from heat.engine import stack
from heat.engine import stk_defn
from heat.engine import template from heat.engine import template
from heat.tests import common from heat.tests import common
from heat.tests.openstack.nova import fakes as fakes_nova from heat.tests.openstack.nova import fakes as fakes_nova
@ -697,11 +699,12 @@ class TemplateTest(common.HeatTestCase):
@staticmethod @staticmethod
def resolve(snippet, template, stack=None): def resolve(snippet, template, stack=None):
return function.resolve(template.parse(stack, snippet)) return function.resolve(template.parse(stack and stack.defn, snippet))
@staticmethod @staticmethod
def resolve_condition(snippet, template, stack=None): def resolve_condition(snippet, template, stack=None):
return function.resolve(template.parse_condition(stack, snippet)) return function.resolve(template.parse_condition(stack and stack.defn,
snippet))
def test_defaults(self): def test_defaults(self):
empty = template.Template(empty_template) empty = template.Template(empty_template)
@ -900,21 +903,19 @@ class TemplateTest(common.HeatTestCase):
def test_resource_refs(self): def test_resource_refs(self):
tmpl = template.Template(resource_template) tmpl = template.Template(resource_template)
stk = stack.Stack(self.ctx, 'test', tmpl) stk = stack.Stack(self.ctx, 'test', tmpl)
stk.validate()
self.m.StubOutWithMock(stk['foo'], 'FnGetRefId') data = node_data.NodeData.from_dict({'reference_id': 'bar'})
stk['foo'].FnGetRefId().MultipleTimes().AndReturn('bar') stk_defn.update_resource_data(stk.defn, 'foo', data)
self.m.ReplayAll()
r_snippet = {"Ref": "foo"} r_snippet = {"Ref": "foo"}
self.assertEqual("bar", self.resolve(r_snippet, tmpl, stk)) self.assertEqual("bar", self.resolve(r_snippet, tmpl, stk))
self.m.VerifyAll()
def test_resource_refs_param(self): def test_resource_refs_param(self):
tmpl = template.Template(resource_template) tmpl = template.Template(resource_template)
stk = stack.Stack(self.ctx, 'test', tmpl) stk = stack.Stack(self.ctx, 'test', tmpl)
p_snippet = {"Ref": "baz"} p_snippet = {"Ref": "baz"}
parsed = tmpl.parse(stk, p_snippet) parsed = tmpl.parse(stk.defn, p_snippet)
self.assertIsInstance(parsed, cfn_funcs.ParamRef) self.assertIsInstance(parsed, cfn_funcs.ParamRef)
def test_select_from_list(self): def test_select_from_list(self):
@ -1654,7 +1655,7 @@ class ResolveDataTest(common.HeatTestCase):
template.Template(empty_template)) template.Template(empty_template))
def resolve(self, snippet): def resolve(self, snippet):
return function.resolve(self.stack.t.parse(self.stack, snippet)) return function.resolve(self.stack.t.parse(self.stack.defn, snippet))
def test_join_split(self): def test_join_split(self):
# join # join