Merge "Add config entries to skip integration tests"
diff --git a/common/config.py b/common/config.py
index 5a33590..c7a324b 100644
--- a/common/config.py
+++ b/common/config.py
@@ -94,21 +94,24 @@
     cfg.IntOpt('tenant_network_mask_bits',
                default=28,
                help="The mask bits for tenant ipv4 subnets"),
-    cfg.BoolOpt('skip_software_config_tests',
-                default=True,
-                help="Skip software config deployment tests"),
+    cfg.BoolOpt('skip_scenario_tests',
+                default=False,
+                help="Skip all scenario tests"),
+    cfg.BoolOpt('skip_functional_tests',
+                default=False,
+                help="Skip all functional tests"),
+    cfg.ListOpt('skip_functional_test_list',
+                help="List of functional test class names to skip "
+                     "ex. AutoscalingGroupTest, CreateStackTest"),
+    cfg.ListOpt('skip_scenario_test_list',
+                help="List of scenario test class names to skip "
+                     "ex. NeutronLoadBalancerTest,"),
+    cfg.ListOpt('skip_test_stack_action_list',
+                help="List of stack actions in tests to skip "
+                     "ex. ABANDON, ADOPT, SUSPEND, RESUME"),
     cfg.IntOpt('volume_size',
                default=1,
                help='Default size in GB for volumes created by volumes tests'),
