Refactored existing tempest API tests
We must set up Tempest for Watcher (http://docs.openstack.org/developer/tempest/configuration.html) to run integration tests inside devstack environment. This patchset is a refactoring of the stale Tempest tests to now use the latest Tempest coding standards (like using plugins and credentials factory). This commit will have an effect on the doc as we need to integrate Tempest in the Watcher documentation. DocImpact Partially Implements: blueprint tempest-basic-set-up Change-Id: I7600ff8a28d524b56c7dd4903ac4d203634ae412
This commit is contained in:
committed by
Jean-Emile DARTOIS
parent
8832ad78e2
commit
595b13a622
0
watcher_tempest_plugin/tests/api/admin/__init__.py
Normal file
0
watcher_tempest_plugin/tests/api/admin/__init__.py
Normal file
139
watcher_tempest_plugin/tests/api/admin/base.py
Normal file
139
watcher_tempest_plugin/tests/api/admin/base.py
Normal file
@@ -0,0 +1,139 @@
|
||||
# -*- encoding: utf-8 -*-
|
||||
# Copyright (c) 2016 b<>com
|
||||
#
|
||||
# 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.
|
||||
|
||||
import functools
|
||||
|
||||
from tempest import test
|
||||
from tempest_lib.common.utils import data_utils
|
||||
from tempest_lib import exceptions as lib_exc
|
||||
|
||||
from watcher_tempest_plugin import infra_optim_clients as clients
|
||||
|
||||
# Resources must be deleted in a specific order, this list
|
||||
# defines the resource types to clean up, and the correct order.
|
||||
RESOURCE_TYPES = ['audit_template']
|
||||
# RESOURCE_TYPES = ['action', 'action_plan', 'audit', 'audit_template']
|
||||
|
||||
|
||||
def creates(resource):
|
||||
"""Decorator that adds resources to the appropriate cleanup list."""
|
||||
|
||||
def decorator(f):
|
||||
@functools.wraps(f)
|
||||
def wrapper(cls, *args, **kwargs):
|
||||
resp, body = f(cls, *args, **kwargs)
|
||||
|
||||
if 'uuid' in body:
|
||||
cls.created_objects[resource].add(body['uuid'])
|
||||
|
||||
return resp, body
|
||||
return wrapper
|
||||
return decorator
|
||||
|
||||
|
||||
class BaseInfraOptimTest(test.BaseTestCase):
|
||||
"""Base class for Infrastructure Optimization API tests."""
|
||||
|
||||
@classmethod
|
||||
def setup_credentials(cls):
|
||||
super(BaseInfraOptimTest, cls).setup_credentials()
|
||||
cls.mgr = clients.AdminManager()
|
||||
|
||||
@classmethod
|
||||
def setup_clients(cls):
|
||||
super(BaseInfraOptimTest, cls).setup_clients()
|
||||
cls.client = cls.mgr.io_client
|
||||
|
||||
@classmethod
|
||||
def resource_setup(cls):
|
||||
super(BaseInfraOptimTest, cls).resource_setup()
|
||||
|
||||
cls.created_objects = {}
|
||||
for resource in RESOURCE_TYPES:
|
||||
cls.created_objects[resource] = set()
|
||||
|
||||
@classmethod
|
||||
def resource_cleanup(cls):
|
||||
"""Ensure that all created objects get destroyed."""
|
||||
|
||||
try:
|
||||
for resource in RESOURCE_TYPES:
|
||||
uuids = cls.created_objects[resource]
|
||||
delete_method = getattr(cls.client, 'delete_%s' % resource)
|
||||
for u in uuids:
|
||||
delete_method(u, ignore_errors=lib_exc.NotFound)
|
||||
finally:
|
||||
super(BaseInfraOptimTest, cls).resource_cleanup()
|
||||
|
||||
def validate_self_link(self, resource, uuid, link):
|
||||
"""Check whether the given self link formatted correctly."""
|
||||
expected_link = "{base}/{pref}/{res}/{uuid}".format(
|
||||
base=self.client.base_url,
|
||||
pref=self.client.URI_PREFIX,
|
||||
res=resource,
|
||||
uuid=uuid
|
||||
)
|
||||
self.assertEqual(expected_link, link)
|
||||
|
||||
def assert_expected(self, expected, actual,
|
||||
keys=('created_at', 'updated_at', 'deleted_at')):
|
||||
# Check if not expected keys/values exists in actual response body
|
||||
for key, value in expected.items():
|
||||
if key not in keys:
|
||||
self.assertIn(key, actual)
|
||||
self.assertEqual(value, actual[key])
|
||||
|
||||
# ### AUDIT TEMPLATES ### #
|
||||
|
||||
@classmethod
|
||||
@creates('audit_template')
|
||||
def create_audit_template(cls, name=None, description=None, goal=None,
|
||||
host_aggregate=None, extra=None):
|
||||
"""Wrapper utility for creating a test audit template
|
||||
|
||||
:param name: The name of the audit template. Default: My Audit Template
|
||||
:param description: The description of the audit template.
|
||||
Default: AT Description
|
||||
:param goal: The goal associated within the audit template.
|
||||
Default: DUMMY
|
||||
:param host_aggregate: ID of the host aggregate targeted by
|
||||
this audit template. Default: 1
|
||||
:param extra: IMetadata associated to this audit template.
|
||||
Default: {}
|
||||
:return: A tuple with The HTTP response and its body
|
||||
"""
|
||||
|
||||
description = description or data_utils.rand_name(
|
||||
'test-audit_template')
|
||||
resp, body = cls.client.create_audit_template(
|
||||
name=name, description=description, goal=goal,
|
||||
host_aggregate=host_aggregate, extra=extra)
|
||||
return resp, body
|
||||
|
||||
@classmethod
|
||||
def delete_audit_template(cls, uuid):
|
||||
"""Deletes a audit_template having the specified UUID
|
||||
|
||||
:param uuid: The unique identifier of the audit template
|
||||
:return: Server response
|
||||
"""
|
||||
|
||||
resp, body = cls.client.delete_audit_template(uuid)
|
||||
|
||||
if uuid in cls.created_objects['audit_template']:
|
||||
cls.created_objects['audit_template'].remove(uuid)
|
||||
|
||||
return resp
|
||||
47
watcher_tempest_plugin/tests/api/admin/test_api_discovery.py
Normal file
47
watcher_tempest_plugin/tests/api/admin/test_api_discovery.py
Normal file
@@ -0,0 +1,47 @@
|
||||
# -*- encoding: utf-8 -*-
|
||||
# Copyright (c) 2016 b<>com
|
||||
#
|
||||
# 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 tempest import test
|
||||
|
||||
from watcher_tempest_plugin.tests.api.admin import base
|
||||
|
||||
|
||||
class TestApiDiscovery(base.BaseInfraOptimTest):
|
||||
"""Tests for API discovery features."""
|
||||
|
||||
@test.attr(type='smoke')
|
||||
def test_api_versions(self):
|
||||
_, descr = self.client.get_api_description()
|
||||
expected_versions = ('v1',)
|
||||
versions = [version['id'] for version in descr['versions']]
|
||||
|
||||
for v in expected_versions:
|
||||
self.assertIn(v, versions)
|
||||
|
||||
@test.attr(type='smoke')
|
||||
def test_default_version(self):
|
||||
_, descr = self.client.get_api_description()
|
||||
default_version = descr['default_version']
|
||||
self.assertEqual(default_version['id'], 'v1')
|
||||
|
||||
@test.attr(type='smoke')
|
||||
def test_version_1_resources(self):
|
||||
_, descr = self.client.get_version_description(version='v1')
|
||||
expected_resources = ('audit_templates', 'audits', 'action_plans',
|
||||
'actions', 'links', 'media_types')
|
||||
|
||||
for res in expected_resources:
|
||||
self.assertIn(res, descr)
|
||||
245
watcher_tempest_plugin/tests/api/admin/test_audit_template.py
Normal file
245
watcher_tempest_plugin/tests/api/admin/test_audit_template.py
Normal file
@@ -0,0 +1,245 @@
|
||||
# -*- encoding: utf-8 -*-
|
||||
# Copyright (c) 2016 b<>com
|
||||
#
|
||||
# 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 __future__ import unicode_literals
|
||||
|
||||
import uuid
|
||||
|
||||
from tempest import test
|
||||
from tempest_lib import decorators
|
||||
from tempest_lib import exceptions as lib_exc
|
||||
|
||||
from watcher_tempest_plugin.tests.api.admin import base
|
||||
|
||||
|
||||
class TestCreateDeleteAuditTemplate(base.BaseInfraOptimTest):
|
||||
"""Tests on audit templates"""
|
||||
|
||||
@test.attr(type='smoke')
|
||||
def test_create_audit_template(self):
|
||||
params = {'name': 'my at name %s' % uuid.uuid4(),
|
||||
'description': 'my at description',
|
||||
'host_aggregate': 12,
|
||||
'goal': 'DUMMY',
|
||||
'extra': {'str': 'value', 'int': 123, 'float': 0.123,
|
||||
'bool': True, 'list': [1, 2, 3],
|
||||
'dict': {'foo': 'bar'}}}
|
||||
|
||||
_, body = self.create_audit_template(**params)
|
||||
self.assert_expected(params, body)
|
||||
|
||||
_, audit_template = self.client.show_audit_template(body['uuid'])
|
||||
self.assert_expected(audit_template, body)
|
||||
|
||||
@test.attr(type='smoke')
|
||||
def test_create_audit_template_unicode_description(self):
|
||||
# Use a unicode string for testing:
|
||||
params = {'name': 'my at name %s' % uuid.uuid4(),
|
||||
'description': 'my àt déscrïptïôn',
|
||||
'host_aggregate': 12,
|
||||
'goal': 'DUMMY',
|
||||
'extra': {'foo': 'bar'}}
|
||||
|
||||
_, body = self.create_audit_template(**params)
|
||||
self.assert_expected(params, body)
|
||||
|
||||
_, audit_template = self.client.show_audit_template(body['uuid'])
|
||||
self.assert_expected(audit_template, body)
|
||||
|
||||
@test.attr(type='smoke')
|
||||
def test_delete_audit_template(self):
|
||||
_, body = self.create_audit_template()
|
||||
audit_uuid = body['uuid']
|
||||
|
||||
self.delete_audit_template(audit_uuid)
|
||||
|
||||
self.assertRaises(lib_exc.NotFound, self.client.show_audit_template,
|
||||
audit_uuid)
|
||||
|
||||
|
||||
class TestAuditTemplate(base.BaseInfraOptimTest):
|
||||
"""Tests for audit_template."""
|
||||
|
||||
@classmethod
|
||||
def resource_setup(cls):
|
||||
super(TestAuditTemplate, cls).resource_setup()
|
||||
_, cls.audit_template = cls.create_audit_template()
|
||||
|
||||
@test.attr(type='smoke')
|
||||
def test_show_audit_template(self):
|
||||
_, audit_template = self.client.show_audit_template(
|
||||
self.audit_template['uuid'])
|
||||
|
||||
self.assert_expected(self.audit_template, audit_template)
|
||||
|
||||
@decorators.skip_because(bug="1510189")
|
||||
@test.attr(type='smoke')
|
||||
def test_filter_audit_template_by_goal(self):
|
||||
_, audit_template = self.client.\
|
||||
filter_audit_template_by_goal(self.audit_template['goal'])
|
||||
|
||||
self.assert_expected(self.audit_template,
|
||||
audit_template['audit_templates'][0])
|
||||
|
||||
@decorators.skip_because(bug="1510189")
|
||||
@test.attr(type='smoke')
|
||||
def test_filter_audit_template_by_host_aggregate(self):
|
||||
_, audit_template = self.client.\
|
||||
filter_audit_template_by_host_aggregate(
|
||||
self.audit_template['host_aggregate'])
|
||||
|
||||
self.assert_expected(self.audit_template,
|
||||
audit_template['audit_templates'][0])
|
||||
|
||||
@test.attr(type='smoke')
|
||||
def test_show_audit_template_with_links(self):
|
||||
_, audit_template = self.client.show_audit_template(
|
||||
self.audit_template['uuid'])
|
||||
self.assertIn('links', audit_template.keys())
|
||||
self.assertEqual(2, len(audit_template['links']))
|
||||
self.assertIn(audit_template['uuid'],
|
||||
audit_template['links'][0]['href'])
|
||||
|
||||
@test.attr(type="smoke")
|
||||
def test_list_audit_templates(self):
|
||||
_, body = self.client.list_audit_templates()
|
||||
self.assertIn(self.audit_template['uuid'],
|
||||
[i['uuid'] for i in body['audit_templates']])
|
||||
# Verify self links.
|
||||
for audit_template in body['audit_templates']:
|
||||
self.validate_self_link('audit_templates', audit_template['uuid'],
|
||||
audit_template['links'][0]['href'])
|
||||
|
||||
@test.attr(type='smoke')
|
||||
def test_list_with_limit(self):
|
||||
# We create 3 extra audit templates to exceed the limit we fix
|
||||
for _ in range(3):
|
||||
self.create_audit_template()
|
||||
|
||||
_, body = self.client.list_audit_templates(limit=3)
|
||||
|
||||
next_marker = body['audit_templates'][-1]['uuid']
|
||||
self.assertEqual(len(body['audit_templates']), 3)
|
||||
self.assertIn(next_marker, body['next'])
|
||||
|
||||
@test.attr(type='smoke')
|
||||
def test_update_audit_template_replace(self):
|
||||
params = {'name': 'my at name %s' % uuid.uuid4(),
|
||||
'description': 'my at description',
|
||||
'host_aggregate': 12,
|
||||
'goal': 'DUMMY',
|
||||
'extra': {'key1': 'value1', 'key2': 'value2'}}
|
||||
|
||||
_, body = self.create_audit_template(**params)
|
||||
|
||||
new_name = 'my at new name %s' % uuid.uuid4()
|
||||
new_description = 'my new at description'
|
||||
new_host_aggregate = 10
|
||||
new_goal = 'A NEW GOAL'
|
||||
new_extra = {'key1': 'new-value1', 'key2': 'new-value2'}
|
||||
|
||||
patch = [{'path': '/name',
|
||||
'op': 'replace',
|
||||
'value': new_name},
|
||||
{'path': '/description',
|
||||
'op': 'replace',
|
||||
'value': new_description},
|
||||
{'path': '/host_aggregate',
|
||||
'op': 'replace',
|
||||
'value': new_host_aggregate},
|
||||
{'path': '/goal',
|
||||
'op': 'replace',
|
||||
'value': new_goal},
|
||||
{'path': '/extra/key1',
|
||||
'op': 'replace',
|
||||
'value': new_extra['key1']},
|
||||
{'path': '/extra/key2',
|
||||
'op': 'replace',
|
||||
'value': new_extra['key2']}]
|
||||
|
||||
self.client.update_audit_template(body['uuid'], patch)
|
||||
|
||||
_, body = self.client.show_audit_template(body['uuid'])
|
||||
self.assertEqual(new_name, body['name'])
|
||||
self.assertEqual(new_description, body['description'])
|
||||
self.assertEqual(new_host_aggregate, body['host_aggregate'])
|
||||
self.assertEqual(new_goal, body['goal'])
|
||||
self.assertEqual(new_extra, body['extra'])
|
||||
|
||||
@test.attr(type='smoke')
|
||||
def test_update_audit_template_remove(self):
|
||||
extra = {'key1': 'value1', 'key2': 'value2', 'key3': 'value3'}
|
||||
description = 'my at description'
|
||||
goal = 'DUMMY'
|
||||
name = 'my at name %s' % uuid.uuid4()
|
||||
params = {'name': name,
|
||||
'description': description,
|
||||
'host_aggregate': 12,
|
||||
'goal': goal,
|
||||
'extra': extra}
|
||||
|
||||
_, audit_template = self.create_audit_template(**params)
|
||||
|
||||
# Removing one item from the collection
|
||||
self.client.update_audit_template(
|
||||
audit_template['uuid'],
|
||||
[{'path': '/extra/key2', 'op': 'remove'}])
|
||||
|
||||
extra.pop('key2')
|
||||
_, body = self.client.show_audit_template(audit_template['uuid'])
|
||||
self.assertEqual(extra, body['extra'])
|
||||
|
||||
# Removing the collection
|
||||
self.client.update_audit_template(
|
||||
audit_template['uuid'],
|
||||
[{'path': '/extra', 'op': 'remove'}])
|
||||
_, body = self.client.show_audit_template(audit_template['uuid'])
|
||||
self.assertEqual({}, body['extra'])
|
||||
|
||||
# Removing the Host Aggregate ID
|
||||
self.client.update_audit_template(
|
||||
audit_template['uuid'],
|
||||
[{'path': '/host_aggregate', 'op': 'remove'}])
|
||||
_, body = self.client.show_audit_template(audit_template['uuid'])
|
||||
self.assertEqual({}, body['extra'])
|
||||
|
||||
# Assert nothing else was changed
|
||||
self.assertEqual(name, body['name'])
|
||||
self.assertEqual(description, body['description'])
|
||||
self.assertEqual(goal, body['goal'])
|
||||
|
||||
@test.attr(type='smoke')
|
||||
def test_update_audit_template_add(self):
|
||||
params = {'name': 'my at name %s' % uuid.uuid4(),
|
||||
'description': 'my at description',
|
||||
'host_aggregate': 12,
|
||||
'goal': 'DUMMY'}
|
||||
|
||||
_, body = self.create_audit_template(**params)
|
||||
|
||||
extra = {'key1': 'value1', 'key2': 'value2'}
|
||||
|
||||
patch = [{'path': '/extra/key1',
|
||||
'op': 'add',
|
||||
'value': extra['key1']},
|
||||
{'path': '/extra/key2',
|
||||
'op': 'add',
|
||||
'value': extra['key2']}]
|
||||
|
||||
self.client.update_audit_template(body['uuid'], patch)
|
||||
|
||||
_, body = self.client.show_audit_template(body['uuid'])
|
||||
self.assertEqual(extra, body['extra'])
|
||||
Reference in New Issue
Block a user