blob: e2203d906f13b9efa364f0cc03feb93d42901fba [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;
Bob King2d27dcf2020-02-11 15:00:50 +08001639 ifFile["rules"][2]["actions"][0]["if"]["condition"]["run_rule"] =
1640 "set_voltage_rule";
1641 ifFile["rules"][2]["actions"][0]["if"]["then"][0]["run_rule"] =
1642 "read_sensors_rule";
1643 ifFile["rules"][2]["actions"][0]["if"]["else"][0]["run_rule"] =
1644 "read_sensors_rule";
1645 ifFile["rules"][2]["id"] = "rule_if";
Bob Kingead0b052020-01-21 11:29:03 +08001646 // Valid: test if.
1647 {
1648 json configFile = ifFile;
1649 EXPECT_JSON_VALID(configFile);
1650 }
1651 // Valid: test if with required properties.
1652 {
1653 json configFile = ifFile;
Bob King2d27dcf2020-02-11 15:00:50 +08001654 configFile["rules"][2]["actions"][0]["if"].erase("else");
Bob Kingead0b052020-01-21 11:29:03 +08001655 EXPECT_JSON_VALID(configFile);
1656 }
1657 // Invalid: test if with no property condition.
1658 {
1659 json configFile = ifFile;
Bob King2d27dcf2020-02-11 15:00:50 +08001660 configFile["rules"][2]["actions"][0]["if"].erase("condition");
Bob Kingead0b052020-01-21 11:29:03 +08001661 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1662 "u'condition' is a required property");
1663 }
1664 // Invalid: test if with no property then.
1665 {
1666 json configFile = ifFile;
Bob King2d27dcf2020-02-11 15:00:50 +08001667 configFile["rules"][2]["actions"][0]["if"].erase("then");
Bob Kingead0b052020-01-21 11:29:03 +08001668 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1669 "u'then' is a required property");
1670 }
1671 // Invalid: test if with property then empty array.
1672 {
1673 json configFile = ifFile;
Bob King2d27dcf2020-02-11 15:00:50 +08001674 configFile["rules"][2]["actions"][0]["if"]["then"] = json::array();
Bob Kingead0b052020-01-21 11:29:03 +08001675 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1676 "[] is too short");
1677 }
1678 // Invalid: test if with property else empty array.
1679 {
1680 json configFile = ifFile;
Bob King2d27dcf2020-02-11 15:00:50 +08001681 configFile["rules"][2]["actions"][0]["if"]["else"] = json::array();
Bob Kingead0b052020-01-21 11:29:03 +08001682 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1683 "[] is too short");
1684 }
1685 // Invalid: test if with property condition wrong type.
1686 {
1687 json configFile = ifFile;
Bob King2d27dcf2020-02-11 15:00:50 +08001688 configFile["rules"][2]["actions"][0]["if"]["condition"] = 1;
Bob Kingead0b052020-01-21 11:29:03 +08001689 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1690 "1 is not of type u'object'");
1691 }
1692 // Invalid: test if with property then wrong type.
1693 {
1694 json configFile = ifFile;
Bob King2d27dcf2020-02-11 15:00:50 +08001695 configFile["rules"][2]["actions"][0]["if"]["then"] = 1;
Bob Kingead0b052020-01-21 11:29:03 +08001696 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1697 "1 is not of type u'array'");
1698 }
1699 // Invalid: test if with property else wrong type.
1700 {
1701 json configFile = ifFile;
Bob King2d27dcf2020-02-11 15:00:50 +08001702 configFile["rules"][2]["actions"][0]["if"]["else"] = 1;
Bob Kingead0b052020-01-21 11:29:03 +08001703 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1704 "1 is not of type u'array'");
1705 }
1706}
Bob Kingbfe9fe72020-01-21 11:29:57 +08001707TEST(ValidateRegulatorsConfigTest, Not)
1708{
1709 json notFile = validConfigFile;
1710 notFile["rules"][0]["actions"][1]["not"]["i2c_compare_byte"]["register"] =
1711 "0xA0";
1712 notFile["rules"][0]["actions"][1]["not"]["i2c_compare_byte"]["value"] =
1713 "0xFF";
1714 // Valid: test not.
1715 {
1716 json configFile = notFile;
1717 EXPECT_JSON_VALID(configFile);
1718 }
1719 // Invalid: test not with wrong type.
1720 {
1721 json configFile = notFile;
1722 configFile["rules"][0]["actions"][1]["not"] = 1;
1723 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1724 "1 is not of type u'object'");
1725 }
1726}
Bob Kingcfc29d02020-01-21 11:30:50 +08001727TEST(ValidateRegulatorsConfigTest, Or)
1728{
1729 json orFile = validConfigFile;
1730 orFile["rules"][0]["actions"][1]["or"][0]["i2c_compare_byte"]["register"] =
1731 "0xA0";
1732 orFile["rules"][0]["actions"][1]["or"][0]["i2c_compare_byte"]["value"] =
1733 "0x00";
1734 orFile["rules"][0]["actions"][1]["or"][1]["i2c_compare_byte"]["register"] =
1735 "0xA1";
1736 orFile["rules"][0]["actions"][1]["or"][1]["i2c_compare_byte"]["value"] =
1737 "0x00";
1738 // Valid: test or.
1739 {
1740 json configFile = orFile;
1741 EXPECT_JSON_VALID(configFile);
1742 }
1743 // Invalid: test or with empty array.
1744 {
1745 json configFile = orFile;
1746 configFile["rules"][0]["actions"][1]["or"] = json::array();
1747 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1748 "[] is too short");
1749 }
1750 // Invalid: test or with wrong type.
1751 {
1752 json configFile = orFile;
1753 configFile["rules"][0]["actions"][1]["or"] = 1;
1754 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1755 "1 is not of type u'array'");
1756 }
1757}
Bob Kingd6618092020-01-21 11:31:46 +08001758TEST(ValidateRegulatorsConfigTest, PmbusReadSensor)
1759{
1760 json pmbusReadSensorFile = validConfigFile;
1761 pmbusReadSensorFile["rules"][0]["actions"][1]["pmbus_read_sensor"]["type"] =
1762 "vout";
1763 pmbusReadSensorFile["rules"][0]["actions"][1]["pmbus_read_sensor"]
1764 ["command"] = "0x8B";
1765 pmbusReadSensorFile["rules"][0]["actions"][1]["pmbus_read_sensor"]
1766 ["format"] = "linear_16";
1767 pmbusReadSensorFile["rules"][0]["actions"][1]["pmbus_read_sensor"]
1768 ["exponent"] = -8;
1769 // Valid: test pmbus_read_sensor.
1770 {
1771 json configFile = pmbusReadSensorFile;
1772 EXPECT_JSON_VALID(configFile);
1773 }
1774 // Valid: test pmbus_read_sensor with required properties.
1775 {
1776 json configFile = pmbusReadSensorFile;
1777 configFile["rules"][0]["actions"][1]["pmbus_read_sensor"].erase(
1778 "exponent");
1779 EXPECT_JSON_VALID(configFile);
1780 }
1781 // Invalid: test pmbus_read_sensor with no type.
1782 {
1783 json configFile = pmbusReadSensorFile;
1784 configFile["rules"][0]["actions"][1]["pmbus_read_sensor"].erase("type");
1785 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1786 "u'type' is a required property");
1787 }
1788 // Invalid: test pmbus_read_sensor with no command.
1789 {
1790 json configFile = pmbusReadSensorFile;
1791 configFile["rules"][0]["actions"][1]["pmbus_read_sensor"].erase(
1792 "command");
1793 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1794 "u'command' is a required property");
1795 }
1796 // Invalid: test pmbus_read_sensor with no format.
1797 {
1798 json configFile = pmbusReadSensorFile;
1799 configFile["rules"][0]["actions"][1]["pmbus_read_sensor"].erase(
1800 "format");
1801 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1802 "u'format' is a required property");
1803 }
1804 // Invalid: test pmbus_read_sensor with property type wrong type.
1805 {
1806 json configFile = pmbusReadSensorFile;
1807 configFile["rules"][0]["actions"][1]["pmbus_read_sensor"]["type"] =
1808 true;
1809 EXPECT_JSON_INVALID(
1810 configFile, "Validation failed.",
1811 "True is not one of [u'iout', u'iout_peak', u'iout_valley', "
1812 "u'pout', u'temperature', u'temperature_peak', u'vout', "
1813 "u'vout_peak', u'vout_valley']");
1814 }
1815 // Invalid: test pmbus_read_sensor with property command wrong type.
1816 {
1817 json configFile = pmbusReadSensorFile;
1818 configFile["rules"][0]["actions"][1]["pmbus_read_sensor"]["command"] =
1819 true;
1820 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1821 "True is not of type u'string'");
1822 }
1823 // Invalid: test pmbus_read_sensor with property format wrong type.
1824 {
1825 json configFile = pmbusReadSensorFile;
1826 configFile["rules"][0]["actions"][1]["pmbus_read_sensor"]["format"] =
1827 true;
1828 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1829 "True is not one of [u'linear_11', u'linear_16']");
1830 }
1831 // Invalid: test pmbus_read_sensor with property exponent wrong type.
1832 {
1833 json configFile = pmbusReadSensorFile;
1834 configFile["rules"][0]["actions"][1]["pmbus_read_sensor"]["exponent"] =
1835 true;
1836 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1837 "True is not of type u'integer'");
1838 }
1839 // Invalid: test pmbus_read_sensor with property type wrong format.
1840 {
1841 json configFile = pmbusReadSensorFile;
1842 configFile["rules"][0]["actions"][1]["pmbus_read_sensor"]["type"] =
1843 "foo";
1844 EXPECT_JSON_INVALID(
1845 configFile, "Validation failed.",
1846 "u'foo' is not one of [u'iout', u'iout_peak', u'iout_valley', "
1847 "u'pout', u'temperature', u'temperature_peak', u'vout', "
1848 "u'vout_peak', u'vout_valley']");
1849 }
1850 // Invalid: test pmbus_read_sensor with property command wrong format.
1851 {
1852 json configFile = pmbusReadSensorFile;
1853 configFile["rules"][0]["actions"][1]["pmbus_read_sensor"]["command"] =
1854 "0x8B0";
1855 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1856 "u'0x8B0' does not match u'^0x[0-9a-fA-F]{2}$'");
1857 }
1858 // Invalid: test pmbus_read_sensor with property format wrong format.
1859 {
1860 json configFile = pmbusReadSensorFile;
1861 configFile["rules"][0]["actions"][1]["pmbus_read_sensor"]["format"] =
1862 "foo";
1863 EXPECT_JSON_INVALID(
1864 configFile, "Validation failed.",
1865 "u'foo' is not one of [u'linear_11', u'linear_16']");
1866 }
1867}
Bob King02179c62020-01-21 11:32:36 +08001868TEST(ValidateRegulatorsConfigTest, PmbusWriteVoutCommand)
1869{
1870 json pmbusWriteVoutCommandFile = validConfigFile;
1871 pmbusWriteVoutCommandFile["rules"][0]["actions"][1]
1872 ["pmbus_write_vout_command"]["volts"] = 1.03;
1873 pmbusWriteVoutCommandFile["rules"][0]["actions"][1]
1874 ["pmbus_write_vout_command"]["format"] = "linear";
1875 pmbusWriteVoutCommandFile["rules"][0]["actions"][1]
1876 ["pmbus_write_vout_command"]["exponent"] = -8;
1877 pmbusWriteVoutCommandFile["rules"][0]["actions"][1]
1878 ["pmbus_write_vout_command"]["is_verified"] = true;
1879 // Valid: test pmbus_write_vout_command.
1880 {
1881 json configFile = pmbusWriteVoutCommandFile;
1882 EXPECT_JSON_VALID(configFile);
1883 }
1884 // Valid: test pmbus_write_vout_command with required properties.
1885 {
1886 json configFile = pmbusWriteVoutCommandFile;
1887 configFile["rules"][0]["actions"][1]["pmbus_write_vout_command"].erase(
1888 "volts");
1889 configFile["rules"][0]["actions"][1]["pmbus_write_vout_command"].erase(
1890 "exponent");
1891 configFile["rules"][0]["actions"][1]["pmbus_write_vout_command"].erase(
1892 "is_verified");
1893 EXPECT_JSON_VALID(configFile);
1894 }
1895 // Invalid: test pmbus_write_vout_command with no format.
1896 {
1897 json configFile = pmbusWriteVoutCommandFile;
1898 configFile["rules"][0]["actions"][1]["pmbus_write_vout_command"].erase(
1899 "format");
1900 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1901 "u'format' is a required property");
1902 }
1903 // Invalid: test pmbus_write_vout_command with property volts wrong type.
1904 {
1905 json configFile = pmbusWriteVoutCommandFile;
1906 configFile["rules"][0]["actions"][1]["pmbus_write_vout_command"]
1907 ["volts"] = true;
1908 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1909 "True is not of type u'number'");
1910 }
1911 // Invalid: test pmbus_write_vout_command with property format wrong type.
1912 {
1913 json configFile = pmbusWriteVoutCommandFile;
1914 configFile["rules"][0]["actions"][1]["pmbus_write_vout_command"]
1915 ["format"] = true;
1916 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1917 "True is not one of [u'linear']");
1918 }
1919 // Invalid: test pmbus_write_vout_command with property exponent wrong type.
1920 {
1921 json configFile = pmbusWriteVoutCommandFile;
1922 configFile["rules"][0]["actions"][1]["pmbus_write_vout_command"]
1923 ["exponent"] = 1.3;
1924 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1925 "1.3 is not of type u'integer'");
1926 }
1927 // Invalid: test pmbus_write_vout_command with property is_verified wrong
1928 // type.
1929 {
1930 json configFile = pmbusWriteVoutCommandFile;
1931 configFile["rules"][0]["actions"][1]["pmbus_write_vout_command"]
1932 ["is_verified"] = 1;
1933 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1934 "1 is not of type u'boolean'");
1935 }
1936 // Invalid: test pmbus_write_vout_command with property format wrong format.
1937 {
1938 json configFile = pmbusWriteVoutCommandFile;
1939 configFile["rules"][0]["actions"][1]["pmbus_write_vout_command"]
1940 ["format"] = "foo";
1941 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1942 "u'foo' is not one of [u'linear']");
1943 }
1944}
Bob King99d8fa12020-01-31 11:23:40 +08001945TEST(ValidateRegulatorsConfigTest, PresenceDetection)
1946{
1947 json presenceDetectionFile = validConfigFile;
1948 presenceDetectionFile
1949 ["chassis"][0]["devices"][0]["presence_detection"]["comments"][0] =
1950 "Regulator is only present on the FooBar backplane";
1951 presenceDetectionFile["chassis"][0]["devices"][0]["presence_detection"]
1952 ["rule_id"] = "is_foobar_backplane_installed_rule";
1953 // Valid: test presence_detection with only property rule_id.
1954 {
1955 json configFile = presenceDetectionFile;
1956 EXPECT_JSON_VALID(configFile);
1957 }
1958 // Valid: test presence_detection with only property actions.
1959 {
1960 json configFile = presenceDetectionFile;
1961 configFile["chassis"][0]["devices"][0]["presence_detection"].erase(
1962 "rule_id");
1963 configFile["chassis"][0]["devices"][0]["presence_detection"]["actions"]
1964 [0]["compare_presence"]["fru"] =
1965 "/system/chassis/motherboard/cpu3";
1966 configFile["chassis"][0]["devices"][0]["presence_detection"]["actions"]
1967 [0]["compare_presence"]["value"] = true;
1968 configFile["chassis"][0]["devices"][0]["presence_detection"].erase(
1969 "comments");
1970 EXPECT_JSON_VALID(configFile);
1971 }
1972 // Invalid: test presence_detection with both property rule_id and actions.
1973 {
1974 json configFile = presenceDetectionFile;
1975 configFile["chassis"][0]["devices"][0]["presence_detection"]["actions"]
1976 [0]["compare_presence"]["fru"] =
1977 "/system/chassis/motherboard/cpu3";
1978 configFile["chassis"][0]["devices"][0]["presence_detection"]["actions"]
1979 [0]["compare_presence"]["value"] = true;
1980 EXPECT_JSON_INVALID(
1981 configFile, "Validation failed.",
1982 "{u'comments': [u'Regulator is only present on the FooBar "
1983 "backplane'], u'actions': [{u'compare_presence': {u'value': True, "
1984 "u'fru': u'/system/chassis/motherboard/cpu3'}}], u'rule_id': "
1985 "u'is_foobar_backplane_installed_rule'} is valid under each of "
1986 "{u'required': [u'actions']}, {u'required': [u'rule_id']}");
1987 }
1988 // Invalid: test presence_detection with no rule_id and actions.
1989 {
1990 json configFile = presenceDetectionFile;
1991 configFile["chassis"][0]["devices"][0]["presence_detection"].erase(
1992 "rule_id");
1993 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1994 "u'rule_id' is a required property");
1995 }
1996 // Invalid: test presence_detection with property comments wrong type.
1997 {
1998 json configFile = presenceDetectionFile;
1999 configFile["chassis"][0]["devices"][0]["presence_detection"]
2000 ["comments"] = true;
2001 EXPECT_JSON_INVALID(configFile, "Validation failed.",
2002 "True is not of type u'array'");
2003 }
2004 // Invalid: test presence_detection with property rule_id wrong type.
2005 {
2006 json configFile = presenceDetectionFile;
2007 configFile["chassis"][0]["devices"][0]["presence_detection"]
2008 ["rule_id"] = true;
2009 EXPECT_JSON_INVALID(configFile, "Validation failed.",
2010 "True is not of type u'string'");
2011 }
2012 // Invalid: test presence_detection with property actions wrong type.
2013 {
2014 json configFile = presenceDetectionFile;
2015 configFile["chassis"][0]["devices"][0]["presence_detection"].erase(
2016 "rule_id");
2017 configFile["chassis"][0]["devices"][0]["presence_detection"]
2018 ["actions"] = true;
2019 EXPECT_JSON_INVALID(configFile, "Validation failed.",
2020 "True is not of type u'array'");
2021 }
2022 // Invalid: test presence_detection with property rule_id wrong format.
2023 {
2024 json configFile = presenceDetectionFile;
2025 configFile["chassis"][0]["devices"][0]["presence_detection"]
2026 ["rule_id"] = "id@";
2027 EXPECT_JSON_INVALID(configFile, "Validation failed.",
2028 "u'id@' does not match u'^[A-Za-z0-9_]+$'");
2029 }
2030 // Invalid: test presence_detection with property comments empty array.
2031 {
2032 json configFile = presenceDetectionFile;
2033 configFile["chassis"][0]["devices"][0]["presence_detection"]
2034 ["comments"] = json::array();
2035 EXPECT_JSON_INVALID(configFile, "Validation failed.",
2036 "[] is too short");
2037 }
2038 // Invalid: test presence_detection with property actions empty array.
2039 {
2040 json configFile = presenceDetectionFile;
2041 configFile["chassis"][0]["devices"][0]["presence_detection"].erase(
2042 "rule_id");
2043 configFile["chassis"][0]["devices"][0]["presence_detection"]
2044 ["actions"] = json::array();
2045 EXPECT_JSON_INVALID(configFile, "Validation failed.",
2046 "[] is too short");
2047 }
2048}
Bob Kinge9260b52020-01-21 11:46:13 +08002049TEST(ValidateRegulatorsConfigTest, Rail)
2050{
2051 // Valid: test rail.
2052 {
2053 json configFile = validConfigFile;
2054 EXPECT_JSON_VALID(configFile);
2055 }
2056 // Valid: test rail with required properties.
2057 {
2058 json configFile = validConfigFile;
2059 configFile["chassis"][0]["devices"][0]["rails"][0].erase("comments");
2060 configFile["chassis"][0]["devices"][0]["rails"][0].erase(
2061 "configuration");
2062 configFile["chassis"][0]["devices"][0]["rails"][0].erase(
2063 "sensor_monitoring");
2064 EXPECT_JSON_VALID(configFile);
2065 }
2066 // Invalid: test rail with no id.
2067 {
2068 json configFile = validConfigFile;
2069 configFile["chassis"][0]["devices"][0]["rails"][0].erase("id");
2070 EXPECT_JSON_INVALID(configFile, "Validation failed.",
2071 "u'id' is a required property");
2072 }
2073 // Invalid: test rail with comments wrong type.
2074 {
2075 json configFile = validConfigFile;
2076 configFile["chassis"][0]["devices"][0]["rails"][0]["comments"] = true;
2077 EXPECT_JSON_INVALID(configFile, "Validation failed.",
2078 "True is not of type u'array'");
2079 }
2080 // Invalid: test rail with id wrong type.
2081 {
2082 json configFile = validConfigFile;
2083 configFile["chassis"][0]["devices"][0]["rails"][0]["id"] = true;
2084 EXPECT_JSON_INVALID(configFile, "Validation failed.",
2085 "True is not of type u'string'");
2086 }
2087 // Invalid: test rail with configuration wrong type.
2088 {
2089 json configFile = validConfigFile;
2090 configFile["chassis"][0]["devices"][0]["rails"][0]["configuration"] =
2091 true;
2092 EXPECT_JSON_INVALID(configFile, "Validation failed.",
2093 "True is not of type u'object'");
2094 }
2095 // Invalid: test rail with sensor_monitoring wrong type.
2096 {
2097 json configFile = validConfigFile;
2098 configFile["chassis"][0]["devices"][0]["rails"][0]
2099 ["sensor_monitoring"] = true;
2100 EXPECT_JSON_INVALID(configFile, "Validation failed.",
2101 "True is not of type u'object'");
2102 }
2103 // Invalid: test rail with comments empty array.
2104 {
2105 json configFile = validConfigFile;
2106 configFile["chassis"][0]["devices"][0]["rails"][0]["comments"] =
2107 json::array();
2108 EXPECT_JSON_INVALID(configFile, "Validation failed.",
2109 "[] is too short");
2110 }
2111 // Invalid: test rail with id wrong format.
2112 {
2113 json configFile = validConfigFile;
2114 configFile["chassis"][0]["devices"][0]["rails"][0]["id"] = "id~";
2115 EXPECT_JSON_INVALID(configFile, "Validation failed.",
2116 "u'id~' does not match u'^[A-Za-z0-9_]+$'");
2117 }
2118}
Bob King64df7da2020-01-31 12:04:12 +08002119TEST(ValidateRegulatorsConfigTest, Rule)
2120{
2121 // valid test comments property, id property,
2122 // action property specified.
2123 {
2124 json configFile = validConfigFile;
2125 EXPECT_JSON_VALID(configFile);
2126 }
2127
2128 // valid test rule with no comments
2129 {
2130 json configFile = validConfigFile;
2131 configFile["rules"][0].erase("comments");
2132 EXPECT_JSON_VALID(configFile);
2133 }
2134
2135 // invalid test comments property has invalid value type
2136 {
2137 json configFile = validConfigFile;
2138 configFile["rules"][0]["comments"] = {1};
2139 EXPECT_JSON_INVALID(configFile, "Validation failed.",
2140 "1 is not of type u'string'");
2141 }
2142
2143 // invalid test rule with no ID
2144 {
2145 json configFile = validConfigFile;
2146 configFile["rules"][0].erase("id");
2147 EXPECT_JSON_INVALID(configFile, "Validation failed.",
2148 "u'id' is a required property");
2149 }
2150
2151 // invalid test id property has invalid value type (not string)
2152 {
2153 json configFile = validConfigFile;
2154 configFile["rules"][0]["id"] = true;
2155 EXPECT_JSON_INVALID(configFile, "Validation failed.",
2156 "True is not of type u'string'");
2157 }
2158
2159 // invalid test id property has invalid value
2160 {
2161 json configFile = validConfigFile;
2162 configFile["rules"][0]["id"] = "foo%";
2163 EXPECT_JSON_INVALID(configFile, "Validation failed.",
2164 "u'foo%' does not match u'^[A-Za-z0-9_]+$'");
2165 }
2166
2167 // invalid test rule with no actions property
2168 {
2169 json configFile = validConfigFile;
2170 configFile["rules"][0].erase("actions");
2171 EXPECT_JSON_INVALID(configFile, "Validation failed.",
2172 "u'actions' is a required property");
2173 }
2174
2175 // valid test rule with multiple actions
2176 {
2177 json configFile = validConfigFile;
2178 configFile["rules"][0]["actions"][1]["run_rule"] =
2179 "set_page0_voltage_rule";
2180 EXPECT_JSON_VALID(configFile);
2181 }
2182
2183 // invalid test actions property has invalid value type (not an array)
2184 {
2185 json configFile = validConfigFile;
2186 configFile["rules"][0]["actions"] = 1;
2187 EXPECT_JSON_INVALID(configFile, "Validation failed.",
2188 "1 is not of type u'array'");
2189 }
2190
2191 // invalid test actions property has invalid value of action
2192 {
2193 json configFile = validConfigFile;
2194 configFile["rules"][0]["actions"][0] = "foo";
2195 EXPECT_JSON_INVALID(configFile, "Validation failed.",
2196 "u'foo' is not of type u'object'");
2197 }
2198
2199 // invalid test actions property has empty array
2200 {
2201 json configFile = validConfigFile;
2202 configFile["rules"][0]["actions"] = json::array();
2203 EXPECT_JSON_INVALID(configFile, "Validation failed.",
2204 "[] is too short");
2205 }
2206}
Bob Kinge86c2e52020-01-21 11:33:32 +08002207TEST(ValidateRegulatorsConfigTest, RunRule)
2208{
2209 json runRuleFile = validConfigFile;
2210 runRuleFile["rules"][0]["actions"][1]["run_rule"] = "set_voltage_rule1";
2211 // Valid: test run_rule.
2212 {
2213 json configFile = runRuleFile;
2214 EXPECT_JSON_VALID(configFile);
2215 }
2216 // Invalid: test run_rule wrong type.
2217 {
2218 json configFile = runRuleFile;
2219 configFile["rules"][0]["actions"][1]["run_rule"] = true;
2220 EXPECT_JSON_INVALID(configFile, "Validation failed.",
2221 "True is not of type u'string'");
2222 }
2223 // Invalid: test run_rule wrong format.
2224 {
2225 json configFile = runRuleFile;
2226 configFile["rules"][0]["actions"][1]["run_rule"] = "set_voltage_rule%";
2227 EXPECT_JSON_INVALID(
2228 configFile, "Validation failed.",
2229 "u'set_voltage_rule%' does not match u'^[A-Za-z0-9_]+$'");
2230 }
2231}
Bob Kingfcc2a2f2020-01-31 11:29:45 +08002232TEST(ValidateRegulatorsConfigTest, SensorMonitoring)
2233{
2234 // Valid: test rails sensor_monitoring with only property rule id.
2235 {
2236 json configFile = validConfigFile;
2237 EXPECT_JSON_VALID(configFile);
2238 }
2239 // Valid: test rails sensor_monitoring with only property actions.
2240 {
2241 json configFile = validConfigFile;
2242 configFile["chassis"][0]["devices"][0]["rails"][0]["sensor_monitoring"]
2243 .erase("rule_id");
2244 configFile["chassis"][0]["devices"][0]["rails"][0]["sensor_monitoring"]
2245 ["actions"][0]["compare_presence"]["fru"] =
2246 "/system/chassis/motherboard/cpu3";
2247 configFile["chassis"][0]["devices"][0]["rails"][0]["sensor_monitoring"]
2248 ["actions"][0]["compare_presence"]["value"] = true;
2249 configFile["chassis"][0]["devices"][0]["rails"][0]["sensor_monitoring"]
2250 ["comments"][0] = "comments";
2251 EXPECT_JSON_VALID(configFile);
2252 }
2253 // Invalid: test rails sensor_monitoring with both property rule_id and
2254 // actions.
2255 {
2256 json configFile = validConfigFile;
2257 configFile["chassis"][0]["devices"][0]["rails"][0]["sensor_monitoring"]
2258 ["actions"][0]["compare_presence"]["fru"] =
2259 "/system/chassis/motherboard/cpu3";
2260 configFile["chassis"][0]["devices"][0]["rails"][0]["sensor_monitoring"]
2261 ["actions"][0]["compare_presence"]["value"] = true;
2262 EXPECT_JSON_INVALID(
2263 configFile, "Validation failed.",
2264 "{u'rule_id': u'read_sensors_rule', u'actions': "
2265 "[{u'compare_presence': {u'value': True, u'fru': "
2266 "u'/system/chassis/motherboard/cpu3'}}]} is valid under each of "
2267 "{u'required': [u'actions']}, {u'required': [u'rule_id']}");
2268 }
2269 // Invalid: test rails sensor_monitoring with no rule_id and actions.
2270 {
2271 json configFile = validConfigFile;
2272 configFile["chassis"][0]["devices"][0]["rails"][0]["sensor_monitoring"]
2273 .erase("rule_id");
2274 EXPECT_JSON_INVALID(configFile, "Validation failed.",
2275 "u'rule_id' is a required property");
2276 }
2277 // Invalid: test rails sensor_monitoring with property comments wrong type.
2278 {
2279 json configFile = validConfigFile;
2280 configFile["chassis"][0]["devices"][0]["rails"][0]["sensor_monitoring"]
2281 ["comments"] = true;
2282 EXPECT_JSON_INVALID(configFile, "Validation failed.",
2283 "True is not of type u'array'");
2284 }
2285 // Invalid: test rails sensor_monitoring with property rule_id wrong type.
2286 {
2287 json configFile = validConfigFile;
2288 configFile["chassis"][0]["devices"][0]["rails"][0]["sensor_monitoring"]
2289 ["rule_id"] = true;
2290 EXPECT_JSON_INVALID(configFile, "Validation failed.",
2291 "True is not of type u'string'");
2292 }
2293 // Invalid: test rails sensor_monitoring with property actions wrong type.
2294 {
2295 json configFile = validConfigFile;
2296 configFile["chassis"][0]["devices"][0]["rails"][0]["sensor_monitoring"]
2297 .erase("rule_id");
2298 configFile["chassis"][0]["devices"][0]["rails"][0]["sensor_monitoring"]
2299 ["actions"] = true;
2300 EXPECT_JSON_INVALID(configFile, "Validation failed.",
2301 "True is not of type u'array'");
2302 }
2303 // Invalid: test rails sensor_monitoring with property rule_id wrong format.
2304 {
2305 json configFile = validConfigFile;
2306 configFile["chassis"][0]["devices"][0]["rails"][0]["sensor_monitoring"]
2307 ["rule_id"] = "id@";
2308 EXPECT_JSON_INVALID(configFile, "Validation failed.",
2309 "u'id@' does not match u'^[A-Za-z0-9_]+$'");
2310 }
2311 // Invalid: test rails sensor_monitoring with property comments empty array.
2312 {
2313 json configFile = validConfigFile;
2314 configFile["chassis"][0]["devices"][0]["rails"][0]["sensor_monitoring"]
2315 ["comments"] = json::array();
2316 EXPECT_JSON_INVALID(configFile, "Validation failed.",
2317 "[] is too short");
2318 }
2319 // Invalid: test rails sensor_monitoring with property actions empty array.
2320 {
2321 json configFile = validConfigFile;
2322 configFile["chassis"][0]["devices"][0]["rails"][0]["sensor_monitoring"]
2323 .erase("rule_id");
2324 configFile["chassis"][0]["devices"][0]["rails"][0]["sensor_monitoring"]
2325 ["actions"] = json::array();
2326 EXPECT_JSON_INVALID(configFile, "Validation failed.",
2327 "[] is too short");
2328 }
2329}
Bob King68230aa2020-01-21 11:34:33 +08002330TEST(ValidateRegulatorsConfigTest, SetDevice)
2331{
2332 json setDeviceFile = validConfigFile;
2333 setDeviceFile["rules"][0]["actions"][1]["set_device"] = "io_expander2";
2334 // Valid: test set_device.
2335 {
2336 json configFile = setDeviceFile;
2337 EXPECT_JSON_VALID(configFile);
2338 }
2339 // Invalid: test set_device wrong type.
2340 {
2341 json configFile = setDeviceFile;
2342 configFile["rules"][0]["actions"][1]["set_device"] = true;
2343 EXPECT_JSON_INVALID(configFile, "Validation failed.",
2344 "True is not of type u'string'");
2345 }
2346 // Invalid: test set_device wrong format.
2347 {
2348 json configFile = setDeviceFile;
2349 configFile["rules"][0]["actions"][1]["set_device"] = "io_expander2%";
2350 EXPECT_JSON_INVALID(
2351 configFile, "Validation failed.",
2352 "u'io_expander2%' does not match u'^[A-Za-z0-9_]+$'");
2353 }
2354}
Bob King3643cc02020-01-31 11:32:56 +08002355TEST(ValidateRegulatorsConfigTest, DuplicateRuleID)
2356{
2357 // Invalid: test duplicate ID in rule.
2358 {
2359 json configFile = validConfigFile;
Bob Kingb3e48bc2020-02-18 09:59:09 +08002360 configFile["rules"][2]["id"] = "set_voltage_rule";
2361 configFile["rules"][2]["actions"][0]["pmbus_write_vout_command"]
Bob King3643cc02020-01-31 11:32:56 +08002362 ["format"] = "linear";
2363 EXPECT_JSON_INVALID(configFile, "Error: Duplicate rule ID.", "");
2364 }
2365}
2366TEST(ValidateRegulatorsConfigTest, DuplicateChassisNumber)
2367{
2368 // Invalid: test duplicate number in chassis.
2369 {
2370 json configFile = validConfigFile;
2371 configFile["chassis"][1]["number"] = 1;
2372 EXPECT_JSON_INVALID(configFile, "Error: Duplicate chassis number.", "");
2373 }
2374}
2375TEST(ValidateRegulatorsConfigTest, DuplicateDeviceID)
2376{
2377 // Invalid: test duplicate ID in device.
2378 {
2379 json configFile = validConfigFile;
2380 configFile["chassis"][0]["devices"][1]["id"] = "vdd_regulator";
2381 configFile["chassis"][0]["devices"][1]["is_regulator"] = true;
2382 configFile["chassis"][0]["devices"][1]["fru"] =
2383 "/system/chassis/motherboard/regulator1";
2384 configFile["chassis"][0]["devices"][1]["i2c_interface"]["bus"] = 2;
2385 configFile["chassis"][0]["devices"][1]["i2c_interface"]["address"] =
2386 "0x71";
2387 EXPECT_JSON_INVALID(configFile, "Error: Duplicate device ID.", "");
2388 }
2389}
2390TEST(ValidateRegulatorsConfigTest, DuplicateRailID)
2391{
2392 // Invalid: test duplicate ID in rail.
2393 {
2394 json configFile = validConfigFile;
2395 configFile["chassis"][0]["devices"][0]["rails"][1]["id"] = "vdd";
2396 EXPECT_JSON_INVALID(configFile, "Error: Duplicate rail ID.", "");
2397 }
2398}
2399TEST(ValidateRegulatorsConfigTest, InfiniteLoops)
2400{
2401 // Invalid: test run_rule with infinite loop (rules run each other).
2402 {
2403 json configFile = validConfigFile;
2404 configFile["rules"][2]["actions"][0]["run_rule"] = "set_voltage_rule2";
2405 configFile["rules"][2]["id"] = "set_voltage_rule1";
2406 configFile["rules"][3]["actions"][0]["run_rule"] = "set_voltage_rule1";
2407 configFile["rules"][3]["id"] = "set_voltage_rule2";
2408 EXPECT_JSON_INVALID(configFile,
2409 "Infinite loop caused by run_rule actions.", "");
2410 }
2411 // Invalid: test run_rule with infinite loop (rule runs itself).
2412 {
2413 json configFile = validConfigFile;
2414 configFile["rules"][2]["actions"][0]["run_rule"] = "set_voltage_rule1";
2415 configFile["rules"][2]["id"] = "set_voltage_rule1";
2416 EXPECT_JSON_INVALID(configFile,
2417 "Infinite loop caused by run_rule actions.", "");
2418 }
2419 // Invalid: test run_rule with infinite loop (indirect loop).
2420 {
2421 json configFile = validConfigFile;
2422 configFile["rules"][2]["actions"][0]["run_rule"] = "set_voltage_rule2";
2423 configFile["rules"][2]["id"] = "set_voltage_rule1";
2424 configFile["rules"][3]["actions"][0]["run_rule"] = "set_voltage_rule3";
2425 configFile["rules"][3]["id"] = "set_voltage_rule2";
2426 configFile["rules"][4]["actions"][0]["run_rule"] = "set_voltage_rule1";
2427 configFile["rules"][4]["id"] = "set_voltage_rule3";
2428 EXPECT_JSON_INVALID(configFile,
2429 "Infinite loop caused by run_rule actions.", "");
2430 }
2431}