Add integration tests for admin actions

Add integration tests for super admin actions.

Change-Id: I277f23800274729cf7128fdcb4521e4b221233cf
Partial-Bug: #1466694
diff --git a/common/config.py b/common/config.py
index e99d034..0397953 100644
--- a/common/config.py
+++ b/common/config.py
@@ -35,6 +35,9 @@
                default=(os.environ.get('OS_PROJECT_NAME') or
                         os.environ.get('OS_TENANT_NAME')),
                help="Tenant name to use for API requests."),
+    cfg.StrOpt('admin_tenant_name',
+               default='admin',
+               help="Admin tenant name to use for admin API requests."),
     cfg.StrOpt('auth_url',
                default=os.environ.get('OS_AUTH_URL'),
                help="Full URI of the OpenStack Identity API (Keystone)"),
diff --git a/common/test.py b/common/test.py
index 16d5920..c864d3b 100644
--- a/common/test.py
+++ b/common/test.py
@@ -81,8 +81,16 @@
                              'No username configured')
         self.assertIsNotNone(self.conf.password,
                              'No password configured')
+        self.setup_clients(self.conf)
+        self.useFixture(fixtures.FakeLogger(format=_LOG_FORMAT))
+        self.updated_time = {}
+        if self.conf.disable_ssl_certificate_validation:
+            self.verify_cert = False
+        else:
+            self.verify_cert = self.conf.ca_file or True
 
-        self.manager = clients.ClientManager(self.conf)
+    def setup_clients(self, conf):
+        self.manager = clients.ClientManager(conf)
         self.identity_client = self.manager.identity_client
         self.orchestration_client = self.manager.orchestration_client
         self.compute_client = self.manager.compute_client
@@ -90,12 +98,19 @@
         self.volume_client = self.manager.volume_client
         self.object_client = self.manager.object_client
         self.metering_client = self.manager.metering_client
-        self.useFixture(fixtures.FakeLogger(format=_LOG_FORMAT))
-        self.updated_time = {}
-        if self.conf.disable_ssl_certificate_validation:
-            self.verify_cert = False
-        else:
-            self.verify_cert = self.conf.ca_file or True
+
+        self.client = self.orchestration_client
+
+    def setup_clients_for_admin(self):
+        self.assertIsNotNone(self.conf.admin_username,
+                             'No admin username configured')
+        self.assertIsNotNone(self.conf.admin_password,
+                             'No admin password configured')
+        conf = config.init_conf()
+        conf.username = self.conf.admin_username
+        conf.password = self.conf.admin_password
+        conf.tenant_name = self.conf.admin_tenant_name
+        self.setup_clients(conf)
 
     def get_remote_client(self, server_or_ip, username, private_key=None):
         if isinstance(server_or_ip, six.string_types):
diff --git a/functional/functional_base.py b/functional/functional_base.py
index 9f76011..73ccf1d 100644
--- a/functional/functional_base.py
+++ b/functional/functional_base.py
@@ -20,7 +20,6 @@
     def setUp(self):
         super(FunctionalTestsBase, self).setUp()
         self.check_skip()
-        self.client = self.orchestration_client
 
     def check_skip(self):
         test_cls_name = reflection.get_class_name(self, fully_qualified=False)
