blob: 870109b3a5db77f20e986bf5b23570c64cffc38e [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 Kleina2e42c42019-04-17 16:13:19 -060015from chromite.api.gen.chromite.api import test_pb2
16from chromite.cbuildbot import commands
Alex Kleinfa6ebdc2019-05-10 10:57:31 -060017from chromite.lib import constants
Alex Kleina2e42c42019-04-17 16:13:19 -060018from chromite.lib import cros_build_lib
19from chromite.lib import cros_test_lib
20from chromite.lib import failures_lib
21from chromite.lib import osutils
22from chromite.lib import portage_util
23
24
Evan Hernandez4e388a52019-05-01 12:16:33 -060025class BuildTargetUnitTestTest(cros_test_lib.MockTempDirTestCase):
Alex Kleina2e42c42019-04-17 16:13:19 -060026 """Tests for the UnitTest function."""
27
28 def _GetInput(self, board=None, result_path=None, chroot_path=None,
Alex Kleinf2674462019-05-16 16:47:24 -060029 cache_dir=None, empty_sysroot=None, blacklist=None):
Alex Kleina2e42c42019-04-17 16:13:19 -060030 """Helper to build an input message instance."""
Alex Kleinf2674462019-05-16 16:47:24 -060031 formatted_blacklist = []
32 for pkg in blacklist or []:
33 formatted_blacklist.append({'category': pkg.category,
34 'package_name': pkg.package})
35
Alex Kleina2e42c42019-04-17 16:13:19 -060036 return test_pb2.BuildTargetUnitTestRequest(
37 build_target={'name': board}, result_path=result_path,
Alex Kleinfa6ebdc2019-05-10 10:57:31 -060038 chroot={'path': chroot_path, 'cache_dir': cache_dir},
Alex Kleinf2674462019-05-16 16:47:24 -060039 flags={'empty_sysroot': empty_sysroot},
40 package_blacklist=formatted_blacklist,
Alex Kleina2e42c42019-04-17 16:13:19 -060041 )
42
43 def _GetOutput(self):
44 """Helper to get an empty output message instance."""
45 return test_pb2.BuildTargetUnitTestResponse()
46
47 def testNoArgumentFails(self):
48 """Test no arguments fails."""
49 input_msg = self._GetInput()
50 output_msg = self._GetOutput()
51 with self.assertRaises(cros_build_lib.DieSystemExit):
52 test_controller.BuildTargetUnitTest(input_msg, output_msg)
53
54 def testNoBuildTargetFails(self):
55 """Test missing build target name fails."""
56 input_msg = self._GetInput(result_path=self.tempdir)
57 output_msg = self._GetOutput()
58 with self.assertRaises(cros_build_lib.DieSystemExit):
59 test_controller.BuildTargetUnitTest(input_msg, output_msg)
60
61 def testNoResultPathFails(self):
62 """Test missing result path fails."""
63 # Missing result_path.
64 input_msg = self._GetInput(board='board')
65 output_msg = self._GetOutput()
66 with self.assertRaises(cros_build_lib.DieSystemExit):
67 test_controller.BuildTargetUnitTest(input_msg, output_msg)
68
69 def testPackageBuildFailure(self):
70 """Test handling of raised BuildPackageFailure."""
71 tempdir = osutils.TempDir(base_dir=self.tempdir)
72 self.PatchObject(osutils, 'TempDir', return_value=tempdir)
73
74 pkgs = ['cat/pkg', 'foo/bar']
75 expected = [('cat', 'pkg'), ('foo', 'bar')]
76 rce = cros_build_lib.RunCommandError('error',
77 cros_build_lib.CommandResult())
78 error = failures_lib.PackageBuildFailure(rce, 'shortname', pkgs)
79 self.PatchObject(commands, 'RunUnitTests', side_effect=error)
80
81 input_msg = self._GetInput(board='board', result_path=self.tempdir)
82 output_msg = self._GetOutput()
83
84 rc = test_controller.BuildTargetUnitTest(input_msg, output_msg)
85
Alex Klein8cb365a2019-05-15 16:24:53 -060086 self.assertEqual(controller.RETURN_CODE_UNSUCCESSFUL_RESPONSE_AVAILABLE, rc)
Alex Kleina2e42c42019-04-17 16:13:19 -060087 self.assertTrue(output_msg.failed_packages)
88 failed = []
89 for pi in output_msg.failed_packages:
90 failed.append((pi.category, pi.package_name))
91 self.assertItemsEqual(expected, failed)
92
93 def testPopulatedEmergeFile(self):
94 """Test build script failure due to using outside emerge status file."""
95 tempdir = osutils.TempDir(base_dir=self.tempdir)
96 self.PatchObject(osutils, 'TempDir', return_value=tempdir)
97
98 pkgs = ['cat/pkg', 'foo/bar']
99 cpvs = [portage_util.SplitCPV(pkg, strict=False) for pkg in pkgs]
100 expected = [('cat', 'pkg'), ('foo', 'bar')]
101 rce = cros_build_lib.RunCommandError('error',
102 cros_build_lib.CommandResult())
103 error = failures_lib.BuildScriptFailure(rce, 'shortname')
104 self.PatchObject(commands, 'RunUnitTests', side_effect=error)
105 self.PatchObject(portage_util, 'ParseParallelEmergeStatusFile',
106 return_value=cpvs)
107
108 input_msg = self._GetInput(board='board', result_path=self.tempdir)
109 output_msg = self._GetOutput()
110
111 rc = test_controller.BuildTargetUnitTest(input_msg, output_msg)
112
Alex Klein8cb365a2019-05-15 16:24:53 -0600113 self.assertEqual(controller.RETURN_CODE_UNSUCCESSFUL_RESPONSE_AVAILABLE, rc)
Alex Kleina2e42c42019-04-17 16:13:19 -0600114 self.assertTrue(output_msg.failed_packages)
115 failed = []
116 for pi in output_msg.failed_packages:
117 failed.append((pi.category, pi.package_name))
118 self.assertItemsEqual(expected, failed)
119
120 def testOtherBuildScriptFailure(self):
121 """Test build script failure due to non-package emerge error."""
122 tempdir = osutils.TempDir(base_dir=self.tempdir)
123 self.PatchObject(osutils, 'TempDir', return_value=tempdir)
124
125 rce = cros_build_lib.RunCommandError('error',
126 cros_build_lib.CommandResult())
127 error = failures_lib.BuildScriptFailure(rce, 'shortname')
Alex Kleinfa6ebdc2019-05-10 10:57:31 -0600128 patch = self.PatchObject(commands, 'RunUnitTests', side_effect=error)
Alex Kleina2e42c42019-04-17 16:13:19 -0600129 self.PatchObject(portage_util, 'ParseParallelEmergeStatusFile',
130 return_value=[])
131
Alex Kleinf2674462019-05-16 16:47:24 -0600132 pkgs = ['foo/bar', 'cat/pkg']
133 blacklist = [portage_util.SplitCPV(p, strict=False) for p in pkgs]
Alex Kleinfa6ebdc2019-05-10 10:57:31 -0600134 input_msg = self._GetInput(board='board', result_path=self.tempdir,
Alex Kleinf2674462019-05-16 16:47:24 -0600135 empty_sysroot=True, blacklist=blacklist)
Alex Kleina2e42c42019-04-17 16:13:19 -0600136 output_msg = self._GetOutput()
137
138 rc = test_controller.BuildTargetUnitTest(input_msg, output_msg)
139
Alex Klein8cb365a2019-05-15 16:24:53 -0600140 self.assertEqual(controller.RETURN_CODE_COMPLETED_UNSUCCESSFULLY, rc)
Alex Kleina2e42c42019-04-17 16:13:19 -0600141 self.assertFalse(output_msg.failed_packages)
Alex Kleinfa6ebdc2019-05-10 10:57:31 -0600142 patch.assert_called_with(constants.SOURCE_ROOT, 'board', extra_env=mock.ANY,
Alex Kleinf2674462019-05-16 16:47:24 -0600143 chroot_args=mock.ANY, build_stage=False,
144 blacklist=pkgs)
Evan Hernandez4e388a52019-05-01 12:16:33 -0600145
146
147class VmTestTest(cros_test_lib.MockTestCase):
148 """Test the VmTest endpoint."""
149
150 def _GetInput(self, **kwargs):
151 values = dict(
152 build_target=common_pb2.BuildTarget(name='target'),
Alex Klein311b8022019-06-05 16:00:07 -0600153 vm_path=common_pb2.Path(path='/path/to/image.bin',
154 location=common_pb2.Path.INSIDE),
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(
Alex Kleinaa705412019-06-04 15:00:30 -0600158 port=1234, private_key_path={'path':'/path/to/id_rsa',
159 'location': common_pb2.Path.INSIDE}),
Evan Hernandez4e388a52019-05-01 12:16:33 -0600160 )
161 values.update(kwargs)
162 return test_pb2.VmTestRequest(**values)
163
164 def setUp(self):
165 self.rc_mock = cros_test_lib.RunCommandMock()
166 self.rc_mock.SetDefaultCmdResult()
167 self.StartPatcher(self.rc_mock)
168
169 def testTastAllOptions(self):
170 """Test VmTest for Tast with all options set."""
171 test_controller.VmTest(self._GetInput(), None)
172 self.rc_mock.assertCommandContains([
Achuith Bhandarkara9e9c3d2019-05-22 13:56:11 -0700173 'cros_run_test', '--debug', '--no-display', '--copy-on-write',
Evan Hernandez4e388a52019-05-01 12:16:33 -0600174 '--board', 'target',
175 '--image-path', '/path/to/image.bin',
176 '--tast', 'suite',
177 '--ssh-port', '1234',
178 '--private-key', '/path/to/id_rsa',
179 ])
180
181 def testAutotestAllOptions(self):
182 """Test VmTest for Autotest with all options set."""
183 input_proto = self._GetInput(test_harness=test_pb2.VmTestRequest.AUTOTEST)
184 test_controller.VmTest(input_proto, None)
185 self.rc_mock.assertCommandContains([
Achuith Bhandarkara9e9c3d2019-05-22 13:56:11 -0700186 'cros_run_test', '--debug', '--no-display', '--copy-on-write',
Evan Hernandez4e388a52019-05-01 12:16:33 -0600187 '--board', 'target',
188 '--image-path', '/path/to/image.bin',
189 '--autotest', 'suite',
190 '--ssh-port', '1234',
191 '--private-key', '/path/to/id_rsa',
192 '--test_that-args=--whitelist-chrome-crashes',
193 ])
194
195 def testMissingBuildTarget(self):
196 """Test VmTest dies when build_target not set."""
197 input_proto = self._GetInput(build_target=None)
198 with self.assertRaises(cros_build_lib.DieSystemExit):
199 test_controller.VmTest(input_proto, None)
200
201 def testMissingVmImage(self):
202 """Test VmTest dies when vm_image not set."""
Alex Klein311b8022019-06-05 16:00:07 -0600203 input_proto = self._GetInput(vm_path=None)
Evan Hernandez4e388a52019-05-01 12:16:33 -0600204 with self.assertRaises(cros_build_lib.DieSystemExit):
205 test_controller.VmTest(input_proto, None)
206
207 def testMissingTestHarness(self):
208 """Test VmTest dies when test_harness not specified."""
209 input_proto = self._GetInput(
210 test_harness=test_pb2.VmTestRequest.UNSPECIFIED)
211 with self.assertRaises(cros_build_lib.DieSystemExit):
212 test_controller.VmTest(input_proto, None)
213
214 def testMissingVmTests(self):
215 """Test VmTest dies when vm_tests not set."""
216 input_proto = self._GetInput(vm_tests=[])
217 with self.assertRaises(cros_build_lib.DieSystemExit):
218 test_controller.VmTest(input_proto, None)