blob: e6b84ecb3367b31a84a0e7b0b0d44b157694617d [file] [log] [blame]
Bob King386d33f2019-12-26 17:28:56 +08001/**
Bob King0dcbdf52020-01-20 17:19:39 +08002 * Copyright c 2020 IBM Corporation
Bob King386d33f2019-12-26 17:28:56 +08003 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
Shawn McCarney0f6ebad2020-09-04 16:43:00 -050016#include "temporary_file.hpp"
Shawn McCarney80c0b042020-03-27 12:08:53 -050017
18#include <stdio.h> // for popen(), pclose(), fgets()
19#include <sys/stat.h> // for chmod()
20#include <sys/wait.h> // for WEXITSTATUS
Bob King386d33f2019-12-26 17:28:56 +080021
Bob King386d33f2019-12-26 17:28:56 +080022#include <nlohmann/json.hpp>
23
Shawn McCarney80c0b042020-03-27 12:08:53 -050024#include <cstdio>
Bob King0dcbdf52020-01-20 17:19:39 +080025#include <fstream>
26
Bob King386d33f2019-12-26 17:28:56 +080027#include <gtest/gtest.h>
28
29#define EXPECT_FILE_VALID(configFile) expectFileValid(configFile)
30#define EXPECT_FILE_INVALID(configFile, expectedErrorMessage, \
31 expectedOutputMessage) \
32 expectFileInvalid(configFile, expectedErrorMessage, expectedOutputMessage)
33#define EXPECT_JSON_VALID(configFileJson) expectJsonValid(configFileJson)
34#define EXPECT_JSON_INVALID(configFileJson, expectedErrorMessage, \
35 expectedOutputMessage) \
36 expectJsonInvalid(configFileJson, expectedErrorMessage, \
37 expectedOutputMessage)
38
Shawn McCarney80c0b042020-03-27 12:08:53 -050039using namespace phosphor::power::regulators;
Bob King386d33f2019-12-26 17:28:56 +080040using json = nlohmann::json;
41
42const json validConfigFile = R"(
43 {
44 "comments": [ "Config file for a FooBar one-chassis system" ],
45
46 "rules": [
47 {
48 "comments": [ "Sets output voltage for a PMBus regulator rail" ],
49 "id": "set_voltage_rule",
50 "actions": [
51 {
52 "pmbus_write_vout_command": {
53 "format": "linear"
54 }
55 }
56 ]
Bob Kingb3e48bc2020-02-18 09:59:09 +080057 },
58 {
59 "comments": [ "Reads sensors from a PMBus regulator rail" ],
60 "id": "read_sensors_rule",
61 "actions": [
62 {
63 "comments": [ "Read output voltage from READ_VOUT." ],
64 "pmbus_read_sensor": {
65 "type": "vout",
66 "command": "0x8B",
67 "format": "linear_16"
68 }
69 }
70 ]
Bob King386d33f2019-12-26 17:28:56 +080071 }
72 ],
73
74 "chassis": [
75 {
76 "comments": [ "Chassis number 1 containing CPUs and memory" ],
77 "number": 1,
Shawn McCarneyecbeeea2021-04-29 21:08:18 -050078 "inventory_path": "system/chassis",
Bob King386d33f2019-12-26 17:28:56 +080079 "devices": [
80 {
81 "comments": [ "IR35221 regulator producing the Vdd rail" ],
82 "id": "vdd_regulator",
83 "is_regulator": true,
Bob Kinga76898f2020-10-13 15:08:33 +080084 "fru": "system/chassis/motherboard/regulator1",
Bob King386d33f2019-12-26 17:28:56 +080085 "i2c_interface": {
86 "bus": 1,
87 "address": "0x70"
88 },
89 "rails": [
90 {
91 "comments": [ "Vdd rail" ],
92 "id": "vdd",
93 "configuration": {
94 "volts": 1.03,
95 "rule_id": "set_voltage_rule"
96 },
97 "sensor_monitoring": {
98 "rule_id": "read_sensors_rule"
99 }
100 }
101 ]
102 }
103 ]
104 }
105 ]
106 }
107)"_json;
108
Bob King386d33f2019-12-26 17:28:56 +0800109std::string getValidationToolCommand(const std::string& configFileName)
110{
Bob Kinga57e0812020-03-12 10:47:42 +0800111 std::string command =
112 "../phosphor-regulators/tools/validate-regulators-config.py -s \
113 ../phosphor-regulators/schema/config_schema.json -c ";
Bob King386d33f2019-12-26 17:28:56 +0800114 command += configFileName;
115 return command;
116}
117
Bob Kinga57e0812020-03-12 10:47:42 +0800118int runToolForOutputWithCommand(std::string command,
119 std::string& standardOutput,
120 std::string& standardError)
Bob King386d33f2019-12-26 17:28:56 +0800121{
122 // run the validation tool with the temporary file and return the output
123 // of the validation tool.
Shawn McCarney0f6ebad2020-09-04 16:43:00 -0500124 TemporaryFile tmpFile;
125 command += " 2> " + tmpFile.getPath().string();
Bob King386d33f2019-12-26 17:28:56 +0800126 // get the jsonschema print from validation tool.
127 char buffer[256];
Bob Kinga57e0812020-03-12 10:47:42 +0800128 std::string result;
Bob King386d33f2019-12-26 17:28:56 +0800129 // to get the stdout from the validation tool.
130 FILE* pipe = popen(command.c_str(), "r");
131 if (!pipe)
132 {
133 throw std::runtime_error("popen() failed!");
134 }
135 while (!std::feof(pipe))
136 {
137 if (fgets(buffer, sizeof buffer, pipe) != NULL)
138 {
139 result += buffer;
140 }
141 }
142 int returnValue = pclose(pipe);
143 // Check if pclose() failed
144 if (returnValue == -1)
145 {
146 // unable to close pipe. Print error and exit function.
147 throw std::runtime_error("pclose() failed!");
148 }
149 std::string firstLine = result.substr(0, result.find('\n'));
Bob Kinga57e0812020-03-12 10:47:42 +0800150 standardOutput = firstLine;
Bob King386d33f2019-12-26 17:28:56 +0800151 // Get command exit status from return value
152 int exitStatus = WEXITSTATUS(returnValue);
Bob Kinga57e0812020-03-12 10:47:42 +0800153
154 // Read the standardError from tmpFile.
Shawn McCarney0f6ebad2020-09-04 16:43:00 -0500155 std::ifstream input(tmpFile.getPath());
Bob Kinga57e0812020-03-12 10:47:42 +0800156 std::string line;
157
158 if (std::getline(input, line))
159 {
160 standardError = line;
161 }
162
Bob King386d33f2019-12-26 17:28:56 +0800163 return exitStatus;
164}
165
Bob Kinged009652020-02-20 14:54:13 +0800166int runToolForOutput(const std::string& configFileName, std::string& output,
Bob Kinga57e0812020-03-12 10:47:42 +0800167 std::string& error)
Bob Kinged009652020-02-20 14:54:13 +0800168{
169 std::string command = getValidationToolCommand(configFileName);
Bob Kinga57e0812020-03-12 10:47:42 +0800170 return runToolForOutputWithCommand(command, output, error);
Bob Kinged009652020-02-20 14:54:13 +0800171}
172
Bob King386d33f2019-12-26 17:28:56 +0800173void expectFileValid(const std::string& configFileName)
174{
Bob Kinged009652020-02-20 14:54:13 +0800175 std::string errorMessage;
176 std::string outputMessage;
Bob Kinga57e0812020-03-12 10:47:42 +0800177 EXPECT_EQ(runToolForOutput(configFileName, outputMessage, errorMessage), 0);
Bob King386d33f2019-12-26 17:28:56 +0800178 EXPECT_EQ(errorMessage, "");
179 EXPECT_EQ(outputMessage, "");
180}
181
182void expectFileInvalid(const std::string& configFileName,
183 const std::string& expectedErrorMessage,
184 const std::string& expectedOutputMessage)
185{
Bob Kinged009652020-02-20 14:54:13 +0800186 std::string errorMessage;
187 std::string outputMessage;
Bob Kinga57e0812020-03-12 10:47:42 +0800188 EXPECT_EQ(runToolForOutput(configFileName, outputMessage, errorMessage), 1);
Bob King386d33f2019-12-26 17:28:56 +0800189 EXPECT_EQ(errorMessage, expectedErrorMessage);
190 EXPECT_EQ(outputMessage, expectedOutputMessage);
191}
192
Bob Kinga57e0812020-03-12 10:47:42 +0800193void writeDataToFile(const json configFileJson, std::string fileName)
Bob King386d33f2019-12-26 17:28:56 +0800194{
Bob King386d33f2019-12-26 17:28:56 +0800195 std::string jsonData = configFileJson.dump();
196 std::ofstream out(fileName);
197 out << jsonData;
198 out.close();
Bob Kinged009652020-02-20 14:54:13 +0800199}
200
201void expectJsonValid(const json configFileJson)
202{
Shawn McCarney0f6ebad2020-09-04 16:43:00 -0500203 TemporaryFile tmpFile;
204 std::string fileName = tmpFile.getPath().string();
Bob Kinga57e0812020-03-12 10:47:42 +0800205 writeDataToFile(configFileJson, fileName);
Bob Kinged009652020-02-20 14:54:13 +0800206
Bob King386d33f2019-12-26 17:28:56 +0800207 EXPECT_FILE_VALID(fileName);
Bob King386d33f2019-12-26 17:28:56 +0800208}
209
210void expectJsonInvalid(const json configFileJson,
211 const std::string& expectedErrorMessage,
212 const std::string& expectedOutputMessage)
213{
Shawn McCarney0f6ebad2020-09-04 16:43:00 -0500214 TemporaryFile tmpFile;
215 std::string fileName = tmpFile.getPath().string();
Bob Kinga57e0812020-03-12 10:47:42 +0800216 writeDataToFile(configFileJson, fileName);
Bob King386d33f2019-12-26 17:28:56 +0800217
218 EXPECT_FILE_INVALID(fileName, expectedErrorMessage, expectedOutputMessage);
Bob King386d33f2019-12-26 17:28:56 +0800219}
220
Bob Kinged009652020-02-20 14:54:13 +0800221void expectCommandLineSyntax(const std::string& expectedErrorMessage,
222 const std::string& expectedOutputMessage,
Shawn McCarney525e20c2020-04-14 11:05:39 -0500223 const std::string& command, int status)
Bob Kinged009652020-02-20 14:54:13 +0800224{
225 std::string errorMessage;
226 std::string outputMessage;
Bob Kinga57e0812020-03-12 10:47:42 +0800227 EXPECT_EQ(runToolForOutputWithCommand(command, outputMessage, errorMessage),
228 status);
Bob Kinged009652020-02-20 14:54:13 +0800229 EXPECT_EQ(errorMessage, expectedErrorMessage);
230 EXPECT_EQ(outputMessage, expectedOutputMessage);
231}
232
Bob King3afa7112020-03-19 09:35:31 +0800233TEST(ValidateRegulatorsConfigTest, Action)
234{
235 // Valid: Comments property not specified
236 {
237 json configFile = validConfigFile;
238 EXPECT_JSON_VALID(configFile);
239 }
240 // Valid: Comments property specified
241 {
242 json configFile = validConfigFile;
243 configFile["rules"][0]["actions"][0]["comments"][0] =
244 "Set VOUT_COMMAND";
245 EXPECT_JSON_VALID(configFile);
246 }
247 // Valid: and action type specified
248 {
249 json configFile = validConfigFile;
250 json andAction =
251 R"(
252 {
253 "and": [
254 { "i2c_compare_byte": { "register": "0xA0", "value": "0x00" } },
255 { "i2c_compare_byte": { "register": "0xA1", "value": "0x00" } }
256 ]
257 }
258 )"_json;
259 configFile["rules"][0]["actions"].push_back(andAction);
260 EXPECT_JSON_VALID(configFile);
261 }
262 // Valid: compare_presence action type specified
263 {
264 json configFile = validConfigFile;
265 configFile["rules"][0]["actions"][1]["compare_presence"]["fru"] =
Bob Kinga76898f2020-10-13 15:08:33 +0800266 "system/chassis/motherboard/regulator2";
Bob King3afa7112020-03-19 09:35:31 +0800267 configFile["rules"][0]["actions"][1]["compare_presence"]["value"] =
268 true;
269 EXPECT_JSON_VALID(configFile);
270 }
271 // Valid: compare_vpd action type specified
272 {
273 json configFile = validConfigFile;
274 configFile["rules"][0]["actions"][1]["compare_vpd"]["fru"] =
Bob Kinga76898f2020-10-13 15:08:33 +0800275 "system/chassis/motherboard/regulator2";
Bob King3afa7112020-03-19 09:35:31 +0800276 configFile["rules"][0]["actions"][1]["compare_vpd"]["keyword"] = "CCIN";
277 configFile["rules"][0]["actions"][1]["compare_vpd"]["value"] = "2D35";
278 EXPECT_JSON_VALID(configFile);
279 }
280 // Valid: i2c_compare_bit action type specified
281 {
282 json configFile = validConfigFile;
283 configFile["rules"][0]["actions"][1]["i2c_compare_bit"]["register"] =
284 "0xA0";
285 configFile["rules"][0]["actions"][1]["i2c_compare_bit"]["position"] = 3;
286 configFile["rules"][0]["actions"][1]["i2c_compare_bit"]["value"] = 1;
287 EXPECT_JSON_VALID(configFile);
288 }
289 // Valid: i2c_compare_byte action type specified
290 {
291 json configFile = validConfigFile;
292 configFile["rules"][0]["actions"][1]["i2c_compare_byte"]["register"] =
293 "0x82";
294 configFile["rules"][0]["actions"][1]["i2c_compare_byte"]["value"] =
295 "0x40";
296 configFile["rules"][0]["actions"][1]["i2c_compare_byte"]["mask"] =
297 "0x7F";
298 EXPECT_JSON_VALID(configFile);
299 }
300 // Valid: i2c_compare_bytes action type specified
301 {
302 json configFile = validConfigFile;
303 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["register"] =
304 "0x82";
305 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["values"] = {
306 "0x02", "0x73"};
307 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["masks"] = {
308 "0x7F", "0x7F"};
309 EXPECT_JSON_VALID(configFile);
310 }
311 // Valid: i2c_write_bit action type specified
312 {
313 json configFile = validConfigFile;
314 configFile["rules"][0]["actions"][1]["i2c_write_bit"]["register"] =
315 "0xA0";
316 configFile["rules"][0]["actions"][1]["i2c_write_bit"]["position"] = 3;
317 configFile["rules"][0]["actions"][1]["i2c_write_bit"]["value"] = 1;
318 EXPECT_JSON_VALID(configFile);
319 }
320 // Valid: i2c_write_byte action type specified
321 {
322 json configFile = validConfigFile;
323 configFile["rules"][0]["actions"][1]["i2c_write_byte"]["register"] =
324 "0x82";
325 configFile["rules"][0]["actions"][1]["i2c_write_byte"]["value"] =
326 "0x40";
327 configFile["rules"][0]["actions"][1]["i2c_write_byte"]["mask"] = "0x7F";
328 EXPECT_JSON_VALID(configFile);
329 }
330 // Valid: i2c_write_bytes action type specified
331 {
332 json configFile = validConfigFile;
333 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["register"] =
334 "0x82";
335 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["values"] = {
336 "0x02", "0x73"};
337 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["masks"] = {
338 "0x7F", "0x7F"};
339 EXPECT_JSON_VALID(configFile);
340 }
341 // Valid: if action type specified
342 {
343 json configFile = validConfigFile;
344 configFile["rules"][2]["actions"][0]["if"]["condition"]["run_rule"] =
345 "set_voltage_rule";
346 configFile["rules"][2]["actions"][0]["if"]["then"][0]["run_rule"] =
347 "read_sensors_rule";
348 configFile["rules"][2]["actions"][0]["if"]["else"][0]["run_rule"] =
349 "read_sensors_rule";
350 configFile["rules"][2]["id"] = "rule_if";
351 EXPECT_JSON_VALID(configFile);
352 }
353 // Valid: not action type specified
354 {
355 json configFile = validConfigFile;
356 configFile["rules"][0]["actions"][1]["not"]["i2c_compare_byte"]
357 ["register"] = "0xA0";
358 configFile["rules"][0]["actions"][1]["not"]["i2c_compare_byte"]
359 ["value"] = "0xFF";
360 EXPECT_JSON_VALID(configFile);
361 }
362 // Valid: or action type specified
363 {
364 json configFile = validConfigFile;
365 configFile["rules"][0]["actions"][1]["or"][0]["i2c_compare_byte"]
366 ["register"] = "0xA0";
367 configFile["rules"][0]["actions"][1]["or"][0]["i2c_compare_byte"]
368 ["value"] = "0x00";
369 configFile["rules"][0]["actions"][1]["or"][1]["i2c_compare_byte"]
370 ["register"] = "0xA1";
371 configFile["rules"][0]["actions"][1]["or"][1]["i2c_compare_byte"]
372 ["value"] = "0x00";
373 EXPECT_JSON_VALID(configFile);
374 }
375 // Valid: pmbus_read_sensor and pmbus_write_vout_command action type
376 // specified
377 {
378 EXPECT_JSON_VALID(validConfigFile);
379 }
380 // Valid: run_rule action type specified
381 {
382 json configFile = validConfigFile;
383 configFile["rules"][0]["actions"][1]["run_rule"] = "read_sensors_rule";
384 EXPECT_JSON_VALID(configFile);
385 }
386 // Valid: set_device action type specified
387 {
388 json configFile = validConfigFile;
389 configFile["rules"][0]["actions"][1]["set_device"] = "vdd_regulator";
390 EXPECT_JSON_VALID(configFile);
391 }
392 // Invalid: Wrong data type for comments (should be array of string)
393 {
394 json configFile = validConfigFile;
395 configFile["rules"][0]["actions"][0]["comments"] = true;
396 EXPECT_JSON_INVALID(configFile, "Validation failed.",
397 "True is not of type 'array'");
398 }
399 // Invalid: Wrong data type for action type (such as "i2c_write_byte": true)
400 {
401 json configFile = validConfigFile;
402 configFile["rules"][0]["actions"][1]["i2c_write_byte"] = true;
403 EXPECT_JSON_INVALID(configFile, "Validation failed.",
404 "True is not of type 'object'");
405 }
406 // Invalid: Empty comments array
407 {
408 json configFile = validConfigFile;
409 configFile["rules"][0]["actions"][0]["comments"] = json::array();
410 EXPECT_JSON_INVALID(configFile, "Validation failed.",
411 "[] is too short");
412 }
413 // Invalid: Comments array has wrong element type (should be string)
414 {
415 json configFile = validConfigFile;
416 configFile["rules"][0]["actions"][0]["comments"][0] = true;
417 EXPECT_JSON_INVALID(configFile, "Validation failed.",
418 "True is not of type 'string'");
419 }
420 // Invalid: No action type specified
421 {
422 json configFile = validConfigFile;
423 configFile["rules"][0]["actions"][1]["comments"][0] =
424 "Check if bit 3 is on";
425 EXPECT_JSON_INVALID(configFile, "Validation failed.",
426 "'and' is a required property");
427 }
428 // Invalid: Multiple action types specified (such as both 'compare_presence'
429 // and 'pmbus_write_vout_command')
430 {
431 json configFile = validConfigFile;
432 configFile["rules"][0]["actions"][0]["compare_presence"]["value"] =
433 true;
434 EXPECT_JSON_INVALID(
435 configFile, "Validation failed.",
436 "{'compare_presence': {'value': True}, 'pmbus_write_vout_command': "
437 "{'format': 'linear'}} is valid under each of {'required': "
438 "['pmbus_write_vout_command']}, {'required': "
439 "['compare_presence']}");
440 }
441 // Invalid: Unexpected property specified (like 'foo')
442 {
443 json configFile = validConfigFile;
444 configFile["rules"][0]["actions"][1]["foo"] = "foo";
445 EXPECT_JSON_INVALID(
446 configFile, "Validation failed.",
447 "Additional properties are not allowed ('foo' was unexpected)");
448 }
449}
Bob Kingbeaf6532020-01-21 11:03:49 +0800450TEST(ValidateRegulatorsConfigTest, And)
451{
452 // Valid.
453 {
454 json configFile = validConfigFile;
455 json andAction =
456 R"(
457 {
458 "and": [
459 { "i2c_compare_byte": { "register": "0xA0", "value": "0x00" } },
460 { "i2c_compare_byte": { "register": "0xA1", "value": "0x00" } }
461 ]
462 }
463 )"_json;
464 configFile["rules"][0]["actions"].push_back(andAction);
465 EXPECT_JSON_VALID(configFile);
466 }
467
468 // Invalid: actions property value is an empty array.
469 {
470 json configFile = validConfigFile;
471 json andAction =
472 R"(
473 {
474 "and": []
475 }
476 )"_json;
477 configFile["rules"][0]["actions"].push_back(andAction);
478 EXPECT_JSON_INVALID(configFile, "Validation failed.",
479 "[] is too short");
480 }
481
482 // Invalid: actions property has incorrect value data type.
483 {
484 json configFile = validConfigFile;
485 json andAction =
486 R"(
487 {
488 "and": true
489 }
490 )"_json;
491 configFile["rules"][0]["actions"].push_back(andAction);
492 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800493 "True is not of type 'array'");
Bob Kingbeaf6532020-01-21 11:03:49 +0800494 }
495
496 // Invalid: actions property value contains wrong element type
497 {
498 json configFile = validConfigFile;
499 json andAction =
500 R"(
501 {
502 "and": ["foo"]
503 }
504 )"_json;
505 configFile["rules"][0]["actions"].push_back(andAction);
506 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800507 "'foo' is not of type 'object'");
Bob Kingbeaf6532020-01-21 11:03:49 +0800508 }
509}
Bob King3728f562020-01-21 11:35:31 +0800510TEST(ValidateRegulatorsConfigTest, Chassis)
511{
512 // Valid: test chassis.
513 {
514 json configFile = validConfigFile;
515 EXPECT_JSON_VALID(configFile);
516 }
Shawn McCarneyecbeeea2021-04-29 21:08:18 -0500517 // Valid: test chassis with only required properties.
Bob King3728f562020-01-21 11:35:31 +0800518 {
519 json configFile = validConfigFile;
520 configFile["chassis"][0].erase("comments");
Shawn McCarneyecbeeea2021-04-29 21:08:18 -0500521 configFile["chassis"][0].erase("inventory_path");
Bob King3728f562020-01-21 11:35:31 +0800522 configFile["chassis"][0].erase("devices");
523 EXPECT_JSON_VALID(configFile);
524 }
525 // Invalid: test chassis with no number.
526 {
527 json configFile = validConfigFile;
528 configFile["chassis"][0].erase("number");
529 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800530 "'number' is a required property");
Bob King3728f562020-01-21 11:35:31 +0800531 }
532 // Invalid: test chassis with property comments wrong type.
533 {
534 json configFile = validConfigFile;
535 configFile["chassis"][0]["comments"] = true;
536 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800537 "True is not of type 'array'");
Bob King3728f562020-01-21 11:35:31 +0800538 }
539 // Invalid: test chassis with property number wrong type.
540 {
541 json configFile = validConfigFile;
542 configFile["chassis"][0]["number"] = 1.3;
543 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800544 "1.3 is not of type 'integer'");
Bob King3728f562020-01-21 11:35:31 +0800545 }
Shawn McCarneyecbeeea2021-04-29 21:08:18 -0500546 // Invalid: test chassis with property inventory_path wrong type.
547 {
548 json configFile = validConfigFile;
549 configFile["chassis"][0]["inventory_path"] = 2;
550 EXPECT_JSON_INVALID(configFile, "Validation failed.",
551 "2 is not of type 'string'");
552 }
Bob King3728f562020-01-21 11:35:31 +0800553 // Invalid: test chassis with property devices wrong type.
554 {
555 json configFile = validConfigFile;
556 configFile["chassis"][0]["devices"] = true;
557 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800558 "True is not of type 'array'");
Bob King3728f562020-01-21 11:35:31 +0800559 }
560 // Invalid: test chassis with property comments empty array.
561 {
562 json configFile = validConfigFile;
563 configFile["chassis"][0]["comments"] = json::array();
564 EXPECT_JSON_INVALID(configFile, "Validation failed.",
565 "[] is too short");
566 }
567 // Invalid: test chassis with property devices empty array.
568 {
569 json configFile = validConfigFile;
570 configFile["chassis"][0]["devices"] = json::array();
571 EXPECT_JSON_INVALID(configFile, "Validation failed.",
572 "[] is too short");
573 }
574 // Invalid: test chassis with property number less than 1.
575 {
576 json configFile = validConfigFile;
577 configFile["chassis"][0]["number"] = 0;
578 EXPECT_JSON_INVALID(configFile, "Validation failed.",
579 "0 is less than the minimum of 1");
580 }
Shawn McCarneyecbeeea2021-04-29 21:08:18 -0500581 // Invalid: test chassis with property inventory_path empty string.
582 {
583 json configFile = validConfigFile;
584 configFile["chassis"][0]["inventory_path"] = "";
585 EXPECT_JSON_INVALID(configFile, "Validation failed.",
586 "'' is too short");
587 }
Bob King3728f562020-01-21 11:35:31 +0800588}
Bob Kingbf1cbea2020-01-21 11:08:50 +0800589TEST(ValidateRegulatorsConfigTest, ComparePresence)
590{
591 json comparePresenceFile = validConfigFile;
592 comparePresenceFile["rules"][0]["actions"][1]["compare_presence"]["fru"] =
Bob Kinga76898f2020-10-13 15:08:33 +0800593 "system/chassis/motherboard/regulator2";
Bob Kingbf1cbea2020-01-21 11:08:50 +0800594 comparePresenceFile["rules"][0]["actions"][1]["compare_presence"]["value"] =
595 true;
596 // Valid.
597 {
598 json configFile = comparePresenceFile;
599 EXPECT_JSON_VALID(configFile);
600 }
601
602 // Invalid: no FRU property.
603 {
604 json configFile = comparePresenceFile;
605 configFile["rules"][0]["actions"][1]["compare_presence"].erase("fru");
606 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800607 "'fru' is a required property");
Bob Kingbf1cbea2020-01-21 11:08:50 +0800608 }
609
610 // Invalid: FRU property length is string less than 1.
611 {
612 json configFile = comparePresenceFile;
613 configFile["rules"][0]["actions"][1]["compare_presence"]["fru"] = "";
614 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800615 "'' is too short");
Bob Kingbf1cbea2020-01-21 11:08:50 +0800616 }
617
618 // Invalid: no value property.
619 {
620 json configFile = comparePresenceFile;
621 configFile["rules"][0]["actions"][1]["compare_presence"].erase("value");
622 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800623 "'value' is a required property");
Bob Kingbf1cbea2020-01-21 11:08:50 +0800624 }
625
626 // Invalid: value property type is not boolean.
627 {
628 json configFile = comparePresenceFile;
629 configFile["rules"][0]["actions"][1]["compare_presence"]["value"] = "1";
630 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800631 "'1' is not of type 'boolean'");
Bob Kingbf1cbea2020-01-21 11:08:50 +0800632 }
633
634 // Invalid: FRU property type is not string.
635 {
636 json configFile = comparePresenceFile;
637 configFile["rules"][0]["actions"][1]["compare_presence"]["fru"] = 1;
638 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800639 "1 is not of type 'string'");
Bob Kingbf1cbea2020-01-21 11:08:50 +0800640 }
641}
Bob Kingf8b77a02020-01-21 11:09:47 +0800642TEST(ValidateRegulatorsConfigTest, CompareVpd)
643{
644 json compareVpdFile = validConfigFile;
645 compareVpdFile["rules"][0]["actions"][1]["compare_vpd"]["fru"] =
Bob Kinga76898f2020-10-13 15:08:33 +0800646 "system/chassis/motherboard/regulator2";
Bob Kingf8b77a02020-01-21 11:09:47 +0800647 compareVpdFile["rules"][0]["actions"][1]["compare_vpd"]["keyword"] = "CCIN";
648 compareVpdFile["rules"][0]["actions"][1]["compare_vpd"]["value"] = "2D35";
649
650 // Valid.
651 {
652 json configFile = compareVpdFile;
653 EXPECT_JSON_VALID(configFile);
654 }
655
656 // Invalid: no FRU property.
657 {
658 json configFile = compareVpdFile;
659 configFile["rules"][0]["actions"][1]["compare_vpd"].erase("fru");
660 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800661 "'fru' is a required property");
Bob Kingf8b77a02020-01-21 11:09:47 +0800662 }
663
664 // Invalid: no keyword property.
665 {
666 json configFile = compareVpdFile;
667 configFile["rules"][0]["actions"][1]["compare_vpd"].erase("keyword");
668 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800669 "'keyword' is a required property");
Bob Kingf8b77a02020-01-21 11:09:47 +0800670 }
671
672 // Invalid: no value property.
673 {
674 json configFile = compareVpdFile;
675 configFile["rules"][0]["actions"][1]["compare_vpd"].erase("value");
676 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800677 "'value' is a required property");
Bob Kingf8b77a02020-01-21 11:09:47 +0800678 }
679
680 // Invalid: property FRU wrong type.
681 {
682 json configFile = compareVpdFile;
683 configFile["rules"][0]["actions"][1]["compare_vpd"]["fru"] = 1;
684 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800685 "1 is not of type 'string'");
Bob Kingf8b77a02020-01-21 11:09:47 +0800686 }
687
688 // Invalid: property FRU is string less than 1.
689 {
690 json configFile = compareVpdFile;
691 configFile["rules"][0]["actions"][1]["compare_vpd"]["fru"] = "";
692 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800693 "'' is too short");
Bob Kingf8b77a02020-01-21 11:09:47 +0800694 }
695
696 // Invalid: property keyword is not "CCIN", "Manufacturer", "Model",
697 // "PartNumber"
698 {
699 json configFile = compareVpdFile;
700 configFile["rules"][0]["actions"][1]["compare_vpd"]["keyword"] =
701 "Number";
702 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800703 "'Number' is not one of ['CCIN', "
704 "'Manufacturer', 'Model', 'PartNumber']");
Bob Kingf8b77a02020-01-21 11:09:47 +0800705 }
706
707 // Invalid: property value wrong type.
708 {
709 json configFile = compareVpdFile;
710 configFile["rules"][0]["actions"][1]["compare_vpd"]["value"] = 1;
711 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800712 "1 is not of type 'string'");
Bob Kingf8b77a02020-01-21 11:09:47 +0800713 }
714}
Bob King20057412020-03-16 16:50:17 +0800715TEST(ValidateRegulatorsConfigTest, ConfigFile)
716{
717 // Valid: Only required properties specified
718 {
719 json configFile;
720 configFile["chassis"][0]["number"] = 1;
721 EXPECT_JSON_VALID(configFile);
722 }
723 // Valid: All properties specified
724 {
725 json configFile = validConfigFile;
726 EXPECT_JSON_VALID(configFile);
727 }
728 // Invalid: Required chassis property not specified
729 {
730 json configFile = validConfigFile;
731 configFile.erase("chassis");
732 EXPECT_JSON_INVALID(configFile, "Validation failed.",
733 "'chassis' is a required property");
734 }
735 // Invalid: Wrong data type for comments
736 {
737 json configFile = validConfigFile;
738 configFile["comments"] = true;
739 EXPECT_JSON_INVALID(configFile, "Validation failed.",
740 "True is not of type 'array'");
741 }
742 // Invalid: Wrong data type for rules
743 {
744 json configFile = validConfigFile;
745 configFile["rules"] = true;
746 EXPECT_JSON_INVALID(configFile, "Validation failed.",
747 "True is not of type 'array'");
748 }
749 // Invalid: Wrong data type for chassis
750 {
751 json configFile = validConfigFile;
752 configFile["chassis"] = true;
753 EXPECT_JSON_INVALID(configFile, "Validation failed.",
754 "True is not of type 'array'");
755 }
756 // Invalid: Empty comments array;
757 {
758 json configFile = validConfigFile;
759 configFile["comments"] = json::array();
760 EXPECT_JSON_INVALID(configFile, "Validation failed.",
761 "[] is too short");
762 }
763 // Invalid: Empty rules array
764 {
765 json configFile = validConfigFile;
766 configFile["rules"] = json::array();
767 EXPECT_JSON_INVALID(configFile, "Validation failed.",
768 "[] is too short");
769 }
770 // Invalid: Empty chassis array
771 {
772 json configFile = validConfigFile;
773 configFile["chassis"] = json::array();
774 EXPECT_JSON_INVALID(configFile, "Validation failed.",
775 "[] is too short");
776 }
777 // Invalid: Comments array has wrong element type (should be string)
778 {
779 json configFile = validConfigFile;
780 configFile["comments"][0] = true;
781 EXPECT_JSON_INVALID(configFile, "Validation failed.",
782 "True is not of type 'string'");
783 }
784 // Invalid: Rules array has wrong element type (should be rule)
785 {
786 json configFile = validConfigFile;
787 configFile["rules"][0] = true;
788 EXPECT_JSON_INVALID(configFile, "Validation failed.",
789 "True is not of type 'object'");
790 }
791 // Invalid: Chassis array has wrong element type (should be chassis)
792 {
793 json configFile = validConfigFile;
794 configFile["chassis"][0] = true;
795 EXPECT_JSON_INVALID(configFile, "Validation failed.",
796 "True is not of type 'object'");
797 }
798 // Invalid: Unexpected property specified
799 {
800 json configFile = validConfigFile;
801 configFile["foo"] = json::array();
802 EXPECT_JSON_INVALID(
803 configFile, "Validation failed.",
804 "Additional properties are not allowed ('foo' was unexpected)");
805 }
806}
Bob King4c67a3a2020-02-07 09:48:11 +0800807TEST(ValidateRegulatorsConfigTest, Configuration)
808{
809 json configurationFile = validConfigFile;
810 configurationFile["chassis"][0]["devices"][0]["configuration"]["comments"]
811 [0] = "Set rail to 1.25V using standard rule";
812 configurationFile["chassis"][0]["devices"][0]["configuration"]["volts"] =
813 1.25;
814 configurationFile["chassis"][0]["devices"][0]["configuration"]["rule_id"] =
815 "set_voltage_rule";
816 // Valid: test configuration with property rule_id and with no actions.
817 {
818 json configFile = configurationFile;
Bob King78793102020-03-13 13:16:09 +0800819 configFile["chassis"][0]["devices"][0]["configuration"]["comments"][1] =
820 "test multiple array elements in comments.";
Bob King4c67a3a2020-02-07 09:48:11 +0800821 EXPECT_JSON_VALID(configFile);
822 }
823 // Valid: test configuration with property actions and with no rule_id.
824 {
825 json configFile = configurationFile;
826 configFile["chassis"][0]["devices"][0]["configuration"].erase(
827 "rule_id");
828 configFile["chassis"][0]["devices"][0]["configuration"]["actions"][0]
829 ["compare_presence"]["fru"] =
Bob Kinga76898f2020-10-13 15:08:33 +0800830 "system/chassis/motherboard/cpu3";
Bob King4c67a3a2020-02-07 09:48:11 +0800831 configFile["chassis"][0]["devices"][0]["configuration"]["actions"][0]
832 ["compare_presence"]["value"] = true;
833 EXPECT_JSON_VALID(configFile);
834 }
835 // Valid: comments not specified (optional property).
836 {
837 json configFile = configurationFile;
838 configFile["chassis"][0]["devices"][0]["configuration"].erase(
839 "comments");
840 EXPECT_JSON_VALID(configFile);
841 }
842 // Valid: volts not specified (optional property).
843 {
844 json configFile = configurationFile;
845 configFile["chassis"][0]["devices"][0]["configuration"].erase("volts");
846 EXPECT_JSON_VALID(configFile);
847 }
848 // Valid: configuration is property of a rail (vs. a device).
849 {
850 json configFile = validConfigFile;
851 configFile["chassis"][0]["devices"][0]["rails"][0]["configuration"]
852 ["comments"][0] = "Set rail to 1.25V using standard rule";
853 configFile["chassis"][0]["devices"][0]["rails"][0]["configuration"]
854 ["volts"] = 1.25;
855 configFile["chassis"][0]["devices"][0]["rails"][0]["configuration"]
856 ["rule_id"] = "set_voltage_rule";
857 EXPECT_JSON_VALID(configFile);
858 }
859 // Invalid: comments property has wrong data type (not an array).
860 {
861 json configFile = configurationFile;
862 configFile["chassis"][0]["devices"][0]["configuration"]["comments"] = 1;
863 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800864 "1 is not of type 'array'");
Bob King4c67a3a2020-02-07 09:48:11 +0800865 }
866 // Invalid: test configuration with both actions and rule_id properties.
867 {
868 json configFile = configurationFile;
869 configFile["chassis"][0]["devices"][0]["configuration"]["actions"][0]
870 ["compare_presence"]["fru"] =
Bob Kinga76898f2020-10-13 15:08:33 +0800871 "system/chassis/motherboard/cpu3";
Bob King4c67a3a2020-02-07 09:48:11 +0800872 configFile["chassis"][0]["devices"][0]["configuration"]["actions"][0]
873 ["compare_presence"]["value"] = true;
874 EXPECT_JSON_INVALID(
875 configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800876 "{'actions': [{'compare_presence': {'fru': "
Bob Kinga76898f2020-10-13 15:08:33 +0800877 "'system/chassis/motherboard/cpu3', 'value': True}}], 'comments': "
Bob King358c4172020-03-16 13:57:08 +0800878 "['Set rail to 1.25V using standard rule'], 'rule_id': "
879 "'set_voltage_rule', 'volts': 1.25} is valid under each of "
880 "{'required': ['actions']}, {'required': ['rule_id']}");
Bob King4c67a3a2020-02-07 09:48:11 +0800881 }
882 // Invalid: test configuration with no rule_id and actions.
883 {
884 json configFile = configurationFile;
885 configFile["chassis"][0]["devices"][0]["configuration"].erase(
886 "rule_id");
887 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800888 "'rule_id' is a required property");
Bob King4c67a3a2020-02-07 09:48:11 +0800889 }
890 // Invalid: test configuration with property volts wrong type.
891 {
892 json configFile = configurationFile;
893 configFile["chassis"][0]["devices"][0]["configuration"]["volts"] = true;
894 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800895 "True is not of type 'number'");
Bob King4c67a3a2020-02-07 09:48:11 +0800896 }
897 // Invalid: test configuration with property rule_id wrong type.
898 {
899 json configFile = configurationFile;
900 configFile["chassis"][0]["devices"][0]["configuration"]["rule_id"] =
901 true;
902 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800903 "True is not of type 'string'");
Bob King4c67a3a2020-02-07 09:48:11 +0800904 }
905 // Invalid: test configuration with property actions wrong type.
906 {
907 json configFile = configurationFile;
908 configFile["chassis"][0]["devices"][0]["configuration"].erase(
909 "rule_id");
910 configFile["chassis"][0]["devices"][0]["configuration"]["actions"] =
911 true;
912 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800913 "True is not of type 'array'");
Bob King4c67a3a2020-02-07 09:48:11 +0800914 }
915 // Invalid: test configuration with property comments empty array.
916 {
917 json configFile = configurationFile;
918 configFile["chassis"][0]["devices"][0]["configuration"]["comments"] =
919 json::array();
920 EXPECT_JSON_INVALID(configFile, "Validation failed.",
921 "[] is too short");
922 }
923 // Invalid: test configuration with property rule_id wrong format.
924 {
925 json configFile = configurationFile;
926 configFile["chassis"][0]["devices"][0]["configuration"]["rule_id"] =
927 "id!";
928 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800929 "'id!' does not match '^[A-Za-z0-9_]+$'");
Bob King4c67a3a2020-02-07 09:48:11 +0800930 }
931 // Invalid: test configuration with property actions empty array.
932 {
933 json configFile = configurationFile;
934 configFile["chassis"][0]["devices"][0]["configuration"].erase(
935 "rule_id");
936 configFile["chassis"][0]["devices"][0]["configuration"]["actions"] =
937 json::array();
938 EXPECT_JSON_INVALID(configFile, "Validation failed.",
939 "[] is too short");
940 }
941}
Bob Kinga2ba2df2020-02-04 14:38:44 +0800942TEST(ValidateRegulatorsConfigTest, Device)
943{
944
945 // Valid: test devices.
946 {
947 json configFile = validConfigFile;
948 EXPECT_JSON_VALID(configFile);
949 }
950 // Valid: test devices with required properties.
951 {
952 json configFile = validConfigFile;
953 configFile["chassis"][0]["devices"][0].erase("comments");
954 configFile["chassis"][0]["devices"][0].erase("presence_detection");
955 configFile["chassis"][0]["devices"][0].erase("configuration");
956 configFile["chassis"][0]["devices"][0].erase("rails");
957 EXPECT_JSON_VALID(configFile);
958 }
959 // Invalid: test devices with no id.
960 {
961 json configFile = validConfigFile;
962 configFile["chassis"][0]["devices"][0].erase("id");
963 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800964 "'id' is a required property");
Bob Kinga2ba2df2020-02-04 14:38:44 +0800965 }
966 // Invalid: test devices with no is_regulator.
967 {
968 json configFile = validConfigFile;
969 configFile["chassis"][0]["devices"][0].erase("is_regulator");
970 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800971 "'is_regulator' is a required property");
Bob Kinga2ba2df2020-02-04 14:38:44 +0800972 }
973 // Invalid: test devices with no fru.
974 {
975 json configFile = validConfigFile;
976 configFile["chassis"][0]["devices"][0].erase("fru");
977 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800978 "'fru' is a required property");
Bob Kinga2ba2df2020-02-04 14:38:44 +0800979 }
980 // Invalid: test devices with no i2c_interface.
981 {
982 json configFile = validConfigFile;
983 configFile["chassis"][0]["devices"][0].erase("i2c_interface");
984 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800985 "'i2c_interface' is a required property");
Bob Kinga2ba2df2020-02-04 14:38:44 +0800986 }
987 // Invalid: test devices with property comments wrong type.
988 {
989 json configFile = validConfigFile;
990 configFile["chassis"][0]["devices"][0]["comments"] = true;
991 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800992 "True is not of type 'array'");
Bob Kinga2ba2df2020-02-04 14:38:44 +0800993 }
994 // Invalid: test devices with property id wrong type.
995 {
996 json configFile = validConfigFile;
997 configFile["chassis"][0]["devices"][0]["id"] = true;
998 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800999 "True is not of type 'string'");
Bob Kinga2ba2df2020-02-04 14:38:44 +08001000 }
1001 // Invalid: test devices with property is_regulator wrong type.
1002 {
1003 json configFile = validConfigFile;
1004 configFile["chassis"][0]["devices"][0]["is_regulator"] = 1;
1005 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001006 "1 is not of type 'boolean'");
Bob Kinga2ba2df2020-02-04 14:38:44 +08001007 }
1008 // Invalid: test devices with property fru wrong type.
1009 {
1010 json configFile = validConfigFile;
1011 configFile["chassis"][0]["devices"][0]["fru"] = true;
1012 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001013 "True is not of type 'string'");
Bob Kinga2ba2df2020-02-04 14:38:44 +08001014 }
1015 // Invalid: test devices with property i2c_interface wrong type.
1016 {
1017 json configFile = validConfigFile;
1018 configFile["chassis"][0]["devices"][0]["i2c_interface"] = true;
1019 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001020 "True is not of type 'object'");
Bob Kinga2ba2df2020-02-04 14:38:44 +08001021 }
1022 // Invalid: test devices with property presence_detection wrong
1023 // type.
1024 {
1025 json configFile = validConfigFile;
1026 configFile["chassis"][0]["devices"][0]["presence_detection"] = true;
1027 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001028 "True is not of type 'object'");
Bob Kinga2ba2df2020-02-04 14:38:44 +08001029 }
1030 // Invalid: test devices with property configuration wrong type.
1031 {
1032 json configFile = validConfigFile;
1033 configFile["chassis"][0]["devices"][0]["configuration"] = true;
1034 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001035 "True is not of type 'object'");
Bob Kinga2ba2df2020-02-04 14:38:44 +08001036 }
1037 // Invalid: test devices with property rails wrong type.
1038 {
1039 json configFile = validConfigFile;
1040 configFile["chassis"][0]["devices"][0]["rails"] = true;
1041 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001042 "True is not of type 'array'");
Bob Kinga2ba2df2020-02-04 14:38:44 +08001043 }
1044 // Invalid: test devices with property comments empty array.
1045 {
1046 json configFile = validConfigFile;
1047 configFile["chassis"][0]["devices"][0]["comments"] = json::array();
1048 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1049 "[] is too short");
1050 }
1051 // Invalid: test devices with property fru length less than 1.
1052 {
1053 json configFile = validConfigFile;
1054 configFile["chassis"][0]["devices"][0]["fru"] = "";
1055 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001056 "'' is too short");
Bob Kinga2ba2df2020-02-04 14:38:44 +08001057 }
1058 // Invalid: test devices with property id wrong format.
1059 {
1060 json configFile = validConfigFile;
1061 configFile["chassis"][0]["devices"][0]["id"] = "id#";
1062 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001063 "'id#' does not match '^[A-Za-z0-9_]+$'");
Bob Kinga2ba2df2020-02-04 14:38:44 +08001064 }
1065 // Invalid: test devices with property rails empty array.
1066 {
1067 json configFile = validConfigFile;
1068 configFile["chassis"][0]["devices"][0]["rails"] = json::array();
1069 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1070 "[] is too short");
1071 }
1072}
Bob King4ab8cbb2020-01-21 11:10:48 +08001073TEST(ValidateRegulatorsConfigTest, I2CCompareBit)
1074{
1075 json i2cCompareBitFile = validConfigFile;
1076 i2cCompareBitFile["rules"][0]["actions"][1]["i2c_compare_bit"]["register"] =
1077 "0xA0";
1078 i2cCompareBitFile["rules"][0]["actions"][1]["i2c_compare_bit"]["position"] =
1079 3;
1080 i2cCompareBitFile["rules"][0]["actions"][1]["i2c_compare_bit"]["value"] = 1;
1081 // Valid: test rule actions i2c_compare_bit.
1082 {
1083 json configFile = i2cCompareBitFile;
1084 EXPECT_JSON_VALID(configFile);
1085 }
1086 // Invalid: test i2c_compare_bit with no register.
1087 {
1088 json configFile = i2cCompareBitFile;
1089 configFile["rules"][0]["actions"][1]["i2c_compare_bit"].erase(
1090 "register");
1091 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001092 "'register' is a required property");
Bob King4ab8cbb2020-01-21 11:10:48 +08001093 }
1094 // Invalid: test i2c_compare_bit with no position.
1095 {
1096 json configFile = i2cCompareBitFile;
1097 configFile["rules"][0]["actions"][1]["i2c_compare_bit"].erase(
1098 "position");
1099 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001100 "'position' is a required property");
Bob King4ab8cbb2020-01-21 11:10:48 +08001101 }
1102 // Invalid: test i2c_compare_bit with no value.
1103 {
1104 json configFile = i2cCompareBitFile;
1105 configFile["rules"][0]["actions"][1]["i2c_compare_bit"].erase("value");
1106 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001107 "'value' is a required property");
Bob King4ab8cbb2020-01-21 11:10:48 +08001108 }
1109 // Invalid: test i2c_compare_bit with register wrong type.
1110 {
1111 json configFile = i2cCompareBitFile;
1112 configFile["rules"][0]["actions"][1]["i2c_compare_bit"]["register"] = 1;
1113 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001114 "1 is not of type 'string'");
Bob King4ab8cbb2020-01-21 11:10:48 +08001115 }
1116 // Invalid: test i2c_compare_bit with register wrong format.
1117 {
1118 json configFile = i2cCompareBitFile;
1119 configFile["rules"][0]["actions"][1]["i2c_compare_bit"]["register"] =
1120 "0xA00";
1121 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001122 "'0xA00' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King4ab8cbb2020-01-21 11:10:48 +08001123 }
1124 // Invalid: test i2c_compare_bit with position wrong type.
1125 {
1126 json configFile = i2cCompareBitFile;
1127 configFile["rules"][0]["actions"][1]["i2c_compare_bit"]["position"] =
1128 3.1;
1129 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001130 "3.1 is not of type 'integer'");
Bob King4ab8cbb2020-01-21 11:10:48 +08001131 }
1132 // Invalid: test i2c_compare_bit with position greater than 7.
1133 {
1134 json configFile = i2cCompareBitFile;
1135 configFile["rules"][0]["actions"][1]["i2c_compare_bit"]["position"] = 8;
1136 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1137 "8 is greater than the maximum of 7");
1138 }
1139 // Invalid: test i2c_compare_bit with position less than 0.
1140 {
1141 json configFile = i2cCompareBitFile;
1142 configFile["rules"][0]["actions"][1]["i2c_compare_bit"]["position"] =
1143 -1;
1144 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1145 "-1 is less than the minimum of 0");
1146 }
1147 // Invalid: test i2c_compare_bit with value wrong type.
1148 {
1149 json configFile = i2cCompareBitFile;
1150 configFile["rules"][0]["actions"][1]["i2c_compare_bit"]["value"] = "1";
1151 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001152 "'1' is not of type 'integer'");
Bob King4ab8cbb2020-01-21 11:10:48 +08001153 }
1154 // Invalid: test i2c_compare_bit with value greater than 1.
1155 {
1156 json configFile = i2cCompareBitFile;
1157 configFile["rules"][0]["actions"][1]["i2c_compare_bit"]["value"] = 2;
1158 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1159 "2 is greater than the maximum of 1");
1160 }
1161 // Invalid: test i2c_compare_bit with value less than 0.
1162 {
1163 json configFile = i2cCompareBitFile;
1164 configFile["rules"][0]["actions"][1]["i2c_compare_bit"]["value"] = -1;
1165 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1166 "-1 is less than the minimum of 0");
1167 }
1168}
Bob King514023d2020-01-21 11:13:05 +08001169TEST(ValidateRegulatorsConfigTest, I2CCompareByte)
1170{
1171 json i2cCompareByteFile = validConfigFile;
1172 i2cCompareByteFile["rules"][0]["actions"][1]["i2c_compare_byte"]
1173 ["register"] = "0x82";
1174 i2cCompareByteFile["rules"][0]["actions"][1]["i2c_compare_byte"]["value"] =
1175 "0x40";
1176 i2cCompareByteFile["rules"][0]["actions"][1]["i2c_compare_byte"]["mask"] =
1177 "0x7F";
1178 // Valid: test i2c_compare_byte with all properties.
1179 {
1180 json configFile = i2cCompareByteFile;
1181 EXPECT_JSON_VALID(configFile);
1182 }
1183 // Valid: test i2c_compare_byte with all required properties.
1184 {
1185 json configFile = i2cCompareByteFile;
1186 configFile["rules"][0]["actions"][1]["i2c_compare_byte"].erase("mask");
1187 EXPECT_JSON_VALID(configFile);
1188 }
1189 // Invalid: test i2c_compare_byte with no register.
1190 {
1191 json configFile = i2cCompareByteFile;
1192 configFile["rules"][0]["actions"][1]["i2c_compare_byte"].erase(
1193 "register");
1194 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001195 "'register' is a required property");
Bob King514023d2020-01-21 11:13:05 +08001196 }
1197 // Invalid: test i2c_compare_byte with no value.
1198 {
1199 json configFile = i2cCompareByteFile;
1200 configFile["rules"][0]["actions"][1]["i2c_compare_byte"].erase("value");
1201 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001202 "'value' is a required property");
Bob King514023d2020-01-21 11:13:05 +08001203 }
1204 // Invalid: test i2c_compare_byte with property register wrong type.
1205 {
1206 json configFile = i2cCompareByteFile;
1207 configFile["rules"][0]["actions"][1]["i2c_compare_byte"]["register"] =
1208 1;
1209 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001210 "1 is not of type 'string'");
Bob King514023d2020-01-21 11:13:05 +08001211 }
1212 // Invalid: test i2c_compare_byte with property value wrong type.
1213 {
1214 json configFile = i2cCompareByteFile;
1215 configFile["rules"][0]["actions"][1]["i2c_compare_byte"]["value"] = 1;
1216 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001217 "1 is not of type 'string'");
Bob King514023d2020-01-21 11:13:05 +08001218 }
1219 // Invalid: test i2c_compare_byte with property mask wrong type.
1220 {
1221 json configFile = i2cCompareByteFile;
1222 configFile["rules"][0]["actions"][1]["i2c_compare_byte"]["mask"] = 1;
1223 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001224 "1 is not of type 'string'");
Bob King514023d2020-01-21 11:13:05 +08001225 }
1226 // Invalid: test i2c_compare_byte with property register more than 2 hex
1227 // digits.
1228 {
1229 json configFile = i2cCompareByteFile;
1230 configFile["rules"][0]["actions"][1]["i2c_compare_byte"]["register"] =
1231 "0x820";
1232 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001233 "'0x820' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King514023d2020-01-21 11:13:05 +08001234 }
1235 // Invalid: test i2c_compare_byte with property value more than 2 hex
1236 // digits.
1237 {
1238 json configFile = i2cCompareByteFile;
1239 configFile["rules"][0]["actions"][1]["i2c_compare_byte"]["value"] =
1240 "0x820";
1241 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001242 "'0x820' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King514023d2020-01-21 11:13:05 +08001243 }
1244 // Invalid: test i2c_compare_byte with property mask more than 2 hex digits.
1245 {
1246 json configFile = i2cCompareByteFile;
1247 configFile["rules"][0]["actions"][1]["i2c_compare_byte"]["mask"] =
1248 "0x820";
1249 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001250 "'0x820' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King514023d2020-01-21 11:13:05 +08001251 }
1252 // Invalid: test i2c_compare_byte with property register less than 2 hex
1253 // digits.
1254 {
1255 json configFile = i2cCompareByteFile;
1256 configFile["rules"][0]["actions"][1]["i2c_compare_byte"]["register"] =
1257 "0x8";
1258 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001259 "'0x8' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King514023d2020-01-21 11:13:05 +08001260 }
1261 // Invalid: test i2c_compare_byte with property value less than 2 hex
1262 // digits.
1263 {
1264 json configFile = i2cCompareByteFile;
1265 configFile["rules"][0]["actions"][1]["i2c_compare_byte"]["value"] =
1266 "0x8";
1267 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001268 "'0x8' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King514023d2020-01-21 11:13:05 +08001269 }
1270 // Invalid: test i2c_compare_byte with property mask less than 2 hex digits.
1271 {
1272 json configFile = i2cCompareByteFile;
1273 configFile["rules"][0]["actions"][1]["i2c_compare_byte"]["mask"] =
1274 "0x8";
1275 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001276 "'0x8' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King514023d2020-01-21 11:13:05 +08001277 }
1278 // Invalid: test i2c_compare_byte with property register no leading prefix.
1279 {
1280 json configFile = i2cCompareByteFile;
1281 configFile["rules"][0]["actions"][1]["i2c_compare_byte"]["register"] =
1282 "82";
1283 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001284 "'82' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King514023d2020-01-21 11:13:05 +08001285 }
1286 // Invalid: test i2c_compare_byte with property value no leading prefix.
1287 {
1288 json configFile = i2cCompareByteFile;
1289 configFile["rules"][0]["actions"][1]["i2c_compare_byte"]["value"] =
1290 "82";
1291 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001292 "'82' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King514023d2020-01-21 11:13:05 +08001293 }
1294 // Invalid: test i2c_compare_byte with property mask no leading prefix.
1295 {
1296 json configFile = i2cCompareByteFile;
1297 configFile["rules"][0]["actions"][1]["i2c_compare_byte"]["mask"] = "82";
1298 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001299 "'82' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King514023d2020-01-21 11:13:05 +08001300 }
1301 // Invalid: test i2c_compare_byte with property register invalid hex digit.
1302 {
1303 json configFile = i2cCompareByteFile;
1304 configFile["rules"][0]["actions"][1]["i2c_compare_byte"]["register"] =
1305 "0xG1";
1306 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001307 "'0xG1' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King514023d2020-01-21 11:13:05 +08001308 }
1309 // Invalid: test i2c_compare_byte with property value invalid hex digit.
1310 {
1311 json configFile = i2cCompareByteFile;
1312 configFile["rules"][0]["actions"][1]["i2c_compare_byte"]["value"] =
1313 "0xG1";
1314 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001315 "'0xG1' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King514023d2020-01-21 11:13:05 +08001316 }
1317 // Invalid: test i2c_compare_byte with property mask invalid hex digit.
1318 {
1319 json configFile = i2cCompareByteFile;
1320 configFile["rules"][0]["actions"][1]["i2c_compare_byte"]["mask"] =
1321 "0xG1";
1322 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001323 "'0xG1' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King514023d2020-01-21 11:13:05 +08001324 }
1325}
Bob Kingfb162bb2020-01-21 11:28:07 +08001326TEST(ValidateRegulatorsConfigTest, I2CCompareBytes)
1327{
1328 json i2cCompareBytesFile = validConfigFile;
1329 i2cCompareBytesFile["rules"][0]["actions"][1]["i2c_compare_bytes"]
1330 ["register"] = "0x82";
1331 i2cCompareBytesFile["rules"][0]["actions"][1]["i2c_compare_bytes"]
1332 ["values"] = {"0x02", "0x73"};
1333 i2cCompareBytesFile["rules"][0]["actions"][1]["i2c_compare_bytes"]
1334 ["masks"] = {"0x7F", "0x7F"};
1335 // Valid: test i2c_compare_bytes.
1336 {
1337 json configFile = i2cCompareBytesFile;
1338 EXPECT_JSON_VALID(configFile);
1339 }
1340 // Valid: test i2c_compare_bytes with all required properties.
1341 {
1342 json configFile = i2cCompareBytesFile;
1343 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"].erase(
1344 "masks");
1345 EXPECT_JSON_VALID(configFile);
1346 }
1347 // Invalid: test i2c_compare_bytes with no register.
1348 {
1349 json configFile = i2cCompareBytesFile;
1350 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"].erase(
1351 "register");
1352 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001353 "'register' is a required property");
Bob Kingfb162bb2020-01-21 11:28:07 +08001354 }
1355 // Invalid: test i2c_compare_bytes with no values.
1356 {
1357 json configFile = i2cCompareBytesFile;
1358 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"].erase(
1359 "values");
1360 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001361 "'values' is a required property");
Bob Kingfb162bb2020-01-21 11:28:07 +08001362 }
1363 // Invalid: test i2c_compare_bytes with property values as empty array.
1364 {
1365 json configFile = i2cCompareBytesFile;
1366 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["values"] =
1367 json::array();
1368 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1369 "[] is too short");
1370 }
1371 // Invalid: test i2c_compare_bytes with property masks as empty array.
1372 {
1373 json configFile = i2cCompareBytesFile;
1374 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["masks"] =
1375 json::array();
1376 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1377 "[] is too short");
1378 }
1379 // Invalid: test i2c_compare_bytes with property register wrong type.
1380 {
1381 json configFile = i2cCompareBytesFile;
1382 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["register"] =
1383 1;
1384 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001385 "1 is not of type 'string'");
Bob Kingfb162bb2020-01-21 11:28:07 +08001386 }
1387 // Invalid: test i2c_compare_bytes with property values wrong type.
1388 {
1389 json configFile = i2cCompareBytesFile;
1390 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["values"] = 1;
1391 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001392 "1 is not of type 'array'");
Bob Kingfb162bb2020-01-21 11:28:07 +08001393 }
1394 // Invalid: test i2c_compare_bytes with property masks wrong type.
1395 {
1396 json configFile = i2cCompareBytesFile;
1397 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["masks"] = 1;
1398 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001399 "1 is not of type 'array'");
Bob Kingfb162bb2020-01-21 11:28:07 +08001400 }
1401 // Invalid: test i2c_compare_bytes with property register more than 2 hex
1402 // digits.
1403 {
1404 json configFile = i2cCompareBytesFile;
1405 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["register"] =
1406 "0x820";
1407 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001408 "'0x820' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob Kingfb162bb2020-01-21 11:28:07 +08001409 }
1410 // Invalid: test i2c_compare_bytes with property values more than 2 hex
1411 // digits.
1412 {
1413 json configFile = i2cCompareBytesFile;
1414 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["values"][0] =
1415 "0x820";
1416 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001417 "'0x820' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob Kingfb162bb2020-01-21 11:28:07 +08001418 }
1419 // Invalid: test i2c_compare_bytes with property masks more than 2 hex
1420 // digits.
1421 {
1422 json configFile = i2cCompareBytesFile;
1423 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["masks"][0] =
1424 "0x820";
1425 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001426 "'0x820' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob Kingfb162bb2020-01-21 11:28:07 +08001427 }
1428 // Invalid: test i2c_compare_bytes with property register less than 2 hex
1429 // digits.
1430 {
1431 json configFile = i2cCompareBytesFile;
1432 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["register"] =
1433 "0x8";
1434 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001435 "'0x8' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob Kingfb162bb2020-01-21 11:28:07 +08001436 }
1437 // Invalid: test i2c_compare_bytes with property values less than 2 hex
1438 // digits.
1439 {
1440 json configFile = i2cCompareBytesFile;
1441 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["values"][0] =
1442 "0x8";
1443 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001444 "'0x8' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob Kingfb162bb2020-01-21 11:28:07 +08001445 }
1446 // Invalid: test i2c_compare_bytes with property masks less than 2 hex
1447 // digits.
1448 {
1449 json configFile = i2cCompareBytesFile;
1450 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["masks"][0] =
1451 "0x8";
1452 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001453 "'0x8' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob Kingfb162bb2020-01-21 11:28:07 +08001454 }
1455 // Invalid: test i2c_compare_bytes with property register no leading prefix.
1456 {
1457 json configFile = i2cCompareBytesFile;
1458 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["register"] =
1459 "82";
1460 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001461 "'82' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob Kingfb162bb2020-01-21 11:28:07 +08001462 }
1463 // Invalid: test i2c_compare_bytes with property values no leading prefix.
1464 {
1465 json configFile = i2cCompareBytesFile;
1466 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["values"][0] =
1467 "82";
1468 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001469 "'82' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob Kingfb162bb2020-01-21 11:28:07 +08001470 }
1471 // Invalid: test i2c_compare_bytes with property masks no leading prefix.
1472 {
1473 json configFile = i2cCompareBytesFile;
1474 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["masks"][0] =
1475 "82";
1476 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001477 "'82' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob Kingfb162bb2020-01-21 11:28:07 +08001478 }
1479 // Invalid: test i2c_compare_bytes with property register invalid hex digit.
1480 {
1481 json configFile = i2cCompareBytesFile;
1482 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["register"] =
1483 "0xG1";
1484 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001485 "'0xG1' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob Kingfb162bb2020-01-21 11:28:07 +08001486 }
1487 // Invalid: test i2c_compare_bytes with property values invalid hex digit.
1488 {
1489 json configFile = i2cCompareBytesFile;
1490 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["values"][0] =
1491 "0xG1";
1492 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001493 "'0xG1' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob Kingfb162bb2020-01-21 11:28:07 +08001494 }
1495 // Invalid: test i2c_compare_bytes with property masks invalid hex digit.
1496 {
1497 json configFile = i2cCompareBytesFile;
1498 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["masks"][0] =
1499 "0xG1";
1500 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001501 "'0xG1' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob Kingfb162bb2020-01-21 11:28:07 +08001502 }
1503}
Bob Kingca93f1f2020-01-31 11:21:16 +08001504TEST(ValidateRegulatorsConfigTest, I2CInterface)
1505{
1506 // Valid: test i2c_interface.
1507 {
1508 json configFile = validConfigFile;
1509 EXPECT_JSON_VALID(configFile);
1510 }
1511 // Invalid: testi2c_interface with no bus.
1512 {
1513 json configFile = validConfigFile;
1514 configFile["chassis"][0]["devices"][0]["i2c_interface"].erase("bus");
1515 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001516 "'bus' is a required property");
Bob Kingca93f1f2020-01-31 11:21:16 +08001517 }
1518 // Invalid: test i2c_interface with no address.
1519 {
1520 json configFile = validConfigFile;
1521 configFile["chassis"][0]["devices"][0]["i2c_interface"].erase(
1522 "address");
1523 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001524 "'address' is a required property");
Bob Kingca93f1f2020-01-31 11:21:16 +08001525 }
1526 // Invalid: test i2c_interface with property bus wrong type.
1527 {
1528 json configFile = validConfigFile;
1529 configFile["chassis"][0]["devices"][0]["i2c_interface"]["bus"] = true;
1530 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001531 "True is not of type 'integer'");
Bob Kingca93f1f2020-01-31 11:21:16 +08001532 }
1533 // Invalid: test i2c_interface with property address wrong
1534 // type.
1535 {
1536 json configFile = validConfigFile;
1537 configFile["chassis"][0]["devices"][0]["i2c_interface"]["address"] =
1538 true;
1539 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001540 "True is not of type 'string'");
Bob Kingca93f1f2020-01-31 11:21:16 +08001541 }
1542 // Invalid: test i2c_interface with property bus less than
1543 // 0.
1544 {
1545 json configFile = validConfigFile;
1546 configFile["chassis"][0]["devices"][0]["i2c_interface"]["bus"] = -1;
1547 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1548 "-1 is less than the minimum of 0");
1549 }
1550 // Invalid: test i2c_interface with property address wrong
1551 // format.
1552 {
1553 json configFile = validConfigFile;
1554 configFile["chassis"][0]["devices"][0]["i2c_interface"]["address"] =
1555 "0x700";
1556 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001557 "'0x700' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob Kingca93f1f2020-01-31 11:21:16 +08001558 }
1559}
Bob King188db7d2020-01-31 13:01:01 +08001560TEST(ValidateRegulatorsConfigTest, I2CWriteBit)
1561{
1562 json i2cWriteBitFile = validConfigFile;
1563 i2cWriteBitFile["rules"][0]["actions"][1]["i2c_write_bit"]["register"] =
1564 "0xA0";
1565 i2cWriteBitFile["rules"][0]["actions"][1]["i2c_write_bit"]["position"] = 3;
1566 i2cWriteBitFile["rules"][0]["actions"][1]["i2c_write_bit"]["value"] = 1;
1567 // Valid: test rule actions i2c_write_bit.
1568 {
1569 json configFile = i2cWriteBitFile;
1570 EXPECT_JSON_VALID(configFile);
1571 }
1572 // Invalid: test i2c_write_bit with no register.
1573 {
1574 json configFile = i2cWriteBitFile;
1575 configFile["rules"][0]["actions"][1]["i2c_write_bit"].erase("register");
1576 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001577 "'register' is a required property");
Bob King188db7d2020-01-31 13:01:01 +08001578 }
1579 // Invalid: test i2c_write_bit with no position.
1580 {
1581 json configFile = i2cWriteBitFile;
1582 configFile["rules"][0]["actions"][1]["i2c_write_bit"].erase("position");
1583 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001584 "'position' is a required property");
Bob King188db7d2020-01-31 13:01:01 +08001585 }
1586 // Invalid: test i2c_write_bit with no value.
1587 {
1588 json configFile = i2cWriteBitFile;
1589 configFile["rules"][0]["actions"][1]["i2c_write_bit"].erase("value");
1590 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001591 "'value' is a required property");
Bob King188db7d2020-01-31 13:01:01 +08001592 }
1593 // Invalid: test i2c_write_bit with register wrong type.
1594 {
1595 json configFile = i2cWriteBitFile;
1596 configFile["rules"][0]["actions"][1]["i2c_write_bit"]["register"] = 1;
1597 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001598 "1 is not of type 'string'");
Bob King188db7d2020-01-31 13:01:01 +08001599 }
1600 // Invalid: test i2c_write_bit with register wrong format.
1601 {
1602 json configFile = i2cWriteBitFile;
1603 configFile["rules"][0]["actions"][1]["i2c_write_bit"]["register"] =
1604 "0xA00";
1605 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001606 "'0xA00' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08001607 }
1608 // Invalid: test i2c_write_bit with position wrong type.
1609 {
1610 json configFile = i2cWriteBitFile;
1611 configFile["rules"][0]["actions"][1]["i2c_write_bit"]["position"] = 3.1;
1612 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001613 "3.1 is not of type 'integer'");
Bob King188db7d2020-01-31 13:01:01 +08001614 }
1615 // Invalid: test i2c_write_bit with position greater than 7.
1616 {
1617 json configFile = i2cWriteBitFile;
1618 configFile["rules"][0]["actions"][1]["i2c_write_bit"]["position"] = 8;
1619 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1620 "8 is greater than the maximum of 7");
1621 }
1622 // Invalid: test i2c_write_bit with position less than 0.
1623 {
1624 json configFile = i2cWriteBitFile;
1625 configFile["rules"][0]["actions"][1]["i2c_write_bit"]["position"] = -1;
1626 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1627 "-1 is less than the minimum of 0");
1628 }
1629 // Invalid: test i2c_write_bit with value wrong type.
1630 {
1631 json configFile = i2cWriteBitFile;
1632 configFile["rules"][0]["actions"][1]["i2c_write_bit"]["value"] = "1";
1633 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001634 "'1' is not of type 'integer'");
Bob King188db7d2020-01-31 13:01:01 +08001635 }
1636 // Invalid: test i2c_write_bit with value greater than 1.
1637 {
1638 json configFile = i2cWriteBitFile;
1639 configFile["rules"][0]["actions"][1]["i2c_write_bit"]["value"] = 2;
1640 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1641 "2 is greater than the maximum of 1");
1642 }
1643 // Invalid: test i2c_write_bit with value less than 0.
1644 {
1645 json configFile = i2cWriteBitFile;
1646 configFile["rules"][0]["actions"][1]["i2c_write_bit"]["value"] = -1;
1647 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1648 "-1 is less than the minimum of 0");
1649 }
1650}
1651TEST(ValidateRegulatorsConfigTest, I2CWriteByte)
1652{
1653 json i2cWriteByteFile = validConfigFile;
1654 i2cWriteByteFile["rules"][0]["actions"][1]["i2c_write_byte"]["register"] =
1655 "0x82";
1656 i2cWriteByteFile["rules"][0]["actions"][1]["i2c_write_byte"]["value"] =
1657 "0x40";
1658 i2cWriteByteFile["rules"][0]["actions"][1]["i2c_write_byte"]["mask"] =
1659 "0x7F";
1660 // Valid: test i2c_write_byte with all properties.
1661 {
1662 json configFile = i2cWriteByteFile;
1663 EXPECT_JSON_VALID(configFile);
1664 }
1665 // Valid: test i2c_write_byte with all required properties.
1666 {
1667 json configFile = i2cWriteByteFile;
1668 configFile["rules"][0]["actions"][1]["i2c_write_byte"].erase("mask");
1669 EXPECT_JSON_VALID(configFile);
1670 }
1671 // Invalid: test i2c_write_byte with no register.
1672 {
1673 json configFile = i2cWriteByteFile;
1674 configFile["rules"][0]["actions"][1]["i2c_write_byte"].erase(
1675 "register");
1676 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001677 "'register' is a required property");
Bob King188db7d2020-01-31 13:01:01 +08001678 }
1679 // Invalid: test i2c_write_byte with no value.
1680 {
1681 json configFile = i2cWriteByteFile;
1682 configFile["rules"][0]["actions"][1]["i2c_write_byte"].erase("value");
1683 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001684 "'value' is a required property");
Bob King188db7d2020-01-31 13:01:01 +08001685 }
1686 // Invalid: test i2c_write_byte with property register wrong type.
1687 {
1688 json configFile = i2cWriteByteFile;
1689 configFile["rules"][0]["actions"][1]["i2c_write_byte"]["register"] = 1;
1690 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001691 "1 is not of type 'string'");
Bob King188db7d2020-01-31 13:01:01 +08001692 }
1693 // Invalid: test i2c_write_byte with property value wrong type.
1694 {
1695 json configFile = i2cWriteByteFile;
1696 configFile["rules"][0]["actions"][1]["i2c_write_byte"]["value"] = 1;
1697 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001698 "1 is not of type 'string'");
Bob King188db7d2020-01-31 13:01:01 +08001699 }
1700 // Invalid: test i2c_write_byte with property mask wrong type.
1701 {
1702 json configFile = i2cWriteByteFile;
1703 configFile["rules"][0]["actions"][1]["i2c_write_byte"]["mask"] = 1;
1704 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001705 "1 is not of type 'string'");
Bob King188db7d2020-01-31 13:01:01 +08001706 }
1707 // Invalid: test i2c_write_byte with property register more than 2 hex
1708 // digits.
1709 {
1710 json configFile = i2cWriteByteFile;
1711 configFile["rules"][0]["actions"][1]["i2c_write_byte"]["register"] =
1712 "0x820";
1713 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001714 "'0x820' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08001715 }
1716 // Invalid: test i2c_write_byte with property value more than 2 hex
1717 // digits.
1718 {
1719 json configFile = i2cWriteByteFile;
1720 configFile["rules"][0]["actions"][1]["i2c_write_byte"]["value"] =
1721 "0x820";
1722 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001723 "'0x820' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08001724 }
1725 // Invalid: test i2c_write_byte with property mask more than 2 hex digits.
1726 {
1727 json configFile = i2cWriteByteFile;
1728 configFile["rules"][0]["actions"][1]["i2c_write_byte"]["mask"] =
1729 "0x820";
1730 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001731 "'0x820' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08001732 }
1733 // Invalid: test i2c_write_byte with property register less than 2 hex
1734 // digits.
1735 {
1736 json configFile = i2cWriteByteFile;
1737 configFile["rules"][0]["actions"][1]["i2c_write_byte"]["register"] =
1738 "0x8";
1739 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001740 "'0x8' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08001741 }
1742 // Invalid: test i2c_write_byte with property value less than 2 hex
1743 // digits.
1744 {
1745 json configFile = i2cWriteByteFile;
1746 configFile["rules"][0]["actions"][1]["i2c_write_byte"]["value"] = "0x8";
1747 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001748 "'0x8' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08001749 }
1750 // Invalid: test i2c_write_byte with property mask less than 2 hex digits.
1751 {
1752 json configFile = i2cWriteByteFile;
1753 configFile["rules"][0]["actions"][1]["i2c_write_byte"]["mask"] = "0x8";
1754 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001755 "'0x8' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08001756 }
1757 // Invalid: test i2c_write_byte with property register no leading prefix.
1758 {
1759 json configFile = i2cWriteByteFile;
1760 configFile["rules"][0]["actions"][1]["i2c_write_byte"]["register"] =
1761 "82";
1762 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001763 "'82' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08001764 }
1765 // Invalid: test i2c_write_byte with property value no leading prefix.
1766 {
1767 json configFile = i2cWriteByteFile;
1768 configFile["rules"][0]["actions"][1]["i2c_write_byte"]["value"] = "82";
1769 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001770 "'82' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08001771 }
1772 // Invalid: test i2c_write_byte with property mask no leading prefix.
1773 {
1774 json configFile = i2cWriteByteFile;
1775 configFile["rules"][0]["actions"][1]["i2c_write_byte"]["mask"] = "82";
1776 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001777 "'82' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08001778 }
1779 // Invalid: test i2c_write_byte with property register invalid hex digit.
1780 {
1781 json configFile = i2cWriteByteFile;
1782 configFile["rules"][0]["actions"][1]["i2c_write_byte"]["register"] =
1783 "0xG1";
1784 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001785 "'0xG1' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08001786 }
1787 // Invalid: test i2c_write_byte with property value invalid hex digit.
1788 {
1789 json configFile = i2cWriteByteFile;
1790 configFile["rules"][0]["actions"][1]["i2c_write_byte"]["value"] =
1791 "0xG1";
1792 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001793 "'0xG1' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08001794 }
1795 // Invalid: test i2c_write_byte with property mask invalid hex digit.
1796 {
1797 json configFile = i2cWriteByteFile;
1798 configFile["rules"][0]["actions"][1]["i2c_write_byte"]["mask"] = "0xG1";
1799 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001800 "'0xG1' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08001801 }
1802}
1803TEST(ValidateRegulatorsConfigTest, I2CWriteBytes)
1804{
1805 json i2cWriteBytesFile = validConfigFile;
1806 i2cWriteBytesFile["rules"][0]["actions"][1]["i2c_write_bytes"]["register"] =
1807 "0x82";
1808 i2cWriteBytesFile["rules"][0]["actions"][1]["i2c_write_bytes"]["values"] = {
1809 "0x02", "0x73"};
1810 i2cWriteBytesFile["rules"][0]["actions"][1]["i2c_write_bytes"]["masks"] = {
1811 "0x7F", "0x7F"};
1812 // Valid: test i2c_write_bytes.
1813 {
1814 json configFile = i2cWriteBytesFile;
1815 EXPECT_JSON_VALID(configFile);
1816 }
1817 // Valid: test i2c_write_bytes with all required properties.
1818 {
1819 json configFile = i2cWriteBytesFile;
1820 configFile["rules"][0]["actions"][1]["i2c_write_bytes"].erase("masks");
1821 EXPECT_JSON_VALID(configFile);
1822 }
1823 // Invalid: test i2c_write_bytes with no register.
1824 {
1825 json configFile = i2cWriteBytesFile;
1826 configFile["rules"][0]["actions"][1]["i2c_write_bytes"].erase(
1827 "register");
1828 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001829 "'register' is a required property");
Bob King188db7d2020-01-31 13:01:01 +08001830 }
1831 // Invalid: test i2c_write_bytes with no values.
1832 {
1833 json configFile = i2cWriteBytesFile;
1834 configFile["rules"][0]["actions"][1]["i2c_write_bytes"].erase("values");
1835 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001836 "'values' is a required property");
Bob King188db7d2020-01-31 13:01:01 +08001837 }
1838 // Invalid: test i2c_write_bytes with property values as empty array.
1839 {
1840 json configFile = i2cWriteBytesFile;
1841 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["values"] =
1842 json::array();
1843 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1844 "[] is too short");
1845 }
1846 // Invalid: test i2c_write_bytes with property masks as empty array.
1847 {
1848 json configFile = i2cWriteBytesFile;
1849 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["masks"] =
1850 json::array();
1851 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1852 "[] is too short");
1853 }
1854 // Invalid: test i2c_write_bytes with property register wrong type.
1855 {
1856 json configFile = i2cWriteBytesFile;
1857 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["register"] = 1;
1858 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001859 "1 is not of type 'string'");
Bob King188db7d2020-01-31 13:01:01 +08001860 }
1861 // Invalid: test i2c_write_bytes with property values wrong type.
1862 {
1863 json configFile = i2cWriteBytesFile;
1864 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["values"] = 1;
1865 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001866 "1 is not of type 'array'");
Bob King188db7d2020-01-31 13:01:01 +08001867 }
1868 // Invalid: test i2c_write_bytes with property masks wrong type.
1869 {
1870 json configFile = i2cWriteBytesFile;
1871 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["masks"] = 1;
1872 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001873 "1 is not of type 'array'");
Bob King188db7d2020-01-31 13:01:01 +08001874 }
1875 // Invalid: test i2c_write_bytes with property register more than 2 hex
1876 // digits.
1877 {
1878 json configFile = i2cWriteBytesFile;
1879 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["register"] =
1880 "0x820";
1881 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001882 "'0x820' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08001883 }
1884 // Invalid: test i2c_write_bytes with property values more than 2 hex
1885 // digits.
1886 {
1887 json configFile = i2cWriteBytesFile;
1888 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["values"][0] =
1889 "0x820";
1890 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001891 "'0x820' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08001892 }
1893 // Invalid: test i2c_write_bytes with property masks more than 2 hex
1894 // digits.
1895 {
1896 json configFile = i2cWriteBytesFile;
1897 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["masks"][0] =
1898 "0x820";
1899 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001900 "'0x820' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08001901 }
1902 // Invalid: test i2c_write_bytes with property register less than 2 hex
1903 // digits.
1904 {
1905 json configFile = i2cWriteBytesFile;
1906 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["register"] =
1907 "0x8";
1908 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001909 "'0x8' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08001910 }
1911 // Invalid: test i2c_write_bytes with property values less than 2 hex
1912 // digits.
1913 {
1914 json configFile = i2cWriteBytesFile;
1915 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["values"][0] =
1916 "0x8";
1917 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001918 "'0x8' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08001919 }
1920 // Invalid: test i2c_write_bytes with property masks less than 2 hex
1921 // digits.
1922 {
1923 json configFile = i2cWriteBytesFile;
1924 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["masks"][0] =
1925 "0x8";
1926 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001927 "'0x8' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08001928 }
1929 // Invalid: test i2c_write_bytes with property register no leading prefix.
1930 {
1931 json configFile = i2cWriteBytesFile;
1932 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["register"] =
1933 "82";
1934 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001935 "'82' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08001936 }
1937 // Invalid: test i2c_write_bytes with property values no leading prefix.
1938 {
1939 json configFile = i2cWriteBytesFile;
1940 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["values"][0] =
1941 "82";
1942 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001943 "'82' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08001944 }
1945 // Invalid: test i2c_write_bytes with property masks no leading prefix.
1946 {
1947 json configFile = i2cWriteBytesFile;
1948 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["masks"][0] =
1949 "82";
1950 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001951 "'82' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08001952 }
1953 // Invalid: test i2c_write_bytes with property register invalid hex digit.
1954 {
1955 json configFile = i2cWriteBytesFile;
1956 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["register"] =
1957 "0xG1";
1958 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001959 "'0xG1' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08001960 }
1961 // Invalid: test i2c_write_bytes with property values invalid hex digit.
1962 {
1963 json configFile = i2cWriteBytesFile;
1964 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["values"][0] =
1965 "0xG1";
1966 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001967 "'0xG1' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08001968 }
1969 // Invalid: test i2c_write_bytes with property masks invalid hex digit.
1970 {
1971 json configFile = i2cWriteBytesFile;
1972 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["masks"][0] =
1973 "0xG1";
1974 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001975 "'0xG1' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08001976 }
1977}
Bob Kingead0b052020-01-21 11:29:03 +08001978TEST(ValidateRegulatorsConfigTest, If)
1979{
1980 json ifFile = validConfigFile;
Bob King2d27dcf2020-02-11 15:00:50 +08001981 ifFile["rules"][2]["actions"][0]["if"]["condition"]["run_rule"] =
1982 "set_voltage_rule";
1983 ifFile["rules"][2]["actions"][0]["if"]["then"][0]["run_rule"] =
1984 "read_sensors_rule";
1985 ifFile["rules"][2]["actions"][0]["if"]["else"][0]["run_rule"] =
1986 "read_sensors_rule";
1987 ifFile["rules"][2]["id"] = "rule_if";
Bob Kingead0b052020-01-21 11:29:03 +08001988 // Valid: test if.
1989 {
1990 json configFile = ifFile;
1991 EXPECT_JSON_VALID(configFile);
1992 }
1993 // Valid: test if with required properties.
1994 {
1995 json configFile = ifFile;
Bob King2d27dcf2020-02-11 15:00:50 +08001996 configFile["rules"][2]["actions"][0]["if"].erase("else");
Bob Kingead0b052020-01-21 11:29:03 +08001997 EXPECT_JSON_VALID(configFile);
1998 }
1999 // Invalid: test if with no property condition.
2000 {
2001 json configFile = ifFile;
Bob King2d27dcf2020-02-11 15:00:50 +08002002 configFile["rules"][2]["actions"][0]["if"].erase("condition");
Bob Kingead0b052020-01-21 11:29:03 +08002003 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002004 "'condition' is a required property");
Bob Kingead0b052020-01-21 11:29:03 +08002005 }
2006 // Invalid: test if with no property then.
2007 {
2008 json configFile = ifFile;
Bob King2d27dcf2020-02-11 15:00:50 +08002009 configFile["rules"][2]["actions"][0]["if"].erase("then");
Bob Kingead0b052020-01-21 11:29:03 +08002010 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002011 "'then' is a required property");
Bob Kingead0b052020-01-21 11:29:03 +08002012 }
2013 // Invalid: test if with property then empty array.
2014 {
2015 json configFile = ifFile;
Bob King2d27dcf2020-02-11 15:00:50 +08002016 configFile["rules"][2]["actions"][0]["if"]["then"] = json::array();
Bob Kingead0b052020-01-21 11:29:03 +08002017 EXPECT_JSON_INVALID(configFile, "Validation failed.",
2018 "[] is too short");
2019 }
2020 // Invalid: test if with property else empty array.
2021 {
2022 json configFile = ifFile;
Bob King2d27dcf2020-02-11 15:00:50 +08002023 configFile["rules"][2]["actions"][0]["if"]["else"] = json::array();
Bob Kingead0b052020-01-21 11:29:03 +08002024 EXPECT_JSON_INVALID(configFile, "Validation failed.",
2025 "[] is too short");
2026 }
2027 // Invalid: test if with property condition wrong type.
2028 {
2029 json configFile = ifFile;
Bob King2d27dcf2020-02-11 15:00:50 +08002030 configFile["rules"][2]["actions"][0]["if"]["condition"] = 1;
Bob Kingead0b052020-01-21 11:29:03 +08002031 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002032 "1 is not of type 'object'");
Bob Kingead0b052020-01-21 11:29:03 +08002033 }
2034 // Invalid: test if with property then wrong type.
2035 {
2036 json configFile = ifFile;
Bob King2d27dcf2020-02-11 15:00:50 +08002037 configFile["rules"][2]["actions"][0]["if"]["then"] = 1;
Bob Kingead0b052020-01-21 11:29:03 +08002038 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002039 "1 is not of type 'array'");
Bob Kingead0b052020-01-21 11:29:03 +08002040 }
2041 // Invalid: test if with property else wrong type.
2042 {
2043 json configFile = ifFile;
Bob King2d27dcf2020-02-11 15:00:50 +08002044 configFile["rules"][2]["actions"][0]["if"]["else"] = 1;
Bob Kingead0b052020-01-21 11:29:03 +08002045 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002046 "1 is not of type 'array'");
Bob Kingead0b052020-01-21 11:29:03 +08002047 }
2048}
Bob Kingbfe9fe72020-01-21 11:29:57 +08002049TEST(ValidateRegulatorsConfigTest, Not)
2050{
2051 json notFile = validConfigFile;
2052 notFile["rules"][0]["actions"][1]["not"]["i2c_compare_byte"]["register"] =
2053 "0xA0";
2054 notFile["rules"][0]["actions"][1]["not"]["i2c_compare_byte"]["value"] =
2055 "0xFF";
2056 // Valid: test not.
2057 {
2058 json configFile = notFile;
2059 EXPECT_JSON_VALID(configFile);
2060 }
2061 // Invalid: test not with wrong type.
2062 {
2063 json configFile = notFile;
2064 configFile["rules"][0]["actions"][1]["not"] = 1;
2065 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002066 "1 is not of type 'object'");
Bob Kingbfe9fe72020-01-21 11:29:57 +08002067 }
2068}
Bob Kingcfc29d02020-01-21 11:30:50 +08002069TEST(ValidateRegulatorsConfigTest, Or)
2070{
2071 json orFile = validConfigFile;
2072 orFile["rules"][0]["actions"][1]["or"][0]["i2c_compare_byte"]["register"] =
2073 "0xA0";
2074 orFile["rules"][0]["actions"][1]["or"][0]["i2c_compare_byte"]["value"] =
2075 "0x00";
2076 orFile["rules"][0]["actions"][1]["or"][1]["i2c_compare_byte"]["register"] =
2077 "0xA1";
2078 orFile["rules"][0]["actions"][1]["or"][1]["i2c_compare_byte"]["value"] =
2079 "0x00";
2080 // Valid: test or.
2081 {
2082 json configFile = orFile;
2083 EXPECT_JSON_VALID(configFile);
2084 }
2085 // Invalid: test or with empty array.
2086 {
2087 json configFile = orFile;
2088 configFile["rules"][0]["actions"][1]["or"] = json::array();
2089 EXPECT_JSON_INVALID(configFile, "Validation failed.",
2090 "[] is too short");
2091 }
2092 // Invalid: test or with wrong type.
2093 {
2094 json configFile = orFile;
2095 configFile["rules"][0]["actions"][1]["or"] = 1;
2096 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002097 "1 is not of type 'array'");
Bob Kingcfc29d02020-01-21 11:30:50 +08002098 }
2099}
Bob Kingd6618092020-01-21 11:31:46 +08002100TEST(ValidateRegulatorsConfigTest, PmbusReadSensor)
2101{
2102 json pmbusReadSensorFile = validConfigFile;
2103 pmbusReadSensorFile["rules"][0]["actions"][1]["pmbus_read_sensor"]["type"] =
2104 "vout";
2105 pmbusReadSensorFile["rules"][0]["actions"][1]["pmbus_read_sensor"]
2106 ["command"] = "0x8B";
2107 pmbusReadSensorFile["rules"][0]["actions"][1]["pmbus_read_sensor"]
2108 ["format"] = "linear_16";
2109 pmbusReadSensorFile["rules"][0]["actions"][1]["pmbus_read_sensor"]
2110 ["exponent"] = -8;
2111 // Valid: test pmbus_read_sensor.
2112 {
2113 json configFile = pmbusReadSensorFile;
2114 EXPECT_JSON_VALID(configFile);
2115 }
2116 // Valid: test pmbus_read_sensor with required properties.
2117 {
2118 json configFile = pmbusReadSensorFile;
2119 configFile["rules"][0]["actions"][1]["pmbus_read_sensor"].erase(
2120 "exponent");
2121 EXPECT_JSON_VALID(configFile);
2122 }
2123 // Invalid: test pmbus_read_sensor with no type.
2124 {
2125 json configFile = pmbusReadSensorFile;
2126 configFile["rules"][0]["actions"][1]["pmbus_read_sensor"].erase("type");
2127 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002128 "'type' is a required property");
Bob Kingd6618092020-01-21 11:31:46 +08002129 }
2130 // Invalid: test pmbus_read_sensor with no command.
2131 {
2132 json configFile = pmbusReadSensorFile;
2133 configFile["rules"][0]["actions"][1]["pmbus_read_sensor"].erase(
2134 "command");
2135 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002136 "'command' is a required property");
Bob Kingd6618092020-01-21 11:31:46 +08002137 }
2138 // Invalid: test pmbus_read_sensor with no format.
2139 {
2140 json configFile = pmbusReadSensorFile;
2141 configFile["rules"][0]["actions"][1]["pmbus_read_sensor"].erase(
2142 "format");
2143 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002144 "'format' is a required property");
Bob Kingd6618092020-01-21 11:31:46 +08002145 }
2146 // Invalid: test pmbus_read_sensor with property type wrong type.
2147 {
2148 json configFile = pmbusReadSensorFile;
2149 configFile["rules"][0]["actions"][1]["pmbus_read_sensor"]["type"] =
2150 true;
Bob King358c4172020-03-16 13:57:08 +08002151 EXPECT_JSON_INVALID(configFile, "Validation failed.",
2152 "True is not of type 'string'");
Bob Kingd6618092020-01-21 11:31:46 +08002153 }
2154 // Invalid: test pmbus_read_sensor with property command wrong type.
2155 {
2156 json configFile = pmbusReadSensorFile;
2157 configFile["rules"][0]["actions"][1]["pmbus_read_sensor"]["command"] =
2158 true;
2159 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002160 "True is not of type 'string'");
Bob Kingd6618092020-01-21 11:31:46 +08002161 }
2162 // Invalid: test pmbus_read_sensor with property format wrong type.
2163 {
2164 json configFile = pmbusReadSensorFile;
2165 configFile["rules"][0]["actions"][1]["pmbus_read_sensor"]["format"] =
2166 true;
2167 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002168 "True is not of type 'string'");
Bob Kingd6618092020-01-21 11:31:46 +08002169 }
2170 // Invalid: test pmbus_read_sensor with property exponent wrong type.
2171 {
2172 json configFile = pmbusReadSensorFile;
2173 configFile["rules"][0]["actions"][1]["pmbus_read_sensor"]["exponent"] =
2174 true;
2175 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002176 "True is not of type 'integer'");
Bob Kingd6618092020-01-21 11:31:46 +08002177 }
2178 // Invalid: test pmbus_read_sensor with property type wrong format.
2179 {
2180 json configFile = pmbusReadSensorFile;
2181 configFile["rules"][0]["actions"][1]["pmbus_read_sensor"]["type"] =
2182 "foo";
2183 EXPECT_JSON_INVALID(
2184 configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002185 "'foo' is not one of ['iout', 'iout_peak', 'iout_valley', "
2186 "'pout', 'temperature', 'temperature_peak', 'vout', "
2187 "'vout_peak', 'vout_valley']");
Bob Kingd6618092020-01-21 11:31:46 +08002188 }
2189 // Invalid: test pmbus_read_sensor with property command wrong format.
2190 {
2191 json configFile = pmbusReadSensorFile;
2192 configFile["rules"][0]["actions"][1]["pmbus_read_sensor"]["command"] =
2193 "0x8B0";
2194 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002195 "'0x8B0' does not match '^0x[0-9a-fA-F]{2}$'");
Bob Kingd6618092020-01-21 11:31:46 +08002196 }
2197 // Invalid: test pmbus_read_sensor with property format wrong format.
2198 {
2199 json configFile = pmbusReadSensorFile;
2200 configFile["rules"][0]["actions"][1]["pmbus_read_sensor"]["format"] =
2201 "foo";
Bob King358c4172020-03-16 13:57:08 +08002202 EXPECT_JSON_INVALID(configFile, "Validation failed.",
2203 "'foo' is not one of ['linear_11', 'linear_16']");
Bob Kingd6618092020-01-21 11:31:46 +08002204 }
2205}
Bob King02179c62020-01-21 11:32:36 +08002206TEST(ValidateRegulatorsConfigTest, PmbusWriteVoutCommand)
2207{
2208 json pmbusWriteVoutCommandFile = validConfigFile;
2209 pmbusWriteVoutCommandFile["rules"][0]["actions"][1]
2210 ["pmbus_write_vout_command"]["volts"] = 1.03;
2211 pmbusWriteVoutCommandFile["rules"][0]["actions"][1]
2212 ["pmbus_write_vout_command"]["format"] = "linear";
2213 pmbusWriteVoutCommandFile["rules"][0]["actions"][1]
2214 ["pmbus_write_vout_command"]["exponent"] = -8;
2215 pmbusWriteVoutCommandFile["rules"][0]["actions"][1]
2216 ["pmbus_write_vout_command"]["is_verified"] = true;
2217 // Valid: test pmbus_write_vout_command.
2218 {
2219 json configFile = pmbusWriteVoutCommandFile;
2220 EXPECT_JSON_VALID(configFile);
2221 }
2222 // Valid: test pmbus_write_vout_command with required properties.
2223 {
2224 json configFile = pmbusWriteVoutCommandFile;
2225 configFile["rules"][0]["actions"][1]["pmbus_write_vout_command"].erase(
2226 "volts");
2227 configFile["rules"][0]["actions"][1]["pmbus_write_vout_command"].erase(
2228 "exponent");
2229 configFile["rules"][0]["actions"][1]["pmbus_write_vout_command"].erase(
2230 "is_verified");
2231 EXPECT_JSON_VALID(configFile);
2232 }
2233 // Invalid: test pmbus_write_vout_command with no format.
2234 {
2235 json configFile = pmbusWriteVoutCommandFile;
2236 configFile["rules"][0]["actions"][1]["pmbus_write_vout_command"].erase(
2237 "format");
2238 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002239 "'format' is a required property");
Bob King02179c62020-01-21 11:32:36 +08002240 }
2241 // Invalid: test pmbus_write_vout_command with property volts wrong type.
2242 {
2243 json configFile = pmbusWriteVoutCommandFile;
2244 configFile["rules"][0]["actions"][1]["pmbus_write_vout_command"]
2245 ["volts"] = true;
2246 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002247 "True is not of type 'number'");
Bob King02179c62020-01-21 11:32:36 +08002248 }
2249 // Invalid: test pmbus_write_vout_command with property format wrong type.
2250 {
2251 json configFile = pmbusWriteVoutCommandFile;
2252 configFile["rules"][0]["actions"][1]["pmbus_write_vout_command"]
2253 ["format"] = true;
2254 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002255 "True is not of type 'string'");
Bob King02179c62020-01-21 11:32:36 +08002256 }
2257 // Invalid: test pmbus_write_vout_command with property exponent wrong type.
2258 {
2259 json configFile = pmbusWriteVoutCommandFile;
2260 configFile["rules"][0]["actions"][1]["pmbus_write_vout_command"]
2261 ["exponent"] = 1.3;
2262 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002263 "1.3 is not of type 'integer'");
Bob King02179c62020-01-21 11:32:36 +08002264 }
2265 // Invalid: test pmbus_write_vout_command with property is_verified wrong
2266 // type.
2267 {
2268 json configFile = pmbusWriteVoutCommandFile;
2269 configFile["rules"][0]["actions"][1]["pmbus_write_vout_command"]
2270 ["is_verified"] = 1;
2271 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002272 "1 is not of type 'boolean'");
Bob King02179c62020-01-21 11:32:36 +08002273 }
2274 // Invalid: test pmbus_write_vout_command with property format wrong format.
2275 {
2276 json configFile = pmbusWriteVoutCommandFile;
2277 configFile["rules"][0]["actions"][1]["pmbus_write_vout_command"]
2278 ["format"] = "foo";
2279 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002280 "'foo' is not one of ['linear']");
Bob King02179c62020-01-21 11:32:36 +08002281 }
2282}
Bob King99d8fa12020-01-31 11:23:40 +08002283TEST(ValidateRegulatorsConfigTest, PresenceDetection)
2284{
2285 json presenceDetectionFile = validConfigFile;
2286 presenceDetectionFile
2287 ["chassis"][0]["devices"][0]["presence_detection"]["comments"][0] =
2288 "Regulator is only present on the FooBar backplane";
2289 presenceDetectionFile["chassis"][0]["devices"][0]["presence_detection"]
Bob Kingf4ff1162020-02-11 15:13:38 +08002290 ["rule_id"] = "set_voltage_rule";
Bob King99d8fa12020-01-31 11:23:40 +08002291 // Valid: test presence_detection with only property rule_id.
2292 {
2293 json configFile = presenceDetectionFile;
2294 EXPECT_JSON_VALID(configFile);
2295 }
2296 // Valid: test presence_detection with only property actions.
2297 {
2298 json configFile = presenceDetectionFile;
2299 configFile["chassis"][0]["devices"][0]["presence_detection"].erase(
2300 "rule_id");
2301 configFile["chassis"][0]["devices"][0]["presence_detection"]["actions"]
2302 [0]["compare_presence"]["fru"] =
Bob Kinga76898f2020-10-13 15:08:33 +08002303 "system/chassis/motherboard/cpu3";
Bob King99d8fa12020-01-31 11:23:40 +08002304 configFile["chassis"][0]["devices"][0]["presence_detection"]["actions"]
2305 [0]["compare_presence"]["value"] = true;
2306 configFile["chassis"][0]["devices"][0]["presence_detection"].erase(
2307 "comments");
2308 EXPECT_JSON_VALID(configFile);
2309 }
2310 // Invalid: test presence_detection with both property rule_id and actions.
2311 {
2312 json configFile = presenceDetectionFile;
2313 configFile["chassis"][0]["devices"][0]["presence_detection"]["actions"]
2314 [0]["compare_presence"]["fru"] =
Bob Kinga76898f2020-10-13 15:08:33 +08002315 "system/chassis/motherboard/cpu3";
Bob King99d8fa12020-01-31 11:23:40 +08002316 configFile["chassis"][0]["devices"][0]["presence_detection"]["actions"]
2317 [0]["compare_presence"]["value"] = true;
2318 EXPECT_JSON_INVALID(
2319 configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002320 "{'actions': [{'compare_presence': {'fru': "
Bob Kinga76898f2020-10-13 15:08:33 +08002321 "'system/chassis/motherboard/cpu3', 'value': True}}], 'comments': "
Bob King358c4172020-03-16 13:57:08 +08002322 "['Regulator is only present on the FooBar backplane'], 'rule_id': "
2323 "'set_voltage_rule'} is valid under each of {'required': "
2324 "['actions']}, {'required': ['rule_id']}");
Bob King99d8fa12020-01-31 11:23:40 +08002325 }
2326 // Invalid: test presence_detection with no rule_id and actions.
2327 {
2328 json configFile = presenceDetectionFile;
2329 configFile["chassis"][0]["devices"][0]["presence_detection"].erase(
2330 "rule_id");
2331 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002332 "'rule_id' is a required property");
Bob King99d8fa12020-01-31 11:23:40 +08002333 }
2334 // Invalid: test presence_detection with property comments wrong type.
2335 {
2336 json configFile = presenceDetectionFile;
2337 configFile["chassis"][0]["devices"][0]["presence_detection"]
2338 ["comments"] = true;
2339 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002340 "True is not of type 'array'");
Bob King99d8fa12020-01-31 11:23:40 +08002341 }
2342 // Invalid: test presence_detection with property rule_id wrong type.
2343 {
2344 json configFile = presenceDetectionFile;
2345 configFile["chassis"][0]["devices"][0]["presence_detection"]
2346 ["rule_id"] = true;
2347 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002348 "True is not of type 'string'");
Bob King99d8fa12020-01-31 11:23:40 +08002349 }
2350 // Invalid: test presence_detection with property actions wrong type.
2351 {
2352 json configFile = presenceDetectionFile;
2353 configFile["chassis"][0]["devices"][0]["presence_detection"].erase(
2354 "rule_id");
2355 configFile["chassis"][0]["devices"][0]["presence_detection"]
2356 ["actions"] = true;
2357 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002358 "True is not of type 'array'");
Bob King99d8fa12020-01-31 11:23:40 +08002359 }
2360 // Invalid: test presence_detection with property rule_id wrong format.
2361 {
2362 json configFile = presenceDetectionFile;
2363 configFile["chassis"][0]["devices"][0]["presence_detection"]
2364 ["rule_id"] = "id@";
2365 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002366 "'id@' does not match '^[A-Za-z0-9_]+$'");
Bob King99d8fa12020-01-31 11:23:40 +08002367 }
2368 // Invalid: test presence_detection with property comments empty array.
2369 {
2370 json configFile = presenceDetectionFile;
2371 configFile["chassis"][0]["devices"][0]["presence_detection"]
2372 ["comments"] = json::array();
2373 EXPECT_JSON_INVALID(configFile, "Validation failed.",
2374 "[] is too short");
2375 }
2376 // Invalid: test presence_detection with property actions empty array.
2377 {
2378 json configFile = presenceDetectionFile;
2379 configFile["chassis"][0]["devices"][0]["presence_detection"].erase(
2380 "rule_id");
2381 configFile["chassis"][0]["devices"][0]["presence_detection"]
2382 ["actions"] = json::array();
2383 EXPECT_JSON_INVALID(configFile, "Validation failed.",
2384 "[] is too short");
2385 }
2386}
Bob Kinge9260b52020-01-21 11:46:13 +08002387TEST(ValidateRegulatorsConfigTest, Rail)
2388{
2389 // Valid: test rail.
2390 {
2391 json configFile = validConfigFile;
2392 EXPECT_JSON_VALID(configFile);
2393 }
2394 // Valid: test rail with required properties.
2395 {
2396 json configFile = validConfigFile;
2397 configFile["chassis"][0]["devices"][0]["rails"][0].erase("comments");
2398 configFile["chassis"][0]["devices"][0]["rails"][0].erase(
2399 "configuration");
2400 configFile["chassis"][0]["devices"][0]["rails"][0].erase(
2401 "sensor_monitoring");
2402 EXPECT_JSON_VALID(configFile);
2403 }
2404 // Invalid: test rail with no id.
2405 {
2406 json configFile = validConfigFile;
2407 configFile["chassis"][0]["devices"][0]["rails"][0].erase("id");
2408 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002409 "'id' is a required property");
Bob Kinge9260b52020-01-21 11:46:13 +08002410 }
2411 // Invalid: test rail with comments wrong type.
2412 {
2413 json configFile = validConfigFile;
2414 configFile["chassis"][0]["devices"][0]["rails"][0]["comments"] = true;
2415 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002416 "True is not of type 'array'");
Bob Kinge9260b52020-01-21 11:46:13 +08002417 }
2418 // Invalid: test rail with id wrong type.
2419 {
2420 json configFile = validConfigFile;
2421 configFile["chassis"][0]["devices"][0]["rails"][0]["id"] = true;
2422 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002423 "True is not of type 'string'");
Bob Kinge9260b52020-01-21 11:46:13 +08002424 }
2425 // Invalid: test rail with configuration wrong type.
2426 {
2427 json configFile = validConfigFile;
2428 configFile["chassis"][0]["devices"][0]["rails"][0]["configuration"] =
2429 true;
2430 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002431 "True is not of type 'object'");
Bob Kinge9260b52020-01-21 11:46:13 +08002432 }
2433 // Invalid: test rail with sensor_monitoring wrong type.
2434 {
2435 json configFile = validConfigFile;
2436 configFile["chassis"][0]["devices"][0]["rails"][0]
2437 ["sensor_monitoring"] = true;
2438 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002439 "True is not of type 'object'");
Bob Kinge9260b52020-01-21 11:46:13 +08002440 }
2441 // Invalid: test rail with comments empty array.
2442 {
2443 json configFile = validConfigFile;
2444 configFile["chassis"][0]["devices"][0]["rails"][0]["comments"] =
2445 json::array();
2446 EXPECT_JSON_INVALID(configFile, "Validation failed.",
2447 "[] is too short");
2448 }
2449 // Invalid: test rail with id wrong format.
2450 {
2451 json configFile = validConfigFile;
2452 configFile["chassis"][0]["devices"][0]["rails"][0]["id"] = "id~";
2453 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002454 "'id~' does not match '^[A-Za-z0-9_]+$'");
Bob Kinge9260b52020-01-21 11:46:13 +08002455 }
2456}
Bob King64df7da2020-01-31 12:04:12 +08002457TEST(ValidateRegulatorsConfigTest, Rule)
2458{
2459 // valid test comments property, id property,
2460 // action property specified.
2461 {
2462 json configFile = validConfigFile;
2463 EXPECT_JSON_VALID(configFile);
2464 }
2465
2466 // valid test rule with no comments
2467 {
2468 json configFile = validConfigFile;
2469 configFile["rules"][0].erase("comments");
2470 EXPECT_JSON_VALID(configFile);
2471 }
2472
2473 // invalid test comments property has invalid value type
2474 {
2475 json configFile = validConfigFile;
2476 configFile["rules"][0]["comments"] = {1};
2477 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002478 "1 is not of type 'string'");
Bob King64df7da2020-01-31 12:04:12 +08002479 }
2480
2481 // invalid test rule with no ID
2482 {
2483 json configFile = validConfigFile;
2484 configFile["rules"][0].erase("id");
2485 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002486 "'id' is a required property");
Bob King64df7da2020-01-31 12:04:12 +08002487 }
2488
2489 // invalid test id property has invalid value type (not string)
2490 {
2491 json configFile = validConfigFile;
2492 configFile["rules"][0]["id"] = true;
2493 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002494 "True is not of type 'string'");
Bob King64df7da2020-01-31 12:04:12 +08002495 }
2496
2497 // invalid test id property has invalid value
2498 {
2499 json configFile = validConfigFile;
2500 configFile["rules"][0]["id"] = "foo%";
2501 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002502 "'foo%' does not match '^[A-Za-z0-9_]+$'");
Bob King64df7da2020-01-31 12:04:12 +08002503 }
2504
2505 // invalid test rule with no actions property
2506 {
2507 json configFile = validConfigFile;
2508 configFile["rules"][0].erase("actions");
2509 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002510 "'actions' is a required property");
Bob King64df7da2020-01-31 12:04:12 +08002511 }
2512
2513 // valid test rule with multiple actions
2514 {
2515 json configFile = validConfigFile;
Bob King63d795f2020-02-11 15:22:09 +08002516 configFile["rules"][0]["actions"][1]["run_rule"] = "read_sensors_rule";
Bob King64df7da2020-01-31 12:04:12 +08002517 EXPECT_JSON_VALID(configFile);
2518 }
2519
2520 // invalid test actions property has invalid value type (not an array)
2521 {
2522 json configFile = validConfigFile;
2523 configFile["rules"][0]["actions"] = 1;
2524 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002525 "1 is not of type 'array'");
Bob King64df7da2020-01-31 12:04:12 +08002526 }
2527
2528 // invalid test actions property has invalid value of action
2529 {
2530 json configFile = validConfigFile;
2531 configFile["rules"][0]["actions"][0] = "foo";
2532 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002533 "'foo' is not of type 'object'");
Bob King64df7da2020-01-31 12:04:12 +08002534 }
2535
2536 // invalid test actions property has empty array
2537 {
2538 json configFile = validConfigFile;
2539 configFile["rules"][0]["actions"] = json::array();
2540 EXPECT_JSON_INVALID(configFile, "Validation failed.",
2541 "[] is too short");
2542 }
2543}
Bob Kinge86c2e52020-01-21 11:33:32 +08002544TEST(ValidateRegulatorsConfigTest, RunRule)
2545{
2546 json runRuleFile = validConfigFile;
Bob King7d3a9f12020-02-11 15:34:52 +08002547 runRuleFile["rules"][0]["actions"][1]["run_rule"] = "read_sensors_rule";
Bob Kinge86c2e52020-01-21 11:33:32 +08002548 // Valid: test run_rule.
2549 {
2550 json configFile = runRuleFile;
2551 EXPECT_JSON_VALID(configFile);
2552 }
2553 // Invalid: test run_rule wrong type.
2554 {
2555 json configFile = runRuleFile;
2556 configFile["rules"][0]["actions"][1]["run_rule"] = true;
2557 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002558 "True is not of type 'string'");
Bob Kinge86c2e52020-01-21 11:33:32 +08002559 }
2560 // Invalid: test run_rule wrong format.
2561 {
2562 json configFile = runRuleFile;
2563 configFile["rules"][0]["actions"][1]["run_rule"] = "set_voltage_rule%";
2564 EXPECT_JSON_INVALID(
2565 configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002566 "'set_voltage_rule%' does not match '^[A-Za-z0-9_]+$'");
Bob Kinge86c2e52020-01-21 11:33:32 +08002567 }
2568}
Bob Kingfcc2a2f2020-01-31 11:29:45 +08002569TEST(ValidateRegulatorsConfigTest, SensorMonitoring)
2570{
2571 // Valid: test rails sensor_monitoring with only property rule id.
2572 {
2573 json configFile = validConfigFile;
2574 EXPECT_JSON_VALID(configFile);
2575 }
2576 // Valid: test rails sensor_monitoring with only property actions.
2577 {
2578 json configFile = validConfigFile;
2579 configFile["chassis"][0]["devices"][0]["rails"][0]["sensor_monitoring"]
2580 .erase("rule_id");
2581 configFile["chassis"][0]["devices"][0]["rails"][0]["sensor_monitoring"]
2582 ["actions"][0]["compare_presence"]["fru"] =
Bob Kinga76898f2020-10-13 15:08:33 +08002583 "system/chassis/motherboard/cpu3";
Bob Kingfcc2a2f2020-01-31 11:29:45 +08002584 configFile["chassis"][0]["devices"][0]["rails"][0]["sensor_monitoring"]
2585 ["actions"][0]["compare_presence"]["value"] = true;
2586 configFile["chassis"][0]["devices"][0]["rails"][0]["sensor_monitoring"]
2587 ["comments"][0] = "comments";
2588 EXPECT_JSON_VALID(configFile);
2589 }
2590 // Invalid: test rails sensor_monitoring with both property rule_id and
2591 // actions.
2592 {
2593 json configFile = validConfigFile;
2594 configFile["chassis"][0]["devices"][0]["rails"][0]["sensor_monitoring"]
2595 ["actions"][0]["compare_presence"]["fru"] =
Bob Kinga76898f2020-10-13 15:08:33 +08002596 "system/chassis/motherboard/cpu3";
Bob Kingfcc2a2f2020-01-31 11:29:45 +08002597 configFile["chassis"][0]["devices"][0]["rails"][0]["sensor_monitoring"]
2598 ["actions"][0]["compare_presence"]["value"] = true;
2599 EXPECT_JSON_INVALID(
2600 configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002601 "{'actions': [{'compare_presence': {'fru': "
Bob Kinga76898f2020-10-13 15:08:33 +08002602 "'system/chassis/motherboard/cpu3', 'value': True}}], 'rule_id': "
Bob King358c4172020-03-16 13:57:08 +08002603 "'read_sensors_rule'} is valid under each of {'required': "
2604 "['actions']}, {'required': ['rule_id']}");
Bob Kingfcc2a2f2020-01-31 11:29:45 +08002605 }
2606 // Invalid: test rails sensor_monitoring with no rule_id and actions.
2607 {
2608 json configFile = validConfigFile;
2609 configFile["chassis"][0]["devices"][0]["rails"][0]["sensor_monitoring"]
2610 .erase("rule_id");
2611 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002612 "'rule_id' is a required property");
Bob Kingfcc2a2f2020-01-31 11:29:45 +08002613 }
2614 // Invalid: test rails sensor_monitoring with property comments wrong type.
2615 {
2616 json configFile = validConfigFile;
2617 configFile["chassis"][0]["devices"][0]["rails"][0]["sensor_monitoring"]
2618 ["comments"] = true;
2619 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002620 "True is not of type 'array'");
Bob Kingfcc2a2f2020-01-31 11:29:45 +08002621 }
2622 // Invalid: test rails sensor_monitoring with property rule_id wrong type.
2623 {
2624 json configFile = validConfigFile;
2625 configFile["chassis"][0]["devices"][0]["rails"][0]["sensor_monitoring"]
2626 ["rule_id"] = true;
2627 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002628 "True is not of type 'string'");
Bob Kingfcc2a2f2020-01-31 11:29:45 +08002629 }
2630 // Invalid: test rails sensor_monitoring with property actions wrong type.
2631 {
2632 json configFile = validConfigFile;
2633 configFile["chassis"][0]["devices"][0]["rails"][0]["sensor_monitoring"]
2634 .erase("rule_id");
2635 configFile["chassis"][0]["devices"][0]["rails"][0]["sensor_monitoring"]
2636 ["actions"] = true;
2637 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002638 "True is not of type 'array'");
Bob Kingfcc2a2f2020-01-31 11:29:45 +08002639 }
2640 // Invalid: test rails sensor_monitoring with property rule_id wrong format.
2641 {
2642 json configFile = validConfigFile;
2643 configFile["chassis"][0]["devices"][0]["rails"][0]["sensor_monitoring"]
2644 ["rule_id"] = "id@";
2645 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002646 "'id@' does not match '^[A-Za-z0-9_]+$'");
Bob Kingfcc2a2f2020-01-31 11:29:45 +08002647 }
2648 // Invalid: test rails sensor_monitoring with property comments empty array.
2649 {
2650 json configFile = validConfigFile;
2651 configFile["chassis"][0]["devices"][0]["rails"][0]["sensor_monitoring"]
2652 ["comments"] = json::array();
2653 EXPECT_JSON_INVALID(configFile, "Validation failed.",
2654 "[] is too short");
2655 }
2656 // Invalid: test rails sensor_monitoring with property actions empty array.
2657 {
2658 json configFile = validConfigFile;
2659 configFile["chassis"][0]["devices"][0]["rails"][0]["sensor_monitoring"]
2660 .erase("rule_id");
2661 configFile["chassis"][0]["devices"][0]["rails"][0]["sensor_monitoring"]
2662 ["actions"] = json::array();
2663 EXPECT_JSON_INVALID(configFile, "Validation failed.",
2664 "[] is too short");
2665 }
2666}
Bob King68230aa2020-01-21 11:34:33 +08002667TEST(ValidateRegulatorsConfigTest, SetDevice)
2668{
2669 json setDeviceFile = validConfigFile;
Bob King7d3a9f12020-02-11 15:34:52 +08002670 setDeviceFile["rules"][0]["actions"][1]["set_device"] = "vdd_regulator";
Bob King68230aa2020-01-21 11:34:33 +08002671 // Valid: test set_device.
2672 {
2673 json configFile = setDeviceFile;
2674 EXPECT_JSON_VALID(configFile);
2675 }
2676 // Invalid: test set_device wrong type.
2677 {
2678 json configFile = setDeviceFile;
2679 configFile["rules"][0]["actions"][1]["set_device"] = true;
2680 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002681 "True is not of type 'string'");
Bob King68230aa2020-01-21 11:34:33 +08002682 }
2683 // Invalid: test set_device wrong format.
2684 {
2685 json configFile = setDeviceFile;
2686 configFile["rules"][0]["actions"][1]["set_device"] = "io_expander2%";
Bob King358c4172020-03-16 13:57:08 +08002687 EXPECT_JSON_INVALID(configFile, "Validation failed.",
2688 "'io_expander2%' does not match '^[A-Za-z0-9_]+$'");
Bob King68230aa2020-01-21 11:34:33 +08002689 }
2690}
Bob King3643cc02020-01-31 11:32:56 +08002691TEST(ValidateRegulatorsConfigTest, DuplicateRuleID)
2692{
2693 // Invalid: test duplicate ID in rule.
2694 {
2695 json configFile = validConfigFile;
Bob Kingb3e48bc2020-02-18 09:59:09 +08002696 configFile["rules"][2]["id"] = "set_voltage_rule";
2697 configFile["rules"][2]["actions"][0]["pmbus_write_vout_command"]
Bob King3643cc02020-01-31 11:32:56 +08002698 ["format"] = "linear";
2699 EXPECT_JSON_INVALID(configFile, "Error: Duplicate rule ID.", "");
2700 }
2701}
2702TEST(ValidateRegulatorsConfigTest, DuplicateChassisNumber)
2703{
2704 // Invalid: test duplicate number in chassis.
2705 {
2706 json configFile = validConfigFile;
2707 configFile["chassis"][1]["number"] = 1;
2708 EXPECT_JSON_INVALID(configFile, "Error: Duplicate chassis number.", "");
2709 }
2710}
2711TEST(ValidateRegulatorsConfigTest, DuplicateDeviceID)
2712{
2713 // Invalid: test duplicate ID in device.
2714 {
2715 json configFile = validConfigFile;
2716 configFile["chassis"][0]["devices"][1]["id"] = "vdd_regulator";
2717 configFile["chassis"][0]["devices"][1]["is_regulator"] = true;
2718 configFile["chassis"][0]["devices"][1]["fru"] =
Bob Kinga76898f2020-10-13 15:08:33 +08002719 "system/chassis/motherboard/regulator1";
Bob King3643cc02020-01-31 11:32:56 +08002720 configFile["chassis"][0]["devices"][1]["i2c_interface"]["bus"] = 2;
2721 configFile["chassis"][0]["devices"][1]["i2c_interface"]["address"] =
2722 "0x71";
2723 EXPECT_JSON_INVALID(configFile, "Error: Duplicate device ID.", "");
2724 }
2725}
2726TEST(ValidateRegulatorsConfigTest, DuplicateRailID)
2727{
2728 // Invalid: test duplicate ID in rail.
2729 {
2730 json configFile = validConfigFile;
2731 configFile["chassis"][0]["devices"][0]["rails"][1]["id"] = "vdd";
2732 EXPECT_JSON_INVALID(configFile, "Error: Duplicate rail ID.", "");
2733 }
2734}
Bob King78793102020-03-13 13:16:09 +08002735TEST(ValidateRegulatorsConfigTest, DuplicateObjectID)
2736{
2737 // Invalid: test duplicate object ID in device and rail.
2738 {
2739 json configFile = validConfigFile;
2740 configFile["chassis"][0]["devices"][0]["rails"][1]["id"] =
2741 "vdd_regulator";
2742 EXPECT_JSON_INVALID(configFile, "Error: Duplicate ID.", "");
2743 }
2744 // Invalid: test duplicate object ID in device and rule.
2745 {
2746 json configFile = validConfigFile;
2747 configFile["rules"][2]["id"] = "vdd_regulator";
2748 configFile["rules"][2]["actions"][0]["pmbus_write_vout_command"]
2749 ["format"] = "linear";
2750 EXPECT_JSON_INVALID(configFile, "Error: Duplicate ID.", "");
2751 }
2752 // Invalid: test duplicate object ID in rule and rail.
2753 {
2754 json configFile = validConfigFile;
2755 configFile["chassis"][0]["devices"][0]["rails"][1]["id"] =
2756 "set_voltage_rule";
2757 EXPECT_JSON_INVALID(configFile, "Error: Duplicate ID.", "");
2758 }
2759}
Bob King3643cc02020-01-31 11:32:56 +08002760TEST(ValidateRegulatorsConfigTest, InfiniteLoops)
2761{
2762 // Invalid: test run_rule with infinite loop (rules run each other).
2763 {
2764 json configFile = validConfigFile;
2765 configFile["rules"][2]["actions"][0]["run_rule"] = "set_voltage_rule2";
2766 configFile["rules"][2]["id"] = "set_voltage_rule1";
2767 configFile["rules"][3]["actions"][0]["run_rule"] = "set_voltage_rule1";
2768 configFile["rules"][3]["id"] = "set_voltage_rule2";
2769 EXPECT_JSON_INVALID(configFile,
2770 "Infinite loop caused by run_rule actions.", "");
2771 }
2772 // Invalid: test run_rule with infinite loop (rule runs itself).
2773 {
2774 json configFile = validConfigFile;
2775 configFile["rules"][2]["actions"][0]["run_rule"] = "set_voltage_rule1";
2776 configFile["rules"][2]["id"] = "set_voltage_rule1";
2777 EXPECT_JSON_INVALID(configFile,
2778 "Infinite loop caused by run_rule actions.", "");
2779 }
2780 // Invalid: test run_rule with infinite loop (indirect loop).
2781 {
2782 json configFile = validConfigFile;
2783 configFile["rules"][2]["actions"][0]["run_rule"] = "set_voltage_rule2";
2784 configFile["rules"][2]["id"] = "set_voltage_rule1";
2785 configFile["rules"][3]["actions"][0]["run_rule"] = "set_voltage_rule3";
2786 configFile["rules"][3]["id"] = "set_voltage_rule2";
2787 configFile["rules"][4]["actions"][0]["run_rule"] = "set_voltage_rule1";
2788 configFile["rules"][4]["id"] = "set_voltage_rule3";
2789 EXPECT_JSON_INVALID(configFile,
2790 "Infinite loop caused by run_rule actions.", "");
2791 }
2792}
Bob Kingf88203a2020-02-18 13:26:07 +08002793TEST(ValidateRegulatorsConfigTest, RunRuleValueExists)
2794{
2795 // Invalid: test run_rule actions specify a rule ID that does not exist.
2796 {
2797 json configFile = validConfigFile;
2798 configFile["rules"][2]["actions"][0]["run_rule"] = "set_voltage_rule2";
2799 configFile["rules"][2]["id"] = "set_voltage_rule1";
2800 EXPECT_JSON_INVALID(configFile, "Error: Rule ID does not exist.", "");
2801 }
2802}
Bob King13b2ad92020-02-18 13:31:39 +08002803TEST(ValidateRegulatorsConfigTest, SetDeviceValueExists)
2804{
2805 // Invalid: test set_device actions specify a device ID that does not exist.
2806 {
2807 json configFile = validConfigFile;
2808 configFile["rules"][2]["actions"][0]["set_device"] = "vdd_regulator2";
2809 configFile["rules"][2]["id"] = "set_voltage_rule1";
2810 EXPECT_JSON_INVALID(configFile, "Error: Device ID does not exist.", "");
2811 }
2812}
Bob King21b09be2020-02-18 13:33:09 +08002813TEST(ValidateRegulatorsConfigTest, RuleIDExists)
2814{
2815 // Invalid: test rule_id property in configuration specifies a rule ID that
2816 // does not exist.
2817 {
2818 json configFile = validConfigFile;
2819 configFile["chassis"][0]["devices"][0]["configuration"]["rule_id"] =
2820 "set_voltage_rule2";
2821 EXPECT_JSON_INVALID(configFile, "Error: Rule ID does not exist.", "");
2822 }
2823 // Invalid: test rule_id property in presence_detection specifies a rule ID
2824 // that does not exist.
2825 {
2826 json configFile = validConfigFile;
2827 configFile["chassis"][0]["devices"][0]["presence_detection"]
2828 ["rule_id"] = "set_voltage_rule2";
2829 EXPECT_JSON_INVALID(configFile, "Error: Rule ID does not exist.", "");
2830 }
2831 // Invalid: test rule_id property in sensor_monitoring specifies a rule ID
2832 // that does not exist.
2833 {
2834 json configFile = validConfigFile;
2835 configFile["chassis"][0]["devices"][0]["rails"][0]["sensor_monitoring"]
2836 ["rule_id"] = "set_voltage_rule2";
2837 EXPECT_JSON_INVALID(configFile, "Error: Rule ID does not exist.", "");
2838 }
2839}
Bob Kingdc72b622020-02-18 13:36:18 +08002840TEST(ValidateRegulatorsConfigTest, NumberOfElementsInMasks)
2841{
2842 // Invalid: test number of elements in masks not equal to number in values
2843 // in i2c_compare_bytes.
2844 {
2845 json configFile = validConfigFile;
2846 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["register"] =
2847 "0x82";
2848 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["values"] = {
2849 "0x02", "0x73"};
2850 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["masks"] = {
2851 "0x7F"};
2852 EXPECT_JSON_INVALID(configFile,
2853 "Error: Invalid i2c_compare_bytes action.", "");
2854 }
2855 // Invalid: test number of elements in masks not equal to number in values
2856 // in i2c_write_bytes.
2857 {
2858 json configFile = validConfigFile;
2859 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["register"] =
2860 "0x82";
2861 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["values"] = {
2862 "0x02", "0x73"};
2863 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["masks"] = {
2864 "0x7F"};
2865 EXPECT_JSON_INVALID(configFile,
2866 "Error: Invalid i2c_write_bytes action.", "");
2867 }
2868}
Bob Kinged009652020-02-20 14:54:13 +08002869TEST(ValidateRegulatorsConfigTest, CommandLineSyntax)
2870{
Bob Kinga57e0812020-03-12 10:47:42 +08002871 std::string validateTool =
2872 " ../phosphor-regulators/tools/validate-regulators-config.py ";
Bob Kinged009652020-02-20 14:54:13 +08002873 std::string schema = " -s ";
Bob Kinga57e0812020-03-12 10:47:42 +08002874 std::string schemaFile =
2875 " ../phosphor-regulators/schema/config_schema.json ";
Bob Kinged009652020-02-20 14:54:13 +08002876 std::string configuration = " -c ";
2877 std::string command;
2878 std::string errorMessage;
2879 std::string outputMessage;
2880 std::string outputMessageHelp =
2881 "usage: validate-regulators-config.py [-h] [-s SCHEMA_FILE]";
2882 int valid = 0;
2883
Shawn McCarney0f6ebad2020-09-04 16:43:00 -05002884 TemporaryFile tmpFile;
2885 std::string fileName = tmpFile.getPath().string();
Bob Kinga57e0812020-03-12 10:47:42 +08002886 writeDataToFile(validConfigFile, fileName);
Bob Kinged009652020-02-20 14:54:13 +08002887 // Valid: -s specified
2888 {
2889 command = validateTool + "-s " + schemaFile + configuration + fileName;
2890 expectCommandLineSyntax(errorMessage, outputMessage, command, valid);
2891 }
2892 // Valid: --schema-file specified
2893 {
2894 command = validateTool + "--schema-file " + schemaFile + configuration +
2895 fileName;
2896 expectCommandLineSyntax(errorMessage, outputMessage, command, valid);
2897 }
2898 // Valid: -c specified
2899 {
2900 command = validateTool + schema + schemaFile + "-c " + fileName;
2901 expectCommandLineSyntax(errorMessage, outputMessage, command, valid);
2902 }
2903 // Valid: --configuration-file specified
2904 {
2905 command = validateTool + schema + schemaFile + "--configuration-file " +
2906 fileName;
2907 expectCommandLineSyntax(errorMessage, outputMessage, command, valid);
2908 }
2909 // Valid: -h specified
2910 {
2911 command = validateTool + "-h ";
2912 expectCommandLineSyntax(errorMessage, outputMessageHelp, command,
2913 valid);
2914 }
2915 // Valid: --help specified
2916 {
2917 command = validateTool + "--help ";
2918 expectCommandLineSyntax(errorMessage, outputMessageHelp, command,
2919 valid);
2920 }
2921 // Invalid: -c/--configuration-file not specified
2922 {
2923 command = validateTool + schema + schemaFile;
2924 expectCommandLineSyntax("Error: Configuration file is required.",
2925 outputMessageHelp, command, 1);
2926 }
2927 // Invalid: -s/--schema-file not specified
2928 {
2929 command = validateTool + configuration + fileName;
2930 expectCommandLineSyntax("Error: Schema file is required.",
2931 outputMessageHelp, command, 1);
2932 }
Bob Kingb7552f02020-10-15 14:34:17 +08002933 // Invalid: -c specified more than once
2934 {
2935 command = validateTool + schema + schemaFile + "-c -c " + fileName;
2936 expectCommandLineSyntax(outputMessageHelp, outputMessage, command, 2);
2937 }
Bob Kinged009652020-02-20 14:54:13 +08002938 // Invalid: -s specified more than once
2939 {
2940 command =
2941 validateTool + "-s -s " + schemaFile + configuration + fileName;
2942 expectCommandLineSyntax(outputMessageHelp, outputMessage, command, 2);
2943 }
Bob Kinged009652020-02-20 14:54:13 +08002944 // Invalid: No file name specified after -c
2945 {
2946 command = validateTool + schema + schemaFile + configuration;
2947 expectCommandLineSyntax(outputMessageHelp, outputMessage, command, 2);
2948 }
2949 // Invalid: No file name specified after -s
2950 {
2951 command = validateTool + schema + configuration + fileName;
2952 expectCommandLineSyntax(outputMessageHelp, outputMessage, command, 2);
2953 }
2954 // Invalid: File specified after -c does not exist
2955 {
2956 command = validateTool + schema + schemaFile + configuration +
2957 "../notExistFile";
Bob Kingb7552f02020-10-15 14:34:17 +08002958 expectCommandLineSyntax("Error: Configuration file does not exist.",
2959 outputMessageHelp, command, 1);
Bob Kinged009652020-02-20 14:54:13 +08002960 }
2961 // Invalid: File specified after -s does not exist
2962 {
2963 command = validateTool + schema + "../notExistFile " + configuration +
2964 fileName;
Bob Kingb7552f02020-10-15 14:34:17 +08002965 expectCommandLineSyntax("Error: Schema file does not exist.",
2966 outputMessageHelp, command, 1);
2967 }
2968 // Invalid: File specified after -c is not right data format
2969 {
2970 TemporaryFile wrongFormatFile;
2971 std::string wrongFormatFileName = wrongFormatFile.getPath().string();
2972 std::ofstream out(wrongFormatFileName);
2973 out << "foo";
2974 out.close();
2975 command = validateTool + schema + schemaFile + configuration +
2976 wrongFormatFileName;
Bob Kinged009652020-02-20 14:54:13 +08002977 expectCommandLineSyntax(
Bob Kingb7552f02020-10-15 14:34:17 +08002978 "Error: Configuration file is not in the JSON format.",
2979 outputMessageHelp, command, 1);
Bob Kinged009652020-02-20 14:54:13 +08002980 }
2981 // Invalid: File specified after -s is not right data format
2982 {
Shawn McCarney0f6ebad2020-09-04 16:43:00 -05002983 TemporaryFile wrongFormatFile;
2984 std::string wrongFormatFileName = wrongFormatFile.getPath().string();
Bob Kinga57e0812020-03-12 10:47:42 +08002985 std::ofstream out(wrongFormatFileName);
Bob Kinged009652020-02-20 14:54:13 +08002986 out << "foo";
2987 out.close();
Bob Kinga57e0812020-03-12 10:47:42 +08002988 command = validateTool + schema + wrongFormatFileName + configuration +
2989 fileName;
Bob Kingb7552f02020-10-15 14:34:17 +08002990 expectCommandLineSyntax("Error: Schema file is not in the JSON format.",
2991 outputMessageHelp, command, 1);
Bob Kinged009652020-02-20 14:54:13 +08002992 }
2993 // Invalid: File specified after -c is not readable
2994 {
Shawn McCarney0f6ebad2020-09-04 16:43:00 -05002995 TemporaryFile notReadableFile;
2996 std::string notReadableFileName = notReadableFile.getPath().string();
Bob Kinga57e0812020-03-12 10:47:42 +08002997 writeDataToFile(validConfigFile, notReadableFileName);
Bob Kinged009652020-02-20 14:54:13 +08002998 command = validateTool + schema + schemaFile + configuration +
Bob Kinga57e0812020-03-12 10:47:42 +08002999 notReadableFileName;
3000 chmod(notReadableFileName.c_str(), 0222);
Bob Kingb7552f02020-10-15 14:34:17 +08003001 expectCommandLineSyntax("Error: Configuration file is not readable.",
3002 outputMessageHelp, command, 1);
Bob Kinged009652020-02-20 14:54:13 +08003003 }
3004 // Invalid: File specified after -s is not readable
3005 {
Shawn McCarney0f6ebad2020-09-04 16:43:00 -05003006 TemporaryFile notReadableFile;
3007 std::string notReadableFileName = notReadableFile.getPath().string();
Bob Kinga57e0812020-03-12 10:47:42 +08003008 writeDataToFile(validConfigFile, notReadableFileName);
3009 command = validateTool + schema + notReadableFileName + configuration +
3010 fileName;
3011 chmod(notReadableFileName.c_str(), 0222);
Bob Kingb7552f02020-10-15 14:34:17 +08003012 expectCommandLineSyntax("Error: Schema file is not readable.",
3013 outputMessageHelp, command, 1);
Bob Kinged009652020-02-20 14:54:13 +08003014 }
3015 // Invalid: Unexpected parameter specified (like -g)
3016 {
3017 command = validateTool + schema + schemaFile + configuration +
3018 fileName + " -g";
3019 expectCommandLineSyntax(outputMessageHelp, outputMessage, command, 2);
3020 }
Bob Kinged009652020-02-20 14:54:13 +08003021}