# -*- coding: utf-8 -*-
# Copyright 2019 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.

"""Artifacts service tests."""

from __future__ import print_function

from operator import attrgetter

import json
import os
import shutil

import mock

from chromite.lib import autotest_util
from chromite.lib import build_target_lib
from chromite.lib import chroot_lib
from chromite.lib import constants
from chromite.lib import cros_build_lib
from chromite.lib import cros_test_lib
from chromite.lib import osutils
from chromite.lib import partial_mock
from chromite.lib import portage_util
from chromite.lib import sysroot_lib
from chromite.lib import toolchain_util
from chromite.lib.paygen import partition_lib
from chromite.lib.paygen import paygen_payload_lib
from chromite.lib.paygen import paygen_stateful_payload_lib
from chromite.service import artifacts


class BundleAutotestFilesTest(cros_test_lib.MockTempDirTestCase):
  """Test the Bundle Autotest Files function."""

  def setUp(self):
    self.output_dir = os.path.join(self.tempdir, 'output_dir')
    self.archive_dir = os.path.join(self.tempdir, 'archive_base_dir')

    sysroot_path = os.path.join(self.tempdir, 'sysroot')
    self.chroot = chroot_lib.Chroot(self.tempdir)
    self.sysroot = sysroot_lib.Sysroot('sysroot')
    self.sysroot_dne = sysroot_lib.Sysroot('sysroot_DNE')

    # Make sure we have the valid paths.
    osutils.SafeMakedirs(self.output_dir)
    osutils.SafeMakedirs(sysroot_path)

  def testInvalidOutputDirectory(self):
    """Test invalid output directory."""
    with self.assertRaises(AssertionError):
      artifacts.BundleAutotestFiles(self.chroot, self.sysroot, None)

  def testInvalidSysroot(self):
    """Test sysroot that does not exist."""
    with self.assertRaises(AssertionError):
      artifacts.BundleAutotestFiles(self.chroot, self.sysroot_dne,
                                    self.output_dir)

  def testArchiveDirectoryDoesNotExist(self):
    """Test archive directory that does not exist causes error."""
    self.assertEqual(
        artifacts.BundleAutotestFiles(self.chroot, self.sysroot,
                                      self.output_dir), {})

  def testSuccess(self):
    """Test a successful call handling."""
    ab_path = os.path.join(self.tempdir, self.sysroot.path,
                           constants.AUTOTEST_BUILD_PATH)
    osutils.SafeMakedirs(ab_path)

    # Makes all of the individual calls to build out each of the tarballs work
    # nicely with a single patch.
    self.PatchObject(autotest_util.AutotestTarballBuilder, '_BuildTarball',
                     side_effect=lambda _, path, **kwargs: osutils.Touch(path))

    result = artifacts.BundleAutotestFiles(self.chroot, self.sysroot,
                                           self.output_dir)

    for archive in result.values():
      self.assertStartsWith(archive, self.output_dir)
      self.assertExists(archive)


class ArchiveChromeEbuildEnvTest(cros_test_lib.MockTempDirTestCase):
  """ArchiveChromeEbuildEnv tests."""

  def setUp(self):
    # Create the chroot and sysroot instances.
    self.chroot_path = os.path.join(self.tempdir, 'chroot_dir')
    self.chroot = chroot_lib.Chroot(path=self.chroot_path)
    self.sysroot_path = os.path.join(self.chroot_path, 'sysroot_dir')
    self.sysroot = sysroot_lib.Sysroot(self.sysroot_path)

    # Create the output directory.
    self.output_dir = os.path.join(self.tempdir, 'output_dir')
    osutils.SafeMakedirs(self.output_dir)

    # The sysroot's /var/db/pkg prefix for the chrome package directories.
    var_db_pkg = os.path.join(self.sysroot_path, portage_util.VDB_PATH)
    # Create the var/db/pkg dir so we have that much for no-chrome tests.
    osutils.SafeMakedirs(var_db_pkg)

    # Two versions of chrome to test the multiple version checks/handling.
    chrome_v1 = '%s-1.0.0-r1' % constants.CHROME_PN
    chrome_v2 = '%s-2.0.0-r1' % constants.CHROME_PN

    # Build the two chrome version paths.
    chrome_cat_dir = os.path.join(var_db_pkg, constants.CHROME_CN)
    self.chrome_v1_dir = os.path.join(chrome_cat_dir, chrome_v1)
    self.chrome_v2_dir = os.path.join(chrome_cat_dir, chrome_v2)

    # Directory tuple for verifying the result archive contents.
    self.expected_archive_contents = cros_test_lib.Directory('./',
                                                             'environment')

    # Create a environment.bz2 file to put into folders.
    env_file = os.path.join(self.tempdir, 'environment')
    osutils.Touch(env_file)
    cros_build_lib.run(['bzip2', env_file])
    self.env_bz2 = '%s.bz2' % env_file

  def _CreateChromeDir(self, path, populate=True):
    """Setup a chrome package directory.

    Args:
      path (str): The full chrome package path.
      populate (bool): Whether to include the environment bz2.
    """
    osutils.SafeMakedirs(path)
    if populate:
      shutil.copy(self.env_bz2, path)

  def testSingleChromeVersion(self):
    """Test a successful single-version run."""
    self._CreateChromeDir(self.chrome_v1_dir)

    created = artifacts.ArchiveChromeEbuildEnv(self.sysroot, self.output_dir)

    self.assertStartsWith(created, self.output_dir)
    cros_test_lib.VerifyTarball(created, self.expected_archive_contents)

  def testMultipleChromeVersions(self):
    """Test a successful multiple version run."""
    # Create both directories, but don't populate the v1 dir so it'll hit an
    # error if the wrong one is used.
    self._CreateChromeDir(self.chrome_v1_dir, populate=False)
    self._CreateChromeDir(self.chrome_v2_dir)

    created = artifacts.ArchiveChromeEbuildEnv(self.sysroot, self.output_dir)

    self.assertStartsWith(created, self.output_dir)
    cros_test_lib.VerifyTarball(created, self.expected_archive_contents)

  def testNoChrome(self):
    """Test no version of chrome present."""
    with self.assertRaises(artifacts.NoFilesError):
      artifacts.ArchiveChromeEbuildEnv(self.sysroot, self.output_dir)


