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

"""Unittest for the results reporter."""

from __future__ import division
from __future__ import print_function

from StringIO import StringIO

import collections
import mock
import os
import test_flag
import unittest

from benchmark_run import MockBenchmarkRun
from cros_utils import logger
from experiment_factory import ExperimentFactory
from experiment_file import ExperimentFile
from machine_manager import MockCrosMachine
from machine_manager import MockMachineManager
from results_cache import MockResult
from results_report import BenchmarkResults
from results_report import HTMLResultsReport
from results_report import JSONResultsReport
from results_report import ParseChromeosImage
from results_report import ParseStandardPerfReport
from results_report import TextResultsReport


class FreeFunctionsTest(unittest.TestCase):
  """Tests for any free functions in results_report."""

  def testParseChromeosImage(self):
    # N.B. the cases with blank versions aren't explicitly supported by
    # ParseChromeosImage. I'm not sure if they need to be supported, but the
    # goal of this was to capture existing functionality as much as possible.
    base_case = '/my/chroot/src/build/images/x86-generic/R01-1.0.date-time' \
        '/chromiumos_test_image.bin'
    self.assertEqual(ParseChromeosImage(base_case), ('R01-1.0', base_case))

    dir_base_case = os.path.dirname(base_case)
    self.assertEqual(ParseChromeosImage(dir_base_case), ('', dir_base_case))

    buildbot_case = '/my/chroot/chroot/tmp/buildbot-build/R02-1.0.date-time' \
        '/chromiumos_test_image.bin'
    buildbot_img = buildbot_case.split('/chroot/tmp')[1]

    self.assertEqual(
        ParseChromeosImage(buildbot_case), ('R02-1.0', buildbot_img))
    self.assertEqual(
        ParseChromeosImage(os.path.dirname(buildbot_case)),
        ('', os.path.dirname(buildbot_img)))

    # Ensure we don't act completely insanely given a few mildly insane paths.
    fun_case = '/chromiumos_test_image.bin'
    self.assertEqual(ParseChromeosImage(fun_case), ('', fun_case))

    fun_case2 = 'chromiumos_test_image.bin'
    self.assertEqual(ParseChromeosImage(fun_case2), ('', fun_case2))


# There are many ways for this to be done better, but the linter complains
# about all of them (that I can think of, at least).
_fake_path_number = [0]


def FakePath(ext):
  """Makes a unique path that shouldn't exist on the host system.

  Each call returns a different path, so if said path finds its way into an
  error message, it may be easier to track it to its source.
  """
  _fake_path_number[0] += 1
  prefix = '/tmp/should/not/exist/%d/' % (_fake_path_number[0],)
  return os.path.join(prefix, ext)


def MakeMockExperiment(compiler='gcc'):
  """Mocks an experiment using the given compiler."""
  mock_experiment_file = StringIO("""
      board: x86-alex
      remote: 127.0.0.1
      perf_args: record -a -e cycles
      benchmark: PageCycler {
        iterations: 3
      }

      image1 {
        chromeos_image: %s
      }

      image2 {
        remote: 127.0.0.2
        chromeos_image: %s
      }
      """ % (FakePath('cros_image1.bin'), FakePath('cros_image2.bin')))
  efile = ExperimentFile(mock_experiment_file)
  experiment = ExperimentFactory().GetExperiment(efile,
                                                 FakePath('working_directory'),
                                                 FakePath('log_dir'))
  for label in experiment.labels:
    label.compiler = compiler
  return experiment


def _InjectSuccesses(experiment, how_many, keyvals, for_benchmark=0,
                     label=None):
  """Injects successful experiment runs (for each label) into the experiment."""
  # Defensive copy of keyvals, so if it's modified, we'll know.
  keyvals = dict(keyvals)
  num_configs = len(experiment.benchmarks) * len(experiment.labels)
  num_runs = len(experiment.benchmark_runs) // num_configs

  # TODO(gbiv): Centralize the mocking of these, maybe? (It's also done in
  # benchmark_run_unittest)
  bench = experiment.benchmarks[for_benchmark]
  cache_conditions = []
  log_level = 'average'
  share_cache = ''
  locks_dir = ''
  log = logger.GetLogger()
  machine_manager = MockMachineManager(
      FakePath('chromeos_root'), 0, log_level, locks_dir)
  machine_manager.AddMachine('testing_machine')
  machine = next(
      m for m in machine_manager.GetMachines() if m.name == 'testing_machine')
  for label in experiment.labels:

    def MakeSuccessfulRun(n):
      run = MockBenchmarkRun('mock_success%d' % (n,), bench, label,
                             1 + n + num_runs, cache_conditions,
                             machine_manager, log, log_level, share_cache, {})
      mock_result = MockResult(log, label, log_level, machine)
      mock_result.keyvals = keyvals
      run.result = mock_result
      return run

    experiment.benchmark_runs.extend(
        MakeSuccessfulRun(n) for n in range(how_many))
  return experiment


