blob: 2763cc9ca7514967d178c51187a0aa4d1b71d4ab [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");
568 configFile["chassis"][0].erase("devices");
569 EXPECT_JSON_VALID(configFile);
570 }
571 // Invalid: test chassis with no number.
572 {
573 json configFile = validConfigFile;
574 configFile["chassis"][0].erase("number");
575 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800576 "'number' is a required property");
Bob King3728f562020-01-21 11:35:31 +0800577 }
Shawn McCarney4c88a4c2021-09-21 15:29:24 -0500578 // Invalid: test chassis with no inventory_path.
579 {
580 json configFile = validConfigFile;
581 configFile["chassis"][0].erase("inventory_path");
582 EXPECT_JSON_INVALID(configFile, "Validation failed.",
583 "'inventory_path' is a required property");
584 }
Bob King3728f562020-01-21 11:35:31 +0800585 // Invalid: test chassis with property comments wrong type.
586 {
587 json configFile = validConfigFile;
588 configFile["chassis"][0]["comments"] = true;
589 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800590 "True is not of type 'array'");
Bob King3728f562020-01-21 11:35:31 +0800591 }
592 // Invalid: test chassis with property number wrong type.
593 {
594 json configFile = validConfigFile;
595 configFile["chassis"][0]["number"] = 1.3;
596 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800597 "1.3 is not of type 'integer'");
Bob King3728f562020-01-21 11:35:31 +0800598 }
Shawn McCarneyecbeeea2021-04-29 21:08:18 -0500599 // Invalid: test chassis with property inventory_path wrong type.
600 {
601 json configFile = validConfigFile;
602 configFile["chassis"][0]["inventory_path"] = 2;
603 EXPECT_JSON_INVALID(configFile, "Validation failed.",
604 "2 is not of type 'string'");
605 }
Bob King3728f562020-01-21 11:35:31 +0800606 // Invalid: test chassis with property devices wrong type.
607 {
608 json configFile = validConfigFile;
609 configFile["chassis"][0]["devices"] = true;
610 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800611 "True is not of type 'array'");
Bob King3728f562020-01-21 11:35:31 +0800612 }
613 // Invalid: test chassis with property comments empty array.
614 {
615 json configFile = validConfigFile;
616 configFile["chassis"][0]["comments"] = json::array();
617 EXPECT_JSON_INVALID(configFile, "Validation failed.",
618 "[] is too short");
619 }
620 // Invalid: test chassis with property devices empty array.
621 {
622 json configFile = validConfigFile;
623 configFile["chassis"][0]["devices"] = json::array();
624 EXPECT_JSON_INVALID(configFile, "Validation failed.",
625 "[] is too short");
626 }
627 // Invalid: test chassis with property number less than 1.
628 {
629 json configFile = validConfigFile;
630 configFile["chassis"][0]["number"] = 0;
631 EXPECT_JSON_INVALID(configFile, "Validation failed.",
632 "0 is less than the minimum of 1");
633 }
Shawn McCarneyecbeeea2021-04-29 21:08:18 -0500634 // Invalid: test chassis with property inventory_path empty string.
635 {
636 json configFile = validConfigFile;
637 configFile["chassis"][0]["inventory_path"] = "";
638 EXPECT_JSON_INVALID(configFile, "Validation failed.",
639 "'' is too short");
640 }
Bob King3728f562020-01-21 11:35:31 +0800641}
Shawn McCarney846dde52021-08-14 12:47:44 -0500642
Bob Kingbf1cbea2020-01-21 11:08:50 +0800643TEST(ValidateRegulatorsConfigTest, ComparePresence)
644{
645 json comparePresenceFile = validConfigFile;
646 comparePresenceFile["rules"][0]["actions"][1]["compare_presence"]["fru"] =
Bob Kinga76898f2020-10-13 15:08:33 +0800647 "system/chassis/motherboard/regulator2";
Bob Kingbf1cbea2020-01-21 11:08:50 +0800648 comparePresenceFile["rules"][0]["actions"][1]["compare_presence"]["value"] =
649 true;
650 // Valid.
651 {
652 json configFile = comparePresenceFile;
653 EXPECT_JSON_VALID(configFile);
654 }
655
656 // Invalid: no FRU property.
657 {
658 json configFile = comparePresenceFile;
659 configFile["rules"][0]["actions"][1]["compare_presence"].erase("fru");
660 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800661 "'fru' is a required property");
Bob Kingbf1cbea2020-01-21 11:08:50 +0800662 }
663
664 // Invalid: FRU property length is string less than 1.
665 {
666 json configFile = comparePresenceFile;
667 configFile["rules"][0]["actions"][1]["compare_presence"]["fru"] = "";
668 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800669 "'' is too short");
Bob Kingbf1cbea2020-01-21 11:08:50 +0800670 }
671
672 // Invalid: no value property.
673 {
674 json configFile = comparePresenceFile;
675 configFile["rules"][0]["actions"][1]["compare_presence"].erase("value");
676 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800677 "'value' is a required property");
Bob Kingbf1cbea2020-01-21 11:08:50 +0800678 }
679
680 // Invalid: value property type is not boolean.
681 {
682 json configFile = comparePresenceFile;
683 configFile["rules"][0]["actions"][1]["compare_presence"]["value"] = "1";
684 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800685 "'1' is not of type 'boolean'");
Bob Kingbf1cbea2020-01-21 11:08:50 +0800686 }
687
688 // Invalid: FRU property type is not string.
689 {
690 json configFile = comparePresenceFile;
691 configFile["rules"][0]["actions"][1]["compare_presence"]["fru"] = 1;
692 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800693 "1 is not of type 'string'");
Bob Kingbf1cbea2020-01-21 11:08:50 +0800694 }
695}
Shawn McCarney846dde52021-08-14 12:47:44 -0500696
Bob Kingf8b77a02020-01-21 11:09:47 +0800697TEST(ValidateRegulatorsConfigTest, CompareVpd)
698{
699 json compareVpdFile = validConfigFile;
700 compareVpdFile["rules"][0]["actions"][1]["compare_vpd"]["fru"] =
Bob Kinga76898f2020-10-13 15:08:33 +0800701 "system/chassis/motherboard/regulator2";
Bob Kingf8b77a02020-01-21 11:09:47 +0800702 compareVpdFile["rules"][0]["actions"][1]["compare_vpd"]["keyword"] = "CCIN";
703 compareVpdFile["rules"][0]["actions"][1]["compare_vpd"]["value"] = "2D35";
704
Shawn McCarneya2a830b2021-10-30 14:24:31 -0500705 // Valid: value property: not empty.
Bob Kingf8b77a02020-01-21 11:09:47 +0800706 {
707 json configFile = compareVpdFile;
708 EXPECT_JSON_VALID(configFile);
709 }
Shawn McCarneya2a830b2021-10-30 14:24:31 -0500710
711 // Valid: value property: empty.
712 {
713 json configFile = compareVpdFile;
714 configFile["rules"][0]["actions"][1]["compare_vpd"]["value"] = "";
715 EXPECT_JSON_VALID(configFile);
716 }
717
718 // Valid: byte_values property: not empty.
Matt Spinleraacc2aa2021-05-25 09:31:35 -0600719 {
720 json configFile = compareVpdFile;
721 configFile["rules"][0]["actions"][1]["compare_vpd"].erase("value");
722 configFile["rules"][0]["actions"][1]["compare_vpd"]["byte_values"] = {
723 "0x01", "0x02"};
724 EXPECT_JSON_VALID(configFile);
725 }
Bob Kingf8b77a02020-01-21 11:09:47 +0800726
Shawn McCarneya2a830b2021-10-30 14:24:31 -0500727 // Valid: byte_values property: empty.
728 {
729 json configFile = compareVpdFile;
730 configFile["rules"][0]["actions"][1]["compare_vpd"].erase("value");
731 configFile["rules"][0]["actions"][1]["compare_vpd"]["byte_values"] =
732 json::array();
733 EXPECT_JSON_VALID(configFile);
734 }
735
Bob Kingf8b77a02020-01-21 11:09:47 +0800736 // Invalid: no FRU property.
737 {
738 json configFile = compareVpdFile;
739 configFile["rules"][0]["actions"][1]["compare_vpd"].erase("fru");
740 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800741 "'fru' is a required property");
Bob Kingf8b77a02020-01-21 11:09:47 +0800742 }
743
744 // Invalid: no keyword property.
745 {
746 json configFile = compareVpdFile;
747 configFile["rules"][0]["actions"][1]["compare_vpd"].erase("keyword");
748 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800749 "'keyword' is a required property");
Bob Kingf8b77a02020-01-21 11:09:47 +0800750 }
751
752 // Invalid: no value property.
753 {
754 json configFile = compareVpdFile;
755 configFile["rules"][0]["actions"][1]["compare_vpd"].erase("value");
756 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800757 "'value' is a required property");
Bob Kingf8b77a02020-01-21 11:09:47 +0800758 }
759
760 // Invalid: property FRU wrong type.
761 {
762 json configFile = compareVpdFile;
763 configFile["rules"][0]["actions"][1]["compare_vpd"]["fru"] = 1;
764 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800765 "1 is not of type 'string'");
Bob Kingf8b77a02020-01-21 11:09:47 +0800766 }
767
768 // Invalid: property FRU is string less than 1.
769 {
770 json configFile = compareVpdFile;
771 configFile["rules"][0]["actions"][1]["compare_vpd"]["fru"] = "";
772 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800773 "'' is too short");
Bob Kingf8b77a02020-01-21 11:09:47 +0800774 }
775
776 // Invalid: property keyword is not "CCIN", "Manufacturer", "Model",
Matt Spinleraacc2aa2021-05-25 09:31:35 -0600777 // "PartNumber", "HW"
Bob Kingf8b77a02020-01-21 11:09:47 +0800778 {
779 json configFile = compareVpdFile;
780 configFile["rules"][0]["actions"][1]["compare_vpd"]["keyword"] =
781 "Number";
782 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800783 "'Number' is not one of ['CCIN', "
Matt Spinleraacc2aa2021-05-25 09:31:35 -0600784 "'Manufacturer', 'Model', 'PartNumber', 'HW']");
Bob Kingf8b77a02020-01-21 11:09:47 +0800785 }
786
787 // Invalid: property value wrong type.
788 {
789 json configFile = compareVpdFile;
790 configFile["rules"][0]["actions"][1]["compare_vpd"]["value"] = 1;
791 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800792 "1 is not of type 'string'");
Bob Kingf8b77a02020-01-21 11:09:47 +0800793 }
Matt Spinleraacc2aa2021-05-25 09:31:35 -0600794
795 // Invalid: property byte_values has wrong type
796 {
797 json configFile = compareVpdFile;
798 configFile["rules"][0]["actions"][1]["compare_vpd"].erase("value");
799 configFile["rules"][0]["actions"][1]["compare_vpd"]["byte_values"] =
800 "0x50";
801 EXPECT_JSON_INVALID(configFile, "Validation failed.",
802 "'0x50' is not of type 'array'");
803 }
804
Matt Spinleraacc2aa2021-05-25 09:31:35 -0600805 // Invalid: properties byte_values and value both exist
806 {
807 json configFile = compareVpdFile;
808 configFile["rules"][0]["actions"][1]["compare_vpd"]["byte_values"] = {
809 "0x01", "0x02"};
810 EXPECT_JSON_INVALID(
811 configFile, "Validation failed.",
812 "{'byte_values': ['0x01', '0x02'], 'fru': "
813 "'system/chassis/motherboard/regulator2', 'keyword': 'CCIN', "
814 "'value': '2D35'} is valid under each of {'required': "
815 "['byte_values']}, {'required': ['value']}");
816 }
Bob Kingf8b77a02020-01-21 11:09:47 +0800817}
Shawn McCarney846dde52021-08-14 12:47:44 -0500818
Bob King20057412020-03-16 16:50:17 +0800819TEST(ValidateRegulatorsConfigTest, ConfigFile)
820{
821 // Valid: Only required properties specified
822 {
823 json configFile;
824 configFile["chassis"][0]["number"] = 1;
Shawn McCarney4c88a4c2021-09-21 15:29:24 -0500825 configFile["chassis"][0]["inventory_path"] = "system/chassis";
Bob King20057412020-03-16 16:50:17 +0800826 EXPECT_JSON_VALID(configFile);
827 }
828 // Valid: All properties specified
829 {
830 json configFile = validConfigFile;
831 EXPECT_JSON_VALID(configFile);
832 }
833 // Invalid: Required chassis property not specified
834 {
835 json configFile = validConfigFile;
836 configFile.erase("chassis");
837 EXPECT_JSON_INVALID(configFile, "Validation failed.",
838 "'chassis' is a required property");
839 }
840 // Invalid: Wrong data type for comments
841 {
842 json configFile = validConfigFile;
843 configFile["comments"] = true;
844 EXPECT_JSON_INVALID(configFile, "Validation failed.",
845 "True is not of type 'array'");
846 }
847 // Invalid: Wrong data type for rules
848 {
849 json configFile = validConfigFile;
850 configFile["rules"] = true;
851 EXPECT_JSON_INVALID(configFile, "Validation failed.",
852 "True is not of type 'array'");
853 }
854 // Invalid: Wrong data type for chassis
855 {
856 json configFile = validConfigFile;
857 configFile["chassis"] = true;
858 EXPECT_JSON_INVALID(configFile, "Validation failed.",
859 "True is not of type 'array'");
860 }
861 // Invalid: Empty comments array;
862 {
863 json configFile = validConfigFile;
864 configFile["comments"] = json::array();
865 EXPECT_JSON_INVALID(configFile, "Validation failed.",
866 "[] is too short");
867 }
868 // Invalid: Empty rules array
869 {
870 json configFile = validConfigFile;
871 configFile["rules"] = json::array();
872 EXPECT_JSON_INVALID(configFile, "Validation failed.",
873 "[] is too short");
874 }
875 // Invalid: Empty chassis array
876 {
877 json configFile = validConfigFile;
878 configFile["chassis"] = json::array();
879 EXPECT_JSON_INVALID(configFile, "Validation failed.",
880 "[] is too short");
881 }
882 // Invalid: Comments array has wrong element type (should be string)
883 {
884 json configFile = validConfigFile;
885 configFile["comments"][0] = true;
886 EXPECT_JSON_INVALID(configFile, "Validation failed.",
887 "True is not of type 'string'");
888 }
889 // Invalid: Rules array has wrong element type (should be rule)
890 {
891 json configFile = validConfigFile;
892 configFile["rules"][0] = true;
893 EXPECT_JSON_INVALID(configFile, "Validation failed.",
894 "True is not of type 'object'");
895 }
896 // Invalid: Chassis array has wrong element type (should be chassis)
897 {
898 json configFile = validConfigFile;
899 configFile["chassis"][0] = true;
900 EXPECT_JSON_INVALID(configFile, "Validation failed.",
901 "True is not of type 'object'");
902 }
903 // Invalid: Unexpected property specified
904 {
905 json configFile = validConfigFile;
906 configFile["foo"] = json::array();
907 EXPECT_JSON_INVALID(
908 configFile, "Validation failed.",
909 "Additional properties are not allowed ('foo' was unexpected)");
910 }
911}
Shawn McCarney846dde52021-08-14 12:47:44 -0500912
Bob King4c67a3a2020-02-07 09:48:11 +0800913TEST(ValidateRegulatorsConfigTest, Configuration)
914{
915 json configurationFile = validConfigFile;
916 configurationFile["chassis"][0]["devices"][0]["configuration"]["comments"]
917 [0] = "Set rail to 1.25V using standard rule";
918 configurationFile["chassis"][0]["devices"][0]["configuration"]["volts"] =
919 1.25;
920 configurationFile["chassis"][0]["devices"][0]["configuration"]["rule_id"] =
921 "set_voltage_rule";
922 // Valid: test configuration with property rule_id and with no actions.
923 {
924 json configFile = configurationFile;
Bob King78793102020-03-13 13:16:09 +0800925 configFile["chassis"][0]["devices"][0]["configuration"]["comments"][1] =
926 "test multiple array elements in comments.";
Bob King4c67a3a2020-02-07 09:48:11 +0800927 EXPECT_JSON_VALID(configFile);
928 }
929 // Valid: test configuration with property actions and with no rule_id.
930 {
931 json configFile = configurationFile;
932 configFile["chassis"][0]["devices"][0]["configuration"].erase(
933 "rule_id");
934 configFile["chassis"][0]["devices"][0]["configuration"]["actions"][0]
935 ["compare_presence"]["fru"] =
Bob Kinga76898f2020-10-13 15:08:33 +0800936 "system/chassis/motherboard/cpu3";
Bob King4c67a3a2020-02-07 09:48:11 +0800937 configFile["chassis"][0]["devices"][0]["configuration"]["actions"][0]
938 ["compare_presence"]["value"] = true;
939 EXPECT_JSON_VALID(configFile);
940 }
941 // Valid: comments not specified (optional property).
942 {
943 json configFile = configurationFile;
944 configFile["chassis"][0]["devices"][0]["configuration"].erase(
945 "comments");
946 EXPECT_JSON_VALID(configFile);
947 }
948 // Valid: volts not specified (optional property).
949 {
950 json configFile = configurationFile;
951 configFile["chassis"][0]["devices"][0]["configuration"].erase("volts");
952 EXPECT_JSON_VALID(configFile);
953 }
954 // Valid: configuration is property of a rail (vs. a device).
955 {
956 json configFile = validConfigFile;
957 configFile["chassis"][0]["devices"][0]["rails"][0]["configuration"]
958 ["comments"][0] = "Set rail to 1.25V using standard rule";
959 configFile["chassis"][0]["devices"][0]["rails"][0]["configuration"]
960 ["volts"] = 1.25;
961 configFile["chassis"][0]["devices"][0]["rails"][0]["configuration"]
962 ["rule_id"] = "set_voltage_rule";
963 EXPECT_JSON_VALID(configFile);
964 }
965 // Invalid: comments property has wrong data type (not an array).
966 {
967 json configFile = configurationFile;
968 configFile["chassis"][0]["devices"][0]["configuration"]["comments"] = 1;
969 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800970 "1 is not of type 'array'");
Bob King4c67a3a2020-02-07 09:48:11 +0800971 }
972 // Invalid: test configuration with both actions and rule_id properties.
973 {
974 json configFile = configurationFile;
975 configFile["chassis"][0]["devices"][0]["configuration"]["actions"][0]
976 ["compare_presence"]["fru"] =
Bob Kinga76898f2020-10-13 15:08:33 +0800977 "system/chassis/motherboard/cpu3";
Bob King4c67a3a2020-02-07 09:48:11 +0800978 configFile["chassis"][0]["devices"][0]["configuration"]["actions"][0]
979 ["compare_presence"]["value"] = true;
Shawn McCarney846dde52021-08-14 12:47:44 -0500980 EXPECT_JSON_INVALID(configFile, "Validation failed.", "");
Bob King4c67a3a2020-02-07 09:48:11 +0800981 }
982 // Invalid: test configuration with no rule_id and actions.
983 {
984 json configFile = configurationFile;
985 configFile["chassis"][0]["devices"][0]["configuration"].erase(
986 "rule_id");
987 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800988 "'rule_id' is a required property");
Bob King4c67a3a2020-02-07 09:48:11 +0800989 }
990 // Invalid: test configuration with property volts wrong type.
991 {
992 json configFile = configurationFile;
993 configFile["chassis"][0]["devices"][0]["configuration"]["volts"] = true;
994 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800995 "True is not of type 'number'");
Bob King4c67a3a2020-02-07 09:48:11 +0800996 }
997 // Invalid: test configuration with property rule_id wrong type.
998 {
999 json configFile = configurationFile;
1000 configFile["chassis"][0]["devices"][0]["configuration"]["rule_id"] =
1001 true;
1002 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001003 "True is not of type 'string'");
Bob King4c67a3a2020-02-07 09:48:11 +08001004 }
1005 // Invalid: test configuration with property actions wrong type.
1006 {
1007 json configFile = configurationFile;
1008 configFile["chassis"][0]["devices"][0]["configuration"].erase(
1009 "rule_id");
1010 configFile["chassis"][0]["devices"][0]["configuration"]["actions"] =
1011 true;
1012 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001013 "True is not of type 'array'");
Bob King4c67a3a2020-02-07 09:48:11 +08001014 }
1015 // Invalid: test configuration with property comments empty array.
1016 {
1017 json configFile = configurationFile;
1018 configFile["chassis"][0]["devices"][0]["configuration"]["comments"] =
1019 json::array();
1020 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1021 "[] is too short");
1022 }
1023 // Invalid: test configuration with property rule_id wrong format.
1024 {
1025 json configFile = configurationFile;
1026 configFile["chassis"][0]["devices"][0]["configuration"]["rule_id"] =
1027 "id!";
1028 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001029 "'id!' does not match '^[A-Za-z0-9_]+$'");
Bob King4c67a3a2020-02-07 09:48:11 +08001030 }
1031 // Invalid: test configuration with property actions empty array.
1032 {
1033 json configFile = configurationFile;
1034 configFile["chassis"][0]["devices"][0]["configuration"].erase(
1035 "rule_id");
1036 configFile["chassis"][0]["devices"][0]["configuration"]["actions"] =
1037 json::array();
1038 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1039 "[] is too short");
1040 }
1041}
Shawn McCarney846dde52021-08-14 12:47:44 -05001042
Bob Kinga2ba2df2020-02-04 14:38:44 +08001043TEST(ValidateRegulatorsConfigTest, Device)
1044{
Bob Kinga2ba2df2020-02-04 14:38:44 +08001045 // Valid: test devices.
1046 {
1047 json configFile = validConfigFile;
1048 EXPECT_JSON_VALID(configFile);
1049 }
1050 // Valid: test devices with required properties.
1051 {
1052 json configFile = validConfigFile;
1053 configFile["chassis"][0]["devices"][0].erase("comments");
1054 configFile["chassis"][0]["devices"][0].erase("presence_detection");
1055 configFile["chassis"][0]["devices"][0].erase("configuration");
Shawn McCarney846dde52021-08-14 12:47:44 -05001056 configFile["chassis"][0]["devices"][0].erase("phase_fault_detection");
Bob Kinga2ba2df2020-02-04 14:38:44 +08001057 configFile["chassis"][0]["devices"][0].erase("rails");
1058 EXPECT_JSON_VALID(configFile);
1059 }
1060 // Invalid: test devices with no id.
1061 {
1062 json configFile = validConfigFile;
1063 configFile["chassis"][0]["devices"][0].erase("id");
1064 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001065 "'id' is a required property");
Bob Kinga2ba2df2020-02-04 14:38:44 +08001066 }
1067 // Invalid: test devices with no is_regulator.
1068 {
1069 json configFile = validConfigFile;
1070 configFile["chassis"][0]["devices"][0].erase("is_regulator");
1071 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001072 "'is_regulator' is a required property");
Bob Kinga2ba2df2020-02-04 14:38:44 +08001073 }
1074 // Invalid: test devices with no fru.
1075 {
1076 json configFile = validConfigFile;
1077 configFile["chassis"][0]["devices"][0].erase("fru");
1078 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001079 "'fru' is a required property");
Bob Kinga2ba2df2020-02-04 14:38:44 +08001080 }
1081 // Invalid: test devices with no i2c_interface.
1082 {
1083 json configFile = validConfigFile;
1084 configFile["chassis"][0]["devices"][0].erase("i2c_interface");
1085 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001086 "'i2c_interface' is a required property");
Bob Kinga2ba2df2020-02-04 14:38:44 +08001087 }
Shawn McCarney846dde52021-08-14 12:47:44 -05001088 // Invalid: is_regulator=false: phase_fault_detection specified
1089 {
1090 json configFile = validConfigFile;
1091 configFile["chassis"][0]["devices"][0]["is_regulator"] = false;
1092 configFile["chassis"][0]["devices"][0].erase("rails");
1093 configFile["chassis"][0]["devices"][0]["phase_fault_detection"]
1094 ["rule_id"] = "detect_phase_faults_rule";
1095 EXPECT_JSON_INVALID(configFile, "Validation failed.", "");
1096 }
1097 // Invalid: is_regulator=false: rails specified
1098 {
1099 json configFile = validConfigFile;
1100 configFile["chassis"][0]["devices"][0]["is_regulator"] = false;
1101 EXPECT_JSON_INVALID(configFile, "Validation failed.", "");
1102 }
1103 // Invalid: is_regulator=false: phase_fault_detection and rails specified
1104 {
1105 json configFile = validConfigFile;
1106 configFile["chassis"][0]["devices"][0]["is_regulator"] = false;
1107 configFile["chassis"][0]["devices"][0]["phase_fault_detection"]
1108 ["rule_id"] = "detect_phase_faults_rule";
1109 EXPECT_JSON_INVALID(configFile, "Validation failed.", "");
1110 }
Bob Kinga2ba2df2020-02-04 14:38:44 +08001111 // Invalid: test devices with property comments wrong type.
1112 {
1113 json configFile = validConfigFile;
1114 configFile["chassis"][0]["devices"][0]["comments"] = true;
1115 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001116 "True is not of type 'array'");
Bob Kinga2ba2df2020-02-04 14:38:44 +08001117 }
1118 // Invalid: test devices with property id wrong type.
1119 {
1120 json configFile = validConfigFile;
1121 configFile["chassis"][0]["devices"][0]["id"] = 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 is_regulator wrong type.
1126 {
1127 json configFile = validConfigFile;
1128 configFile["chassis"][0]["devices"][0]["is_regulator"] = 1;
1129 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001130 "1 is not of type 'boolean'");
Bob Kinga2ba2df2020-02-04 14:38:44 +08001131 }
1132 // Invalid: test devices with property fru wrong type.
1133 {
1134 json configFile = validConfigFile;
1135 configFile["chassis"][0]["devices"][0]["fru"] = true;
1136 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001137 "True is not of type 'string'");
Bob Kinga2ba2df2020-02-04 14:38:44 +08001138 }
1139 // Invalid: test devices with property i2c_interface wrong type.
1140 {
1141 json configFile = validConfigFile;
1142 configFile["chassis"][0]["devices"][0]["i2c_interface"] = true;
1143 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001144 "True is not of type 'object'");
Bob Kinga2ba2df2020-02-04 14:38:44 +08001145 }
1146 // Invalid: test devices with property presence_detection wrong
1147 // type.
1148 {
1149 json configFile = validConfigFile;
1150 configFile["chassis"][0]["devices"][0]["presence_detection"] = true;
1151 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001152 "True is not of type 'object'");
Bob Kinga2ba2df2020-02-04 14:38:44 +08001153 }
1154 // Invalid: test devices with property configuration wrong type.
1155 {
1156 json configFile = validConfigFile;
1157 configFile["chassis"][0]["devices"][0]["configuration"] = true;
1158 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001159 "True is not of type 'object'");
Bob Kinga2ba2df2020-02-04 14:38:44 +08001160 }
Shawn McCarney846dde52021-08-14 12:47:44 -05001161 // Invalid: test devices with property phase_fault_detection wrong type.
1162 {
1163 json configFile = validConfigFile;
1164 configFile["chassis"][0]["devices"][0]["phase_fault_detection"] = true;
1165 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1166 "True is not of type 'object'");
1167 }
Bob Kinga2ba2df2020-02-04 14:38:44 +08001168 // Invalid: test devices with property rails wrong type.
1169 {
1170 json configFile = validConfigFile;
1171 configFile["chassis"][0]["devices"][0]["rails"] = true;
1172 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001173 "True is not of type 'array'");
Bob Kinga2ba2df2020-02-04 14:38:44 +08001174 }
1175 // Invalid: test devices with property comments empty array.
1176 {
1177 json configFile = validConfigFile;
1178 configFile["chassis"][0]["devices"][0]["comments"] = json::array();
1179 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1180 "[] is too short");
1181 }
1182 // Invalid: test devices with property fru length less than 1.
1183 {
1184 json configFile = validConfigFile;
1185 configFile["chassis"][0]["devices"][0]["fru"] = "";
1186 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001187 "'' is too short");
Bob Kinga2ba2df2020-02-04 14:38:44 +08001188 }
1189 // Invalid: test devices with property id wrong format.
1190 {
1191 json configFile = validConfigFile;
1192 configFile["chassis"][0]["devices"][0]["id"] = "id#";
1193 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001194 "'id#' does not match '^[A-Za-z0-9_]+$'");
Bob Kinga2ba2df2020-02-04 14:38:44 +08001195 }
1196 // Invalid: test devices with property rails empty array.
1197 {
1198 json configFile = validConfigFile;
1199 configFile["chassis"][0]["devices"][0]["rails"] = json::array();
1200 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1201 "[] is too short");
1202 }
1203}
Shawn McCarney846dde52021-08-14 12:47:44 -05001204
1205TEST(ValidateRegulatorsConfigTest, I2CCaptureBytes)
1206{
1207 json initialFile = validConfigFile;
1208 initialFile["rules"][0]["actions"][1]["i2c_capture_bytes"]["register"] =
1209 "0xA0";
1210 initialFile["rules"][0]["actions"][1]["i2c_capture_bytes"]["count"] = 2;
1211
1212 // Valid: All required properties
1213 {
1214 json configFile = initialFile;
1215 EXPECT_JSON_VALID(configFile);
1216 }
1217
1218 // Invalid: register not specified
1219 {
1220 json configFile = initialFile;
1221 configFile["rules"][0]["actions"][1]["i2c_capture_bytes"].erase(
1222 "register");
1223 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1224 "'register' is a required property");
1225 }
1226
1227 // Invalid: count not specified
1228 {
1229 json configFile = initialFile;
1230 configFile["rules"][0]["actions"][1]["i2c_capture_bytes"].erase(
1231 "count");
1232 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1233 "'count' is a required property");
1234 }
1235
1236 // Invalid: invalid property specified
1237 {
1238 json configFile = initialFile;
1239 configFile["rules"][0]["actions"][1]["i2c_capture_bytes"]["foo"] = true;
1240 EXPECT_JSON_INVALID(
1241 configFile, "Validation failed.",
1242 "Additional properties are not allowed ('foo' was unexpected)");
1243 }
1244
1245 // Invalid: register has wrong data type
1246 {
1247 json configFile = initialFile;
1248 configFile["rules"][0]["actions"][1]["i2c_capture_bytes"]["register"] =
1249 1;
1250 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1251 "1 is not of type 'string'");
1252 }
1253
1254 // Invalid: register has wrong format
1255 {
1256 json configFile = initialFile;
1257 configFile["rules"][0]["actions"][1]["i2c_capture_bytes"]["register"] =
1258 "0xA00";
1259 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1260 "'0xA00' does not match '^0x[0-9A-Fa-f]{2}$'");
1261 }
1262
1263 // Invalid: count has wrong data type
1264 {
1265 json configFile = initialFile;
1266 configFile["rules"][0]["actions"][1]["i2c_capture_bytes"]["count"] =
1267 3.1;
1268 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1269 "3.1 is not of type 'integer'");
1270 }
1271
1272 // Invalid: count < 1
1273 {
1274 json configFile = initialFile;
1275 configFile["rules"][0]["actions"][1]["i2c_capture_bytes"]["count"] = 0;
1276 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1277 "0 is less than the minimum of 1");
1278 }
1279}
1280
Bob King4ab8cbb2020-01-21 11:10:48 +08001281TEST(ValidateRegulatorsConfigTest, I2CCompareBit)
1282{
1283 json i2cCompareBitFile = validConfigFile;
1284 i2cCompareBitFile["rules"][0]["actions"][1]["i2c_compare_bit"]["register"] =
1285 "0xA0";
1286 i2cCompareBitFile["rules"][0]["actions"][1]["i2c_compare_bit"]["position"] =
1287 3;
1288 i2cCompareBitFile["rules"][0]["actions"][1]["i2c_compare_bit"]["value"] = 1;
1289 // Valid: test rule actions i2c_compare_bit.
1290 {
1291 json configFile = i2cCompareBitFile;
1292 EXPECT_JSON_VALID(configFile);
1293 }
1294 // Invalid: test i2c_compare_bit with no register.
1295 {
1296 json configFile = i2cCompareBitFile;
1297 configFile["rules"][0]["actions"][1]["i2c_compare_bit"].erase(
1298 "register");
1299 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001300 "'register' is a required property");
Bob King4ab8cbb2020-01-21 11:10:48 +08001301 }
1302 // Invalid: test i2c_compare_bit with no position.
1303 {
1304 json configFile = i2cCompareBitFile;
1305 configFile["rules"][0]["actions"][1]["i2c_compare_bit"].erase(
1306 "position");
1307 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001308 "'position' is a required property");
Bob King4ab8cbb2020-01-21 11:10:48 +08001309 }
1310 // Invalid: test i2c_compare_bit with no value.
1311 {
1312 json configFile = i2cCompareBitFile;
1313 configFile["rules"][0]["actions"][1]["i2c_compare_bit"].erase("value");
1314 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001315 "'value' is a required property");
Bob King4ab8cbb2020-01-21 11:10:48 +08001316 }
1317 // Invalid: test i2c_compare_bit with register wrong type.
1318 {
1319 json configFile = i2cCompareBitFile;
1320 configFile["rules"][0]["actions"][1]["i2c_compare_bit"]["register"] = 1;
1321 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001322 "1 is not of type 'string'");
Bob King4ab8cbb2020-01-21 11:10:48 +08001323 }
1324 // Invalid: test i2c_compare_bit with register wrong format.
1325 {
1326 json configFile = i2cCompareBitFile;
1327 configFile["rules"][0]["actions"][1]["i2c_compare_bit"]["register"] =
1328 "0xA00";
1329 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001330 "'0xA00' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King4ab8cbb2020-01-21 11:10:48 +08001331 }
1332 // Invalid: test i2c_compare_bit with position wrong type.
1333 {
1334 json configFile = i2cCompareBitFile;
1335 configFile["rules"][0]["actions"][1]["i2c_compare_bit"]["position"] =
1336 3.1;
1337 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001338 "3.1 is not of type 'integer'");
Bob King4ab8cbb2020-01-21 11:10:48 +08001339 }
1340 // Invalid: test i2c_compare_bit with position greater than 7.
1341 {
1342 json configFile = i2cCompareBitFile;
1343 configFile["rules"][0]["actions"][1]["i2c_compare_bit"]["position"] = 8;
1344 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1345 "8 is greater than the maximum of 7");
1346 }
1347 // Invalid: test i2c_compare_bit with position less than 0.
1348 {
1349 json configFile = i2cCompareBitFile;
1350 configFile["rules"][0]["actions"][1]["i2c_compare_bit"]["position"] =
1351 -1;
1352 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1353 "-1 is less than the minimum of 0");
1354 }
1355 // Invalid: test i2c_compare_bit with value wrong type.
1356 {
1357 json configFile = i2cCompareBitFile;
1358 configFile["rules"][0]["actions"][1]["i2c_compare_bit"]["value"] = "1";
1359 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001360 "'1' is not of type 'integer'");
Bob King4ab8cbb2020-01-21 11:10:48 +08001361 }
1362 // Invalid: test i2c_compare_bit with value greater than 1.
1363 {
1364 json configFile = i2cCompareBitFile;
1365 configFile["rules"][0]["actions"][1]["i2c_compare_bit"]["value"] = 2;
1366 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1367 "2 is greater than the maximum of 1");
1368 }
1369 // Invalid: test i2c_compare_bit with value less than 0.
1370 {
1371 json configFile = i2cCompareBitFile;
1372 configFile["rules"][0]["actions"][1]["i2c_compare_bit"]["value"] = -1;
1373 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1374 "-1 is less than the minimum of 0");
1375 }
1376}
Shawn McCarney846dde52021-08-14 12:47:44 -05001377
Bob King514023d2020-01-21 11:13:05 +08001378TEST(ValidateRegulatorsConfigTest, I2CCompareByte)
1379{
1380 json i2cCompareByteFile = validConfigFile;
1381 i2cCompareByteFile["rules"][0]["actions"][1]["i2c_compare_byte"]
1382 ["register"] = "0x82";
1383 i2cCompareByteFile["rules"][0]["actions"][1]["i2c_compare_byte"]["value"] =
1384 "0x40";
1385 i2cCompareByteFile["rules"][0]["actions"][1]["i2c_compare_byte"]["mask"] =
1386 "0x7F";
1387 // Valid: test i2c_compare_byte with all properties.
1388 {
1389 json configFile = i2cCompareByteFile;
1390 EXPECT_JSON_VALID(configFile);
1391 }
1392 // Valid: test i2c_compare_byte with all required properties.
1393 {
1394 json configFile = i2cCompareByteFile;
1395 configFile["rules"][0]["actions"][1]["i2c_compare_byte"].erase("mask");
1396 EXPECT_JSON_VALID(configFile);
1397 }
1398 // Invalid: test i2c_compare_byte with no register.
1399 {
1400 json configFile = i2cCompareByteFile;
1401 configFile["rules"][0]["actions"][1]["i2c_compare_byte"].erase(
1402 "register");
1403 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001404 "'register' is a required property");
Bob King514023d2020-01-21 11:13:05 +08001405 }
1406 // Invalid: test i2c_compare_byte with no value.
1407 {
1408 json configFile = i2cCompareByteFile;
1409 configFile["rules"][0]["actions"][1]["i2c_compare_byte"].erase("value");
1410 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001411 "'value' is a required property");
Bob King514023d2020-01-21 11:13:05 +08001412 }
1413 // Invalid: test i2c_compare_byte with property register wrong type.
1414 {
1415 json configFile = i2cCompareByteFile;
1416 configFile["rules"][0]["actions"][1]["i2c_compare_byte"]["register"] =
1417 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 value wrong type.
1422 {
1423 json configFile = i2cCompareByteFile;
1424 configFile["rules"][0]["actions"][1]["i2c_compare_byte"]["value"] = 1;
1425 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001426 "1 is not of type 'string'");
Bob King514023d2020-01-21 11:13:05 +08001427 }
1428 // Invalid: test i2c_compare_byte with property mask wrong type.
1429 {
1430 json configFile = i2cCompareByteFile;
1431 configFile["rules"][0]["actions"][1]["i2c_compare_byte"]["mask"] = 1;
1432 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001433 "1 is not of type 'string'");
Bob King514023d2020-01-21 11:13:05 +08001434 }
1435 // Invalid: test i2c_compare_byte with property register more than 2 hex
1436 // digits.
1437 {
1438 json configFile = i2cCompareByteFile;
1439 configFile["rules"][0]["actions"][1]["i2c_compare_byte"]["register"] =
1440 "0x820";
1441 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001442 "'0x820' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King514023d2020-01-21 11:13:05 +08001443 }
1444 // Invalid: test i2c_compare_byte with property value more than 2 hex
1445 // digits.
1446 {
1447 json configFile = i2cCompareByteFile;
1448 configFile["rules"][0]["actions"][1]["i2c_compare_byte"]["value"] =
1449 "0x820";
1450 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001451 "'0x820' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King514023d2020-01-21 11:13:05 +08001452 }
1453 // Invalid: test i2c_compare_byte with property mask more than 2 hex digits.
1454 {
1455 json configFile = i2cCompareByteFile;
1456 configFile["rules"][0]["actions"][1]["i2c_compare_byte"]["mask"] =
1457 "0x820";
1458 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001459 "'0x820' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King514023d2020-01-21 11:13:05 +08001460 }
1461 // Invalid: test i2c_compare_byte with property register less than 2 hex
1462 // digits.
1463 {
1464 json configFile = i2cCompareByteFile;
1465 configFile["rules"][0]["actions"][1]["i2c_compare_byte"]["register"] =
1466 "0x8";
1467 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001468 "'0x8' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King514023d2020-01-21 11:13:05 +08001469 }
1470 // Invalid: test i2c_compare_byte with property value less than 2 hex
1471 // digits.
1472 {
1473 json configFile = i2cCompareByteFile;
1474 configFile["rules"][0]["actions"][1]["i2c_compare_byte"]["value"] =
1475 "0x8";
1476 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001477 "'0x8' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King514023d2020-01-21 11:13:05 +08001478 }
1479 // Invalid: test i2c_compare_byte with property mask less than 2 hex digits.
1480 {
1481 json configFile = i2cCompareByteFile;
1482 configFile["rules"][0]["actions"][1]["i2c_compare_byte"]["mask"] =
1483 "0x8";
1484 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001485 "'0x8' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King514023d2020-01-21 11:13:05 +08001486 }
1487 // Invalid: test i2c_compare_byte with property register no leading prefix.
1488 {
1489 json configFile = i2cCompareByteFile;
1490 configFile["rules"][0]["actions"][1]["i2c_compare_byte"]["register"] =
1491 "82";
1492 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001493 "'82' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King514023d2020-01-21 11:13:05 +08001494 }
1495 // Invalid: test i2c_compare_byte with property value no leading prefix.
1496 {
1497 json configFile = i2cCompareByteFile;
1498 configFile["rules"][0]["actions"][1]["i2c_compare_byte"]["value"] =
1499 "82";
1500 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001501 "'82' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King514023d2020-01-21 11:13:05 +08001502 }
1503 // Invalid: test i2c_compare_byte with property mask no leading prefix.
1504 {
1505 json configFile = i2cCompareByteFile;
1506 configFile["rules"][0]["actions"][1]["i2c_compare_byte"]["mask"] = "82";
1507 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001508 "'82' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King514023d2020-01-21 11:13:05 +08001509 }
1510 // Invalid: test i2c_compare_byte with property register invalid hex digit.
1511 {
1512 json configFile = i2cCompareByteFile;
1513 configFile["rules"][0]["actions"][1]["i2c_compare_byte"]["register"] =
1514 "0xG1";
1515 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001516 "'0xG1' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King514023d2020-01-21 11:13:05 +08001517 }
1518 // Invalid: test i2c_compare_byte with property value invalid hex digit.
1519 {
1520 json configFile = i2cCompareByteFile;
1521 configFile["rules"][0]["actions"][1]["i2c_compare_byte"]["value"] =
1522 "0xG1";
1523 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001524 "'0xG1' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King514023d2020-01-21 11:13:05 +08001525 }
1526 // Invalid: test i2c_compare_byte with property mask invalid hex digit.
1527 {
1528 json configFile = i2cCompareByteFile;
1529 configFile["rules"][0]["actions"][1]["i2c_compare_byte"]["mask"] =
1530 "0xG1";
1531 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001532 "'0xG1' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King514023d2020-01-21 11:13:05 +08001533 }
1534}
Shawn McCarney846dde52021-08-14 12:47:44 -05001535
Bob Kingfb162bb2020-01-21 11:28:07 +08001536TEST(ValidateRegulatorsConfigTest, I2CCompareBytes)
1537{
1538 json i2cCompareBytesFile = validConfigFile;
1539 i2cCompareBytesFile["rules"][0]["actions"][1]["i2c_compare_bytes"]
1540 ["register"] = "0x82";
1541 i2cCompareBytesFile["rules"][0]["actions"][1]["i2c_compare_bytes"]
1542 ["values"] = {"0x02", "0x73"};
1543 i2cCompareBytesFile["rules"][0]["actions"][1]["i2c_compare_bytes"]
1544 ["masks"] = {"0x7F", "0x7F"};
1545 // Valid: test i2c_compare_bytes.
1546 {
1547 json configFile = i2cCompareBytesFile;
1548 EXPECT_JSON_VALID(configFile);
1549 }
1550 // Valid: test i2c_compare_bytes with all required properties.
1551 {
1552 json configFile = i2cCompareBytesFile;
1553 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"].erase(
1554 "masks");
1555 EXPECT_JSON_VALID(configFile);
1556 }
1557 // Invalid: test i2c_compare_bytes with no register.
1558 {
1559 json configFile = i2cCompareBytesFile;
1560 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"].erase(
1561 "register");
1562 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001563 "'register' is a required property");
Bob Kingfb162bb2020-01-21 11:28:07 +08001564 }
1565 // Invalid: test i2c_compare_bytes with no values.
1566 {
1567 json configFile = i2cCompareBytesFile;
1568 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"].erase(
1569 "values");
1570 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001571 "'values' is a required property");
Bob Kingfb162bb2020-01-21 11:28:07 +08001572 }
1573 // Invalid: test i2c_compare_bytes with property values as empty array.
1574 {
1575 json configFile = i2cCompareBytesFile;
1576 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["values"] =
1577 json::array();
1578 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1579 "[] is too short");
1580 }
1581 // Invalid: test i2c_compare_bytes with property masks as empty array.
1582 {
1583 json configFile = i2cCompareBytesFile;
1584 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["masks"] =
1585 json::array();
1586 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1587 "[] is too short");
1588 }
1589 // Invalid: test i2c_compare_bytes with property register wrong type.
1590 {
1591 json configFile = i2cCompareBytesFile;
1592 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["register"] =
1593 1;
1594 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001595 "1 is not of type 'string'");
Bob Kingfb162bb2020-01-21 11:28:07 +08001596 }
1597 // Invalid: test i2c_compare_bytes with property values wrong type.
1598 {
1599 json configFile = i2cCompareBytesFile;
1600 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["values"] = 1;
1601 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001602 "1 is not of type 'array'");
Bob Kingfb162bb2020-01-21 11:28:07 +08001603 }
1604 // Invalid: test i2c_compare_bytes with property masks wrong type.
1605 {
1606 json configFile = i2cCompareBytesFile;
1607 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["masks"] = 1;
1608 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001609 "1 is not of type 'array'");
Bob Kingfb162bb2020-01-21 11:28:07 +08001610 }
1611 // Invalid: test i2c_compare_bytes with property register more than 2 hex
1612 // digits.
1613 {
1614 json configFile = i2cCompareBytesFile;
1615 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["register"] =
1616 "0x820";
1617 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001618 "'0x820' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob Kingfb162bb2020-01-21 11:28:07 +08001619 }
1620 // Invalid: test i2c_compare_bytes with property values more than 2 hex
1621 // digits.
1622 {
1623 json configFile = i2cCompareBytesFile;
1624 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["values"][0] =
1625 "0x820";
1626 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001627 "'0x820' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob Kingfb162bb2020-01-21 11:28:07 +08001628 }
1629 // Invalid: test i2c_compare_bytes with property masks more than 2 hex
1630 // digits.
1631 {
1632 json configFile = i2cCompareBytesFile;
1633 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["masks"][0] =
1634 "0x820";
1635 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001636 "'0x820' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob Kingfb162bb2020-01-21 11:28:07 +08001637 }
1638 // Invalid: test i2c_compare_bytes with property register less than 2 hex
1639 // digits.
1640 {
1641 json configFile = i2cCompareBytesFile;
1642 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["register"] =
1643 "0x8";
1644 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001645 "'0x8' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob Kingfb162bb2020-01-21 11:28:07 +08001646 }
1647 // Invalid: test i2c_compare_bytes with property values less than 2 hex
1648 // digits.
1649 {
1650 json configFile = i2cCompareBytesFile;
1651 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["values"][0] =
1652 "0x8";
1653 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001654 "'0x8' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob Kingfb162bb2020-01-21 11:28:07 +08001655 }
1656 // Invalid: test i2c_compare_bytes with property masks less than 2 hex
1657 // digits.
1658 {
1659 json configFile = i2cCompareBytesFile;
1660 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["masks"][0] =
1661 "0x8";
1662 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001663 "'0x8' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob Kingfb162bb2020-01-21 11:28:07 +08001664 }
1665 // Invalid: test i2c_compare_bytes with property register no leading prefix.
1666 {
1667 json configFile = i2cCompareBytesFile;
1668 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["register"] =
1669 "82";
1670 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001671 "'82' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob Kingfb162bb2020-01-21 11:28:07 +08001672 }
1673 // Invalid: test i2c_compare_bytes with property values no leading prefix.
1674 {
1675 json configFile = i2cCompareBytesFile;
1676 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["values"][0] =
1677 "82";
1678 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001679 "'82' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob Kingfb162bb2020-01-21 11:28:07 +08001680 }
1681 // Invalid: test i2c_compare_bytes with property masks no leading prefix.
1682 {
1683 json configFile = i2cCompareBytesFile;
1684 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["masks"][0] =
1685 "82";
1686 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001687 "'82' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob Kingfb162bb2020-01-21 11:28:07 +08001688 }
1689 // Invalid: test i2c_compare_bytes with property register invalid hex digit.
1690 {
1691 json configFile = i2cCompareBytesFile;
1692 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["register"] =
1693 "0xG1";
1694 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001695 "'0xG1' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob Kingfb162bb2020-01-21 11:28:07 +08001696 }
1697 // Invalid: test i2c_compare_bytes with property values invalid hex digit.
1698 {
1699 json configFile = i2cCompareBytesFile;
1700 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["values"][0] =
1701 "0xG1";
1702 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001703 "'0xG1' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob Kingfb162bb2020-01-21 11:28:07 +08001704 }
1705 // Invalid: test i2c_compare_bytes with property masks invalid hex digit.
1706 {
1707 json configFile = i2cCompareBytesFile;
1708 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["masks"][0] =
1709 "0xG1";
1710 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001711 "'0xG1' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob Kingfb162bb2020-01-21 11:28:07 +08001712 }
1713}
Shawn McCarney846dde52021-08-14 12:47:44 -05001714
Bob Kingca93f1f2020-01-31 11:21:16 +08001715TEST(ValidateRegulatorsConfigTest, I2CInterface)
1716{
1717 // Valid: test i2c_interface.
1718 {
1719 json configFile = validConfigFile;
1720 EXPECT_JSON_VALID(configFile);
1721 }
1722 // Invalid: testi2c_interface with no bus.
1723 {
1724 json configFile = validConfigFile;
1725 configFile["chassis"][0]["devices"][0]["i2c_interface"].erase("bus");
1726 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001727 "'bus' is a required property");
Bob Kingca93f1f2020-01-31 11:21:16 +08001728 }
1729 // Invalid: test i2c_interface with no address.
1730 {
1731 json configFile = validConfigFile;
1732 configFile["chassis"][0]["devices"][0]["i2c_interface"].erase(
1733 "address");
1734 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001735 "'address' is a required property");
Bob Kingca93f1f2020-01-31 11:21:16 +08001736 }
1737 // Invalid: test i2c_interface with property bus wrong type.
1738 {
1739 json configFile = validConfigFile;
1740 configFile["chassis"][0]["devices"][0]["i2c_interface"]["bus"] = true;
1741 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001742 "True is not of type 'integer'");
Bob Kingca93f1f2020-01-31 11:21:16 +08001743 }
1744 // Invalid: test i2c_interface with property address wrong
1745 // type.
1746 {
1747 json configFile = validConfigFile;
1748 configFile["chassis"][0]["devices"][0]["i2c_interface"]["address"] =
1749 true;
1750 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001751 "True is not of type 'string'");
Bob Kingca93f1f2020-01-31 11:21:16 +08001752 }
1753 // Invalid: test i2c_interface with property bus less than
1754 // 0.
1755 {
1756 json configFile = validConfigFile;
1757 configFile["chassis"][0]["devices"][0]["i2c_interface"]["bus"] = -1;
1758 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1759 "-1 is less than the minimum of 0");
1760 }
1761 // Invalid: test i2c_interface with property address wrong
1762 // format.
1763 {
1764 json configFile = validConfigFile;
1765 configFile["chassis"][0]["devices"][0]["i2c_interface"]["address"] =
1766 "0x700";
1767 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001768 "'0x700' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob Kingca93f1f2020-01-31 11:21:16 +08001769 }
1770}
Shawn McCarney846dde52021-08-14 12:47:44 -05001771
Bob King188db7d2020-01-31 13:01:01 +08001772TEST(ValidateRegulatorsConfigTest, I2CWriteBit)
1773{
1774 json i2cWriteBitFile = validConfigFile;
1775 i2cWriteBitFile["rules"][0]["actions"][1]["i2c_write_bit"]["register"] =
1776 "0xA0";
1777 i2cWriteBitFile["rules"][0]["actions"][1]["i2c_write_bit"]["position"] = 3;
1778 i2cWriteBitFile["rules"][0]["actions"][1]["i2c_write_bit"]["value"] = 1;
1779 // Valid: test rule actions i2c_write_bit.
1780 {
1781 json configFile = i2cWriteBitFile;
1782 EXPECT_JSON_VALID(configFile);
1783 }
1784 // Invalid: test i2c_write_bit with no register.
1785 {
1786 json configFile = i2cWriteBitFile;
1787 configFile["rules"][0]["actions"][1]["i2c_write_bit"].erase("register");
1788 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001789 "'register' is a required property");
Bob King188db7d2020-01-31 13:01:01 +08001790 }
1791 // Invalid: test i2c_write_bit with no position.
1792 {
1793 json configFile = i2cWriteBitFile;
1794 configFile["rules"][0]["actions"][1]["i2c_write_bit"].erase("position");
1795 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001796 "'position' is a required property");
Bob King188db7d2020-01-31 13:01:01 +08001797 }
1798 // Invalid: test i2c_write_bit with no value.
1799 {
1800 json configFile = i2cWriteBitFile;
1801 configFile["rules"][0]["actions"][1]["i2c_write_bit"].erase("value");
1802 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001803 "'value' is a required property");
Bob King188db7d2020-01-31 13:01:01 +08001804 }
1805 // Invalid: test i2c_write_bit with register wrong type.
1806 {
1807 json configFile = i2cWriteBitFile;
1808 configFile["rules"][0]["actions"][1]["i2c_write_bit"]["register"] = 1;
1809 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001810 "1 is not of type 'string'");
Bob King188db7d2020-01-31 13:01:01 +08001811 }
1812 // Invalid: test i2c_write_bit with register wrong format.
1813 {
1814 json configFile = i2cWriteBitFile;
1815 configFile["rules"][0]["actions"][1]["i2c_write_bit"]["register"] =
1816 "0xA00";
1817 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001818 "'0xA00' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08001819 }
1820 // Invalid: test i2c_write_bit with position wrong type.
1821 {
1822 json configFile = i2cWriteBitFile;
1823 configFile["rules"][0]["actions"][1]["i2c_write_bit"]["position"] = 3.1;
1824 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001825 "3.1 is not of type 'integer'");
Bob King188db7d2020-01-31 13:01:01 +08001826 }
1827 // Invalid: test i2c_write_bit with position greater than 7.
1828 {
1829 json configFile = i2cWriteBitFile;
1830 configFile["rules"][0]["actions"][1]["i2c_write_bit"]["position"] = 8;
1831 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1832 "8 is greater than the maximum of 7");
1833 }
1834 // Invalid: test i2c_write_bit with position less than 0.
1835 {
1836 json configFile = i2cWriteBitFile;
1837 configFile["rules"][0]["actions"][1]["i2c_write_bit"]["position"] = -1;
1838 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1839 "-1 is less than the minimum of 0");
1840 }
1841 // Invalid: test i2c_write_bit with value wrong type.
1842 {
1843 json configFile = i2cWriteBitFile;
1844 configFile["rules"][0]["actions"][1]["i2c_write_bit"]["value"] = "1";
1845 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001846 "'1' is not of type 'integer'");
Bob King188db7d2020-01-31 13:01:01 +08001847 }
1848 // Invalid: test i2c_write_bit with value greater than 1.
1849 {
1850 json configFile = i2cWriteBitFile;
1851 configFile["rules"][0]["actions"][1]["i2c_write_bit"]["value"] = 2;
1852 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1853 "2 is greater than the maximum of 1");
1854 }
1855 // Invalid: test i2c_write_bit with value less than 0.
1856 {
1857 json configFile = i2cWriteBitFile;
1858 configFile["rules"][0]["actions"][1]["i2c_write_bit"]["value"] = -1;
1859 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1860 "-1 is less than the minimum of 0");
1861 }
1862}
Shawn McCarney846dde52021-08-14 12:47:44 -05001863
Bob King188db7d2020-01-31 13:01:01 +08001864TEST(ValidateRegulatorsConfigTest, I2CWriteByte)
1865{
1866 json i2cWriteByteFile = validConfigFile;
1867 i2cWriteByteFile["rules"][0]["actions"][1]["i2c_write_byte"]["register"] =
1868 "0x82";
1869 i2cWriteByteFile["rules"][0]["actions"][1]["i2c_write_byte"]["value"] =
1870 "0x40";
1871 i2cWriteByteFile["rules"][0]["actions"][1]["i2c_write_byte"]["mask"] =
1872 "0x7F";
1873 // Valid: test i2c_write_byte with all properties.
1874 {
1875 json configFile = i2cWriteByteFile;
1876 EXPECT_JSON_VALID(configFile);
1877 }
1878 // Valid: test i2c_write_byte with all required properties.
1879 {
1880 json configFile = i2cWriteByteFile;
1881 configFile["rules"][0]["actions"][1]["i2c_write_byte"].erase("mask");
1882 EXPECT_JSON_VALID(configFile);
1883 }
1884 // Invalid: test i2c_write_byte with no register.
1885 {
1886 json configFile = i2cWriteByteFile;
1887 configFile["rules"][0]["actions"][1]["i2c_write_byte"].erase(
1888 "register");
1889 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001890 "'register' is a required property");
Bob King188db7d2020-01-31 13:01:01 +08001891 }
1892 // Invalid: test i2c_write_byte with no value.
1893 {
1894 json configFile = i2cWriteByteFile;
1895 configFile["rules"][0]["actions"][1]["i2c_write_byte"].erase("value");
1896 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001897 "'value' is a required property");
Bob King188db7d2020-01-31 13:01:01 +08001898 }
1899 // Invalid: test i2c_write_byte with property register wrong type.
1900 {
1901 json configFile = i2cWriteByteFile;
1902 configFile["rules"][0]["actions"][1]["i2c_write_byte"]["register"] = 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 value wrong type.
1907 {
1908 json configFile = i2cWriteByteFile;
1909 configFile["rules"][0]["actions"][1]["i2c_write_byte"]["value"] = 1;
1910 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001911 "1 is not of type 'string'");
Bob King188db7d2020-01-31 13:01:01 +08001912 }
1913 // Invalid: test i2c_write_byte with property mask wrong type.
1914 {
1915 json configFile = i2cWriteByteFile;
1916 configFile["rules"][0]["actions"][1]["i2c_write_byte"]["mask"] = 1;
1917 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001918 "1 is not of type 'string'");
Bob King188db7d2020-01-31 13:01:01 +08001919 }
1920 // Invalid: test i2c_write_byte with property register more than 2 hex
1921 // digits.
1922 {
1923 json configFile = i2cWriteByteFile;
1924 configFile["rules"][0]["actions"][1]["i2c_write_byte"]["register"] =
1925 "0x820";
1926 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001927 "'0x820' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08001928 }
1929 // Invalid: test i2c_write_byte with property value more than 2 hex
1930 // digits.
1931 {
1932 json configFile = i2cWriteByteFile;
1933 configFile["rules"][0]["actions"][1]["i2c_write_byte"]["value"] =
1934 "0x820";
1935 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001936 "'0x820' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08001937 }
1938 // Invalid: test i2c_write_byte with property mask more than 2 hex digits.
1939 {
1940 json configFile = i2cWriteByteFile;
1941 configFile["rules"][0]["actions"][1]["i2c_write_byte"]["mask"] =
1942 "0x820";
1943 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001944 "'0x820' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08001945 }
1946 // Invalid: test i2c_write_byte with property register less than 2 hex
1947 // digits.
1948 {
1949 json configFile = i2cWriteByteFile;
1950 configFile["rules"][0]["actions"][1]["i2c_write_byte"]["register"] =
1951 "0x8";
1952 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001953 "'0x8' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08001954 }
1955 // Invalid: test i2c_write_byte with property value less than 2 hex
1956 // digits.
1957 {
1958 json configFile = i2cWriteByteFile;
1959 configFile["rules"][0]["actions"][1]["i2c_write_byte"]["value"] = "0x8";
1960 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001961 "'0x8' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08001962 }
1963 // Invalid: test i2c_write_byte with property mask less than 2 hex digits.
1964 {
1965 json configFile = i2cWriteByteFile;
1966 configFile["rules"][0]["actions"][1]["i2c_write_byte"]["mask"] = "0x8";
1967 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001968 "'0x8' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08001969 }
1970 // Invalid: test i2c_write_byte with property register no leading prefix.
1971 {
1972 json configFile = i2cWriteByteFile;
1973 configFile["rules"][0]["actions"][1]["i2c_write_byte"]["register"] =
1974 "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 value no leading prefix.
1979 {
1980 json configFile = i2cWriteByteFile;
1981 configFile["rules"][0]["actions"][1]["i2c_write_byte"]["value"] = "82";
1982 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001983 "'82' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08001984 }
1985 // Invalid: test i2c_write_byte with property mask no leading prefix.
1986 {
1987 json configFile = i2cWriteByteFile;
1988 configFile["rules"][0]["actions"][1]["i2c_write_byte"]["mask"] = "82";
1989 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001990 "'82' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08001991 }
1992 // Invalid: test i2c_write_byte with property register invalid hex digit.
1993 {
1994 json configFile = i2cWriteByteFile;
1995 configFile["rules"][0]["actions"][1]["i2c_write_byte"]["register"] =
1996 "0xG1";
1997 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001998 "'0xG1' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08001999 }
2000 // Invalid: test i2c_write_byte with property value invalid hex digit.
2001 {
2002 json configFile = i2cWriteByteFile;
2003 configFile["rules"][0]["actions"][1]["i2c_write_byte"]["value"] =
2004 "0xG1";
2005 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002006 "'0xG1' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08002007 }
2008 // Invalid: test i2c_write_byte with property mask invalid hex digit.
2009 {
2010 json configFile = i2cWriteByteFile;
2011 configFile["rules"][0]["actions"][1]["i2c_write_byte"]["mask"] = "0xG1";
2012 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002013 "'0xG1' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08002014 }
2015}
Shawn McCarney846dde52021-08-14 12:47:44 -05002016
Bob King188db7d2020-01-31 13:01:01 +08002017TEST(ValidateRegulatorsConfigTest, I2CWriteBytes)
2018{
2019 json i2cWriteBytesFile = validConfigFile;
2020 i2cWriteBytesFile["rules"][0]["actions"][1]["i2c_write_bytes"]["register"] =
2021 "0x82";
2022 i2cWriteBytesFile["rules"][0]["actions"][1]["i2c_write_bytes"]["values"] = {
2023 "0x02", "0x73"};
2024 i2cWriteBytesFile["rules"][0]["actions"][1]["i2c_write_bytes"]["masks"] = {
2025 "0x7F", "0x7F"};
2026 // Valid: test i2c_write_bytes.
2027 {
2028 json configFile = i2cWriteBytesFile;
2029 EXPECT_JSON_VALID(configFile);
2030 }
2031 // Valid: test i2c_write_bytes with all required properties.
2032 {
2033 json configFile = i2cWriteBytesFile;
2034 configFile["rules"][0]["actions"][1]["i2c_write_bytes"].erase("masks");
2035 EXPECT_JSON_VALID(configFile);
2036 }
2037 // Invalid: test i2c_write_bytes with no register.
2038 {
2039 json configFile = i2cWriteBytesFile;
2040 configFile["rules"][0]["actions"][1]["i2c_write_bytes"].erase(
2041 "register");
2042 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002043 "'register' is a required property");
Bob King188db7d2020-01-31 13:01:01 +08002044 }
2045 // Invalid: test i2c_write_bytes with no values.
2046 {
2047 json configFile = i2cWriteBytesFile;
2048 configFile["rules"][0]["actions"][1]["i2c_write_bytes"].erase("values");
2049 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002050 "'values' is a required property");
Bob King188db7d2020-01-31 13:01:01 +08002051 }
2052 // Invalid: test i2c_write_bytes with property values as empty array.
2053 {
2054 json configFile = i2cWriteBytesFile;
2055 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["values"] =
2056 json::array();
2057 EXPECT_JSON_INVALID(configFile, "Validation failed.",
2058 "[] is too short");
2059 }
2060 // Invalid: test i2c_write_bytes with property masks as empty array.
2061 {
2062 json configFile = i2cWriteBytesFile;
2063 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["masks"] =
2064 json::array();
2065 EXPECT_JSON_INVALID(configFile, "Validation failed.",
2066 "[] is too short");
2067 }
2068 // Invalid: test i2c_write_bytes with property register wrong type.
2069 {
2070 json configFile = i2cWriteBytesFile;
2071 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["register"] = 1;
2072 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002073 "1 is not of type 'string'");
Bob King188db7d2020-01-31 13:01:01 +08002074 }
2075 // Invalid: test i2c_write_bytes with property values wrong type.
2076 {
2077 json configFile = i2cWriteBytesFile;
2078 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["values"] = 1;
2079 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002080 "1 is not of type 'array'");
Bob King188db7d2020-01-31 13:01:01 +08002081 }
2082 // Invalid: test i2c_write_bytes with property masks wrong type.
2083 {
2084 json configFile = i2cWriteBytesFile;
2085 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["masks"] = 1;
2086 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002087 "1 is not of type 'array'");
Bob King188db7d2020-01-31 13:01:01 +08002088 }
2089 // Invalid: test i2c_write_bytes with property register more than 2 hex
2090 // digits.
2091 {
2092 json configFile = i2cWriteBytesFile;
2093 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["register"] =
2094 "0x820";
2095 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002096 "'0x820' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08002097 }
2098 // Invalid: test i2c_write_bytes with property values more than 2 hex
2099 // digits.
2100 {
2101 json configFile = i2cWriteBytesFile;
2102 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["values"][0] =
2103 "0x820";
2104 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002105 "'0x820' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08002106 }
2107 // Invalid: test i2c_write_bytes with property masks more than 2 hex
2108 // digits.
2109 {
2110 json configFile = i2cWriteBytesFile;
2111 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["masks"][0] =
2112 "0x820";
2113 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002114 "'0x820' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08002115 }
2116 // Invalid: test i2c_write_bytes with property register less than 2 hex
2117 // digits.
2118 {
2119 json configFile = i2cWriteBytesFile;
2120 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["register"] =
2121 "0x8";
2122 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002123 "'0x8' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08002124 }
2125 // Invalid: test i2c_write_bytes with property values less than 2 hex
2126 // digits.
2127 {
2128 json configFile = i2cWriteBytesFile;
2129 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["values"][0] =
2130 "0x8";
2131 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002132 "'0x8' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08002133 }
2134 // Invalid: test i2c_write_bytes with property masks less than 2 hex
2135 // digits.
2136 {
2137 json configFile = i2cWriteBytesFile;
2138 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["masks"][0] =
2139 "0x8";
2140 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002141 "'0x8' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08002142 }
2143 // Invalid: test i2c_write_bytes with property register no leading prefix.
2144 {
2145 json configFile = i2cWriteBytesFile;
2146 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["register"] =
2147 "82";
2148 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002149 "'82' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08002150 }
2151 // Invalid: test i2c_write_bytes with property values no leading prefix.
2152 {
2153 json configFile = i2cWriteBytesFile;
2154 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["values"][0] =
2155 "82";
2156 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002157 "'82' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08002158 }
2159 // Invalid: test i2c_write_bytes with property masks no leading prefix.
2160 {
2161 json configFile = i2cWriteBytesFile;
2162 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["masks"][0] =
2163 "82";
2164 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002165 "'82' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08002166 }
2167 // Invalid: test i2c_write_bytes with property register invalid hex digit.
2168 {
2169 json configFile = i2cWriteBytesFile;
2170 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["register"] =
2171 "0xG1";
2172 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002173 "'0xG1' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08002174 }
2175 // Invalid: test i2c_write_bytes with property values invalid hex digit.
2176 {
2177 json configFile = i2cWriteBytesFile;
2178 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["values"][0] =
2179 "0xG1";
2180 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002181 "'0xG1' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08002182 }
2183 // Invalid: test i2c_write_bytes with property masks invalid hex digit.
2184 {
2185 json configFile = i2cWriteBytesFile;
2186 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["masks"][0] =
2187 "0xG1";
2188 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002189 "'0xG1' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08002190 }
2191}
Shawn McCarney846dde52021-08-14 12:47:44 -05002192
Bob Kingead0b052020-01-21 11:29:03 +08002193TEST(ValidateRegulatorsConfigTest, If)
2194{
2195 json ifFile = validConfigFile;
Shawn McCarney846dde52021-08-14 12:47:44 -05002196 ifFile["rules"][4]["actions"][0]["if"]["condition"]["run_rule"] =
Bob King2d27dcf2020-02-11 15:00:50 +08002197 "set_voltage_rule";
Shawn McCarney846dde52021-08-14 12:47:44 -05002198 ifFile["rules"][4]["actions"][0]["if"]["then"][0]["run_rule"] =
Bob King2d27dcf2020-02-11 15:00:50 +08002199 "read_sensors_rule";
Shawn McCarney846dde52021-08-14 12:47:44 -05002200 ifFile["rules"][4]["actions"][0]["if"]["else"][0]["run_rule"] =
Bob King2d27dcf2020-02-11 15:00:50 +08002201 "read_sensors_rule";
Shawn McCarney846dde52021-08-14 12:47:44 -05002202 ifFile["rules"][4]["id"] = "rule_if";
Bob Kingead0b052020-01-21 11:29:03 +08002203 // Valid: test if.
2204 {
2205 json configFile = ifFile;
2206 EXPECT_JSON_VALID(configFile);
2207 }
2208 // Valid: test if with required properties.
2209 {
2210 json configFile = ifFile;
Shawn McCarney846dde52021-08-14 12:47:44 -05002211 configFile["rules"][4]["actions"][0]["if"].erase("else");
Bob Kingead0b052020-01-21 11:29:03 +08002212 EXPECT_JSON_VALID(configFile);
2213 }
2214 // Invalid: test if with no property condition.
2215 {
2216 json configFile = ifFile;
Shawn McCarney846dde52021-08-14 12:47:44 -05002217 configFile["rules"][4]["actions"][0]["if"].erase("condition");
Bob Kingead0b052020-01-21 11:29:03 +08002218 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002219 "'condition' is a required property");
Bob Kingead0b052020-01-21 11:29:03 +08002220 }
2221 // Invalid: test if with no property then.
2222 {
2223 json configFile = ifFile;
Shawn McCarney846dde52021-08-14 12:47:44 -05002224 configFile["rules"][4]["actions"][0]["if"].erase("then");
Bob Kingead0b052020-01-21 11:29:03 +08002225 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002226 "'then' is a required property");
Bob Kingead0b052020-01-21 11:29:03 +08002227 }
2228 // Invalid: test if with property then empty array.
2229 {
2230 json configFile = ifFile;
Shawn McCarney846dde52021-08-14 12:47:44 -05002231 configFile["rules"][4]["actions"][0]["if"]["then"] = json::array();
Bob Kingead0b052020-01-21 11:29:03 +08002232 EXPECT_JSON_INVALID(configFile, "Validation failed.",
2233 "[] is too short");
2234 }
2235 // Invalid: test if with property else empty array.
2236 {
2237 json configFile = ifFile;
Shawn McCarney846dde52021-08-14 12:47:44 -05002238 configFile["rules"][4]["actions"][0]["if"]["else"] = json::array();
Bob Kingead0b052020-01-21 11:29:03 +08002239 EXPECT_JSON_INVALID(configFile, "Validation failed.",
2240 "[] is too short");
2241 }
2242 // Invalid: test if with property condition wrong type.
2243 {
2244 json configFile = ifFile;
Shawn McCarney846dde52021-08-14 12:47:44 -05002245 configFile["rules"][4]["actions"][0]["if"]["condition"] = 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 'object'");
Bob Kingead0b052020-01-21 11:29:03 +08002248 }
2249 // Invalid: test if with property then wrong type.
2250 {
2251 json configFile = ifFile;
Shawn McCarney846dde52021-08-14 12:47:44 -05002252 configFile["rules"][4]["actions"][0]["if"]["then"] = 1;
Bob Kingead0b052020-01-21 11:29:03 +08002253 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002254 "1 is not of type 'array'");
Bob Kingead0b052020-01-21 11:29:03 +08002255 }
2256 // Invalid: test if with property else wrong type.
2257 {
2258 json configFile = ifFile;
Shawn McCarney846dde52021-08-14 12:47:44 -05002259 configFile["rules"][4]["actions"][0]["if"]["else"] = 1;
Bob Kingead0b052020-01-21 11:29:03 +08002260 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002261 "1 is not of type 'array'");
Bob Kingead0b052020-01-21 11:29:03 +08002262 }
2263}
Shawn McCarney846dde52021-08-14 12:47:44 -05002264
2265TEST(ValidateRegulatorsConfigTest, LogPhaseFault)
2266{
2267 json initialFile = validConfigFile;
2268 initialFile["rules"][0]["actions"][1]["log_phase_fault"]["type"] = "n";
2269
2270 // Valid: All required properties
2271 {
2272 json configFile = initialFile;
2273 EXPECT_JSON_VALID(configFile);
2274 }
2275
2276 // Invalid: type not specified
2277 {
2278 json configFile = initialFile;
2279 configFile["rules"][0]["actions"][1]["log_phase_fault"].erase("type");
2280 EXPECT_JSON_INVALID(configFile, "Validation failed.",
2281 "'type' is a required property");
2282 }
2283
2284 // Invalid: invalid property specified
2285 {
2286 json configFile = initialFile;
2287 configFile["rules"][0]["actions"][1]["log_phase_fault"]["foo"] = true;
2288 EXPECT_JSON_INVALID(
2289 configFile, "Validation failed.",
2290 "Additional properties are not allowed ('foo' was unexpected)");
2291 }
2292
2293 // Invalid: type has wrong data type
2294 {
2295 json configFile = initialFile;
2296 configFile["rules"][0]["actions"][1]["log_phase_fault"]["type"] = true;
2297 EXPECT_JSON_INVALID(configFile, "Validation failed.",
2298 "True is not of type 'string'");
2299 }
2300
2301 // Invalid: type has invalid value
2302 {
2303 json configFile = initialFile;
2304 configFile["rules"][0]["actions"][1]["log_phase_fault"]["type"] = "n+2";
2305 EXPECT_JSON_INVALID(configFile, "Validation failed.",
2306 "'n+2' is not one of ['n+1', 'n']");
2307 }
2308}
2309
Bob Kingbfe9fe72020-01-21 11:29:57 +08002310TEST(ValidateRegulatorsConfigTest, Not)
2311{
2312 json notFile = validConfigFile;
2313 notFile["rules"][0]["actions"][1]["not"]["i2c_compare_byte"]["register"] =
2314 "0xA0";
2315 notFile["rules"][0]["actions"][1]["not"]["i2c_compare_byte"]["value"] =
2316 "0xFF";
2317 // Valid: test not.
2318 {
2319 json configFile = notFile;
2320 EXPECT_JSON_VALID(configFile);
2321 }
2322 // Invalid: test not with wrong type.
2323 {
2324 json configFile = notFile;
2325 configFile["rules"][0]["actions"][1]["not"] = 1;
2326 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002327 "1 is not of type 'object'");
Bob Kingbfe9fe72020-01-21 11:29:57 +08002328 }
2329}
Shawn McCarney846dde52021-08-14 12:47:44 -05002330
Bob Kingcfc29d02020-01-21 11:30:50 +08002331TEST(ValidateRegulatorsConfigTest, Or)
2332{
2333 json orFile = validConfigFile;
2334 orFile["rules"][0]["actions"][1]["or"][0]["i2c_compare_byte"]["register"] =
2335 "0xA0";
2336 orFile["rules"][0]["actions"][1]["or"][0]["i2c_compare_byte"]["value"] =
2337 "0x00";
2338 orFile["rules"][0]["actions"][1]["or"][1]["i2c_compare_byte"]["register"] =
2339 "0xA1";
2340 orFile["rules"][0]["actions"][1]["or"][1]["i2c_compare_byte"]["value"] =
2341 "0x00";
2342 // Valid: test or.
2343 {
2344 json configFile = orFile;
2345 EXPECT_JSON_VALID(configFile);
2346 }
2347 // Invalid: test or with empty array.
2348 {
2349 json configFile = orFile;
2350 configFile["rules"][0]["actions"][1]["or"] = json::array();
2351 EXPECT_JSON_INVALID(configFile, "Validation failed.",
2352 "[] is too short");
2353 }
2354 // Invalid: test or with wrong type.
2355 {
2356 json configFile = orFile;
2357 configFile["rules"][0]["actions"][1]["or"] = 1;
2358 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002359 "1 is not of type 'array'");
Bob Kingcfc29d02020-01-21 11:30:50 +08002360 }
2361}
Shawn McCarney846dde52021-08-14 12:47:44 -05002362
2363TEST(ValidateRegulatorsConfigTest, PhaseFaultDetection)
2364{
2365 json initialFile = validConfigFile;
2366 initialFile["chassis"][0]["devices"][0]["phase_fault_detection"]
2367 ["rule_id"] = "detect_phase_faults_rule";
2368
2369 // Valid: comments specified
2370 {
2371 json configFile = initialFile;
2372 configFile["chassis"][0]["devices"][0]["phase_fault_detection"]
2373 ["comments"][0] = "Detect phase faults";
2374 EXPECT_JSON_VALID(configFile);
2375 }
2376
2377 // Valid: device_id specified
2378 {
2379 json configFile = initialFile;
2380 configFile["chassis"][0]["devices"][0]["phase_fault_detection"]
2381 ["device_id"] = "vdd_regulator";
2382 EXPECT_JSON_VALID(configFile);
2383 }
2384
2385 // Valid: rule_id specified
2386 {
2387 json configFile = initialFile;
2388 EXPECT_JSON_VALID(configFile);
2389 }
2390
2391 // Valid: actions specified
2392 {
2393 json configFile = initialFile;
2394 configFile["chassis"][0]["devices"][0]["phase_fault_detection"].erase(
2395 "rule_id");
2396 configFile["chassis"][0]["devices"][0]["phase_fault_detection"]
2397 ["actions"][0]["run_rule"] = "detect_phase_faults_rule";
2398 EXPECT_JSON_VALID(configFile);
2399 }
2400
2401 // Invalid: rule_id and actions specified
2402 {
2403 json configFile = initialFile;
2404 configFile["chassis"][0]["devices"][0]["phase_fault_detection"]
2405 ["actions"][0]["run_rule"] = "detect_phase_faults_rule";
2406 EXPECT_JSON_INVALID(configFile, "Validation failed.", "");
2407 }
2408
2409 // Invalid: neither rule_id nor actions specified
2410 {
2411 json configFile = initialFile;
2412 configFile["chassis"][0]["devices"][0]["phase_fault_detection"].erase(
2413 "rule_id");
2414 EXPECT_JSON_INVALID(configFile, "Validation failed.",
2415 "'rule_id' is a required property");
2416 }
2417
2418 // Invalid: comments has wrong data type
2419 {
2420 json configFile = initialFile;
2421 configFile["chassis"][0]["devices"][0]["phase_fault_detection"]
2422 ["comments"] = true;
2423 EXPECT_JSON_INVALID(configFile, "Validation failed.",
2424 "True is not of type 'array'");
2425 }
2426
2427 // Invalid: device_id has wrong data type
2428 {
2429 json configFile = initialFile;
2430 configFile["chassis"][0]["devices"][0]["phase_fault_detection"]
2431 ["device_id"] = true;
2432 EXPECT_JSON_INVALID(configFile, "Validation failed.",
2433 "True is not of type 'string'");
2434 }
2435
2436 // Invalid: rule_id has wrong data type
2437 {
2438 json configFile = initialFile;
2439 configFile["chassis"][0]["devices"][0]["phase_fault_detection"]
2440 ["rule_id"] = true;
2441 EXPECT_JSON_INVALID(configFile, "Validation failed.",
2442 "True is not of type 'string'");
2443 }
2444
2445 // Invalid: actions has wrong data type
2446 {
2447 json configFile = initialFile;
2448 configFile["chassis"][0]["devices"][0]["phase_fault_detection"].erase(
2449 "rule_id");
2450 configFile["chassis"][0]["devices"][0]["phase_fault_detection"]
2451 ["actions"] = true;
2452 EXPECT_JSON_INVALID(configFile, "Validation failed.",
2453 "True is not of type 'array'");
2454 }
2455
2456 // Invalid: device_id has invalid format
2457 {
2458 json configFile = initialFile;
2459 configFile["chassis"][0]["devices"][0]["phase_fault_detection"]
2460 ["device_id"] = "id@";
2461 EXPECT_JSON_INVALID(configFile, "Validation failed.",
2462 "'id@' does not match '^[A-Za-z0-9_]+$'");
2463 }
2464
2465 // Invalid: rule_id has invalid format
2466 {
2467 json configFile = initialFile;
2468 configFile["chassis"][0]["devices"][0]["phase_fault_detection"]
2469 ["rule_id"] = "id@";
2470 EXPECT_JSON_INVALID(configFile, "Validation failed.",
2471 "'id@' does not match '^[A-Za-z0-9_]+$'");
2472 }
2473
2474 // Invalid: comments array is empty
2475 {
2476 json configFile = initialFile;
2477 configFile["chassis"][0]["devices"][0]["phase_fault_detection"]
2478 ["comments"] = json::array();
2479 EXPECT_JSON_INVALID(configFile, "Validation failed.",
2480 "[] is too short");
2481 }
2482
2483 // Invalid: actions array is empty
2484 {
2485 json configFile = initialFile;
2486 configFile["chassis"][0]["devices"][0]["phase_fault_detection"].erase(
2487 "rule_id");
2488 configFile["chassis"][0]["devices"][0]["phase_fault_detection"]
2489 ["actions"] = json::array();
2490 EXPECT_JSON_INVALID(configFile, "Validation failed.",
2491 "[] is too short");
2492 }
2493}
2494
Bob Kingd6618092020-01-21 11:31:46 +08002495TEST(ValidateRegulatorsConfigTest, PmbusReadSensor)
2496{
2497 json pmbusReadSensorFile = validConfigFile;
2498 pmbusReadSensorFile["rules"][0]["actions"][1]["pmbus_read_sensor"]["type"] =
2499 "vout";
2500 pmbusReadSensorFile["rules"][0]["actions"][1]["pmbus_read_sensor"]
2501 ["command"] = "0x8B";
2502 pmbusReadSensorFile["rules"][0]["actions"][1]["pmbus_read_sensor"]
2503 ["format"] = "linear_16";
2504 pmbusReadSensorFile["rules"][0]["actions"][1]["pmbus_read_sensor"]
2505 ["exponent"] = -8;
2506 // Valid: test pmbus_read_sensor.
2507 {
2508 json configFile = pmbusReadSensorFile;
2509 EXPECT_JSON_VALID(configFile);
2510 }
2511 // Valid: test pmbus_read_sensor with required properties.
2512 {
2513 json configFile = pmbusReadSensorFile;
2514 configFile["rules"][0]["actions"][1]["pmbus_read_sensor"].erase(
2515 "exponent");
2516 EXPECT_JSON_VALID(configFile);
2517 }
2518 // Invalid: test pmbus_read_sensor with no type.
2519 {
2520 json configFile = pmbusReadSensorFile;
2521 configFile["rules"][0]["actions"][1]["pmbus_read_sensor"].erase("type");
2522 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002523 "'type' is a required property");
Bob Kingd6618092020-01-21 11:31:46 +08002524 }
2525 // Invalid: test pmbus_read_sensor with no command.
2526 {
2527 json configFile = pmbusReadSensorFile;
2528 configFile["rules"][0]["actions"][1]["pmbus_read_sensor"].erase(
2529 "command");
2530 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002531 "'command' is a required property");
Bob Kingd6618092020-01-21 11:31:46 +08002532 }
2533 // Invalid: test pmbus_read_sensor with no format.
2534 {
2535 json configFile = pmbusReadSensorFile;
2536 configFile["rules"][0]["actions"][1]["pmbus_read_sensor"].erase(
2537 "format");
2538 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002539 "'format' is a required property");
Bob Kingd6618092020-01-21 11:31:46 +08002540 }
2541 // Invalid: test pmbus_read_sensor with property type wrong type.
2542 {
2543 json configFile = pmbusReadSensorFile;
2544 configFile["rules"][0]["actions"][1]["pmbus_read_sensor"]["type"] =
2545 true;
Bob King358c4172020-03-16 13:57:08 +08002546 EXPECT_JSON_INVALID(configFile, "Validation failed.",
2547 "True is not of type 'string'");
Bob Kingd6618092020-01-21 11:31:46 +08002548 }
2549 // Invalid: test pmbus_read_sensor with property command wrong type.
2550 {
2551 json configFile = pmbusReadSensorFile;
2552 configFile["rules"][0]["actions"][1]["pmbus_read_sensor"]["command"] =
2553 true;
2554 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002555 "True is not of type 'string'");
Bob Kingd6618092020-01-21 11:31:46 +08002556 }
2557 // Invalid: test pmbus_read_sensor with property format wrong type.
2558 {
2559 json configFile = pmbusReadSensorFile;
2560 configFile["rules"][0]["actions"][1]["pmbus_read_sensor"]["format"] =
2561 true;
2562 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002563 "True is not of type 'string'");
Bob Kingd6618092020-01-21 11:31:46 +08002564 }
2565 // Invalid: test pmbus_read_sensor with property exponent wrong type.
2566 {
2567 json configFile = pmbusReadSensorFile;
2568 configFile["rules"][0]["actions"][1]["pmbus_read_sensor"]["exponent"] =
2569 true;
2570 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002571 "True is not of type 'integer'");
Bob Kingd6618092020-01-21 11:31:46 +08002572 }
2573 // Invalid: test pmbus_read_sensor with property type wrong format.
2574 {
2575 json configFile = pmbusReadSensorFile;
2576 configFile["rules"][0]["actions"][1]["pmbus_read_sensor"]["type"] =
2577 "foo";
2578 EXPECT_JSON_INVALID(
2579 configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002580 "'foo' is not one of ['iout', 'iout_peak', 'iout_valley', "
2581 "'pout', 'temperature', 'temperature_peak', 'vout', "
2582 "'vout_peak', 'vout_valley']");
Bob Kingd6618092020-01-21 11:31:46 +08002583 }
2584 // Invalid: test pmbus_read_sensor with property command wrong format.
2585 {
2586 json configFile = pmbusReadSensorFile;
2587 configFile["rules"][0]["actions"][1]["pmbus_read_sensor"]["command"] =
2588 "0x8B0";
2589 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002590 "'0x8B0' does not match '^0x[0-9a-fA-F]{2}$'");
Bob Kingd6618092020-01-21 11:31:46 +08002591 }
2592 // Invalid: test pmbus_read_sensor with property format wrong format.
2593 {
2594 json configFile = pmbusReadSensorFile;
2595 configFile["rules"][0]["actions"][1]["pmbus_read_sensor"]["format"] =
2596 "foo";
Bob King358c4172020-03-16 13:57:08 +08002597 EXPECT_JSON_INVALID(configFile, "Validation failed.",
2598 "'foo' is not one of ['linear_11', 'linear_16']");
Bob Kingd6618092020-01-21 11:31:46 +08002599 }
2600}
Shawn McCarney846dde52021-08-14 12:47:44 -05002601
Bob King02179c62020-01-21 11:32:36 +08002602TEST(ValidateRegulatorsConfigTest, PmbusWriteVoutCommand)
2603{
2604 json pmbusWriteVoutCommandFile = validConfigFile;
2605 pmbusWriteVoutCommandFile["rules"][0]["actions"][1]
2606 ["pmbus_write_vout_command"]["volts"] = 1.03;
2607 pmbusWriteVoutCommandFile["rules"][0]["actions"][1]
2608 ["pmbus_write_vout_command"]["format"] = "linear";
2609 pmbusWriteVoutCommandFile["rules"][0]["actions"][1]
2610 ["pmbus_write_vout_command"]["exponent"] = -8;
2611 pmbusWriteVoutCommandFile["rules"][0]["actions"][1]
2612 ["pmbus_write_vout_command"]["is_verified"] = true;
2613 // Valid: test pmbus_write_vout_command.
2614 {
2615 json configFile = pmbusWriteVoutCommandFile;
2616 EXPECT_JSON_VALID(configFile);
2617 }
2618 // Valid: test pmbus_write_vout_command with required properties.
2619 {
2620 json configFile = pmbusWriteVoutCommandFile;
2621 configFile["rules"][0]["actions"][1]["pmbus_write_vout_command"].erase(
2622 "volts");
2623 configFile["rules"][0]["actions"][1]["pmbus_write_vout_command"].erase(
2624 "exponent");
2625 configFile["rules"][0]["actions"][1]["pmbus_write_vout_command"].erase(
2626 "is_verified");
2627 EXPECT_JSON_VALID(configFile);
2628 }
2629 // Invalid: test pmbus_write_vout_command with no format.
2630 {
2631 json configFile = pmbusWriteVoutCommandFile;
2632 configFile["rules"][0]["actions"][1]["pmbus_write_vout_command"].erase(
2633 "format");
2634 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002635 "'format' is a required property");
Bob King02179c62020-01-21 11:32:36 +08002636 }
2637 // Invalid: test pmbus_write_vout_command with property volts wrong type.
2638 {
2639 json configFile = pmbusWriteVoutCommandFile;
2640 configFile["rules"][0]["actions"][1]["pmbus_write_vout_command"]
2641 ["volts"] = true;
2642 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002643 "True is not of type 'number'");
Bob King02179c62020-01-21 11:32:36 +08002644 }
2645 // Invalid: test pmbus_write_vout_command with property format wrong type.
2646 {
2647 json configFile = pmbusWriteVoutCommandFile;
2648 configFile["rules"][0]["actions"][1]["pmbus_write_vout_command"]
2649 ["format"] = true;
2650 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002651 "True is not of type 'string'");
Bob King02179c62020-01-21 11:32:36 +08002652 }
2653 // Invalid: test pmbus_write_vout_command with property exponent wrong type.
2654 {
2655 json configFile = pmbusWriteVoutCommandFile;
2656 configFile["rules"][0]["actions"][1]["pmbus_write_vout_command"]
2657 ["exponent"] = 1.3;
2658 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002659 "1.3 is not of type 'integer'");
Bob King02179c62020-01-21 11:32:36 +08002660 }
2661 // Invalid: test pmbus_write_vout_command with property is_verified wrong
2662 // type.
2663 {
2664 json configFile = pmbusWriteVoutCommandFile;
2665 configFile["rules"][0]["actions"][1]["pmbus_write_vout_command"]
2666 ["is_verified"] = 1;
2667 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002668 "1 is not of type 'boolean'");
Bob King02179c62020-01-21 11:32:36 +08002669 }
2670 // Invalid: test pmbus_write_vout_command with property format wrong format.
2671 {
2672 json configFile = pmbusWriteVoutCommandFile;
2673 configFile["rules"][0]["actions"][1]["pmbus_write_vout_command"]
2674 ["format"] = "foo";
2675 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002676 "'foo' is not one of ['linear']");
Bob King02179c62020-01-21 11:32:36 +08002677 }
2678}
Shawn McCarney846dde52021-08-14 12:47:44 -05002679
Bob King99d8fa12020-01-31 11:23:40 +08002680TEST(ValidateRegulatorsConfigTest, PresenceDetection)
2681{
2682 json presenceDetectionFile = validConfigFile;
Bob King99d8fa12020-01-31 11:23:40 +08002683 presenceDetectionFile["chassis"][0]["devices"][0]["presence_detection"]
Shawn McCarney846dde52021-08-14 12:47:44 -05002684 ["comments"][0] =
2685 "Regulator is only present if CPU3 is present";
2686 presenceDetectionFile["chassis"][0]["devices"][0]["presence_detection"]
2687 ["rule_id"] = "detect_presence_rule";
Bob King99d8fa12020-01-31 11:23:40 +08002688 // Valid: test presence_detection with only property rule_id.
2689 {
2690 json configFile = presenceDetectionFile;
2691 EXPECT_JSON_VALID(configFile);
2692 }
2693 // Valid: test presence_detection with only property actions.
2694 {
2695 json configFile = presenceDetectionFile;
2696 configFile["chassis"][0]["devices"][0]["presence_detection"].erase(
2697 "rule_id");
2698 configFile["chassis"][0]["devices"][0]["presence_detection"]["actions"]
2699 [0]["compare_presence"]["fru"] =
Bob Kinga76898f2020-10-13 15:08:33 +08002700 "system/chassis/motherboard/cpu3";
Bob King99d8fa12020-01-31 11:23:40 +08002701 configFile["chassis"][0]["devices"][0]["presence_detection"]["actions"]
2702 [0]["compare_presence"]["value"] = true;
2703 configFile["chassis"][0]["devices"][0]["presence_detection"].erase(
2704 "comments");
2705 EXPECT_JSON_VALID(configFile);
2706 }
2707 // Invalid: test presence_detection with both property rule_id and actions.
2708 {
2709 json configFile = presenceDetectionFile;
2710 configFile["chassis"][0]["devices"][0]["presence_detection"]["actions"]
2711 [0]["compare_presence"]["fru"] =
Bob Kinga76898f2020-10-13 15:08:33 +08002712 "system/chassis/motherboard/cpu3";
Bob King99d8fa12020-01-31 11:23:40 +08002713 configFile["chassis"][0]["devices"][0]["presence_detection"]["actions"]
2714 [0]["compare_presence"]["value"] = true;
Shawn McCarney846dde52021-08-14 12:47:44 -05002715 EXPECT_JSON_INVALID(configFile, "Validation failed.", "");
Bob King99d8fa12020-01-31 11:23:40 +08002716 }
2717 // Invalid: test presence_detection with no rule_id and actions.
2718 {
2719 json configFile = presenceDetectionFile;
2720 configFile["chassis"][0]["devices"][0]["presence_detection"].erase(
2721 "rule_id");
2722 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002723 "'rule_id' is a required property");
Bob King99d8fa12020-01-31 11:23:40 +08002724 }
2725 // Invalid: test presence_detection with property comments wrong type.
2726 {
2727 json configFile = presenceDetectionFile;
2728 configFile["chassis"][0]["devices"][0]["presence_detection"]
2729 ["comments"] = true;
2730 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002731 "True is not of type 'array'");
Bob King99d8fa12020-01-31 11:23:40 +08002732 }
2733 // Invalid: test presence_detection with property rule_id wrong type.
2734 {
2735 json configFile = presenceDetectionFile;
2736 configFile["chassis"][0]["devices"][0]["presence_detection"]
2737 ["rule_id"] = true;
2738 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002739 "True is not of type 'string'");
Bob King99d8fa12020-01-31 11:23:40 +08002740 }
2741 // Invalid: test presence_detection with property actions wrong type.
2742 {
2743 json configFile = presenceDetectionFile;
2744 configFile["chassis"][0]["devices"][0]["presence_detection"].erase(
2745 "rule_id");
2746 configFile["chassis"][0]["devices"][0]["presence_detection"]
2747 ["actions"] = true;
2748 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002749 "True is not of type 'array'");
Bob King99d8fa12020-01-31 11:23:40 +08002750 }
2751 // Invalid: test presence_detection with property rule_id wrong format.
2752 {
2753 json configFile = presenceDetectionFile;
2754 configFile["chassis"][0]["devices"][0]["presence_detection"]
2755 ["rule_id"] = "id@";
2756 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002757 "'id@' does not match '^[A-Za-z0-9_]+$'");
Bob King99d8fa12020-01-31 11:23:40 +08002758 }
2759 // Invalid: test presence_detection with property comments empty array.
2760 {
2761 json configFile = presenceDetectionFile;
2762 configFile["chassis"][0]["devices"][0]["presence_detection"]
2763 ["comments"] = json::array();
2764 EXPECT_JSON_INVALID(configFile, "Validation failed.",
2765 "[] is too short");
2766 }
2767 // Invalid: test presence_detection with property actions empty array.
2768 {
2769 json configFile = presenceDetectionFile;
2770 configFile["chassis"][0]["devices"][0]["presence_detection"].erase(
2771 "rule_id");
2772 configFile["chassis"][0]["devices"][0]["presence_detection"]
2773 ["actions"] = json::array();
2774 EXPECT_JSON_INVALID(configFile, "Validation failed.",
2775 "[] is too short");
2776 }
2777}
Shawn McCarney846dde52021-08-14 12:47:44 -05002778
Bob Kinge9260b52020-01-21 11:46:13 +08002779TEST(ValidateRegulatorsConfigTest, Rail)
2780{
2781 // Valid: test rail.
2782 {
2783 json configFile = validConfigFile;
2784 EXPECT_JSON_VALID(configFile);
2785 }
2786 // Valid: test rail with required properties.
2787 {
2788 json configFile = validConfigFile;
2789 configFile["chassis"][0]["devices"][0]["rails"][0].erase("comments");
2790 configFile["chassis"][0]["devices"][0]["rails"][0].erase(
2791 "configuration");
2792 configFile["chassis"][0]["devices"][0]["rails"][0].erase(
2793 "sensor_monitoring");
2794 EXPECT_JSON_VALID(configFile);
2795 }
2796 // Invalid: test rail with no id.
2797 {
2798 json configFile = validConfigFile;
2799 configFile["chassis"][0]["devices"][0]["rails"][0].erase("id");
2800 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002801 "'id' is a required property");
Bob Kinge9260b52020-01-21 11:46:13 +08002802 }
2803 // Invalid: test rail with comments wrong type.
2804 {
2805 json configFile = validConfigFile;
2806 configFile["chassis"][0]["devices"][0]["rails"][0]["comments"] = true;
2807 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002808 "True is not of type 'array'");
Bob Kinge9260b52020-01-21 11:46:13 +08002809 }
2810 // Invalid: test rail with id wrong type.
2811 {
2812 json configFile = validConfigFile;
2813 configFile["chassis"][0]["devices"][0]["rails"][0]["id"] = true;
2814 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002815 "True is not of type 'string'");
Bob Kinge9260b52020-01-21 11:46:13 +08002816 }
2817 // Invalid: test rail with configuration wrong type.
2818 {
2819 json configFile = validConfigFile;
2820 configFile["chassis"][0]["devices"][0]["rails"][0]["configuration"] =
2821 true;
2822 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002823 "True is not of type 'object'");
Bob Kinge9260b52020-01-21 11:46:13 +08002824 }
2825 // Invalid: test rail with sensor_monitoring wrong type.
2826 {
2827 json configFile = validConfigFile;
2828 configFile["chassis"][0]["devices"][0]["rails"][0]
2829 ["sensor_monitoring"] = true;
2830 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002831 "True is not of type 'object'");
Bob Kinge9260b52020-01-21 11:46:13 +08002832 }
2833 // Invalid: test rail with comments empty array.
2834 {
2835 json configFile = validConfigFile;
2836 configFile["chassis"][0]["devices"][0]["rails"][0]["comments"] =
2837 json::array();
2838 EXPECT_JSON_INVALID(configFile, "Validation failed.",
2839 "[] is too short");
2840 }
2841 // Invalid: test rail with id wrong format.
2842 {
2843 json configFile = validConfigFile;
2844 configFile["chassis"][0]["devices"][0]["rails"][0]["id"] = "id~";
2845 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002846 "'id~' does not match '^[A-Za-z0-9_]+$'");
Bob Kinge9260b52020-01-21 11:46:13 +08002847 }
2848}
Shawn McCarney846dde52021-08-14 12:47:44 -05002849
Bob King64df7da2020-01-31 12:04:12 +08002850TEST(ValidateRegulatorsConfigTest, Rule)
2851{
2852 // valid test comments property, id property,
2853 // action property specified.
2854 {
2855 json configFile = validConfigFile;
2856 EXPECT_JSON_VALID(configFile);
2857 }
2858
2859 // valid test rule with no comments
2860 {
2861 json configFile = validConfigFile;
2862 configFile["rules"][0].erase("comments");
2863 EXPECT_JSON_VALID(configFile);
2864 }
2865
2866 // invalid test comments property has invalid value type
2867 {
2868 json configFile = validConfigFile;
2869 configFile["rules"][0]["comments"] = {1};
2870 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002871 "1 is not of type 'string'");
Bob King64df7da2020-01-31 12:04:12 +08002872 }
2873
2874 // invalid test rule with no ID
2875 {
2876 json configFile = validConfigFile;
2877 configFile["rules"][0].erase("id");
2878 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002879 "'id' is a required property");
Bob King64df7da2020-01-31 12:04:12 +08002880 }
2881
2882 // invalid test id property has invalid value type (not string)
2883 {
2884 json configFile = validConfigFile;
2885 configFile["rules"][0]["id"] = true;
2886 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002887 "True is not of type 'string'");
Bob King64df7da2020-01-31 12:04:12 +08002888 }
2889
2890 // invalid test id property has invalid value
2891 {
2892 json configFile = validConfigFile;
2893 configFile["rules"][0]["id"] = "foo%";
2894 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002895 "'foo%' does not match '^[A-Za-z0-9_]+$'");
Bob King64df7da2020-01-31 12:04:12 +08002896 }
2897
2898 // invalid test rule with no actions property
2899 {
2900 json configFile = validConfigFile;
2901 configFile["rules"][0].erase("actions");
2902 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002903 "'actions' is a required property");
Bob King64df7da2020-01-31 12:04:12 +08002904 }
2905
2906 // valid test rule with multiple actions
2907 {
2908 json configFile = validConfigFile;
Bob King63d795f2020-02-11 15:22:09 +08002909 configFile["rules"][0]["actions"][1]["run_rule"] = "read_sensors_rule";
Bob King64df7da2020-01-31 12:04:12 +08002910 EXPECT_JSON_VALID(configFile);
2911 }
2912
2913 // invalid test actions property has invalid value type (not an array)
2914 {
2915 json configFile = validConfigFile;
2916 configFile["rules"][0]["actions"] = 1;
2917 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002918 "1 is not of type 'array'");
Bob King64df7da2020-01-31 12:04:12 +08002919 }
2920
2921 // invalid test actions property has invalid value of action
2922 {
2923 json configFile = validConfigFile;
2924 configFile["rules"][0]["actions"][0] = "foo";
2925 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002926 "'foo' is not of type 'object'");
Bob King64df7da2020-01-31 12:04:12 +08002927 }
2928
2929 // invalid test actions property has empty array
2930 {
2931 json configFile = validConfigFile;
2932 configFile["rules"][0]["actions"] = json::array();
2933 EXPECT_JSON_INVALID(configFile, "Validation failed.",
2934 "[] is too short");
2935 }
2936}
Shawn McCarney846dde52021-08-14 12:47:44 -05002937
Bob Kinge86c2e52020-01-21 11:33:32 +08002938TEST(ValidateRegulatorsConfigTest, RunRule)
2939{
2940 json runRuleFile = validConfigFile;
Bob King7d3a9f12020-02-11 15:34:52 +08002941 runRuleFile["rules"][0]["actions"][1]["run_rule"] = "read_sensors_rule";
Bob Kinge86c2e52020-01-21 11:33:32 +08002942 // Valid: test run_rule.
2943 {
2944 json configFile = runRuleFile;
2945 EXPECT_JSON_VALID(configFile);
2946 }
2947 // Invalid: test run_rule wrong type.
2948 {
2949 json configFile = runRuleFile;
2950 configFile["rules"][0]["actions"][1]["run_rule"] = true;
2951 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002952 "True is not of type 'string'");
Bob Kinge86c2e52020-01-21 11:33:32 +08002953 }
2954 // Invalid: test run_rule wrong format.
2955 {
2956 json configFile = runRuleFile;
2957 configFile["rules"][0]["actions"][1]["run_rule"] = "set_voltage_rule%";
2958 EXPECT_JSON_INVALID(
2959 configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002960 "'set_voltage_rule%' does not match '^[A-Za-z0-9_]+$'");
Bob Kinge86c2e52020-01-21 11:33:32 +08002961 }
2962}
Shawn McCarney846dde52021-08-14 12:47:44 -05002963
Bob Kingfcc2a2f2020-01-31 11:29:45 +08002964TEST(ValidateRegulatorsConfigTest, SensorMonitoring)
2965{
2966 // Valid: test rails sensor_monitoring with only property rule id.
2967 {
2968 json configFile = validConfigFile;
2969 EXPECT_JSON_VALID(configFile);
2970 }
2971 // Valid: test rails sensor_monitoring with only property actions.
2972 {
2973 json configFile = validConfigFile;
2974 configFile["chassis"][0]["devices"][0]["rails"][0]["sensor_monitoring"]
2975 .erase("rule_id");
2976 configFile["chassis"][0]["devices"][0]["rails"][0]["sensor_monitoring"]
2977 ["actions"][0]["compare_presence"]["fru"] =
Bob Kinga76898f2020-10-13 15:08:33 +08002978 "system/chassis/motherboard/cpu3";
Bob Kingfcc2a2f2020-01-31 11:29:45 +08002979 configFile["chassis"][0]["devices"][0]["rails"][0]["sensor_monitoring"]
2980 ["actions"][0]["compare_presence"]["value"] = true;
2981 configFile["chassis"][0]["devices"][0]["rails"][0]["sensor_monitoring"]
2982 ["comments"][0] = "comments";
2983 EXPECT_JSON_VALID(configFile);
2984 }
2985 // Invalid: test rails sensor_monitoring with both property rule_id and
2986 // actions.
2987 {
2988 json configFile = validConfigFile;
2989 configFile["chassis"][0]["devices"][0]["rails"][0]["sensor_monitoring"]
2990 ["actions"][0]["compare_presence"]["fru"] =
Bob Kinga76898f2020-10-13 15:08:33 +08002991 "system/chassis/motherboard/cpu3";
Bob Kingfcc2a2f2020-01-31 11:29:45 +08002992 configFile["chassis"][0]["devices"][0]["rails"][0]["sensor_monitoring"]
2993 ["actions"][0]["compare_presence"]["value"] = true;
Shawn McCarney846dde52021-08-14 12:47:44 -05002994 EXPECT_JSON_INVALID(configFile, "Validation failed.", "");
Bob Kingfcc2a2f2020-01-31 11:29:45 +08002995 }
2996 // Invalid: test rails sensor_monitoring with no rule_id and actions.
2997 {
2998 json configFile = validConfigFile;
2999 configFile["chassis"][0]["devices"][0]["rails"][0]["sensor_monitoring"]
3000 .erase("rule_id");
3001 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08003002 "'rule_id' is a required property");
Bob Kingfcc2a2f2020-01-31 11:29:45 +08003003 }
3004 // Invalid: test rails sensor_monitoring with property comments wrong type.
3005 {
3006 json configFile = validConfigFile;
3007 configFile["chassis"][0]["devices"][0]["rails"][0]["sensor_monitoring"]
3008 ["comments"] = true;
3009 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08003010 "True is not of type 'array'");
Bob Kingfcc2a2f2020-01-31 11:29:45 +08003011 }
3012 // Invalid: test rails sensor_monitoring with property rule_id wrong type.
3013 {
3014 json configFile = validConfigFile;
3015 configFile["chassis"][0]["devices"][0]["rails"][0]["sensor_monitoring"]
3016 ["rule_id"] = true;
3017 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08003018 "True is not of type 'string'");
Bob Kingfcc2a2f2020-01-31 11:29:45 +08003019 }
3020 // Invalid: test rails sensor_monitoring with property actions wrong type.
3021 {
3022 json configFile = validConfigFile;
3023 configFile["chassis"][0]["devices"][0]["rails"][0]["sensor_monitoring"]
3024 .erase("rule_id");
3025 configFile["chassis"][0]["devices"][0]["rails"][0]["sensor_monitoring"]
3026 ["actions"] = true;
3027 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08003028 "True is not of type 'array'");
Bob Kingfcc2a2f2020-01-31 11:29:45 +08003029 }
3030 // Invalid: test rails sensor_monitoring with property rule_id wrong format.
3031 {
3032 json configFile = validConfigFile;
3033 configFile["chassis"][0]["devices"][0]["rails"][0]["sensor_monitoring"]
3034 ["rule_id"] = "id@";
3035 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08003036 "'id@' does not match '^[A-Za-z0-9_]+$'");
Bob Kingfcc2a2f2020-01-31 11:29:45 +08003037 }
3038 // Invalid: test rails sensor_monitoring with property comments empty array.
3039 {
3040 json configFile = validConfigFile;
3041 configFile["chassis"][0]["devices"][0]["rails"][0]["sensor_monitoring"]
3042 ["comments"] = json::array();
3043 EXPECT_JSON_INVALID(configFile, "Validation failed.",
3044 "[] is too short");
3045 }
3046 // Invalid: test rails sensor_monitoring with property actions empty array.
3047 {
3048 json configFile = validConfigFile;
3049 configFile["chassis"][0]["devices"][0]["rails"][0]["sensor_monitoring"]
3050 .erase("rule_id");
3051 configFile["chassis"][0]["devices"][0]["rails"][0]["sensor_monitoring"]
3052 ["actions"] = json::array();
3053 EXPECT_JSON_INVALID(configFile, "Validation failed.",
3054 "[] is too short");
3055 }
3056}
Shawn McCarney846dde52021-08-14 12:47:44 -05003057
Bob King68230aa2020-01-21 11:34:33 +08003058TEST(ValidateRegulatorsConfigTest, SetDevice)
3059{
3060 json setDeviceFile = validConfigFile;
Bob King7d3a9f12020-02-11 15:34:52 +08003061 setDeviceFile["rules"][0]["actions"][1]["set_device"] = "vdd_regulator";
Bob King68230aa2020-01-21 11:34:33 +08003062 // Valid: test set_device.
3063 {
3064 json configFile = setDeviceFile;
3065 EXPECT_JSON_VALID(configFile);
3066 }
3067 // Invalid: test set_device wrong type.
3068 {
3069 json configFile = setDeviceFile;
3070 configFile["rules"][0]["actions"][1]["set_device"] = true;
3071 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08003072 "True is not of type 'string'");
Bob King68230aa2020-01-21 11:34:33 +08003073 }
3074 // Invalid: test set_device wrong format.
3075 {
3076 json configFile = setDeviceFile;
3077 configFile["rules"][0]["actions"][1]["set_device"] = "io_expander2%";
Bob King358c4172020-03-16 13:57:08 +08003078 EXPECT_JSON_INVALID(configFile, "Validation failed.",
3079 "'io_expander2%' does not match '^[A-Za-z0-9_]+$'");
Bob King68230aa2020-01-21 11:34:33 +08003080 }
3081}
Shawn McCarney846dde52021-08-14 12:47:44 -05003082
Bob King3643cc02020-01-31 11:32:56 +08003083TEST(ValidateRegulatorsConfigTest, DuplicateRuleID)
3084{
3085 // Invalid: test duplicate ID in rule.
3086 {
3087 json configFile = validConfigFile;
Shawn McCarney846dde52021-08-14 12:47:44 -05003088 configFile["rules"][4]["id"] = "set_voltage_rule";
3089 configFile["rules"][4]["actions"][0]["pmbus_write_vout_command"]
Bob King3643cc02020-01-31 11:32:56 +08003090 ["format"] = "linear";
3091 EXPECT_JSON_INVALID(configFile, "Error: Duplicate rule ID.", "");
3092 }
3093}
Shawn McCarney846dde52021-08-14 12:47:44 -05003094
Bob King3643cc02020-01-31 11:32:56 +08003095TEST(ValidateRegulatorsConfigTest, DuplicateChassisNumber)
3096{
3097 // Invalid: test duplicate number in chassis.
3098 {
3099 json configFile = validConfigFile;
3100 configFile["chassis"][1]["number"] = 1;
Shawn McCarney4c88a4c2021-09-21 15:29:24 -05003101 configFile["chassis"][1]["inventory_path"] = "system/chassis2";
Bob King3643cc02020-01-31 11:32:56 +08003102 EXPECT_JSON_INVALID(configFile, "Error: Duplicate chassis number.", "");
3103 }
3104}
Shawn McCarney846dde52021-08-14 12:47:44 -05003105
Bob King3643cc02020-01-31 11:32:56 +08003106TEST(ValidateRegulatorsConfigTest, DuplicateDeviceID)
3107{
3108 // Invalid: test duplicate ID in device.
3109 {
3110 json configFile = validConfigFile;
3111 configFile["chassis"][0]["devices"][1]["id"] = "vdd_regulator";
3112 configFile["chassis"][0]["devices"][1]["is_regulator"] = true;
3113 configFile["chassis"][0]["devices"][1]["fru"] =
Bob Kinga76898f2020-10-13 15:08:33 +08003114 "system/chassis/motherboard/regulator1";
Bob King3643cc02020-01-31 11:32:56 +08003115 configFile["chassis"][0]["devices"][1]["i2c_interface"]["bus"] = 2;
3116 configFile["chassis"][0]["devices"][1]["i2c_interface"]["address"] =
3117 "0x71";
3118 EXPECT_JSON_INVALID(configFile, "Error: Duplicate device ID.", "");
3119 }
3120}
Shawn McCarney846dde52021-08-14 12:47:44 -05003121
Bob King3643cc02020-01-31 11:32:56 +08003122TEST(ValidateRegulatorsConfigTest, DuplicateRailID)
3123{
3124 // Invalid: test duplicate ID in rail.
3125 {
3126 json configFile = validConfigFile;
3127 configFile["chassis"][0]["devices"][0]["rails"][1]["id"] = "vdd";
3128 EXPECT_JSON_INVALID(configFile, "Error: Duplicate rail ID.", "");
3129 }
3130}
Shawn McCarney846dde52021-08-14 12:47:44 -05003131
Bob King78793102020-03-13 13:16:09 +08003132TEST(ValidateRegulatorsConfigTest, DuplicateObjectID)
3133{
3134 // Invalid: test duplicate object ID in device and rail.
3135 {
3136 json configFile = validConfigFile;
3137 configFile["chassis"][0]["devices"][0]["rails"][1]["id"] =
3138 "vdd_regulator";
3139 EXPECT_JSON_INVALID(configFile, "Error: Duplicate ID.", "");
3140 }
3141 // Invalid: test duplicate object ID in device and rule.
3142 {
3143 json configFile = validConfigFile;
Shawn McCarney846dde52021-08-14 12:47:44 -05003144 configFile["rules"][4]["id"] = "vdd_regulator";
3145 configFile["rules"][4]["actions"][0]["pmbus_write_vout_command"]
Bob King78793102020-03-13 13:16:09 +08003146 ["format"] = "linear";
3147 EXPECT_JSON_INVALID(configFile, "Error: Duplicate ID.", "");
3148 }
3149 // Invalid: test duplicate object ID in rule and rail.
3150 {
3151 json configFile = validConfigFile;
3152 configFile["chassis"][0]["devices"][0]["rails"][1]["id"] =
3153 "set_voltage_rule";
3154 EXPECT_JSON_INVALID(configFile, "Error: Duplicate ID.", "");
3155 }
3156}
Shawn McCarney846dde52021-08-14 12:47:44 -05003157
Bob King3643cc02020-01-31 11:32:56 +08003158TEST(ValidateRegulatorsConfigTest, InfiniteLoops)
3159{
3160 // Invalid: test run_rule with infinite loop (rules run each other).
3161 {
3162 json configFile = validConfigFile;
Shawn McCarney846dde52021-08-14 12:47:44 -05003163 configFile["rules"][4]["actions"][0]["run_rule"] = "set_voltage_rule2";
3164 configFile["rules"][4]["id"] = "set_voltage_rule1";
3165 configFile["rules"][5]["actions"][0]["run_rule"] = "set_voltage_rule1";
3166 configFile["rules"][5]["id"] = "set_voltage_rule2";
Bob King3643cc02020-01-31 11:32:56 +08003167 EXPECT_JSON_INVALID(configFile,
3168 "Infinite loop caused by run_rule actions.", "");
3169 }
3170 // Invalid: test run_rule with infinite loop (rule runs itself).
3171 {
3172 json configFile = validConfigFile;
Shawn McCarney846dde52021-08-14 12:47:44 -05003173 configFile["rules"][4]["actions"][0]["run_rule"] = "set_voltage_rule1";
3174 configFile["rules"][4]["id"] = "set_voltage_rule1";
Bob King3643cc02020-01-31 11:32:56 +08003175 EXPECT_JSON_INVALID(configFile,
3176 "Infinite loop caused by run_rule actions.", "");
3177 }
3178 // Invalid: test run_rule with infinite loop (indirect loop).
3179 {
3180 json configFile = validConfigFile;
Shawn McCarney846dde52021-08-14 12:47:44 -05003181 configFile["rules"][4]["actions"][0]["run_rule"] = "set_voltage_rule2";
3182 configFile["rules"][4]["id"] = "set_voltage_rule1";
3183 configFile["rules"][5]["actions"][0]["run_rule"] = "set_voltage_rule3";
3184 configFile["rules"][5]["id"] = "set_voltage_rule2";
3185 configFile["rules"][6]["actions"][0]["run_rule"] = "set_voltage_rule1";
3186 configFile["rules"][6]["id"] = "set_voltage_rule3";
Bob King3643cc02020-01-31 11:32:56 +08003187 EXPECT_JSON_INVALID(configFile,
3188 "Infinite loop caused by run_rule actions.", "");
3189 }
3190}
Shawn McCarney846dde52021-08-14 12:47:44 -05003191
Bob Kingf88203a2020-02-18 13:26:07 +08003192TEST(ValidateRegulatorsConfigTest, RunRuleValueExists)
3193{
3194 // Invalid: test run_rule actions specify a rule ID that does not exist.
3195 {
3196 json configFile = validConfigFile;
Shawn McCarney846dde52021-08-14 12:47:44 -05003197 configFile["rules"][4]["actions"][0]["run_rule"] = "set_voltage_rule2";
3198 configFile["rules"][4]["id"] = "set_voltage_rule1";
Bob Kingf88203a2020-02-18 13:26:07 +08003199 EXPECT_JSON_INVALID(configFile, "Error: Rule ID does not exist.", "");
3200 }
3201}
Shawn McCarney846dde52021-08-14 12:47:44 -05003202
Bob King13b2ad92020-02-18 13:31:39 +08003203TEST(ValidateRegulatorsConfigTest, SetDeviceValueExists)
3204{
3205 // Invalid: test set_device actions specify a device ID that does not exist.
3206 {
3207 json configFile = validConfigFile;
Shawn McCarney846dde52021-08-14 12:47:44 -05003208 configFile["rules"][4]["actions"][0]["set_device"] = "vdd_regulator2";
3209 configFile["rules"][4]["id"] = "set_voltage_rule1";
Bob King13b2ad92020-02-18 13:31:39 +08003210 EXPECT_JSON_INVALID(configFile, "Error: Device ID does not exist.", "");
3211 }
3212}
Shawn McCarney846dde52021-08-14 12:47:44 -05003213
Bob King21b09be2020-02-18 13:33:09 +08003214TEST(ValidateRegulatorsConfigTest, RuleIDExists)
3215{
3216 // Invalid: test rule_id property in configuration specifies a rule ID that
3217 // does not exist.
3218 {
3219 json configFile = validConfigFile;
3220 configFile["chassis"][0]["devices"][0]["configuration"]["rule_id"] =
3221 "set_voltage_rule2";
3222 EXPECT_JSON_INVALID(configFile, "Error: Rule ID does not exist.", "");
3223 }
3224 // Invalid: test rule_id property in presence_detection specifies a rule ID
3225 // that does not exist.
3226 {
3227 json configFile = validConfigFile;
3228 configFile["chassis"][0]["devices"][0]["presence_detection"]
Shawn McCarney5d4a9c72021-08-19 18:45:59 -05003229 ["rule_id"] = "detect_presence_rule2";
3230 EXPECT_JSON_INVALID(configFile, "Error: Rule ID does not exist.", "");
3231 }
3232 // Invalid: test rule_id property in phase_fault_detection specifies a rule
3233 // ID that does not exist.
3234 {
3235 json configFile = validConfigFile;
3236 configFile["chassis"][0]["devices"][0]["phase_fault_detection"]
3237 ["rule_id"] = "detect_phase_faults_rule2";
Bob King21b09be2020-02-18 13:33:09 +08003238 EXPECT_JSON_INVALID(configFile, "Error: Rule ID does not exist.", "");
3239 }
3240 // Invalid: test rule_id property in sensor_monitoring specifies a rule ID
3241 // that does not exist.
3242 {
3243 json configFile = validConfigFile;
3244 configFile["chassis"][0]["devices"][0]["rails"][0]["sensor_monitoring"]
Shawn McCarney5d4a9c72021-08-19 18:45:59 -05003245 ["rule_id"] = "read_sensors_rule2";
Bob King21b09be2020-02-18 13:33:09 +08003246 EXPECT_JSON_INVALID(configFile, "Error: Rule ID does not exist.", "");
3247 }
3248}
Shawn McCarney846dde52021-08-14 12:47:44 -05003249
Shawn McCarney5d4a9c72021-08-19 18:45:59 -05003250TEST(ValidateRegulatorsConfigTest, DeviceIDExists)
3251{
3252 // Invalid: test device_id property in phase_fault_detection specifies a
3253 // device ID that does not exist.
3254 {
3255 json configFile = validConfigFile;
3256 configFile["chassis"][0]["devices"][0]["phase_fault_detection"]
3257 ["device_id"] = "vdd_regulator2";
3258 configFile["chassis"][0]["devices"][0]["phase_fault_detection"]
3259 ["rule_id"] = "detect_phase_faults_rule";
3260 EXPECT_JSON_INVALID(configFile, "Error: Device ID does not exist.", "");
3261 }
3262}
3263
Bob Kingdc72b622020-02-18 13:36:18 +08003264TEST(ValidateRegulatorsConfigTest, NumberOfElementsInMasks)
3265{
3266 // Invalid: test number of elements in masks not equal to number in values
3267 // in i2c_compare_bytes.
3268 {
3269 json configFile = validConfigFile;
3270 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["register"] =
3271 "0x82";
3272 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["values"] = {
3273 "0x02", "0x73"};
3274 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["masks"] = {
3275 "0x7F"};
3276 EXPECT_JSON_INVALID(configFile,
3277 "Error: Invalid i2c_compare_bytes action.", "");
3278 }
3279 // Invalid: test number of elements in masks not equal to number in values
3280 // in i2c_write_bytes.
3281 {
3282 json configFile = validConfigFile;
3283 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["register"] =
3284 "0x82";
3285 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["values"] = {
3286 "0x02", "0x73"};
3287 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["masks"] = {
3288 "0x7F"};
3289 EXPECT_JSON_INVALID(configFile,
3290 "Error: Invalid i2c_write_bytes action.", "");
3291 }
3292}
Shawn McCarney846dde52021-08-14 12:47:44 -05003293
Bob Kinged009652020-02-20 14:54:13 +08003294TEST(ValidateRegulatorsConfigTest, CommandLineSyntax)
3295{
Bob Kinga57e0812020-03-12 10:47:42 +08003296 std::string validateTool =
3297 " ../phosphor-regulators/tools/validate-regulators-config.py ";
Bob Kinged009652020-02-20 14:54:13 +08003298 std::string schema = " -s ";
Bob Kinga57e0812020-03-12 10:47:42 +08003299 std::string schemaFile =
3300 " ../phosphor-regulators/schema/config_schema.json ";
Bob Kinged009652020-02-20 14:54:13 +08003301 std::string configuration = " -c ";
3302 std::string command;
3303 std::string errorMessage;
3304 std::string outputMessage;
3305 std::string outputMessageHelp =
3306 "usage: validate-regulators-config.py [-h] [-s SCHEMA_FILE]";
3307 int valid = 0;
3308
Shawn McCarney0f6ebad2020-09-04 16:43:00 -05003309 TemporaryFile tmpFile;
3310 std::string fileName = tmpFile.getPath().string();
Bob Kinga57e0812020-03-12 10:47:42 +08003311 writeDataToFile(validConfigFile, fileName);
Bob Kinged009652020-02-20 14:54:13 +08003312 // Valid: -s specified
3313 {
3314 command = validateTool + "-s " + schemaFile + configuration + fileName;
3315 expectCommandLineSyntax(errorMessage, outputMessage, command, valid);
3316 }
3317 // Valid: --schema-file specified
3318 {
3319 command = validateTool + "--schema-file " + schemaFile + configuration +
3320 fileName;
3321 expectCommandLineSyntax(errorMessage, outputMessage, command, valid);
3322 }
3323 // Valid: -c specified
3324 {
3325 command = validateTool + schema + schemaFile + "-c " + fileName;
3326 expectCommandLineSyntax(errorMessage, outputMessage, command, valid);
3327 }
3328 // Valid: --configuration-file specified
3329 {
3330 command = validateTool + schema + schemaFile + "--configuration-file " +
3331 fileName;
3332 expectCommandLineSyntax(errorMessage, outputMessage, command, valid);
3333 }
3334 // Valid: -h specified
3335 {
3336 command = validateTool + "-h ";
3337 expectCommandLineSyntax(errorMessage, outputMessageHelp, command,
3338 valid);
3339 }
3340 // Valid: --help specified
3341 {
3342 command = validateTool + "--help ";
3343 expectCommandLineSyntax(errorMessage, outputMessageHelp, command,
3344 valid);
3345 }
3346 // Invalid: -c/--configuration-file not specified
3347 {
3348 command = validateTool + schema + schemaFile;
3349 expectCommandLineSyntax("Error: Configuration file is required.",
3350 outputMessageHelp, command, 1);
3351 }
3352 // Invalid: -s/--schema-file not specified
3353 {
3354 command = validateTool + configuration + fileName;
3355 expectCommandLineSyntax("Error: Schema file is required.",
3356 outputMessageHelp, command, 1);
3357 }
Bob Kingb7552f02020-10-15 14:34:17 +08003358 // Invalid: -c specified more than once
3359 {
3360 command = validateTool + schema + schemaFile + "-c -c " + fileName;
3361 expectCommandLineSyntax(outputMessageHelp, outputMessage, command, 2);
3362 }
Bob Kinged009652020-02-20 14:54:13 +08003363 // Invalid: -s specified more than once
3364 {
3365 command =
3366 validateTool + "-s -s " + schemaFile + configuration + fileName;
3367 expectCommandLineSyntax(outputMessageHelp, outputMessage, command, 2);
3368 }
Bob Kinged009652020-02-20 14:54:13 +08003369 // Invalid: No file name specified after -c
3370 {
3371 command = validateTool + schema + schemaFile + configuration;
3372 expectCommandLineSyntax(outputMessageHelp, outputMessage, command, 2);
3373 }
3374 // Invalid: No file name specified after -s
3375 {
3376 command = validateTool + schema + configuration + fileName;
3377 expectCommandLineSyntax(outputMessageHelp, outputMessage, command, 2);
3378 }
3379 // Invalid: File specified after -c does not exist
3380 {
3381 command = validateTool + schema + schemaFile + configuration +
3382 "../notExistFile";
Bob Kingb7552f02020-10-15 14:34:17 +08003383 expectCommandLineSyntax("Error: Configuration file does not exist.",
3384 outputMessageHelp, command, 1);
Bob Kinged009652020-02-20 14:54:13 +08003385 }
3386 // Invalid: File specified after -s does not exist
3387 {
3388 command = validateTool + schema + "../notExistFile " + configuration +
3389 fileName;
Bob Kingb7552f02020-10-15 14:34:17 +08003390 expectCommandLineSyntax("Error: Schema file does not exist.",
3391 outputMessageHelp, command, 1);
3392 }
3393 // Invalid: File specified after -c is not right data format
3394 {
3395 TemporaryFile wrongFormatFile;
3396 std::string wrongFormatFileName = wrongFormatFile.getPath().string();
3397 std::ofstream out(wrongFormatFileName);
3398 out << "foo";
3399 out.close();
3400 command = validateTool + schema + schemaFile + configuration +
3401 wrongFormatFileName;
Bob Kinged009652020-02-20 14:54:13 +08003402 expectCommandLineSyntax(
Bob Kingb7552f02020-10-15 14:34:17 +08003403 "Error: Configuration file is not in the JSON format.",
3404 outputMessageHelp, command, 1);
Bob Kinged009652020-02-20 14:54:13 +08003405 }
3406 // Invalid: File specified after -s is not right data format
3407 {
Shawn McCarney0f6ebad2020-09-04 16:43:00 -05003408 TemporaryFile wrongFormatFile;
3409 std::string wrongFormatFileName = wrongFormatFile.getPath().string();
Bob Kinga57e0812020-03-12 10:47:42 +08003410 std::ofstream out(wrongFormatFileName);
Bob Kinged009652020-02-20 14:54:13 +08003411 out << "foo";
3412 out.close();
Bob Kinga57e0812020-03-12 10:47:42 +08003413 command = validateTool + schema + wrongFormatFileName + configuration +
3414 fileName;
Bob Kingb7552f02020-10-15 14:34:17 +08003415 expectCommandLineSyntax("Error: Schema file is not in the JSON format.",
3416 outputMessageHelp, command, 1);
Bob Kinged009652020-02-20 14:54:13 +08003417 }
3418 // Invalid: File specified after -c is not readable
3419 {
Shawn McCarney0f6ebad2020-09-04 16:43:00 -05003420 TemporaryFile notReadableFile;
3421 std::string notReadableFileName = notReadableFile.getPath().string();
Bob Kinga57e0812020-03-12 10:47:42 +08003422 writeDataToFile(validConfigFile, notReadableFileName);
Bob Kinged009652020-02-20 14:54:13 +08003423 command = validateTool + schema + schemaFile + configuration +
Bob Kinga57e0812020-03-12 10:47:42 +08003424 notReadableFileName;
3425 chmod(notReadableFileName.c_str(), 0222);
Bob Kingb7552f02020-10-15 14:34:17 +08003426 expectCommandLineSyntax("Error: Configuration file is not readable.",
3427 outputMessageHelp, command, 1);
Bob Kinged009652020-02-20 14:54:13 +08003428 }
3429 // Invalid: File specified after -s is not readable
3430 {
Shawn McCarney0f6ebad2020-09-04 16:43:00 -05003431 TemporaryFile notReadableFile;
3432 std::string notReadableFileName = notReadableFile.getPath().string();
Bob Kinga57e0812020-03-12 10:47:42 +08003433 writeDataToFile(validConfigFile, notReadableFileName);
3434 command = validateTool + schema + notReadableFileName + configuration +
3435 fileName;
3436 chmod(notReadableFileName.c_str(), 0222);
Bob Kingb7552f02020-10-15 14:34:17 +08003437 expectCommandLineSyntax("Error: Schema file is not readable.",
3438 outputMessageHelp, command, 1);
Bob Kinged009652020-02-20 14:54:13 +08003439 }
3440 // Invalid: Unexpected parameter specified (like -g)
3441 {
3442 command = validateTool + schema + schemaFile + configuration +
3443 fileName + " -g";
3444 expectCommandLineSyntax(outputMessageHelp, outputMessage, command, 2);
3445 }
Bob Kinged009652020-02-20 14:54:13 +08003446}