blob: f831a8e8ba2480ba44a78818b13b6989574a4927 [file] [log] [blame]
Alex Kleina2e42c42019-04-17 16:13:19 -06001# -*- 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"""The test controller tests."""
7
8from __future__ import print_function
9
Alex Kleinfa6ebdc2019-05-10 10:57:31 -060010import mock
11
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 Klein4f0eb432019-05-02 13:56:04 -060015from chromite.api.gen.chromite.api import image_pb2
Alex Kleina2e42c42019-04-17 16:13:19 -060016from chromite.api.gen.chromite.api import test_pb2
17from chromite.cbuildbot import commands
Alex Kleinfa6ebdc2019-05-10 10:57:31 -060018from chromite.lib import constants
Alex Kleina2e42c42019-04-17 16:13:19 -060019from chromite.lib import cros_build_lib
20from chromite.lib import cros_test_lib
21from chromite.lib import failures_lib
22from chromite.lib import osutils
23from chromite.lib import portage_util
24
25
Evan Hernandez4e388a52019-05-01 12:16:33 -060026class BuildTargetUnitTestTest(cros_test_lib.MockTempDirTestCase):
Alex Kleina2e42c42019-04-17 16:13:19 -060027 """Tests for the UnitTest function."""
28
29 def _GetInput(self, board=None, result_path=None, chroot_path=None,
Alex Kleinf2674462019-05-16 16:47:24 -060030 cache_dir=None, empty_sysroot=None, blacklist=None):
Alex Kleina2e42c42019-04-17 16:13:19 -060031 """Helper to build an input message instance."""
Alex Kleinf2674462019-05-16 16:47:24 -060032 formatted_blacklist = []
33 for pkg in blacklist or []:
34 formatted_blacklist.append({'category': pkg.category,
35 'package_name': pkg.package})
36
Alex Kleina2e42c42019-04-17 16:13:19 -060037 return test_pb2.BuildTargetUnitTestRequest(
38 build_target={'name': board}, result_path=result_path,
Alex Kleinfa6ebdc2019-05-10 10:57:31 -060039 chroot={'path': chroot_path, 'cache_dir': cache_dir},
Alex Kleinf2674462019-05-16 16:47:24 -060040 flags={'empty_sysroot': empty_sysroot},
41 package_blacklist=formatted_blacklist,
Alex Kleina2e42c42019-04-17 16:13:19 -060042 )
43
44 def _GetOutput(self):
45 """Helper to get an empty output message instance."""
46 return test_pb2.BuildTargetUnitTestResponse()
47
48 def testNoArgumentFails(self):
49 """Test no arguments fails."""
50 input_msg = self._GetInput()
51 output_msg = self._GetOutput()
52 with self.assertRaises(cros_build_lib.DieSystemExit):
53 test_controller.BuildTargetUnitTest(input_msg, output_msg)
54
55 def testNoBuildTargetFails(self):
56 """Test missing build target name fails."""
57 input_msg = self._GetInput(result_path=self.tempdir)
58 output_msg = self._GetOutput()
59 with self.assertRaises(cros_build_lib.DieSystemExit):
60 test_controller.BuildTargetUnitTest(input_msg, output_msg)
61
62 def testNoResultPathFails(self):
63 """Test missing result path fails."""
64 # Missing result_path.
65 input_msg = self._GetInput(board='board')
66 output_msg = self._GetOutput()
67 with self.assertRaises(cros_build_lib.DieSystemExit):
68 test_controller.BuildTargetUnitTest(input_msg, output_msg)
69
70 def testPackageBuildFailure(self):
71 """Test handling of raised BuildPackageFailure."""
72 tempdir = osutils.TempDir(base_dir=self.tempdir)
73 self.PatchObject(osutils, 'TempDir', return_value=tempdir)
74
75 pkgs = ['cat/pkg', 'foo/bar']
76 expected = [('cat', 'pkg'), ('foo', 'bar')]
77 rce = cros_build_lib.RunCommandError('error',
78 cros_build_lib.CommandResult())
79 error = failures_lib.PackageBuildFailure(rce, 'shortname', pkgs)
80 self.PatchObject(commands, 'RunUnitTests', side_effect=error)
81
82 input_msg = self._GetInput(board='board', result_path=self.tempdir)
83 output_msg = self._GetOutput()
84
85 rc = test_controller.BuildTargetUnitTest(input_msg, output_msg)
86
Alex Klein8cb365a2019-05-15 16:24:53 -060087 self.assertEqual(controller.RETURN_CODE_UNSUCCESSFUL_RESPONSE_AVAILABLE, rc)
Alex Kleina2e42c42019-04-17 16:13:19 -060088 self.assertTrue(output_msg.failed_packages)
89 failed = []
90 for pi in output_msg.failed_packages:
91 failed.append((pi.category, pi.package_name))
92 self.assertItemsEqual(expected, failed)
93
94 def testPopulatedEmergeFile(self):
95 """Test build script failure due to using outside emerge status file."""
96 tempdir = osutils.TempDir(base_dir=self.tempdir)
97 self.PatchObject(osutils, 'TempDir', return_value=tempdir)
98
99 pkgs = ['cat/pkg', 'foo/bar']
100 cpvs = [portage_util.SplitCPV(pkg, strict=False) for pkg in pkgs]
101 expected = [('cat', 'pkg'), ('foo', 'bar')]
102 rce = cros_build_lib.RunCommandError('error',
103 cros_build_lib.CommandResult())
104 error = failures_lib.BuildScriptFailure(rce, 'shortname')
105 self.PatchObject(commands, 'RunUnitTests', side_effect=error)
106 self.PatchObject(portage_util, 'ParseParallelEmergeStatusFile',
107 return_value=cpvs)
108
109 input_msg = self._GetInput(board='board', result_path=self.tempdir)
110 output_msg = self._GetOutput()
111
112 rc = test_controller.BuildTargetUnitTest(input_msg, output_msg)
113
Alex Klein8cb365a2019-05-15 16:24:53 -0600114 self.assertEqual(controller.RETURN_CODE_UNSUCCESSFUL_RESPONSE_AVAILABLE, rc)
Alex Kleina2e42c42019-04-17 16:13:19 -0600115 self.assertTrue(output_msg.failed_packages)
116 failed = []
117 for pi in output_msg.failed_packages:
118 failed.append((pi.category, pi.package_name))
119 self.assertItemsEqual(expected, failed)
120
121 def testOtherBuildScriptFailure(self):
122 """Test build script failure due to non-package emerge error."""
123 tempdir = osutils.TempDir(base_dir=self.tempdir)
124 self.PatchObject(osutils, 'TempDir', return_value=tempdir)
125
126 rce = cros_build_lib.RunCommandError('error',
127 cros_build_lib.CommandResult())
128 error = failures_lib.BuildScriptFailure(rce, 'shortname')
Alex Kleinfa6ebdc2019-05-10 10:57:31 -0600129 patch = self.PatchObject(commands, 'RunUnitTests', side_effect=error)
Alex Kleina2e42c42019-04-17 16:13:19 -0600130 self.PatchObject(portage_util, 'ParseParallelEmergeStatusFile',
131 return_value=[])
132
Alex Kleinf2674462019-05-16 16:47:24 -0600133 pkgs = ['foo/bar', 'cat/pkg']
134 blacklist = [portage_util.SplitCPV(p, strict=False) for p in pkgs]
Alex Kleinfa6ebdc2019-05-10 10:57:31 -0600135 input_msg = self._GetInput(board='board', result_path=self.tempdir,
Alex Kleinf2674462019-05-16 16:47:24 -0600136 empty_sysroot=True, blacklist=blacklist)
Alex Kleina2e42c42019-04-17 16:13:19 -0600137 output_msg = self._GetOutput()
138
139 rc = test_controller.BuildTargetUnitTest(input_msg, output_msg)
140
Alex Klein8cb365a2019-05-15 16:24:53 -0600141 self.assertEqual(controller.RETURN_CODE_COMPLETED_UNSUCCESSFULLY, rc)
Alex Kleina2e42c42019-04-17 16:13:19 -0600142 self.assertFalse(output_msg.failed_packages)
Alex Kleinfa6ebdc2019-05-10 10:57:31 -0600143 patch.assert_called_with(constants.SOURCE_ROOT, 'board', extra_env=mock.ANY,
Alex Kleinf2674462019-05-16 16:47:24 -0600144 chroot_args=mock.ANY, build_stage=False,
145 blacklist=pkgs)
Evan Hernandez4e388a52019-05-01 12:16:33 -0600146
147
148class VmTestTest(cros_test_lib.MockTestCase):
149 """Test the VmTest endpoint."""
150
151 def _GetInput(self, **kwargs):
152 values = dict(
153 build_target=common_pb2.BuildTarget(name='target'),
Alex Klein4f0eb432019-05-02 13:56:04 -0600154 vm_image=image_pb2.VmImage(path='/path/to/image.bin'),
Evan Hernandez4e388a52019-05-01 12:16:33 -0600155 test_harness=test_pb2.VmTestRequest.TAST,
156 vm_tests=[test_pb2.VmTestRequest.VmTest(pattern='suite')],
157 ssh_options=test_pb2.VmTestRequest.SshOptions(
158 port=1234, private_key_path='/path/to/id_rsa'),
159 )
160 values.update(kwargs)
161 return test_pb2.VmTestRequest(**values)
162
163 def setUp(self):
164 self.rc_mock = cros_test_lib.RunCommandMock()
165 self.rc_mock.SetDefaultCmdResult()
166 self.StartPatcher(self.rc_mock)
167
168 def testTastAllOptions(self):
169 """Test VmTest for Tast with all options set."""
170 test_controller.VmTest(self._GetInput(), None)
171 self.rc_mock.assertCommandContains([
172 'cros_run_vm_test', '--debug', '--no-display', '--copy-on-write',
173 '--board', 'target',
174 '--image-path', '/path/to/image.bin',
175 '--tast', 'suite',
176 '--ssh-port', '1234',
177 '--private-key', '/path/to/id_rsa',
178 ])
179
180 def testAutotestAllOptions(self):
181 """Test VmTest for Autotest with all options set."""
182 input_proto = self._GetInput(test_harness=test_pb2.VmTestRequest.AUTOTEST)
183 test_controller.VmTest(input_proto, None)
184 self.rc_mock.assertCommandContains([
185 'cros_run_vm_test', '--debug', '--no-display', '--copy-on-write',
186 '--board', 'target',
187 '--image-path', '/path/to/image.bin',
188 '--autotest', 'suite',
189 '--ssh-port', '1234',
190 '--private-key', '/path/to/id_rsa',
191 '--test_that-args=--whitelist-chrome-crashes',
192 ])
193
194 def testMissingBuildTarget(self):
195 """Test VmTest dies when build_target not set."""
196 input_proto = self._GetInput(build_target=None)
197 with self.assertRaises(cros_build_lib.DieSystemExit):
198 test_controller.VmTest(input_proto, None)
199
200 def testMissingVmImage(self):
201 """Test VmTest dies when vm_image not set."""
202 input_proto = self._GetInput(vm_image=None)
203 with self.assertRaises(cros_build_lib.DieSystemExit):
204 test_controller.VmTest(input_proto, None)
205
206 def testMissingTestHarness(self):
207 """Test VmTest dies when test_harness not specified."""
208 input_proto = self._GetInput(
209 test_harness=test_pb2.VmTestRequest.UNSPECIFIED)
210 with self.assertRaises(cros_build_lib.DieSystemExit):
211 test_controller.VmTest(input_proto, None)
212
213 def testMissingVmTests(self):
214 """Test VmTest dies when vm_tests not set."""
215 input_proto = self._GetInput(vm_tests=[])
216 with self.assertRaises(cros_build_lib.DieSystemExit):
217 test_controller.VmTest(input_proto, None)