#!/usr/bin/env python2
# -*- coding: utf-8 -*-
#
# Copyright 2019 The Chromium OS Authors. All rights reserved.
# 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."""

from __future__ import print_function

import mock
import unittest

import os

from cros_utils import command_executer

import heat_map


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('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('__builtin__.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()
