# -*- coding: utf-8 -*-
# Copyright (c) 2013 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.

"""Test cros_generate_breakpad_symbols."""

from __future__ import print_function

import ctypes
import os

import mock
from six.moves import StringIO

from chromite.lib import cros_test_lib
from chromite.lib import osutils
from chromite.lib import parallel
from chromite.lib import parallel_unittest
from chromite.lib import partial_mock
from chromite.scripts import cros_generate_breakpad_symbols


class FindDebugDirMock(partial_mock.PartialMock):
  """Mock out the DebugDir helper so we can point it to a tempdir."""

  TARGET = 'chromite.scripts.cros_generate_breakpad_symbols'
  ATTRS = ('FindDebugDir',)
  DEFAULT_ATTR = 'FindDebugDir'

  def __init__(self, path, *args, **kwargs):
    self.path = path
    super(FindDebugDirMock, self).__init__(*args, **kwargs)

  # pylint: disable=unused-argument
  def FindDebugDir(self, _board, sysroot=None):
    return self.path


# This long decorator triggers a false positive in the docstring test.
# https://github.com/PyCQA/pylint/issues/3077
# pylint: disable=bad-docstring-quotes
@mock.patch('chromite.scripts.cros_generate_breakpad_symbols.'
            'GenerateBreakpadSymbol')
