From 7aac24de75c57ab6e6b3b247e034265732fdf6f4 Mon Sep 17 00:00:00 2001 From: Anton Studenov Date: Fri, 16 Sep 2016 23:07:04 +0300 Subject: [PATCH] Use hook executer inside task engine Added code that uses HookExecuter to run hooks. Added functional tests. implements spec: hook_section Change-Id: I7b9a8bfd766c3044d6d824f8b4f2cbc4665c12bf --- rally-jobs/rally.yaml | 40 +++++++ tests/functional/test_cli_task.py | 181 ++++++++++++++++++++++++++++++ 2 files changed, 221 insertions(+) diff --git a/rally-jobs/rally.yaml b/rally-jobs/rally.yaml index 4b0c0911..aaace98c 100644 --- a/rally-jobs/rally.yaml +++ b/rally-jobs/rally.yaml @@ -559,6 +559,46 @@ failure_rate: max: 0 + - + args: + sleep: 0.25 + runner: + type: "constant" + times: 10 + concurrency: 2 + hooks: + - name: sys_call + description: test hook + args: /bin/true + trigger: + name: event + args: + unit: iteration + at: [2, 4, 6, 8, 10] + sla: + failure_rate: + max: 0 + + - + args: + sleep: 1 + runner: + type: "constant" + times: 10 + concurrency: 1 + hooks: + - name: sys_call + description: test hook + args: /bin/true + trigger: + name: event + args: + unit: time + at: [0, 2, 4, 6, 8, 10] + sla: + failure_rate: + max: 0 + Dummy.dummy_exception: - args: diff --git a/tests/functional/test_cli_task.py b/tests/functional/test_cli_task.py index 0b7de437..a16e6ba6 100644 --- a/tests/functional/test_cli_task.py +++ b/tests/functional/test_cli_task.py @@ -1027,3 +1027,184 @@ class SLAPerfDegrTestCase(unittest.TestCase): ] data = rally("task sla_check --json", getjson=True) self.assertEqual(expected, data) + + +class HookTestCase(unittest.TestCase): + + def setUp(self): + super(HookTestCase, self).setUp() + self.started = time.time() + + def _assert_results_time(self, results): + for result in results: + started_at = result["started_at"] + finished_at = result["finished_at"] + self.assertIsInstance(started_at, float) + self.assertGreater(started_at, self.started) + self.assertIsInstance(finished_at, float) + self.assertGreater(finished_at, self.started) + self.assertGreater(finished_at, started_at) + + def _get_sample_task_config(self, cmd, description, runner): + return { + "Dummy.dummy": [ + { + "args": { + "sleep": 0.1, + }, + "runner": runner, + "hooks": [ + { + "name": "sys_call", + "description": description, + "args": cmd, + "trigger": { + "name": "event", + "args": { + "unit": "iteration", + "at": [5], + } + } + } + ] + } + ] + } + + def _get_result(self, description, iteration=None, second=None): + triggered_by = {} + if iteration is not None: + triggered_by["iteration"] = iteration + elif second is not None: + triggered_by["time"] = second + result = { + "hook": "sys_call", + "description": description, + "finished_at": mock.ANY, + "started_at": mock.ANY, + "triggered_by": triggered_by, + "status": "success", + } + return result + + def test_hook_result_with_constant_runner(self): + rally = utils.Rally() + cfg = self._get_sample_task_config( + cmd="/bin/true", + description="event_hook", + runner={"type": "constant", "times": 10, "concurrency": 3}) + config = utils.TaskConfig(cfg) + rally("task start --task %s" % config.filename) + results = json.loads(rally("task results")) + hook_results = results[0]["hooks"] + expected = [ + self._get_result("event_hook", iteration=5) + ] + self.assertEqual(expected, hook_results) + self._assert_results_time(hook_results) + + def test_hook_result_with_constant_for_duration_runner(self): + rally = utils.Rally() + cfg = self._get_sample_task_config( + cmd="/bin/true", + description="event_hook", + runner={"type": "constant_for_duration", + "concurrency": 3, "duration": 10}) + config = utils.TaskConfig(cfg) + rally("task start --task %s" % config.filename) + results = json.loads(rally("task results")) + hook_results = results[0]["hooks"] + expected = [ + self._get_result("event_hook", iteration=5) + ] + self.assertEqual(expected, hook_results) + self._assert_results_time(hook_results) + + def test_hook_result_with_rps_runner(self): + rally = utils.Rally() + cfg = self._get_sample_task_config( + cmd="/bin/true", + description="event_hook", + runner={"type": "rps", "rps": 3, "times": 10}) + config = utils.TaskConfig(cfg) + rally("task start --task %s" % config.filename) + results = json.loads(rally("task results")) + hook_results = results[0]["hooks"] + expected = [ + self._get_result("event_hook", iteration=5) + ] + self.assertEqual(expected, hook_results) + self._assert_results_time(hook_results) + + def test_hook_result_with_serial_runner(self): + rally = utils.Rally() + cfg = self._get_sample_task_config( + cmd="/bin/true", + description="event_hook", + runner={"type": "serial", "times": 10}) + config = utils.TaskConfig(cfg) + rally("task start --task %s" % config.filename) + results = json.loads(rally("task results")) + hook_results = results[0]["hooks"] + expected = [ + self._get_result("event_hook", iteration=5) + ] + self.assertEqual(expected, hook_results) + self._assert_results_time(hook_results) + + def test_hook_result_error(self): + rally = utils.Rally() + cfg = self._get_sample_task_config( + cmd="/bin/false", + description="event_hook", + runner={"type": "constant", "times": 20, "concurrency": 3}) + config = utils.TaskConfig(cfg) + rally("task start --task %s" % config.filename) + results = json.loads(rally("task results")) + hook_results = results[0]["hooks"] + expected = [ + { + "description": "event_hook", + "finished_at": mock.ANY, + "started_at": mock.ANY, + "hook": "sys_call", + "triggered_by": {"iteration": 5}, + "status": "failed", + "error": ["n/a", "Subprocess returned 1", ""], + } + ] + self.assertEqual(expected, hook_results) + self._assert_results_time(hook_results) + + def test_time_hook(self): + rally = utils.Rally() + cfg = self._get_sample_task_config( + cmd="/bin/true", + description="event_hook", + runner={"type": "constant_for_duration", + "concurrency": 3, "duration": 10}) + cfg["Dummy.dummy"][0]["hooks"].append({ + "name": "sys_call", + "description": "time_hook", + "args": "/bin/true", + "trigger": { + "name": "event", + "args": { + "unit": "time", + "at": [3, 6, 9], + } + } + }) + + config = utils.TaskConfig(cfg) + rally("task start --task %s" % config.filename) + results = json.loads(rally("task results")) + hook_results = results[0]["hooks"] + expected = [ + self._get_result("event_hook", iteration=5), + self._get_result("time_hook", second=3), + self._get_result("time_hook", second=6), + self._get_result("time_hook", second=9), + ] + self.assertEqual(expected, hook_results) + self._assert_results_time(hook_results)