Mike Frysinger | f1ba7ad | 2022-09-12 05:42:57 -0400 | [diff] [blame] | 1 | # Copyright 2019 The ChromiumOS Authors |
Alex Klein | 2b23672 | 2019-06-19 15:44:26 -0600 | [diff] [blame] | 2 | # Use of this source code is governed by a BSD-style license that can be |
| 3 | # found in the LICENSE file. |
| 4 | |
| 5 | """Tests for the validate module.""" |
| 6 | |
Alex Klein | 2b23672 | 2019-06-19 15:44:26 -0600 | [diff] [blame] | 7 | import os |
| 8 | |
Alex Klein | 69339cc | 2019-07-22 14:08:35 -0600 | [diff] [blame] | 9 | from chromite.api import api_config |
Alex Klein | 2b23672 | 2019-06-19 15:44:26 -0600 | [diff] [blame] | 10 | from chromite.api import validate |
Alex Klein | 86242bf | 2020-09-22 15:23:23 -0600 | [diff] [blame] | 11 | from chromite.api.gen.chromite.api import build_api_test_pb2 |
Alex Klein | 2b23672 | 2019-06-19 15:44:26 -0600 | [diff] [blame] | 12 | from chromite.api.gen.chromiumos import common_pb2 |
| 13 | from chromite.lib import cros_build_lib |
| 14 | from chromite.lib import cros_test_lib |
| 15 | from chromite.lib import osutils |
| 16 | |
Mike Frysinger | ef94e4c | 2020-02-10 23:59:54 -0500 | [diff] [blame] | 17 | |
Alex Klein | bdace30 | 2020-12-03 14:40:23 -0700 | [diff] [blame] | 18 | # These tests test the validators by defining a local `impl` function that |
| 19 | # has the same parameters as a controller function and the validator being |
| 20 | # tested. The validators don't care that they aren't actually controller |
| 21 | # functions, they just need the function to look like one, so it works |
| 22 | # to pass an arbitrary message; i.e. passing one of the Request messages |
| 23 | # we'd usually expect in a controller is not required. The validator |
| 24 | # just needs to be checking one of the fields on the message being used. |
Alex Klein | 2008aee | 2019-08-20 16:25:27 -0600 | [diff] [blame] | 25 | class ExistsTest(cros_test_lib.TempDirTestCase, api_config.ApiConfigMixin): |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 26 | """Tests for the exists validator.""" |
Alex Klein | 2b23672 | 2019-06-19 15:44:26 -0600 | [diff] [blame] | 27 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 28 | def test_not_exists(self): |
| 29 | """Test the validator fails when given a path that doesn't exist.""" |
| 30 | path = os.path.join(self.tempdir, "DOES_NOT_EXIST") |
Alex Klein | 2b23672 | 2019-06-19 15:44:26 -0600 | [diff] [blame] | 31 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 32 | @validate.exists("path") |
| 33 | def impl(_input_proto, _output_proto, _config): |
| 34 | self.fail("Incorrectly allowed method to execute.") |
Alex Klein | 2b23672 | 2019-06-19 15:44:26 -0600 | [diff] [blame] | 35 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 36 | with self.assertRaises(cros_build_lib.DieSystemExit): |
| 37 | impl(common_pb2.Chroot(path=path), None, self.api_config) |
Alex Klein | 2b23672 | 2019-06-19 15:44:26 -0600 | [diff] [blame] | 38 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 39 | def test_exists(self): |
| 40 | """Test the validator fails when given a path that doesn't exist.""" |
| 41 | path = os.path.join(self.tempdir, "chroot") |
| 42 | osutils.SafeMakedirs(path) |
Alex Klein | 2b23672 | 2019-06-19 15:44:26 -0600 | [diff] [blame] | 43 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 44 | @validate.exists("path") |
| 45 | def impl(_input_proto, _output_proto, _config): |
| 46 | pass |
Alex Klein | 2b23672 | 2019-06-19 15:44:26 -0600 | [diff] [blame] | 47 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 48 | impl(common_pb2.Chroot(path=path), None, self.api_config) |
Alex Klein | 2008aee | 2019-08-20 16:25:27 -0600 | [diff] [blame] | 49 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 50 | def test_skip_validation(self): |
| 51 | """Test skipping validation case.""" |
Alex Klein | 2008aee | 2019-08-20 16:25:27 -0600 | [diff] [blame] | 52 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 53 | @validate.exists("path") |
| 54 | def impl(_input_proto, _output_proto, _config): |
| 55 | pass |
| 56 | |
| 57 | # This would otherwise raise an error for an invalid path. |
| 58 | impl(common_pb2.Chroot(), None, self.no_validate_config) |
Alex Klein | 2b23672 | 2019-06-19 15:44:26 -0600 | [diff] [blame] | 59 | |
| 60 | |
Greg Edelston | 53d34a1 | 2023-03-27 15:43:53 -0600 | [diff] [blame^] | 61 | class EqTest(cros_test_lib.TestCase, api_config.ApiConfigMixin): |
| 62 | """Tests for the eq validator.""" |
| 63 | |
| 64 | def test_eq(self): |
| 65 | """Test a valid value.""" |
| 66 | |
| 67 | @validate.eq("location", common_pb2.Path.Location.OUTSIDE) |
| 68 | def impl(_input_proto, _output_proto, _config): |
| 69 | pass |
| 70 | |
| 71 | impl( |
| 72 | common_pb2.Path( |
| 73 | path="/", location=common_pb2.Path.Location.OUTSIDE |
| 74 | ), |
| 75 | None, |
| 76 | self.api_config, |
| 77 | ) |
| 78 | |
| 79 | def test_not_eq(self): |
| 80 | """Test an invalid value.""" |
| 81 | |
| 82 | @validate.eq("location", common_pb2.Path.Location.OUTSIDE) |
| 83 | def impl(_input_proto, _output_proto, _config): |
| 84 | pass |
| 85 | |
| 86 | # Should be failing on the invalid value. |
| 87 | with self.assertRaises(cros_build_lib.DieSystemExit): |
| 88 | impl( |
| 89 | common_pb2.Path( |
| 90 | path="/", location=common_pb2.Path.Location.INSIDE |
| 91 | ), |
| 92 | None, |
| 93 | self.api_config, |
| 94 | ) |
| 95 | |
| 96 | def test_not_set(self): |
| 97 | """Test an unset value.""" |
| 98 | |
| 99 | @validate.eq("location", common_pb2.Path.Location.OUTSIDE) |
| 100 | def impl(_input_proto, _output_proto, _config): |
| 101 | pass |
| 102 | |
| 103 | # Should be failing without a value set. |
| 104 | with self.assertRaises(cros_build_lib.DieSystemExit): |
| 105 | impl(common_pb2.Path(path="/"), None, self.api_config) |
| 106 | |
| 107 | def test_skip_validation(self): |
| 108 | """Test skipping validation case.""" |
| 109 | |
| 110 | @validate.eq("location", common_pb2.Path.Location.OUTSIDE) |
| 111 | def impl(_input_proto, _output_proto, _config): |
| 112 | pass |
| 113 | |
| 114 | # This would otherwise raise an error for an invalid path. |
| 115 | impl(common_pb2.Path(path="/"), None, self.no_validate_config) |
| 116 | |
| 117 | |
Alex Klein | 2008aee | 2019-08-20 16:25:27 -0600 | [diff] [blame] | 118 | class IsInTest(cros_test_lib.TestCase, api_config.ApiConfigMixin): |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 119 | """Tests for the is_in validator.""" |
Alex Klein | 231d2da | 2019-07-22 16:44:45 -0600 | [diff] [blame] | 120 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 121 | def test_in(self): |
| 122 | """Test a valid value.""" |
Alex Klein | 231d2da | 2019-07-22 16:44:45 -0600 | [diff] [blame] | 123 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 124 | @validate.is_in("path", ["/chroot/path", "/other/chroot/path"]) |
| 125 | def impl(_input_proto, _output_proto, _config): |
| 126 | pass |
Alex Klein | 231d2da | 2019-07-22 16:44:45 -0600 | [diff] [blame] | 127 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 128 | # Make sure all of the values work. |
| 129 | impl(common_pb2.Chroot(path="/chroot/path"), None, self.api_config) |
| 130 | impl( |
| 131 | common_pb2.Chroot(path="/other/chroot/path"), None, self.api_config |
| 132 | ) |
Alex Klein | 231d2da | 2019-07-22 16:44:45 -0600 | [diff] [blame] | 133 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 134 | def test_not_in(self): |
| 135 | """Test an invalid value.""" |
Alex Klein | 231d2da | 2019-07-22 16:44:45 -0600 | [diff] [blame] | 136 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 137 | @validate.is_in("path", ["/chroot/path", "/other/chroot/path"]) |
| 138 | def impl(_input_proto, _output_proto, _config): |
| 139 | pass |
Alex Klein | 231d2da | 2019-07-22 16:44:45 -0600 | [diff] [blame] | 140 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 141 | # Should be failing on the invalid value. |
| 142 | with self.assertRaises(cros_build_lib.DieSystemExit): |
| 143 | impl(common_pb2.Chroot(path="/bad/value"), None, self.api_config) |
Alex Klein | 2008aee | 2019-08-20 16:25:27 -0600 | [diff] [blame] | 144 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 145 | def test_not_set(self): |
| 146 | """Test an unset value.""" |
Alex Klein | 2008aee | 2019-08-20 16:25:27 -0600 | [diff] [blame] | 147 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 148 | @validate.is_in("path", ["/chroot/path", "/other/chroot/path"]) |
| 149 | def impl(_input_proto, _output_proto, _config): |
| 150 | pass |
| 151 | |
| 152 | # Should be failing without a value set. |
| 153 | with self.assertRaises(cros_build_lib.DieSystemExit): |
| 154 | impl(common_pb2.Chroot(), None, self.api_config) |
| 155 | |
| 156 | def test_skip_validation(self): |
| 157 | """Test skipping validation case.""" |
| 158 | |
| 159 | @validate.is_in("path", ["/chroot/path", "/other/chroot/path"]) |
| 160 | def impl(_input_proto, _output_proto, _config): |
| 161 | pass |
| 162 | |
| 163 | # This would otherwise raise an error for an invalid path. |
| 164 | impl(common_pb2.Chroot(), None, self.no_validate_config) |
Alex Klein | 231d2da | 2019-07-22 16:44:45 -0600 | [diff] [blame] | 165 | |
| 166 | |
Alex Klein | bdace30 | 2020-12-03 14:40:23 -0700 | [diff] [blame] | 167 | class EachInTest(cros_test_lib.TestCase, api_config.ApiConfigMixin): |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 168 | """Tests for the each_in validator.""" |
Alex Klein | bdace30 | 2020-12-03 14:40:23 -0700 | [diff] [blame] | 169 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 170 | # Easier access to the enum values. |
| 171 | ENUM_FOO = build_api_test_pb2.TEST_ENUM_FOO |
| 172 | ENUM_BAR = build_api_test_pb2.TEST_ENUM_BAR |
| 173 | ENUM_BAZ = build_api_test_pb2.TEST_ENUM_BAZ |
Alex Klein | bdace30 | 2020-12-03 14:40:23 -0700 | [diff] [blame] | 174 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 175 | # pylint: disable=docstring-misnamed-args |
| 176 | def _message_request(self, *messages): |
| 177 | """Build a request instance, filling out the messages field. |
Alex Klein | bdace30 | 2020-12-03 14:40:23 -0700 | [diff] [blame] | 178 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 179 | Args: |
Alex Klein | a044268 | 2022-10-10 13:47:38 -0600 | [diff] [blame] | 180 | messages: Each messages data (id, name, flag, enum) as lists. Only |
| 181 | requires as many as are set. e.g. _request([1], [2]) will create |
| 182 | two messages with only ids set. _request([1, 'name']) will |
| 183 | create one with id and name set, but not flag or enum. |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 184 | """ |
| 185 | request = build_api_test_pb2.TestRequestMessage() |
| 186 | for message in messages or []: |
| 187 | msg = request.messages.add() |
| 188 | try: |
| 189 | msg.id = message[0] |
| 190 | msg.name = message[1] |
| 191 | msg.flag = message[2] |
| 192 | except IndexError: |
| 193 | pass |
Alex Klein | bdace30 | 2020-12-03 14:40:23 -0700 | [diff] [blame] | 194 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 195 | return request |
Alex Klein | bdace30 | 2020-12-03 14:40:23 -0700 | [diff] [blame] | 196 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 197 | def _enums_request(self, *enum_values): |
| 198 | """Build a request instance, setting the test_enums field.""" |
| 199 | request = build_api_test_pb2.TestRequestMessage() |
| 200 | for value in enum_values: |
| 201 | request.test_enums.append(value) |
Alex Klein | bdace30 | 2020-12-03 14:40:23 -0700 | [diff] [blame] | 202 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 203 | return request |
Alex Klein | bdace30 | 2020-12-03 14:40:23 -0700 | [diff] [blame] | 204 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 205 | def _numbers_request(self, *numbers): |
| 206 | """Build a request instance, setting the numbers field.""" |
| 207 | request = build_api_test_pb2.TestRequestMessage() |
| 208 | request.numbers.extend(numbers) |
Alex Klein | bdace30 | 2020-12-03 14:40:23 -0700 | [diff] [blame] | 209 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 210 | return request |
Alex Klein | bdace30 | 2020-12-03 14:40:23 -0700 | [diff] [blame] | 211 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 212 | def test_message_in(self): |
| 213 | """Test valid values.""" |
Alex Klein | bdace30 | 2020-12-03 14:40:23 -0700 | [diff] [blame] | 214 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 215 | @validate.each_in("messages", "name", ["foo", "bar"]) |
| 216 | def impl(_input_proto, _output_proto, _config): |
| 217 | pass |
Alex Klein | bdace30 | 2020-12-03 14:40:23 -0700 | [diff] [blame] | 218 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 219 | impl(self._message_request([1, "foo"]), None, self.api_config) |
| 220 | impl( |
| 221 | self._message_request([1, "foo"], [2, "bar"]), None, self.api_config |
| 222 | ) |
Alex Klein | bdace30 | 2020-12-03 14:40:23 -0700 | [diff] [blame] | 223 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 224 | def test_enum_in(self): |
| 225 | """Test valid enum values.""" |
Alex Klein | bdace30 | 2020-12-03 14:40:23 -0700 | [diff] [blame] | 226 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 227 | @validate.each_in("test_enums", None, [self.ENUM_FOO, self.ENUM_BAR]) |
| 228 | def impl(_input_proto, _output_proto, _config): |
| 229 | pass |
Alex Klein | bdace30 | 2020-12-03 14:40:23 -0700 | [diff] [blame] | 230 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 231 | impl(self._enums_request(self.ENUM_FOO), None, self.api_config) |
| 232 | impl( |
| 233 | self._enums_request(self.ENUM_FOO, self.ENUM_BAR), |
| 234 | None, |
| 235 | self.api_config, |
| 236 | ) |
Alex Klein | bdace30 | 2020-12-03 14:40:23 -0700 | [diff] [blame] | 237 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 238 | def test_scalar_in(self): |
| 239 | """Test valid scalar values.""" |
Alex Klein | bdace30 | 2020-12-03 14:40:23 -0700 | [diff] [blame] | 240 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 241 | @validate.each_in("numbers", None, [1, 2]) |
| 242 | def impl(_input_proto, _output_proto, _config): |
| 243 | pass |
Alex Klein | bdace30 | 2020-12-03 14:40:23 -0700 | [diff] [blame] | 244 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 245 | impl(self._numbers_request(1), None, self.api_config) |
| 246 | impl(self._numbers_request(1, 2), None, self.api_config) |
Alex Klein | bdace30 | 2020-12-03 14:40:23 -0700 | [diff] [blame] | 247 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 248 | def test_message_not_in(self): |
| 249 | """Test an invalid value.""" |
Alex Klein | bdace30 | 2020-12-03 14:40:23 -0700 | [diff] [blame] | 250 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 251 | @validate.each_in("messages", "name", ["foo", "bar"]) |
| 252 | def impl(_input_proto, _output_proto, _config): |
| 253 | pass |
Alex Klein | bdace30 | 2020-12-03 14:40:23 -0700 | [diff] [blame] | 254 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 255 | # Should be failing on the invalid value. |
| 256 | with self.assertRaises(cros_build_lib.DieSystemExit): |
| 257 | impl(self._message_request([1, "invalid"]), None, self.api_config) |
| 258 | with self.assertRaises(cros_build_lib.DieSystemExit): |
| 259 | impl( |
| 260 | self._message_request([1, "invalid"], [2, "invalid"]), |
| 261 | None, |
| 262 | self.api_config, |
| 263 | ) |
| 264 | with self.assertRaises(cros_build_lib.DieSystemExit): |
| 265 | impl( |
| 266 | self._message_request([1, "foo"], [2, "invalid"]), |
| 267 | None, |
| 268 | self.api_config, |
| 269 | ) |
Alex Klein | bdace30 | 2020-12-03 14:40:23 -0700 | [diff] [blame] | 270 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 271 | def test_enum_not_in(self): |
| 272 | """Test an invalid enum value.""" |
Alex Klein | bdace30 | 2020-12-03 14:40:23 -0700 | [diff] [blame] | 273 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 274 | @validate.each_in("test_enums", None, [self.ENUM_FOO, self.ENUM_BAR]) |
| 275 | def impl(_input_proto, _output_proto, _config): |
| 276 | pass |
Alex Klein | bdace30 | 2020-12-03 14:40:23 -0700 | [diff] [blame] | 277 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 278 | # Only invalid values. |
| 279 | with self.assertRaises(cros_build_lib.DieSystemExit): |
| 280 | impl(self._enums_request(self.ENUM_BAZ), None, self.api_config) |
| 281 | # Mixed valid/invalid values. |
| 282 | with self.assertRaises(cros_build_lib.DieSystemExit): |
| 283 | impl( |
| 284 | self._enums_request(self.ENUM_FOO, self.ENUM_BAZ), |
| 285 | None, |
| 286 | self.api_config, |
| 287 | ) |
Alex Klein | bdace30 | 2020-12-03 14:40:23 -0700 | [diff] [blame] | 288 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 289 | def test_scalar_not_in(self): |
| 290 | """Test invalid scalar value.""" |
Alex Klein | bdace30 | 2020-12-03 14:40:23 -0700 | [diff] [blame] | 291 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 292 | @validate.each_in("numbers", None, [1, 2]) |
| 293 | def impl(_input_proto, _output_proto, _config): |
| 294 | pass |
Alex Klein | bdace30 | 2020-12-03 14:40:23 -0700 | [diff] [blame] | 295 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 296 | # Only invalid values. |
| 297 | with self.assertRaises(cros_build_lib.DieSystemExit): |
| 298 | impl(self._numbers_request(3), None, self.api_config) |
| 299 | # Mixed valid/invalid values. |
| 300 | with self.assertRaises(cros_build_lib.DieSystemExit): |
| 301 | impl(self._numbers_request(1, 2, 3), None, self.api_config) |
Alex Klein | bdace30 | 2020-12-03 14:40:23 -0700 | [diff] [blame] | 302 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 303 | def test_not_set(self): |
| 304 | """Test an unset value.""" |
Alex Klein | bdace30 | 2020-12-03 14:40:23 -0700 | [diff] [blame] | 305 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 306 | @validate.each_in("messages", "name", ["foo", "bar"]) |
| 307 | def impl(_input_proto, _output_proto, _config): |
| 308 | pass |
Alex Klein | bdace30 | 2020-12-03 14:40:23 -0700 | [diff] [blame] | 309 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 310 | # Should be failing without a value set. |
| 311 | # No entries in the field. |
| 312 | with self.assertRaises(cros_build_lib.DieSystemExit): |
| 313 | impl(self._message_request(), None, self.api_config) |
| 314 | # No value set on lone entry. |
| 315 | with self.assertRaises(cros_build_lib.DieSystemExit): |
| 316 | impl(self._message_request([1]), None, self.api_config) |
| 317 | # No value set on multiple entries. |
| 318 | with self.assertRaises(cros_build_lib.DieSystemExit): |
| 319 | impl(self._message_request([1], [2]), None, self.api_config) |
| 320 | # Some valid and some invalid entries. |
| 321 | with self.assertRaises(cros_build_lib.DieSystemExit): |
| 322 | impl(self._message_request([1, "foo"], [2]), None, self.api_config) |
Alex Klein | bdace30 | 2020-12-03 14:40:23 -0700 | [diff] [blame] | 323 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 324 | def test_optional(self): |
| 325 | """Test optional argument.""" |
Alex Klein | bdace30 | 2020-12-03 14:40:23 -0700 | [diff] [blame] | 326 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 327 | @validate.each_in("messages", "name", ["foo", "bar"], optional=True) |
| 328 | @validate.each_in( |
| 329 | "test_enums", None, [self.ENUM_FOO, self.ENUM_BAR], optional=True |
| 330 | ) |
| 331 | @validate.each_in("numbers", None, [1, 2], optional=True) |
| 332 | def impl(_input_proto, _output_proto, _config): |
| 333 | pass |
Alex Klein | bdace30 | 2020-12-03 14:40:23 -0700 | [diff] [blame] | 334 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 335 | # No entries in the field succeeds. |
| 336 | impl(self._message_request(), None, self.api_config) |
Alex Klein | bdace30 | 2020-12-03 14:40:23 -0700 | [diff] [blame] | 337 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 338 | # Still fails when entries exist but value unset cases. |
| 339 | # No value set on lone entry. |
| 340 | with self.assertRaises(cros_build_lib.DieSystemExit): |
| 341 | impl(self._message_request([1]), None, self.api_config) |
| 342 | # No value set on multiple entries. |
| 343 | with self.assertRaises(cros_build_lib.DieSystemExit): |
| 344 | impl(self._message_request([1], [2]), None, self.api_config) |
| 345 | # Some valid and some invalid entries. |
| 346 | with self.assertRaises(cros_build_lib.DieSystemExit): |
| 347 | impl(self._message_request([1, "foo"], [2]), None, self.api_config) |
Alex Klein | bdace30 | 2020-12-03 14:40:23 -0700 | [diff] [blame] | 348 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 349 | def test_skip_validation(self): |
| 350 | """Test skipping validation case.""" |
Alex Klein | bdace30 | 2020-12-03 14:40:23 -0700 | [diff] [blame] | 351 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 352 | @validate.each_in("messages", "name", ["foo", "bar"]) |
| 353 | @validate.each_in("test_enums", None, [self.ENUM_FOO, self.ENUM_BAR]) |
| 354 | @validate.each_in("numbers", None, [1, 2]) |
| 355 | def impl(_input_proto, _output_proto, _config): |
| 356 | pass |
Alex Klein | bdace30 | 2020-12-03 14:40:23 -0700 | [diff] [blame] | 357 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 358 | # This would otherwise raise an error for multiple invalid fields. |
| 359 | impl( |
| 360 | self._message_request([1, "invalid"]), None, self.no_validate_config |
| 361 | ) |
Alex Klein | bdace30 | 2020-12-03 14:40:23 -0700 | [diff] [blame] | 362 | |
| 363 | |
Alex Klein | 60c8052 | 2020-10-13 18:05:38 -0600 | [diff] [blame] | 364 | class RequireTest(cros_test_lib.TestCase, api_config.ApiConfigMixin): |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 365 | """Tests for the require validator.""" |
Alex Klein | 2b23672 | 2019-06-19 15:44:26 -0600 | [diff] [blame] | 366 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 367 | def test_invalid_field(self): |
| 368 | """Test validator fails when given an unset value.""" |
Alex Klein | 2b23672 | 2019-06-19 15:44:26 -0600 | [diff] [blame] | 369 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 370 | @validate.require("does.not.exist") |
| 371 | def impl(_input_proto, _output_proto, _config): |
| 372 | self.fail("Incorrectly allowed method to execute.") |
Alex Klein | 2b23672 | 2019-06-19 15:44:26 -0600 | [diff] [blame] | 373 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 374 | with self.assertRaises(cros_build_lib.DieSystemExit): |
| 375 | impl(common_pb2.Chroot(), None, self.api_config) |
Alex Klein | 2b23672 | 2019-06-19 15:44:26 -0600 | [diff] [blame] | 376 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 377 | def test_not_set(self): |
| 378 | """Test validator fails when given an unset value.""" |
Alex Klein | 2b23672 | 2019-06-19 15:44:26 -0600 | [diff] [blame] | 379 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 380 | @validate.require("env.use_flags") |
| 381 | def impl(_input_proto, _output_proto, _config): |
| 382 | self.fail("Incorrectly allowed method to execute.") |
Alex Klein | 2b23672 | 2019-06-19 15:44:26 -0600 | [diff] [blame] | 383 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 384 | with self.assertRaises(cros_build_lib.DieSystemExit): |
| 385 | impl(common_pb2.Chroot(), None, self.api_config) |
Alex Klein | 2b23672 | 2019-06-19 15:44:26 -0600 | [diff] [blame] | 386 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 387 | def test_set(self): |
| 388 | """Test validator passes when given set values.""" |
Alex Klein | 2b23672 | 2019-06-19 15:44:26 -0600 | [diff] [blame] | 389 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 390 | @validate.require("path", "env.use_flags") |
| 391 | def impl(_input_proto, _output_proto, _config): |
| 392 | pass |
Alex Klein | 2b23672 | 2019-06-19 15:44:26 -0600 | [diff] [blame] | 393 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 394 | in_proto = common_pb2.Chroot( |
| 395 | path="/chroot/path", env={"use_flags": [{"flag": "test"}]} |
| 396 | ) |
| 397 | impl(in_proto, None, self.api_config) |
Alex Klein | 2b23672 | 2019-06-19 15:44:26 -0600 | [diff] [blame] | 398 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 399 | def test_mixed(self): |
| 400 | """Test validator fails when given a set value and an unset value.""" |
Alex Klein | 2b23672 | 2019-06-19 15:44:26 -0600 | [diff] [blame] | 401 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 402 | @validate.require("path", "env.use_flags") |
| 403 | def impl(_input_proto, _output_proto, _config): |
| 404 | pass |
Alex Klein | 2b23672 | 2019-06-19 15:44:26 -0600 | [diff] [blame] | 405 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 406 | with self.assertRaises(cros_build_lib.DieSystemExit): |
| 407 | impl(common_pb2.Chroot(path="/chroot/path"), None, self.api_config) |
Alex Klein | 2008aee | 2019-08-20 16:25:27 -0600 | [diff] [blame] | 408 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 409 | def test_skip_validation(self): |
| 410 | """Test skipping validation case.""" |
Alex Klein | 2008aee | 2019-08-20 16:25:27 -0600 | [diff] [blame] | 411 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 412 | @validate.require("path", "env.use_flags") |
| 413 | def impl(_input_proto, _output_proto, _config): |
| 414 | pass |
| 415 | |
| 416 | # This would otherwise raise an error for an invalid path. |
| 417 | impl(common_pb2.Chroot(), None, self.no_validate_config) |
Alex Klein | 69339cc | 2019-07-22 14:08:35 -0600 | [diff] [blame] | 418 | |
| 419 | |
Alex Klein | 60c8052 | 2020-10-13 18:05:38 -0600 | [diff] [blame] | 420 | class RequireAnyTest(cros_test_lib.TestCase, api_config.ApiConfigMixin): |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 421 | """Tests for the require_any validator.""" |
Alex Klein | 60c8052 | 2020-10-13 18:05:38 -0600 | [diff] [blame] | 422 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 423 | def _get_request( |
| 424 | self, mid: int = None, name: str = None, flag: bool = None |
| 425 | ): |
| 426 | """Build a request instance from the given data.""" |
| 427 | request = build_api_test_pb2.MultiFieldMessage() |
Alex Klein | 60c8052 | 2020-10-13 18:05:38 -0600 | [diff] [blame] | 428 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 429 | if mid: |
| 430 | request.id = mid |
| 431 | if name: |
| 432 | request.name = name |
| 433 | if flag: |
| 434 | request.flag = flag |
Alex Klein | 60c8052 | 2020-10-13 18:05:38 -0600 | [diff] [blame] | 435 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 436 | return request |
Alex Klein | 60c8052 | 2020-10-13 18:05:38 -0600 | [diff] [blame] | 437 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 438 | def test_invalid_field(self): |
| 439 | """Test validator fails when given an invalid field.""" |
Alex Klein | 60c8052 | 2020-10-13 18:05:38 -0600 | [diff] [blame] | 440 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 441 | @validate.require_any("does.not.exist", "also.invalid") |
| 442 | def impl(_input_proto, _output_proto, _config): |
| 443 | self.fail("Incorrectly allowed method to execute.") |
Alex Klein | 60c8052 | 2020-10-13 18:05:38 -0600 | [diff] [blame] | 444 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 445 | with self.assertRaises(cros_build_lib.DieSystemExit): |
| 446 | impl(self._get_request(), None, self.api_config) |
Alex Klein | 60c8052 | 2020-10-13 18:05:38 -0600 | [diff] [blame] | 447 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 448 | def test_not_set(self): |
| 449 | """Test validator fails when given unset values.""" |
Alex Klein | 60c8052 | 2020-10-13 18:05:38 -0600 | [diff] [blame] | 450 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 451 | @validate.require_any("id", "name") |
| 452 | def impl(_input_proto, _output_proto, _config): |
| 453 | self.fail("Incorrectly allowed method to execute.") |
Alex Klein | 60c8052 | 2020-10-13 18:05:38 -0600 | [diff] [blame] | 454 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 455 | with self.assertRaises(cros_build_lib.DieSystemExit): |
| 456 | impl(self._get_request(flag=True), None, self.api_config) |
Alex Klein | 60c8052 | 2020-10-13 18:05:38 -0600 | [diff] [blame] | 457 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 458 | def test_set(self): |
| 459 | """Test validator passes when given set values.""" |
Alex Klein | 60c8052 | 2020-10-13 18:05:38 -0600 | [diff] [blame] | 460 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 461 | @validate.require_any("id", "name") |
| 462 | def impl(_input_proto, _output_proto, _config): |
| 463 | pass |
Alex Klein | 60c8052 | 2020-10-13 18:05:38 -0600 | [diff] [blame] | 464 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 465 | impl(self._get_request(1), None, self.api_config) |
| 466 | impl(self._get_request(name="foo"), None, self.api_config) |
| 467 | impl(self._get_request(1, name="foo"), None, self.api_config) |
Alex Klein | 60c8052 | 2020-10-13 18:05:38 -0600 | [diff] [blame] | 468 | |
| 469 | |
Alex Klein | 86242bf | 2020-09-22 15:23:23 -0600 | [diff] [blame] | 470 | class RequireEachTest(cros_test_lib.TestCase, api_config.ApiConfigMixin): |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 471 | """Tests for the require_each validator.""" |
Alex Klein | 86242bf | 2020-09-22 15:23:23 -0600 | [diff] [blame] | 472 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 473 | def _multi_field_message(self, msg_id=None, name=None, flag=None): |
| 474 | msg = build_api_test_pb2.MultiFieldMessage() |
| 475 | if msg_id is not None: |
| 476 | msg.id = int(msg_id) |
| 477 | if name is not None: |
| 478 | msg.name = str(name) |
| 479 | if flag is not None: |
| 480 | msg.flag = bool(flag) |
| 481 | return msg |
Alex Klein | 86242bf | 2020-09-22 15:23:23 -0600 | [diff] [blame] | 482 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 483 | def _request(self, messages=None, count=0): |
| 484 | """Build the request.""" |
| 485 | if messages is None: |
| 486 | messages = [self._multi_field_message() for _ in range(count)] |
Alex Klein | 86242bf | 2020-09-22 15:23:23 -0600 | [diff] [blame] | 487 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 488 | request = build_api_test_pb2.TestRequestMessage() |
| 489 | for message in messages: |
| 490 | msg = request.messages.add() |
| 491 | msg.CopyFrom(message) |
Alex Klein | 86242bf | 2020-09-22 15:23:23 -0600 | [diff] [blame] | 492 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 493 | return request |
Alex Klein | 86242bf | 2020-09-22 15:23:23 -0600 | [diff] [blame] | 494 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 495 | def test_invalid_field(self): |
| 496 | """Test validator fails when given an invalid field.""" |
Alex Klein | 86242bf | 2020-09-22 15:23:23 -0600 | [diff] [blame] | 497 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 498 | @validate.require_each("does.not", ["exist"]) |
| 499 | def impl(_input_proto, _output_proto, _config): |
| 500 | self.fail("Incorrectly allowed method to execute.") |
Alex Klein | 86242bf | 2020-09-22 15:23:23 -0600 | [diff] [blame] | 501 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 502 | with self.assertRaises(cros_build_lib.DieSystemExit): |
| 503 | impl(self._request(), None, self.api_config) |
Alex Klein | 86242bf | 2020-09-22 15:23:23 -0600 | [diff] [blame] | 504 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 505 | def test_invalid_call_no_subfields(self): |
| 506 | """Test validator fails when given no subfields.""" |
Alex Klein | 86242bf | 2020-09-22 15:23:23 -0600 | [diff] [blame] | 507 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 508 | with self.assertRaises(AssertionError): |
Alex Klein | 86242bf | 2020-09-22 15:23:23 -0600 | [diff] [blame] | 509 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 510 | @validate.require_each("does.not", []) |
| 511 | def _(_input_proto, _output_proto, _config): |
| 512 | pass |
Alex Klein | 86242bf | 2020-09-22 15:23:23 -0600 | [diff] [blame] | 513 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 514 | def test_invalid_call_invalid_subfields(self): |
| 515 | """Test validator fails when given subfields incorrectly.""" |
Alex Klein | 86242bf | 2020-09-22 15:23:23 -0600 | [diff] [blame] | 516 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 517 | with self.assertRaises(AssertionError): |
Alex Klein | 86242bf | 2020-09-22 15:23:23 -0600 | [diff] [blame] | 518 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 519 | @validate.require_each("does.not", "exist") |
| 520 | def _(_input_proto, _output_proto, _config): |
| 521 | pass |
Alex Klein | 86242bf | 2020-09-22 15:23:23 -0600 | [diff] [blame] | 522 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 523 | def test_not_set(self): |
| 524 | """Test validator fails when given an unset value.""" |
Alex Klein | 86242bf | 2020-09-22 15:23:23 -0600 | [diff] [blame] | 525 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 526 | @validate.require_each("messages", ["id"]) |
| 527 | def impl(_input_proto, _output_proto, _config): |
| 528 | self.fail("Incorrectly allowed method to execute.") |
Alex Klein | 86242bf | 2020-09-22 15:23:23 -0600 | [diff] [blame] | 529 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 530 | with self.assertRaises(cros_build_lib.DieSystemExit): |
| 531 | impl(self._request(count=2), None, self.api_config) |
Alex Klein | 86242bf | 2020-09-22 15:23:23 -0600 | [diff] [blame] | 532 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 533 | def test_no_elements_success(self): |
| 534 | """Test validator fails when given no messages in the repeated field.""" |
Alex Klein | 86242bf | 2020-09-22 15:23:23 -0600 | [diff] [blame] | 535 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 536 | @validate.require_each("messages", ["id"]) |
| 537 | def impl(_input_proto, _output_proto, _config): |
| 538 | pass |
Alex Klein | 86242bf | 2020-09-22 15:23:23 -0600 | [diff] [blame] | 539 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 540 | impl(self._request(), None, self.api_config) |
Alex Klein | 86242bf | 2020-09-22 15:23:23 -0600 | [diff] [blame] | 541 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 542 | def test_no_elements_failure(self): |
| 543 | """Test validator fails when given no messages in the repeated field.""" |
Alex Klein | 86242bf | 2020-09-22 15:23:23 -0600 | [diff] [blame] | 544 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 545 | @validate.require_each("messages", ["id"], allow_empty=False) |
| 546 | def impl(_input_proto, _output_proto, _config): |
| 547 | self.fail("Incorrectly allowed method to execute.") |
Alex Klein | 86242bf | 2020-09-22 15:23:23 -0600 | [diff] [blame] | 548 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 549 | with self.assertRaises(cros_build_lib.DieSystemExit): |
| 550 | impl(self._request(), None, self.api_config) |
Alex Klein | 86242bf | 2020-09-22 15:23:23 -0600 | [diff] [blame] | 551 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 552 | def test_set(self): |
| 553 | """Test validator passes when given set values.""" |
Alex Klein | 86242bf | 2020-09-22 15:23:23 -0600 | [diff] [blame] | 554 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 555 | @validate.require_each("messages", ["id"]) |
| 556 | def impl(_input_proto, _output_proto, _config): |
| 557 | pass |
Alex Klein | 86242bf | 2020-09-22 15:23:23 -0600 | [diff] [blame] | 558 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 559 | messages = [self._multi_field_message(msg_id=i) for i in range(1, 5)] |
| 560 | impl(self._request(messages=messages), None, self.api_config) |
Alex Klein | 86242bf | 2020-09-22 15:23:23 -0600 | [diff] [blame] | 561 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 562 | def test_one_set_fails(self): |
| 563 | """Test validator passes when given set values.""" |
Alex Klein | 86242bf | 2020-09-22 15:23:23 -0600 | [diff] [blame] | 564 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 565 | @validate.require_each("messages", ["id", "name"]) |
| 566 | def impl(_input_proto, _output_proto, _config): |
| 567 | pass |
Alex Klein | 86242bf | 2020-09-22 15:23:23 -0600 | [diff] [blame] | 568 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 569 | messages = [self._multi_field_message(msg_id=i) for i in range(1, 5)] |
| 570 | with self.assertRaises(cros_build_lib.DieSystemExit): |
| 571 | impl(self._request(messages=messages), None, self.api_config) |
Alex Klein | 86242bf | 2020-09-22 15:23:23 -0600 | [diff] [blame] | 572 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 573 | def test_multi_set(self): |
| 574 | """Test validator passes when all values set.""" |
Alex Klein | 86242bf | 2020-09-22 15:23:23 -0600 | [diff] [blame] | 575 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 576 | @validate.require_each("messages", ["id", "name"]) |
| 577 | def impl(_input_proto, _output_proto, _config): |
| 578 | pass |
Alex Klein | 86242bf | 2020-09-22 15:23:23 -0600 | [diff] [blame] | 579 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 580 | messages = [ |
| 581 | self._multi_field_message(msg_id=i, name=i) for i in range(1, 5) |
| 582 | ] |
| 583 | impl(self._request(messages=messages), None, self.api_config) |
| 584 | |
| 585 | def test_skip_validation(self): |
| 586 | """Test skipping validation case.""" |
| 587 | |
| 588 | @validate.require_each("messages", ["id"], allow_empty=False) |
| 589 | def impl(_input_proto, _output_proto, _config): |
| 590 | pass |
| 591 | |
| 592 | impl(self._request(), None, self.no_validate_config) |
Alex Klein | 86242bf | 2020-09-22 15:23:23 -0600 | [diff] [blame] | 593 | |
| 594 | |
Alex Klein | 69339cc | 2019-07-22 14:08:35 -0600 | [diff] [blame] | 595 | class ValidateOnlyTest(cros_test_lib.TestCase, api_config.ApiConfigMixin): |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 596 | """validate_only decorator tests.""" |
Alex Klein | 69339cc | 2019-07-22 14:08:35 -0600 | [diff] [blame] | 597 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 598 | def test_validate_only(self): |
| 599 | """Test validate only.""" |
Alex Klein | 69339cc | 2019-07-22 14:08:35 -0600 | [diff] [blame] | 600 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 601 | @validate.require("path") |
| 602 | @validate.validation_complete |
| 603 | def impl(_input_proto, _output_proto, _config): |
| 604 | self.fail("Implementation was called.") |
| 605 | return 1 |
Alex Klein | 69339cc | 2019-07-22 14:08:35 -0600 | [diff] [blame] | 606 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 607 | # Just using arbitrary messages, we just need the |
| 608 | # (request, response, config) arguments so it can check the config. |
| 609 | rc = impl( |
| 610 | common_pb2.Chroot(path="/chroot/path"), |
| 611 | common_pb2.Chroot(), |
| 612 | self.validate_only_config, |
| 613 | ) |
Alex Klein | 69339cc | 2019-07-22 14:08:35 -0600 | [diff] [blame] | 614 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 615 | self.assertEqual(0, rc) |
Alex Klein | 69339cc | 2019-07-22 14:08:35 -0600 | [diff] [blame] | 616 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 617 | def test_no_validate_only(self): |
| 618 | """Test no use of validate only.""" |
| 619 | |
| 620 | @validate.validation_complete |
| 621 | def impl(_input_proto, _output_proto, _config): |
| 622 | self.fail("Incorrectly allowed method to execute.") |
| 623 | |
Alex Klein | 54c891a | 2023-01-24 10:45:41 -0700 | [diff] [blame] | 624 | # We will get an assertion error unless validate_only prevents the |
| 625 | # function from being called. |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 626 | with self.assertRaises(AssertionError): |
| 627 | impl(common_pb2.Chroot(), common_pb2.Chroot(), self.api_config) |