Merge "Add test for remote nested stacks"
diff --git a/.zuul.yaml b/.zuul.yaml
index f7d9698..88da946 100644
--- a/.zuul.yaml
+++ b/.zuul.yaml
@@ -13,9 +13,26 @@
parent: heat-functional-convg-mysql-lbaasv2-py35
override-checkout: stable/queens
+- job:
+ name: heat-functional-convg-rocky
+ parent: heat-functional-convg-mysql-lbaasv2
+ override-checkout: stable/rocky
+
+- job:
+ name: heat-functional-orig-rocky
+ parent: heat-functional-orig-mysql-lbaasv2
+ override-checkout: stable/rocky
+
+- job:
+ name: heat-functional-convg-rocky-py35
+ parent: heat-functional-convg-mysql-lbaasv2-py35
+ override-checkout: stable/rocky
- project:
+ templates:
+ - check-requirements
+ - tempest-plugin-jobs
check:
jobs:
- heat-functional-orig-mysql-lbaasv2
@@ -25,7 +42,11 @@
- heat-functional-convg-queens
- heat-functional-convg-queens-py35
- heat-functional-orig-queens
+ - heat-functional-convg-rocky
+ - heat-functional-convg-rocky-py35
+ - heat-functional-orig-rocky
gate:
+ queue: heat
jobs:
- heat-functional-orig-mysql-lbaasv2
- heat-functional-convg-mysql-lbaasv2
diff --git a/heat_tempest_plugin/common/test.py b/heat_tempest_plugin/common/test.py
index aacd019..ccbc12a 100644
--- a/heat_tempest_plugin/common/test.py
+++ b/heat_tempest_plugin/common/test.py
@@ -109,6 +109,29 @@
return decorator
+def requires_service_type(service_type):
+ '''Decorator for tests requiring a specific service being available.
+
+ The decorated test will be skipped when a service 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
+
+ manager = clients.ClientManager(conf)
+ try:
+ manager.identity_client.get_endpoint_url(
+ service_type, conf.region, conf.endpoint_type)
+ except kc_exceptions.EndpointNotFound:
+ skipper = testtools.skip(
+ "%s service not available, skipping test." % service_type)
+ return skipper(test_method)
+ else:
+ return test_method
+ return decorator
+
+
def requires_feature(feature):
'''Decorator for tests requring specific feature.
@@ -246,15 +269,6 @@
return False
return True
- def is_service_available(self, service_type):
- try:
- self.identity_client.get_endpoint_url(
- service_type, self.conf.region)
- except kc_exceptions.EndpointNotFound:
- return False
- else:
- return True
-
@staticmethod
def _stack_output(stack, output_key, validate_errors=True):
"""Return a stack output value for a given key."""
diff --git a/heat_tempest_plugin/plugin.py b/heat_tempest_plugin/plugin.py
index 6926691..0eeb519 100644
--- a/heat_tempest_plugin/plugin.py
+++ b/heat_tempest_plugin/plugin.py
@@ -22,7 +22,23 @@
class HeatTempestPlugin(plugins.TempestPlugin):
+ """A HeatTempestPlugin class
+
+ Provides the basic hooks for an external plugin to provide tempest the
+ necessary information to run the plugin.
+ """
+
def load_tests(self):
+ """Provide Load tests information
+
+ Method to return the information necessary to load the tests in the
+ plugin.
+
+ :return: a tuple with the first value being the test_dir and the second
+ being the top_level
+ :return type: tuple
+ """
+
base_path = os.path.split(os.path.dirname(
os.path.abspath(__file__)))[0]
test_dir = "heat_tempest_plugin"
@@ -30,6 +46,15 @@
return full_test_dir, base_path
def register_opts(self, conf):
+ """Add additional configuration options to tempest.
+
+ This method will be run for the plugin during the register_opts()
+ function in tempest.config
+
+ Parameters:
+ conf (ConfigOpts): The conf object that can be used to register
+ additional options on.
+ """
config.register_opt_group(conf, heat_config.service_available_group,
heat_config.ServiceAvailableGroup)
config.register_opt_group(conf, heat_config.heat_group,
@@ -38,6 +63,13 @@
heat_config.HeatFeaturesGroup)
def get_opt_lists(self):
+ """Get a list of options for sample config generation
+
+ Return option_list: A list of tuples with the group name
+ and options in that group.
+ Return type: list
+ """
+
return [(heat_config.heat_group.name,
heat_config.HeatGroup),
(heat_config.heat_features_group.name,
diff --git a/heat_tempest_plugin/services/clients.py b/heat_tempest_plugin/services/clients.py
index 3999cee..d6e1dfb 100644
--- a/heat_tempest_plugin/services/clients.py
+++ b/heat_tempest_plugin/services/clients.py
@@ -111,7 +111,7 @@
self.HEATCLIENT_VERSION,
endpoint,
session=session,
- endpoint_type='publicURL',
+ endpoint_type=self.conf.endpoint_type,
service_type='orchestration',
region_name=self.conf.region,
username=self._username(),
@@ -174,6 +174,8 @@
args = {
'auth_version': self.auth_version,
'session': self.identity_client.session,
+ 'cacert': self.ca_file,
+ 'insecure': self.insecure,
'os_options': {'endpoint_type': self.conf.endpoint_type,
'region_name': self.conf.region,
'service_type': 'object-store'},
diff --git a/heat_tempest_plugin/tests/functional/test_event_sinks.py b/heat_tempest_plugin/tests/functional/test_event_sinks.py
index 7cb1d7b..dd1accc 100644
--- a/heat_tempest_plugin/tests/functional/test_event_sinks.py
+++ b/heat_tempest_plugin/tests/functional/test_event_sinks.py
@@ -19,6 +19,7 @@
from heat_tempest_plugin.tests.functional import functional_base
+@test.requires_service_type('messaging')
class ZaqarEventSinkTest(functional_base.FunctionalTestsBase):
template = '''
heat_template_version: "2013-05-23"
diff --git a/heat_tempest_plugin/tests/functional/test_remote_stack.py b/heat_tempest_plugin/tests/functional/test_remote_stack.py
index 5e778e7..1a467f4 100644
--- a/heat_tempest_plugin/tests/functional/test_remote_stack.py
+++ b/heat_tempest_plugin/tests/functional/test_remote_stack.py
@@ -94,9 +94,10 @@
ex = self.assertRaises(exc.HTTPBadRequest, self.stack_create, **kwargs)
error_msg = ('ERROR: Cannot establish connection to Heat endpoint '
- 'at region "DARKHOLE" due to "publicURL endpoint for '
+ 'at region "DARKHOLE" due to '
+ '"(?:public|internal|admin)(?:URL)? endpoint for '
'orchestration service in DARKHOLE region not found"')
- self.assertEqual(error_msg, six.text_type(ex))
+ self.assertRegex(six.text_type(ex), error_msg)
@decorators.idempotent_id('b2190dfc-d223-4595-b168-6c42b0f3a3e5')
def test_stack_resource_validation_fail(self):
diff --git a/heat_tempest_plugin/tests/functional/test_software_config.py b/heat_tempest_plugin/tests/functional/test_software_config.py
index f034096..ada67f2 100644
--- a/heat_tempest_plugin/tests/functional/test_software_config.py
+++ b/heat_tempest_plugin/tests/functional/test_software_config.py
@@ -183,6 +183,7 @@
verify=self.verify_cert)
+@test.requires_service_type('messaging')
class ZaqarSignalTransportTest(functional_base.FunctionalTestsBase):
server_template = '''
heat_template_version: "2013-05-23"
diff --git a/heat_tempest_plugin/tests/functional/test_waitcondition.py b/heat_tempest_plugin/tests/functional/test_waitcondition.py
index b50c0a2..3bffd76 100644
--- a/heat_tempest_plugin/tests/functional/test_waitcondition.py
+++ b/heat_tempest_plugin/tests/functional/test_waitcondition.py
@@ -16,9 +16,11 @@
from tempest.lib import decorators
from zaqarclient.queues.v2 import client as zaqarclient
+from heat_tempest_plugin.common import test
from heat_tempest_plugin.tests.functional import functional_base
+@test.requires_service_type('messaging')
class ZaqarWaitConditionTest(functional_base.FunctionalTestsBase):
template = '''
heat_template_version: "2013-05-23"
@@ -54,7 +56,7 @@
password=signal['password'],
project_id=signal['project_id'])
endpoint = ks.service_catalog.url_for(
- service_type='messaging', endpoint_type='publicURL')
+ service_type='messaging', endpoint_type=self.conf.endpoint_type)
conf = {
'auth_opts': {
'backend': 'keystone',
diff --git a/heat_tempest_plugin/tests/scenario/test_aodh_alarm.py b/heat_tempest_plugin/tests/scenario/test_aodh_alarm.py
index 4e25158..dafca12 100644
--- a/heat_tempest_plugin/tests/scenario/test_aodh_alarm.py
+++ b/heat_tempest_plugin/tests/scenario/test_aodh_alarm.py
@@ -51,9 +51,9 @@
stack_identifier = self.stack_create(template=self.template,
parameters=parameters)
- measures = [{'timestamp': test.isotime(datetime.datetime.now()),
+ measures = [{'timestamp': test.isotime(datetime.datetime.utcnow()),
'value': 100}, {'timestamp': test.isotime(
- datetime.datetime.now() + datetime.timedelta(
+ datetime.datetime.utcnow() + datetime.timedelta(
minutes=1)), 'value': 100}]
# send measures(should cause the alarm to fire)
self.metric_client.metric.add_measures(metric['id'], measures)
diff --git a/heat_tempest_plugin/tests/scenario/test_octavia_lbaas.py b/heat_tempest_plugin/tests/scenario/test_octavia_lbaas.py
index 67afadc..ce07262 100644
--- a/heat_tempest_plugin/tests/scenario/test_octavia_lbaas.py
+++ b/heat_tempest_plugin/tests/scenario/test_octavia_lbaas.py
@@ -45,10 +45,11 @@
@decorators.idempotent_id('5d2c4452-4433-4438-899c-7711c01d3c50')
def test_create_update_loadbalancer(self):
+ statuses = ['PENDING_UPDATE', 'ACTIVE']
stack_identifier = self._create_stack()
stack = self.client.stacks.get(stack_identifier)
output = self._stack_output(stack, 'loadbalancer')
- self.assertEqual('ONLINE', output['operating_status'])
+ self.assertIn(output['provisioning_status'], statuses)
self.parameters['lb_algorithm'] = 'SOURCE_IP'
self.update_stack(stack_identifier,
@@ -57,16 +58,17 @@
stack = self.client.stacks.get(stack_identifier)
output = self._stack_output(stack, 'loadbalancer')
- self.assertEqual('ONLINE', output['operating_status'])
+ self.assertIn(output['provisioning_status'], statuses)
output = self._stack_output(stack, 'pool')
self.assertEqual('SOURCE_IP', output['lb_algorithm'])
@decorators.idempotent_id('970e91af-1be8-4990-837b-66f9b5aff2b9')
def test_add_delete_poolmember(self):
+ statuses = ['PENDING_UPDATE', 'ACTIVE']
stack_identifier = self._create_stack()
stack = self.client.stacks.get(stack_identifier)
output = self._stack_output(stack, 'loadbalancer')
- self.assertEqual('ONLINE', output['operating_status'])
+ self.assertIn(output['provisioning_status'], statuses)
output = self._stack_output(stack, 'pool')
self.assertEqual(1, len(output['members']))
# add pool member
@@ -77,7 +79,7 @@
stack = self.client.stacks.get(stack_identifier)
output = self._stack_output(stack, 'loadbalancer')
- self.assertEqual('ONLINE', output['operating_status'])
+ self.assertIn(output['provisioning_status'], statuses)
output = self._stack_output(stack, 'pool')
self.assertEqual(2, len(output['members']))
# delete pool member
@@ -88,6 +90,6 @@
stack = self.client.stacks.get(stack_identifier)
output = self._stack_output(stack, 'loadbalancer')
- self.assertEqual('ONLINE', output['operating_status'])
+ self.assertIn(output['provisioning_status'], statuses)
output = self._stack_output(stack, 'pool')
self.assertEqual(1, len(output['members']))
diff --git a/tox.ini b/tox.ini
index 7b8aeec..549457a 100644
--- a/tox.ini
+++ b/tox.ini
@@ -12,6 +12,7 @@
testr run {posargs}
[testenv:pep8]
+basepython = python3
setenv =
PYTHONPATH = .
commands =
@@ -25,12 +26,14 @@
check-uuid --fix --package heat_tempest_plugin
[testenv:docs]
+basepython = python3
deps = -r{toxinidir}/requirements.txt
-r{toxinidir}/test-requirements.txt
sphinxcontrib-httpdomain
commands = python setup.py build_sphinx
[testenv:venv]
+basepython = python3
commands = {posargs}
[flake8]