blob: 7069290ae0ce947dd8503f1e56c3bb4d64a231d6 [file] [log] [blame]
# Copyright (c) 2012 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 SDK stages."""
from __future__ import print_function
import json
import os
import unittest
from chromite.cbuildbot import commands
from chromite.lib import constants
from chromite.cbuildbot.stages import sdk_stages
from chromite.cbuildbot.stages import generic_stages_unittest
from chromite.lib import cros_build_lib
from chromite.lib import osutils
from chromite.lib import perf_uploader
from chromite.lib import portage_util
from chromite.lib import toolchain
class SDKBuildToolchainsStageTest(
generic_stages_unittest.AbstractStageTestCase):
"""Tests SDK toolchain building."""
def setUp(self):
# This code has its own unit tests, so no need to go testing it here.
self.run_mock = self.PatchObject(commands, 'RunBuildScript')
def ConstructStage(self):
return sdk_stages.SDKBuildToolchainsStage(self._run)
def testNormal(self):
"""Basic run through the main code."""
self._Prepare('chromiumos-sdk')
self.RunStage()
self.assertEqual(self.run_mock.call_count, 2)
# Sanity check args passed to RunBuildScript.
for call in self.run_mock.call_args_list:
buildroot, cmd = call[0]
self.assertTrue(isinstance(buildroot, basestring))
self.assertTrue(isinstance(cmd, (tuple, list)))
for ele in cmd:
self.assertTrue(isinstance(ele, basestring))
class SDKPackageStageTest(generic_stages_unittest.AbstractStageTestCase):
"""Tests SDK package and Manifest creation."""
fake_packages = (('cat1/package', '1'), ('cat1/package', '2'),
('cat2/package', '3'), ('cat2/package', '4'))
def setUp(self):
# Replace SudoRunCommand, since we don't care about sudo.
self.PatchObject(cros_build_lib, 'SudoRunCommand',
wraps=cros_build_lib.RunCommand)
# Prepare a fake chroot.
self.fake_chroot = os.path.join(self.build_root, 'chroot/build/amd64-host')
self.fake_json_data = {}
osutils.SafeMakedirs(self.fake_chroot)
osutils.Touch(os.path.join(self.fake_chroot, 'file'))
for package, v in self.fake_packages:
cpv = portage_util.SplitCPV('%s-%s' % (package, v))
key = '%s/%s' % (cpv.category, cpv.package)
self.fake_json_data.setdefault(key, []).append([v, {}])
def ConstructStage(self):
return sdk_stages.SDKPackageStage(self._run)
def testTarballCreation(self):
"""Tests whether we package the tarball and correctly create a Manifest."""
# We'll test this separately.
self.PatchObject(sdk_stages.SDKPackageStage, '_SendPerfValues')
self._Prepare('chromiumos-sdk')
fake_tarball = os.path.join(self.build_root, 'built-sdk.tar.xz')
fake_manifest = os.path.join(self.build_root,
'built-sdk.tar.xz.Manifest')
self.PatchObject(portage_util, 'ListInstalledPackages',
return_value=self.fake_packages)
self.RunStage()
# Check tarball for the correct contents.
output = cros_build_lib.RunCommand(
['tar', '-I', 'xz', '-tvf', fake_tarball],
capture_output=True).output.splitlines()
# First line is './', use it as an anchor, count the chars, and strip as
# much from all other lines.
stripchars = len(output[0]) - 1
tar_lines = [x[stripchars:] for x in output]
self.assertNotIn('/build/amd64-host/', tar_lines)
self.assertIn('/file', tar_lines)
# Verify manifest contents.
real_json_data = json.loads(osutils.ReadFile(fake_manifest))
self.assertEqual(real_json_data['packages'],
self.fake_json_data)
def testPerf(self):
"""Check perf data points are generated/uploaded."""
m = self.PatchObject(perf_uploader, 'UploadPerfValues')
sdk_data = 'asldjfasf'
sdk_size = len(sdk_data)
sdk_tarball = os.path.join(self.tempdir, 'sdk.tar.xz')
osutils.WriteFile(sdk_tarball, sdk_data)
tarball_dir = os.path.join(self.tempdir, constants.DEFAULT_CHROOT_DIR,
constants.SDK_TOOLCHAINS_OUTPUT)
arm_tar = os.path.join(tarball_dir, 'arm-cros-linux-gnu.tar.xz')
x86_tar = os.path.join(tarball_dir, 'i686-pc-linux-gnu.tar.xz')
osutils.Touch(arm_tar, makedirs=True)
osutils.Touch(x86_tar, makedirs=True)
# pylint: disable=protected-access
sdk_stages.SDKPackageStage._SendPerfValues(
self.tempdir, sdk_tarball, 'http://some/log', '123.4.5.6', 'sdk-bot')
# pylint: enable=protected-access
perf_values = m.call_args[0][0]
exp = perf_uploader.PerformanceValue(
description='base',
value=sdk_size,
units='bytes',
higher_is_better=False,
graph='cros-sdk-size',
stdio_uri='http://some/log',
)
self.assertEqual(exp, perf_values[0])
exp = set((
perf_uploader.PerformanceValue(
description='arm-cros-linux-gnu',
value=0,
units='bytes',
higher_is_better=False,
graph='cros-sdk-size',
stdio_uri='http://some/log',
),
perf_uploader.PerformanceValue(
description='i686-pc-linux-gnu',
value=0,
units='bytes',
higher_is_better=False,
graph='cros-sdk-size',
stdio_uri='http://some/log',
),
perf_uploader.PerformanceValue(
description='base_plus_arm-cros-linux-gnu',
value=sdk_size,
units='bytes',
higher_is_better=False,
graph='cros-sdk-size',
stdio_uri='http://some/log',
),
perf_uploader.PerformanceValue(
description='base_plus_i686-pc-linux-gnu',
value=sdk_size,
units='bytes',
higher_is_better=False,
graph='cros-sdk-size',
stdio_uri='http://some/log',
),
))
self.assertEqual(exp, set(perf_values[1:]))
platform_name = m.call_args[0][1]
self.assertEqual(platform_name, 'sdk-bot')
test_name = m.call_args[0][2]
self.assertEqual(test_name, 'sdk')
kwargs = m.call_args[1]
self.assertEqual(kwargs['revision'], 123456)
class SDKPackageToolchainOverlaysStageTest(
generic_stages_unittest.AbstractStageTestCase):
"""Tests board toolchain overlay installation and packaging."""
def setUp(self):
# Mock out running of cros_setup_toolchains.
self.PatchObject(commands, 'RunBuildScript', wraps=self.FakeRunBuildScript)
self._setup_toolchain_cmds = []
# Prepare a fake chroot.
self.fake_chroot = os.path.join(self.build_root, 'chroot/build/amd64-host')
osutils.SafeMakedirs(self.fake_chroot)
osutils.Touch(os.path.join(self.fake_chroot, 'file'))
def FakeRunBuildScript(self, build_root, cmd, chromite_cmd=False, **kwargs):
if cmd[0] == 'cros_setup_toolchains':
self.assertEqual(self.build_root, build_root)
self.assertTrue(chromite_cmd)
self.assertTrue(kwargs.get('enter_chroot', False))
self.assertTrue(kwargs.get('sudo', False))
# Drop a uniquely named file in the toolchain overlay merged location.
sysroot = None
board = None
targets = None
for opt in cmd[1:]:
if opt.startswith('--sysroot='):
sysroot = opt[len('--sysroot='):]
elif opt.startswith('--include-boards='):
board = opt[len('--include-boards='):]
elif opt.startswith('--targets='):
targets = opt[len('--targets='):]
self.assertTrue(sysroot)
self.assertTrue(board)
self.assertEqual('boards', targets)
merged_dir = os.path.join(self.build_root, constants.DEFAULT_CHROOT_DIR,
sysroot.lstrip(os.path.sep))
osutils.Touch(os.path.join(merged_dir, board + '.tmp'))
def ConstructStage(self):
return sdk_stages.SDKPackageToolchainOverlaysStage(self._run)
# TODO(akeshet): determine why this test is flaky
@unittest.skip("Skip flaky test.")
def testTarballCreation(self):
"""Tests that tarballs are created for all board toolchains."""
self._Prepare('chromiumos-sdk')
self.RunStage()
# Check that a tarball was created correctly for all toolchain sets.
sdk_toolchains = set(toolchain.GetToolchainsForBoard('sdk'))
all_toolchain_combos = set()
for board in self._run.site_config.GetBoards():
try:
toolchains = set(toolchain.GetToolchainsForBoard(board).iterkeys())
if toolchains.issubset(sdk_toolchains):
all_toolchain_combos.add('-'.join(sorted(toolchains)))
except portage_util.MissingOverlayException:
pass
for toolchains in all_toolchain_combos:
overlay_tarball = os.path.join(
self.build_root, constants.DEFAULT_CHROOT_DIR,
constants.SDK_OVERLAYS_OUTPUT,
'built-sdk-overlay-toolchains-%s.tar.xz' % toolchains)
output = cros_build_lib.RunCommand(
['tar', '-I', 'xz', '-tf', overlay_tarball],
capture_output=True).output.splitlines()
# Check that the overlay tarball contains a marker file and that the
# board recorded by this marker file indeed uses the toolchains for which
# the tarball was built.
tmp_files = [os.path.basename(x) for x in output if x.endswith('.tmp')]
self.assertEqual(1, len(tmp_files))
board = tmp_files[0][:-len('.tmp')]
board_toolchains = '-'.join(sorted(
toolchain.GetToolchainsForBoard(board).iterkeys()))
self.assertEqual(toolchains, board_toolchains)
class SDKTestStageTest(generic_stages_unittest.AbstractStageTestCase):
"""Tests SDK test phase."""
def setUp(self):
# This code has its own unit tests, so no need to go testing it here.
self.run_mock = self.PatchObject(cros_build_lib, 'RunCommand')
def ConstructStage(self):
return sdk_stages.SDKTestStage(self._run)
def testNormal(self):
"""Basic run through the main code."""
self._Prepare('chromiumos-sdk')
self.RunStage()