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