class GenerateSymbolsTest(cros_test_lib.MockTempDirTestCase):
  """Test GenerateBreakpadSymbols."""

  def setUp(self):
    self.board = 'monkey-board'
    self.board_dir = os.path.join(self.tempdir, 'build', self.board)
    self.debug_dir = os.path.join(self.board_dir, 'usr', 'lib', 'debug')
    self.breakpad_dir = os.path.join(self.debug_dir, 'breakpad')

    # Generate a tree of files which we'll scan through.
    elf_files = [
        'bin/elf',
        'iii/large-elf',
        # Need some kernel modules (with & without matching .debug).
        'lib/modules/3.10/module.ko',
        'lib/modules/3.10/module-no-debug.ko',
        # Need a file which has an ELF only, but not a .debug.
        'usr/bin/elf-only',
        'usr/sbin/elf',
    ]
    debug_files = [
        'bin/bad-file',
        'bin/elf.debug',
        'iii/large-elf.debug',
        'lib/modules/3.10/module.ko.debug',
        # Need a file which has a .debug only, but not an ELF.
        'sbin/debug-only.debug',
        'usr/sbin/elf.debug',
    ]
    for f in ([os.path.join(self.board_dir, x) for x in elf_files] +
              [os.path.join(self.debug_dir, x) for x in debug_files]):
      osutils.Touch(f, makedirs=True)

    # Set up random build dirs and symlinks.
    buildid = os.path.join(self.debug_dir, '.build-id', '00')
    osutils.SafeMakedirs(buildid)
    os.symlink('/asdf', os.path.join(buildid, 'foo'))
    os.symlink('/bin/sh', os.path.join(buildid, 'foo.debug'))
    os.symlink('/bin/sh', os.path.join(self.debug_dir, 'file.debug'))
    osutils.WriteFile(os.path.join(self.debug_dir, 'iii', 'large-elf.debug'),
                      'just some content')

    self.StartPatcher(FindDebugDirMock(self.debug_dir))

  def testNormal(self, gen_mock):
    """Verify all the files we expect to get generated do"""
    with parallel_unittest.ParallelMock():
      ret = cros_generate_breakpad_symbols.GenerateBreakpadSymbols(
          self.board, sysroot=self.board_dir)
      self.assertEqual(ret, 0)
      self.assertEqual(gen_mock.call_count, 3)

      # The largest ELF should be processed first.
      call1 = (os.path.join(self.board_dir, 'iii/large-elf'),
               os.path.join(self.debug_dir, 'iii/large-elf.debug'))
      self.assertEqual(gen_mock.call_args_list[0][0], call1)

      # The other ELFs can be called in any order.
      call2 = (os.path.join(self.board_dir, 'bin/elf'),
               os.path.join(self.debug_dir, 'bin/elf.debug'))
      call3 = (os.path.join(self.board_dir, 'usr/sbin/elf'),
               os.path.join(self.debug_dir, 'usr/sbin/elf.debug'))
      exp_calls = set((call2, call3))
      actual_calls = set((gen_mock.call_args_list[1][0],
                          gen_mock.call_args_list[2][0]))
      self.assertEqual(exp_calls, actual_calls)

  def testFileList(self, gen_mock):
    """Verify that file_list restricts the symbols generated"""
    with parallel_unittest.ParallelMock():
      call1 = (os.path.join(self.board_dir, 'usr/sbin/elf'),
               os.path.join(self.debug_dir, 'usr/sbin/elf.debug'))

      # Filter with elf path.
      ret = cros_generate_breakpad_symbols.GenerateBreakpadSymbols(
          self.board, sysroot=self.board_dir, breakpad_dir=self.breakpad_dir,
          file_list=[os.path.join(self.board_dir, 'usr', 'sbin', 'elf')])
      self.assertEqual(ret, 0)
      self.assertEqual(gen_mock.call_count, 1)
      self.assertEqual(gen_mock.call_args_list[0][0], call1)

      # Filter with debug symbols file path.
      gen_mock.reset_mock()
      ret = cros_generate_breakpad_symbols.GenerateBreakpadSymbols(
          self.board, sysroot=self.board_dir, breakpad_dir=self.breakpad_dir,
          file_list=[os.path.join(self.debug_dir, 'usr', 'sbin', 'elf.debug')])
      self.assertEqual(ret, 0)
      self.assertEqual(gen_mock.call_count, 1)
      self.assertEqual(gen_mock.call_args_list[0][0], call1)


  def testGenLimit(self, gen_mock):
    """Verify generate_count arg works"""
    with parallel_unittest.ParallelMock():
      # Generate nothing!
      ret = cros_generate_breakpad_symbols.GenerateBreakpadSymbols(
          self.board, sysroot=self.board_dir, breakpad_dir=self.breakpad_dir,
          generate_count=0)
      self.assertEqual(ret, 0)
      self.assertEqual(gen_mock.call_count, 0)

      # Generate just one.
      ret = cros_generate_breakpad_symbols.GenerateBreakpadSymbols(
          self.board, sysroot=self.board_dir, breakpad_dir=self.breakpad_dir,
          generate_count=1)
      self.assertEqual(ret, 0)
      self.assertEqual(gen_mock.call_count, 1)

      # The largest ELF should be processed first.
      call1 = (os.path.join(self.board_dir, 'iii/large-elf'),
               os.path.join(self.debug_dir, 'iii/large-elf.debug'))
      self.assertEqual(gen_mock.call_args_list[0][0], call1)

  def testGenErrors(self, gen_mock):
    """Verify we handle errors from generation correctly"""
    def _SetError(*_args, **kwargs):
      kwargs['num_errors'].value += 1
      return 1
    gen_mock.side_effect = _SetError
    with parallel_unittest.ParallelMock():
      ret = cros_generate_breakpad_symbols.GenerateBreakpadSymbols(
          self.board, sysroot=self.board_dir)
      self.assertEqual(ret, 3)
      self.assertEqual(gen_mock.call_count, 3)

  def testCleaningTrue(self, gen_mock):
    """Verify behavior of clean_breakpad=True"""
    with parallel_unittest.ParallelMock():
      # Dir does not exist, and then does.
      self.assertNotExists(self.breakpad_dir)
      ret = cros_generate_breakpad_symbols.GenerateBreakpadSymbols(
          self.board, sysroot=self.board_dir, generate_count=1,
          clean_breakpad=True)
      self.assertEqual(ret, 0)
      self.assertEqual(gen_mock.call_count, 1)
      self.assertExists(self.breakpad_dir)

      # Dir exists before & after.
      # File exists, but then doesn't.
      dummy_file = os.path.join(self.breakpad_dir, 'fooooooooo')
      osutils.Touch(dummy_file)
      ret = cros_generate_breakpad_symbols.GenerateBreakpadSymbols(
          self.board, sysroot=self.board_dir, generate_count=1,
          clean_breakpad=True)
      self.assertEqual(ret, 0)
      self.assertEqual(gen_mock.call_count, 2)
      self.assertNotExists(dummy_file)

  def testCleaningFalse(self, gen_mock):
    """Verify behavior of clean_breakpad=False"""
    with parallel_unittest.ParallelMock():
      # Dir does not exist, and then does.
      self.assertNotExists(self.breakpad_dir)
      ret = cros_generate_breakpad_symbols.GenerateBreakpadSymbols(
          self.board, sysroot=self.board_dir, generate_count=1,
          clean_breakpad=False)
      self.assertEqual(ret, 0)
      self.assertEqual(gen_mock.call_count, 1)
      self.assertExists(self.breakpad_dir)

      # Dir exists before & after.
      # File exists before & after.
      dummy_file = os.path.join(self.breakpad_dir, 'fooooooooo')
      osutils.Touch(dummy_file)
      ret = cros_generate_breakpad_symbols.GenerateBreakpadSymbols(
          self.board, sysroot=self.board_dir, generate_count=1,
          clean_breakpad=False)
      self.assertEqual(ret, 0)
      self.assertEqual(gen_mock.call_count, 2)
      self.assertExists(dummy_file)

  def testExclusionList(self, gen_mock):
    """Verify files in directories of the exclusion list are excluded"""
    exclude_dirs = ['bin', 'usr', 'fake/dir/fake']
    with parallel_unittest.ParallelMock():
      ret = cros_generate_breakpad_symbols.GenerateBreakpadSymbols(
          self.board, sysroot=self.board_dir, exclude_dirs=exclude_dirs)
      self.assertEqual(ret, 0)
      self.assertEqual(gen_mock.call_count, 1)