class TextResultsReportTest(unittest.TestCase):
  """Tests that the output of a text report contains the things we pass in.

  At the moment, this doesn't care deeply about the format in which said
  things are displayed. It just cares that they're present.
  """

  def _checkReport(self, email):
    num_success = 2
    success_keyvals = {'retval': 0, 'machine': 'some bot', 'a_float': 3.96}
    experiment = _InjectSuccesses(MakeMockExperiment(), num_success,
                                  success_keyvals)
    text_report = TextResultsReport.FromExperiment(experiment, email=email) \
                                   .GetReport()
    self.assertIn(str(success_keyvals['a_float']), text_report)
    self.assertIn(success_keyvals['machine'], text_report)
    self.assertIn(MockCrosMachine.CPUINFO_STRING, text_report)
    return text_report

  def testOutput(self):
    email_report = self._checkReport(email=True)
    text_report = self._checkReport(email=False)

    # Ensure that the reports somehow different. Otherwise, having the
    # distinction is useless.
    self.assertNotEqual(email_report, text_report)


class HTMLResultsReportTest(unittest.TestCase):
  """Tests that the output of a HTML report contains the things we pass in.

  At the moment, this doesn't care deeply about the format in which said
  things are displayed. It just cares that they're present.
  """

  _TestOutput = collections.namedtuple('TestOutput', [
      'summary_table', 'perf_html', 'chart_js', 'charts', 'full_table',
      'experiment_file'
  ])

  @staticmethod
  def _GetTestOutput(perf_table, chart_js, summary_table, print_table,
                     chart_divs, full_table, experiment_file):
    # N.B. Currently we don't check chart_js; it's just passed through because
    # cros lint complains otherwise.
    summary_table = print_table(summary_table, 'HTML')
    perf_html = print_table(perf_table, 'HTML')
    full_table = print_table(full_table, 'HTML')
    return HTMLResultsReportTest._TestOutput(
        summary_table=summary_table,
        perf_html=perf_html,
        chart_js=chart_js,
        charts=chart_divs,
        full_table=full_table,
        experiment_file=experiment_file)

  def _GetOutput(self, experiment=None, benchmark_results=None):
    with mock.patch('results_report_templates.GenerateHTMLPage') as standin:
      if experiment is not None:
        HTMLResultsReport.FromExperiment(experiment).GetReport()
      else:
        HTMLResultsReport(benchmark_results).GetReport()
      mod_mock = standin
    self.assertEquals(mod_mock.call_count, 1)
    # call_args[0] is positional args, call_args[1] is kwargs.
    self.assertEquals(mod_mock.call_args[0], tuple())
    fmt_args = mod_mock.call_args[1]
    return self._GetTestOutput(**fmt_args)

  def testNoSuccessOutput(self):
    output = self._GetOutput(MakeMockExperiment())
    self.assertIn('no result', output.summary_table)
    self.assertIn('no result', output.full_table)
    self.assertEqual(output.charts, '')
    self.assertNotEqual(output.experiment_file, '')

  def testSuccessfulOutput(self):
    num_success = 2
    success_keyvals = {'retval': 0, 'a_float': 3.96}
    output = self._GetOutput(
        _InjectSuccesses(MakeMockExperiment(), num_success, success_keyvals))

    self.assertNotIn('no result', output.summary_table)
    #self.assertIn(success_keyvals['machine'], output.summary_table)
    self.assertIn('a_float', output.summary_table)
    self.assertIn(str(success_keyvals['a_float']), output.summary_table)
    self.assertIn('a_float', output.full_table)
    # The _ in a_float is filtered out when we're generating HTML.
    self.assertIn('afloat', output.charts)
    # And make sure we have our experiment file...
    self.assertNotEqual(output.experiment_file, '')

  def testBenchmarkResultFailure(self):
    labels = ['label1']
    benchmark_names_and_iterations = [('bench1', 1)]
    benchmark_keyvals = {'bench1': [[]]}
    results = BenchmarkResults(labels, benchmark_names_and_iterations,
                               benchmark_keyvals)
    output = self._GetOutput(benchmark_results=results)
    self.assertIn('no result', output.summary_table)
    self.assertEqual(output.charts, '')
    self.assertEqual(output.experiment_file, '')

  def testBenchmarkResultSuccess(self):
    labels = ['label1']
    benchmark_names_and_iterations = [('bench1', 1)]
    benchmark_keyvals = {'bench1': [[{'retval': 1, 'foo': 2.0}]]}
    results = BenchmarkResults(labels, benchmark_names_and_iterations,
                               benchmark_keyvals)
    output = self._GetOutput(benchmark_results=results)
    self.assertNotIn('no result', output.summary_table)
    self.assertIn('bench1', output.summary_table)
    self.assertIn('bench1', output.full_table)
    self.assertNotEqual(output.charts, '')
    self.assertEqual(output.experiment_file, '')


