Merge "Add tempest test for reactive enforcement"

This commit is contained in:
Jenkins 2015-05-15 18:28:37 +00:00 committed by Gerrit Code Review
commit 7de574bba7
4 changed files with 121 additions and 5 deletions

View File

@ -1094,3 +1094,19 @@ class ExecutionDriver(object):
raise exception.CongressException(
'driver %s has no "execute" method but was asked to '
'execute %s on arguments %s' % (self.name, action, action_args))
def _convert_args(self, positional_args):
"""Convert positional args to optional/named args.
:param <list> positional_args: items are assumed being
ordered as ['key1', 'value1', 'key2', 'value2',].
:return <dict>: {'key1': 'value1', 'key2': 'value2'}
"""
if len(positional_args) % 2 != 0:
raise exception.InvalidParamException(
'%s must be in pairs to convert to optional/named args'
% positional_args)
named_args = {}
for key, val in zip(*[iter(positional_args)] * 2):
named_args.update({key: val})
return named_args

View File

@ -167,7 +167,37 @@ class NovaDriver(datasource_driver.DataSourceDriver,
def execute(self, action, action_args):
"""Overwrite ExecutionDriver.execute()."""
# action can be written as a method or an API call.
# action_agrs can be utilized for distinguishing the two.
# This is an API call via client:
LOG.info("%s:: executing %s on %s", self.name, action, action_args)
f = getattr(self, action, None)
if f:
f(action_args)
else:
self._execute_api(self.nova_client, action, action_args)
# "action" methods - to be used with "execute"
def servers_set_meta(self, args):
"""A wrapper for servers.set_meta().
'execute[p(x)]' doesn't take optional args at the moment.
Therefore, this function translates the positional ARGS
to optional args and call the servers.set_meta() api.
:param <list> args: expected server ID and pairs of meta
data in positional args such as:
{'positional': ['server_id', 'meta1', 'value1', 'meta2', 'value2']}
Usage:
execute[nova.servers_set_meta(svr_id, meta1, val1, meta2, val2) :-
triggering_table(id)
"""
action = 'servers.set_meta'
positional_args = args.get('positional', [])
if not positional_args:
LOG.error('Args not found for servers_set_meta()')
return
# Strip off the server_id before converting meta data pairs
server_id = positional_args.pop(0)
meta_data = self._convert_args(positional_args)
action_args = {'named': {'server': server_id,
'metadata': meta_data}}
self._execute_api(self.nova_client, action, action_args)

View File

@ -0,0 +1,26 @@
# Copyright (c) 2015 Hewlett Packard. All rights reserved.
#
# 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 retrying
@retrying.retry(stop_max_attempt_number=20, wait_fixed=1000)
def retry_check_function_return_value(f, expected_value, error_msg=None):
"""Check if function f returns expected value."""
if not error_msg:
error_msg = 'Expected value "%s" not found' % expected_value
r = f()
if r != expected_value:
raise Exception(error_msg)

View File

@ -17,6 +17,7 @@ from oslo_log import log as logging
from tempest import config # noqa
from tempest import exceptions # noqa
from tempest.scenario import helper
from tempest.scenario import manager_congress # noqa
from tempest import test # noqa
@ -54,7 +55,24 @@ class TestPolicyBasicOps(manager_congress.ScenarioPolicyBase):
resp['id'])
return resp['name']
def _create_test_server(self):
def _create_policy_rule(self, policy_name, rule, rule_name=None,
comment=None):
body = {'rule': rule}
if rule_name:
body['name'] = rule_name
if comment:
body['comment'] = comment
client = self.admin_manager.congress_client
response = client.create_policy_rule(policy_name, body)
if response:
self.addCleanup(client.delete_policy_rule, policy_name,
response['id'])
return response
else:
raise Exception('Failed to create policy rule (%s, %s)'
% (policy_name, rule))
def _create_test_server(self, name=None):
image_ref = CONF.compute.image_ref
flavor_ref = CONF.compute.flavor_ref
keypair = self.create_keypair()
@ -62,7 +80,8 @@ class TestPolicyBasicOps(manager_congress.ScenarioPolicyBase):
security_groups = [{'name': security_group['name']}]
create_kwargs = {'key_name': keypair['name'],
'security_groups': security_groups}
instance = self.create_server(image=image_ref,
instance = self.create_server(name=name,
image=image_ref,
flavor=flavor_ref,
create_kwargs=create_kwargs)
return instance
@ -122,6 +141,31 @@ class TestPolicyBasicOps(manager_congress.ScenarioPolicyBase):
raise exceptions.TimeoutException("Data did not converge in time "
"or failure in server")
@test.attr(type='smoke')
@test.services('compute', 'network')
def test_reactive_enforcement(self):
servers_client = self.admin_manager.servers_client
server_name = 'server_under_test'
server = self._create_test_server(name=server_name)
policy_name = self._create_random_policy()
meta_key = 'meta_test_key1'
meta_val = 'value1'
meta_data = {meta_key: meta_val}
rules = [
'execute[nova:servers_set_meta(id, "%s", "%s")] :- '
'test_servers(id)' % (meta_key, meta_val),
'test_servers(id) :- '
'nova:servers(id, name, host_id, status, '
'tenant_id, user_id, image_id, flavor_id),'
'equal(name, "%s")' % server_name]
for rule in rules:
self._create_policy_rule(policy_name, rule)
f = lambda: servers_client.get_server_metadata_item(server['id'],
meta_key)
helper.retry_check_function_return_value(f, meta_data)
class TestCongressDataSources(manager_congress.ScenarioPolicyBase):