class ArchiveImagesTest(cros_test_lib.TempDirTestCase):
  """ArchiveImages tests."""

  def setUp(self):
    self.image_dir = os.path.join(self.tempdir, 'images')
    osutils.SafeMakedirs(self.image_dir)
    self.output_dir = os.path.join(self.tempdir, 'output')
    osutils.SafeMakedirs(self.output_dir)

    self.images = []
    for img in artifacts.IMAGE_TARS.keys():
      full_path = os.path.join(self.image_dir, img)
      self.images.append(full_path)
      osutils.Touch(full_path)

    osutils.Touch(os.path.join(self.image_dir, 'irrelevant_image.bin'))
    osutils.Touch(os.path.join(self.image_dir, 'foo.txt'))
    osutils.Touch(os.path.join(self.image_dir, 'bar'))

  def testNoImages(self):
    """Test an empty directory handling."""
    artifacts.ArchiveImages(self.tempdir, self.output_dir)
    self.assertFalse(os.listdir(self.output_dir))

  def testAllImages(self):
    """Test each image gets picked up."""
    created = artifacts.ArchiveImages(self.image_dir, self.output_dir)
    self.assertCountEqual(list(artifacts.IMAGE_TARS.values()), created)


class CreateChromeRootTest(cros_test_lib.RunCommandTempDirTestCase):
  """CreateChromeRoot tests."""

  def setUp(self):
    # Create the build target.
    self.build_target = build_target_lib.BuildTarget('board')

    # Create the chroot.
    self.chroot_dir = os.path.join(self.tempdir, 'chroot')
    self.chroot_tmp = os.path.join(self.chroot_dir, 'tmp')
    osutils.SafeMakedirs(self.chroot_tmp)
    self.chroot = chroot_lib.Chroot(path=self.chroot_dir)

    # Create the output directory.
    self.output_dir = os.path.join(self.tempdir, 'output_dir')
    osutils.SafeMakedirs(self.output_dir)

  def testRunCommandError(self):
    """Test handling when the run command call is not successful."""
    self.rc.SetDefaultCmdResult(
        side_effect=cros_build_lib.RunCommandError('Error'))

    with self.assertRaises(artifacts.CrosGenerateSysrootError):
      artifacts.CreateChromeRoot(self.chroot, self.build_target,
                                 self.output_dir)

  def testSuccess(self):
    """Test success case."""
    # Separate tempdir for the method itself.
    call_tempdir = os.path.join(self.chroot_tmp, 'cgs_call_tempdir')
    osutils.SafeMakedirs(call_tempdir)
    self.PatchObject(osutils.TempDir, '__enter__', return_value=call_tempdir)

    # Set up files in the tempdir since the command isn't being called to
    # generate anything for it to handle.
    files = ['file1', 'file2', 'file3']
    expected_files = [os.path.join(self.output_dir, f) for f in files]
    for f in files:
      osutils.Touch(os.path.join(call_tempdir, f))

    created = artifacts.CreateChromeRoot(self.chroot, self.build_target,
                                         self.output_dir)

    # Just test the command itself and the parameter-based args.
    self.assertCommandContains(['cros_generate_sysroot',
                                '--board', self.build_target.name])
    # Make sure we
    self.assertCountEqual(expected_files, created)
    for f in created:
      self.assertExists(f)


