blob: 0bafa20ad89a622cfb3ba15f54eec0dcd2a99aaf [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>
Bob Kinged009652020-02-20 14:54:13 +080019#include <sys/stat.h>
Bob King386d33f2019-12-26 17:28:56 +080020#include <sys/wait.h>
21
Bob King386d33f2019-12-26 17:28:56 +080022#include <nlohmann/json.hpp>
23
Bob King0dcbdf52020-01-20 17:19:39 +080024#include <fstream>
25
Bob King386d33f2019-12-26 17:28:56 +080026#include <gtest/gtest.h>
27
28#define EXPECT_FILE_VALID(configFile) expectFileValid(configFile)
29#define EXPECT_FILE_INVALID(configFile, expectedErrorMessage, \
30 expectedOutputMessage) \
31 expectFileInvalid(configFile, expectedErrorMessage, expectedOutputMessage)
32#define EXPECT_JSON_VALID(configFileJson) expectJsonValid(configFileJson)
33#define EXPECT_JSON_INVALID(configFileJson, expectedErrorMessage, \
34 expectedOutputMessage) \
35 expectJsonInvalid(configFileJson, expectedErrorMessage, \
36 expectedOutputMessage)
37
38using json = nlohmann::json;
39
40const json validConfigFile = R"(
41 {
42 "comments": [ "Config file for a FooBar one-chassis system" ],
43
44 "rules": [
45 {
46 "comments": [ "Sets output voltage for a PMBus regulator rail" ],
47 "id": "set_voltage_rule",
48 "actions": [
49 {
50 "pmbus_write_vout_command": {
51 "format": "linear"
52 }
53 }
54 ]
Bob Kingb3e48bc2020-02-18 09:59:09 +080055 },
56 {
57 "comments": [ "Reads sensors from a PMBus regulator rail" ],
58 "id": "read_sensors_rule",
59 "actions": [
60 {
61 "comments": [ "Read output voltage from READ_VOUT." ],
62 "pmbus_read_sensor": {
63 "type": "vout",
64 "command": "0x8B",
65 "format": "linear_16"
66 }
67 }
68 ]
Bob King386d33f2019-12-26 17:28:56 +080069 }
70 ],
71
72 "chassis": [
73 {
74 "comments": [ "Chassis number 1 containing CPUs and memory" ],
75 "number": 1,
76 "devices": [
77 {
78 "comments": [ "IR35221 regulator producing the Vdd rail" ],
79 "id": "vdd_regulator",
80 "is_regulator": true,
81 "fru": "/system/chassis/motherboard/regulator1",
82 "i2c_interface": {
83 "bus": 1,
84 "address": "0x70"
85 },
86 "rails": [
87 {
88 "comments": [ "Vdd rail" ],
89 "id": "vdd",
90 "configuration": {
91 "volts": 1.03,
92 "rule_id": "set_voltage_rule"
93 },
94 "sensor_monitoring": {
95 "rule_id": "read_sensors_rule"
96 }
97 }
98 ]
99 }
100 ]
101 }
102 ]
103 }
104)"_json;
105
Bob Kinga57e0812020-03-12 10:47:42 +0800106class TmpFile
Bob King386d33f2019-12-26 17:28:56 +0800107{
Bob Kinga57e0812020-03-12 10:47:42 +0800108 public:
109 TmpFile()
Bob King386d33f2019-12-26 17:28:56 +0800110 {
Bob Kinga57e0812020-03-12 10:47:42 +0800111 int fd = mkstemp(fileName);
112 if (fd == -1)
113 {
114 perror("Can't create temporary file");
115 }
116 close(fd);
Bob King386d33f2019-12-26 17:28:56 +0800117 }
Bob Kinga57e0812020-03-12 10:47:42 +0800118
119 std::string getName()
120 {
121 return fileName;
122 }
123
124 ~TmpFile()
125 {
126 unlink(fileName);
127 }
128
129 private:
130 char fileName[17] = "/tmp/temp-XXXXXX";
131};
Bob King386d33f2019-12-26 17:28:56 +0800132
133std::string getValidationToolCommand(const std::string& configFileName)
134{
Bob Kinga57e0812020-03-12 10:47:42 +0800135 std::string command =
136 "../phosphor-regulators/tools/validate-regulators-config.py -s \
137 ../phosphor-regulators/schema/config_schema.json -c ";
Bob King386d33f2019-12-26 17:28:56 +0800138 command += configFileName;
139 return command;
140}
141
Bob Kinga57e0812020-03-12 10:47:42 +0800142int runToolForOutputWithCommand(std::string command,
143 std::string& standardOutput,
144 std::string& standardError)
Bob King386d33f2019-12-26 17:28:56 +0800145{
146 // run the validation tool with the temporary file and return the output
147 // of the validation tool.
Bob Kinga57e0812020-03-12 10:47:42 +0800148 TmpFile tmpFile;
149 command += " 2> " + tmpFile.getName();
Bob King386d33f2019-12-26 17:28:56 +0800150 // get the jsonschema print from validation tool.
151 char buffer[256];
Bob Kinga57e0812020-03-12 10:47:42 +0800152 std::string result;
Bob King386d33f2019-12-26 17:28:56 +0800153 // to get the stdout from the validation tool.
154 FILE* pipe = popen(command.c_str(), "r");
155 if (!pipe)
156 {
157 throw std::runtime_error("popen() failed!");
158 }
159 while (!std::feof(pipe))
160 {
161 if (fgets(buffer, sizeof buffer, pipe) != NULL)
162 {
163 result += buffer;
164 }
165 }
166 int returnValue = pclose(pipe);
167 // Check if pclose() failed
168 if (returnValue == -1)
169 {
170 // unable to close pipe. Print error and exit function.
171 throw std::runtime_error("pclose() failed!");
172 }
173 std::string firstLine = result.substr(0, result.find('\n'));
Bob Kinga57e0812020-03-12 10:47:42 +0800174 standardOutput = firstLine;
Bob King386d33f2019-12-26 17:28:56 +0800175 // Get command exit status from return value
176 int exitStatus = WEXITSTATUS(returnValue);
Bob Kinga57e0812020-03-12 10:47:42 +0800177
178 // Read the standardError from tmpFile.
179 std::ifstream input(tmpFile.getName().c_str());
180 std::string line;
181
182 if (std::getline(input, line))
183 {
184 standardError = line;
185 }
186
Bob King386d33f2019-12-26 17:28:56 +0800187 return exitStatus;
188}
189
Bob Kinged009652020-02-20 14:54:13 +0800190int runToolForOutput(const std::string& configFileName, std::string& output,
Bob Kinga57e0812020-03-12 10:47:42 +0800191 std::string& error)
Bob Kinged009652020-02-20 14:54:13 +0800192{
193 std::string command = getValidationToolCommand(configFileName);
Bob Kinga57e0812020-03-12 10:47:42 +0800194 return runToolForOutputWithCommand(command, output, error);
Bob Kinged009652020-02-20 14:54:13 +0800195}
196
Bob King386d33f2019-12-26 17:28:56 +0800197void expectFileValid(const std::string& configFileName)
198{
Bob Kinged009652020-02-20 14:54:13 +0800199 std::string errorMessage;
200 std::string outputMessage;
Bob Kinga57e0812020-03-12 10:47:42 +0800201 EXPECT_EQ(runToolForOutput(configFileName, outputMessage, errorMessage), 0);
Bob King386d33f2019-12-26 17:28:56 +0800202 EXPECT_EQ(errorMessage, "");
203 EXPECT_EQ(outputMessage, "");
204}
205
206void expectFileInvalid(const std::string& configFileName,
207 const std::string& expectedErrorMessage,
208 const std::string& expectedOutputMessage)
209{
Bob Kinged009652020-02-20 14:54:13 +0800210 std::string errorMessage;
211 std::string outputMessage;
Bob Kinga57e0812020-03-12 10:47:42 +0800212 EXPECT_EQ(runToolForOutput(configFileName, outputMessage, errorMessage), 1);
Bob King386d33f2019-12-26 17:28:56 +0800213 EXPECT_EQ(errorMessage, expectedErrorMessage);
214 EXPECT_EQ(outputMessage, expectedOutputMessage);
215}
216
Bob Kinga57e0812020-03-12 10:47:42 +0800217void writeDataToFile(const json configFileJson, std::string fileName)
Bob King386d33f2019-12-26 17:28:56 +0800218{
Bob King386d33f2019-12-26 17:28:56 +0800219 std::string jsonData = configFileJson.dump();
220 std::ofstream out(fileName);
221 out << jsonData;
222 out.close();
Bob Kinged009652020-02-20 14:54:13 +0800223}
224
225void expectJsonValid(const json configFileJson)
226{
227 std::string fileName;
Bob Kinga57e0812020-03-12 10:47:42 +0800228 TmpFile tmpFile;
229 fileName = tmpFile.getName();
230 writeDataToFile(configFileJson, fileName);
Bob Kinged009652020-02-20 14:54:13 +0800231
Bob King386d33f2019-12-26 17:28:56 +0800232 EXPECT_FILE_VALID(fileName);
Bob King386d33f2019-12-26 17:28:56 +0800233}
234
235void expectJsonInvalid(const json configFileJson,
236 const std::string& expectedErrorMessage,
237 const std::string& expectedOutputMessage)
238{
239 std::string fileName;
Bob Kinga57e0812020-03-12 10:47:42 +0800240 TmpFile tmpFile;
241 fileName = tmpFile.getName();
242 writeDataToFile(configFileJson, fileName);
Bob King386d33f2019-12-26 17:28:56 +0800243
244 EXPECT_FILE_INVALID(fileName, expectedErrorMessage, expectedOutputMessage);
Bob King386d33f2019-12-26 17:28:56 +0800245}
246
Bob Kinged009652020-02-20 14:54:13 +0800247void expectCommandLineSyntax(const std::string& expectedErrorMessage,
248 const std::string& expectedOutputMessage,
249 std::string command, int status)
250{
251 std::string errorMessage;
252 std::string outputMessage;
Bob Kinga57e0812020-03-12 10:47:42 +0800253 EXPECT_EQ(runToolForOutputWithCommand(command, outputMessage, errorMessage),
254 status);
Bob Kinged009652020-02-20 14:54:13 +0800255 EXPECT_EQ(errorMessage, expectedErrorMessage);
256 EXPECT_EQ(outputMessage, expectedOutputMessage);
257}
258
Bob Kingbeaf6532020-01-21 11:03:49 +0800259TEST(ValidateRegulatorsConfigTest, And)
260{
261 // Valid.
262 {
263 json configFile = validConfigFile;
264 json andAction =
265 R"(
266 {
267 "and": [
268 { "i2c_compare_byte": { "register": "0xA0", "value": "0x00" } },
269 { "i2c_compare_byte": { "register": "0xA1", "value": "0x00" } }
270 ]
271 }
272 )"_json;
273 configFile["rules"][0]["actions"].push_back(andAction);
274 EXPECT_JSON_VALID(configFile);
275 }
276
277 // Invalid: actions property value is an empty array.
278 {
279 json configFile = validConfigFile;
280 json andAction =
281 R"(
282 {
283 "and": []
284 }
285 )"_json;
286 configFile["rules"][0]["actions"].push_back(andAction);
287 EXPECT_JSON_INVALID(configFile, "Validation failed.",
288 "[] is too short");
289 }
290
291 // Invalid: actions property has incorrect value data type.
292 {
293 json configFile = validConfigFile;
294 json andAction =
295 R"(
296 {
297 "and": true
298 }
299 )"_json;
300 configFile["rules"][0]["actions"].push_back(andAction);
301 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800302 "True is not of type 'array'");
Bob Kingbeaf6532020-01-21 11:03:49 +0800303 }
304
305 // Invalid: actions property value contains wrong element type
306 {
307 json configFile = validConfigFile;
308 json andAction =
309 R"(
310 {
311 "and": ["foo"]
312 }
313 )"_json;
314 configFile["rules"][0]["actions"].push_back(andAction);
315 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800316 "'foo' is not of type 'object'");
Bob Kingbeaf6532020-01-21 11:03:49 +0800317 }
318}
Bob King3728f562020-01-21 11:35:31 +0800319TEST(ValidateRegulatorsConfigTest, Chassis)
320{
321 // Valid: test chassis.
322 {
323 json configFile = validConfigFile;
324 EXPECT_JSON_VALID(configFile);
325 }
326 // Valid: test chassis with required properties.
327 {
328 json configFile = validConfigFile;
329 configFile["chassis"][0].erase("comments");
330 configFile["chassis"][0].erase("devices");
331 EXPECT_JSON_VALID(configFile);
332 }
333 // Invalid: test chassis with no number.
334 {
335 json configFile = validConfigFile;
336 configFile["chassis"][0].erase("number");
337 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800338 "'number' is a required property");
Bob King3728f562020-01-21 11:35:31 +0800339 }
340 // Invalid: test chassis with property comments wrong type.
341 {
342 json configFile = validConfigFile;
343 configFile["chassis"][0]["comments"] = true;
344 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800345 "True is not of type 'array'");
Bob King3728f562020-01-21 11:35:31 +0800346 }
347 // Invalid: test chassis with property number wrong type.
348 {
349 json configFile = validConfigFile;
350 configFile["chassis"][0]["number"] = 1.3;
351 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800352 "1.3 is not of type 'integer'");
Bob King3728f562020-01-21 11:35:31 +0800353 }
354 // Invalid: test chassis with property devices wrong type.
355 {
356 json configFile = validConfigFile;
357 configFile["chassis"][0]["devices"] = true;
358 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800359 "True is not of type 'array'");
Bob King3728f562020-01-21 11:35:31 +0800360 }
361 // Invalid: test chassis with property comments empty array.
362 {
363 json configFile = validConfigFile;
364 configFile["chassis"][0]["comments"] = json::array();
365 EXPECT_JSON_INVALID(configFile, "Validation failed.",
366 "[] is too short");
367 }
368 // Invalid: test chassis with property devices empty array.
369 {
370 json configFile = validConfigFile;
371 configFile["chassis"][0]["devices"] = json::array();
372 EXPECT_JSON_INVALID(configFile, "Validation failed.",
373 "[] is too short");
374 }
375 // Invalid: test chassis with property number less than 1.
376 {
377 json configFile = validConfigFile;
378 configFile["chassis"][0]["number"] = 0;
379 EXPECT_JSON_INVALID(configFile, "Validation failed.",
380 "0 is less than the minimum of 1");
381 }
382}
Bob Kingbf1cbea2020-01-21 11:08:50 +0800383TEST(ValidateRegulatorsConfigTest, ComparePresence)
384{
385 json comparePresenceFile = validConfigFile;
386 comparePresenceFile["rules"][0]["actions"][1]["compare_presence"]["fru"] =
387 "/system/chassis/motherboard/regulator2";
388 comparePresenceFile["rules"][0]["actions"][1]["compare_presence"]["value"] =
389 true;
390 // Valid.
391 {
392 json configFile = comparePresenceFile;
393 EXPECT_JSON_VALID(configFile);
394 }
395
396 // Invalid: no FRU property.
397 {
398 json configFile = comparePresenceFile;
399 configFile["rules"][0]["actions"][1]["compare_presence"].erase("fru");
400 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800401 "'fru' is a required property");
Bob Kingbf1cbea2020-01-21 11:08:50 +0800402 }
403
404 // Invalid: FRU property length is string less than 1.
405 {
406 json configFile = comparePresenceFile;
407 configFile["rules"][0]["actions"][1]["compare_presence"]["fru"] = "";
408 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800409 "'' is too short");
Bob Kingbf1cbea2020-01-21 11:08:50 +0800410 }
411
412 // Invalid: no value property.
413 {
414 json configFile = comparePresenceFile;
415 configFile["rules"][0]["actions"][1]["compare_presence"].erase("value");
416 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800417 "'value' is a required property");
Bob Kingbf1cbea2020-01-21 11:08:50 +0800418 }
419
420 // Invalid: value property type is not boolean.
421 {
422 json configFile = comparePresenceFile;
423 configFile["rules"][0]["actions"][1]["compare_presence"]["value"] = "1";
424 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800425 "'1' is not of type 'boolean'");
Bob Kingbf1cbea2020-01-21 11:08:50 +0800426 }
427
428 // Invalid: FRU property type is not string.
429 {
430 json configFile = comparePresenceFile;
431 configFile["rules"][0]["actions"][1]["compare_presence"]["fru"] = 1;
432 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800433 "1 is not of type 'string'");
Bob Kingbf1cbea2020-01-21 11:08:50 +0800434 }
435}
Bob Kingf8b77a02020-01-21 11:09:47 +0800436TEST(ValidateRegulatorsConfigTest, CompareVpd)
437{
438 json compareVpdFile = validConfigFile;
439 compareVpdFile["rules"][0]["actions"][1]["compare_vpd"]["fru"] =
440 "/system/chassis/motherboard/regulator2";
441 compareVpdFile["rules"][0]["actions"][1]["compare_vpd"]["keyword"] = "CCIN";
442 compareVpdFile["rules"][0]["actions"][1]["compare_vpd"]["value"] = "2D35";
443
444 // Valid.
445 {
446 json configFile = compareVpdFile;
447 EXPECT_JSON_VALID(configFile);
448 }
449
450 // Invalid: no FRU property.
451 {
452 json configFile = compareVpdFile;
453 configFile["rules"][0]["actions"][1]["compare_vpd"].erase("fru");
454 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800455 "'fru' is a required property");
Bob Kingf8b77a02020-01-21 11:09:47 +0800456 }
457
458 // Invalid: no keyword property.
459 {
460 json configFile = compareVpdFile;
461 configFile["rules"][0]["actions"][1]["compare_vpd"].erase("keyword");
462 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800463 "'keyword' is a required property");
Bob Kingf8b77a02020-01-21 11:09:47 +0800464 }
465
466 // Invalid: no value property.
467 {
468 json configFile = compareVpdFile;
469 configFile["rules"][0]["actions"][1]["compare_vpd"].erase("value");
470 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800471 "'value' is a required property");
Bob Kingf8b77a02020-01-21 11:09:47 +0800472 }
473
474 // Invalid: property FRU wrong type.
475 {
476 json configFile = compareVpdFile;
477 configFile["rules"][0]["actions"][1]["compare_vpd"]["fru"] = 1;
478 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800479 "1 is not of type 'string'");
Bob Kingf8b77a02020-01-21 11:09:47 +0800480 }
481
482 // Invalid: property FRU is string less than 1.
483 {
484 json configFile = compareVpdFile;
485 configFile["rules"][0]["actions"][1]["compare_vpd"]["fru"] = "";
486 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800487 "'' is too short");
Bob Kingf8b77a02020-01-21 11:09:47 +0800488 }
489
490 // Invalid: property keyword is not "CCIN", "Manufacturer", "Model",
491 // "PartNumber"
492 {
493 json configFile = compareVpdFile;
494 configFile["rules"][0]["actions"][1]["compare_vpd"]["keyword"] =
495 "Number";
496 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800497 "'Number' is not one of ['CCIN', "
498 "'Manufacturer', 'Model', 'PartNumber']");
Bob Kingf8b77a02020-01-21 11:09:47 +0800499 }
500
501 // Invalid: property value wrong type.
502 {
503 json configFile = compareVpdFile;
504 configFile["rules"][0]["actions"][1]["compare_vpd"]["value"] = 1;
505 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800506 "1 is not of type 'string'");
Bob Kingf8b77a02020-01-21 11:09:47 +0800507 }
508}
Bob King4c67a3a2020-02-07 09:48:11 +0800509TEST(ValidateRegulatorsConfigTest, Configuration)
510{
511 json configurationFile = validConfigFile;
512 configurationFile["chassis"][0]["devices"][0]["configuration"]["comments"]
513 [0] = "Set rail to 1.25V using standard rule";
514 configurationFile["chassis"][0]["devices"][0]["configuration"]["volts"] =
515 1.25;
516 configurationFile["chassis"][0]["devices"][0]["configuration"]["rule_id"] =
517 "set_voltage_rule";
518 // Valid: test configuration with property rule_id and with no actions.
519 {
520 json configFile = configurationFile;
521 EXPECT_JSON_VALID(configFile);
522 }
523 // Valid: test configuration with property actions and with no rule_id.
524 {
525 json configFile = configurationFile;
526 configFile["chassis"][0]["devices"][0]["configuration"].erase(
527 "rule_id");
528 configFile["chassis"][0]["devices"][0]["configuration"]["actions"][0]
529 ["compare_presence"]["fru"] =
530 "/system/chassis/motherboard/cpu3";
531 configFile["chassis"][0]["devices"][0]["configuration"]["actions"][0]
532 ["compare_presence"]["value"] = true;
533 EXPECT_JSON_VALID(configFile);
534 }
535 // Valid: comments not specified (optional property).
536 {
537 json configFile = configurationFile;
538 configFile["chassis"][0]["devices"][0]["configuration"].erase(
539 "comments");
540 EXPECT_JSON_VALID(configFile);
541 }
542 // Valid: volts not specified (optional property).
543 {
544 json configFile = configurationFile;
545 configFile["chassis"][0]["devices"][0]["configuration"].erase("volts");
546 EXPECT_JSON_VALID(configFile);
547 }
548 // Valid: configuration is property of a rail (vs. a device).
549 {
550 json configFile = validConfigFile;
551 configFile["chassis"][0]["devices"][0]["rails"][0]["configuration"]
552 ["comments"][0] = "Set rail to 1.25V using standard rule";
553 configFile["chassis"][0]["devices"][0]["rails"][0]["configuration"]
554 ["volts"] = 1.25;
555 configFile["chassis"][0]["devices"][0]["rails"][0]["configuration"]
556 ["rule_id"] = "set_voltage_rule";
557 EXPECT_JSON_VALID(configFile);
558 }
559 // Invalid: comments property has wrong data type (not an array).
560 {
561 json configFile = configurationFile;
562 configFile["chassis"][0]["devices"][0]["configuration"]["comments"] = 1;
563 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800564 "1 is not of type 'array'");
Bob King4c67a3a2020-02-07 09:48:11 +0800565 }
566 // Invalid: test configuration with both actions and rule_id properties.
567 {
568 json configFile = configurationFile;
569 configFile["chassis"][0]["devices"][0]["configuration"]["actions"][0]
570 ["compare_presence"]["fru"] =
571 "/system/chassis/motherboard/cpu3";
572 configFile["chassis"][0]["devices"][0]["configuration"]["actions"][0]
573 ["compare_presence"]["value"] = true;
574 EXPECT_JSON_INVALID(
575 configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800576 "{'actions': [{'compare_presence': {'fru': "
577 "'/system/chassis/motherboard/cpu3', 'value': True}}], 'comments': "
578 "['Set rail to 1.25V using standard rule'], 'rule_id': "
579 "'set_voltage_rule', 'volts': 1.25} is valid under each of "
580 "{'required': ['actions']}, {'required': ['rule_id']}");
Bob King4c67a3a2020-02-07 09:48:11 +0800581 }
582 // Invalid: test configuration with no rule_id and actions.
583 {
584 json configFile = configurationFile;
585 configFile["chassis"][0]["devices"][0]["configuration"].erase(
586 "rule_id");
587 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800588 "'rule_id' is a required property");
Bob King4c67a3a2020-02-07 09:48:11 +0800589 }
590 // Invalid: test configuration with property volts wrong type.
591 {
592 json configFile = configurationFile;
593 configFile["chassis"][0]["devices"][0]["configuration"]["volts"] = true;
594 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800595 "True is not of type 'number'");
Bob King4c67a3a2020-02-07 09:48:11 +0800596 }
597 // Invalid: test configuration with property rule_id wrong type.
598 {
599 json configFile = configurationFile;
600 configFile["chassis"][0]["devices"][0]["configuration"]["rule_id"] =
601 true;
602 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800603 "True is not of type 'string'");
Bob King4c67a3a2020-02-07 09:48:11 +0800604 }
605 // Invalid: test configuration with property actions wrong type.
606 {
607 json configFile = configurationFile;
608 configFile["chassis"][0]["devices"][0]["configuration"].erase(
609 "rule_id");
610 configFile["chassis"][0]["devices"][0]["configuration"]["actions"] =
611 true;
612 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800613 "True is not of type 'array'");
Bob King4c67a3a2020-02-07 09:48:11 +0800614 }
615 // Invalid: test configuration with property comments empty array.
616 {
617 json configFile = configurationFile;
618 configFile["chassis"][0]["devices"][0]["configuration"]["comments"] =
619 json::array();
620 EXPECT_JSON_INVALID(configFile, "Validation failed.",
621 "[] is too short");
622 }
623 // Invalid: test configuration with property rule_id wrong format.
624 {
625 json configFile = configurationFile;
626 configFile["chassis"][0]["devices"][0]["configuration"]["rule_id"] =
627 "id!";
628 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800629 "'id!' does not match '^[A-Za-z0-9_]+$'");
Bob King4c67a3a2020-02-07 09:48:11 +0800630 }
631 // Invalid: test configuration with property actions empty array.
632 {
633 json configFile = configurationFile;
634 configFile["chassis"][0]["devices"][0]["configuration"].erase(
635 "rule_id");
636 configFile["chassis"][0]["devices"][0]["configuration"]["actions"] =
637 json::array();
638 EXPECT_JSON_INVALID(configFile, "Validation failed.",
639 "[] is too short");
640 }
641}
Bob Kinga2ba2df2020-02-04 14:38:44 +0800642TEST(ValidateRegulatorsConfigTest, Device)
643{
644
645 // Valid: test devices.
646 {
647 json configFile = validConfigFile;
648 EXPECT_JSON_VALID(configFile);
649 }
650 // Valid: test devices with required properties.
651 {
652 json configFile = validConfigFile;
653 configFile["chassis"][0]["devices"][0].erase("comments");
654 configFile["chassis"][0]["devices"][0].erase("presence_detection");
655 configFile["chassis"][0]["devices"][0].erase("configuration");
656 configFile["chassis"][0]["devices"][0].erase("rails");
657 EXPECT_JSON_VALID(configFile);
658 }
659 // Invalid: test devices with no id.
660 {
661 json configFile = validConfigFile;
662 configFile["chassis"][0]["devices"][0].erase("id");
663 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800664 "'id' is a required property");
Bob Kinga2ba2df2020-02-04 14:38:44 +0800665 }
666 // Invalid: test devices with no is_regulator.
667 {
668 json configFile = validConfigFile;
669 configFile["chassis"][0]["devices"][0].erase("is_regulator");
670 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800671 "'is_regulator' is a required property");
Bob Kinga2ba2df2020-02-04 14:38:44 +0800672 }
673 // Invalid: test devices with no fru.
674 {
675 json configFile = validConfigFile;
676 configFile["chassis"][0]["devices"][0].erase("fru");
677 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800678 "'fru' is a required property");
Bob Kinga2ba2df2020-02-04 14:38:44 +0800679 }
680 // Invalid: test devices with no i2c_interface.
681 {
682 json configFile = validConfigFile;
683 configFile["chassis"][0]["devices"][0].erase("i2c_interface");
684 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800685 "'i2c_interface' is a required property");
Bob Kinga2ba2df2020-02-04 14:38:44 +0800686 }
687 // Invalid: test devices with property comments wrong type.
688 {
689 json configFile = validConfigFile;
690 configFile["chassis"][0]["devices"][0]["comments"] = true;
691 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800692 "True is not of type 'array'");
Bob Kinga2ba2df2020-02-04 14:38:44 +0800693 }
694 // Invalid: test devices with property id wrong type.
695 {
696 json configFile = validConfigFile;
697 configFile["chassis"][0]["devices"][0]["id"] = true;
698 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800699 "True is not of type 'string'");
Bob Kinga2ba2df2020-02-04 14:38:44 +0800700 }
701 // Invalid: test devices with property is_regulator wrong type.
702 {
703 json configFile = validConfigFile;
704 configFile["chassis"][0]["devices"][0]["is_regulator"] = 1;
705 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800706 "1 is not of type 'boolean'");
Bob Kinga2ba2df2020-02-04 14:38:44 +0800707 }
708 // Invalid: test devices with property fru wrong type.
709 {
710 json configFile = validConfigFile;
711 configFile["chassis"][0]["devices"][0]["fru"] = true;
712 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800713 "True is not of type 'string'");
Bob Kinga2ba2df2020-02-04 14:38:44 +0800714 }
715 // Invalid: test devices with property i2c_interface wrong type.
716 {
717 json configFile = validConfigFile;
718 configFile["chassis"][0]["devices"][0]["i2c_interface"] = true;
719 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800720 "True is not of type 'object'");
Bob Kinga2ba2df2020-02-04 14:38:44 +0800721 }
722 // Invalid: test devices with property presence_detection wrong
723 // type.
724 {
725 json configFile = validConfigFile;
726 configFile["chassis"][0]["devices"][0]["presence_detection"] = true;
727 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800728 "True is not of type 'object'");
Bob Kinga2ba2df2020-02-04 14:38:44 +0800729 }
730 // Invalid: test devices with property configuration wrong type.
731 {
732 json configFile = validConfigFile;
733 configFile["chassis"][0]["devices"][0]["configuration"] = true;
734 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800735 "True is not of type 'object'");
Bob Kinga2ba2df2020-02-04 14:38:44 +0800736 }
737 // Invalid: test devices with property rails wrong type.
738 {
739 json configFile = validConfigFile;
740 configFile["chassis"][0]["devices"][0]["rails"] = true;
741 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800742 "True is not of type 'array'");
Bob Kinga2ba2df2020-02-04 14:38:44 +0800743 }
744 // Invalid: test devices with property comments empty array.
745 {
746 json configFile = validConfigFile;
747 configFile["chassis"][0]["devices"][0]["comments"] = json::array();
748 EXPECT_JSON_INVALID(configFile, "Validation failed.",
749 "[] is too short");
750 }
751 // Invalid: test devices with property fru length less than 1.
752 {
753 json configFile = validConfigFile;
754 configFile["chassis"][0]["devices"][0]["fru"] = "";
755 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800756 "'' is too short");
Bob Kinga2ba2df2020-02-04 14:38:44 +0800757 }
758 // Invalid: test devices with property id wrong format.
759 {
760 json configFile = validConfigFile;
761 configFile["chassis"][0]["devices"][0]["id"] = "id#";
762 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800763 "'id#' does not match '^[A-Za-z0-9_]+$'");
Bob Kinga2ba2df2020-02-04 14:38:44 +0800764 }
765 // Invalid: test devices with property rails empty array.
766 {
767 json configFile = validConfigFile;
768 configFile["chassis"][0]["devices"][0]["rails"] = json::array();
769 EXPECT_JSON_INVALID(configFile, "Validation failed.",
770 "[] is too short");
771 }
772}
Bob King4ab8cbb2020-01-21 11:10:48 +0800773TEST(ValidateRegulatorsConfigTest, I2CCompareBit)
774{
775 json i2cCompareBitFile = validConfigFile;
776 i2cCompareBitFile["rules"][0]["actions"][1]["i2c_compare_bit"]["register"] =
777 "0xA0";
778 i2cCompareBitFile["rules"][0]["actions"][1]["i2c_compare_bit"]["position"] =
779 3;
780 i2cCompareBitFile["rules"][0]["actions"][1]["i2c_compare_bit"]["value"] = 1;
781 // Valid: test rule actions i2c_compare_bit.
782 {
783 json configFile = i2cCompareBitFile;
784 EXPECT_JSON_VALID(configFile);
785 }
786 // Invalid: test i2c_compare_bit with no register.
787 {
788 json configFile = i2cCompareBitFile;
789 configFile["rules"][0]["actions"][1]["i2c_compare_bit"].erase(
790 "register");
791 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800792 "'register' is a required property");
Bob King4ab8cbb2020-01-21 11:10:48 +0800793 }
794 // Invalid: test i2c_compare_bit with no position.
795 {
796 json configFile = i2cCompareBitFile;
797 configFile["rules"][0]["actions"][1]["i2c_compare_bit"].erase(
798 "position");
799 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800800 "'position' is a required property");
Bob King4ab8cbb2020-01-21 11:10:48 +0800801 }
802 // Invalid: test i2c_compare_bit with no value.
803 {
804 json configFile = i2cCompareBitFile;
805 configFile["rules"][0]["actions"][1]["i2c_compare_bit"].erase("value");
806 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800807 "'value' is a required property");
Bob King4ab8cbb2020-01-21 11:10:48 +0800808 }
809 // Invalid: test i2c_compare_bit with register wrong type.
810 {
811 json configFile = i2cCompareBitFile;
812 configFile["rules"][0]["actions"][1]["i2c_compare_bit"]["register"] = 1;
813 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800814 "1 is not of type 'string'");
Bob King4ab8cbb2020-01-21 11:10:48 +0800815 }
816 // Invalid: test i2c_compare_bit with register wrong format.
817 {
818 json configFile = i2cCompareBitFile;
819 configFile["rules"][0]["actions"][1]["i2c_compare_bit"]["register"] =
820 "0xA00";
821 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800822 "'0xA00' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King4ab8cbb2020-01-21 11:10:48 +0800823 }
824 // Invalid: test i2c_compare_bit with position wrong type.
825 {
826 json configFile = i2cCompareBitFile;
827 configFile["rules"][0]["actions"][1]["i2c_compare_bit"]["position"] =
828 3.1;
829 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800830 "3.1 is not of type 'integer'");
Bob King4ab8cbb2020-01-21 11:10:48 +0800831 }
832 // Invalid: test i2c_compare_bit with position greater than 7.
833 {
834 json configFile = i2cCompareBitFile;
835 configFile["rules"][0]["actions"][1]["i2c_compare_bit"]["position"] = 8;
836 EXPECT_JSON_INVALID(configFile, "Validation failed.",
837 "8 is greater than the maximum of 7");
838 }
839 // Invalid: test i2c_compare_bit with position less than 0.
840 {
841 json configFile = i2cCompareBitFile;
842 configFile["rules"][0]["actions"][1]["i2c_compare_bit"]["position"] =
843 -1;
844 EXPECT_JSON_INVALID(configFile, "Validation failed.",
845 "-1 is less than the minimum of 0");
846 }
847 // Invalid: test i2c_compare_bit with value wrong type.
848 {
849 json configFile = i2cCompareBitFile;
850 configFile["rules"][0]["actions"][1]["i2c_compare_bit"]["value"] = "1";
851 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800852 "'1' is not of type 'integer'");
Bob King4ab8cbb2020-01-21 11:10:48 +0800853 }
854 // Invalid: test i2c_compare_bit with value greater than 1.
855 {
856 json configFile = i2cCompareBitFile;
857 configFile["rules"][0]["actions"][1]["i2c_compare_bit"]["value"] = 2;
858 EXPECT_JSON_INVALID(configFile, "Validation failed.",
859 "2 is greater than the maximum of 1");
860 }
861 // Invalid: test i2c_compare_bit with value less than 0.
862 {
863 json configFile = i2cCompareBitFile;
864 configFile["rules"][0]["actions"][1]["i2c_compare_bit"]["value"] = -1;
865 EXPECT_JSON_INVALID(configFile, "Validation failed.",
866 "-1 is less than the minimum of 0");
867 }
868}
Bob King514023d2020-01-21 11:13:05 +0800869TEST(ValidateRegulatorsConfigTest, I2CCompareByte)
870{
871 json i2cCompareByteFile = validConfigFile;
872 i2cCompareByteFile["rules"][0]["actions"][1]["i2c_compare_byte"]
873 ["register"] = "0x82";
874 i2cCompareByteFile["rules"][0]["actions"][1]["i2c_compare_byte"]["value"] =
875 "0x40";
876 i2cCompareByteFile["rules"][0]["actions"][1]["i2c_compare_byte"]["mask"] =
877 "0x7F";
878 // Valid: test i2c_compare_byte with all properties.
879 {
880 json configFile = i2cCompareByteFile;
881 EXPECT_JSON_VALID(configFile);
882 }
883 // Valid: test i2c_compare_byte with all required properties.
884 {
885 json configFile = i2cCompareByteFile;
886 configFile["rules"][0]["actions"][1]["i2c_compare_byte"].erase("mask");
887 EXPECT_JSON_VALID(configFile);
888 }
889 // Invalid: test i2c_compare_byte with no register.
890 {
891 json configFile = i2cCompareByteFile;
892 configFile["rules"][0]["actions"][1]["i2c_compare_byte"].erase(
893 "register");
894 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800895 "'register' is a required property");
Bob King514023d2020-01-21 11:13:05 +0800896 }
897 // Invalid: test i2c_compare_byte with no value.
898 {
899 json configFile = i2cCompareByteFile;
900 configFile["rules"][0]["actions"][1]["i2c_compare_byte"].erase("value");
901 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800902 "'value' is a required property");
Bob King514023d2020-01-21 11:13:05 +0800903 }
904 // Invalid: test i2c_compare_byte with property register wrong type.
905 {
906 json configFile = i2cCompareByteFile;
907 configFile["rules"][0]["actions"][1]["i2c_compare_byte"]["register"] =
908 1;
909 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800910 "1 is not of type 'string'");
Bob King514023d2020-01-21 11:13:05 +0800911 }
912 // Invalid: test i2c_compare_byte with property value wrong type.
913 {
914 json configFile = i2cCompareByteFile;
915 configFile["rules"][0]["actions"][1]["i2c_compare_byte"]["value"] = 1;
916 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800917 "1 is not of type 'string'");
Bob King514023d2020-01-21 11:13:05 +0800918 }
919 // Invalid: test i2c_compare_byte with property mask wrong type.
920 {
921 json configFile = i2cCompareByteFile;
922 configFile["rules"][0]["actions"][1]["i2c_compare_byte"]["mask"] = 1;
923 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800924 "1 is not of type 'string'");
Bob King514023d2020-01-21 11:13:05 +0800925 }
926 // Invalid: test i2c_compare_byte with property register more than 2 hex
927 // digits.
928 {
929 json configFile = i2cCompareByteFile;
930 configFile["rules"][0]["actions"][1]["i2c_compare_byte"]["register"] =
931 "0x820";
932 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800933 "'0x820' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King514023d2020-01-21 11:13:05 +0800934 }
935 // Invalid: test i2c_compare_byte with property value more than 2 hex
936 // digits.
937 {
938 json configFile = i2cCompareByteFile;
939 configFile["rules"][0]["actions"][1]["i2c_compare_byte"]["value"] =
940 "0x820";
941 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800942 "'0x820' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King514023d2020-01-21 11:13:05 +0800943 }
944 // Invalid: test i2c_compare_byte with property mask more than 2 hex digits.
945 {
946 json configFile = i2cCompareByteFile;
947 configFile["rules"][0]["actions"][1]["i2c_compare_byte"]["mask"] =
948 "0x820";
949 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800950 "'0x820' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King514023d2020-01-21 11:13:05 +0800951 }
952 // Invalid: test i2c_compare_byte with property register less than 2 hex
953 // digits.
954 {
955 json configFile = i2cCompareByteFile;
956 configFile["rules"][0]["actions"][1]["i2c_compare_byte"]["register"] =
957 "0x8";
958 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800959 "'0x8' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King514023d2020-01-21 11:13:05 +0800960 }
961 // Invalid: test i2c_compare_byte with property value less than 2 hex
962 // digits.
963 {
964 json configFile = i2cCompareByteFile;
965 configFile["rules"][0]["actions"][1]["i2c_compare_byte"]["value"] =
966 "0x8";
967 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800968 "'0x8' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King514023d2020-01-21 11:13:05 +0800969 }
970 // Invalid: test i2c_compare_byte with property mask less than 2 hex digits.
971 {
972 json configFile = i2cCompareByteFile;
973 configFile["rules"][0]["actions"][1]["i2c_compare_byte"]["mask"] =
974 "0x8";
975 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800976 "'0x8' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King514023d2020-01-21 11:13:05 +0800977 }
978 // Invalid: test i2c_compare_byte with property register no leading prefix.
979 {
980 json configFile = i2cCompareByteFile;
981 configFile["rules"][0]["actions"][1]["i2c_compare_byte"]["register"] =
982 "82";
983 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800984 "'82' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King514023d2020-01-21 11:13:05 +0800985 }
986 // Invalid: test i2c_compare_byte with property value no leading prefix.
987 {
988 json configFile = i2cCompareByteFile;
989 configFile["rules"][0]["actions"][1]["i2c_compare_byte"]["value"] =
990 "82";
991 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800992 "'82' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King514023d2020-01-21 11:13:05 +0800993 }
994 // Invalid: test i2c_compare_byte with property mask no leading prefix.
995 {
996 json configFile = i2cCompareByteFile;
997 configFile["rules"][0]["actions"][1]["i2c_compare_byte"]["mask"] = "82";
998 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800999 "'82' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King514023d2020-01-21 11:13:05 +08001000 }
1001 // Invalid: test i2c_compare_byte with property register invalid hex digit.
1002 {
1003 json configFile = i2cCompareByteFile;
1004 configFile["rules"][0]["actions"][1]["i2c_compare_byte"]["register"] =
1005 "0xG1";
1006 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001007 "'0xG1' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King514023d2020-01-21 11:13:05 +08001008 }
1009 // Invalid: test i2c_compare_byte with property value invalid hex digit.
1010 {
1011 json configFile = i2cCompareByteFile;
1012 configFile["rules"][0]["actions"][1]["i2c_compare_byte"]["value"] =
1013 "0xG1";
1014 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001015 "'0xG1' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King514023d2020-01-21 11:13:05 +08001016 }
1017 // Invalid: test i2c_compare_byte with property mask invalid hex digit.
1018 {
1019 json configFile = i2cCompareByteFile;
1020 configFile["rules"][0]["actions"][1]["i2c_compare_byte"]["mask"] =
1021 "0xG1";
1022 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001023 "'0xG1' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King514023d2020-01-21 11:13:05 +08001024 }
1025}
Bob Kingfb162bb2020-01-21 11:28:07 +08001026TEST(ValidateRegulatorsConfigTest, I2CCompareBytes)
1027{
1028 json i2cCompareBytesFile = validConfigFile;
1029 i2cCompareBytesFile["rules"][0]["actions"][1]["i2c_compare_bytes"]
1030 ["register"] = "0x82";
1031 i2cCompareBytesFile["rules"][0]["actions"][1]["i2c_compare_bytes"]
1032 ["values"] = {"0x02", "0x73"};
1033 i2cCompareBytesFile["rules"][0]["actions"][1]["i2c_compare_bytes"]
1034 ["masks"] = {"0x7F", "0x7F"};
1035 // Valid: test i2c_compare_bytes.
1036 {
1037 json configFile = i2cCompareBytesFile;
1038 EXPECT_JSON_VALID(configFile);
1039 }
1040 // Valid: test i2c_compare_bytes with all required properties.
1041 {
1042 json configFile = i2cCompareBytesFile;
1043 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"].erase(
1044 "masks");
1045 EXPECT_JSON_VALID(configFile);
1046 }
1047 // Invalid: test i2c_compare_bytes with no register.
1048 {
1049 json configFile = i2cCompareBytesFile;
1050 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"].erase(
1051 "register");
1052 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001053 "'register' is a required property");
Bob Kingfb162bb2020-01-21 11:28:07 +08001054 }
1055 // Invalid: test i2c_compare_bytes with no values.
1056 {
1057 json configFile = i2cCompareBytesFile;
1058 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"].erase(
1059 "values");
1060 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001061 "'values' is a required property");
Bob Kingfb162bb2020-01-21 11:28:07 +08001062 }
1063 // Invalid: test i2c_compare_bytes with property values as empty array.
1064 {
1065 json configFile = i2cCompareBytesFile;
1066 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["values"] =
1067 json::array();
1068 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1069 "[] is too short");
1070 }
1071 // Invalid: test i2c_compare_bytes with property masks as empty array.
1072 {
1073 json configFile = i2cCompareBytesFile;
1074 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["masks"] =
1075 json::array();
1076 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1077 "[] is too short");
1078 }
1079 // Invalid: test i2c_compare_bytes with property register wrong type.
1080 {
1081 json configFile = i2cCompareBytesFile;
1082 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["register"] =
1083 1;
1084 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001085 "1 is not of type 'string'");
Bob Kingfb162bb2020-01-21 11:28:07 +08001086 }
1087 // Invalid: test i2c_compare_bytes with property values wrong type.
1088 {
1089 json configFile = i2cCompareBytesFile;
1090 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["values"] = 1;
1091 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001092 "1 is not of type 'array'");
Bob Kingfb162bb2020-01-21 11:28:07 +08001093 }
1094 // Invalid: test i2c_compare_bytes with property masks wrong type.
1095 {
1096 json configFile = i2cCompareBytesFile;
1097 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["masks"] = 1;
1098 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001099 "1 is not of type 'array'");
Bob Kingfb162bb2020-01-21 11:28:07 +08001100 }
1101 // Invalid: test i2c_compare_bytes with property register more than 2 hex
1102 // digits.
1103 {
1104 json configFile = i2cCompareBytesFile;
1105 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["register"] =
1106 "0x820";
1107 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001108 "'0x820' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob Kingfb162bb2020-01-21 11:28:07 +08001109 }
1110 // Invalid: test i2c_compare_bytes with property values more than 2 hex
1111 // digits.
1112 {
1113 json configFile = i2cCompareBytesFile;
1114 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["values"][0] =
1115 "0x820";
1116 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001117 "'0x820' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob Kingfb162bb2020-01-21 11:28:07 +08001118 }
1119 // Invalid: test i2c_compare_bytes with property masks more than 2 hex
1120 // digits.
1121 {
1122 json configFile = i2cCompareBytesFile;
1123 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["masks"][0] =
1124 "0x820";
1125 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001126 "'0x820' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob Kingfb162bb2020-01-21 11:28:07 +08001127 }
1128 // Invalid: test i2c_compare_bytes with property register less than 2 hex
1129 // digits.
1130 {
1131 json configFile = i2cCompareBytesFile;
1132 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["register"] =
1133 "0x8";
1134 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001135 "'0x8' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob Kingfb162bb2020-01-21 11:28:07 +08001136 }
1137 // Invalid: test i2c_compare_bytes with property values less than 2 hex
1138 // digits.
1139 {
1140 json configFile = i2cCompareBytesFile;
1141 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["values"][0] =
1142 "0x8";
1143 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001144 "'0x8' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob Kingfb162bb2020-01-21 11:28:07 +08001145 }
1146 // Invalid: test i2c_compare_bytes with property masks less than 2 hex
1147 // digits.
1148 {
1149 json configFile = i2cCompareBytesFile;
1150 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["masks"][0] =
1151 "0x8";
1152 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001153 "'0x8' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob Kingfb162bb2020-01-21 11:28:07 +08001154 }
1155 // Invalid: test i2c_compare_bytes with property register no leading prefix.
1156 {
1157 json configFile = i2cCompareBytesFile;
1158 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["register"] =
1159 "82";
1160 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001161 "'82' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob Kingfb162bb2020-01-21 11:28:07 +08001162 }
1163 // Invalid: test i2c_compare_bytes with property values no leading prefix.
1164 {
1165 json configFile = i2cCompareBytesFile;
1166 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["values"][0] =
1167 "82";
1168 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001169 "'82' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob Kingfb162bb2020-01-21 11:28:07 +08001170 }
1171 // Invalid: test i2c_compare_bytes with property masks no leading prefix.
1172 {
1173 json configFile = i2cCompareBytesFile;
1174 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["masks"][0] =
1175 "82";
1176 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001177 "'82' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob Kingfb162bb2020-01-21 11:28:07 +08001178 }
1179 // Invalid: test i2c_compare_bytes with property register invalid hex digit.
1180 {
1181 json configFile = i2cCompareBytesFile;
1182 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["register"] =
1183 "0xG1";
1184 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001185 "'0xG1' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob Kingfb162bb2020-01-21 11:28:07 +08001186 }
1187 // Invalid: test i2c_compare_bytes with property values invalid hex digit.
1188 {
1189 json configFile = i2cCompareBytesFile;
1190 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["values"][0] =
1191 "0xG1";
1192 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001193 "'0xG1' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob Kingfb162bb2020-01-21 11:28:07 +08001194 }
1195 // Invalid: test i2c_compare_bytes with property masks invalid hex digit.
1196 {
1197 json configFile = i2cCompareBytesFile;
1198 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["masks"][0] =
1199 "0xG1";
1200 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001201 "'0xG1' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob Kingfb162bb2020-01-21 11:28:07 +08001202 }
1203}
Bob Kingca93f1f2020-01-31 11:21:16 +08001204TEST(ValidateRegulatorsConfigTest, I2CInterface)
1205{
1206 // Valid: test i2c_interface.
1207 {
1208 json configFile = validConfigFile;
1209 EXPECT_JSON_VALID(configFile);
1210 }
1211 // Invalid: testi2c_interface with no bus.
1212 {
1213 json configFile = validConfigFile;
1214 configFile["chassis"][0]["devices"][0]["i2c_interface"].erase("bus");
1215 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001216 "'bus' is a required property");
Bob Kingca93f1f2020-01-31 11:21:16 +08001217 }
1218 // Invalid: test i2c_interface with no address.
1219 {
1220 json configFile = validConfigFile;
1221 configFile["chassis"][0]["devices"][0]["i2c_interface"].erase(
1222 "address");
1223 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001224 "'address' is a required property");
Bob Kingca93f1f2020-01-31 11:21:16 +08001225 }
1226 // Invalid: test i2c_interface with property bus wrong type.
1227 {
1228 json configFile = validConfigFile;
1229 configFile["chassis"][0]["devices"][0]["i2c_interface"]["bus"] = true;
1230 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001231 "True is not of type 'integer'");
Bob Kingca93f1f2020-01-31 11:21:16 +08001232 }
1233 // Invalid: test i2c_interface with property address wrong
1234 // type.
1235 {
1236 json configFile = validConfigFile;
1237 configFile["chassis"][0]["devices"][0]["i2c_interface"]["address"] =
1238 true;
1239 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001240 "True is not of type 'string'");
Bob Kingca93f1f2020-01-31 11:21:16 +08001241 }
1242 // Invalid: test i2c_interface with property bus less than
1243 // 0.
1244 {
1245 json configFile = validConfigFile;
1246 configFile["chassis"][0]["devices"][0]["i2c_interface"]["bus"] = -1;
1247 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1248 "-1 is less than the minimum of 0");
1249 }
1250 // Invalid: test i2c_interface with property address wrong
1251 // format.
1252 {
1253 json configFile = validConfigFile;
1254 configFile["chassis"][0]["devices"][0]["i2c_interface"]["address"] =
1255 "0x700";
1256 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001257 "'0x700' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob Kingca93f1f2020-01-31 11:21:16 +08001258 }
1259}
Bob King188db7d2020-01-31 13:01:01 +08001260TEST(ValidateRegulatorsConfigTest, I2CWriteBit)
1261{
1262 json i2cWriteBitFile = validConfigFile;
1263 i2cWriteBitFile["rules"][0]["actions"][1]["i2c_write_bit"]["register"] =
1264 "0xA0";
1265 i2cWriteBitFile["rules"][0]["actions"][1]["i2c_write_bit"]["position"] = 3;
1266 i2cWriteBitFile["rules"][0]["actions"][1]["i2c_write_bit"]["value"] = 1;
1267 // Valid: test rule actions i2c_write_bit.
1268 {
1269 json configFile = i2cWriteBitFile;
1270 EXPECT_JSON_VALID(configFile);
1271 }
1272 // Invalid: test i2c_write_bit with no register.
1273 {
1274 json configFile = i2cWriteBitFile;
1275 configFile["rules"][0]["actions"][1]["i2c_write_bit"].erase("register");
1276 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001277 "'register' is a required property");
Bob King188db7d2020-01-31 13:01:01 +08001278 }
1279 // Invalid: test i2c_write_bit with no position.
1280 {
1281 json configFile = i2cWriteBitFile;
1282 configFile["rules"][0]["actions"][1]["i2c_write_bit"].erase("position");
1283 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001284 "'position' is a required property");
Bob King188db7d2020-01-31 13:01:01 +08001285 }
1286 // Invalid: test i2c_write_bit with no value.
1287 {
1288 json configFile = i2cWriteBitFile;
1289 configFile["rules"][0]["actions"][1]["i2c_write_bit"].erase("value");
1290 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001291 "'value' is a required property");
Bob King188db7d2020-01-31 13:01:01 +08001292 }
1293 // Invalid: test i2c_write_bit with register wrong type.
1294 {
1295 json configFile = i2cWriteBitFile;
1296 configFile["rules"][0]["actions"][1]["i2c_write_bit"]["register"] = 1;
1297 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001298 "1 is not of type 'string'");
Bob King188db7d2020-01-31 13:01:01 +08001299 }
1300 // Invalid: test i2c_write_bit with register wrong format.
1301 {
1302 json configFile = i2cWriteBitFile;
1303 configFile["rules"][0]["actions"][1]["i2c_write_bit"]["register"] =
1304 "0xA00";
1305 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001306 "'0xA00' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08001307 }
1308 // Invalid: test i2c_write_bit with position wrong type.
1309 {
1310 json configFile = i2cWriteBitFile;
1311 configFile["rules"][0]["actions"][1]["i2c_write_bit"]["position"] = 3.1;
1312 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001313 "3.1 is not of type 'integer'");
Bob King188db7d2020-01-31 13:01:01 +08001314 }
1315 // Invalid: test i2c_write_bit with position greater than 7.
1316 {
1317 json configFile = i2cWriteBitFile;
1318 configFile["rules"][0]["actions"][1]["i2c_write_bit"]["position"] = 8;
1319 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1320 "8 is greater than the maximum of 7");
1321 }
1322 // Invalid: test i2c_write_bit with position less than 0.
1323 {
1324 json configFile = i2cWriteBitFile;
1325 configFile["rules"][0]["actions"][1]["i2c_write_bit"]["position"] = -1;
1326 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1327 "-1 is less than the minimum of 0");
1328 }
1329 // Invalid: test i2c_write_bit with value wrong type.
1330 {
1331 json configFile = i2cWriteBitFile;
1332 configFile["rules"][0]["actions"][1]["i2c_write_bit"]["value"] = "1";
1333 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001334 "'1' is not of type 'integer'");
Bob King188db7d2020-01-31 13:01:01 +08001335 }
1336 // Invalid: test i2c_write_bit with value greater than 1.
1337 {
1338 json configFile = i2cWriteBitFile;
1339 configFile["rules"][0]["actions"][1]["i2c_write_bit"]["value"] = 2;
1340 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1341 "2 is greater than the maximum of 1");
1342 }
1343 // Invalid: test i2c_write_bit with value less than 0.
1344 {
1345 json configFile = i2cWriteBitFile;
1346 configFile["rules"][0]["actions"][1]["i2c_write_bit"]["value"] = -1;
1347 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1348 "-1 is less than the minimum of 0");
1349 }
1350}
1351TEST(ValidateRegulatorsConfigTest, I2CWriteByte)
1352{
1353 json i2cWriteByteFile = validConfigFile;
1354 i2cWriteByteFile["rules"][0]["actions"][1]["i2c_write_byte"]["register"] =
1355 "0x82";
1356 i2cWriteByteFile["rules"][0]["actions"][1]["i2c_write_byte"]["value"] =
1357 "0x40";
1358 i2cWriteByteFile["rules"][0]["actions"][1]["i2c_write_byte"]["mask"] =
1359 "0x7F";
1360 // Valid: test i2c_write_byte with all properties.
1361 {
1362 json configFile = i2cWriteByteFile;
1363 EXPECT_JSON_VALID(configFile);
1364 }
1365 // Valid: test i2c_write_byte with all required properties.
1366 {
1367 json configFile = i2cWriteByteFile;
1368 configFile["rules"][0]["actions"][1]["i2c_write_byte"].erase("mask");
1369 EXPECT_JSON_VALID(configFile);
1370 }
1371 // Invalid: test i2c_write_byte with no register.
1372 {
1373 json configFile = i2cWriteByteFile;
1374 configFile["rules"][0]["actions"][1]["i2c_write_byte"].erase(
1375 "register");
1376 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001377 "'register' is a required property");
Bob King188db7d2020-01-31 13:01:01 +08001378 }
1379 // Invalid: test i2c_write_byte with no value.
1380 {
1381 json configFile = i2cWriteByteFile;
1382 configFile["rules"][0]["actions"][1]["i2c_write_byte"].erase("value");
1383 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001384 "'value' is a required property");
Bob King188db7d2020-01-31 13:01:01 +08001385 }
1386 // Invalid: test i2c_write_byte with property register wrong type.
1387 {
1388 json configFile = i2cWriteByteFile;
1389 configFile["rules"][0]["actions"][1]["i2c_write_byte"]["register"] = 1;
1390 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001391 "1 is not of type 'string'");
Bob King188db7d2020-01-31 13:01:01 +08001392 }
1393 // Invalid: test i2c_write_byte with property value wrong type.
1394 {
1395 json configFile = i2cWriteByteFile;
1396 configFile["rules"][0]["actions"][1]["i2c_write_byte"]["value"] = 1;
1397 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001398 "1 is not of type 'string'");
Bob King188db7d2020-01-31 13:01:01 +08001399 }
1400 // Invalid: test i2c_write_byte with property mask wrong type.
1401 {
1402 json configFile = i2cWriteByteFile;
1403 configFile["rules"][0]["actions"][1]["i2c_write_byte"]["mask"] = 1;
1404 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001405 "1 is not of type 'string'");
Bob King188db7d2020-01-31 13:01:01 +08001406 }
1407 // Invalid: test i2c_write_byte with property register more than 2 hex
1408 // digits.
1409 {
1410 json configFile = i2cWriteByteFile;
1411 configFile["rules"][0]["actions"][1]["i2c_write_byte"]["register"] =
1412 "0x820";
1413 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001414 "'0x820' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08001415 }
1416 // Invalid: test i2c_write_byte with property value more than 2 hex
1417 // digits.
1418 {
1419 json configFile = i2cWriteByteFile;
1420 configFile["rules"][0]["actions"][1]["i2c_write_byte"]["value"] =
1421 "0x820";
1422 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001423 "'0x820' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08001424 }
1425 // Invalid: test i2c_write_byte with property mask more than 2 hex digits.
1426 {
1427 json configFile = i2cWriteByteFile;
1428 configFile["rules"][0]["actions"][1]["i2c_write_byte"]["mask"] =
1429 "0x820";
1430 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001431 "'0x820' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08001432 }
1433 // Invalid: test i2c_write_byte with property register less than 2 hex
1434 // digits.
1435 {
1436 json configFile = i2cWriteByteFile;
1437 configFile["rules"][0]["actions"][1]["i2c_write_byte"]["register"] =
1438 "0x8";
1439 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001440 "'0x8' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08001441 }
1442 // Invalid: test i2c_write_byte with property value less than 2 hex
1443 // digits.
1444 {
1445 json configFile = i2cWriteByteFile;
1446 configFile["rules"][0]["actions"][1]["i2c_write_byte"]["value"] = "0x8";
1447 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001448 "'0x8' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08001449 }
1450 // Invalid: test i2c_write_byte with property mask less than 2 hex digits.
1451 {
1452 json configFile = i2cWriteByteFile;
1453 configFile["rules"][0]["actions"][1]["i2c_write_byte"]["mask"] = "0x8";
1454 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001455 "'0x8' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08001456 }
1457 // Invalid: test i2c_write_byte with property register no leading prefix.
1458 {
1459 json configFile = i2cWriteByteFile;
1460 configFile["rules"][0]["actions"][1]["i2c_write_byte"]["register"] =
1461 "82";
1462 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001463 "'82' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08001464 }
1465 // Invalid: test i2c_write_byte with property value no leading prefix.
1466 {
1467 json configFile = i2cWriteByteFile;
1468 configFile["rules"][0]["actions"][1]["i2c_write_byte"]["value"] = "82";
1469 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001470 "'82' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08001471 }
1472 // Invalid: test i2c_write_byte with property mask no leading prefix.
1473 {
1474 json configFile = i2cWriteByteFile;
1475 configFile["rules"][0]["actions"][1]["i2c_write_byte"]["mask"] = "82";
1476 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001477 "'82' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08001478 }
1479 // Invalid: test i2c_write_byte with property register invalid hex digit.
1480 {
1481 json configFile = i2cWriteByteFile;
1482 configFile["rules"][0]["actions"][1]["i2c_write_byte"]["register"] =
1483 "0xG1";
1484 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001485 "'0xG1' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08001486 }
1487 // Invalid: test i2c_write_byte with property value invalid hex digit.
1488 {
1489 json configFile = i2cWriteByteFile;
1490 configFile["rules"][0]["actions"][1]["i2c_write_byte"]["value"] =
1491 "0xG1";
1492 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001493 "'0xG1' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08001494 }
1495 // Invalid: test i2c_write_byte with property mask invalid hex digit.
1496 {
1497 json configFile = i2cWriteByteFile;
1498 configFile["rules"][0]["actions"][1]["i2c_write_byte"]["mask"] = "0xG1";
1499 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001500 "'0xG1' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08001501 }
1502}
1503TEST(ValidateRegulatorsConfigTest, I2CWriteBytes)
1504{
1505 json i2cWriteBytesFile = validConfigFile;
1506 i2cWriteBytesFile["rules"][0]["actions"][1]["i2c_write_bytes"]["register"] =
1507 "0x82";
1508 i2cWriteBytesFile["rules"][0]["actions"][1]["i2c_write_bytes"]["values"] = {
1509 "0x02", "0x73"};
1510 i2cWriteBytesFile["rules"][0]["actions"][1]["i2c_write_bytes"]["masks"] = {
1511 "0x7F", "0x7F"};
1512 // Valid: test i2c_write_bytes.
1513 {
1514 json configFile = i2cWriteBytesFile;
1515 EXPECT_JSON_VALID(configFile);
1516 }
1517 // Valid: test i2c_write_bytes with all required properties.
1518 {
1519 json configFile = i2cWriteBytesFile;
1520 configFile["rules"][0]["actions"][1]["i2c_write_bytes"].erase("masks");
1521 EXPECT_JSON_VALID(configFile);
1522 }
1523 // Invalid: test i2c_write_bytes with no register.
1524 {
1525 json configFile = i2cWriteBytesFile;
1526 configFile["rules"][0]["actions"][1]["i2c_write_bytes"].erase(
1527 "register");
1528 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001529 "'register' is a required property");
Bob King188db7d2020-01-31 13:01:01 +08001530 }
1531 // Invalid: test i2c_write_bytes with no values.
1532 {
1533 json configFile = i2cWriteBytesFile;
1534 configFile["rules"][0]["actions"][1]["i2c_write_bytes"].erase("values");
1535 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001536 "'values' is a required property");
Bob King188db7d2020-01-31 13:01:01 +08001537 }
1538 // Invalid: test i2c_write_bytes with property values as empty array.
1539 {
1540 json configFile = i2cWriteBytesFile;
1541 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["values"] =
1542 json::array();
1543 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1544 "[] is too short");
1545 }
1546 // Invalid: test i2c_write_bytes with property masks as empty array.
1547 {
1548 json configFile = i2cWriteBytesFile;
1549 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["masks"] =
1550 json::array();
1551 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1552 "[] is too short");
1553 }
1554 // Invalid: test i2c_write_bytes with property register wrong type.
1555 {
1556 json configFile = i2cWriteBytesFile;
1557 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["register"] = 1;
1558 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001559 "1 is not of type 'string'");
Bob King188db7d2020-01-31 13:01:01 +08001560 }
1561 // Invalid: test i2c_write_bytes with property values wrong type.
1562 {
1563 json configFile = i2cWriteBytesFile;
1564 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["values"] = 1;
1565 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001566 "1 is not of type 'array'");
Bob King188db7d2020-01-31 13:01:01 +08001567 }
1568 // Invalid: test i2c_write_bytes with property masks wrong type.
1569 {
1570 json configFile = i2cWriteBytesFile;
1571 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["masks"] = 1;
1572 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001573 "1 is not of type 'array'");
Bob King188db7d2020-01-31 13:01:01 +08001574 }
1575 // Invalid: test i2c_write_bytes with property register more than 2 hex
1576 // digits.
1577 {
1578 json configFile = i2cWriteBytesFile;
1579 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["register"] =
1580 "0x820";
1581 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001582 "'0x820' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08001583 }
1584 // Invalid: test i2c_write_bytes with property values more than 2 hex
1585 // digits.
1586 {
1587 json configFile = i2cWriteBytesFile;
1588 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["values"][0] =
1589 "0x820";
1590 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001591 "'0x820' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08001592 }
1593 // Invalid: test i2c_write_bytes with property masks more than 2 hex
1594 // digits.
1595 {
1596 json configFile = i2cWriteBytesFile;
1597 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["masks"][0] =
1598 "0x820";
1599 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001600 "'0x820' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08001601 }
1602 // Invalid: test i2c_write_bytes with property register less than 2 hex
1603 // digits.
1604 {
1605 json configFile = i2cWriteBytesFile;
1606 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["register"] =
1607 "0x8";
1608 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001609 "'0x8' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08001610 }
1611 // Invalid: test i2c_write_bytes with property values less than 2 hex
1612 // digits.
1613 {
1614 json configFile = i2cWriteBytesFile;
1615 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["values"][0] =
1616 "0x8";
1617 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001618 "'0x8' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08001619 }
1620 // Invalid: test i2c_write_bytes with property masks less than 2 hex
1621 // digits.
1622 {
1623 json configFile = i2cWriteBytesFile;
1624 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["masks"][0] =
1625 "0x8";
1626 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001627 "'0x8' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08001628 }
1629 // Invalid: test i2c_write_bytes with property register no leading prefix.
1630 {
1631 json configFile = i2cWriteBytesFile;
1632 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["register"] =
1633 "82";
1634 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001635 "'82' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08001636 }
1637 // Invalid: test i2c_write_bytes with property values no leading prefix.
1638 {
1639 json configFile = i2cWriteBytesFile;
1640 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["values"][0] =
1641 "82";
1642 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001643 "'82' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08001644 }
1645 // Invalid: test i2c_write_bytes with property masks no leading prefix.
1646 {
1647 json configFile = i2cWriteBytesFile;
1648 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["masks"][0] =
1649 "82";
1650 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001651 "'82' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08001652 }
1653 // Invalid: test i2c_write_bytes with property register invalid hex digit.
1654 {
1655 json configFile = i2cWriteBytesFile;
1656 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["register"] =
1657 "0xG1";
1658 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001659 "'0xG1' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08001660 }
1661 // Invalid: test i2c_write_bytes with property values invalid hex digit.
1662 {
1663 json configFile = i2cWriteBytesFile;
1664 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["values"][0] =
1665 "0xG1";
1666 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001667 "'0xG1' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08001668 }
1669 // Invalid: test i2c_write_bytes with property masks invalid hex digit.
1670 {
1671 json configFile = i2cWriteBytesFile;
1672 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["masks"][0] =
1673 "0xG1";
1674 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001675 "'0xG1' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08001676 }
1677}
Bob Kingead0b052020-01-21 11:29:03 +08001678TEST(ValidateRegulatorsConfigTest, If)
1679{
1680 json ifFile = validConfigFile;
Bob King2d27dcf2020-02-11 15:00:50 +08001681 ifFile["rules"][2]["actions"][0]["if"]["condition"]["run_rule"] =
1682 "set_voltage_rule";
1683 ifFile["rules"][2]["actions"][0]["if"]["then"][0]["run_rule"] =
1684 "read_sensors_rule";
1685 ifFile["rules"][2]["actions"][0]["if"]["else"][0]["run_rule"] =
1686 "read_sensors_rule";
1687 ifFile["rules"][2]["id"] = "rule_if";
Bob Kingead0b052020-01-21 11:29:03 +08001688 // Valid: test if.
1689 {
1690 json configFile = ifFile;
1691 EXPECT_JSON_VALID(configFile);
1692 }
1693 // Valid: test if with required properties.
1694 {
1695 json configFile = ifFile;
Bob King2d27dcf2020-02-11 15:00:50 +08001696 configFile["rules"][2]["actions"][0]["if"].erase("else");
Bob Kingead0b052020-01-21 11:29:03 +08001697 EXPECT_JSON_VALID(configFile);
1698 }
1699 // Invalid: test if with no property condition.
1700 {
1701 json configFile = ifFile;
Bob King2d27dcf2020-02-11 15:00:50 +08001702 configFile["rules"][2]["actions"][0]["if"].erase("condition");
Bob Kingead0b052020-01-21 11:29:03 +08001703 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001704 "'condition' is a required property");
Bob Kingead0b052020-01-21 11:29:03 +08001705 }
1706 // Invalid: test if with no property then.
1707 {
1708 json configFile = ifFile;
Bob King2d27dcf2020-02-11 15:00:50 +08001709 configFile["rules"][2]["actions"][0]["if"].erase("then");
Bob Kingead0b052020-01-21 11:29:03 +08001710 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001711 "'then' is a required property");
Bob Kingead0b052020-01-21 11:29:03 +08001712 }
1713 // Invalid: test if with property then empty array.
1714 {
1715 json configFile = ifFile;
Bob King2d27dcf2020-02-11 15:00:50 +08001716 configFile["rules"][2]["actions"][0]["if"]["then"] = json::array();
Bob Kingead0b052020-01-21 11:29:03 +08001717 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1718 "[] is too short");
1719 }
1720 // Invalid: test if with property else empty array.
1721 {
1722 json configFile = ifFile;
Bob King2d27dcf2020-02-11 15:00:50 +08001723 configFile["rules"][2]["actions"][0]["if"]["else"] = json::array();
Bob Kingead0b052020-01-21 11:29:03 +08001724 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1725 "[] is too short");
1726 }
1727 // Invalid: test if with property condition wrong type.
1728 {
1729 json configFile = ifFile;
Bob King2d27dcf2020-02-11 15:00:50 +08001730 configFile["rules"][2]["actions"][0]["if"]["condition"] = 1;
Bob Kingead0b052020-01-21 11:29:03 +08001731 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001732 "1 is not of type 'object'");
Bob Kingead0b052020-01-21 11:29:03 +08001733 }
1734 // Invalid: test if with property then wrong type.
1735 {
1736 json configFile = ifFile;
Bob King2d27dcf2020-02-11 15:00:50 +08001737 configFile["rules"][2]["actions"][0]["if"]["then"] = 1;
Bob Kingead0b052020-01-21 11:29:03 +08001738 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001739 "1 is not of type 'array'");
Bob Kingead0b052020-01-21 11:29:03 +08001740 }
1741 // Invalid: test if with property else wrong type.
1742 {
1743 json configFile = ifFile;
Bob King2d27dcf2020-02-11 15:00:50 +08001744 configFile["rules"][2]["actions"][0]["if"]["else"] = 1;
Bob Kingead0b052020-01-21 11:29:03 +08001745 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001746 "1 is not of type 'array'");
Bob Kingead0b052020-01-21 11:29:03 +08001747 }
1748}
Bob Kingbfe9fe72020-01-21 11:29:57 +08001749TEST(ValidateRegulatorsConfigTest, Not)
1750{
1751 json notFile = validConfigFile;
1752 notFile["rules"][0]["actions"][1]["not"]["i2c_compare_byte"]["register"] =
1753 "0xA0";
1754 notFile["rules"][0]["actions"][1]["not"]["i2c_compare_byte"]["value"] =
1755 "0xFF";
1756 // Valid: test not.
1757 {
1758 json configFile = notFile;
1759 EXPECT_JSON_VALID(configFile);
1760 }
1761 // Invalid: test not with wrong type.
1762 {
1763 json configFile = notFile;
1764 configFile["rules"][0]["actions"][1]["not"] = 1;
1765 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001766 "1 is not of type 'object'");
Bob Kingbfe9fe72020-01-21 11:29:57 +08001767 }
1768}
Bob Kingcfc29d02020-01-21 11:30:50 +08001769TEST(ValidateRegulatorsConfigTest, Or)
1770{
1771 json orFile = validConfigFile;
1772 orFile["rules"][0]["actions"][1]["or"][0]["i2c_compare_byte"]["register"] =
1773 "0xA0";
1774 orFile["rules"][0]["actions"][1]["or"][0]["i2c_compare_byte"]["value"] =
1775 "0x00";
1776 orFile["rules"][0]["actions"][1]["or"][1]["i2c_compare_byte"]["register"] =
1777 "0xA1";
1778 orFile["rules"][0]["actions"][1]["or"][1]["i2c_compare_byte"]["value"] =
1779 "0x00";
1780 // Valid: test or.
1781 {
1782 json configFile = orFile;
1783 EXPECT_JSON_VALID(configFile);
1784 }
1785 // Invalid: test or with empty array.
1786 {
1787 json configFile = orFile;
1788 configFile["rules"][0]["actions"][1]["or"] = json::array();
1789 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1790 "[] is too short");
1791 }
1792 // Invalid: test or with wrong type.
1793 {
1794 json configFile = orFile;
1795 configFile["rules"][0]["actions"][1]["or"] = 1;
1796 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001797 "1 is not of type 'array'");
Bob Kingcfc29d02020-01-21 11:30:50 +08001798 }
1799}
Bob Kingd6618092020-01-21 11:31:46 +08001800TEST(ValidateRegulatorsConfigTest, PmbusReadSensor)
1801{
1802 json pmbusReadSensorFile = validConfigFile;
1803 pmbusReadSensorFile["rules"][0]["actions"][1]["pmbus_read_sensor"]["type"] =
1804 "vout";
1805 pmbusReadSensorFile["rules"][0]["actions"][1]["pmbus_read_sensor"]
1806 ["command"] = "0x8B";
1807 pmbusReadSensorFile["rules"][0]["actions"][1]["pmbus_read_sensor"]
1808 ["format"] = "linear_16";
1809 pmbusReadSensorFile["rules"][0]["actions"][1]["pmbus_read_sensor"]
1810 ["exponent"] = -8;
1811 // Valid: test pmbus_read_sensor.
1812 {
1813 json configFile = pmbusReadSensorFile;
1814 EXPECT_JSON_VALID(configFile);
1815 }
1816 // Valid: test pmbus_read_sensor with required properties.
1817 {
1818 json configFile = pmbusReadSensorFile;
1819 configFile["rules"][0]["actions"][1]["pmbus_read_sensor"].erase(
1820 "exponent");
1821 EXPECT_JSON_VALID(configFile);
1822 }
1823 // Invalid: test pmbus_read_sensor with no type.
1824 {
1825 json configFile = pmbusReadSensorFile;
1826 configFile["rules"][0]["actions"][1]["pmbus_read_sensor"].erase("type");
1827 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001828 "'type' is a required property");
Bob Kingd6618092020-01-21 11:31:46 +08001829 }
1830 // Invalid: test pmbus_read_sensor with no command.
1831 {
1832 json configFile = pmbusReadSensorFile;
1833 configFile["rules"][0]["actions"][1]["pmbus_read_sensor"].erase(
1834 "command");
1835 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001836 "'command' is a required property");
Bob Kingd6618092020-01-21 11:31:46 +08001837 }
1838 // Invalid: test pmbus_read_sensor with no format.
1839 {
1840 json configFile = pmbusReadSensorFile;
1841 configFile["rules"][0]["actions"][1]["pmbus_read_sensor"].erase(
1842 "format");
1843 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001844 "'format' is a required property");
Bob Kingd6618092020-01-21 11:31:46 +08001845 }
1846 // Invalid: test pmbus_read_sensor with property type wrong type.
1847 {
1848 json configFile = pmbusReadSensorFile;
1849 configFile["rules"][0]["actions"][1]["pmbus_read_sensor"]["type"] =
1850 true;
Bob King358c4172020-03-16 13:57:08 +08001851 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1852 "True is not of type 'string'");
Bob Kingd6618092020-01-21 11:31:46 +08001853 }
1854 // Invalid: test pmbus_read_sensor with property command wrong type.
1855 {
1856 json configFile = pmbusReadSensorFile;
1857 configFile["rules"][0]["actions"][1]["pmbus_read_sensor"]["command"] =
1858 true;
1859 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001860 "True is not of type 'string'");
Bob Kingd6618092020-01-21 11:31:46 +08001861 }
1862 // Invalid: test pmbus_read_sensor with property format wrong type.
1863 {
1864 json configFile = pmbusReadSensorFile;
1865 configFile["rules"][0]["actions"][1]["pmbus_read_sensor"]["format"] =
1866 true;
1867 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001868 "True is not of type 'string'");
Bob Kingd6618092020-01-21 11:31:46 +08001869 }
1870 // Invalid: test pmbus_read_sensor with property exponent wrong type.
1871 {
1872 json configFile = pmbusReadSensorFile;
1873 configFile["rules"][0]["actions"][1]["pmbus_read_sensor"]["exponent"] =
1874 true;
1875 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001876 "True is not of type 'integer'");
Bob Kingd6618092020-01-21 11:31:46 +08001877 }
1878 // Invalid: test pmbus_read_sensor with property type wrong format.
1879 {
1880 json configFile = pmbusReadSensorFile;
1881 configFile["rules"][0]["actions"][1]["pmbus_read_sensor"]["type"] =
1882 "foo";
1883 EXPECT_JSON_INVALID(
1884 configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001885 "'foo' is not one of ['iout', 'iout_peak', 'iout_valley', "
1886 "'pout', 'temperature', 'temperature_peak', 'vout', "
1887 "'vout_peak', 'vout_valley']");
Bob Kingd6618092020-01-21 11:31:46 +08001888 }
1889 // Invalid: test pmbus_read_sensor with property command wrong format.
1890 {
1891 json configFile = pmbusReadSensorFile;
1892 configFile["rules"][0]["actions"][1]["pmbus_read_sensor"]["command"] =
1893 "0x8B0";
1894 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001895 "'0x8B0' does not match '^0x[0-9a-fA-F]{2}$'");
Bob Kingd6618092020-01-21 11:31:46 +08001896 }
1897 // Invalid: test pmbus_read_sensor with property format wrong format.
1898 {
1899 json configFile = pmbusReadSensorFile;
1900 configFile["rules"][0]["actions"][1]["pmbus_read_sensor"]["format"] =
1901 "foo";
Bob King358c4172020-03-16 13:57:08 +08001902 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1903 "'foo' is not one of ['linear_11', 'linear_16']");
Bob Kingd6618092020-01-21 11:31:46 +08001904 }
1905}
Bob King02179c62020-01-21 11:32:36 +08001906TEST(ValidateRegulatorsConfigTest, PmbusWriteVoutCommand)
1907{
1908 json pmbusWriteVoutCommandFile = validConfigFile;
1909 pmbusWriteVoutCommandFile["rules"][0]["actions"][1]
1910 ["pmbus_write_vout_command"]["volts"] = 1.03;
1911 pmbusWriteVoutCommandFile["rules"][0]["actions"][1]
1912 ["pmbus_write_vout_command"]["format"] = "linear";
1913 pmbusWriteVoutCommandFile["rules"][0]["actions"][1]
1914 ["pmbus_write_vout_command"]["exponent"] = -8;
1915 pmbusWriteVoutCommandFile["rules"][0]["actions"][1]
1916 ["pmbus_write_vout_command"]["is_verified"] = true;
1917 // Valid: test pmbus_write_vout_command.
1918 {
1919 json configFile = pmbusWriteVoutCommandFile;
1920 EXPECT_JSON_VALID(configFile);
1921 }
1922 // Valid: test pmbus_write_vout_command with required properties.
1923 {
1924 json configFile = pmbusWriteVoutCommandFile;
1925 configFile["rules"][0]["actions"][1]["pmbus_write_vout_command"].erase(
1926 "volts");
1927 configFile["rules"][0]["actions"][1]["pmbus_write_vout_command"].erase(
1928 "exponent");
1929 configFile["rules"][0]["actions"][1]["pmbus_write_vout_command"].erase(
1930 "is_verified");
1931 EXPECT_JSON_VALID(configFile);
1932 }
1933 // Invalid: test pmbus_write_vout_command with no format.
1934 {
1935 json configFile = pmbusWriteVoutCommandFile;
1936 configFile["rules"][0]["actions"][1]["pmbus_write_vout_command"].erase(
1937 "format");
1938 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001939 "'format' is a required property");
Bob King02179c62020-01-21 11:32:36 +08001940 }
1941 // Invalid: test pmbus_write_vout_command with property volts wrong type.
1942 {
1943 json configFile = pmbusWriteVoutCommandFile;
1944 configFile["rules"][0]["actions"][1]["pmbus_write_vout_command"]
1945 ["volts"] = true;
1946 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001947 "True is not of type 'number'");
Bob King02179c62020-01-21 11:32:36 +08001948 }
1949 // Invalid: test pmbus_write_vout_command with property format wrong type.
1950 {
1951 json configFile = pmbusWriteVoutCommandFile;
1952 configFile["rules"][0]["actions"][1]["pmbus_write_vout_command"]
1953 ["format"] = true;
1954 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001955 "True is not of type 'string'");
Bob King02179c62020-01-21 11:32:36 +08001956 }
1957 // Invalid: test pmbus_write_vout_command with property exponent wrong type.
1958 {
1959 json configFile = pmbusWriteVoutCommandFile;
1960 configFile["rules"][0]["actions"][1]["pmbus_write_vout_command"]
1961 ["exponent"] = 1.3;
1962 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001963 "1.3 is not of type 'integer'");
Bob King02179c62020-01-21 11:32:36 +08001964 }
1965 // Invalid: test pmbus_write_vout_command with property is_verified wrong
1966 // type.
1967 {
1968 json configFile = pmbusWriteVoutCommandFile;
1969 configFile["rules"][0]["actions"][1]["pmbus_write_vout_command"]
1970 ["is_verified"] = 1;
1971 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001972 "1 is not of type 'boolean'");
Bob King02179c62020-01-21 11:32:36 +08001973 }
1974 // Invalid: test pmbus_write_vout_command with property format wrong format.
1975 {
1976 json configFile = pmbusWriteVoutCommandFile;
1977 configFile["rules"][0]["actions"][1]["pmbus_write_vout_command"]
1978 ["format"] = "foo";
1979 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001980 "'foo' is not one of ['linear']");
Bob King02179c62020-01-21 11:32:36 +08001981 }
1982}
Bob King99d8fa12020-01-31 11:23:40 +08001983TEST(ValidateRegulatorsConfigTest, PresenceDetection)
1984{
1985 json presenceDetectionFile = validConfigFile;
1986 presenceDetectionFile
1987 ["chassis"][0]["devices"][0]["presence_detection"]["comments"][0] =
1988 "Regulator is only present on the FooBar backplane";
1989 presenceDetectionFile["chassis"][0]["devices"][0]["presence_detection"]
Bob Kingf4ff1162020-02-11 15:13:38 +08001990 ["rule_id"] = "set_voltage_rule";
Bob King99d8fa12020-01-31 11:23:40 +08001991 // Valid: test presence_detection with only property rule_id.
1992 {
1993 json configFile = presenceDetectionFile;
1994 EXPECT_JSON_VALID(configFile);
1995 }
1996 // Valid: test presence_detection with only property actions.
1997 {
1998 json configFile = presenceDetectionFile;
1999 configFile["chassis"][0]["devices"][0]["presence_detection"].erase(
2000 "rule_id");
2001 configFile["chassis"][0]["devices"][0]["presence_detection"]["actions"]
2002 [0]["compare_presence"]["fru"] =
2003 "/system/chassis/motherboard/cpu3";
2004 configFile["chassis"][0]["devices"][0]["presence_detection"]["actions"]
2005 [0]["compare_presence"]["value"] = true;
2006 configFile["chassis"][0]["devices"][0]["presence_detection"].erase(
2007 "comments");
2008 EXPECT_JSON_VALID(configFile);
2009 }
2010 // Invalid: test presence_detection with both property rule_id and actions.
2011 {
2012 json configFile = presenceDetectionFile;
2013 configFile["chassis"][0]["devices"][0]["presence_detection"]["actions"]
2014 [0]["compare_presence"]["fru"] =
2015 "/system/chassis/motherboard/cpu3";
2016 configFile["chassis"][0]["devices"][0]["presence_detection"]["actions"]
2017 [0]["compare_presence"]["value"] = true;
2018 EXPECT_JSON_INVALID(
2019 configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002020 "{'actions': [{'compare_presence': {'fru': "
2021 "'/system/chassis/motherboard/cpu3', 'value': True}}], 'comments': "
2022 "['Regulator is only present on the FooBar backplane'], 'rule_id': "
2023 "'set_voltage_rule'} is valid under each of {'required': "
2024 "['actions']}, {'required': ['rule_id']}");
Bob King99d8fa12020-01-31 11:23:40 +08002025 }
2026 // Invalid: test presence_detection with no rule_id and actions.
2027 {
2028 json configFile = presenceDetectionFile;
2029 configFile["chassis"][0]["devices"][0]["presence_detection"].erase(
2030 "rule_id");
2031 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002032 "'rule_id' is a required property");
Bob King99d8fa12020-01-31 11:23:40 +08002033 }
2034 // Invalid: test presence_detection with property comments wrong type.
2035 {
2036 json configFile = presenceDetectionFile;
2037 configFile["chassis"][0]["devices"][0]["presence_detection"]
2038 ["comments"] = true;
2039 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002040 "True is not of type 'array'");
Bob King99d8fa12020-01-31 11:23:40 +08002041 }
2042 // Invalid: test presence_detection with property rule_id wrong type.
2043 {
2044 json configFile = presenceDetectionFile;
2045 configFile["chassis"][0]["devices"][0]["presence_detection"]
2046 ["rule_id"] = true;
2047 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002048 "True is not of type 'string'");
Bob King99d8fa12020-01-31 11:23:40 +08002049 }
2050 // Invalid: test presence_detection with property actions wrong type.
2051 {
2052 json configFile = presenceDetectionFile;
2053 configFile["chassis"][0]["devices"][0]["presence_detection"].erase(
2054 "rule_id");
2055 configFile["chassis"][0]["devices"][0]["presence_detection"]
2056 ["actions"] = true;
2057 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002058 "True is not of type 'array'");
Bob King99d8fa12020-01-31 11:23:40 +08002059 }
2060 // Invalid: test presence_detection with property rule_id wrong format.
2061 {
2062 json configFile = presenceDetectionFile;
2063 configFile["chassis"][0]["devices"][0]["presence_detection"]
2064 ["rule_id"] = "id@";
2065 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002066 "'id@' does not match '^[A-Za-z0-9_]+$'");
Bob King99d8fa12020-01-31 11:23:40 +08002067 }
2068 // Invalid: test presence_detection with property comments empty array.
2069 {
2070 json configFile = presenceDetectionFile;
2071 configFile["chassis"][0]["devices"][0]["presence_detection"]
2072 ["comments"] = json::array();
2073 EXPECT_JSON_INVALID(configFile, "Validation failed.",
2074 "[] is too short");
2075 }
2076 // Invalid: test presence_detection with property actions empty array.
2077 {
2078 json configFile = presenceDetectionFile;
2079 configFile["chassis"][0]["devices"][0]["presence_detection"].erase(
2080 "rule_id");
2081 configFile["chassis"][0]["devices"][0]["presence_detection"]
2082 ["actions"] = json::array();
2083 EXPECT_JSON_INVALID(configFile, "Validation failed.",
2084 "[] is too short");
2085 }
2086}
Bob Kinge9260b52020-01-21 11:46:13 +08002087TEST(ValidateRegulatorsConfigTest, Rail)
2088{
2089 // Valid: test rail.
2090 {
2091 json configFile = validConfigFile;
2092 EXPECT_JSON_VALID(configFile);
2093 }
2094 // Valid: test rail with required properties.
2095 {
2096 json configFile = validConfigFile;
2097 configFile["chassis"][0]["devices"][0]["rails"][0].erase("comments");
2098 configFile["chassis"][0]["devices"][0]["rails"][0].erase(
2099 "configuration");
2100 configFile["chassis"][0]["devices"][0]["rails"][0].erase(
2101 "sensor_monitoring");
2102 EXPECT_JSON_VALID(configFile);
2103 }
2104 // Invalid: test rail with no id.
2105 {
2106 json configFile = validConfigFile;
2107 configFile["chassis"][0]["devices"][0]["rails"][0].erase("id");
2108 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002109 "'id' is a required property");
Bob Kinge9260b52020-01-21 11:46:13 +08002110 }
2111 // Invalid: test rail with comments wrong type.
2112 {
2113 json configFile = validConfigFile;
2114 configFile["chassis"][0]["devices"][0]["rails"][0]["comments"] = true;
2115 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002116 "True is not of type 'array'");
Bob Kinge9260b52020-01-21 11:46:13 +08002117 }
2118 // Invalid: test rail with id wrong type.
2119 {
2120 json configFile = validConfigFile;
2121 configFile["chassis"][0]["devices"][0]["rails"][0]["id"] = true;
2122 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002123 "True is not of type 'string'");
Bob Kinge9260b52020-01-21 11:46:13 +08002124 }
2125 // Invalid: test rail with configuration wrong type.
2126 {
2127 json configFile = validConfigFile;
2128 configFile["chassis"][0]["devices"][0]["rails"][0]["configuration"] =
2129 true;
2130 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002131 "True is not of type 'object'");
Bob Kinge9260b52020-01-21 11:46:13 +08002132 }
2133 // Invalid: test rail with sensor_monitoring wrong type.
2134 {
2135 json configFile = validConfigFile;
2136 configFile["chassis"][0]["devices"][0]["rails"][0]
2137 ["sensor_monitoring"] = true;
2138 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002139 "True is not of type 'object'");
Bob Kinge9260b52020-01-21 11:46:13 +08002140 }
2141 // Invalid: test rail with comments empty array.
2142 {
2143 json configFile = validConfigFile;
2144 configFile["chassis"][0]["devices"][0]["rails"][0]["comments"] =
2145 json::array();
2146 EXPECT_JSON_INVALID(configFile, "Validation failed.",
2147 "[] is too short");
2148 }
2149 // Invalid: test rail with id wrong format.
2150 {
2151 json configFile = validConfigFile;
2152 configFile["chassis"][0]["devices"][0]["rails"][0]["id"] = "id~";
2153 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002154 "'id~' does not match '^[A-Za-z0-9_]+$'");
Bob Kinge9260b52020-01-21 11:46:13 +08002155 }
2156}
Bob King64df7da2020-01-31 12:04:12 +08002157TEST(ValidateRegulatorsConfigTest, Rule)
2158{
2159 // valid test comments property, id property,
2160 // action property specified.
2161 {
2162 json configFile = validConfigFile;
2163 EXPECT_JSON_VALID(configFile);
2164 }
2165
2166 // valid test rule with no comments
2167 {
2168 json configFile = validConfigFile;
2169 configFile["rules"][0].erase("comments");
2170 EXPECT_JSON_VALID(configFile);
2171 }
2172
2173 // invalid test comments property has invalid value type
2174 {
2175 json configFile = validConfigFile;
2176 configFile["rules"][0]["comments"] = {1};
2177 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002178 "1 is not of type 'string'");
Bob King64df7da2020-01-31 12:04:12 +08002179 }
2180
2181 // invalid test rule with no ID
2182 {
2183 json configFile = validConfigFile;
2184 configFile["rules"][0].erase("id");
2185 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002186 "'id' is a required property");
Bob King64df7da2020-01-31 12:04:12 +08002187 }
2188
2189 // invalid test id property has invalid value type (not string)
2190 {
2191 json configFile = validConfigFile;
2192 configFile["rules"][0]["id"] = true;
2193 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002194 "True is not of type 'string'");
Bob King64df7da2020-01-31 12:04:12 +08002195 }
2196
2197 // invalid test id property has invalid value
2198 {
2199 json configFile = validConfigFile;
2200 configFile["rules"][0]["id"] = "foo%";
2201 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002202 "'foo%' does not match '^[A-Za-z0-9_]+$'");
Bob King64df7da2020-01-31 12:04:12 +08002203 }
2204
2205 // invalid test rule with no actions property
2206 {
2207 json configFile = validConfigFile;
2208 configFile["rules"][0].erase("actions");
2209 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002210 "'actions' is a required property");
Bob King64df7da2020-01-31 12:04:12 +08002211 }
2212
2213 // valid test rule with multiple actions
2214 {
2215 json configFile = validConfigFile;
Bob King63d795f2020-02-11 15:22:09 +08002216 configFile["rules"][0]["actions"][1]["run_rule"] = "read_sensors_rule";
Bob King64df7da2020-01-31 12:04:12 +08002217 EXPECT_JSON_VALID(configFile);
2218 }
2219
2220 // invalid test actions property has invalid value type (not an array)
2221 {
2222 json configFile = validConfigFile;
2223 configFile["rules"][0]["actions"] = 1;
2224 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002225 "1 is not of type 'array'");
Bob King64df7da2020-01-31 12:04:12 +08002226 }
2227
2228 // invalid test actions property has invalid value of action
2229 {
2230 json configFile = validConfigFile;
2231 configFile["rules"][0]["actions"][0] = "foo";
2232 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002233 "'foo' is not of type 'object'");
Bob King64df7da2020-01-31 12:04:12 +08002234 }
2235
2236 // invalid test actions property has empty array
2237 {
2238 json configFile = validConfigFile;
2239 configFile["rules"][0]["actions"] = json::array();
2240 EXPECT_JSON_INVALID(configFile, "Validation failed.",
2241 "[] is too short");
2242 }
2243}
Bob Kinge86c2e52020-01-21 11:33:32 +08002244TEST(ValidateRegulatorsConfigTest, RunRule)
2245{
2246 json runRuleFile = validConfigFile;
Bob King7d3a9f12020-02-11 15:34:52 +08002247 runRuleFile["rules"][0]["actions"][1]["run_rule"] = "read_sensors_rule";
Bob Kinge86c2e52020-01-21 11:33:32 +08002248 // Valid: test run_rule.
2249 {
2250 json configFile = runRuleFile;
2251 EXPECT_JSON_VALID(configFile);
2252 }
2253 // Invalid: test run_rule wrong type.
2254 {
2255 json configFile = runRuleFile;
2256 configFile["rules"][0]["actions"][1]["run_rule"] = true;
2257 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002258 "True is not of type 'string'");
Bob Kinge86c2e52020-01-21 11:33:32 +08002259 }
2260 // Invalid: test run_rule wrong format.
2261 {
2262 json configFile = runRuleFile;
2263 configFile["rules"][0]["actions"][1]["run_rule"] = "set_voltage_rule%";
2264 EXPECT_JSON_INVALID(
2265 configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002266 "'set_voltage_rule%' does not match '^[A-Za-z0-9_]+$'");
Bob Kinge86c2e52020-01-21 11:33:32 +08002267 }
2268}
Bob Kingfcc2a2f2020-01-31 11:29:45 +08002269TEST(ValidateRegulatorsConfigTest, SensorMonitoring)
2270{
2271 // Valid: test rails sensor_monitoring with only property rule id.
2272 {
2273 json configFile = validConfigFile;
2274 EXPECT_JSON_VALID(configFile);
2275 }
2276 // Valid: test rails sensor_monitoring with only property actions.
2277 {
2278 json configFile = validConfigFile;
2279 configFile["chassis"][0]["devices"][0]["rails"][0]["sensor_monitoring"]
2280 .erase("rule_id");
2281 configFile["chassis"][0]["devices"][0]["rails"][0]["sensor_monitoring"]
2282 ["actions"][0]["compare_presence"]["fru"] =
2283 "/system/chassis/motherboard/cpu3";
2284 configFile["chassis"][0]["devices"][0]["rails"][0]["sensor_monitoring"]
2285 ["actions"][0]["compare_presence"]["value"] = true;
2286 configFile["chassis"][0]["devices"][0]["rails"][0]["sensor_monitoring"]
2287 ["comments"][0] = "comments";
2288 EXPECT_JSON_VALID(configFile);
2289 }
2290 // Invalid: test rails sensor_monitoring with both property rule_id and
2291 // actions.
2292 {
2293 json configFile = validConfigFile;
2294 configFile["chassis"][0]["devices"][0]["rails"][0]["sensor_monitoring"]
2295 ["actions"][0]["compare_presence"]["fru"] =
2296 "/system/chassis/motherboard/cpu3";
2297 configFile["chassis"][0]["devices"][0]["rails"][0]["sensor_monitoring"]
2298 ["actions"][0]["compare_presence"]["value"] = true;
2299 EXPECT_JSON_INVALID(
2300 configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002301 "{'actions': [{'compare_presence': {'fru': "
2302 "'/system/chassis/motherboard/cpu3', 'value': True}}], 'rule_id': "
2303 "'read_sensors_rule'} is valid under each of {'required': "
2304 "['actions']}, {'required': ['rule_id']}");
Bob Kingfcc2a2f2020-01-31 11:29:45 +08002305 }
2306 // Invalid: test rails sensor_monitoring with no rule_id and actions.
2307 {
2308 json configFile = validConfigFile;
2309 configFile["chassis"][0]["devices"][0]["rails"][0]["sensor_monitoring"]
2310 .erase("rule_id");
2311 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002312 "'rule_id' is a required property");
Bob Kingfcc2a2f2020-01-31 11:29:45 +08002313 }
2314 // Invalid: test rails sensor_monitoring with property comments wrong type.
2315 {
2316 json configFile = validConfigFile;
2317 configFile["chassis"][0]["devices"][0]["rails"][0]["sensor_monitoring"]
2318 ["comments"] = true;
2319 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002320 "True is not of type 'array'");
Bob Kingfcc2a2f2020-01-31 11:29:45 +08002321 }
2322 // Invalid: test rails sensor_monitoring with property rule_id wrong type.
2323 {
2324 json configFile = validConfigFile;
2325 configFile["chassis"][0]["devices"][0]["rails"][0]["sensor_monitoring"]
2326 ["rule_id"] = true;
2327 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002328 "True is not of type 'string'");
Bob Kingfcc2a2f2020-01-31 11:29:45 +08002329 }
2330 // Invalid: test rails sensor_monitoring with property actions wrong type.
2331 {
2332 json configFile = validConfigFile;
2333 configFile["chassis"][0]["devices"][0]["rails"][0]["sensor_monitoring"]
2334 .erase("rule_id");
2335 configFile["chassis"][0]["devices"][0]["rails"][0]["sensor_monitoring"]
2336 ["actions"] = true;
2337 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002338 "True is not of type 'array'");
Bob Kingfcc2a2f2020-01-31 11:29:45 +08002339 }
2340 // Invalid: test rails sensor_monitoring with property rule_id wrong format.
2341 {
2342 json configFile = validConfigFile;
2343 configFile["chassis"][0]["devices"][0]["rails"][0]["sensor_monitoring"]
2344 ["rule_id"] = "id@";
2345 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002346 "'id@' does not match '^[A-Za-z0-9_]+$'");
Bob Kingfcc2a2f2020-01-31 11:29:45 +08002347 }
2348 // Invalid: test rails sensor_monitoring with property comments empty array.
2349 {
2350 json configFile = validConfigFile;
2351 configFile["chassis"][0]["devices"][0]["rails"][0]["sensor_monitoring"]
2352 ["comments"] = json::array();
2353 EXPECT_JSON_INVALID(configFile, "Validation failed.",
2354 "[] is too short");
2355 }
2356 // Invalid: test rails sensor_monitoring with property actions empty array.
2357 {
2358 json configFile = validConfigFile;
2359 configFile["chassis"][0]["devices"][0]["rails"][0]["sensor_monitoring"]
2360 .erase("rule_id");
2361 configFile["chassis"][0]["devices"][0]["rails"][0]["sensor_monitoring"]
2362 ["actions"] = json::array();
2363 EXPECT_JSON_INVALID(configFile, "Validation failed.",
2364 "[] is too short");
2365 }
2366}
Bob King68230aa2020-01-21 11:34:33 +08002367TEST(ValidateRegulatorsConfigTest, SetDevice)
2368{
2369 json setDeviceFile = validConfigFile;
Bob King7d3a9f12020-02-11 15:34:52 +08002370 setDeviceFile["rules"][0]["actions"][1]["set_device"] = "vdd_regulator";
Bob King68230aa2020-01-21 11:34:33 +08002371 // Valid: test set_device.
2372 {
2373 json configFile = setDeviceFile;
2374 EXPECT_JSON_VALID(configFile);
2375 }
2376 // Invalid: test set_device wrong type.
2377 {
2378 json configFile = setDeviceFile;
2379 configFile["rules"][0]["actions"][1]["set_device"] = true;
2380 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002381 "True is not of type 'string'");
Bob King68230aa2020-01-21 11:34:33 +08002382 }
2383 // Invalid: test set_device wrong format.
2384 {
2385 json configFile = setDeviceFile;
2386 configFile["rules"][0]["actions"][1]["set_device"] = "io_expander2%";
Bob King358c4172020-03-16 13:57:08 +08002387 EXPECT_JSON_INVALID(configFile, "Validation failed.",
2388 "'io_expander2%' does not match '^[A-Za-z0-9_]+$'");
Bob King68230aa2020-01-21 11:34:33 +08002389 }
2390}
Bob King3643cc02020-01-31 11:32:56 +08002391TEST(ValidateRegulatorsConfigTest, DuplicateRuleID)
2392{
2393 // Invalid: test duplicate ID in rule.
2394 {
2395 json configFile = validConfigFile;
Bob Kingb3e48bc2020-02-18 09:59:09 +08002396 configFile["rules"][2]["id"] = "set_voltage_rule";
2397 configFile["rules"][2]["actions"][0]["pmbus_write_vout_command"]
Bob King3643cc02020-01-31 11:32:56 +08002398 ["format"] = "linear";
2399 EXPECT_JSON_INVALID(configFile, "Error: Duplicate rule ID.", "");
2400 }
2401}
2402TEST(ValidateRegulatorsConfigTest, DuplicateChassisNumber)
2403{
2404 // Invalid: test duplicate number in chassis.
2405 {
2406 json configFile = validConfigFile;
2407 configFile["chassis"][1]["number"] = 1;
2408 EXPECT_JSON_INVALID(configFile, "Error: Duplicate chassis number.", "");
2409 }
2410}
2411TEST(ValidateRegulatorsConfigTest, DuplicateDeviceID)
2412{
2413 // Invalid: test duplicate ID in device.
2414 {
2415 json configFile = validConfigFile;
2416 configFile["chassis"][0]["devices"][1]["id"] = "vdd_regulator";
2417 configFile["chassis"][0]["devices"][1]["is_regulator"] = true;
2418 configFile["chassis"][0]["devices"][1]["fru"] =
2419 "/system/chassis/motherboard/regulator1";
2420 configFile["chassis"][0]["devices"][1]["i2c_interface"]["bus"] = 2;
2421 configFile["chassis"][0]["devices"][1]["i2c_interface"]["address"] =
2422 "0x71";
2423 EXPECT_JSON_INVALID(configFile, "Error: Duplicate device ID.", "");
2424 }
2425}
2426TEST(ValidateRegulatorsConfigTest, DuplicateRailID)
2427{
2428 // Invalid: test duplicate ID in rail.
2429 {
2430 json configFile = validConfigFile;
2431 configFile["chassis"][0]["devices"][0]["rails"][1]["id"] = "vdd";
2432 EXPECT_JSON_INVALID(configFile, "Error: Duplicate rail ID.", "");
2433 }
2434}
2435TEST(ValidateRegulatorsConfigTest, InfiniteLoops)
2436{
2437 // Invalid: test run_rule with infinite loop (rules run each other).
2438 {
2439 json configFile = validConfigFile;
2440 configFile["rules"][2]["actions"][0]["run_rule"] = "set_voltage_rule2";
2441 configFile["rules"][2]["id"] = "set_voltage_rule1";
2442 configFile["rules"][3]["actions"][0]["run_rule"] = "set_voltage_rule1";
2443 configFile["rules"][3]["id"] = "set_voltage_rule2";
2444 EXPECT_JSON_INVALID(configFile,
2445 "Infinite loop caused by run_rule actions.", "");
2446 }
2447 // Invalid: test run_rule with infinite loop (rule runs itself).
2448 {
2449 json configFile = validConfigFile;
2450 configFile["rules"][2]["actions"][0]["run_rule"] = "set_voltage_rule1";
2451 configFile["rules"][2]["id"] = "set_voltage_rule1";
2452 EXPECT_JSON_INVALID(configFile,
2453 "Infinite loop caused by run_rule actions.", "");
2454 }
2455 // Invalid: test run_rule with infinite loop (indirect loop).
2456 {
2457 json configFile = validConfigFile;
2458 configFile["rules"][2]["actions"][0]["run_rule"] = "set_voltage_rule2";
2459 configFile["rules"][2]["id"] = "set_voltage_rule1";
2460 configFile["rules"][3]["actions"][0]["run_rule"] = "set_voltage_rule3";
2461 configFile["rules"][3]["id"] = "set_voltage_rule2";
2462 configFile["rules"][4]["actions"][0]["run_rule"] = "set_voltage_rule1";
2463 configFile["rules"][4]["id"] = "set_voltage_rule3";
2464 EXPECT_JSON_INVALID(configFile,
2465 "Infinite loop caused by run_rule actions.", "");
2466 }
2467}
Bob Kingf88203a2020-02-18 13:26:07 +08002468TEST(ValidateRegulatorsConfigTest, RunRuleValueExists)
2469{
2470 // Invalid: test run_rule actions specify a rule ID that does not exist.
2471 {
2472 json configFile = validConfigFile;
2473 configFile["rules"][2]["actions"][0]["run_rule"] = "set_voltage_rule2";
2474 configFile["rules"][2]["id"] = "set_voltage_rule1";
2475 EXPECT_JSON_INVALID(configFile, "Error: Rule ID does not exist.", "");
2476 }
2477}
Bob King13b2ad92020-02-18 13:31:39 +08002478TEST(ValidateRegulatorsConfigTest, SetDeviceValueExists)
2479{
2480 // Invalid: test set_device actions specify a device ID that does not exist.
2481 {
2482 json configFile = validConfigFile;
2483 configFile["rules"][2]["actions"][0]["set_device"] = "vdd_regulator2";
2484 configFile["rules"][2]["id"] = "set_voltage_rule1";
2485 EXPECT_JSON_INVALID(configFile, "Error: Device ID does not exist.", "");
2486 }
2487}
Bob King21b09be2020-02-18 13:33:09 +08002488TEST(ValidateRegulatorsConfigTest, RuleIDExists)
2489{
2490 // Invalid: test rule_id property in configuration specifies a rule ID that
2491 // does not exist.
2492 {
2493 json configFile = validConfigFile;
2494 configFile["chassis"][0]["devices"][0]["configuration"]["rule_id"] =
2495 "set_voltage_rule2";
2496 EXPECT_JSON_INVALID(configFile, "Error: Rule ID does not exist.", "");
2497 }
2498 // Invalid: test rule_id property in presence_detection specifies a rule ID
2499 // that does not exist.
2500 {
2501 json configFile = validConfigFile;
2502 configFile["chassis"][0]["devices"][0]["presence_detection"]
2503 ["rule_id"] = "set_voltage_rule2";
2504 EXPECT_JSON_INVALID(configFile, "Error: Rule ID does not exist.", "");
2505 }
2506 // Invalid: test rule_id property in sensor_monitoring specifies a rule ID
2507 // that does not exist.
2508 {
2509 json configFile = validConfigFile;
2510 configFile["chassis"][0]["devices"][0]["rails"][0]["sensor_monitoring"]
2511 ["rule_id"] = "set_voltage_rule2";
2512 EXPECT_JSON_INVALID(configFile, "Error: Rule ID does not exist.", "");
2513 }
2514}
Bob Kingdc72b622020-02-18 13:36:18 +08002515TEST(ValidateRegulatorsConfigTest, NumberOfElementsInMasks)
2516{
2517 // Invalid: test number of elements in masks not equal to number in values
2518 // in i2c_compare_bytes.
2519 {
2520 json configFile = validConfigFile;
2521 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["register"] =
2522 "0x82";
2523 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["values"] = {
2524 "0x02", "0x73"};
2525 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["masks"] = {
2526 "0x7F"};
2527 EXPECT_JSON_INVALID(configFile,
2528 "Error: Invalid i2c_compare_bytes action.", "");
2529 }
2530 // Invalid: test number of elements in masks not equal to number in values
2531 // in i2c_write_bytes.
2532 {
2533 json configFile = validConfigFile;
2534 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["register"] =
2535 "0x82";
2536 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["values"] = {
2537 "0x02", "0x73"};
2538 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["masks"] = {
2539 "0x7F"};
2540 EXPECT_JSON_INVALID(configFile,
2541 "Error: Invalid i2c_write_bytes action.", "");
2542 }
2543}
Bob Kinged009652020-02-20 14:54:13 +08002544TEST(ValidateRegulatorsConfigTest, CommandLineSyntax)
2545{
Bob Kinga57e0812020-03-12 10:47:42 +08002546 std::string validateTool =
2547 " ../phosphor-regulators/tools/validate-regulators-config.py ";
Bob Kinged009652020-02-20 14:54:13 +08002548 std::string schema = " -s ";
Bob Kinga57e0812020-03-12 10:47:42 +08002549 std::string schemaFile =
2550 " ../phosphor-regulators/schema/config_schema.json ";
Bob Kinged009652020-02-20 14:54:13 +08002551 std::string configuration = " -c ";
2552 std::string command;
2553 std::string errorMessage;
2554 std::string outputMessage;
2555 std::string outputMessageHelp =
2556 "usage: validate-regulators-config.py [-h] [-s SCHEMA_FILE]";
2557 int valid = 0;
2558
2559 std::string fileName;
Bob Kinga57e0812020-03-12 10:47:42 +08002560 TmpFile tmpFile;
2561 fileName = tmpFile.getName();
2562 writeDataToFile(validConfigFile, fileName);
Bob Kinged009652020-02-20 14:54:13 +08002563 // Valid: -s specified
2564 {
2565 command = validateTool + "-s " + schemaFile + configuration + fileName;
2566 expectCommandLineSyntax(errorMessage, outputMessage, command, valid);
2567 }
2568 // Valid: --schema-file specified
2569 {
2570 command = validateTool + "--schema-file " + schemaFile + configuration +
2571 fileName;
2572 expectCommandLineSyntax(errorMessage, outputMessage, command, valid);
2573 }
2574 // Valid: -c specified
2575 {
2576 command = validateTool + schema + schemaFile + "-c " + fileName;
2577 expectCommandLineSyntax(errorMessage, outputMessage, command, valid);
2578 }
2579 // Valid: --configuration-file specified
2580 {
2581 command = validateTool + schema + schemaFile + "--configuration-file " +
2582 fileName;
2583 expectCommandLineSyntax(errorMessage, outputMessage, command, valid);
2584 }
2585 // Valid: -h specified
2586 {
2587 command = validateTool + "-h ";
2588 expectCommandLineSyntax(errorMessage, outputMessageHelp, command,
2589 valid);
2590 }
2591 // Valid: --help specified
2592 {
2593 command = validateTool + "--help ";
2594 expectCommandLineSyntax(errorMessage, outputMessageHelp, command,
2595 valid);
2596 }
2597 // Invalid: -c/--configuration-file not specified
2598 {
2599 command = validateTool + schema + schemaFile;
2600 expectCommandLineSyntax("Error: Configuration file is required.",
2601 outputMessageHelp, command, 1);
2602 }
2603 // Invalid: -s/--schema-file not specified
2604 {
2605 command = validateTool + configuration + fileName;
2606 expectCommandLineSyntax("Error: Schema file is required.",
2607 outputMessageHelp, command, 1);
2608 }
2609 // Invalid: -s specified more than once
2610 {
2611 command =
2612 validateTool + "-s -s " + schemaFile + configuration + fileName;
2613 expectCommandLineSyntax(outputMessageHelp, outputMessage, command, 2);
2614 }
2615 // Invalid: -c specified more than once
2616 {
2617 command = validateTool + schema + schemaFile + "-c -c " + fileName;
2618 expectCommandLineSyntax(outputMessageHelp, outputMessage, command, 2);
2619 }
2620 // Invalid: No file name specified after -c
2621 {
2622 command = validateTool + schema + schemaFile + configuration;
2623 expectCommandLineSyntax(outputMessageHelp, outputMessage, command, 2);
2624 }
2625 // Invalid: No file name specified after -s
2626 {
2627 command = validateTool + schema + configuration + fileName;
2628 expectCommandLineSyntax(outputMessageHelp, outputMessage, command, 2);
2629 }
2630 // Invalid: File specified after -c does not exist
2631 {
2632 command = validateTool + schema + schemaFile + configuration +
2633 "../notExistFile";
2634 expectCommandLineSyntax(
2635 "Traceback (most recent call last):", outputMessage, command, 1);
2636 }
2637 // Invalid: File specified after -s does not exist
2638 {
2639 command = validateTool + schema + "../notExistFile " + configuration +
2640 fileName;
2641 expectCommandLineSyntax(
2642 "Traceback (most recent call last):", outputMessage, command, 1);
2643 }
2644 // Invalid: File specified after -s is not right data format
2645 {
Bob Kinga57e0812020-03-12 10:47:42 +08002646 std::string wrongFormatFileName;
2647 TmpFile wrongFormatFile;
2648 wrongFormatFileName = wrongFormatFile.getName();
2649 std::ofstream out(wrongFormatFileName);
Bob Kinged009652020-02-20 14:54:13 +08002650 out << "foo";
2651 out.close();
Bob Kinga57e0812020-03-12 10:47:42 +08002652 command = validateTool + schema + wrongFormatFileName + configuration +
2653 fileName;
Bob Kinged009652020-02-20 14:54:13 +08002654 expectCommandLineSyntax(
2655 "Traceback (most recent call last):", outputMessage, command, 1);
Bob Kinged009652020-02-20 14:54:13 +08002656 }
2657 // Invalid: File specified after -c is not readable
2658 {
Bob Kinga57e0812020-03-12 10:47:42 +08002659 std::string notReadableFileName;
2660 TmpFile notReadableFile;
2661 notReadableFileName = notReadableFile.getName();
2662 writeDataToFile(validConfigFile, notReadableFileName);
Bob Kinged009652020-02-20 14:54:13 +08002663 command = validateTool + schema + schemaFile + configuration +
Bob Kinga57e0812020-03-12 10:47:42 +08002664 notReadableFileName;
2665 chmod(notReadableFileName.c_str(), 0222);
Bob Kinged009652020-02-20 14:54:13 +08002666 expectCommandLineSyntax(
2667 "Traceback (most recent call last):", outputMessage, command, 1);
Bob Kinged009652020-02-20 14:54:13 +08002668 }
2669 // Invalid: File specified after -s is not readable
2670 {
Bob Kinga57e0812020-03-12 10:47:42 +08002671 std::string notReadableFileName;
2672 TmpFile notReadableFile;
2673 notReadableFileName = notReadableFile.getName();
2674 writeDataToFile(validConfigFile, notReadableFileName);
2675 command = validateTool + schema + notReadableFileName + configuration +
2676 fileName;
2677 chmod(notReadableFileName.c_str(), 0222);
Bob Kinged009652020-02-20 14:54:13 +08002678 expectCommandLineSyntax(
2679 "Traceback (most recent call last):", outputMessage, command, 1);
Bob Kinged009652020-02-20 14:54:13 +08002680 }
2681 // Invalid: Unexpected parameter specified (like -g)
2682 {
2683 command = validateTool + schema + schemaFile + configuration +
2684 fileName + " -g";
2685 expectCommandLineSyntax(outputMessageHelp, outputMessage, command, 2);
2686 }
Bob Kinged009652020-02-20 14:54:13 +08002687}