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