class JSONResultsReportTest(unittest.TestCase):
  """Tests JSONResultsReport."""

  REQUIRED_REPORT_KEYS = ('date', 'time', 'label', 'test_name', 'pass')
  EXPERIMENT_REPORT_KEYS = ('board', 'chromeos_image', 'chromeos_version',
                            'chrome_version', 'compiler')

  @staticmethod
  def _GetRequiredKeys(is_experiment):
    required_keys = JSONResultsReportTest.REQUIRED_REPORT_KEYS
    if is_experiment:
      required_keys += JSONResultsReportTest.EXPERIMENT_REPORT_KEYS
    return required_keys

  def _CheckRequiredKeys(self, test_output, is_experiment):
    required_keys = self._GetRequiredKeys(is_experiment)
    for output in test_output:
      for key in required_keys:
        self.assertIn(key, output)

  def testAllFailedJSONReportOutput(self):
    experiment = MakeMockExperiment()
    results = JSONResultsReport.FromExperiment(experiment).GetReportObject()
    self._CheckRequiredKeys(results, is_experiment=True)
    # Nothing succeeded; we don't send anything more than what's required.
    required_keys = self._GetRequiredKeys(is_experiment=True)
    for result in results:
      self.assertItemsEqual(result.iterkeys(), required_keys)

  def testJSONReportOutputWithSuccesses(self):
    success_keyvals = {
        'retval': 0,
        'a_float': '2.3',
        'many_floats': [['1.0', '2.0'], ['3.0']],
        'machine': "i'm a pirate"
    }

    # 2 is arbitrary.
    num_success = 2
    experiment = _InjectSuccesses(MakeMockExperiment(), num_success,
                                  success_keyvals)
    results = JSONResultsReport.FromExperiment(experiment).GetReportObject()
    self._CheckRequiredKeys(results, is_experiment=True)

    num_passes = num_success * len(experiment.labels)
    non_failures = [r for r in results if r['pass']]
    self.assertEqual(num_passes, len(non_failures))

    # TODO(gbiv): ...Is the 3.0 *actually* meant to be dropped?
    expected_detailed = {'a_float': 2.3, 'many_floats': [1.0, 2.0]}
    for pass_ in non_failures:
      self.assertIn('detailed_results', pass_)
      self.assertDictEqual(expected_detailed, pass_['detailed_results'])
      self.assertIn('machine', pass_)
      self.assertEqual(success_keyvals['machine'], pass_['machine'])

  def testFailedJSONReportOutputWithoutExperiment(self):
    labels = ['label1']
    # yapf:disable
    benchmark_names_and_iterations = [('bench1', 1), ('bench2', 2),
                                      ('bench3', 1), ('bench4', 0)]
    # yapf:enable

    benchmark_keyvals = {
        'bench1': [[{
            'retval': 1,
            'foo': 2.0
        }]],
        'bench2': [[{
            'retval': 1,
            'foo': 4.0
        }, {
            'retval': -1,
            'bar': 999
        }]],
        # lack of retval is considered a failure.
        'bench3': [[{}]],
        'bench4': [[]]
    }
    bench_results = BenchmarkResults(labels, benchmark_names_and_iterations,
                                     benchmark_keyvals)
    results = JSONResultsReport(bench_results).GetReportObject()
    self._CheckRequiredKeys(results, is_experiment=False)
    self.assertFalse(any(r['pass'] for r in results))

  def testJSONGetReportObeysJSONSettings(self):
    labels = ['label1']
    benchmark_names_and_iterations = [('bench1', 1)]
    # These can be anything, really. So long as they're distinctive.
    separators = (',\t\n\t', ':\t\n\t')
    benchmark_keyvals = {'bench1': [[{'retval': 0, 'foo': 2.0}]]}
    bench_results = BenchmarkResults(labels, benchmark_names_and_iterations,
                                     benchmark_keyvals)
    reporter = JSONResultsReport(
        bench_results, json_args={'separators': separators})
    result_str = reporter.GetReport()
    self.assertIn(separators[0], result_str)
    self.assertIn(separators[1], result_str)

  def testSuccessfulJSONReportOutputWithoutExperiment(self):
    labels = ['label1']
    benchmark_names_and_iterations = [('bench1', 1), ('bench2', 2)]
    benchmark_keyvals = {
        'bench1': [[{
            'retval': 0,
            'foo': 2.0
        }]],
        'bench2': [[{
            'retval': 0,
            'foo': 4.0
        }, {
            'retval': 0,
            'bar': 999
        }]]
    }
    bench_results = BenchmarkResults(labels, benchmark_names_and_iterations,
                                     benchmark_keyvals)
    results = JSONResultsReport(bench_results).GetReportObject()
    self._CheckRequiredKeys(results, is_experiment=False)
    self.assertTrue(all(r['pass'] for r in results))
    # Enforce that the results have *some* deterministic order.
    keyfn = lambda r: (r['test_name'], r['detailed_results'].get('foo', 5.0))
    sorted_results = sorted(results, key=keyfn)
    detailed_results = [r['detailed_results'] for r in sorted_results]
    bench1, bench2_foo, bench2_bar = detailed_results
    self.assertEqual(bench1['foo'], 2.0)
    self.assertEqual(bench2_foo['foo'], 4.0)
    self.assertEqual(bench2_bar['bar'], 999)
    self.assertNotIn('bar', bench1)
    self.assertNotIn('bar', bench2_foo)
    self.assertNotIn('foo', bench2_bar)


