Merge "Move rally.benchmark.scenarios.utils"
This commit is contained in:
commit
c6ac4ef45e
@ -86,7 +86,7 @@ In a toy example below, we define a scenario class *MyScenario* with one benchma
|
||||
::
|
||||
|
||||
from rally.benchmark.scenarios import base
|
||||
from rally.benchmark.scenarios import utils
|
||||
from rally.benchmark import utils
|
||||
|
||||
|
||||
class MyScenario(base.Scenario):
|
||||
|
@ -1,124 +0,0 @@
|
||||
# Copyright 2013 IBM Corp.
|
||||
#
|
||||
# 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 jsonschema
|
||||
|
||||
from rally import consts
|
||||
|
||||
|
||||
class ActionBuilder(object):
|
||||
"""Builder class for mapping and creating action objects.
|
||||
|
||||
An action list is an array of single key/value dicts which takes
|
||||
the form:
|
||||
|
||||
[{"action": times}, {"action": times}...]
|
||||
|
||||
Here 'action' is a string which indicates a action to perform and
|
||||
'times' is a non-zero positive integer which specifies how many
|
||||
times to run the action in sequence.
|
||||
|
||||
This utility builder class will build and return methods which
|
||||
wrapper the action call the given amount of times.
|
||||
"""
|
||||
|
||||
SCHEMA_TEMPLATE = {
|
||||
"type": "array",
|
||||
"$schema": consts.JSON_SCHEMA,
|
||||
"items": {
|
||||
"type": "object",
|
||||
"properties": {},
|
||||
"additionalProperties": False,
|
||||
"minItems": 0
|
||||
}
|
||||
}
|
||||
|
||||
ITEM_TEMPLATE = {
|
||||
"type": "integer",
|
||||
"minimum": 0,
|
||||
"exclusiveMinimum": True,
|
||||
"optional": True
|
||||
}
|
||||
|
||||
def __init__(self, action_keywords):
|
||||
"""Create a new instance of the builder for the given action keywords.
|
||||
|
||||
:param action_keywords: A list of strings which are the keywords this
|
||||
instance of the builder supports.
|
||||
"""
|
||||
self._bindings = {}
|
||||
self.schema = dict(ActionBuilder.SCHEMA_TEMPLATE)
|
||||
for kw in action_keywords:
|
||||
self.schema["items"]["properties"][kw] = (
|
||||
ActionBuilder.ITEM_TEMPLATE)
|
||||
|
||||
def bind_action(self, action_key, action, *args, **kwargs):
|
||||
"""Bind an action to an action key.
|
||||
|
||||
Static args/kwargs can be optionally binded.
|
||||
:param action_key: The action keyword to bind the action to.
|
||||
:param action: A method/function to call for the action.
|
||||
:param args: (optional) Static positional args to prepend
|
||||
to all invocations of the action.
|
||||
:param kwargs: (optional) Static kwargs to prepend to all
|
||||
invocations of the action.
|
||||
"""
|
||||
self.validate([{action_key: 1}])
|
||||
self._bindings[action_key] = {
|
||||
"action": action,
|
||||
"args": args or (),
|
||||
"kwargs": kwargs or {}
|
||||
}
|
||||
|
||||
def validate(self, actions):
|
||||
"""Validate the list of action objects against the builder schema.
|
||||
|
||||
:param actions: The list of action objects to validate.
|
||||
"""
|
||||
jsonschema.validate(actions, self.schema)
|
||||
|
||||
def _build(self, func, times, *args, **kwargs):
|
||||
"""Build the wrapper action call."""
|
||||
def _f():
|
||||
for i in range(times):
|
||||
func(*args, **kwargs)
|
||||
return _f
|
||||
|
||||
def build_actions(self, actions, *args, **kwargs):
|
||||
"""Build a list of callable actions.
|
||||
|
||||
A list of callable actions based on the given action object list and
|
||||
the actions bound to this builder.
|
||||
|
||||
:param actions: A list of action objects to build callable
|
||||
action for.
|
||||
:param args: (optional) Positional args to pass into each
|
||||
built action. These will be appended to any args set for the
|
||||
action via its binding.
|
||||
:param kwargs: (optional) Keyword args to pass into each built
|
||||
action. These will be appended to any kwards set for the action
|
||||
via its binding.
|
||||
"""
|
||||
self.validate(actions)
|
||||
bound_actions = []
|
||||
for action in actions:
|
||||
action_key = list(action)[0]
|
||||
times = action.get(action_key)
|
||||
binding = self._bindings.get(action_key)
|
||||
dft_kwargs = dict(binding["kwargs"])
|
||||
dft_kwargs.update(kwargs or {})
|
||||
bound_actions.append(
|
||||
self._build(binding["action"], times,
|
||||
*(binding["args"] + args), **dft_kwargs))
|
||||
return bound_actions
|
@ -17,11 +17,13 @@ import itertools
|
||||
import time
|
||||
import traceback
|
||||
|
||||
import jsonschema
|
||||
from novaclient import exceptions as nova_exc
|
||||
import six
|
||||
|
||||
from rally.common.i18n import _
|
||||
from rally.common import log as logging
|
||||
from rally import consts
|
||||
from rally import exceptions
|
||||
|
||||
|
||||
@ -175,3 +177,110 @@ def check_service_status(client, service_name):
|
||||
"nova. Pre-Grizzly OpenStack deployment?"))
|
||||
return False
|
||||
return False
|
||||
|
||||
|
||||
class ActionBuilder(object):
|
||||
"""Builder class for mapping and creating action objects.
|
||||
|
||||
An action list is an array of single key/value dicts which takes
|
||||
the form:
|
||||
|
||||
[{"action": times}, {"action": times}...]
|
||||
|
||||
Here 'action' is a string which indicates a action to perform and
|
||||
'times' is a non-zero positive integer which specifies how many
|
||||
times to run the action in sequence.
|
||||
|
||||
This utility builder class will build and return methods which
|
||||
wrapper the action call the given amount of times.
|
||||
"""
|
||||
|
||||
SCHEMA_TEMPLATE = {
|
||||
"type": "array",
|
||||
"$schema": consts.JSON_SCHEMA,
|
||||
"items": {
|
||||
"type": "object",
|
||||
"properties": {},
|
||||
"additionalProperties": False,
|
||||
"minItems": 0
|
||||
}
|
||||
}
|
||||
|
||||
ITEM_TEMPLATE = {
|
||||
"type": "integer",
|
||||
"minimum": 0,
|
||||
"exclusiveMinimum": True,
|
||||
"optional": True
|
||||
}
|
||||
|
||||
def __init__(self, action_keywords):
|
||||
"""Create a new instance of the builder for the given action keywords.
|
||||
|
||||
:param action_keywords: A list of strings which are the keywords this
|
||||
instance of the builder supports.
|
||||
"""
|
||||
self._bindings = {}
|
||||
self.schema = dict(ActionBuilder.SCHEMA_TEMPLATE)
|
||||
for kw in action_keywords:
|
||||
self.schema["items"]["properties"][kw] = (
|
||||
ActionBuilder.ITEM_TEMPLATE)
|
||||
|
||||
def bind_action(self, action_key, action, *args, **kwargs):
|
||||
"""Bind an action to an action key.
|
||||
|
||||
Static args/kwargs can be optionally binded.
|
||||
:param action_key: The action keyword to bind the action to.
|
||||
:param action: A method/function to call for the action.
|
||||
:param args: (optional) Static positional args to prepend
|
||||
to all invocations of the action.
|
||||
:param kwargs: (optional) Static kwargs to prepend to all
|
||||
invocations of the action.
|
||||
"""
|
||||
self.validate([{action_key: 1}])
|
||||
self._bindings[action_key] = {
|
||||
"action": action,
|
||||
"args": args or (),
|
||||
"kwargs": kwargs or {}
|
||||
}
|
||||
|
||||
def validate(self, actions):
|
||||
"""Validate the list of action objects against the builder schema.
|
||||
|
||||
:param actions: The list of action objects to validate.
|
||||
"""
|
||||
jsonschema.validate(actions, self.schema)
|
||||
|
||||
def _build(self, func, times, *args, **kwargs):
|
||||
"""Build the wrapper action call."""
|
||||
def _f():
|
||||
for i in range(times):
|
||||
func(*args, **kwargs)
|
||||
return _f
|
||||
|
||||
def build_actions(self, actions, *args, **kwargs):
|
||||
"""Build a list of callable actions.
|
||||
|
||||
A list of callable actions based on the given action object list and
|
||||
the actions bound to this builder.
|
||||
|
||||
:param actions: A list of action objects to build callable
|
||||
action for.
|
||||
:param args: (optional) Positional args to pass into each
|
||||
built action. These will be appended to any args set for the
|
||||
action via its binding.
|
||||
:param kwargs: (optional) Keyword args to pass into each built
|
||||
action. These will be appended to any kwards set for the action
|
||||
via its binding.
|
||||
"""
|
||||
self.validate(actions)
|
||||
bound_actions = []
|
||||
for action in actions:
|
||||
action_key = list(action)[0]
|
||||
times = action.get(action_key)
|
||||
binding = self._bindings.get(action_key)
|
||||
dft_kwargs = dict(binding["kwargs"])
|
||||
dft_kwargs.update(kwargs or {})
|
||||
bound_actions.append(
|
||||
self._build(binding["action"], times,
|
||||
*(binding["args"] + args), **dft_kwargs))
|
||||
return bound_actions
|
||||
|
@ -16,8 +16,8 @@
|
||||
import jsonschema
|
||||
|
||||
from rally.benchmark.scenarios import base
|
||||
from rally.benchmark.scenarios import utils as scenario_utils
|
||||
from rally.benchmark import types as types
|
||||
from rally.benchmark import utils as bench_utils
|
||||
from rally.benchmark import validation
|
||||
from rally.common import log as logging
|
||||
from rally import consts
|
||||
@ -301,7 +301,7 @@ class NovaServers(utils.NovaScenario,
|
||||
def _bind_actions(self):
|
||||
actions = ["hard_reboot", "soft_reboot", "stop_start",
|
||||
"rescue_unrescue"]
|
||||
action_builder = scenario_utils.ActionBuilder(actions)
|
||||
action_builder = bench_utils.ActionBuilder(actions)
|
||||
action_builder.bind_action("hard_reboot", self._reboot_server)
|
||||
action_builder.bind_action("soft_reboot", self._soft_reboot_server)
|
||||
action_builder.bind_action("stop_start",
|
||||
|
@ -1,184 +0,0 @@
|
||||
# Copyright 2013 IBM Corp.
|
||||
#
|
||||
# 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 jsonschema import exceptions as schema_exceptions
|
||||
import mock
|
||||
|
||||
from rally.benchmark.scenarios import utils
|
||||
from tests.unit import test
|
||||
|
||||
|
||||
def action_one(self, *args, **kwargs):
|
||||
pass
|
||||
|
||||
|
||||
def action_two(self, *args, **kwargs):
|
||||
pass
|
||||
|
||||
|
||||
class ActionBuilderTestCase(test.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
super(ActionBuilderTestCase, self).setUp()
|
||||
self.mock_one = "%s.action_one" % __name__
|
||||
self.mock_two = "%s.action_two" % __name__
|
||||
|
||||
def test_invalid_keyword(self):
|
||||
builder = utils.ActionBuilder(["action_one", "action_two"])
|
||||
self.assertRaises(schema_exceptions.ValidationError,
|
||||
builder.build_actions, [{"missing": 1}])
|
||||
|
||||
def test_invalid_bind(self):
|
||||
builder = utils.ActionBuilder(["action_one"])
|
||||
self.assertRaises(schema_exceptions.ValidationError,
|
||||
builder.bind_action, "missing", action_one)
|
||||
|
||||
def test_invalid_schema(self):
|
||||
builder = utils.ActionBuilder(["action_one", "action_two"])
|
||||
self.assertRaises(schema_exceptions.ValidationError,
|
||||
builder.validate, [{"action_oone": 1},
|
||||
{"action_twoo": 2}])
|
||||
self.assertRaises(schema_exceptions.ValidationError,
|
||||
builder.validate, [{"action_one": -1},
|
||||
{"action_two": 2}])
|
||||
self.assertRaises(schema_exceptions.ValidationError,
|
||||
builder.validate, [{"action_one": 0},
|
||||
{"action_two": 2}])
|
||||
self.assertRaises(schema_exceptions.ValidationError,
|
||||
builder.validate, [{1: 0},
|
||||
{"action_two": 2}])
|
||||
self.assertRaises(schema_exceptions.ValidationError,
|
||||
builder.validate, [{"action_two": "action_two"}])
|
||||
|
||||
def test_positional_args(self):
|
||||
with mock.patch(self.mock_one) as mock_action_one:
|
||||
with mock.patch(self.mock_two) as mock_action_two:
|
||||
builder = utils.ActionBuilder(["action_one", "action_two"])
|
||||
builder.bind_action("action_one", mock_action_one, "a", "b")
|
||||
builder.bind_action("action_two", mock_action_two, "c")
|
||||
actions = builder.build_actions([{"action_two": 3},
|
||||
{"action_one": 4}])
|
||||
for action in actions:
|
||||
action()
|
||||
self.assertEqual(4, mock_action_one.call_count,
|
||||
"action one not called 4 times")
|
||||
mock_calls = []
|
||||
for i in range(4):
|
||||
mock_calls.append(mock.call("a", "b"))
|
||||
mock_action_one.assert_has_calls(mock_calls)
|
||||
|
||||
self.assertEqual(3, mock_action_two.call_count,
|
||||
"action two not called 3 times")
|
||||
mock_calls = []
|
||||
for i in range(3):
|
||||
mock_calls.append(mock.call("c"))
|
||||
mock_action_two.assert_has_calls(mock_calls)
|
||||
|
||||
with mock.patch(self.mock_one) as mock_action_one:
|
||||
with mock.patch(self.mock_two) as mock_action_two:
|
||||
builder = utils.ActionBuilder(["action_one", "action_two"])
|
||||
builder.bind_action("action_one", mock_action_one, "a", "b")
|
||||
builder.bind_action("action_two", mock_action_two, "c")
|
||||
actions = builder.build_actions([{"action_two": 3},
|
||||
{"action_one": 4}],
|
||||
"d", 5)
|
||||
for action in actions:
|
||||
action()
|
||||
self.assertEqual(4, mock_action_one.call_count,
|
||||
"action one not called 4 times")
|
||||
mock_calls = []
|
||||
for i in range(4):
|
||||
mock_calls.append(mock.call("a", "b", "d", 5))
|
||||
mock_action_one.assert_has_calls(mock_calls)
|
||||
|
||||
self.assertEqual(3, mock_action_two.call_count,
|
||||
"action two not called 3 times")
|
||||
mock_calls = []
|
||||
for i in range(3):
|
||||
mock_calls.append(mock.call("c", "d", 5))
|
||||
mock_action_two.assert_has_calls(mock_calls)
|
||||
|
||||
def test_kwargs(self):
|
||||
with mock.patch(self.mock_one) as mock_action_one:
|
||||
with mock.patch(self.mock_two) as mock_action_two:
|
||||
builder = utils.ActionBuilder(["action_one", "action_two"])
|
||||
builder.bind_action("action_one", mock_action_one, a=1, b=2)
|
||||
builder.bind_action("action_two", mock_action_two, c=3)
|
||||
actions = builder.build_actions([{"action_two": 3},
|
||||
{"action_one": 4}])
|
||||
for action in actions:
|
||||
action()
|
||||
self.assertEqual(4, mock_action_one.call_count,
|
||||
"action one not called 4 times")
|
||||
mock_calls = []
|
||||
for i in range(4):
|
||||
mock_calls.append(mock.call(a=1, b=2))
|
||||
mock_action_one.assert_has_calls(mock_calls)
|
||||
|
||||
self.assertEqual(3, mock_action_two.call_count,
|
||||
"action two not called 3 times")
|
||||
mock_calls = []
|
||||
for i in range(3):
|
||||
mock_calls.append(mock.call(c=3))
|
||||
mock_action_two.assert_has_calls(mock_calls)
|
||||
|
||||
with mock.patch(self.mock_one) as mock_action_one:
|
||||
with mock.patch(self.mock_two) as mock_action_two:
|
||||
builder = utils.ActionBuilder(["action_one", "action_two"])
|
||||
builder.bind_action("action_one", mock_action_one, a=1, b=2)
|
||||
builder.bind_action("action_two", mock_action_two, c=3)
|
||||
actions = builder.build_actions([{"action_two": 3},
|
||||
{"action_one": 4}],
|
||||
d=4, e=5)
|
||||
for action in actions:
|
||||
action()
|
||||
self.assertEqual(4, mock_action_one.call_count,
|
||||
"action one not called 4 times")
|
||||
mock_calls = []
|
||||
for i in range(4):
|
||||
mock_calls.append(mock.call(a=1, b=2, d=4, e=5))
|
||||
mock_action_one.assert_has_calls(mock_calls)
|
||||
|
||||
self.assertEqual(3, mock_action_two.call_count,
|
||||
"action two not called 3 times")
|
||||
mock_calls = []
|
||||
for i in range(3):
|
||||
mock_calls.append(mock.call(c=3, d=4, e=5))
|
||||
mock_action_two.assert_has_calls(mock_calls)
|
||||
|
||||
def test_mixed_args(self):
|
||||
with mock.patch(self.mock_one) as mock_action_one:
|
||||
with mock.patch(self.mock_two) as mock_action_two:
|
||||
builder = utils.ActionBuilder(["action_one", "action_two"])
|
||||
builder.bind_action("action_one", mock_action_one, "one",
|
||||
a=1, b=2)
|
||||
builder.bind_action("action_two", mock_action_two, "two", c=3)
|
||||
actions = builder.build_actions([{"action_two": 3},
|
||||
{"action_one": 4}],
|
||||
"three", d=4)
|
||||
for action in actions:
|
||||
action()
|
||||
self.assertEqual(4, mock_action_one.call_count,
|
||||
"action one not called 4 times")
|
||||
mock_calls = []
|
||||
for i in range(4):
|
||||
mock_calls.append(mock.call("one", "three", a=1, b=2, d=4))
|
||||
mock_action_one.assert_has_calls(mock_calls)
|
||||
|
||||
self.assertEqual(3, mock_action_two.call_count,
|
||||
"action two not called 3 times")
|
||||
mock_calls = []
|
||||
for i in range(3):
|
||||
mock_calls.append(mock.call("two", "three", c=3, d=4))
|
||||
mock_action_two.assert_has_calls(mock_calls)
|
@ -15,6 +15,7 @@
|
||||
|
||||
import datetime
|
||||
|
||||
from jsonschema import exceptions as schema_exceptions
|
||||
import mock
|
||||
|
||||
from rally.benchmark import utils
|
||||
@ -232,3 +233,168 @@ class WaitForTestCase(test.TestCase):
|
||||
|
||||
self.assertIn("FakeResource", str(exc))
|
||||
self.assertIn("fake_new_status", str(exc))
|
||||
|
||||
|
||||
def action_one(self, *args, **kwargs):
|
||||
pass
|
||||
|
||||
|
||||
def action_two(self, *args, **kwargs):
|
||||
pass
|
||||
|
||||
|
||||
class ActionBuilderTestCase(test.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
super(ActionBuilderTestCase, self).setUp()
|
||||
self.mock_one = "%s.action_one" % __name__
|
||||
self.mock_two = "%s.action_two" % __name__
|
||||
|
||||
def test_invalid_keyword(self):
|
||||
builder = utils.ActionBuilder(["action_one", "action_two"])
|
||||
self.assertRaises(schema_exceptions.ValidationError,
|
||||
builder.build_actions, [{"missing": 1}])
|
||||
|
||||
def test_invalid_bind(self):
|
||||
builder = utils.ActionBuilder(["action_one"])
|
||||
self.assertRaises(schema_exceptions.ValidationError,
|
||||
builder.bind_action, "missing", action_one)
|
||||
|
||||
def test_invalid_schema(self):
|
||||
builder = utils.ActionBuilder(["action_one", "action_two"])
|
||||
self.assertRaises(schema_exceptions.ValidationError,
|
||||
builder.validate, [{"action_oone": 1},
|
||||
{"action_twoo": 2}])
|
||||
self.assertRaises(schema_exceptions.ValidationError,
|
||||
builder.validate, [{"action_one": -1},
|
||||
{"action_two": 2}])
|
||||
self.assertRaises(schema_exceptions.ValidationError,
|
||||
builder.validate, [{"action_one": 0},
|
||||
{"action_two": 2}])
|
||||
self.assertRaises(schema_exceptions.ValidationError,
|
||||
builder.validate, [{1: 0},
|
||||
{"action_two": 2}])
|
||||
self.assertRaises(schema_exceptions.ValidationError,
|
||||
builder.validate, [{"action_two": "action_two"}])
|
||||
|
||||
def test_positional_args(self):
|
||||
with mock.patch(self.mock_one) as mock_action_one:
|
||||
with mock.patch(self.mock_two) as mock_action_two:
|
||||
builder = utils.ActionBuilder(["action_one", "action_two"])
|
||||
builder.bind_action("action_one", mock_action_one, "a", "b")
|
||||
builder.bind_action("action_two", mock_action_two, "c")
|
||||
actions = builder.build_actions([{"action_two": 3},
|
||||
{"action_one": 4}])
|
||||
for action in actions:
|
||||
action()
|
||||
self.assertEqual(4, mock_action_one.call_count,
|
||||
"action one not called 4 times")
|
||||
mock_calls = []
|
||||
for i in range(4):
|
||||
mock_calls.append(mock.call("a", "b"))
|
||||
mock_action_one.assert_has_calls(mock_calls)
|
||||
|
||||
self.assertEqual(3, mock_action_two.call_count,
|
||||
"action two not called 3 times")
|
||||
mock_calls = []
|
||||
for i in range(3):
|
||||
mock_calls.append(mock.call("c"))
|
||||
mock_action_two.assert_has_calls(mock_calls)
|
||||
|
||||
with mock.patch(self.mock_one) as mock_action_one:
|
||||
with mock.patch(self.mock_two) as mock_action_two:
|
||||
builder = utils.ActionBuilder(["action_one", "action_two"])
|
||||
builder.bind_action("action_one", mock_action_one, "a", "b")
|
||||
builder.bind_action("action_two", mock_action_two, "c")
|
||||
actions = builder.build_actions([{"action_two": 3},
|
||||
{"action_one": 4}],
|
||||
"d", 5)
|
||||
for action in actions:
|
||||
action()
|
||||
self.assertEqual(4, mock_action_one.call_count,
|
||||
"action one not called 4 times")
|
||||
mock_calls = []
|
||||
for i in range(4):
|
||||
mock_calls.append(mock.call("a", "b", "d", 5))
|
||||
mock_action_one.assert_has_calls(mock_calls)
|
||||
|
||||
self.assertEqual(3, mock_action_two.call_count,
|
||||
"action two not called 3 times")
|
||||
mock_calls = []
|
||||
for i in range(3):
|
||||
mock_calls.append(mock.call("c", "d", 5))
|
||||
mock_action_two.assert_has_calls(mock_calls)
|
||||
|
||||
def test_kwargs(self):
|
||||
with mock.patch(self.mock_one) as mock_action_one:
|
||||
with mock.patch(self.mock_two) as mock_action_two:
|
||||
builder = utils.ActionBuilder(["action_one", "action_two"])
|
||||
builder.bind_action("action_one", mock_action_one, a=1, b=2)
|
||||
builder.bind_action("action_two", mock_action_two, c=3)
|
||||
actions = builder.build_actions([{"action_two": 3},
|
||||
{"action_one": 4}])
|
||||
for action in actions:
|
||||
action()
|
||||
self.assertEqual(4, mock_action_one.call_count,
|
||||
"action one not called 4 times")
|
||||
mock_calls = []
|
||||
for i in range(4):
|
||||
mock_calls.append(mock.call(a=1, b=2))
|
||||
mock_action_one.assert_has_calls(mock_calls)
|
||||
|
||||
self.assertEqual(3, mock_action_two.call_count,
|
||||
"action two not called 3 times")
|
||||
mock_calls = []
|
||||
for i in range(3):
|
||||
mock_calls.append(mock.call(c=3))
|
||||
mock_action_two.assert_has_calls(mock_calls)
|
||||
|
||||
with mock.patch(self.mock_one) as mock_action_one:
|
||||
with mock.patch(self.mock_two) as mock_action_two:
|
||||
builder = utils.ActionBuilder(["action_one", "action_two"])
|
||||
builder.bind_action("action_one", mock_action_one, a=1, b=2)
|
||||
builder.bind_action("action_two", mock_action_two, c=3)
|
||||
actions = builder.build_actions([{"action_two": 3},
|
||||
{"action_one": 4}],
|
||||
d=4, e=5)
|
||||
for action in actions:
|
||||
action()
|
||||
self.assertEqual(4, mock_action_one.call_count,
|
||||
"action one not called 4 times")
|
||||
mock_calls = []
|
||||
for i in range(4):
|
||||
mock_calls.append(mock.call(a=1, b=2, d=4, e=5))
|
||||
mock_action_one.assert_has_calls(mock_calls)
|
||||
|
||||
self.assertEqual(3, mock_action_two.call_count,
|
||||
"action two not called 3 times")
|
||||
mock_calls = []
|
||||
for i in range(3):
|
||||
mock_calls.append(mock.call(c=3, d=4, e=5))
|
||||
mock_action_two.assert_has_calls(mock_calls)
|
||||
|
||||
def test_mixed_args(self):
|
||||
with mock.patch(self.mock_one) as mock_action_one:
|
||||
with mock.patch(self.mock_two) as mock_action_two:
|
||||
builder = utils.ActionBuilder(["action_one", "action_two"])
|
||||
builder.bind_action("action_one", mock_action_one, "one",
|
||||
a=1, b=2)
|
||||
builder.bind_action("action_two", mock_action_two, "two", c=3)
|
||||
actions = builder.build_actions([{"action_two": 3},
|
||||
{"action_one": 4}],
|
||||
"three", d=4)
|
||||
for action in actions:
|
||||
action()
|
||||
self.assertEqual(4, mock_action_one.call_count,
|
||||
"action one not called 4 times")
|
||||
mock_calls = []
|
||||
for i in range(4):
|
||||
mock_calls.append(mock.call("one", "three", a=1, b=2, d=4))
|
||||
mock_action_one.assert_has_calls(mock_calls)
|
||||
|
||||
self.assertEqual(3, mock_action_two.call_count,
|
||||
"action two not called 3 times")
|
||||
mock_calls = []
|
||||
for i in range(3):
|
||||
mock_calls.append(mock.call("two", "three", c=3, d=4))
|
||||
mock_action_two.assert_has_calls(mock_calls)
|
||||
|
Loading…
Reference in New Issue
Block a user