class BundleEBuildLogsTarballTest(cros_test_lib.TempDirTestCase):
  """BundleEBuildLogsTarball tests."""

  def testBundleEBuildLogsTarball(self):
    """Verifies that the correct EBuild tar files are bundled."""
    board = 'samus'
    # Create chroot object and sysroot object
    chroot_path = os.path.join(self.tempdir, 'chroot')
    chroot = chroot_lib.Chroot(path=chroot_path)
    sysroot_path = os.path.join('build', board)
    sysroot = sysroot_lib.Sysroot(sysroot_path)

    # Create parent dir for logs
    log_parent_dir = os.path.join(chroot.path, 'build')

    # Names of log files typically found in a build directory.
    log_files = (
        '',
        'x11-libs:libdrm-2.4.81-r24:20170816-175008.log',
        'x11-libs:libpciaccess-0.12.902-r2:20170816-174849.log',
        'x11-libs:libva-1.7.1-r2:20170816-175019.log',
        'x11-libs:libva-intel-driver-1.7.1-r4:20170816-175029.log',
        'x11-libs:libxkbcommon-0.4.3-r2:20170816-174908.log',
        'x11-libs:pango-1.32.5-r1:20170816-174954.log',
        'x11-libs:pixman-0.32.4:20170816-174832.log',
        'x11-misc:xkeyboard-config-2.15-r3:20170816-174908.log',
        'x11-proto:kbproto-1.0.5:20170816-174849.log',
        'x11-proto:xproto-7.0.31:20170816-174849.log',
    )
    tarred_files = [os.path.join('logs', x) for x in log_files]
    log_files_root = os.path.join(log_parent_dir,
                                  '%s/tmp/portage/logs' % board)
    # Generate a representative set of log files produced by a typical build.
    cros_test_lib.CreateOnDiskHierarchy(log_files_root, log_files)

    archive_dir = self.tempdir
    tarball = artifacts.BundleEBuildLogsTarball(chroot, sysroot, archive_dir)
    self.assertEqual('ebuild_logs.tar.xz', tarball)

    # Verify the tarball contents.
    tarball_fullpath = os.path.join(self.tempdir, tarball)
    cros_test_lib.VerifyTarball(tarball_fullpath, tarred_files)


class BundleChromeOSConfigTest(cros_test_lib.TempDirTestCase):
  """BundleChromeOSConfig tests."""

  def setUp(self):
    self.board = 'samus'

    # Create chroot object and sysroot object
    chroot_path = os.path.join(self.tempdir, 'chroot')
    self.chroot = chroot_lib.Chroot(path=chroot_path)
    sysroot_path = os.path.join('build', self.board)
    self.sysroot = sysroot_lib.Sysroot(sysroot_path)

    self.archive_dir = self.tempdir

  def testBundleChromeOSConfig(self):
    """Verifies that the correct ChromeOS config file is bundled."""
    # Create parent dir for ChromeOS Config output.
    config_parent_dir = os.path.join(self.chroot.path, 'build')

    # Names of ChromeOS Config files typically found in a build directory.
    config_files = ('config.json',
                    cros_test_lib.Directory('yaml', [
                        'config.c', 'config.yaml', 'ec_config.c', 'ec_config.h',
                        'model.yaml', 'private-model.yaml'
                    ]))
    config_files_root = os.path.join(
        config_parent_dir, '%s/usr/share/chromeos-config' % self.board)
    # Generate a representative set of config files produced by a typical build.
    cros_test_lib.CreateOnDiskHierarchy(config_files_root, config_files)

    # Write a payload to the config.yaml file.
    test_config_payload = {
        'chromeos': {
            'configs': [{
                'identity': {
                    'platform-name': 'Samus'
                }
            }]
        }
    }
    with open(os.path.join(config_files_root, 'yaml', 'config.yaml'), 'w') as f:
      json.dump(test_config_payload, f)

    config_filename = artifacts.BundleChromeOSConfig(self.chroot, self.sysroot,
                                                     self.archive_dir)
    self.assertEqual('config.yaml', config_filename)

    with open(os.path.join(self.archive_dir, config_filename), 'r') as f:
      self.assertEqual(test_config_payload, json.load(f))

  def testNoChromeOSConfigFound(self):
    """Verifies that None is returned when no ChromeOS config file is found."""
    self.assertIsNone(
        artifacts.BundleChromeOSConfig(self.chroot, self.sysroot,
                                       self.archive_dir))


