#!/usr/bin/env python2
#
# 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 xrange(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']
    benchmark_names_and_iterations = [('bench1', 1), ('bench2', 2),
                                      ('bench3', 1), ('bench4', 0)]
    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()
