From 7c9705d670f39e2da209a8ca05d4e5eb6b2ab909 Mon Sep 17 00:00:00 2001 From: Alexander Maretskiy Date: Tue, 27 Sep 2016 17:50:29 +0300 Subject: [PATCH] [Hooks][Reports] Show Hooks output in HTML report This adds support of hooks output (both "additive" and "complete") to HTML report. Tab "Hooks" with output charts appears in case if hook has saved some output. Change-Id: I9f14cec23da51ff1603d04338b8f95e6ae2a6801 --- rally-jobs/extra/hook_example_script.sh | 56 +++++++++++++++++++++++++ rally-jobs/rally.yaml | 30 +++++++++---- tests/functional/test_cli_task.py | 37 ++++++++-------- 3 files changed, 99 insertions(+), 24 deletions(-) create mode 100644 rally-jobs/extra/hook_example_script.sh diff --git a/rally-jobs/extra/hook_example_script.sh b/rally-jobs/extra/hook_example_script.sh new file mode 100644 index 00000000..c084c0f8 --- /dev/null +++ b/rally-jobs/extra/hook_example_script.sh @@ -0,0 +1,56 @@ +#!/bin/sh + +rand_int() { + od -An -tu -N1 /dev/urandom | tr -d ' ' +} + +cat << EOF +{ + "additive": [ + { + "title": "Statistics table from Hook", + "chart_plugin": "StatsTable", + "data": [ + ["Alice", $(rand_int)], + ["Bob", $(rand_int)], + ["Carol", $(rand_int)]] + }, + { + "title": "StackedArea chart from Hook", + "description": "This is generated by ${0}", + "chart_plugin": "StackedArea", + "data": [ + ["Alpha", $(rand_int)], + ["Beta", $(rand_int)], + ["Gamma", $(rand_int)]] + } + ], + "complete": [ + { + "title": "Lines chart from Hook", + "description": "Random data generated by ${0}", + "chart_plugin": "Lines", + "axis_label": "X-axis label", + "label": "Y-axis label", + "data": [ + ["Foo", [[1, $(rand_int)], [2, $(rand_int)], [3, $(rand_int)], [4, $(rand_int)], [5, $(rand_int)]]], + ["Bar", [[1, $(rand_int)], [2, $(rand_int)], [3, $(rand_int)], [4, $(rand_int)], [5, $(rand_int)]]], + ["Spam", [[1, $(rand_int)], [2, $(rand_int)], [3, $(rand_int)], [4, $(rand_int)], [5, $(rand_int)]]], + ["Quiz", [[1, $(rand_int)], [2, $(rand_int)], [3, $(rand_int)], [4, $(rand_int)], [5, $(rand_int)]]] + ] + }, + { + "title": "Pie chart from Hook", + "description": "Yet another data generated by ${0}", + "chart_plugin": "Pie", + "data": [ + ["Cat", $(rand_int)], + ["Tiger", $(rand_int)], + ["Jaguar", $(rand_int)], + ["Panther", $(rand_int)], + ["Lynx", $(rand_int)] + ] + } + ] +} +EOF diff --git a/rally-jobs/rally.yaml b/rally-jobs/rally.yaml index 7f4ce95a..d160b790 100644 --- a/rally-jobs/rally.yaml +++ b/rally-jobs/rally.yaml @@ -561,20 +561,36 @@ - args: - sleep: 0.25 + sleep: 0.75 runner: type: "constant" - times: 10 + times: 20 concurrency: 2 hooks: - name: sys_call - description: test hook - args: /bin/true + description: Run script + args: sh /home/jenkins/.rally/extra/hook_example_script.sh trigger: name: event args: unit: iteration - at: [2, 4, 6, 8, 10] + at: [2, 5, 8, 13, 17] + - name: sys_call + description: Show time + args: date +%Y-%m-%dT%H:%M:%S + trigger: + name: event + args: + unit: time + at: [0, 2, 5, 6, 9] + - name: sys_call + description: Show system name + args: uname -a + trigger: + name: event + args: + unit: iteration + at: [2, 3, 4, 5, 6, 8, 10, 12, 13, 15, 17, 18] sla: failure_rate: max: 0 @@ -610,8 +626,8 @@ concurrency: 1 hooks: - name: sys_call - description: test hook - args: /bin/true + description: Get system name + args: uname -a trigger: name: event args: diff --git a/tests/functional/test_cli_task.py b/tests/functional/test_cli_task.py index 898a1777..25c04600 100644 --- a/tests/functional/test_cli_task.py +++ b/tests/functional/test_cli_task.py @@ -1072,23 +1072,31 @@ class HookTestCase(unittest.TestCase): ] } - def _get_result(self, config, iterations=None, seconds=None): - result = { - "config": config, - "results": [], - "summary": {"success": 0} - } + def _get_result(self, config, iterations=None, seconds=None, error=False): + result = {"config": config, "results": [], "summary": {}} events = iterations if iterations else seconds event_type = "iteration" if iterations else "time" - + status = "failed" if error else "success" for i in range(len(events)): - result["results"].append({ + itr_result = { "finished_at": mock.ANY, "started_at": mock.ANY, "triggered_by": {"event_type": event_type, "value": events[i]}, - "status": "success"}) - result["summary"]["success"] += 1 - + "status": status, + "output": { + "additive": [], + "complete": [{"chart_plugin": "TextArea", + "data": ["RetCode: %i" % error, + "StdOut: (empty)", + "StdErr: (empty)"], + "description": "Args: %s" % config["args"], + "title": "System call"}]}} + if error: + itr_result["error"] = {"etype": "n/a", + "msg": "Subprocess returned 1", + "details": "stdout: "} + result["results"].append(itr_result) + result["summary"][status] = len(events) return result def test_hook_result_with_constant_runner(self): @@ -1163,12 +1171,7 @@ class HookTestCase(unittest.TestCase): results = json.loads(rally("task results")) hook_results = results[0]["hooks"] hooks_cfg = cfg["Dummy.dummy"][0]["hooks"] - expected = [self._get_result(hooks_cfg[0], iterations=[5])] - expected[0]["results"][0]["status"] = "failed" - expected[0]["summary"] = {"failed": 1} - expected[0]["results"][0]["error"] = {"etype": "n/a", - "msg": "Subprocess returned 1", - "details": ""} + expected = [self._get_result(hooks_cfg[0], iterations=[5], error=True)] self.assertEqual(expected, hook_results) self._assert_results_time(hook_results)