blob: 2b915b903a69c46877cb37dfbb9e2e155e39ac5e [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 */
16#include <errno.h>
17#include <stdio.h>
18#include <stdlib.h>
Bob Kinged009652020-02-20 14:54:13 +080019#include <sys/stat.h>
Bob King386d33f2019-12-26 17:28:56 +080020#include <sys/wait.h>
21
Bob King386d33f2019-12-26 17:28:56 +080022#include <nlohmann/json.hpp>
23
Bob King0dcbdf52020-01-20 17:19:39 +080024#include <fstream>
25
Bob King386d33f2019-12-26 17:28:56 +080026#include <gtest/gtest.h>
27
28#define EXPECT_FILE_VALID(configFile) expectFileValid(configFile)
29#define EXPECT_FILE_INVALID(configFile, expectedErrorMessage, \
30 expectedOutputMessage) \
31 expectFileInvalid(configFile, expectedErrorMessage, expectedOutputMessage)
32#define EXPECT_JSON_VALID(configFileJson) expectJsonValid(configFileJson)
33#define EXPECT_JSON_INVALID(configFileJson, expectedErrorMessage, \
34 expectedOutputMessage) \
35 expectJsonInvalid(configFileJson, expectedErrorMessage, \
36 expectedOutputMessage)
37
38using json = nlohmann::json;
39
40const json validConfigFile = R"(
41 {
42 "comments": [ "Config file for a FooBar one-chassis system" ],
43
44 "rules": [
45 {
46 "comments": [ "Sets output voltage for a PMBus regulator rail" ],
47 "id": "set_voltage_rule",
48 "actions": [
49 {
50 "pmbus_write_vout_command": {
51 "format": "linear"
52 }
53 }
54 ]
Bob Kingb3e48bc2020-02-18 09:59:09 +080055 },
56 {
57 "comments": [ "Reads sensors from a PMBus regulator rail" ],
58 "id": "read_sensors_rule",
59 "actions": [
60 {
61 "comments": [ "Read output voltage from READ_VOUT." ],
62 "pmbus_read_sensor": {
63 "type": "vout",
64 "command": "0x8B",
65 "format": "linear_16"
66 }
67 }
68 ]
Bob King386d33f2019-12-26 17:28:56 +080069 }
70 ],
71
72 "chassis": [
73 {
74 "comments": [ "Chassis number 1 containing CPUs and memory" ],
75 "number": 1,
76 "devices": [
77 {
78 "comments": [ "IR35221 regulator producing the Vdd rail" ],
79 "id": "vdd_regulator",
80 "is_regulator": true,
81 "fru": "/system/chassis/motherboard/regulator1",
82 "i2c_interface": {
83 "bus": 1,
84 "address": "0x70"
85 },
86 "rails": [
87 {
88 "comments": [ "Vdd rail" ],
89 "id": "vdd",
90 "configuration": {
91 "volts": 1.03,
92 "rule_id": "set_voltage_rule"
93 },
94 "sensor_monitoring": {
95 "rule_id": "read_sensors_rule"
96 }
97 }
98 ]
99 }
100 ]
101 }
102 ]
103 }
104)"_json;
105
Bob Kinga57e0812020-03-12 10:47:42 +0800106class TmpFile
Bob King386d33f2019-12-26 17:28:56 +0800107{
Bob Kinga57e0812020-03-12 10:47:42 +0800108 public:
109 TmpFile()
Bob King386d33f2019-12-26 17:28:56 +0800110 {
Bob Kinga57e0812020-03-12 10:47:42 +0800111 int fd = mkstemp(fileName);
112 if (fd == -1)
113 {
114 perror("Can't create temporary file");
115 }
116 close(fd);
Bob King386d33f2019-12-26 17:28:56 +0800117 }
Bob Kinga57e0812020-03-12 10:47:42 +0800118
119 std::string getName()
120 {
121 return fileName;
122 }
123
124 ~TmpFile()
125 {
126 unlink(fileName);
127 }
128
129 private:
130 char fileName[17] = "/tmp/temp-XXXXXX";
131};
Bob King386d33f2019-12-26 17:28:56 +0800132
133std::string getValidationToolCommand(const std::string& configFileName)
134{
Bob Kinga57e0812020-03-12 10:47:42 +0800135 std::string command =
136 "../phosphor-regulators/tools/validate-regulators-config.py -s \
137 ../phosphor-regulators/schema/config_schema.json -c ";
Bob King386d33f2019-12-26 17:28:56 +0800138 command += configFileName;
139 return command;
140}
141
Bob Kinga57e0812020-03-12 10:47:42 +0800142int runToolForOutputWithCommand(std::string command,
143 std::string& standardOutput,
144 std::string& standardError)
Bob King386d33f2019-12-26 17:28:56 +0800145{
146 // run the validation tool with the temporary file and return the output
147 // of the validation tool.
Bob Kinga57e0812020-03-12 10:47:42 +0800148 TmpFile tmpFile;
149 command += " 2> " + tmpFile.getName();
Bob King386d33f2019-12-26 17:28:56 +0800150 // get the jsonschema print from validation tool.
151 char buffer[256];
Bob Kinga57e0812020-03-12 10:47:42 +0800152 std::string result;
Bob King386d33f2019-12-26 17:28:56 +0800153 // to get the stdout from the validation tool.
154 FILE* pipe = popen(command.c_str(), "r");
155 if (!pipe)
156 {
157 throw std::runtime_error("popen() failed!");
158 }
159 while (!std::feof(pipe))
160 {
161 if (fgets(buffer, sizeof buffer, pipe) != NULL)
162 {
163 result += buffer;
164 }
165 }
166 int returnValue = pclose(pipe);
167 // Check if pclose() failed
168 if (returnValue == -1)
169 {
170 // unable to close pipe. Print error and exit function.
171 throw std::runtime_error("pclose() failed!");
172 }
173 std::string firstLine = result.substr(0, result.find('\n'));
Bob Kinga57e0812020-03-12 10:47:42 +0800174 standardOutput = firstLine;
Bob King386d33f2019-12-26 17:28:56 +0800175 // Get command exit status from return value
176 int exitStatus = WEXITSTATUS(returnValue);
Bob Kinga57e0812020-03-12 10:47:42 +0800177
178 // Read the standardError from tmpFile.
179 std::ifstream input(tmpFile.getName().c_str());
180 std::string line;
181
182 if (std::getline(input, line))
183 {
184 standardError = line;
185 }
186
Bob King386d33f2019-12-26 17:28:56 +0800187 return exitStatus;
188}
189
Bob Kinged009652020-02-20 14:54:13 +0800190int runToolForOutput(const std::string& configFileName, std::string& output,
Bob Kinga57e0812020-03-12 10:47:42 +0800191 std::string& error)
Bob Kinged009652020-02-20 14:54:13 +0800192{
193 std::string command = getValidationToolCommand(configFileName);
Bob Kinga57e0812020-03-12 10:47:42 +0800194 return runToolForOutputWithCommand(command, output, error);
Bob Kinged009652020-02-20 14:54:13 +0800195}
196
Bob King386d33f2019-12-26 17:28:56 +0800197void expectFileValid(const std::string& configFileName)
198{
Bob Kinged009652020-02-20 14:54:13 +0800199 std::string errorMessage;
200 std::string outputMessage;
Bob Kinga57e0812020-03-12 10:47:42 +0800201 EXPECT_EQ(runToolForOutput(configFileName, outputMessage, errorMessage), 0);
Bob King386d33f2019-12-26 17:28:56 +0800202 EXPECT_EQ(errorMessage, "");
203 EXPECT_EQ(outputMessage, "");
204}
205
206void expectFileInvalid(const std::string& configFileName,
207 const std::string& expectedErrorMessage,
208 const std::string& expectedOutputMessage)
209{
Bob Kinged009652020-02-20 14:54:13 +0800210 std::string errorMessage;
211 std::string outputMessage;
Bob Kinga57e0812020-03-12 10:47:42 +0800212 EXPECT_EQ(runToolForOutput(configFileName, outputMessage, errorMessage), 1);
Bob King386d33f2019-12-26 17:28:56 +0800213 EXPECT_EQ(errorMessage, expectedErrorMessage);
214 EXPECT_EQ(outputMessage, expectedOutputMessage);
215}
216
Bob Kinga57e0812020-03-12 10:47:42 +0800217void writeDataToFile(const json configFileJson, std::string fileName)
Bob King386d33f2019-12-26 17:28:56 +0800218{
Bob King386d33f2019-12-26 17:28:56 +0800219 std::string jsonData = configFileJson.dump();
220 std::ofstream out(fileName);
221 out << jsonData;
222 out.close();
Bob Kinged009652020-02-20 14:54:13 +0800223}
224
225void expectJsonValid(const json configFileJson)
226{
227 std::string fileName;
Bob Kinga57e0812020-03-12 10:47:42 +0800228 TmpFile tmpFile;
229 fileName = tmpFile.getName();
230 writeDataToFile(configFileJson, fileName);
Bob Kinged009652020-02-20 14:54:13 +0800231
Bob King386d33f2019-12-26 17:28:56 +0800232 EXPECT_FILE_VALID(fileName);
Bob King386d33f2019-12-26 17:28:56 +0800233}
234
235void expectJsonInvalid(const json configFileJson,
236 const std::string& expectedErrorMessage,
237 const std::string& expectedOutputMessage)
238{
239 std::string fileName;
Bob Kinga57e0812020-03-12 10:47:42 +0800240 TmpFile tmpFile;
241 fileName = tmpFile.getName();
242 writeDataToFile(configFileJson, fileName);
Bob King386d33f2019-12-26 17:28:56 +0800243
244 EXPECT_FILE_INVALID(fileName, expectedErrorMessage, expectedOutputMessage);
Bob King386d33f2019-12-26 17:28:56 +0800245}
246
Bob Kinged009652020-02-20 14:54:13 +0800247void expectCommandLineSyntax(const std::string& expectedErrorMessage,
248 const std::string& expectedOutputMessage,
249 std::string command, int status)
250{
251 std::string errorMessage;
252 std::string outputMessage;
Bob Kinga57e0812020-03-12 10:47:42 +0800253 EXPECT_EQ(runToolForOutputWithCommand(command, outputMessage, errorMessage),
254 status);
Bob Kinged009652020-02-20 14:54:13 +0800255 EXPECT_EQ(errorMessage, expectedErrorMessage);
256 EXPECT_EQ(outputMessage, expectedOutputMessage);
257}
258
Bob King3afa7112020-03-19 09:35:31 +0800259TEST(ValidateRegulatorsConfigTest, Action)
260{
261 // Valid: Comments property not specified
262 {
263 json configFile = validConfigFile;
264 EXPECT_JSON_VALID(configFile);
265 }
266 // Valid: Comments property specified
267 {
268 json configFile = validConfigFile;
269 configFile["rules"][0]["actions"][0]["comments"][0] =
270 "Set VOUT_COMMAND";
271 EXPECT_JSON_VALID(configFile);
272 }
273 // Valid: and action type specified
274 {
275 json configFile = validConfigFile;
276 json andAction =
277 R"(
278 {
279 "and": [
280 { "i2c_compare_byte": { "register": "0xA0", "value": "0x00" } },
281 { "i2c_compare_byte": { "register": "0xA1", "value": "0x00" } }
282 ]
283 }
284 )"_json;
285 configFile["rules"][0]["actions"].push_back(andAction);
286 EXPECT_JSON_VALID(configFile);
287 }
288 // Valid: compare_presence action type specified
289 {
290 json configFile = validConfigFile;
291 configFile["rules"][0]["actions"][1]["compare_presence"]["fru"] =
292 "/system/chassis/motherboard/regulator2";
293 configFile["rules"][0]["actions"][1]["compare_presence"]["value"] =
294 true;
295 EXPECT_JSON_VALID(configFile);
296 }
297 // Valid: compare_vpd action type specified
298 {
299 json configFile = validConfigFile;
300 configFile["rules"][0]["actions"][1]["compare_vpd"]["fru"] =
301 "/system/chassis/motherboard/regulator2";
302 configFile["rules"][0]["actions"][1]["compare_vpd"]["keyword"] = "CCIN";
303 configFile["rules"][0]["actions"][1]["compare_vpd"]["value"] = "2D35";
304 EXPECT_JSON_VALID(configFile);
305 }
306 // Valid: i2c_compare_bit action type specified
307 {
308 json configFile = validConfigFile;
309 configFile["rules"][0]["actions"][1]["i2c_compare_bit"]["register"] =
310 "0xA0";
311 configFile["rules"][0]["actions"][1]["i2c_compare_bit"]["position"] = 3;
312 configFile["rules"][0]["actions"][1]["i2c_compare_bit"]["value"] = 1;
313 EXPECT_JSON_VALID(configFile);
314 }
315 // Valid: i2c_compare_byte action type specified
316 {
317 json configFile = validConfigFile;
318 configFile["rules"][0]["actions"][1]["i2c_compare_byte"]["register"] =
319 "0x82";
320 configFile["rules"][0]["actions"][1]["i2c_compare_byte"]["value"] =
321 "0x40";
322 configFile["rules"][0]["actions"][1]["i2c_compare_byte"]["mask"] =
323 "0x7F";
324 EXPECT_JSON_VALID(configFile);
325 }
326 // Valid: i2c_compare_bytes action type specified
327 {
328 json configFile = validConfigFile;
329 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["register"] =
330 "0x82";
331 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["values"] = {
332 "0x02", "0x73"};
333 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["masks"] = {
334 "0x7F", "0x7F"};
335 EXPECT_JSON_VALID(configFile);
336 }
337 // Valid: i2c_write_bit action type specified
338 {
339 json configFile = validConfigFile;
340 configFile["rules"][0]["actions"][1]["i2c_write_bit"]["register"] =
341 "0xA0";
342 configFile["rules"][0]["actions"][1]["i2c_write_bit"]["position"] = 3;
343 configFile["rules"][0]["actions"][1]["i2c_write_bit"]["value"] = 1;
344 EXPECT_JSON_VALID(configFile);
345 }
346 // Valid: i2c_write_byte action type specified
347 {
348 json configFile = validConfigFile;
349 configFile["rules"][0]["actions"][1]["i2c_write_byte"]["register"] =
350 "0x82";
351 configFile["rules"][0]["actions"][1]["i2c_write_byte"]["value"] =
352 "0x40";
353 configFile["rules"][0]["actions"][1]["i2c_write_byte"]["mask"] = "0x7F";
354 EXPECT_JSON_VALID(configFile);
355 }
356 // Valid: i2c_write_bytes action type specified
357 {
358 json configFile = validConfigFile;
359 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["register"] =
360 "0x82";
361 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["values"] = {
362 "0x02", "0x73"};
363 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["masks"] = {
364 "0x7F", "0x7F"};
365 EXPECT_JSON_VALID(configFile);
366 }
367 // Valid: if action type specified
368 {
369 json configFile = validConfigFile;
370 configFile["rules"][2]["actions"][0]["if"]["condition"]["run_rule"] =
371 "set_voltage_rule";
372 configFile["rules"][2]["actions"][0]["if"]["then"][0]["run_rule"] =
373 "read_sensors_rule";
374 configFile["rules"][2]["actions"][0]["if"]["else"][0]["run_rule"] =
375 "read_sensors_rule";
376 configFile["rules"][2]["id"] = "rule_if";
377 EXPECT_JSON_VALID(configFile);
378 }
379 // Valid: not action type specified
380 {
381 json configFile = validConfigFile;
382 configFile["rules"][0]["actions"][1]["not"]["i2c_compare_byte"]
383 ["register"] = "0xA0";
384 configFile["rules"][0]["actions"][1]["not"]["i2c_compare_byte"]
385 ["value"] = "0xFF";
386 EXPECT_JSON_VALID(configFile);
387 }
388 // Valid: or action type specified
389 {
390 json configFile = validConfigFile;
391 configFile["rules"][0]["actions"][1]["or"][0]["i2c_compare_byte"]
392 ["register"] = "0xA0";
393 configFile["rules"][0]["actions"][1]["or"][0]["i2c_compare_byte"]
394 ["value"] = "0x00";
395 configFile["rules"][0]["actions"][1]["or"][1]["i2c_compare_byte"]
396 ["register"] = "0xA1";
397 configFile["rules"][0]["actions"][1]["or"][1]["i2c_compare_byte"]
398 ["value"] = "0x00";
399 EXPECT_JSON_VALID(configFile);
400 }
401 // Valid: pmbus_read_sensor and pmbus_write_vout_command action type
402 // specified
403 {
404 EXPECT_JSON_VALID(validConfigFile);
405 }
406 // Valid: run_rule action type specified
407 {
408 json configFile = validConfigFile;
409 configFile["rules"][0]["actions"][1]["run_rule"] = "read_sensors_rule";
410 EXPECT_JSON_VALID(configFile);
411 }
412 // Valid: set_device action type specified
413 {
414 json configFile = validConfigFile;
415 configFile["rules"][0]["actions"][1]["set_device"] = "vdd_regulator";
416 EXPECT_JSON_VALID(configFile);
417 }
418 // Invalid: Wrong data type for comments (should be array of string)
419 {
420 json configFile = validConfigFile;
421 configFile["rules"][0]["actions"][0]["comments"] = true;
422 EXPECT_JSON_INVALID(configFile, "Validation failed.",
423 "True is not of type 'array'");
424 }
425 // Invalid: Wrong data type for action type (such as "i2c_write_byte": true)
426 {
427 json configFile = validConfigFile;
428 configFile["rules"][0]["actions"][1]["i2c_write_byte"] = true;
429 EXPECT_JSON_INVALID(configFile, "Validation failed.",
430 "True is not of type 'object'");
431 }
432 // Invalid: Empty comments array
433 {
434 json configFile = validConfigFile;
435 configFile["rules"][0]["actions"][0]["comments"] = json::array();
436 EXPECT_JSON_INVALID(configFile, "Validation failed.",
437 "[] is too short");
438 }
439 // Invalid: Comments array has wrong element type (should be string)
440 {
441 json configFile = validConfigFile;
442 configFile["rules"][0]["actions"][0]["comments"][0] = true;
443 EXPECT_JSON_INVALID(configFile, "Validation failed.",
444 "True is not of type 'string'");
445 }
446 // Invalid: No action type specified
447 {
448 json configFile = validConfigFile;
449 configFile["rules"][0]["actions"][1]["comments"][0] =
450 "Check if bit 3 is on";
451 EXPECT_JSON_INVALID(configFile, "Validation failed.",
452 "'and' is a required property");
453 }
454 // Invalid: Multiple action types specified (such as both 'compare_presence'
455 // and 'pmbus_write_vout_command')
456 {
457 json configFile = validConfigFile;
458 configFile["rules"][0]["actions"][0]["compare_presence"]["value"] =
459 true;
460 EXPECT_JSON_INVALID(
461 configFile, "Validation failed.",
462 "{'compare_presence': {'value': True}, 'pmbus_write_vout_command': "
463 "{'format': 'linear'}} is valid under each of {'required': "
464 "['pmbus_write_vout_command']}, {'required': "
465 "['compare_presence']}");
466 }
467 // Invalid: Unexpected property specified (like 'foo')
468 {
469 json configFile = validConfigFile;
470 configFile["rules"][0]["actions"][1]["foo"] = "foo";
471 EXPECT_JSON_INVALID(
472 configFile, "Validation failed.",
473 "Additional properties are not allowed ('foo' was unexpected)");
474 }
475}
Bob Kingbeaf6532020-01-21 11:03:49 +0800476TEST(ValidateRegulatorsConfigTest, And)
477{
478 // Valid.
479 {
480 json configFile = validConfigFile;
481 json andAction =
482 R"(
483 {
484 "and": [
485 { "i2c_compare_byte": { "register": "0xA0", "value": "0x00" } },
486 { "i2c_compare_byte": { "register": "0xA1", "value": "0x00" } }
487 ]
488 }
489 )"_json;
490 configFile["rules"][0]["actions"].push_back(andAction);
491 EXPECT_JSON_VALID(configFile);
492 }
493
494 // Invalid: actions property value is an empty array.
495 {
496 json configFile = validConfigFile;
497 json andAction =
498 R"(
499 {
500 "and": []
501 }
502 )"_json;
503 configFile["rules"][0]["actions"].push_back(andAction);
504 EXPECT_JSON_INVALID(configFile, "Validation failed.",
505 "[] is too short");
506 }
507
508 // Invalid: actions property has incorrect value data type.
509 {
510 json configFile = validConfigFile;
511 json andAction =
512 R"(
513 {
514 "and": true
515 }
516 )"_json;
517 configFile["rules"][0]["actions"].push_back(andAction);
518 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800519 "True is not of type 'array'");
Bob Kingbeaf6532020-01-21 11:03:49 +0800520 }
521
522 // Invalid: actions property value contains wrong element type
523 {
524 json configFile = validConfigFile;
525 json andAction =
526 R"(
527 {
528 "and": ["foo"]
529 }
530 )"_json;
531 configFile["rules"][0]["actions"].push_back(andAction);
532 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800533 "'foo' is not of type 'object'");
Bob Kingbeaf6532020-01-21 11:03:49 +0800534 }
535}
Bob King3728f562020-01-21 11:35:31 +0800536TEST(ValidateRegulatorsConfigTest, Chassis)
537{
538 // Valid: test chassis.
539 {
540 json configFile = validConfigFile;
541 EXPECT_JSON_VALID(configFile);
542 }
543 // Valid: test chassis with required properties.
544 {
545 json configFile = validConfigFile;
546 configFile["chassis"][0].erase("comments");
547 configFile["chassis"][0].erase("devices");
548 EXPECT_JSON_VALID(configFile);
549 }
550 // Invalid: test chassis with no number.
551 {
552 json configFile = validConfigFile;
553 configFile["chassis"][0].erase("number");
554 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800555 "'number' is a required property");
Bob King3728f562020-01-21 11:35:31 +0800556 }
557 // Invalid: test chassis with property comments wrong type.
558 {
559 json configFile = validConfigFile;
560 configFile["chassis"][0]["comments"] = true;
561 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800562 "True is not of type 'array'");
Bob King3728f562020-01-21 11:35:31 +0800563 }
564 // Invalid: test chassis with property number wrong type.
565 {
566 json configFile = validConfigFile;
567 configFile["chassis"][0]["number"] = 1.3;
568 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800569 "1.3 is not of type 'integer'");
Bob King3728f562020-01-21 11:35:31 +0800570 }
571 // Invalid: test chassis with property devices wrong type.
572 {
573 json configFile = validConfigFile;
574 configFile["chassis"][0]["devices"] = true;
575 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800576 "True is not of type 'array'");
Bob King3728f562020-01-21 11:35:31 +0800577 }
578 // Invalid: test chassis with property comments empty array.
579 {
580 json configFile = validConfigFile;
581 configFile["chassis"][0]["comments"] = json::array();
582 EXPECT_JSON_INVALID(configFile, "Validation failed.",
583 "[] is too short");
584 }
585 // Invalid: test chassis with property devices empty array.
586 {
587 json configFile = validConfigFile;
588 configFile["chassis"][0]["devices"] = json::array();
589 EXPECT_JSON_INVALID(configFile, "Validation failed.",
590 "[] is too short");
591 }
592 // Invalid: test chassis with property number less than 1.
593 {
594 json configFile = validConfigFile;
595 configFile["chassis"][0]["number"] = 0;
596 EXPECT_JSON_INVALID(configFile, "Validation failed.",
597 "0 is less than the minimum of 1");
598 }
599}
Bob Kingbf1cbea2020-01-21 11:08:50 +0800600TEST(ValidateRegulatorsConfigTest, ComparePresence)
601{
602 json comparePresenceFile = validConfigFile;
603 comparePresenceFile["rules"][0]["actions"][1]["compare_presence"]["fru"] =
604 "/system/chassis/motherboard/regulator2";
605 comparePresenceFile["rules"][0]["actions"][1]["compare_presence"]["value"] =
606 true;
607 // Valid.
608 {
609 json configFile = comparePresenceFile;
610 EXPECT_JSON_VALID(configFile);
611 }
612
613 // Invalid: no FRU property.
614 {
615 json configFile = comparePresenceFile;
616 configFile["rules"][0]["actions"][1]["compare_presence"].erase("fru");
617 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800618 "'fru' is a required property");
Bob Kingbf1cbea2020-01-21 11:08:50 +0800619 }
620
621 // Invalid: FRU property length is string less than 1.
622 {
623 json configFile = comparePresenceFile;
624 configFile["rules"][0]["actions"][1]["compare_presence"]["fru"] = "";
625 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800626 "'' is too short");
Bob Kingbf1cbea2020-01-21 11:08:50 +0800627 }
628
629 // Invalid: no value property.
630 {
631 json configFile = comparePresenceFile;
632 configFile["rules"][0]["actions"][1]["compare_presence"].erase("value");
633 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800634 "'value' is a required property");
Bob Kingbf1cbea2020-01-21 11:08:50 +0800635 }
636
637 // Invalid: value property type is not boolean.
638 {
639 json configFile = comparePresenceFile;
640 configFile["rules"][0]["actions"][1]["compare_presence"]["value"] = "1";
641 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800642 "'1' is not of type 'boolean'");
Bob Kingbf1cbea2020-01-21 11:08:50 +0800643 }
644
645 // Invalid: FRU property type is not string.
646 {
647 json configFile = comparePresenceFile;
648 configFile["rules"][0]["actions"][1]["compare_presence"]["fru"] = 1;
649 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800650 "1 is not of type 'string'");
Bob Kingbf1cbea2020-01-21 11:08:50 +0800651 }
652}
Bob Kingf8b77a02020-01-21 11:09:47 +0800653TEST(ValidateRegulatorsConfigTest, CompareVpd)
654{
655 json compareVpdFile = validConfigFile;
656 compareVpdFile["rules"][0]["actions"][1]["compare_vpd"]["fru"] =
657 "/system/chassis/motherboard/regulator2";
658 compareVpdFile["rules"][0]["actions"][1]["compare_vpd"]["keyword"] = "CCIN";
659 compareVpdFile["rules"][0]["actions"][1]["compare_vpd"]["value"] = "2D35";
660
661 // Valid.
662 {
663 json configFile = compareVpdFile;
664 EXPECT_JSON_VALID(configFile);
665 }
666
667 // Invalid: no FRU property.
668 {
669 json configFile = compareVpdFile;
670 configFile["rules"][0]["actions"][1]["compare_vpd"].erase("fru");
671 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800672 "'fru' is a required property");
Bob Kingf8b77a02020-01-21 11:09:47 +0800673 }
674
675 // Invalid: no keyword property.
676 {
677 json configFile = compareVpdFile;
678 configFile["rules"][0]["actions"][1]["compare_vpd"].erase("keyword");
679 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800680 "'keyword' is a required property");
Bob Kingf8b77a02020-01-21 11:09:47 +0800681 }
682
683 // Invalid: no value property.
684 {
685 json configFile = compareVpdFile;
686 configFile["rules"][0]["actions"][1]["compare_vpd"].erase("value");
687 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800688 "'value' is a required property");
Bob Kingf8b77a02020-01-21 11:09:47 +0800689 }
690
691 // Invalid: property FRU wrong type.
692 {
693 json configFile = compareVpdFile;
694 configFile["rules"][0]["actions"][1]["compare_vpd"]["fru"] = 1;
695 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800696 "1 is not of type 'string'");
Bob Kingf8b77a02020-01-21 11:09:47 +0800697 }
698
699 // Invalid: property FRU is string less than 1.
700 {
701 json configFile = compareVpdFile;
702 configFile["rules"][0]["actions"][1]["compare_vpd"]["fru"] = "";
703 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800704 "'' is too short");
Bob Kingf8b77a02020-01-21 11:09:47 +0800705 }
706
707 // Invalid: property keyword is not "CCIN", "Manufacturer", "Model",
708 // "PartNumber"
709 {
710 json configFile = compareVpdFile;
711 configFile["rules"][0]["actions"][1]["compare_vpd"]["keyword"] =
712 "Number";
713 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800714 "'Number' is not one of ['CCIN', "
715 "'Manufacturer', 'Model', 'PartNumber']");
Bob Kingf8b77a02020-01-21 11:09:47 +0800716 }
717
718 // Invalid: property value wrong type.
719 {
720 json configFile = compareVpdFile;
721 configFile["rules"][0]["actions"][1]["compare_vpd"]["value"] = 1;
722 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800723 "1 is not of type 'string'");
Bob Kingf8b77a02020-01-21 11:09:47 +0800724 }
725}
Bob King20057412020-03-16 16:50:17 +0800726TEST(ValidateRegulatorsConfigTest, ConfigFile)
727{
728 // Valid: Only required properties specified
729 {
730 json configFile;
731 configFile["chassis"][0]["number"] = 1;
732 EXPECT_JSON_VALID(configFile);
733 }
734 // Valid: All properties specified
735 {
736 json configFile = validConfigFile;
737 EXPECT_JSON_VALID(configFile);
738 }
739 // Invalid: Required chassis property not specified
740 {
741 json configFile = validConfigFile;
742 configFile.erase("chassis");
743 EXPECT_JSON_INVALID(configFile, "Validation failed.",
744 "'chassis' is a required property");
745 }
746 // Invalid: Wrong data type for comments
747 {
748 json configFile = validConfigFile;
749 configFile["comments"] = true;
750 EXPECT_JSON_INVALID(configFile, "Validation failed.",
751 "True is not of type 'array'");
752 }
753 // Invalid: Wrong data type for rules
754 {
755 json configFile = validConfigFile;
756 configFile["rules"] = true;
757 EXPECT_JSON_INVALID(configFile, "Validation failed.",
758 "True is not of type 'array'");
759 }
760 // Invalid: Wrong data type for chassis
761 {
762 json configFile = validConfigFile;
763 configFile["chassis"] = true;
764 EXPECT_JSON_INVALID(configFile, "Validation failed.",
765 "True is not of type 'array'");
766 }
767 // Invalid: Empty comments array;
768 {
769 json configFile = validConfigFile;
770 configFile["comments"] = json::array();
771 EXPECT_JSON_INVALID(configFile, "Validation failed.",
772 "[] is too short");
773 }
774 // Invalid: Empty rules array
775 {
776 json configFile = validConfigFile;
777 configFile["rules"] = json::array();
778 EXPECT_JSON_INVALID(configFile, "Validation failed.",
779 "[] is too short");
780 }
781 // Invalid: Empty chassis array
782 {
783 json configFile = validConfigFile;
784 configFile["chassis"] = json::array();
785 EXPECT_JSON_INVALID(configFile, "Validation failed.",
786 "[] is too short");
787 }
788 // Invalid: Comments array has wrong element type (should be string)
789 {
790 json configFile = validConfigFile;
791 configFile["comments"][0] = true;
792 EXPECT_JSON_INVALID(configFile, "Validation failed.",
793 "True is not of type 'string'");
794 }
795 // Invalid: Rules array has wrong element type (should be rule)
796 {
797 json configFile = validConfigFile;
798 configFile["rules"][0] = true;
799 EXPECT_JSON_INVALID(configFile, "Validation failed.",
800 "True is not of type 'object'");
801 }
802 // Invalid: Chassis array has wrong element type (should be chassis)
803 {
804 json configFile = validConfigFile;
805 configFile["chassis"][0] = true;
806 EXPECT_JSON_INVALID(configFile, "Validation failed.",
807 "True is not of type 'object'");
808 }
809 // Invalid: Unexpected property specified
810 {
811 json configFile = validConfigFile;
812 configFile["foo"] = json::array();
813 EXPECT_JSON_INVALID(
814 configFile, "Validation failed.",
815 "Additional properties are not allowed ('foo' was unexpected)");
816 }
817}
Bob King4c67a3a2020-02-07 09:48:11 +0800818TEST(ValidateRegulatorsConfigTest, Configuration)
819{
820 json configurationFile = validConfigFile;
821 configurationFile["chassis"][0]["devices"][0]["configuration"]["comments"]
822 [0] = "Set rail to 1.25V using standard rule";
823 configurationFile["chassis"][0]["devices"][0]["configuration"]["volts"] =
824 1.25;
825 configurationFile["chassis"][0]["devices"][0]["configuration"]["rule_id"] =
826 "set_voltage_rule";
827 // Valid: test configuration with property rule_id and with no actions.
828 {
829 json configFile = configurationFile;
Bob King78793102020-03-13 13:16:09 +0800830 configFile["chassis"][0]["devices"][0]["configuration"]["comments"][1] =
831 "test multiple array elements in comments.";
Bob King4c67a3a2020-02-07 09:48:11 +0800832 EXPECT_JSON_VALID(configFile);
833 }
834 // Valid: test configuration with property actions and with no rule_id.
835 {
836 json configFile = configurationFile;
837 configFile["chassis"][0]["devices"][0]["configuration"].erase(
838 "rule_id");
839 configFile["chassis"][0]["devices"][0]["configuration"]["actions"][0]
840 ["compare_presence"]["fru"] =
841 "/system/chassis/motherboard/cpu3";
842 configFile["chassis"][0]["devices"][0]["configuration"]["actions"][0]
843 ["compare_presence"]["value"] = true;
844 EXPECT_JSON_VALID(configFile);
845 }
846 // Valid: comments not specified (optional property).
847 {
848 json configFile = configurationFile;
849 configFile["chassis"][0]["devices"][0]["configuration"].erase(
850 "comments");
851 EXPECT_JSON_VALID(configFile);
852 }
853 // Valid: volts not specified (optional property).
854 {
855 json configFile = configurationFile;
856 configFile["chassis"][0]["devices"][0]["configuration"].erase("volts");
857 EXPECT_JSON_VALID(configFile);
858 }
859 // Valid: configuration is property of a rail (vs. a device).
860 {
861 json configFile = validConfigFile;
862 configFile["chassis"][0]["devices"][0]["rails"][0]["configuration"]
863 ["comments"][0] = "Set rail to 1.25V using standard rule";
864 configFile["chassis"][0]["devices"][0]["rails"][0]["configuration"]
865 ["volts"] = 1.25;
866 configFile["chassis"][0]["devices"][0]["rails"][0]["configuration"]
867 ["rule_id"] = "set_voltage_rule";
868 EXPECT_JSON_VALID(configFile);
869 }
870 // Invalid: comments property has wrong data type (not an array).
871 {
872 json configFile = configurationFile;
873 configFile["chassis"][0]["devices"][0]["configuration"]["comments"] = 1;
874 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800875 "1 is not of type 'array'");
Bob King4c67a3a2020-02-07 09:48:11 +0800876 }
877 // Invalid: test configuration with both actions and rule_id properties.
878 {
879 json configFile = configurationFile;
880 configFile["chassis"][0]["devices"][0]["configuration"]["actions"][0]
881 ["compare_presence"]["fru"] =
882 "/system/chassis/motherboard/cpu3";
883 configFile["chassis"][0]["devices"][0]["configuration"]["actions"][0]
884 ["compare_presence"]["value"] = true;
885 EXPECT_JSON_INVALID(
886 configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800887 "{'actions': [{'compare_presence': {'fru': "
888 "'/system/chassis/motherboard/cpu3', 'value': True}}], 'comments': "
889 "['Set rail to 1.25V using standard rule'], 'rule_id': "
890 "'set_voltage_rule', 'volts': 1.25} is valid under each of "
891 "{'required': ['actions']}, {'required': ['rule_id']}");
Bob King4c67a3a2020-02-07 09:48:11 +0800892 }
893 // Invalid: test configuration with no rule_id and actions.
894 {
895 json configFile = configurationFile;
896 configFile["chassis"][0]["devices"][0]["configuration"].erase(
897 "rule_id");
898 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800899 "'rule_id' is a required property");
Bob King4c67a3a2020-02-07 09:48:11 +0800900 }
901 // Invalid: test configuration with property volts wrong type.
902 {
903 json configFile = configurationFile;
904 configFile["chassis"][0]["devices"][0]["configuration"]["volts"] = true;
905 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800906 "True is not of type 'number'");
Bob King4c67a3a2020-02-07 09:48:11 +0800907 }
908 // Invalid: test configuration with property rule_id wrong type.
909 {
910 json configFile = configurationFile;
911 configFile["chassis"][0]["devices"][0]["configuration"]["rule_id"] =
912 true;
913 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800914 "True is not of type 'string'");
Bob King4c67a3a2020-02-07 09:48:11 +0800915 }
916 // Invalid: test configuration with property actions wrong type.
917 {
918 json configFile = configurationFile;
919 configFile["chassis"][0]["devices"][0]["configuration"].erase(
920 "rule_id");
921 configFile["chassis"][0]["devices"][0]["configuration"]["actions"] =
922 true;
923 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800924 "True is not of type 'array'");
Bob King4c67a3a2020-02-07 09:48:11 +0800925 }
926 // Invalid: test configuration with property comments empty array.
927 {
928 json configFile = configurationFile;
929 configFile["chassis"][0]["devices"][0]["configuration"]["comments"] =
930 json::array();
931 EXPECT_JSON_INVALID(configFile, "Validation failed.",
932 "[] is too short");
933 }
934 // Invalid: test configuration with property rule_id wrong format.
935 {
936 json configFile = configurationFile;
937 configFile["chassis"][0]["devices"][0]["configuration"]["rule_id"] =
938 "id!";
939 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800940 "'id!' does not match '^[A-Za-z0-9_]+$'");
Bob King4c67a3a2020-02-07 09:48:11 +0800941 }
942 // Invalid: test configuration with property actions empty array.
943 {
944 json configFile = configurationFile;
945 configFile["chassis"][0]["devices"][0]["configuration"].erase(
946 "rule_id");
947 configFile["chassis"][0]["devices"][0]["configuration"]["actions"] =
948 json::array();
949 EXPECT_JSON_INVALID(configFile, "Validation failed.",
950 "[] is too short");
951 }
952}
Bob Kinga2ba2df2020-02-04 14:38:44 +0800953TEST(ValidateRegulatorsConfigTest, Device)
954{
955
956 // Valid: test devices.
957 {
958 json configFile = validConfigFile;
959 EXPECT_JSON_VALID(configFile);
960 }
961 // Valid: test devices with required properties.
962 {
963 json configFile = validConfigFile;
964 configFile["chassis"][0]["devices"][0].erase("comments");
965 configFile["chassis"][0]["devices"][0].erase("presence_detection");
966 configFile["chassis"][0]["devices"][0].erase("configuration");
967 configFile["chassis"][0]["devices"][0].erase("rails");
968 EXPECT_JSON_VALID(configFile);
969 }
970 // Invalid: test devices with no id.
971 {
972 json configFile = validConfigFile;
973 configFile["chassis"][0]["devices"][0].erase("id");
974 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800975 "'id' is a required property");
Bob Kinga2ba2df2020-02-04 14:38:44 +0800976 }
977 // Invalid: test devices with no is_regulator.
978 {
979 json configFile = validConfigFile;
980 configFile["chassis"][0]["devices"][0].erase("is_regulator");
981 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800982 "'is_regulator' is a required property");
Bob Kinga2ba2df2020-02-04 14:38:44 +0800983 }
984 // Invalid: test devices with no fru.
985 {
986 json configFile = validConfigFile;
987 configFile["chassis"][0]["devices"][0].erase("fru");
988 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800989 "'fru' is a required property");
Bob Kinga2ba2df2020-02-04 14:38:44 +0800990 }
991 // Invalid: test devices with no i2c_interface.
992 {
993 json configFile = validConfigFile;
994 configFile["chassis"][0]["devices"][0].erase("i2c_interface");
995 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800996 "'i2c_interface' is a required property");
Bob Kinga2ba2df2020-02-04 14:38:44 +0800997 }
998 // Invalid: test devices with property comments wrong type.
999 {
1000 json configFile = validConfigFile;
1001 configFile["chassis"][0]["devices"][0]["comments"] = true;
1002 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001003 "True is not of type 'array'");
Bob Kinga2ba2df2020-02-04 14:38:44 +08001004 }
1005 // Invalid: test devices with property id wrong type.
1006 {
1007 json configFile = validConfigFile;
1008 configFile["chassis"][0]["devices"][0]["id"] = true;
1009 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001010 "True is not of type 'string'");
Bob Kinga2ba2df2020-02-04 14:38:44 +08001011 }
1012 // Invalid: test devices with property is_regulator wrong type.
1013 {
1014 json configFile = validConfigFile;
1015 configFile["chassis"][0]["devices"][0]["is_regulator"] = 1;
1016 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001017 "1 is not of type 'boolean'");
Bob Kinga2ba2df2020-02-04 14:38:44 +08001018 }
1019 // Invalid: test devices with property fru wrong type.
1020 {
1021 json configFile = validConfigFile;
1022 configFile["chassis"][0]["devices"][0]["fru"] = true;
1023 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001024 "True is not of type 'string'");
Bob Kinga2ba2df2020-02-04 14:38:44 +08001025 }
1026 // Invalid: test devices with property i2c_interface wrong type.
1027 {
1028 json configFile = validConfigFile;
1029 configFile["chassis"][0]["devices"][0]["i2c_interface"] = true;
1030 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001031 "True is not of type 'object'");
Bob Kinga2ba2df2020-02-04 14:38:44 +08001032 }
1033 // Invalid: test devices with property presence_detection wrong
1034 // type.
1035 {
1036 json configFile = validConfigFile;
1037 configFile["chassis"][0]["devices"][0]["presence_detection"] = true;
1038 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001039 "True is not of type 'object'");
Bob Kinga2ba2df2020-02-04 14:38:44 +08001040 }
1041 // Invalid: test devices with property configuration wrong type.
1042 {
1043 json configFile = validConfigFile;
1044 configFile["chassis"][0]["devices"][0]["configuration"] = true;
1045 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001046 "True is not of type 'object'");
Bob Kinga2ba2df2020-02-04 14:38:44 +08001047 }
1048 // Invalid: test devices with property rails wrong type.
1049 {
1050 json configFile = validConfigFile;
1051 configFile["chassis"][0]["devices"][0]["rails"] = true;
1052 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001053 "True is not of type 'array'");
Bob Kinga2ba2df2020-02-04 14:38:44 +08001054 }
1055 // Invalid: test devices with property comments empty array.
1056 {
1057 json configFile = validConfigFile;
1058 configFile["chassis"][0]["devices"][0]["comments"] = json::array();
1059 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1060 "[] is too short");
1061 }
1062 // Invalid: test devices with property fru length less than 1.
1063 {
1064 json configFile = validConfigFile;
1065 configFile["chassis"][0]["devices"][0]["fru"] = "";
1066 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001067 "'' is too short");
Bob Kinga2ba2df2020-02-04 14:38:44 +08001068 }
1069 // Invalid: test devices with property id wrong format.
1070 {
1071 json configFile = validConfigFile;
1072 configFile["chassis"][0]["devices"][0]["id"] = "id#";
1073 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001074 "'id#' does not match '^[A-Za-z0-9_]+$'");
Bob Kinga2ba2df2020-02-04 14:38:44 +08001075 }
1076 // Invalid: test devices with property rails empty array.
1077 {
1078 json configFile = validConfigFile;
1079 configFile["chassis"][0]["devices"][0]["rails"] = json::array();
1080 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1081 "[] is too short");
1082 }
1083}
Bob King4ab8cbb2020-01-21 11:10:48 +08001084TEST(ValidateRegulatorsConfigTest, I2CCompareBit)
1085{
1086 json i2cCompareBitFile = validConfigFile;
1087 i2cCompareBitFile["rules"][0]["actions"][1]["i2c_compare_bit"]["register"] =
1088 "0xA0";
1089 i2cCompareBitFile["rules"][0]["actions"][1]["i2c_compare_bit"]["position"] =
1090 3;
1091 i2cCompareBitFile["rules"][0]["actions"][1]["i2c_compare_bit"]["value"] = 1;
1092 // Valid: test rule actions i2c_compare_bit.
1093 {
1094 json configFile = i2cCompareBitFile;
1095 EXPECT_JSON_VALID(configFile);
1096 }
1097 // Invalid: test i2c_compare_bit with no register.
1098 {
1099 json configFile = i2cCompareBitFile;
1100 configFile["rules"][0]["actions"][1]["i2c_compare_bit"].erase(
1101 "register");
1102 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001103 "'register' is a required property");
Bob King4ab8cbb2020-01-21 11:10:48 +08001104 }
1105 // Invalid: test i2c_compare_bit with no position.
1106 {
1107 json configFile = i2cCompareBitFile;
1108 configFile["rules"][0]["actions"][1]["i2c_compare_bit"].erase(
1109 "position");
1110 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001111 "'position' is a required property");
Bob King4ab8cbb2020-01-21 11:10:48 +08001112 }
1113 // Invalid: test i2c_compare_bit with no value.
1114 {
1115 json configFile = i2cCompareBitFile;
1116 configFile["rules"][0]["actions"][1]["i2c_compare_bit"].erase("value");
1117 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001118 "'value' is a required property");
Bob King4ab8cbb2020-01-21 11:10:48 +08001119 }
1120 // Invalid: test i2c_compare_bit with register wrong type.
1121 {
1122 json configFile = i2cCompareBitFile;
1123 configFile["rules"][0]["actions"][1]["i2c_compare_bit"]["register"] = 1;
1124 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001125 "1 is not of type 'string'");
Bob King4ab8cbb2020-01-21 11:10:48 +08001126 }
1127 // Invalid: test i2c_compare_bit with register wrong format.
1128 {
1129 json configFile = i2cCompareBitFile;
1130 configFile["rules"][0]["actions"][1]["i2c_compare_bit"]["register"] =
1131 "0xA00";
1132 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001133 "'0xA00' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King4ab8cbb2020-01-21 11:10:48 +08001134 }
1135 // Invalid: test i2c_compare_bit with position wrong type.
1136 {
1137 json configFile = i2cCompareBitFile;
1138 configFile["rules"][0]["actions"][1]["i2c_compare_bit"]["position"] =
1139 3.1;
1140 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001141 "3.1 is not of type 'integer'");
Bob King4ab8cbb2020-01-21 11:10:48 +08001142 }
1143 // Invalid: test i2c_compare_bit with position greater than 7.
1144 {
1145 json configFile = i2cCompareBitFile;
1146 configFile["rules"][0]["actions"][1]["i2c_compare_bit"]["position"] = 8;
1147 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1148 "8 is greater than the maximum of 7");
1149 }
1150 // Invalid: test i2c_compare_bit with position less than 0.
1151 {
1152 json configFile = i2cCompareBitFile;
1153 configFile["rules"][0]["actions"][1]["i2c_compare_bit"]["position"] =
1154 -1;
1155 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1156 "-1 is less than the minimum of 0");
1157 }
1158 // Invalid: test i2c_compare_bit with value wrong type.
1159 {
1160 json configFile = i2cCompareBitFile;
1161 configFile["rules"][0]["actions"][1]["i2c_compare_bit"]["value"] = "1";
1162 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001163 "'1' is not of type 'integer'");
Bob King4ab8cbb2020-01-21 11:10:48 +08001164 }
1165 // Invalid: test i2c_compare_bit with value greater than 1.
1166 {
1167 json configFile = i2cCompareBitFile;
1168 configFile["rules"][0]["actions"][1]["i2c_compare_bit"]["value"] = 2;
1169 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1170 "2 is greater than the maximum of 1");
1171 }
1172 // Invalid: test i2c_compare_bit with value less than 0.
1173 {
1174 json configFile = i2cCompareBitFile;
1175 configFile["rules"][0]["actions"][1]["i2c_compare_bit"]["value"] = -1;
1176 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1177 "-1 is less than the minimum of 0");
1178 }
1179}
Bob King514023d2020-01-21 11:13:05 +08001180TEST(ValidateRegulatorsConfigTest, I2CCompareByte)
1181{
1182 json i2cCompareByteFile = validConfigFile;
1183 i2cCompareByteFile["rules"][0]["actions"][1]["i2c_compare_byte"]
1184 ["register"] = "0x82";
1185 i2cCompareByteFile["rules"][0]["actions"][1]["i2c_compare_byte"]["value"] =
1186 "0x40";
1187 i2cCompareByteFile["rules"][0]["actions"][1]["i2c_compare_byte"]["mask"] =
1188 "0x7F";
1189 // Valid: test i2c_compare_byte with all properties.
1190 {
1191 json configFile = i2cCompareByteFile;
1192 EXPECT_JSON_VALID(configFile);
1193 }
1194 // Valid: test i2c_compare_byte with all required properties.
1195 {
1196 json configFile = i2cCompareByteFile;
1197 configFile["rules"][0]["actions"][1]["i2c_compare_byte"].erase("mask");
1198 EXPECT_JSON_VALID(configFile);
1199 }
1200 // Invalid: test i2c_compare_byte with no register.
1201 {
1202 json configFile = i2cCompareByteFile;
1203 configFile["rules"][0]["actions"][1]["i2c_compare_byte"].erase(
1204 "register");
1205 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001206 "'register' is a required property");
Bob King514023d2020-01-21 11:13:05 +08001207 }
1208 // Invalid: test i2c_compare_byte with no value.
1209 {
1210 json configFile = i2cCompareByteFile;
1211 configFile["rules"][0]["actions"][1]["i2c_compare_byte"].erase("value");
1212 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001213 "'value' is a required property");
Bob King514023d2020-01-21 11:13:05 +08001214 }
1215 // Invalid: test i2c_compare_byte with property register wrong type.
1216 {
1217 json configFile = i2cCompareByteFile;
1218 configFile["rules"][0]["actions"][1]["i2c_compare_byte"]["register"] =
1219 1;
1220 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001221 "1 is not of type 'string'");
Bob King514023d2020-01-21 11:13:05 +08001222 }
1223 // Invalid: test i2c_compare_byte with property value wrong type.
1224 {
1225 json configFile = i2cCompareByteFile;
1226 configFile["rules"][0]["actions"][1]["i2c_compare_byte"]["value"] = 1;
1227 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001228 "1 is not of type 'string'");
Bob King514023d2020-01-21 11:13:05 +08001229 }
1230 // Invalid: test i2c_compare_byte with property mask wrong type.
1231 {
1232 json configFile = i2cCompareByteFile;
1233 configFile["rules"][0]["actions"][1]["i2c_compare_byte"]["mask"] = 1;
1234 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001235 "1 is not of type 'string'");
Bob King514023d2020-01-21 11:13:05 +08001236 }
1237 // Invalid: test i2c_compare_byte with property register more than 2 hex
1238 // digits.
1239 {
1240 json configFile = i2cCompareByteFile;
1241 configFile["rules"][0]["actions"][1]["i2c_compare_byte"]["register"] =
1242 "0x820";
1243 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001244 "'0x820' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King514023d2020-01-21 11:13:05 +08001245 }
1246 // Invalid: test i2c_compare_byte with property value more than 2 hex
1247 // digits.
1248 {
1249 json configFile = i2cCompareByteFile;
1250 configFile["rules"][0]["actions"][1]["i2c_compare_byte"]["value"] =
1251 "0x820";
1252 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001253 "'0x820' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King514023d2020-01-21 11:13:05 +08001254 }
1255 // Invalid: test i2c_compare_byte with property mask more than 2 hex digits.
1256 {
1257 json configFile = i2cCompareByteFile;
1258 configFile["rules"][0]["actions"][1]["i2c_compare_byte"]["mask"] =
1259 "0x820";
1260 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001261 "'0x820' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King514023d2020-01-21 11:13:05 +08001262 }
1263 // Invalid: test i2c_compare_byte with property register less than 2 hex
1264 // digits.
1265 {
1266 json configFile = i2cCompareByteFile;
1267 configFile["rules"][0]["actions"][1]["i2c_compare_byte"]["register"] =
1268 "0x8";
1269 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001270 "'0x8' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King514023d2020-01-21 11:13:05 +08001271 }
1272 // Invalid: test i2c_compare_byte with property value less than 2 hex
1273 // digits.
1274 {
1275 json configFile = i2cCompareByteFile;
1276 configFile["rules"][0]["actions"][1]["i2c_compare_byte"]["value"] =
1277 "0x8";
1278 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001279 "'0x8' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King514023d2020-01-21 11:13:05 +08001280 }
1281 // Invalid: test i2c_compare_byte with property mask less than 2 hex digits.
1282 {
1283 json configFile = i2cCompareByteFile;
1284 configFile["rules"][0]["actions"][1]["i2c_compare_byte"]["mask"] =
1285 "0x8";
1286 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001287 "'0x8' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King514023d2020-01-21 11:13:05 +08001288 }
1289 // Invalid: test i2c_compare_byte with property register no leading prefix.
1290 {
1291 json configFile = i2cCompareByteFile;
1292 configFile["rules"][0]["actions"][1]["i2c_compare_byte"]["register"] =
1293 "82";
1294 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001295 "'82' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King514023d2020-01-21 11:13:05 +08001296 }
1297 // Invalid: test i2c_compare_byte with property value no leading prefix.
1298 {
1299 json configFile = i2cCompareByteFile;
1300 configFile["rules"][0]["actions"][1]["i2c_compare_byte"]["value"] =
1301 "82";
1302 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001303 "'82' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King514023d2020-01-21 11:13:05 +08001304 }
1305 // Invalid: test i2c_compare_byte with property mask no leading prefix.
1306 {
1307 json configFile = i2cCompareByteFile;
1308 configFile["rules"][0]["actions"][1]["i2c_compare_byte"]["mask"] = "82";
1309 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001310 "'82' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King514023d2020-01-21 11:13:05 +08001311 }
1312 // Invalid: test i2c_compare_byte with property register invalid hex digit.
1313 {
1314 json configFile = i2cCompareByteFile;
1315 configFile["rules"][0]["actions"][1]["i2c_compare_byte"]["register"] =
1316 "0xG1";
1317 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001318 "'0xG1' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King514023d2020-01-21 11:13:05 +08001319 }
1320 // Invalid: test i2c_compare_byte with property value invalid hex digit.
1321 {
1322 json configFile = i2cCompareByteFile;
1323 configFile["rules"][0]["actions"][1]["i2c_compare_byte"]["value"] =
1324 "0xG1";
1325 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001326 "'0xG1' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King514023d2020-01-21 11:13:05 +08001327 }
1328 // Invalid: test i2c_compare_byte with property mask invalid hex digit.
1329 {
1330 json configFile = i2cCompareByteFile;
1331 configFile["rules"][0]["actions"][1]["i2c_compare_byte"]["mask"] =
1332 "0xG1";
1333 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001334 "'0xG1' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King514023d2020-01-21 11:13:05 +08001335 }
1336}
Bob Kingfb162bb2020-01-21 11:28:07 +08001337TEST(ValidateRegulatorsConfigTest, I2CCompareBytes)
1338{
1339 json i2cCompareBytesFile = validConfigFile;
1340 i2cCompareBytesFile["rules"][0]["actions"][1]["i2c_compare_bytes"]
1341 ["register"] = "0x82";
1342 i2cCompareBytesFile["rules"][0]["actions"][1]["i2c_compare_bytes"]
1343 ["values"] = {"0x02", "0x73"};
1344 i2cCompareBytesFile["rules"][0]["actions"][1]["i2c_compare_bytes"]
1345 ["masks"] = {"0x7F", "0x7F"};
1346 // Valid: test i2c_compare_bytes.
1347 {
1348 json configFile = i2cCompareBytesFile;
1349 EXPECT_JSON_VALID(configFile);
1350 }
1351 // Valid: test i2c_compare_bytes with all required properties.
1352 {
1353 json configFile = i2cCompareBytesFile;
1354 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"].erase(
1355 "masks");
1356 EXPECT_JSON_VALID(configFile);
1357 }
1358 // Invalid: test i2c_compare_bytes with no register.
1359 {
1360 json configFile = i2cCompareBytesFile;
1361 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"].erase(
1362 "register");
1363 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001364 "'register' is a required property");
Bob Kingfb162bb2020-01-21 11:28:07 +08001365 }
1366 // Invalid: test i2c_compare_bytes with no values.
1367 {
1368 json configFile = i2cCompareBytesFile;
1369 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"].erase(
1370 "values");
1371 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001372 "'values' is a required property");
Bob Kingfb162bb2020-01-21 11:28:07 +08001373 }
1374 // Invalid: test i2c_compare_bytes with property values as empty array.
1375 {
1376 json configFile = i2cCompareBytesFile;
1377 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["values"] =
1378 json::array();
1379 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1380 "[] is too short");
1381 }
1382 // Invalid: test i2c_compare_bytes with property masks as empty array.
1383 {
1384 json configFile = i2cCompareBytesFile;
1385 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["masks"] =
1386 json::array();
1387 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1388 "[] is too short");
1389 }
1390 // Invalid: test i2c_compare_bytes with property register wrong type.
1391 {
1392 json configFile = i2cCompareBytesFile;
1393 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["register"] =
1394 1;
1395 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001396 "1 is not of type 'string'");
Bob Kingfb162bb2020-01-21 11:28:07 +08001397 }
1398 // Invalid: test i2c_compare_bytes with property values wrong type.
1399 {
1400 json configFile = i2cCompareBytesFile;
1401 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["values"] = 1;
1402 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001403 "1 is not of type 'array'");
Bob Kingfb162bb2020-01-21 11:28:07 +08001404 }
1405 // Invalid: test i2c_compare_bytes with property masks wrong type.
1406 {
1407 json configFile = i2cCompareBytesFile;
1408 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["masks"] = 1;
1409 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001410 "1 is not of type 'array'");
Bob Kingfb162bb2020-01-21 11:28:07 +08001411 }
1412 // Invalid: test i2c_compare_bytes with property register more than 2 hex
1413 // digits.
1414 {
1415 json configFile = i2cCompareBytesFile;
1416 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["register"] =
1417 "0x820";
1418 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001419 "'0x820' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob Kingfb162bb2020-01-21 11:28:07 +08001420 }
1421 // Invalid: test i2c_compare_bytes with property values more than 2 hex
1422 // digits.
1423 {
1424 json configFile = i2cCompareBytesFile;
1425 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["values"][0] =
1426 "0x820";
1427 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001428 "'0x820' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob Kingfb162bb2020-01-21 11:28:07 +08001429 }
1430 // Invalid: test i2c_compare_bytes with property masks more than 2 hex
1431 // digits.
1432 {
1433 json configFile = i2cCompareBytesFile;
1434 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["masks"][0] =
1435 "0x820";
1436 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001437 "'0x820' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob Kingfb162bb2020-01-21 11:28:07 +08001438 }
1439 // Invalid: test i2c_compare_bytes with property register less than 2 hex
1440 // digits.
1441 {
1442 json configFile = i2cCompareBytesFile;
1443 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["register"] =
1444 "0x8";
1445 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001446 "'0x8' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob Kingfb162bb2020-01-21 11:28:07 +08001447 }
1448 // Invalid: test i2c_compare_bytes with property values less than 2 hex
1449 // digits.
1450 {
1451 json configFile = i2cCompareBytesFile;
1452 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["values"][0] =
1453 "0x8";
1454 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001455 "'0x8' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob Kingfb162bb2020-01-21 11:28:07 +08001456 }
1457 // Invalid: test i2c_compare_bytes with property masks less than 2 hex
1458 // digits.
1459 {
1460 json configFile = i2cCompareBytesFile;
1461 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["masks"][0] =
1462 "0x8";
1463 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001464 "'0x8' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob Kingfb162bb2020-01-21 11:28:07 +08001465 }
1466 // Invalid: test i2c_compare_bytes with property register no leading prefix.
1467 {
1468 json configFile = i2cCompareBytesFile;
1469 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["register"] =
1470 "82";
1471 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001472 "'82' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob Kingfb162bb2020-01-21 11:28:07 +08001473 }
1474 // Invalid: test i2c_compare_bytes with property values no leading prefix.
1475 {
1476 json configFile = i2cCompareBytesFile;
1477 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["values"][0] =
1478 "82";
1479 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001480 "'82' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob Kingfb162bb2020-01-21 11:28:07 +08001481 }
1482 // Invalid: test i2c_compare_bytes with property masks no leading prefix.
1483 {
1484 json configFile = i2cCompareBytesFile;
1485 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["masks"][0] =
1486 "82";
1487 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001488 "'82' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob Kingfb162bb2020-01-21 11:28:07 +08001489 }
1490 // Invalid: test i2c_compare_bytes with property register invalid hex digit.
1491 {
1492 json configFile = i2cCompareBytesFile;
1493 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["register"] =
1494 "0xG1";
1495 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001496 "'0xG1' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob Kingfb162bb2020-01-21 11:28:07 +08001497 }
1498 // Invalid: test i2c_compare_bytes with property values invalid hex digit.
1499 {
1500 json configFile = i2cCompareBytesFile;
1501 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["values"][0] =
1502 "0xG1";
1503 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001504 "'0xG1' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob Kingfb162bb2020-01-21 11:28:07 +08001505 }
1506 // Invalid: test i2c_compare_bytes with property masks invalid hex digit.
1507 {
1508 json configFile = i2cCompareBytesFile;
1509 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["masks"][0] =
1510 "0xG1";
1511 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001512 "'0xG1' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob Kingfb162bb2020-01-21 11:28:07 +08001513 }
1514}
Bob Kingca93f1f2020-01-31 11:21:16 +08001515TEST(ValidateRegulatorsConfigTest, I2CInterface)
1516{
1517 // Valid: test i2c_interface.
1518 {
1519 json configFile = validConfigFile;
1520 EXPECT_JSON_VALID(configFile);
1521 }
1522 // Invalid: testi2c_interface with no bus.
1523 {
1524 json configFile = validConfigFile;
1525 configFile["chassis"][0]["devices"][0]["i2c_interface"].erase("bus");
1526 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001527 "'bus' is a required property");
Bob Kingca93f1f2020-01-31 11:21:16 +08001528 }
1529 // Invalid: test i2c_interface with no address.
1530 {
1531 json configFile = validConfigFile;
1532 configFile["chassis"][0]["devices"][0]["i2c_interface"].erase(
1533 "address");
1534 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001535 "'address' is a required property");
Bob Kingca93f1f2020-01-31 11:21:16 +08001536 }
1537 // Invalid: test i2c_interface with property bus wrong type.
1538 {
1539 json configFile = validConfigFile;
1540 configFile["chassis"][0]["devices"][0]["i2c_interface"]["bus"] = true;
1541 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001542 "True is not of type 'integer'");
Bob Kingca93f1f2020-01-31 11:21:16 +08001543 }
1544 // Invalid: test i2c_interface with property address wrong
1545 // type.
1546 {
1547 json configFile = validConfigFile;
1548 configFile["chassis"][0]["devices"][0]["i2c_interface"]["address"] =
1549 true;
1550 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001551 "True is not of type 'string'");
Bob Kingca93f1f2020-01-31 11:21:16 +08001552 }
1553 // Invalid: test i2c_interface with property bus less than
1554 // 0.
1555 {
1556 json configFile = validConfigFile;
1557 configFile["chassis"][0]["devices"][0]["i2c_interface"]["bus"] = -1;
1558 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1559 "-1 is less than the minimum of 0");
1560 }
1561 // Invalid: test i2c_interface with property address wrong
1562 // format.
1563 {
1564 json configFile = validConfigFile;
1565 configFile["chassis"][0]["devices"][0]["i2c_interface"]["address"] =
1566 "0x700";
1567 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001568 "'0x700' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob Kingca93f1f2020-01-31 11:21:16 +08001569 }
1570}
Bob King188db7d2020-01-31 13:01:01 +08001571TEST(ValidateRegulatorsConfigTest, I2CWriteBit)
1572{
1573 json i2cWriteBitFile = validConfigFile;
1574 i2cWriteBitFile["rules"][0]["actions"][1]["i2c_write_bit"]["register"] =
1575 "0xA0";
1576 i2cWriteBitFile["rules"][0]["actions"][1]["i2c_write_bit"]["position"] = 3;
1577 i2cWriteBitFile["rules"][0]["actions"][1]["i2c_write_bit"]["value"] = 1;
1578 // Valid: test rule actions i2c_write_bit.
1579 {
1580 json configFile = i2cWriteBitFile;
1581 EXPECT_JSON_VALID(configFile);
1582 }
1583 // Invalid: test i2c_write_bit with no register.
1584 {
1585 json configFile = i2cWriteBitFile;
1586 configFile["rules"][0]["actions"][1]["i2c_write_bit"].erase("register");
1587 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001588 "'register' is a required property");
Bob King188db7d2020-01-31 13:01:01 +08001589 }
1590 // Invalid: test i2c_write_bit with no position.
1591 {
1592 json configFile = i2cWriteBitFile;
1593 configFile["rules"][0]["actions"][1]["i2c_write_bit"].erase("position");
1594 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001595 "'position' is a required property");
Bob King188db7d2020-01-31 13:01:01 +08001596 }
1597 // Invalid: test i2c_write_bit with no value.
1598 {
1599 json configFile = i2cWriteBitFile;
1600 configFile["rules"][0]["actions"][1]["i2c_write_bit"].erase("value");
1601 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001602 "'value' is a required property");
Bob King188db7d2020-01-31 13:01:01 +08001603 }
1604 // Invalid: test i2c_write_bit with register wrong type.
1605 {
1606 json configFile = i2cWriteBitFile;
1607 configFile["rules"][0]["actions"][1]["i2c_write_bit"]["register"] = 1;
1608 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001609 "1 is not of type 'string'");
Bob King188db7d2020-01-31 13:01:01 +08001610 }
1611 // Invalid: test i2c_write_bit with register wrong format.
1612 {
1613 json configFile = i2cWriteBitFile;
1614 configFile["rules"][0]["actions"][1]["i2c_write_bit"]["register"] =
1615 "0xA00";
1616 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001617 "'0xA00' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08001618 }
1619 // Invalid: test i2c_write_bit with position wrong type.
1620 {
1621 json configFile = i2cWriteBitFile;
1622 configFile["rules"][0]["actions"][1]["i2c_write_bit"]["position"] = 3.1;
1623 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001624 "3.1 is not of type 'integer'");
Bob King188db7d2020-01-31 13:01:01 +08001625 }
1626 // Invalid: test i2c_write_bit with position greater than 7.
1627 {
1628 json configFile = i2cWriteBitFile;
1629 configFile["rules"][0]["actions"][1]["i2c_write_bit"]["position"] = 8;
1630 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1631 "8 is greater than the maximum of 7");
1632 }
1633 // Invalid: test i2c_write_bit with position less than 0.
1634 {
1635 json configFile = i2cWriteBitFile;
1636 configFile["rules"][0]["actions"][1]["i2c_write_bit"]["position"] = -1;
1637 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1638 "-1 is less than the minimum of 0");
1639 }
1640 // Invalid: test i2c_write_bit with value wrong type.
1641 {
1642 json configFile = i2cWriteBitFile;
1643 configFile["rules"][0]["actions"][1]["i2c_write_bit"]["value"] = "1";
1644 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001645 "'1' is not of type 'integer'");
Bob King188db7d2020-01-31 13:01:01 +08001646 }
1647 // Invalid: test i2c_write_bit with value greater than 1.
1648 {
1649 json configFile = i2cWriteBitFile;
1650 configFile["rules"][0]["actions"][1]["i2c_write_bit"]["value"] = 2;
1651 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1652 "2 is greater than the maximum of 1");
1653 }
1654 // Invalid: test i2c_write_bit with value less than 0.
1655 {
1656 json configFile = i2cWriteBitFile;
1657 configFile["rules"][0]["actions"][1]["i2c_write_bit"]["value"] = -1;
1658 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1659 "-1 is less than the minimum of 0");
1660 }
1661}
1662TEST(ValidateRegulatorsConfigTest, I2CWriteByte)
1663{
1664 json i2cWriteByteFile = validConfigFile;
1665 i2cWriteByteFile["rules"][0]["actions"][1]["i2c_write_byte"]["register"] =
1666 "0x82";
1667 i2cWriteByteFile["rules"][0]["actions"][1]["i2c_write_byte"]["value"] =
1668 "0x40";
1669 i2cWriteByteFile["rules"][0]["actions"][1]["i2c_write_byte"]["mask"] =
1670 "0x7F";
1671 // Valid: test i2c_write_byte with all properties.
1672 {
1673 json configFile = i2cWriteByteFile;
1674 EXPECT_JSON_VALID(configFile);
1675 }
1676 // Valid: test i2c_write_byte with all required properties.
1677 {
1678 json configFile = i2cWriteByteFile;
1679 configFile["rules"][0]["actions"][1]["i2c_write_byte"].erase("mask");
1680 EXPECT_JSON_VALID(configFile);
1681 }
1682 // Invalid: test i2c_write_byte with no register.
1683 {
1684 json configFile = i2cWriteByteFile;
1685 configFile["rules"][0]["actions"][1]["i2c_write_byte"].erase(
1686 "register");
1687 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001688 "'register' is a required property");
Bob King188db7d2020-01-31 13:01:01 +08001689 }
1690 // Invalid: test i2c_write_byte with no value.
1691 {
1692 json configFile = i2cWriteByteFile;
1693 configFile["rules"][0]["actions"][1]["i2c_write_byte"].erase("value");
1694 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001695 "'value' is a required property");
Bob King188db7d2020-01-31 13:01:01 +08001696 }
1697 // Invalid: test i2c_write_byte with property register wrong type.
1698 {
1699 json configFile = i2cWriteByteFile;
1700 configFile["rules"][0]["actions"][1]["i2c_write_byte"]["register"] = 1;
1701 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001702 "1 is not of type 'string'");
Bob King188db7d2020-01-31 13:01:01 +08001703 }
1704 // Invalid: test i2c_write_byte with property value wrong type.
1705 {
1706 json configFile = i2cWriteByteFile;
1707 configFile["rules"][0]["actions"][1]["i2c_write_byte"]["value"] = 1;
1708 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001709 "1 is not of type 'string'");
Bob King188db7d2020-01-31 13:01:01 +08001710 }
1711 // Invalid: test i2c_write_byte with property mask wrong type.
1712 {
1713 json configFile = i2cWriteByteFile;
1714 configFile["rules"][0]["actions"][1]["i2c_write_byte"]["mask"] = 1;
1715 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001716 "1 is not of type 'string'");
Bob King188db7d2020-01-31 13:01:01 +08001717 }
1718 // Invalid: test i2c_write_byte with property register more than 2 hex
1719 // digits.
1720 {
1721 json configFile = i2cWriteByteFile;
1722 configFile["rules"][0]["actions"][1]["i2c_write_byte"]["register"] =
1723 "0x820";
1724 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001725 "'0x820' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08001726 }
1727 // Invalid: test i2c_write_byte with property value more than 2 hex
1728 // digits.
1729 {
1730 json configFile = i2cWriteByteFile;
1731 configFile["rules"][0]["actions"][1]["i2c_write_byte"]["value"] =
1732 "0x820";
1733 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001734 "'0x820' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08001735 }
1736 // Invalid: test i2c_write_byte with property mask more than 2 hex digits.
1737 {
1738 json configFile = i2cWriteByteFile;
1739 configFile["rules"][0]["actions"][1]["i2c_write_byte"]["mask"] =
1740 "0x820";
1741 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001742 "'0x820' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08001743 }
1744 // Invalid: test i2c_write_byte with property register less than 2 hex
1745 // digits.
1746 {
1747 json configFile = i2cWriteByteFile;
1748 configFile["rules"][0]["actions"][1]["i2c_write_byte"]["register"] =
1749 "0x8";
1750 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001751 "'0x8' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08001752 }
1753 // Invalid: test i2c_write_byte with property value less than 2 hex
1754 // digits.
1755 {
1756 json configFile = i2cWriteByteFile;
1757 configFile["rules"][0]["actions"][1]["i2c_write_byte"]["value"] = "0x8";
1758 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001759 "'0x8' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08001760 }
1761 // Invalid: test i2c_write_byte with property mask less than 2 hex digits.
1762 {
1763 json configFile = i2cWriteByteFile;
1764 configFile["rules"][0]["actions"][1]["i2c_write_byte"]["mask"] = "0x8";
1765 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001766 "'0x8' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08001767 }
1768 // Invalid: test i2c_write_byte with property register no leading prefix.
1769 {
1770 json configFile = i2cWriteByteFile;
1771 configFile["rules"][0]["actions"][1]["i2c_write_byte"]["register"] =
1772 "82";
1773 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001774 "'82' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08001775 }
1776 // Invalid: test i2c_write_byte with property value no leading prefix.
1777 {
1778 json configFile = i2cWriteByteFile;
1779 configFile["rules"][0]["actions"][1]["i2c_write_byte"]["value"] = "82";
1780 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001781 "'82' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08001782 }
1783 // Invalid: test i2c_write_byte with property mask no leading prefix.
1784 {
1785 json configFile = i2cWriteByteFile;
1786 configFile["rules"][0]["actions"][1]["i2c_write_byte"]["mask"] = "82";
1787 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001788 "'82' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08001789 }
1790 // Invalid: test i2c_write_byte with property register invalid hex digit.
1791 {
1792 json configFile = i2cWriteByteFile;
1793 configFile["rules"][0]["actions"][1]["i2c_write_byte"]["register"] =
1794 "0xG1";
1795 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001796 "'0xG1' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08001797 }
1798 // Invalid: test i2c_write_byte with property value invalid hex digit.
1799 {
1800 json configFile = i2cWriteByteFile;
1801 configFile["rules"][0]["actions"][1]["i2c_write_byte"]["value"] =
1802 "0xG1";
1803 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001804 "'0xG1' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08001805 }
1806 // Invalid: test i2c_write_byte with property mask invalid hex digit.
1807 {
1808 json configFile = i2cWriteByteFile;
1809 configFile["rules"][0]["actions"][1]["i2c_write_byte"]["mask"] = "0xG1";
1810 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001811 "'0xG1' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08001812 }
1813}
1814TEST(ValidateRegulatorsConfigTest, I2CWriteBytes)
1815{
1816 json i2cWriteBytesFile = validConfigFile;
1817 i2cWriteBytesFile["rules"][0]["actions"][1]["i2c_write_bytes"]["register"] =
1818 "0x82";
1819 i2cWriteBytesFile["rules"][0]["actions"][1]["i2c_write_bytes"]["values"] = {
1820 "0x02", "0x73"};
1821 i2cWriteBytesFile["rules"][0]["actions"][1]["i2c_write_bytes"]["masks"] = {
1822 "0x7F", "0x7F"};
1823 // Valid: test i2c_write_bytes.
1824 {
1825 json configFile = i2cWriteBytesFile;
1826 EXPECT_JSON_VALID(configFile);
1827 }
1828 // Valid: test i2c_write_bytes with all required properties.
1829 {
1830 json configFile = i2cWriteBytesFile;
1831 configFile["rules"][0]["actions"][1]["i2c_write_bytes"].erase("masks");
1832 EXPECT_JSON_VALID(configFile);
1833 }
1834 // Invalid: test i2c_write_bytes with no register.
1835 {
1836 json configFile = i2cWriteBytesFile;
1837 configFile["rules"][0]["actions"][1]["i2c_write_bytes"].erase(
1838 "register");
1839 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001840 "'register' is a required property");
Bob King188db7d2020-01-31 13:01:01 +08001841 }
1842 // Invalid: test i2c_write_bytes with no values.
1843 {
1844 json configFile = i2cWriteBytesFile;
1845 configFile["rules"][0]["actions"][1]["i2c_write_bytes"].erase("values");
1846 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001847 "'values' is a required property");
Bob King188db7d2020-01-31 13:01:01 +08001848 }
1849 // Invalid: test i2c_write_bytes with property values as empty array.
1850 {
1851 json configFile = i2cWriteBytesFile;
1852 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["values"] =
1853 json::array();
1854 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1855 "[] is too short");
1856 }
1857 // Invalid: test i2c_write_bytes with property masks as empty array.
1858 {
1859 json configFile = i2cWriteBytesFile;
1860 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["masks"] =
1861 json::array();
1862 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1863 "[] is too short");
1864 }
1865 // Invalid: test i2c_write_bytes with property register wrong type.
1866 {
1867 json configFile = i2cWriteBytesFile;
1868 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["register"] = 1;
1869 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001870 "1 is not of type 'string'");
Bob King188db7d2020-01-31 13:01:01 +08001871 }
1872 // Invalid: test i2c_write_bytes with property values wrong type.
1873 {
1874 json configFile = i2cWriteBytesFile;
1875 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["values"] = 1;
1876 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001877 "1 is not of type 'array'");
Bob King188db7d2020-01-31 13:01:01 +08001878 }
1879 // Invalid: test i2c_write_bytes with property masks wrong type.
1880 {
1881 json configFile = i2cWriteBytesFile;
1882 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["masks"] = 1;
1883 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001884 "1 is not of type 'array'");
Bob King188db7d2020-01-31 13:01:01 +08001885 }
1886 // Invalid: test i2c_write_bytes with property register more than 2 hex
1887 // digits.
1888 {
1889 json configFile = i2cWriteBytesFile;
1890 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["register"] =
1891 "0x820";
1892 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001893 "'0x820' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08001894 }
1895 // Invalid: test i2c_write_bytes with property values more than 2 hex
1896 // digits.
1897 {
1898 json configFile = i2cWriteBytesFile;
1899 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["values"][0] =
1900 "0x820";
1901 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001902 "'0x820' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08001903 }
1904 // Invalid: test i2c_write_bytes with property masks more than 2 hex
1905 // digits.
1906 {
1907 json configFile = i2cWriteBytesFile;
1908 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["masks"][0] =
1909 "0x820";
1910 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001911 "'0x820' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08001912 }
1913 // Invalid: test i2c_write_bytes with property register less than 2 hex
1914 // digits.
1915 {
1916 json configFile = i2cWriteBytesFile;
1917 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["register"] =
1918 "0x8";
1919 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001920 "'0x8' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08001921 }
1922 // Invalid: test i2c_write_bytes with property values less than 2 hex
1923 // digits.
1924 {
1925 json configFile = i2cWriteBytesFile;
1926 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["values"][0] =
1927 "0x8";
1928 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001929 "'0x8' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08001930 }
1931 // Invalid: test i2c_write_bytes with property masks less than 2 hex
1932 // digits.
1933 {
1934 json configFile = i2cWriteBytesFile;
1935 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["masks"][0] =
1936 "0x8";
1937 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001938 "'0x8' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08001939 }
1940 // Invalid: test i2c_write_bytes with property register no leading prefix.
1941 {
1942 json configFile = i2cWriteBytesFile;
1943 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["register"] =
1944 "82";
1945 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001946 "'82' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08001947 }
1948 // Invalid: test i2c_write_bytes with property values no leading prefix.
1949 {
1950 json configFile = i2cWriteBytesFile;
1951 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["values"][0] =
1952 "82";
1953 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001954 "'82' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08001955 }
1956 // Invalid: test i2c_write_bytes with property masks no leading prefix.
1957 {
1958 json configFile = i2cWriteBytesFile;
1959 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["masks"][0] =
1960 "82";
1961 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001962 "'82' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08001963 }
1964 // Invalid: test i2c_write_bytes with property register invalid hex digit.
1965 {
1966 json configFile = i2cWriteBytesFile;
1967 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["register"] =
1968 "0xG1";
1969 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001970 "'0xG1' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08001971 }
1972 // Invalid: test i2c_write_bytes with property values invalid hex digit.
1973 {
1974 json configFile = i2cWriteBytesFile;
1975 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["values"][0] =
1976 "0xG1";
1977 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001978 "'0xG1' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08001979 }
1980 // Invalid: test i2c_write_bytes with property masks invalid hex digit.
1981 {
1982 json configFile = i2cWriteBytesFile;
1983 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["masks"][0] =
1984 "0xG1";
1985 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001986 "'0xG1' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08001987 }
1988}
Bob Kingead0b052020-01-21 11:29:03 +08001989TEST(ValidateRegulatorsConfigTest, If)
1990{
1991 json ifFile = validConfigFile;
Bob King2d27dcf2020-02-11 15:00:50 +08001992 ifFile["rules"][2]["actions"][0]["if"]["condition"]["run_rule"] =
1993 "set_voltage_rule";
1994 ifFile["rules"][2]["actions"][0]["if"]["then"][0]["run_rule"] =
1995 "read_sensors_rule";
1996 ifFile["rules"][2]["actions"][0]["if"]["else"][0]["run_rule"] =
1997 "read_sensors_rule";
1998 ifFile["rules"][2]["id"] = "rule_if";
Bob Kingead0b052020-01-21 11:29:03 +08001999 // Valid: test if.
2000 {
2001 json configFile = ifFile;
2002 EXPECT_JSON_VALID(configFile);
2003 }
2004 // Valid: test if with required properties.
2005 {
2006 json configFile = ifFile;
Bob King2d27dcf2020-02-11 15:00:50 +08002007 configFile["rules"][2]["actions"][0]["if"].erase("else");
Bob Kingead0b052020-01-21 11:29:03 +08002008 EXPECT_JSON_VALID(configFile);
2009 }
2010 // Invalid: test if with no property condition.
2011 {
2012 json configFile = ifFile;
Bob King2d27dcf2020-02-11 15:00:50 +08002013 configFile["rules"][2]["actions"][0]["if"].erase("condition");
Bob Kingead0b052020-01-21 11:29:03 +08002014 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002015 "'condition' is a required property");
Bob Kingead0b052020-01-21 11:29:03 +08002016 }
2017 // Invalid: test if with no property then.
2018 {
2019 json configFile = ifFile;
Bob King2d27dcf2020-02-11 15:00:50 +08002020 configFile["rules"][2]["actions"][0]["if"].erase("then");
Bob Kingead0b052020-01-21 11:29:03 +08002021 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002022 "'then' is a required property");
Bob Kingead0b052020-01-21 11:29:03 +08002023 }
2024 // Invalid: test if with property then empty array.
2025 {
2026 json configFile = ifFile;
Bob King2d27dcf2020-02-11 15:00:50 +08002027 configFile["rules"][2]["actions"][0]["if"]["then"] = json::array();
Bob Kingead0b052020-01-21 11:29:03 +08002028 EXPECT_JSON_INVALID(configFile, "Validation failed.",
2029 "[] is too short");
2030 }
2031 // Invalid: test if with property else empty array.
2032 {
2033 json configFile = ifFile;
Bob King2d27dcf2020-02-11 15:00:50 +08002034 configFile["rules"][2]["actions"][0]["if"]["else"] = json::array();
Bob Kingead0b052020-01-21 11:29:03 +08002035 EXPECT_JSON_INVALID(configFile, "Validation failed.",
2036 "[] is too short");
2037 }
2038 // Invalid: test if with property condition wrong type.
2039 {
2040 json configFile = ifFile;
Bob King2d27dcf2020-02-11 15:00:50 +08002041 configFile["rules"][2]["actions"][0]["if"]["condition"] = 1;
Bob Kingead0b052020-01-21 11:29:03 +08002042 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002043 "1 is not of type 'object'");
Bob Kingead0b052020-01-21 11:29:03 +08002044 }
2045 // Invalid: test if with property then wrong type.
2046 {
2047 json configFile = ifFile;
Bob King2d27dcf2020-02-11 15:00:50 +08002048 configFile["rules"][2]["actions"][0]["if"]["then"] = 1;
Bob Kingead0b052020-01-21 11:29:03 +08002049 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002050 "1 is not of type 'array'");
Bob Kingead0b052020-01-21 11:29:03 +08002051 }
2052 // Invalid: test if with property else wrong type.
2053 {
2054 json configFile = ifFile;
Bob King2d27dcf2020-02-11 15:00:50 +08002055 configFile["rules"][2]["actions"][0]["if"]["else"] = 1;
Bob Kingead0b052020-01-21 11:29:03 +08002056 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002057 "1 is not of type 'array'");
Bob Kingead0b052020-01-21 11:29:03 +08002058 }
2059}
Bob Kingbfe9fe72020-01-21 11:29:57 +08002060TEST(ValidateRegulatorsConfigTest, Not)
2061{
2062 json notFile = validConfigFile;
2063 notFile["rules"][0]["actions"][1]["not"]["i2c_compare_byte"]["register"] =
2064 "0xA0";
2065 notFile["rules"][0]["actions"][1]["not"]["i2c_compare_byte"]["value"] =
2066 "0xFF";
2067 // Valid: test not.
2068 {
2069 json configFile = notFile;
2070 EXPECT_JSON_VALID(configFile);
2071 }
2072 // Invalid: test not with wrong type.
2073 {
2074 json configFile = notFile;
2075 configFile["rules"][0]["actions"][1]["not"] = 1;
2076 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002077 "1 is not of type 'object'");
Bob Kingbfe9fe72020-01-21 11:29:57 +08002078 }
2079}
Bob Kingcfc29d02020-01-21 11:30:50 +08002080TEST(ValidateRegulatorsConfigTest, Or)
2081{
2082 json orFile = validConfigFile;
2083 orFile["rules"][0]["actions"][1]["or"][0]["i2c_compare_byte"]["register"] =
2084 "0xA0";
2085 orFile["rules"][0]["actions"][1]["or"][0]["i2c_compare_byte"]["value"] =
2086 "0x00";
2087 orFile["rules"][0]["actions"][1]["or"][1]["i2c_compare_byte"]["register"] =
2088 "0xA1";
2089 orFile["rules"][0]["actions"][1]["or"][1]["i2c_compare_byte"]["value"] =
2090 "0x00";
2091 // Valid: test or.
2092 {
2093 json configFile = orFile;
2094 EXPECT_JSON_VALID(configFile);
2095 }
2096 // Invalid: test or with empty array.
2097 {
2098 json configFile = orFile;
2099 configFile["rules"][0]["actions"][1]["or"] = json::array();
2100 EXPECT_JSON_INVALID(configFile, "Validation failed.",
2101 "[] is too short");
2102 }
2103 // Invalid: test or with wrong type.
2104 {
2105 json configFile = orFile;
2106 configFile["rules"][0]["actions"][1]["or"] = 1;
2107 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002108 "1 is not of type 'array'");
Bob Kingcfc29d02020-01-21 11:30:50 +08002109 }
2110}
Bob Kingd6618092020-01-21 11:31:46 +08002111TEST(ValidateRegulatorsConfigTest, PmbusReadSensor)
2112{
2113 json pmbusReadSensorFile = validConfigFile;
2114 pmbusReadSensorFile["rules"][0]["actions"][1]["pmbus_read_sensor"]["type"] =
2115 "vout";
2116 pmbusReadSensorFile["rules"][0]["actions"][1]["pmbus_read_sensor"]
2117 ["command"] = "0x8B";
2118 pmbusReadSensorFile["rules"][0]["actions"][1]["pmbus_read_sensor"]
2119 ["format"] = "linear_16";
2120 pmbusReadSensorFile["rules"][0]["actions"][1]["pmbus_read_sensor"]
2121 ["exponent"] = -8;
2122 // Valid: test pmbus_read_sensor.
2123 {
2124 json configFile = pmbusReadSensorFile;
2125 EXPECT_JSON_VALID(configFile);
2126 }
2127 // Valid: test pmbus_read_sensor with required properties.
2128 {
2129 json configFile = pmbusReadSensorFile;
2130 configFile["rules"][0]["actions"][1]["pmbus_read_sensor"].erase(
2131 "exponent");
2132 EXPECT_JSON_VALID(configFile);
2133 }
2134 // Invalid: test pmbus_read_sensor with no type.
2135 {
2136 json configFile = pmbusReadSensorFile;
2137 configFile["rules"][0]["actions"][1]["pmbus_read_sensor"].erase("type");
2138 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002139 "'type' is a required property");
Bob Kingd6618092020-01-21 11:31:46 +08002140 }
2141 // Invalid: test pmbus_read_sensor with no command.
2142 {
2143 json configFile = pmbusReadSensorFile;
2144 configFile["rules"][0]["actions"][1]["pmbus_read_sensor"].erase(
2145 "command");
2146 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002147 "'command' is a required property");
Bob Kingd6618092020-01-21 11:31:46 +08002148 }
2149 // Invalid: test pmbus_read_sensor with no format.
2150 {
2151 json configFile = pmbusReadSensorFile;
2152 configFile["rules"][0]["actions"][1]["pmbus_read_sensor"].erase(
2153 "format");
2154 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002155 "'format' is a required property");
Bob Kingd6618092020-01-21 11:31:46 +08002156 }
2157 // Invalid: test pmbus_read_sensor with property type wrong type.
2158 {
2159 json configFile = pmbusReadSensorFile;
2160 configFile["rules"][0]["actions"][1]["pmbus_read_sensor"]["type"] =
2161 true;
Bob King358c4172020-03-16 13:57:08 +08002162 EXPECT_JSON_INVALID(configFile, "Validation failed.",
2163 "True is not of type 'string'");
Bob Kingd6618092020-01-21 11:31:46 +08002164 }
2165 // Invalid: test pmbus_read_sensor with property command wrong type.
2166 {
2167 json configFile = pmbusReadSensorFile;
2168 configFile["rules"][0]["actions"][1]["pmbus_read_sensor"]["command"] =
2169 true;
2170 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002171 "True is not of type 'string'");
Bob Kingd6618092020-01-21 11:31:46 +08002172 }
2173 // Invalid: test pmbus_read_sensor with property format wrong type.
2174 {
2175 json configFile = pmbusReadSensorFile;
2176 configFile["rules"][0]["actions"][1]["pmbus_read_sensor"]["format"] =
2177 true;
2178 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002179 "True is not of type 'string'");
Bob Kingd6618092020-01-21 11:31:46 +08002180 }
2181 // Invalid: test pmbus_read_sensor with property exponent wrong type.
2182 {
2183 json configFile = pmbusReadSensorFile;
2184 configFile["rules"][0]["actions"][1]["pmbus_read_sensor"]["exponent"] =
2185 true;
2186 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002187 "True is not of type 'integer'");
Bob Kingd6618092020-01-21 11:31:46 +08002188 }
2189 // Invalid: test pmbus_read_sensor with property type wrong format.
2190 {
2191 json configFile = pmbusReadSensorFile;
2192 configFile["rules"][0]["actions"][1]["pmbus_read_sensor"]["type"] =
2193 "foo";
2194 EXPECT_JSON_INVALID(
2195 configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002196 "'foo' is not one of ['iout', 'iout_peak', 'iout_valley', "
2197 "'pout', 'temperature', 'temperature_peak', 'vout', "
2198 "'vout_peak', 'vout_valley']");
Bob Kingd6618092020-01-21 11:31:46 +08002199 }
2200 // Invalid: test pmbus_read_sensor with property command wrong format.
2201 {
2202 json configFile = pmbusReadSensorFile;
2203 configFile["rules"][0]["actions"][1]["pmbus_read_sensor"]["command"] =
2204 "0x8B0";
2205 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002206 "'0x8B0' does not match '^0x[0-9a-fA-F]{2}$'");
Bob Kingd6618092020-01-21 11:31:46 +08002207 }
2208 // Invalid: test pmbus_read_sensor with property format wrong format.
2209 {
2210 json configFile = pmbusReadSensorFile;
2211 configFile["rules"][0]["actions"][1]["pmbus_read_sensor"]["format"] =
2212 "foo";
Bob King358c4172020-03-16 13:57:08 +08002213 EXPECT_JSON_INVALID(configFile, "Validation failed.",
2214 "'foo' is not one of ['linear_11', 'linear_16']");
Bob Kingd6618092020-01-21 11:31:46 +08002215 }
2216}
Bob King02179c62020-01-21 11:32:36 +08002217TEST(ValidateRegulatorsConfigTest, PmbusWriteVoutCommand)
2218{
2219 json pmbusWriteVoutCommandFile = validConfigFile;
2220 pmbusWriteVoutCommandFile["rules"][0]["actions"][1]
2221 ["pmbus_write_vout_command"]["volts"] = 1.03;
2222 pmbusWriteVoutCommandFile["rules"][0]["actions"][1]
2223 ["pmbus_write_vout_command"]["format"] = "linear";
2224 pmbusWriteVoutCommandFile["rules"][0]["actions"][1]
2225 ["pmbus_write_vout_command"]["exponent"] = -8;
2226 pmbusWriteVoutCommandFile["rules"][0]["actions"][1]
2227 ["pmbus_write_vout_command"]["is_verified"] = true;
2228 // Valid: test pmbus_write_vout_command.
2229 {
2230 json configFile = pmbusWriteVoutCommandFile;
2231 EXPECT_JSON_VALID(configFile);
2232 }
2233 // Valid: test pmbus_write_vout_command with required properties.
2234 {
2235 json configFile = pmbusWriteVoutCommandFile;
2236 configFile["rules"][0]["actions"][1]["pmbus_write_vout_command"].erase(
2237 "volts");
2238 configFile["rules"][0]["actions"][1]["pmbus_write_vout_command"].erase(
2239 "exponent");
2240 configFile["rules"][0]["actions"][1]["pmbus_write_vout_command"].erase(
2241 "is_verified");
2242 EXPECT_JSON_VALID(configFile);
2243 }
2244 // Invalid: test pmbus_write_vout_command with no format.
2245 {
2246 json configFile = pmbusWriteVoutCommandFile;
2247 configFile["rules"][0]["actions"][1]["pmbus_write_vout_command"].erase(
2248 "format");
2249 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002250 "'format' is a required property");
Bob King02179c62020-01-21 11:32:36 +08002251 }
2252 // Invalid: test pmbus_write_vout_command with property volts wrong type.
2253 {
2254 json configFile = pmbusWriteVoutCommandFile;
2255 configFile["rules"][0]["actions"][1]["pmbus_write_vout_command"]
2256 ["volts"] = true;
2257 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002258 "True is not of type 'number'");
Bob King02179c62020-01-21 11:32:36 +08002259 }
2260 // Invalid: test pmbus_write_vout_command with property format wrong type.
2261 {
2262 json configFile = pmbusWriteVoutCommandFile;
2263 configFile["rules"][0]["actions"][1]["pmbus_write_vout_command"]
2264 ["format"] = true;
2265 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002266 "True is not of type 'string'");
Bob King02179c62020-01-21 11:32:36 +08002267 }
2268 // Invalid: test pmbus_write_vout_command with property exponent wrong type.
2269 {
2270 json configFile = pmbusWriteVoutCommandFile;
2271 configFile["rules"][0]["actions"][1]["pmbus_write_vout_command"]
2272 ["exponent"] = 1.3;
2273 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002274 "1.3 is not of type 'integer'");
Bob King02179c62020-01-21 11:32:36 +08002275 }
2276 // Invalid: test pmbus_write_vout_command with property is_verified wrong
2277 // type.
2278 {
2279 json configFile = pmbusWriteVoutCommandFile;
2280 configFile["rules"][0]["actions"][1]["pmbus_write_vout_command"]
2281 ["is_verified"] = 1;
2282 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002283 "1 is not of type 'boolean'");
Bob King02179c62020-01-21 11:32:36 +08002284 }
2285 // Invalid: test pmbus_write_vout_command with property format wrong format.
2286 {
2287 json configFile = pmbusWriteVoutCommandFile;
2288 configFile["rules"][0]["actions"][1]["pmbus_write_vout_command"]
2289 ["format"] = "foo";
2290 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002291 "'foo' is not one of ['linear']");
Bob King02179c62020-01-21 11:32:36 +08002292 }
2293}
Bob King99d8fa12020-01-31 11:23:40 +08002294TEST(ValidateRegulatorsConfigTest, PresenceDetection)
2295{
2296 json presenceDetectionFile = validConfigFile;
2297 presenceDetectionFile
2298 ["chassis"][0]["devices"][0]["presence_detection"]["comments"][0] =
2299 "Regulator is only present on the FooBar backplane";
2300 presenceDetectionFile["chassis"][0]["devices"][0]["presence_detection"]
Bob Kingf4ff1162020-02-11 15:13:38 +08002301 ["rule_id"] = "set_voltage_rule";
Bob King99d8fa12020-01-31 11:23:40 +08002302 // Valid: test presence_detection with only property rule_id.
2303 {
2304 json configFile = presenceDetectionFile;
2305 EXPECT_JSON_VALID(configFile);
2306 }
2307 // Valid: test presence_detection with only property actions.
2308 {
2309 json configFile = presenceDetectionFile;
2310 configFile["chassis"][0]["devices"][0]["presence_detection"].erase(
2311 "rule_id");
2312 configFile["chassis"][0]["devices"][0]["presence_detection"]["actions"]
2313 [0]["compare_presence"]["fru"] =
2314 "/system/chassis/motherboard/cpu3";
2315 configFile["chassis"][0]["devices"][0]["presence_detection"]["actions"]
2316 [0]["compare_presence"]["value"] = true;
2317 configFile["chassis"][0]["devices"][0]["presence_detection"].erase(
2318 "comments");
2319 EXPECT_JSON_VALID(configFile);
2320 }
2321 // Invalid: test presence_detection with both property rule_id and actions.
2322 {
2323 json configFile = presenceDetectionFile;
2324 configFile["chassis"][0]["devices"][0]["presence_detection"]["actions"]
2325 [0]["compare_presence"]["fru"] =
2326 "/system/chassis/motherboard/cpu3";
2327 configFile["chassis"][0]["devices"][0]["presence_detection"]["actions"]
2328 [0]["compare_presence"]["value"] = true;
2329 EXPECT_JSON_INVALID(
2330 configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002331 "{'actions': [{'compare_presence': {'fru': "
2332 "'/system/chassis/motherboard/cpu3', 'value': True}}], 'comments': "
2333 "['Regulator is only present on the FooBar backplane'], 'rule_id': "
2334 "'set_voltage_rule'} is valid under each of {'required': "
2335 "['actions']}, {'required': ['rule_id']}");
Bob King99d8fa12020-01-31 11:23:40 +08002336 }
2337 // Invalid: test presence_detection with no rule_id and actions.
2338 {
2339 json configFile = presenceDetectionFile;
2340 configFile["chassis"][0]["devices"][0]["presence_detection"].erase(
2341 "rule_id");
2342 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002343 "'rule_id' is a required property");
Bob King99d8fa12020-01-31 11:23:40 +08002344 }
2345 // Invalid: test presence_detection with property comments wrong type.
2346 {
2347 json configFile = presenceDetectionFile;
2348 configFile["chassis"][0]["devices"][0]["presence_detection"]
2349 ["comments"] = true;
2350 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002351 "True is not of type 'array'");
Bob King99d8fa12020-01-31 11:23:40 +08002352 }
2353 // Invalid: test presence_detection with property rule_id wrong type.
2354 {
2355 json configFile = presenceDetectionFile;
2356 configFile["chassis"][0]["devices"][0]["presence_detection"]
2357 ["rule_id"] = true;
2358 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002359 "True is not of type 'string'");
Bob King99d8fa12020-01-31 11:23:40 +08002360 }
2361 // Invalid: test presence_detection with property actions wrong type.
2362 {
2363 json configFile = presenceDetectionFile;
2364 configFile["chassis"][0]["devices"][0]["presence_detection"].erase(
2365 "rule_id");
2366 configFile["chassis"][0]["devices"][0]["presence_detection"]
2367 ["actions"] = true;
2368 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002369 "True is not of type 'array'");
Bob King99d8fa12020-01-31 11:23:40 +08002370 }
2371 // Invalid: test presence_detection with property rule_id wrong format.
2372 {
2373 json configFile = presenceDetectionFile;
2374 configFile["chassis"][0]["devices"][0]["presence_detection"]
2375 ["rule_id"] = "id@";
2376 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002377 "'id@' does not match '^[A-Za-z0-9_]+$'");
Bob King99d8fa12020-01-31 11:23:40 +08002378 }
2379 // Invalid: test presence_detection with property comments empty array.
2380 {
2381 json configFile = presenceDetectionFile;
2382 configFile["chassis"][0]["devices"][0]["presence_detection"]
2383 ["comments"] = json::array();
2384 EXPECT_JSON_INVALID(configFile, "Validation failed.",
2385 "[] is too short");
2386 }
2387 // Invalid: test presence_detection with property actions empty array.
2388 {
2389 json configFile = presenceDetectionFile;
2390 configFile["chassis"][0]["devices"][0]["presence_detection"].erase(
2391 "rule_id");
2392 configFile["chassis"][0]["devices"][0]["presence_detection"]
2393 ["actions"] = json::array();
2394 EXPECT_JSON_INVALID(configFile, "Validation failed.",
2395 "[] is too short");
2396 }
2397}
Bob Kinge9260b52020-01-21 11:46:13 +08002398TEST(ValidateRegulatorsConfigTest, Rail)
2399{
2400 // Valid: test rail.
2401 {
2402 json configFile = validConfigFile;
2403 EXPECT_JSON_VALID(configFile);
2404 }
2405 // Valid: test rail with required properties.
2406 {
2407 json configFile = validConfigFile;
2408 configFile["chassis"][0]["devices"][0]["rails"][0].erase("comments");
2409 configFile["chassis"][0]["devices"][0]["rails"][0].erase(
2410 "configuration");
2411 configFile["chassis"][0]["devices"][0]["rails"][0].erase(
2412 "sensor_monitoring");
2413 EXPECT_JSON_VALID(configFile);
2414 }
2415 // Invalid: test rail with no id.
2416 {
2417 json configFile = validConfigFile;
2418 configFile["chassis"][0]["devices"][0]["rails"][0].erase("id");
2419 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002420 "'id' is a required property");
Bob Kinge9260b52020-01-21 11:46:13 +08002421 }
2422 // Invalid: test rail with comments wrong type.
2423 {
2424 json configFile = validConfigFile;
2425 configFile["chassis"][0]["devices"][0]["rails"][0]["comments"] = true;
2426 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002427 "True is not of type 'array'");
Bob Kinge9260b52020-01-21 11:46:13 +08002428 }
2429 // Invalid: test rail with id wrong type.
2430 {
2431 json configFile = validConfigFile;
2432 configFile["chassis"][0]["devices"][0]["rails"][0]["id"] = true;
2433 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002434 "True is not of type 'string'");
Bob Kinge9260b52020-01-21 11:46:13 +08002435 }
2436 // Invalid: test rail with configuration wrong type.
2437 {
2438 json configFile = validConfigFile;
2439 configFile["chassis"][0]["devices"][0]["rails"][0]["configuration"] =
2440 true;
2441 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002442 "True is not of type 'object'");
Bob Kinge9260b52020-01-21 11:46:13 +08002443 }
2444 // Invalid: test rail with sensor_monitoring wrong type.
2445 {
2446 json configFile = validConfigFile;
2447 configFile["chassis"][0]["devices"][0]["rails"][0]
2448 ["sensor_monitoring"] = true;
2449 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002450 "True is not of type 'object'");
Bob Kinge9260b52020-01-21 11:46:13 +08002451 }
2452 // Invalid: test rail with comments empty array.
2453 {
2454 json configFile = validConfigFile;
2455 configFile["chassis"][0]["devices"][0]["rails"][0]["comments"] =
2456 json::array();
2457 EXPECT_JSON_INVALID(configFile, "Validation failed.",
2458 "[] is too short");
2459 }
2460 // Invalid: test rail with id wrong format.
2461 {
2462 json configFile = validConfigFile;
2463 configFile["chassis"][0]["devices"][0]["rails"][0]["id"] = "id~";
2464 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002465 "'id~' does not match '^[A-Za-z0-9_]+$'");
Bob Kinge9260b52020-01-21 11:46:13 +08002466 }
2467}
Bob King64df7da2020-01-31 12:04:12 +08002468TEST(ValidateRegulatorsConfigTest, Rule)
2469{
2470 // valid test comments property, id property,
2471 // action property specified.
2472 {
2473 json configFile = validConfigFile;
2474 EXPECT_JSON_VALID(configFile);
2475 }
2476
2477 // valid test rule with no comments
2478 {
2479 json configFile = validConfigFile;
2480 configFile["rules"][0].erase("comments");
2481 EXPECT_JSON_VALID(configFile);
2482 }
2483
2484 // invalid test comments property has invalid value type
2485 {
2486 json configFile = validConfigFile;
2487 configFile["rules"][0]["comments"] = {1};
2488 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002489 "1 is not of type 'string'");
Bob King64df7da2020-01-31 12:04:12 +08002490 }
2491
2492 // invalid test rule with no ID
2493 {
2494 json configFile = validConfigFile;
2495 configFile["rules"][0].erase("id");
2496 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002497 "'id' is a required property");
Bob King64df7da2020-01-31 12:04:12 +08002498 }
2499
2500 // invalid test id property has invalid value type (not string)
2501 {
2502 json configFile = validConfigFile;
2503 configFile["rules"][0]["id"] = true;
2504 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002505 "True is not of type 'string'");
Bob King64df7da2020-01-31 12:04:12 +08002506 }
2507
2508 // invalid test id property has invalid value
2509 {
2510 json configFile = validConfigFile;
2511 configFile["rules"][0]["id"] = "foo%";
2512 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002513 "'foo%' does not match '^[A-Za-z0-9_]+$'");
Bob King64df7da2020-01-31 12:04:12 +08002514 }
2515
2516 // invalid test rule with no actions property
2517 {
2518 json configFile = validConfigFile;
2519 configFile["rules"][0].erase("actions");
2520 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002521 "'actions' is a required property");
Bob King64df7da2020-01-31 12:04:12 +08002522 }
2523
2524 // valid test rule with multiple actions
2525 {
2526 json configFile = validConfigFile;
Bob King63d795f2020-02-11 15:22:09 +08002527 configFile["rules"][0]["actions"][1]["run_rule"] = "read_sensors_rule";
Bob King64df7da2020-01-31 12:04:12 +08002528 EXPECT_JSON_VALID(configFile);
2529 }
2530
2531 // invalid test actions property has invalid value type (not an array)
2532 {
2533 json configFile = validConfigFile;
2534 configFile["rules"][0]["actions"] = 1;
2535 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002536 "1 is not of type 'array'");
Bob King64df7da2020-01-31 12:04:12 +08002537 }
2538
2539 // invalid test actions property has invalid value of action
2540 {
2541 json configFile = validConfigFile;
2542 configFile["rules"][0]["actions"][0] = "foo";
2543 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002544 "'foo' is not of type 'object'");
Bob King64df7da2020-01-31 12:04:12 +08002545 }
2546
2547 // invalid test actions property has empty array
2548 {
2549 json configFile = validConfigFile;
2550 configFile["rules"][0]["actions"] = json::array();
2551 EXPECT_JSON_INVALID(configFile, "Validation failed.",
2552 "[] is too short");
2553 }
2554}
Bob Kinge86c2e52020-01-21 11:33:32 +08002555TEST(ValidateRegulatorsConfigTest, RunRule)
2556{
2557 json runRuleFile = validConfigFile;
Bob King7d3a9f12020-02-11 15:34:52 +08002558 runRuleFile["rules"][0]["actions"][1]["run_rule"] = "read_sensors_rule";
Bob Kinge86c2e52020-01-21 11:33:32 +08002559 // Valid: test run_rule.
2560 {
2561 json configFile = runRuleFile;
2562 EXPECT_JSON_VALID(configFile);
2563 }
2564 // Invalid: test run_rule wrong type.
2565 {
2566 json configFile = runRuleFile;
2567 configFile["rules"][0]["actions"][1]["run_rule"] = true;
2568 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002569 "True is not of type 'string'");
Bob Kinge86c2e52020-01-21 11:33:32 +08002570 }
2571 // Invalid: test run_rule wrong format.
2572 {
2573 json configFile = runRuleFile;
2574 configFile["rules"][0]["actions"][1]["run_rule"] = "set_voltage_rule%";
2575 EXPECT_JSON_INVALID(
2576 configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002577 "'set_voltage_rule%' does not match '^[A-Za-z0-9_]+$'");
Bob Kinge86c2e52020-01-21 11:33:32 +08002578 }
2579}
Bob Kingfcc2a2f2020-01-31 11:29:45 +08002580TEST(ValidateRegulatorsConfigTest, SensorMonitoring)
2581{
2582 // Valid: test rails sensor_monitoring with only property rule id.
2583 {
2584 json configFile = validConfigFile;
2585 EXPECT_JSON_VALID(configFile);
2586 }
2587 // Valid: test rails sensor_monitoring with only property actions.
2588 {
2589 json configFile = validConfigFile;
2590 configFile["chassis"][0]["devices"][0]["rails"][0]["sensor_monitoring"]
2591 .erase("rule_id");
2592 configFile["chassis"][0]["devices"][0]["rails"][0]["sensor_monitoring"]
2593 ["actions"][0]["compare_presence"]["fru"] =
2594 "/system/chassis/motherboard/cpu3";
2595 configFile["chassis"][0]["devices"][0]["rails"][0]["sensor_monitoring"]
2596 ["actions"][0]["compare_presence"]["value"] = true;
2597 configFile["chassis"][0]["devices"][0]["rails"][0]["sensor_monitoring"]
2598 ["comments"][0] = "comments";
2599 EXPECT_JSON_VALID(configFile);
2600 }
2601 // Invalid: test rails sensor_monitoring with both property rule_id and
2602 // actions.
2603 {
2604 json configFile = validConfigFile;
2605 configFile["chassis"][0]["devices"][0]["rails"][0]["sensor_monitoring"]
2606 ["actions"][0]["compare_presence"]["fru"] =
2607 "/system/chassis/motherboard/cpu3";
2608 configFile["chassis"][0]["devices"][0]["rails"][0]["sensor_monitoring"]
2609 ["actions"][0]["compare_presence"]["value"] = true;
2610 EXPECT_JSON_INVALID(
2611 configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002612 "{'actions': [{'compare_presence': {'fru': "
2613 "'/system/chassis/motherboard/cpu3', 'value': True}}], 'rule_id': "
2614 "'read_sensors_rule'} is valid under each of {'required': "
2615 "['actions']}, {'required': ['rule_id']}");
Bob Kingfcc2a2f2020-01-31 11:29:45 +08002616 }
2617 // Invalid: test rails sensor_monitoring with no rule_id and actions.
2618 {
2619 json configFile = validConfigFile;
2620 configFile["chassis"][0]["devices"][0]["rails"][0]["sensor_monitoring"]
2621 .erase("rule_id");
2622 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002623 "'rule_id' is a required property");
Bob Kingfcc2a2f2020-01-31 11:29:45 +08002624 }
2625 // Invalid: test rails sensor_monitoring with property comments wrong type.
2626 {
2627 json configFile = validConfigFile;
2628 configFile["chassis"][0]["devices"][0]["rails"][0]["sensor_monitoring"]
2629 ["comments"] = true;
2630 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002631 "True is not of type 'array'");
Bob Kingfcc2a2f2020-01-31 11:29:45 +08002632 }
2633 // Invalid: test rails sensor_monitoring with property rule_id wrong type.
2634 {
2635 json configFile = validConfigFile;
2636 configFile["chassis"][0]["devices"][0]["rails"][0]["sensor_monitoring"]
2637 ["rule_id"] = true;
2638 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002639 "True is not of type 'string'");
Bob Kingfcc2a2f2020-01-31 11:29:45 +08002640 }
2641 // Invalid: test rails sensor_monitoring with property actions wrong type.
2642 {
2643 json configFile = validConfigFile;
2644 configFile["chassis"][0]["devices"][0]["rails"][0]["sensor_monitoring"]
2645 .erase("rule_id");
2646 configFile["chassis"][0]["devices"][0]["rails"][0]["sensor_monitoring"]
2647 ["actions"] = true;
2648 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002649 "True is not of type 'array'");
Bob Kingfcc2a2f2020-01-31 11:29:45 +08002650 }
2651 // Invalid: test rails sensor_monitoring with property rule_id wrong format.
2652 {
2653 json configFile = validConfigFile;
2654 configFile["chassis"][0]["devices"][0]["rails"][0]["sensor_monitoring"]
2655 ["rule_id"] = "id@";
2656 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002657 "'id@' does not match '^[A-Za-z0-9_]+$'");
Bob Kingfcc2a2f2020-01-31 11:29:45 +08002658 }
2659 // Invalid: test rails sensor_monitoring with property comments empty array.
2660 {
2661 json configFile = validConfigFile;
2662 configFile["chassis"][0]["devices"][0]["rails"][0]["sensor_monitoring"]
2663 ["comments"] = json::array();
2664 EXPECT_JSON_INVALID(configFile, "Validation failed.",
2665 "[] is too short");
2666 }
2667 // Invalid: test rails sensor_monitoring with property actions empty array.
2668 {
2669 json configFile = validConfigFile;
2670 configFile["chassis"][0]["devices"][0]["rails"][0]["sensor_monitoring"]
2671 .erase("rule_id");
2672 configFile["chassis"][0]["devices"][0]["rails"][0]["sensor_monitoring"]
2673 ["actions"] = json::array();
2674 EXPECT_JSON_INVALID(configFile, "Validation failed.",
2675 "[] is too short");
2676 }
2677}
Bob King68230aa2020-01-21 11:34:33 +08002678TEST(ValidateRegulatorsConfigTest, SetDevice)
2679{
2680 json setDeviceFile = validConfigFile;
Bob King7d3a9f12020-02-11 15:34:52 +08002681 setDeviceFile["rules"][0]["actions"][1]["set_device"] = "vdd_regulator";
Bob King68230aa2020-01-21 11:34:33 +08002682 // Valid: test set_device.
2683 {
2684 json configFile = setDeviceFile;
2685 EXPECT_JSON_VALID(configFile);
2686 }
2687 // Invalid: test set_device wrong type.
2688 {
2689 json configFile = setDeviceFile;
2690 configFile["rules"][0]["actions"][1]["set_device"] = true;
2691 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002692 "True is not of type 'string'");
Bob King68230aa2020-01-21 11:34:33 +08002693 }
2694 // Invalid: test set_device wrong format.
2695 {
2696 json configFile = setDeviceFile;
2697 configFile["rules"][0]["actions"][1]["set_device"] = "io_expander2%";
Bob King358c4172020-03-16 13:57:08 +08002698 EXPECT_JSON_INVALID(configFile, "Validation failed.",
2699 "'io_expander2%' does not match '^[A-Za-z0-9_]+$'");
Bob King68230aa2020-01-21 11:34:33 +08002700 }
2701}
Bob King3643cc02020-01-31 11:32:56 +08002702TEST(ValidateRegulatorsConfigTest, DuplicateRuleID)
2703{
2704 // Invalid: test duplicate ID in rule.
2705 {
2706 json configFile = validConfigFile;
Bob Kingb3e48bc2020-02-18 09:59:09 +08002707 configFile["rules"][2]["id"] = "set_voltage_rule";
2708 configFile["rules"][2]["actions"][0]["pmbus_write_vout_command"]
Bob King3643cc02020-01-31 11:32:56 +08002709 ["format"] = "linear";
2710 EXPECT_JSON_INVALID(configFile, "Error: Duplicate rule ID.", "");
2711 }
2712}
2713TEST(ValidateRegulatorsConfigTest, DuplicateChassisNumber)
2714{
2715 // Invalid: test duplicate number in chassis.
2716 {
2717 json configFile = validConfigFile;
2718 configFile["chassis"][1]["number"] = 1;
2719 EXPECT_JSON_INVALID(configFile, "Error: Duplicate chassis number.", "");
2720 }
2721}
2722TEST(ValidateRegulatorsConfigTest, DuplicateDeviceID)
2723{
2724 // Invalid: test duplicate ID in device.
2725 {
2726 json configFile = validConfigFile;
2727 configFile["chassis"][0]["devices"][1]["id"] = "vdd_regulator";
2728 configFile["chassis"][0]["devices"][1]["is_regulator"] = true;
2729 configFile["chassis"][0]["devices"][1]["fru"] =
2730 "/system/chassis/motherboard/regulator1";
2731 configFile["chassis"][0]["devices"][1]["i2c_interface"]["bus"] = 2;
2732 configFile["chassis"][0]["devices"][1]["i2c_interface"]["address"] =
2733 "0x71";
2734 EXPECT_JSON_INVALID(configFile, "Error: Duplicate device ID.", "");
2735 }
2736}
2737TEST(ValidateRegulatorsConfigTest, DuplicateRailID)
2738{
2739 // Invalid: test duplicate ID in rail.
2740 {
2741 json configFile = validConfigFile;
2742 configFile["chassis"][0]["devices"][0]["rails"][1]["id"] = "vdd";
2743 EXPECT_JSON_INVALID(configFile, "Error: Duplicate rail ID.", "");
2744 }
2745}
Bob King78793102020-03-13 13:16:09 +08002746TEST(ValidateRegulatorsConfigTest, DuplicateObjectID)
2747{
2748 // Invalid: test duplicate object ID in device and rail.
2749 {
2750 json configFile = validConfigFile;
2751 configFile["chassis"][0]["devices"][0]["rails"][1]["id"] =
2752 "vdd_regulator";
2753 EXPECT_JSON_INVALID(configFile, "Error: Duplicate ID.", "");
2754 }
2755 // Invalid: test duplicate object ID in device and rule.
2756 {
2757 json configFile = validConfigFile;
2758 configFile["rules"][2]["id"] = "vdd_regulator";
2759 configFile["rules"][2]["actions"][0]["pmbus_write_vout_command"]
2760 ["format"] = "linear";
2761 EXPECT_JSON_INVALID(configFile, "Error: Duplicate ID.", "");
2762 }
2763 // Invalid: test duplicate object ID in rule and rail.
2764 {
2765 json configFile = validConfigFile;
2766 configFile["chassis"][0]["devices"][0]["rails"][1]["id"] =
2767 "set_voltage_rule";
2768 EXPECT_JSON_INVALID(configFile, "Error: Duplicate ID.", "");
2769 }
2770}
Bob King3643cc02020-01-31 11:32:56 +08002771TEST(ValidateRegulatorsConfigTest, InfiniteLoops)
2772{
2773 // Invalid: test run_rule with infinite loop (rules run each other).
2774 {
2775 json configFile = validConfigFile;
2776 configFile["rules"][2]["actions"][0]["run_rule"] = "set_voltage_rule2";
2777 configFile["rules"][2]["id"] = "set_voltage_rule1";
2778 configFile["rules"][3]["actions"][0]["run_rule"] = "set_voltage_rule1";
2779 configFile["rules"][3]["id"] = "set_voltage_rule2";
2780 EXPECT_JSON_INVALID(configFile,
2781 "Infinite loop caused by run_rule actions.", "");
2782 }
2783 // Invalid: test run_rule with infinite loop (rule runs itself).
2784 {
2785 json configFile = validConfigFile;
2786 configFile["rules"][2]["actions"][0]["run_rule"] = "set_voltage_rule1";
2787 configFile["rules"][2]["id"] = "set_voltage_rule1";
2788 EXPECT_JSON_INVALID(configFile,
2789 "Infinite loop caused by run_rule actions.", "");
2790 }
2791 // Invalid: test run_rule with infinite loop (indirect loop).
2792 {
2793 json configFile = validConfigFile;
2794 configFile["rules"][2]["actions"][0]["run_rule"] = "set_voltage_rule2";
2795 configFile["rules"][2]["id"] = "set_voltage_rule1";
2796 configFile["rules"][3]["actions"][0]["run_rule"] = "set_voltage_rule3";
2797 configFile["rules"][3]["id"] = "set_voltage_rule2";
2798 configFile["rules"][4]["actions"][0]["run_rule"] = "set_voltage_rule1";
2799 configFile["rules"][4]["id"] = "set_voltage_rule3";
2800 EXPECT_JSON_INVALID(configFile,
2801 "Infinite loop caused by run_rule actions.", "");
2802 }
2803}
Bob Kingf88203a2020-02-18 13:26:07 +08002804TEST(ValidateRegulatorsConfigTest, RunRuleValueExists)
2805{
2806 // Invalid: test run_rule actions specify a rule ID that does not exist.
2807 {
2808 json configFile = validConfigFile;
2809 configFile["rules"][2]["actions"][0]["run_rule"] = "set_voltage_rule2";
2810 configFile["rules"][2]["id"] = "set_voltage_rule1";
2811 EXPECT_JSON_INVALID(configFile, "Error: Rule ID does not exist.", "");
2812 }
2813}
Bob King13b2ad92020-02-18 13:31:39 +08002814TEST(ValidateRegulatorsConfigTest, SetDeviceValueExists)
2815{
2816 // Invalid: test set_device actions specify a device ID that does not exist.
2817 {
2818 json configFile = validConfigFile;
2819 configFile["rules"][2]["actions"][0]["set_device"] = "vdd_regulator2";
2820 configFile["rules"][2]["id"] = "set_voltage_rule1";
2821 EXPECT_JSON_INVALID(configFile, "Error: Device ID does not exist.", "");
2822 }
2823}
Bob King21b09be2020-02-18 13:33:09 +08002824TEST(ValidateRegulatorsConfigTest, RuleIDExists)
2825{
2826 // Invalid: test rule_id property in configuration specifies a rule ID that
2827 // does not exist.
2828 {
2829 json configFile = validConfigFile;
2830 configFile["chassis"][0]["devices"][0]["configuration"]["rule_id"] =
2831 "set_voltage_rule2";
2832 EXPECT_JSON_INVALID(configFile, "Error: Rule ID does not exist.", "");
2833 }
2834 // Invalid: test rule_id property in presence_detection specifies a rule ID
2835 // that does not exist.
2836 {
2837 json configFile = validConfigFile;
2838 configFile["chassis"][0]["devices"][0]["presence_detection"]
2839 ["rule_id"] = "set_voltage_rule2";
2840 EXPECT_JSON_INVALID(configFile, "Error: Rule ID does not exist.", "");
2841 }
2842 // Invalid: test rule_id property in sensor_monitoring specifies a rule ID
2843 // that does not exist.
2844 {
2845 json configFile = validConfigFile;
2846 configFile["chassis"][0]["devices"][0]["rails"][0]["sensor_monitoring"]
2847 ["rule_id"] = "set_voltage_rule2";
2848 EXPECT_JSON_INVALID(configFile, "Error: Rule ID does not exist.", "");
2849 }
2850}
Bob Kingdc72b622020-02-18 13:36:18 +08002851TEST(ValidateRegulatorsConfigTest, NumberOfElementsInMasks)
2852{
2853 // Invalid: test number of elements in masks not equal to number in values
2854 // in i2c_compare_bytes.
2855 {
2856 json configFile = validConfigFile;
2857 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["register"] =
2858 "0x82";
2859 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["values"] = {
2860 "0x02", "0x73"};
2861 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["masks"] = {
2862 "0x7F"};
2863 EXPECT_JSON_INVALID(configFile,
2864 "Error: Invalid i2c_compare_bytes action.", "");
2865 }
2866 // Invalid: test number of elements in masks not equal to number in values
2867 // in i2c_write_bytes.
2868 {
2869 json configFile = validConfigFile;
2870 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["register"] =
2871 "0x82";
2872 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["values"] = {
2873 "0x02", "0x73"};
2874 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["masks"] = {
2875 "0x7F"};
2876 EXPECT_JSON_INVALID(configFile,
2877 "Error: Invalid i2c_write_bytes action.", "");
2878 }
2879}
Bob Kinged009652020-02-20 14:54:13 +08002880TEST(ValidateRegulatorsConfigTest, CommandLineSyntax)
2881{
Bob Kinga57e0812020-03-12 10:47:42 +08002882 std::string validateTool =
2883 " ../phosphor-regulators/tools/validate-regulators-config.py ";
Bob Kinged009652020-02-20 14:54:13 +08002884 std::string schema = " -s ";
Bob Kinga57e0812020-03-12 10:47:42 +08002885 std::string schemaFile =
2886 " ../phosphor-regulators/schema/config_schema.json ";
Bob Kinged009652020-02-20 14:54:13 +08002887 std::string configuration = " -c ";
2888 std::string command;
2889 std::string errorMessage;
2890 std::string outputMessage;
2891 std::string outputMessageHelp =
2892 "usage: validate-regulators-config.py [-h] [-s SCHEMA_FILE]";
2893 int valid = 0;
2894
2895 std::string fileName;
Bob Kinga57e0812020-03-12 10:47:42 +08002896 TmpFile tmpFile;
2897 fileName = tmpFile.getName();
2898 writeDataToFile(validConfigFile, fileName);
Bob Kinged009652020-02-20 14:54:13 +08002899 // Valid: -s specified
2900 {
2901 command = validateTool + "-s " + schemaFile + configuration + fileName;
2902 expectCommandLineSyntax(errorMessage, outputMessage, command, valid);
2903 }
2904 // Valid: --schema-file specified
2905 {
2906 command = validateTool + "--schema-file " + schemaFile + configuration +
2907 fileName;
2908 expectCommandLineSyntax(errorMessage, outputMessage, command, valid);
2909 }
2910 // Valid: -c specified
2911 {
2912 command = validateTool + schema + schemaFile + "-c " + fileName;
2913 expectCommandLineSyntax(errorMessage, outputMessage, command, valid);
2914 }
2915 // Valid: --configuration-file specified
2916 {
2917 command = validateTool + schema + schemaFile + "--configuration-file " +
2918 fileName;
2919 expectCommandLineSyntax(errorMessage, outputMessage, command, valid);
2920 }
2921 // Valid: -h specified
2922 {
2923 command = validateTool + "-h ";
2924 expectCommandLineSyntax(errorMessage, outputMessageHelp, command,
2925 valid);
2926 }
2927 // Valid: --help specified
2928 {
2929 command = validateTool + "--help ";
2930 expectCommandLineSyntax(errorMessage, outputMessageHelp, command,
2931 valid);
2932 }
2933 // Invalid: -c/--configuration-file not specified
2934 {
2935 command = validateTool + schema + schemaFile;
2936 expectCommandLineSyntax("Error: Configuration file is required.",
2937 outputMessageHelp, command, 1);
2938 }
2939 // Invalid: -s/--schema-file not specified
2940 {
2941 command = validateTool + configuration + fileName;
2942 expectCommandLineSyntax("Error: Schema file is required.",
2943 outputMessageHelp, command, 1);
2944 }
2945 // Invalid: -s specified more than once
2946 {
2947 command =
2948 validateTool + "-s -s " + schemaFile + configuration + fileName;
2949 expectCommandLineSyntax(outputMessageHelp, outputMessage, command, 2);
2950 }
2951 // Invalid: -c specified more than once
2952 {
2953 command = validateTool + schema + schemaFile + "-c -c " + fileName;
2954 expectCommandLineSyntax(outputMessageHelp, outputMessage, command, 2);
2955 }
2956 // Invalid: No file name specified after -c
2957 {
2958 command = validateTool + schema + schemaFile + configuration;
2959 expectCommandLineSyntax(outputMessageHelp, outputMessage, command, 2);
2960 }
2961 // Invalid: No file name specified after -s
2962 {
2963 command = validateTool + schema + configuration + fileName;
2964 expectCommandLineSyntax(outputMessageHelp, outputMessage, command, 2);
2965 }
2966 // Invalid: File specified after -c does not exist
2967 {
2968 command = validateTool + schema + schemaFile + configuration +
2969 "../notExistFile";
2970 expectCommandLineSyntax(
2971 "Traceback (most recent call last):", outputMessage, command, 1);
2972 }
2973 // Invalid: File specified after -s does not exist
2974 {
2975 command = validateTool + schema + "../notExistFile " + configuration +
2976 fileName;
2977 expectCommandLineSyntax(
2978 "Traceback (most recent call last):", outputMessage, command, 1);
2979 }
2980 // Invalid: File specified after -s is not right data format
2981 {
Bob Kinga57e0812020-03-12 10:47:42 +08002982 std::string wrongFormatFileName;
2983 TmpFile wrongFormatFile;
2984 wrongFormatFileName = wrongFormatFile.getName();
2985 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 Kinged009652020-02-20 14:54:13 +08002990 expectCommandLineSyntax(
2991 "Traceback (most recent call last):", outputMessage, command, 1);
Bob Kinged009652020-02-20 14:54:13 +08002992 }
2993 // Invalid: File specified after -c is not readable
2994 {
Bob Kinga57e0812020-03-12 10:47:42 +08002995 std::string notReadableFileName;
2996 TmpFile notReadableFile;
2997 notReadableFileName = notReadableFile.getName();
2998 writeDataToFile(validConfigFile, notReadableFileName);
Bob Kinged009652020-02-20 14:54:13 +08002999 command = validateTool + schema + schemaFile + configuration +
Bob Kinga57e0812020-03-12 10:47:42 +08003000 notReadableFileName;
3001 chmod(notReadableFileName.c_str(), 0222);
Bob Kinged009652020-02-20 14:54:13 +08003002 expectCommandLineSyntax(
3003 "Traceback (most recent call last):", outputMessage, command, 1);
Bob Kinged009652020-02-20 14:54:13 +08003004 }
3005 // Invalid: File specified after -s is not readable
3006 {
Bob Kinga57e0812020-03-12 10:47:42 +08003007 std::string notReadableFileName;
3008 TmpFile notReadableFile;
3009 notReadableFileName = notReadableFile.getName();
3010 writeDataToFile(validConfigFile, notReadableFileName);
3011 command = validateTool + schema + notReadableFileName + configuration +
3012 fileName;
3013 chmod(notReadableFileName.c_str(), 0222);
Bob Kinged009652020-02-20 14:54:13 +08003014 expectCommandLineSyntax(
3015 "Traceback (most recent call last):", outputMessage, command, 1);
Bob Kinged009652020-02-20 14:54:13 +08003016 }
3017 // Invalid: Unexpected parameter specified (like -g)
3018 {
3019 command = validateTool + schema + schemaFile + configuration +
3020 fileName + " -g";
3021 expectCommandLineSyntax(outputMessageHelp, outputMessage, command, 2);
3022 }
Bob Kinged009652020-02-20 14:54:13 +08003023}