blob: 4eeada702e7d9a85a759b8e71c6cc03aee48e2a1 [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
106std::string createTmpFile()
107{
108 // create temporary file using mkstemp under /tmp/. random name for XXXXXX
109 char fileName[] = "/tmp/temp-XXXXXX";
110 int fd = mkstemp(fileName);
111 if (fd == -1)
112 {
113 perror("Can't create temporary file");
114 }
115 close(fd);
116 return fileName;
117}
118
119std::string getValidationToolCommand(const std::string& configFileName)
120{
Bob Kinged009652020-02-20 14:54:13 +0800121 std::string command = "../tools/validate-regulators-config.py -s \
Bob King386d33f2019-12-26 17:28:56 +0800122 ../schema/config_schema.json -c ";
123 command += configFileName;
124 return command;
125}
126
Bob Kinged009652020-02-20 14:54:13 +0800127int runToolForOutput(std::string& output, std::string command,
Bob King386d33f2019-12-26 17:28:56 +0800128 bool isReadingStderr = false)
129{
130 // run the validation tool with the temporary file and return the output
131 // of the validation tool.
Bob King386d33f2019-12-26 17:28:56 +0800132 // reading the stderr while isReadingStderr is true.
133 if (isReadingStderr == true)
134 {
135 command += " 2>&1 >/dev/null";
136 }
137 // get the jsonschema print from validation tool.
138 char buffer[256];
139 std::string result = "";
140 // to get the stdout from the validation tool.
141 FILE* pipe = popen(command.c_str(), "r");
142 if (!pipe)
143 {
144 throw std::runtime_error("popen() failed!");
145 }
146 while (!std::feof(pipe))
147 {
148 if (fgets(buffer, sizeof buffer, pipe) != NULL)
149 {
150 result += buffer;
151 }
152 }
153 int returnValue = pclose(pipe);
154 // Check if pclose() failed
155 if (returnValue == -1)
156 {
157 // unable to close pipe. Print error and exit function.
158 throw std::runtime_error("pclose() failed!");
159 }
160 std::string firstLine = result.substr(0, result.find('\n'));
161 output = firstLine;
162 // Get command exit status from return value
163 int exitStatus = WEXITSTATUS(returnValue);
164 return exitStatus;
165}
166
Bob Kinged009652020-02-20 14:54:13 +0800167int runToolForOutput(const std::string& configFileName, std::string& output,
168 bool isReadingStderr = false)
169{
170 std::string command = getValidationToolCommand(configFileName);
171 return runToolForOutput(output, command, isReadingStderr);
172}
173
Bob King386d33f2019-12-26 17:28:56 +0800174void expectFileValid(const std::string& configFileName)
175{
Bob Kinged009652020-02-20 14:54:13 +0800176 std::string errorMessage;
177 std::string outputMessage;
Bob King386d33f2019-12-26 17:28:56 +0800178 EXPECT_EQ(runToolForOutput(configFileName, errorMessage, true), 0);
179 EXPECT_EQ(runToolForOutput(configFileName, outputMessage), 0);
180 EXPECT_EQ(errorMessage, "");
181 EXPECT_EQ(outputMessage, "");
182}
183
184void expectFileInvalid(const std::string& configFileName,
185 const std::string& expectedErrorMessage,
186 const std::string& expectedOutputMessage)
187{
Bob Kinged009652020-02-20 14:54:13 +0800188 std::string errorMessage;
189 std::string outputMessage;
Bob King386d33f2019-12-26 17:28:56 +0800190 EXPECT_EQ(runToolForOutput(configFileName, errorMessage, true), 1);
191 EXPECT_EQ(runToolForOutput(configFileName, outputMessage), 1);
192 EXPECT_EQ(errorMessage, expectedErrorMessage);
193 EXPECT_EQ(outputMessage, expectedOutputMessage);
194}
195
Bob Kinged009652020-02-20 14:54:13 +0800196std::string writeDataToTmpFile(const json configFileJson)
Bob King386d33f2019-12-26 17:28:56 +0800197{
198 std::string fileName;
199 fileName = createTmpFile();
200 std::string jsonData = configFileJson.dump();
201 std::ofstream out(fileName);
202 out << jsonData;
203 out.close();
204
Bob Kinged009652020-02-20 14:54:13 +0800205 return fileName;
206}
207
208void expectJsonValid(const json configFileJson)
209{
210 std::string fileName;
211 fileName = writeDataToTmpFile(configFileJson);
212
Bob King386d33f2019-12-26 17:28:56 +0800213 EXPECT_FILE_VALID(fileName);
214 unlink(fileName.c_str());
215}
216
217void expectJsonInvalid(const json configFileJson,
218 const std::string& expectedErrorMessage,
219 const std::string& expectedOutputMessage)
220{
221 std::string fileName;
Bob Kinged009652020-02-20 14:54:13 +0800222 fileName = writeDataToTmpFile(configFileJson);
Bob King386d33f2019-12-26 17:28:56 +0800223
224 EXPECT_FILE_INVALID(fileName, expectedErrorMessage, expectedOutputMessage);
225 unlink(fileName.c_str());
226}
227
Bob Kinged009652020-02-20 14:54:13 +0800228void expectCommandLineSyntax(const std::string& expectedErrorMessage,
229 const std::string& expectedOutputMessage,
230 std::string command, int status)
231{
232 std::string errorMessage;
233 std::string outputMessage;
234 EXPECT_EQ(runToolForOutput(errorMessage, command, true), status);
235 EXPECT_EQ(runToolForOutput(outputMessage, command), status);
236 EXPECT_EQ(errorMessage, expectedErrorMessage);
237 EXPECT_EQ(outputMessage, expectedOutputMessage);
238}
239
Bob Kingbeaf6532020-01-21 11:03:49 +0800240TEST(ValidateRegulatorsConfigTest, And)
241{
242 // Valid.
243 {
244 json configFile = validConfigFile;
245 json andAction =
246 R"(
247 {
248 "and": [
249 { "i2c_compare_byte": { "register": "0xA0", "value": "0x00" } },
250 { "i2c_compare_byte": { "register": "0xA1", "value": "0x00" } }
251 ]
252 }
253 )"_json;
254 configFile["rules"][0]["actions"].push_back(andAction);
255 EXPECT_JSON_VALID(configFile);
256 }
257
258 // Invalid: actions property value is an empty array.
259 {
260 json configFile = validConfigFile;
261 json andAction =
262 R"(
263 {
264 "and": []
265 }
266 )"_json;
267 configFile["rules"][0]["actions"].push_back(andAction);
268 EXPECT_JSON_INVALID(configFile, "Validation failed.",
269 "[] is too short");
270 }
271
272 // Invalid: actions property has incorrect value data type.
273 {
274 json configFile = validConfigFile;
275 json andAction =
276 R"(
277 {
278 "and": true
279 }
280 )"_json;
281 configFile["rules"][0]["actions"].push_back(andAction);
282 EXPECT_JSON_INVALID(configFile, "Validation failed.",
283 "True is not of type u'array'");
284 }
285
286 // Invalid: actions property value contains wrong element type
287 {
288 json configFile = validConfigFile;
289 json andAction =
290 R"(
291 {
292 "and": ["foo"]
293 }
294 )"_json;
295 configFile["rules"][0]["actions"].push_back(andAction);
296 EXPECT_JSON_INVALID(configFile, "Validation failed.",
297 "u'foo' is not of type u'object'");
298 }
299}
Bob King3728f562020-01-21 11:35:31 +0800300TEST(ValidateRegulatorsConfigTest, Chassis)
301{
302 // Valid: test chassis.
303 {
304 json configFile = validConfigFile;
305 EXPECT_JSON_VALID(configFile);
306 }
307 // Valid: test chassis with required properties.
308 {
309 json configFile = validConfigFile;
310 configFile["chassis"][0].erase("comments");
311 configFile["chassis"][0].erase("devices");
312 EXPECT_JSON_VALID(configFile);
313 }
314 // Invalid: test chassis with no number.
315 {
316 json configFile = validConfigFile;
317 configFile["chassis"][0].erase("number");
318 EXPECT_JSON_INVALID(configFile, "Validation failed.",
319 "u'number' is a required property");
320 }
321 // Invalid: test chassis with property comments wrong type.
322 {
323 json configFile = validConfigFile;
324 configFile["chassis"][0]["comments"] = true;
325 EXPECT_JSON_INVALID(configFile, "Validation failed.",
326 "True is not of type u'array'");
327 }
328 // Invalid: test chassis with property number wrong type.
329 {
330 json configFile = validConfigFile;
331 configFile["chassis"][0]["number"] = 1.3;
332 EXPECT_JSON_INVALID(configFile, "Validation failed.",
333 "1.3 is not of type u'integer'");
334 }
335 // Invalid: test chassis with property devices wrong type.
336 {
337 json configFile = validConfigFile;
338 configFile["chassis"][0]["devices"] = true;
339 EXPECT_JSON_INVALID(configFile, "Validation failed.",
340 "True is not of type u'array'");
341 }
342 // Invalid: test chassis with property comments empty array.
343 {
344 json configFile = validConfigFile;
345 configFile["chassis"][0]["comments"] = json::array();
346 EXPECT_JSON_INVALID(configFile, "Validation failed.",
347 "[] is too short");
348 }
349 // Invalid: test chassis with property devices empty array.
350 {
351 json configFile = validConfigFile;
352 configFile["chassis"][0]["devices"] = json::array();
353 EXPECT_JSON_INVALID(configFile, "Validation failed.",
354 "[] is too short");
355 }
356 // Invalid: test chassis with property number less than 1.
357 {
358 json configFile = validConfigFile;
359 configFile["chassis"][0]["number"] = 0;
360 EXPECT_JSON_INVALID(configFile, "Validation failed.",
361 "0 is less than the minimum of 1");
362 }
363}
Bob Kingbf1cbea2020-01-21 11:08:50 +0800364TEST(ValidateRegulatorsConfigTest, ComparePresence)
365{
366 json comparePresenceFile = validConfigFile;
367 comparePresenceFile["rules"][0]["actions"][1]["compare_presence"]["fru"] =
368 "/system/chassis/motherboard/regulator2";
369 comparePresenceFile["rules"][0]["actions"][1]["compare_presence"]["value"] =
370 true;
371 // Valid.
372 {
373 json configFile = comparePresenceFile;
374 EXPECT_JSON_VALID(configFile);
375 }
376
377 // Invalid: no FRU property.
378 {
379 json configFile = comparePresenceFile;
380 configFile["rules"][0]["actions"][1]["compare_presence"].erase("fru");
381 EXPECT_JSON_INVALID(configFile, "Validation failed.",
382 "u'fru' is a required property");
383 }
384
385 // Invalid: FRU property length is string less than 1.
386 {
387 json configFile = comparePresenceFile;
388 configFile["rules"][0]["actions"][1]["compare_presence"]["fru"] = "";
389 EXPECT_JSON_INVALID(configFile, "Validation failed.",
390 "u'' is too short");
391 }
392
393 // Invalid: no value property.
394 {
395 json configFile = comparePresenceFile;
396 configFile["rules"][0]["actions"][1]["compare_presence"].erase("value");
397 EXPECT_JSON_INVALID(configFile, "Validation failed.",
398 "u'value' is a required property");
399 }
400
401 // Invalid: value property type is not boolean.
402 {
403 json configFile = comparePresenceFile;
404 configFile["rules"][0]["actions"][1]["compare_presence"]["value"] = "1";
405 EXPECT_JSON_INVALID(configFile, "Validation failed.",
406 "u'1' is not of type u'boolean'");
407 }
408
409 // Invalid: FRU property type is not string.
410 {
411 json configFile = comparePresenceFile;
412 configFile["rules"][0]["actions"][1]["compare_presence"]["fru"] = 1;
413 EXPECT_JSON_INVALID(configFile, "Validation failed.",
414 "1 is not of type u'string'");
415 }
416}
Bob Kingf8b77a02020-01-21 11:09:47 +0800417TEST(ValidateRegulatorsConfigTest, CompareVpd)
418{
419 json compareVpdFile = validConfigFile;
420 compareVpdFile["rules"][0]["actions"][1]["compare_vpd"]["fru"] =
421 "/system/chassis/motherboard/regulator2";
422 compareVpdFile["rules"][0]["actions"][1]["compare_vpd"]["keyword"] = "CCIN";
423 compareVpdFile["rules"][0]["actions"][1]["compare_vpd"]["value"] = "2D35";
424
425 // Valid.
426 {
427 json configFile = compareVpdFile;
428 EXPECT_JSON_VALID(configFile);
429 }
430
431 // Invalid: no FRU property.
432 {
433 json configFile = compareVpdFile;
434 configFile["rules"][0]["actions"][1]["compare_vpd"].erase("fru");
435 EXPECT_JSON_INVALID(configFile, "Validation failed.",
436 "u'fru' is a required property");
437 }
438
439 // Invalid: no keyword property.
440 {
441 json configFile = compareVpdFile;
442 configFile["rules"][0]["actions"][1]["compare_vpd"].erase("keyword");
443 EXPECT_JSON_INVALID(configFile, "Validation failed.",
444 "u'keyword' is a required property");
445 }
446
447 // Invalid: no value property.
448 {
449 json configFile = compareVpdFile;
450 configFile["rules"][0]["actions"][1]["compare_vpd"].erase("value");
451 EXPECT_JSON_INVALID(configFile, "Validation failed.",
452 "u'value' is a required property");
453 }
454
455 // Invalid: property FRU wrong type.
456 {
457 json configFile = compareVpdFile;
458 configFile["rules"][0]["actions"][1]["compare_vpd"]["fru"] = 1;
459 EXPECT_JSON_INVALID(configFile, "Validation failed.",
460 "1 is not of type u'string'");
461 }
462
463 // Invalid: property FRU is string less than 1.
464 {
465 json configFile = compareVpdFile;
466 configFile["rules"][0]["actions"][1]["compare_vpd"]["fru"] = "";
467 EXPECT_JSON_INVALID(configFile, "Validation failed.",
468 "u'' is too short");
469 }
470
471 // Invalid: property keyword is not "CCIN", "Manufacturer", "Model",
472 // "PartNumber"
473 {
474 json configFile = compareVpdFile;
475 configFile["rules"][0]["actions"][1]["compare_vpd"]["keyword"] =
476 "Number";
477 EXPECT_JSON_INVALID(configFile, "Validation failed.",
478 "u'Number' is not one of [u'CCIN', "
479 "u'Manufacturer', u'Model', u'PartNumber']");
480 }
481
482 // Invalid: property value wrong type.
483 {
484 json configFile = compareVpdFile;
485 configFile["rules"][0]["actions"][1]["compare_vpd"]["value"] = 1;
486 EXPECT_JSON_INVALID(configFile, "Validation failed.",
487 "1 is not of type u'string'");
488 }
489}
Bob King4c67a3a2020-02-07 09:48:11 +0800490TEST(ValidateRegulatorsConfigTest, Configuration)
491{
492 json configurationFile = validConfigFile;
493 configurationFile["chassis"][0]["devices"][0]["configuration"]["comments"]
494 [0] = "Set rail to 1.25V using standard rule";
495 configurationFile["chassis"][0]["devices"][0]["configuration"]["volts"] =
496 1.25;
497 configurationFile["chassis"][0]["devices"][0]["configuration"]["rule_id"] =
498 "set_voltage_rule";
499 // Valid: test configuration with property rule_id and with no actions.
500 {
501 json configFile = configurationFile;
502 EXPECT_JSON_VALID(configFile);
503 }
504 // Valid: test configuration with property actions and with no rule_id.
505 {
506 json configFile = configurationFile;
507 configFile["chassis"][0]["devices"][0]["configuration"].erase(
508 "rule_id");
509 configFile["chassis"][0]["devices"][0]["configuration"]["actions"][0]
510 ["compare_presence"]["fru"] =
511 "/system/chassis/motherboard/cpu3";
512 configFile["chassis"][0]["devices"][0]["configuration"]["actions"][0]
513 ["compare_presence"]["value"] = true;
514 EXPECT_JSON_VALID(configFile);
515 }
516 // Valid: comments not specified (optional property).
517 {
518 json configFile = configurationFile;
519 configFile["chassis"][0]["devices"][0]["configuration"].erase(
520 "comments");
521 EXPECT_JSON_VALID(configFile);
522 }
523 // Valid: volts not specified (optional property).
524 {
525 json configFile = configurationFile;
526 configFile["chassis"][0]["devices"][0]["configuration"].erase("volts");
527 EXPECT_JSON_VALID(configFile);
528 }
529 // Valid: configuration is property of a rail (vs. a device).
530 {
531 json configFile = validConfigFile;
532 configFile["chassis"][0]["devices"][0]["rails"][0]["configuration"]
533 ["comments"][0] = "Set rail to 1.25V using standard rule";
534 configFile["chassis"][0]["devices"][0]["rails"][0]["configuration"]
535 ["volts"] = 1.25;
536 configFile["chassis"][0]["devices"][0]["rails"][0]["configuration"]
537 ["rule_id"] = "set_voltage_rule";
538 EXPECT_JSON_VALID(configFile);
539 }
540 // Invalid: comments property has wrong data type (not an array).
541 {
542 json configFile = configurationFile;
543 configFile["chassis"][0]["devices"][0]["configuration"]["comments"] = 1;
544 EXPECT_JSON_INVALID(configFile, "Validation failed.",
545 "1 is not of type u'array'");
546 }
547 // Invalid: test configuration with both actions and rule_id properties.
548 {
549 json configFile = configurationFile;
550 configFile["chassis"][0]["devices"][0]["configuration"]["actions"][0]
551 ["compare_presence"]["fru"] =
552 "/system/chassis/motherboard/cpu3";
553 configFile["chassis"][0]["devices"][0]["configuration"]["actions"][0]
554 ["compare_presence"]["value"] = true;
555 EXPECT_JSON_INVALID(
556 configFile, "Validation failed.",
557 "{u'volts': 1.25, u'comments': [u'Set rail to 1.25V using standard "
558 "rule'], u'actions': [{u'compare_presence': {u'value': True, "
559 "u'fru': u'/system/chassis/motherboard/cpu3'}}], u'rule_id': "
560 "u'set_voltage_rule'} is valid under each of {u'required': "
561 "[u'actions']}, {u'required': [u'rule_id']}");
562 }
563 // Invalid: test configuration with no rule_id and actions.
564 {
565 json configFile = configurationFile;
566 configFile["chassis"][0]["devices"][0]["configuration"].erase(
567 "rule_id");
568 EXPECT_JSON_INVALID(configFile, "Validation failed.",
569 "u'rule_id' is a required property");
570 }
571 // Invalid: test configuration with property volts wrong type.
572 {
573 json configFile = configurationFile;
574 configFile["chassis"][0]["devices"][0]["configuration"]["volts"] = true;
575 EXPECT_JSON_INVALID(configFile, "Validation failed.",
576 "True is not of type u'number'");
577 }
578 // Invalid: test configuration with property rule_id wrong type.
579 {
580 json configFile = configurationFile;
581 configFile["chassis"][0]["devices"][0]["configuration"]["rule_id"] =
582 true;
583 EXPECT_JSON_INVALID(configFile, "Validation failed.",
584 "True is not of type u'string'");
585 }
586 // Invalid: test configuration with property actions wrong type.
587 {
588 json configFile = configurationFile;
589 configFile["chassis"][0]["devices"][0]["configuration"].erase(
590 "rule_id");
591 configFile["chassis"][0]["devices"][0]["configuration"]["actions"] =
592 true;
593 EXPECT_JSON_INVALID(configFile, "Validation failed.",
594 "True is not of type u'array'");
595 }
596 // Invalid: test configuration with property comments empty array.
597 {
598 json configFile = configurationFile;
599 configFile["chassis"][0]["devices"][0]["configuration"]["comments"] =
600 json::array();
601 EXPECT_JSON_INVALID(configFile, "Validation failed.",
602 "[] is too short");
603 }
604 // Invalid: test configuration with property rule_id wrong format.
605 {
606 json configFile = configurationFile;
607 configFile["chassis"][0]["devices"][0]["configuration"]["rule_id"] =
608 "id!";
609 EXPECT_JSON_INVALID(configFile, "Validation failed.",
610 "u'id!' does not match u'^[A-Za-z0-9_]+$'");
611 }
612 // Invalid: test configuration with property actions empty array.
613 {
614 json configFile = configurationFile;
615 configFile["chassis"][0]["devices"][0]["configuration"].erase(
616 "rule_id");
617 configFile["chassis"][0]["devices"][0]["configuration"]["actions"] =
618 json::array();
619 EXPECT_JSON_INVALID(configFile, "Validation failed.",
620 "[] is too short");
621 }
622}
Bob Kinga2ba2df2020-02-04 14:38:44 +0800623TEST(ValidateRegulatorsConfigTest, Device)
624{
625
626 // Valid: test devices.
627 {
628 json configFile = validConfigFile;
629 EXPECT_JSON_VALID(configFile);
630 }
631 // Valid: test devices with required properties.
632 {
633 json configFile = validConfigFile;
634 configFile["chassis"][0]["devices"][0].erase("comments");
635 configFile["chassis"][0]["devices"][0].erase("presence_detection");
636 configFile["chassis"][0]["devices"][0].erase("configuration");
637 configFile["chassis"][0]["devices"][0].erase("rails");
638 EXPECT_JSON_VALID(configFile);
639 }
640 // Invalid: test devices with no id.
641 {
642 json configFile = validConfigFile;
643 configFile["chassis"][0]["devices"][0].erase("id");
644 EXPECT_JSON_INVALID(configFile, "Validation failed.",
645 "u'id' is a required property");
646 }
647 // Invalid: test devices with no is_regulator.
648 {
649 json configFile = validConfigFile;
650 configFile["chassis"][0]["devices"][0].erase("is_regulator");
651 EXPECT_JSON_INVALID(configFile, "Validation failed.",
652 "u'is_regulator' is a required property");
653 }
654 // Invalid: test devices with no fru.
655 {
656 json configFile = validConfigFile;
657 configFile["chassis"][0]["devices"][0].erase("fru");
658 EXPECT_JSON_INVALID(configFile, "Validation failed.",
659 "u'fru' is a required property");
660 }
661 // Invalid: test devices with no i2c_interface.
662 {
663 json configFile = validConfigFile;
664 configFile["chassis"][0]["devices"][0].erase("i2c_interface");
665 EXPECT_JSON_INVALID(configFile, "Validation failed.",
666 "u'i2c_interface' is a required property");
667 }
668 // Invalid: test devices with property comments wrong type.
669 {
670 json configFile = validConfigFile;
671 configFile["chassis"][0]["devices"][0]["comments"] = true;
672 EXPECT_JSON_INVALID(configFile, "Validation failed.",
673 "True is not of type u'array'");
674 }
675 // Invalid: test devices with property id wrong type.
676 {
677 json configFile = validConfigFile;
678 configFile["chassis"][0]["devices"][0]["id"] = true;
679 EXPECT_JSON_INVALID(configFile, "Validation failed.",
680 "True is not of type u'string'");
681 }
682 // Invalid: test devices with property is_regulator wrong type.
683 {
684 json configFile = validConfigFile;
685 configFile["chassis"][0]["devices"][0]["is_regulator"] = 1;
686 EXPECT_JSON_INVALID(configFile, "Validation failed.",
687 "1 is not of type u'boolean'");
688 }
689 // Invalid: test devices with property fru wrong type.
690 {
691 json configFile = validConfigFile;
692 configFile["chassis"][0]["devices"][0]["fru"] = true;
693 EXPECT_JSON_INVALID(configFile, "Validation failed.",
694 "True is not of type u'string'");
695 }
696 // Invalid: test devices with property i2c_interface wrong type.
697 {
698 json configFile = validConfigFile;
699 configFile["chassis"][0]["devices"][0]["i2c_interface"] = true;
700 EXPECT_JSON_INVALID(configFile, "Validation failed.",
701 "True is not of type u'object'");
702 }
703 // Invalid: test devices with property presence_detection wrong
704 // type.
705 {
706 json configFile = validConfigFile;
707 configFile["chassis"][0]["devices"][0]["presence_detection"] = true;
708 EXPECT_JSON_INVALID(configFile, "Validation failed.",
709 "True is not of type u'object'");
710 }
711 // Invalid: test devices with property configuration wrong type.
712 {
713 json configFile = validConfigFile;
714 configFile["chassis"][0]["devices"][0]["configuration"] = true;
715 EXPECT_JSON_INVALID(configFile, "Validation failed.",
716 "True is not of type u'object'");
717 }
718 // Invalid: test devices with property rails wrong type.
719 {
720 json configFile = validConfigFile;
721 configFile["chassis"][0]["devices"][0]["rails"] = true;
722 EXPECT_JSON_INVALID(configFile, "Validation failed.",
723 "True is not of type u'array'");
724 }
725 // Invalid: test devices with property comments empty array.
726 {
727 json configFile = validConfigFile;
728 configFile["chassis"][0]["devices"][0]["comments"] = json::array();
729 EXPECT_JSON_INVALID(configFile, "Validation failed.",
730 "[] is too short");
731 }
732 // Invalid: test devices with property fru length less than 1.
733 {
734 json configFile = validConfigFile;
735 configFile["chassis"][0]["devices"][0]["fru"] = "";
736 EXPECT_JSON_INVALID(configFile, "Validation failed.",
737 "u'' is too short");
738 }
739 // Invalid: test devices with property id wrong format.
740 {
741 json configFile = validConfigFile;
742 configFile["chassis"][0]["devices"][0]["id"] = "id#";
743 EXPECT_JSON_INVALID(configFile, "Validation failed.",
744 "u'id#' does not match u'^[A-Za-z0-9_]+$'");
745 }
746 // Invalid: test devices with property rails empty array.
747 {
748 json configFile = validConfigFile;
749 configFile["chassis"][0]["devices"][0]["rails"] = json::array();
750 EXPECT_JSON_INVALID(configFile, "Validation failed.",
751 "[] is too short");
752 }
753}
Bob King4ab8cbb2020-01-21 11:10:48 +0800754TEST(ValidateRegulatorsConfigTest, I2CCompareBit)
755{
756 json i2cCompareBitFile = validConfigFile;
757 i2cCompareBitFile["rules"][0]["actions"][1]["i2c_compare_bit"]["register"] =
758 "0xA0";
759 i2cCompareBitFile["rules"][0]["actions"][1]["i2c_compare_bit"]["position"] =
760 3;
761 i2cCompareBitFile["rules"][0]["actions"][1]["i2c_compare_bit"]["value"] = 1;
762 // Valid: test rule actions i2c_compare_bit.
763 {
764 json configFile = i2cCompareBitFile;
765 EXPECT_JSON_VALID(configFile);
766 }
767 // Invalid: test i2c_compare_bit with no register.
768 {
769 json configFile = i2cCompareBitFile;
770 configFile["rules"][0]["actions"][1]["i2c_compare_bit"].erase(
771 "register");
772 EXPECT_JSON_INVALID(configFile, "Validation failed.",
773 "u'register' is a required property");
774 }
775 // Invalid: test i2c_compare_bit with no position.
776 {
777 json configFile = i2cCompareBitFile;
778 configFile["rules"][0]["actions"][1]["i2c_compare_bit"].erase(
779 "position");
780 EXPECT_JSON_INVALID(configFile, "Validation failed.",
781 "u'position' is a required property");
782 }
783 // Invalid: test i2c_compare_bit with no value.
784 {
785 json configFile = i2cCompareBitFile;
786 configFile["rules"][0]["actions"][1]["i2c_compare_bit"].erase("value");
787 EXPECT_JSON_INVALID(configFile, "Validation failed.",
788 "u'value' is a required property");
789 }
790 // Invalid: test i2c_compare_bit with register wrong type.
791 {
792 json configFile = i2cCompareBitFile;
793 configFile["rules"][0]["actions"][1]["i2c_compare_bit"]["register"] = 1;
794 EXPECT_JSON_INVALID(configFile, "Validation failed.",
795 "1 is not of type u'string'");
796 }
797 // Invalid: test i2c_compare_bit with register wrong format.
798 {
799 json configFile = i2cCompareBitFile;
800 configFile["rules"][0]["actions"][1]["i2c_compare_bit"]["register"] =
801 "0xA00";
802 EXPECT_JSON_INVALID(configFile, "Validation failed.",
803 "u'0xA00' does not match u'^0x[0-9A-Fa-f]{2}$'");
804 }
805 // Invalid: test i2c_compare_bit with position wrong type.
806 {
807 json configFile = i2cCompareBitFile;
808 configFile["rules"][0]["actions"][1]["i2c_compare_bit"]["position"] =
809 3.1;
810 EXPECT_JSON_INVALID(configFile, "Validation failed.",
811 "3.1 is not of type u'integer'");
812 }
813 // Invalid: test i2c_compare_bit with position greater than 7.
814 {
815 json configFile = i2cCompareBitFile;
816 configFile["rules"][0]["actions"][1]["i2c_compare_bit"]["position"] = 8;
817 EXPECT_JSON_INVALID(configFile, "Validation failed.",
818 "8 is greater than the maximum of 7");
819 }
820 // Invalid: test i2c_compare_bit with position less than 0.
821 {
822 json configFile = i2cCompareBitFile;
823 configFile["rules"][0]["actions"][1]["i2c_compare_bit"]["position"] =
824 -1;
825 EXPECT_JSON_INVALID(configFile, "Validation failed.",
826 "-1 is less than the minimum of 0");
827 }
828 // Invalid: test i2c_compare_bit with value wrong type.
829 {
830 json configFile = i2cCompareBitFile;
831 configFile["rules"][0]["actions"][1]["i2c_compare_bit"]["value"] = "1";
832 EXPECT_JSON_INVALID(configFile, "Validation failed.",
833 "u'1' is not of type u'integer'");
834 }
835 // Invalid: test i2c_compare_bit with value greater than 1.
836 {
837 json configFile = i2cCompareBitFile;
838 configFile["rules"][0]["actions"][1]["i2c_compare_bit"]["value"] = 2;
839 EXPECT_JSON_INVALID(configFile, "Validation failed.",
840 "2 is greater than the maximum of 1");
841 }
842 // Invalid: test i2c_compare_bit with value less than 0.
843 {
844 json configFile = i2cCompareBitFile;
845 configFile["rules"][0]["actions"][1]["i2c_compare_bit"]["value"] = -1;
846 EXPECT_JSON_INVALID(configFile, "Validation failed.",
847 "-1 is less than the minimum of 0");
848 }
849}
Bob King514023d2020-01-21 11:13:05 +0800850TEST(ValidateRegulatorsConfigTest, I2CCompareByte)
851{
852 json i2cCompareByteFile = validConfigFile;
853 i2cCompareByteFile["rules"][0]["actions"][1]["i2c_compare_byte"]
854 ["register"] = "0x82";
855 i2cCompareByteFile["rules"][0]["actions"][1]["i2c_compare_byte"]["value"] =
856 "0x40";
857 i2cCompareByteFile["rules"][0]["actions"][1]["i2c_compare_byte"]["mask"] =
858 "0x7F";
859 // Valid: test i2c_compare_byte with all properties.
860 {
861 json configFile = i2cCompareByteFile;
862 EXPECT_JSON_VALID(configFile);
863 }
864 // Valid: test i2c_compare_byte with all required properties.
865 {
866 json configFile = i2cCompareByteFile;
867 configFile["rules"][0]["actions"][1]["i2c_compare_byte"].erase("mask");
868 EXPECT_JSON_VALID(configFile);
869 }
870 // Invalid: test i2c_compare_byte with no register.
871 {
872 json configFile = i2cCompareByteFile;
873 configFile["rules"][0]["actions"][1]["i2c_compare_byte"].erase(
874 "register");
875 EXPECT_JSON_INVALID(configFile, "Validation failed.",
876 "u'register' is a required property");
877 }
878 // Invalid: test i2c_compare_byte with no value.
879 {
880 json configFile = i2cCompareByteFile;
881 configFile["rules"][0]["actions"][1]["i2c_compare_byte"].erase("value");
882 EXPECT_JSON_INVALID(configFile, "Validation failed.",
883 "u'value' is a required property");
884 }
885 // Invalid: test i2c_compare_byte with property register wrong type.
886 {
887 json configFile = i2cCompareByteFile;
888 configFile["rules"][0]["actions"][1]["i2c_compare_byte"]["register"] =
889 1;
890 EXPECT_JSON_INVALID(configFile, "Validation failed.",
891 "1 is not of type u'string'");
892 }
893 // Invalid: test i2c_compare_byte with property value wrong type.
894 {
895 json configFile = i2cCompareByteFile;
896 configFile["rules"][0]["actions"][1]["i2c_compare_byte"]["value"] = 1;
897 EXPECT_JSON_INVALID(configFile, "Validation failed.",
898 "1 is not of type u'string'");
899 }
900 // Invalid: test i2c_compare_byte with property mask wrong type.
901 {
902 json configFile = i2cCompareByteFile;
903 configFile["rules"][0]["actions"][1]["i2c_compare_byte"]["mask"] = 1;
904 EXPECT_JSON_INVALID(configFile, "Validation failed.",
905 "1 is not of type u'string'");
906 }
907 // Invalid: test i2c_compare_byte with property register more than 2 hex
908 // digits.
909 {
910 json configFile = i2cCompareByteFile;
911 configFile["rules"][0]["actions"][1]["i2c_compare_byte"]["register"] =
912 "0x820";
913 EXPECT_JSON_INVALID(configFile, "Validation failed.",
914 "u'0x820' does not match u'^0x[0-9A-Fa-f]{2}$'");
915 }
916 // Invalid: test i2c_compare_byte with property value more than 2 hex
917 // digits.
918 {
919 json configFile = i2cCompareByteFile;
920 configFile["rules"][0]["actions"][1]["i2c_compare_byte"]["value"] =
921 "0x820";
922 EXPECT_JSON_INVALID(configFile, "Validation failed.",
923 "u'0x820' does not match u'^0x[0-9A-Fa-f]{2}$'");
924 }
925 // Invalid: test i2c_compare_byte with property mask more than 2 hex digits.
926 {
927 json configFile = i2cCompareByteFile;
928 configFile["rules"][0]["actions"][1]["i2c_compare_byte"]["mask"] =
929 "0x820";
930 EXPECT_JSON_INVALID(configFile, "Validation failed.",
931 "u'0x820' does not match u'^0x[0-9A-Fa-f]{2}$'");
932 }
933 // Invalid: test i2c_compare_byte with property register less than 2 hex
934 // digits.
935 {
936 json configFile = i2cCompareByteFile;
937 configFile["rules"][0]["actions"][1]["i2c_compare_byte"]["register"] =
938 "0x8";
939 EXPECT_JSON_INVALID(configFile, "Validation failed.",
940 "u'0x8' does not match u'^0x[0-9A-Fa-f]{2}$'");
941 }
942 // Invalid: test i2c_compare_byte with property value less than 2 hex
943 // digits.
944 {
945 json configFile = i2cCompareByteFile;
946 configFile["rules"][0]["actions"][1]["i2c_compare_byte"]["value"] =
947 "0x8";
948 EXPECT_JSON_INVALID(configFile, "Validation failed.",
949 "u'0x8' does not match u'^0x[0-9A-Fa-f]{2}$'");
950 }
951 // Invalid: test i2c_compare_byte with property mask less than 2 hex digits.
952 {
953 json configFile = i2cCompareByteFile;
954 configFile["rules"][0]["actions"][1]["i2c_compare_byte"]["mask"] =
955 "0x8";
956 EXPECT_JSON_INVALID(configFile, "Validation failed.",
957 "u'0x8' does not match u'^0x[0-9A-Fa-f]{2}$'");
958 }
959 // Invalid: test i2c_compare_byte with property register no leading prefix.
960 {
961 json configFile = i2cCompareByteFile;
962 configFile["rules"][0]["actions"][1]["i2c_compare_byte"]["register"] =
963 "82";
964 EXPECT_JSON_INVALID(configFile, "Validation failed.",
965 "u'82' does not match u'^0x[0-9A-Fa-f]{2}$'");
966 }
967 // Invalid: test i2c_compare_byte with property value no leading prefix.
968 {
969 json configFile = i2cCompareByteFile;
970 configFile["rules"][0]["actions"][1]["i2c_compare_byte"]["value"] =
971 "82";
972 EXPECT_JSON_INVALID(configFile, "Validation failed.",
973 "u'82' does not match u'^0x[0-9A-Fa-f]{2}$'");
974 }
975 // Invalid: test i2c_compare_byte with property mask no leading prefix.
976 {
977 json configFile = i2cCompareByteFile;
978 configFile["rules"][0]["actions"][1]["i2c_compare_byte"]["mask"] = "82";
979 EXPECT_JSON_INVALID(configFile, "Validation failed.",
980 "u'82' does not match u'^0x[0-9A-Fa-f]{2}$'");
981 }
982 // Invalid: test i2c_compare_byte with property register invalid hex digit.
983 {
984 json configFile = i2cCompareByteFile;
985 configFile["rules"][0]["actions"][1]["i2c_compare_byte"]["register"] =
986 "0xG1";
987 EXPECT_JSON_INVALID(configFile, "Validation failed.",
988 "u'0xG1' does not match u'^0x[0-9A-Fa-f]{2}$'");
989 }
990 // Invalid: test i2c_compare_byte with property value invalid hex digit.
991 {
992 json configFile = i2cCompareByteFile;
993 configFile["rules"][0]["actions"][1]["i2c_compare_byte"]["value"] =
994 "0xG1";
995 EXPECT_JSON_INVALID(configFile, "Validation failed.",
996 "u'0xG1' does not match u'^0x[0-9A-Fa-f]{2}$'");
997 }
998 // Invalid: test i2c_compare_byte with property mask invalid hex digit.
999 {
1000 json configFile = i2cCompareByteFile;
1001 configFile["rules"][0]["actions"][1]["i2c_compare_byte"]["mask"] =
1002 "0xG1";
1003 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1004 "u'0xG1' does not match u'^0x[0-9A-Fa-f]{2}$'");
1005 }
1006}
Bob Kingfb162bb2020-01-21 11:28:07 +08001007TEST(ValidateRegulatorsConfigTest, I2CCompareBytes)
1008{
1009 json i2cCompareBytesFile = validConfigFile;
1010 i2cCompareBytesFile["rules"][0]["actions"][1]["i2c_compare_bytes"]
1011 ["register"] = "0x82";
1012 i2cCompareBytesFile["rules"][0]["actions"][1]["i2c_compare_bytes"]
1013 ["values"] = {"0x02", "0x73"};
1014 i2cCompareBytesFile["rules"][0]["actions"][1]["i2c_compare_bytes"]
1015 ["masks"] = {"0x7F", "0x7F"};
1016 // Valid: test i2c_compare_bytes.
1017 {
1018 json configFile = i2cCompareBytesFile;
1019 EXPECT_JSON_VALID(configFile);
1020 }
1021 // Valid: test i2c_compare_bytes with all required properties.
1022 {
1023 json configFile = i2cCompareBytesFile;
1024 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"].erase(
1025 "masks");
1026 EXPECT_JSON_VALID(configFile);
1027 }
1028 // Invalid: test i2c_compare_bytes with no register.
1029 {
1030 json configFile = i2cCompareBytesFile;
1031 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"].erase(
1032 "register");
1033 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1034 "u'register' is a required property");
1035 }
1036 // Invalid: test i2c_compare_bytes with no values.
1037 {
1038 json configFile = i2cCompareBytesFile;
1039 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"].erase(
1040 "values");
1041 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1042 "u'values' is a required property");
1043 }
1044 // Invalid: test i2c_compare_bytes with property values as empty array.
1045 {
1046 json configFile = i2cCompareBytesFile;
1047 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["values"] =
1048 json::array();
1049 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1050 "[] is too short");
1051 }
1052 // Invalid: test i2c_compare_bytes with property masks as empty array.
1053 {
1054 json configFile = i2cCompareBytesFile;
1055 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["masks"] =
1056 json::array();
1057 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1058 "[] is too short");
1059 }
1060 // Invalid: test i2c_compare_bytes with property register wrong type.
1061 {
1062 json configFile = i2cCompareBytesFile;
1063 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["register"] =
1064 1;
1065 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1066 "1 is not of type u'string'");
1067 }
1068 // Invalid: test i2c_compare_bytes with property values wrong type.
1069 {
1070 json configFile = i2cCompareBytesFile;
1071 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["values"] = 1;
1072 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1073 "1 is not of type u'array'");
1074 }
1075 // Invalid: test i2c_compare_bytes with property masks wrong type.
1076 {
1077 json configFile = i2cCompareBytesFile;
1078 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["masks"] = 1;
1079 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1080 "1 is not of type u'array'");
1081 }
1082 // Invalid: test i2c_compare_bytes with property register more than 2 hex
1083 // digits.
1084 {
1085 json configFile = i2cCompareBytesFile;
1086 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["register"] =
1087 "0x820";
1088 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1089 "u'0x820' does not match u'^0x[0-9A-Fa-f]{2}$'");
1090 }
1091 // Invalid: test i2c_compare_bytes with property values more than 2 hex
1092 // digits.
1093 {
1094 json configFile = i2cCompareBytesFile;
1095 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["values"][0] =
1096 "0x820";
1097 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1098 "u'0x820' does not match u'^0x[0-9A-Fa-f]{2}$'");
1099 }
1100 // Invalid: test i2c_compare_bytes with property masks more than 2 hex
1101 // digits.
1102 {
1103 json configFile = i2cCompareBytesFile;
1104 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["masks"][0] =
1105 "0x820";
1106 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1107 "u'0x820' does not match u'^0x[0-9A-Fa-f]{2}$'");
1108 }
1109 // Invalid: test i2c_compare_bytes with property register less than 2 hex
1110 // digits.
1111 {
1112 json configFile = i2cCompareBytesFile;
1113 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["register"] =
1114 "0x8";
1115 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1116 "u'0x8' does not match u'^0x[0-9A-Fa-f]{2}$'");
1117 }
1118 // Invalid: test i2c_compare_bytes with property values less than 2 hex
1119 // digits.
1120 {
1121 json configFile = i2cCompareBytesFile;
1122 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["values"][0] =
1123 "0x8";
1124 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1125 "u'0x8' does not match u'^0x[0-9A-Fa-f]{2}$'");
1126 }
1127 // Invalid: test i2c_compare_bytes with property masks less than 2 hex
1128 // digits.
1129 {
1130 json configFile = i2cCompareBytesFile;
1131 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["masks"][0] =
1132 "0x8";
1133 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1134 "u'0x8' does not match u'^0x[0-9A-Fa-f]{2}$'");
1135 }
1136 // Invalid: test i2c_compare_bytes with property register no leading prefix.
1137 {
1138 json configFile = i2cCompareBytesFile;
1139 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["register"] =
1140 "82";
1141 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1142 "u'82' does not match u'^0x[0-9A-Fa-f]{2}$'");
1143 }
1144 // Invalid: test i2c_compare_bytes with property values no leading prefix.
1145 {
1146 json configFile = i2cCompareBytesFile;
1147 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["values"][0] =
1148 "82";
1149 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1150 "u'82' does not match u'^0x[0-9A-Fa-f]{2}$'");
1151 }
1152 // Invalid: test i2c_compare_bytes with property masks no leading prefix.
1153 {
1154 json configFile = i2cCompareBytesFile;
1155 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["masks"][0] =
1156 "82";
1157 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1158 "u'82' does not match u'^0x[0-9A-Fa-f]{2}$'");
1159 }
1160 // Invalid: test i2c_compare_bytes with property register invalid hex digit.
1161 {
1162 json configFile = i2cCompareBytesFile;
1163 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["register"] =
1164 "0xG1";
1165 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1166 "u'0xG1' does not match u'^0x[0-9A-Fa-f]{2}$'");
1167 }
1168 // Invalid: test i2c_compare_bytes with property values invalid hex digit.
1169 {
1170 json configFile = i2cCompareBytesFile;
1171 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["values"][0] =
1172 "0xG1";
1173 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1174 "u'0xG1' does not match u'^0x[0-9A-Fa-f]{2}$'");
1175 }
1176 // Invalid: test i2c_compare_bytes with property masks invalid hex digit.
1177 {
1178 json configFile = i2cCompareBytesFile;
1179 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["masks"][0] =
1180 "0xG1";
1181 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1182 "u'0xG1' does not match u'^0x[0-9A-Fa-f]{2}$'");
1183 }
1184}
Bob Kingca93f1f2020-01-31 11:21:16 +08001185TEST(ValidateRegulatorsConfigTest, I2CInterface)
1186{
1187 // Valid: test i2c_interface.
1188 {
1189 json configFile = validConfigFile;
1190 EXPECT_JSON_VALID(configFile);
1191 }
1192 // Invalid: testi2c_interface with no bus.
1193 {
1194 json configFile = validConfigFile;
1195 configFile["chassis"][0]["devices"][0]["i2c_interface"].erase("bus");
1196 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1197 "u'bus' is a required property");
1198 }
1199 // Invalid: test i2c_interface with no address.
1200 {
1201 json configFile = validConfigFile;
1202 configFile["chassis"][0]["devices"][0]["i2c_interface"].erase(
1203 "address");
1204 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1205 "u'address' is a required property");
1206 }
1207 // Invalid: test i2c_interface with property bus wrong type.
1208 {
1209 json configFile = validConfigFile;
1210 configFile["chassis"][0]["devices"][0]["i2c_interface"]["bus"] = true;
1211 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1212 "True is not of type u'integer'");
1213 }
1214 // Invalid: test i2c_interface with property address wrong
1215 // type.
1216 {
1217 json configFile = validConfigFile;
1218 configFile["chassis"][0]["devices"][0]["i2c_interface"]["address"] =
1219 true;
1220 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1221 "True is not of type u'string'");
1222 }
1223 // Invalid: test i2c_interface with property bus less than
1224 // 0.
1225 {
1226 json configFile = validConfigFile;
1227 configFile["chassis"][0]["devices"][0]["i2c_interface"]["bus"] = -1;
1228 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1229 "-1 is less than the minimum of 0");
1230 }
1231 // Invalid: test i2c_interface with property address wrong
1232 // format.
1233 {
1234 json configFile = validConfigFile;
1235 configFile["chassis"][0]["devices"][0]["i2c_interface"]["address"] =
1236 "0x700";
1237 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1238 "u'0x700' does not match u'^0x[0-9A-Fa-f]{2}$'");
1239 }
1240}
Bob King188db7d2020-01-31 13:01:01 +08001241TEST(ValidateRegulatorsConfigTest, I2CWriteBit)
1242{
1243 json i2cWriteBitFile = validConfigFile;
1244 i2cWriteBitFile["rules"][0]["actions"][1]["i2c_write_bit"]["register"] =
1245 "0xA0";
1246 i2cWriteBitFile["rules"][0]["actions"][1]["i2c_write_bit"]["position"] = 3;
1247 i2cWriteBitFile["rules"][0]["actions"][1]["i2c_write_bit"]["value"] = 1;
1248 // Valid: test rule actions i2c_write_bit.
1249 {
1250 json configFile = i2cWriteBitFile;
1251 EXPECT_JSON_VALID(configFile);
1252 }
1253 // Invalid: test i2c_write_bit with no register.
1254 {
1255 json configFile = i2cWriteBitFile;
1256 configFile["rules"][0]["actions"][1]["i2c_write_bit"].erase("register");
1257 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1258 "u'register' is a required property");
1259 }
1260 // Invalid: test i2c_write_bit with no position.
1261 {
1262 json configFile = i2cWriteBitFile;
1263 configFile["rules"][0]["actions"][1]["i2c_write_bit"].erase("position");
1264 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1265 "u'position' is a required property");
1266 }
1267 // Invalid: test i2c_write_bit with no value.
1268 {
1269 json configFile = i2cWriteBitFile;
1270 configFile["rules"][0]["actions"][1]["i2c_write_bit"].erase("value");
1271 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1272 "u'value' is a required property");
1273 }
1274 // Invalid: test i2c_write_bit with register wrong type.
1275 {
1276 json configFile = i2cWriteBitFile;
1277 configFile["rules"][0]["actions"][1]["i2c_write_bit"]["register"] = 1;
1278 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1279 "1 is not of type u'string'");
1280 }
1281 // Invalid: test i2c_write_bit with register wrong format.
1282 {
1283 json configFile = i2cWriteBitFile;
1284 configFile["rules"][0]["actions"][1]["i2c_write_bit"]["register"] =
1285 "0xA00";
1286 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1287 "u'0xA00' does not match u'^0x[0-9A-Fa-f]{2}$'");
1288 }
1289 // Invalid: test i2c_write_bit with position wrong type.
1290 {
1291 json configFile = i2cWriteBitFile;
1292 configFile["rules"][0]["actions"][1]["i2c_write_bit"]["position"] = 3.1;
1293 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1294 "3.1 is not of type u'integer'");
1295 }
1296 // Invalid: test i2c_write_bit with position greater than 7.
1297 {
1298 json configFile = i2cWriteBitFile;
1299 configFile["rules"][0]["actions"][1]["i2c_write_bit"]["position"] = 8;
1300 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1301 "8 is greater than the maximum of 7");
1302 }
1303 // Invalid: test i2c_write_bit with position less than 0.
1304 {
1305 json configFile = i2cWriteBitFile;
1306 configFile["rules"][0]["actions"][1]["i2c_write_bit"]["position"] = -1;
1307 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1308 "-1 is less than the minimum of 0");
1309 }
1310 // Invalid: test i2c_write_bit with value wrong type.
1311 {
1312 json configFile = i2cWriteBitFile;
1313 configFile["rules"][0]["actions"][1]["i2c_write_bit"]["value"] = "1";
1314 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1315 "u'1' is not of type u'integer'");
1316 }
1317 // Invalid: test i2c_write_bit with value greater than 1.
1318 {
1319 json configFile = i2cWriteBitFile;
1320 configFile["rules"][0]["actions"][1]["i2c_write_bit"]["value"] = 2;
1321 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1322 "2 is greater than the maximum of 1");
1323 }
1324 // Invalid: test i2c_write_bit with value less than 0.
1325 {
1326 json configFile = i2cWriteBitFile;
1327 configFile["rules"][0]["actions"][1]["i2c_write_bit"]["value"] = -1;
1328 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1329 "-1 is less than the minimum of 0");
1330 }
1331}
1332TEST(ValidateRegulatorsConfigTest, I2CWriteByte)
1333{
1334 json i2cWriteByteFile = validConfigFile;
1335 i2cWriteByteFile["rules"][0]["actions"][1]["i2c_write_byte"]["register"] =
1336 "0x82";
1337 i2cWriteByteFile["rules"][0]["actions"][1]["i2c_write_byte"]["value"] =
1338 "0x40";
1339 i2cWriteByteFile["rules"][0]["actions"][1]["i2c_write_byte"]["mask"] =
1340 "0x7F";
1341 // Valid: test i2c_write_byte with all properties.
1342 {
1343 json configFile = i2cWriteByteFile;
1344 EXPECT_JSON_VALID(configFile);
1345 }
1346 // Valid: test i2c_write_byte with all required properties.
1347 {
1348 json configFile = i2cWriteByteFile;
1349 configFile["rules"][0]["actions"][1]["i2c_write_byte"].erase("mask");
1350 EXPECT_JSON_VALID(configFile);
1351 }
1352 // Invalid: test i2c_write_byte with no register.
1353 {
1354 json configFile = i2cWriteByteFile;
1355 configFile["rules"][0]["actions"][1]["i2c_write_byte"].erase(
1356 "register");
1357 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1358 "u'register' is a required property");
1359 }
1360 // Invalid: test i2c_write_byte with no value.
1361 {
1362 json configFile = i2cWriteByteFile;
1363 configFile["rules"][0]["actions"][1]["i2c_write_byte"].erase("value");
1364 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1365 "u'value' is a required property");
1366 }
1367 // Invalid: test i2c_write_byte with property register wrong type.
1368 {
1369 json configFile = i2cWriteByteFile;
1370 configFile["rules"][0]["actions"][1]["i2c_write_byte"]["register"] = 1;
1371 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1372 "1 is not of type u'string'");
1373 }
1374 // Invalid: test i2c_write_byte with property value wrong type.
1375 {
1376 json configFile = i2cWriteByteFile;
1377 configFile["rules"][0]["actions"][1]["i2c_write_byte"]["value"] = 1;
1378 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1379 "1 is not of type u'string'");
1380 }
1381 // Invalid: test i2c_write_byte with property mask wrong type.
1382 {
1383 json configFile = i2cWriteByteFile;
1384 configFile["rules"][0]["actions"][1]["i2c_write_byte"]["mask"] = 1;
1385 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1386 "1 is not of type u'string'");
1387 }
1388 // Invalid: test i2c_write_byte with property register more than 2 hex
1389 // digits.
1390 {
1391 json configFile = i2cWriteByteFile;
1392 configFile["rules"][0]["actions"][1]["i2c_write_byte"]["register"] =
1393 "0x820";
1394 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1395 "u'0x820' does not match u'^0x[0-9A-Fa-f]{2}$'");
1396 }
1397 // Invalid: test i2c_write_byte with property value more than 2 hex
1398 // digits.
1399 {
1400 json configFile = i2cWriteByteFile;
1401 configFile["rules"][0]["actions"][1]["i2c_write_byte"]["value"] =
1402 "0x820";
1403 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1404 "u'0x820' does not match u'^0x[0-9A-Fa-f]{2}$'");
1405 }
1406 // Invalid: test i2c_write_byte with property mask more than 2 hex digits.
1407 {
1408 json configFile = i2cWriteByteFile;
1409 configFile["rules"][0]["actions"][1]["i2c_write_byte"]["mask"] =
1410 "0x820";
1411 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1412 "u'0x820' does not match u'^0x[0-9A-Fa-f]{2}$'");
1413 }
1414 // Invalid: test i2c_write_byte with property register less than 2 hex
1415 // digits.
1416 {
1417 json configFile = i2cWriteByteFile;
1418 configFile["rules"][0]["actions"][1]["i2c_write_byte"]["register"] =
1419 "0x8";
1420 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1421 "u'0x8' does not match u'^0x[0-9A-Fa-f]{2}$'");
1422 }
1423 // Invalid: test i2c_write_byte with property value less than 2 hex
1424 // digits.
1425 {
1426 json configFile = i2cWriteByteFile;
1427 configFile["rules"][0]["actions"][1]["i2c_write_byte"]["value"] = "0x8";
1428 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1429 "u'0x8' does not match u'^0x[0-9A-Fa-f]{2}$'");
1430 }
1431 // Invalid: test i2c_write_byte with property mask less than 2 hex digits.
1432 {
1433 json configFile = i2cWriteByteFile;
1434 configFile["rules"][0]["actions"][1]["i2c_write_byte"]["mask"] = "0x8";
1435 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1436 "u'0x8' does not match u'^0x[0-9A-Fa-f]{2}$'");
1437 }
1438 // Invalid: test i2c_write_byte with property register no leading prefix.
1439 {
1440 json configFile = i2cWriteByteFile;
1441 configFile["rules"][0]["actions"][1]["i2c_write_byte"]["register"] =
1442 "82";
1443 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1444 "u'82' does not match u'^0x[0-9A-Fa-f]{2}$'");
1445 }
1446 // Invalid: test i2c_write_byte with property value no leading prefix.
1447 {
1448 json configFile = i2cWriteByteFile;
1449 configFile["rules"][0]["actions"][1]["i2c_write_byte"]["value"] = "82";
1450 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1451 "u'82' does not match u'^0x[0-9A-Fa-f]{2}$'");
1452 }
1453 // Invalid: test i2c_write_byte with property mask no leading prefix.
1454 {
1455 json configFile = i2cWriteByteFile;
1456 configFile["rules"][0]["actions"][1]["i2c_write_byte"]["mask"] = "82";
1457 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1458 "u'82' does not match u'^0x[0-9A-Fa-f]{2}$'");
1459 }
1460 // Invalid: test i2c_write_byte with property register invalid hex digit.
1461 {
1462 json configFile = i2cWriteByteFile;
1463 configFile["rules"][0]["actions"][1]["i2c_write_byte"]["register"] =
1464 "0xG1";
1465 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1466 "u'0xG1' does not match u'^0x[0-9A-Fa-f]{2}$'");
1467 }
1468 // Invalid: test i2c_write_byte with property value invalid hex digit.
1469 {
1470 json configFile = i2cWriteByteFile;
1471 configFile["rules"][0]["actions"][1]["i2c_write_byte"]["value"] =
1472 "0xG1";
1473 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1474 "u'0xG1' does not match u'^0x[0-9A-Fa-f]{2}$'");
1475 }
1476 // Invalid: test i2c_write_byte with property mask invalid hex digit.
1477 {
1478 json configFile = i2cWriteByteFile;
1479 configFile["rules"][0]["actions"][1]["i2c_write_byte"]["mask"] = "0xG1";
1480 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1481 "u'0xG1' does not match u'^0x[0-9A-Fa-f]{2}$'");
1482 }
1483}
1484TEST(ValidateRegulatorsConfigTest, I2CWriteBytes)
1485{
1486 json i2cWriteBytesFile = validConfigFile;
1487 i2cWriteBytesFile["rules"][0]["actions"][1]["i2c_write_bytes"]["register"] =
1488 "0x82";
1489 i2cWriteBytesFile["rules"][0]["actions"][1]["i2c_write_bytes"]["values"] = {
1490 "0x02", "0x73"};
1491 i2cWriteBytesFile["rules"][0]["actions"][1]["i2c_write_bytes"]["masks"] = {
1492 "0x7F", "0x7F"};
1493 // Valid: test i2c_write_bytes.
1494 {
1495 json configFile = i2cWriteBytesFile;
1496 EXPECT_JSON_VALID(configFile);
1497 }
1498 // Valid: test i2c_write_bytes with all required properties.
1499 {
1500 json configFile = i2cWriteBytesFile;
1501 configFile["rules"][0]["actions"][1]["i2c_write_bytes"].erase("masks");
1502 EXPECT_JSON_VALID(configFile);
1503 }
1504 // Invalid: test i2c_write_bytes with no register.
1505 {
1506 json configFile = i2cWriteBytesFile;
1507 configFile["rules"][0]["actions"][1]["i2c_write_bytes"].erase(
1508 "register");
1509 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1510 "u'register' is a required property");
1511 }
1512 // Invalid: test i2c_write_bytes with no values.
1513 {
1514 json configFile = i2cWriteBytesFile;
1515 configFile["rules"][0]["actions"][1]["i2c_write_bytes"].erase("values");
1516 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1517 "u'values' is a required property");
1518 }
1519 // Invalid: test i2c_write_bytes with property values as empty array.
1520 {
1521 json configFile = i2cWriteBytesFile;
1522 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["values"] =
1523 json::array();
1524 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1525 "[] is too short");
1526 }
1527 // Invalid: test i2c_write_bytes with property masks as empty array.
1528 {
1529 json configFile = i2cWriteBytesFile;
1530 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["masks"] =
1531 json::array();
1532 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1533 "[] is too short");
1534 }
1535 // Invalid: test i2c_write_bytes with property register wrong type.
1536 {
1537 json configFile = i2cWriteBytesFile;
1538 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["register"] = 1;
1539 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1540 "1 is not of type u'string'");
1541 }
1542 // Invalid: test i2c_write_bytes with property values wrong type.
1543 {
1544 json configFile = i2cWriteBytesFile;
1545 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["values"] = 1;
1546 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1547 "1 is not of type u'array'");
1548 }
1549 // Invalid: test i2c_write_bytes with property masks wrong type.
1550 {
1551 json configFile = i2cWriteBytesFile;
1552 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["masks"] = 1;
1553 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1554 "1 is not of type u'array'");
1555 }
1556 // Invalid: test i2c_write_bytes with property register more than 2 hex
1557 // digits.
1558 {
1559 json configFile = i2cWriteBytesFile;
1560 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["register"] =
1561 "0x820";
1562 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1563 "u'0x820' does not match u'^0x[0-9A-Fa-f]{2}$'");
1564 }
1565 // Invalid: test i2c_write_bytes with property values more than 2 hex
1566 // digits.
1567 {
1568 json configFile = i2cWriteBytesFile;
1569 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["values"][0] =
1570 "0x820";
1571 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1572 "u'0x820' does not match u'^0x[0-9A-Fa-f]{2}$'");
1573 }
1574 // Invalid: test i2c_write_bytes with property masks more than 2 hex
1575 // digits.
1576 {
1577 json configFile = i2cWriteBytesFile;
1578 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["masks"][0] =
1579 "0x820";
1580 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1581 "u'0x820' does not match u'^0x[0-9A-Fa-f]{2}$'");
1582 }
1583 // Invalid: test i2c_write_bytes with property register less than 2 hex
1584 // digits.
1585 {
1586 json configFile = i2cWriteBytesFile;
1587 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["register"] =
1588 "0x8";
1589 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1590 "u'0x8' does not match u'^0x[0-9A-Fa-f]{2}$'");
1591 }
1592 // Invalid: test i2c_write_bytes with property values less than 2 hex
1593 // digits.
1594 {
1595 json configFile = i2cWriteBytesFile;
1596 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["values"][0] =
1597 "0x8";
1598 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1599 "u'0x8' does not match u'^0x[0-9A-Fa-f]{2}$'");
1600 }
1601 // Invalid: test i2c_write_bytes with property masks less than 2 hex
1602 // digits.
1603 {
1604 json configFile = i2cWriteBytesFile;
1605 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["masks"][0] =
1606 "0x8";
1607 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1608 "u'0x8' does not match u'^0x[0-9A-Fa-f]{2}$'");
1609 }
1610 // Invalid: test i2c_write_bytes with property register no leading prefix.
1611 {
1612 json configFile = i2cWriteBytesFile;
1613 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["register"] =
1614 "82";
1615 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1616 "u'82' does not match u'^0x[0-9A-Fa-f]{2}$'");
1617 }
1618 // Invalid: test i2c_write_bytes with property values no leading prefix.
1619 {
1620 json configFile = i2cWriteBytesFile;
1621 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["values"][0] =
1622 "82";
1623 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1624 "u'82' does not match u'^0x[0-9A-Fa-f]{2}$'");
1625 }
1626 // Invalid: test i2c_write_bytes with property masks no leading prefix.
1627 {
1628 json configFile = i2cWriteBytesFile;
1629 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["masks"][0] =
1630 "82";
1631 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1632 "u'82' does not match u'^0x[0-9A-Fa-f]{2}$'");
1633 }
1634 // Invalid: test i2c_write_bytes with property register invalid hex digit.
1635 {
1636 json configFile = i2cWriteBytesFile;
1637 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["register"] =
1638 "0xG1";
1639 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1640 "u'0xG1' does not match u'^0x[0-9A-Fa-f]{2}$'");
1641 }
1642 // Invalid: test i2c_write_bytes with property values invalid hex digit.
1643 {
1644 json configFile = i2cWriteBytesFile;
1645 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["values"][0] =
1646 "0xG1";
1647 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1648 "u'0xG1' does not match u'^0x[0-9A-Fa-f]{2}$'");
1649 }
1650 // Invalid: test i2c_write_bytes with property masks invalid hex digit.
1651 {
1652 json configFile = i2cWriteBytesFile;
1653 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["masks"][0] =
1654 "0xG1";
1655 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1656 "u'0xG1' does not match u'^0x[0-9A-Fa-f]{2}$'");
1657 }
1658}
Bob Kingead0b052020-01-21 11:29:03 +08001659TEST(ValidateRegulatorsConfigTest, If)
1660{
1661 json ifFile = validConfigFile;
Bob King2d27dcf2020-02-11 15:00:50 +08001662 ifFile["rules"][2]["actions"][0]["if"]["condition"]["run_rule"] =
1663 "set_voltage_rule";
1664 ifFile["rules"][2]["actions"][0]["if"]["then"][0]["run_rule"] =
1665 "read_sensors_rule";
1666 ifFile["rules"][2]["actions"][0]["if"]["else"][0]["run_rule"] =
1667 "read_sensors_rule";
1668 ifFile["rules"][2]["id"] = "rule_if";
Bob Kingead0b052020-01-21 11:29:03 +08001669 // Valid: test if.
1670 {
1671 json configFile = ifFile;
1672 EXPECT_JSON_VALID(configFile);
1673 }
1674 // Valid: test if with required properties.
1675 {
1676 json configFile = ifFile;
Bob King2d27dcf2020-02-11 15:00:50 +08001677 configFile["rules"][2]["actions"][0]["if"].erase("else");
Bob Kingead0b052020-01-21 11:29:03 +08001678 EXPECT_JSON_VALID(configFile);
1679 }
1680 // Invalid: test if with no property condition.
1681 {
1682 json configFile = ifFile;
Bob King2d27dcf2020-02-11 15:00:50 +08001683 configFile["rules"][2]["actions"][0]["if"].erase("condition");
Bob Kingead0b052020-01-21 11:29:03 +08001684 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1685 "u'condition' is a required property");
1686 }
1687 // Invalid: test if with no property then.
1688 {
1689 json configFile = ifFile;
Bob King2d27dcf2020-02-11 15:00:50 +08001690 configFile["rules"][2]["actions"][0]["if"].erase("then");
Bob Kingead0b052020-01-21 11:29:03 +08001691 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1692 "u'then' is a required property");
1693 }
1694 // Invalid: test if with property then empty array.
1695 {
1696 json configFile = ifFile;
Bob King2d27dcf2020-02-11 15:00:50 +08001697 configFile["rules"][2]["actions"][0]["if"]["then"] = json::array();
Bob Kingead0b052020-01-21 11:29:03 +08001698 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1699 "[] is too short");
1700 }
1701 // Invalid: test if with property else empty array.
1702 {
1703 json configFile = ifFile;
Bob King2d27dcf2020-02-11 15:00:50 +08001704 configFile["rules"][2]["actions"][0]["if"]["else"] = json::array();
Bob Kingead0b052020-01-21 11:29:03 +08001705 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1706 "[] is too short");
1707 }
1708 // Invalid: test if with property condition wrong type.
1709 {
1710 json configFile = ifFile;
Bob King2d27dcf2020-02-11 15:00:50 +08001711 configFile["rules"][2]["actions"][0]["if"]["condition"] = 1;
Bob Kingead0b052020-01-21 11:29:03 +08001712 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1713 "1 is not of type u'object'");
1714 }
1715 // Invalid: test if with property then wrong type.
1716 {
1717 json configFile = ifFile;
Bob King2d27dcf2020-02-11 15:00:50 +08001718 configFile["rules"][2]["actions"][0]["if"]["then"] = 1;
Bob Kingead0b052020-01-21 11:29:03 +08001719 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1720 "1 is not of type u'array'");
1721 }
1722 // Invalid: test if with property else wrong type.
1723 {
1724 json configFile = ifFile;
Bob King2d27dcf2020-02-11 15:00:50 +08001725 configFile["rules"][2]["actions"][0]["if"]["else"] = 1;
Bob Kingead0b052020-01-21 11:29:03 +08001726 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1727 "1 is not of type u'array'");
1728 }
1729}
Bob Kingbfe9fe72020-01-21 11:29:57 +08001730TEST(ValidateRegulatorsConfigTest, Not)
1731{
1732 json notFile = validConfigFile;
1733 notFile["rules"][0]["actions"][1]["not"]["i2c_compare_byte"]["register"] =
1734 "0xA0";
1735 notFile["rules"][0]["actions"][1]["not"]["i2c_compare_byte"]["value"] =
1736 "0xFF";
1737 // Valid: test not.
1738 {
1739 json configFile = notFile;
1740 EXPECT_JSON_VALID(configFile);
1741 }
1742 // Invalid: test not with wrong type.
1743 {
1744 json configFile = notFile;
1745 configFile["rules"][0]["actions"][1]["not"] = 1;
1746 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1747 "1 is not of type u'object'");
1748 }
1749}
Bob Kingcfc29d02020-01-21 11:30:50 +08001750TEST(ValidateRegulatorsConfigTest, Or)
1751{
1752 json orFile = validConfigFile;
1753 orFile["rules"][0]["actions"][1]["or"][0]["i2c_compare_byte"]["register"] =
1754 "0xA0";
1755 orFile["rules"][0]["actions"][1]["or"][0]["i2c_compare_byte"]["value"] =
1756 "0x00";
1757 orFile["rules"][0]["actions"][1]["or"][1]["i2c_compare_byte"]["register"] =
1758 "0xA1";
1759 orFile["rules"][0]["actions"][1]["or"][1]["i2c_compare_byte"]["value"] =
1760 "0x00";
1761 // Valid: test or.
1762 {
1763 json configFile = orFile;
1764 EXPECT_JSON_VALID(configFile);
1765 }
1766 // Invalid: test or with empty array.
1767 {
1768 json configFile = orFile;
1769 configFile["rules"][0]["actions"][1]["or"] = json::array();
1770 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1771 "[] is too short");
1772 }
1773 // Invalid: test or with wrong type.
1774 {
1775 json configFile = orFile;
1776 configFile["rules"][0]["actions"][1]["or"] = 1;
1777 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1778 "1 is not of type u'array'");
1779 }
1780}
Bob Kingd6618092020-01-21 11:31:46 +08001781TEST(ValidateRegulatorsConfigTest, PmbusReadSensor)
1782{
1783 json pmbusReadSensorFile = validConfigFile;
1784 pmbusReadSensorFile["rules"][0]["actions"][1]["pmbus_read_sensor"]["type"] =
1785 "vout";
1786 pmbusReadSensorFile["rules"][0]["actions"][1]["pmbus_read_sensor"]
1787 ["command"] = "0x8B";
1788 pmbusReadSensorFile["rules"][0]["actions"][1]["pmbus_read_sensor"]
1789 ["format"] = "linear_16";
1790 pmbusReadSensorFile["rules"][0]["actions"][1]["pmbus_read_sensor"]
1791 ["exponent"] = -8;
1792 // Valid: test pmbus_read_sensor.
1793 {
1794 json configFile = pmbusReadSensorFile;
1795 EXPECT_JSON_VALID(configFile);
1796 }
1797 // Valid: test pmbus_read_sensor with required properties.
1798 {
1799 json configFile = pmbusReadSensorFile;
1800 configFile["rules"][0]["actions"][1]["pmbus_read_sensor"].erase(
1801 "exponent");
1802 EXPECT_JSON_VALID(configFile);
1803 }
1804 // Invalid: test pmbus_read_sensor with no type.
1805 {
1806 json configFile = pmbusReadSensorFile;
1807 configFile["rules"][0]["actions"][1]["pmbus_read_sensor"].erase("type");
1808 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1809 "u'type' is a required property");
1810 }
1811 // Invalid: test pmbus_read_sensor with no command.
1812 {
1813 json configFile = pmbusReadSensorFile;
1814 configFile["rules"][0]["actions"][1]["pmbus_read_sensor"].erase(
1815 "command");
1816 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1817 "u'command' is a required property");
1818 }
1819 // Invalid: test pmbus_read_sensor with no format.
1820 {
1821 json configFile = pmbusReadSensorFile;
1822 configFile["rules"][0]["actions"][1]["pmbus_read_sensor"].erase(
1823 "format");
1824 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1825 "u'format' is a required property");
1826 }
1827 // Invalid: test pmbus_read_sensor with property type wrong type.
1828 {
1829 json configFile = pmbusReadSensorFile;
1830 configFile["rules"][0]["actions"][1]["pmbus_read_sensor"]["type"] =
1831 true;
1832 EXPECT_JSON_INVALID(
1833 configFile, "Validation failed.",
1834 "True is not one of [u'iout', u'iout_peak', u'iout_valley', "
1835 "u'pout', u'temperature', u'temperature_peak', u'vout', "
1836 "u'vout_peak', u'vout_valley']");
1837 }
1838 // Invalid: test pmbus_read_sensor with property command wrong type.
1839 {
1840 json configFile = pmbusReadSensorFile;
1841 configFile["rules"][0]["actions"][1]["pmbus_read_sensor"]["command"] =
1842 true;
1843 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1844 "True is not of type u'string'");
1845 }
1846 // Invalid: test pmbus_read_sensor with property format wrong type.
1847 {
1848 json configFile = pmbusReadSensorFile;
1849 configFile["rules"][0]["actions"][1]["pmbus_read_sensor"]["format"] =
1850 true;
1851 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1852 "True is not one of [u'linear_11', u'linear_16']");
1853 }
1854 // Invalid: test pmbus_read_sensor with property exponent wrong type.
1855 {
1856 json configFile = pmbusReadSensorFile;
1857 configFile["rules"][0]["actions"][1]["pmbus_read_sensor"]["exponent"] =
1858 true;
1859 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1860 "True is not of type u'integer'");
1861 }
1862 // Invalid: test pmbus_read_sensor with property type wrong format.
1863 {
1864 json configFile = pmbusReadSensorFile;
1865 configFile["rules"][0]["actions"][1]["pmbus_read_sensor"]["type"] =
1866 "foo";
1867 EXPECT_JSON_INVALID(
1868 configFile, "Validation failed.",
1869 "u'foo' is not one of [u'iout', u'iout_peak', u'iout_valley', "
1870 "u'pout', u'temperature', u'temperature_peak', u'vout', "
1871 "u'vout_peak', u'vout_valley']");
1872 }
1873 // Invalid: test pmbus_read_sensor with property command wrong format.
1874 {
1875 json configFile = pmbusReadSensorFile;
1876 configFile["rules"][0]["actions"][1]["pmbus_read_sensor"]["command"] =
1877 "0x8B0";
1878 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1879 "u'0x8B0' does not match u'^0x[0-9a-fA-F]{2}$'");
1880 }
1881 // Invalid: test pmbus_read_sensor with property format wrong format.
1882 {
1883 json configFile = pmbusReadSensorFile;
1884 configFile["rules"][0]["actions"][1]["pmbus_read_sensor"]["format"] =
1885 "foo";
1886 EXPECT_JSON_INVALID(
1887 configFile, "Validation failed.",
1888 "u'foo' is not one of [u'linear_11', u'linear_16']");
1889 }
1890}
Bob King02179c62020-01-21 11:32:36 +08001891TEST(ValidateRegulatorsConfigTest, PmbusWriteVoutCommand)
1892{
1893 json pmbusWriteVoutCommandFile = validConfigFile;
1894 pmbusWriteVoutCommandFile["rules"][0]["actions"][1]
1895 ["pmbus_write_vout_command"]["volts"] = 1.03;
1896 pmbusWriteVoutCommandFile["rules"][0]["actions"][1]
1897 ["pmbus_write_vout_command"]["format"] = "linear";
1898 pmbusWriteVoutCommandFile["rules"][0]["actions"][1]
1899 ["pmbus_write_vout_command"]["exponent"] = -8;
1900 pmbusWriteVoutCommandFile["rules"][0]["actions"][1]
1901 ["pmbus_write_vout_command"]["is_verified"] = true;
1902 // Valid: test pmbus_write_vout_command.
1903 {
1904 json configFile = pmbusWriteVoutCommandFile;
1905 EXPECT_JSON_VALID(configFile);
1906 }
1907 // Valid: test pmbus_write_vout_command with required properties.
1908 {
1909 json configFile = pmbusWriteVoutCommandFile;
1910 configFile["rules"][0]["actions"][1]["pmbus_write_vout_command"].erase(
1911 "volts");
1912 configFile["rules"][0]["actions"][1]["pmbus_write_vout_command"].erase(
1913 "exponent");
1914 configFile["rules"][0]["actions"][1]["pmbus_write_vout_command"].erase(
1915 "is_verified");
1916 EXPECT_JSON_VALID(configFile);
1917 }
1918 // Invalid: test pmbus_write_vout_command with no format.
1919 {
1920 json configFile = pmbusWriteVoutCommandFile;
1921 configFile["rules"][0]["actions"][1]["pmbus_write_vout_command"].erase(
1922 "format");
1923 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1924 "u'format' is a required property");
1925 }
1926 // Invalid: test pmbus_write_vout_command with property volts wrong type.
1927 {
1928 json configFile = pmbusWriteVoutCommandFile;
1929 configFile["rules"][0]["actions"][1]["pmbus_write_vout_command"]
1930 ["volts"] = true;
1931 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1932 "True is not of type u'number'");
1933 }
1934 // Invalid: test pmbus_write_vout_command with property format wrong type.
1935 {
1936 json configFile = pmbusWriteVoutCommandFile;
1937 configFile["rules"][0]["actions"][1]["pmbus_write_vout_command"]
1938 ["format"] = true;
1939 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1940 "True is not one of [u'linear']");
1941 }
1942 // Invalid: test pmbus_write_vout_command with property exponent wrong type.
1943 {
1944 json configFile = pmbusWriteVoutCommandFile;
1945 configFile["rules"][0]["actions"][1]["pmbus_write_vout_command"]
1946 ["exponent"] = 1.3;
1947 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1948 "1.3 is not of type u'integer'");
1949 }
1950 // Invalid: test pmbus_write_vout_command with property is_verified wrong
1951 // type.
1952 {
1953 json configFile = pmbusWriteVoutCommandFile;
1954 configFile["rules"][0]["actions"][1]["pmbus_write_vout_command"]
1955 ["is_verified"] = 1;
1956 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1957 "1 is not of type u'boolean'");
1958 }
1959 // Invalid: test pmbus_write_vout_command with property format wrong format.
1960 {
1961 json configFile = pmbusWriteVoutCommandFile;
1962 configFile["rules"][0]["actions"][1]["pmbus_write_vout_command"]
1963 ["format"] = "foo";
1964 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1965 "u'foo' is not one of [u'linear']");
1966 }
1967}
Bob King99d8fa12020-01-31 11:23:40 +08001968TEST(ValidateRegulatorsConfigTest, PresenceDetection)
1969{
1970 json presenceDetectionFile = validConfigFile;
1971 presenceDetectionFile
1972 ["chassis"][0]["devices"][0]["presence_detection"]["comments"][0] =
1973 "Regulator is only present on the FooBar backplane";
1974 presenceDetectionFile["chassis"][0]["devices"][0]["presence_detection"]
Bob Kingf4ff1162020-02-11 15:13:38 +08001975 ["rule_id"] = "set_voltage_rule";
Bob King99d8fa12020-01-31 11:23:40 +08001976 // Valid: test presence_detection with only property rule_id.
1977 {
1978 json configFile = presenceDetectionFile;
1979 EXPECT_JSON_VALID(configFile);
1980 }
1981 // Valid: test presence_detection with only property actions.
1982 {
1983 json configFile = presenceDetectionFile;
1984 configFile["chassis"][0]["devices"][0]["presence_detection"].erase(
1985 "rule_id");
1986 configFile["chassis"][0]["devices"][0]["presence_detection"]["actions"]
1987 [0]["compare_presence"]["fru"] =
1988 "/system/chassis/motherboard/cpu3";
1989 configFile["chassis"][0]["devices"][0]["presence_detection"]["actions"]
1990 [0]["compare_presence"]["value"] = true;
1991 configFile["chassis"][0]["devices"][0]["presence_detection"].erase(
1992 "comments");
1993 EXPECT_JSON_VALID(configFile);
1994 }
1995 // Invalid: test presence_detection with both property rule_id and actions.
1996 {
1997 json configFile = presenceDetectionFile;
1998 configFile["chassis"][0]["devices"][0]["presence_detection"]["actions"]
1999 [0]["compare_presence"]["fru"] =
2000 "/system/chassis/motherboard/cpu3";
2001 configFile["chassis"][0]["devices"][0]["presence_detection"]["actions"]
2002 [0]["compare_presence"]["value"] = true;
2003 EXPECT_JSON_INVALID(
2004 configFile, "Validation failed.",
2005 "{u'comments': [u'Regulator is only present on the FooBar "
2006 "backplane'], u'actions': [{u'compare_presence': {u'value': True, "
2007 "u'fru': u'/system/chassis/motherboard/cpu3'}}], u'rule_id': "
Bob Kingf4ff1162020-02-11 15:13:38 +08002008 "u'set_voltage_rule'} is valid under each of "
Bob King99d8fa12020-01-31 11:23:40 +08002009 "{u'required': [u'actions']}, {u'required': [u'rule_id']}");
2010 }
2011 // Invalid: test presence_detection with no rule_id and actions.
2012 {
2013 json configFile = presenceDetectionFile;
2014 configFile["chassis"][0]["devices"][0]["presence_detection"].erase(
2015 "rule_id");
2016 EXPECT_JSON_INVALID(configFile, "Validation failed.",
2017 "u'rule_id' is a required property");
2018 }
2019 // Invalid: test presence_detection with property comments wrong type.
2020 {
2021 json configFile = presenceDetectionFile;
2022 configFile["chassis"][0]["devices"][0]["presence_detection"]
2023 ["comments"] = true;
2024 EXPECT_JSON_INVALID(configFile, "Validation failed.",
2025 "True is not of type u'array'");
2026 }
2027 // Invalid: test presence_detection with property rule_id wrong type.
2028 {
2029 json configFile = presenceDetectionFile;
2030 configFile["chassis"][0]["devices"][0]["presence_detection"]
2031 ["rule_id"] = true;
2032 EXPECT_JSON_INVALID(configFile, "Validation failed.",
2033 "True is not of type u'string'");
2034 }
2035 // Invalid: test presence_detection with property actions wrong type.
2036 {
2037 json configFile = presenceDetectionFile;
2038 configFile["chassis"][0]["devices"][0]["presence_detection"].erase(
2039 "rule_id");
2040 configFile["chassis"][0]["devices"][0]["presence_detection"]
2041 ["actions"] = true;
2042 EXPECT_JSON_INVALID(configFile, "Validation failed.",
2043 "True is not of type u'array'");
2044 }
2045 // Invalid: test presence_detection with property rule_id wrong format.
2046 {
2047 json configFile = presenceDetectionFile;
2048 configFile["chassis"][0]["devices"][0]["presence_detection"]
2049 ["rule_id"] = "id@";
2050 EXPECT_JSON_INVALID(configFile, "Validation failed.",
2051 "u'id@' does not match u'^[A-Za-z0-9_]+$'");
2052 }
2053 // Invalid: test presence_detection with property comments empty array.
2054 {
2055 json configFile = presenceDetectionFile;
2056 configFile["chassis"][0]["devices"][0]["presence_detection"]
2057 ["comments"] = json::array();
2058 EXPECT_JSON_INVALID(configFile, "Validation failed.",
2059 "[] is too short");
2060 }
2061 // Invalid: test presence_detection with property actions empty array.
2062 {
2063 json configFile = presenceDetectionFile;
2064 configFile["chassis"][0]["devices"][0]["presence_detection"].erase(
2065 "rule_id");
2066 configFile["chassis"][0]["devices"][0]["presence_detection"]
2067 ["actions"] = json::array();
2068 EXPECT_JSON_INVALID(configFile, "Validation failed.",
2069 "[] is too short");
2070 }
2071}
Bob Kinge9260b52020-01-21 11:46:13 +08002072TEST(ValidateRegulatorsConfigTest, Rail)
2073{
2074 // Valid: test rail.
2075 {
2076 json configFile = validConfigFile;
2077 EXPECT_JSON_VALID(configFile);
2078 }
2079 // Valid: test rail with required properties.
2080 {
2081 json configFile = validConfigFile;
2082 configFile["chassis"][0]["devices"][0]["rails"][0].erase("comments");
2083 configFile["chassis"][0]["devices"][0]["rails"][0].erase(
2084 "configuration");
2085 configFile["chassis"][0]["devices"][0]["rails"][0].erase(
2086 "sensor_monitoring");
2087 EXPECT_JSON_VALID(configFile);
2088 }
2089 // Invalid: test rail with no id.
2090 {
2091 json configFile = validConfigFile;
2092 configFile["chassis"][0]["devices"][0]["rails"][0].erase("id");
2093 EXPECT_JSON_INVALID(configFile, "Validation failed.",
2094 "u'id' is a required property");
2095 }
2096 // Invalid: test rail with comments wrong type.
2097 {
2098 json configFile = validConfigFile;
2099 configFile["chassis"][0]["devices"][0]["rails"][0]["comments"] = true;
2100 EXPECT_JSON_INVALID(configFile, "Validation failed.",
2101 "True is not of type u'array'");
2102 }
2103 // Invalid: test rail with id wrong type.
2104 {
2105 json configFile = validConfigFile;
2106 configFile["chassis"][0]["devices"][0]["rails"][0]["id"] = true;
2107 EXPECT_JSON_INVALID(configFile, "Validation failed.",
2108 "True is not of type u'string'");
2109 }
2110 // Invalid: test rail with configuration wrong type.
2111 {
2112 json configFile = validConfigFile;
2113 configFile["chassis"][0]["devices"][0]["rails"][0]["configuration"] =
2114 true;
2115 EXPECT_JSON_INVALID(configFile, "Validation failed.",
2116 "True is not of type u'object'");
2117 }
2118 // Invalid: test rail with sensor_monitoring wrong type.
2119 {
2120 json configFile = validConfigFile;
2121 configFile["chassis"][0]["devices"][0]["rails"][0]
2122 ["sensor_monitoring"] = true;
2123 EXPECT_JSON_INVALID(configFile, "Validation failed.",
2124 "True is not of type u'object'");
2125 }
2126 // Invalid: test rail with comments empty array.
2127 {
2128 json configFile = validConfigFile;
2129 configFile["chassis"][0]["devices"][0]["rails"][0]["comments"] =
2130 json::array();
2131 EXPECT_JSON_INVALID(configFile, "Validation failed.",
2132 "[] is too short");
2133 }
2134 // Invalid: test rail with id wrong format.
2135 {
2136 json configFile = validConfigFile;
2137 configFile["chassis"][0]["devices"][0]["rails"][0]["id"] = "id~";
2138 EXPECT_JSON_INVALID(configFile, "Validation failed.",
2139 "u'id~' does not match u'^[A-Za-z0-9_]+$'");
2140 }
2141}
Bob King64df7da2020-01-31 12:04:12 +08002142TEST(ValidateRegulatorsConfigTest, Rule)
2143{
2144 // valid test comments property, id property,
2145 // action property specified.
2146 {
2147 json configFile = validConfigFile;
2148 EXPECT_JSON_VALID(configFile);
2149 }
2150
2151 // valid test rule with no comments
2152 {
2153 json configFile = validConfigFile;
2154 configFile["rules"][0].erase("comments");
2155 EXPECT_JSON_VALID(configFile);
2156 }
2157
2158 // invalid test comments property has invalid value type
2159 {
2160 json configFile = validConfigFile;
2161 configFile["rules"][0]["comments"] = {1};
2162 EXPECT_JSON_INVALID(configFile, "Validation failed.",
2163 "1 is not of type u'string'");
2164 }
2165
2166 // invalid test rule with no ID
2167 {
2168 json configFile = validConfigFile;
2169 configFile["rules"][0].erase("id");
2170 EXPECT_JSON_INVALID(configFile, "Validation failed.",
2171 "u'id' is a required property");
2172 }
2173
2174 // invalid test id property has invalid value type (not string)
2175 {
2176 json configFile = validConfigFile;
2177 configFile["rules"][0]["id"] = true;
2178 EXPECT_JSON_INVALID(configFile, "Validation failed.",
2179 "True is not of type u'string'");
2180 }
2181
2182 // invalid test id property has invalid value
2183 {
2184 json configFile = validConfigFile;
2185 configFile["rules"][0]["id"] = "foo%";
2186 EXPECT_JSON_INVALID(configFile, "Validation failed.",
2187 "u'foo%' does not match u'^[A-Za-z0-9_]+$'");
2188 }
2189
2190 // invalid test rule with no actions property
2191 {
2192 json configFile = validConfigFile;
2193 configFile["rules"][0].erase("actions");
2194 EXPECT_JSON_INVALID(configFile, "Validation failed.",
2195 "u'actions' is a required property");
2196 }
2197
2198 // valid test rule with multiple actions
2199 {
2200 json configFile = validConfigFile;
Bob King63d795f2020-02-11 15:22:09 +08002201 configFile["rules"][0]["actions"][1]["run_rule"] = "read_sensors_rule";
Bob King64df7da2020-01-31 12:04:12 +08002202 EXPECT_JSON_VALID(configFile);
2203 }
2204
2205 // invalid test actions property has invalid value type (not an array)
2206 {
2207 json configFile = validConfigFile;
2208 configFile["rules"][0]["actions"] = 1;
2209 EXPECT_JSON_INVALID(configFile, "Validation failed.",
2210 "1 is not of type u'array'");
2211 }
2212
2213 // invalid test actions property has invalid value of action
2214 {
2215 json configFile = validConfigFile;
2216 configFile["rules"][0]["actions"][0] = "foo";
2217 EXPECT_JSON_INVALID(configFile, "Validation failed.",
2218 "u'foo' is not of type u'object'");
2219 }
2220
2221 // invalid test actions property has empty array
2222 {
2223 json configFile = validConfigFile;
2224 configFile["rules"][0]["actions"] = json::array();
2225 EXPECT_JSON_INVALID(configFile, "Validation failed.",
2226 "[] is too short");
2227 }
2228}
Bob Kinge86c2e52020-01-21 11:33:32 +08002229TEST(ValidateRegulatorsConfigTest, RunRule)
2230{
2231 json runRuleFile = validConfigFile;
Bob King7d3a9f12020-02-11 15:34:52 +08002232 runRuleFile["rules"][0]["actions"][1]["run_rule"] = "read_sensors_rule";
Bob Kinge86c2e52020-01-21 11:33:32 +08002233 // Valid: test run_rule.
2234 {
2235 json configFile = runRuleFile;
2236 EXPECT_JSON_VALID(configFile);
2237 }
2238 // Invalid: test run_rule wrong type.
2239 {
2240 json configFile = runRuleFile;
2241 configFile["rules"][0]["actions"][1]["run_rule"] = true;
2242 EXPECT_JSON_INVALID(configFile, "Validation failed.",
2243 "True is not of type u'string'");
2244 }
2245 // Invalid: test run_rule wrong format.
2246 {
2247 json configFile = runRuleFile;
2248 configFile["rules"][0]["actions"][1]["run_rule"] = "set_voltage_rule%";
2249 EXPECT_JSON_INVALID(
2250 configFile, "Validation failed.",
2251 "u'set_voltage_rule%' does not match u'^[A-Za-z0-9_]+$'");
2252 }
2253}
Bob Kingfcc2a2f2020-01-31 11:29:45 +08002254TEST(ValidateRegulatorsConfigTest, SensorMonitoring)
2255{
2256 // Valid: test rails sensor_monitoring with only property rule id.
2257 {
2258 json configFile = validConfigFile;
2259 EXPECT_JSON_VALID(configFile);
2260 }
2261 // Valid: test rails sensor_monitoring with only property actions.
2262 {
2263 json configFile = validConfigFile;
2264 configFile["chassis"][0]["devices"][0]["rails"][0]["sensor_monitoring"]
2265 .erase("rule_id");
2266 configFile["chassis"][0]["devices"][0]["rails"][0]["sensor_monitoring"]
2267 ["actions"][0]["compare_presence"]["fru"] =
2268 "/system/chassis/motherboard/cpu3";
2269 configFile["chassis"][0]["devices"][0]["rails"][0]["sensor_monitoring"]
2270 ["actions"][0]["compare_presence"]["value"] = true;
2271 configFile["chassis"][0]["devices"][0]["rails"][0]["sensor_monitoring"]
2272 ["comments"][0] = "comments";
2273 EXPECT_JSON_VALID(configFile);
2274 }
2275 // Invalid: test rails sensor_monitoring with both property rule_id and
2276 // actions.
2277 {
2278 json configFile = validConfigFile;
2279 configFile["chassis"][0]["devices"][0]["rails"][0]["sensor_monitoring"]
2280 ["actions"][0]["compare_presence"]["fru"] =
2281 "/system/chassis/motherboard/cpu3";
2282 configFile["chassis"][0]["devices"][0]["rails"][0]["sensor_monitoring"]
2283 ["actions"][0]["compare_presence"]["value"] = true;
2284 EXPECT_JSON_INVALID(
2285 configFile, "Validation failed.",
2286 "{u'rule_id': u'read_sensors_rule', u'actions': "
2287 "[{u'compare_presence': {u'value': True, u'fru': "
2288 "u'/system/chassis/motherboard/cpu3'}}]} is valid under each of "
2289 "{u'required': [u'actions']}, {u'required': [u'rule_id']}");
2290 }
2291 // Invalid: test rails sensor_monitoring with no rule_id and actions.
2292 {
2293 json configFile = validConfigFile;
2294 configFile["chassis"][0]["devices"][0]["rails"][0]["sensor_monitoring"]
2295 .erase("rule_id");
2296 EXPECT_JSON_INVALID(configFile, "Validation failed.",
2297 "u'rule_id' is a required property");
2298 }
2299 // Invalid: test rails sensor_monitoring with property comments wrong type.
2300 {
2301 json configFile = validConfigFile;
2302 configFile["chassis"][0]["devices"][0]["rails"][0]["sensor_monitoring"]
2303 ["comments"] = true;
2304 EXPECT_JSON_INVALID(configFile, "Validation failed.",
2305 "True is not of type u'array'");
2306 }
2307 // Invalid: test rails sensor_monitoring with property rule_id wrong type.
2308 {
2309 json configFile = validConfigFile;
2310 configFile["chassis"][0]["devices"][0]["rails"][0]["sensor_monitoring"]
2311 ["rule_id"] = true;
2312 EXPECT_JSON_INVALID(configFile, "Validation failed.",
2313 "True is not of type u'string'");
2314 }
2315 // Invalid: test rails sensor_monitoring with property actions wrong type.
2316 {
2317 json configFile = validConfigFile;
2318 configFile["chassis"][0]["devices"][0]["rails"][0]["sensor_monitoring"]
2319 .erase("rule_id");
2320 configFile["chassis"][0]["devices"][0]["rails"][0]["sensor_monitoring"]
2321 ["actions"] = true;
2322 EXPECT_JSON_INVALID(configFile, "Validation failed.",
2323 "True is not of type u'array'");
2324 }
2325 // Invalid: test rails sensor_monitoring with property rule_id wrong format.
2326 {
2327 json configFile = validConfigFile;
2328 configFile["chassis"][0]["devices"][0]["rails"][0]["sensor_monitoring"]
2329 ["rule_id"] = "id@";
2330 EXPECT_JSON_INVALID(configFile, "Validation failed.",
2331 "u'id@' does not match u'^[A-Za-z0-9_]+$'");
2332 }
2333 // Invalid: test rails sensor_monitoring with property comments empty array.
2334 {
2335 json configFile = validConfigFile;
2336 configFile["chassis"][0]["devices"][0]["rails"][0]["sensor_monitoring"]
2337 ["comments"] = json::array();
2338 EXPECT_JSON_INVALID(configFile, "Validation failed.",
2339 "[] is too short");
2340 }
2341 // Invalid: test rails sensor_monitoring with property actions empty array.
2342 {
2343 json configFile = validConfigFile;
2344 configFile["chassis"][0]["devices"][0]["rails"][0]["sensor_monitoring"]
2345 .erase("rule_id");
2346 configFile["chassis"][0]["devices"][0]["rails"][0]["sensor_monitoring"]
2347 ["actions"] = json::array();
2348 EXPECT_JSON_INVALID(configFile, "Validation failed.",
2349 "[] is too short");
2350 }
2351}
Bob King68230aa2020-01-21 11:34:33 +08002352TEST(ValidateRegulatorsConfigTest, SetDevice)
2353{
2354 json setDeviceFile = validConfigFile;
Bob King7d3a9f12020-02-11 15:34:52 +08002355 setDeviceFile["rules"][0]["actions"][1]["set_device"] = "vdd_regulator";
Bob King68230aa2020-01-21 11:34:33 +08002356 // Valid: test set_device.
2357 {
2358 json configFile = setDeviceFile;
2359 EXPECT_JSON_VALID(configFile);
2360 }
2361 // Invalid: test set_device wrong type.
2362 {
2363 json configFile = setDeviceFile;
2364 configFile["rules"][0]["actions"][1]["set_device"] = true;
2365 EXPECT_JSON_INVALID(configFile, "Validation failed.",
2366 "True is not of type u'string'");
2367 }
2368 // Invalid: test set_device wrong format.
2369 {
2370 json configFile = setDeviceFile;
2371 configFile["rules"][0]["actions"][1]["set_device"] = "io_expander2%";
2372 EXPECT_JSON_INVALID(
2373 configFile, "Validation failed.",
2374 "u'io_expander2%' does not match u'^[A-Za-z0-9_]+$'");
2375 }
2376}
Bob King3643cc02020-01-31 11:32:56 +08002377TEST(ValidateRegulatorsConfigTest, DuplicateRuleID)
2378{
2379 // Invalid: test duplicate ID in rule.
2380 {
2381 json configFile = validConfigFile;
Bob Kingb3e48bc2020-02-18 09:59:09 +08002382 configFile["rules"][2]["id"] = "set_voltage_rule";
2383 configFile["rules"][2]["actions"][0]["pmbus_write_vout_command"]
Bob King3643cc02020-01-31 11:32:56 +08002384 ["format"] = "linear";
2385 EXPECT_JSON_INVALID(configFile, "Error: Duplicate rule ID.", "");
2386 }
2387}
2388TEST(ValidateRegulatorsConfigTest, DuplicateChassisNumber)
2389{
2390 // Invalid: test duplicate number in chassis.
2391 {
2392 json configFile = validConfigFile;
2393 configFile["chassis"][1]["number"] = 1;
2394 EXPECT_JSON_INVALID(configFile, "Error: Duplicate chassis number.", "");
2395 }
2396}
2397TEST(ValidateRegulatorsConfigTest, DuplicateDeviceID)
2398{
2399 // Invalid: test duplicate ID in device.
2400 {
2401 json configFile = validConfigFile;
2402 configFile["chassis"][0]["devices"][1]["id"] = "vdd_regulator";
2403 configFile["chassis"][0]["devices"][1]["is_regulator"] = true;
2404 configFile["chassis"][0]["devices"][1]["fru"] =
2405 "/system/chassis/motherboard/regulator1";
2406 configFile["chassis"][0]["devices"][1]["i2c_interface"]["bus"] = 2;
2407 configFile["chassis"][0]["devices"][1]["i2c_interface"]["address"] =
2408 "0x71";
2409 EXPECT_JSON_INVALID(configFile, "Error: Duplicate device ID.", "");
2410 }
2411}
2412TEST(ValidateRegulatorsConfigTest, DuplicateRailID)
2413{
2414 // Invalid: test duplicate ID in rail.
2415 {
2416 json configFile = validConfigFile;
2417 configFile["chassis"][0]["devices"][0]["rails"][1]["id"] = "vdd";
2418 EXPECT_JSON_INVALID(configFile, "Error: Duplicate rail ID.", "");
2419 }
2420}
2421TEST(ValidateRegulatorsConfigTest, InfiniteLoops)
2422{
2423 // Invalid: test run_rule with infinite loop (rules run each other).
2424 {
2425 json configFile = validConfigFile;
2426 configFile["rules"][2]["actions"][0]["run_rule"] = "set_voltage_rule2";
2427 configFile["rules"][2]["id"] = "set_voltage_rule1";
2428 configFile["rules"][3]["actions"][0]["run_rule"] = "set_voltage_rule1";
2429 configFile["rules"][3]["id"] = "set_voltage_rule2";
2430 EXPECT_JSON_INVALID(configFile,
2431 "Infinite loop caused by run_rule actions.", "");
2432 }
2433 // Invalid: test run_rule with infinite loop (rule runs itself).
2434 {
2435 json configFile = validConfigFile;
2436 configFile["rules"][2]["actions"][0]["run_rule"] = "set_voltage_rule1";
2437 configFile["rules"][2]["id"] = "set_voltage_rule1";
2438 EXPECT_JSON_INVALID(configFile,
2439 "Infinite loop caused by run_rule actions.", "");
2440 }
2441 // Invalid: test run_rule with infinite loop (indirect loop).
2442 {
2443 json configFile = validConfigFile;
2444 configFile["rules"][2]["actions"][0]["run_rule"] = "set_voltage_rule2";
2445 configFile["rules"][2]["id"] = "set_voltage_rule1";
2446 configFile["rules"][3]["actions"][0]["run_rule"] = "set_voltage_rule3";
2447 configFile["rules"][3]["id"] = "set_voltage_rule2";
2448 configFile["rules"][4]["actions"][0]["run_rule"] = "set_voltage_rule1";
2449 configFile["rules"][4]["id"] = "set_voltage_rule3";
2450 EXPECT_JSON_INVALID(configFile,
2451 "Infinite loop caused by run_rule actions.", "");
2452 }
2453}
Bob Kingf88203a2020-02-18 13:26:07 +08002454TEST(ValidateRegulatorsConfigTest, RunRuleValueExists)
2455{
2456 // Invalid: test run_rule actions specify a rule ID that does not exist.
2457 {
2458 json configFile = validConfigFile;
2459 configFile["rules"][2]["actions"][0]["run_rule"] = "set_voltage_rule2";
2460 configFile["rules"][2]["id"] = "set_voltage_rule1";
2461 EXPECT_JSON_INVALID(configFile, "Error: Rule ID does not exist.", "");
2462 }
2463}
Bob King13b2ad92020-02-18 13:31:39 +08002464TEST(ValidateRegulatorsConfigTest, SetDeviceValueExists)
2465{
2466 // Invalid: test set_device actions specify a device ID that does not exist.
2467 {
2468 json configFile = validConfigFile;
2469 configFile["rules"][2]["actions"][0]["set_device"] = "vdd_regulator2";
2470 configFile["rules"][2]["id"] = "set_voltage_rule1";
2471 EXPECT_JSON_INVALID(configFile, "Error: Device ID does not exist.", "");
2472 }
2473}
Bob King21b09be2020-02-18 13:33:09 +08002474TEST(ValidateRegulatorsConfigTest, RuleIDExists)
2475{
2476 // Invalid: test rule_id property in configuration specifies a rule ID that
2477 // does not exist.
2478 {
2479 json configFile = validConfigFile;
2480 configFile["chassis"][0]["devices"][0]["configuration"]["rule_id"] =
2481 "set_voltage_rule2";
2482 EXPECT_JSON_INVALID(configFile, "Error: Rule ID does not exist.", "");
2483 }
2484 // Invalid: test rule_id property in presence_detection specifies a rule ID
2485 // that does not exist.
2486 {
2487 json configFile = validConfigFile;
2488 configFile["chassis"][0]["devices"][0]["presence_detection"]
2489 ["rule_id"] = "set_voltage_rule2";
2490 EXPECT_JSON_INVALID(configFile, "Error: Rule ID does not exist.", "");
2491 }
2492 // Invalid: test rule_id property in sensor_monitoring specifies a rule ID
2493 // that does not exist.
2494 {
2495 json configFile = validConfigFile;
2496 configFile["chassis"][0]["devices"][0]["rails"][0]["sensor_monitoring"]
2497 ["rule_id"] = "set_voltage_rule2";
2498 EXPECT_JSON_INVALID(configFile, "Error: Rule ID does not exist.", "");
2499 }
2500}
Bob Kingdc72b622020-02-18 13:36:18 +08002501TEST(ValidateRegulatorsConfigTest, NumberOfElementsInMasks)
2502{
2503 // Invalid: test number of elements in masks not equal to number in values
2504 // in i2c_compare_bytes.
2505 {
2506 json configFile = validConfigFile;
2507 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["register"] =
2508 "0x82";
2509 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["values"] = {
2510 "0x02", "0x73"};
2511 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["masks"] = {
2512 "0x7F"};
2513 EXPECT_JSON_INVALID(configFile,
2514 "Error: Invalid i2c_compare_bytes action.", "");
2515 }
2516 // Invalid: test number of elements in masks not equal to number in values
2517 // in i2c_write_bytes.
2518 {
2519 json configFile = validConfigFile;
2520 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["register"] =
2521 "0x82";
2522 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["values"] = {
2523 "0x02", "0x73"};
2524 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["masks"] = {
2525 "0x7F"};
2526 EXPECT_JSON_INVALID(configFile,
2527 "Error: Invalid i2c_write_bytes action.", "");
2528 }
2529}
Bob Kinged009652020-02-20 14:54:13 +08002530TEST(ValidateRegulatorsConfigTest, CommandLineSyntax)
2531{
2532 std::string validateTool = "../tools/validate-regulators-config.py ";
2533 std::string schema = " -s ";
2534 std::string schemaFile = " ../schema/config_schema.json ";
2535 std::string configuration = " -c ";
2536 std::string command;
2537 std::string errorMessage;
2538 std::string outputMessage;
2539 std::string outputMessageHelp =
2540 "usage: validate-regulators-config.py [-h] [-s SCHEMA_FILE]";
2541 int valid = 0;
2542
2543 std::string fileName;
2544 fileName = writeDataToTmpFile(validConfigFile);
2545 // Valid: -s specified
2546 {
2547 command = validateTool + "-s " + schemaFile + configuration + fileName;
2548 expectCommandLineSyntax(errorMessage, outputMessage, command, valid);
2549 }
2550 // Valid: --schema-file specified
2551 {
2552 command = validateTool + "--schema-file " + schemaFile + configuration +
2553 fileName;
2554 expectCommandLineSyntax(errorMessage, outputMessage, command, valid);
2555 }
2556 // Valid: -c specified
2557 {
2558 command = validateTool + schema + schemaFile + "-c " + fileName;
2559 expectCommandLineSyntax(errorMessage, outputMessage, command, valid);
2560 }
2561 // Valid: --configuration-file specified
2562 {
2563 command = validateTool + schema + schemaFile + "--configuration-file " +
2564 fileName;
2565 expectCommandLineSyntax(errorMessage, outputMessage, command, valid);
2566 }
2567 // Valid: -h specified
2568 {
2569 command = validateTool + "-h ";
2570 expectCommandLineSyntax(errorMessage, outputMessageHelp, command,
2571 valid);
2572 }
2573 // Valid: --help specified
2574 {
2575 command = validateTool + "--help ";
2576 expectCommandLineSyntax(errorMessage, outputMessageHelp, command,
2577 valid);
2578 }
2579 // Invalid: -c/--configuration-file not specified
2580 {
2581 command = validateTool + schema + schemaFile;
2582 expectCommandLineSyntax("Error: Configuration file is required.",
2583 outputMessageHelp, command, 1);
2584 }
2585 // Invalid: -s/--schema-file not specified
2586 {
2587 command = validateTool + configuration + fileName;
2588 expectCommandLineSyntax("Error: Schema file is required.",
2589 outputMessageHelp, command, 1);
2590 }
2591 // Invalid: -s specified more than once
2592 {
2593 command =
2594 validateTool + "-s -s " + schemaFile + configuration + fileName;
2595 expectCommandLineSyntax(outputMessageHelp, outputMessage, command, 2);
2596 }
2597 // Invalid: -c specified more than once
2598 {
2599 command = validateTool + schema + schemaFile + "-c -c " + fileName;
2600 expectCommandLineSyntax(outputMessageHelp, outputMessage, command, 2);
2601 }
2602 // Invalid: No file name specified after -c
2603 {
2604 command = validateTool + schema + schemaFile + configuration;
2605 expectCommandLineSyntax(outputMessageHelp, outputMessage, command, 2);
2606 }
2607 // Invalid: No file name specified after -s
2608 {
2609 command = validateTool + schema + configuration + fileName;
2610 expectCommandLineSyntax(outputMessageHelp, outputMessage, command, 2);
2611 }
2612 // Invalid: File specified after -c does not exist
2613 {
2614 command = validateTool + schema + schemaFile + configuration +
2615 "../notExistFile";
2616 expectCommandLineSyntax(
2617 "Traceback (most recent call last):", outputMessage, command, 1);
2618 }
2619 // Invalid: File specified after -s does not exist
2620 {
2621 command = validateTool + schema + "../notExistFile " + configuration +
2622 fileName;
2623 expectCommandLineSyntax(
2624 "Traceback (most recent call last):", outputMessage, command, 1);
2625 }
2626 // Invalid: File specified after -s is not right data format
2627 {
2628 std::string wrongFormatFile;
2629 wrongFormatFile = createTmpFile();
2630 std::ofstream out(wrongFormatFile);
2631 out << "foo";
2632 out.close();
2633 command =
2634 validateTool + schema + wrongFormatFile + configuration + fileName;
2635 expectCommandLineSyntax(
2636 "Traceback (most recent call last):", outputMessage, command, 1);
2637 unlink(wrongFormatFile.c_str());
2638 }
2639 // Invalid: File specified after -c is not readable
2640 {
2641 std::string notReadableFile;
2642 notReadableFile = writeDataToTmpFile(validConfigFile);
2643 command = validateTool + schema + schemaFile + configuration +
2644 notReadableFile;
2645 chmod(notReadableFile.c_str(), 0222);
2646 expectCommandLineSyntax(
2647 "Traceback (most recent call last):", outputMessage, command, 1);
2648 unlink(notReadableFile.c_str());
2649 }
2650 // Invalid: File specified after -s is not readable
2651 {
2652 std::string notReadableFile;
2653 notReadableFile = writeDataToTmpFile(validConfigFile);
2654 command =
2655 validateTool + schema + notReadableFile + configuration + fileName;
2656 chmod(notReadableFile.c_str(), 0222);
2657 expectCommandLineSyntax(
2658 "Traceback (most recent call last):", outputMessage, command, 1);
2659 unlink(notReadableFile.c_str());
2660 }
2661 // Invalid: Unexpected parameter specified (like -g)
2662 {
2663 command = validateTool + schema + schemaFile + configuration +
2664 fileName + " -g";
2665 expectCommandLineSyntax(outputMessageHelp, outputMessage, command, 2);
2666 }
2667 unlink(fileName.c_str());
2668}