#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# Copyright 2020 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 remove_cold_functions."""

from __future__ import print_function

import io
from unittest.mock import patch
import unittest

from afdo_redaction import remove_cold_functions


def _construct_profile(indices=None):
  real_world_profile_functions = [
      """SomeFunction1:24150:300
 2: 75
 3: 23850
 39: 225
      """,
      """SomeFunction2:8925:225
 0: 225
 0.2: 150
 0.1: SomeFunction2:6300
  3: 6300
 0.2: SomeFunction2:150
  3: 75
      """,
      """SomeFunction3:7500:75
 0: 75
 0.2: 75
 0.1: SomeFunction3:6600
  1: 6600
 0.2: SomeFunction3:75
  1: 75
      """,
      """LargerFunction4:51450:0
 1: 0
 3: 0
 3.1: 7350
 4: 7350
 7: 7350
 8: 7350
 9: 7350
 12: 0
 15: 0
 13: AnotherFunction5:0
  3: 0
  3.1: 0
  3.2: 0
  4: 0
  5: 0
  6: 0
  7: 0
  8: 0
  9: 0
      """,
      """SomeFakeFunction5:7500:75
 0: 75
 0.2: 75
 0.1: SomeFakeFunction5:6600
  1: 6600
 0.2: SomeFakeFunction5:75
  1: 75
      """,
  ]

  ret = []
  if not indices:
    for x in real_world_profile_functions:
      ret += x.strip().splitlines()
    return ret

  ret = []
  for i in indices:
    ret += real_world_profile_functions[i].strip().splitlines()
  return ret


def _run_test(input_lines, goal, cwp_file=None, benchmark_file=None):
  input_buf = io.StringIO('\n'.join(input_lines))
  output_buf = io.StringIO()
  remove_cold_functions.run(input_buf, output_buf, goal, cwp_file,
                            benchmark_file)
  return output_buf.getvalue().splitlines()


class Test(unittest.TestCase):
  """Test functions in remove_cold_functions.py"""

  def test_empty_profile(self):
    self.assertEqual(_run_test([], 0), [])

  def test_remove_all_functions_fail(self):
    input_profile_lines = _construct_profile()
    with self.assertRaises(Exception) as context:
      _run_test(input_profile_lines, 0)
    self.assertEqual(
        str(context.exception),
        "It's invalid to remove all functions in the profile")

  def test_remove_cold_functions_work(self):
    input_profile_lines = _construct_profile()
    # To make sure the cold functions are removed in order
    expected_profile_lines = {
        5: input_profile_lines,
        # Entry 4 wins the tie breaker because the name is smaller
        # alphabetically.
        4: _construct_profile([0, 1, 3, 4]),
        3: _construct_profile([0, 1, 3]),
        2: _construct_profile([0, 3]),
        1: _construct_profile([3]),
    }

    for num in expected_profile_lines:
      self.assertCountEqual(
          _run_test(input_profile_lines, num), expected_profile_lines[num])

  def test_analyze_cwp_and_benchmark_work(self):
    input_profile_lines = _construct_profile()
    cwp_profile = _construct_profile([0, 1, 3, 4])
    benchmark_profile = _construct_profile([1, 2, 3, 4])
    cwp_buf = io.StringIO('\n'.join(cwp_profile))
    benchmark_buf = io.StringIO('\n'.join(benchmark_profile))
    with patch('sys.stderr', new=io.StringIO()) as fake_output:
      _run_test(input_profile_lines, 3, cwp_buf, benchmark_buf)

    output = fake_output.getvalue()
    self.assertIn('Retained 3/5 (60.0%) functions in the profile', output)
    self.assertIn(
        'Retained 1/1 (100.0%) functions only appear in the CWP profile',
        output)
    self.assertIn(
        'Retained 0/1 (0.0%) functions only appear in the benchmark profile',
        output)
    self.assertIn(
        'Retained 2/3 (66.7%) functions appear in both CWP and benchmark'
        ' profiles', output)


if __name__ == '__main__':
  unittest.main()
