build api push_image endpoint
BUG=None
TEST=run_tests and call_scripts
Change-Id: If309250d50b47c1ed306c330c309a9524257cb08
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/chromite/+/2570241
Commit-Queue: Jack Neus <jackneus@google.com>
Commit-Queue: George Engelbrecht <engeg@google.com>
Tested-by: Jack Neus <jackneus@google.com>
Tested-by: George Engelbrecht <engeg@google.com>
Reviewed-by: George Engelbrecht <engeg@google.com>
Reviewed-by: Alex Klein <saklein@chromium.org>
diff --git a/api/controller/image_unittest.py b/api/controller/image_unittest.py
index 56de3c3..f5b4f9a 100644
--- a/api/controller/image_unittest.py
+++ b/api/controller/image_unittest.py
@@ -16,11 +16,13 @@
from chromite.api.controller import image as image_controller
from chromite.api.gen.chromite.api import image_pb2
from chromite.api.gen.chromiumos import common_pb2
+from chromite.api.gen.chromite.api import sysroot_pb2
from chromite.lib import constants
from chromite.lib import cros_build_lib
from chromite.lib import cros_test_lib
from chromite.lib import image_lib
from chromite.lib import osutils
+from chromite.scripts import pushimage
from chromite.service import image as image_service
@@ -30,7 +32,11 @@
def setUp(self):
self.response = image_pb2.CreateImageResult()
- def _GetRequest(self, board=None, types=None, version=None, builder_path=None,
+ def _GetRequest(self,
+ board=None,
+ types=None,
+ version=None,
+ builder_path=None,
disable_rootfs_verification=False):
"""Helper to build a request instance."""
return image_pb2.CreateImageRequest(
@@ -84,8 +90,8 @@
build_patch = self.PatchObject(image_service, 'Build', return_value=result)
image_controller.Create(request, self.response, self.api_config)
- build_patch.assert_called_with(images=[constants.IMAGE_TYPE_BASE],
- board='board', config=mock.ANY)
+ build_patch.assert_called_with(
+ images=[constants.IMAGE_TYPE_BASE], board='board', config=mock.ANY)
def testSingleTypeSpecified(self):
"""Test it's properly using a specified type."""
@@ -96,8 +102,8 @@
build_patch = self.PatchObject(image_service, 'Build', return_value=result)
image_controller.Create(request, self.response, self.api_config)
- build_patch.assert_called_with(images=[constants.IMAGE_TYPE_DEV],
- board='board', config=mock.ANY)
+ build_patch.assert_called_with(
+ images=[constants.IMAGE_TYPE_DEV], board='board', config=mock.ANY)
def testMultipleAndImpliedTypes(self):
"""Test multiple types and implied type handling."""
@@ -112,8 +118,8 @@
build_patch = self.PatchObject(image_service, 'Build', return_value=result)
image_controller.Create(request, self.response, self.api_config)
- build_patch.assert_called_with(images=expected_images, board='board',
- config=mock.ANY)
+ build_patch.assert_called_with(
+ images=expected_images, board='board', config=mock.ANY)
def testFailedPackageHandling(self):
"""Test failed packages are populated correctly."""
@@ -320,3 +326,111 @@
self.PatchObject(image_service, 'Test', return_value=False)
image_controller.Test(input_proto, output_proto, self.api_config)
self.assertFalse(output_proto.success)
+
+
+class PushImageTest(cros_test_lib.MockTestCase, api_config.ApiConfigMixin):
+ """Push image test."""
+
+ def setUp(self):
+ self.response = image_pb2.PushImageResponse()
+
+ def _GetRequest(
+ self,
+ gs_image_dir='gs://chromeos-image-archive/atlas-release/R89-13604.0.0',
+ build_target_name='atlas',
+ profile='foo',
+ sign_types=None,
+ dryrun=True):
+ return image_pb2.PushImageRequest(
+ gs_image_dir=gs_image_dir,
+ sysroot=sysroot_pb2.Sysroot(
+ build_target=common_pb2.BuildTarget(name=build_target_name)),
+ profile=common_pb2.Profile(name=profile),
+ sign_types=sign_types,
+ dryrun=dryrun)
+
+ def testValidateOnly(self):
+ """Check that a validate only call does not execute any logic."""
+ patch = self.PatchObject(pushimage, 'PushImage')
+
+ req = self._GetRequest(sign_types=[
+ common_pb2.IMAGE_TYPE_RECOVERY, common_pb2.IMAGE_TYPE_FACTORY,
+ common_pb2.IMAGE_TYPE_FIRMWARE, common_pb2.IMAGE_TYPE_ACCESSORY_USBPD,
+ common_pb2.IMAGE_TYPE_ACCESSORY_RWSIG, common_pb2.IMAGE_TYPE_BASE,
+ common_pb2.IMAGE_TYPE_CR50_FIRMWARE
+ ])
+ res = image_controller.PushImage(req, self.response,
+ self.validate_only_config)
+ patch.assert_not_called()
+ self.assertEqual(res, controller.RETURN_CODE_VALID_INPUT)
+
+ def testValidateOnlyInvalid(self):
+ """Check that validate call rejects invalid sign types."""
+ patch = self.PatchObject(pushimage, 'PushImage')
+
+ # Pass unsupported image type.
+ req = self._GetRequest(sign_types=[common_pb2.IMAGE_TYPE_DLC])
+ res = image_controller.PushImage(req, self.response,
+ self.validate_only_config)
+ patch.assert_not_called()
+ self.assertEqual(res, controller.RETURN_CODE_INVALID_INPUT)
+
+ def testMockCall(self):
+ """Test that mock call does not execute any logic, returns mocked value."""
+ patch = self.PatchObject(pushimage, 'PushImage')
+
+ rc = image_controller.PushImage(self._GetRequest(), self.response,
+ self.mock_call_config)
+ patch.assert_not_called()
+ self.assertEqual(controller.RETURN_CODE_SUCCESS, rc)
+
+ def testMockError(self):
+ """Test that mock call does not execute any logic, returns error."""
+ patch = self.PatchObject(pushimage, 'PushImage')
+
+ rc = image_controller.PushImage(self._GetRequest(), self.response,
+ self.mock_error_config)
+ patch.assert_not_called()
+ self.assertEqual(controller.RETURN_CODE_COMPLETED_UNSUCCESSFULLY, rc)
+
+ def testNoBuildTarget(self):
+ """Test no build target given fails."""
+ request = self._GetRequest(build_target_name='')
+
+ # No build target should cause it to fail.
+ with self.assertRaises(cros_build_lib.DieSystemExit):
+ image_controller.PushImage(request, self.response, self.api_config)
+
+ def testNoGsImageDir(self):
+ """Test no image dir given fails."""
+ request = self._GetRequest(gs_image_dir='')
+
+ # No image dir should cause it to fail.
+ with self.assertRaises(cros_build_lib.DieSystemExit):
+ image_controller.PushImage(request, self.response, self.api_config)
+
+ def testCallCorrect(self):
+ """Check that a call is called with the correct parameters."""
+ patch = self.PatchObject(pushimage, 'PushImage')
+
+ request = self._GetRequest(
+ dryrun=False, profile='', sign_types=[common_pb2.IMAGE_TYPE_RECOVERY])
+ image_controller.PushImage(request, self.response, self.api_config)
+ patch.assert_called_with(
+ request.gs_image_dir,
+ request.sysroot.build_target.name,
+ dry_run=request.dryrun,
+ profile=request.profile.name,
+ sign_types=['recovery'])
+
+ def testCallSucceeds(self):
+ """Check that a (dry run) call is made successfully."""
+ request = self._GetRequest(sign_types=[common_pb2.IMAGE_TYPE_RECOVERY])
+ res = image_controller.PushImage(request, self.response, self.api_config)
+ self.assertEqual(res, controller.RETURN_CODE_SUCCESS)
+
+ def testCallFailsWithBadImageDir(self):
+ """Check that a (dry run) call fails when given a bad gs_image_dir."""
+ request = self._GetRequest(gs_image_dir='foo')
+ res = image_controller.PushImage(request, self.response, self.api_config)
+ self.assertEqual(res, controller.RETURN_CODE_COMPLETED_UNSUCCESSFULLY)