blob: 7eff9381d05f2d4549df659d29c9f7f3d365f93f [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 King4ab8cbb2020-01-21 11:10:48 +0800541TEST(ValidateRegulatorsConfigTest, I2CCompareBit)
542{
543 json i2cCompareBitFile = validConfigFile;
544 i2cCompareBitFile["rules"][0]["actions"][1]["i2c_compare_bit"]["register"] =
545 "0xA0";
546 i2cCompareBitFile["rules"][0]["actions"][1]["i2c_compare_bit"]["position"] =
547 3;
548 i2cCompareBitFile["rules"][0]["actions"][1]["i2c_compare_bit"]["value"] = 1;
549 // Valid: test rule actions i2c_compare_bit.
550 {
551 json configFile = i2cCompareBitFile;
552 EXPECT_JSON_VALID(configFile);
553 }
554 // Invalid: test i2c_compare_bit with no register.
555 {
556 json configFile = i2cCompareBitFile;
557 configFile["rules"][0]["actions"][1]["i2c_compare_bit"].erase(
558 "register");
559 EXPECT_JSON_INVALID(configFile, "Validation failed.",
560 "u'register' is a required property");
561 }
562 // Invalid: test i2c_compare_bit with no position.
563 {
564 json configFile = i2cCompareBitFile;
565 configFile["rules"][0]["actions"][1]["i2c_compare_bit"].erase(
566 "position");
567 EXPECT_JSON_INVALID(configFile, "Validation failed.",
568 "u'position' is a required property");
569 }
570 // Invalid: test i2c_compare_bit with no value.
571 {
572 json configFile = i2cCompareBitFile;
573 configFile["rules"][0]["actions"][1]["i2c_compare_bit"].erase("value");
574 EXPECT_JSON_INVALID(configFile, "Validation failed.",
575 "u'value' is a required property");
576 }
577 // Invalid: test i2c_compare_bit with register wrong type.
578 {
579 json configFile = i2cCompareBitFile;
580 configFile["rules"][0]["actions"][1]["i2c_compare_bit"]["register"] = 1;
581 EXPECT_JSON_INVALID(configFile, "Validation failed.",
582 "1 is not of type u'string'");
583 }
584 // Invalid: test i2c_compare_bit with register wrong format.
585 {
586 json configFile = i2cCompareBitFile;
587 configFile["rules"][0]["actions"][1]["i2c_compare_bit"]["register"] =
588 "0xA00";
589 EXPECT_JSON_INVALID(configFile, "Validation failed.",
590 "u'0xA00' does not match u'^0x[0-9A-Fa-f]{2}$'");
591 }
592 // Invalid: test i2c_compare_bit with position wrong type.
593 {
594 json configFile = i2cCompareBitFile;
595 configFile["rules"][0]["actions"][1]["i2c_compare_bit"]["position"] =
596 3.1;
597 EXPECT_JSON_INVALID(configFile, "Validation failed.",
598 "3.1 is not of type u'integer'");
599 }
600 // Invalid: test i2c_compare_bit with position greater than 7.
601 {
602 json configFile = i2cCompareBitFile;
603 configFile["rules"][0]["actions"][1]["i2c_compare_bit"]["position"] = 8;
604 EXPECT_JSON_INVALID(configFile, "Validation failed.",
605 "8 is greater than the maximum of 7");
606 }
607 // Invalid: test i2c_compare_bit with position less than 0.
608 {
609 json configFile = i2cCompareBitFile;
610 configFile["rules"][0]["actions"][1]["i2c_compare_bit"]["position"] =
611 -1;
612 EXPECT_JSON_INVALID(configFile, "Validation failed.",
613 "-1 is less than the minimum of 0");
614 }
615 // Invalid: test i2c_compare_bit with value wrong type.
616 {
617 json configFile = i2cCompareBitFile;
618 configFile["rules"][0]["actions"][1]["i2c_compare_bit"]["value"] = "1";
619 EXPECT_JSON_INVALID(configFile, "Validation failed.",
620 "u'1' is not of type u'integer'");
621 }
622 // Invalid: test i2c_compare_bit with value greater than 1.
623 {
624 json configFile = i2cCompareBitFile;
625 configFile["rules"][0]["actions"][1]["i2c_compare_bit"]["value"] = 2;
626 EXPECT_JSON_INVALID(configFile, "Validation failed.",
627 "2 is greater than the maximum of 1");
628 }
629 // Invalid: test i2c_compare_bit with value less than 0.
630 {
631 json configFile = i2cCompareBitFile;
632 configFile["rules"][0]["actions"][1]["i2c_compare_bit"]["value"] = -1;
633 EXPECT_JSON_INVALID(configFile, "Validation failed.",
634 "-1 is less than the minimum of 0");
635 }
636}
Bob King514023d2020-01-21 11:13:05 +0800637TEST(ValidateRegulatorsConfigTest, I2CCompareByte)
638{
639 json i2cCompareByteFile = validConfigFile;
640 i2cCompareByteFile["rules"][0]["actions"][1]["i2c_compare_byte"]
641 ["register"] = "0x82";
642 i2cCompareByteFile["rules"][0]["actions"][1]["i2c_compare_byte"]["value"] =
643 "0x40";
644 i2cCompareByteFile["rules"][0]["actions"][1]["i2c_compare_byte"]["mask"] =
645 "0x7F";
646 // Valid: test i2c_compare_byte with all properties.
647 {
648 json configFile = i2cCompareByteFile;
649 EXPECT_JSON_VALID(configFile);
650 }
651 // Valid: test i2c_compare_byte with all required properties.
652 {
653 json configFile = i2cCompareByteFile;
654 configFile["rules"][0]["actions"][1]["i2c_compare_byte"].erase("mask");
655 EXPECT_JSON_VALID(configFile);
656 }
657 // Invalid: test i2c_compare_byte with no register.
658 {
659 json configFile = i2cCompareByteFile;
660 configFile["rules"][0]["actions"][1]["i2c_compare_byte"].erase(
661 "register");
662 EXPECT_JSON_INVALID(configFile, "Validation failed.",
663 "u'register' is a required property");
664 }
665 // Invalid: test i2c_compare_byte with no value.
666 {
667 json configFile = i2cCompareByteFile;
668 configFile["rules"][0]["actions"][1]["i2c_compare_byte"].erase("value");
669 EXPECT_JSON_INVALID(configFile, "Validation failed.",
670 "u'value' is a required property");
671 }
672 // Invalid: test i2c_compare_byte with property register wrong type.
673 {
674 json configFile = i2cCompareByteFile;
675 configFile["rules"][0]["actions"][1]["i2c_compare_byte"]["register"] =
676 1;
677 EXPECT_JSON_INVALID(configFile, "Validation failed.",
678 "1 is not of type u'string'");
679 }
680 // Invalid: test i2c_compare_byte with property value wrong type.
681 {
682 json configFile = i2cCompareByteFile;
683 configFile["rules"][0]["actions"][1]["i2c_compare_byte"]["value"] = 1;
684 EXPECT_JSON_INVALID(configFile, "Validation failed.",
685 "1 is not of type u'string'");
686 }
687 // Invalid: test i2c_compare_byte with property mask wrong type.
688 {
689 json configFile = i2cCompareByteFile;
690 configFile["rules"][0]["actions"][1]["i2c_compare_byte"]["mask"] = 1;
691 EXPECT_JSON_INVALID(configFile, "Validation failed.",
692 "1 is not of type u'string'");
693 }
694 // Invalid: test i2c_compare_byte with property register more than 2 hex
695 // digits.
696 {
697 json configFile = i2cCompareByteFile;
698 configFile["rules"][0]["actions"][1]["i2c_compare_byte"]["register"] =
699 "0x820";
700 EXPECT_JSON_INVALID(configFile, "Validation failed.",
701 "u'0x820' does not match u'^0x[0-9A-Fa-f]{2}$'");
702 }
703 // Invalid: test i2c_compare_byte with property value more than 2 hex
704 // digits.
705 {
706 json configFile = i2cCompareByteFile;
707 configFile["rules"][0]["actions"][1]["i2c_compare_byte"]["value"] =
708 "0x820";
709 EXPECT_JSON_INVALID(configFile, "Validation failed.",
710 "u'0x820' does not match u'^0x[0-9A-Fa-f]{2}$'");
711 }
712 // Invalid: test i2c_compare_byte with property mask more than 2 hex digits.
713 {
714 json configFile = i2cCompareByteFile;
715 configFile["rules"][0]["actions"][1]["i2c_compare_byte"]["mask"] =
716 "0x820";
717 EXPECT_JSON_INVALID(configFile, "Validation failed.",
718 "u'0x820' does not match u'^0x[0-9A-Fa-f]{2}$'");
719 }
720 // Invalid: test i2c_compare_byte with property register less than 2 hex
721 // digits.
722 {
723 json configFile = i2cCompareByteFile;
724 configFile["rules"][0]["actions"][1]["i2c_compare_byte"]["register"] =
725 "0x8";
726 EXPECT_JSON_INVALID(configFile, "Validation failed.",
727 "u'0x8' does not match u'^0x[0-9A-Fa-f]{2}$'");
728 }
729 // Invalid: test i2c_compare_byte with property value less than 2 hex
730 // digits.
731 {
732 json configFile = i2cCompareByteFile;
733 configFile["rules"][0]["actions"][1]["i2c_compare_byte"]["value"] =
734 "0x8";
735 EXPECT_JSON_INVALID(configFile, "Validation failed.",
736 "u'0x8' does not match u'^0x[0-9A-Fa-f]{2}$'");
737 }
738 // Invalid: test i2c_compare_byte with property mask less than 2 hex digits.
739 {
740 json configFile = i2cCompareByteFile;
741 configFile["rules"][0]["actions"][1]["i2c_compare_byte"]["mask"] =
742 "0x8";
743 EXPECT_JSON_INVALID(configFile, "Validation failed.",
744 "u'0x8' does not match u'^0x[0-9A-Fa-f]{2}$'");
745 }
746 // Invalid: test i2c_compare_byte with property register no leading prefix.
747 {
748 json configFile = i2cCompareByteFile;
749 configFile["rules"][0]["actions"][1]["i2c_compare_byte"]["register"] =
750 "82";
751 EXPECT_JSON_INVALID(configFile, "Validation failed.",
752 "u'82' does not match u'^0x[0-9A-Fa-f]{2}$'");
753 }
754 // Invalid: test i2c_compare_byte with property value no leading prefix.
755 {
756 json configFile = i2cCompareByteFile;
757 configFile["rules"][0]["actions"][1]["i2c_compare_byte"]["value"] =
758 "82";
759 EXPECT_JSON_INVALID(configFile, "Validation failed.",
760 "u'82' does not match u'^0x[0-9A-Fa-f]{2}$'");
761 }
762 // Invalid: test i2c_compare_byte with property mask no leading prefix.
763 {
764 json configFile = i2cCompareByteFile;
765 configFile["rules"][0]["actions"][1]["i2c_compare_byte"]["mask"] = "82";
766 EXPECT_JSON_INVALID(configFile, "Validation failed.",
767 "u'82' does not match u'^0x[0-9A-Fa-f]{2}$'");
768 }
769 // Invalid: test i2c_compare_byte with property register invalid hex digit.
770 {
771 json configFile = i2cCompareByteFile;
772 configFile["rules"][0]["actions"][1]["i2c_compare_byte"]["register"] =
773 "0xG1";
774 EXPECT_JSON_INVALID(configFile, "Validation failed.",
775 "u'0xG1' does not match u'^0x[0-9A-Fa-f]{2}$'");
776 }
777 // Invalid: test i2c_compare_byte with property value invalid hex digit.
778 {
779 json configFile = i2cCompareByteFile;
780 configFile["rules"][0]["actions"][1]["i2c_compare_byte"]["value"] =
781 "0xG1";
782 EXPECT_JSON_INVALID(configFile, "Validation failed.",
783 "u'0xG1' does not match u'^0x[0-9A-Fa-f]{2}$'");
784 }
785 // Invalid: test i2c_compare_byte with property mask invalid hex digit.
786 {
787 json configFile = i2cCompareByteFile;
788 configFile["rules"][0]["actions"][1]["i2c_compare_byte"]["mask"] =
789 "0xG1";
790 EXPECT_JSON_INVALID(configFile, "Validation failed.",
791 "u'0xG1' does not match u'^0x[0-9A-Fa-f]{2}$'");
792 }
793}
Bob Kingfb162bb2020-01-21 11:28:07 +0800794TEST(ValidateRegulatorsConfigTest, I2CCompareBytes)
795{
796 json i2cCompareBytesFile = validConfigFile;
797 i2cCompareBytesFile["rules"][0]["actions"][1]["i2c_compare_bytes"]
798 ["register"] = "0x82";
799 i2cCompareBytesFile["rules"][0]["actions"][1]["i2c_compare_bytes"]
800 ["values"] = {"0x02", "0x73"};
801 i2cCompareBytesFile["rules"][0]["actions"][1]["i2c_compare_bytes"]
802 ["masks"] = {"0x7F", "0x7F"};
803 // Valid: test i2c_compare_bytes.
804 {
805 json configFile = i2cCompareBytesFile;
806 EXPECT_JSON_VALID(configFile);
807 }
808 // Valid: test i2c_compare_bytes with all required properties.
809 {
810 json configFile = i2cCompareBytesFile;
811 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"].erase(
812 "masks");
813 EXPECT_JSON_VALID(configFile);
814 }
815 // Invalid: test i2c_compare_bytes with no register.
816 {
817 json configFile = i2cCompareBytesFile;
818 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"].erase(
819 "register");
820 EXPECT_JSON_INVALID(configFile, "Validation failed.",
821 "u'register' is a required property");
822 }
823 // Invalid: test i2c_compare_bytes with no values.
824 {
825 json configFile = i2cCompareBytesFile;
826 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"].erase(
827 "values");
828 EXPECT_JSON_INVALID(configFile, "Validation failed.",
829 "u'values' is a required property");
830 }
831 // Invalid: test i2c_compare_bytes with property values as empty array.
832 {
833 json configFile = i2cCompareBytesFile;
834 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["values"] =
835 json::array();
836 EXPECT_JSON_INVALID(configFile, "Validation failed.",
837 "[] is too short");
838 }
839 // Invalid: test i2c_compare_bytes with property masks as empty array.
840 {
841 json configFile = i2cCompareBytesFile;
842 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["masks"] =
843 json::array();
844 EXPECT_JSON_INVALID(configFile, "Validation failed.",
845 "[] is too short");
846 }
847 // Invalid: test i2c_compare_bytes with property register wrong type.
848 {
849 json configFile = i2cCompareBytesFile;
850 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["register"] =
851 1;
852 EXPECT_JSON_INVALID(configFile, "Validation failed.",
853 "1 is not of type u'string'");
854 }
855 // Invalid: test i2c_compare_bytes with property values wrong type.
856 {
857 json configFile = i2cCompareBytesFile;
858 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["values"] = 1;
859 EXPECT_JSON_INVALID(configFile, "Validation failed.",
860 "1 is not of type u'array'");
861 }
862 // Invalid: test i2c_compare_bytes with property masks wrong type.
863 {
864 json configFile = i2cCompareBytesFile;
865 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["masks"] = 1;
866 EXPECT_JSON_INVALID(configFile, "Validation failed.",
867 "1 is not of type u'array'");
868 }
869 // Invalid: test i2c_compare_bytes with property register more than 2 hex
870 // digits.
871 {
872 json configFile = i2cCompareBytesFile;
873 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["register"] =
874 "0x820";
875 EXPECT_JSON_INVALID(configFile, "Validation failed.",
876 "u'0x820' does not match u'^0x[0-9A-Fa-f]{2}$'");
877 }
878 // Invalid: test i2c_compare_bytes with property values more than 2 hex
879 // digits.
880 {
881 json configFile = i2cCompareBytesFile;
882 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["values"][0] =
883 "0x820";
884 EXPECT_JSON_INVALID(configFile, "Validation failed.",
885 "u'0x820' does not match u'^0x[0-9A-Fa-f]{2}$'");
886 }
887 // Invalid: test i2c_compare_bytes with property masks more than 2 hex
888 // digits.
889 {
890 json configFile = i2cCompareBytesFile;
891 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["masks"][0] =
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_bytes with property register less than 2 hex
897 // digits.
898 {
899 json configFile = i2cCompareBytesFile;
900 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["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_bytes with property values less than 2 hex
906 // digits.
907 {
908 json configFile = i2cCompareBytesFile;
909 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["values"][0] =
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_bytes with property masks less than 2 hex
915 // digits.
916 {
917 json configFile = i2cCompareBytesFile;
918 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["masks"][0] =
919 "0x8";
920 EXPECT_JSON_INVALID(configFile, "Validation failed.",
921 "u'0x8' does not match u'^0x[0-9A-Fa-f]{2}$'");
922 }
923 // Invalid: test i2c_compare_bytes with property register no leading prefix.
924 {
925 json configFile = i2cCompareBytesFile;
926 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["register"] =
927 "82";
928 EXPECT_JSON_INVALID(configFile, "Validation failed.",
929 "u'82' does not match u'^0x[0-9A-Fa-f]{2}$'");
930 }
931 // Invalid: test i2c_compare_bytes with property values no leading prefix.
932 {
933 json configFile = i2cCompareBytesFile;
934 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["values"][0] =
935 "82";
936 EXPECT_JSON_INVALID(configFile, "Validation failed.",
937 "u'82' does not match u'^0x[0-9A-Fa-f]{2}$'");
938 }
939 // Invalid: test i2c_compare_bytes with property masks no leading prefix.
940 {
941 json configFile = i2cCompareBytesFile;
942 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["masks"][0] =
943 "82";
944 EXPECT_JSON_INVALID(configFile, "Validation failed.",
945 "u'82' does not match u'^0x[0-9A-Fa-f]{2}$'");
946 }
947 // Invalid: test i2c_compare_bytes with property register invalid hex digit.
948 {
949 json configFile = i2cCompareBytesFile;
950 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["register"] =
951 "0xG1";
952 EXPECT_JSON_INVALID(configFile, "Validation failed.",
953 "u'0xG1' does not match u'^0x[0-9A-Fa-f]{2}$'");
954 }
955 // Invalid: test i2c_compare_bytes with property values invalid hex digit.
956 {
957 json configFile = i2cCompareBytesFile;
958 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["values"][0] =
959 "0xG1";
960 EXPECT_JSON_INVALID(configFile, "Validation failed.",
961 "u'0xG1' does not match u'^0x[0-9A-Fa-f]{2}$'");
962 }
963 // Invalid: test i2c_compare_bytes with property masks invalid hex digit.
964 {
965 json configFile = i2cCompareBytesFile;
966 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["masks"][0] =
967 "0xG1";
968 EXPECT_JSON_INVALID(configFile, "Validation failed.",
969 "u'0xG1' does not match u'^0x[0-9A-Fa-f]{2}$'");
970 }
971}
Bob Kingead0b052020-01-21 11:29:03 +0800972TEST(ValidateRegulatorsConfigTest, If)
973{
974 json ifFile = validConfigFile;
975 ifFile["rules"][0]["actions"][1]["if"]["condition"]["run_rule"] =
976 "is_downlevel_regulator";
977 ifFile["rules"][0]["actions"][1]["if"]["then"][0]["run_rule"] =
978 "configure_downlevel_regulator";
979 ifFile["rules"][0]["actions"][1]["if"]["else"][0]["run_rule"] =
980 "configure_downlevel_regulator";
981 // Valid: test if.
982 {
983 json configFile = ifFile;
984 EXPECT_JSON_VALID(configFile);
985 }
986 // Valid: test if with required properties.
987 {
988 json configFile = ifFile;
989 configFile["rules"][0]["actions"][1]["if"].erase("else");
990 EXPECT_JSON_VALID(configFile);
991 }
992 // Invalid: test if with no property condition.
993 {
994 json configFile = ifFile;
995 configFile["rules"][0]["actions"][1]["if"].erase("condition");
996 EXPECT_JSON_INVALID(configFile, "Validation failed.",
997 "u'condition' is a required property");
998 }
999 // Invalid: test if with no property then.
1000 {
1001 json configFile = ifFile;
1002 configFile["rules"][0]["actions"][1]["if"].erase("then");
1003 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1004 "u'then' is a required property");
1005 }
1006 // Invalid: test if with property then empty array.
1007 {
1008 json configFile = ifFile;
1009 configFile["rules"][0]["actions"][1]["if"]["then"] = json::array();
1010 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1011 "[] is too short");
1012 }
1013 // Invalid: test if with property else empty array.
1014 {
1015 json configFile = ifFile;
1016 configFile["rules"][0]["actions"][1]["if"]["else"] = json::array();
1017 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1018 "[] is too short");
1019 }
1020 // Invalid: test if with property condition wrong type.
1021 {
1022 json configFile = ifFile;
1023 configFile["rules"][0]["actions"][1]["if"]["condition"] = 1;
1024 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1025 "1 is not of type u'object'");
1026 }
1027 // Invalid: test if with property then wrong type.
1028 {
1029 json configFile = ifFile;
1030 configFile["rules"][0]["actions"][1]["if"]["then"] = 1;
1031 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1032 "1 is not of type u'array'");
1033 }
1034 // Invalid: test if with property else wrong type.
1035 {
1036 json configFile = ifFile;
1037 configFile["rules"][0]["actions"][1]["if"]["else"] = 1;
1038 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1039 "1 is not of type u'array'");
1040 }
1041}
Bob Kingbfe9fe72020-01-21 11:29:57 +08001042TEST(ValidateRegulatorsConfigTest, Not)
1043{
1044 json notFile = validConfigFile;
1045 notFile["rules"][0]["actions"][1]["not"]["i2c_compare_byte"]["register"] =
1046 "0xA0";
1047 notFile["rules"][0]["actions"][1]["not"]["i2c_compare_byte"]["value"] =
1048 "0xFF";
1049 // Valid: test not.
1050 {
1051 json configFile = notFile;
1052 EXPECT_JSON_VALID(configFile);
1053 }
1054 // Invalid: test not with wrong type.
1055 {
1056 json configFile = notFile;
1057 configFile["rules"][0]["actions"][1]["not"] = 1;
1058 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1059 "1 is not of type u'object'");
1060 }
1061}
Bob Kingcfc29d02020-01-21 11:30:50 +08001062TEST(ValidateRegulatorsConfigTest, Or)
1063{
1064 json orFile = validConfigFile;
1065 orFile["rules"][0]["actions"][1]["or"][0]["i2c_compare_byte"]["register"] =
1066 "0xA0";
1067 orFile["rules"][0]["actions"][1]["or"][0]["i2c_compare_byte"]["value"] =
1068 "0x00";
1069 orFile["rules"][0]["actions"][1]["or"][1]["i2c_compare_byte"]["register"] =
1070 "0xA1";
1071 orFile["rules"][0]["actions"][1]["or"][1]["i2c_compare_byte"]["value"] =
1072 "0x00";
1073 // Valid: test or.
1074 {
1075 json configFile = orFile;
1076 EXPECT_JSON_VALID(configFile);
1077 }
1078 // Invalid: test or with empty array.
1079 {
1080 json configFile = orFile;
1081 configFile["rules"][0]["actions"][1]["or"] = json::array();
1082 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1083 "[] is too short");
1084 }
1085 // Invalid: test or with wrong type.
1086 {
1087 json configFile = orFile;
1088 configFile["rules"][0]["actions"][1]["or"] = 1;
1089 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1090 "1 is not of type u'array'");
1091 }
1092}
Bob Kingd6618092020-01-21 11:31:46 +08001093TEST(ValidateRegulatorsConfigTest, PmbusReadSensor)
1094{
1095 json pmbusReadSensorFile = validConfigFile;
1096 pmbusReadSensorFile["rules"][0]["actions"][1]["pmbus_read_sensor"]["type"] =
1097 "vout";
1098 pmbusReadSensorFile["rules"][0]["actions"][1]["pmbus_read_sensor"]
1099 ["command"] = "0x8B";
1100 pmbusReadSensorFile["rules"][0]["actions"][1]["pmbus_read_sensor"]
1101 ["format"] = "linear_16";
1102 pmbusReadSensorFile["rules"][0]["actions"][1]["pmbus_read_sensor"]
1103 ["exponent"] = -8;
1104 // Valid: test pmbus_read_sensor.
1105 {
1106 json configFile = pmbusReadSensorFile;
1107 EXPECT_JSON_VALID(configFile);
1108 }
1109 // Valid: test pmbus_read_sensor with required properties.
1110 {
1111 json configFile = pmbusReadSensorFile;
1112 configFile["rules"][0]["actions"][1]["pmbus_read_sensor"].erase(
1113 "exponent");
1114 EXPECT_JSON_VALID(configFile);
1115 }
1116 // Invalid: test pmbus_read_sensor with no type.
1117 {
1118 json configFile = pmbusReadSensorFile;
1119 configFile["rules"][0]["actions"][1]["pmbus_read_sensor"].erase("type");
1120 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1121 "u'type' is a required property");
1122 }
1123 // Invalid: test pmbus_read_sensor with no command.
1124 {
1125 json configFile = pmbusReadSensorFile;
1126 configFile["rules"][0]["actions"][1]["pmbus_read_sensor"].erase(
1127 "command");
1128 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1129 "u'command' is a required property");
1130 }
1131 // Invalid: test pmbus_read_sensor with no format.
1132 {
1133 json configFile = pmbusReadSensorFile;
1134 configFile["rules"][0]["actions"][1]["pmbus_read_sensor"].erase(
1135 "format");
1136 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1137 "u'format' is a required property");
1138 }
1139 // Invalid: test pmbus_read_sensor with property type wrong type.
1140 {
1141 json configFile = pmbusReadSensorFile;
1142 configFile["rules"][0]["actions"][1]["pmbus_read_sensor"]["type"] =
1143 true;
1144 EXPECT_JSON_INVALID(
1145 configFile, "Validation failed.",
1146 "True is not one of [u'iout', u'iout_peak', u'iout_valley', "
1147 "u'pout', u'temperature', u'temperature_peak', u'vout', "
1148 "u'vout_peak', u'vout_valley']");
1149 }
1150 // Invalid: test pmbus_read_sensor with property command wrong type.
1151 {
1152 json configFile = pmbusReadSensorFile;
1153 configFile["rules"][0]["actions"][1]["pmbus_read_sensor"]["command"] =
1154 true;
1155 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1156 "True is not of type u'string'");
1157 }
1158 // Invalid: test pmbus_read_sensor with property format wrong type.
1159 {
1160 json configFile = pmbusReadSensorFile;
1161 configFile["rules"][0]["actions"][1]["pmbus_read_sensor"]["format"] =
1162 true;
1163 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1164 "True is not one of [u'linear_11', u'linear_16']");
1165 }
1166 // Invalid: test pmbus_read_sensor with property exponent wrong type.
1167 {
1168 json configFile = pmbusReadSensorFile;
1169 configFile["rules"][0]["actions"][1]["pmbus_read_sensor"]["exponent"] =
1170 true;
1171 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1172 "True is not of type u'integer'");
1173 }
1174 // Invalid: test pmbus_read_sensor with property type wrong format.
1175 {
1176 json configFile = pmbusReadSensorFile;
1177 configFile["rules"][0]["actions"][1]["pmbus_read_sensor"]["type"] =
1178 "foo";
1179 EXPECT_JSON_INVALID(
1180 configFile, "Validation failed.",
1181 "u'foo' is not one of [u'iout', u'iout_peak', u'iout_valley', "
1182 "u'pout', u'temperature', u'temperature_peak', u'vout', "
1183 "u'vout_peak', u'vout_valley']");
1184 }
1185 // Invalid: test pmbus_read_sensor with property command wrong format.
1186 {
1187 json configFile = pmbusReadSensorFile;
1188 configFile["rules"][0]["actions"][1]["pmbus_read_sensor"]["command"] =
1189 "0x8B0";
1190 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1191 "u'0x8B0' does not match u'^0x[0-9a-fA-F]{2}$'");
1192 }
1193 // Invalid: test pmbus_read_sensor with property format wrong format.
1194 {
1195 json configFile = pmbusReadSensorFile;
1196 configFile["rules"][0]["actions"][1]["pmbus_read_sensor"]["format"] =
1197 "foo";
1198 EXPECT_JSON_INVALID(
1199 configFile, "Validation failed.",
1200 "u'foo' is not one of [u'linear_11', u'linear_16']");
1201 }
1202}
Bob King02179c62020-01-21 11:32:36 +08001203TEST(ValidateRegulatorsConfigTest, PmbusWriteVoutCommand)
1204{
1205 json pmbusWriteVoutCommandFile = validConfigFile;
1206 pmbusWriteVoutCommandFile["rules"][0]["actions"][1]
1207 ["pmbus_write_vout_command"]["volts"] = 1.03;
1208 pmbusWriteVoutCommandFile["rules"][0]["actions"][1]
1209 ["pmbus_write_vout_command"]["format"] = "linear";
1210 pmbusWriteVoutCommandFile["rules"][0]["actions"][1]
1211 ["pmbus_write_vout_command"]["exponent"] = -8;
1212 pmbusWriteVoutCommandFile["rules"][0]["actions"][1]
1213 ["pmbus_write_vout_command"]["is_verified"] = true;
1214 // Valid: test pmbus_write_vout_command.
1215 {
1216 json configFile = pmbusWriteVoutCommandFile;
1217 EXPECT_JSON_VALID(configFile);
1218 }
1219 // Valid: test pmbus_write_vout_command with required properties.
1220 {
1221 json configFile = pmbusWriteVoutCommandFile;
1222 configFile["rules"][0]["actions"][1]["pmbus_write_vout_command"].erase(
1223 "volts");
1224 configFile["rules"][0]["actions"][1]["pmbus_write_vout_command"].erase(
1225 "exponent");
1226 configFile["rules"][0]["actions"][1]["pmbus_write_vout_command"].erase(
1227 "is_verified");
1228 EXPECT_JSON_VALID(configFile);
1229 }
1230 // Invalid: test pmbus_write_vout_command with no format.
1231 {
1232 json configFile = pmbusWriteVoutCommandFile;
1233 configFile["rules"][0]["actions"][1]["pmbus_write_vout_command"].erase(
1234 "format");
1235 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1236 "u'format' is a required property");
1237 }
1238 // Invalid: test pmbus_write_vout_command with property volts wrong type.
1239 {
1240 json configFile = pmbusWriteVoutCommandFile;
1241 configFile["rules"][0]["actions"][1]["pmbus_write_vout_command"]
1242 ["volts"] = true;
1243 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1244 "True is not of type u'number'");
1245 }
1246 // Invalid: test pmbus_write_vout_command with property format wrong type.
1247 {
1248 json configFile = pmbusWriteVoutCommandFile;
1249 configFile["rules"][0]["actions"][1]["pmbus_write_vout_command"]
1250 ["format"] = true;
1251 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1252 "True is not one of [u'linear']");
1253 }
1254 // Invalid: test pmbus_write_vout_command with property exponent wrong type.
1255 {
1256 json configFile = pmbusWriteVoutCommandFile;
1257 configFile["rules"][0]["actions"][1]["pmbus_write_vout_command"]
1258 ["exponent"] = 1.3;
1259 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1260 "1.3 is not of type u'integer'");
1261 }
1262 // Invalid: test pmbus_write_vout_command with property is_verified wrong
1263 // type.
1264 {
1265 json configFile = pmbusWriteVoutCommandFile;
1266 configFile["rules"][0]["actions"][1]["pmbus_write_vout_command"]
1267 ["is_verified"] = 1;
1268 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1269 "1 is not of type u'boolean'");
1270 }
1271 // Invalid: test pmbus_write_vout_command with property format wrong format.
1272 {
1273 json configFile = pmbusWriteVoutCommandFile;
1274 configFile["rules"][0]["actions"][1]["pmbus_write_vout_command"]
1275 ["format"] = "foo";
1276 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1277 "u'foo' is not one of [u'linear']");
1278 }
1279}
Bob Kinge86c2e52020-01-21 11:33:32 +08001280TEST(ValidateRegulatorsConfigTest, RunRule)
1281{
1282 json runRuleFile = validConfigFile;
1283 runRuleFile["rules"][0]["actions"][1]["run_rule"] = "set_voltage_rule1";
1284 // Valid: test run_rule.
1285 {
1286 json configFile = runRuleFile;
1287 EXPECT_JSON_VALID(configFile);
1288 }
1289 // Invalid: test run_rule wrong type.
1290 {
1291 json configFile = runRuleFile;
1292 configFile["rules"][0]["actions"][1]["run_rule"] = true;
1293 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1294 "True is not of type u'string'");
1295 }
1296 // Invalid: test run_rule wrong format.
1297 {
1298 json configFile = runRuleFile;
1299 configFile["rules"][0]["actions"][1]["run_rule"] = "set_voltage_rule%";
1300 EXPECT_JSON_INVALID(
1301 configFile, "Validation failed.",
1302 "u'set_voltage_rule%' does not match u'^[A-Za-z0-9_]+$'");
1303 }
1304}
Bob King68230aa2020-01-21 11:34:33 +08001305TEST(ValidateRegulatorsConfigTest, SetDevice)
1306{
1307 json setDeviceFile = validConfigFile;
1308 setDeviceFile["rules"][0]["actions"][1]["set_device"] = "io_expander2";
1309 // Valid: test set_device.
1310 {
1311 json configFile = setDeviceFile;
1312 EXPECT_JSON_VALID(configFile);
1313 }
1314 // Invalid: test set_device wrong type.
1315 {
1316 json configFile = setDeviceFile;
1317 configFile["rules"][0]["actions"][1]["set_device"] = true;
1318 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1319 "True is not of type u'string'");
1320 }
1321 // Invalid: test set_device wrong format.
1322 {
1323 json configFile = setDeviceFile;
1324 configFile["rules"][0]["actions"][1]["set_device"] = "io_expander2%";
1325 EXPECT_JSON_INVALID(
1326 configFile, "Validation failed.",
1327 "u'io_expander2%' does not match u'^[A-Za-z0-9_]+$'");
1328 }
1329}