| #!/usr/bin/env python3 |
| # -*- coding: utf-8 -*- |
| # |
| # Copyright 2019 The ChromiumOS Authors |
| # Use of this source code is governed by a BSD-style license that can be |
| # found in the LICENSE file. |
| |
| """Tests for heat_map.py.""" |
| |
| |
| import os |
| import unittest |
| import unittest.mock as mock |
| |
| from cros_utils import command_executer |
| from heatmaps import heat_map |
| from heatmaps import heatmap_generator |
| |
| |
| def make_heatmap( |
| chromeos_root="/path/to/fake/chromeos_root/", |
| perf_data="/any_path/perf.data", |
| ): |
| return heat_map.HeatMapProducer(chromeos_root, perf_data, None, None, "") |
| |
| |
| def fake_mkdtemp(prefix): |
| """Mock tempfile.mkdtemp() by just create a pathname.""" |
| return prefix + "random_dir" |
| |
| |
| def fake_parser_error(_, msg): |
| """Redirect parser.error() to exception.""" |
| raise Exception(msg) |
| |
| |
| def fake_generate_perf_report_exception(_): |
| raise Exception |
| |
| |
| class HeatmapTest(unittest.TestCase): |
| """All of our tests for heat_map.""" |
| |
| # pylint: disable=protected-access |
| @mock.patch("shutil.copy2") |
| @mock.patch("tempfile.mkdtemp") |
| def test_EnsureFileInChrootAlreadyInside(self, mock_mkdtemp, mock_copy): |
| perf_data_inchroot = ( |
| "/path/to/fake/chromeos_root/chroot/inchroot_path/perf.data" |
| ) |
| heatmap = make_heatmap(perf_data=perf_data_inchroot) |
| heatmap._EnsureFileInChroot() |
| self.assertFalse(heatmap.temp_dir_created) |
| self.assertEqual( |
| heatmap.temp_dir, |
| "/path/to/fake/chromeos_root/chroot/inchroot_path/", |
| ) |
| self.assertEqual(heatmap.temp_perf_inchroot, "/inchroot_path/") |
| mock_mkdtemp.assert_not_called() |
| mock_copy.assert_not_called() |
| |
| @mock.patch("shutil.copy2") |
| @mock.patch("tempfile.mkdtemp", fake_mkdtemp) |
| def test_EnsureFileInChrootOutsideNeedCopy(self, mock_copy): |
| heatmap = make_heatmap() |
| heatmap._EnsureFileInChroot() |
| self.assertTrue(heatmap.temp_dir_created) |
| self.assertEqual(mock_copy.call_count, 1) |
| self.assertEqual( |
| heatmap.temp_dir, "/path/to/fake/chromeos_root/src/random_dir" |
| ) |
| self.assertEqual(heatmap.temp_perf_inchroot, "~/trunk/src/random_dir") |
| |
| @mock.patch.object(command_executer.CommandExecuter, "ChrootRunCommand") |
| def test_GeneratePerfReport(self, mock_ChrootRunCommand): |
| heatmap = make_heatmap() |
| heatmap.temp_dir = "/fake/chroot/inchroot_path/" |
| heatmap.temp_perf_inchroot = "/inchroot_path/" |
| mock_ChrootRunCommand.return_value = 0 |
| heatmap._GeneratePerfReport() |
| cmd = ( |
| "cd %s && perf report -D -i perf.data > perf_report.txt" |
| % heatmap.temp_perf_inchroot |
| ) |
| mock_ChrootRunCommand.assert_called_with(heatmap.chromeos_root, cmd) |
| self.assertEqual(mock_ChrootRunCommand.call_count, 1) |
| self.assertEqual( |
| heatmap.perf_report, "/fake/chroot/inchroot_path/perf_report.txt" |
| ) |
| |
| @mock.patch.object(heatmap_generator, "HeatmapGenerator") |
| def test_GetHeatMap(self, mock_heatmap_generator): |
| heatmap = make_heatmap() |
| heatmap._GetHeatMap(10) |
| self.assertTrue(mock_heatmap_generator.called) |
| |
| @mock.patch.object(heat_map.HeatMapProducer, "_EnsureFileInChroot") |
| @mock.patch.object(heat_map.HeatMapProducer, "_GeneratePerfReport") |
| @mock.patch.object(heat_map.HeatMapProducer, "_GetHeatMap") |
| @mock.patch.object(heat_map.HeatMapProducer, "_RemoveFiles") |
| def test_Run( |
| self, |
| mock_remove_files, |
| mock_get_heatmap, |
| mock_generate_perf_report, |
| mock_ensure_file_in_chroot, |
| ): |
| heatmap = make_heatmap() |
| heatmap.Run(10) |
| mock_ensure_file_in_chroot.assert_called_once_with() |
| mock_generate_perf_report.assert_called_once_with() |
| mock_get_heatmap.assert_called_once_with(10) |
| mock_remove_files.assert_called_once_with() |
| |
| @mock.patch.object(heat_map.HeatMapProducer, "_EnsureFileInChroot") |
| @mock.patch.object( |
| heat_map.HeatMapProducer, |
| "_GeneratePerfReport", |
| new=fake_generate_perf_report_exception, |
| ) |
| @mock.patch.object(heat_map.HeatMapProducer, "_GetHeatMap") |
| @mock.patch.object(heat_map.HeatMapProducer, "_RemoveFiles") |
| @mock.patch("builtins.print") |
| def test_Run_with_exception( |
| self, |
| mock_print, |
| mock_remove_files, |
| mock_get_heatmap, |
| mock_ensure_file_in_chroot, |
| ): |
| heatmap = make_heatmap() |
| with self.assertRaises(Exception): |
| heatmap.Run(10) |
| mock_ensure_file_in_chroot.assert_called_once_with() |
| mock_get_heatmap.assert_not_called() |
| mock_remove_files.assert_called_once_with() |
| mock_print.assert_not_called() |
| |
| @mock.patch("argparse.ArgumentParser.error", fake_parser_error) |
| @mock.patch.object(os.path, "isfile") |
| @mock.patch.object(heat_map, "IsARepoRoot") |
| def test_main_arg_format(self, mock_IsARepoRoot, mock_isfile): |
| """Test wrong arg format are detected.""" |
| args = [ |
| "--chromeos_root=/fake/chroot/", |
| "--perf_data=/path/to/perf.data", |
| ] |
| |
| # Test --chromeos_root format |
| mock_IsARepoRoot.return_value = False |
| with self.assertRaises(Exception) as msg: |
| heat_map.main(args) |
| self.assertIn("does not contain .repo dir.", str(msg.exception)) |
| |
| # Test --perf_data format |
| mock_IsARepoRoot.return_value = True |
| mock_isfile.return_value = False |
| with self.assertRaises(Exception) as msg: |
| heat_map.main(args) |
| self.assertIn("Cannot find perf_data", str(msg.exception)) |
| |
| # Test --hugepage format |
| mock_isfile.return_value = True |
| args.append("--hugepage=0") |
| with self.assertRaises(Exception) as msg: |
| heat_map.main(args) |
| self.assertIn("Wrong format of hugepage range", str(msg.exception)) |
| |
| # Test --hugepage parse |
| args[-1] = "--hugepage=0,4096" |
| heat_map.HeatMapProducer = mock.MagicMock() |
| heat_map.main(args) |
| heat_map.HeatMapProducer.assert_called_with( |
| "/fake/chroot/", "/path/to/perf.data", [0, 4096], None, "" |
| ) |
| |
| |
| if __name__ == "__main__": |
| unittest.main() |