class BundleVmFilesTest(cros_test_lib.TempDirTestCase):
  """BundleVmFiles tests."""

  def testBundleVmFiles(self):
    """Verifies that the correct files are bundled"""
    # Create the chroot instance.
    chroot_path = os.path.join(self.tempdir, 'chroot')
    chroot = chroot_lib.Chroot(path=chroot_path)

    # Create the test_results_dir
    test_results_dir = 'test/results'

    # Create a set of files where some should get bundled up as VM files.
    # Add a suffix (123) to one of the files matching the VM pattern prefix.
    vm_files = ('file1.txt',
                'file2.txt',
                'chromiumos_qemu_disk.bin' + '123',
                'chromiumos_qemu_mem.bin'
               )

    target_test_dir = os.path.join(chroot_path, test_results_dir)
    cros_test_lib.CreateOnDiskHierarchy(target_test_dir, vm_files)

    # Create the output directory.
    output_dir = os.path.join(self.tempdir, 'output_dir')
    osutils.SafeMakedirs(output_dir)

    archives = artifacts.BundleVmFiles(
        chroot, test_results_dir, output_dir)
    expected_archive_files = [
        output_dir + '/chromiumos_qemu_disk.bin' + '123.tar',
        output_dir + '/chromiumos_qemu_mem.bin.tar']
    self.assertCountEqual(archives, expected_archive_files)


class BuildFirmwareArchiveTest(cros_test_lib.TempDirTestCase):
  """BuildFirmwareArchive tests."""

  def testBuildFirmwareArchive(self):
    """Verifies that firmware archiver includes proper files"""
    # Assorted set of file names, some of which are supposed to be included in
    # the archive.
    fw_files = (
        'dts/emeraldlake2.dts',
        'image-link.rw.bin',
        'nv_image-link.bin',
        'pci8086,0166.rom',
        'seabios.cbfs',
        'u-boot.elf',
        'u-boot_netboot.bin',
        'updater-link.rw.sh',
        'x86-memtest',
    )

    board = 'link'
    # fw_test_root = os.path.join(self.tempdir, os.path.basename(__file__))
    fw_test_root = self.tempdir
    fw_files_root = os.path.join(fw_test_root,
                                 'chroot/build/%s/firmware' % board)
    # Generate a representative set of files produced by a typical build.
    cros_test_lib.CreateOnDiskHierarchy(fw_files_root, fw_files)

    # Create the chroot and sysroot instances.
    chroot_path = os.path.join(self.tempdir, 'chroot')
    chroot = chroot_lib.Chroot(path=chroot_path)
    sysroot = sysroot_lib.Sysroot('/build/link')

    # Create an archive from the simulated firmware directory
    tarball = os.path.join(
        fw_test_root,
        artifacts.BuildFirmwareArchive(chroot, sysroot, fw_test_root))

    # Verify the tarball contents.
    cros_test_lib.VerifyTarball(tarball, fw_files)

class BundleFpmcuUnittestsTest(cros_test_lib.TempDirTestCase):
  """BundleFpmcuUnittests tests."""

  def testBundleFpmcuUnittests(self):
    """Verifies that the resulting tarball includes proper files"""
    unittest_files = (
        'bloonchipper/test_rsa.bin',
        'dartmonkey/test_utils.bin',
    )

    board = 'hatch'
    unittest_files_root = os.path.join(
        self.tempdir,
        'chroot/build/%s/firmware/chromeos-fpmcu-unittests' % board)
    cros_test_lib.CreateOnDiskHierarchy(unittest_files_root, unittest_files)

    chroot_path = os.path.join(self.tempdir, 'chroot')
    chroot = chroot_lib.Chroot(path=chroot_path)
    sysroot = sysroot_lib.Sysroot('/build/%s' % board)

    tarball = os.path.join(
        self.tempdir,
        artifacts.BundleFpmcuUnittests(chroot, sysroot, self.tempdir))
    cros_test_lib.VerifyTarball(
        tarball,
        unittest_files + ('bloonchipper/', 'dartmonkey/'))

