Merge "API Tempest tests on Action plans"

This commit is contained in:
Jenkins 2016-01-22 16:49:27 +00:00 committed by Gerrit Code Review
commit b47aefac30
3 changed files with 255 additions and 2 deletions

View File

@ -185,4 +185,51 @@ class InfraOptimClientJSON(base.BaseInfraOptimClient):
:return: Tuple with the server response and the updated audit
"""
return self._patch_request('audits', uuid, patch)
return self._patch_request('audits', audit_uuid, patch)
# ### ACTION PLANS ### #
@base.handle_errors
def list_action_plans(self, **kwargs):
"""List all existing action plan"""
return self._list_request('action_plans', **kwargs)
@base.handle_errors
def list_action_plans_detail(self, **kwargs):
"""Lists details of all existing action plan"""
return self._list_request('/action_plans/detail', **kwargs)
@base.handle_errors
def list_action_plan_by_audit(self, audit_uuid):
"""Lists all action plans associated with an audit"""
return self._list_request('/action_plans', audit_uuid=audit_uuid)
@base.handle_errors
def show_action_plan(self, action_plan_uuid):
"""Gets a specific action plan
:param action_plan_uuid: Unique identifier of the action plan
:return: Serialized action plan as a dictionary
"""
return self._show_request('/action_plans', action_plan_uuid)
@base.handle_errors
def delete_action_plan(self, action_plan_uuid):
"""Deletes an action_plan having the specified UUID
:param action_plan_uuid: The unique identifier of the action_plan
:return: A tuple with the server response and the response body
"""
return self._delete_request('/action_plans', action_plan_uuid)
@base.handle_errors
def update_action_plan(self, action_plan_uuid, patch):
"""Update the specified action plan
:param action_plan_uuid: The unique identifier of the action_plan
:param patch: List of dicts representing json patches.
:return: Tuple with the server response and the updated action_plan
"""
return self._patch_request('/action_plans', action_plan_uuid, patch)

View File

@ -24,7 +24,7 @@ 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', 'audit']
RESOURCE_TYPES = ['audit_template', 'audit', 'action_plan']
# RESOURCE_TYPES = ['action', 'action_plan', 'audit', 'audit_template']
@ -170,3 +170,44 @@ class BaseInfraOptimTest(test.BaseTestCase):
cls.created_objects['audit'].remove(audit_uuid)
return resp
@classmethod
def has_audit_succeeded(cls, audit_uuid):
_, audit = cls.client.show_audit(audit_uuid)
return audit.get('state') == 'SUCCEEDED'
# ### ACTION PLANS ### #
@classmethod
@creates('action_plan')
def start_action_plan(cls, audit_uuid, type='ONESHOT',
state='PENDING', deadline=None):
"""Wrapper utility for creating a test action plan
:param audit_uuid: Audit Template UUID this action plan will use
:param type: Audit type (either ONESHOT or CONTINUOUS)
:return: A tuple with The HTTP response and its body
"""
resp, body = cls.client.create_action_plan(
audit_uuid=audit_uuid, type=type,
state=state, deadline=deadline)
return resp, body
@classmethod
def delete_action_plan(cls, action_plan_uuid):
"""Deletes an action plan having the specified UUID
:param action_plan_uuid: The unique identifier of the action plan.
:return: the HTTP response
"""
resp, body = cls.client.delete_action_plan(action_plan_uuid)
if action_plan_uuid in cls.created_objects['action_plan']:
cls.created_objects['action_plan'].remove(action_plan_uuid)
return resp
@classmethod
def has_action_plan_finished(cls, action_plan_uuid):
_, action_plan = cls.client.show_action_plan(action_plan_uuid)
return action_plan.get('state') in ('FAILED', 'SUCCEEDED', 'CANCELLED')

View File

@ -0,0 +1,165 @@
# -*- 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 functools
from tempest import test
from tempest_lib import exceptions as lib_exc
from watcher_tempest_plugin.tests.api.admin import base
class TestCreateDeleteExecuteActionPlan(base.BaseInfraOptimTest):
"""Tests for action plans"""
@test.attr(type='smoke')
def test_create_action_plan(self):
_, audit_template = self.create_audit_template()
_, audit = self.create_audit(audit_template['uuid'])
self.assertTrue(test.call_until_true(
func=functools.partial(self.has_audit_succeeded, audit['uuid']),
duration=10,
sleep_for=.5
))
_, action_plans = self.client.list_action_plan_by_audit(audit['uuid'])
action_plan = action_plans['action_plans'][0]
_, action_plan = self.client.show_action_plan(action_plan['uuid'])
self.assertEqual(action_plan['audit_uuid'], audit['uuid'])
self.assertEqual(action_plan['state'], 'RECOMMENDED')
@test.attr(type='smoke')
def test_delete_action_plan(self):
_, audit_template = self.create_audit_template()
_, audit = self.create_audit(audit_template['uuid'])
self.assertTrue(test.call_until_true(
func=functools.partial(self.has_audit_succeeded, audit['uuid']),
duration=10,
sleep_for=.5
))
_, action_plans = self.client.list_action_plan_by_audit(audit['uuid'])
action_plan = action_plans['action_plans'][0]
_, action_plan = self.client.show_action_plan(action_plan['uuid'])
self.client.delete_action_plan(action_plan['uuid'])
self.assertRaises(lib_exc.NotFound, self.client.show_action_plan,
action_plan['uuid'])
@test.attr(type='smoke')
def test_execute_dummy_action_plan(self):
_, audit_template = self.create_audit_template()
_, audit = self.create_audit(audit_template['uuid'])
self.assertTrue(test.call_until_true(
func=functools.partial(self.has_audit_succeeded, audit['uuid']),
duration=10,
sleep_for=.5
))
_, action_plans = self.client.list_action_plan_by_audit(audit['uuid'])
action_plan = action_plans['action_plans'][0]
_, action_plan = self.client.show_action_plan(action_plan['uuid'])
# Execute the action by changing its state to STARTING
_, updated_ap = self.client.update_action_plan(
action_plan['uuid'],
patch=[{'path': '/state', 'op': 'replace', 'value': 'STARTING'}]
)
self.assertTrue(test.call_until_true(
func=functools.partial(
self.has_action_plan_finished, action_plan['uuid']),
duration=10,
sleep_for=.5
))
_, finished_ap = self.client.show_action_plan(action_plan['uuid'])
self.assertIn(updated_ap['state'], ('STARTING', 'ONGOING'))
self.assertEqual(finished_ap['state'], 'SUCCEEDED')
class TestShowListActionPlan(base.BaseInfraOptimTest):
"""Tests for action_plan."""
@classmethod
def resource_setup(cls):
super(TestShowListActionPlan, cls).resource_setup()
_, cls.audit_template = cls.create_audit_template()
_, cls.audit = cls.create_audit(cls.audit_template['uuid'])
assert test.call_until_true(
func=functools.partial(cls.has_audit_succeeded, cls.audit['uuid']),
duration=10,
sleep_for=.5
)
_, action_plans = cls.client.list_action_plan_by_audit(
cls.audit['uuid'])
cls.action_plan = action_plans['action_plans'][0]
@test.attr(type='smoke')
def test_show_action_plan(self):
_, action_plan = self.client.show_action_plan(
self.action_plan['uuid'])
self.assert_expected(self.action_plan, action_plan)
@test.attr(type='smoke')
def test_show_action_plan_detail(self):
_, action_plans = self.client.list_action_plans_detail(
audit_uuid=self.audit['uuid'])
action_plan = action_plans['action_plans'][0]
self.assert_expected(self.action_plan, action_plan)
@test.attr(type='smoke')
def test_show_action_plan_with_links(self):
_, action_plan = self.client.show_action_plan(
self.action_plan['uuid'])
self.assertIn('links', action_plan.keys())
self.assertEqual(2, len(action_plan['links']))
self.assertIn(action_plan['uuid'],
action_plan['links'][0]['href'])
@test.attr(type="smoke")
def test_list_action_plans(self):
_, body = self.client.list_action_plans()
self.assertIn(self.action_plan['uuid'],
[i['uuid'] for i in body['action_plans']])
# Verify self links.
for action_plan in body['action_plans']:
self.validate_self_link('action_plans', action_plan['uuid'],
action_plan['links'][0]['href'])
@test.attr(type='smoke')
def test_list_with_limit(self):
# We create 3 extra audits to exceed the limit we fix
for _ in range(3):
self.create_audit(self.audit_template['uuid'])
_, body = self.client.list_action_plans(limit=3)
next_marker = body['action_plans'][-1]['uuid']
self.assertEqual(len(body['action_plans']), 3)
self.assertIn(next_marker, body['next'])