Add a test for environment change in failed update

Add a functional test which verifies that adding a new resource during
an update, with a new custom resource type mapping in the environment,
allows for recovery when the update fails.

Change-Id: I7e52703b7f45c79a3a1434200d1e49988e78f333
Related-Bug: 1508096
diff --git a/functional/test_create_update.py b/functional/test_create_update.py
index 153eb9f..b86b163 100644
--- a/functional/test_create_update.py
+++ b/functional/test_create_update.py
@@ -501,3 +501,35 @@
                           existing=True)
         self.assertEqual({u'aresource': u'OS::Heat::TestResource'},
                          self.list_resources(stack_identifier))
+
+    def test_stack_update_with_new_env(self):
+        """Update handles new resource types in the environment.
+
+        If a resource type appears during an update and the update fails,
+        retrying the update is able to find the type properly in the
+        environment.
+        """
+        stack_identifier = self.stack_create(
+            template=test_template_one_resource)
+
+        # Update with a new resource and make the update fails
+        template = _change_rsrc_properties(test_template_one_resource,
+                                           ['test1'], {'fail': True})
+        template['resources']['test2'] = {'type': 'My::TestResource'}
+        template['resources']['test1']['depends_on'] = 'test2'
+        env = {'resource_registry':
+               {'My::TestResource': 'OS::Heat::TestResource'}}
+        self.update_stack(stack_identifier,
+                          template=template,
+                          environment=env,
+                          expected_status='UPDATE_FAILED')
+
+        # Fixing the template should fix the stack
+        template = _change_rsrc_properties(template,
+                                           ['test1'], {'fail': False})
+        self.update_stack(stack_identifier,
+                          template=template,
+                          environment=env)
+        self.assertEqual({'test1': 'OS::Heat::TestResource',
+                          'test2': 'My::TestResource'},
+                         self.list_resources(stack_identifier))