class BundleAFDOGenerationArtifacts(cros_test_lib.MockTempDirTestCase):
  """BundleAFDOGenerationArtifacts tests."""

  def setUp(self):
    # Create the build target.
    self.build_target = build_target_lib.BuildTarget('board')

    # Create the chroot.
    self.chroot_dir = os.path.join(self.tempdir, 'chroot')
    self.chroot_tmp = os.path.join(self.chroot_dir, 'tmp')
    osutils.SafeMakedirs(self.chroot_tmp)
    self.chroot = chroot_lib.Chroot(path=self.chroot_dir)

    # Create the output directory.
    self.output_dir = os.path.join(self.tempdir, 'output_dir')
    osutils.SafeMakedirs(self.output_dir)

    self.chrome_root = os.path.join(self.tempdir, 'chrome_root')

  def testRunSuccess(self):
    """Generic function for testing success cases for different types."""

    # Separate tempdir for the method itself.
    call_tempdir = os.path.join(self.chroot_tmp, 'call_tempdir')
    osutils.SafeMakedirs(call_tempdir)
    self.PatchObject(osutils.TempDir, '__enter__', return_value=call_tempdir)

    mock_orderfile_generate = self.PatchObject(
        toolchain_util, 'GenerateChromeOrderfile',
        autospec=True)

    mock_afdo_generate = self.PatchObject(
        toolchain_util, 'GenerateBenchmarkAFDOProfile',
        autospec=True)

    # Test both orderfile and AFDO.
    for is_orderfile in [False, True]:
      # Set up files in the tempdir since the command isn't being called to
      # generate anything for it to handle.
      files = ['artifact1', 'artifact2']
      expected_files = [os.path.join(self.output_dir, f) for f in files]
      for f in files:
        osutils.Touch(os.path.join(call_tempdir, f))

      created = artifacts.BundleAFDOGenerationArtifacts(
          is_orderfile, self.chroot, self.chrome_root,
          self.build_target, self.output_dir)

      # Test right class is called with right arguments
      if is_orderfile:
        mock_orderfile_generate.assert_called_once_with(
            board=self.build_target.name,
            chrome_root=self.chrome_root,
            output_dir=call_tempdir,
            chroot_path=self.chroot.path,
            chroot_args=self.chroot.get_enter_args()
        )
      else:
        mock_afdo_generate.assert_called_once_with(
            board=self.build_target.name,
            output_dir=call_tempdir,
            chroot_path=self.chroot.path,
            chroot_args=self.chroot.get_enter_args(),
        )

      # Make sure we get all the expected files
      self.assertCountEqual(expected_files, created)
      for f in created:
        self.assertExists(f)
        os.remove(f)


class FetchPinnedGuestImagesTest(cros_test_lib.TempDirTestCase):
  """FetchPinnedGuestImages tests."""

  def setUp(self):
    self.chroot = chroot_lib.Chroot(self.tempdir)
    self.sysroot = sysroot_lib.Sysroot('/sysroot')
    sysroot_path = os.path.join(self.tempdir, 'sysroot')
    osutils.SafeMakedirs(sysroot_path)

    self.pin_dir = os.path.join(sysroot_path, constants.GUEST_IMAGES_PINS_PATH)
    osutils.SafeMakedirs(self.pin_dir)

  def testSuccess(self):
    """Tests that generating a guest images tarball."""
    for filename in ('file1', 'file2'):
      pin_file = os.path.join(self.pin_dir, filename + '.json')
      with open(pin_file, 'w') as f:
        pin = {
            'filename': filename + '.tar.gz',
            'gsuri': 'gs://%s' % filename,
        }
        json.dump(pin, f)

    expected = [
        artifacts.PinnedGuestImage(filename='file1.tar.gz', uri='gs://file1'),
        artifacts.PinnedGuestImage(filename='file2.tar.gz', uri='gs://file2'),
    ]

    pins = artifacts.FetchPinnedGuestImages(self.chroot, self.sysroot)
    self.assertCountEqual(expected, pins)

  def testBadPin(self):
    """Tests that generating a guest images tarball with a bad pin file."""
    pin_file = os.path.join(self.pin_dir, 'file1.json')
    with open(pin_file, 'w') as f:
      pin = {
          'gsuri': 'gs://%s' % 'file1',
      }
      json.dump(pin, f)

    pins = artifacts.FetchPinnedGuestImages(self.chroot, self.sysroot)
    self.assertFalse(pins)

  def testNoPins(self):
    """Tests that generating a guest images tarball with no pins."""
    pins = artifacts.FetchPinnedGuestImages(self.chroot, self.sysroot)
    self.assertFalse(pins)


