blob: 9ce3c09afa8f8d60f845b84eede7e40019ca2f33 [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.
"""Unittests for workspace stages."""
from __future__ import print_function
import os
import shutil
import mock
from chromite.cbuildbot.builders import workspace_builders_unittest
from chromite.cbuildbot import commands
from chromite.cbuildbot import manifest_version
from chromite.cbuildbot.stages import branch_archive_stages
from chromite.cbuildbot.stages import generic_stages
from chromite.cbuildbot.stages import workspace_stages_unittest
from chromite.lib import cros_build_lib
from chromite.lib import gs
from chromite.lib import gs_unittest
from chromite.lib import osutils
from chromite.lib import portage_util
# pylint: disable=too-many-ancestors
# pylint: disable=protected-access
class BranchArchiveStageTestBase(workspace_stages_unittest.WorkspaceStageBase,
gs_unittest.AbstractGSContextTest):
"""Base class for test suites."""
def setUp(self):
self.CreateMockOverlay('board', self.workspace)
self.upload_mock = self.PatchObject(
generic_stages.ArchivingStageMixin, 'UploadArtifact')
# It would be nice to include the prefix in the return path. How?
tempdir_mock = self.PatchObject(osutils, 'TempDir')
tempdir_mock.return_value.__enter__.return_value = '/tempdir'
self.copy_mock = self.PatchObject(shutil, 'copyfile')
self.mkdir_mock = self.PatchObject(os, 'mkdir')
self.gs_copy_mock = self.PatchObject(gs.GSContext, 'CopyInto')
self.push_mock = self.PatchObject(
commands, 'PushImages')
self.write_mock = self.PatchObject(osutils, 'WriteFile')
self.read_overlay_file_mock = self.PatchObject(
portage_util, 'ReadOverlayFile',
return_value='{"extra_upload_urls":["gs://chromeos-extra-archive"]}')
def ConstructStage(self):
"""Returns an instance of the stage to be tested.
Note: Must be implemented in subclasses.
"""
raise NotImplementedError(self, 'ConstructStage: Implement in your test')
class FirmwareArchiveStageTest(BranchArchiveStageTestBase):
"""Test FirmwareArchiveStage."""
def ConstructStage(self):
self._run.attrs.version_info = manifest_version.VersionInfo(
'10.0.0', chrome_branch='10')
self._run.attrs.release_tag = 'infra-tag'
return branch_archive_stages.FirmwareArchiveStage(
self._run, self.buildstore, build_root=self.workspace, board='board')
def testProd(self):
"""Tests sync command used by default."""
self.PatchObject(commands, 'BuildFirmwareArchive',
return_value='/tempdir/firmware_from_source.tar.bz2')
self._Prepare(
'test-firmwarebranch',
site_config=workspace_builders_unittest.CreateMockSiteConfig())
self.RunStage()
# Validate properties.
self.assertEqual(self.stage.dummy_config,
'board-firmware')
self.assertEqual(self.stage.dummy_version,
'R1-1.2.3')
self.assertEqual(self.stage.dummy_archive_url,
'gs://chromeos-image-archive/board-firmware/R1-1.2.3')
self.assertEqual(self.copy_mock.call_args_list, [
mock.call(
'/tempdir/firmware_from_source.tar.bz2',
'/tempdir/board/firmware_from_source.tar.bz2'),
mock.call(
'/tempdir/metadata.json',
'/tempdir/board/metadata.json'),
])
self.assertEqual(self.upload_mock.call_args_list, [
mock.call(
'/tempdir/board/firmware_from_source.tar.bz2',
prefix='board',
archive=True),
mock.call('/tempdir/board/metadata.json', archive=True),
])
self.assertEqual(self.read_overlay_file_mock.call_args_list, 2 * [
mock.call(
'scripts/artifacts.json', buildroot=self.workspace, board='board'),
])
self.assertEqual(self.gs_copy_mock.call_args_list, [
mock.call(
'/tempdir/firmware_from_source.tar.bz2',
'gs://chromeos-image-archive/board-firmware/R1-1.2.3',
recursive=True, parallel=True),
mock.call(
'/tempdir/firmware_from_source.tar.bz2',
'gs://chromeos-extra-archive/board-firmware/R1-1.2.3',
recursive=True, parallel=True),
mock.call(
'/tempdir/metadata.json',
'gs://chromeos-image-archive/board-firmware/R1-1.2.3',
recursive=True, parallel=True),
mock.call(
'/tempdir/metadata.json',
'gs://chromeos-extra-archive/board-firmware/R1-1.2.3',
recursive=True, parallel=True),
])
self.assertEqual(self.push_mock.call_args_list, [
mock.call(
profile=None,
buildroot=self.workspace,
sign_types=['firmware', 'accessory_rwsig'],
dryrun=False,
archive_url=('gs://chromeos-image-archive/'
'board-firmware/R1-1.2.3'),
board='board'),
])
def testDebug(self):
"""Tests sync command used by default."""
self.PatchObject(commands, 'BuildFirmwareArchive',
return_value='/tempdir/firmware_from_source.tar.bz2')
self._Prepare(
'test-firmwarebranch',
site_config=workspace_builders_unittest.CreateMockSiteConfig(),
extra_cmd_args=['--debug'])
self.RunStage()
# Validate properties.
self.assertEqual(self.stage.dummy_config,
'board-firmware-tryjob')
self.assertEqual(self.stage.dummy_version,
'R1-1.2.3-bNone')
self.assertEqual(self.stage.dummy_archive_url,
'gs://chromeos-image-archive/board-firmware-tryjob/'
'R1-1.2.3-bNone')
self.assertEqual(self.copy_mock.call_args_list, [
mock.call(
'/tempdir/firmware_from_source.tar.bz2',
'/tempdir/board/firmware_from_source.tar.bz2'),
mock.call(
'/tempdir/metadata.json',
'/tempdir/board/metadata.json'),
])
self.assertEqual(self.upload_mock.call_args_list, [
mock.call(
'/tempdir/board/firmware_from_source.tar.bz2',
prefix='board',
archive=True),
mock.call('/tempdir/board/metadata.json', archive=True),
])
self.assertEqual(self.read_overlay_file_mock.call_args_list, 2 * [
mock.call(
'scripts/artifacts.json', buildroot=self.workspace, board='board'),
])
self.assertEqual(self.gs_copy_mock.call_args_list, [
mock.call(
'/tempdir/firmware_from_source.tar.bz2',
'gs://chromeos-image-archive/board-firmware-tryjob/R1-1.2.3-bNone',
recursive=True, parallel=True),
mock.call(
'/tempdir/firmware_from_source.tar.bz2',
'gs://chromeos-extra-archive/board-firmware-tryjob/R1-1.2.3-bNone',
recursive=True, parallel=True),
mock.call(
'/tempdir/metadata.json',
'gs://chromeos-image-archive/board-firmware-tryjob/R1-1.2.3-bNone',
recursive=True, parallel=True),
mock.call(
'/tempdir/metadata.json',
'gs://chromeos-extra-archive/board-firmware-tryjob/R1-1.2.3-bNone',
recursive=True, parallel=True),
])
self.assertEqual(self.push_mock.call_args_list, [
mock.call(
profile=None,
buildroot=self.workspace,
sign_types=['firmware', 'accessory_rwsig'],
dryrun=True,
archive_url=('gs://chromeos-image-archive/'
'board-firmware-tryjob/R1-1.2.3-bNone'),
board='board'),
])
class FactoryArchiveStageTest(BranchArchiveStageTestBase):
"""Test FactoryArchiveStage."""
def setUp(self):
self.build_image_mock = self.PatchObject(
commands, 'BuildFactoryInstallImage',
return_value='/factory_image')
self.net_boot_mock = self.PatchObject(
commands, 'MakeNetboot')
self.factory_zip_mock = self.PatchObject(
commands, 'BuildFactoryZip',
return_value='/factory.zip')
self.create_tar_mock = self.PatchObject(
cros_build_lib, 'CreateTarball')
def ConstructStage(self):
self._run.attrs.version_info = manifest_version.VersionInfo(
'10.0.0', chrome_branch='10')
self._run.attrs.release_tag = 'infra-tag'
return branch_archive_stages.FactoryArchiveStage(
self._run, self.buildstore, build_root=self.workspace, board='board')
def testProd(self):
"""Tests sync command used by default."""
self._Prepare(
'test-factorybranch',
site_config=workspace_builders_unittest.CreateMockSiteConfig())
self.RunStage()
# Validate properties.
self.assertEqual(self.stage.dummy_config,
'board-factory')
self.assertEqual(self.stage.dummy_version,
'R1-1.2.3')
self.assertEqual(self.stage.dummy_archive_url,
'gs://chromeos-image-archive/board-factory/R1-1.2.3')
self.assertEqual(self.build_image_mock.call_args_list, [
mock.call(
self.workspace,
'board',
extra_env={
'FEATURES': 'separatedebug',
'USE': '-cros-debug chrome_internal',
}),
])
self.assertEqual(self.net_boot_mock.call_args_list, [
mock.call(
self.workspace,
'board',
'/factory_image'),
])
self.assertEqual(self.factory_zip_mock.call_args_list, [
mock.call(
self.workspace,
'board',
'/tempdir',
'/factory_image',
'R1-1.2.3'),
])
self.assertEqual(self.create_tar_mock.call_args_list, [
mock.call(
'/tempdir/chromiumos_test_image.tar.xz',
inputs=['chromiumos_test_image.bin'],
compression=1,
cwd=os.path.join(self.workspace,
'src/build/images/board/latest')),
])
self.assertEqual(self.copy_mock.call_args_list, [
mock.call(
'/factory.zip',
'/tempdir/board/factory.zip'),
mock.call(
'/tempdir/chromiumos_test_image.tar.xz',
'/tempdir/board/chromiumos_test_image.tar.xz'),
mock.call(
'/tempdir/metadata.json',
'/tempdir/board/metadata.json'),
])
self.assertEqual(self.upload_mock.call_args_list, [
mock.call('/tempdir/board/factory.zip', archive=True),
mock.call('/tempdir/board/chromiumos_test_image.tar.xz', archive=True),
mock.call('/tempdir/board/metadata.json', archive=True),
])
self.assertEqual(self.read_overlay_file_mock.call_args_list, 3 * [
mock.call(
'scripts/artifacts.json', buildroot=self.workspace, board='board')
])
self.assertEqual(self.gs_copy_mock.call_args_list, [
mock.call(
'/factory.zip',
'gs://chromeos-image-archive/board-factory/R1-1.2.3',
recursive=True, parallel=True),
mock.call(
'/factory.zip',
'gs://chromeos-extra-archive/board-factory/R1-1.2.3',
recursive=True, parallel=True),
mock.call(
'/tempdir/chromiumos_test_image.tar.xz',
'gs://chromeos-image-archive/board-factory/R1-1.2.3',
recursive=True, parallel=True),
mock.call(
'/tempdir/chromiumos_test_image.tar.xz',
'gs://chromeos-extra-archive/board-factory/R1-1.2.3',
recursive=True, parallel=True),
mock.call(
'/tempdir/metadata.json',
'gs://chromeos-image-archive/board-factory/R1-1.2.3',
recursive=True, parallel=True),
mock.call(
'/tempdir/metadata.json',
'gs://chromeos-extra-archive/board-factory/R1-1.2.3',
recursive=True, parallel=True),
])
self.assertEqual(self.push_mock.call_args_list, [
mock.call(
profile=None,
buildroot=self.workspace,
sign_types=['factory'],
dryrun=False,
archive_url=('gs://chromeos-image-archive/'
'board-factory/R1-1.2.3'),
board='board'),
])
def testDebug(self):
"""Tests sync command used by default."""
self._Prepare(
'test-factorybranch',
site_config=workspace_builders_unittest.CreateMockSiteConfig(),
extra_cmd_args=['--debug'])
self.RunStage()
# Validate properties.
self.assertEqual(self.stage.dummy_config,
'board-factory-tryjob')
self.assertEqual(self.stage.dummy_version,
'R1-1.2.3-bNone')
self.assertEqual(self.stage.dummy_archive_url,
'gs://chromeos-image-archive/board-factory-tryjob/'
'R1-1.2.3-bNone')
self.assertEqual(self.build_image_mock.call_args_list, [
mock.call(
self.workspace,
'board',
extra_env={
'FEATURES': 'separatedebug',
'USE': '-cros-debug chrome_internal',
}),
])
self.assertEqual(self.net_boot_mock.call_args_list, [
mock.call(
self.workspace,
'board',
'/factory_image'),
])
self.assertEqual(self.factory_zip_mock.call_args_list, [
mock.call(
self.workspace,
'board',
'/tempdir',
'/factory_image',
'R1-1.2.3-bNone'),
])
self.assertEqual(self.create_tar_mock.call_args_list, [
mock.call(
'/tempdir/chromiumos_test_image.tar.xz',
inputs=['chromiumos_test_image.bin'],
compression=1,
cwd=os.path.join(self.workspace,
'src/build/images/board/latest')),
])
self.assertEqual(self.copy_mock.call_args_list, [
mock.call(
'/factory.zip',
'/tempdir/board/factory.zip'),
mock.call(
'/tempdir/chromiumos_test_image.tar.xz',
'/tempdir/board/chromiumos_test_image.tar.xz'),
mock.call(
'/tempdir/metadata.json',
'/tempdir/board/metadata.json'),
])
self.assertEqual(self.upload_mock.call_args_list, [
mock.call('/tempdir/board/factory.zip', archive=True),
mock.call('/tempdir/board/chromiumos_test_image.tar.xz', archive=True),
mock.call('/tempdir/board/metadata.json', archive=True),
])
self.assertEqual(self.read_overlay_file_mock.call_args_list, 3 * [
mock.call(
'scripts/artifacts.json', buildroot=self.workspace, board='board'),
])
self.assertEqual(self.gs_copy_mock.call_args_list, [
mock.call(
'/factory.zip',
'gs://chromeos-image-archive/board-factory-tryjob/R1-1.2.3-bNone',
recursive=True, parallel=True),
mock.call(
'/factory.zip',
'gs://chromeos-extra-archive/board-factory-tryjob/R1-1.2.3-bNone',
recursive=True, parallel=True),
mock.call(
'/tempdir/chromiumos_test_image.tar.xz',
'gs://chromeos-image-archive/board-factory-tryjob/R1-1.2.3-bNone',
recursive=True, parallel=True),
mock.call(
'/tempdir/chromiumos_test_image.tar.xz',
'gs://chromeos-extra-archive/board-factory-tryjob/R1-1.2.3-bNone',
recursive=True, parallel=True),
mock.call(
'/tempdir/metadata.json',
'gs://chromeos-image-archive/board-factory-tryjob/R1-1.2.3-bNone',
recursive=True, parallel=True),
mock.call(
'/tempdir/metadata.json',
'gs://chromeos-extra-archive/board-factory-tryjob/R1-1.2.3-bNone',
recursive=True, parallel=True),
])
self.assertEqual(self.push_mock.call_args_list, [
mock.call(
profile=None,
buildroot=self.workspace,
sign_types=['factory'],
dryrun=True,
archive_url=('gs://chromeos-image-archive/'
'board-factory-tryjob/R1-1.2.3-bNone'),
board='board'),
])