blob: 5d4aba6fc4d14417c866fd4ad1dc5379390b9dc6 [file] [log] [blame]
Alex Kleina2e42c42019-04-17 16:13:19 -06001# Copyright 2019 The Chromium OS Authors. All rights reserved.
2# Use of this source code is governed by a BSD-style license that can be
3# found in the LICENSE file.
4
5"""The test controller tests."""
6
Alex Klein9f915782020-02-14 23:15:09 +00007import contextlib
Mike Frysingeref94e4c2020-02-10 23:59:54 -05008import os
Mike Frysinger166fea02021-02-12 05:30:33 -05009from unittest import mock
Mike Frysingeref94e4c2020-02-10 23:59:54 -050010
Alex Klein231d2da2019-07-22 16:44:45 -060011from chromite.api import api_config
Alex Klein8cb365a2019-05-15 16:24:53 -060012from chromite.api import controller
Alex Kleina2e42c42019-04-17 16:13:19 -060013from chromite.api.controller import test as test_controller
Evan Hernandez4e388a52019-05-01 12:16:33 -060014from chromite.api.gen.chromiumos import common_pb2
Alex Kleina2e42c42019-04-17 16:13:19 -060015from chromite.api.gen.chromite.api import test_pb2
Andrew Lamb763e3be2021-07-27 17:22:02 -060016from chromite.api.gen.chromiumos.build.api import system_image_pb2
17from chromite.api.gen.chromiumos.build.api import portage_pb2
Andrew Lambd814afa2021-08-11 11:04:20 -060018from chromite.api.gen.chromiumos.config.payload import flat_config_pb2
19from chromite.api.gen.chromiumos.config.api import design_pb2
20from chromite.api.gen.chromiumos.config.api import design_id_pb2
Andrew Lamb763e3be2021-07-27 17:22:02 -060021from chromite.api.gen.chromiumos.test.api import coverage_rule_pb2
22from chromite.api.gen.chromiumos.test.api import dut_attribute_pb2
23from chromite.api.gen.chromiumos.test.api import test_suite_pb2
24from chromite.api.gen.chromiumos.test.plan import source_test_plan_pb2
Jack Neusc9707c32021-07-23 21:48:54 +000025from chromite.lib import build_target_lib
Evan Hernandeze1e05d32019-07-19 12:32:18 -060026from chromite.lib import chroot_lib
Alex Kleina2e42c42019-04-17 16:13:19 -060027from chromite.lib import cros_build_lib
28from chromite.lib import cros_test_lib
Evan Hernandezdc3f0bb2019-06-06 12:46:52 -060029from chromite.lib import image_lib
Alex Kleina2e42c42019-04-17 16:13:19 -060030from chromite.lib import osutils
David Wellingc1433c22021-06-25 16:29:48 +000031from chromite.lib import sysroot_lib
Alex Klein18a60af2020-06-11 12:08:47 -060032from chromite.lib.parser import package_info
Evan Hernandezdc3f0bb2019-06-06 12:46:52 -060033from chromite.scripts import cros_set_lsb_release
34from chromite.service import test as test_service
Andrew Lamb763e3be2021-07-27 17:22:02 -060035from chromite.third_party.google.protobuf import json_format
Mike Frysingere652ba12019-09-08 00:57:43 -040036from chromite.utils import key_value_store
Alex Kleina2e42c42019-04-17 16:13:19 -060037
38
Michael Mortensen8ca4d3b2019-11-27 09:35:22 -070039class DebugInfoTestTest(cros_test_lib.MockTempDirTestCase,
40 api_config.ApiConfigMixin):
41 """Tests for the DebugInfoTest function."""
42
43 def setUp(self):
44 self.board = 'board'
45 self.chroot_path = os.path.join(self.tempdir, 'chroot')
46 self.sysroot_path = '/build/board'
47 self.full_sysroot_path = os.path.join(self.chroot_path,
48 self.sysroot_path.lstrip(os.sep))
49 osutils.SafeMakedirs(self.full_sysroot_path)
50
51 def _GetInput(self, sysroot_path=None, build_target=None):
52 """Helper to build an input message instance."""
53 proto = test_pb2.DebugInfoTestRequest()
54 if sysroot_path:
55 proto.sysroot.path = sysroot_path
56 if build_target:
57 proto.sysroot.build_target.name = build_target
58 return proto
59
60 def _GetOutput(self):
61 """Helper to get an empty output message instance."""
62 return test_pb2.DebugInfoTestResponse()
63
64 def testValidateOnly(self):
65 """Sanity check that a validate only call does not execute any logic."""
66 patch = self.PatchObject(test_service, 'DebugInfoTest')
67 input_msg = self._GetInput(sysroot_path=self.full_sysroot_path)
68 test_controller.DebugInfoTest(input_msg, self._GetOutput(),
69 self.validate_only_config)
70 patch.assert_not_called()
71
Michael Mortensen85d38402019-12-12 09:50:29 -070072 def testMockError(self):
73 """Test mock error call does not execute any logic, returns error."""
74 patch = self.PatchObject(test_service, 'DebugInfoTest')
75
76 input_msg = self._GetInput(sysroot_path=self.full_sysroot_path)
77 rc = test_controller.DebugInfoTest(input_msg, self._GetOutput(),
78 self.mock_error_config)
79 patch.assert_not_called()
80 self.assertEqual(controller.RETURN_CODE_COMPLETED_UNSUCCESSFULLY, rc)
81
82 def testMockCall(self):
83 """Test mock call does not execute any logic, returns success."""
84 patch = self.PatchObject(test_service, 'DebugInfoTest')
85
86 input_msg = self._GetInput(sysroot_path=self.full_sysroot_path)
87 rc = test_controller.DebugInfoTest(input_msg, self._GetOutput(),
88 self.mock_call_config)
89 patch.assert_not_called()
90 self.assertEqual(controller.RETURN_CODE_SUCCESS, rc)
91
Michael Mortensen8ca4d3b2019-11-27 09:35:22 -070092 def testNoBuildTargetNoSysrootFails(self):
93 """Test missing build target name and sysroot path fails."""
94 input_msg = self._GetInput()
95 output_msg = self._GetOutput()
96 with self.assertRaises(cros_build_lib.DieSystemExit):
97 test_controller.DebugInfoTest(input_msg, output_msg, self.api_config)
98
99 def testDebugInfoTest(self):
100 """Call DebugInfoTest with valid sysroot_path."""
101 request = self._GetInput(sysroot_path=self.full_sysroot_path)
102
103 test_controller.DebugInfoTest(request, self._GetOutput(), self.api_config)
104
105
Alex Klein231d2da2019-07-22 16:44:45 -0600106class BuildTargetUnitTestTest(cros_test_lib.MockTempDirTestCase,
107 api_config.ApiConfigMixin):
Alex Kleina2e42c42019-04-17 16:13:19 -0600108 """Tests for the UnitTest function."""
109
Navil Perezc0b29a82020-07-07 14:17:48 +0000110 def _GetInput(self,
111 board=None,
112 result_path=None,
113 chroot_path=None,
114 cache_dir=None,
115 empty_sysroot=None,
116 packages=None,
Alex Kleinb64e5f82020-09-23 10:55:31 -0600117 blocklist=None):
Alex Kleina2e42c42019-04-17 16:13:19 -0600118 """Helper to build an input message instance."""
Navil Perezc0b29a82020-07-07 14:17:48 +0000119 formatted_packages = []
120 for pkg in packages or []:
121 formatted_packages.append({
122 'category': pkg.category,
123 'package_name': pkg.package
124 })
Alex Kleinb64e5f82020-09-23 10:55:31 -0600125 formatted_blocklist = []
126 for pkg in blocklist or []:
127 formatted_blocklist.append({'category': pkg.category,
Alex Kleinf2674462019-05-16 16:47:24 -0600128 'package_name': pkg.package})
129
Alex Kleina2e42c42019-04-17 16:13:19 -0600130 return test_pb2.BuildTargetUnitTestRequest(
131 build_target={'name': board}, result_path=result_path,
Alex Kleinfa6ebdc2019-05-10 10:57:31 -0600132 chroot={'path': chroot_path, 'cache_dir': cache_dir},
Alex Kleinf2674462019-05-16 16:47:24 -0600133 flags={'empty_sysroot': empty_sysroot},
Alex Klein64ac34c2020-09-23 10:21:33 -0600134 packages=formatted_packages,
Alex Klein157caf42021-07-01 14:36:43 -0600135 package_blocklist=formatted_blocklist,
Alex Kleina2e42c42019-04-17 16:13:19 -0600136 )
137
138 def _GetOutput(self):
139 """Helper to get an empty output message instance."""
140 return test_pb2.BuildTargetUnitTestResponse()
141
Alex Klein231d2da2019-07-22 16:44:45 -0600142 def testValidateOnly(self):
143 """Sanity check that a validate only call does not execute any logic."""
144 patch = self.PatchObject(test_service, 'BuildTargetUnitTest')
145
146 input_msg = self._GetInput(board='board', result_path=self.tempdir)
147 test_controller.BuildTargetUnitTest(input_msg, self._GetOutput(),
148 self.validate_only_config)
149 patch.assert_not_called()
150
Michael Mortensen82cd62d2019-12-01 14:58:54 -0700151 def testMockCall(self):
152 """Test that a mock call does not execute logic, returns mocked value."""
153 patch = self.PatchObject(test_service, 'BuildTargetUnitTest')
154
155 input_msg = self._GetInput(board='board', result_path=self.tempdir)
156 response = self._GetOutput()
157 test_controller.BuildTargetUnitTest(input_msg, response,
158 self.mock_call_config)
159 patch.assert_not_called()
160 self.assertEqual(response.tarball_path,
161 os.path.join(input_msg.result_path, 'unit_tests.tar'))
162
163 def testMockError(self):
Michael Mortensen85d38402019-12-12 09:50:29 -0700164 """Test that a mock error does not execute logic, returns error."""
Michael Mortensen82cd62d2019-12-01 14:58:54 -0700165 patch = self.PatchObject(test_service, 'BuildTargetUnitTest')
166
167 input_msg = self._GetInput(board='board', result_path=self.tempdir)
168 response = self._GetOutput()
169 rc = test_controller.BuildTargetUnitTest(input_msg, response,
170 self.mock_error_config)
171 patch.assert_not_called()
172 self.assertEqual(controller.RETURN_CODE_UNSUCCESSFUL_RESPONSE_AVAILABLE, rc)
173 self.assertTrue(response.failed_packages)
174 self.assertEqual(response.failed_packages[0].category, 'foo')
175 self.assertEqual(response.failed_packages[0].package_name, 'bar')
176 self.assertEqual(response.failed_packages[1].category, 'cat')
177 self.assertEqual(response.failed_packages[1].package_name, 'pkg')
178
Alex Kleina2e42c42019-04-17 16:13:19 -0600179 def testNoArgumentFails(self):
180 """Test no arguments fails."""
181 input_msg = self._GetInput()
182 output_msg = self._GetOutput()
183 with self.assertRaises(cros_build_lib.DieSystemExit):
Alex Klein231d2da2019-07-22 16:44:45 -0600184 test_controller.BuildTargetUnitTest(input_msg, output_msg,
185 self.api_config)
Alex Kleina2e42c42019-04-17 16:13:19 -0600186
187 def testNoBuildTargetFails(self):
188 """Test missing build target name fails."""
189 input_msg = self._GetInput(result_path=self.tempdir)
190 output_msg = self._GetOutput()
191 with self.assertRaises(cros_build_lib.DieSystemExit):
Alex Klein231d2da2019-07-22 16:44:45 -0600192 test_controller.BuildTargetUnitTest(input_msg, output_msg,
193 self.api_config)
Alex Kleina2e42c42019-04-17 16:13:19 -0600194
195 def testNoResultPathFails(self):
196 """Test missing result path fails."""
197 # Missing result_path.
198 input_msg = self._GetInput(board='board')
199 output_msg = self._GetOutput()
200 with self.assertRaises(cros_build_lib.DieSystemExit):
Alex Klein231d2da2019-07-22 16:44:45 -0600201 test_controller.BuildTargetUnitTest(input_msg, output_msg,
202 self.api_config)
Alex Kleina2e42c42019-04-17 16:13:19 -0600203
Alex Klein64ac34c2020-09-23 10:21:33 -0600204 def testInvalidPackageFails(self):
205 """Test missing result path fails."""
206 # Missing result_path.
207 pkg = package_info.PackageInfo(package='bar')
208 input_msg = self._GetInput(board='board', result_path=self.tempdir,
209 packages=[pkg])
210 output_msg = self._GetOutput()
211 with self.assertRaises(cros_build_lib.DieSystemExit):
212 test_controller.BuildTargetUnitTest(input_msg, output_msg,
213 self.api_config)
214
Alex Kleina2e42c42019-04-17 16:13:19 -0600215 def testPackageBuildFailure(self):
216 """Test handling of raised BuildPackageFailure."""
217 tempdir = osutils.TempDir(base_dir=self.tempdir)
218 self.PatchObject(osutils, 'TempDir', return_value=tempdir)
219
220 pkgs = ['cat/pkg', 'foo/bar']
221 expected = [('cat', 'pkg'), ('foo', 'bar')]
Alex Kleina2e42c42019-04-17 16:13:19 -0600222
Alex Klein38c7d9e2019-05-08 09:31:19 -0600223 result = test_service.BuildTargetUnitTestResult(1, None)
Alex Kleinea0c89e2021-09-09 15:17:35 -0600224 result.failed_pkgs = [package_info.parse(p) for p in pkgs]
Alex Klein38c7d9e2019-05-08 09:31:19 -0600225 self.PatchObject(test_service, 'BuildTargetUnitTest', return_value=result)
Alex Kleina2e42c42019-04-17 16:13:19 -0600226
227 input_msg = self._GetInput(board='board', result_path=self.tempdir)
228 output_msg = self._GetOutput()
229
Alex Klein231d2da2019-07-22 16:44:45 -0600230 rc = test_controller.BuildTargetUnitTest(input_msg, output_msg,
231 self.api_config)
Alex Kleina2e42c42019-04-17 16:13:19 -0600232
Alex Klein8cb365a2019-05-15 16:24:53 -0600233 self.assertEqual(controller.RETURN_CODE_UNSUCCESSFUL_RESPONSE_AVAILABLE, rc)
Alex Kleina2e42c42019-04-17 16:13:19 -0600234 self.assertTrue(output_msg.failed_packages)
235 failed = []
236 for pi in output_msg.failed_packages:
237 failed.append((pi.category, pi.package_name))
Mike Frysinger678735c2019-09-28 18:23:28 -0400238 self.assertCountEqual(expected, failed)
Alex Kleina2e42c42019-04-17 16:13:19 -0600239
240 def testOtherBuildScriptFailure(self):
241 """Test build script failure due to non-package emerge error."""
242 tempdir = osutils.TempDir(base_dir=self.tempdir)
243 self.PatchObject(osutils, 'TempDir', return_value=tempdir)
244
Alex Klein38c7d9e2019-05-08 09:31:19 -0600245 result = test_service.BuildTargetUnitTestResult(1, None)
246 self.PatchObject(test_service, 'BuildTargetUnitTest', return_value=result)
Alex Kleina2e42c42019-04-17 16:13:19 -0600247
Alex Kleinf2674462019-05-16 16:47:24 -0600248 pkgs = ['foo/bar', 'cat/pkg']
Alex Kleinb64e5f82020-09-23 10:55:31 -0600249 blocklist = [package_info.SplitCPV(p, strict=False) for p in pkgs]
Alex Kleinfa6ebdc2019-05-10 10:57:31 -0600250 input_msg = self._GetInput(board='board', result_path=self.tempdir,
Alex Kleinb64e5f82020-09-23 10:55:31 -0600251 empty_sysroot=True, blocklist=blocklist)
Alex Kleina2e42c42019-04-17 16:13:19 -0600252 output_msg = self._GetOutput()
253
Alex Klein231d2da2019-07-22 16:44:45 -0600254 rc = test_controller.BuildTargetUnitTest(input_msg, output_msg,
255 self.api_config)
Alex Kleina2e42c42019-04-17 16:13:19 -0600256
Alex Klein8cb365a2019-05-15 16:24:53 -0600257 self.assertEqual(controller.RETURN_CODE_COMPLETED_UNSUCCESSFULLY, rc)
Alex Kleina2e42c42019-04-17 16:13:19 -0600258 self.assertFalse(output_msg.failed_packages)
Evan Hernandez4e388a52019-05-01 12:16:33 -0600259
Michael Mortensen82cd62d2019-12-01 14:58:54 -0700260 def testBuildTargetUnitTest(self):
261 """Test BuildTargetUnitTest successful call."""
Navil Perezc0b29a82020-07-07 14:17:48 +0000262 pkgs = ['foo/bar', 'cat/pkg']
Alex Klein18a60af2020-06-11 12:08:47 -0600263 packages = [package_info.SplitCPV(p, strict=False) for p in pkgs]
Navil Perezc0b29a82020-07-07 14:17:48 +0000264 input_msg = self._GetInput(
265 board='board', result_path=self.tempdir, packages=packages)
Michael Mortensen82cd62d2019-12-01 14:58:54 -0700266
267 result = test_service.BuildTargetUnitTestResult(0, None)
268 self.PatchObject(test_service, 'BuildTargetUnitTest', return_value=result)
269
270 tarball_result = os.path.join(input_msg.result_path, 'unit_tests.tar')
271 self.PatchObject(test_service, 'BuildTargetUnitTestTarball',
272 return_value=tarball_result)
273
274 response = self._GetOutput()
275 test_controller.BuildTargetUnitTest(input_msg, response,
276 self.api_config)
277 self.assertEqual(response.tarball_path,
278 os.path.join(input_msg.result_path, 'unit_tests.tar'))
279
Evan Hernandez4e388a52019-05-01 12:16:33 -0600280
Sean McAllister17eed8d2021-09-21 10:41:16 -0600281class DockerConstraintsTest(cros_test_lib.MockTestCase):
282 """Tests for Docker argument constraints."""
283
284 def assertValid(self, output):
285 return output is None
286
287 def assertInvalid(self, output):
288 return not self.assertValid(output)
289
290 def testValidDockerTag(self):
291 """Check logic for validating docker tag format."""
292 # pylint: disable=protected-access
293
294 invalid_tags = [
295 '.invalid-tag',
296 '-invalid-tag',
297 'invalid-tag;',
298 'invalid'*100,
299 ]
300
301 for tag in invalid_tags:
302 self.assertInvalid(test_controller._ValidDockerTag(tag))
303
304 valid_tags = [
305 'valid-tag',
306 'valid-tag-',
307 'valid.tag.',
308 ]
309
310 for tag in valid_tags:
311 self.assertValid(test_controller._ValidDockerTag(tag))
312
313
314 def testValidDockerLabelKey(self):
315 """Check logic for validating docker label key format."""
316 # pylint: disable=protected-access
317
318 invalid_keys = [
319 'Invalid-keY',
320 'Invalid-key',
321 'invalid-keY',
322 'iNVALID-KEy',
323 'invalid_key',
324 'invalid-key;',
325 ]
326
327 for key in invalid_keys:
328 self.assertInvalid(test_controller._ValidDockerLabelKey(key))
329
330 valid_keys = [
331 'chromeos.valid-key',
332 'chromeos.valid-key-2',
333 ]
334
335 for key in valid_keys:
336 self.assertValid(test_controller._ValidDockerLabelKey(key))
337
338
C Shapiro91af1ce2021-06-17 12:42:09 -0500339class BuildTestServiceContainers(cros_test_lib.MockTestCase,
David Wellingc1433c22021-06-25 16:29:48 +0000340 api_config.ApiConfigMixin):
C Shapiro91af1ce2021-06-17 12:42:09 -0500341 """Tests for the BuildTestServiceContainers function."""
342
343 def setUp(self):
344 self.request = test_pb2.BuildTestServiceContainersRequest(
345 chroot={'path': '/path/to/chroot'},
346 build_target={'name': 'build_target'},
David Wellingc1433c22021-06-25 16:29:48 +0000347 version='R93-14033.0.0',
C Shapiro91af1ce2021-06-17 12:42:09 -0500348 )
349
C Shapiro91af1ce2021-06-17 12:42:09 -0500350 def testSuccess(self):
351 """Check passing case with mocked cros_build_lib.run."""
352 patch = self.PatchObject(
353 cros_build_lib, 'run',
354 return_value=cros_build_lib.CommandResult(returncode=0))
355
356 response = test_pb2.BuildTestServiceContainersResponse()
357 test_controller.BuildTestServiceContainers(
358 self.request,
359 response,
360 self.api_config)
361 patch.assert_called()
362 for result in response.results:
363 self.assertEqual(result.WhichOneof('result'), 'success')
364
C Shapiro91af1ce2021-06-17 12:42:09 -0500365 def testFailure(self):
366 """Check failure case with mocked cros_build_lib.run."""
367 patch = self.PatchObject(
368 cros_build_lib, 'run',
369 return_value=cros_build_lib.CommandResult(returncode=1))
370
371 response = test_pb2.BuildTestServiceContainersResponse()
372 test_controller.BuildTestServiceContainers(
373 self.request,
374 response,
375 self.api_config)
376 patch.assert_called()
377 for result in response.results:
378 self.assertEqual(result.WhichOneof('result'), 'failure')
379
380
Michael Mortensen8ca4d3b2019-11-27 09:35:22 -0700381class ChromiteUnitTestTest(cros_test_lib.MockTestCase,
382 api_config.ApiConfigMixin):
383 """Tests for the ChromiteInfoTest function."""
384
385 def setUp(self):
386 self.board = 'board'
387 self.chroot_path = '/path/to/chroot'
388
389 def _GetInput(self, chroot_path=None):
390 """Helper to build an input message instance."""
391 proto = test_pb2.ChromiteUnitTestRequest(
392 chroot={'path': chroot_path},
393 )
394 return proto
395
396 def _GetOutput(self):
397 """Helper to get an empty output message instance."""
398 return test_pb2.ChromiteUnitTestResponse()
399
400 def testValidateOnly(self):
401 """Sanity check that a validate only call does not execute any logic."""
402 patch = self.PatchObject(cros_build_lib, 'run')
403
404 input_msg = self._GetInput(chroot_path=self.chroot_path)
405 test_controller.ChromiteUnitTest(input_msg, self._GetOutput(),
406 self.validate_only_config)
407 patch.assert_not_called()
408
Michael Mortensen7a860eb2019-12-03 20:25:15 -0700409 def testMockError(self):
410 """Test mock error call does not execute any logic, returns error."""
411 patch = self.PatchObject(cros_build_lib, 'run')
412
413 input_msg = self._GetInput(chroot_path=self.chroot_path)
414 rc = test_controller.ChromiteUnitTest(input_msg, self._GetOutput(),
415 self.mock_error_config)
416 patch.assert_not_called()
417 self.assertEqual(controller.RETURN_CODE_COMPLETED_UNSUCCESSFULLY, rc)
418
419 def testMockCall(self):
420 """Test mock call does not execute any logic, returns success."""
421 patch = self.PatchObject(cros_build_lib, 'run')
422
423 input_msg = self._GetInput(chroot_path=self.chroot_path)
424 rc = test_controller.ChromiteUnitTest(input_msg, self._GetOutput(),
425 self.mock_call_config)
426 patch.assert_not_called()
427 self.assertEqual(controller.RETURN_CODE_SUCCESS, rc)
428
Michael Mortensen8ca4d3b2019-11-27 09:35:22 -0700429 def testChromiteUnitTest(self):
430 """Call ChromiteUnitTest with mocked cros_build_lib.run."""
431 request = self._GetInput(chroot_path=self.chroot_path)
432 patch = self.PatchObject(
433 cros_build_lib, 'run',
434 return_value=cros_build_lib.CommandResult(returncode=0))
435
436 test_controller.ChromiteUnitTest(request, self._GetOutput(),
437 self.api_config)
438 patch.assert_called_once()
439
440
Alex Klein4bc8f4f2019-08-16 14:53:30 -0600441class CrosSigningTestTest(cros_test_lib.RunCommandTestCase,
442 api_config.ApiConfigMixin):
443 """CrosSigningTest tests."""
444
Michael Mortensen82cd62d2019-12-01 14:58:54 -0700445 def setUp(self):
446 self.chroot_path = '/path/to/chroot'
447
448 def _GetInput(self, chroot_path=None):
449 """Helper to build an input message instance."""
450 proto = test_pb2.CrosSigningTestRequest(
451 chroot={'path': chroot_path},
452 )
453 return proto
454
455 def _GetOutput(self):
456 """Helper to get an empty output message instance."""
457 return test_pb2.CrosSigningTestResponse()
458
Alex Klein4bc8f4f2019-08-16 14:53:30 -0600459 def testValidateOnly(self):
460 """Sanity check that a validate only call does not execute any logic."""
461 test_controller.CrosSigningTest(None, None, self.validate_only_config)
462 self.assertFalse(self.rc.call_count)
463
Michael Mortensen7a7646d2019-12-12 15:36:14 -0700464 def testMockCall(self):
465 """Test mock call does not execute any logic, returns success."""
466 rc = test_controller.CrosSigningTest(None, None, self.mock_call_config)
467 self.assertFalse(self.rc.call_count)
468 self.assertEqual(controller.RETURN_CODE_SUCCESS, rc)
469
Michael Mortensen82cd62d2019-12-01 14:58:54 -0700470 def testCrosSigningTest(self):
471 """Call CrosSigningTest with mocked cros_build_lib.run."""
472 request = self._GetInput(chroot_path=self.chroot_path)
473 patch = self.PatchObject(
474 cros_build_lib, 'run',
475 return_value=cros_build_lib.CommandResult(returncode=0))
476
477 test_controller.CrosSigningTest(request, self._GetOutput(),
478 self.api_config)
479 patch.assert_called_once()
480
Alex Klein4bc8f4f2019-08-16 14:53:30 -0600481
Michael Mortensenc28d6f12019-10-03 13:34:51 -0600482class SimpleChromeWorkflowTestTest(cros_test_lib.MockTestCase,
483 api_config.ApiConfigMixin):
484 """Test the SimpleChromeWorkflowTest endpoint."""
485
486 @staticmethod
487 def _Output():
488 return test_pb2.SimpleChromeWorkflowTestResponse()
489
David Wellingc1433c22021-06-25 16:29:48 +0000490 def _Input(self,
491 sysroot_path=None,
492 build_target=None,
493 chrome_root=None,
Michael Mortensenc28d6f12019-10-03 13:34:51 -0600494 goma_config=None):
495 proto = test_pb2.SimpleChromeWorkflowTestRequest()
496 if sysroot_path:
497 proto.sysroot.path = sysroot_path
498 if build_target:
499 proto.sysroot.build_target.name = build_target
500 if chrome_root:
501 proto.chrome_root = chrome_root
502 if goma_config:
503 proto.goma_config = goma_config
504 return proto
505
506 def setUp(self):
507 self.chrome_path = 'path/to/chrome'
508 self.sysroot_dir = 'build/board'
509 self.build_target = 'amd64'
510 self.mock_simple_chrome_workflow_test = self.PatchObject(
511 test_service, 'SimpleChromeWorkflowTest')
512
513 def testMissingBuildTarget(self):
Michael Mortensen82cd62d2019-12-01 14:58:54 -0700514 """Test SimpleChromeWorkflowTest dies when build_target not set."""
Michael Mortensenc28d6f12019-10-03 13:34:51 -0600515 input_proto = self._Input(build_target=None, sysroot_path='/sysroot/dir',
516 chrome_root='/chrome/path')
517 with self.assertRaises(cros_build_lib.DieSystemExit):
518 test_controller.SimpleChromeWorkflowTest(input_proto, None,
519 self.api_config)
520
521 def testMissingSysrootPath(self):
Michael Mortensen82cd62d2019-12-01 14:58:54 -0700522 """Test SimpleChromeWorkflowTest dies when build_target not set."""
Michael Mortensenc28d6f12019-10-03 13:34:51 -0600523 input_proto = self._Input(build_target='board', sysroot_path=None,
524 chrome_root='/chrome/path')
525 with self.assertRaises(cros_build_lib.DieSystemExit):
526 test_controller.SimpleChromeWorkflowTest(input_proto, None,
527 self.api_config)
528
529 def testMissingChromeRoot(self):
Michael Mortensen82cd62d2019-12-01 14:58:54 -0700530 """Test SimpleChromeWorkflowTest dies when build_target not set."""
Michael Mortensenc28d6f12019-10-03 13:34:51 -0600531 input_proto = self._Input(build_target='board', sysroot_path='/sysroot/dir',
532 chrome_root=None)
533 with self.assertRaises(cros_build_lib.DieSystemExit):
534 test_controller.SimpleChromeWorkflowTest(input_proto, None,
535 self.api_config)
536
537 def testSimpleChromeWorkflowTest(self):
538 """Call SimpleChromeWorkflowTest with valid args and temp dir."""
539 request = self._Input(sysroot_path='sysroot_path', build_target='board',
540 chrome_root='/path/to/chrome')
541 response = self._Output()
542
543 test_controller.SimpleChromeWorkflowTest(request, response, self.api_config)
544 self.mock_simple_chrome_workflow_test.assert_called()
545
546 def testValidateOnly(self):
547 request = self._Input(sysroot_path='sysroot_path', build_target='board',
548 chrome_root='/path/to/chrome')
549 test_controller.SimpleChromeWorkflowTest(request, self._Output(),
550 self.validate_only_config)
551 self.mock_simple_chrome_workflow_test.assert_not_called()
552
Michael Mortensen7a7646d2019-12-12 15:36:14 -0700553 def testMockCall(self):
554 """Test mock call does not execute any logic, returns success."""
555 patch = self.mock_simple_chrome_workflow_test = self.PatchObject(
556 test_service, 'SimpleChromeWorkflowTest')
557
558 request = self._Input(sysroot_path='sysroot_path', build_target='board',
559 chrome_root='/path/to/chrome')
560 rc = test_controller.SimpleChromeWorkflowTest(request, self._Output(),
561 self.mock_call_config)
562 patch.assert_not_called()
563 self.assertEqual(controller.RETURN_CODE_SUCCESS, rc)
564
Michael Mortensenc28d6f12019-10-03 13:34:51 -0600565
Alex Klein231d2da2019-07-22 16:44:45 -0600566class VmTestTest(cros_test_lib.RunCommandTestCase, api_config.ApiConfigMixin):
Evan Hernandez4e388a52019-05-01 12:16:33 -0600567 """Test the VmTest endpoint."""
568
569 def _GetInput(self, **kwargs):
570 values = dict(
571 build_target=common_pb2.BuildTarget(name='target'),
Alex Klein311b8022019-06-05 16:00:07 -0600572 vm_path=common_pb2.Path(path='/path/to/image.bin',
573 location=common_pb2.Path.INSIDE),
Evan Hernandez4e388a52019-05-01 12:16:33 -0600574 test_harness=test_pb2.VmTestRequest.TAST,
575 vm_tests=[test_pb2.VmTestRequest.VmTest(pattern='suite')],
576 ssh_options=test_pb2.VmTestRequest.SshOptions(
Alex Klein231d2da2019-07-22 16:44:45 -0600577 port=1234, private_key_path={'path': '/path/to/id_rsa',
Alex Kleinaa705412019-06-04 15:00:30 -0600578 'location': common_pb2.Path.INSIDE}),
Evan Hernandez4e388a52019-05-01 12:16:33 -0600579 )
580 values.update(kwargs)
581 return test_pb2.VmTestRequest(**values)
582
Michael Mortensen82cd62d2019-12-01 14:58:54 -0700583 def _Output(self):
584 return test_pb2.VmTestResponse()
585
Alex Klein231d2da2019-07-22 16:44:45 -0600586 def testValidateOnly(self):
587 """Sanity check that a validate only call does not execute any logic."""
588 test_controller.VmTest(self._GetInput(), None, self.validate_only_config)
589 self.assertEqual(0, self.rc.call_count)
Evan Hernandez4e388a52019-05-01 12:16:33 -0600590
Michael Mortensen7a7646d2019-12-12 15:36:14 -0700591 def testMockCall(self):
592 """Test mock call does not execute any logic."""
593 patch = self.PatchObject(cros_build_lib, 'run')
594
595 request = self._GetInput()
596 response = self._Output()
597 # VmTest does not return a value, checking mocked value is flagged by lint.
598 test_controller.VmTest(request, response, self.mock_call_config)
599 patch.assert_not_called()
600
Evan Hernandez4e388a52019-05-01 12:16:33 -0600601 def testTastAllOptions(self):
602 """Test VmTest for Tast with all options set."""
Alex Klein231d2da2019-07-22 16:44:45 -0600603 test_controller.VmTest(self._GetInput(), None, self.api_config)
604 self.assertCommandContains([
Achuith Bhandarkara9e9c3d2019-05-22 13:56:11 -0700605 'cros_run_test', '--debug', '--no-display', '--copy-on-write',
Evan Hernandez4e388a52019-05-01 12:16:33 -0600606 '--board', 'target',
607 '--image-path', '/path/to/image.bin',
608 '--tast', 'suite',
609 '--ssh-port', '1234',
610 '--private-key', '/path/to/id_rsa',
611 ])
612
613 def testAutotestAllOptions(self):
614 """Test VmTest for Autotest with all options set."""
615 input_proto = self._GetInput(test_harness=test_pb2.VmTestRequest.AUTOTEST)
Alex Klein231d2da2019-07-22 16:44:45 -0600616 test_controller.VmTest(input_proto, None, self.api_config)
617 self.assertCommandContains([
Achuith Bhandarkara9e9c3d2019-05-22 13:56:11 -0700618 'cros_run_test', '--debug', '--no-display', '--copy-on-write',
Evan Hernandez4e388a52019-05-01 12:16:33 -0600619 '--board', 'target',
620 '--image-path', '/path/to/image.bin',
621 '--autotest', 'suite',
622 '--ssh-port', '1234',
623 '--private-key', '/path/to/id_rsa',
Greg Edelstondcb0e912020-08-31 11:09:40 -0600624 '--test_that-args=--allow-chrome-crashes',
Evan Hernandez4e388a52019-05-01 12:16:33 -0600625 ])
626
627 def testMissingBuildTarget(self):
628 """Test VmTest dies when build_target not set."""
629 input_proto = self._GetInput(build_target=None)
630 with self.assertRaises(cros_build_lib.DieSystemExit):
Alex Klein231d2da2019-07-22 16:44:45 -0600631 test_controller.VmTest(input_proto, None, self.api_config)
Evan Hernandez4e388a52019-05-01 12:16:33 -0600632
633 def testMissingVmImage(self):
634 """Test VmTest dies when vm_image not set."""
Alex Klein311b8022019-06-05 16:00:07 -0600635 input_proto = self._GetInput(vm_path=None)
Evan Hernandez4e388a52019-05-01 12:16:33 -0600636 with self.assertRaises(cros_build_lib.DieSystemExit):
Alex Klein231d2da2019-07-22 16:44:45 -0600637 test_controller.VmTest(input_proto, None, self.api_config)
Evan Hernandez4e388a52019-05-01 12:16:33 -0600638
639 def testMissingTestHarness(self):
640 """Test VmTest dies when test_harness not specified."""
641 input_proto = self._GetInput(
642 test_harness=test_pb2.VmTestRequest.UNSPECIFIED)
643 with self.assertRaises(cros_build_lib.DieSystemExit):
Alex Klein231d2da2019-07-22 16:44:45 -0600644 test_controller.VmTest(input_proto, None, self.api_config)
Evan Hernandez4e388a52019-05-01 12:16:33 -0600645
646 def testMissingVmTests(self):
647 """Test VmTest dies when vm_tests not set."""
648 input_proto = self._GetInput(vm_tests=[])
649 with self.assertRaises(cros_build_lib.DieSystemExit):
Alex Klein231d2da2019-07-22 16:44:45 -0600650 test_controller.VmTest(input_proto, None, self.api_config)
Evan Hernandezdc3f0bb2019-06-06 12:46:52 -0600651
Michael Mortensen82cd62d2019-12-01 14:58:54 -0700652 def testVmTest(self):
653 """Call VmTest with valid args and temp dir."""
654 request = self._GetInput()
655 response = self._Output()
656 patch = self.PatchObject(
657 cros_build_lib, 'run',
658 return_value=cros_build_lib.CommandResult(returncode=0))
659
660 test_controller.VmTest(request, response, self.api_config)
661 patch.assert_called()
662
Evan Hernandezdc3f0bb2019-06-06 12:46:52 -0600663
Alex Klein231d2da2019-07-22 16:44:45 -0600664class MoblabVmTestTest(cros_test_lib.MockTestCase, api_config.ApiConfigMixin):
Evan Hernandezdc3f0bb2019-06-06 12:46:52 -0600665 """Test the MoblabVmTest endpoint."""
666
667 @staticmethod
668 def _Payload(path):
669 return test_pb2.MoblabVmTestRequest.Payload(
670 path=common_pb2.Path(path=path))
671
672 @staticmethod
673 def _Output():
674 return test_pb2.MoblabVmTestResponse()
675
676 def _Input(self):
677 return test_pb2.MoblabVmTestRequest(
Evan Hernandeze1e05d32019-07-19 12:32:18 -0600678 chroot=common_pb2.Chroot(path=self.chroot_dir),
Evan Hernandezdc3f0bb2019-06-06 12:46:52 -0600679 image_payload=self._Payload(self.image_payload_dir),
680 cache_payloads=[self._Payload(self.autotest_payload_dir)])
681
682 def setUp(self):
Evan Hernandeze1e05d32019-07-19 12:32:18 -0600683 self.chroot_dir = '/chroot'
684 self.chroot_tmp_dir = '/chroot/tmp'
Evan Hernandezdc3f0bb2019-06-06 12:46:52 -0600685 self.image_payload_dir = '/payloads/image'
686 self.autotest_payload_dir = '/payloads/autotest'
687 self.builder = 'moblab-generic-vm/R12-3.4.5-67.890'
688 self.image_cache_dir = '/mnt/moblab/cache'
689 self.image_mount_dir = '/mnt/image'
690
Evan Hernandeze1e05d32019-07-19 12:32:18 -0600691 self.PatchObject(chroot_lib.Chroot, 'tempdir', osutils.TempDir)
Evan Hernandez655e8042019-06-13 12:50:44 -0600692
Evan Hernandezdc3f0bb2019-06-06 12:46:52 -0600693 self.mock_create_moblab_vms = self.PatchObject(
694 test_service, 'CreateMoblabVm')
695 self.mock_prepare_moblab_vm_image_cache = self.PatchObject(
696 test_service, 'PrepareMoblabVmImageCache',
697 return_value=self.image_cache_dir)
698 self.mock_run_moblab_vm_tests = self.PatchObject(
699 test_service, 'RunMoblabVmTest')
700 self.mock_validate_moblab_vm_tests = self.PatchObject(
701 test_service, 'ValidateMoblabVmTest')
702
703 @contextlib.contextmanager
Alex Klein38c7d9e2019-05-08 09:31:19 -0600704 def MockLoopbackPartitions(*_args, **_kwargs):
Evan Hernandezdc3f0bb2019-06-06 12:46:52 -0600705 mount = mock.MagicMock()
Evan Hernandez40ee7452019-06-13 12:51:43 -0600706 mount.Mount.return_value = [self.image_mount_dir]
Evan Hernandezdc3f0bb2019-06-06 12:46:52 -0600707 yield mount
Alex Klein231d2da2019-07-22 16:44:45 -0600708
Evan Hernandezdc3f0bb2019-06-06 12:46:52 -0600709 self.PatchObject(image_lib, 'LoopbackPartitions', MockLoopbackPartitions)
710
Alex Klein231d2da2019-07-22 16:44:45 -0600711 def testValidateOnly(self):
712 """Sanity check that a validate only call does not execute any logic."""
713 test_controller.MoblabVmTest(self._Input(), self._Output(),
714 self.validate_only_config)
715 self.mock_create_moblab_vms.assert_not_called()
716
Michael Mortensen7a7646d2019-12-12 15:36:14 -0700717 def testMockCall(self):
718 """Test mock call does not execute any logic."""
719 patch = self.PatchObject(key_value_store, 'LoadFile')
720
721 # MoblabVmTest does not return a value, checking mocked value is flagged by
722 # lint.
723 test_controller.MoblabVmTest(self._Input(), self._Output(),
724 self.mock_call_config)
725 patch.assert_not_called()
726
Evan Hernandezdc3f0bb2019-06-06 12:46:52 -0600727 def testImageContainsBuilder(self):
728 """MoblabVmTest calls service with correct args."""
729 request = self._Input()
730 response = self._Output()
731
732 self.PatchObject(
Mike Frysingere652ba12019-09-08 00:57:43 -0400733 key_value_store, 'LoadFile',
Evan Hernandezdc3f0bb2019-06-06 12:46:52 -0600734 return_value={cros_set_lsb_release.LSB_KEY_BUILDER_PATH: self.builder})
735
Alex Klein231d2da2019-07-22 16:44:45 -0600736 test_controller.MoblabVmTest(request, response, self.api_config)
Evan Hernandezdc3f0bb2019-06-06 12:46:52 -0600737
738 self.assertEqual(
739 self.mock_create_moblab_vms.call_args_list,
Evan Hernandeze1e05d32019-07-19 12:32:18 -0600740 [mock.call(mock.ANY, self.chroot_dir, self.image_payload_dir)])
Evan Hernandezdc3f0bb2019-06-06 12:46:52 -0600741 self.assertEqual(
742 self.mock_prepare_moblab_vm_image_cache.call_args_list,
743 [mock.call(mock.ANY, self.builder, [self.autotest_payload_dir])])
744 self.assertEqual(
745 self.mock_run_moblab_vm_tests.call_args_list,
Evan Hernandez655e8042019-06-13 12:50:44 -0600746 [mock.call(mock.ANY, mock.ANY, self.builder, self.image_cache_dir,
747 mock.ANY)])
Evan Hernandezdc3f0bb2019-06-06 12:46:52 -0600748 self.assertEqual(
749 self.mock_validate_moblab_vm_tests.call_args_list,
750 [mock.call(mock.ANY)])
751
752 def testImageMissingBuilder(self):
753 """MoblabVmTest dies when builder path not found in lsb-release."""
754 request = self._Input()
755 response = self._Output()
756
Mike Frysingere652ba12019-09-08 00:57:43 -0400757 self.PatchObject(key_value_store, 'LoadFile', return_value={})
Evan Hernandezdc3f0bb2019-06-06 12:46:52 -0600758
759 with self.assertRaises(cros_build_lib.DieSystemExit):
Alex Klein231d2da2019-07-22 16:44:45 -0600760 test_controller.MoblabVmTest(request, response, self.api_config)
David Wellingc1433c22021-06-25 16:29:48 +0000761
762
763class GetArtifactsTest(cros_test_lib.MockTempDirTestCase):
764 """Test GetArtifacts."""
765
766 CODE_COVERAGE_LLVM_ARTIFACT_TYPE = (
767 common_pb2.ArtifactsByService.Test.ArtifactType.CODE_COVERAGE_LLVM_JSON
768 )
George Engelbrecht764b1cd2021-06-18 17:01:07 -0600769 UNIT_TEST_ARTIFACT_TYPE = (
770 common_pb2.ArtifactsByService.Test.ArtifactType.UNIT_TESTS
771 )
David Wellingc1433c22021-06-25 16:29:48 +0000772
773 def setUp(self):
774 """Set up the class for tests."""
775 chroot_dir = os.path.join(self.tempdir, 'chroot')
776 osutils.SafeMakedirs(chroot_dir)
777 osutils.SafeMakedirs(os.path.join(chroot_dir, 'tmp'))
778 self.chroot = chroot_lib.Chroot(chroot_dir)
779
780 sysroot_path = os.path.join(chroot_dir, 'build', 'board')
781 osutils.SafeMakedirs(sysroot_path)
782 self.sysroot = sysroot_lib.Sysroot(sysroot_path)
783
Jack Neusc9707c32021-07-23 21:48:54 +0000784 self.build_target = build_target_lib.BuildTarget('board')
785
David Wellingc1433c22021-06-25 16:29:48 +0000786 def testReturnsEmptyListWhenNoOutputArtifactsProvided(self):
787 """Test empty list is returned when there are no output_artifacts."""
788 result = test_controller.GetArtifacts(
789 common_pb2.ArtifactsByService.Test(output_artifacts=[]),
Jack Neusc9707c32021-07-23 21:48:54 +0000790 self.chroot, self.sysroot, self.build_target, self.tempdir)
David Wellingc1433c22021-06-25 16:29:48 +0000791
792 self.assertEqual(len(result), 0)
793
794 def testShouldCallBundleCodeCoverageLlvmJsonForEachValidArtifact(self):
795 """Test BundleCodeCoverageLlvmJson is called on each valid artifact."""
Sean McAllister17eed8d2021-09-21 10:41:16 -0600796 BundleCodeCoverageLlvmJson_mock = (
797 self.PatchObject(
798 test_service,
799 'BundleCodeCoverageLlvmJson',
800 return_value='test'))
David Wellingc1433c22021-06-25 16:29:48 +0000801
802 test_controller.GetArtifacts(
803 common_pb2.ArtifactsByService.Test(output_artifacts=[
804 # Valid
805 common_pb2.ArtifactsByService.Test.ArtifactInfo(
806 artifact_types=[
807 self.CODE_COVERAGE_LLVM_ARTIFACT_TYPE
808 ]
809 ),
810
811 # Invalid
812 common_pb2.ArtifactsByService.Test.ArtifactInfo(
813 artifact_types=[
814 common_pb2.ArtifactsByService.Test.ArtifactType.UNIT_TESTS
815 ]
816 ),
817 ]),
Jack Neusc9707c32021-07-23 21:48:54 +0000818 self.chroot, self.sysroot, self.build_target, self.tempdir)
David Wellingc1433c22021-06-25 16:29:48 +0000819
820 BundleCodeCoverageLlvmJson_mock.assert_called_once()
821
822 def testShouldReturnValidResult(self):
823 """Test result contains paths and code_coverage_llvm_json type."""
824 self.PatchObject(test_service, 'BundleCodeCoverageLlvmJson',
Sean McAllister17eed8d2021-09-21 10:41:16 -0600825 return_value='test')
George Engelbrecht764b1cd2021-06-18 17:01:07 -0600826 self.PatchObject(test_service, 'BuildTargetUnitTestTarball',
Sean McAllister17eed8d2021-09-21 10:41:16 -0600827 return_value='unit_tests.tar')
David Wellingc1433c22021-06-25 16:29:48 +0000828
829 result = test_controller.GetArtifacts(
830 common_pb2.ArtifactsByService.Test(output_artifacts=[
831 # Valid
832 common_pb2.ArtifactsByService.Test.ArtifactInfo(
833 artifact_types=[
George Engelbrecht764b1cd2021-06-18 17:01:07 -0600834 self.UNIT_TEST_ARTIFACT_TYPE
835 ]
836 ),
837 common_pb2.ArtifactsByService.Test.ArtifactInfo(
838 artifact_types=[
David Wellingc1433c22021-06-25 16:29:48 +0000839 self.CODE_COVERAGE_LLVM_ARTIFACT_TYPE
840 ]
841 ),
842 ]),
Jack Neusc9707c32021-07-23 21:48:54 +0000843 self.chroot, self.sysroot, self.build_target, self.tempdir)
David Wellingc1433c22021-06-25 16:29:48 +0000844
George Engelbrecht764b1cd2021-06-18 17:01:07 -0600845 self.assertEqual(result[0]['paths'], ['unit_tests.tar'])
846 self.assertEqual(result[0]['type'], self.UNIT_TEST_ARTIFACT_TYPE)
847 self.assertEqual(result[1]['paths'], ['test'])
848 self.assertEqual(result[1]['type'], self.CODE_COVERAGE_LLVM_ARTIFACT_TYPE)
Andrew Lamb763e3be2021-07-27 17:22:02 -0600849
850
851class GetCoverageRulesTest(cros_test_lib.RunCommandTempDirTestCase,
852 api_config.ApiConfigMixin):
853 """Tests for GetCoverageRules."""
854
Andrew Lambd814afa2021-08-11 11:04:20 -0600855 def _Input(self):
Andrew Lamb763e3be2021-07-27 17:22:02 -0600856 """Returns a sample GetCoverageRulesRequest for testing."""
Andrew Lambd814afa2021-08-11 11:04:20 -0600857 build_metadata_list_path = os.path.join(self.tempdir,
858 'build_metadata_list.jsonproto')
859 build_metadata_list = system_image_pb2.SystemImage.BuildMetadataList(
860 values=[
Andrew Lamb763e3be2021-07-27 17:22:02 -0600861 system_image_pb2.SystemImage.BuildMetadata(
862 build_target=system_image_pb2.SystemImage.BuildTarget(
863 portage_build_target=portage_pb2.Portage.BuildTarget(
864 overlay_name='overlayA')),
865 package_summary=system_image_pb2.SystemImage.BuildMetadata
866 .PackageSummary(
867 kernel=system_image_pb2.SystemImage.BuildMetadata.Kernel(
868 version='4.4')))
Andrew Lambd814afa2021-08-11 11:04:20 -0600869 ])
870 osutils.WriteFile(build_metadata_list_path,
871 json_format.MessageToJson(build_metadata_list))
872
873 dut_attribute_list_path = os.path.join(self.tempdir,
874 'dut_attribute_list.jsonproto')
875 dut_attribute_list = dut_attribute_pb2.DutAttributeList(dut_attributes=[
876 dut_attribute_pb2.DutAttribute(
877 id=dut_attribute_pb2.DutAttribute.Id(value='system_build_target'))
878 ])
879 osutils.WriteFile(dut_attribute_list_path,
880 json_format.MessageToJson(dut_attribute_list))
881
882 flat_config_list_path = os.path.join(self.tempdir,
883 'flat_config_list.jsonproto')
884 flat_config_list = flat_config_pb2.FlatConfigList(values=[
885 flat_config_pb2.FlatConfig(
886 hw_design=design_pb2.Design(
887 id=design_id_pb2.DesignId(value='design1')
888 )
889 )
890 ])
891 osutils.WriteFile(flat_config_list_path,
892 json_format.MessageToJson(flat_config_list))
893
894 return test_pb2.GetCoverageRulesRequest(
895 source_test_plans=[
896 source_test_plan_pb2.SourceTestPlan(
897 requirements=source_test_plan_pb2.SourceTestPlan.Requirements(
898 kernel_versions=source_test_plan_pb2.SourceTestPlan
899 .Requirements.KernelVersions()),
900 test_tags=['kernel']),
901 ],
902 build_metadata_list=common_pb2.Path(
903 path=build_metadata_list_path, location=common_pb2.Path.OUTSIDE),
904 dut_attribute_list=common_pb2.Path(
905 path=dut_attribute_list_path, location=common_pb2.Path.OUTSIDE),
906 flat_config_list=common_pb2.Path(
907 path=flat_config_list_path, location=common_pb2.Path.OUTSIDE),
908 )
Andrew Lamb763e3be2021-07-27 17:22:02 -0600909
910 @staticmethod
911 def _Output():
912 """Returns a sample GetCoverageRulesResponse for testing."""
913 return test_pb2.GetCoverageRulesResponse(coverage_rules=[
914 coverage_rule_pb2.CoverageRule(
915 name='kernel:4.4',
916 test_suites=[
917 test_suite_pb2.TestSuite(
918 test_case_tag_criteria=test_suite_pb2.TestSuite
919 .TestCaseTagCriteria(tags=['kernel']))
920 ],
921 dut_criteria=[
922 dut_attribute_pb2.DutCriterion(
923 attribute_id=dut_attribute_pb2.DutAttribute.Id(
924 value='system_build_target'),
925 values=['overlayA'],
926 )
927 ])
928 ])
929
930 @staticmethod
931 def _write_coverage_rules(path, coverage_rules):
932 """Write a list of CoverageRules in the same format as testplan."""
933 osutils.WriteFile(
934 path, '\n'.join(
935 json_format.MessageToJson(rule).replace('\n', '')
936 for rule in coverage_rules))
937
938 def testWritesInputsAndReturnsCoverageRules(self):
939 """Test inputs are written, and output of testplan is parsed."""
940 output_proto = test_pb2.GetCoverageRulesResponse()
941
942 self.rc.SetDefaultCmdResult(
943 side_effect=lambda _: self._write_coverage_rules(
944 os.path.join(self.tempdir, 'out.jsonpb'),
945 self._Output().coverage_rules))
946 self.PatchObject(osutils.TempDir, '__enter__', return_value=self.tempdir)
947
948 test_controller.GetCoverageRules(self._Input(), output_proto,
949 self.api_config)
950
Andrew Lamb763e3be2021-07-27 17:22:02 -0600951 self.assertEqual(output_proto, self._Output())