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
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
def validate(self):

View File

@ -222,9 +222,7 @@ class GetAttThenSelect(function.Function):
return
attr = function.resolve(self._attribute)
from heat.engine import resource
if (type(res).get_attribute == resource.Resource.get_attribute and
attr not in res.attributes_schema):
if attr not in res.attributes_schema:
raise exception.InvalidTemplateAttribute(
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
# by invoking stack.resources. Maintain light-weight stack.
res_defn = resource_owning_stack.t.resource_definitions(
resource_owning_stack)[db_res.name]
res_defn = resource_owning_stack.defn.resource_definition(db_res.name)
resource = cls(db_res.name, res_defn, resource_owning_stack)
resource._load_data(db_res)
@ -1343,8 +1342,7 @@ class Resource(status.ResourceStatus):
self._calling_engine_id = engine_id
registry = new_stack.env.registry
new_res_def = new_stack.t.resource_definitions(
new_stack)[self.name]
new_res_def = new_stack.defn.resource_definition(self.name)
new_res_type = registry.get_class_to_instantiate(
new_res_def.resource_type, resource_name=self.name)
restricted_actions = registry.get_rsrc_restricted_actions(

View File

@ -309,7 +309,7 @@ class InstanceGroup(stack_resource.StackResource):
def changing_instances(tmpl):
instances = grouputils.get_members(self)
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
affected = set(k for k, v in current ^ updated)
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))
test_tmpl = self._assemble_nested([first_name],
include_all=True)
res_def = next(six.itervalues(
test_tmpl.resource_definitions(self.stack)))
res_def = next(six.itervalues(test_tmpl.resource_definitions(None)))
# make sure we can resolve the nested resource type
self.stack.env.get_class_to_instantiate(res_def.resource_type)

View File

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

View File

@ -166,7 +166,7 @@ class TestAutoScalingPolicy(common.HeatTestCase):
'reference_id': 'convg_xyz'
})}
stack = utils.parse_stack(t, cache_data=cache_data)
rsrc = stack['my-policy']
rsrc = stack.defn['my-policy']
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,
cache_data=cache_data)
rsrc = stack['LaunchConfig']
rsrc = stack.defn['LaunchConfig']
self.assertEqual('convg_xyz', rsrc.FnGetRefId())
def test_launch_config_create_with_instanceid(self):

View File

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

View File

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

View File

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

View File

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

View File

@ -73,7 +73,7 @@ class BaseVolumeTest(common.HeatTestCase):
data['Properties']['AvailabilityZone'] = 'nova'
Volume = aws_vol.Volume
vol = Volume(resource_name,
stack.t.resource_definitions(stack)[resource_name],
stack.defn.resource_definition(resource_name),
stack)
return vol
@ -94,9 +94,8 @@ class BaseVolumeTest(common.HeatTestCase):
Attachment = os_vol.CinderVolumeAttachment
else:
Attachment = aws_vol.VolumeAttachment
resource_defns = stack.t.resource_definitions(stack)
rsrc = Attachment(resource_name,
resource_defns[resource_name],
stack.defn.resource_definition(resource_name),
stack)
self.assertIsNone(rsrc.validate())
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 import rsrc_defn
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 import common
from heat.tests import utils
@ -320,7 +320,7 @@ class LoadbalancerReloadTest(common.HeatTestCase):
properties = t['Resources']['ElasticLoadBalancer']['Properties']
properties['AvailabilityZones'] = {'Fn::GetAZs': ''}
self.patchobject(parser.Stack, 'get_availability_zones',
self.patchobject(stk_defn.StackDefinition, 'get_availability_zones',
return_value=['abc', 'xyz'])
mock_members = self.patchobject(grouputils, 'get_member_refids')

View File

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

View File

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

View File

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

View File

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

View File

@ -1104,7 +1104,8 @@ class SoftwareDeploymentTest(common.HeatTestCase):
'attrs': {'foo': 'bar'}
})}
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):
self._create_stack(self.template)

View File

@ -291,7 +291,7 @@ class SwiftSignalHandleTest(common.HeatTestCase):
})
}
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())

View File

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

View File

