Merge "Don't resolve outputs during polling stack status"
diff --git a/common/test.py b/common/test.py
index 1848803..f6889ab 100644
--- a/common/test.py
+++ b/common/test.py
@@ -477,7 +477,8 @@
def stack_create(self, stack_name=None, template=None, files=None,
parameters=None, environment=None, tags=None,
expected_status='CREATE_COMPLETE',
- disable_rollback=True, enable_cleanup=True):
+ disable_rollback=True, enable_cleanup=True,
+ environment_files=None):
name = stack_name or self._stack_rand_name()
templ = template or self.template
templ_files = files or {}
@@ -490,7 +491,8 @@
disable_rollback=disable_rollback,
parameters=params,
environment=env,
- tags=tags
+ tags=tags,
+ environment_files=environment_files
)
if expected_status not in ['ROLLBACK_COMPLETE'] and enable_cleanup:
self.addCleanup(self._stack_delete, name)
diff --git a/functional/test_aws_stack.py b/functional/test_aws_stack.py
index 9649a02..13c4278 100644
--- a/functional/test_aws_stack.py
+++ b/functional/test_aws_stack.py
@@ -115,7 +115,7 @@
def test_nested_stack_create_with_timeout(self):
url = self.publish_template(self.nested_template)
self.template = self.test_template.replace('the.yaml', url)
- timeout_template = yaml.load(self.template)
+ timeout_template = yaml.safe_load(self.template)
props = timeout_template['Resources']['the_nested']['Properties']
props['TimeoutInMinutes'] = '50'
@@ -142,7 +142,7 @@
}
},
"environment": {"parameters": {}},
- "template": yaml.load(self.template)
+ "template": yaml.safe_load(self.template)
}
stack_identifier = self.stack_adopt(adopt_data=json.dumps(adopt_data))
@@ -163,7 +163,7 @@
}
},
"environment": {"parameters": {}},
- "template": yaml.load(self.template)
+ "template": yaml.safe_load(self.template)
}
stack_identifier = self.stack_adopt(adopt_data=json.dumps(adopt_data),
@@ -180,7 +180,7 @@
stack = self.client.stacks.get(stack_identifier)
self.assertEqual('bar', self._stack_output(stack, 'output_foo'))
- new_template = yaml.load(self.template)
+ new_template = yaml.safe_load(self.template)
props = new_template['Resources']['the_nested']['Properties']
props['TemplateURL'] = self.publish_template(self.update_template,
cleanup=False)
diff --git a/functional/test_conditional_exposure.py b/functional/test_conditional_exposure.py
index c1175f1..f1b7d97 100644
--- a/functional/test_conditional_exposure.py
+++ b/functional/test_conditional_exposure.py
@@ -76,6 +76,20 @@
ram: 20000
vcpus: 10
"""
+ fl_tmpl_nested = """
+heat_template_version: 2015-10-15
+
+resources:
+ not4everyonerg:
+ type: OS::Heat::ResourceGroup
+ properties:
+ count: 1
+ resource_def:
+ type: OS::Nova::Flavor
+ properties:
+ ram: 20000
+ vcpus: 10
+"""
def test_non_admin_forbidden_create_flavors(self):
"""Fail to create Flavor resource w/o admin role.
@@ -91,6 +105,14 @@
template=self.fl_tmpl)
self.assertIn(self.forbidden_resource_type, ex.message)
+ def test_non_admin_forbidden_create_flavors_nested(self):
+ stack_name = self._stack_rand_name()
+ ex = self.assertRaises(exc.Forbidden,
+ self.client.stacks.create,
+ stack_name=stack_name,
+ template=self.fl_tmpl_nested)
+ self.assertIn(self.forbidden_resource_type, ex.message)
+
def test_forbidden_resource_not_listed(self):
resources = self.client.resource_types.list()
self.assertNotIn(self.forbidden_resource_type,
diff --git a/functional/test_default_parameters.py b/functional/test_default_parameters.py
index 3e00c35..a33823f 100644
--- a/functional/test_default_parameters.py
+++ b/functional/test_default_parameters.py
@@ -75,7 +75,7 @@
if not self.temp_def:
# remove the default from the parameter in the nested template.
- ntempl = yaml.load(self.nested_template)
+ ntempl = yaml.safe_load(self.nested_template)
del ntempl['parameters']['length']['default']
nested_template = yaml.dump(ntempl)
else:
diff --git a/functional/test_env_merge.py b/functional/test_env_merge.py
new file mode 100644
index 0000000..5e222b8
--- /dev/null
+++ b/functional/test_env_merge.py
@@ -0,0 +1,95 @@
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+from heat_integrationtests.functional import functional_base
+
+
+TEMPLATE = '''
+ heat_template_version: 2015-04-30
+ parameters:
+ p0:
+ type: string
+ default: CORRECT
+ p1:
+ type: string
+ default: INCORRECT
+ p2:
+ type: string
+ default: INCORRECT
+ resources:
+ r1:
+ type: test::R1
+ r2:
+ type: test::R2
+ r3a:
+ type: test::R3
+ r3b:
+ type: test::R3
+'''
+
+ENV_1 = '''
+ parameters:
+ p1: CORRECT
+ p2: INCORRECT-E1
+ resource_registry:
+ test::R1: OS::Heat::RandomString
+ test::R2: BROKEN
+ test::R3: OS::Heat::None
+'''
+
+ENV_2 = '''
+ parameters:
+ p2: CORRECT
+ resource_registry:
+ test::R2: OS::Heat::RandomString
+ resources:
+ r3b:
+ test::R3: OS::Heat::RandomString
+'''
+
+
+class EnvironmentMergingTests(functional_base.FunctionalTestsBase):
+
+ def test_server_environment_merging(self):
+
+ # Setup
+ files = {'env1.yaml': ENV_1, 'env2.yaml': ENV_2}
+ environment_files = ['env1.yaml', 'env2.yaml']
+
+ # Test
+ stack_id = self.stack_create(stack_name='env_merge',
+ template=TEMPLATE,
+ files=files,
+ environment_files=environment_files)
+
+ # Verify
+
+ # Since there is no environment show, the registry overriding
+ # is partially verified by there being no error. If it wasn't
+ # working, test::R2 would remain mapped to BROKEN in env1.
+
+ # Sanity check
+ resources = self.list_resources(stack_id)
+ self.assertEqual(4, len(resources))
+
+ # Verify the parameters are correctly set
+ stack = self.client.stacks.get(stack_id)
+ self.assertEqual('CORRECT', stack.parameters['p0'])
+ self.assertEqual('CORRECT', stack.parameters['p1'])
+ self.assertEqual('CORRECT', stack.parameters['p2'])
+
+ # Verify that r3b has been overridden into a RandomString
+ # by checking to see that it has a value
+ r3b = self.client.resources.get(stack_id, 'r3b')
+ r3b_attrs = r3b.attributes
+ self.assertTrue('value' in r3b_attrs)
diff --git a/functional/test_nova_server_networks.py b/functional/test_nova_server_networks.py
index 99311d0..ae550b2 100644
--- a/functional/test_nova_server_networks.py
+++ b/functional/test_nova_server_networks.py
@@ -64,3 +64,25 @@
parameters=parms)
networks = self.get_outputs(stack_identifier, 'networks')
self.assertEqual(['11.11.11.11'], networks['my_net'])
+
+ def test_create_update_server_with_subnet(self):
+ parms = {'flavor': self.conf.minimal_instance_type,
+ 'image': self.conf.minimal_image_ref}
+ template = server_with_sub_fixed_ip_template.replace(
+ 'fixed_ip: 11.11.11.11', 'fixed_ip: 11.11.11.22')
+ stack_identifier = self.stack_create(
+ template=template,
+ stack_name='create_server_with_sub_ip',
+ parameters=parms)
+ networks = self.get_outputs(stack_identifier, 'networks')
+ self.assertEqual(['11.11.11.22'], networks['my_net'])
+
+ # update the server only with subnet, we won't pass
+ # both port_id and net_id to attach interface, then update success
+ template_only_subnet = template.replace(
+ 'fixed_ip: 11.11.11.22', '')
+ self.update_stack(stack_identifier,
+ template_only_subnet,
+ parameters=parms)
+ new_networks = self.get_outputs(stack_identifier, 'networks')
+ self.assertNotEqual(['11.11.11.22'], new_networks['my_net'])
diff --git a/functional/test_resource_group.py b/functional/test_resource_group.py
index e40376c..1e9edd5 100644
--- a/functional/test_resource_group.py
+++ b/functional/test_resource_group.py
@@ -419,7 +419,7 @@
super(ResourceGroupAdoptTest, self).setUp()
def _yaml_to_json(self, yaml_templ):
- return yaml.load(yaml_templ)
+ return yaml.safe_load(yaml_templ)
def test_adopt(self):
data = {
@@ -455,7 +455,7 @@
}
},
"environment": {"parameters": {}},
- "template": yaml.load(self.main_template)
+ "template": yaml.safe_load(self.main_template)
}
stack_identifier = self.stack_adopt(
adopt_data=json.dumps(data))
@@ -556,7 +556,7 @@
Simple rolling update with no conflict in batch size
and minimum instances in service.
"""
- updt_template = yaml.load(copy.deepcopy(self.template))
+ updt_template = yaml.safe_load(copy.deepcopy(self.template))
grp = updt_template['resources']['random_group']
policy = grp['update_policy']['rolling_update']
policy['min_in_service'] = '1'
@@ -575,7 +575,7 @@
Simple rolling update replace with no conflict in batch size
and minimum instances in service.
"""
- updt_template = yaml.load(copy.deepcopy(self.template))
+ updt_template = yaml.safe_load(copy.deepcopy(self.template))
grp = updt_template['resources']['random_group']
policy = grp['update_policy']['rolling_update']
policy['min_in_service'] = '1'
@@ -594,7 +594,7 @@
Simple rolling update with reduced size.
"""
- updt_template = yaml.load(copy.deepcopy(self.template))
+ updt_template = yaml.safe_load(copy.deepcopy(self.template))
grp = updt_template['resources']['random_group']
policy = grp['update_policy']['rolling_update']
policy['min_in_service'] = '1'
@@ -613,7 +613,7 @@
Simple rolling update with increased size.
"""
- updt_template = yaml.load(copy.deepcopy(self.template))
+ updt_template = yaml.safe_load(copy.deepcopy(self.template))
grp = updt_template['resources']['random_group']
policy = grp['update_policy']['rolling_update']
policy['min_in_service'] = '1'
@@ -632,7 +632,7 @@
Update with capacity adjustment with enough resources.
"""
- updt_template = yaml.load(copy.deepcopy(self.template))
+ updt_template = yaml.safe_load(copy.deepcopy(self.template))
grp = updt_template['resources']['random_group']
policy = grp['update_policy']['rolling_update']
policy['min_in_service'] = '8'
@@ -652,7 +652,7 @@
Rolling update with capacity adjustment due to conflict in
batch size and minimum instances in service.
"""
- updt_template = yaml.load(copy.deepcopy(self.template))
+ updt_template = yaml.safe_load(copy.deepcopy(self.template))
grp = updt_template['resources']['random_group']
policy = grp['update_policy']['rolling_update']
policy['min_in_service'] = '8'
@@ -671,7 +671,7 @@
Rolling Update with a huge batch size(more than
current size).
"""
- updt_template = yaml.load(copy.deepcopy(self.template))
+ updt_template = yaml.safe_load(copy.deepcopy(self.template))
grp = updt_template['resources']['random_group']
policy = grp['update_policy']['rolling_update']
policy['min_in_service'] = '0'
@@ -689,7 +689,7 @@
Rolling Update with a huge number of minimum instances
in service.
"""
- updt_template = yaml.load(copy.deepcopy(self.template))
+ updt_template = yaml.safe_load(copy.deepcopy(self.template))
grp = updt_template['resources']['random_group']
policy = grp['update_policy']['rolling_update']
policy['min_in_service'] = '20'
diff --git a/functional/test_template_resource.py b/functional/test_template_resource.py
index 9249a6e..fa34e2e 100644
--- a/functional/test_template_resource.py
+++ b/functional/test_template_resource.py
@@ -602,7 +602,7 @@
super(TemplateResourceAdoptTest, self).setUp()
def _yaml_to_json(self, yaml_templ):
- return yaml.load(yaml_templ)
+ return yaml.safe_load(yaml_templ)
def test_abandon(self):
stack_identifier = self.stack_create(
@@ -635,7 +635,7 @@
}
},
"environment": {"parameters": {}},
- "template": yaml.load(self.main_template)
+ "template": yaml.safe_load(self.main_template)
}
stack_identifier = self.stack_adopt(
diff --git a/scenario/test_autoscaling_lb.py b/scenario/test_autoscaling_lb.py
index 080f17f..e3de091 100644
--- a/scenario/test_autoscaling_lb.py
+++ b/scenario/test_autoscaling_lb.py
@@ -38,7 +38,11 @@
resp = set()
for count in range(retries):
time.sleep(1)
- r = requests.get(url)
+ try:
+ r = requests.get(url)
+ except requests.exceptions.ConnectionError:
+ # The LB may not be up yet, let's retry
+ continue
# skip unsuccessful requests
if r.status_code == 200:
resp.add(r.text)