blob: 8faf6b851429d7a96ef56cf2d67fe2a3a3c83224 [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 */
Shawn McCarney0f6ebad2020-09-04 16:43:00 -050016#include "temporary_file.hpp"
Shawn McCarney80c0b042020-03-27 12:08:53 -050017
18#include <stdio.h> // for popen(), pclose(), fgets()
19#include <sys/stat.h> // for chmod()
20#include <sys/wait.h> // for WEXITSTATUS
Bob King386d33f2019-12-26 17:28:56 +080021
Bob King386d33f2019-12-26 17:28:56 +080022#include <nlohmann/json.hpp>
23
Shawn McCarney80c0b042020-03-27 12:08:53 -050024#include <cstdio>
Bob King0dcbdf52020-01-20 17:19:39 +080025#include <fstream>
26
Bob King386d33f2019-12-26 17:28:56 +080027#include <gtest/gtest.h>
28
29#define EXPECT_FILE_VALID(configFile) expectFileValid(configFile)
30#define EXPECT_FILE_INVALID(configFile, expectedErrorMessage, \
31 expectedOutputMessage) \
32 expectFileInvalid(configFile, expectedErrorMessage, expectedOutputMessage)
33#define EXPECT_JSON_VALID(configFileJson) expectJsonValid(configFileJson)
34#define EXPECT_JSON_INVALID(configFileJson, expectedErrorMessage, \
35 expectedOutputMessage) \
36 expectJsonInvalid(configFileJson, expectedErrorMessage, \
37 expectedOutputMessage)
38
Shawn McCarney80c0b042020-03-27 12:08:53 -050039using namespace phosphor::power::regulators;
Bob King386d33f2019-12-26 17:28:56 +080040using json = nlohmann::json;
41
42const json validConfigFile = R"(
43 {
44 "comments": [ "Config file for a FooBar one-chassis system" ],
45
46 "rules": [
47 {
48 "comments": [ "Sets output voltage for a PMBus regulator rail" ],
49 "id": "set_voltage_rule",
50 "actions": [
51 {
52 "pmbus_write_vout_command": {
53 "format": "linear"
54 }
55 }
56 ]
Bob Kingb3e48bc2020-02-18 09:59:09 +080057 },
58 {
59 "comments": [ "Reads sensors from a PMBus regulator rail" ],
60 "id": "read_sensors_rule",
61 "actions": [
62 {
63 "comments": [ "Read output voltage from READ_VOUT." ],
64 "pmbus_read_sensor": {
65 "type": "vout",
66 "command": "0x8B",
67 "format": "linear_16"
68 }
69 }
70 ]
Shawn McCarney846dde52021-08-14 12:47:44 -050071 },
72 {
73 "comments": [ "Detects presence of regulators associated with CPU3" ],
74 "id": "detect_presence_rule",
75 "actions": [
76 {
77 "compare_presence": {
78 "fru": "system/chassis/motherboard/cpu3",
79 "value": true
80 }
81 }
82 ]
83 },
84 {
85 "comments": [ "Detects and logs redundant phase faults" ],
86 "id": "detect_phase_faults_rule",
87 "actions": [
88 {
89 "if": {
90 "condition": {
91 "i2c_compare_bit": { "register": "0x02", "position": 3, "value": 1 }
92 },
93 "then": [
94 { "log_phase_fault": { "type": "n" } }
95 ]
96 }
97 }
98 ]
Bob King386d33f2019-12-26 17:28:56 +080099 }
100 ],
101
102 "chassis": [
103 {
104 "comments": [ "Chassis number 1 containing CPUs and memory" ],
105 "number": 1,
Shawn McCarneyecbeeea2021-04-29 21:08:18 -0500106 "inventory_path": "system/chassis",
Bob King386d33f2019-12-26 17:28:56 +0800107 "devices": [
108 {
109 "comments": [ "IR35221 regulator producing the Vdd rail" ],
110 "id": "vdd_regulator",
111 "is_regulator": true,
Bob Kinga76898f2020-10-13 15:08:33 +0800112 "fru": "system/chassis/motherboard/regulator1",
Bob King386d33f2019-12-26 17:28:56 +0800113 "i2c_interface": {
114 "bus": 1,
115 "address": "0x70"
116 },
117 "rails": [
118 {
119 "comments": [ "Vdd rail" ],
120 "id": "vdd",
121 "configuration": {
122 "volts": 1.03,
123 "rule_id": "set_voltage_rule"
124 },
125 "sensor_monitoring": {
126 "rule_id": "read_sensors_rule"
127 }
128 }
129 ]
130 }
131 ]
132 }
133 ]
134 }
135)"_json;
136
Bob King386d33f2019-12-26 17:28:56 +0800137std::string getValidationToolCommand(const std::string& configFileName)
138{
Bob Kinga57e0812020-03-12 10:47:42 +0800139 std::string command =
140 "../phosphor-regulators/tools/validate-regulators-config.py -s \
141 ../phosphor-regulators/schema/config_schema.json -c ";
Bob King386d33f2019-12-26 17:28:56 +0800142 command += configFileName;
143 return command;
144}
145
Bob Kinga57e0812020-03-12 10:47:42 +0800146int runToolForOutputWithCommand(std::string command,
147 std::string& standardOutput,
148 std::string& standardError)
Bob King386d33f2019-12-26 17:28:56 +0800149{
150 // run the validation tool with the temporary file and return the output
151 // of the validation tool.
Shawn McCarney0f6ebad2020-09-04 16:43:00 -0500152 TemporaryFile tmpFile;
153 command += " 2> " + tmpFile.getPath().string();
Bob King386d33f2019-12-26 17:28:56 +0800154 // get the jsonschema print from validation tool.
155 char buffer[256];
Bob Kinga57e0812020-03-12 10:47:42 +0800156 std::string result;
Bob King386d33f2019-12-26 17:28:56 +0800157 // to get the stdout from the validation tool.
158 FILE* pipe = popen(command.c_str(), "r");
159 if (!pipe)
160 {
161 throw std::runtime_error("popen() failed!");
162 }
163 while (!std::feof(pipe))
164 {
165 if (fgets(buffer, sizeof buffer, pipe) != NULL)
166 {
167 result += buffer;
168 }
169 }
170 int returnValue = pclose(pipe);
171 // Check if pclose() failed
172 if (returnValue == -1)
173 {
174 // unable to close pipe. Print error and exit function.
175 throw std::runtime_error("pclose() failed!");
176 }
177 std::string firstLine = result.substr(0, result.find('\n'));
Bob Kinga57e0812020-03-12 10:47:42 +0800178 standardOutput = firstLine;
Bob King386d33f2019-12-26 17:28:56 +0800179 // Get command exit status from return value
180 int exitStatus = WEXITSTATUS(returnValue);
Bob Kinga57e0812020-03-12 10:47:42 +0800181
182 // Read the standardError from tmpFile.
Shawn McCarney0f6ebad2020-09-04 16:43:00 -0500183 std::ifstream input(tmpFile.getPath());
Bob Kinga57e0812020-03-12 10:47:42 +0800184 std::string line;
185
186 if (std::getline(input, line))
187 {
188 standardError = line;
189 }
190
Bob King386d33f2019-12-26 17:28:56 +0800191 return exitStatus;
192}
193
Bob Kinged009652020-02-20 14:54:13 +0800194int runToolForOutput(const std::string& configFileName, std::string& output,
Bob Kinga57e0812020-03-12 10:47:42 +0800195 std::string& error)
Bob Kinged009652020-02-20 14:54:13 +0800196{
197 std::string command = getValidationToolCommand(configFileName);
Bob Kinga57e0812020-03-12 10:47:42 +0800198 return runToolForOutputWithCommand(command, output, error);
Bob Kinged009652020-02-20 14:54:13 +0800199}
200
Bob King386d33f2019-12-26 17:28:56 +0800201void expectFileValid(const std::string& configFileName)
202{
Bob Kinged009652020-02-20 14:54:13 +0800203 std::string errorMessage;
204 std::string outputMessage;
Bob Kinga57e0812020-03-12 10:47:42 +0800205 EXPECT_EQ(runToolForOutput(configFileName, outputMessage, errorMessage), 0);
Bob King386d33f2019-12-26 17:28:56 +0800206 EXPECT_EQ(errorMessage, "");
207 EXPECT_EQ(outputMessage, "");
208}
209
210void expectFileInvalid(const std::string& configFileName,
211 const std::string& expectedErrorMessage,
212 const std::string& expectedOutputMessage)
213{
Bob Kinged009652020-02-20 14:54:13 +0800214 std::string errorMessage;
215 std::string outputMessage;
Bob Kinga57e0812020-03-12 10:47:42 +0800216 EXPECT_EQ(runToolForOutput(configFileName, outputMessage, errorMessage), 1);
Bob King386d33f2019-12-26 17:28:56 +0800217 EXPECT_EQ(errorMessage, expectedErrorMessage);
Shawn McCarney846dde52021-08-14 12:47:44 -0500218 if (expectedOutputMessage != "")
219 {
220 EXPECT_EQ(outputMessage, expectedOutputMessage);
221 }
Bob King386d33f2019-12-26 17:28:56 +0800222}
223
Bob Kinga57e0812020-03-12 10:47:42 +0800224void writeDataToFile(const json configFileJson, std::string fileName)
Bob King386d33f2019-12-26 17:28:56 +0800225{
Bob King386d33f2019-12-26 17:28:56 +0800226 std::string jsonData = configFileJson.dump();
227 std::ofstream out(fileName);
228 out << jsonData;
229 out.close();
Bob Kinged009652020-02-20 14:54:13 +0800230}
231
232void expectJsonValid(const json configFileJson)
233{
Shawn McCarney0f6ebad2020-09-04 16:43:00 -0500234 TemporaryFile tmpFile;
235 std::string fileName = tmpFile.getPath().string();
Bob Kinga57e0812020-03-12 10:47:42 +0800236 writeDataToFile(configFileJson, fileName);
Bob Kinged009652020-02-20 14:54:13 +0800237
Bob King386d33f2019-12-26 17:28:56 +0800238 EXPECT_FILE_VALID(fileName);
Bob King386d33f2019-12-26 17:28:56 +0800239}
240
241void expectJsonInvalid(const json configFileJson,
242 const std::string& expectedErrorMessage,
243 const std::string& expectedOutputMessage)
244{
Shawn McCarney0f6ebad2020-09-04 16:43:00 -0500245 TemporaryFile tmpFile;
246 std::string fileName = tmpFile.getPath().string();
Bob Kinga57e0812020-03-12 10:47:42 +0800247 writeDataToFile(configFileJson, fileName);
Bob King386d33f2019-12-26 17:28:56 +0800248
249 EXPECT_FILE_INVALID(fileName, expectedErrorMessage, expectedOutputMessage);
Bob King386d33f2019-12-26 17:28:56 +0800250}
251
Bob Kinged009652020-02-20 14:54:13 +0800252void expectCommandLineSyntax(const std::string& expectedErrorMessage,
253 const std::string& expectedOutputMessage,
Shawn McCarney525e20c2020-04-14 11:05:39 -0500254 const std::string& command, int status)
Bob Kinged009652020-02-20 14:54:13 +0800255{
256 std::string errorMessage;
257 std::string outputMessage;
Bob Kinga57e0812020-03-12 10:47:42 +0800258 EXPECT_EQ(runToolForOutputWithCommand(command, outputMessage, errorMessage),
259 status);
Bob Kinged009652020-02-20 14:54:13 +0800260 EXPECT_EQ(errorMessage, expectedErrorMessage);
261 EXPECT_EQ(outputMessage, expectedOutputMessage);
262}
263
Bob King3afa7112020-03-19 09:35:31 +0800264TEST(ValidateRegulatorsConfigTest, Action)
265{
266 // Valid: Comments property not specified
267 {
268 json configFile = validConfigFile;
269 EXPECT_JSON_VALID(configFile);
270 }
271 // Valid: Comments property specified
272 {
273 json configFile = validConfigFile;
274 configFile["rules"][0]["actions"][0]["comments"][0] =
275 "Set VOUT_COMMAND";
276 EXPECT_JSON_VALID(configFile);
277 }
278 // Valid: and action type specified
279 {
280 json configFile = validConfigFile;
281 json andAction =
282 R"(
283 {
284 "and": [
285 { "i2c_compare_byte": { "register": "0xA0", "value": "0x00" } },
286 { "i2c_compare_byte": { "register": "0xA1", "value": "0x00" } }
287 ]
288 }
289 )"_json;
290 configFile["rules"][0]["actions"].push_back(andAction);
291 EXPECT_JSON_VALID(configFile);
292 }
293 // Valid: compare_presence action type specified
294 {
295 json configFile = validConfigFile;
296 configFile["rules"][0]["actions"][1]["compare_presence"]["fru"] =
Bob Kinga76898f2020-10-13 15:08:33 +0800297 "system/chassis/motherboard/regulator2";
Bob King3afa7112020-03-19 09:35:31 +0800298 configFile["rules"][0]["actions"][1]["compare_presence"]["value"] =
299 true;
300 EXPECT_JSON_VALID(configFile);
301 }
302 // Valid: compare_vpd action type specified
303 {
304 json configFile = validConfigFile;
305 configFile["rules"][0]["actions"][1]["compare_vpd"]["fru"] =
Bob Kinga76898f2020-10-13 15:08:33 +0800306 "system/chassis/motherboard/regulator2";
Bob King3afa7112020-03-19 09:35:31 +0800307 configFile["rules"][0]["actions"][1]["compare_vpd"]["keyword"] = "CCIN";
308 configFile["rules"][0]["actions"][1]["compare_vpd"]["value"] = "2D35";
309 EXPECT_JSON_VALID(configFile);
310 }
Shawn McCarney846dde52021-08-14 12:47:44 -0500311 // Valid: i2c_capture_bytes action type specified
312 {
313 json configFile = validConfigFile;
314 configFile["rules"][0]["actions"][1]["i2c_capture_bytes"]["register"] =
315 "0xA0";
316 configFile["rules"][0]["actions"][1]["i2c_capture_bytes"]["count"] = 2;
317 EXPECT_JSON_VALID(configFile);
318 }
Bob King3afa7112020-03-19 09:35:31 +0800319 // Valid: i2c_compare_bit action type specified
320 {
321 json configFile = validConfigFile;
322 configFile["rules"][0]["actions"][1]["i2c_compare_bit"]["register"] =
323 "0xA0";
324 configFile["rules"][0]["actions"][1]["i2c_compare_bit"]["position"] = 3;
325 configFile["rules"][0]["actions"][1]["i2c_compare_bit"]["value"] = 1;
326 EXPECT_JSON_VALID(configFile);
327 }
328 // Valid: i2c_compare_byte action type specified
329 {
330 json configFile = validConfigFile;
331 configFile["rules"][0]["actions"][1]["i2c_compare_byte"]["register"] =
332 "0x82";
333 configFile["rules"][0]["actions"][1]["i2c_compare_byte"]["value"] =
334 "0x40";
335 configFile["rules"][0]["actions"][1]["i2c_compare_byte"]["mask"] =
336 "0x7F";
337 EXPECT_JSON_VALID(configFile);
338 }
339 // Valid: i2c_compare_bytes action type specified
340 {
341 json configFile = validConfigFile;
342 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["register"] =
343 "0x82";
344 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["values"] = {
345 "0x02", "0x73"};
346 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["masks"] = {
347 "0x7F", "0x7F"};
348 EXPECT_JSON_VALID(configFile);
349 }
350 // Valid: i2c_write_bit action type specified
351 {
352 json configFile = validConfigFile;
353 configFile["rules"][0]["actions"][1]["i2c_write_bit"]["register"] =
354 "0xA0";
355 configFile["rules"][0]["actions"][1]["i2c_write_bit"]["position"] = 3;
356 configFile["rules"][0]["actions"][1]["i2c_write_bit"]["value"] = 1;
357 EXPECT_JSON_VALID(configFile);
358 }
359 // Valid: i2c_write_byte action type specified
360 {
361 json configFile = validConfigFile;
362 configFile["rules"][0]["actions"][1]["i2c_write_byte"]["register"] =
363 "0x82";
364 configFile["rules"][0]["actions"][1]["i2c_write_byte"]["value"] =
365 "0x40";
366 configFile["rules"][0]["actions"][1]["i2c_write_byte"]["mask"] = "0x7F";
367 EXPECT_JSON_VALID(configFile);
368 }
369 // Valid: i2c_write_bytes action type specified
370 {
371 json configFile = validConfigFile;
372 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["register"] =
373 "0x82";
374 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["values"] = {
375 "0x02", "0x73"};
376 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["masks"] = {
377 "0x7F", "0x7F"};
378 EXPECT_JSON_VALID(configFile);
379 }
380 // Valid: if action type specified
381 {
382 json configFile = validConfigFile;
Shawn McCarney846dde52021-08-14 12:47:44 -0500383 configFile["rules"][4]["actions"][0]["if"]["condition"]["run_rule"] =
Bob King3afa7112020-03-19 09:35:31 +0800384 "set_voltage_rule";
Shawn McCarney846dde52021-08-14 12:47:44 -0500385 configFile["rules"][4]["actions"][0]["if"]["then"][0]["run_rule"] =
Bob King3afa7112020-03-19 09:35:31 +0800386 "read_sensors_rule";
Shawn McCarney846dde52021-08-14 12:47:44 -0500387 configFile["rules"][4]["actions"][0]["if"]["else"][0]["run_rule"] =
Bob King3afa7112020-03-19 09:35:31 +0800388 "read_sensors_rule";
Shawn McCarney846dde52021-08-14 12:47:44 -0500389 configFile["rules"][4]["id"] = "rule_if";
390 EXPECT_JSON_VALID(configFile);
391 }
392 // Valid: log_phase_fault action type specified
393 {
394 json configFile = validConfigFile;
395 configFile["rules"][0]["actions"][1]["log_phase_fault"]["type"] = "n+1";
Bob King3afa7112020-03-19 09:35:31 +0800396 EXPECT_JSON_VALID(configFile);
397 }
398 // Valid: not action type specified
399 {
400 json configFile = validConfigFile;
401 configFile["rules"][0]["actions"][1]["not"]["i2c_compare_byte"]
402 ["register"] = "0xA0";
403 configFile["rules"][0]["actions"][1]["not"]["i2c_compare_byte"]
404 ["value"] = "0xFF";
405 EXPECT_JSON_VALID(configFile);
406 }
407 // Valid: or action type specified
408 {
409 json configFile = validConfigFile;
410 configFile["rules"][0]["actions"][1]["or"][0]["i2c_compare_byte"]
411 ["register"] = "0xA0";
412 configFile["rules"][0]["actions"][1]["or"][0]["i2c_compare_byte"]
413 ["value"] = "0x00";
414 configFile["rules"][0]["actions"][1]["or"][1]["i2c_compare_byte"]
415 ["register"] = "0xA1";
416 configFile["rules"][0]["actions"][1]["or"][1]["i2c_compare_byte"]
417 ["value"] = "0x00";
418 EXPECT_JSON_VALID(configFile);
419 }
420 // Valid: pmbus_read_sensor and pmbus_write_vout_command action type
421 // specified
422 {
423 EXPECT_JSON_VALID(validConfigFile);
424 }
425 // Valid: run_rule action type specified
426 {
427 json configFile = validConfigFile;
428 configFile["rules"][0]["actions"][1]["run_rule"] = "read_sensors_rule";
429 EXPECT_JSON_VALID(configFile);
430 }
431 // Valid: set_device action type specified
432 {
433 json configFile = validConfigFile;
434 configFile["rules"][0]["actions"][1]["set_device"] = "vdd_regulator";
435 EXPECT_JSON_VALID(configFile);
436 }
437 // Invalid: Wrong data type for comments (should be array of string)
438 {
439 json configFile = validConfigFile;
440 configFile["rules"][0]["actions"][0]["comments"] = true;
441 EXPECT_JSON_INVALID(configFile, "Validation failed.",
442 "True is not of type 'array'");
443 }
444 // Invalid: Wrong data type for action type (such as "i2c_write_byte": true)
445 {
446 json configFile = validConfigFile;
447 configFile["rules"][0]["actions"][1]["i2c_write_byte"] = true;
448 EXPECT_JSON_INVALID(configFile, "Validation failed.",
449 "True is not of type 'object'");
450 }
451 // Invalid: Empty comments array
452 {
453 json configFile = validConfigFile;
454 configFile["rules"][0]["actions"][0]["comments"] = json::array();
455 EXPECT_JSON_INVALID(configFile, "Validation failed.",
456 "[] is too short");
457 }
458 // Invalid: Comments array has wrong element type (should be string)
459 {
460 json configFile = validConfigFile;
461 configFile["rules"][0]["actions"][0]["comments"][0] = true;
462 EXPECT_JSON_INVALID(configFile, "Validation failed.",
463 "True is not of type 'string'");
464 }
465 // Invalid: No action type specified
466 {
467 json configFile = validConfigFile;
468 configFile["rules"][0]["actions"][1]["comments"][0] =
469 "Check if bit 3 is on";
470 EXPECT_JSON_INVALID(configFile, "Validation failed.",
471 "'and' is a required property");
472 }
473 // Invalid: Multiple action types specified (such as both 'compare_presence'
474 // and 'pmbus_write_vout_command')
475 {
476 json configFile = validConfigFile;
477 configFile["rules"][0]["actions"][0]["compare_presence"]["value"] =
478 true;
479 EXPECT_JSON_INVALID(
480 configFile, "Validation failed.",
481 "{'compare_presence': {'value': True}, 'pmbus_write_vout_command': "
482 "{'format': 'linear'}} is valid under each of {'required': "
483 "['pmbus_write_vout_command']}, {'required': "
484 "['compare_presence']}");
485 }
486 // Invalid: Unexpected property specified (like 'foo')
487 {
488 json configFile = validConfigFile;
489 configFile["rules"][0]["actions"][1]["foo"] = "foo";
490 EXPECT_JSON_INVALID(
491 configFile, "Validation failed.",
492 "Additional properties are not allowed ('foo' was unexpected)");
493 }
494}
Shawn McCarney846dde52021-08-14 12:47:44 -0500495
Bob Kingbeaf6532020-01-21 11:03:49 +0800496TEST(ValidateRegulatorsConfigTest, And)
497{
498 // Valid.
499 {
500 json configFile = validConfigFile;
501 json andAction =
502 R"(
503 {
504 "and": [
505 { "i2c_compare_byte": { "register": "0xA0", "value": "0x00" } },
506 { "i2c_compare_byte": { "register": "0xA1", "value": "0x00" } }
507 ]
508 }
509 )"_json;
510 configFile["rules"][0]["actions"].push_back(andAction);
511 EXPECT_JSON_VALID(configFile);
512 }
513
514 // Invalid: actions property value is an empty array.
515 {
516 json configFile = validConfigFile;
517 json andAction =
518 R"(
519 {
520 "and": []
521 }
522 )"_json;
523 configFile["rules"][0]["actions"].push_back(andAction);
524 EXPECT_JSON_INVALID(configFile, "Validation failed.",
525 "[] is too short");
526 }
527
528 // Invalid: actions property has incorrect value data type.
529 {
530 json configFile = validConfigFile;
531 json andAction =
532 R"(
533 {
534 "and": true
535 }
536 )"_json;
537 configFile["rules"][0]["actions"].push_back(andAction);
538 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800539 "True is not of type 'array'");
Bob Kingbeaf6532020-01-21 11:03:49 +0800540 }
541
542 // Invalid: actions property value contains wrong element type
543 {
544 json configFile = validConfigFile;
545 json andAction =
546 R"(
547 {
548 "and": ["foo"]
549 }
550 )"_json;
551 configFile["rules"][0]["actions"].push_back(andAction);
552 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800553 "'foo' is not of type 'object'");
Bob Kingbeaf6532020-01-21 11:03:49 +0800554 }
555}
Shawn McCarney846dde52021-08-14 12:47:44 -0500556
Bob King3728f562020-01-21 11:35:31 +0800557TEST(ValidateRegulatorsConfigTest, Chassis)
558{
559 // Valid: test chassis.
560 {
561 json configFile = validConfigFile;
562 EXPECT_JSON_VALID(configFile);
563 }
Shawn McCarneyecbeeea2021-04-29 21:08:18 -0500564 // Valid: test chassis with only required properties.
Bob King3728f562020-01-21 11:35:31 +0800565 {
566 json configFile = validConfigFile;
567 configFile["chassis"][0].erase("comments");
Shawn McCarneyecbeeea2021-04-29 21:08:18 -0500568 configFile["chassis"][0].erase("inventory_path");
Bob King3728f562020-01-21 11:35:31 +0800569 configFile["chassis"][0].erase("devices");
570 EXPECT_JSON_VALID(configFile);
571 }
572 // Invalid: test chassis with no number.
573 {
574 json configFile = validConfigFile;
575 configFile["chassis"][0].erase("number");
576 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800577 "'number' is a required property");
Bob King3728f562020-01-21 11:35:31 +0800578 }
579 // Invalid: test chassis with property comments wrong type.
580 {
581 json configFile = validConfigFile;
582 configFile["chassis"][0]["comments"] = true;
583 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800584 "True is not of type 'array'");
Bob King3728f562020-01-21 11:35:31 +0800585 }
586 // Invalid: test chassis with property number wrong type.
587 {
588 json configFile = validConfigFile;
589 configFile["chassis"][0]["number"] = 1.3;
590 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800591 "1.3 is not of type 'integer'");
Bob King3728f562020-01-21 11:35:31 +0800592 }
Shawn McCarneyecbeeea2021-04-29 21:08:18 -0500593 // Invalid: test chassis with property inventory_path wrong type.
594 {
595 json configFile = validConfigFile;
596 configFile["chassis"][0]["inventory_path"] = 2;
597 EXPECT_JSON_INVALID(configFile, "Validation failed.",
598 "2 is not of type 'string'");
599 }
Bob King3728f562020-01-21 11:35:31 +0800600 // Invalid: test chassis with property devices wrong type.
601 {
602 json configFile = validConfigFile;
603 configFile["chassis"][0]["devices"] = true;
604 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800605 "True is not of type 'array'");
Bob King3728f562020-01-21 11:35:31 +0800606 }
607 // Invalid: test chassis with property comments empty array.
608 {
609 json configFile = validConfigFile;
610 configFile["chassis"][0]["comments"] = json::array();
611 EXPECT_JSON_INVALID(configFile, "Validation failed.",
612 "[] is too short");
613 }
614 // Invalid: test chassis with property devices empty array.
615 {
616 json configFile = validConfigFile;
617 configFile["chassis"][0]["devices"] = json::array();
618 EXPECT_JSON_INVALID(configFile, "Validation failed.",
619 "[] is too short");
620 }
621 // Invalid: test chassis with property number less than 1.
622 {
623 json configFile = validConfigFile;
624 configFile["chassis"][0]["number"] = 0;
625 EXPECT_JSON_INVALID(configFile, "Validation failed.",
626 "0 is less than the minimum of 1");
627 }
Shawn McCarneyecbeeea2021-04-29 21:08:18 -0500628 // Invalid: test chassis with property inventory_path empty string.
629 {
630 json configFile = validConfigFile;
631 configFile["chassis"][0]["inventory_path"] = "";
632 EXPECT_JSON_INVALID(configFile, "Validation failed.",
633 "'' is too short");
634 }
Bob King3728f562020-01-21 11:35:31 +0800635}
Shawn McCarney846dde52021-08-14 12:47:44 -0500636
Bob Kingbf1cbea2020-01-21 11:08:50 +0800637TEST(ValidateRegulatorsConfigTest, ComparePresence)
638{
639 json comparePresenceFile = validConfigFile;
640 comparePresenceFile["rules"][0]["actions"][1]["compare_presence"]["fru"] =
Bob Kinga76898f2020-10-13 15:08:33 +0800641 "system/chassis/motherboard/regulator2";
Bob Kingbf1cbea2020-01-21 11:08:50 +0800642 comparePresenceFile["rules"][0]["actions"][1]["compare_presence"]["value"] =
643 true;
644 // Valid.
645 {
646 json configFile = comparePresenceFile;
647 EXPECT_JSON_VALID(configFile);
648 }
649
650 // Invalid: no FRU property.
651 {
652 json configFile = comparePresenceFile;
653 configFile["rules"][0]["actions"][1]["compare_presence"].erase("fru");
654 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800655 "'fru' is a required property");
Bob Kingbf1cbea2020-01-21 11:08:50 +0800656 }
657
658 // Invalid: FRU property length is string less than 1.
659 {
660 json configFile = comparePresenceFile;
661 configFile["rules"][0]["actions"][1]["compare_presence"]["fru"] = "";
662 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800663 "'' is too short");
Bob Kingbf1cbea2020-01-21 11:08:50 +0800664 }
665
666 // Invalid: no value property.
667 {
668 json configFile = comparePresenceFile;
669 configFile["rules"][0]["actions"][1]["compare_presence"].erase("value");
670 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800671 "'value' is a required property");
Bob Kingbf1cbea2020-01-21 11:08:50 +0800672 }
673
674 // Invalid: value property type is not boolean.
675 {
676 json configFile = comparePresenceFile;
677 configFile["rules"][0]["actions"][1]["compare_presence"]["value"] = "1";
678 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800679 "'1' is not of type 'boolean'");
Bob Kingbf1cbea2020-01-21 11:08:50 +0800680 }
681
682 // Invalid: FRU property type is not string.
683 {
684 json configFile = comparePresenceFile;
685 configFile["rules"][0]["actions"][1]["compare_presence"]["fru"] = 1;
686 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800687 "1 is not of type 'string'");
Bob Kingbf1cbea2020-01-21 11:08:50 +0800688 }
689}
Shawn McCarney846dde52021-08-14 12:47:44 -0500690
Bob Kingf8b77a02020-01-21 11:09:47 +0800691TEST(ValidateRegulatorsConfigTest, CompareVpd)
692{
693 json compareVpdFile = validConfigFile;
694 compareVpdFile["rules"][0]["actions"][1]["compare_vpd"]["fru"] =
Bob Kinga76898f2020-10-13 15:08:33 +0800695 "system/chassis/motherboard/regulator2";
Bob Kingf8b77a02020-01-21 11:09:47 +0800696 compareVpdFile["rules"][0]["actions"][1]["compare_vpd"]["keyword"] = "CCIN";
697 compareVpdFile["rules"][0]["actions"][1]["compare_vpd"]["value"] = "2D35";
698
699 // Valid.
700 {
701 json configFile = compareVpdFile;
702 EXPECT_JSON_VALID(configFile);
703 }
Matt Spinleraacc2aa2021-05-25 09:31:35 -0600704 // Valid, using byte_values.
705 {
706 json configFile = compareVpdFile;
707 configFile["rules"][0]["actions"][1]["compare_vpd"].erase("value");
708 configFile["rules"][0]["actions"][1]["compare_vpd"]["byte_values"] = {
709 "0x01", "0x02"};
710 EXPECT_JSON_VALID(configFile);
711 }
Bob Kingf8b77a02020-01-21 11:09:47 +0800712
713 // Invalid: no FRU property.
714 {
715 json configFile = compareVpdFile;
716 configFile["rules"][0]["actions"][1]["compare_vpd"].erase("fru");
717 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800718 "'fru' is a required property");
Bob Kingf8b77a02020-01-21 11:09:47 +0800719 }
720
721 // Invalid: no keyword property.
722 {
723 json configFile = compareVpdFile;
724 configFile["rules"][0]["actions"][1]["compare_vpd"].erase("keyword");
725 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800726 "'keyword' is a required property");
Bob Kingf8b77a02020-01-21 11:09:47 +0800727 }
728
729 // Invalid: no value property.
730 {
731 json configFile = compareVpdFile;
732 configFile["rules"][0]["actions"][1]["compare_vpd"].erase("value");
733 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800734 "'value' is a required property");
Bob Kingf8b77a02020-01-21 11:09:47 +0800735 }
736
737 // Invalid: property FRU wrong type.
738 {
739 json configFile = compareVpdFile;
740 configFile["rules"][0]["actions"][1]["compare_vpd"]["fru"] = 1;
741 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800742 "1 is not of type 'string'");
Bob Kingf8b77a02020-01-21 11:09:47 +0800743 }
744
745 // Invalid: property FRU is string less than 1.
746 {
747 json configFile = compareVpdFile;
748 configFile["rules"][0]["actions"][1]["compare_vpd"]["fru"] = "";
749 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800750 "'' is too short");
Bob Kingf8b77a02020-01-21 11:09:47 +0800751 }
752
753 // Invalid: property keyword is not "CCIN", "Manufacturer", "Model",
Matt Spinleraacc2aa2021-05-25 09:31:35 -0600754 // "PartNumber", "HW"
Bob Kingf8b77a02020-01-21 11:09:47 +0800755 {
756 json configFile = compareVpdFile;
757 configFile["rules"][0]["actions"][1]["compare_vpd"]["keyword"] =
758 "Number";
759 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800760 "'Number' is not one of ['CCIN', "
Matt Spinleraacc2aa2021-05-25 09:31:35 -0600761 "'Manufacturer', 'Model', 'PartNumber', 'HW']");
Bob Kingf8b77a02020-01-21 11:09:47 +0800762 }
763
764 // Invalid: property value wrong type.
765 {
766 json configFile = compareVpdFile;
767 configFile["rules"][0]["actions"][1]["compare_vpd"]["value"] = 1;
768 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800769 "1 is not of type 'string'");
Bob Kingf8b77a02020-01-21 11:09:47 +0800770 }
Matt Spinleraacc2aa2021-05-25 09:31:35 -0600771
772 // Invalid: property byte_values has wrong type
773 {
774 json configFile = compareVpdFile;
775 configFile["rules"][0]["actions"][1]["compare_vpd"].erase("value");
776 configFile["rules"][0]["actions"][1]["compare_vpd"]["byte_values"] =
777 "0x50";
778 EXPECT_JSON_INVALID(configFile, "Validation failed.",
779 "'0x50' is not of type 'array'");
780 }
781
782 // Invalid: property byte_values is empty
783 {
784 json configFile = compareVpdFile;
785 configFile["rules"][0]["actions"][1]["compare_vpd"].erase("value");
786 configFile["rules"][0]["actions"][1]["compare_vpd"]["byte_values"] =
787 json::array();
788 EXPECT_JSON_INVALID(configFile, "Validation failed.",
789 "[] is too short");
790 }
791
792 // Invalid: properties byte_values and value both exist
793 {
794 json configFile = compareVpdFile;
795 configFile["rules"][0]["actions"][1]["compare_vpd"]["byte_values"] = {
796 "0x01", "0x02"};
797 EXPECT_JSON_INVALID(
798 configFile, "Validation failed.",
799 "{'byte_values': ['0x01', '0x02'], 'fru': "
800 "'system/chassis/motherboard/regulator2', 'keyword': 'CCIN', "
801 "'value': '2D35'} is valid under each of {'required': "
802 "['byte_values']}, {'required': ['value']}");
803 }
Bob Kingf8b77a02020-01-21 11:09:47 +0800804}
Shawn McCarney846dde52021-08-14 12:47:44 -0500805
Bob King20057412020-03-16 16:50:17 +0800806TEST(ValidateRegulatorsConfigTest, ConfigFile)
807{
808 // Valid: Only required properties specified
809 {
810 json configFile;
811 configFile["chassis"][0]["number"] = 1;
812 EXPECT_JSON_VALID(configFile);
813 }
814 // Valid: All properties specified
815 {
816 json configFile = validConfigFile;
817 EXPECT_JSON_VALID(configFile);
818 }
819 // Invalid: Required chassis property not specified
820 {
821 json configFile = validConfigFile;
822 configFile.erase("chassis");
823 EXPECT_JSON_INVALID(configFile, "Validation failed.",
824 "'chassis' is a required property");
825 }
826 // Invalid: Wrong data type for comments
827 {
828 json configFile = validConfigFile;
829 configFile["comments"] = true;
830 EXPECT_JSON_INVALID(configFile, "Validation failed.",
831 "True is not of type 'array'");
832 }
833 // Invalid: Wrong data type for rules
834 {
835 json configFile = validConfigFile;
836 configFile["rules"] = true;
837 EXPECT_JSON_INVALID(configFile, "Validation failed.",
838 "True is not of type 'array'");
839 }
840 // Invalid: Wrong data type for chassis
841 {
842 json configFile = validConfigFile;
843 configFile["chassis"] = true;
844 EXPECT_JSON_INVALID(configFile, "Validation failed.",
845 "True is not of type 'array'");
846 }
847 // Invalid: Empty comments array;
848 {
849 json configFile = validConfigFile;
850 configFile["comments"] = json::array();
851 EXPECT_JSON_INVALID(configFile, "Validation failed.",
852 "[] is too short");
853 }
854 // Invalid: Empty rules array
855 {
856 json configFile = validConfigFile;
857 configFile["rules"] = json::array();
858 EXPECT_JSON_INVALID(configFile, "Validation failed.",
859 "[] is too short");
860 }
861 // Invalid: Empty chassis array
862 {
863 json configFile = validConfigFile;
864 configFile["chassis"] = json::array();
865 EXPECT_JSON_INVALID(configFile, "Validation failed.",
866 "[] is too short");
867 }
868 // Invalid: Comments array has wrong element type (should be string)
869 {
870 json configFile = validConfigFile;
871 configFile["comments"][0] = true;
872 EXPECT_JSON_INVALID(configFile, "Validation failed.",
873 "True is not of type 'string'");
874 }
875 // Invalid: Rules array has wrong element type (should be rule)
876 {
877 json configFile = validConfigFile;
878 configFile["rules"][0] = true;
879 EXPECT_JSON_INVALID(configFile, "Validation failed.",
880 "True is not of type 'object'");
881 }
882 // Invalid: Chassis array has wrong element type (should be chassis)
883 {
884 json configFile = validConfigFile;
885 configFile["chassis"][0] = true;
886 EXPECT_JSON_INVALID(configFile, "Validation failed.",
887 "True is not of type 'object'");
888 }
889 // Invalid: Unexpected property specified
890 {
891 json configFile = validConfigFile;
892 configFile["foo"] = json::array();
893 EXPECT_JSON_INVALID(
894 configFile, "Validation failed.",
895 "Additional properties are not allowed ('foo' was unexpected)");
896 }
897}
Shawn McCarney846dde52021-08-14 12:47:44 -0500898
Bob King4c67a3a2020-02-07 09:48:11 +0800899TEST(ValidateRegulatorsConfigTest, Configuration)
900{
901 json configurationFile = validConfigFile;
902 configurationFile["chassis"][0]["devices"][0]["configuration"]["comments"]
903 [0] = "Set rail to 1.25V using standard rule";
904 configurationFile["chassis"][0]["devices"][0]["configuration"]["volts"] =
905 1.25;
906 configurationFile["chassis"][0]["devices"][0]["configuration"]["rule_id"] =
907 "set_voltage_rule";
908 // Valid: test configuration with property rule_id and with no actions.
909 {
910 json configFile = configurationFile;
Bob King78793102020-03-13 13:16:09 +0800911 configFile["chassis"][0]["devices"][0]["configuration"]["comments"][1] =
912 "test multiple array elements in comments.";
Bob King4c67a3a2020-02-07 09:48:11 +0800913 EXPECT_JSON_VALID(configFile);
914 }
915 // Valid: test configuration with property actions and with no rule_id.
916 {
917 json configFile = configurationFile;
918 configFile["chassis"][0]["devices"][0]["configuration"].erase(
919 "rule_id");
920 configFile["chassis"][0]["devices"][0]["configuration"]["actions"][0]
921 ["compare_presence"]["fru"] =
Bob Kinga76898f2020-10-13 15:08:33 +0800922 "system/chassis/motherboard/cpu3";
Bob King4c67a3a2020-02-07 09:48:11 +0800923 configFile["chassis"][0]["devices"][0]["configuration"]["actions"][0]
924 ["compare_presence"]["value"] = true;
925 EXPECT_JSON_VALID(configFile);
926 }
927 // Valid: comments not specified (optional property).
928 {
929 json configFile = configurationFile;
930 configFile["chassis"][0]["devices"][0]["configuration"].erase(
931 "comments");
932 EXPECT_JSON_VALID(configFile);
933 }
934 // Valid: volts not specified (optional property).
935 {
936 json configFile = configurationFile;
937 configFile["chassis"][0]["devices"][0]["configuration"].erase("volts");
938 EXPECT_JSON_VALID(configFile);
939 }
940 // Valid: configuration is property of a rail (vs. a device).
941 {
942 json configFile = validConfigFile;
943 configFile["chassis"][0]["devices"][0]["rails"][0]["configuration"]
944 ["comments"][0] = "Set rail to 1.25V using standard rule";
945 configFile["chassis"][0]["devices"][0]["rails"][0]["configuration"]
946 ["volts"] = 1.25;
947 configFile["chassis"][0]["devices"][0]["rails"][0]["configuration"]
948 ["rule_id"] = "set_voltage_rule";
949 EXPECT_JSON_VALID(configFile);
950 }
951 // Invalid: comments property has wrong data type (not an array).
952 {
953 json configFile = configurationFile;
954 configFile["chassis"][0]["devices"][0]["configuration"]["comments"] = 1;
955 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800956 "1 is not of type 'array'");
Bob King4c67a3a2020-02-07 09:48:11 +0800957 }
958 // Invalid: test configuration with both actions and rule_id properties.
959 {
960 json configFile = configurationFile;
961 configFile["chassis"][0]["devices"][0]["configuration"]["actions"][0]
962 ["compare_presence"]["fru"] =
Bob Kinga76898f2020-10-13 15:08:33 +0800963 "system/chassis/motherboard/cpu3";
Bob King4c67a3a2020-02-07 09:48:11 +0800964 configFile["chassis"][0]["devices"][0]["configuration"]["actions"][0]
965 ["compare_presence"]["value"] = true;
Shawn McCarney846dde52021-08-14 12:47:44 -0500966 EXPECT_JSON_INVALID(configFile, "Validation failed.", "");
Bob King4c67a3a2020-02-07 09:48:11 +0800967 }
968 // Invalid: test configuration with no rule_id and actions.
969 {
970 json configFile = configurationFile;
971 configFile["chassis"][0]["devices"][0]["configuration"].erase(
972 "rule_id");
973 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800974 "'rule_id' is a required property");
Bob King4c67a3a2020-02-07 09:48:11 +0800975 }
976 // Invalid: test configuration with property volts wrong type.
977 {
978 json configFile = configurationFile;
979 configFile["chassis"][0]["devices"][0]["configuration"]["volts"] = true;
980 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800981 "True is not of type 'number'");
Bob King4c67a3a2020-02-07 09:48:11 +0800982 }
983 // Invalid: test configuration with property rule_id wrong type.
984 {
985 json configFile = configurationFile;
986 configFile["chassis"][0]["devices"][0]["configuration"]["rule_id"] =
987 true;
988 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800989 "True is not of type 'string'");
Bob King4c67a3a2020-02-07 09:48:11 +0800990 }
991 // Invalid: test configuration with property actions wrong type.
992 {
993 json configFile = configurationFile;
994 configFile["chassis"][0]["devices"][0]["configuration"].erase(
995 "rule_id");
996 configFile["chassis"][0]["devices"][0]["configuration"]["actions"] =
997 true;
998 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800999 "True is not of type 'array'");
Bob King4c67a3a2020-02-07 09:48:11 +08001000 }
1001 // Invalid: test configuration with property comments empty array.
1002 {
1003 json configFile = configurationFile;
1004 configFile["chassis"][0]["devices"][0]["configuration"]["comments"] =
1005 json::array();
1006 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1007 "[] is too short");
1008 }
1009 // Invalid: test configuration with property rule_id wrong format.
1010 {
1011 json configFile = configurationFile;
1012 configFile["chassis"][0]["devices"][0]["configuration"]["rule_id"] =
1013 "id!";
1014 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001015 "'id!' does not match '^[A-Za-z0-9_]+$'");
Bob King4c67a3a2020-02-07 09:48:11 +08001016 }
1017 // Invalid: test configuration with property actions empty array.
1018 {
1019 json configFile = configurationFile;
1020 configFile["chassis"][0]["devices"][0]["configuration"].erase(
1021 "rule_id");
1022 configFile["chassis"][0]["devices"][0]["configuration"]["actions"] =
1023 json::array();
1024 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1025 "[] is too short");
1026 }
1027}
Shawn McCarney846dde52021-08-14 12:47:44 -05001028
Bob Kinga2ba2df2020-02-04 14:38:44 +08001029TEST(ValidateRegulatorsConfigTest, Device)
1030{
Bob Kinga2ba2df2020-02-04 14:38:44 +08001031 // Valid: test devices.
1032 {
1033 json configFile = validConfigFile;
1034 EXPECT_JSON_VALID(configFile);
1035 }
1036 // Valid: test devices with required properties.
1037 {
1038 json configFile = validConfigFile;
1039 configFile["chassis"][0]["devices"][0].erase("comments");
1040 configFile["chassis"][0]["devices"][0].erase("presence_detection");
1041 configFile["chassis"][0]["devices"][0].erase("configuration");
Shawn McCarney846dde52021-08-14 12:47:44 -05001042 configFile["chassis"][0]["devices"][0].erase("phase_fault_detection");
Bob Kinga2ba2df2020-02-04 14:38:44 +08001043 configFile["chassis"][0]["devices"][0].erase("rails");
1044 EXPECT_JSON_VALID(configFile);
1045 }
1046 // Invalid: test devices with no id.
1047 {
1048 json configFile = validConfigFile;
1049 configFile["chassis"][0]["devices"][0].erase("id");
1050 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001051 "'id' is a required property");
Bob Kinga2ba2df2020-02-04 14:38:44 +08001052 }
1053 // Invalid: test devices with no is_regulator.
1054 {
1055 json configFile = validConfigFile;
1056 configFile["chassis"][0]["devices"][0].erase("is_regulator");
1057 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001058 "'is_regulator' is a required property");
Bob Kinga2ba2df2020-02-04 14:38:44 +08001059 }
1060 // Invalid: test devices with no fru.
1061 {
1062 json configFile = validConfigFile;
1063 configFile["chassis"][0]["devices"][0].erase("fru");
1064 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001065 "'fru' is a required property");
Bob Kinga2ba2df2020-02-04 14:38:44 +08001066 }
1067 // Invalid: test devices with no i2c_interface.
1068 {
1069 json configFile = validConfigFile;
1070 configFile["chassis"][0]["devices"][0].erase("i2c_interface");
1071 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001072 "'i2c_interface' is a required property");
Bob Kinga2ba2df2020-02-04 14:38:44 +08001073 }
Shawn McCarney846dde52021-08-14 12:47:44 -05001074 // Invalid: is_regulator=false: phase_fault_detection specified
1075 {
1076 json configFile = validConfigFile;
1077 configFile["chassis"][0]["devices"][0]["is_regulator"] = false;
1078 configFile["chassis"][0]["devices"][0].erase("rails");
1079 configFile["chassis"][0]["devices"][0]["phase_fault_detection"]
1080 ["rule_id"] = "detect_phase_faults_rule";
1081 EXPECT_JSON_INVALID(configFile, "Validation failed.", "");
1082 }
1083 // Invalid: is_regulator=false: rails specified
1084 {
1085 json configFile = validConfigFile;
1086 configFile["chassis"][0]["devices"][0]["is_regulator"] = false;
1087 EXPECT_JSON_INVALID(configFile, "Validation failed.", "");
1088 }
1089 // Invalid: is_regulator=false: phase_fault_detection and rails specified
1090 {
1091 json configFile = validConfigFile;
1092 configFile["chassis"][0]["devices"][0]["is_regulator"] = false;
1093 configFile["chassis"][0]["devices"][0]["phase_fault_detection"]
1094 ["rule_id"] = "detect_phase_faults_rule";
1095 EXPECT_JSON_INVALID(configFile, "Validation failed.", "");
1096 }
Bob Kinga2ba2df2020-02-04 14:38:44 +08001097 // Invalid: test devices with property comments wrong type.
1098 {
1099 json configFile = validConfigFile;
1100 configFile["chassis"][0]["devices"][0]["comments"] = true;
1101 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001102 "True is not of type 'array'");
Bob Kinga2ba2df2020-02-04 14:38:44 +08001103 }
1104 // Invalid: test devices with property id wrong type.
1105 {
1106 json configFile = validConfigFile;
1107 configFile["chassis"][0]["devices"][0]["id"] = true;
1108 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001109 "True is not of type 'string'");
Bob Kinga2ba2df2020-02-04 14:38:44 +08001110 }
1111 // Invalid: test devices with property is_regulator wrong type.
1112 {
1113 json configFile = validConfigFile;
1114 configFile["chassis"][0]["devices"][0]["is_regulator"] = 1;
1115 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001116 "1 is not of type 'boolean'");
Bob Kinga2ba2df2020-02-04 14:38:44 +08001117 }
1118 // Invalid: test devices with property fru wrong type.
1119 {
1120 json configFile = validConfigFile;
1121 configFile["chassis"][0]["devices"][0]["fru"] = true;
1122 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001123 "True is not of type 'string'");
Bob Kinga2ba2df2020-02-04 14:38:44 +08001124 }
1125 // Invalid: test devices with property i2c_interface wrong type.
1126 {
1127 json configFile = validConfigFile;
1128 configFile["chassis"][0]["devices"][0]["i2c_interface"] = true;
1129 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001130 "True is not of type 'object'");
Bob Kinga2ba2df2020-02-04 14:38:44 +08001131 }
1132 // Invalid: test devices with property presence_detection wrong
1133 // type.
1134 {
1135 json configFile = validConfigFile;
1136 configFile["chassis"][0]["devices"][0]["presence_detection"] = true;
1137 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001138 "True is not of type 'object'");
Bob Kinga2ba2df2020-02-04 14:38:44 +08001139 }
1140 // Invalid: test devices with property configuration wrong type.
1141 {
1142 json configFile = validConfigFile;
1143 configFile["chassis"][0]["devices"][0]["configuration"] = true;
1144 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001145 "True is not of type 'object'");
Bob Kinga2ba2df2020-02-04 14:38:44 +08001146 }
Shawn McCarney846dde52021-08-14 12:47:44 -05001147 // Invalid: test devices with property phase_fault_detection wrong type.
1148 {
1149 json configFile = validConfigFile;
1150 configFile["chassis"][0]["devices"][0]["phase_fault_detection"] = true;
1151 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1152 "True is not of type 'object'");
1153 }
Bob Kinga2ba2df2020-02-04 14:38:44 +08001154 // Invalid: test devices with property rails wrong type.
1155 {
1156 json configFile = validConfigFile;
1157 configFile["chassis"][0]["devices"][0]["rails"] = true;
1158 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001159 "True is not of type 'array'");
Bob Kinga2ba2df2020-02-04 14:38:44 +08001160 }
1161 // Invalid: test devices with property comments empty array.
1162 {
1163 json configFile = validConfigFile;
1164 configFile["chassis"][0]["devices"][0]["comments"] = json::array();
1165 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1166 "[] is too short");
1167 }
1168 // Invalid: test devices with property fru length less than 1.
1169 {
1170 json configFile = validConfigFile;
1171 configFile["chassis"][0]["devices"][0]["fru"] = "";
1172 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001173 "'' is too short");
Bob Kinga2ba2df2020-02-04 14:38:44 +08001174 }
1175 // Invalid: test devices with property id wrong format.
1176 {
1177 json configFile = validConfigFile;
1178 configFile["chassis"][0]["devices"][0]["id"] = "id#";
1179 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001180 "'id#' does not match '^[A-Za-z0-9_]+$'");
Bob Kinga2ba2df2020-02-04 14:38:44 +08001181 }
1182 // Invalid: test devices with property rails empty array.
1183 {
1184 json configFile = validConfigFile;
1185 configFile["chassis"][0]["devices"][0]["rails"] = json::array();
1186 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1187 "[] is too short");
1188 }
1189}
Shawn McCarney846dde52021-08-14 12:47:44 -05001190
1191TEST(ValidateRegulatorsConfigTest, I2CCaptureBytes)
1192{
1193 json initialFile = validConfigFile;
1194 initialFile["rules"][0]["actions"][1]["i2c_capture_bytes"]["register"] =
1195 "0xA0";
1196 initialFile["rules"][0]["actions"][1]["i2c_capture_bytes"]["count"] = 2;
1197
1198 // Valid: All required properties
1199 {
1200 json configFile = initialFile;
1201 EXPECT_JSON_VALID(configFile);
1202 }
1203
1204 // Invalid: register not specified
1205 {
1206 json configFile = initialFile;
1207 configFile["rules"][0]["actions"][1]["i2c_capture_bytes"].erase(
1208 "register");
1209 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1210 "'register' is a required property");
1211 }
1212
1213 // Invalid: count not specified
1214 {
1215 json configFile = initialFile;
1216 configFile["rules"][0]["actions"][1]["i2c_capture_bytes"].erase(
1217 "count");
1218 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1219 "'count' is a required property");
1220 }
1221
1222 // Invalid: invalid property specified
1223 {
1224 json configFile = initialFile;
1225 configFile["rules"][0]["actions"][1]["i2c_capture_bytes"]["foo"] = true;
1226 EXPECT_JSON_INVALID(
1227 configFile, "Validation failed.",
1228 "Additional properties are not allowed ('foo' was unexpected)");
1229 }
1230
1231 // Invalid: register has wrong data type
1232 {
1233 json configFile = initialFile;
1234 configFile["rules"][0]["actions"][1]["i2c_capture_bytes"]["register"] =
1235 1;
1236 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1237 "1 is not of type 'string'");
1238 }
1239
1240 // Invalid: register has wrong format
1241 {
1242 json configFile = initialFile;
1243 configFile["rules"][0]["actions"][1]["i2c_capture_bytes"]["register"] =
1244 "0xA00";
1245 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1246 "'0xA00' does not match '^0x[0-9A-Fa-f]{2}$'");
1247 }
1248
1249 // Invalid: count has wrong data type
1250 {
1251 json configFile = initialFile;
1252 configFile["rules"][0]["actions"][1]["i2c_capture_bytes"]["count"] =
1253 3.1;
1254 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1255 "3.1 is not of type 'integer'");
1256 }
1257
1258 // Invalid: count < 1
1259 {
1260 json configFile = initialFile;
1261 configFile["rules"][0]["actions"][1]["i2c_capture_bytes"]["count"] = 0;
1262 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1263 "0 is less than the minimum of 1");
1264 }
1265}
1266
Bob King4ab8cbb2020-01-21 11:10:48 +08001267TEST(ValidateRegulatorsConfigTest, I2CCompareBit)
1268{
1269 json i2cCompareBitFile = validConfigFile;
1270 i2cCompareBitFile["rules"][0]["actions"][1]["i2c_compare_bit"]["register"] =
1271 "0xA0";
1272 i2cCompareBitFile["rules"][0]["actions"][1]["i2c_compare_bit"]["position"] =
1273 3;
1274 i2cCompareBitFile["rules"][0]["actions"][1]["i2c_compare_bit"]["value"] = 1;
1275 // Valid: test rule actions i2c_compare_bit.
1276 {
1277 json configFile = i2cCompareBitFile;
1278 EXPECT_JSON_VALID(configFile);
1279 }
1280 // Invalid: test i2c_compare_bit with no register.
1281 {
1282 json configFile = i2cCompareBitFile;
1283 configFile["rules"][0]["actions"][1]["i2c_compare_bit"].erase(
1284 "register");
1285 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001286 "'register' is a required property");
Bob King4ab8cbb2020-01-21 11:10:48 +08001287 }
1288 // Invalid: test i2c_compare_bit with no position.
1289 {
1290 json configFile = i2cCompareBitFile;
1291 configFile["rules"][0]["actions"][1]["i2c_compare_bit"].erase(
1292 "position");
1293 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001294 "'position' is a required property");
Bob King4ab8cbb2020-01-21 11:10:48 +08001295 }
1296 // Invalid: test i2c_compare_bit with no value.
1297 {
1298 json configFile = i2cCompareBitFile;
1299 configFile["rules"][0]["actions"][1]["i2c_compare_bit"].erase("value");
1300 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001301 "'value' is a required property");
Bob King4ab8cbb2020-01-21 11:10:48 +08001302 }
1303 // Invalid: test i2c_compare_bit with register wrong type.
1304 {
1305 json configFile = i2cCompareBitFile;
1306 configFile["rules"][0]["actions"][1]["i2c_compare_bit"]["register"] = 1;
1307 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001308 "1 is not of type 'string'");
Bob King4ab8cbb2020-01-21 11:10:48 +08001309 }
1310 // Invalid: test i2c_compare_bit with register wrong format.
1311 {
1312 json configFile = i2cCompareBitFile;
1313 configFile["rules"][0]["actions"][1]["i2c_compare_bit"]["register"] =
1314 "0xA00";
1315 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001316 "'0xA00' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King4ab8cbb2020-01-21 11:10:48 +08001317 }
1318 // Invalid: test i2c_compare_bit with position wrong type.
1319 {
1320 json configFile = i2cCompareBitFile;
1321 configFile["rules"][0]["actions"][1]["i2c_compare_bit"]["position"] =
1322 3.1;
1323 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001324 "3.1 is not of type 'integer'");
Bob King4ab8cbb2020-01-21 11:10:48 +08001325 }
1326 // Invalid: test i2c_compare_bit with position greater than 7.
1327 {
1328 json configFile = i2cCompareBitFile;
1329 configFile["rules"][0]["actions"][1]["i2c_compare_bit"]["position"] = 8;
1330 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1331 "8 is greater than the maximum of 7");
1332 }
1333 // Invalid: test i2c_compare_bit with position less than 0.
1334 {
1335 json configFile = i2cCompareBitFile;
1336 configFile["rules"][0]["actions"][1]["i2c_compare_bit"]["position"] =
1337 -1;
1338 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1339 "-1 is less than the minimum of 0");
1340 }
1341 // Invalid: test i2c_compare_bit with value wrong type.
1342 {
1343 json configFile = i2cCompareBitFile;
1344 configFile["rules"][0]["actions"][1]["i2c_compare_bit"]["value"] = "1";
1345 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001346 "'1' is not of type 'integer'");
Bob King4ab8cbb2020-01-21 11:10:48 +08001347 }
1348 // Invalid: test i2c_compare_bit with value greater than 1.
1349 {
1350 json configFile = i2cCompareBitFile;
1351 configFile["rules"][0]["actions"][1]["i2c_compare_bit"]["value"] = 2;
1352 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1353 "2 is greater than the maximum of 1");
1354 }
1355 // Invalid: test i2c_compare_bit with value less than 0.
1356 {
1357 json configFile = i2cCompareBitFile;
1358 configFile["rules"][0]["actions"][1]["i2c_compare_bit"]["value"] = -1;
1359 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1360 "-1 is less than the minimum of 0");
1361 }
1362}
Shawn McCarney846dde52021-08-14 12:47:44 -05001363
Bob King514023d2020-01-21 11:13:05 +08001364TEST(ValidateRegulatorsConfigTest, I2CCompareByte)
1365{
1366 json i2cCompareByteFile = validConfigFile;
1367 i2cCompareByteFile["rules"][0]["actions"][1]["i2c_compare_byte"]
1368 ["register"] = "0x82";
1369 i2cCompareByteFile["rules"][0]["actions"][1]["i2c_compare_byte"]["value"] =
1370 "0x40";
1371 i2cCompareByteFile["rules"][0]["actions"][1]["i2c_compare_byte"]["mask"] =
1372 "0x7F";
1373 // Valid: test i2c_compare_byte with all properties.
1374 {
1375 json configFile = i2cCompareByteFile;
1376 EXPECT_JSON_VALID(configFile);
1377 }
1378 // Valid: test i2c_compare_byte with all required properties.
1379 {
1380 json configFile = i2cCompareByteFile;
1381 configFile["rules"][0]["actions"][1]["i2c_compare_byte"].erase("mask");
1382 EXPECT_JSON_VALID(configFile);
1383 }
1384 // Invalid: test i2c_compare_byte with no register.
1385 {
1386 json configFile = i2cCompareByteFile;
1387 configFile["rules"][0]["actions"][1]["i2c_compare_byte"].erase(
1388 "register");
1389 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001390 "'register' is a required property");
Bob King514023d2020-01-21 11:13:05 +08001391 }
1392 // Invalid: test i2c_compare_byte with no value.
1393 {
1394 json configFile = i2cCompareByteFile;
1395 configFile["rules"][0]["actions"][1]["i2c_compare_byte"].erase("value");
1396 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001397 "'value' is a required property");
Bob King514023d2020-01-21 11:13:05 +08001398 }
1399 // Invalid: test i2c_compare_byte with property register wrong type.
1400 {
1401 json configFile = i2cCompareByteFile;
1402 configFile["rules"][0]["actions"][1]["i2c_compare_byte"]["register"] =
1403 1;
1404 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001405 "1 is not of type 'string'");
Bob King514023d2020-01-21 11:13:05 +08001406 }
1407 // Invalid: test i2c_compare_byte with property value wrong type.
1408 {
1409 json configFile = i2cCompareByteFile;
1410 configFile["rules"][0]["actions"][1]["i2c_compare_byte"]["value"] = 1;
1411 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001412 "1 is not of type 'string'");
Bob King514023d2020-01-21 11:13:05 +08001413 }
1414 // Invalid: test i2c_compare_byte with property mask wrong type.
1415 {
1416 json configFile = i2cCompareByteFile;
1417 configFile["rules"][0]["actions"][1]["i2c_compare_byte"]["mask"] = 1;
1418 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001419 "1 is not of type 'string'");
Bob King514023d2020-01-21 11:13:05 +08001420 }
1421 // Invalid: test i2c_compare_byte with property register more than 2 hex
1422 // digits.
1423 {
1424 json configFile = i2cCompareByteFile;
1425 configFile["rules"][0]["actions"][1]["i2c_compare_byte"]["register"] =
1426 "0x820";
1427 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001428 "'0x820' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King514023d2020-01-21 11:13:05 +08001429 }
1430 // Invalid: test i2c_compare_byte with property value more than 2 hex
1431 // digits.
1432 {
1433 json configFile = i2cCompareByteFile;
1434 configFile["rules"][0]["actions"][1]["i2c_compare_byte"]["value"] =
1435 "0x820";
1436 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001437 "'0x820' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King514023d2020-01-21 11:13:05 +08001438 }
1439 // Invalid: test i2c_compare_byte with property mask more than 2 hex digits.
1440 {
1441 json configFile = i2cCompareByteFile;
1442 configFile["rules"][0]["actions"][1]["i2c_compare_byte"]["mask"] =
1443 "0x820";
1444 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001445 "'0x820' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King514023d2020-01-21 11:13:05 +08001446 }
1447 // Invalid: test i2c_compare_byte with property register less than 2 hex
1448 // digits.
1449 {
1450 json configFile = i2cCompareByteFile;
1451 configFile["rules"][0]["actions"][1]["i2c_compare_byte"]["register"] =
1452 "0x8";
1453 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001454 "'0x8' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King514023d2020-01-21 11:13:05 +08001455 }
1456 // Invalid: test i2c_compare_byte with property value less than 2 hex
1457 // digits.
1458 {
1459 json configFile = i2cCompareByteFile;
1460 configFile["rules"][0]["actions"][1]["i2c_compare_byte"]["value"] =
1461 "0x8";
1462 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001463 "'0x8' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King514023d2020-01-21 11:13:05 +08001464 }
1465 // Invalid: test i2c_compare_byte with property mask less than 2 hex digits.
1466 {
1467 json configFile = i2cCompareByteFile;
1468 configFile["rules"][0]["actions"][1]["i2c_compare_byte"]["mask"] =
1469 "0x8";
1470 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001471 "'0x8' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King514023d2020-01-21 11:13:05 +08001472 }
1473 // Invalid: test i2c_compare_byte with property register no leading prefix.
1474 {
1475 json configFile = i2cCompareByteFile;
1476 configFile["rules"][0]["actions"][1]["i2c_compare_byte"]["register"] =
1477 "82";
1478 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001479 "'82' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King514023d2020-01-21 11:13:05 +08001480 }
1481 // Invalid: test i2c_compare_byte with property value no leading prefix.
1482 {
1483 json configFile = i2cCompareByteFile;
1484 configFile["rules"][0]["actions"][1]["i2c_compare_byte"]["value"] =
1485 "82";
1486 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001487 "'82' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King514023d2020-01-21 11:13:05 +08001488 }
1489 // Invalid: test i2c_compare_byte with property mask no leading prefix.
1490 {
1491 json configFile = i2cCompareByteFile;
1492 configFile["rules"][0]["actions"][1]["i2c_compare_byte"]["mask"] = "82";
1493 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001494 "'82' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King514023d2020-01-21 11:13:05 +08001495 }
1496 // Invalid: test i2c_compare_byte with property register invalid hex digit.
1497 {
1498 json configFile = i2cCompareByteFile;
1499 configFile["rules"][0]["actions"][1]["i2c_compare_byte"]["register"] =
1500 "0xG1";
1501 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001502 "'0xG1' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King514023d2020-01-21 11:13:05 +08001503 }
1504 // Invalid: test i2c_compare_byte with property value invalid hex digit.
1505 {
1506 json configFile = i2cCompareByteFile;
1507 configFile["rules"][0]["actions"][1]["i2c_compare_byte"]["value"] =
1508 "0xG1";
1509 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001510 "'0xG1' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King514023d2020-01-21 11:13:05 +08001511 }
1512 // Invalid: test i2c_compare_byte with property mask invalid hex digit.
1513 {
1514 json configFile = i2cCompareByteFile;
1515 configFile["rules"][0]["actions"][1]["i2c_compare_byte"]["mask"] =
1516 "0xG1";
1517 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001518 "'0xG1' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King514023d2020-01-21 11:13:05 +08001519 }
1520}
Shawn McCarney846dde52021-08-14 12:47:44 -05001521
Bob Kingfb162bb2020-01-21 11:28:07 +08001522TEST(ValidateRegulatorsConfigTest, I2CCompareBytes)
1523{
1524 json i2cCompareBytesFile = validConfigFile;
1525 i2cCompareBytesFile["rules"][0]["actions"][1]["i2c_compare_bytes"]
1526 ["register"] = "0x82";
1527 i2cCompareBytesFile["rules"][0]["actions"][1]["i2c_compare_bytes"]
1528 ["values"] = {"0x02", "0x73"};
1529 i2cCompareBytesFile["rules"][0]["actions"][1]["i2c_compare_bytes"]
1530 ["masks"] = {"0x7F", "0x7F"};
1531 // Valid: test i2c_compare_bytes.
1532 {
1533 json configFile = i2cCompareBytesFile;
1534 EXPECT_JSON_VALID(configFile);
1535 }
1536 // Valid: test i2c_compare_bytes with all required properties.
1537 {
1538 json configFile = i2cCompareBytesFile;
1539 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"].erase(
1540 "masks");
1541 EXPECT_JSON_VALID(configFile);
1542 }
1543 // Invalid: test i2c_compare_bytes with no register.
1544 {
1545 json configFile = i2cCompareBytesFile;
1546 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"].erase(
1547 "register");
1548 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001549 "'register' is a required property");
Bob Kingfb162bb2020-01-21 11:28:07 +08001550 }
1551 // Invalid: test i2c_compare_bytes with no values.
1552 {
1553 json configFile = i2cCompareBytesFile;
1554 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"].erase(
1555 "values");
1556 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001557 "'values' is a required property");
Bob Kingfb162bb2020-01-21 11:28:07 +08001558 }
1559 // Invalid: test i2c_compare_bytes with property values as empty array.
1560 {
1561 json configFile = i2cCompareBytesFile;
1562 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["values"] =
1563 json::array();
1564 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1565 "[] is too short");
1566 }
1567 // Invalid: test i2c_compare_bytes with property masks as empty array.
1568 {
1569 json configFile = i2cCompareBytesFile;
1570 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["masks"] =
1571 json::array();
1572 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1573 "[] is too short");
1574 }
1575 // Invalid: test i2c_compare_bytes with property register wrong type.
1576 {
1577 json configFile = i2cCompareBytesFile;
1578 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["register"] =
1579 1;
1580 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001581 "1 is not of type 'string'");
Bob Kingfb162bb2020-01-21 11:28:07 +08001582 }
1583 // Invalid: test i2c_compare_bytes with property values wrong type.
1584 {
1585 json configFile = i2cCompareBytesFile;
1586 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["values"] = 1;
1587 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001588 "1 is not of type 'array'");
Bob Kingfb162bb2020-01-21 11:28:07 +08001589 }
1590 // Invalid: test i2c_compare_bytes with property masks wrong type.
1591 {
1592 json configFile = i2cCompareBytesFile;
1593 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["masks"] = 1;
1594 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001595 "1 is not of type 'array'");
Bob Kingfb162bb2020-01-21 11:28:07 +08001596 }
1597 // Invalid: test i2c_compare_bytes with property register more than 2 hex
1598 // digits.
1599 {
1600 json configFile = i2cCompareBytesFile;
1601 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["register"] =
1602 "0x820";
1603 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001604 "'0x820' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob Kingfb162bb2020-01-21 11:28:07 +08001605 }
1606 // Invalid: test i2c_compare_bytes with property values more than 2 hex
1607 // digits.
1608 {
1609 json configFile = i2cCompareBytesFile;
1610 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["values"][0] =
1611 "0x820";
1612 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001613 "'0x820' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob Kingfb162bb2020-01-21 11:28:07 +08001614 }
1615 // Invalid: test i2c_compare_bytes with property masks more than 2 hex
1616 // digits.
1617 {
1618 json configFile = i2cCompareBytesFile;
1619 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["masks"][0] =
1620 "0x820";
1621 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001622 "'0x820' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob Kingfb162bb2020-01-21 11:28:07 +08001623 }
1624 // Invalid: test i2c_compare_bytes with property register less than 2 hex
1625 // digits.
1626 {
1627 json configFile = i2cCompareBytesFile;
1628 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["register"] =
1629 "0x8";
1630 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001631 "'0x8' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob Kingfb162bb2020-01-21 11:28:07 +08001632 }
1633 // Invalid: test i2c_compare_bytes with property values less than 2 hex
1634 // digits.
1635 {
1636 json configFile = i2cCompareBytesFile;
1637 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["values"][0] =
1638 "0x8";
1639 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001640 "'0x8' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob Kingfb162bb2020-01-21 11:28:07 +08001641 }
1642 // Invalid: test i2c_compare_bytes with property masks less than 2 hex
1643 // digits.
1644 {
1645 json configFile = i2cCompareBytesFile;
1646 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["masks"][0] =
1647 "0x8";
1648 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001649 "'0x8' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob Kingfb162bb2020-01-21 11:28:07 +08001650 }
1651 // Invalid: test i2c_compare_bytes with property register no leading prefix.
1652 {
1653 json configFile = i2cCompareBytesFile;
1654 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["register"] =
1655 "82";
1656 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001657 "'82' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob Kingfb162bb2020-01-21 11:28:07 +08001658 }
1659 // Invalid: test i2c_compare_bytes with property values no leading prefix.
1660 {
1661 json configFile = i2cCompareBytesFile;
1662 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["values"][0] =
1663 "82";
1664 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001665 "'82' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob Kingfb162bb2020-01-21 11:28:07 +08001666 }
1667 // Invalid: test i2c_compare_bytes with property masks no leading prefix.
1668 {
1669 json configFile = i2cCompareBytesFile;
1670 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["masks"][0] =
1671 "82";
1672 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001673 "'82' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob Kingfb162bb2020-01-21 11:28:07 +08001674 }
1675 // Invalid: test i2c_compare_bytes with property register invalid hex digit.
1676 {
1677 json configFile = i2cCompareBytesFile;
1678 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["register"] =
1679 "0xG1";
1680 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001681 "'0xG1' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob Kingfb162bb2020-01-21 11:28:07 +08001682 }
1683 // Invalid: test i2c_compare_bytes with property values invalid hex digit.
1684 {
1685 json configFile = i2cCompareBytesFile;
1686 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["values"][0] =
1687 "0xG1";
1688 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001689 "'0xG1' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob Kingfb162bb2020-01-21 11:28:07 +08001690 }
1691 // Invalid: test i2c_compare_bytes with property masks invalid hex digit.
1692 {
1693 json configFile = i2cCompareBytesFile;
1694 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["masks"][0] =
1695 "0xG1";
1696 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001697 "'0xG1' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob Kingfb162bb2020-01-21 11:28:07 +08001698 }
1699}
Shawn McCarney846dde52021-08-14 12:47:44 -05001700
Bob Kingca93f1f2020-01-31 11:21:16 +08001701TEST(ValidateRegulatorsConfigTest, I2CInterface)
1702{
1703 // Valid: test i2c_interface.
1704 {
1705 json configFile = validConfigFile;
1706 EXPECT_JSON_VALID(configFile);
1707 }
1708 // Invalid: testi2c_interface with no bus.
1709 {
1710 json configFile = validConfigFile;
1711 configFile["chassis"][0]["devices"][0]["i2c_interface"].erase("bus");
1712 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001713 "'bus' is a required property");
Bob Kingca93f1f2020-01-31 11:21:16 +08001714 }
1715 // Invalid: test i2c_interface with no address.
1716 {
1717 json configFile = validConfigFile;
1718 configFile["chassis"][0]["devices"][0]["i2c_interface"].erase(
1719 "address");
1720 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001721 "'address' is a required property");
Bob Kingca93f1f2020-01-31 11:21:16 +08001722 }
1723 // Invalid: test i2c_interface with property bus wrong type.
1724 {
1725 json configFile = validConfigFile;
1726 configFile["chassis"][0]["devices"][0]["i2c_interface"]["bus"] = true;
1727 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001728 "True is not of type 'integer'");
Bob Kingca93f1f2020-01-31 11:21:16 +08001729 }
1730 // Invalid: test i2c_interface with property address wrong
1731 // type.
1732 {
1733 json configFile = validConfigFile;
1734 configFile["chassis"][0]["devices"][0]["i2c_interface"]["address"] =
1735 true;
1736 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001737 "True is not of type 'string'");
Bob Kingca93f1f2020-01-31 11:21:16 +08001738 }
1739 // Invalid: test i2c_interface with property bus less than
1740 // 0.
1741 {
1742 json configFile = validConfigFile;
1743 configFile["chassis"][0]["devices"][0]["i2c_interface"]["bus"] = -1;
1744 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1745 "-1 is less than the minimum of 0");
1746 }
1747 // Invalid: test i2c_interface with property address wrong
1748 // format.
1749 {
1750 json configFile = validConfigFile;
1751 configFile["chassis"][0]["devices"][0]["i2c_interface"]["address"] =
1752 "0x700";
1753 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001754 "'0x700' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob Kingca93f1f2020-01-31 11:21:16 +08001755 }
1756}
Shawn McCarney846dde52021-08-14 12:47:44 -05001757
Bob King188db7d2020-01-31 13:01:01 +08001758TEST(ValidateRegulatorsConfigTest, I2CWriteBit)
1759{
1760 json i2cWriteBitFile = validConfigFile;
1761 i2cWriteBitFile["rules"][0]["actions"][1]["i2c_write_bit"]["register"] =
1762 "0xA0";
1763 i2cWriteBitFile["rules"][0]["actions"][1]["i2c_write_bit"]["position"] = 3;
1764 i2cWriteBitFile["rules"][0]["actions"][1]["i2c_write_bit"]["value"] = 1;
1765 // Valid: test rule actions i2c_write_bit.
1766 {
1767 json configFile = i2cWriteBitFile;
1768 EXPECT_JSON_VALID(configFile);
1769 }
1770 // Invalid: test i2c_write_bit with no register.
1771 {
1772 json configFile = i2cWriteBitFile;
1773 configFile["rules"][0]["actions"][1]["i2c_write_bit"].erase("register");
1774 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001775 "'register' is a required property");
Bob King188db7d2020-01-31 13:01:01 +08001776 }
1777 // Invalid: test i2c_write_bit with no position.
1778 {
1779 json configFile = i2cWriteBitFile;
1780 configFile["rules"][0]["actions"][1]["i2c_write_bit"].erase("position");
1781 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001782 "'position' is a required property");
Bob King188db7d2020-01-31 13:01:01 +08001783 }
1784 // Invalid: test i2c_write_bit with no value.
1785 {
1786 json configFile = i2cWriteBitFile;
1787 configFile["rules"][0]["actions"][1]["i2c_write_bit"].erase("value");
1788 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001789 "'value' is a required property");
Bob King188db7d2020-01-31 13:01:01 +08001790 }
1791 // Invalid: test i2c_write_bit with register wrong type.
1792 {
1793 json configFile = i2cWriteBitFile;
1794 configFile["rules"][0]["actions"][1]["i2c_write_bit"]["register"] = 1;
1795 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001796 "1 is not of type 'string'");
Bob King188db7d2020-01-31 13:01:01 +08001797 }
1798 // Invalid: test i2c_write_bit with register wrong format.
1799 {
1800 json configFile = i2cWriteBitFile;
1801 configFile["rules"][0]["actions"][1]["i2c_write_bit"]["register"] =
1802 "0xA00";
1803 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001804 "'0xA00' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08001805 }
1806 // Invalid: test i2c_write_bit with position wrong type.
1807 {
1808 json configFile = i2cWriteBitFile;
1809 configFile["rules"][0]["actions"][1]["i2c_write_bit"]["position"] = 3.1;
1810 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001811 "3.1 is not of type 'integer'");
Bob King188db7d2020-01-31 13:01:01 +08001812 }
1813 // Invalid: test i2c_write_bit with position greater than 7.
1814 {
1815 json configFile = i2cWriteBitFile;
1816 configFile["rules"][0]["actions"][1]["i2c_write_bit"]["position"] = 8;
1817 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1818 "8 is greater than the maximum of 7");
1819 }
1820 // Invalid: test i2c_write_bit with position less than 0.
1821 {
1822 json configFile = i2cWriteBitFile;
1823 configFile["rules"][0]["actions"][1]["i2c_write_bit"]["position"] = -1;
1824 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1825 "-1 is less than the minimum of 0");
1826 }
1827 // Invalid: test i2c_write_bit with value wrong type.
1828 {
1829 json configFile = i2cWriteBitFile;
1830 configFile["rules"][0]["actions"][1]["i2c_write_bit"]["value"] = "1";
1831 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001832 "'1' is not of type 'integer'");
Bob King188db7d2020-01-31 13:01:01 +08001833 }
1834 // Invalid: test i2c_write_bit with value greater than 1.
1835 {
1836 json configFile = i2cWriteBitFile;
1837 configFile["rules"][0]["actions"][1]["i2c_write_bit"]["value"] = 2;
1838 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1839 "2 is greater than the maximum of 1");
1840 }
1841 // Invalid: test i2c_write_bit with value less than 0.
1842 {
1843 json configFile = i2cWriteBitFile;
1844 configFile["rules"][0]["actions"][1]["i2c_write_bit"]["value"] = -1;
1845 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1846 "-1 is less than the minimum of 0");
1847 }
1848}
Shawn McCarney846dde52021-08-14 12:47:44 -05001849
Bob King188db7d2020-01-31 13:01:01 +08001850TEST(ValidateRegulatorsConfigTest, I2CWriteByte)
1851{
1852 json i2cWriteByteFile = validConfigFile;
1853 i2cWriteByteFile["rules"][0]["actions"][1]["i2c_write_byte"]["register"] =
1854 "0x82";
1855 i2cWriteByteFile["rules"][0]["actions"][1]["i2c_write_byte"]["value"] =
1856 "0x40";
1857 i2cWriteByteFile["rules"][0]["actions"][1]["i2c_write_byte"]["mask"] =
1858 "0x7F";
1859 // Valid: test i2c_write_byte with all properties.
1860 {
1861 json configFile = i2cWriteByteFile;
1862 EXPECT_JSON_VALID(configFile);
1863 }
1864 // Valid: test i2c_write_byte with all required properties.
1865 {
1866 json configFile = i2cWriteByteFile;
1867 configFile["rules"][0]["actions"][1]["i2c_write_byte"].erase("mask");
1868 EXPECT_JSON_VALID(configFile);
1869 }
1870 // Invalid: test i2c_write_byte with no register.
1871 {
1872 json configFile = i2cWriteByteFile;
1873 configFile["rules"][0]["actions"][1]["i2c_write_byte"].erase(
1874 "register");
1875 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001876 "'register' is a required property");
Bob King188db7d2020-01-31 13:01:01 +08001877 }
1878 // Invalid: test i2c_write_byte with no value.
1879 {
1880 json configFile = i2cWriteByteFile;
1881 configFile["rules"][0]["actions"][1]["i2c_write_byte"].erase("value");
1882 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001883 "'value' is a required property");
Bob King188db7d2020-01-31 13:01:01 +08001884 }
1885 // Invalid: test i2c_write_byte with property register wrong type.
1886 {
1887 json configFile = i2cWriteByteFile;
1888 configFile["rules"][0]["actions"][1]["i2c_write_byte"]["register"] = 1;
1889 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001890 "1 is not of type 'string'");
Bob King188db7d2020-01-31 13:01:01 +08001891 }
1892 // Invalid: test i2c_write_byte with property value wrong type.
1893 {
1894 json configFile = i2cWriteByteFile;
1895 configFile["rules"][0]["actions"][1]["i2c_write_byte"]["value"] = 1;
1896 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001897 "1 is not of type 'string'");
Bob King188db7d2020-01-31 13:01:01 +08001898 }
1899 // Invalid: test i2c_write_byte with property mask wrong type.
1900 {
1901 json configFile = i2cWriteByteFile;
1902 configFile["rules"][0]["actions"][1]["i2c_write_byte"]["mask"] = 1;
1903 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001904 "1 is not of type 'string'");
Bob King188db7d2020-01-31 13:01:01 +08001905 }
1906 // Invalid: test i2c_write_byte with property register more than 2 hex
1907 // digits.
1908 {
1909 json configFile = i2cWriteByteFile;
1910 configFile["rules"][0]["actions"][1]["i2c_write_byte"]["register"] =
1911 "0x820";
1912 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001913 "'0x820' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08001914 }
1915 // Invalid: test i2c_write_byte with property value more than 2 hex
1916 // digits.
1917 {
1918 json configFile = i2cWriteByteFile;
1919 configFile["rules"][0]["actions"][1]["i2c_write_byte"]["value"] =
1920 "0x820";
1921 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001922 "'0x820' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08001923 }
1924 // Invalid: test i2c_write_byte with property mask more than 2 hex digits.
1925 {
1926 json configFile = i2cWriteByteFile;
1927 configFile["rules"][0]["actions"][1]["i2c_write_byte"]["mask"] =
1928 "0x820";
1929 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001930 "'0x820' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08001931 }
1932 // Invalid: test i2c_write_byte with property register less than 2 hex
1933 // digits.
1934 {
1935 json configFile = i2cWriteByteFile;
1936 configFile["rules"][0]["actions"][1]["i2c_write_byte"]["register"] =
1937 "0x8";
1938 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001939 "'0x8' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08001940 }
1941 // Invalid: test i2c_write_byte with property value less than 2 hex
1942 // digits.
1943 {
1944 json configFile = i2cWriteByteFile;
1945 configFile["rules"][0]["actions"][1]["i2c_write_byte"]["value"] = "0x8";
1946 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001947 "'0x8' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08001948 }
1949 // Invalid: test i2c_write_byte with property mask less than 2 hex digits.
1950 {
1951 json configFile = i2cWriteByteFile;
1952 configFile["rules"][0]["actions"][1]["i2c_write_byte"]["mask"] = "0x8";
1953 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001954 "'0x8' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08001955 }
1956 // Invalid: test i2c_write_byte with property register no leading prefix.
1957 {
1958 json configFile = i2cWriteByteFile;
1959 configFile["rules"][0]["actions"][1]["i2c_write_byte"]["register"] =
1960 "82";
1961 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001962 "'82' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08001963 }
1964 // Invalid: test i2c_write_byte with property value no leading prefix.
1965 {
1966 json configFile = i2cWriteByteFile;
1967 configFile["rules"][0]["actions"][1]["i2c_write_byte"]["value"] = "82";
1968 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001969 "'82' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08001970 }
1971 // Invalid: test i2c_write_byte with property mask no leading prefix.
1972 {
1973 json configFile = i2cWriteByteFile;
1974 configFile["rules"][0]["actions"][1]["i2c_write_byte"]["mask"] = "82";
1975 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001976 "'82' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08001977 }
1978 // Invalid: test i2c_write_byte with property register invalid hex digit.
1979 {
1980 json configFile = i2cWriteByteFile;
1981 configFile["rules"][0]["actions"][1]["i2c_write_byte"]["register"] =
1982 "0xG1";
1983 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001984 "'0xG1' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08001985 }
1986 // Invalid: test i2c_write_byte with property value invalid hex digit.
1987 {
1988 json configFile = i2cWriteByteFile;
1989 configFile["rules"][0]["actions"][1]["i2c_write_byte"]["value"] =
1990 "0xG1";
1991 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001992 "'0xG1' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08001993 }
1994 // Invalid: test i2c_write_byte with property mask invalid hex digit.
1995 {
1996 json configFile = i2cWriteByteFile;
1997 configFile["rules"][0]["actions"][1]["i2c_write_byte"]["mask"] = "0xG1";
1998 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001999 "'0xG1' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08002000 }
2001}
Shawn McCarney846dde52021-08-14 12:47:44 -05002002
Bob King188db7d2020-01-31 13:01:01 +08002003TEST(ValidateRegulatorsConfigTest, I2CWriteBytes)
2004{
2005 json i2cWriteBytesFile = validConfigFile;
2006 i2cWriteBytesFile["rules"][0]["actions"][1]["i2c_write_bytes"]["register"] =
2007 "0x82";
2008 i2cWriteBytesFile["rules"][0]["actions"][1]["i2c_write_bytes"]["values"] = {
2009 "0x02", "0x73"};
2010 i2cWriteBytesFile["rules"][0]["actions"][1]["i2c_write_bytes"]["masks"] = {
2011 "0x7F", "0x7F"};
2012 // Valid: test i2c_write_bytes.
2013 {
2014 json configFile = i2cWriteBytesFile;
2015 EXPECT_JSON_VALID(configFile);
2016 }
2017 // Valid: test i2c_write_bytes with all required properties.
2018 {
2019 json configFile = i2cWriteBytesFile;
2020 configFile["rules"][0]["actions"][1]["i2c_write_bytes"].erase("masks");
2021 EXPECT_JSON_VALID(configFile);
2022 }
2023 // Invalid: test i2c_write_bytes with no register.
2024 {
2025 json configFile = i2cWriteBytesFile;
2026 configFile["rules"][0]["actions"][1]["i2c_write_bytes"].erase(
2027 "register");
2028 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002029 "'register' is a required property");
Bob King188db7d2020-01-31 13:01:01 +08002030 }
2031 // Invalid: test i2c_write_bytes with no values.
2032 {
2033 json configFile = i2cWriteBytesFile;
2034 configFile["rules"][0]["actions"][1]["i2c_write_bytes"].erase("values");
2035 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002036 "'values' is a required property");
Bob King188db7d2020-01-31 13:01:01 +08002037 }
2038 // Invalid: test i2c_write_bytes with property values as empty array.
2039 {
2040 json configFile = i2cWriteBytesFile;
2041 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["values"] =
2042 json::array();
2043 EXPECT_JSON_INVALID(configFile, "Validation failed.",
2044 "[] is too short");
2045 }
2046 // Invalid: test i2c_write_bytes with property masks as empty array.
2047 {
2048 json configFile = i2cWriteBytesFile;
2049 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["masks"] =
2050 json::array();
2051 EXPECT_JSON_INVALID(configFile, "Validation failed.",
2052 "[] is too short");
2053 }
2054 // Invalid: test i2c_write_bytes with property register wrong type.
2055 {
2056 json configFile = i2cWriteBytesFile;
2057 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["register"] = 1;
2058 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002059 "1 is not of type 'string'");
Bob King188db7d2020-01-31 13:01:01 +08002060 }
2061 // Invalid: test i2c_write_bytes with property values wrong type.
2062 {
2063 json configFile = i2cWriteBytesFile;
2064 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["values"] = 1;
2065 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002066 "1 is not of type 'array'");
Bob King188db7d2020-01-31 13:01:01 +08002067 }
2068 // Invalid: test i2c_write_bytes with property masks wrong type.
2069 {
2070 json configFile = i2cWriteBytesFile;
2071 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["masks"] = 1;
2072 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002073 "1 is not of type 'array'");
Bob King188db7d2020-01-31 13:01:01 +08002074 }
2075 // Invalid: test i2c_write_bytes with property register more than 2 hex
2076 // digits.
2077 {
2078 json configFile = i2cWriteBytesFile;
2079 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["register"] =
2080 "0x820";
2081 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002082 "'0x820' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08002083 }
2084 // Invalid: test i2c_write_bytes with property values more than 2 hex
2085 // digits.
2086 {
2087 json configFile = i2cWriteBytesFile;
2088 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["values"][0] =
2089 "0x820";
2090 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002091 "'0x820' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08002092 }
2093 // Invalid: test i2c_write_bytes with property masks more than 2 hex
2094 // digits.
2095 {
2096 json configFile = i2cWriteBytesFile;
2097 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["masks"][0] =
2098 "0x820";
2099 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002100 "'0x820' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08002101 }
2102 // Invalid: test i2c_write_bytes with property register less than 2 hex
2103 // digits.
2104 {
2105 json configFile = i2cWriteBytesFile;
2106 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["register"] =
2107 "0x8";
2108 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002109 "'0x8' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08002110 }
2111 // Invalid: test i2c_write_bytes with property values less than 2 hex
2112 // digits.
2113 {
2114 json configFile = i2cWriteBytesFile;
2115 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["values"][0] =
2116 "0x8";
2117 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002118 "'0x8' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08002119 }
2120 // Invalid: test i2c_write_bytes with property masks less than 2 hex
2121 // digits.
2122 {
2123 json configFile = i2cWriteBytesFile;
2124 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["masks"][0] =
2125 "0x8";
2126 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002127 "'0x8' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08002128 }
2129 // Invalid: test i2c_write_bytes with property register no leading prefix.
2130 {
2131 json configFile = i2cWriteBytesFile;
2132 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["register"] =
2133 "82";
2134 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002135 "'82' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08002136 }
2137 // Invalid: test i2c_write_bytes with property values no leading prefix.
2138 {
2139 json configFile = i2cWriteBytesFile;
2140 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["values"][0] =
2141 "82";
2142 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002143 "'82' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08002144 }
2145 // Invalid: test i2c_write_bytes with property masks no leading prefix.
2146 {
2147 json configFile = i2cWriteBytesFile;
2148 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["masks"][0] =
2149 "82";
2150 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002151 "'82' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08002152 }
2153 // Invalid: test i2c_write_bytes with property register invalid hex digit.
2154 {
2155 json configFile = i2cWriteBytesFile;
2156 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["register"] =
2157 "0xG1";
2158 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002159 "'0xG1' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08002160 }
2161 // Invalid: test i2c_write_bytes with property values invalid hex digit.
2162 {
2163 json configFile = i2cWriteBytesFile;
2164 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["values"][0] =
2165 "0xG1";
2166 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002167 "'0xG1' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08002168 }
2169 // Invalid: test i2c_write_bytes with property masks invalid hex digit.
2170 {
2171 json configFile = i2cWriteBytesFile;
2172 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["masks"][0] =
2173 "0xG1";
2174 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002175 "'0xG1' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08002176 }
2177}
Shawn McCarney846dde52021-08-14 12:47:44 -05002178
Bob Kingead0b052020-01-21 11:29:03 +08002179TEST(ValidateRegulatorsConfigTest, If)
2180{
2181 json ifFile = validConfigFile;
Shawn McCarney846dde52021-08-14 12:47:44 -05002182 ifFile["rules"][4]["actions"][0]["if"]["condition"]["run_rule"] =
Bob King2d27dcf2020-02-11 15:00:50 +08002183 "set_voltage_rule";
Shawn McCarney846dde52021-08-14 12:47:44 -05002184 ifFile["rules"][4]["actions"][0]["if"]["then"][0]["run_rule"] =
Bob King2d27dcf2020-02-11 15:00:50 +08002185 "read_sensors_rule";
Shawn McCarney846dde52021-08-14 12:47:44 -05002186 ifFile["rules"][4]["actions"][0]["if"]["else"][0]["run_rule"] =
Bob King2d27dcf2020-02-11 15:00:50 +08002187 "read_sensors_rule";
Shawn McCarney846dde52021-08-14 12:47:44 -05002188 ifFile["rules"][4]["id"] = "rule_if";
Bob Kingead0b052020-01-21 11:29:03 +08002189 // Valid: test if.
2190 {
2191 json configFile = ifFile;
2192 EXPECT_JSON_VALID(configFile);
2193 }
2194 // Valid: test if with required properties.
2195 {
2196 json configFile = ifFile;
Shawn McCarney846dde52021-08-14 12:47:44 -05002197 configFile["rules"][4]["actions"][0]["if"].erase("else");
Bob Kingead0b052020-01-21 11:29:03 +08002198 EXPECT_JSON_VALID(configFile);
2199 }
2200 // Invalid: test if with no property condition.
2201 {
2202 json configFile = ifFile;
Shawn McCarney846dde52021-08-14 12:47:44 -05002203 configFile["rules"][4]["actions"][0]["if"].erase("condition");
Bob Kingead0b052020-01-21 11:29:03 +08002204 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002205 "'condition' is a required property");
Bob Kingead0b052020-01-21 11:29:03 +08002206 }
2207 // Invalid: test if with no property then.
2208 {
2209 json configFile = ifFile;
Shawn McCarney846dde52021-08-14 12:47:44 -05002210 configFile["rules"][4]["actions"][0]["if"].erase("then");
Bob Kingead0b052020-01-21 11:29:03 +08002211 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002212 "'then' is a required property");
Bob Kingead0b052020-01-21 11:29:03 +08002213 }
2214 // Invalid: test if with property then empty array.
2215 {
2216 json configFile = ifFile;
Shawn McCarney846dde52021-08-14 12:47:44 -05002217 configFile["rules"][4]["actions"][0]["if"]["then"] = json::array();
Bob Kingead0b052020-01-21 11:29:03 +08002218 EXPECT_JSON_INVALID(configFile, "Validation failed.",
2219 "[] is too short");
2220 }
2221 // Invalid: test if with property else empty array.
2222 {
2223 json configFile = ifFile;
Shawn McCarney846dde52021-08-14 12:47:44 -05002224 configFile["rules"][4]["actions"][0]["if"]["else"] = json::array();
Bob Kingead0b052020-01-21 11:29:03 +08002225 EXPECT_JSON_INVALID(configFile, "Validation failed.",
2226 "[] is too short");
2227 }
2228 // Invalid: test if with property condition wrong type.
2229 {
2230 json configFile = ifFile;
Shawn McCarney846dde52021-08-14 12:47:44 -05002231 configFile["rules"][4]["actions"][0]["if"]["condition"] = 1;
Bob Kingead0b052020-01-21 11:29:03 +08002232 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002233 "1 is not of type 'object'");
Bob Kingead0b052020-01-21 11:29:03 +08002234 }
2235 // Invalid: test if with property then wrong type.
2236 {
2237 json configFile = ifFile;
Shawn McCarney846dde52021-08-14 12:47:44 -05002238 configFile["rules"][4]["actions"][0]["if"]["then"] = 1;
Bob Kingead0b052020-01-21 11:29:03 +08002239 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002240 "1 is not of type 'array'");
Bob Kingead0b052020-01-21 11:29:03 +08002241 }
2242 // Invalid: test if with property else wrong type.
2243 {
2244 json configFile = ifFile;
Shawn McCarney846dde52021-08-14 12:47:44 -05002245 configFile["rules"][4]["actions"][0]["if"]["else"] = 1;
Bob Kingead0b052020-01-21 11:29:03 +08002246 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002247 "1 is not of type 'array'");
Bob Kingead0b052020-01-21 11:29:03 +08002248 }
2249}
Shawn McCarney846dde52021-08-14 12:47:44 -05002250
2251TEST(ValidateRegulatorsConfigTest, LogPhaseFault)
2252{
2253 json initialFile = validConfigFile;
2254 initialFile["rules"][0]["actions"][1]["log_phase_fault"]["type"] = "n";
2255
2256 // Valid: All required properties
2257 {
2258 json configFile = initialFile;
2259 EXPECT_JSON_VALID(configFile);
2260 }
2261
2262 // Invalid: type not specified
2263 {
2264 json configFile = initialFile;
2265 configFile["rules"][0]["actions"][1]["log_phase_fault"].erase("type");
2266 EXPECT_JSON_INVALID(configFile, "Validation failed.",
2267 "'type' is a required property");
2268 }
2269
2270 // Invalid: invalid property specified
2271 {
2272 json configFile = initialFile;
2273 configFile["rules"][0]["actions"][1]["log_phase_fault"]["foo"] = true;
2274 EXPECT_JSON_INVALID(
2275 configFile, "Validation failed.",
2276 "Additional properties are not allowed ('foo' was unexpected)");
2277 }
2278
2279 // Invalid: type has wrong data type
2280 {
2281 json configFile = initialFile;
2282 configFile["rules"][0]["actions"][1]["log_phase_fault"]["type"] = true;
2283 EXPECT_JSON_INVALID(configFile, "Validation failed.",
2284 "True is not of type 'string'");
2285 }
2286
2287 // Invalid: type has invalid value
2288 {
2289 json configFile = initialFile;
2290 configFile["rules"][0]["actions"][1]["log_phase_fault"]["type"] = "n+2";
2291 EXPECT_JSON_INVALID(configFile, "Validation failed.",
2292 "'n+2' is not one of ['n+1', 'n']");
2293 }
2294}
2295
Bob Kingbfe9fe72020-01-21 11:29:57 +08002296TEST(ValidateRegulatorsConfigTest, Not)
2297{
2298 json notFile = validConfigFile;
2299 notFile["rules"][0]["actions"][1]["not"]["i2c_compare_byte"]["register"] =
2300 "0xA0";
2301 notFile["rules"][0]["actions"][1]["not"]["i2c_compare_byte"]["value"] =
2302 "0xFF";
2303 // Valid: test not.
2304 {
2305 json configFile = notFile;
2306 EXPECT_JSON_VALID(configFile);
2307 }
2308 // Invalid: test not with wrong type.
2309 {
2310 json configFile = notFile;
2311 configFile["rules"][0]["actions"][1]["not"] = 1;
2312 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002313 "1 is not of type 'object'");
Bob Kingbfe9fe72020-01-21 11:29:57 +08002314 }
2315}
Shawn McCarney846dde52021-08-14 12:47:44 -05002316
Bob Kingcfc29d02020-01-21 11:30:50 +08002317TEST(ValidateRegulatorsConfigTest, Or)
2318{
2319 json orFile = validConfigFile;
2320 orFile["rules"][0]["actions"][1]["or"][0]["i2c_compare_byte"]["register"] =
2321 "0xA0";
2322 orFile["rules"][0]["actions"][1]["or"][0]["i2c_compare_byte"]["value"] =
2323 "0x00";
2324 orFile["rules"][0]["actions"][1]["or"][1]["i2c_compare_byte"]["register"] =
2325 "0xA1";
2326 orFile["rules"][0]["actions"][1]["or"][1]["i2c_compare_byte"]["value"] =
2327 "0x00";
2328 // Valid: test or.
2329 {
2330 json configFile = orFile;
2331 EXPECT_JSON_VALID(configFile);
2332 }
2333 // Invalid: test or with empty array.
2334 {
2335 json configFile = orFile;
2336 configFile["rules"][0]["actions"][1]["or"] = json::array();
2337 EXPECT_JSON_INVALID(configFile, "Validation failed.",
2338 "[] is too short");
2339 }
2340 // Invalid: test or with wrong type.
2341 {
2342 json configFile = orFile;
2343 configFile["rules"][0]["actions"][1]["or"] = 1;
2344 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002345 "1 is not of type 'array'");
Bob Kingcfc29d02020-01-21 11:30:50 +08002346 }
2347}
Shawn McCarney846dde52021-08-14 12:47:44 -05002348
2349TEST(ValidateRegulatorsConfigTest, PhaseFaultDetection)
2350{
2351 json initialFile = validConfigFile;
2352 initialFile["chassis"][0]["devices"][0]["phase_fault_detection"]
2353 ["rule_id"] = "detect_phase_faults_rule";
2354
2355 // Valid: comments specified
2356 {
2357 json configFile = initialFile;
2358 configFile["chassis"][0]["devices"][0]["phase_fault_detection"]
2359 ["comments"][0] = "Detect phase faults";
2360 EXPECT_JSON_VALID(configFile);
2361 }
2362
2363 // Valid: device_id specified
2364 {
2365 json configFile = initialFile;
2366 configFile["chassis"][0]["devices"][0]["phase_fault_detection"]
2367 ["device_id"] = "vdd_regulator";
2368 EXPECT_JSON_VALID(configFile);
2369 }
2370
2371 // Valid: rule_id specified
2372 {
2373 json configFile = initialFile;
2374 EXPECT_JSON_VALID(configFile);
2375 }
2376
2377 // Valid: actions specified
2378 {
2379 json configFile = initialFile;
2380 configFile["chassis"][0]["devices"][0]["phase_fault_detection"].erase(
2381 "rule_id");
2382 configFile["chassis"][0]["devices"][0]["phase_fault_detection"]
2383 ["actions"][0]["run_rule"] = "detect_phase_faults_rule";
2384 EXPECT_JSON_VALID(configFile);
2385 }
2386
2387 // Invalid: rule_id and actions specified
2388 {
2389 json configFile = initialFile;
2390 configFile["chassis"][0]["devices"][0]["phase_fault_detection"]
2391 ["actions"][0]["run_rule"] = "detect_phase_faults_rule";
2392 EXPECT_JSON_INVALID(configFile, "Validation failed.", "");
2393 }
2394
2395 // Invalid: neither rule_id nor actions specified
2396 {
2397 json configFile = initialFile;
2398 configFile["chassis"][0]["devices"][0]["phase_fault_detection"].erase(
2399 "rule_id");
2400 EXPECT_JSON_INVALID(configFile, "Validation failed.",
2401 "'rule_id' is a required property");
2402 }
2403
2404 // Invalid: comments has wrong data type
2405 {
2406 json configFile = initialFile;
2407 configFile["chassis"][0]["devices"][0]["phase_fault_detection"]
2408 ["comments"] = true;
2409 EXPECT_JSON_INVALID(configFile, "Validation failed.",
2410 "True is not of type 'array'");
2411 }
2412
2413 // Invalid: device_id has wrong data type
2414 {
2415 json configFile = initialFile;
2416 configFile["chassis"][0]["devices"][0]["phase_fault_detection"]
2417 ["device_id"] = true;
2418 EXPECT_JSON_INVALID(configFile, "Validation failed.",
2419 "True is not of type 'string'");
2420 }
2421
2422 // Invalid: rule_id has wrong data type
2423 {
2424 json configFile = initialFile;
2425 configFile["chassis"][0]["devices"][0]["phase_fault_detection"]
2426 ["rule_id"] = true;
2427 EXPECT_JSON_INVALID(configFile, "Validation failed.",
2428 "True is not of type 'string'");
2429 }
2430
2431 // Invalid: actions has wrong data type
2432 {
2433 json configFile = initialFile;
2434 configFile["chassis"][0]["devices"][0]["phase_fault_detection"].erase(
2435 "rule_id");
2436 configFile["chassis"][0]["devices"][0]["phase_fault_detection"]
2437 ["actions"] = true;
2438 EXPECT_JSON_INVALID(configFile, "Validation failed.",
2439 "True is not of type 'array'");
2440 }
2441
2442 // Invalid: device_id has invalid format
2443 {
2444 json configFile = initialFile;
2445 configFile["chassis"][0]["devices"][0]["phase_fault_detection"]
2446 ["device_id"] = "id@";
2447 EXPECT_JSON_INVALID(configFile, "Validation failed.",
2448 "'id@' does not match '^[A-Za-z0-9_]+$'");
2449 }
2450
2451 // Invalid: rule_id has invalid format
2452 {
2453 json configFile = initialFile;
2454 configFile["chassis"][0]["devices"][0]["phase_fault_detection"]
2455 ["rule_id"] = "id@";
2456 EXPECT_JSON_INVALID(configFile, "Validation failed.",
2457 "'id@' does not match '^[A-Za-z0-9_]+$'");
2458 }
2459
2460 // Invalid: comments array is empty
2461 {
2462 json configFile = initialFile;
2463 configFile["chassis"][0]["devices"][0]["phase_fault_detection"]
2464 ["comments"] = json::array();
2465 EXPECT_JSON_INVALID(configFile, "Validation failed.",
2466 "[] is too short");
2467 }
2468
2469 // Invalid: actions array is empty
2470 {
2471 json configFile = initialFile;
2472 configFile["chassis"][0]["devices"][0]["phase_fault_detection"].erase(
2473 "rule_id");
2474 configFile["chassis"][0]["devices"][0]["phase_fault_detection"]
2475 ["actions"] = json::array();
2476 EXPECT_JSON_INVALID(configFile, "Validation failed.",
2477 "[] is too short");
2478 }
2479}
2480
Bob Kingd6618092020-01-21 11:31:46 +08002481TEST(ValidateRegulatorsConfigTest, PmbusReadSensor)
2482{
2483 json pmbusReadSensorFile = validConfigFile;
2484 pmbusReadSensorFile["rules"][0]["actions"][1]["pmbus_read_sensor"]["type"] =
2485 "vout";
2486 pmbusReadSensorFile["rules"][0]["actions"][1]["pmbus_read_sensor"]
2487 ["command"] = "0x8B";
2488 pmbusReadSensorFile["rules"][0]["actions"][1]["pmbus_read_sensor"]
2489 ["format"] = "linear_16";
2490 pmbusReadSensorFile["rules"][0]["actions"][1]["pmbus_read_sensor"]
2491 ["exponent"] = -8;
2492 // Valid: test pmbus_read_sensor.
2493 {
2494 json configFile = pmbusReadSensorFile;
2495 EXPECT_JSON_VALID(configFile);
2496 }
2497 // Valid: test pmbus_read_sensor with required properties.
2498 {
2499 json configFile = pmbusReadSensorFile;
2500 configFile["rules"][0]["actions"][1]["pmbus_read_sensor"].erase(
2501 "exponent");
2502 EXPECT_JSON_VALID(configFile);
2503 }
2504 // Invalid: test pmbus_read_sensor with no type.
2505 {
2506 json configFile = pmbusReadSensorFile;
2507 configFile["rules"][0]["actions"][1]["pmbus_read_sensor"].erase("type");
2508 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002509 "'type' is a required property");
Bob Kingd6618092020-01-21 11:31:46 +08002510 }
2511 // Invalid: test pmbus_read_sensor with no command.
2512 {
2513 json configFile = pmbusReadSensorFile;
2514 configFile["rules"][0]["actions"][1]["pmbus_read_sensor"].erase(
2515 "command");
2516 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002517 "'command' is a required property");
Bob Kingd6618092020-01-21 11:31:46 +08002518 }
2519 // Invalid: test pmbus_read_sensor with no format.
2520 {
2521 json configFile = pmbusReadSensorFile;
2522 configFile["rules"][0]["actions"][1]["pmbus_read_sensor"].erase(
2523 "format");
2524 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002525 "'format' is a required property");
Bob Kingd6618092020-01-21 11:31:46 +08002526 }
2527 // Invalid: test pmbus_read_sensor with property type wrong type.
2528 {
2529 json configFile = pmbusReadSensorFile;
2530 configFile["rules"][0]["actions"][1]["pmbus_read_sensor"]["type"] =
2531 true;
Bob King358c4172020-03-16 13:57:08 +08002532 EXPECT_JSON_INVALID(configFile, "Validation failed.",
2533 "True is not of type 'string'");
Bob Kingd6618092020-01-21 11:31:46 +08002534 }
2535 // Invalid: test pmbus_read_sensor with property command wrong type.
2536 {
2537 json configFile = pmbusReadSensorFile;
2538 configFile["rules"][0]["actions"][1]["pmbus_read_sensor"]["command"] =
2539 true;
2540 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002541 "True is not of type 'string'");
Bob Kingd6618092020-01-21 11:31:46 +08002542 }
2543 // Invalid: test pmbus_read_sensor with property format wrong type.
2544 {
2545 json configFile = pmbusReadSensorFile;
2546 configFile["rules"][0]["actions"][1]["pmbus_read_sensor"]["format"] =
2547 true;
2548 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002549 "True is not of type 'string'");
Bob Kingd6618092020-01-21 11:31:46 +08002550 }
2551 // Invalid: test pmbus_read_sensor with property exponent wrong type.
2552 {
2553 json configFile = pmbusReadSensorFile;
2554 configFile["rules"][0]["actions"][1]["pmbus_read_sensor"]["exponent"] =
2555 true;
2556 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002557 "True is not of type 'integer'");
Bob Kingd6618092020-01-21 11:31:46 +08002558 }
2559 // Invalid: test pmbus_read_sensor with property type wrong format.
2560 {
2561 json configFile = pmbusReadSensorFile;
2562 configFile["rules"][0]["actions"][1]["pmbus_read_sensor"]["type"] =
2563 "foo";
2564 EXPECT_JSON_INVALID(
2565 configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002566 "'foo' is not one of ['iout', 'iout_peak', 'iout_valley', "
2567 "'pout', 'temperature', 'temperature_peak', 'vout', "
2568 "'vout_peak', 'vout_valley']");
Bob Kingd6618092020-01-21 11:31:46 +08002569 }
2570 // Invalid: test pmbus_read_sensor with property command wrong format.
2571 {
2572 json configFile = pmbusReadSensorFile;
2573 configFile["rules"][0]["actions"][1]["pmbus_read_sensor"]["command"] =
2574 "0x8B0";
2575 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002576 "'0x8B0' does not match '^0x[0-9a-fA-F]{2}$'");
Bob Kingd6618092020-01-21 11:31:46 +08002577 }
2578 // Invalid: test pmbus_read_sensor with property format wrong format.
2579 {
2580 json configFile = pmbusReadSensorFile;
2581 configFile["rules"][0]["actions"][1]["pmbus_read_sensor"]["format"] =
2582 "foo";
Bob King358c4172020-03-16 13:57:08 +08002583 EXPECT_JSON_INVALID(configFile, "Validation failed.",
2584 "'foo' is not one of ['linear_11', 'linear_16']");
Bob Kingd6618092020-01-21 11:31:46 +08002585 }
2586}
Shawn McCarney846dde52021-08-14 12:47:44 -05002587
Bob King02179c62020-01-21 11:32:36 +08002588TEST(ValidateRegulatorsConfigTest, PmbusWriteVoutCommand)
2589{
2590 json pmbusWriteVoutCommandFile = validConfigFile;
2591 pmbusWriteVoutCommandFile["rules"][0]["actions"][1]
2592 ["pmbus_write_vout_command"]["volts"] = 1.03;
2593 pmbusWriteVoutCommandFile["rules"][0]["actions"][1]
2594 ["pmbus_write_vout_command"]["format"] = "linear";
2595 pmbusWriteVoutCommandFile["rules"][0]["actions"][1]
2596 ["pmbus_write_vout_command"]["exponent"] = -8;
2597 pmbusWriteVoutCommandFile["rules"][0]["actions"][1]
2598 ["pmbus_write_vout_command"]["is_verified"] = true;
2599 // Valid: test pmbus_write_vout_command.
2600 {
2601 json configFile = pmbusWriteVoutCommandFile;
2602 EXPECT_JSON_VALID(configFile);
2603 }
2604 // Valid: test pmbus_write_vout_command with required properties.
2605 {
2606 json configFile = pmbusWriteVoutCommandFile;
2607 configFile["rules"][0]["actions"][1]["pmbus_write_vout_command"].erase(
2608 "volts");
2609 configFile["rules"][0]["actions"][1]["pmbus_write_vout_command"].erase(
2610 "exponent");
2611 configFile["rules"][0]["actions"][1]["pmbus_write_vout_command"].erase(
2612 "is_verified");
2613 EXPECT_JSON_VALID(configFile);
2614 }
2615 // Invalid: test pmbus_write_vout_command with no format.
2616 {
2617 json configFile = pmbusWriteVoutCommandFile;
2618 configFile["rules"][0]["actions"][1]["pmbus_write_vout_command"].erase(
2619 "format");
2620 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002621 "'format' is a required property");
Bob King02179c62020-01-21 11:32:36 +08002622 }
2623 // Invalid: test pmbus_write_vout_command with property volts wrong type.
2624 {
2625 json configFile = pmbusWriteVoutCommandFile;
2626 configFile["rules"][0]["actions"][1]["pmbus_write_vout_command"]
2627 ["volts"] = true;
2628 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002629 "True is not of type 'number'");
Bob King02179c62020-01-21 11:32:36 +08002630 }
2631 // Invalid: test pmbus_write_vout_command with property format wrong type.
2632 {
2633 json configFile = pmbusWriteVoutCommandFile;
2634 configFile["rules"][0]["actions"][1]["pmbus_write_vout_command"]
2635 ["format"] = true;
2636 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002637 "True is not of type 'string'");
Bob King02179c62020-01-21 11:32:36 +08002638 }
2639 // Invalid: test pmbus_write_vout_command with property exponent wrong type.
2640 {
2641 json configFile = pmbusWriteVoutCommandFile;
2642 configFile["rules"][0]["actions"][1]["pmbus_write_vout_command"]
2643 ["exponent"] = 1.3;
2644 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002645 "1.3 is not of type 'integer'");
Bob King02179c62020-01-21 11:32:36 +08002646 }
2647 // Invalid: test pmbus_write_vout_command with property is_verified wrong
2648 // type.
2649 {
2650 json configFile = pmbusWriteVoutCommandFile;
2651 configFile["rules"][0]["actions"][1]["pmbus_write_vout_command"]
2652 ["is_verified"] = 1;
2653 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002654 "1 is not of type 'boolean'");
Bob King02179c62020-01-21 11:32:36 +08002655 }
2656 // Invalid: test pmbus_write_vout_command with property format wrong format.
2657 {
2658 json configFile = pmbusWriteVoutCommandFile;
2659 configFile["rules"][0]["actions"][1]["pmbus_write_vout_command"]
2660 ["format"] = "foo";
2661 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002662 "'foo' is not one of ['linear']");
Bob King02179c62020-01-21 11:32:36 +08002663 }
2664}
Shawn McCarney846dde52021-08-14 12:47:44 -05002665
Bob King99d8fa12020-01-31 11:23:40 +08002666TEST(ValidateRegulatorsConfigTest, PresenceDetection)
2667{
2668 json presenceDetectionFile = validConfigFile;
Bob King99d8fa12020-01-31 11:23:40 +08002669 presenceDetectionFile["chassis"][0]["devices"][0]["presence_detection"]
Shawn McCarney846dde52021-08-14 12:47:44 -05002670 ["comments"][0] =
2671 "Regulator is only present if CPU3 is present";
2672 presenceDetectionFile["chassis"][0]["devices"][0]["presence_detection"]
2673 ["rule_id"] = "detect_presence_rule";
Bob King99d8fa12020-01-31 11:23:40 +08002674 // Valid: test presence_detection with only property rule_id.
2675 {
2676 json configFile = presenceDetectionFile;
2677 EXPECT_JSON_VALID(configFile);
2678 }
2679 // Valid: test presence_detection with only property actions.
2680 {
2681 json configFile = presenceDetectionFile;
2682 configFile["chassis"][0]["devices"][0]["presence_detection"].erase(
2683 "rule_id");
2684 configFile["chassis"][0]["devices"][0]["presence_detection"]["actions"]
2685 [0]["compare_presence"]["fru"] =
Bob Kinga76898f2020-10-13 15:08:33 +08002686 "system/chassis/motherboard/cpu3";
Bob King99d8fa12020-01-31 11:23:40 +08002687 configFile["chassis"][0]["devices"][0]["presence_detection"]["actions"]
2688 [0]["compare_presence"]["value"] = true;
2689 configFile["chassis"][0]["devices"][0]["presence_detection"].erase(
2690 "comments");
2691 EXPECT_JSON_VALID(configFile);
2692 }
2693 // Invalid: test presence_detection with both property rule_id and actions.
2694 {
2695 json configFile = presenceDetectionFile;
2696 configFile["chassis"][0]["devices"][0]["presence_detection"]["actions"]
2697 [0]["compare_presence"]["fru"] =
Bob Kinga76898f2020-10-13 15:08:33 +08002698 "system/chassis/motherboard/cpu3";
Bob King99d8fa12020-01-31 11:23:40 +08002699 configFile["chassis"][0]["devices"][0]["presence_detection"]["actions"]
2700 [0]["compare_presence"]["value"] = true;
Shawn McCarney846dde52021-08-14 12:47:44 -05002701 EXPECT_JSON_INVALID(configFile, "Validation failed.", "");
Bob King99d8fa12020-01-31 11:23:40 +08002702 }
2703 // Invalid: test presence_detection with no rule_id and actions.
2704 {
2705 json configFile = presenceDetectionFile;
2706 configFile["chassis"][0]["devices"][0]["presence_detection"].erase(
2707 "rule_id");
2708 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002709 "'rule_id' is a required property");
Bob King99d8fa12020-01-31 11:23:40 +08002710 }
2711 // Invalid: test presence_detection with property comments wrong type.
2712 {
2713 json configFile = presenceDetectionFile;
2714 configFile["chassis"][0]["devices"][0]["presence_detection"]
2715 ["comments"] = true;
2716 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002717 "True is not of type 'array'");
Bob King99d8fa12020-01-31 11:23:40 +08002718 }
2719 // Invalid: test presence_detection with property rule_id wrong type.
2720 {
2721 json configFile = presenceDetectionFile;
2722 configFile["chassis"][0]["devices"][0]["presence_detection"]
2723 ["rule_id"] = true;
2724 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002725 "True is not of type 'string'");
Bob King99d8fa12020-01-31 11:23:40 +08002726 }
2727 // Invalid: test presence_detection with property actions wrong type.
2728 {
2729 json configFile = presenceDetectionFile;
2730 configFile["chassis"][0]["devices"][0]["presence_detection"].erase(
2731 "rule_id");
2732 configFile["chassis"][0]["devices"][0]["presence_detection"]
2733 ["actions"] = true;
2734 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002735 "True is not of type 'array'");
Bob King99d8fa12020-01-31 11:23:40 +08002736 }
2737 // Invalid: test presence_detection with property rule_id wrong format.
2738 {
2739 json configFile = presenceDetectionFile;
2740 configFile["chassis"][0]["devices"][0]["presence_detection"]
2741 ["rule_id"] = "id@";
2742 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002743 "'id@' does not match '^[A-Za-z0-9_]+$'");
Bob King99d8fa12020-01-31 11:23:40 +08002744 }
2745 // Invalid: test presence_detection with property comments empty array.
2746 {
2747 json configFile = presenceDetectionFile;
2748 configFile["chassis"][0]["devices"][0]["presence_detection"]
2749 ["comments"] = json::array();
2750 EXPECT_JSON_INVALID(configFile, "Validation failed.",
2751 "[] is too short");
2752 }
2753 // Invalid: test presence_detection with property actions empty array.
2754 {
2755 json configFile = presenceDetectionFile;
2756 configFile["chassis"][0]["devices"][0]["presence_detection"].erase(
2757 "rule_id");
2758 configFile["chassis"][0]["devices"][0]["presence_detection"]
2759 ["actions"] = json::array();
2760 EXPECT_JSON_INVALID(configFile, "Validation failed.",
2761 "[] is too short");
2762 }
2763}
Shawn McCarney846dde52021-08-14 12:47:44 -05002764
Bob Kinge9260b52020-01-21 11:46:13 +08002765TEST(ValidateRegulatorsConfigTest, Rail)
2766{
2767 // Valid: test rail.
2768 {
2769 json configFile = validConfigFile;
2770 EXPECT_JSON_VALID(configFile);
2771 }
2772 // Valid: test rail with required properties.
2773 {
2774 json configFile = validConfigFile;
2775 configFile["chassis"][0]["devices"][0]["rails"][0].erase("comments");
2776 configFile["chassis"][0]["devices"][0]["rails"][0].erase(
2777 "configuration");
2778 configFile["chassis"][0]["devices"][0]["rails"][0].erase(
2779 "sensor_monitoring");
2780 EXPECT_JSON_VALID(configFile);
2781 }
2782 // Invalid: test rail with no id.
2783 {
2784 json configFile = validConfigFile;
2785 configFile["chassis"][0]["devices"][0]["rails"][0].erase("id");
2786 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002787 "'id' is a required property");
Bob Kinge9260b52020-01-21 11:46:13 +08002788 }
2789 // Invalid: test rail with comments wrong type.
2790 {
2791 json configFile = validConfigFile;
2792 configFile["chassis"][0]["devices"][0]["rails"][0]["comments"] = true;
2793 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002794 "True is not of type 'array'");
Bob Kinge9260b52020-01-21 11:46:13 +08002795 }
2796 // Invalid: test rail with id wrong type.
2797 {
2798 json configFile = validConfigFile;
2799 configFile["chassis"][0]["devices"][0]["rails"][0]["id"] = true;
2800 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002801 "True is not of type 'string'");
Bob Kinge9260b52020-01-21 11:46:13 +08002802 }
2803 // Invalid: test rail with configuration wrong type.
2804 {
2805 json configFile = validConfigFile;
2806 configFile["chassis"][0]["devices"][0]["rails"][0]["configuration"] =
2807 true;
2808 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002809 "True is not of type 'object'");
Bob Kinge9260b52020-01-21 11:46:13 +08002810 }
2811 // Invalid: test rail with sensor_monitoring wrong type.
2812 {
2813 json configFile = validConfigFile;
2814 configFile["chassis"][0]["devices"][0]["rails"][0]
2815 ["sensor_monitoring"] = true;
2816 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002817 "True is not of type 'object'");
Bob Kinge9260b52020-01-21 11:46:13 +08002818 }
2819 // Invalid: test rail with comments empty array.
2820 {
2821 json configFile = validConfigFile;
2822 configFile["chassis"][0]["devices"][0]["rails"][0]["comments"] =
2823 json::array();
2824 EXPECT_JSON_INVALID(configFile, "Validation failed.",
2825 "[] is too short");
2826 }
2827 // Invalid: test rail with id wrong format.
2828 {
2829 json configFile = validConfigFile;
2830 configFile["chassis"][0]["devices"][0]["rails"][0]["id"] = "id~";
2831 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002832 "'id~' does not match '^[A-Za-z0-9_]+$'");
Bob Kinge9260b52020-01-21 11:46:13 +08002833 }
2834}
Shawn McCarney846dde52021-08-14 12:47:44 -05002835
Bob King64df7da2020-01-31 12:04:12 +08002836TEST(ValidateRegulatorsConfigTest, Rule)
2837{
2838 // valid test comments property, id property,
2839 // action property specified.
2840 {
2841 json configFile = validConfigFile;
2842 EXPECT_JSON_VALID(configFile);
2843 }
2844
2845 // valid test rule with no comments
2846 {
2847 json configFile = validConfigFile;
2848 configFile["rules"][0].erase("comments");
2849 EXPECT_JSON_VALID(configFile);
2850 }
2851
2852 // invalid test comments property has invalid value type
2853 {
2854 json configFile = validConfigFile;
2855 configFile["rules"][0]["comments"] = {1};
2856 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002857 "1 is not of type 'string'");
Bob King64df7da2020-01-31 12:04:12 +08002858 }
2859
2860 // invalid test rule with no ID
2861 {
2862 json configFile = validConfigFile;
2863 configFile["rules"][0].erase("id");
2864 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002865 "'id' is a required property");
Bob King64df7da2020-01-31 12:04:12 +08002866 }
2867
2868 // invalid test id property has invalid value type (not string)
2869 {
2870 json configFile = validConfigFile;
2871 configFile["rules"][0]["id"] = true;
2872 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002873 "True is not of type 'string'");
Bob King64df7da2020-01-31 12:04:12 +08002874 }
2875
2876 // invalid test id property has invalid value
2877 {
2878 json configFile = validConfigFile;
2879 configFile["rules"][0]["id"] = "foo%";
2880 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002881 "'foo%' does not match '^[A-Za-z0-9_]+$'");
Bob King64df7da2020-01-31 12:04:12 +08002882 }
2883
2884 // invalid test rule with no actions property
2885 {
2886 json configFile = validConfigFile;
2887 configFile["rules"][0].erase("actions");
2888 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002889 "'actions' is a required property");
Bob King64df7da2020-01-31 12:04:12 +08002890 }
2891
2892 // valid test rule with multiple actions
2893 {
2894 json configFile = validConfigFile;
Bob King63d795f2020-02-11 15:22:09 +08002895 configFile["rules"][0]["actions"][1]["run_rule"] = "read_sensors_rule";
Bob King64df7da2020-01-31 12:04:12 +08002896 EXPECT_JSON_VALID(configFile);
2897 }
2898
2899 // invalid test actions property has invalid value type (not an array)
2900 {
2901 json configFile = validConfigFile;
2902 configFile["rules"][0]["actions"] = 1;
2903 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002904 "1 is not of type 'array'");
Bob King64df7da2020-01-31 12:04:12 +08002905 }
2906
2907 // invalid test actions property has invalid value of action
2908 {
2909 json configFile = validConfigFile;
2910 configFile["rules"][0]["actions"][0] = "foo";
2911 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002912 "'foo' is not of type 'object'");
Bob King64df7da2020-01-31 12:04:12 +08002913 }
2914
2915 // invalid test actions property has empty array
2916 {
2917 json configFile = validConfigFile;
2918 configFile["rules"][0]["actions"] = json::array();
2919 EXPECT_JSON_INVALID(configFile, "Validation failed.",
2920 "[] is too short");
2921 }
2922}
Shawn McCarney846dde52021-08-14 12:47:44 -05002923
Bob Kinge86c2e52020-01-21 11:33:32 +08002924TEST(ValidateRegulatorsConfigTest, RunRule)
2925{
2926 json runRuleFile = validConfigFile;
Bob King7d3a9f12020-02-11 15:34:52 +08002927 runRuleFile["rules"][0]["actions"][1]["run_rule"] = "read_sensors_rule";
Bob Kinge86c2e52020-01-21 11:33:32 +08002928 // Valid: test run_rule.
2929 {
2930 json configFile = runRuleFile;
2931 EXPECT_JSON_VALID(configFile);
2932 }
2933 // Invalid: test run_rule wrong type.
2934 {
2935 json configFile = runRuleFile;
2936 configFile["rules"][0]["actions"][1]["run_rule"] = true;
2937 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002938 "True is not of type 'string'");
Bob Kinge86c2e52020-01-21 11:33:32 +08002939 }
2940 // Invalid: test run_rule wrong format.
2941 {
2942 json configFile = runRuleFile;
2943 configFile["rules"][0]["actions"][1]["run_rule"] = "set_voltage_rule%";
2944 EXPECT_JSON_INVALID(
2945 configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002946 "'set_voltage_rule%' does not match '^[A-Za-z0-9_]+$'");
Bob Kinge86c2e52020-01-21 11:33:32 +08002947 }
2948}
Shawn McCarney846dde52021-08-14 12:47:44 -05002949
Bob Kingfcc2a2f2020-01-31 11:29:45 +08002950TEST(ValidateRegulatorsConfigTest, SensorMonitoring)
2951{
2952 // Valid: test rails sensor_monitoring with only property rule id.
2953 {
2954 json configFile = validConfigFile;
2955 EXPECT_JSON_VALID(configFile);
2956 }
2957 // Valid: test rails sensor_monitoring with only property actions.
2958 {
2959 json configFile = validConfigFile;
2960 configFile["chassis"][0]["devices"][0]["rails"][0]["sensor_monitoring"]
2961 .erase("rule_id");
2962 configFile["chassis"][0]["devices"][0]["rails"][0]["sensor_monitoring"]
2963 ["actions"][0]["compare_presence"]["fru"] =
Bob Kinga76898f2020-10-13 15:08:33 +08002964 "system/chassis/motherboard/cpu3";
Bob Kingfcc2a2f2020-01-31 11:29:45 +08002965 configFile["chassis"][0]["devices"][0]["rails"][0]["sensor_monitoring"]
2966 ["actions"][0]["compare_presence"]["value"] = true;
2967 configFile["chassis"][0]["devices"][0]["rails"][0]["sensor_monitoring"]
2968 ["comments"][0] = "comments";
2969 EXPECT_JSON_VALID(configFile);
2970 }
2971 // Invalid: test rails sensor_monitoring with both property rule_id and
2972 // actions.
2973 {
2974 json configFile = validConfigFile;
2975 configFile["chassis"][0]["devices"][0]["rails"][0]["sensor_monitoring"]
2976 ["actions"][0]["compare_presence"]["fru"] =
Bob Kinga76898f2020-10-13 15:08:33 +08002977 "system/chassis/motherboard/cpu3";
Bob Kingfcc2a2f2020-01-31 11:29:45 +08002978 configFile["chassis"][0]["devices"][0]["rails"][0]["sensor_monitoring"]
2979 ["actions"][0]["compare_presence"]["value"] = true;
Shawn McCarney846dde52021-08-14 12:47:44 -05002980 EXPECT_JSON_INVALID(configFile, "Validation failed.", "");
Bob Kingfcc2a2f2020-01-31 11:29:45 +08002981 }
2982 // Invalid: test rails sensor_monitoring with no rule_id and actions.
2983 {
2984 json configFile = validConfigFile;
2985 configFile["chassis"][0]["devices"][0]["rails"][0]["sensor_monitoring"]
2986 .erase("rule_id");
2987 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002988 "'rule_id' is a required property");
Bob Kingfcc2a2f2020-01-31 11:29:45 +08002989 }
2990 // Invalid: test rails sensor_monitoring with property comments wrong type.
2991 {
2992 json configFile = validConfigFile;
2993 configFile["chassis"][0]["devices"][0]["rails"][0]["sensor_monitoring"]
2994 ["comments"] = true;
2995 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002996 "True is not of type 'array'");
Bob Kingfcc2a2f2020-01-31 11:29:45 +08002997 }
2998 // Invalid: test rails sensor_monitoring with property rule_id wrong type.
2999 {
3000 json configFile = validConfigFile;
3001 configFile["chassis"][0]["devices"][0]["rails"][0]["sensor_monitoring"]
3002 ["rule_id"] = true;
3003 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08003004 "True is not of type 'string'");
Bob Kingfcc2a2f2020-01-31 11:29:45 +08003005 }
3006 // Invalid: test rails sensor_monitoring with property actions wrong type.
3007 {
3008 json configFile = validConfigFile;
3009 configFile["chassis"][0]["devices"][0]["rails"][0]["sensor_monitoring"]
3010 .erase("rule_id");
3011 configFile["chassis"][0]["devices"][0]["rails"][0]["sensor_monitoring"]
3012 ["actions"] = true;
3013 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08003014 "True is not of type 'array'");
Bob Kingfcc2a2f2020-01-31 11:29:45 +08003015 }
3016 // Invalid: test rails sensor_monitoring with property rule_id wrong format.
3017 {
3018 json configFile = validConfigFile;
3019 configFile["chassis"][0]["devices"][0]["rails"][0]["sensor_monitoring"]
3020 ["rule_id"] = "id@";
3021 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08003022 "'id@' does not match '^[A-Za-z0-9_]+$'");
Bob Kingfcc2a2f2020-01-31 11:29:45 +08003023 }
3024 // Invalid: test rails sensor_monitoring with property comments empty array.
3025 {
3026 json configFile = validConfigFile;
3027 configFile["chassis"][0]["devices"][0]["rails"][0]["sensor_monitoring"]
3028 ["comments"] = json::array();
3029 EXPECT_JSON_INVALID(configFile, "Validation failed.",
3030 "[] is too short");
3031 }
3032 // Invalid: test rails sensor_monitoring with property actions empty array.
3033 {
3034 json configFile = validConfigFile;
3035 configFile["chassis"][0]["devices"][0]["rails"][0]["sensor_monitoring"]
3036 .erase("rule_id");
3037 configFile["chassis"][0]["devices"][0]["rails"][0]["sensor_monitoring"]
3038 ["actions"] = json::array();
3039 EXPECT_JSON_INVALID(configFile, "Validation failed.",
3040 "[] is too short");
3041 }
3042}
Shawn McCarney846dde52021-08-14 12:47:44 -05003043
Bob King68230aa2020-01-21 11:34:33 +08003044TEST(ValidateRegulatorsConfigTest, SetDevice)
3045{
3046 json setDeviceFile = validConfigFile;
Bob King7d3a9f12020-02-11 15:34:52 +08003047 setDeviceFile["rules"][0]["actions"][1]["set_device"] = "vdd_regulator";
Bob King68230aa2020-01-21 11:34:33 +08003048 // Valid: test set_device.
3049 {
3050 json configFile = setDeviceFile;
3051 EXPECT_JSON_VALID(configFile);
3052 }
3053 // Invalid: test set_device wrong type.
3054 {
3055 json configFile = setDeviceFile;
3056 configFile["rules"][0]["actions"][1]["set_device"] = true;
3057 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08003058 "True is not of type 'string'");
Bob King68230aa2020-01-21 11:34:33 +08003059 }
3060 // Invalid: test set_device wrong format.
3061 {
3062 json configFile = setDeviceFile;
3063 configFile["rules"][0]["actions"][1]["set_device"] = "io_expander2%";
Bob King358c4172020-03-16 13:57:08 +08003064 EXPECT_JSON_INVALID(configFile, "Validation failed.",
3065 "'io_expander2%' does not match '^[A-Za-z0-9_]+$'");
Bob King68230aa2020-01-21 11:34:33 +08003066 }
3067}
Shawn McCarney846dde52021-08-14 12:47:44 -05003068
Bob King3643cc02020-01-31 11:32:56 +08003069TEST(ValidateRegulatorsConfigTest, DuplicateRuleID)
3070{
3071 // Invalid: test duplicate ID in rule.
3072 {
3073 json configFile = validConfigFile;
Shawn McCarney846dde52021-08-14 12:47:44 -05003074 configFile["rules"][4]["id"] = "set_voltage_rule";
3075 configFile["rules"][4]["actions"][0]["pmbus_write_vout_command"]
Bob King3643cc02020-01-31 11:32:56 +08003076 ["format"] = "linear";
3077 EXPECT_JSON_INVALID(configFile, "Error: Duplicate rule ID.", "");
3078 }
3079}
Shawn McCarney846dde52021-08-14 12:47:44 -05003080
Bob King3643cc02020-01-31 11:32:56 +08003081TEST(ValidateRegulatorsConfigTest, DuplicateChassisNumber)
3082{
3083 // Invalid: test duplicate number in chassis.
3084 {
3085 json configFile = validConfigFile;
3086 configFile["chassis"][1]["number"] = 1;
3087 EXPECT_JSON_INVALID(configFile, "Error: Duplicate chassis number.", "");
3088 }
3089}
Shawn McCarney846dde52021-08-14 12:47:44 -05003090
Bob King3643cc02020-01-31 11:32:56 +08003091TEST(ValidateRegulatorsConfigTest, DuplicateDeviceID)
3092{
3093 // Invalid: test duplicate ID in device.
3094 {
3095 json configFile = validConfigFile;
3096 configFile["chassis"][0]["devices"][1]["id"] = "vdd_regulator";
3097 configFile["chassis"][0]["devices"][1]["is_regulator"] = true;
3098 configFile["chassis"][0]["devices"][1]["fru"] =
Bob Kinga76898f2020-10-13 15:08:33 +08003099 "system/chassis/motherboard/regulator1";
Bob King3643cc02020-01-31 11:32:56 +08003100 configFile["chassis"][0]["devices"][1]["i2c_interface"]["bus"] = 2;
3101 configFile["chassis"][0]["devices"][1]["i2c_interface"]["address"] =
3102 "0x71";
3103 EXPECT_JSON_INVALID(configFile, "Error: Duplicate device ID.", "");
3104 }
3105}
Shawn McCarney846dde52021-08-14 12:47:44 -05003106
Bob King3643cc02020-01-31 11:32:56 +08003107TEST(ValidateRegulatorsConfigTest, DuplicateRailID)
3108{
3109 // Invalid: test duplicate ID in rail.
3110 {
3111 json configFile = validConfigFile;
3112 configFile["chassis"][0]["devices"][0]["rails"][1]["id"] = "vdd";
3113 EXPECT_JSON_INVALID(configFile, "Error: Duplicate rail ID.", "");
3114 }
3115}
Shawn McCarney846dde52021-08-14 12:47:44 -05003116
Bob King78793102020-03-13 13:16:09 +08003117TEST(ValidateRegulatorsConfigTest, DuplicateObjectID)
3118{
3119 // Invalid: test duplicate object ID in device and rail.
3120 {
3121 json configFile = validConfigFile;
3122 configFile["chassis"][0]["devices"][0]["rails"][1]["id"] =
3123 "vdd_regulator";
3124 EXPECT_JSON_INVALID(configFile, "Error: Duplicate ID.", "");
3125 }
3126 // Invalid: test duplicate object ID in device and rule.
3127 {
3128 json configFile = validConfigFile;
Shawn McCarney846dde52021-08-14 12:47:44 -05003129 configFile["rules"][4]["id"] = "vdd_regulator";
3130 configFile["rules"][4]["actions"][0]["pmbus_write_vout_command"]
Bob King78793102020-03-13 13:16:09 +08003131 ["format"] = "linear";
3132 EXPECT_JSON_INVALID(configFile, "Error: Duplicate ID.", "");
3133 }
3134 // Invalid: test duplicate object ID in rule and rail.
3135 {
3136 json configFile = validConfigFile;
3137 configFile["chassis"][0]["devices"][0]["rails"][1]["id"] =
3138 "set_voltage_rule";
3139 EXPECT_JSON_INVALID(configFile, "Error: Duplicate ID.", "");
3140 }
3141}
Shawn McCarney846dde52021-08-14 12:47:44 -05003142
Bob King3643cc02020-01-31 11:32:56 +08003143TEST(ValidateRegulatorsConfigTest, InfiniteLoops)
3144{
3145 // Invalid: test run_rule with infinite loop (rules run each other).
3146 {
3147 json configFile = validConfigFile;
Shawn McCarney846dde52021-08-14 12:47:44 -05003148 configFile["rules"][4]["actions"][0]["run_rule"] = "set_voltage_rule2";
3149 configFile["rules"][4]["id"] = "set_voltage_rule1";
3150 configFile["rules"][5]["actions"][0]["run_rule"] = "set_voltage_rule1";
3151 configFile["rules"][5]["id"] = "set_voltage_rule2";
Bob King3643cc02020-01-31 11:32:56 +08003152 EXPECT_JSON_INVALID(configFile,
3153 "Infinite loop caused by run_rule actions.", "");
3154 }
3155 // Invalid: test run_rule with infinite loop (rule runs itself).
3156 {
3157 json configFile = validConfigFile;
Shawn McCarney846dde52021-08-14 12:47:44 -05003158 configFile["rules"][4]["actions"][0]["run_rule"] = "set_voltage_rule1";
3159 configFile["rules"][4]["id"] = "set_voltage_rule1";
Bob King3643cc02020-01-31 11:32:56 +08003160 EXPECT_JSON_INVALID(configFile,
3161 "Infinite loop caused by run_rule actions.", "");
3162 }
3163 // Invalid: test run_rule with infinite loop (indirect loop).
3164 {
3165 json configFile = validConfigFile;
Shawn McCarney846dde52021-08-14 12:47:44 -05003166 configFile["rules"][4]["actions"][0]["run_rule"] = "set_voltage_rule2";
3167 configFile["rules"][4]["id"] = "set_voltage_rule1";
3168 configFile["rules"][5]["actions"][0]["run_rule"] = "set_voltage_rule3";
3169 configFile["rules"][5]["id"] = "set_voltage_rule2";
3170 configFile["rules"][6]["actions"][0]["run_rule"] = "set_voltage_rule1";
3171 configFile["rules"][6]["id"] = "set_voltage_rule3";
Bob King3643cc02020-01-31 11:32:56 +08003172 EXPECT_JSON_INVALID(configFile,
3173 "Infinite loop caused by run_rule actions.", "");
3174 }
3175}
Shawn McCarney846dde52021-08-14 12:47:44 -05003176
Bob Kingf88203a2020-02-18 13:26:07 +08003177TEST(ValidateRegulatorsConfigTest, RunRuleValueExists)
3178{
3179 // Invalid: test run_rule actions specify a rule ID that does not exist.
3180 {
3181 json configFile = validConfigFile;
Shawn McCarney846dde52021-08-14 12:47:44 -05003182 configFile["rules"][4]["actions"][0]["run_rule"] = "set_voltage_rule2";
3183 configFile["rules"][4]["id"] = "set_voltage_rule1";
Bob Kingf88203a2020-02-18 13:26:07 +08003184 EXPECT_JSON_INVALID(configFile, "Error: Rule ID does not exist.", "");
3185 }
3186}
Shawn McCarney846dde52021-08-14 12:47:44 -05003187
Bob King13b2ad92020-02-18 13:31:39 +08003188TEST(ValidateRegulatorsConfigTest, SetDeviceValueExists)
3189{
3190 // Invalid: test set_device actions specify a device ID that does not exist.
3191 {
3192 json configFile = validConfigFile;
Shawn McCarney846dde52021-08-14 12:47:44 -05003193 configFile["rules"][4]["actions"][0]["set_device"] = "vdd_regulator2";
3194 configFile["rules"][4]["id"] = "set_voltage_rule1";
Bob King13b2ad92020-02-18 13:31:39 +08003195 EXPECT_JSON_INVALID(configFile, "Error: Device ID does not exist.", "");
3196 }
3197}
Shawn McCarney846dde52021-08-14 12:47:44 -05003198
Bob King21b09be2020-02-18 13:33:09 +08003199TEST(ValidateRegulatorsConfigTest, RuleIDExists)
3200{
3201 // Invalid: test rule_id property in configuration specifies a rule ID that
3202 // does not exist.
3203 {
3204 json configFile = validConfigFile;
3205 configFile["chassis"][0]["devices"][0]["configuration"]["rule_id"] =
3206 "set_voltage_rule2";
3207 EXPECT_JSON_INVALID(configFile, "Error: Rule ID does not exist.", "");
3208 }
3209 // Invalid: test rule_id property in presence_detection specifies a rule ID
3210 // that does not exist.
3211 {
3212 json configFile = validConfigFile;
3213 configFile["chassis"][0]["devices"][0]["presence_detection"]
3214 ["rule_id"] = "set_voltage_rule2";
3215 EXPECT_JSON_INVALID(configFile, "Error: Rule ID does not exist.", "");
3216 }
3217 // Invalid: test rule_id property in sensor_monitoring specifies a rule ID
3218 // that does not exist.
3219 {
3220 json configFile = validConfigFile;
3221 configFile["chassis"][0]["devices"][0]["rails"][0]["sensor_monitoring"]
3222 ["rule_id"] = "set_voltage_rule2";
3223 EXPECT_JSON_INVALID(configFile, "Error: Rule ID does not exist.", "");
3224 }
3225}
Shawn McCarney846dde52021-08-14 12:47:44 -05003226
Bob Kingdc72b622020-02-18 13:36:18 +08003227TEST(ValidateRegulatorsConfigTest, NumberOfElementsInMasks)
3228{
3229 // Invalid: test number of elements in masks not equal to number in values
3230 // in i2c_compare_bytes.
3231 {
3232 json configFile = validConfigFile;
3233 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["register"] =
3234 "0x82";
3235 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["values"] = {
3236 "0x02", "0x73"};
3237 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["masks"] = {
3238 "0x7F"};
3239 EXPECT_JSON_INVALID(configFile,
3240 "Error: Invalid i2c_compare_bytes action.", "");
3241 }
3242 // Invalid: test number of elements in masks not equal to number in values
3243 // in i2c_write_bytes.
3244 {
3245 json configFile = validConfigFile;
3246 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["register"] =
3247 "0x82";
3248 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["values"] = {
3249 "0x02", "0x73"};
3250 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["masks"] = {
3251 "0x7F"};
3252 EXPECT_JSON_INVALID(configFile,
3253 "Error: Invalid i2c_write_bytes action.", "");
3254 }
3255}
Shawn McCarney846dde52021-08-14 12:47:44 -05003256
Bob Kinged009652020-02-20 14:54:13 +08003257TEST(ValidateRegulatorsConfigTest, CommandLineSyntax)
3258{
Bob Kinga57e0812020-03-12 10:47:42 +08003259 std::string validateTool =
3260 " ../phosphor-regulators/tools/validate-regulators-config.py ";
Bob Kinged009652020-02-20 14:54:13 +08003261 std::string schema = " -s ";
Bob Kinga57e0812020-03-12 10:47:42 +08003262 std::string schemaFile =
3263 " ../phosphor-regulators/schema/config_schema.json ";
Bob Kinged009652020-02-20 14:54:13 +08003264 std::string configuration = " -c ";
3265 std::string command;
3266 std::string errorMessage;
3267 std::string outputMessage;
3268 std::string outputMessageHelp =
3269 "usage: validate-regulators-config.py [-h] [-s SCHEMA_FILE]";
3270 int valid = 0;
3271
Shawn McCarney0f6ebad2020-09-04 16:43:00 -05003272 TemporaryFile tmpFile;
3273 std::string fileName = tmpFile.getPath().string();
Bob Kinga57e0812020-03-12 10:47:42 +08003274 writeDataToFile(validConfigFile, fileName);
Bob Kinged009652020-02-20 14:54:13 +08003275 // Valid: -s specified
3276 {
3277 command = validateTool + "-s " + schemaFile + configuration + fileName;
3278 expectCommandLineSyntax(errorMessage, outputMessage, command, valid);
3279 }
3280 // Valid: --schema-file specified
3281 {
3282 command = validateTool + "--schema-file " + schemaFile + configuration +
3283 fileName;
3284 expectCommandLineSyntax(errorMessage, outputMessage, command, valid);
3285 }
3286 // Valid: -c specified
3287 {
3288 command = validateTool + schema + schemaFile + "-c " + fileName;
3289 expectCommandLineSyntax(errorMessage, outputMessage, command, valid);
3290 }
3291 // Valid: --configuration-file specified
3292 {
3293 command = validateTool + schema + schemaFile + "--configuration-file " +
3294 fileName;
3295 expectCommandLineSyntax(errorMessage, outputMessage, command, valid);
3296 }
3297 // Valid: -h specified
3298 {
3299 command = validateTool + "-h ";
3300 expectCommandLineSyntax(errorMessage, outputMessageHelp, command,
3301 valid);
3302 }
3303 // Valid: --help specified
3304 {
3305 command = validateTool + "--help ";
3306 expectCommandLineSyntax(errorMessage, outputMessageHelp, command,
3307 valid);
3308 }
3309 // Invalid: -c/--configuration-file not specified
3310 {
3311 command = validateTool + schema + schemaFile;
3312 expectCommandLineSyntax("Error: Configuration file is required.",
3313 outputMessageHelp, command, 1);
3314 }
3315 // Invalid: -s/--schema-file not specified
3316 {
3317 command = validateTool + configuration + fileName;
3318 expectCommandLineSyntax("Error: Schema file is required.",
3319 outputMessageHelp, command, 1);
3320 }
Bob Kingb7552f02020-10-15 14:34:17 +08003321 // Invalid: -c specified more than once
3322 {
3323 command = validateTool + schema + schemaFile + "-c -c " + fileName;
3324 expectCommandLineSyntax(outputMessageHelp, outputMessage, command, 2);
3325 }
Bob Kinged009652020-02-20 14:54:13 +08003326 // Invalid: -s specified more than once
3327 {
3328 command =
3329 validateTool + "-s -s " + schemaFile + configuration + fileName;
3330 expectCommandLineSyntax(outputMessageHelp, outputMessage, command, 2);
3331 }
Bob Kinged009652020-02-20 14:54:13 +08003332 // Invalid: No file name specified after -c
3333 {
3334 command = validateTool + schema + schemaFile + configuration;
3335 expectCommandLineSyntax(outputMessageHelp, outputMessage, command, 2);
3336 }
3337 // Invalid: No file name specified after -s
3338 {
3339 command = validateTool + schema + configuration + fileName;
3340 expectCommandLineSyntax(outputMessageHelp, outputMessage, command, 2);
3341 }
3342 // Invalid: File specified after -c does not exist
3343 {
3344 command = validateTool + schema + schemaFile + configuration +
3345 "../notExistFile";
Bob Kingb7552f02020-10-15 14:34:17 +08003346 expectCommandLineSyntax("Error: Configuration file does not exist.",
3347 outputMessageHelp, command, 1);
Bob Kinged009652020-02-20 14:54:13 +08003348 }
3349 // Invalid: File specified after -s does not exist
3350 {
3351 command = validateTool + schema + "../notExistFile " + configuration +
3352 fileName;
Bob Kingb7552f02020-10-15 14:34:17 +08003353 expectCommandLineSyntax("Error: Schema file does not exist.",
3354 outputMessageHelp, command, 1);
3355 }
3356 // Invalid: File specified after -c is not right data format
3357 {
3358 TemporaryFile wrongFormatFile;
3359 std::string wrongFormatFileName = wrongFormatFile.getPath().string();
3360 std::ofstream out(wrongFormatFileName);
3361 out << "foo";
3362 out.close();
3363 command = validateTool + schema + schemaFile + configuration +
3364 wrongFormatFileName;
Bob Kinged009652020-02-20 14:54:13 +08003365 expectCommandLineSyntax(
Bob Kingb7552f02020-10-15 14:34:17 +08003366 "Error: Configuration file is not in the JSON format.",
3367 outputMessageHelp, command, 1);
Bob Kinged009652020-02-20 14:54:13 +08003368 }
3369 // Invalid: File specified after -s is not right data format
3370 {
Shawn McCarney0f6ebad2020-09-04 16:43:00 -05003371 TemporaryFile wrongFormatFile;
3372 std::string wrongFormatFileName = wrongFormatFile.getPath().string();
Bob Kinga57e0812020-03-12 10:47:42 +08003373 std::ofstream out(wrongFormatFileName);
Bob Kinged009652020-02-20 14:54:13 +08003374 out << "foo";
3375 out.close();
Bob Kinga57e0812020-03-12 10:47:42 +08003376 command = validateTool + schema + wrongFormatFileName + configuration +
3377 fileName;
Bob Kingb7552f02020-10-15 14:34:17 +08003378 expectCommandLineSyntax("Error: Schema file is not in the JSON format.",
3379 outputMessageHelp, command, 1);
Bob Kinged009652020-02-20 14:54:13 +08003380 }
3381 // Invalid: File specified after -c is not readable
3382 {
Shawn McCarney0f6ebad2020-09-04 16:43:00 -05003383 TemporaryFile notReadableFile;
3384 std::string notReadableFileName = notReadableFile.getPath().string();
Bob Kinga57e0812020-03-12 10:47:42 +08003385 writeDataToFile(validConfigFile, notReadableFileName);
Bob Kinged009652020-02-20 14:54:13 +08003386 command = validateTool + schema + schemaFile + configuration +
Bob Kinga57e0812020-03-12 10:47:42 +08003387 notReadableFileName;
3388 chmod(notReadableFileName.c_str(), 0222);
Bob Kingb7552f02020-10-15 14:34:17 +08003389 expectCommandLineSyntax("Error: Configuration file is not readable.",
3390 outputMessageHelp, command, 1);
Bob Kinged009652020-02-20 14:54:13 +08003391 }
3392 // Invalid: File specified after -s is not readable
3393 {
Shawn McCarney0f6ebad2020-09-04 16:43:00 -05003394 TemporaryFile notReadableFile;
3395 std::string notReadableFileName = notReadableFile.getPath().string();
Bob Kinga57e0812020-03-12 10:47:42 +08003396 writeDataToFile(validConfigFile, notReadableFileName);
3397 command = validateTool + schema + notReadableFileName + configuration +
3398 fileName;
3399 chmod(notReadableFileName.c_str(), 0222);
Bob Kingb7552f02020-10-15 14:34:17 +08003400 expectCommandLineSyntax("Error: Schema file is not readable.",
3401 outputMessageHelp, command, 1);
Bob Kinged009652020-02-20 14:54:13 +08003402 }
3403 // Invalid: Unexpected parameter specified (like -g)
3404 {
3405 command = validateTool + schema + schemaFile + configuration +
3406 fileName + " -g";
3407 expectCommandLineSyntax(outputMessageHelp, outputMessage, command, 2);
3408 }
Bob Kinged009652020-02-20 14:54:13 +08003409}