Merge "Updated from global requirements"
diff --git a/heat_tempest_plugin/common/test.py b/heat_tempest_plugin/common/test.py
index dbd2e27..a4c0edf 100644
--- a/heat_tempest_plugin/common/test.py
+++ b/heat_tempest_plugin/common/test.py
@@ -34,6 +34,7 @@
 
 LOG = logging.getLogger(__name__)
 _LOG_FORMAT = "%(levelname)8s [%(name)s] %(message)s"
+_resource_types = None
 
 
 def call_until_true(duration, sleep_for, func, *args, **kwargs):
@@ -86,6 +87,45 @@
     return skipper(test_method)
 
 
+def requires_resource_type(resource_type):
+    '''Decorator for tests requiring a resource type.
+
+    The decorated test will be skipped when the resource type is not available.
+    '''
+    def decorator(test_method):
+        conf = getattr(config.CONF, 'heat_plugin', None)
+        if not conf or conf.auth_url is None:
+            return test_method
+
+        global _resource_types
+        if not _resource_types:
+            manager = clients.ClientManager(conf)
+            obj_rtypes = manager.orchestration_client.resource_types.list()
+            _resource_types = list(t.resource_type for t in obj_rtypes)
+        rtype_available = resource_type and resource_type in _resource_types
+        skipper = testtools.skipUnless(
+            rtype_available,
+            "%s resource type not available, skipping test." % resource_type)
+        return skipper(test_method)
+    return decorator
+
+
+def requires_feature(feature):
+    '''Decorator for tests requring specific feature.
+
+    The decorated test will be skipped when a specific feature is disabled.
+    '''
+    def decorator(test_method):
+        features_group = getattr(config.CONF, 'heat_features_enabled', None)
+        if not features_group:
+            return test_method
+        feature_enabled = config.CONF.heat_features_enabled.get(feature, False)
+        skipper = testtools.skipUnless(feature_enabled,
+                                       "%s - Feature not enabled." % feature)
+        return skipper(test_method)
+    return decorator
+
+
 class HeatIntegrationTest(testtools.testcase.WithAttributes,
                           testscenarios.WithScenarios,
                           testtools.TestCase):
diff --git a/heat_tempest_plugin/config.py b/heat_tempest_plugin/config.py
index d658a98..e4c7b47 100644
--- a/heat_tempest_plugin/config.py
+++ b/heat_tempest_plugin/config.py
@@ -156,7 +156,18 @@
 
 ]
 
+heat_features_group = cfg.OptGroup(
+    name='heat_features_enabled',
+    title="Enabled Orchestration Service Features")
+
+HeatFeaturesGroup = [
+    cfg.BoolOpt('stack_cancel',
+                default=False,
+                help="If false, skip stack cancel tests")
+]
+
 
 def list_opts():
     yield heat_group.name, HeatGroup
+    yield heat_features_group.name, HeatFeaturesGroup
     yield service_available_group.name, ServiceAvailableGroup
diff --git a/heat_tempest_plugin/plugin.py b/heat_tempest_plugin/plugin.py
index acf4fc7..6926691 100644
--- a/heat_tempest_plugin/plugin.py
+++ b/heat_tempest_plugin/plugin.py
@@ -34,7 +34,11 @@
                                   heat_config.ServiceAvailableGroup)
         config.register_opt_group(conf, heat_config.heat_group,
                                   heat_config.HeatGroup)
+        config.register_opt_group(conf, heat_config.heat_features_group,
+                                  heat_config.HeatFeaturesGroup)
 
     def get_opt_lists(self):
         return [(heat_config.heat_group.name,
-                 heat_config.HeatGroup)]
+                 heat_config.HeatGroup),
+                (heat_config.heat_features_group.name,
+                 heat_config.HeatFeaturesGroup)]
diff --git a/heat_tempest_plugin/tests/functional/test_create_update_neutron_trunk.py b/heat_tempest_plugin/tests/functional/test_create_update_neutron_trunk.py
index ff5bcaf..bdcb58e 100644
--- a/heat_tempest_plugin/tests/functional/test_create_update_neutron_trunk.py
+++ b/heat_tempest_plugin/tests/functional/test_create_update_neutron_trunk.py
@@ -17,6 +17,7 @@
 
 from tempest.lib import decorators
 
+from heat_tempest_plugin.common import test
 from heat_tempest_plugin.tests.functional import functional_base
 
 
@@ -72,6 +73,7 @@
 '''
 
 
+@test.requires_resource_type('OS::Neutron::Trunk')
 class UpdateTrunkTest(functional_base.FunctionalTestsBase):
 
     @staticmethod
diff --git a/heat_tempest_plugin/tests/functional/test_os_wait_condition.py b/heat_tempest_plugin/tests/functional/test_os_wait_condition.py
index dc78341..603b5e5 100644
--- a/heat_tempest_plugin/tests/functional/test_os_wait_condition.py
+++ b/heat_tempest_plugin/tests/functional/test_os_wait_condition.py
@@ -57,11 +57,11 @@
             wc_notify --data-binary ''{"status": "SUCCESS", "reason":
             "signal4", "data": "data4"}''
 
-            # check signals with the same number
+            # check signals with the same ID
 
-            wc_notify --data-binary ''{"status": "SUCCESS", "id": "5"}''
+            wc_notify --data-binary ''{"status": "SUCCESS", "id": "test5"}''
 
-            wc_notify --data-binary ''{"status": "SUCCESS", "id": "5"}''
+            wc_notify --data-binary ''{"status": "SUCCESS", "id": "test5"}''
 
             # loop for 20 signals without reasons and data
 
diff --git a/heat_tempest_plugin/tests/scenario/test_server_signal.py b/heat_tempest_plugin/tests/scenario/test_server_signal.py
index a43c74a..1823087 100644
--- a/heat_tempest_plugin/tests/scenario/test_server_signal.py
+++ b/heat_tempest_plugin/tests/scenario/test_server_signal.py
@@ -29,6 +29,7 @@
             'key_name': self.keypair_name,
             'flavor': flavor,
             'image': image,
+            'public_net': self.conf.floating_network_name,
             'timeout': self.conf.build_timeout,
             'user_data_format': user_data_format
         }