#!/usr/bin/env python2
# -*- coding: utf-8 -*-
# Copyright 2018 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 redact_profile.py."""

from __future__ import division, print_function

import StringIO
import unittest

import redact_profile

_redact_limit = redact_profile.dedup_records.func_defaults[0]


def _redact(input_lines, summary_to=None):
  if isinstance(input_lines, str):
    input_lines = input_lines.splitlines()

  if summary_to is None:
    summary_to = StringIO.StringIO()

  output_to = StringIO.StringIO()
  redact_profile.run(profile_input_file=input_lines,
                     summary_output_file=summary_to,
                     profile_output_file=output_to)
  return output_to.getvalue()


def _redact_with_summary(input_lines):
  summary = StringIO.StringIO()
  result = _redact(input_lines, summary_to=summary)
  return result, summary.getvalue()


def _generate_repeated_function_body(repeats, fn_name='_some_name'):
  # Arbitrary function body ripped from a textual AFDO profile.
  function_header = fn_name + ':1234:185'
  function_body = [
      ' 6: 83',
      ' 15: 126',
      ' 62832: 126',
      ' 6: _ZNK5blink10PaintLayer14GroupedMappingEv:2349',
      '  1: 206',
      '  1: _ZNK5blink10PaintLayer14GroupedMappersEv:2060',
      '   1: 206',
      ' 11: _ZNK5blink10PaintLayer25GetCompositedLayerMappingEv:800',
      '  2.1: 80',
  ]

  # Be sure to zfill this, so the functions are output in sorted order.
  num_width = len(str(repeats))

  lines = []
  for i in range(repeats):
    num = str(i).zfill(num_width)
    lines.append(num + function_header)
    lines.extend(function_body)
  return lines


class Tests(unittest.TestCase):
  """All of our tests for redact_profile."""
  def test_no_input_works(self):
    self.assertEqual(_redact(''), '')

  def test_single_function_works(self):
    lines = _generate_repeated_function_body(1)
    result_file = '\n'.join(lines) + '\n'
    self.assertEqual(_redact(lines), result_file)

  def test_duplicate_of_single_function_works(self):
    lines = _generate_repeated_function_body(2)
    result_file = '\n'.join(lines) + '\n'
    self.assertEqual(_redact(lines), result_file)

  def test_not_too_many_duplicates_of_single_function_redacts_none(self):
    lines = _generate_repeated_function_body(_redact_limit - 1)
    result_file = '\n'.join(lines) + '\n'
    self.assertEqual(_redact(lines), result_file)

  def test_many_duplicates_of_single_function_redacts_them_all(self):
    lines = _generate_repeated_function_body(_redact_limit)
    self.assertEqual(_redact(lines), '')

  def test_many_duplicates_of_single_function_leaves_other_functions(self):
    kept_lines = _generate_repeated_function_body(1, fn_name='_keep_me')
    # Something to distinguish us from the rest. Just bump a random counter.
    kept_lines[1] += '1'

    result_file = '\n'.join(kept_lines) + '\n'

    lines = _generate_repeated_function_body(_redact_limit,
                                             fn_name='_discard_me')
    self.assertEqual(_redact(kept_lines + lines), result_file)
    self.assertEqual(_redact(lines + kept_lines), result_file)

    more_lines = _generate_repeated_function_body(_redact_limit,
                                                  fn_name='_and_discard_me')
    self.assertEqual(_redact(lines + kept_lines + more_lines), result_file)
    self.assertEqual(_redact(lines + more_lines), '')

  def test_correct_summary_is_printed_when_nothing_is_redacted(self):
    lines = _generate_repeated_function_body(1)
    _, summary = _redact_with_summary(lines)
    self.assertIn('Retained 1/1 functions', summary)
    self.assertIn('Retained 827/827 samples, total', summary)
    # Note that top-level samples == "samples without inlining taken into
    # account," not "sum(entry_counts)"
    self.assertIn('Retained 335/335 top-level samples', summary)

  def test_correct_summary_is_printed_when_everything_is_redacted(self):
    lines = _generate_repeated_function_body(_redact_limit)
    _, summary = _redact_with_summary(lines)
    self.assertIn('Retained 0/100 functions', summary)
    self.assertIn('Retained 0/82,700 samples, total', summary)
    self.assertIn('Retained 0/33,500 top-level samples', summary)

  def test_correct_summary_is_printed_when_most_everything_is_redacted(self):
    kept_lines = _generate_repeated_function_body(1, fn_name='_keep_me')
    kept_lines[1] += '1'

    lines = _generate_repeated_function_body(_redact_limit)
    _, summary = _redact_with_summary(kept_lines + lines)
    self.assertIn('Retained 1/101 functions', summary)
    self.assertIn('Retained 1,575/84,275 samples, total', summary)
    self.assertIn('Retained 1,083/34,583 top-level samples', summary)


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