Build API: Adding setup board functionality
BUG=chromium:905026, b:128844647
TEST=run_tests
Change-Id: If828d4da8778a5456aa3ab74c79cf86c55b10faa
Reviewed-on: https://chromium-review.googlesource.com/1529330
Commit-Ready: Alex Klein <saklein@chromium.org>
Tested-by: Alex Klein <saklein@chromium.org>
Reviewed-by: Evan Hernandez <evanhernandez@chromium.org>
diff --git a/api/controller/sysroot_unittest.py b/api/controller/sysroot_unittest.py
new file mode 100644
index 0000000..d61fa74
--- /dev/null
+++ b/api/controller/sysroot_unittest.py
@@ -0,0 +1,188 @@
+# -*- 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.
+
+"""Sysroot controller tests."""
+
+from __future__ import print_function
+
+import os
+
+from chromite.api.controller import sysroot as sysroot_controller
+from chromite.api.gen.chromite.api import sysroot_pb2
+from chromite.lib import build_target_util
+from chromite.lib import cros_build_lib
+from chromite.lib import cros_test_lib
+from chromite.lib import osutils
+from chromite.lib import portage_util
+from chromite.lib import sysroot_lib
+from chromite.service import sysroot as sysroot_service
+
+
+class CreateTest(cros_test_lib.MockTestCase):
+ """Create function tests."""
+
+ def _InputProto(self, build_target=None, profile=None, replace=False,
+ current=False):
+ """Helper to build and input proto instance."""
+ proto = sysroot_pb2.SysrootCreateRequest()
+ if build_target:
+ proto.build_target.name = build_target
+ if profile:
+ proto.profile.name = profile
+ if replace:
+ proto.flags.replace = replace
+ if current:
+ proto.flags.chroot_current = current
+
+ return proto
+
+ def _OutputProto(self):
+ """Helper to build output proto instance."""
+ return sysroot_pb2.SysrootCreateResponse()
+
+ def testArgumentValidation(self):
+ """Test the input argument validation."""
+ # Error when no name provided.
+ in_proto = self._InputProto()
+ out_proto = self._OutputProto()
+ with self.assertRaises(cros_build_lib.DieSystemExit):
+ sysroot_controller.Create(in_proto, out_proto)
+
+ # Valid when board passed.
+ result = sysroot_lib.Sysroot('/sysroot/path')
+ patch = self.PatchObject(sysroot_service, 'Create', return_value=result)
+ in_proto = self._InputProto('board')
+ out_proto = self._OutputProto()
+ sysroot_controller.Create(in_proto, out_proto)
+ patch.assert_called_once()
+
+ def testArgumentHandling(self):
+ """Test the arguments get processed and passed correctly."""
+ sysroot_path = '/sysroot/path'
+
+ sysroot = sysroot_lib.Sysroot(sysroot_path)
+ create_patch = self.PatchObject(sysroot_service, 'Create',
+ return_value=sysroot)
+ target_patch = self.PatchObject(build_target_util, 'BuildTarget')
+ rc_patch = self.PatchObject(sysroot_service, 'SetupBoardRunConfig')
+
+ # Default values.
+ board = 'board'
+ profile = None
+ force = False
+ upgrade_chroot = True
+ in_proto = self._InputProto(build_target=board, profile=profile,
+ replace=force, current=not upgrade_chroot)
+ out_proto = self._OutputProto()
+ sysroot_controller.Create(in_proto, out_proto)
+
+ # Default value checks.
+ target_patch.assert_called_with(name=board, profile=profile)
+ rc_patch.assert_called_with(force=force, upgrade_chroot=upgrade_chroot)
+ self.assertEqual(board, out_proto.sysroot.build_target.name)
+ self.assertEqual(sysroot_path, out_proto.sysroot.path)
+
+ # Not default values.
+ create_patch.reset_mock()
+ board = 'board'
+ profile = 'profile'
+ force = True
+ upgrade_chroot = False
+ in_proto = self._InputProto(build_target=board, profile=profile,
+ replace=force, current=not upgrade_chroot)
+ out_proto = self._OutputProto()
+ sysroot_controller.Create(in_proto, out_proto)
+
+ # Not default value checks.
+ target_patch.assert_called_with(name=board, profile=profile)
+ rc_patch.assert_called_with(force=force, upgrade_chroot=upgrade_chroot)
+ self.assertEqual(board, out_proto.sysroot.build_target.name)
+ self.assertEqual(sysroot_path, out_proto.sysroot.path)
+
+
+class InstallToolchainTest(cros_test_lib.MockTempDirTestCase):
+ """Install toolchain function tests."""
+
+ def setUp(self):
+ self.PatchObject(cros_build_lib, 'IsInsideChroot', return_value=True)
+ self.board = 'board'
+ self.sysroot = os.path.join(self.tempdir, 'board')
+ self.invalid_sysroot = os.path.join(self.tempdir, 'invalid', 'sysroot')
+ osutils.SafeMakedirs(self.sysroot)
+
+ def _InputProto(self, build_target=None, sysroot_path=None,
+ compile_source=False):
+ """Helper to build and input proto instance."""
+ proto = sysroot_pb2.InstallToolchainRequest()
+ if build_target:
+ proto.sysroot.build_target.name = build_target
+ if sysroot_path:
+ proto.sysroot.path = sysroot_path
+ if compile_source:
+ proto.flags.compile_source = compile_source
+
+ return proto
+
+ def _OutputProto(self):
+ """Helper to build output proto instance."""
+ return sysroot_pb2.InstallToolchainResponse()
+
+ def testArgumentValidation(self):
+ """Test the argument validation."""
+ # Test errors on missing inputs.
+ out_proto = self._OutputProto()
+ # Both missing.
+ in_proto = self._InputProto()
+ with self.assertRaises(cros_build_lib.DieSystemExit):
+ sysroot_controller.InstallToolchain(in_proto, out_proto)
+
+ # Sysroot path missing.
+ in_proto = self._InputProto(build_target=self.board)
+ with self.assertRaises(cros_build_lib.DieSystemExit):
+ sysroot_controller.InstallToolchain(in_proto, out_proto)
+
+ # Build target name missing.
+ in_proto = self._InputProto(sysroot_path=self.sysroot)
+ with self.assertRaises(cros_build_lib.DieSystemExit):
+ sysroot_controller.InstallToolchain(in_proto, out_proto)
+
+ # Both provided, but invalid sysroot path.
+ in_proto = self._InputProto(build_target=self.board,
+ sysroot_path=self.invalid_sysroot)
+ with self.assertRaises(cros_build_lib.DieSystemExit):
+ sysroot_controller.InstallToolchain(in_proto, out_proto)
+
+ def testSuccessOutputHandling(self):
+ """Test the output is processed and recorded correctly."""
+ self.PatchObject(sysroot_service, 'InstallToolchain')
+ out_proto = self._OutputProto()
+ in_proto = self._InputProto(build_target=self.board,
+ sysroot_path=self.sysroot)
+
+ rc = sysroot_controller.InstallToolchain(in_proto, out_proto)
+ self.assertFalse(rc)
+ self.assertFalse(out_proto.failed_packages)
+
+
+ def testErrorOutputHandling(self):
+ """Test the error output is processed and recorded correctly."""
+ out_proto = self._OutputProto()
+ in_proto = self._InputProto(build_target=self.board,
+ sysroot_path=self.sysroot)
+
+ err_pkgs = ['cat/pkg', 'cat2/pkg2']
+ err_cpvs = [portage_util.SplitCPV(pkg, strict=False) for pkg in err_pkgs]
+ expected = [('cat', 'pkg'), ('cat2', 'pkg2')]
+ err = sysroot_lib.ToolchainInstallError('Error',
+ cros_build_lib.CommandResult(),
+ tc_info=err_cpvs)
+ self.PatchObject(sysroot_service, 'InstallToolchain', side_effect=err)
+
+ rc = sysroot_controller.InstallToolchain(in_proto, out_proto)
+ self.assertTrue(rc)
+ self.assertTrue(out_proto.failed_packages)
+ for package in out_proto.failed_packages:
+ cat_pkg = (package.category, package.package_name)
+ self.assertIn(cat_pkg, expected)