#!/usr/bin/python
# Copyright 2018 The Chromium 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 code coverage tools."""

import os
import re
import shutil
import subprocess
import sys
import unittest

# Appends third_party/ so that coverage_utils can import jinja2 from
# third_party/, note that this is not done inside coverage_utils because
# coverage_utils is also used outside of Chromium source tree.
sys.path.append(
    os.path.join(
        os.path.dirname(__file__), os.path.pardir, os.path.pardir,
        'third_party'))
import coverage_utils


def _RecursiveDirectoryListing(dirpath):
  """Returns a list of relative paths to all files in a given directory."""
  result = []
  for root, _, files in os.walk(dirpath):
    for f in files:
      result.append(os.path.relpath(os.path.join(root, f), dirpath))
  return result


def _ReadFile(filepath):
  """Returns contents of a given file."""
  with open(filepath) as f:
    return f.read()


class CoverageTest(unittest.TestCase):

  def setUp(self):
    self.maxDiff = 1000
    self.COVERAGE_TOOLS_DIR = os.path.abspath(os.path.dirname(__file__))
    self.COVERAGE_SCRIPT = os.path.join(self.COVERAGE_TOOLS_DIR, 'coverage.py')
    self.COVERAGE_UTILS = os.path.join(self.COVERAGE_TOOLS_DIR,
                                       'coverage_utils.py')

    self.CHROMIUM_SRC_DIR = os.path.dirname(
        os.path.dirname(self.COVERAGE_TOOLS_DIR))
    self.BUILD_DIR = os.path.join(self.CHROMIUM_SRC_DIR, 'out',
                                  'code_coverage_tools_test')

    self.REPORT_DIR_1 = os.path.join(self.BUILD_DIR, 'report1')
    self.REPORT_DIR_1_NO_COMPONENTS = os.path.join(self.BUILD_DIR,
                                                   'report1_no_components')
    self.REPORT_DIR_2 = os.path.join(self.BUILD_DIR, 'report2')
    self.REPORT_DIR_3 = os.path.join(self.BUILD_DIR, 'report3')

    self.LLVM_COV = os.path.join(self.CHROMIUM_SRC_DIR, 'third_party',
                                 'llvm-build', 'Release+Asserts', 'bin',
                                 'llvm-cov')

    self.PYTHON = 'python'
    self.PLATFORM = coverage_utils.GetHostPlatform()
    if self.PLATFORM == 'win32':
      self.LLVM_COV += '.exe'
      self.PYTHON += '.exe'

    # Even though 'is_component_build=false' is recommended, we intentionally
    # use 'is_component_build=true' to test handling of shared libraries.
    self.GN_ARGS = """use_clang_coverage=true
                      dcheck_always_on=true
                      ffmpeg_branding=\"ChromeOS\"
                      is_component_build=true
                      is_debug=false
                      proprietary_codecs=true
                      use_libfuzzer=true"""

    shutil.rmtree(self.BUILD_DIR, ignore_errors=True)

    gn_gen_cmd = ['gn', 'gen', self.BUILD_DIR, '--args=%s' % self.GN_ARGS]
    self.run_cmd(gn_gen_cmd)

    build_cmd = [
        'autoninja', '-C', self.BUILD_DIR, 'crypto_unittests',
        'libpng_read_fuzzer'
    ]
    self.run_cmd(build_cmd)

  def tearDown(self):
    shutil.rmtree(self.BUILD_DIR, ignore_errors=True)

  def run_cmd(self, cmd):
    return subprocess.check_output(cmd, cwd=self.CHROMIUM_SRC_DIR)

  def verify_component_view(self, filepath):
    """Asserts that a given component view looks correct."""
    # There must be several Blink and Internals components.
    with open(filepath) as f:
      data = f.read()

    counts = data.count('Blink') + data.count('Internals')
    self.assertGreater(counts, 5)

  def verify_directory_view(self, filepath):
    """Asserts that a given directory view looks correct."""
    # Directory view page does a redirect to another page, extract its URL.
    with open(filepath) as f:
      data = f.read()

    url = re.search(r'.*refresh.*url=([a-zA-Z0-9_\-\/.]+).*', data).group(1)
    directory_view_path = os.path.join(os.path.dirname(filepath), url)

    # There must be at least 'crypto' and 'third_party' directories.
    with open(directory_view_path) as f:
      data = f.read()

    self.assertTrue('crypto' in data and 'third_party' in data)

  def verify_file_view(self, filepath):
    """Asserts that a given file view looks correct."""
    # There must be hundreds of '.*crypto.*' files and 10+ of '.*libpng.*'.
    with open(filepath) as f:
      data = f.read()

    self.assertGreater(data.count('crypto'), 100)
    self.assertGreater(data.count('libpng'), 10)

  def test_different_workflows_and_cross_check_the_results(self):
    """Test a few different workflows and assert that the results are the same

    and look legit.
    """
    # Testcase 1. End-to-end report generation using coverage.py script. This is
    # the workflow of a regular user.
    cmd = [
        self.COVERAGE_SCRIPT,
        'crypto_unittests',
        'libpng_read_fuzzer',
        '-v',
        '-b',
        self.BUILD_DIR,
        '-o',
        self.REPORT_DIR_1,
        '-c'
        '%s/crypto_unittests' % self.BUILD_DIR,
        '-c',
        '%s/libpng_read_fuzzer -runs=0 third_party/libpng/' % self.BUILD_DIR,
    ]
    self.run_cmd(cmd)

    output_dir = os.path.join(self.REPORT_DIR_1, self.PLATFORM)
    self.verify_component_view(
        os.path.join(output_dir, 'component_view_index.html'))
    self.verify_directory_view(
        os.path.join(output_dir, 'directory_view_index.html'))
    self.verify_file_view(os.path.join(output_dir, 'file_view_index.html'))

    # Also try generating a report without components view. Useful for cross
    # checking with the report produced in the testcase #3.
    cmd = [
        self.COVERAGE_SCRIPT,
        'crypto_unittests',
        'libpng_read_fuzzer',
        '-v',
        '-b',
        self.BUILD_DIR,
        '-o',
        self.REPORT_DIR_1_NO_COMPONENTS,
        '-c'
        '%s/crypto_unittests' % self.BUILD_DIR,
        '-c',
        '%s/libpng_read_fuzzer -runs=0 third_party/libpng/' % self.BUILD_DIR,
        '--no-component-view',
    ]
    self.run_cmd(cmd)

    output_dir = os.path.join(self.REPORT_DIR_1_NO_COMPONENTS, self.PLATFORM)
    self.verify_directory_view(
        os.path.join(output_dir, 'directory_view_index.html'))
    self.verify_file_view(os.path.join(output_dir, 'file_view_index.html'))
    self.assertFalse(
        os.path.exists(os.path.join(output_dir, 'component_view_index.html')))

    # Testcase #2. Run the script for post processing in Chromium tree. This is
    # the workflow of the code coverage bots.
    instr_profile_path = os.path.join(self.REPORT_DIR_1, self.PLATFORM,
                                      'coverage.profdata')

    cmd = [
        self.COVERAGE_SCRIPT,
        'crypto_unittests',
        'libpng_read_fuzzer',
        '-v',
        '-b',
        self.BUILD_DIR,
        '-p',
        instr_profile_path,
        '-o',
        self.REPORT_DIR_2,
    ]
    self.run_cmd(cmd)

    # Verify that the output dirs are the same except of the expected diff.
    report_1_listing = set(_RecursiveDirectoryListing(self.REPORT_DIR_1))
    report_2_listing = set(_RecursiveDirectoryListing(self.REPORT_DIR_2))
    logs_subdir = os.path.join(self.PLATFORM, 'logs')
    self.assertEqual(
        set([
            os.path.join(self.PLATFORM, 'coverage.profdata'),
            os.path.join(logs_subdir, 'crypto_unittests_output.log'),
            os.path.join(logs_subdir, 'libpng_read_fuzzer_output.log'),
        ]), report_1_listing - report_2_listing)

    output_dir = os.path.join(self.REPORT_DIR_2, self.PLATFORM)
    self.verify_component_view(
        os.path.join(output_dir, 'component_view_index.html'))
    self.verify_directory_view(
        os.path.join(output_dir, 'directory_view_index.html'))
    self.verify_file_view(os.path.join(output_dir, 'file_view_index.html'))

    # Verify that the file view pages are binary equal.
    report_1_file_view_data = _ReadFile(
        os.path.join(self.REPORT_DIR_1, self.PLATFORM, 'file_view_index.html'))
    report_2_file_view_data = _ReadFile(
        os.path.join(self.REPORT_DIR_2, self.PLATFORM, 'file_view_index.html'))
    self.assertEqual(report_1_file_view_data, report_2_file_view_data)

    # Testcase #3, run coverage_utils.py on manually produced report and summary
    # file. This is the workflow of OSS-Fuzz code coverage job.
    objects = [
        '-object=%s' % os.path.join(self.BUILD_DIR, 'crypto_unittests'),
        '-object=%s' % os.path.join(self.BUILD_DIR, 'libpng_read_fuzzer'),
    ]

    cmd = [
        self.PYTHON,
        self.COVERAGE_UTILS,
        '-v',
        'shared_libs',
        '-build-dir=%s' % self.BUILD_DIR,
    ] + objects

    shared_libraries = self.run_cmd(cmd)
    objects.extend(shared_libraries.split())

    instr_profile_path = os.path.join(self.REPORT_DIR_1_NO_COMPONENTS,
                                      self.PLATFORM, 'coverage.profdata')
    cmd = [
        self.LLVM_COV,
        'show',
        '-format=html',
        '-output-dir=%s' % self.REPORT_DIR_3,
        '-instr-profile=%s' % instr_profile_path,
    ] + objects
    if self.PLATFORM in ['linux', 'mac']:
      cmd.extend(['-Xdemangler', 'c++filt', '-Xdemangler', '-n'])
    self.run_cmd(cmd)

    cmd = [
        self.LLVM_COV,
        'export',
        '-summary-only',
        '-instr-profile=%s' % instr_profile_path,
    ] + objects
    summary_output = self.run_cmd(cmd)

    summary_path = os.path.join(self.REPORT_DIR_3, 'summary.json')
    with open(summary_path, 'w') as f:
      f.write(summary_output)

    cmd = [
        self.PYTHON,
        self.COVERAGE_UTILS,
        '-v',
        'post_process',
        '-src-root-dir=%s' % self.CHROMIUM_SRC_DIR,
        '-summary-file=%s' % summary_path,
        '-output-dir=%s' % self.REPORT_DIR_3,
    ]
    self.run_cmd(cmd)

    output_dir = os.path.join(self.REPORT_DIR_3, self.PLATFORM)
    self.verify_directory_view(
        os.path.join(output_dir, 'directory_view_index.html'))
    self.verify_file_view(os.path.join(output_dir, 'file_view_index.html'))
    self.assertFalse(
        os.path.exists(os.path.join(output_dir, 'component_view_index.html')))

    # Verify that the file view pages are binary equal.
    report_1_file_view_data_no_component = _ReadFile(
        os.path.join(self.REPORT_DIR_1_NO_COMPONENTS, self.PLATFORM,
                     'file_view_index.html'))
    report_3_file_view_data = _ReadFile(
        os.path.join(self.REPORT_DIR_3, self.PLATFORM, 'file_view_index.html'))
    self.assertEqual(report_1_file_view_data_no_component,
                     report_3_file_view_data)


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