class GenerateSymbolTest(cros_test_lib.RunCommandTempDirTestCase):
  """Test GenerateBreakpadSymbol."""

  def setUp(self):
    self.elf_file = os.path.join(self.tempdir, 'elf')
    osutils.Touch(self.elf_file)
    self.debug_dir = os.path.join(self.tempdir, 'debug')
    self.debug_file = os.path.join(self.debug_dir, 'elf.debug')
    osutils.Touch(self.debug_file, makedirs=True)
    # Not needed as the code itself should create it as needed.
    self.breakpad_dir = os.path.join(self.debug_dir, 'breakpad')

    self.rc.SetDefaultCmdResult(output='MODULE OS CPU ID NAME')
    self.assertCommandContains = self.rc.assertCommandContains
    self.sym_file = os.path.join(self.breakpad_dir, 'NAME/ID/NAME.sym')

    self.StartPatcher(FindDebugDirMock(self.debug_dir))

  def assertCommandArgs(self, i, args):
    """Helper for looking at the args of the |i|th call"""
    self.assertEqual(self.rc.call_args_list[i][0][0], args)

  def testNormal(self):
    """Normal run -- given an ELF and a debug file"""
    ret = cros_generate_breakpad_symbols.GenerateBreakpadSymbol(
        self.elf_file, self.debug_file, self.breakpad_dir)
    self.assertEqual(ret, self.sym_file)
    self.assertEqual(self.rc.call_count, 1)
    self.assertCommandArgs(0, ['dump_syms', '-v', self.elf_file,
                               self.debug_dir])
    self.assertExists(self.sym_file)

  def testNormalNoCfi(self):
    """Normal run w/out CFI"""
    # Make sure the num_errors flag works too.
    num_errors = ctypes.c_int()
    ret = cros_generate_breakpad_symbols.GenerateBreakpadSymbol(
        self.elf_file, breakpad_dir=self.breakpad_dir,
        strip_cfi=True, num_errors=num_errors)
    self.assertEqual(ret, self.sym_file)
    self.assertEqual(num_errors.value, 0)
    self.assertCommandArgs(0, ['dump_syms', '-v', '-c', self.elf_file])
    self.assertEqual(self.rc.call_count, 1)
    self.assertExists(self.sym_file)

  def testNormalElfOnly(self):
    """Normal run -- given just an ELF"""
    ret = cros_generate_breakpad_symbols.GenerateBreakpadSymbol(
        self.elf_file, breakpad_dir=self.breakpad_dir)
    self.assertEqual(ret, self.sym_file)
    self.assertCommandArgs(0, ['dump_syms', '-v', self.elf_file])
    self.assertEqual(self.rc.call_count, 1)
    self.assertExists(self.sym_file)

  def testNormalSudo(self):
    """Normal run where ELF is readable only by root"""
    with mock.patch.object(os, 'access') as mock_access:
      mock_access.return_value = False
      ret = cros_generate_breakpad_symbols.GenerateBreakpadSymbol(
          self.elf_file, breakpad_dir=self.breakpad_dir)
    self.assertEqual(ret, self.sym_file)
    self.assertCommandArgs(0, ['sudo', '--', 'dump_syms', '-v', self.elf_file])

  def testLargeDebugFail(self):
    """Running w/large .debug failed, but retry worked"""
    self.rc.AddCmdResult(['dump_syms', '-v', self.elf_file, self.debug_dir],
                         returncode=1)
    ret = cros_generate_breakpad_symbols.GenerateBreakpadSymbol(
        self.elf_file, self.debug_file, self.breakpad_dir)
    self.assertEqual(ret, self.sym_file)
    self.assertEqual(self.rc.call_count, 2)
    self.assertCommandArgs(0, ['dump_syms', '-v', self.elf_file,
                               self.debug_dir])
    self.assertCommandArgs(
        1, ['dump_syms', '-v', '-c', '-r', self.elf_file, self.debug_dir])
    self.assertExists(self.sym_file)

  def testDebugFail(self):
    """Running w/.debug always failed, but works w/out"""
    self.rc.AddCmdResult(['dump_syms', '-v', self.elf_file, self.debug_dir],
                         returncode=1)
    self.rc.AddCmdResult(['dump_syms', '-v', '-c', '-r', self.elf_file,
                          self.debug_dir],
                         returncode=1)
    ret = cros_generate_breakpad_symbols.GenerateBreakpadSymbol(
        self.elf_file, self.debug_file, self.breakpad_dir)
    self.assertEqual(ret, self.sym_file)
    self.assertEqual(self.rc.call_count, 3)
    self.assertCommandArgs(0, ['dump_syms', '-v', self.elf_file,
                               self.debug_dir])
    self.assertCommandArgs(
        1, ['dump_syms', '-v', '-c', '-r', self.elf_file, self.debug_dir])
    self.assertCommandArgs(2, ['dump_syms', '-v', self.elf_file])
    self.assertExists(self.sym_file)

  def testCompleteFail(self):
    """Running dump_syms always fails"""
    self.rc.SetDefaultCmdResult(returncode=1)
    ret = cros_generate_breakpad_symbols.GenerateBreakpadSymbol(
        self.elf_file, breakpad_dir=self.breakpad_dir)
    self.assertEqual(ret, 1)
    # Make sure the num_errors flag works too.
    num_errors = ctypes.c_int()
    ret = cros_generate_breakpad_symbols.GenerateBreakpadSymbol(
        self.elf_file, breakpad_dir=self.breakpad_dir, num_errors=num_errors)
    self.assertEqual(ret, 1)
    self.assertEqual(num_errors.value, 1)