-    cfg.BoolOpt('skip_stack_adopt_tests',
-                default=False,
-                help="Skip Stack Adopt Integration tests"),
-    cfg.BoolOpt('skip_stack_abandon_tests',
-                default=False,
-                help="Skip Stack Abandon Integration tests"),
-    cfg.BoolOpt('skip_notification_tests',
-                default=False,
-                help="Skip Notification Integration tests"),
     cfg.IntOpt('connectivity_timeout',
                default=120,
                help="Timeout in seconds to wait for connectivity to "
diff --git a/common/test.py b/common/test.py
index 584af6d..747a76e 100644
--- a/common/test.py
+++ b/common/test.py
@@ -443,7 +443,8 @@
     def stack_adopt(self, stack_name=None, files=None,
                     parameters=None, environment=None, adopt_data=None,
                     wait_for_status='ADOPT_COMPLETE'):
-        if self.conf.skip_stack_adopt_tests:
+        if (self.conf.skip_test_stack_action_list and
+                'ADOPT' in self.conf.skip_test_stack_action_list):
             self.skipTest('Testing Stack adopt disabled in conf, skipping')
         name = stack_name or self._stack_rand_name()
         templ_files = files or {}
@@ -465,7 +466,8 @@
         return stack_identifier
 
     def stack_abandon(self, stack_id):
-        if self.conf.skip_stack_abandon_tests:
+        if (self.conf.skip_test_stack_action_list and
+                'ABANDON' in self.conf.skip_test_stack_action_list):
             self.addCleanup(self.client.stacks.delete, stack_id)
             self.skipTest('Testing Stack abandon disabled in conf, skipping')
         info = self.client.stacks.abandon(stack_id=stack_id)
@@ -474,7 +476,9 @@
     def stack_suspend(self, stack_identifier):
         stack_name = stack_identifier.split('/')[0]
         self.client.actions.suspend(stack_name)
-
+        if (self.conf.skip_test_stack_action_list and
+                'SUSPEND' in self.conf.skip_test_stack_action_list):
+            self.skipTest('Testing Stack suspend disabled in conf, skipping')
         # improve debugging by first checking the resource's state.
         self._wait_for_all_resource_status(stack_identifier,
                                            'SUSPEND_COMPLETE')
@@ -483,6 +487,9 @@
     def stack_resume(self, stack_identifier):
         stack_name = stack_identifier.split('/')[0]
         self.client.actions.resume(stack_name)
+        if (self.conf.skip_test_stack_action_list and
+                'RESUME' in self.conf.skip_test_stack_action_list):
+            self.skipTest('Testing Stack resume disabled in conf, skipping')
 
         # improve debugging by first checking the resource's state.
         self._wait_for_all_resource_status(stack_identifier,
diff --git a/functional/functional_base.py b/functional/functional_base.py
new file mode 100644
index 0000000..3a34238
--- /dev/null
+++ b/functional/functional_base.py
@@ -0,0 +1,28 @@
+#    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.common import test
+
+
+class FunctionalTestsBase(test.HeatIntegrationTest):
+
+    def setUp(self):
+        super(FunctionalTestsBase, self).setUp()
+        self.check_skip_test()
+        self.client = self.orchestration_client
+
+    def check_skip_test(self):
+        test_name = self.__class__.__name__
+        test_skipped = (self.conf.skip_functional_test_list and
+                        test_name in self.conf.skip_functional_test_list)
+        if self.conf.skip_functional_tests or test_skipped:
+            self.skipTest('Test disabled in conf, skipping')
diff --git a/functional/test_autoscaling.py b/functional/test_autoscaling.py
index 301981f..87c4c32 100644
--- a/functional/test_autoscaling.py
+++ b/functional/test_autoscaling.py
@@ -17,12 +17,13 @@
 from testtools import matchers
 
 from heat_integrationtests.common import test
+from heat_integrationtests.functional import functional_base
 
 
 LOG = logging.getLogger(__name__)
 
 
-class AutoscalingGroupTest(test.HeatIntegrationTest):
+class AutoscalingGroupTest(functional_base.FunctionalTestsBase):
 
     template = '''
 {
@@ -113,7 +114,6 @@
 
     def setUp(self):
         super(AutoscalingGroupTest, self).setUp()
-        self.client = self.orchestration_client
         if not self.conf.image_ref:
             raise self.skipException("No image configured to test")
         if not self.conf.minimal_image_ref:
diff --git a/functional/test_aws_stack.py b/functional/test_aws_stack.py
index 172bc24..de8c6b8 100644
--- a/functional/test_aws_stack.py
+++ b/functional/test_aws_stack.py
@@ -20,12 +20,12 @@
 import yaml
 
 from heat_integrationtests.common import test
-
+from heat_integrationtests.functional import functional_base
 
 LOG = logging.getLogger(__name__)
 
 
-class AwsStackTest(test.HeatIntegrationTest):
+class AwsStackTest(functional_base.FunctionalTestsBase):
     test_template = '''
 HeatTemplateFormatVersion: '2012-12-12'
 Resources:
@@ -75,7 +75,6 @@
 
     def setUp(self):
         super(AwsStackTest, self).setUp()
-        self.client = self.orchestration_client
         self.object_container_name = AwsStackTest.__name__
         self.project_id = self.identity_client.auth_ref.project_id
         self.object_client.put_container(self.object_container_name)
diff --git a/functional/test_conditional_exposure.py b/functional/test_conditional_exposure.py
index c74b297..2ab297e 100644
--- a/functional/test_conditional_exposure.py
+++ b/functional/test_conditional_exposure.py
@@ -13,13 +13,12 @@
 from heatclient import exc
 import keystoneclient
 
-from heat_integrationtests.common import test
+from heat_integrationtests.functional import functional_base
 
 
-class ConditionalExposureTestBase(test.HeatIntegrationTest):
+class ConditionalExposureTestBase(functional_base.FunctionalTestsBase):
     def setUp(self):
         super(ConditionalExposureTestBase, self).setUp()
-        self.client = self.orchestration_client
 
     def _delete(self, stack_name):
         stacks = self.client.stacks.list()
diff --git a/functional/test_create_update.py b/functional/test_create_update.py
index 6053303..87d7a23 100644
--- a/functional/test_create_update.py
+++ b/functional/test_create_update.py
@@ -12,9 +12,10 @@
 
 
 import copy
-from heat_integrationtests.common import test
 import json
 
+from heat_integrationtests.functional import functional_base
+
 test_template_one_resource = {
     'heat_template_version': '2013-05-23',
     'description': 'Test template to create one instance.',
@@ -68,10 +69,9 @@
         return modified_template
 
 
-class CreateStackTest(test.HeatIntegrationTest):
+class CreateStackTest(functional_base.FunctionalTestsBase):
     def setUp(self):
         super(CreateStackTest, self).setUp()
-        self.client = self.orchestration_client
 
     def test_create_rollback(self):
         values = {'fail': True, 'value': 'test_create_rollback'}
@@ -84,7 +84,7 @@
             disable_rollback=False)
 
 
-class UpdateStackTest(test.HeatIntegrationTest):
+class UpdateStackTest(functional_base.FunctionalTestsBase):
 
     provider_template = {
         'heat_template_version': '2013-05-23',
@@ -132,7 +132,6 @@
 
     def setUp(self):
         super(UpdateStackTest, self).setUp()
-        self.client = self.orchestration_client
 
     def test_stack_update_nochange(self):
         template = _change_rsrc_properties(test_template_one_resource,
diff --git a/functional/test_create_update_neutron_port.py b/functional/test_create_update_neutron_port.py
index 3d82bc4..4b2df59 100644
--- a/functional/test_create_update_neutron_port.py
+++ b/functional/test_create_update_neutron_port.py
@@ -12,7 +12,7 @@
 
 from testtools import testcase
 
-from heat_integrationtests.common import test
+from heat_integrationtests.functional import functional_base
 
 
 test_template = '''
@@ -44,11 +44,10 @@
 '''
 
 
-class UpdatePortTest(test.HeatIntegrationTest):
+class UpdatePortTest(functional_base.FunctionalTestsBase):
 
     def setUp(self):
         super(UpdatePortTest, self).setUp()
-        self.client = self.orchestration_client
 
     def get_port_id_and_ip(self, stack_identifier):
         resources = self.client.resources.list(stack_identifier)
diff --git a/functional/test_default_parameters.py b/functional/test_default_parameters.py
index 00000fd..3e00c35 100644
--- a/functional/test_default_parameters.py
+++ b/functional/test_default_parameters.py
@@ -12,10 +12,10 @@
 
 import yaml
 
-from heat_integrationtests.common import test
+from heat_integrationtests.functional import functional_base
 
 
-class DefaultParametersTest(test.HeatIntegrationTest):
+class DefaultParametersTest(functional_base.FunctionalTestsBase):
 
     template = '''
 heat_template_version: 2013-05-23
@@ -65,7 +65,6 @@
 
     def setUp(self):
         super(DefaultParametersTest, self).setUp()
-        self.client = self.orchestration_client
 
     def test_defaults(self):
         env = {'parameters': {}, 'parameter_defaults': {}}
diff --git a/functional/test_encrypted_parameter.py b/functional/test_encrypted_parameter.py
index c862f17..e1a9b88 100644
--- a/functional/test_encrypted_parameter.py
+++ b/functional/test_encrypted_parameter.py
@@ -10,10 +10,10 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
-from heat_integrationtests.common import test
+from heat_integrationtests.functional import functional_base
 
 
-class EncryptedParametersTest(test.HeatIntegrationTest):
+class EncryptedParametersTest(functional_base.FunctionalTestsBase):
 
     template = '''
 heat_template_version: 2013-05-23
@@ -31,7 +31,6 @@
 
     def setUp(self):
         super(EncryptedParametersTest, self).setUp()
-        self.client = self.orchestration_client
 
     def test_db_encryption(self):
         # Create a stack with a non-default value for 'foo' to be encrypted
diff --git a/functional/test_heat_autoscaling.py b/functional/test_heat_autoscaling.py
index dbe3e8f..e87badb 100644
--- a/functional/test_heat_autoscaling.py
+++ b/functional/test_heat_autoscaling.py
@@ -10,10 +10,10 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
-from heat_integrationtests.common import test
+from heat_integrationtests.functional import functional_base
 
 
-class HeatAutoscalingTest(test.HeatIntegrationTest):
+class HeatAutoscalingTest(functional_base.FunctionalTestsBase):
     template = '''
 heat_template_version: 2014-10-16
 
@@ -74,7 +74,6 @@
 
     def setUp(self):
         super(HeatAutoscalingTest, self).setUp()
-        self.client = self.orchestration_client
 
     def _assert_output_values(self, stack_id):
         stack = self.client.stacks.get(stack_id)
@@ -99,7 +98,7 @@
         self._assert_output_values(stack_id)
 
 
-class AutoScalingGroupUpdateWithNoChanges(test.HeatIntegrationTest):
+class AutoScalingGroupUpdateWithNoChanges(functional_base.FunctionalTestsBase):
 
     template = '''
 heat_template_version: 2013-05-23
@@ -123,7 +122,6 @@
 
     def setUp(self):
         super(AutoScalingGroupUpdateWithNoChanges, self).setUp()
-        self.client = self.orchestration_client
 
     def test_as_group_update_without_resource_changes(self):
         stack_identifier = self.stack_create(template=self.template)
diff --git a/functional/test_hooks.py b/functional/test_hooks.py
index 5c6f6bd..ce1e7aa 100644
--- a/functional/test_hooks.py
+++ b/functional/test_hooks.py
@@ -14,17 +14,16 @@
 
 import yaml
 
-from heat_integrationtests.common import test
+from heat_integrationtests.functional import functional_base
 
 
 LOG = logging.getLogger(__name__)
 
 
-class HooksTest(test.HeatIntegrationTest):
+class HooksTest(functional_base.FunctionalTestsBase):
 
     def setUp(self):
         super(HooksTest, self).setUp()
-        self.client = self.orchestration_client
         self.template = {'heat_template_version': '2014-10-16',
                          'resources': {
                              'foo_step1': {'type': 'OS::Heat::RandomString'},
diff --git a/functional/test_instance_group.py b/functional/test_instance_group.py
index 1455d0b..a8494c2 100644
--- a/functional/test_instance_group.py
+++ b/functional/test_instance_group.py
@@ -15,10 +15,10 @@
 
 from testtools import matchers
 
-from heat_integrationtests.common import test
+from heat_integrationtests.functional import functional_base
 
 
-class InstanceGroupTest(test.HeatIntegrationTest):
+class InstanceGroupTest(functional_base.FunctionalTestsBase):
 
     template = '''
 {
@@ -105,7 +105,6 @@
 
     def setUp(self):
         super(InstanceGroupTest, self).setUp()
-        self.client = self.orchestration_client
         if not self.conf.image_ref:
             raise self.skipException("No image configured to test")
         if not self.conf.minimal_image_ref:
diff --git a/functional/test_notifications.py b/functional/test_notifications.py
index c729a67..3b8e003 100644
--- a/functional/test_notifications.py
+++ b/functional/test_notifications.py
@@ -17,7 +17,7 @@
 import requests
 
 from heat_integrationtests.common import test
-
+from heat_integrationtests.functional import functional_base
 
 BASIC_NOTIFICATIONS = [
     'orchestration.stack.create.start',
@@ -70,7 +70,7 @@
         return self._notifications
 
 
-class NotificationTest(test.HeatIntegrationTest):
+class NotificationTest(functional_base.FunctionalTestsBase):
 
     basic_template = '''
 heat_template_version: 2013-05-23
@@ -124,10 +124,6 @@
 
     def setUp(self):
         super(NotificationTest, self).setUp()
-        if self.conf.skip_notification_tests:
-            self.skipTest('Testing Notifications disabled in conf, skipping')
-
-        self.client = self.orchestration_client
         self.exchange = kombu.Exchange('heat', 'topic', durable=False)
         queue = kombu.Queue(exchange=self.exchange,
                             routing_key='notifications.info',
diff --git a/functional/test_reload_on_sighup.py b/functional/test_reload_on_sighup.py
index f149a58..cba5386 100644
--- a/functional/test_reload_on_sighup.py
+++ b/functional/test_reload_on_sighup.py
@@ -17,10 +17,10 @@
 from oslo_concurrency import processutils
 from six.moves import configparser
 
-from heat_integrationtests.common import test
+from heat_integrationtests.functional import functional_base
 
 
-class ReloadOnSighupTest(test.HeatIntegrationTest):
+class ReloadOnSighupTest(functional_base.FunctionalTestsBase):
 
     def setUp(self):
         self.config_file = "/etc/heat/heat.conf"
diff --git a/functional/test_remote_stack.py b/functional/test_remote_stack.py
index 868f24e..91a165c 100644
--- a/functional/test_remote_stack.py
+++ b/functional/test_remote_stack.py
@@ -14,10 +14,10 @@
 from heatclient import exc
 import six
 
-from heat_integrationtests.common import test
+from heat_integrationtests.functional import functional_base
 
 
-class RemoteStackTest(test.HeatIntegrationTest):
+class RemoteStackTest(functional_base.FunctionalTestsBase):
     template = '''
 heat_template_version: 2013-05-23
 resources:
@@ -45,7 +45,6 @@
 
     def setUp(self):
         super(RemoteStackTest, self).setUp()
-        self.client = self.orchestration_client
 
     def test_remote_stack_alone(self):
         stack_id = self.stack_create(template=self.remote_template)
diff --git a/functional/test_resource_group.py b/functional/test_resource_group.py
index 8bc9950..5335245 100644
--- a/functional/test_resource_group.py
+++ b/functional/test_resource_group.py
@@ -17,10 +17,10 @@
 import six
 import yaml
 
-from heat_integrationtests.common import test
+from heat_integrationtests.functional import functional_base
 
 
-class ResourceGroupTest(test.HeatIntegrationTest):
+class ResourceGroupTest(functional_base.FunctionalTestsBase):
     template = '''
 heat_template_version: 2013-05-23
 resources:
@@ -44,7 +44,6 @@
 
     def setUp(self):
         super(ResourceGroupTest, self).setUp()
-        self.client = self.orchestration_client
 
     def _group_nested_identifier(self, stack_identifier,
                                  group_name='random_group'):
@@ -328,7 +327,7 @@
         self.assertNotEqual(initial_rand, updated_rand)
 
 
-class ResourceGroupTestNullParams(test.HeatIntegrationTest):
+class ResourceGroupTestNullParams(functional_base.FunctionalTestsBase):
     template = '''
 heat_template_version: 2013-05-23
 parameters:
@@ -383,7 +382,6 @@
 
     def setUp(self):
         super(ResourceGroupTestNullParams, self).setUp()
-        self.client = self.orchestration_client
 
     def test_create_pass_zero_parameter(self):
         templ = self.template.replace('type: empty',
@@ -403,7 +401,7 @@
         self.assertEqual(self.param, self._stack_output(stack, 'val')[0])
 
 
-class ResourceGroupAdoptTest(test.HeatIntegrationTest):
+class ResourceGroupAdoptTest(functional_base.FunctionalTestsBase):
     """Prove that we can do resource group adopt."""
 
     main_template = '''
@@ -424,7 +422,6 @@
 
     def setUp(self):
         super(ResourceGroupAdoptTest, self).setUp()
-        self.client = self.orchestration_client
 
     def _yaml_to_json(self, yaml_templ):
         return yaml.load(yaml_templ)
@@ -474,7 +471,7 @@
         self.assertEqual('different', self._stack_output(stack, 'test1'))
 
 
-class ResourceGroupErrorResourceTest(test.HeatIntegrationTest):
+class ResourceGroupErrorResourceTest(functional_base.FunctionalTestsBase):
     template = '''
 heat_template_version: "2013-05-23"
 resources:
@@ -497,7 +494,6 @@
 
     def setUp(self):
         super(ResourceGroupErrorResourceTest, self).setUp()
-        self.client = self.orchestration_client
 
     def test_fail(self):
         stack_identifier = self.stack_create(
diff --git a/functional/test_software_config.py b/functional/test_software_config.py
index 2e0ed76..2f38c55 100644
--- a/functional/test_software_config.py
+++ b/functional/test_software_config.py
@@ -10,10 +10,10 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
-from heat_integrationtests.common import test
+from heat_integrationtests.functional import functional_base
 
 
-class ParallelDeploymentsTest(test.HeatIntegrationTest):
+class ParallelDeploymentsTest(functional_base.FunctionalTestsBase):
     template = '''
 heat_template_version: "2013-05-23"
 parameters:
@@ -63,7 +63,6 @@
 
     def setUp(self):
         super(ParallelDeploymentsTest, self).setUp()
-        self.client = self.orchestration_client
 
     def test_fail(self):
         parms = {'flavor': self.conf.minimal_instance_type,
diff --git a/functional/test_stack_tags.py b/functional/test_stack_tags.py
index cdcdcd3..05600f5 100644
--- a/functional/test_stack_tags.py
+++ b/functional/test_stack_tags.py
@@ -10,10 +10,10 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
-from heat_integrationtests.common import test
+from heat_integrationtests.functional import functional_base
 
 
-class StackTagTest(test.HeatIntegrationTest):
+class StackTagTest(functional_base.FunctionalTestsBase):
 
     template = '''
 heat_template_version: 2014-10-16
@@ -23,7 +23,6 @@
 
     def setUp(self):
         super(StackTagTest, self).setUp()
-        self.client = self.orchestration_client
 
     def test_stack_tag(self):
         # Stack create with stack tags
diff --git a/functional/test_swiftsignal_update.py b/functional/test_swiftsignal_update.py
index 0f1c43c..5321014 100644
--- a/functional/test_swiftsignal_update.py
+++ b/functional/test_swiftsignal_update.py
@@ -11,7 +11,7 @@
 #    under the License.
 
 
-from heat_integrationtests.common import test
+from heat_integrationtests.functional import functional_base
 
 test_template = '''
 heat_template_version: 2014-10-16
@@ -31,11 +31,10 @@
 '''
 
 
-class SwiftSignalHandleUpdateTest(test.HeatIntegrationTest):
+class SwiftSignalHandleUpdateTest(functional_base.FunctionalTestsBase):
 
     def setUp(self):
         super(SwiftSignalHandleUpdateTest, self).setUp()
-        self.client = self.orchestration_client
 
     def test_stack_update_same_template_replace_no_url(self):
         stack_identifier = self.stack_create(template=test_template)
diff --git a/functional/test_template_resource.py b/functional/test_template_resource.py
index 478cfae..a967888 100644
--- a/functional/test_template_resource.py
+++ b/functional/test_template_resource.py
@@ -15,9 +15,10 @@
 import yaml
 
 from heat_integrationtests.common import test
+from heat_integrationtests.functional import functional_base
 
 
-class TemplateResourceTest(test.HeatIntegrationTest):
+class TemplateResourceTest(functional_base.FunctionalTestsBase):
     """Prove that we can use the registry in a nested provider."""
 
     template = '''
@@ -46,7 +47,6 @@
 
     def setUp(self):
         super(TemplateResourceTest, self).setUp()
-        self.client = self.orchestration_client
 
     def test_nested_env(self):
         main_templ = '''
@@ -146,7 +146,7 @@
         self.assertEqual('freddy', secret_out2)
 
 
-class NestedAttributesTest(test.HeatIntegrationTest):
+class NestedAttributesTest(functional_base.FunctionalTestsBase):
     """Prove that we can use the template resource references."""
 
     main_templ = '''
@@ -172,7 +172,6 @@
 
     def setUp(self):
         super(NestedAttributesTest, self).setUp()
-        self.client = self.orchestration_client
 
     def test_stack_ref(self):
         nested_templ = '''
@@ -244,7 +243,7 @@
         self.assertEqual(old_way, test_attr2)
 
 
-class TemplateResourceUpdateTest(test.HeatIntegrationTest):
+class TemplateResourceUpdateTest(functional_base.FunctionalTestsBase):
     """Prove that we can do template resource updates."""
 
     main_template = '''
@@ -458,7 +457,6 @@
 
     def setUp(self):
         super(TemplateResourceUpdateTest, self).setUp()
-        self.client = self.orchestration_client
 
     def test_template_resource_update_template_schema(self):
         stack_identifier = self.stack_create(
@@ -482,7 +480,7 @@
                                 self._stack_output(stack, 'value'))
 
 
-class TemplateResourceUpdateFailedTest(test.HeatIntegrationTest):
+class TemplateResourceUpdateFailedTest(functional_base.FunctionalTestsBase):
     """Prove that we can do updates on a nested stack to fix a stack."""
     main_template = '''
 HeatTemplateFormatVersion: '2012-12-12'
@@ -505,7 +503,6 @@
 
     def setUp(self):
         super(TemplateResourceUpdateFailedTest, self).setUp()
-        self.client = self.orchestration_client
         self.assign_keypair()
 
     def test_update_on_failed_create(self):
@@ -526,7 +523,7 @@
                           files={'server_fail.yaml': self.nested_templ})
 
 
-class TemplateResourceAdoptTest(test.HeatIntegrationTest):
+class TemplateResourceAdoptTest(functional_base.FunctionalTestsBase):
     """Prove that we can do template resource adopt/abandon."""
 
     main_template = '''
@@ -561,7 +558,6 @@
 
     def setUp(self):
         super(TemplateResourceAdoptTest, self).setUp()
-        self.client = self.orchestration_client
 
     def _yaml_to_json(self, yaml_templ):
         return yaml.load(yaml_templ)
@@ -606,7 +602,7 @@
         self.assertEqual('goopie', self._stack_output(stack, 'value'))
 
 
-class TemplateResourceCheckTest(test.HeatIntegrationTest):
+class TemplateResourceCheckTest(functional_base.FunctionalTestsBase):
     """Prove that we can do template resource check."""
 
     main_template = '''
@@ -641,7 +637,6 @@
 
     def setUp(self):
         super(TemplateResourceCheckTest, self).setUp()
-        self.client = self.orchestration_client
 
     def test_check(self):
         stack_identifier = self.stack_create(
@@ -653,7 +648,7 @@
         self._wait_for_stack_status(stack_identifier, 'CHECK_COMPLETE')
 
 
-class TemplateResourceErrorMessageTest(test.HeatIntegrationTest):
+class TemplateResourceErrorMessageTest(functional_base.FunctionalTestsBase):
     """Prove that nested stack errors don't suck."""
     template = '''
 HeatTemplateFormatVersion: '2012-12-12'
@@ -673,7 +668,6 @@
 
     def setUp(self):
         super(TemplateResourceErrorMessageTest, self).setUp()
-        self.client = self.orchestration_client
 
     def test_fail(self):
         stack_identifier = self.stack_create(
@@ -689,7 +683,7 @@
         self.assertEqual(exp, stack.stack_status_reason)
 
 
-class TemplateResourceSuspendResumeTest(test.HeatIntegrationTest):
+class TemplateResourceSuspendResumeTest(functional_base.FunctionalTestsBase):
     """Prove that we can do template resource suspend/resume."""
 
     main_template = '''
@@ -709,7 +703,6 @@
 
     def setUp(self):
         super(TemplateResourceSuspendResumeTest, self).setUp()
-        self.client = self.orchestration_client
 
     def test_suspend_resume(self):
         """Basic test for template resource suspend resume"""
diff --git a/functional/test_validation.py b/functional/test_validation.py
index 1111ea8..da5cd68 100644
--- a/functional/test_validation.py
+++ b/functional/test_validation.py
@@ -11,14 +11,13 @@
 #    under the License.
 
 
-from heat_integrationtests.common import test
+from heat_integrationtests.functional import functional_base
 
 
-class StackValidationTest(test.HeatIntegrationTest):
+class StackValidationTest(functional_base.FunctionalTestsBase):
 
     def setUp(self):
         super(StackValidationTest, self).setUp()
-        self.client = self.orchestration_client
         if not self.conf.minimal_image_ref:
             raise self.skipException("No image configured to test")
 
diff --git a/scenario/scenario_base.py b/scenario/scenario_base.py
index dd25b89..e347e6a 100644
--- a/scenario/scenario_base.py
+++ b/scenario/scenario_base.py
@@ -18,6 +18,8 @@
 
     def setUp(self):
         super(ScenarioTestsBase, self).setUp()
+        self.check_skip_test()
+
         self.client = self.orchestration_client
         self.sub_dir = 'templates'
         self.assign_keypair()
@@ -55,3 +57,10 @@
         )
 
         return stack_id
+
+    def check_skip_test(self):
+        test_name = self.__class__.__name__
+        test_skipped = (self.conf.skip_scenario_test_list and
+                        test_name in self.conf.skip_scenario_test_list)
+        if self.conf.skip_scenario_tests or test_skipped:
+            self.skipTest('Test disabled in conf, skipping')
diff --git a/scenario/test_ceilometer_alarm.py b/scenario/test_ceilometer_alarm.py
index d8f21fd..e0523aa 100644
--- a/scenario/test_ceilometer_alarm.py
+++ b/scenario/test_ceilometer_alarm.py
@@ -13,15 +13,15 @@
 from oslo_log import log as logging
 
 from heat_integrationtests.common import test
+from heat_integrationtests.scenario import scenario_base
 
 LOG = logging.getLogger(__name__)
 
 
-class CeilometerAlarmTest(test.HeatIntegrationTest):
+class CeilometerAlarmTest(scenario_base.ScenarioTestsBase):
     """Class is responsible for testing of ceilometer usage."""
     def setUp(self):
         super(CeilometerAlarmTest, self).setUp()
-        self.client = self.orchestration_client
         self.template = self._load_template(__file__,
                                             'test_ceilometer_alarm.yaml',
                                             'templates')
diff --git a/scenario/test_server_software_config.py b/scenario/test_server_software_config.py
index 19fd1a8..8739a99 100644
--- a/scenario/test_server_software_config.py
+++ b/scenario/test_server_software_config.py
@@ -44,9 +44,6 @@
 
     def setUp(self):
         super(SoftwareConfigIntegrationTest, self).setUp()
-        if self.conf.skip_software_config_tests:
-            self.skipTest('Testing software config disabled in conf, '
-                          'skipping')
         self.stack_name = self._stack_rand_name()
 
     def check_stack(self):
diff --git a/scenario/test_volumes.py b/scenario/test_volumes.py
index 7562304..d4b1aa8 100644
--- a/scenario/test_volumes.py
+++ b/scenario/test_volumes.py
@@ -14,7 +14,6 @@
 from cinderclient import exceptions as cinder_exceptions
 from oslo_log import log as logging
 import six
-from testtools import testcase
 
 from heat_integrationtests.common import exceptions
 from heat_integrationtests.scenario import scenario_base
@@ -101,8 +100,6 @@
                           self.volume_client.volumes.get,
                           volume_id2)
 
-    @testcase.skip('Skipped until failure rate '
-                   'can be reduced ref bug #1382300')
     def test_cinder_volume_create_backup_restore(self):
         """
         Ensure the 'Snapshot' deletion policy works.