blob: 01dbf60bf058508e023adf51c3213319c49be446 [file] [log] [blame]
# -*- 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 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_called_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_called_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_called_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 GatherSymbolFilesTest(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 source_file_name is the full path to where a symbol file was found,
# while relative_path is the relative path (from the search) where
# it is created in the output directory.
expected_symbol_files = [
artifacts.SymbolFileTuple(
source_file_name=os.path.join(input_dir, 'a/b/c/file1.sym'),
relative_path='a/b/c/file1.sym'),
artifacts.SymbolFileTuple(
source_file_name=os.path.join(input_dir, 'a/b/c/d/file2.sym'),
relative_path='a/b/c/d/file2.sym'),
artifacts.SymbolFileTuple(
source_file_name=os.path.join(input_dir, 'a/file3.sym'),
relative_path='a/file3.sym'),
artifacts.SymbolFileTuple(
source_file_name=os.path.join(input_dir, 'a/b/c/d/e/file1.sym'),
relative_path='a/b/c/d/e/file1.sym')
]
# Sort symbol_files and expected_output_files by the relative_path
# attribute.
symbol_files = sorted(symbol_files, key=attrgetter('relative_path'))
expected_symbol_files = sorted(expected_symbol_files,
key=attrgetter('relative_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 relative_paths.
files_in_output_dir = self.getFilesWithRelativeDir(output_dir)
files_in_output_dir.sort()
symbol_file_relative_paths = [obj.relative_path for obj in symbol_files]
symbol_file_relative_paths.sort()
self.assertEqual(files_in_output_dir, symbol_file_relative_paths)
# Verify that the display_name of each symbol does not contain pathsep.
symbol_file_relative_paths = [
os.path.basename(obj.relative_path) for obj in symbol_files
]
for display_name in symbol_file_relative_paths:
self.assertEqual(-1, display_name.find(os.path.sep))
def test_GatherSymbolTarFiles(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)
# Verify the symbol_file relative_paths.
symbol_file_relative_paths = [
obj.relative_path for obj in symbol_files
]
symbol_file_relative_paths.sort()
self.assertEqual(symbol_file_relative_paths,
['dir1/fileZ.sym', 'dir2/fileX.sym', 'dir2/fileY.sym',
'fileA.sym', 'fileB.sym', 'fileC.sym'])
# Verify the symbol_file source_file_names.
symbol_file_source_file_names = [
obj.source_file_name for obj in symbol_files
]
symbol_file_source_file_names.sort()
# Note that the expected symbol_file_source_names are the full path to
# the tarfile followed by the relative path, such as
# /tmp/chromite.test2ng92vzo/some/path/symfiles.tar/dir1/fileZ.sym
expected_symbol_file_source_names = [
os.path.join(tarball_path, 'dir1/fileZ.sym'),
os.path.join(tarball_path, 'dir2/fileX.sym'),
os.path.join(tarball_path, 'dir2/fileY.sym'),
os.path.join(tarball_path, 'fileA.sym'),
os.path.join(tarball_path, 'fileB.sym'),
os.path.join(tarball_path, 'fileC.sym')
]
self.assertEqual(symbol_file_source_file_names,
expected_symbol_file_source_names)
# Verify that the files in output_dir match the SymbolFile relative_paths.
files_in_output_dir = self.getFilesWithRelativeDir(output_dir)
files_in_output_dir.sort()
symbol_file_relative_paths = [obj.relative_path for obj in symbol_files]
symbol_file_relative_paths.sort()
self.assertEqual(files_in_output_dir, symbol_file_relative_paths)
# Verify that the display_name of each symbol does not contain pathsep.
symbol_file_relative_paths = [
os.path.basename(obj.relative_path) for obj in symbol_files
]
for display_name in symbol_file_relative_paths:
self.assertEqual(-1, display_name.find(os.path.sep))
def test_GatherSymbolTarFilesWithNonSymFiles(self):
"""Test that non-symbol files in tar files are not 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/fileU.sym', 'dir1/fileU.txt',
'fileD.sym', 'fileD.txt']
for filename in files_in_tarball:
# we don't care about file contents, so we are using createSymbolFile
# for files whether they end with .sym or not.
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]))
# Verify the symbol_file relative_paths only has .sym files.
symbol_file_relative_paths = [
obj.relative_path for obj in symbol_files
]
symbol_file_relative_paths.sort()
self.assertEqual(symbol_file_relative_paths,
['dir1/fileU.sym', 'fileD.sym'])
for symfile in symbol_file_relative_paths:
extension = symfile.split('.')[1]
self.assertEqual(extension, 'sym')
def test_GatherSymbolFileFullFilePaths(self):
"""Test full filepaths (.sym and .txt) only gather .sym 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)
# We don't care about contents, so use createSymbolFiles for all files.
self.createSymbolFile(os.path.join(input_dir, 'a_file.sym'))
self.createSymbolFile(os.path.join(input_dir, 'a_file.txt'))
# Call artifacts.GatherSymbolFiles with full paths to files, some of which
# don't end in .sym, verify that only .sym files get copied to output_dir.
symbol_files = list(artifacts.GatherSymbolFiles(
tar_tmp_dir, output_dir,
[os.path.join(input_dir, 'a_file.sym'),
os.path.join(input_dir, 'a_file.txt')]))
# Construct the expected symbol files. Note that the SymbolFileTuple
# field source_file_name is the full path to where a symbol file was found,
# while relative_path is the relative path (from the search) where
# it is created in the output directory.
expected_symbol_files = [
artifacts.SymbolFileTuple(
source_file_name=os.path.join(input_dir, 'a_file.sym'),
relative_path='a_file.sym')
]
# 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 only a_file.sym is in the output_dir.
files_in_output_dir = self.getFilesWithRelativeDir(output_dir)
self.assertEqual(files_in_output_dir, ['a_file.sym'])
def test_IsTarball(self):
"""Test IsTarball helper function."""
self.assertTrue(artifacts.IsTarball('file.tar'))
self.assertTrue(artifacts.IsTarball('file.tar.bz2'))
self.assertTrue(artifacts.IsTarball('file.tar.gz'))
self.assertTrue(artifacts.IsTarball('file.tbz'))
self.assertTrue(artifacts.IsTarball('file.txz'))
self.assertFalse(artifacts.IsTarball('file.txt'))
self.assertFalse(artifacts.IsTarball('file.tart'))
self.assertFalse(artifacts.IsTarball('file.bz2'))
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
class GenerateBreakpadSymbolsTest(cros_test_lib.MockTempDirTestCase):
"""Base class for testing GenerateBreakpadSymbols."""
def setUp(self):
self.chroot_dir = os.path.join(self.tempdir, 'chroot_dir')
osutils.SafeMakedirs(self.chroot_dir)
def test_generateBreakpadSymbols(self):
"""Verify that calling the service layer invokes the script as expected."""
chroot = chroot_lib.Chroot(self.chroot_dir)
build_target = build_target_lib.BuildTarget('board')
self.PatchObject(cros_build_lib, 'run')
# Call the method being tested.
artifacts.GenerateBreakpadSymbols(chroot, build_target, False)
cros_build_lib.run.assert_called_with(['cros_generate_breakpad_symbols',
'--board=board',
'--jobs', mock.ANY,
'--exclude-dir=firmware'],
capture_output=True,
enter_chroot=True,
chroot_args=['--chroot', mock.ANY])
def test_generateBreakpadSymbolsWithDebug(self):
"""Verify that calling with debug invokes the script as expected."""
chroot = chroot_lib.Chroot(self.chroot_dir)
build_target = build_target_lib.BuildTarget('board')
self.PatchObject(cros_build_lib, 'run')
# Call the method being tested.
artifacts.GenerateBreakpadSymbols(chroot, build_target, True)
cros_build_lib.run.assert_called_with(['cros_generate_breakpad_symbols',
'--debug',
'--board=board',
'--jobs', mock.ANY,
'--exclude-dir=firmware'],
capture_output=True,
enter_chroot=True,
chroot_args=['--chroot', mock.ANY])