class GeneratePayloadsTest(cros_test_lib.MockTempDirTestCase):
  """Test cases for the payload generation functions."""

  def setUp(self):
    self.target_image = os.path.join(
        self.tempdir,
        'link/R37-5952.0.2014_06_12_2302-a1/chromiumos_test_image.bin')
    osutils.Touch(self.target_image, makedirs=True)
    self.sample_dlc_image = os.path.join(
        self.tempdir,
        'link/R37-5952.0.2014_06_12_2302-a1/dlc/sample-dlc/package/dlc.img')
    osutils.Touch(self.sample_dlc_image, makedirs=True)

  def testGenerateFullTestPayloads(self):
    """Verifies correctly generating full payloads."""
    paygen_mock = self.PatchObject(paygen_payload_lib, 'GenerateUpdatePayload')
    artifacts.GenerateTestPayloads(self.target_image, self.tempdir, full=True)
    payload_path = os.path.join(
        self.tempdir,
        'chromeos_R37-5952.0.2014_06_12_2302-a1_link_full_dev.bin')
    paygen_mock.assert_call_once_with(self.target_image, payload_path)

  def testGenerateDeltaTestPayloads(self):
    """Verifies correctly generating delta payloads."""
    paygen_mock = self.PatchObject(paygen_payload_lib, 'GenerateUpdatePayload')
    artifacts.GenerateTestPayloads(self.target_image, self.tempdir, delta=True)
    payload_path = os.path.join(
        self.tempdir,
        'chromeos_R37-5952.0.2014_06_12_2302-a1_R37-'
        '5952.0.2014_06_12_2302-a1_link_delta_dev.bin')
    paygen_mock.assert_call_once_with(self.target_image, payload_path,
                                      src_image=self.target_image)

  def testGenerateFullDummyDlcTestPayloads(self):
    """Verifies correctly generating full payloads for sample-dlc."""
    paygen_mock = self.PatchObject(paygen_payload_lib, 'GenerateUpdatePayload')
    self.PatchObject(portage_util, 'GetBoardUseFlags',
                     return_value=['dlc_test'])
    artifacts.GenerateTestPayloads(self.target_image, self.tempdir, full=True,
                                   dlc=True)

    rootfs_payload = 'chromeos_R37-5952.0.2014_06_12_2302-a1_link_full_dev.bin'
    dlc_payload = ('dlc_sample-dlc_package_R37-5952.0.2014_06_12_2302-a1_link_'
                   'full_dev.bin')
    paygen_mock.assert_has_calls([
        mock.call(self.target_image,
                  os.path.join(self.tempdir, rootfs_payload)),
        mock.call(self.sample_dlc_image,
                  os.path.join(self.tempdir, dlc_payload)),
    ])

  def testGenerateDeltaDummyDlcTestPayloads(self):
    """Verifies correctly generating delta payloads for sample-dlc."""
    paygen_mock = self.PatchObject(paygen_payload_lib, 'GenerateUpdatePayload')
    self.PatchObject(portage_util, 'GetBoardUseFlags',
                     return_value=['dlc_test'])
    artifacts.GenerateTestPayloads(self.target_image, self.tempdir, delta=True,
                                   dlc=True)

    rootfs_payload = ('chromeos_R37-5952.0.2014_06_12_2302-a1_R37-'
                      '5952.0.2014_06_12_2302-a1_link_delta_dev.bin')
    dlc_payload = ('dlc_sample-dlc_package_R37-5952.0.2014_06_12_2302-a1_R37-'
                   '5952.0.2014_06_12_2302-a1_link_delta_dev.bin')
    paygen_mock.assert_has_calls([
        mock.call(self.target_image,
                  os.path.join(self.tempdir, rootfs_payload),
                  src_image=self.target_image),
        mock.call(self.sample_dlc_image,
                  os.path.join(self.tempdir, dlc_payload),
                  src_image=self.sample_dlc_image),
    ])

  def testGenerateStatefulTestPayloads(self):
    """Verifies correctly generating stateful payloads."""
    paygen_mock = self.PatchObject(paygen_stateful_payload_lib,
                                   'GenerateStatefulPayload')
    artifacts.GenerateTestPayloads(self.target_image, self.tempdir,
                                   stateful=True)
    paygen_mock.assert_call_once_with(self.target_image, self.tempdir)

  def testGenerateQuickProvisionPayloads(self):
    """Verifies correct files are created for quick_provision script."""
    extract_kernel_mock = self.PatchObject(partition_lib, 'ExtractKernel')
    extract_root_mock = self.PatchObject(partition_lib, 'ExtractRoot')
    compress_file_mock = self.PatchObject(cros_build_lib, 'CompressFile')

    artifacts.GenerateQuickProvisionPayloads(self.target_image, self.tempdir)

    extract_kernel_mock.assert_called_once_with(
        self.target_image, partial_mock.HasString('kernel.bin'))
    extract_root_mock.assert_called_once_with(
        self.target_image, partial_mock.HasString('rootfs.bin'),
        truncate=False)

    calls = [mock.call(partial_mock.HasString('kernel.bin'),
                       partial_mock.HasString(
                           constants.QUICK_PROVISION_PAYLOAD_KERNEL)),
             mock.call(partial_mock.HasString('rootfs.bin'),
                       partial_mock.HasString(
                           constants.QUICK_PROVISION_PAYLOAD_ROOTFS))]
    compress_file_mock.assert_has_calls(calls)