diff --git a/functional/test_admin_actions.py b/functional/test_admin_actions.py
new file mode 100644
index 0000000..2c9ff6e
--- /dev/null
+++ b/functional/test_admin_actions.py
@@ -0,0 +1,101 @@
+#    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
+
+# Simple stack
+test_template = {
+    'heat_template_version': '2013-05-23',
+    'resources': {
+        'test1': {
+            'type': 'OS::Heat::TestResource',
+            'properties': {
+                'value': 'Test1'
+            }
+        }
+    }
+}
+
+# Nested stack
+rsg_template = {
+    'heat_template_version': '2013-05-23',
+    'resources': {
+        'random_group': {
+            'type': 'OS::Heat::ResourceGroup',
+            'properties': {
+                'count': 2,
+                'resource_def': {
+                    'type': 'OS::Heat::RandomString',
+                    'properties': {
+                        'length': 30,
+                        'salt': 'initial'
+                    }
+                }
+            }
+        }
+    }
+}
+
+
+class AdminActionsTest(functional_base.FunctionalTestsBase):
+
+    def setUp(self):
+        super(AdminActionsTest, self).setUp()
+        if not self.conf.admin_username or not self.conf.admin_password:
+            self.skipTest('No admin creds found, skipping')
+
+    def create_stack_setup_admin_client(self, template=test_template):
+        # Create the stack with the default user
+        self.stack_identifier = self.stack_create(template=template)
+
+        # Setup admin clients
+        self.setup_clients_for_admin()
+
+    def test_admin_simple_stack_actions(self):
+        self.create_stack_setup_admin_client()
+
+        updated_template = test_template.copy()
+        props = updated_template['resources']['test1']['properties']
+        props['value'] = 'new_value'
+
+        # Update, suspend and resume stack
+        self.update_stack(self.stack_identifier,
+                          template=updated_template)
+        self.stack_suspend(self.stack_identifier)
+        self.stack_resume(self.stack_identifier)
+
+        # List stack resources
+        initial_resources = {'test1': 'OS::Heat::TestResource'}
+        self.assertEqual(initial_resources,
+                         self.list_resources(self.stack_identifier))
+        # Delete stack
+        self._stack_delete(self.stack_identifier)
+
+    def test_admin_complex_stack_actions(self):
+        self.create_stack_setup_admin_client(template=rsg_template)
+
+        updated_template = rsg_template.copy()
+        props = updated_template['resources']['random_group']['properties']
+        props['count'] = 3
+
+        # Update, suspend and resume stack
+        self.update_stack(self.stack_identifier,
+                          template=updated_template)
+        self.stack_suspend(self.stack_identifier)
+        self.stack_resume(self.stack_identifier)
+
+        # List stack resources
+        resources = {'random_group': 'OS::Heat::ResourceGroup'}
+        self.assertEqual(resources,
+                         self.list_resources(self.stack_identifier))
+        # Delete stack
+        self._stack_delete(self.stack_identifier)
diff --git a/functional/test_encryption_vol_type.py b/functional/test_encryption_vol_type.py
index ed49249..b34b094 100644
--- a/functional/test_encryption_vol_type.py
+++ b/functional/test_encryption_vol_type.py
@@ -11,8 +11,6 @@
 #    under the License.
 
 
-from heat_integrationtests.common import clients
-from heat_integrationtests.common import config
 from heat_integrationtests.functional import functional_base
 
 test_encryption_vol_type = {
@@ -44,16 +42,10 @@
         super(EncryptionVolTypeTest, self).setUp()
         if not self.conf.admin_username or not self.conf.admin_password:
             self.skipTest('No admin creds found, skipping')
-        self.conf = config.init_conf()
         # cinder security policy usage of volume type is limited
         # to being used by administrators only.
-        # Temporarily switch to admin
-        self.conf.username = self.conf.admin_username
-        self.conf.password = self.conf.admin_password
-        self.conf.tenant_name = 'admin'
-        self.manager = clients.ClientManager(self.conf)
-        self.client = self.manager.orchestration_client
-        self.volume_client = self.manager.volume_client
+        # Switch to admin
+        self.setup_clients_for_admin()
 
     def check_stack(self, sid):
         vt = 'my_volume_type'
diff --git a/scenario/scenario_base.py b/scenario/scenario_base.py
index d41c9a1..df86e9e 100644
--- a/scenario/scenario_base.py
+++ b/scenario/scenario_base.py
@@ -21,8 +21,6 @@
     def setUp(self):
         super(ScenarioTestsBase, self).setUp()
         self.check_skip()
-
-        self.client = self.orchestration_client
         self.sub_dir = 'templates'
         self.assign_keypair()