class PerfReportParserTest(unittest.TestCase):
  """Tests for the perf report parser in results_report."""

  @staticmethod
  def _ReadRealPerfReport():
    my_dir = os.path.dirname(os.path.realpath(__file__))
    with open(os.path.join(my_dir, 'perf_files/perf.data.report.0')) as f:
      return f.read()

  def testParserParsesRealWorldPerfReport(self):
    report = ParseStandardPerfReport(self._ReadRealPerfReport())
    self.assertItemsEqual(['cycles', 'instructions'], report.keys())

    # Arbitrarily selected known percentages from the perf report.
    known_cycles_percentages = {
        '0xffffffffa4a1f1c9': 0.66,
        '0x0000115bb7ba9b54': 0.47,
        '0x0000000000082e08': 0.00,
        '0xffffffffa4a13e63': 0.00,
    }
    report_cycles = report['cycles']
    self.assertEqual(len(report_cycles), 214)
    for k, v in known_cycles_percentages.iteritems():
      self.assertIn(k, report_cycles)
      self.assertEqual(v, report_cycles[k])

    known_instrunctions_percentages = {
        '0x0000115bb6c35d7a': 1.65,
        '0x0000115bb7ba9b54': 0.67,
        '0x0000000000024f56': 0.00,
        '0xffffffffa4a0ee03': 0.00,
    }
    report_instructions = report['instructions']
    self.assertEqual(len(report_instructions), 492)
    for k, v in known_instrunctions_percentages.iteritems():
      self.assertIn(k, report_instructions)
      self.assertEqual(v, report_instructions[k])


if __name__ == '__main__':
  test_flag.SetTestMode(True)
  unittest.main()