class GenerateCpeExportTest(cros_test_lib.RunCommandTempDirTestCase):
  """GenerateCpeExport tests."""

  def setUp(self):
    self.sysroot = sysroot_lib.Sysroot('/build/board')
    self.chroot = chroot_lib.Chroot(self.tempdir)

    self.chroot_tempdir = osutils.TempDir(base_dir=self.tempdir)
    self.PatchObject(self.chroot, 'tempdir', return_value=self.chroot_tempdir)

    self.output_dir = os.path.join(self.tempdir, 'output_dir')
    osutils.SafeMakedirs(self.output_dir)

    result_file = artifacts.CPE_RESULT_FILE_TEMPLATE % 'board'
    self.result_file = os.path.join(self.output_dir, result_file)

    warnings_file = artifacts.CPE_WARNINGS_FILE_TEMPLATE % 'board'
    self.warnings_file = os.path.join(self.output_dir, warnings_file)

  def testSuccess(self):
    """Test success handling."""
    # Set up warning output and the file the command would be making.
    report = 'Report.'
    warnings = 'Warnings.'
    self.rc.SetDefaultCmdResult(returncode=0, output=report, error=warnings)

    result = artifacts.GenerateCpeReport(self.chroot, self.sysroot,
                                         self.output_dir)

    expected_cmd = ['cros_extract_deps', '--sysroot', '/build/board',
                    '--format', 'cpe', 'virtual/target-os', '--output-path',
                    self.result_file]
    self.assertCommandCalled(expected_cmd, capture_output=True,
                             chroot_args=['--chroot', mock.ANY],
                             enter_chroot=True)

    self.assertEqual(self.result_file, result.report)
    self.assertEqual(self.warnings_file, result.warnings)
    # We cannot assert that self.result_file exists and check contents since we
    # are mocking  cros_extract_deps, but we verified the args to
    # cros_extract_deps.
    self.assertFileContents(self.warnings_file, warnings)


class BundleGceTarballTest(cros_test_lib.MockTempDirTestCase):
  """BundleGceTarball tests."""

  def setUp(self):
    self.output_dir = os.path.join(self.tempdir, 'output_dir')
    self.image_dir = os.path.join(self.tempdir, 'image_dir')
    osutils.SafeMakedirs(self.output_dir)
    osutils.SafeMakedirs(self.image_dir)

    self.image_file = os.path.join(self.image_dir, constants.TEST_IMAGE_BIN)
    osutils.Touch(self.image_file)

  def testSuccess(self):
    # Prepare tempdir for use by the function as tarball root.
    call_tempdir = os.path.join(self.tempdir, 'call_tempdir')
    osutils.SafeMakedirs(call_tempdir)
    self.PatchObject(osutils.TempDir, '__enter__', return_value=call_tempdir)

    tarball = artifacts.BundleGceTarball(self.output_dir, self.image_dir)

    # Verify location and content of the tarball.
    self.assertEqual(tarball, os.path.join(self.output_dir,
                                           constants.TEST_IMAGE_GCE_TAR))
    cros_test_lib.VerifyTarball(tarball, ('disk.raw',))

    # Verify the symlink points the the test image.
    disk_raw = os.path.join(call_tempdir, 'disk.raw')
    self.assertEqual(os.readlink(disk_raw), self.image_file)


