blob: 4ffdf349062a5c3031371a3d69e9be1cd35a9b2d [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 Kleina2e42c42019-04-17 16:13:19 -060012from chromite.api.controller import test as test_controller
Evan Hernandez4e388a52019-05-01 12:16:33 -060013from chromite.api.gen.chromiumos import common_pb2
Alex Klein4f0eb432019-05-02 13:56:04 -060014from chromite.api.gen.chromite.api import image_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 Kleinfa6ebdc2019-05-10 10:57:31 -060029 cache_dir=None, empty_sysroot=None):
Alex Kleina2e42c42019-04-17 16:13:19 -060030 """Helper to build an input message instance."""
31 return test_pb2.BuildTargetUnitTestRequest(
32 build_target={'name': board}, result_path=result_path,
Alex Kleinfa6ebdc2019-05-10 10:57:31 -060033 chroot={'path': chroot_path, 'cache_dir': cache_dir},
34 flags={'empty_sysroot': empty_sysroot}
Alex Kleina2e42c42019-04-17 16:13:19 -060035 )
36
37 def _GetOutput(self):
38 """Helper to get an empty output message instance."""
39 return test_pb2.BuildTargetUnitTestResponse()
40
41 def testNoArgumentFails(self):
42 """Test no arguments fails."""
43 input_msg = self._GetInput()
44 output_msg = self._GetOutput()
45 with self.assertRaises(cros_build_lib.DieSystemExit):
46 test_controller.BuildTargetUnitTest(input_msg, output_msg)
47
48 def testNoBuildTargetFails(self):
49 """Test missing build target name fails."""
50 input_msg = self._GetInput(result_path=self.tempdir)
51 output_msg = self._GetOutput()
52 with self.assertRaises(cros_build_lib.DieSystemExit):
53 test_controller.BuildTargetUnitTest(input_msg, output_msg)
54
55 def testNoResultPathFails(self):
56 """Test missing result path fails."""
57 # Missing result_path.
58 input_msg = self._GetInput(board='board')
59 output_msg = self._GetOutput()
60 with self.assertRaises(cros_build_lib.DieSystemExit):
61 test_controller.BuildTargetUnitTest(input_msg, output_msg)
62
63 def testPackageBuildFailure(self):
64 """Test handling of raised BuildPackageFailure."""
65 tempdir = osutils.TempDir(base_dir=self.tempdir)
66 self.PatchObject(osutils, 'TempDir', return_value=tempdir)
67
68 pkgs = ['cat/pkg', 'foo/bar']
69 expected = [('cat', 'pkg'), ('foo', 'bar')]
70 rce = cros_build_lib.RunCommandError('error',
71 cros_build_lib.CommandResult())
72 error = failures_lib.PackageBuildFailure(rce, 'shortname', pkgs)
73 self.PatchObject(commands, 'RunUnitTests', side_effect=error)
74
75 input_msg = self._GetInput(board='board', result_path=self.tempdir)
76 output_msg = self._GetOutput()
77
78 rc = test_controller.BuildTargetUnitTest(input_msg, output_msg)
79
80 self.assertNotEqual(0, rc)
81 self.assertTrue(output_msg.failed_packages)
82 failed = []
83 for pi in output_msg.failed_packages:
84 failed.append((pi.category, pi.package_name))
85 self.assertItemsEqual(expected, failed)
86
87 def testPopulatedEmergeFile(self):
88 """Test build script failure due to using outside emerge status file."""
89 tempdir = osutils.TempDir(base_dir=self.tempdir)
90 self.PatchObject(osutils, 'TempDir', return_value=tempdir)
91
92 pkgs = ['cat/pkg', 'foo/bar']
93 cpvs = [portage_util.SplitCPV(pkg, strict=False) for pkg in pkgs]
94 expected = [('cat', 'pkg'), ('foo', 'bar')]
95 rce = cros_build_lib.RunCommandError('error',
96 cros_build_lib.CommandResult())
97 error = failures_lib.BuildScriptFailure(rce, 'shortname')
98 self.PatchObject(commands, 'RunUnitTests', side_effect=error)
99 self.PatchObject(portage_util, 'ParseParallelEmergeStatusFile',
100 return_value=cpvs)
101
102 input_msg = self._GetInput(board='board', result_path=self.tempdir)
103 output_msg = self._GetOutput()
104
105 rc = test_controller.BuildTargetUnitTest(input_msg, output_msg)
106
107 self.assertNotEqual(0, rc)
108 self.assertTrue(output_msg.failed_packages)
109 failed = []
110 for pi in output_msg.failed_packages:
111 failed.append((pi.category, pi.package_name))
112 self.assertItemsEqual(expected, failed)
113
114 def testOtherBuildScriptFailure(self):
115 """Test build script failure due to non-package emerge error."""
116 tempdir = osutils.TempDir(base_dir=self.tempdir)
117 self.PatchObject(osutils, 'TempDir', return_value=tempdir)
118
119 rce = cros_build_lib.RunCommandError('error',
120 cros_build_lib.CommandResult())
121 error = failures_lib.BuildScriptFailure(rce, 'shortname')
Alex Kleinfa6ebdc2019-05-10 10:57:31 -0600122 patch = self.PatchObject(commands, 'RunUnitTests', side_effect=error)
Alex Kleina2e42c42019-04-17 16:13:19 -0600123 self.PatchObject(portage_util, 'ParseParallelEmergeStatusFile',
124 return_value=[])
125
Alex Kleinfa6ebdc2019-05-10 10:57:31 -0600126 input_msg = self._GetInput(board='board', result_path=self.tempdir,
127 empty_sysroot=True)
Alex Kleina2e42c42019-04-17 16:13:19 -0600128 output_msg = self._GetOutput()
129
130 rc = test_controller.BuildTargetUnitTest(input_msg, output_msg)
131
132 self.assertNotEqual(0, rc)
133 self.assertFalse(output_msg.failed_packages)
Alex Kleinfa6ebdc2019-05-10 10:57:31 -0600134 patch.assert_called_with(constants.SOURCE_ROOT, 'board', extra_env=mock.ANY,
135 chroot_args=mock.ANY, build_stage=False)
Evan Hernandez4e388a52019-05-01 12:16:33 -0600136
137
138class VmTestTest(cros_test_lib.MockTestCase):
139 """Test the VmTest endpoint."""
140
141 def _GetInput(self, **kwargs):
142 values = dict(
143 build_target=common_pb2.BuildTarget(name='target'),
Alex Klein4f0eb432019-05-02 13:56:04 -0600144 vm_image=image_pb2.VmImage(path='/path/to/image.bin'),
Evan Hernandez4e388a52019-05-01 12:16:33 -0600145 test_harness=test_pb2.VmTestRequest.TAST,
146 vm_tests=[test_pb2.VmTestRequest.VmTest(pattern='suite')],
147 ssh_options=test_pb2.VmTestRequest.SshOptions(
148 port=1234, private_key_path='/path/to/id_rsa'),
149 )
150 values.update(kwargs)
151 return test_pb2.VmTestRequest(**values)
152
153 def setUp(self):
154 self.rc_mock = cros_test_lib.RunCommandMock()
155 self.rc_mock.SetDefaultCmdResult()
156 self.StartPatcher(self.rc_mock)
157
158 def testTastAllOptions(self):
159 """Test VmTest for Tast with all options set."""
160 test_controller.VmTest(self._GetInput(), None)
161 self.rc_mock.assertCommandContains([
162 'cros_run_vm_test', '--debug', '--no-display', '--copy-on-write',
163 '--board', 'target',
164 '--image-path', '/path/to/image.bin',
165 '--tast', 'suite',
166 '--ssh-port', '1234',
167 '--private-key', '/path/to/id_rsa',
168 ])
169
170 def testAutotestAllOptions(self):
171 """Test VmTest for Autotest with all options set."""
172 input_proto = self._GetInput(test_harness=test_pb2.VmTestRequest.AUTOTEST)
173 test_controller.VmTest(input_proto, None)
174 self.rc_mock.assertCommandContains([
175 'cros_run_vm_test', '--debug', '--no-display', '--copy-on-write',
176 '--board', 'target',
177 '--image-path', '/path/to/image.bin',
178 '--autotest', 'suite',
179 '--ssh-port', '1234',
180 '--private-key', '/path/to/id_rsa',
181 '--test_that-args=--whitelist-chrome-crashes',
182 ])
183
184 def testMissingBuildTarget(self):
185 """Test VmTest dies when build_target not set."""
186 input_proto = self._GetInput(build_target=None)
187 with self.assertRaises(cros_build_lib.DieSystemExit):
188 test_controller.VmTest(input_proto, None)
189
190 def testMissingVmImage(self):
191 """Test VmTest dies when vm_image not set."""
192 input_proto = self._GetInput(vm_image=None)
193 with self.assertRaises(cros_build_lib.DieSystemExit):
194 test_controller.VmTest(input_proto, None)
195
196 def testMissingTestHarness(self):
197 """Test VmTest dies when test_harness not specified."""
198 input_proto = self._GetInput(
199 test_harness=test_pb2.VmTestRequest.UNSPECIFIED)
200 with self.assertRaises(cros_build_lib.DieSystemExit):
201 test_controller.VmTest(input_proto, None)
202
203 def testMissingVmTests(self):
204 """Test VmTest dies when vm_tests not set."""
205 input_proto = self._GetInput(vm_tests=[])
206 with self.assertRaises(cros_build_lib.DieSystemExit):
207 test_controller.VmTest(input_proto, None)