Merge "Add tempest test for reactive enforcement"
This commit is contained in:
commit
7de574bba7
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
|
@ -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):
|
||||
|
||||
|
|
Loading…
Reference in New Issue