diff options
Diffstat (limited to 'crosperf/generate_report_unittest.py')
-rwxr-xr-x | crosperf/generate_report_unittest.py | 294 |
1 files changed, 145 insertions, 149 deletions
diff --git a/crosperf/generate_report_unittest.py b/crosperf/generate_report_unittest.py index 8c3510a9..86bbc164 100755 --- a/crosperf/generate_report_unittest.py +++ b/crosperf/generate_report_unittest.py @@ -1,13 +1,11 @@ #!/usr/bin/env python3 # -*- coding: utf-8 -*- -# Copyright 2016 The Chromium OS Authors. All rights reserved. +# Copyright 2016 The ChromiumOS Authors # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. """Test for generate_report.py.""" -from __future__ import division -from __future__ import print_function import copy import json @@ -18,161 +16,159 @@ import generate_report import results_report import test_flag + # pylint: disable=deprecated-module try: - from StringIO import StringIO # for Python 2 + from StringIO import StringIO # for Python 2 except ImportError: - from io import StringIO # for Python 3 + from io import StringIO # for Python 3 class _ContextualStringIO(StringIO): - """StringIO that can be used in `with` statements.""" + """StringIO that can be used in `with` statements.""" - def __init__(self, *args): - StringIO.__init__(self, *args) + def __init__(self, *args): + StringIO.__init__(self, *args) - def __enter__(self): - return self + def __enter__(self): + return self - def __exit__(self, _type, _value, _traceback): - pass + def __exit__(self, _type, _value, _traceback): + pass class GenerateReportTests(unittest.TestCase): - """Tests for generate_report.py.""" - - def testCountBenchmarks(self): - runs = { - 'foo': [[{}, {}, {}], [{}, {}, {}, {}]], - 'bar': [], - 'baz': [[], [{}], [{}, {}, {}]] - } - results = generate_report.CountBenchmarks(runs) - expected_results = [('foo', 4), ('bar', 0), ('baz', 3)] - self.assertCountEqual(expected_results, results) - - def testCutResultsInPlace(self): - bench_data = { - 'foo': [[{ - 'a': 1, - 'b': 2, - 'c': 3 - }, { - 'a': 3, - 'b': 2.5, - 'c': 1 - }]], - 'bar': [[{ - 'd': 11, - 'e': 12, - 'f': 13 - }]], - 'baz': [[{ - 'g': 12, - 'h': 13 - }]], - 'qux': [[{ - 'i': 11 - }]], - } - original_bench_data = copy.deepcopy(bench_data) - - max_keys = 2 - results = generate_report.CutResultsInPlace( - bench_data, max_keys=max_keys, complain_on_update=False) - # Cuts should be in-place. - self.assertIs(results, bench_data) - self.assertCountEqual( - list(original_bench_data.keys()), list(bench_data.keys())) - for bench_name, original_runs in original_bench_data.items(): - bench_runs = bench_data[bench_name] - self.assertEqual(len(original_runs), len(bench_runs)) - # Order of these sub-lists shouldn't have changed. - for original_list, new_list in zip(original_runs, bench_runs): - self.assertEqual(len(original_list), len(new_list)) - for original_keyvals, sub_keyvals in zip(original_list, new_list): - # sub_keyvals must be a subset of original_keyvals - self.assertDictContainsSubset(sub_keyvals, original_keyvals) - - def testCutResultsInPlaceLeavesRetval(self): - bench_data = { - 'foo': [[{ - 'retval': 0, - 'a': 1 - }]], - 'bar': [[{ - 'retval': 1 - }]], - 'baz': [[{ - 'RETVAL': 1 - }]], - } - results = generate_report.CutResultsInPlace( - bench_data, max_keys=0, complain_on_update=False) - # Just reach into results assuming we know it otherwise outputs things in - # the expected way. If it doesn't, testCutResultsInPlace should give an - # indication as to what, exactly, is broken. - self.assertEqual(list(results['foo'][0][0].items()), [('retval', 0)]) - self.assertEqual(list(results['bar'][0][0].items()), [('retval', 1)]) - self.assertEqual(list(results['baz'][0][0].items()), []) - - def _RunMainWithInput(self, args, input_obj): - assert '-i' not in args - args += ['-i', '-'] - input_buf = _ContextualStringIO(json.dumps(input_obj)) - with mock.patch('generate_report.PickInputFile', return_value=input_buf) \ - as patched_pick: - result = generate_report.Main(args) - patched_pick.assert_called_once_with('-') - return result - - @mock.patch('generate_report.RunActions') - def testMain(self, mock_run_actions): - # Email is left out because it's a bit more difficult to test, and it'll be - # mildly obvious if it's failing. - args = ['--json', '--html', '--text'] - return_code = self._RunMainWithInput(args, {'platforms': [], 'data': {}}) - self.assertEqual(0, return_code) - self.assertEqual(mock_run_actions.call_count, 1) - ctors = [ctor for ctor, _ in mock_run_actions.call_args[0][0]] - self.assertEqual(ctors, [ - results_report.JSONResultsReport, - results_report.TextResultsReport, - results_report.HTMLResultsReport, - ]) - - @mock.patch('generate_report.RunActions') - def testMainSelectsHTMLIfNoReportsGiven(self, mock_run_actions): - args = [] - return_code = self._RunMainWithInput(args, {'platforms': [], 'data': {}}) - self.assertEqual(0, return_code) - self.assertEqual(mock_run_actions.call_count, 1) - ctors = [ctor for ctor, _ in mock_run_actions.call_args[0][0]] - self.assertEqual(ctors, [results_report.HTMLResultsReport]) - - # We only mock print_exc so we don't have exception info printed to stdout. - @mock.patch('generate_report.WriteFile', side_effect=ValueError('Oh noo')) - @mock.patch('traceback.print_exc') - def testRunActionsRunsAllActionsRegardlessOfExceptions( - self, mock_print_exc, mock_write_file): - actions = [(None, 'json'), (None, 'html'), (None, 'text'), (None, 'email')] - output_prefix = '-' - ok = generate_report.RunActions( - actions, {}, output_prefix, overwrite=False, verbose=False) - self.assertFalse(ok) - self.assertEqual(mock_write_file.call_count, len(actions)) - self.assertEqual(mock_print_exc.call_count, len(actions)) - - @mock.patch('generate_report.WriteFile') - def testRunActionsReturnsTrueIfAllActionsSucceed(self, mock_write_file): - actions = [(None, 'json'), (None, 'html'), (None, 'text')] - output_prefix = '-' - ok = generate_report.RunActions( - actions, {}, output_prefix, overwrite=False, verbose=False) - self.assertEqual(mock_write_file.call_count, len(actions)) - self.assertTrue(ok) - - -if __name__ == '__main__': - test_flag.SetTestMode(True) - unittest.main() + """Tests for generate_report.py.""" + + def testCountBenchmarks(self): + runs = { + "foo": [[{}, {}, {}], [{}, {}, {}, {}]], + "bar": [], + "baz": [[], [{}], [{}, {}, {}]], + } + results = generate_report.CountBenchmarks(runs) + expected_results = [("foo", 4), ("bar", 0), ("baz", 3)] + self.assertCountEqual(expected_results, results) + + def testCutResultsInPlace(self): + bench_data = { + "foo": [[{"a": 1, "b": 2, "c": 3}, {"a": 3, "b": 2.5, "c": 1}]], + "bar": [[{"d": 11, "e": 12, "f": 13}]], + "baz": [[{"g": 12, "h": 13}]], + "qux": [[{"i": 11}]], + } + original_bench_data = copy.deepcopy(bench_data) + + max_keys = 2 + results = generate_report.CutResultsInPlace( + bench_data, max_keys=max_keys, complain_on_update=False + ) + # Cuts should be in-place. + self.assertIs(results, bench_data) + self.assertCountEqual( + list(original_bench_data.keys()), list(bench_data.keys()) + ) + for bench_name, original_runs in original_bench_data.items(): + bench_runs = bench_data[bench_name] + self.assertEqual(len(original_runs), len(bench_runs)) + # Order of these sub-lists shouldn't have changed. + for original_list, new_list in zip(original_runs, bench_runs): + self.assertEqual(len(original_list), len(new_list)) + for original_keyvals, sub_keyvals in zip( + original_list, new_list + ): + # sub_keyvals must be a subset of original_keyvals + self.assertDictContainsSubset(sub_keyvals, original_keyvals) + + def testCutResultsInPlaceLeavesRetval(self): + bench_data = { + "foo": [[{"retval": 0, "a": 1}]], + "bar": [[{"retval": 1}]], + "baz": [[{"RETVAL": 1}]], + } + results = generate_report.CutResultsInPlace( + bench_data, max_keys=0, complain_on_update=False + ) + # Just reach into results assuming we know it otherwise outputs things in + # the expected way. If it doesn't, testCutResultsInPlace should give an + # indication as to what, exactly, is broken. + self.assertEqual(list(results["foo"][0][0].items()), [("retval", 0)]) + self.assertEqual(list(results["bar"][0][0].items()), [("retval", 1)]) + self.assertEqual(list(results["baz"][0][0].items()), []) + + def _RunMainWithInput(self, args, input_obj): + assert "-i" not in args + args += ["-i", "-"] + input_buf = _ContextualStringIO(json.dumps(input_obj)) + with mock.patch( + "generate_report.PickInputFile", return_value=input_buf + ) as patched_pick: + result = generate_report.Main(args) + patched_pick.assert_called_once_with("-") + return result + + @mock.patch("generate_report.RunActions") + def testMain(self, mock_run_actions): + # Email is left out because it's a bit more difficult to test, and it'll be + # mildly obvious if it's failing. + args = ["--json", "--html", "--text"] + return_code = self._RunMainWithInput( + args, {"platforms": [], "data": {}} + ) + self.assertEqual(0, return_code) + self.assertEqual(mock_run_actions.call_count, 1) + ctors = [ctor for ctor, _ in mock_run_actions.call_args[0][0]] + self.assertEqual( + ctors, + [ + results_report.JSONResultsReport, + results_report.TextResultsReport, + results_report.HTMLResultsReport, + ], + ) + + @mock.patch("generate_report.RunActions") + def testMainSelectsHTMLIfNoReportsGiven(self, mock_run_actions): + args = [] + return_code = self._RunMainWithInput( + args, {"platforms": [], "data": {}} + ) + self.assertEqual(0, return_code) + self.assertEqual(mock_run_actions.call_count, 1) + ctors = [ctor for ctor, _ in mock_run_actions.call_args[0][0]] + self.assertEqual(ctors, [results_report.HTMLResultsReport]) + + # We only mock print_exc so we don't have exception info printed to stdout. + @mock.patch("generate_report.WriteFile", side_effect=ValueError("Oh noo")) + @mock.patch("traceback.print_exc") + def testRunActionsRunsAllActionsRegardlessOfExceptions( + self, mock_print_exc, mock_write_file + ): + actions = [ + (None, "json"), + (None, "html"), + (None, "text"), + (None, "email"), + ] + output_prefix = "-" + ok = generate_report.RunActions( + actions, {}, output_prefix, overwrite=False, verbose=False + ) + self.assertFalse(ok) + self.assertEqual(mock_write_file.call_count, len(actions)) + self.assertEqual(mock_print_exc.call_count, len(actions)) + + @mock.patch("generate_report.WriteFile") + def testRunActionsReturnsTrueIfAllActionsSucceed(self, mock_write_file): + actions = [(None, "json"), (None, "html"), (None, "text")] + output_prefix = "-" + ok = generate_report.RunActions( + actions, {}, output_prefix, overwrite=False, verbose=False + ) + self.assertEqual(mock_write_file.call_count, len(actions)) + self.assertTrue(ok) + + +if __name__ == "__main__": + test_flag.SetTestMode(True) + unittest.main() |