class UtilsTestDir(cros_test_lib.TempDirTestCase):
  """Tests ReadSymsHeader."""

  def testReadSymsHeaderGoodFile(self):
    """Make sure ReadSymsHeader can parse sym files"""
    sym_file = os.path.join(self.tempdir, 'sym')
    osutils.WriteFile(sym_file, 'MODULE Linux x86 s0m31D chrooome')
    result = cros_generate_breakpad_symbols.ReadSymsHeader(sym_file)
    self.assertEqual(result.cpu, 'x86')
    self.assertEqual(result.id, 's0m31D')
    self.assertEqual(result.name, 'chrooome')
    self.assertEqual(result.os, 'Linux')


class UtilsTest(cros_test_lib.TestCase):
  """Tests ReadSymsHeader."""

  def testReadSymsHeaderGoodBuffer(self):
    """Make sure ReadSymsHeader can parse sym file handles"""
    result = cros_generate_breakpad_symbols.ReadSymsHeader(
        StringIO('MODULE Linux arm MY-ID-HERE blkid'))
    self.assertEqual(result.cpu, 'arm')
    self.assertEqual(result.id, 'MY-ID-HERE')
    self.assertEqual(result.name, 'blkid')
    self.assertEqual(result.os, 'Linux')

  def testReadSymsHeaderBadd(self):
    """Make sure ReadSymsHeader throws on bad sym files"""
    self.assertRaises(ValueError, cros_generate_breakpad_symbols.ReadSymsHeader,
                      StringIO('asdf'))

  def testBreakpadDir(self):
    """Make sure board->breakpad path expansion works"""
    expected = '/build/blah/usr/lib/debug/breakpad'
    result = cros_generate_breakpad_symbols.FindBreakpadDir('blah')
    self.assertEqual(expected, result)

  def testDebugDir(self):
    """Make sure board->debug path expansion works"""
    expected = '/build/blah/usr/lib/debug'
    result = cros_generate_breakpad_symbols.FindDebugDir('blah')
    self.assertEqual(expected, result)


def main(_argv):
  # pylint: disable=protected-access
  # Set timeouts small so that if the unit test hangs, it won't hang for long.
  parallel._BackgroundTask.STARTUP_TIMEOUT = 5
  parallel._BackgroundTask.EXIT_TIMEOUT = 5

  # Run the tests.
  cros_test_lib.main(level='info', module=__name__)