@ -296,7 +296,7 @@ class NeutronFloatingIPTest(common.HeatTestCase):
'status': 'COMPLETE',
'reference_id': 'abc'})})
rsrc = stack['floating_ip']
rsrc = stack.defn['floating_ip']
self.assertEqual('abc', rsrc.FnGetRefId())
def test_floatip_association_port(self):
@ -449,7 +449,7 @@ class NeutronFloatingIPTest(common.HeatTestCase):
update_port_id = '2146dfbf-ba77-4083-8e86-d052f671ece5'
props['port_id'] = update_port_id
update_snippet = rsrc_defn.ResourceDefinition(fipa.name, fipa.type(),
stack.t.parse(stack,
stack.t.parse(stack.defn,
props))
scheduler.TaskRunner(fipa.update, update_snippet)()
@ -708,7 +708,7 @@ class NeutronFloatingIPTest(common.HeatTestCase):
update_port_id = '2146dfbf-ba77-4083-8e86-d052f671ece5'
props['port_id'] = update_port_id
update_snippet = rsrc_defn.ResourceDefinition(fip.name, fip.type(),
stack.t.parse(stack,
stack.t.parse(stack.defn,
props))
scheduler.TaskRunner(fip.update, update_snippet)()
self.assertEqual((fip.UPDATE, fip.COMPLETE), fip.state)
@ -718,7 +718,7 @@ class NeutronFloatingIPTest(common.HeatTestCase):
props = copy.deepcopy(fip.properties.data)
del(props['port_id'])
update_snippet = rsrc_defn.ResourceDefinition(fip.name, fip.type(),
stack.t.parse(stack,
stack.t.parse(stack.defn,
props))
scheduler.TaskRunner(fip.update, update_snippet)()
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 openstacksdk
from heat.engine.hot import functions as hot_funcs
from heat.engine import node_data
from heat.engine import resource
from heat.engine.resources.openstack.neutron import subnet
from heat.engine import rsrc_defn
from heat.engine import scheduler
from heat.engine import stk_defn
from heat.tests import common
from heat.tests import utils
@ -682,9 +684,10 @@ class NeutronSubnetTest(common.HeatTestCase):
"""
t = template_format.parse(template)
stack = utils.parse_stack(t)
self.patchobject(stack['net'], 'FnGetRefId',
return_value='fc68ea2c-b60b-4b4f-bd82-94ec81110766')
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 = {
"subnet": {
"id": "91e47a57-7508-46fe-afc9-fc454e8580e1",
@ -696,6 +699,7 @@ class NeutronSubnetTest(common.HeatTestCase):
}
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'))
self.assertIsNone(rsrc.properties.get('network_id'))

View File

@ -369,7 +369,7 @@ class NeutronTrunkTest(common.HeatTestCase):
t = template_format.parse(update_template)
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)
scheduler.TaskRunner(rsrc.create)()
self.assertEqual((rsrc.CREATE, rsrc.COMPLETE), rsrc.state)
@ -390,7 +390,7 @@ class NeutronTrunkTest(common.HeatTestCase):
t = template_format.parse(update_template)
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)
scheduler.TaskRunner(rsrc.create)()
self.assertEqual((rsrc.CREATE, rsrc.COMPLETE), rsrc.state)
@ -411,7 +411,7 @@ class NeutronTrunkTest(common.HeatTestCase):
t = template_format.parse(update_template)
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)
scheduler.TaskRunner(rsrc.create)()
self.assertEqual((rsrc.CREATE, rsrc.COMPLETE), rsrc.state)
@ -440,7 +440,7 @@ class NeutronTrunkTest(common.HeatTestCase):
t = template_format.parse(update_template)
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)
scheduler.TaskRunner(rsrc.create)()
self.assertEqual((rsrc.CREATE, rsrc.COMPLETE), rsrc.state)

View File

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

View File

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

View File

@ -472,7 +472,7 @@ class SwiftTest(common.HeatTestCase):
'reference_id': 'xyz_convg'
})}
stack = utils.parse_stack(self.t, cache_data=cache_data)
rsrc = stack['SwiftContainer']
rsrc = stack.defn['SwiftContainer']
self.assertEqual('xyz_convg', rsrc.FnGetRefId())
@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 rsrc_defn
from heat.engine import stack
from heat.engine import stk_defn
from heat.engine import template
from heat.tests import common
from heat.tests import utils
@ -241,25 +242,38 @@ class ValidateGetAttTest(common.HeatTestCase):
env.load({u'resource_registry':
{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(
utils.dummy_context(), 'test_stack',
template.Template({"HeatTemplateFormatVersion": "2012-12-12"},
env=env),
tmpl,
stack_id=str(uuid.uuid4()))
res_defn = rsrc_defn.ResourceDefinition('test_rsrc',
'OS::Test::GenericResource')
self.rsrc = resource.Resource('test_rsrc', res_defn, self.stack)
self.stack.add_resource(self.rsrc)
self.rsrc = self.stack['test_rsrc']
self.stack.validate()
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.assertIsNone(func.validate())
def test_resource_is_not_appear_in_stack(self):
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'])
ex = self.assertRaises(exception.InvalidTemplateReference,
func.validate)
@ -267,7 +281,15 @@ class ValidateGetAttTest(common.HeatTestCase):
'is incorrect.', six.text_type(ex))
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'])
ex = self.assertRaises(exception.InvalidTemplateAttribute,
func.validate)
@ -278,16 +300,19 @@ class ValidateGetAttTest(common.HeatTestCase):
res_defn = rsrc_defn.ResourceDefinition('test_rsrc',
'OS::Test::FakeResource')
self.rsrc = resource.Resource('test_rsrc', res_defn, self.stack)
self.stack.add_resource(self.rsrc)
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.assertIsNone(func.validate())
def test_get_attr_without_attribute_name(self):
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 '
'of the form [resource_name, attribute]',
six.text_type(ex))

View File

@ -30,6 +30,7 @@ from heat.engine import resource
from heat.engine import resources
from heat.engine import rsrc_defn
from heat.engine import stack as parser
from heat.engine import stk_defn
from heat.engine import template
from heat.tests import common
from heat.tests import generic_resource as generic_rsrc
@ -162,11 +163,12 @@ class HOTemplateTest(common.HeatTestCase):
@staticmethod
def resolve(snippet, template, stack=None):
return function.resolve(template.parse(stack, snippet))
return function.resolve(template.parse(stack and stack.defn, snippet))
@staticmethod
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):
"""Test default content behavior of HOT template."""
@ -1913,7 +1915,7 @@ conditions:
self.assertRaisesRegex(exception.StackValidationFailed,
regxp,
function.validate,
stack.t.parse(stack, snippet))
stack.t.parse(stack.defn, snippet))
def test_add_resource(self):
hot_tpl = template_format.parse('''
@ -2349,7 +2351,7 @@ class HotStackTest(common.HeatTestCase):
self.ctx = utils.dummy_context()
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):
"""Test repeat function with get_attr function as an argument."""
@ -2358,7 +2360,7 @@ class HotStackTest(common.HeatTestCase):
snippet = {'repeat': {'template': 'this is %var%',
'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()
with mock.patch.object(rsrc_defn.ResourceDefinition,
@ -2724,7 +2726,8 @@ class StackAttributesTest(common.HeatTestCase):
template.Template(self.hot_tpl))
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.assertEqual((parser.Stack.CREATE, parser.Stack.COMPLETE),
@ -2748,177 +2751,16 @@ class StackAttributesTest(common.HeatTestCase):
(rsrc.ADOPT, rsrc.COMPLETE)):
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))
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):
def setUp(self):
@ -3067,7 +2909,8 @@ class StackParametersTest(common.HeatTestCase):
stack_id='1ba8c334-2297-4312-8c7c-43763a988ced',
tenant_id='9913ef0a-b8be-4b33-b574-9061441bd373')
self.assertEqual(self.expected,
function.resolve(tmpl.parse(stack, self.snippet)))
function.resolve(tmpl.parse(stack.defn,
self.snippet)))
class HOTParamValidatorTest(common.HeatTestCase):
@ -3598,13 +3441,20 @@ class TestGetAttAllAttributes(common.HeatTestCase):
]
@staticmethod
def resolve(snippet, template, stack=None):
return function.resolve(template.parse(stack, snippet))
def resolve(snippet, template, stack):
return function.resolve(template.parse(stack.defn, snippet))
def test_get_attr_all_attributes(self):
tmpl = template.Template(self.hot_tpl)
stack = parser.Stack(utils.dummy_context(), 'test_get_attr', tmpl)
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()
self.assertEqual((parser.Stack.CREATE, parser.Stack.COMPLETE),
@ -3628,6 +3478,12 @@ class TestGetAttAllAttributes(common.HeatTestCase):
(rsrc.ADOPT, rsrc.COMPLETE)):
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:
ex = self.assertRaises(self.raises,
self.resolve, self.snippet, tmpl, stack)

View File

@ -269,7 +269,10 @@ class WaitConditionMetadataUpdateTest(common.HeatTestCase):
update_metadata('123', 'foo', 'bar')
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
check_empty(sleep_time)
else:
@ -308,7 +311,7 @@ class MetadataRefreshServerTest(common.HeatTestCase):
return_value=1)
@mock.patch.object(server.Server, 'handle_create')
@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,
mock_handle, *args):
temp = template_format.parse(TEST_TEMPLATE_SERVER)
@ -321,7 +324,7 @@ class MetadataRefreshServerTest(common.HeatTestCase):
self.stub_KeypairConstraint_validate()
# Note dummy addresses are from TEST-NET-1 ref rfc5737
mock_get.side_effect = ['192.0.2.1', '192.0.2.2', '192.0.2.2']
mock_get.side_effect = ['192.0.2.1', '192.0.2.2']
# Test
stack.create()

View File

@ -286,7 +286,7 @@ Resources:
'reference_id': 'the_nested_convg_mock'
})}
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())
def test_get_attribute(self):

View File

@ -1910,7 +1910,7 @@ class ResourceTest(common.HeatTestCase):
'action': 'CREATE',
'status': 'COMPLETE'})})
res = stack['res']
res = stack.defn['res']
self.assertEqual('Res', res.FnGetAtt('Foo'))
def test_getatt_with_path_cache_data(self):
@ -1932,50 +1932,9 @@ class ResourceTest(common.HeatTestCase):
'action': 'CREATE',
'status': 'COMPLETE'})})
res = stack['res']
res = stack.defn['res']
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):
cfg.CONF.set_override('encrypt_parameters_and_properties', True)

View File

@ -1328,12 +1328,7 @@ class StackTest(common.HeatTestCase):
(rsrc.RESUME, rsrc.COMPLETE),
(rsrc.UPDATE, rsrc.IN_PROGRESS),
(rsrc.UPDATE, rsrc.FAILED),
(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.UPDATE, rsrc.COMPLETE),
(rsrc.DELETE, rsrc.IN_PROGRESS),
(rsrc.DELETE, rsrc.FAILED),
(rsrc.DELETE, rsrc.COMPLETE)):
@ -2387,11 +2382,14 @@ class StackTest(common.HeatTestCase):
cache_data=cache_data)
# Check if the property has the appropriate resolved value.
cached_property = lightweight_stack['bar'].properties['Foo']
self.assertEqual(cached_property, 'baz')
bar = resource.Resource(
'bar',
lightweight_stack.defn.resource_definition('bar'),
lightweight_stack)
self.assertEqual('baz', bar.properties['Foo'])
# 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)
# Make sure calls are not made to the database to retrieve the
@ -2427,11 +2425,14 @@ class StackTest(common.HeatTestCase):
cache_data=cache_data)
# Check if the property has the appropriate resolved value.
cached_property = lightweight_stack['bar'].properties['Foo']
self.assertEqual(cached_property, 'physical-resource-id')
bar = resource.Resource(
'bar',
lightweight_stack.defn.resource_definition('bar'),
lightweight_stack)
self.assertEqual('physical-resource-id', bar.properties['Foo'])
# 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)
# 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))
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],
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):

View File

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

View File

@ -1269,17 +1269,9 @@ class StackUpdateTest(common.HeatTestCase):
'AResource',
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,
'FnGetRefId',
side_effect=get_ref_id)
'get_reference_id',
return_value='inst-007')
updated_stack = stack.Stack(self.ctx, 'updated_stack',
template.Template(tmpl2))
@ -1293,7 +1285,6 @@ class StackUpdateTest(common.HeatTestCase):
'inst-007',
self.stack['BResource']._stored_properties_data['Foo'])
# Note: mock_id is called 14 times!!!
mock_id.assert_called_with()
def test_update_with_new_resources_with_reference(self):
@ -1383,7 +1374,8 @@ class StackUpdateTest(common.HeatTestCase):
self.stack['BResource']._stored_properties_data['Foo'])
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_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 function
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 stack
from heat.engine import stk_defn
from heat.engine import template
from heat.tests import common
from heat.tests.openstack.nova import fakes as fakes_nova
@ -697,11 +699,12 @@ class TemplateTest(common.HeatTestCase):
@staticmethod
def resolve(snippet, template, stack=None):
return function.resolve(template.parse(stack, snippet))
return function.resolve(template.parse(stack and stack.defn, snippet))
@staticmethod
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):
empty = template.Template(empty_template)
@ -900,21 +903,19 @@ class TemplateTest(common.HeatTestCase):
def test_resource_refs(self):
tmpl = template.Template(resource_template)
stk = stack.Stack(self.ctx, 'test', tmpl)
stk.validate()
self.m.StubOutWithMock(stk['foo'], 'FnGetRefId')
stk['foo'].FnGetRefId().MultipleTimes().AndReturn('bar')
self.m.ReplayAll()
data = node_data.NodeData.from_dict({'reference_id': 'bar'})
stk_defn.update_resource_data(stk.defn, 'foo', data)
r_snippet = {"Ref": "foo"}
self.assertEqual("bar", self.resolve(r_snippet, tmpl, stk))
self.m.VerifyAll()
def test_resource_refs_param(self):
tmpl = template.Template(resource_template)
stk = stack.Stack(self.ctx, 'test', tmpl)
p_snippet = {"Ref": "baz"}
parsed = tmpl.parse(stk, p_snippet)
parsed = tmpl.parse(stk.defn, p_snippet)
self.assertIsInstance(parsed, cfn_funcs.ParamRef)
def test_select_from_list(self):
@ -1654,7 +1655,7 @@ class ResolveDataTest(common.HeatTestCase):
template.Template(empty_template))
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):
# join