blob: 585e4a49be278454a00aceb62ebd02c7349bf80d [file] [log] [blame]
# Copyright 2016 The ChromiumOS Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""Unit tests for chromite.scripts.cbuildbot_launch."""
import os
from pathlib import Path
import time
from unittest import mock
from chromite.cbuildbot import commands
from chromite.cbuildbot import repository
from chromite.lib import build_summary
from chromite.lib import chroot_lib
from chromite.lib import constants
from chromite.lib import cros_sdk_lib
from chromite.lib import cros_test_lib
from chromite.lib import osutils
from chromite.scripts import cbuildbot_launch
EXPECTED_MANIFEST_URL = "https://chrome-internal-review.googlesource.com/chromeos/manifest-internal" # pylint: disable=line-too-long
# It's reasonable for unittests to look at internals.
# pylint: disable=protected-access
class FakeException(Exception):
"""Test exception to raise during tests."""
class CbuildbotLaunchTest(cros_test_lib.MockTestCase):
"""Tests for cbuildbot_launch script."""
def testPreParseArguments(self) -> None:
"""Test we can correctly extract branch values from cbuildbot args."""
CASES = (
(
["--buildroot", "/buildroot", "daisy-incremental"],
(None, "/buildroot"),
),
(
[
"--buildbot",
"--buildroot",
"/buildroot",
"-b",
"release-R57-9202.B",
"daisy-incremental",
],
("release-R57-9202.B", "/buildroot"),
),
(
[
"--debug",
"--buildbot",
"--notests",
"--buildroot",
"/buildroot",
"--branch",
"release-R57-9202.B",
"daisy-incremental",
],
("release-R57-9202.B", "/buildroot"),
),
)
for cmd_args, expected in CASES:
expected_branch, expected_buildroot = expected
options = cbuildbot_launch.PreParseArguments(cmd_args)
self.assertEqual(options.branch, expected_branch)
self.assertEqual(options.buildroot, expected_buildroot)
def testInitialCheckout(self) -> None:
"""Test InitialCheckout with minimum settings."""
mock_repo = mock.MagicMock()
mock_repo.branch = "branch"
argv = ["-r", "/root", "config"]
options = cbuildbot_launch.PreParseArguments(argv)
cbuildbot_launch.InitialCheckout(mock_repo, options)
self.assertEqual(
mock_repo.mock_calls,
[
mock.call.PreLoad("/preload/chromeos"),
mock.call.Sync(jobs=32, detach=True, downgrade_repo=False),
],
)
def testConfigureGlobalEnvironment(self) -> None:
"""Ensure that we can setup our global runtime environment correctly."""
os.environ.pop("LANG", None)
os.environ["LC_MONETARY"] = "bad"
cbuildbot_launch.ConfigureGlobalEnvironment()
# Verify umask is updated.
self.assertEqual(os.umask(0), 0o22)
# Verify ENVs are cleaned up.
self.assertEqual(os.environ["LANG"], "en_US.UTF-8")
self.assertNotIn("LC_MONETARY", os.environ)
class RunTests(cros_test_lib.RunCommandTestCase):
"""Tests for cbuildbot_launch script."""
ARGS_BASE = ["--buildroot", "/buildroot"]
EXPECTED_ARGS_BASE = ["--buildroot", "/cbuildbot_buildroot"]
ARGS_GIT_CACHE = ["--git-cache-dir", "/git-cache"]
ARGS_CONFIG = ["config"]
CMD = ["/cbuildbot_buildroot/chromite/bin/cbuildbot"]
def verifyCbuildbot(self, args, expected_cmd, version) -> None:
"""Ensure we invoke cbuildbot correctly."""
self.PatchObject(
commands,
"GetTargetChromiteApiVersion",
autospec=True,
return_value=version,
)
cbuildbot_launch.Cbuildbot("/cbuildbot_buildroot", "/depot_tools", args)
self.assertCommandCalled(
expected_cmd,
extra_env={"PATH": mock.ANY},
cwd="/cbuildbot_buildroot",
check=False,
)
def testCbuildbotSimple(self) -> None:
"""Ensure we invoke cbuildbot correctly."""
self.verifyCbuildbot(
self.ARGS_BASE + self.ARGS_CONFIG,
self.CMD + self.ARGS_CONFIG + self.EXPECTED_ARGS_BASE,
(0, 4),
)
def testCbuildbotNotFiltered(self) -> None:
"""Ensure we invoke cbuildbot correctly."""
self.verifyCbuildbot(
self.ARGS_BASE + self.ARGS_CONFIG + self.ARGS_GIT_CACHE,
(
self.CMD
+ self.ARGS_CONFIG
+ self.EXPECTED_ARGS_BASE
+ self.ARGS_GIT_CACHE
),
(0, 4),
)
def testCbuildbotFiltered(self) -> None:
"""Ensure we invoke cbuildbot correctly."""
self.verifyCbuildbot(
self.ARGS_BASE + self.ARGS_CONFIG + self.ARGS_GIT_CACHE,
self.CMD + self.ARGS_CONFIG + self.EXPECTED_ARGS_BASE,
(0, 2),
)
def testMainMin(self) -> None:
"""Test a minimal set of command line options."""
self.PatchObject(osutils, "SafeMakedirs", autospec=True)
self.PatchObject(
commands,
"GetTargetChromiteApiVersion",
autospec=True,
return_value=(
constants.REEXEC_API_MAJOR,
constants.REEXEC_API_MINOR,
),
)
mock_repo = mock.MagicMock()
mock_repo.branch = "main"
mock_repo.directory = "/root/repository"
mock_repo_create = self.PatchObject(
repository, "RepoRepository", autospec=True, return_value=mock_repo
)
mock_clean = self.PatchObject(
cbuildbot_launch, "CleanBuildRoot", autospec=True
)
mock_checkout = self.PatchObject(
cbuildbot_launch, "InitialCheckout", autospec=True
)
mock_set_last_build_state = self.PatchObject(
cbuildbot_launch, "SetLastBuildState", autospec=True
)
expected_build_state = build_summary.BuildSummary(
build_number=0,
master_build_id=0,
status=mock.ANY,
buildroot_layout=2,
branch="main",
)
argv = ["-r", "/root", "config"]
options = cbuildbot_launch.PreParseArguments(argv)
cbuildbot_launch._main(options, argv)
# Did we create the repo instance correctly?
self.assertEqual(
mock_repo_create.mock_calls,
[
mock.call(
EXPECTED_MANIFEST_URL,
"/root/repository",
branch="main",
)
],
)
# Ensure we clean, as expected.
self.assertEqual(
mock_clean.mock_calls,
[
mock.call(
"/root",
mock_repo,
"/root/repository/.cache",
expected_build_state,
False,
)
],
)
# Ensure we checkout, as expected.
self.assertEqual(
mock_checkout.mock_calls, [mock.call(mock_repo, options)]
)
# Ensure we invoke cbuildbot, as expected.
self.assertCommandCalled(
[
"/root/repository/chromite/bin/cbuildbot",
"config",
"-r",
"/root/repository",
"--workspace",
"/root/workspace",
"--cache-dir",
"/root/repository/.cache",
# The duplication is a bug, but not harmful.
"--cache-dir",
"/root/repository/.cache",
],
extra_env={"PATH": mock.ANY},
cwd="/root/repository",
check=False,
)
# Ensure we saved the final state, as expected.
self.assertEqual(
expected_build_state.status, constants.BUILDER_STATUS_PASSED
)
self.assertEqual(
mock_set_last_build_state.mock_calls,
[mock.call("/root", expected_build_state)],
)
def testMainMax(self) -> None:
"""Test a larger set of command line options."""
self.PatchObject(osutils, "SafeMakedirs", autospec=True)
self.PatchObject(
commands,
"GetTargetChromiteApiVersion",
autospec=True,
return_value=(
constants.REEXEC_API_MAJOR,
constants.REEXEC_API_MINOR,
),
)
mock_repo = mock.MagicMock()
mock_repo.branch = "branch"
mock_repo.directory = "/root/repository"
mock_summary = build_summary.BuildSummary(
build_number=313,
master_build_id=123123123,
status=constants.BUILDER_STATUS_FAILED,
buildroot_layout=cbuildbot_launch.BUILDROOT_BUILDROOT_LAYOUT,
branch="branch",
)
mock_get_last_build_state = self.PatchObject(
cbuildbot_launch,
"GetLastBuildState",
autospec=True,
return_value=mock_summary,
)
mock_repo_create = self.PatchObject(
repository, "RepoRepository", autospec=True, return_value=mock_repo
)
mock_clean = self.PatchObject(
cbuildbot_launch, "CleanBuildRoot", autospec=True
)
mock_checkout = self.PatchObject(
cbuildbot_launch, "InitialCheckout", autospec=True
)
mock_set_last_build_state = self.PatchObject(
cbuildbot_launch, "SetLastBuildState", autospec=True
)
argv = [
"--buildroot",
"/root",
"--branch",
"branch",
"--git-cache-dir",
"/git-cache",
"--cache-dir",
"/cache",
"--remote-trybot",
"--master-build-id",
"123456789",
"--buildnumber",
"314",
"config",
]
options = cbuildbot_launch.PreParseArguments(argv)
cbuildbot_launch._main(options, argv)
# Did we create the repo instance correctly?
self.assertEqual(
mock_repo_create.mock_calls,
[
mock.call(
EXPECTED_MANIFEST_URL,
"/root/repository",
branch="branch",
)
],
)
# Ensure we look up the previous status.
self.assertEqual(
mock_get_last_build_state.mock_calls, [mock.call("/root")]
)
# Ensure we clean, as expected.
self.assertEqual(
mock_clean.mock_calls,
[
mock.call(
"/root",
mock_repo,
"/cache",
build_summary.BuildSummary(
build_number=314,
master_build_id=123456789,
status=mock.ANY,
branch="branch",
buildroot_layout=2,
),
False,
)
],
)
# Ensure we checkout, as expected.
self.assertEqual(
mock_checkout.mock_calls, [mock.call(mock_repo, options)]
)
# Ensure we invoke cbuildbot, as expected.
self.assertCommandCalled(
[
"/root/repository/chromite/bin/cbuildbot",
"config",
"--buildroot",
"/root/repository",
"--branch",
"branch",
"--git-cache-dir",
"/git-cache",
"--cache-dir",
"/cache",
"--remote-trybot",
"--master-build-id",
"123456789",
"--buildnumber",
"314",
"--previous-build-state",
"eyJicmFuY2giOiJicmFuY2giLCJidWlsZF9udW1iZXIiOjMxMywiYnVpbGRy"
"b290X2xheW91dCI6MiwibWFzdGVyX2J1aWxkX2lkIjoxMjMxMjMxMjMsInN0"
"YXR1cyI6ImZhaWwifQ==",
"--workspace",
"/root/workspace",
"--cache-dir",
"/cache",
],
extra_env={"PATH": mock.ANY},
cwd="/root/repository",
check=False,
)
# Ensure we write the final build state, as expected.
final_state = build_summary.BuildSummary(
build_number=314,
master_build_id=123456789,
status=constants.BUILDER_STATUS_PASSED,
buildroot_layout=2,
branch="branch",
)
self.assertEqual(
mock_set_last_build_state.mock_calls,
[mock.call("/root", final_state)],
)
class CleanBuildRootTest(cros_test_lib.MockTempDirTestCase):
"""Tests for CleanBuildRoot method."""
def setUp(self) -> None:
"""Create standard buildroot contents for cleanup."""
self.root = os.path.join(self.tempdir)
self.previous_build_state = os.path.join(
self.root, ".cbuildbot_build_state.json"
)
self.buildroot = os.path.join(self.root, "buildroot")
self.repo = os.path.join(self.buildroot, ".repo/repo")
self.chroot = os.path.join(self.buildroot, "chroot")
self.general = os.path.join(self.buildroot, "general/general")
self.cache = os.path.join(self.buildroot, ".cache")
self.distfiles = os.path.join(self.cache, "distfiles")
self.mock_repo = mock.Mock(repository.RepoRepository)
self.mock_repo.directory = self.buildroot
def populateBuildroot(self, previous_build_state=None) -> None:
"""Create standard buildroot contents for cleanup."""
if previous_build_state:
osutils.SafeMakedirs(self.root)
osutils.WriteFile(self.previous_build_state, previous_build_state)
# Create files.
for f in (self.repo, self.chroot, self.general, self.distfiles):
osutils.Touch(f, makedirs=True)
def testNoBuildroot(self) -> None:
"""Test CleanBuildRoot with no history."""
self.mock_repo.branch = "main"
build_state = build_summary.BuildSummary(
status=constants.BUILDER_STATUS_INFLIGHT,
buildroot_layout=cbuildbot_launch.BUILDROOT_BUILDROOT_LAYOUT,
branch="main",
)
cbuildbot_launch.CleanBuildRoot(
self.root, self.mock_repo, self.cache, build_state
)
new_summary = cbuildbot_launch.GetLastBuildState(self.root)
self.assertEqual(new_summary.buildroot_layout, 2)
self.assertEqual(new_summary.branch, "main")
self.assertIsNotNone(new_summary.distfiles_ts)
self.assertEqual(new_summary, build_state)
self.assertExists(self.previous_build_state)
def testBuildrootNoState(self) -> None:
"""Test CleanBuildRoot with no state information."""
self.populateBuildroot()
self.mock_repo.branch = "main"
build_state = build_summary.BuildSummary(
status=constants.BUILDER_STATUS_INFLIGHT,
buildroot_layout=cbuildbot_launch.BUILDROOT_BUILDROOT_LAYOUT,
branch="main",
)
cbuildbot_launch.CleanBuildRoot(
self.root, self.mock_repo, self.cache, build_state
)
new_summary = cbuildbot_launch.GetLastBuildState(self.root)
self.assertEqual(new_summary.buildroot_layout, 2)
self.assertEqual(new_summary.branch, "main")
self.assertIsNotNone(new_summary.distfiles_ts)
self.assertEqual(new_summary, build_state)
self.assertNotExists(self.repo)
self.assertNotExists(self.chroot)
self.assertNotExists(self.general)
self.assertNotExists(self.distfiles)
self.assertExists(self.previous_build_state)
def testBuildrootFormatMismatch(self) -> None:
"""Test CleanBuildRoot with buildroot layout mismatch."""
old_build_state = build_summary.BuildSummary(
status=constants.BUILDER_STATUS_PASSED,
buildroot_layout=1,
branch="main",
)
self.populateBuildroot(previous_build_state=old_build_state.to_json())
self.mock_repo.branch = "main"
build_state = build_summary.BuildSummary(
status=constants.BUILDER_STATUS_INFLIGHT,
buildroot_layout=cbuildbot_launch.BUILDROOT_BUILDROOT_LAYOUT,
branch="main",
)
cbuildbot_launch.CleanBuildRoot(
self.root, self.mock_repo, self.cache, build_state
)
new_summary = cbuildbot_launch.GetLastBuildState(self.root)
self.assertEqual(new_summary.buildroot_layout, 2)
self.assertEqual(new_summary.branch, "main")
self.assertIsNotNone(new_summary.distfiles_ts)
self.assertEqual(new_summary, build_state)
self.assertNotExists(self.repo)
self.assertNotExists(self.chroot)
self.assertNotExists(self.general)
self.assertNotExists(self.distfiles)
self.assertExists(self.previous_build_state)
def testBuildrootBranchChange(self) -> None:
"""Test CleanBuildRoot with a change in branches."""
old_build_state = build_summary.BuildSummary(
status=constants.BUILDER_STATUS_PASSED,
buildroot_layout=2,
branch="branchA",
)
self.populateBuildroot(previous_build_state=old_build_state.to_json())
self.mock_repo.branch = "branchB"
m = self.PatchObject(cros_sdk_lib, "CleanupChroot")
build_state = build_summary.BuildSummary(
status=constants.BUILDER_STATUS_INFLIGHT,
buildroot_layout=cbuildbot_launch.BUILDROOT_BUILDROOT_LAYOUT,
branch="branchB",
)
cbuildbot_launch.CleanBuildRoot(
self.root, self.mock_repo, self.cache, build_state
)
new_summary = cbuildbot_launch.GetLastBuildState(self.root)
self.assertEqual(new_summary.buildroot_layout, 2)
self.assertEqual(new_summary.branch, "branchB")
self.assertIsNotNone(new_summary.distfiles_ts)
self.assertEqual(new_summary, build_state)
# self.assertExists(self.repo)
self.assertExists(self.general)
self.assertNotExists(self.distfiles)
self.assertExists(self.previous_build_state)
m.assert_called_with(
chroot_lib.Chroot(
path=self.buildroot / Path(constants.DEFAULT_CHROOT_DIR),
out_path=self.buildroot / constants.DEFAULT_OUT_DIR,
),
)
def testBuildrootBranchMatch(self) -> None:
"""Test CleanBuildRoot with no change in branch."""
old_build_state = build_summary.BuildSummary(
status=constants.BUILDER_STATUS_PASSED,
buildroot_layout=2,
branch="branchA",
)
self.populateBuildroot(previous_build_state=old_build_state.to_json())
self.mock_repo.branch = "branchA"
build_state = build_summary.BuildSummary(
status=constants.BUILDER_STATUS_INFLIGHT,
buildroot_layout=cbuildbot_launch.BUILDROOT_BUILDROOT_LAYOUT,
branch="branchA",
)
cbuildbot_launch.CleanBuildRoot(
self.root, self.mock_repo, self.cache, build_state
)
new_summary = cbuildbot_launch.GetLastBuildState(self.root)
self.assertEqual(new_summary.buildroot_layout, 2)
self.assertEqual(new_summary.branch, "branchA")
self.assertIsNotNone(new_summary.distfiles_ts)
self.assertEqual(new_summary, build_state)
self.assertExists(self.repo)
self.assertExists(self.chroot)
self.assertExists(self.general)
self.assertExists(self.distfiles)
self.assertExists(self.previous_build_state)
def testBuildrootGitLocksPrevPass(self) -> None:
"""Verify not CleanStaleLocks, if previous build was in passed."""
old_build_state = build_summary.BuildSummary(
status=constants.BUILDER_STATUS_PASSED,
buildroot_layout=2,
branch="branchA",
)
self.populateBuildroot(previous_build_state=old_build_state.to_json())
self.mock_repo.branch = "branchA"
build_state = build_summary.BuildSummary(
status=constants.BUILDER_STATUS_INFLIGHT,
buildroot_layout=cbuildbot_launch.BUILDROOT_BUILDROOT_LAYOUT,
branch="branchA",
)
cbuildbot_launch.CleanBuildRoot(
self.root, self.mock_repo, self.cache, build_state
)
self.assertEqual(
self.mock_repo.mock_calls,
[
mock.call.PreLoad(),
mock.call.BuildRootGitCleanup(prune_all=True),
],
)
def testBuildrootGitLocksPrevFail(self) -> None:
"""Verify not CleanStaleLocks, if previous build was in failed."""
old_build_state = build_summary.BuildSummary(
status=constants.BUILDER_STATUS_FAILED,
buildroot_layout=2,
branch="branchA",
)
self.populateBuildroot(previous_build_state=old_build_state.to_json())
self.mock_repo.branch = "branchA"
build_state = build_summary.BuildSummary(
status=constants.BUILDER_STATUS_INFLIGHT,
buildroot_layout=cbuildbot_launch.BUILDROOT_BUILDROOT_LAYOUT,
branch="branchA",
)
cbuildbot_launch.CleanBuildRoot(
self.root, self.mock_repo, self.cache, build_state
)
self.assertEqual(
self.mock_repo.mock_calls,
[
mock.call.PreLoad(),
mock.call.BuildRootGitCleanup(prune_all=True),
],
)
def testBuildrootGitLocksPrevInFlight(self) -> None:
"""Verify CleanStaleLocks, if previous build was in flight."""
old_build_state = build_summary.BuildSummary(
status=constants.BUILDER_STATUS_INFLIGHT,
buildroot_layout=2,
branch="branchA",
)
self.populateBuildroot(previous_build_state=old_build_state.to_json())
self.mock_repo.branch = "branchA"
build_state = build_summary.BuildSummary(
status=constants.BUILDER_STATUS_INFLIGHT,
buildroot_layout=cbuildbot_launch.BUILDROOT_BUILDROOT_LAYOUT,
branch="branchA",
)
cbuildbot_launch.CleanBuildRoot(
self.root, self.mock_repo, self.cache, build_state
)
self.assertEqual(
self.mock_repo.method_calls,
[
mock.call.PreLoad(),
mock.call.CleanStaleLocks(),
mock.call.BuildRootGitCleanup(prune_all=True),
],
)
def testBuildrootDistfilesRecentCache(self) -> None:
"""Test CleanBuildRoot skips distfiles when cache is recent."""
seed_distfiles_ts = time.time() - 60
old_build_state = build_summary.BuildSummary(
status=constants.BUILDER_STATUS_PASSED,
buildroot_layout=2,
branch="branchA",
distfiles_ts=seed_distfiles_ts,
)
self.populateBuildroot(previous_build_state=old_build_state.to_json())
self.mock_repo.branch = "branchA"
build_state = build_summary.BuildSummary(
status=constants.BUILDER_STATUS_INFLIGHT,
buildroot_layout=cbuildbot_launch.BUILDROOT_BUILDROOT_LAYOUT,
branch="branchA",
)
cbuildbot_launch.CleanBuildRoot(
self.root, self.mock_repo, self.cache, build_state
)
new_summary = cbuildbot_launch.GetLastBuildState(self.root)
self.assertEqual(new_summary.buildroot_layout, 2)
self.assertEqual(new_summary.branch, "branchA")
# Same cache creation timestamp is rewritten to state.
self.assertEqual(new_summary.distfiles_ts, seed_distfiles_ts)
self.assertEqual(new_summary, build_state)
self.assertExists(self.repo)
self.assertExists(self.chroot)
self.assertExists(self.general)
self.assertExists(self.distfiles)
self.assertExists(self.previous_build_state)
def testBuildrootDistfilesCacheExpired(self) -> None:
"""Test CleanBuildRoot when the distfiles cache is too old."""
old_build_state = build_summary.BuildSummary(
status=constants.BUILDER_STATUS_PASSED,
buildroot_layout=2,
branch="branchA",
distfiles_ts=100.0,
)
self.populateBuildroot(previous_build_state=old_build_state.to_json())
self.mock_repo.branch = "branchA"
build_state = build_summary.BuildSummary(
status=constants.BUILDER_STATUS_INFLIGHT,
buildroot_layout=cbuildbot_launch.BUILDROOT_BUILDROOT_LAYOUT,
branch="branchA",
)
cbuildbot_launch.CleanBuildRoot(
self.root, self.mock_repo, self.cache, build_state
)
new_summary = cbuildbot_launch.GetLastBuildState(self.root)
self.assertEqual(new_summary.buildroot_layout, 2)
self.assertEqual(new_summary.branch, "branchA")
self.assertIsNotNone(new_summary.distfiles_ts)
self.assertEqual(new_summary, build_state)
self.assertExists(self.repo)
self.assertExists(self.chroot)
self.assertExists(self.general)
self.assertNotExists(self.distfiles)
self.assertExists(self.previous_build_state)
def testRootOwnedCache(self) -> None:
"""Test CleanBuildRoot with no history."""
seed_distfiles_ts = time.time() - 60
old_build_state = build_summary.BuildSummary(
status=constants.BUILDER_STATUS_PASSED,
buildroot_layout=2,
branch="branchA",
distfiles_ts=seed_distfiles_ts,
)
self.populateBuildroot(previous_build_state=old_build_state.to_json())
self.mock_repo.branch = "branchA"
osutils.Chown(self.cache, "root", "root")
build_state = build_summary.BuildSummary(
status=constants.BUILDER_STATUS_INFLIGHT,
buildroot_layout=cbuildbot_launch.BUILDROOT_BUILDROOT_LAYOUT,
branch="branchA",
)
cbuildbot_launch.CleanBuildRoot(
self.root, self.mock_repo, self.cache, build_state
)
new_summary = cbuildbot_launch.GetLastBuildState(self.root)
self.assertEqual(new_summary.buildroot_layout, 2)
self.assertEqual(new_summary.branch, "branchA")
# Same cache creation timestamp is rewritten to state.
self.assertEqual(new_summary.distfiles_ts, seed_distfiles_ts)
self.assertEqual(new_summary, build_state)
self.assertExists(self.repo)
self.assertExists(self.chroot)
self.assertExists(self.general)
self.assertNotExists(self.distfiles)
self.assertExists(self.previous_build_state)
def testBuildrootRepoCleanFailure(self) -> None:
"""Test CleanBuildRoot with repo checkout failure."""
old_build_state = build_summary.BuildSummary(
status=constants.BUILDER_STATUS_PASSED,
buildroot_layout=1,
branch="branchA",
)
self.populateBuildroot(previous_build_state=old_build_state.to_json())
self.mock_repo.branch = "branchA"
self.mock_repo.BuildRootGitCleanup.side_effect = Exception
build_state = build_summary.BuildSummary(
status=constants.BUILDER_STATUS_INFLIGHT,
buildroot_layout=cbuildbot_launch.BUILDROOT_BUILDROOT_LAYOUT,
branch="branchA",
)
cbuildbot_launch.CleanBuildRoot(
self.root, self.mock_repo, self.cache, build_state
)
new_summary = cbuildbot_launch.GetLastBuildState(self.root)
self.assertEqual(new_summary.buildroot_layout, 2)
self.assertEqual(new_summary.branch, "branchA")
self.assertIsNotNone(new_summary.distfiles_ts)
self.assertEqual(new_summary, build_state)
self.assertNotExists(self.repo)
self.assertNotExists(self.chroot)
self.assertNotExists(self.general)
self.assertNotExists(self.distfiles)
self.assertExists(self.previous_build_state)
def testGetCurrentBuildStateNoArgs(self) -> None:
"""Tests GetCurrentBuildState without arguments."""
options = cbuildbot_launch.PreParseArguments(
["--buildroot", self.root, "config"]
)
state = cbuildbot_launch.GetCurrentBuildState(options, "main")
expected_state = build_summary.BuildSummary(
status=constants.BUILDER_STATUS_INFLIGHT,
buildroot_layout=2,
branch="main",
)
self.assertEqual(state, expected_state)
def testGetCurrentBuildStateHasArgs(self) -> None:
"""Tests GetCurrentBuildState with arguments."""
options = cbuildbot_launch.PreParseArguments(
[
"--buildroot",
self.root,
"--buildnumber",
"20",
"--master-build-id",
"50",
"config",
]
)
state = cbuildbot_launch.GetCurrentBuildState(options, "branchA")
expected_state = build_summary.BuildSummary(
build_number=20,
master_build_id=50,
status=constants.BUILDER_STATUS_INFLIGHT,
buildroot_layout=2,
branch="branchA",
)
self.assertEqual(state, expected_state)
def testGetCurrentBuildStateLayout(self) -> None:
"""Test that GetCurrentBuildState uses the current buildroot layout."""
# Change to a future version.
self.PatchObject(cbuildbot_launch, "BUILDROOT_BUILDROOT_LAYOUT", 22)
options = cbuildbot_launch.PreParseArguments(
["--buildroot", self.root, "config"]
)
state = cbuildbot_launch.GetCurrentBuildState(options, "branchA")
expected_state = build_summary.BuildSummary(
status=constants.BUILDER_STATUS_INFLIGHT,
buildroot_layout=22,
branch="branchA",
)
self.assertEqual(state, expected_state)
def testGetLastBuildStateNoFile(self) -> None:
"""Tests GetLastBuildState if the file is missing."""
osutils.SafeMakedirs(self.root)
state = cbuildbot_launch.GetLastBuildState(self.root)
self.assertEqual(state, build_summary.BuildSummary())
def testGetLastBuildStateBadFile(self) -> None:
"""Tests GetLastBuildState if the file contains invalid JSON."""
osutils.SafeMakedirs(self.root)
osutils.WriteFile(self.previous_build_state, "}}")
state = cbuildbot_launch.GetLastBuildState(self.root)
self.assertEqual(state, build_summary.BuildSummary())
def testGetLastBuildStateMissingBuildStatus(self) -> None:
"""Tests GetLastBuildState if the file doesn't have a valid status."""
osutils.SafeMakedirs(self.root)
osutils.WriteFile(self.previous_build_state, '{"build_number": "3"}')
state = cbuildbot_launch.GetLastBuildState(self.root)
self.assertEqual(state, build_summary.BuildSummary())
def testGetLastBuildStateGoodFile(self) -> None:
"""Tests GetLastBuildState on a good file."""
osutils.SafeMakedirs(self.root)
osutils.WriteFile(
self.previous_build_state,
'{"build_number": 1, "master_build_id": 3, "status": "pass"}',
)
state = cbuildbot_launch.GetLastBuildState(self.root)
self.assertEqual(
state,
build_summary.BuildSummary(
build_number=1, master_build_id=3, status="pass"
),
)
def testSetLastBuildState(self) -> None:
"""Verifies that SetLastBuildState writes to the expected file."""
osutils.SafeMakedirs(self.root)
old_state = build_summary.BuildSummary(
build_number=314,
master_build_id=2178,
status=constants.BUILDER_STATUS_PASSED,
)
cbuildbot_launch.SetLastBuildState(self.root, old_state)
saved_state = osutils.ReadFile(self.previous_build_state)
new_state = build_summary.BuildSummary()
new_state.from_json(saved_state)
self.assertEqual(old_state, new_state)