blob: d16028706213fb57c47392bd0981d5ea682b5364 [file] [log] [blame]
Alex Klein2966e302019-01-17 13:29:38 -07001# -*- coding: utf-8 -*-
2# Copyright 2019 The Chromium OS Authors. All rights reserved.
3# Use of this source code is governed by a BSD-style license that can be
4# found in the LICENSE file.
5
6"""Image service tests."""
7
8from __future__ import print_function
9
Alex Klein56355682019-02-07 10:36:54 -070010import mock
Alex Klein2966e302019-01-17 13:29:38 -070011import os
12
Alex Klein7107bdd2019-03-14 17:14:31 -060013from chromite.api.gen.chromite.api import image_pb2
David Burger13e06be2019-05-13 20:33:16 -060014from chromite.api.gen.chromiumos import common_pb2
Alex Kleinb7cdbe62019-02-22 11:41:32 -070015from chromite.api.controller import image as image_controller
Alex Klein56355682019-02-07 10:36:54 -070016from chromite.lib import constants
Alex Klein4f0eb432019-05-02 13:56:04 -060017from chromite.lib import cros_build_lib
Alex Klein2966e302019-01-17 13:29:38 -070018from chromite.lib import cros_test_lib
19from chromite.lib import osutils
Alex Kleinb7cdbe62019-02-22 11:41:32 -070020from chromite.service import image as image_service
Alex Klein2966e302019-01-17 13:29:38 -070021
22
Alex Klein1bcd9882019-03-19 13:25:24 -060023class CreateTest(cros_test_lib.MockTempDirTestCase):
Alex Klein56355682019-02-07 10:36:54 -070024 """Create image tests."""
25
Alex Klein21b95022019-05-09 14:14:46 -060026 def _GetRequest(self, board=None, types=None, version=None, builder_path=None,
27 disable_rootfs_verification=False):
28 """Helper to build a request instance."""
29 return image_pb2.CreateImageRequest(
30 build_target={'name': board},
31 image_types=types,
32 disable_rootfs_verification=disable_rootfs_verification,
33 version=version,
34 builder_path=builder_path,
35 )
36
37 def _GetResponse(self):
38 """Helper to build an empty response instance."""
39 return image_pb2.CreateImageResult()
40
Alex Klein56355682019-02-07 10:36:54 -070041 def testArgumentValidation(self):
42 """Test the argument validation."""
43 input_proto = image_pb2.CreateImageRequest()
44 output_proto = image_pb2.CreateImageResult()
45
46 # No board should cause it to fail.
Alex Klein4f0eb432019-05-02 13:56:04 -060047 with self.assertRaises(cros_build_lib.DieSystemExit):
Alex Kleinb7cdbe62019-02-22 11:41:32 -070048 image_controller.Create(input_proto, output_proto)
Alex Klein56355682019-02-07 10:36:54 -070049
Alex Klein21b95022019-05-09 14:14:46 -060050 def testNoTypeSpecified(self):
51 """Test the image type default."""
52 request = self._GetRequest(board='board')
53 response = self._GetResponse()
54
Alex Klein1bcd9882019-03-19 13:25:24 -060055 # Failed result to avoid the success handling logic.
56 result = image_service.BuildResult(1, [])
57 build_patch = self.PatchObject(image_service, 'Build', return_value=result)
Alex Klein56355682019-02-07 10:36:54 -070058
Alex Klein21b95022019-05-09 14:14:46 -060059 image_controller.Create(request, response)
Alex Klein56355682019-02-07 10:36:54 -070060 build_patch.assert_called_with(images=[constants.IMAGE_TYPE_BASE],
Alex Klein21b95022019-05-09 14:14:46 -060061 board='board', config=mock.ANY)
Alex Klein56355682019-02-07 10:36:54 -070062
Alex Klein21b95022019-05-09 14:14:46 -060063 def testSingleTypeSpecified(self):
64 """Test it's properly using a specified type."""
65 request = self._GetRequest(board='board', types=[common_pb2.DEV])
66 response = self._GetResponse()
67
68 # Failed result to avoid the success handling logic.
69 result = image_service.BuildResult(1, [])
70 build_patch = self.PatchObject(image_service, 'Build', return_value=result)
71
72 image_controller.Create(request, response)
Alex Klein56355682019-02-07 10:36:54 -070073 build_patch.assert_called_with(images=[constants.IMAGE_TYPE_DEV],
Alex Klein21b95022019-05-09 14:14:46 -060074 board='board', config=mock.ANY)
Alex Klein56355682019-02-07 10:36:54 -070075
Alex Klein21b95022019-05-09 14:14:46 -060076 def testMultipleAndImpliedTypes(self):
77 """Test multiple types and implied type handling."""
78 # The TEST_VM type should force it to build the test image.
79 types = [common_pb2.BASE, common_pb2.TEST_VM]
80 expected_images = [constants.IMAGE_TYPE_BASE, constants.IMAGE_TYPE_TEST]
81
82 request = self._GetRequest(board='board', types=types)
83 response = self._GetResponse()
84
85 # Failed result to avoid the success handling logic.
86 result = image_service.BuildResult(1, [])
87 build_patch = self.PatchObject(image_service, 'Build', return_value=result)
88
89 image_controller.Create(request, response)
90 build_patch.assert_called_with(images=expected_images, board='board',
Alex Klein56355682019-02-07 10:36:54 -070091 config=mock.ANY)
92
Alex Klein1bcd9882019-03-19 13:25:24 -060093 def testFailedPackageHandling(self):
94 """Test failed packages are populated correctly."""
95 result = image_service.BuildResult(1, ['foo/bar', 'cat/pkg'])
96 expected_packages = [('foo', 'bar'), ('cat', 'pkg')]
97 self.PatchObject(image_service, 'Build', return_value=result)
98
99 input_proto = image_pb2.CreateImageRequest()
100 input_proto.build_target.name = 'board'
101 output_proto = image_pb2.CreateImageResult()
102
103 image_controller.Create(input_proto, output_proto)
104 for package in output_proto.failed_packages:
105 self.assertIn((package.category, package.package_name), expected_packages)
106
Alex Kleinb7cdbe62019-02-22 11:41:32 -0700107
Alex Klein4f0eb432019-05-02 13:56:04 -0600108class CreateVmTest(cros_test_lib.MockTestCase):
109 """CreateVm tests."""
110
111 def _GetInput(self, board=None, image_type=None):
112 """Helper to create an input proto instance."""
113 # pylint: disable=protected-access
114
115 return image_pb2.CreateVmRequest(
116 image={'build_target': {'name': board}, 'type': image_type})
117
118 def _GetOutput(self):
119 """Helper to create an empty output proto instance."""
120 return image_pb2.CreateVmResponse()
121
122 def testNoArgsFails(self):
123 """Make sure it fails with no arguments."""
124 request = self._GetInput()
125 response = self._GetOutput()
126
127 with self.assertRaises(cros_build_lib.DieSystemExit):
128 image_controller.CreateVm(request, response)
129
130 def testNoBuildTargetFails(self):
131 """Make sure it fails with no build target."""
David Burger13e06be2019-05-13 20:33:16 -0600132 request = self._GetInput(image_type=common_pb2.TEST)
Alex Klein4f0eb432019-05-02 13:56:04 -0600133 response = self._GetOutput()
134
135 with self.assertRaises(cros_build_lib.DieSystemExit):
136 image_controller.CreateVm(request, response)
137
138 def testNoTypeFails(self):
139 """Make sure it fails with no build target."""
140 request = self._GetInput(board='board')
141 response = self._GetOutput()
142
143 with self.assertRaises(cros_build_lib.DieSystemExit):
144 image_controller.CreateVm(request, response)
145
146 def testTestImage(self):
147 """Make sure the test image identification works properly."""
David Burger13e06be2019-05-13 20:33:16 -0600148 request = self._GetInput(board='board', image_type=common_pb2.TEST)
Alex Klein4f0eb432019-05-02 13:56:04 -0600149 response = self._GetOutput()
150 create_patch = self.PatchObject(image_service, 'CreateVm',
151 return_value='/vm/path')
152
153 image_controller.CreateVm(request, response)
154
155 create_patch.assert_called_once_with('board', chroot=mock.ANY, is_test=True)
156
157 def testNonTestImage(self):
158 """Make sure the test image identification works properly."""
David Burger13e06be2019-05-13 20:33:16 -0600159 request = self._GetInput(board='board', image_type=common_pb2.BASE)
Alex Klein4f0eb432019-05-02 13:56:04 -0600160 response = self._GetOutput()
161 create_patch = self.PatchObject(image_service, 'CreateVm',
162 return_value='/vm/path')
163
164 image_controller.CreateVm(request, response)
165
166 create_patch.assert_called_once_with('board', chroot=mock.ANY,
167 is_test=False)
168
169
Alex Klein2966e302019-01-17 13:29:38 -0700170class ImageTest(cros_test_lib.MockTempDirTestCase):
171 """Image service tests."""
172
173 def setUp(self):
174 self.image_path = os.path.join(self.tempdir, 'image.bin')
175 self.board = 'board'
176 self.result_directory = os.path.join(self.tempdir, 'results')
177
178 osutils.SafeMakedirs(self.result_directory)
179 osutils.Touch(self.image_path)
180
181 def testTestArgumentValidation(self):
182 """Test function argument validation tests."""
Alex Kleinb7cdbe62019-02-22 11:41:32 -0700183 self.PatchObject(image_service, 'Test', return_value=True)
Alex Klein2966e302019-01-17 13:29:38 -0700184 input_proto = image_pb2.TestImageRequest()
185 output_proto = image_pb2.TestImageResult()
186
187 # Nothing provided.
Alex Klein4f0eb432019-05-02 13:56:04 -0600188 with self.assertRaises(cros_build_lib.DieSystemExit):
Alex Kleinb7cdbe62019-02-22 11:41:32 -0700189 image_controller.Test(input_proto, output_proto)
Alex Klein2966e302019-01-17 13:29:38 -0700190
191 # Just one argument.
192 input_proto.build_target.name = self.board
Alex Klein4f0eb432019-05-02 13:56:04 -0600193 with self.assertRaises(cros_build_lib.DieSystemExit):
Alex Kleinb7cdbe62019-02-22 11:41:32 -0700194 image_controller.Test(input_proto, output_proto)
Alex Klein2966e302019-01-17 13:29:38 -0700195
196 # Two arguments provided.
197 input_proto.result.directory = self.result_directory
Alex Klein4f0eb432019-05-02 13:56:04 -0600198 with self.assertRaises(cros_build_lib.DieSystemExit):
Alex Kleinb7cdbe62019-02-22 11:41:32 -0700199 image_controller.Test(input_proto, output_proto)
Alex Klein2966e302019-01-17 13:29:38 -0700200
201 # Invalid image path.
202 input_proto.image.path = '/invalid/image/path'
Alex Klein4f0eb432019-05-02 13:56:04 -0600203 with self.assertRaises(cros_build_lib.DieSystemExit):
Alex Kleinb7cdbe62019-02-22 11:41:32 -0700204 image_controller.Test(input_proto, output_proto)
Alex Klein2966e302019-01-17 13:29:38 -0700205
206 # All valid arguments.
207 input_proto.image.path = self.image_path
Alex Kleinb7cdbe62019-02-22 11:41:32 -0700208 image_controller.Test(input_proto, output_proto)
Alex Klein2966e302019-01-17 13:29:38 -0700209
210 def testTestOutputHandling(self):
211 """Test function output tests."""
212 input_proto = image_pb2.TestImageRequest()
213 input_proto.image.path = self.image_path
214 input_proto.build_target.name = self.board
215 input_proto.result.directory = self.result_directory
216 output_proto = image_pb2.TestImageResult()
217
Alex Kleinb7cdbe62019-02-22 11:41:32 -0700218 self.PatchObject(image_service, 'Test', return_value=True)
219 image_controller.Test(input_proto, output_proto)
Alex Klein2966e302019-01-17 13:29:38 -0700220 self.assertTrue(output_proto.success)
221
Alex Kleinb7cdbe62019-02-22 11:41:32 -0700222 self.PatchObject(image_service, 'Test', return_value=False)
223 image_controller.Test(input_proto, output_proto)
Alex Klein2966e302019-01-17 13:29:38 -0700224 self.assertFalse(output_proto.success)