Add create_audit_template_and_delete scenario
This patch set adds create_audit_template_and_delete scenario and appropriate unit tests and samples. Change-Id: I6f073a85439a8529e80631119a9da8618cfb6833
This commit is contained in:
parent
2a08398705
commit
fb632b3cc7
20
rally-jobs/rally-watcher.yaml
Normal file
20
rally-jobs/rally-watcher.yaml
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
---
|
||||||
|
Watcher.create_audit_template_and_delete:
|
||||||
|
-
|
||||||
|
args:
|
||||||
|
goal:
|
||||||
|
name: "dummy"
|
||||||
|
strategy:
|
||||||
|
name: "dummy"
|
||||||
|
extra: {}
|
||||||
|
runner:
|
||||||
|
type: "constant"
|
||||||
|
times: 10
|
||||||
|
concurrency: 2
|
||||||
|
context:
|
||||||
|
users:
|
||||||
|
tenants: 3
|
||||||
|
users_per_tenant: 2
|
||||||
|
sla:
|
||||||
|
failure_rate:
|
||||||
|
max: 0
|
40
rally/plugins/openstack/scenarios/watcher/basic.py
Normal file
40
rally/plugins/openstack/scenarios/watcher/basic.py
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
# 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 rally import consts
|
||||||
|
from rally.plugins.openstack import scenario
|
||||||
|
from rally.plugins.openstack.scenarios.watcher import utils
|
||||||
|
from rally.task import types
|
||||||
|
from rally.task import validation
|
||||||
|
|
||||||
|
|
||||||
|
class Watcher(utils.WatcherScenario):
|
||||||
|
"""Benchmark scenarios for Watcher servers."""
|
||||||
|
|
||||||
|
@types.convert(strategy={"type": "watcher_strategy"},
|
||||||
|
goal={"type": "watcher_goal"})
|
||||||
|
@validation.required_services(consts.Service.WATCHER)
|
||||||
|
@validation.required_openstack(admin=True)
|
||||||
|
@scenario.configure(context={"admin_cleanup": ["watcher"]})
|
||||||
|
def create_audit_template_and_delete(self, goal, strategy, extra=None):
|
||||||
|
"""Create audit template and delete it.
|
||||||
|
|
||||||
|
:param goal: The goal audit template is based on
|
||||||
|
:param strategy: The strategy used to provide resource optimization
|
||||||
|
algorithm
|
||||||
|
:param extra: This field is used to specify some audit template
|
||||||
|
options
|
||||||
|
"""
|
||||||
|
|
||||||
|
extra = extra or {}
|
||||||
|
audit_template = self._create_audit_template(goal, strategy, extra)
|
||||||
|
self._delete_audit_template(audit_template.uuid)
|
41
rally/plugins/openstack/scenarios/watcher/utils.py
Normal file
41
rally/plugins/openstack/scenarios/watcher/utils.py
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
# 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 rally.plugins.openstack import scenario
|
||||||
|
from rally.task import atomic
|
||||||
|
|
||||||
|
|
||||||
|
class WatcherScenario(scenario.OpenStackScenario):
|
||||||
|
"""Base class for Watcher scenarios with basic atomic actions."""
|
||||||
|
|
||||||
|
@atomic.action_timer("watcher.create_audit_template")
|
||||||
|
def _create_audit_template(self, goal_id, strategy_id, extra):
|
||||||
|
"""Create Audit Template in DB
|
||||||
|
|
||||||
|
:param goal_id: UUID Goal
|
||||||
|
:param strategy_id: UUID Strategy
|
||||||
|
:param extra: Audit Template Extra (JSON Dict)
|
||||||
|
:return: Audit Template object
|
||||||
|
"""
|
||||||
|
return self.admin_clients("watcher").audit_template.create(
|
||||||
|
goal=goal_id,
|
||||||
|
strategy=strategy_id,
|
||||||
|
name=self.generate_random_name(),
|
||||||
|
extra=extra or {})
|
||||||
|
|
||||||
|
@atomic.action_timer("watcher.delete_audit_template")
|
||||||
|
def _delete_audit_template(self, audit_template):
|
||||||
|
"""Delete Audit Template from DB
|
||||||
|
|
||||||
|
:param audit_template: Audit Template object
|
||||||
|
"""
|
||||||
|
self.admin_clients("watcher").audit_template.delete(audit_template)
|
@ -166,3 +166,51 @@ class NeutronNetwork(types.ResourceType):
|
|||||||
raise exceptions.InvalidScenarioArgument(
|
raise exceptions.InvalidScenarioArgument(
|
||||||
"Neutron network with name '{name}' not found".format(
|
"Neutron network with name '{name}' not found".format(
|
||||||
name=resource_config.get("name")))
|
name=resource_config.get("name")))
|
||||||
|
|
||||||
|
|
||||||
|
@plugin.configure(name="watcher_strategy")
|
||||||
|
class WatcherStrategy(types.ResourceType):
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def transform(cls, clients, resource_config):
|
||||||
|
"""Transform the resource config to id.
|
||||||
|
|
||||||
|
:param clients: openstack admin client handles
|
||||||
|
:param resource_config: scenario config with `id`, `name` or `regex`
|
||||||
|
|
||||||
|
:returns: id matching resource
|
||||||
|
"""
|
||||||
|
resource_id = resource_config.get("id")
|
||||||
|
if not resource_id:
|
||||||
|
watcherclient = clients.watcher()
|
||||||
|
resource_id = types._id_from_name(
|
||||||
|
resource_config=resource_config,
|
||||||
|
resources=[watcherclient.strategy.get(
|
||||||
|
resource_config.get("name"))],
|
||||||
|
typename="strategy",
|
||||||
|
id_attr="uuid")
|
||||||
|
return resource_id
|
||||||
|
|
||||||
|
|
||||||
|
@plugin.configure(name="watcher_goal")
|
||||||
|
class WatcherGoal(types.ResourceType):
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def transform(cls, clients, resource_config):
|
||||||
|
"""Transform the resource config to id.
|
||||||
|
|
||||||
|
:param clients: openstack admin client handles
|
||||||
|
:param resource_config: scenario config with `id`, `name` or `regex`
|
||||||
|
|
||||||
|
:returns: id matching resource
|
||||||
|
"""
|
||||||
|
resource_id = resource_config.get("id")
|
||||||
|
if not resource_id:
|
||||||
|
watcherclient = clients.watcher()
|
||||||
|
resource_id = types._id_from_name(
|
||||||
|
resource_config=resource_config,
|
||||||
|
resources=[watcherclient.goal.get(
|
||||||
|
resource_config.get("name"))],
|
||||||
|
typename="goal",
|
||||||
|
id_attr="uuid")
|
||||||
|
return resource_id
|
||||||
|
@ -0,0 +1,20 @@
|
|||||||
|
{
|
||||||
|
"Watcher.create_audit_template_and_delete": [
|
||||||
|
{
|
||||||
|
"args": {
|
||||||
|
"goal": {
|
||||||
|
"name": "dummy"
|
||||||
|
},
|
||||||
|
"strategy": {
|
||||||
|
"name": "dummy"
|
||||||
|
},
|
||||||
|
"extra": {}
|
||||||
|
},
|
||||||
|
"runner": {
|
||||||
|
"type": "constant",
|
||||||
|
"times": 10,
|
||||||
|
"concurrency": 2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
@ -0,0 +1,13 @@
|
|||||||
|
---
|
||||||
|
Watcher.create_audit_template_and_delete:
|
||||||
|
-
|
||||||
|
args:
|
||||||
|
goal:
|
||||||
|
name: "dummy"
|
||||||
|
strategy:
|
||||||
|
name: "dummy"
|
||||||
|
extra: {}
|
||||||
|
runner:
|
||||||
|
type: "constant"
|
||||||
|
times: 10
|
||||||
|
concurrency: 2
|
@ -434,15 +434,17 @@ class FakeImageManager(FakeManager):
|
|||||||
|
|
||||||
|
|
||||||
class FakeStrategyManager(FakeManager):
|
class FakeStrategyManager(FakeManager):
|
||||||
|
def get(self, resource_name):
|
||||||
def create(self):
|
for key in self.resources_order:
|
||||||
return FakeStrategy(self)
|
if self.cache[key].name == resource_name:
|
||||||
|
return self.cache[key]
|
||||||
|
|
||||||
|
|
||||||
class FakeGoalManager(FakeManager):
|
class FakeGoalManager(FakeManager):
|
||||||
|
def get(self, resource_name):
|
||||||
def create(self):
|
for key in self.resources_order:
|
||||||
return FakeGoal(self)
|
if self.cache[key].name == resource_name:
|
||||||
|
return self.cache[key]
|
||||||
|
|
||||||
|
|
||||||
class FakePackageManager(FakeManager):
|
class FakePackageManager(FakeManager):
|
||||||
|
35
tests/unit/plugins/openstack/scenarios/watcher/test_basic.py
Normal file
35
tests/unit/plugins/openstack/scenarios/watcher/test_basic.py
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
# Copyright 2016: Servionica LTD.
|
||||||
|
# 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 mock
|
||||||
|
|
||||||
|
from rally.plugins.openstack.scenarios.watcher import basic
|
||||||
|
from tests.unit import test
|
||||||
|
|
||||||
|
|
||||||
|
class WatcherTestCase(test.ScenarioTestCase):
|
||||||
|
|
||||||
|
def test_create_audit_template_and_delete(self):
|
||||||
|
scenario = basic.Watcher(self.context)
|
||||||
|
audit_template = mock.Mock()
|
||||||
|
scenario._create_audit_template = mock.MagicMock(
|
||||||
|
return_value=audit_template)
|
||||||
|
scenario._delete_audit_template = mock.MagicMock()
|
||||||
|
scenario.create_audit_template_and_delete("goal", "strategy", {})
|
||||||
|
scenario._create_audit_template.assert_called_once_with("goal",
|
||||||
|
"strategy",
|
||||||
|
{})
|
||||||
|
scenario._delete_audit_template.assert_called_once_with(
|
||||||
|
audit_template.uuid)
|
47
tests/unit/plugins/openstack/scenarios/watcher/test_utils.py
Normal file
47
tests/unit/plugins/openstack/scenarios/watcher/test_utils.py
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
# Copyright 2016: Servionica LTD.
|
||||||
|
# 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 mock
|
||||||
|
|
||||||
|
from rally.plugins.openstack.scenarios.watcher import utils
|
||||||
|
from tests.unit import test
|
||||||
|
|
||||||
|
|
||||||
|
class WatcherScenarioTestCase(test.ScenarioTestCase):
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
super(WatcherScenarioTestCase, self).setUp()
|
||||||
|
|
||||||
|
def test_create_audit_template(self):
|
||||||
|
watcher_scenario = utils.WatcherScenario(self.context)
|
||||||
|
watcher_scenario.generate_random_name = mock.MagicMock(
|
||||||
|
return_value="mock_name")
|
||||||
|
watcher_scenario._create_audit_template("fake_goal", "fake_strategy",
|
||||||
|
{})
|
||||||
|
self.admin_clients(
|
||||||
|
"watcher").audit_template.create.assert_called_once_with(
|
||||||
|
goal="fake_goal", strategy="fake_strategy",
|
||||||
|
name="mock_name", extra={})
|
||||||
|
self._test_atomic_action_timer(watcher_scenario.atomic_actions(),
|
||||||
|
"watcher.create_audit_template")
|
||||||
|
|
||||||
|
def test_delete_audit_template(self):
|
||||||
|
watcher_scenario = utils.WatcherScenario(self.context)
|
||||||
|
watcher_scenario._delete_audit_template("fake_audit_template")
|
||||||
|
self.admin_clients(
|
||||||
|
"watcher").audit_template.delete.assert_called_once_with(
|
||||||
|
"fake_audit_template")
|
||||||
|
self._test_atomic_action_timer(watcher_scenario.atomic_actions(),
|
||||||
|
"watcher.delete_audit_template")
|
@ -13,6 +13,7 @@
|
|||||||
# License for the specific language governing permissions and limitations
|
# License for the specific language governing permissions and limitations
|
||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
|
import ddt
|
||||||
import mock
|
import mock
|
||||||
|
|
||||||
from rally import exceptions
|
from rally import exceptions
|
||||||
@ -325,3 +326,51 @@ class NeutronNetworkTestCase(test.TestCase):
|
|||||||
self.assertRaises(exceptions.InvalidScenarioArgument,
|
self.assertRaises(exceptions.InvalidScenarioArgument,
|
||||||
types.NeutronNetwork.transform,
|
types.NeutronNetwork.transform,
|
||||||
self.clients, resource_config)
|
self.clients, resource_config)
|
||||||
|
|
||||||
|
|
||||||
|
@ddt.ddt
|
||||||
|
class WatcherStrategyTestCase(test.TestCase):
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
super(WatcherStrategyTestCase, self).setUp()
|
||||||
|
self.clients = fakes.FakeClients()
|
||||||
|
self.strategy = self.clients.watcher().strategy._cache(
|
||||||
|
fakes.FakeResource(name="dummy", id="1"))
|
||||||
|
|
||||||
|
@ddt.data({"resource_config": {"name": "dummy"}})
|
||||||
|
@ddt.unpack
|
||||||
|
def test_transform_by_name(self, resource_config=None):
|
||||||
|
strategy_id = types.WatcherStrategy.transform(self.clients,
|
||||||
|
resource_config)
|
||||||
|
self.assertEqual(self.strategy.uuid, strategy_id)
|
||||||
|
|
||||||
|
@ddt.data({"resource_config": {"name": "dummy-1"}})
|
||||||
|
@ddt.unpack
|
||||||
|
def test_transform_by_name_no_match(self, resource_config=None):
|
||||||
|
self.assertRaises(exceptions.RallyException,
|
||||||
|
types.WatcherStrategy.transform,
|
||||||
|
self.clients, resource_config)
|
||||||
|
|
||||||
|
|
||||||
|
@ddt.ddt
|
||||||
|
class WatcherGoalTestCase(test.TestCase):
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
super(WatcherGoalTestCase, self).setUp()
|
||||||
|
self.clients = fakes.FakeClients()
|
||||||
|
self.goal = self.clients.watcher().goal._cache(
|
||||||
|
fakes.FakeResource(name="dummy", id="1"))
|
||||||
|
|
||||||
|
@ddt.data({"resource_config": {"name": "dummy"}})
|
||||||
|
@ddt.unpack
|
||||||
|
def test_transform_by_name(self, resource_config=None):
|
||||||
|
goal_id = types.WatcherGoal.transform(self.clients,
|
||||||
|
resource_config)
|
||||||
|
self.assertEqual(self.goal.uuid, goal_id)
|
||||||
|
|
||||||
|
@ddt.data({"resource_config": {"name": "dummy-1"}})
|
||||||
|
@ddt.unpack
|
||||||
|
def test_transform_by_name_no_match(self, resource_config=None):
|
||||||
|
self.assertRaises(exceptions.RallyException,
|
||||||
|
types.WatcherGoal.transform,
|
||||||
|
self.clients, resource_config)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user