class TestGatherSymbolFiles(cros_test_lib.MockTempDirTestCase):
  """Base class for testing GatherSymbolFiles."""

  SLIM_CONTENT = """
some junk
"""

  FAT_CONTENT = """
STACK CFI 1234
some junk
STACK CFI 1234
"""


  def createSymbolFile(self, filename, content=FAT_CONTENT, size=0):
    """Create a symbol file using content with minimum size."""
    osutils.SafeMakedirs(os.path.dirname(filename))

    # If a file size is given, force that to be the minimum file size. Create
    # a sparse file so large files are practical.
    with open(filename, 'w+b') as f:
      f.truncate(size)
      f.seek(0)
      f.write(content.encode('utf-8'))

  def test_GatherSymbolFiles(self):
    """Test that files are found and copied."""
    # Create directory with some symbol files.
    tar_tmp_dir = os.path.join(self.tempdir, 'tar_tmp')
    output_dir = os.path.join(self.tempdir, 'output')
    input_dir = os.path.join(self.tempdir, 'input')
    osutils.SafeMakedirs(output_dir)
    self.createSymbolFile(os.path.join(input_dir, 'a/b/c/file1.sym'))
    self.createSymbolFile(os.path.join(input_dir, 'a/b/c/d/file2.sym'))
    self.createSymbolFile(os.path.join(input_dir, 'a/file3.sym'))
    self.createSymbolFile(os.path.join(input_dir, 'a/b/c/d/e/file1.sym'))

    # Call artifacts.GatherSymbolFiles to find symbol files under self.tempdir
    # and copy them to output_dir.
    symbol_files = list(artifacts.GatherSymbolFiles(
        tar_tmp_dir, output_dir, [input_dir]))

    # Construct the expected symbol files. Note that the SymbolFileTuple
    # field file_name is the full path to where a symbol file was found,
    # while display_path is the relative path (from the search) where
    # it is created in the output directory.
    expected_symbol_files = [
        artifacts.SymbolFileTuple(
            file_name=os.path.join(input_dir, 'a/b/c/file1.sym'),
            display_path='a/b/c/file1.sym'),
        artifacts.SymbolFileTuple(
            file_name=os.path.join(input_dir, 'a/b/c/d/file2.sym'),
            display_path='a/b/c/d/file2.sym'),
        artifacts.SymbolFileTuple(
            file_name=os.path.join(input_dir, 'a/file3.sym'),
            display_path='a/file3.sym'),
        artifacts.SymbolFileTuple(
            file_name=os.path.join(input_dir, 'a/b/c/d/e/file1.sym'),
            display_path='a/b/c/d/e/file1.sym')
    ]

    # Sort symbol_files and expected_output_files by the display_path attribute.
    symbol_files = sorted(symbol_files, key=attrgetter('display_path'))
    expected_symbol_files = sorted(expected_symbol_files,
                                   key=attrgetter('display_path'))
    # Compare the files to the expected files. This verifies the size and
    # contents, and on failure shows the full contents.
    self.assertEqual(symbol_files, expected_symbol_files)

    # Verify that the files in output_dir match the SymbolFile display_paths.
    files_in_output_dir = self.getFilesWithRelativeDir(output_dir)
    files_in_output_dir.sort()
    symbol_file_display_paths = [obj.display_path for obj in symbol_files]
    symbol_file_display_paths.sort()
    self.assertEqual(files_in_output_dir, symbol_file_display_paths)

    # Verify that the display_name of each symbol does not contain pathsep.
    symbol_file_display_names = [
        os.path.basename(obj.display_path) for obj in symbol_files
    ]
    for display_name in symbol_file_display_names:
      self.assertEqual(-1, display_name.find(os.path.sep))

  def test_FindSymbolTarFiles(self):
    """Test that symbol files in tar files are extracted."""
    output_dir = os.path.join(self.tempdir, 'output')
    osutils.SafeMakedirs(output_dir)

    # Set up test input directory.
    tarball_dir = os.path.join(self.tempdir, 'some/path')
    files_in_tarball = ['dir1/fileZ.sym', 'dir2/fileY.sym', 'dir2/fileX.sym',
                        'fileA.sym', 'fileB.sym', 'fileC.sym']
    for filename in files_in_tarball:
      self.createSymbolFile(os.path.join(tarball_dir, filename))
    temp_tarball_file_path = os.path.join(self.tempdir, 'symfiles.tar')
    cros_build_lib.CreateTarball(temp_tarball_file_path, tarball_dir)
    # Now that we've created the tarball, remove the .sym files in
    # the tarball dir and move the tarball to that dir.
    for filename in files_in_tarball:
      os.remove(os.path.join(tarball_dir, filename))
    tarball_path = os.path.join(tarball_dir, 'symfiles.tar')
    shutil.move(temp_tarball_file_path, tarball_path)

    # Execute artifacts.GatherSymbolFiles where the path contains the tarball.
    symbol_files = list(artifacts.GatherSymbolFiles(
        tarball_dir, output_dir, [tarball_path]))

    self.assertEqual(len(symbol_files), 6)
    symbol_file_display_names = [
        os.path.basename(obj.display_path) for obj in symbol_files
    ]
    symbol_file_display_names.sort()
    self.assertEqual(symbol_file_display_names,
                     ['fileA.sym', 'fileB.sym', 'fileC.sym',
                      'fileX.sym', 'fileY.sym', 'fileZ.sym'])

    # Verify that the files in output_dir match the SymbolFile display_paths.
    files_in_output_dir = self.getFilesWithRelativeDir(output_dir)
    files_in_output_dir.sort()
    symbol_file_display_paths = [obj.display_path for obj in symbol_files]
    symbol_file_display_paths.sort()
    self.assertEqual(files_in_output_dir, symbol_file_display_paths)
    # Verify that the display_name of each symbol does not contain pathsep.
    symbol_file_display_names = [
        os.path.basename(obj.display_path) for obj in symbol_files
    ]
    for display_name in symbol_file_display_names:
      self.assertEqual(-1, display_name.find(os.path.sep))

  def getFilesWithRelativeDir(self, dest_dir):
    """Find all files below dest_dir using dir relative to dest_dir."""
    relative_files = []
    for path, __, files in os.walk(dest_dir):
      for filename in files:
        fullpath = os.path.join(path, filename)
        relpath = os.path.relpath(fullpath, dest_dir)
        relative_files.append(relpath)
    return relative_files
