blob: aeb56143ab6f76c084abd1c27fd61d892acd5667 [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
203TEST(ValidateRegulatorsConfigTest, Rule)
204{
205 // valid test comments property, id property,
206 // action property specified.
207 {
208 json configFile = validConfigFile;
209 EXPECT_JSON_VALID(configFile);
210 }
211
212 // valid test rule with no comments
213 {
214 json configFile = validConfigFile;
215 configFile["rules"][0].erase("comments");
216 EXPECT_JSON_VALID(configFile);
217 }
218
219 // invalid test comments property has invalid value type
220 {
221 json configFile = validConfigFile;
222 configFile["rules"][0]["comments"] = {1};
223 EXPECT_JSON_INVALID(configFile, "Validation failed.",
224 "1 is not of type u'string'");
225 }
226
227 // invalid test rule with no ID
228 {
229 json configFile = validConfigFile;
230 configFile["rules"][0].erase("id");
231 EXPECT_JSON_INVALID(configFile, "Validation failed.",
232 "u'id' is a required property");
233 }
234
235 // invalid test id property has invalid value type (not string)
236 {
237 json configFile = validConfigFile;
238 configFile["rules"][0]["id"] = true;
239 EXPECT_JSON_INVALID(configFile, "Validation failed.",
240 "True is not of type u'string'");
241 }
242
243 // invalid test id property has invalid value
244 {
245 json configFile = validConfigFile;
246 configFile["rules"][0]["id"] = "foo%";
247 EXPECT_JSON_INVALID(configFile, "Validation failed.",
248 "u'foo%' does not match u'^[A-Za-z0-9_]+$'");
249 }
250
251 // invalid test rule with no actions property
252 {
253 json configFile = validConfigFile;
254 configFile["rules"][0].erase("actions");
255 EXPECT_JSON_INVALID(configFile, "Validation failed.",
256 "u'actions' is a required property");
257 }
258
259 // valid test rule with multiple actions
260 {
261 json configFile = validConfigFile;
262 configFile["rules"][0]["actions"][1]["run_rule"] =
263 "set_page0_voltage_rule";
264 EXPECT_JSON_VALID(configFile);
265 }
266
267 // invalid test actions property has invalid value type (not an array)
268 {
269 json configFile = validConfigFile;
270 configFile["rules"][0]["actions"] = 1;
271 EXPECT_JSON_INVALID(configFile, "Validation failed.",
272 "1 is not of type u'array'");
273 }
274
275 // invalid test actions property has invalid value of action
276 {
277 json configFile = validConfigFile;
278 configFile["rules"][0]["actions"][0] = "foo";
279 EXPECT_JSON_INVALID(configFile, "Validation failed.",
280 "u'foo' is not of type u'object'");
281 }
282
283 // invalid test actions property has empty array
284 {
285 json configFile = validConfigFile;
286 configFile["rules"][0]["actions"] = json::array();
287 EXPECT_JSON_INVALID(configFile, "Validation failed.",
288 "[] is too short");
289 }
Bob King0dcbdf52020-01-20 17:19:39 +0800290}
Bob Kingbeaf6532020-01-21 11:03:49 +0800291TEST(ValidateRegulatorsConfigTest, And)
292{
293 // Valid.
294 {
295 json configFile = validConfigFile;
296 json andAction =
297 R"(
298 {
299 "and": [
300 { "i2c_compare_byte": { "register": "0xA0", "value": "0x00" } },
301 { "i2c_compare_byte": { "register": "0xA1", "value": "0x00" } }
302 ]
303 }
304 )"_json;
305 configFile["rules"][0]["actions"].push_back(andAction);
306 EXPECT_JSON_VALID(configFile);
307 }
308
309 // Invalid: actions property value is an empty array.
310 {
311 json configFile = validConfigFile;
312 json andAction =
313 R"(
314 {
315 "and": []
316 }
317 )"_json;
318 configFile["rules"][0]["actions"].push_back(andAction);
319 EXPECT_JSON_INVALID(configFile, "Validation failed.",
320 "[] is too short");
321 }
322
323 // Invalid: actions property has incorrect value data type.
324 {
325 json configFile = validConfigFile;
326 json andAction =
327 R"(
328 {
329 "and": true
330 }
331 )"_json;
332 configFile["rules"][0]["actions"].push_back(andAction);
333 EXPECT_JSON_INVALID(configFile, "Validation failed.",
334 "True is not of type u'array'");
335 }
336
337 // Invalid: actions property value contains wrong element type
338 {
339 json configFile = validConfigFile;
340 json andAction =
341 R"(
342 {
343 "and": ["foo"]
344 }
345 )"_json;
346 configFile["rules"][0]["actions"].push_back(andAction);
347 EXPECT_JSON_INVALID(configFile, "Validation failed.",
348 "u'foo' is not of type u'object'");
349 }
350}
Bob King3728f562020-01-21 11:35:31 +0800351TEST(ValidateRegulatorsConfigTest, Chassis)
352{
353 // Valid: test chassis.
354 {
355 json configFile = validConfigFile;
356 EXPECT_JSON_VALID(configFile);
357 }
358 // Valid: test chassis with required properties.
359 {
360 json configFile = validConfigFile;
361 configFile["chassis"][0].erase("comments");
362 configFile["chassis"][0].erase("devices");
363 EXPECT_JSON_VALID(configFile);
364 }
365 // Invalid: test chassis with no number.
366 {
367 json configFile = validConfigFile;
368 configFile["chassis"][0].erase("number");
369 EXPECT_JSON_INVALID(configFile, "Validation failed.",
370 "u'number' is a required property");
371 }
372 // Invalid: test chassis with property comments wrong type.
373 {
374 json configFile = validConfigFile;
375 configFile["chassis"][0]["comments"] = true;
376 EXPECT_JSON_INVALID(configFile, "Validation failed.",
377 "True is not of type u'array'");
378 }
379 // Invalid: test chassis with property number wrong type.
380 {
381 json configFile = validConfigFile;
382 configFile["chassis"][0]["number"] = 1.3;
383 EXPECT_JSON_INVALID(configFile, "Validation failed.",
384 "1.3 is not of type u'integer'");
385 }
386 // Invalid: test chassis with property devices wrong type.
387 {
388 json configFile = validConfigFile;
389 configFile["chassis"][0]["devices"] = true;
390 EXPECT_JSON_INVALID(configFile, "Validation failed.",
391 "True is not of type u'array'");
392 }
393 // Invalid: test chassis with property comments empty array.
394 {
395 json configFile = validConfigFile;
396 configFile["chassis"][0]["comments"] = json::array();
397 EXPECT_JSON_INVALID(configFile, "Validation failed.",
398 "[] is too short");
399 }
400 // Invalid: test chassis with property devices empty array.
401 {
402 json configFile = validConfigFile;
403 configFile["chassis"][0]["devices"] = json::array();
404 EXPECT_JSON_INVALID(configFile, "Validation failed.",
405 "[] is too short");
406 }
407 // Invalid: test chassis with property number less than 1.
408 {
409 json configFile = validConfigFile;
410 configFile["chassis"][0]["number"] = 0;
411 EXPECT_JSON_INVALID(configFile, "Validation failed.",
412 "0 is less than the minimum of 1");
413 }
414}
Bob Kingbf1cbea2020-01-21 11:08:50 +0800415TEST(ValidateRegulatorsConfigTest, ComparePresence)
416{
417 json comparePresenceFile = validConfigFile;
418 comparePresenceFile["rules"][0]["actions"][1]["compare_presence"]["fru"] =
419 "/system/chassis/motherboard/regulator2";
420 comparePresenceFile["rules"][0]["actions"][1]["compare_presence"]["value"] =
421 true;
422 // Valid.
423 {
424 json configFile = comparePresenceFile;
425 EXPECT_JSON_VALID(configFile);
426 }
427
428 // Invalid: no FRU property.
429 {
430 json configFile = comparePresenceFile;
431 configFile["rules"][0]["actions"][1]["compare_presence"].erase("fru");
432 EXPECT_JSON_INVALID(configFile, "Validation failed.",
433 "u'fru' is a required property");
434 }
435
436 // Invalid: FRU property length is string less than 1.
437 {
438 json configFile = comparePresenceFile;
439 configFile["rules"][0]["actions"][1]["compare_presence"]["fru"] = "";
440 EXPECT_JSON_INVALID(configFile, "Validation failed.",
441 "u'' is too short");
442 }
443
444 // Invalid: no value property.
445 {
446 json configFile = comparePresenceFile;
447 configFile["rules"][0]["actions"][1]["compare_presence"].erase("value");
448 EXPECT_JSON_INVALID(configFile, "Validation failed.",
449 "u'value' is a required property");
450 }
451
452 // Invalid: value property type is not boolean.
453 {
454 json configFile = comparePresenceFile;
455 configFile["rules"][0]["actions"][1]["compare_presence"]["value"] = "1";
456 EXPECT_JSON_INVALID(configFile, "Validation failed.",
457 "u'1' is not of type u'boolean'");
458 }
459
460 // Invalid: FRU property type is not string.
461 {
462 json configFile = comparePresenceFile;
463 configFile["rules"][0]["actions"][1]["compare_presence"]["fru"] = 1;
464 EXPECT_JSON_INVALID(configFile, "Validation failed.",
465 "1 is not of type u'string'");
466 }
467}
Bob Kingf8b77a02020-01-21 11:09:47 +0800468TEST(ValidateRegulatorsConfigTest, CompareVpd)
469{
470 json compareVpdFile = validConfigFile;
471 compareVpdFile["rules"][0]["actions"][1]["compare_vpd"]["fru"] =
472 "/system/chassis/motherboard/regulator2";
473 compareVpdFile["rules"][0]["actions"][1]["compare_vpd"]["keyword"] = "CCIN";
474 compareVpdFile["rules"][0]["actions"][1]["compare_vpd"]["value"] = "2D35";
475
476 // Valid.
477 {
478 json configFile = compareVpdFile;
479 EXPECT_JSON_VALID(configFile);
480 }
481
482 // Invalid: no FRU property.
483 {
484 json configFile = compareVpdFile;
485 configFile["rules"][0]["actions"][1]["compare_vpd"].erase("fru");
486 EXPECT_JSON_INVALID(configFile, "Validation failed.",
487 "u'fru' is a required property");
488 }
489
490 // Invalid: no keyword property.
491 {
492 json configFile = compareVpdFile;
493 configFile["rules"][0]["actions"][1]["compare_vpd"].erase("keyword");
494 EXPECT_JSON_INVALID(configFile, "Validation failed.",
495 "u'keyword' is a required property");
496 }
497
498 // Invalid: no value property.
499 {
500 json configFile = compareVpdFile;
501 configFile["rules"][0]["actions"][1]["compare_vpd"].erase("value");
502 EXPECT_JSON_INVALID(configFile, "Validation failed.",
503 "u'value' is a required property");
504 }
505
506 // Invalid: property FRU wrong type.
507 {
508 json configFile = compareVpdFile;
509 configFile["rules"][0]["actions"][1]["compare_vpd"]["fru"] = 1;
510 EXPECT_JSON_INVALID(configFile, "Validation failed.",
511 "1 is not of type u'string'");
512 }
513
514 // Invalid: property FRU is string less than 1.
515 {
516 json configFile = compareVpdFile;
517 configFile["rules"][0]["actions"][1]["compare_vpd"]["fru"] = "";
518 EXPECT_JSON_INVALID(configFile, "Validation failed.",
519 "u'' is too short");
520 }
521
522 // Invalid: property keyword is not "CCIN", "Manufacturer", "Model",
523 // "PartNumber"
524 {
525 json configFile = compareVpdFile;
526 configFile["rules"][0]["actions"][1]["compare_vpd"]["keyword"] =
527 "Number";
528 EXPECT_JSON_INVALID(configFile, "Validation failed.",
529 "u'Number' is not one of [u'CCIN', "
530 "u'Manufacturer', u'Model', u'PartNumber']");
531 }
532
533 // Invalid: property value wrong type.
534 {
535 json configFile = compareVpdFile;
536 configFile["rules"][0]["actions"][1]["compare_vpd"]["value"] = 1;
537 EXPECT_JSON_INVALID(configFile, "Validation failed.",
538 "1 is not of type u'string'");
539 }
540}
Bob King4c67a3a2020-02-07 09:48:11 +0800541TEST(ValidateRegulatorsConfigTest, Configuration)
542{
543 json configurationFile = validConfigFile;
544 configurationFile["chassis"][0]["devices"][0]["configuration"]["comments"]
545 [0] = "Set rail to 1.25V using standard rule";
546 configurationFile["chassis"][0]["devices"][0]["configuration"]["volts"] =
547 1.25;
548 configurationFile["chassis"][0]["devices"][0]["configuration"]["rule_id"] =
549 "set_voltage_rule";
550 // Valid: test configuration with property rule_id and with no actions.
551 {
552 json configFile = configurationFile;
553 EXPECT_JSON_VALID(configFile);
554 }
555 // Valid: test configuration with property actions and with no rule_id.
556 {
557 json configFile = configurationFile;
558 configFile["chassis"][0]["devices"][0]["configuration"].erase(
559 "rule_id");
560 configFile["chassis"][0]["devices"][0]["configuration"]["actions"][0]
561 ["compare_presence"]["fru"] =
562 "/system/chassis/motherboard/cpu3";
563 configFile["chassis"][0]["devices"][0]["configuration"]["actions"][0]
564 ["compare_presence"]["value"] = true;
565 EXPECT_JSON_VALID(configFile);
566 }
567 // Valid: comments not specified (optional property).
568 {
569 json configFile = configurationFile;
570 configFile["chassis"][0]["devices"][0]["configuration"].erase(
571 "comments");
572 EXPECT_JSON_VALID(configFile);
573 }
574 // Valid: volts not specified (optional property).
575 {
576 json configFile = configurationFile;
577 configFile["chassis"][0]["devices"][0]["configuration"].erase("volts");
578 EXPECT_JSON_VALID(configFile);
579 }
580 // Valid: configuration is property of a rail (vs. a device).
581 {
582 json configFile = validConfigFile;
583 configFile["chassis"][0]["devices"][0]["rails"][0]["configuration"]
584 ["comments"][0] = "Set rail to 1.25V using standard rule";
585 configFile["chassis"][0]["devices"][0]["rails"][0]["configuration"]
586 ["volts"] = 1.25;
587 configFile["chassis"][0]["devices"][0]["rails"][0]["configuration"]
588 ["rule_id"] = "set_voltage_rule";
589 EXPECT_JSON_VALID(configFile);
590 }
591 // Invalid: comments property has wrong data type (not an array).
592 {
593 json configFile = configurationFile;
594 configFile["chassis"][0]["devices"][0]["configuration"]["comments"] = 1;
595 EXPECT_JSON_INVALID(configFile, "Validation failed.",
596 "1 is not of type u'array'");
597 }
598 // Invalid: test configuration with both actions and rule_id properties.
599 {
600 json configFile = configurationFile;
601 configFile["chassis"][0]["devices"][0]["configuration"]["actions"][0]
602 ["compare_presence"]["fru"] =
603 "/system/chassis/motherboard/cpu3";
604 configFile["chassis"][0]["devices"][0]["configuration"]["actions"][0]
605 ["compare_presence"]["value"] = true;
606 EXPECT_JSON_INVALID(
607 configFile, "Validation failed.",
608 "{u'volts': 1.25, u'comments': [u'Set rail to 1.25V using standard "
609 "rule'], u'actions': [{u'compare_presence': {u'value': True, "
610 "u'fru': u'/system/chassis/motherboard/cpu3'}}], u'rule_id': "
611 "u'set_voltage_rule'} is valid under each of {u'required': "
612 "[u'actions']}, {u'required': [u'rule_id']}");
613 }
614 // Invalid: test configuration with no rule_id and actions.
615 {
616 json configFile = configurationFile;
617 configFile["chassis"][0]["devices"][0]["configuration"].erase(
618 "rule_id");
619 EXPECT_JSON_INVALID(configFile, "Validation failed.",
620 "u'rule_id' is a required property");
621 }
622 // Invalid: test configuration with property volts wrong type.
623 {
624 json configFile = configurationFile;
625 configFile["chassis"][0]["devices"][0]["configuration"]["volts"] = true;
626 EXPECT_JSON_INVALID(configFile, "Validation failed.",
627 "True is not of type u'number'");
628 }
629 // Invalid: test configuration with property rule_id wrong type.
630 {
631 json configFile = configurationFile;
632 configFile["chassis"][0]["devices"][0]["configuration"]["rule_id"] =
633 true;
634 EXPECT_JSON_INVALID(configFile, "Validation failed.",
635 "True is not of type u'string'");
636 }
637 // Invalid: test configuration with property actions wrong type.
638 {
639 json configFile = configurationFile;
640 configFile["chassis"][0]["devices"][0]["configuration"].erase(
641 "rule_id");
642 configFile["chassis"][0]["devices"][0]["configuration"]["actions"] =
643 true;
644 EXPECT_JSON_INVALID(configFile, "Validation failed.",
645 "True is not of type u'array'");
646 }
647 // Invalid: test configuration with property comments empty array.
648 {
649 json configFile = configurationFile;
650 configFile["chassis"][0]["devices"][0]["configuration"]["comments"] =
651 json::array();
652 EXPECT_JSON_INVALID(configFile, "Validation failed.",
653 "[] is too short");
654 }
655 // Invalid: test configuration with property rule_id wrong format.
656 {
657 json configFile = configurationFile;
658 configFile["chassis"][0]["devices"][0]["configuration"]["rule_id"] =
659 "id!";
660 EXPECT_JSON_INVALID(configFile, "Validation failed.",
661 "u'id!' does not match u'^[A-Za-z0-9_]+$'");
662 }
663 // Invalid: test configuration with property actions empty array.
664 {
665 json configFile = configurationFile;
666 configFile["chassis"][0]["devices"][0]["configuration"].erase(
667 "rule_id");
668 configFile["chassis"][0]["devices"][0]["configuration"]["actions"] =
669 json::array();
670 EXPECT_JSON_INVALID(configFile, "Validation failed.",
671 "[] is too short");
672 }
673}
Bob Kinga2ba2df2020-02-04 14:38:44 +0800674TEST(ValidateRegulatorsConfigTest, Device)
675{
676
677 // Valid: test devices.
678 {
679 json configFile = validConfigFile;
680 EXPECT_JSON_VALID(configFile);
681 }
682 // Valid: test devices with required properties.
683 {
684 json configFile = validConfigFile;
685 configFile["chassis"][0]["devices"][0].erase("comments");
686 configFile["chassis"][0]["devices"][0].erase("presence_detection");
687 configFile["chassis"][0]["devices"][0].erase("configuration");
688 configFile["chassis"][0]["devices"][0].erase("rails");
689 EXPECT_JSON_VALID(configFile);
690 }
691 // Invalid: test devices with no id.
692 {
693 json configFile = validConfigFile;
694 configFile["chassis"][0]["devices"][0].erase("id");
695 EXPECT_JSON_INVALID(configFile, "Validation failed.",
696 "u'id' is a required property");
697 }
698 // Invalid: test devices with no is_regulator.
699 {
700 json configFile = validConfigFile;
701 configFile["chassis"][0]["devices"][0].erase("is_regulator");
702 EXPECT_JSON_INVALID(configFile, "Validation failed.",
703 "u'is_regulator' is a required property");
704 }
705 // Invalid: test devices with no fru.
706 {
707 json configFile = validConfigFile;
708 configFile["chassis"][0]["devices"][0].erase("fru");
709 EXPECT_JSON_INVALID(configFile, "Validation failed.",
710 "u'fru' is a required property");
711 }
712 // Invalid: test devices with no i2c_interface.
713 {
714 json configFile = validConfigFile;
715 configFile["chassis"][0]["devices"][0].erase("i2c_interface");
716 EXPECT_JSON_INVALID(configFile, "Validation failed.",
717 "u'i2c_interface' is a required property");
718 }
719 // Invalid: test devices with property comments wrong type.
720 {
721 json configFile = validConfigFile;
722 configFile["chassis"][0]["devices"][0]["comments"] = true;
723 EXPECT_JSON_INVALID(configFile, "Validation failed.",
724 "True is not of type u'array'");
725 }
726 // Invalid: test devices with property id wrong type.
727 {
728 json configFile = validConfigFile;
729 configFile["chassis"][0]["devices"][0]["id"] = true;
730 EXPECT_JSON_INVALID(configFile, "Validation failed.",
731 "True is not of type u'string'");
732 }
733 // Invalid: test devices with property is_regulator wrong type.
734 {
735 json configFile = validConfigFile;
736 configFile["chassis"][0]["devices"][0]["is_regulator"] = 1;
737 EXPECT_JSON_INVALID(configFile, "Validation failed.",
738 "1 is not of type u'boolean'");
739 }
740 // Invalid: test devices with property fru wrong type.
741 {
742 json configFile = validConfigFile;
743 configFile["chassis"][0]["devices"][0]["fru"] = true;
744 EXPECT_JSON_INVALID(configFile, "Validation failed.",
745 "True is not of type u'string'");
746 }
747 // Invalid: test devices with property i2c_interface wrong type.
748 {
749 json configFile = validConfigFile;
750 configFile["chassis"][0]["devices"][0]["i2c_interface"] = true;
751 EXPECT_JSON_INVALID(configFile, "Validation failed.",
752 "True is not of type u'object'");
753 }
754 // Invalid: test devices with property presence_detection wrong
755 // type.
756 {
757 json configFile = validConfigFile;
758 configFile["chassis"][0]["devices"][0]["presence_detection"] = true;
759 EXPECT_JSON_INVALID(configFile, "Validation failed.",
760 "True is not of type u'object'");
761 }
762 // Invalid: test devices with property configuration wrong type.
763 {
764 json configFile = validConfigFile;
765 configFile["chassis"][0]["devices"][0]["configuration"] = true;
766 EXPECT_JSON_INVALID(configFile, "Validation failed.",
767 "True is not of type u'object'");
768 }
769 // Invalid: test devices with property rails wrong type.
770 {
771 json configFile = validConfigFile;
772 configFile["chassis"][0]["devices"][0]["rails"] = true;
773 EXPECT_JSON_INVALID(configFile, "Validation failed.",
774 "True is not of type u'array'");
775 }
776 // Invalid: test devices with property comments empty array.
777 {
778 json configFile = validConfigFile;
779 configFile["chassis"][0]["devices"][0]["comments"] = json::array();
780 EXPECT_JSON_INVALID(configFile, "Validation failed.",
781 "[] is too short");
782 }
783 // Invalid: test devices with property fru length less than 1.
784 {
785 json configFile = validConfigFile;
786 configFile["chassis"][0]["devices"][0]["fru"] = "";
787 EXPECT_JSON_INVALID(configFile, "Validation failed.",
788 "u'' is too short");
789 }
790 // Invalid: test devices with property id wrong format.
791 {
792 json configFile = validConfigFile;
793 configFile["chassis"][0]["devices"][0]["id"] = "id#";
794 EXPECT_JSON_INVALID(configFile, "Validation failed.",
795 "u'id#' does not match u'^[A-Za-z0-9_]+$'");
796 }
797 // Invalid: test devices with property rails empty array.
798 {
799 json configFile = validConfigFile;
800 configFile["chassis"][0]["devices"][0]["rails"] = json::array();
801 EXPECT_JSON_INVALID(configFile, "Validation failed.",
802 "[] is too short");
803 }
804}
Bob King4ab8cbb2020-01-21 11:10:48 +0800805TEST(ValidateRegulatorsConfigTest, I2CCompareBit)
806{
807 json i2cCompareBitFile = validConfigFile;
808 i2cCompareBitFile["rules"][0]["actions"][1]["i2c_compare_bit"]["register"] =
809 "0xA0";
810 i2cCompareBitFile["rules"][0]["actions"][1]["i2c_compare_bit"]["position"] =
811 3;
812 i2cCompareBitFile["rules"][0]["actions"][1]["i2c_compare_bit"]["value"] = 1;
813 // Valid: test rule actions i2c_compare_bit.
814 {
815 json configFile = i2cCompareBitFile;
816 EXPECT_JSON_VALID(configFile);
817 }
818 // Invalid: test i2c_compare_bit with no register.
819 {
820 json configFile = i2cCompareBitFile;
821 configFile["rules"][0]["actions"][1]["i2c_compare_bit"].erase(
822 "register");
823 EXPECT_JSON_INVALID(configFile, "Validation failed.",
824 "u'register' is a required property");
825 }
826 // Invalid: test i2c_compare_bit with no position.
827 {
828 json configFile = i2cCompareBitFile;
829 configFile["rules"][0]["actions"][1]["i2c_compare_bit"].erase(
830 "position");
831 EXPECT_JSON_INVALID(configFile, "Validation failed.",
832 "u'position' is a required property");
833 }
834 // Invalid: test i2c_compare_bit with no value.
835 {
836 json configFile = i2cCompareBitFile;
837 configFile["rules"][0]["actions"][1]["i2c_compare_bit"].erase("value");
838 EXPECT_JSON_INVALID(configFile, "Validation failed.",
839 "u'value' is a required property");
840 }
841 // Invalid: test i2c_compare_bit with register wrong type.
842 {
843 json configFile = i2cCompareBitFile;
844 configFile["rules"][0]["actions"][1]["i2c_compare_bit"]["register"] = 1;
845 EXPECT_JSON_INVALID(configFile, "Validation failed.",
846 "1 is not of type u'string'");
847 }
848 // Invalid: test i2c_compare_bit with register wrong format.
849 {
850 json configFile = i2cCompareBitFile;
851 configFile["rules"][0]["actions"][1]["i2c_compare_bit"]["register"] =
852 "0xA00";
853 EXPECT_JSON_INVALID(configFile, "Validation failed.",
854 "u'0xA00' does not match u'^0x[0-9A-Fa-f]{2}$'");
855 }
856 // Invalid: test i2c_compare_bit with position wrong type.
857 {
858 json configFile = i2cCompareBitFile;
859 configFile["rules"][0]["actions"][1]["i2c_compare_bit"]["position"] =
860 3.1;
861 EXPECT_JSON_INVALID(configFile, "Validation failed.",
862 "3.1 is not of type u'integer'");
863 }
864 // Invalid: test i2c_compare_bit with position greater than 7.
865 {
866 json configFile = i2cCompareBitFile;
867 configFile["rules"][0]["actions"][1]["i2c_compare_bit"]["position"] = 8;
868 EXPECT_JSON_INVALID(configFile, "Validation failed.",
869 "8 is greater than the maximum of 7");
870 }
871 // Invalid: test i2c_compare_bit with position less than 0.
872 {
873 json configFile = i2cCompareBitFile;
874 configFile["rules"][0]["actions"][1]["i2c_compare_bit"]["position"] =
875 -1;
876 EXPECT_JSON_INVALID(configFile, "Validation failed.",
877 "-1 is less than the minimum of 0");
878 }
879 // Invalid: test i2c_compare_bit with value wrong type.
880 {
881 json configFile = i2cCompareBitFile;
882 configFile["rules"][0]["actions"][1]["i2c_compare_bit"]["value"] = "1";
883 EXPECT_JSON_INVALID(configFile, "Validation failed.",
884 "u'1' is not of type u'integer'");
885 }
886 // Invalid: test i2c_compare_bit with value greater than 1.
887 {
888 json configFile = i2cCompareBitFile;
889 configFile["rules"][0]["actions"][1]["i2c_compare_bit"]["value"] = 2;
890 EXPECT_JSON_INVALID(configFile, "Validation failed.",
891 "2 is greater than the maximum of 1");
892 }
893 // Invalid: test i2c_compare_bit with value less than 0.
894 {
895 json configFile = i2cCompareBitFile;
896 configFile["rules"][0]["actions"][1]["i2c_compare_bit"]["value"] = -1;
897 EXPECT_JSON_INVALID(configFile, "Validation failed.",
898 "-1 is less than the minimum of 0");
899 }
900}
Bob King514023d2020-01-21 11:13:05 +0800901TEST(ValidateRegulatorsConfigTest, I2CCompareByte)
902{
903 json i2cCompareByteFile = validConfigFile;
904 i2cCompareByteFile["rules"][0]["actions"][1]["i2c_compare_byte"]
905 ["register"] = "0x82";
906 i2cCompareByteFile["rules"][0]["actions"][1]["i2c_compare_byte"]["value"] =
907 "0x40";
908 i2cCompareByteFile["rules"][0]["actions"][1]["i2c_compare_byte"]["mask"] =
909 "0x7F";
910 // Valid: test i2c_compare_byte with all properties.
911 {
912 json configFile = i2cCompareByteFile;
913 EXPECT_JSON_VALID(configFile);
914 }
915 // Valid: test i2c_compare_byte with all required properties.
916 {
917 json configFile = i2cCompareByteFile;
918 configFile["rules"][0]["actions"][1]["i2c_compare_byte"].erase("mask");
919 EXPECT_JSON_VALID(configFile);
920 }
921 // Invalid: test i2c_compare_byte with no register.
922 {
923 json configFile = i2cCompareByteFile;
924 configFile["rules"][0]["actions"][1]["i2c_compare_byte"].erase(
925 "register");
926 EXPECT_JSON_INVALID(configFile, "Validation failed.",
927 "u'register' is a required property");
928 }
929 // Invalid: test i2c_compare_byte with no value.
930 {
931 json configFile = i2cCompareByteFile;
932 configFile["rules"][0]["actions"][1]["i2c_compare_byte"].erase("value");
933 EXPECT_JSON_INVALID(configFile, "Validation failed.",
934 "u'value' is a required property");
935 }
936 // Invalid: test i2c_compare_byte with property register wrong type.
937 {
938 json configFile = i2cCompareByteFile;
939 configFile["rules"][0]["actions"][1]["i2c_compare_byte"]["register"] =
940 1;
941 EXPECT_JSON_INVALID(configFile, "Validation failed.",
942 "1 is not of type u'string'");
943 }
944 // Invalid: test i2c_compare_byte with property value wrong type.
945 {
946 json configFile = i2cCompareByteFile;
947 configFile["rules"][0]["actions"][1]["i2c_compare_byte"]["value"] = 1;
948 EXPECT_JSON_INVALID(configFile, "Validation failed.",
949 "1 is not of type u'string'");
950 }
951 // Invalid: test i2c_compare_byte with property mask wrong type.
952 {
953 json configFile = i2cCompareByteFile;
954 configFile["rules"][0]["actions"][1]["i2c_compare_byte"]["mask"] = 1;
955 EXPECT_JSON_INVALID(configFile, "Validation failed.",
956 "1 is not of type u'string'");
957 }
958 // Invalid: test i2c_compare_byte with property register more than 2 hex
959 // digits.
960 {
961 json configFile = i2cCompareByteFile;
962 configFile["rules"][0]["actions"][1]["i2c_compare_byte"]["register"] =
963 "0x820";
964 EXPECT_JSON_INVALID(configFile, "Validation failed.",
965 "u'0x820' does not match u'^0x[0-9A-Fa-f]{2}$'");
966 }
967 // Invalid: test i2c_compare_byte with property value more than 2 hex
968 // digits.
969 {
970 json configFile = i2cCompareByteFile;
971 configFile["rules"][0]["actions"][1]["i2c_compare_byte"]["value"] =
972 "0x820";
973 EXPECT_JSON_INVALID(configFile, "Validation failed.",
974 "u'0x820' does not match u'^0x[0-9A-Fa-f]{2}$'");
975 }
976 // Invalid: test i2c_compare_byte with property mask more than 2 hex digits.
977 {
978 json configFile = i2cCompareByteFile;
979 configFile["rules"][0]["actions"][1]["i2c_compare_byte"]["mask"] =
980 "0x820";
981 EXPECT_JSON_INVALID(configFile, "Validation failed.",
982 "u'0x820' does not match u'^0x[0-9A-Fa-f]{2}$'");
983 }
984 // Invalid: test i2c_compare_byte with property register less than 2 hex
985 // digits.
986 {
987 json configFile = i2cCompareByteFile;
988 configFile["rules"][0]["actions"][1]["i2c_compare_byte"]["register"] =
989 "0x8";
990 EXPECT_JSON_INVALID(configFile, "Validation failed.",
991 "u'0x8' does not match u'^0x[0-9A-Fa-f]{2}$'");
992 }
993 // Invalid: test i2c_compare_byte with property value less than 2 hex
994 // digits.
995 {
996 json configFile = i2cCompareByteFile;
997 configFile["rules"][0]["actions"][1]["i2c_compare_byte"]["value"] =
998 "0x8";
999 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1000 "u'0x8' does not match u'^0x[0-9A-Fa-f]{2}$'");
1001 }
1002 // Invalid: test i2c_compare_byte with property mask less than 2 hex digits.
1003 {
1004 json configFile = i2cCompareByteFile;
1005 configFile["rules"][0]["actions"][1]["i2c_compare_byte"]["mask"] =
1006 "0x8";
1007 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1008 "u'0x8' does not match u'^0x[0-9A-Fa-f]{2}$'");
1009 }
1010 // Invalid: test i2c_compare_byte with property register no leading prefix.
1011 {
1012 json configFile = i2cCompareByteFile;
1013 configFile["rules"][0]["actions"][1]["i2c_compare_byte"]["register"] =
1014 "82";
1015 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1016 "u'82' does not match u'^0x[0-9A-Fa-f]{2}$'");
1017 }
1018 // Invalid: test i2c_compare_byte with property value no leading prefix.
1019 {
1020 json configFile = i2cCompareByteFile;
1021 configFile["rules"][0]["actions"][1]["i2c_compare_byte"]["value"] =
1022 "82";
1023 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1024 "u'82' does not match u'^0x[0-9A-Fa-f]{2}$'");
1025 }
1026 // Invalid: test i2c_compare_byte with property mask no leading prefix.
1027 {
1028 json configFile = i2cCompareByteFile;
1029 configFile["rules"][0]["actions"][1]["i2c_compare_byte"]["mask"] = "82";
1030 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1031 "u'82' does not match u'^0x[0-9A-Fa-f]{2}$'");
1032 }
1033 // Invalid: test i2c_compare_byte with property register invalid hex digit.
1034 {
1035 json configFile = i2cCompareByteFile;
1036 configFile["rules"][0]["actions"][1]["i2c_compare_byte"]["register"] =
1037 "0xG1";
1038 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1039 "u'0xG1' does not match u'^0x[0-9A-Fa-f]{2}$'");
1040 }
1041 // Invalid: test i2c_compare_byte with property value invalid hex digit.
1042 {
1043 json configFile = i2cCompareByteFile;
1044 configFile["rules"][0]["actions"][1]["i2c_compare_byte"]["value"] =
1045 "0xG1";
1046 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1047 "u'0xG1' does not match u'^0x[0-9A-Fa-f]{2}$'");
1048 }
1049 // Invalid: test i2c_compare_byte with property mask invalid hex digit.
1050 {
1051 json configFile = i2cCompareByteFile;
1052 configFile["rules"][0]["actions"][1]["i2c_compare_byte"]["mask"] =
1053 "0xG1";
1054 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1055 "u'0xG1' does not match u'^0x[0-9A-Fa-f]{2}$'");
1056 }
1057}
Bob Kingfb162bb2020-01-21 11:28:07 +08001058TEST(ValidateRegulatorsConfigTest, I2CCompareBytes)
1059{
1060 json i2cCompareBytesFile = validConfigFile;
1061 i2cCompareBytesFile["rules"][0]["actions"][1]["i2c_compare_bytes"]
1062 ["register"] = "0x82";
1063 i2cCompareBytesFile["rules"][0]["actions"][1]["i2c_compare_bytes"]
1064 ["values"] = {"0x02", "0x73"};
1065 i2cCompareBytesFile["rules"][0]["actions"][1]["i2c_compare_bytes"]
1066 ["masks"] = {"0x7F", "0x7F"};
1067 // Valid: test i2c_compare_bytes.
1068 {
1069 json configFile = i2cCompareBytesFile;
1070 EXPECT_JSON_VALID(configFile);
1071 }
1072 // Valid: test i2c_compare_bytes with all required properties.
1073 {
1074 json configFile = i2cCompareBytesFile;
1075 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"].erase(
1076 "masks");
1077 EXPECT_JSON_VALID(configFile);
1078 }
1079 // Invalid: test i2c_compare_bytes with no register.
1080 {
1081 json configFile = i2cCompareBytesFile;
1082 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"].erase(
1083 "register");
1084 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1085 "u'register' is a required property");
1086 }
1087 // Invalid: test i2c_compare_bytes with no values.
1088 {
1089 json configFile = i2cCompareBytesFile;
1090 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"].erase(
1091 "values");
1092 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1093 "u'values' is a required property");
1094 }
1095 // Invalid: test i2c_compare_bytes with property values as empty array.
1096 {
1097 json configFile = i2cCompareBytesFile;
1098 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["values"] =
1099 json::array();
1100 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1101 "[] is too short");
1102 }
1103 // Invalid: test i2c_compare_bytes with property masks as empty array.
1104 {
1105 json configFile = i2cCompareBytesFile;
1106 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["masks"] =
1107 json::array();
1108 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1109 "[] is too short");
1110 }
1111 // Invalid: test i2c_compare_bytes with property register wrong type.
1112 {
1113 json configFile = i2cCompareBytesFile;
1114 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["register"] =
1115 1;
1116 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1117 "1 is not of type u'string'");
1118 }
1119 // Invalid: test i2c_compare_bytes with property values wrong type.
1120 {
1121 json configFile = i2cCompareBytesFile;
1122 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["values"] = 1;
1123 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1124 "1 is not of type u'array'");
1125 }
1126 // Invalid: test i2c_compare_bytes with property masks wrong type.
1127 {
1128 json configFile = i2cCompareBytesFile;
1129 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["masks"] = 1;
1130 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1131 "1 is not of type u'array'");
1132 }
1133 // Invalid: test i2c_compare_bytes with property register more than 2 hex
1134 // digits.
1135 {
1136 json configFile = i2cCompareBytesFile;
1137 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["register"] =
1138 "0x820";
1139 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1140 "u'0x820' does not match u'^0x[0-9A-Fa-f]{2}$'");
1141 }
1142 // Invalid: test i2c_compare_bytes with property values more than 2 hex
1143 // digits.
1144 {
1145 json configFile = i2cCompareBytesFile;
1146 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["values"][0] =
1147 "0x820";
1148 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1149 "u'0x820' does not match u'^0x[0-9A-Fa-f]{2}$'");
1150 }
1151 // Invalid: test i2c_compare_bytes with property masks more than 2 hex
1152 // digits.
1153 {
1154 json configFile = i2cCompareBytesFile;
1155 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["masks"][0] =
1156 "0x820";
1157 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1158 "u'0x820' does not match u'^0x[0-9A-Fa-f]{2}$'");
1159 }
1160 // Invalid: test i2c_compare_bytes with property register less than 2 hex
1161 // digits.
1162 {
1163 json configFile = i2cCompareBytesFile;
1164 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["register"] =
1165 "0x8";
1166 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1167 "u'0x8' does not match u'^0x[0-9A-Fa-f]{2}$'");
1168 }
1169 // Invalid: test i2c_compare_bytes with property values less than 2 hex
1170 // digits.
1171 {
1172 json configFile = i2cCompareBytesFile;
1173 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["values"][0] =
1174 "0x8";
1175 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1176 "u'0x8' does not match u'^0x[0-9A-Fa-f]{2}$'");
1177 }
1178 // Invalid: test i2c_compare_bytes with property masks less than 2 hex
1179 // digits.
1180 {
1181 json configFile = i2cCompareBytesFile;
1182 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["masks"][0] =
1183 "0x8";
1184 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1185 "u'0x8' does not match u'^0x[0-9A-Fa-f]{2}$'");
1186 }
1187 // Invalid: test i2c_compare_bytes with property register no leading prefix.
1188 {
1189 json configFile = i2cCompareBytesFile;
1190 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["register"] =
1191 "82";
1192 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1193 "u'82' does not match u'^0x[0-9A-Fa-f]{2}$'");
1194 }
1195 // Invalid: test i2c_compare_bytes with property values no leading prefix.
1196 {
1197 json configFile = i2cCompareBytesFile;
1198 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["values"][0] =
1199 "82";
1200 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1201 "u'82' does not match u'^0x[0-9A-Fa-f]{2}$'");
1202 }
1203 // Invalid: test i2c_compare_bytes with property masks no leading prefix.
1204 {
1205 json configFile = i2cCompareBytesFile;
1206 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["masks"][0] =
1207 "82";
1208 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1209 "u'82' does not match u'^0x[0-9A-Fa-f]{2}$'");
1210 }
1211 // Invalid: test i2c_compare_bytes with property register invalid hex digit.
1212 {
1213 json configFile = i2cCompareBytesFile;
1214 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["register"] =
1215 "0xG1";
1216 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1217 "u'0xG1' does not match u'^0x[0-9A-Fa-f]{2}$'");
1218 }
1219 // Invalid: test i2c_compare_bytes with property values invalid hex digit.
1220 {
1221 json configFile = i2cCompareBytesFile;
1222 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["values"][0] =
1223 "0xG1";
1224 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1225 "u'0xG1' does not match u'^0x[0-9A-Fa-f]{2}$'");
1226 }
1227 // Invalid: test i2c_compare_bytes with property masks invalid hex digit.
1228 {
1229 json configFile = i2cCompareBytesFile;
1230 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["masks"][0] =
1231 "0xG1";
1232 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1233 "u'0xG1' does not match u'^0x[0-9A-Fa-f]{2}$'");
1234 }
1235}
Bob Kingca93f1f2020-01-31 11:21:16 +08001236TEST(ValidateRegulatorsConfigTest, I2CInterface)
1237{
1238 // Valid: test i2c_interface.
1239 {
1240 json configFile = validConfigFile;
1241 EXPECT_JSON_VALID(configFile);
1242 }
1243 // Invalid: testi2c_interface with no bus.
1244 {
1245 json configFile = validConfigFile;
1246 configFile["chassis"][0]["devices"][0]["i2c_interface"].erase("bus");
1247 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1248 "u'bus' is a required property");
1249 }
1250 // Invalid: test i2c_interface with no address.
1251 {
1252 json configFile = validConfigFile;
1253 configFile["chassis"][0]["devices"][0]["i2c_interface"].erase(
1254 "address");
1255 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1256 "u'address' is a required property");
1257 }
1258 // Invalid: test i2c_interface with property bus wrong type.
1259 {
1260 json configFile = validConfigFile;
1261 configFile["chassis"][0]["devices"][0]["i2c_interface"]["bus"] = true;
1262 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1263 "True is not of type u'integer'");
1264 }
1265 // Invalid: test i2c_interface with property address wrong
1266 // type.
1267 {
1268 json configFile = validConfigFile;
1269 configFile["chassis"][0]["devices"][0]["i2c_interface"]["address"] =
1270 true;
1271 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1272 "True is not of type u'string'");
1273 }
1274 // Invalid: test i2c_interface with property bus less than
1275 // 0.
1276 {
1277 json configFile = validConfigFile;
1278 configFile["chassis"][0]["devices"][0]["i2c_interface"]["bus"] = -1;
1279 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1280 "-1 is less than the minimum of 0");
1281 }
1282 // Invalid: test i2c_interface with property address wrong
1283 // format.
1284 {
1285 json configFile = validConfigFile;
1286 configFile["chassis"][0]["devices"][0]["i2c_interface"]["address"] =
1287 "0x700";
1288 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1289 "u'0x700' does not match u'^0x[0-9A-Fa-f]{2}$'");
1290 }
1291}
Bob Kingead0b052020-01-21 11:29:03 +08001292TEST(ValidateRegulatorsConfigTest, If)
1293{
1294 json ifFile = validConfigFile;
1295 ifFile["rules"][0]["actions"][1]["if"]["condition"]["run_rule"] =
1296 "is_downlevel_regulator";
1297 ifFile["rules"][0]["actions"][1]["if"]["then"][0]["run_rule"] =
1298 "configure_downlevel_regulator";
1299 ifFile["rules"][0]["actions"][1]["if"]["else"][0]["run_rule"] =
1300 "configure_downlevel_regulator";
1301 // Valid: test if.
1302 {
1303 json configFile = ifFile;
1304 EXPECT_JSON_VALID(configFile);
1305 }
1306 // Valid: test if with required properties.
1307 {
1308 json configFile = ifFile;
1309 configFile["rules"][0]["actions"][1]["if"].erase("else");
1310 EXPECT_JSON_VALID(configFile);
1311 }
1312 // Invalid: test if with no property condition.
1313 {
1314 json configFile = ifFile;
1315 configFile["rules"][0]["actions"][1]["if"].erase("condition");
1316 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1317 "u'condition' is a required property");
1318 }
1319 // Invalid: test if with no property then.
1320 {
1321 json configFile = ifFile;
1322 configFile["rules"][0]["actions"][1]["if"].erase("then");
1323 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1324 "u'then' is a required property");
1325 }
1326 // Invalid: test if with property then empty array.
1327 {
1328 json configFile = ifFile;
1329 configFile["rules"][0]["actions"][1]["if"]["then"] = json::array();
1330 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1331 "[] is too short");
1332 }
1333 // Invalid: test if with property else empty array.
1334 {
1335 json configFile = ifFile;
1336 configFile["rules"][0]["actions"][1]["if"]["else"] = json::array();
1337 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1338 "[] is too short");
1339 }
1340 // Invalid: test if with property condition wrong type.
1341 {
1342 json configFile = ifFile;
1343 configFile["rules"][0]["actions"][1]["if"]["condition"] = 1;
1344 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1345 "1 is not of type u'object'");
1346 }
1347 // Invalid: test if with property then wrong type.
1348 {
1349 json configFile = ifFile;
1350 configFile["rules"][0]["actions"][1]["if"]["then"] = 1;
1351 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1352 "1 is not of type u'array'");
1353 }
1354 // Invalid: test if with property else wrong type.
1355 {
1356 json configFile = ifFile;
1357 configFile["rules"][0]["actions"][1]["if"]["else"] = 1;
1358 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1359 "1 is not of type u'array'");
1360 }
1361}
Bob Kingbfe9fe72020-01-21 11:29:57 +08001362TEST(ValidateRegulatorsConfigTest, Not)
1363{
1364 json notFile = validConfigFile;
1365 notFile["rules"][0]["actions"][1]["not"]["i2c_compare_byte"]["register"] =
1366 "0xA0";
1367 notFile["rules"][0]["actions"][1]["not"]["i2c_compare_byte"]["value"] =
1368 "0xFF";
1369 // Valid: test not.
1370 {
1371 json configFile = notFile;
1372 EXPECT_JSON_VALID(configFile);
1373 }
1374 // Invalid: test not with wrong type.
1375 {
1376 json configFile = notFile;
1377 configFile["rules"][0]["actions"][1]["not"] = 1;
1378 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1379 "1 is not of type u'object'");
1380 }
1381}
Bob Kingcfc29d02020-01-21 11:30:50 +08001382TEST(ValidateRegulatorsConfigTest, Or)
1383{
1384 json orFile = validConfigFile;
1385 orFile["rules"][0]["actions"][1]["or"][0]["i2c_compare_byte"]["register"] =
1386 "0xA0";
1387 orFile["rules"][0]["actions"][1]["or"][0]["i2c_compare_byte"]["value"] =
1388 "0x00";
1389 orFile["rules"][0]["actions"][1]["or"][1]["i2c_compare_byte"]["register"] =
1390 "0xA1";
1391 orFile["rules"][0]["actions"][1]["or"][1]["i2c_compare_byte"]["value"] =
1392 "0x00";
1393 // Valid: test or.
1394 {
1395 json configFile = orFile;
1396 EXPECT_JSON_VALID(configFile);
1397 }
1398 // Invalid: test or with empty array.
1399 {
1400 json configFile = orFile;
1401 configFile["rules"][0]["actions"][1]["or"] = json::array();
1402 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1403 "[] is too short");
1404 }
1405 // Invalid: test or with wrong type.
1406 {
1407 json configFile = orFile;
1408 configFile["rules"][0]["actions"][1]["or"] = 1;
1409 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1410 "1 is not of type u'array'");
1411 }
1412}
Bob Kingd6618092020-01-21 11:31:46 +08001413TEST(ValidateRegulatorsConfigTest, PmbusReadSensor)
1414{
1415 json pmbusReadSensorFile = validConfigFile;
1416 pmbusReadSensorFile["rules"][0]["actions"][1]["pmbus_read_sensor"]["type"] =
1417 "vout";
1418 pmbusReadSensorFile["rules"][0]["actions"][1]["pmbus_read_sensor"]
1419 ["command"] = "0x8B";
1420 pmbusReadSensorFile["rules"][0]["actions"][1]["pmbus_read_sensor"]
1421 ["format"] = "linear_16";
1422 pmbusReadSensorFile["rules"][0]["actions"][1]["pmbus_read_sensor"]
1423 ["exponent"] = -8;
1424 // Valid: test pmbus_read_sensor.
1425 {
1426 json configFile = pmbusReadSensorFile;
1427 EXPECT_JSON_VALID(configFile);
1428 }
1429 // Valid: test pmbus_read_sensor with required properties.
1430 {
1431 json configFile = pmbusReadSensorFile;
1432 configFile["rules"][0]["actions"][1]["pmbus_read_sensor"].erase(
1433 "exponent");
1434 EXPECT_JSON_VALID(configFile);
1435 }
1436 // Invalid: test pmbus_read_sensor with no type.
1437 {
1438 json configFile = pmbusReadSensorFile;
1439 configFile["rules"][0]["actions"][1]["pmbus_read_sensor"].erase("type");
1440 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1441 "u'type' is a required property");
1442 }
1443 // Invalid: test pmbus_read_sensor with no command.
1444 {
1445 json configFile = pmbusReadSensorFile;
1446 configFile["rules"][0]["actions"][1]["pmbus_read_sensor"].erase(
1447 "command");
1448 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1449 "u'command' is a required property");
1450 }
1451 // Invalid: test pmbus_read_sensor with no format.
1452 {
1453 json configFile = pmbusReadSensorFile;
1454 configFile["rules"][0]["actions"][1]["pmbus_read_sensor"].erase(
1455 "format");
1456 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1457 "u'format' is a required property");
1458 }
1459 // Invalid: test pmbus_read_sensor with property type wrong type.
1460 {
1461 json configFile = pmbusReadSensorFile;
1462 configFile["rules"][0]["actions"][1]["pmbus_read_sensor"]["type"] =
1463 true;
1464 EXPECT_JSON_INVALID(
1465 configFile, "Validation failed.",
1466 "True is not one of [u'iout', u'iout_peak', u'iout_valley', "
1467 "u'pout', u'temperature', u'temperature_peak', u'vout', "
1468 "u'vout_peak', u'vout_valley']");
1469 }
1470 // Invalid: test pmbus_read_sensor with property command wrong type.
1471 {
1472 json configFile = pmbusReadSensorFile;
1473 configFile["rules"][0]["actions"][1]["pmbus_read_sensor"]["command"] =
1474 true;
1475 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1476 "True is not of type u'string'");
1477 }
1478 // Invalid: test pmbus_read_sensor with property format wrong type.
1479 {
1480 json configFile = pmbusReadSensorFile;
1481 configFile["rules"][0]["actions"][1]["pmbus_read_sensor"]["format"] =
1482 true;
1483 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1484 "True is not one of [u'linear_11', u'linear_16']");
1485 }
1486 // Invalid: test pmbus_read_sensor with property exponent wrong type.
1487 {
1488 json configFile = pmbusReadSensorFile;
1489 configFile["rules"][0]["actions"][1]["pmbus_read_sensor"]["exponent"] =
1490 true;
1491 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1492 "True is not of type u'integer'");
1493 }
1494 // Invalid: test pmbus_read_sensor with property type wrong format.
1495 {
1496 json configFile = pmbusReadSensorFile;
1497 configFile["rules"][0]["actions"][1]["pmbus_read_sensor"]["type"] =
1498 "foo";
1499 EXPECT_JSON_INVALID(
1500 configFile, "Validation failed.",
1501 "u'foo' is not one of [u'iout', u'iout_peak', u'iout_valley', "
1502 "u'pout', u'temperature', u'temperature_peak', u'vout', "
1503 "u'vout_peak', u'vout_valley']");
1504 }
1505 // Invalid: test pmbus_read_sensor with property command wrong format.
1506 {
1507 json configFile = pmbusReadSensorFile;
1508 configFile["rules"][0]["actions"][1]["pmbus_read_sensor"]["command"] =
1509 "0x8B0";
1510 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1511 "u'0x8B0' does not match u'^0x[0-9a-fA-F]{2}$'");
1512 }
1513 // Invalid: test pmbus_read_sensor with property format wrong format.
1514 {
1515 json configFile = pmbusReadSensorFile;
1516 configFile["rules"][0]["actions"][1]["pmbus_read_sensor"]["format"] =
1517 "foo";
1518 EXPECT_JSON_INVALID(
1519 configFile, "Validation failed.",
1520 "u'foo' is not one of [u'linear_11', u'linear_16']");
1521 }
1522}
Bob King02179c62020-01-21 11:32:36 +08001523TEST(ValidateRegulatorsConfigTest, PmbusWriteVoutCommand)
1524{
1525 json pmbusWriteVoutCommandFile = validConfigFile;
1526 pmbusWriteVoutCommandFile["rules"][0]["actions"][1]
1527 ["pmbus_write_vout_command"]["volts"] = 1.03;
1528 pmbusWriteVoutCommandFile["rules"][0]["actions"][1]
1529 ["pmbus_write_vout_command"]["format"] = "linear";
1530 pmbusWriteVoutCommandFile["rules"][0]["actions"][1]
1531 ["pmbus_write_vout_command"]["exponent"] = -8;
1532 pmbusWriteVoutCommandFile["rules"][0]["actions"][1]
1533 ["pmbus_write_vout_command"]["is_verified"] = true;
1534 // Valid: test pmbus_write_vout_command.
1535 {
1536 json configFile = pmbusWriteVoutCommandFile;
1537 EXPECT_JSON_VALID(configFile);
1538 }
1539 // Valid: test pmbus_write_vout_command with required properties.
1540 {
1541 json configFile = pmbusWriteVoutCommandFile;
1542 configFile["rules"][0]["actions"][1]["pmbus_write_vout_command"].erase(
1543 "volts");
1544 configFile["rules"][0]["actions"][1]["pmbus_write_vout_command"].erase(
1545 "exponent");
1546 configFile["rules"][0]["actions"][1]["pmbus_write_vout_command"].erase(
1547 "is_verified");
1548 EXPECT_JSON_VALID(configFile);
1549 }
1550 // Invalid: test pmbus_write_vout_command with no format.
1551 {
1552 json configFile = pmbusWriteVoutCommandFile;
1553 configFile["rules"][0]["actions"][1]["pmbus_write_vout_command"].erase(
1554 "format");
1555 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1556 "u'format' is a required property");
1557 }
1558 // Invalid: test pmbus_write_vout_command with property volts wrong type.
1559 {
1560 json configFile = pmbusWriteVoutCommandFile;
1561 configFile["rules"][0]["actions"][1]["pmbus_write_vout_command"]
1562 ["volts"] = true;
1563 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1564 "True is not of type u'number'");
1565 }
1566 // Invalid: test pmbus_write_vout_command with property format wrong type.
1567 {
1568 json configFile = pmbusWriteVoutCommandFile;
1569 configFile["rules"][0]["actions"][1]["pmbus_write_vout_command"]
1570 ["format"] = true;
1571 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1572 "True is not one of [u'linear']");
1573 }
1574 // Invalid: test pmbus_write_vout_command with property exponent wrong type.
1575 {
1576 json configFile = pmbusWriteVoutCommandFile;
1577 configFile["rules"][0]["actions"][1]["pmbus_write_vout_command"]
1578 ["exponent"] = 1.3;
1579 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1580 "1.3 is not of type u'integer'");
1581 }
1582 // Invalid: test pmbus_write_vout_command with property is_verified wrong
1583 // type.
1584 {
1585 json configFile = pmbusWriteVoutCommandFile;
1586 configFile["rules"][0]["actions"][1]["pmbus_write_vout_command"]
1587 ["is_verified"] = 1;
1588 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1589 "1 is not of type u'boolean'");
1590 }
1591 // Invalid: test pmbus_write_vout_command with property format wrong format.
1592 {
1593 json configFile = pmbusWriteVoutCommandFile;
1594 configFile["rules"][0]["actions"][1]["pmbus_write_vout_command"]
1595 ["format"] = "foo";
1596 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1597 "u'foo' is not one of [u'linear']");
1598 }
1599}
Bob King99d8fa12020-01-31 11:23:40 +08001600TEST(ValidateRegulatorsConfigTest, PresenceDetection)
1601{
1602 json presenceDetectionFile = validConfigFile;
1603 presenceDetectionFile
1604 ["chassis"][0]["devices"][0]["presence_detection"]["comments"][0] =
1605 "Regulator is only present on the FooBar backplane";
1606 presenceDetectionFile["chassis"][0]["devices"][0]["presence_detection"]
1607 ["rule_id"] = "is_foobar_backplane_installed_rule";
1608 // Valid: test presence_detection with only property rule_id.
1609 {
1610 json configFile = presenceDetectionFile;
1611 EXPECT_JSON_VALID(configFile);
1612 }
1613 // Valid: test presence_detection with only property actions.
1614 {
1615 json configFile = presenceDetectionFile;
1616 configFile["chassis"][0]["devices"][0]["presence_detection"].erase(
1617 "rule_id");
1618 configFile["chassis"][0]["devices"][0]["presence_detection"]["actions"]
1619 [0]["compare_presence"]["fru"] =
1620 "/system/chassis/motherboard/cpu3";
1621 configFile["chassis"][0]["devices"][0]["presence_detection"]["actions"]
1622 [0]["compare_presence"]["value"] = true;
1623 configFile["chassis"][0]["devices"][0]["presence_detection"].erase(
1624 "comments");
1625 EXPECT_JSON_VALID(configFile);
1626 }
1627 // Invalid: test presence_detection with both property rule_id and actions.
1628 {
1629 json configFile = presenceDetectionFile;
1630 configFile["chassis"][0]["devices"][0]["presence_detection"]["actions"]
1631 [0]["compare_presence"]["fru"] =
1632 "/system/chassis/motherboard/cpu3";
1633 configFile["chassis"][0]["devices"][0]["presence_detection"]["actions"]
1634 [0]["compare_presence"]["value"] = true;
1635 EXPECT_JSON_INVALID(
1636 configFile, "Validation failed.",
1637 "{u'comments': [u'Regulator is only present on the FooBar "
1638 "backplane'], u'actions': [{u'compare_presence': {u'value': True, "
1639 "u'fru': u'/system/chassis/motherboard/cpu3'}}], u'rule_id': "
1640 "u'is_foobar_backplane_installed_rule'} is valid under each of "
1641 "{u'required': [u'actions']}, {u'required': [u'rule_id']}");
1642 }
1643 // Invalid: test presence_detection with no rule_id and actions.
1644 {
1645 json configFile = presenceDetectionFile;
1646 configFile["chassis"][0]["devices"][0]["presence_detection"].erase(
1647 "rule_id");
1648 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1649 "u'rule_id' is a required property");
1650 }
1651 // Invalid: test presence_detection with property comments wrong type.
1652 {
1653 json configFile = presenceDetectionFile;
1654 configFile["chassis"][0]["devices"][0]["presence_detection"]
1655 ["comments"] = true;
1656 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1657 "True is not of type u'array'");
1658 }
1659 // Invalid: test presence_detection with property rule_id wrong type.
1660 {
1661 json configFile = presenceDetectionFile;
1662 configFile["chassis"][0]["devices"][0]["presence_detection"]
1663 ["rule_id"] = true;
1664 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1665 "True is not of type u'string'");
1666 }
1667 // Invalid: test presence_detection with property actions wrong type.
1668 {
1669 json configFile = presenceDetectionFile;
1670 configFile["chassis"][0]["devices"][0]["presence_detection"].erase(
1671 "rule_id");
1672 configFile["chassis"][0]["devices"][0]["presence_detection"]
1673 ["actions"] = true;
1674 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1675 "True is not of type u'array'");
1676 }
1677 // Invalid: test presence_detection with property rule_id wrong format.
1678 {
1679 json configFile = presenceDetectionFile;
1680 configFile["chassis"][0]["devices"][0]["presence_detection"]
1681 ["rule_id"] = "id@";
1682 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1683 "u'id@' does not match u'^[A-Za-z0-9_]+$'");
1684 }
1685 // Invalid: test presence_detection with property comments empty array.
1686 {
1687 json configFile = presenceDetectionFile;
1688 configFile["chassis"][0]["devices"][0]["presence_detection"]
1689 ["comments"] = json::array();
1690 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1691 "[] is too short");
1692 }
1693 // Invalid: test presence_detection with property actions empty array.
1694 {
1695 json configFile = presenceDetectionFile;
1696 configFile["chassis"][0]["devices"][0]["presence_detection"].erase(
1697 "rule_id");
1698 configFile["chassis"][0]["devices"][0]["presence_detection"]
1699 ["actions"] = json::array();
1700 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1701 "[] is too short");
1702 }
1703}
Bob Kinge9260b52020-01-21 11:46:13 +08001704TEST(ValidateRegulatorsConfigTest, Rail)
1705{
1706 // Valid: test rail.
1707 {
1708 json configFile = validConfigFile;
1709 EXPECT_JSON_VALID(configFile);
1710 }
1711 // Valid: test rail with required properties.
1712 {
1713 json configFile = validConfigFile;
1714 configFile["chassis"][0]["devices"][0]["rails"][0].erase("comments");
1715 configFile["chassis"][0]["devices"][0]["rails"][0].erase(
1716 "configuration");
1717 configFile["chassis"][0]["devices"][0]["rails"][0].erase(
1718 "sensor_monitoring");
1719 EXPECT_JSON_VALID(configFile);
1720 }
1721 // Invalid: test rail with no id.
1722 {
1723 json configFile = validConfigFile;
1724 configFile["chassis"][0]["devices"][0]["rails"][0].erase("id");
1725 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1726 "u'id' is a required property");
1727 }
1728 // Invalid: test rail with comments wrong type.
1729 {
1730 json configFile = validConfigFile;
1731 configFile["chassis"][0]["devices"][0]["rails"][0]["comments"] = true;
1732 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1733 "True is not of type u'array'");
1734 }
1735 // Invalid: test rail with id wrong type.
1736 {
1737 json configFile = validConfigFile;
1738 configFile["chassis"][0]["devices"][0]["rails"][0]["id"] = true;
1739 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1740 "True is not of type u'string'");
1741 }
1742 // Invalid: test rail with configuration wrong type.
1743 {
1744 json configFile = validConfigFile;
1745 configFile["chassis"][0]["devices"][0]["rails"][0]["configuration"] =
1746 true;
1747 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1748 "True is not of type u'object'");
1749 }
1750 // Invalid: test rail with sensor_monitoring wrong type.
1751 {
1752 json configFile = validConfigFile;
1753 configFile["chassis"][0]["devices"][0]["rails"][0]
1754 ["sensor_monitoring"] = true;
1755 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1756 "True is not of type u'object'");
1757 }
1758 // Invalid: test rail with comments empty array.
1759 {
1760 json configFile = validConfigFile;
1761 configFile["chassis"][0]["devices"][0]["rails"][0]["comments"] =
1762 json::array();
1763 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1764 "[] is too short");
1765 }
1766 // Invalid: test rail with id wrong format.
1767 {
1768 json configFile = validConfigFile;
1769 configFile["chassis"][0]["devices"][0]["rails"][0]["id"] = "id~";
1770 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1771 "u'id~' does not match u'^[A-Za-z0-9_]+$'");
1772 }
1773}
Bob Kinge86c2e52020-01-21 11:33:32 +08001774TEST(ValidateRegulatorsConfigTest, RunRule)
1775{
1776 json runRuleFile = validConfigFile;
1777 runRuleFile["rules"][0]["actions"][1]["run_rule"] = "set_voltage_rule1";
1778 // Valid: test run_rule.
1779 {
1780 json configFile = runRuleFile;
1781 EXPECT_JSON_VALID(configFile);
1782 }
1783 // Invalid: test run_rule wrong type.
1784 {
1785 json configFile = runRuleFile;
1786 configFile["rules"][0]["actions"][1]["run_rule"] = true;
1787 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1788 "True is not of type u'string'");
1789 }
1790 // Invalid: test run_rule wrong format.
1791 {
1792 json configFile = runRuleFile;
1793 configFile["rules"][0]["actions"][1]["run_rule"] = "set_voltage_rule%";
1794 EXPECT_JSON_INVALID(
1795 configFile, "Validation failed.",
1796 "u'set_voltage_rule%' does not match u'^[A-Za-z0-9_]+$'");
1797 }
1798}
Bob Kingfcc2a2f2020-01-31 11:29:45 +08001799TEST(ValidateRegulatorsConfigTest, SensorMonitoring)
1800{
1801 // Valid: test rails sensor_monitoring with only property rule id.
1802 {
1803 json configFile = validConfigFile;
1804 EXPECT_JSON_VALID(configFile);
1805 }
1806 // Valid: test rails sensor_monitoring with only property actions.
1807 {
1808 json configFile = validConfigFile;
1809 configFile["chassis"][0]["devices"][0]["rails"][0]["sensor_monitoring"]
1810 .erase("rule_id");
1811 configFile["chassis"][0]["devices"][0]["rails"][0]["sensor_monitoring"]
1812 ["actions"][0]["compare_presence"]["fru"] =
1813 "/system/chassis/motherboard/cpu3";
1814 configFile["chassis"][0]["devices"][0]["rails"][0]["sensor_monitoring"]
1815 ["actions"][0]["compare_presence"]["value"] = true;
1816 configFile["chassis"][0]["devices"][0]["rails"][0]["sensor_monitoring"]
1817 ["comments"][0] = "comments";
1818 EXPECT_JSON_VALID(configFile);
1819 }
1820 // Invalid: test rails sensor_monitoring with both property rule_id and
1821 // actions.
1822 {
1823 json configFile = validConfigFile;
1824 configFile["chassis"][0]["devices"][0]["rails"][0]["sensor_monitoring"]
1825 ["actions"][0]["compare_presence"]["fru"] =
1826 "/system/chassis/motherboard/cpu3";
1827 configFile["chassis"][0]["devices"][0]["rails"][0]["sensor_monitoring"]
1828 ["actions"][0]["compare_presence"]["value"] = true;
1829 EXPECT_JSON_INVALID(
1830 configFile, "Validation failed.",
1831 "{u'rule_id': u'read_sensors_rule', u'actions': "
1832 "[{u'compare_presence': {u'value': True, u'fru': "
1833 "u'/system/chassis/motherboard/cpu3'}}]} is valid under each of "
1834 "{u'required': [u'actions']}, {u'required': [u'rule_id']}");
1835 }
1836 // Invalid: test rails sensor_monitoring with no rule_id and actions.
1837 {
1838 json configFile = validConfigFile;
1839 configFile["chassis"][0]["devices"][0]["rails"][0]["sensor_monitoring"]
1840 .erase("rule_id");
1841 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1842 "u'rule_id' is a required property");
1843 }
1844 // Invalid: test rails sensor_monitoring with property comments wrong type.
1845 {
1846 json configFile = validConfigFile;
1847 configFile["chassis"][0]["devices"][0]["rails"][0]["sensor_monitoring"]
1848 ["comments"] = true;
1849 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1850 "True is not of type u'array'");
1851 }
1852 // Invalid: test rails sensor_monitoring with property rule_id wrong type.
1853 {
1854 json configFile = validConfigFile;
1855 configFile["chassis"][0]["devices"][0]["rails"][0]["sensor_monitoring"]
1856 ["rule_id"] = true;
1857 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1858 "True is not of type u'string'");
1859 }
1860 // Invalid: test rails sensor_monitoring with property actions wrong type.
1861 {
1862 json configFile = validConfigFile;
1863 configFile["chassis"][0]["devices"][0]["rails"][0]["sensor_monitoring"]
1864 .erase("rule_id");
1865 configFile["chassis"][0]["devices"][0]["rails"][0]["sensor_monitoring"]
1866 ["actions"] = true;
1867 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1868 "True is not of type u'array'");
1869 }
1870 // Invalid: test rails sensor_monitoring with property rule_id wrong format.
1871 {
1872 json configFile = validConfigFile;
1873 configFile["chassis"][0]["devices"][0]["rails"][0]["sensor_monitoring"]
1874 ["rule_id"] = "id@";
1875 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1876 "u'id@' does not match u'^[A-Za-z0-9_]+$'");
1877 }
1878 // Invalid: test rails sensor_monitoring with property comments empty array.
1879 {
1880 json configFile = validConfigFile;
1881 configFile["chassis"][0]["devices"][0]["rails"][0]["sensor_monitoring"]
1882 ["comments"] = json::array();
1883 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1884 "[] is too short");
1885 }
1886 // Invalid: test rails sensor_monitoring with property actions empty array.
1887 {
1888 json configFile = validConfigFile;
1889 configFile["chassis"][0]["devices"][0]["rails"][0]["sensor_monitoring"]
1890 .erase("rule_id");
1891 configFile["chassis"][0]["devices"][0]["rails"][0]["sensor_monitoring"]
1892 ["actions"] = json::array();
1893 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1894 "[] is too short");
1895 }
1896}
Bob King68230aa2020-01-21 11:34:33 +08001897TEST(ValidateRegulatorsConfigTest, SetDevice)
1898{
1899 json setDeviceFile = validConfigFile;
1900 setDeviceFile["rules"][0]["actions"][1]["set_device"] = "io_expander2";
1901 // Valid: test set_device.
1902 {
1903 json configFile = setDeviceFile;
1904 EXPECT_JSON_VALID(configFile);
1905 }
1906 // Invalid: test set_device wrong type.
1907 {
1908 json configFile = setDeviceFile;
1909 configFile["rules"][0]["actions"][1]["set_device"] = true;
1910 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1911 "True is not of type u'string'");
1912 }
1913 // Invalid: test set_device wrong format.
1914 {
1915 json configFile = setDeviceFile;
1916 configFile["rules"][0]["actions"][1]["set_device"] = "io_expander2%";
1917 EXPECT_JSON_INVALID(
1918 configFile, "Validation failed.",
1919 "u'io_expander2%' does not match u'^[A-Za-z0-9_]+$'");
1920 }
1921}