blob: f6033d5e15498fb11bb89093c6f8bb353e96cd4a [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
705 // Valid.
706 {
707 json configFile = compareVpdFile;
708 EXPECT_JSON_VALID(configFile);
709 }
Matt Spinleraacc2aa2021-05-25 09:31:35 -0600710 // Valid, using byte_values.
711 {
712 json configFile = compareVpdFile;
713 configFile["rules"][0]["actions"][1]["compare_vpd"].erase("value");
714 configFile["rules"][0]["actions"][1]["compare_vpd"]["byte_values"] = {
715 "0x01", "0x02"};
716 EXPECT_JSON_VALID(configFile);
717 }
Bob Kingf8b77a02020-01-21 11:09:47 +0800718
719 // Invalid: no FRU property.
720 {
721 json configFile = compareVpdFile;
722 configFile["rules"][0]["actions"][1]["compare_vpd"].erase("fru");
723 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800724 "'fru' is a required property");
Bob Kingf8b77a02020-01-21 11:09:47 +0800725 }
726
727 // Invalid: no keyword property.
728 {
729 json configFile = compareVpdFile;
730 configFile["rules"][0]["actions"][1]["compare_vpd"].erase("keyword");
731 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800732 "'keyword' is a required property");
Bob Kingf8b77a02020-01-21 11:09:47 +0800733 }
734
735 // Invalid: no value property.
736 {
737 json configFile = compareVpdFile;
738 configFile["rules"][0]["actions"][1]["compare_vpd"].erase("value");
739 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800740 "'value' is a required property");
Bob Kingf8b77a02020-01-21 11:09:47 +0800741 }
742
743 // Invalid: property FRU wrong type.
744 {
745 json configFile = compareVpdFile;
746 configFile["rules"][0]["actions"][1]["compare_vpd"]["fru"] = 1;
747 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800748 "1 is not of type 'string'");
Bob Kingf8b77a02020-01-21 11:09:47 +0800749 }
750
751 // Invalid: property FRU is string less than 1.
752 {
753 json configFile = compareVpdFile;
754 configFile["rules"][0]["actions"][1]["compare_vpd"]["fru"] = "";
755 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800756 "'' is too short");
Bob Kingf8b77a02020-01-21 11:09:47 +0800757 }
758
759 // Invalid: property keyword is not "CCIN", "Manufacturer", "Model",
Matt Spinleraacc2aa2021-05-25 09:31:35 -0600760 // "PartNumber", "HW"
Bob Kingf8b77a02020-01-21 11:09:47 +0800761 {
762 json configFile = compareVpdFile;
763 configFile["rules"][0]["actions"][1]["compare_vpd"]["keyword"] =
764 "Number";
765 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800766 "'Number' is not one of ['CCIN', "
Matt Spinleraacc2aa2021-05-25 09:31:35 -0600767 "'Manufacturer', 'Model', 'PartNumber', 'HW']");
Bob Kingf8b77a02020-01-21 11:09:47 +0800768 }
769
770 // Invalid: property value wrong type.
771 {
772 json configFile = compareVpdFile;
773 configFile["rules"][0]["actions"][1]["compare_vpd"]["value"] = 1;
774 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800775 "1 is not of type 'string'");
Bob Kingf8b77a02020-01-21 11:09:47 +0800776 }
Matt Spinleraacc2aa2021-05-25 09:31:35 -0600777
778 // Invalid: property byte_values has wrong type
779 {
780 json configFile = compareVpdFile;
781 configFile["rules"][0]["actions"][1]["compare_vpd"].erase("value");
782 configFile["rules"][0]["actions"][1]["compare_vpd"]["byte_values"] =
783 "0x50";
784 EXPECT_JSON_INVALID(configFile, "Validation failed.",
785 "'0x50' is not of type 'array'");
786 }
787
788 // Invalid: property byte_values is empty
789 {
790 json configFile = compareVpdFile;
791 configFile["rules"][0]["actions"][1]["compare_vpd"].erase("value");
792 configFile["rules"][0]["actions"][1]["compare_vpd"]["byte_values"] =
793 json::array();
794 EXPECT_JSON_INVALID(configFile, "Validation failed.",
795 "[] is too short");
796 }
797
798 // Invalid: properties byte_values and value both exist
799 {
800 json configFile = compareVpdFile;
801 configFile["rules"][0]["actions"][1]["compare_vpd"]["byte_values"] = {
802 "0x01", "0x02"};
803 EXPECT_JSON_INVALID(
804 configFile, "Validation failed.",
805 "{'byte_values': ['0x01', '0x02'], 'fru': "
806 "'system/chassis/motherboard/regulator2', 'keyword': 'CCIN', "
807 "'value': '2D35'} is valid under each of {'required': "
808 "['byte_values']}, {'required': ['value']}");
809 }
Bob Kingf8b77a02020-01-21 11:09:47 +0800810}
Shawn McCarney846dde52021-08-14 12:47:44 -0500811
Bob King20057412020-03-16 16:50:17 +0800812TEST(ValidateRegulatorsConfigTest, ConfigFile)
813{
814 // Valid: Only required properties specified
815 {
816 json configFile;
817 configFile["chassis"][0]["number"] = 1;
Shawn McCarney4c88a4c2021-09-21 15:29:24 -0500818 configFile["chassis"][0]["inventory_path"] = "system/chassis";
Bob King20057412020-03-16 16:50:17 +0800819 EXPECT_JSON_VALID(configFile);
820 }
821 // Valid: All properties specified
822 {
823 json configFile = validConfigFile;
824 EXPECT_JSON_VALID(configFile);
825 }
826 // Invalid: Required chassis property not specified
827 {
828 json configFile = validConfigFile;
829 configFile.erase("chassis");
830 EXPECT_JSON_INVALID(configFile, "Validation failed.",
831 "'chassis' is a required property");
832 }
833 // Invalid: Wrong data type for comments
834 {
835 json configFile = validConfigFile;
836 configFile["comments"] = true;
837 EXPECT_JSON_INVALID(configFile, "Validation failed.",
838 "True is not of type 'array'");
839 }
840 // Invalid: Wrong data type for rules
841 {
842 json configFile = validConfigFile;
843 configFile["rules"] = true;
844 EXPECT_JSON_INVALID(configFile, "Validation failed.",
845 "True is not of type 'array'");
846 }
847 // Invalid: Wrong data type for chassis
848 {
849 json configFile = validConfigFile;
850 configFile["chassis"] = true;
851 EXPECT_JSON_INVALID(configFile, "Validation failed.",
852 "True is not of type 'array'");
853 }
854 // Invalid: Empty comments array;
855 {
856 json configFile = validConfigFile;
857 configFile["comments"] = json::array();
858 EXPECT_JSON_INVALID(configFile, "Validation failed.",
859 "[] is too short");
860 }
861 // Invalid: Empty rules array
862 {
863 json configFile = validConfigFile;
864 configFile["rules"] = json::array();
865 EXPECT_JSON_INVALID(configFile, "Validation failed.",
866 "[] is too short");
867 }
868 // Invalid: Empty chassis array
869 {
870 json configFile = validConfigFile;
871 configFile["chassis"] = json::array();
872 EXPECT_JSON_INVALID(configFile, "Validation failed.",
873 "[] is too short");
874 }
875 // Invalid: Comments array has wrong element type (should be string)
876 {
877 json configFile = validConfigFile;
878 configFile["comments"][0] = true;
879 EXPECT_JSON_INVALID(configFile, "Validation failed.",
880 "True is not of type 'string'");
881 }
882 // Invalid: Rules array has wrong element type (should be rule)
883 {
884 json configFile = validConfigFile;
885 configFile["rules"][0] = true;
886 EXPECT_JSON_INVALID(configFile, "Validation failed.",
887 "True is not of type 'object'");
888 }
889 // Invalid: Chassis array has wrong element type (should be chassis)
890 {
891 json configFile = validConfigFile;
892 configFile["chassis"][0] = true;
893 EXPECT_JSON_INVALID(configFile, "Validation failed.",
894 "True is not of type 'object'");
895 }
896 // Invalid: Unexpected property specified
897 {
898 json configFile = validConfigFile;
899 configFile["foo"] = json::array();
900 EXPECT_JSON_INVALID(
901 configFile, "Validation failed.",
902 "Additional properties are not allowed ('foo' was unexpected)");
903 }
904}
Shawn McCarney846dde52021-08-14 12:47:44 -0500905
Bob King4c67a3a2020-02-07 09:48:11 +0800906TEST(ValidateRegulatorsConfigTest, Configuration)
907{
908 json configurationFile = validConfigFile;
909 configurationFile["chassis"][0]["devices"][0]["configuration"]["comments"]
910 [0] = "Set rail to 1.25V using standard rule";
911 configurationFile["chassis"][0]["devices"][0]["configuration"]["volts"] =
912 1.25;
913 configurationFile["chassis"][0]["devices"][0]["configuration"]["rule_id"] =
914 "set_voltage_rule";
915 // Valid: test configuration with property rule_id and with no actions.
916 {
917 json configFile = configurationFile;
Bob King78793102020-03-13 13:16:09 +0800918 configFile["chassis"][0]["devices"][0]["configuration"]["comments"][1] =
919 "test multiple array elements in comments.";
Bob King4c67a3a2020-02-07 09:48:11 +0800920 EXPECT_JSON_VALID(configFile);
921 }
922 // Valid: test configuration with property actions and with no rule_id.
923 {
924 json configFile = configurationFile;
925 configFile["chassis"][0]["devices"][0]["configuration"].erase(
926 "rule_id");
927 configFile["chassis"][0]["devices"][0]["configuration"]["actions"][0]
928 ["compare_presence"]["fru"] =
Bob Kinga76898f2020-10-13 15:08:33 +0800929 "system/chassis/motherboard/cpu3";
Bob King4c67a3a2020-02-07 09:48:11 +0800930 configFile["chassis"][0]["devices"][0]["configuration"]["actions"][0]
931 ["compare_presence"]["value"] = true;
932 EXPECT_JSON_VALID(configFile);
933 }
934 // Valid: comments not specified (optional property).
935 {
936 json configFile = configurationFile;
937 configFile["chassis"][0]["devices"][0]["configuration"].erase(
938 "comments");
939 EXPECT_JSON_VALID(configFile);
940 }
941 // Valid: volts not specified (optional property).
942 {
943 json configFile = configurationFile;
944 configFile["chassis"][0]["devices"][0]["configuration"].erase("volts");
945 EXPECT_JSON_VALID(configFile);
946 }
947 // Valid: configuration is property of a rail (vs. a device).
948 {
949 json configFile = validConfigFile;
950 configFile["chassis"][0]["devices"][0]["rails"][0]["configuration"]
951 ["comments"][0] = "Set rail to 1.25V using standard rule";
952 configFile["chassis"][0]["devices"][0]["rails"][0]["configuration"]
953 ["volts"] = 1.25;
954 configFile["chassis"][0]["devices"][0]["rails"][0]["configuration"]
955 ["rule_id"] = "set_voltage_rule";
956 EXPECT_JSON_VALID(configFile);
957 }
958 // Invalid: comments property has wrong data type (not an array).
959 {
960 json configFile = configurationFile;
961 configFile["chassis"][0]["devices"][0]["configuration"]["comments"] = 1;
962 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800963 "1 is not of type 'array'");
Bob King4c67a3a2020-02-07 09:48:11 +0800964 }
965 // Invalid: test configuration with both actions and rule_id properties.
966 {
967 json configFile = configurationFile;
968 configFile["chassis"][0]["devices"][0]["configuration"]["actions"][0]
969 ["compare_presence"]["fru"] =
Bob Kinga76898f2020-10-13 15:08:33 +0800970 "system/chassis/motherboard/cpu3";
Bob King4c67a3a2020-02-07 09:48:11 +0800971 configFile["chassis"][0]["devices"][0]["configuration"]["actions"][0]
972 ["compare_presence"]["value"] = true;
Shawn McCarney846dde52021-08-14 12:47:44 -0500973 EXPECT_JSON_INVALID(configFile, "Validation failed.", "");
Bob King4c67a3a2020-02-07 09:48:11 +0800974 }
975 // Invalid: test configuration with no rule_id and actions.
976 {
977 json configFile = configurationFile;
978 configFile["chassis"][0]["devices"][0]["configuration"].erase(
979 "rule_id");
980 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800981 "'rule_id' is a required property");
Bob King4c67a3a2020-02-07 09:48:11 +0800982 }
983 // Invalid: test configuration with property volts wrong type.
984 {
985 json configFile = configurationFile;
986 configFile["chassis"][0]["devices"][0]["configuration"]["volts"] = true;
987 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800988 "True is not of type 'number'");
Bob King4c67a3a2020-02-07 09:48:11 +0800989 }
990 // Invalid: test configuration with property rule_id wrong type.
991 {
992 json configFile = configurationFile;
993 configFile["chassis"][0]["devices"][0]["configuration"]["rule_id"] =
994 true;
995 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800996 "True is not of type 'string'");
Bob King4c67a3a2020-02-07 09:48:11 +0800997 }
998 // Invalid: test configuration with property actions wrong type.
999 {
1000 json configFile = configurationFile;
1001 configFile["chassis"][0]["devices"][0]["configuration"].erase(
1002 "rule_id");
1003 configFile["chassis"][0]["devices"][0]["configuration"]["actions"] =
1004 true;
1005 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001006 "True is not of type 'array'");
Bob King4c67a3a2020-02-07 09:48:11 +08001007 }
1008 // Invalid: test configuration with property comments empty array.
1009 {
1010 json configFile = configurationFile;
1011 configFile["chassis"][0]["devices"][0]["configuration"]["comments"] =
1012 json::array();
1013 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1014 "[] is too short");
1015 }
1016 // Invalid: test configuration with property rule_id wrong format.
1017 {
1018 json configFile = configurationFile;
1019 configFile["chassis"][0]["devices"][0]["configuration"]["rule_id"] =
1020 "id!";
1021 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001022 "'id!' does not match '^[A-Za-z0-9_]+$'");
Bob King4c67a3a2020-02-07 09:48:11 +08001023 }
1024 // Invalid: test configuration with property actions empty array.
1025 {
1026 json configFile = configurationFile;
1027 configFile["chassis"][0]["devices"][0]["configuration"].erase(
1028 "rule_id");
1029 configFile["chassis"][0]["devices"][0]["configuration"]["actions"] =
1030 json::array();
1031 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1032 "[] is too short");
1033 }
1034}
Shawn McCarney846dde52021-08-14 12:47:44 -05001035
Bob Kinga2ba2df2020-02-04 14:38:44 +08001036TEST(ValidateRegulatorsConfigTest, Device)
1037{
Bob Kinga2ba2df2020-02-04 14:38:44 +08001038 // Valid: test devices.
1039 {
1040 json configFile = validConfigFile;
1041 EXPECT_JSON_VALID(configFile);
1042 }
1043 // Valid: test devices with required properties.
1044 {
1045 json configFile = validConfigFile;
1046 configFile["chassis"][0]["devices"][0].erase("comments");
1047 configFile["chassis"][0]["devices"][0].erase("presence_detection");
1048 configFile["chassis"][0]["devices"][0].erase("configuration");
Shawn McCarney846dde52021-08-14 12:47:44 -05001049 configFile["chassis"][0]["devices"][0].erase("phase_fault_detection");
Bob Kinga2ba2df2020-02-04 14:38:44 +08001050 configFile["chassis"][0]["devices"][0].erase("rails");
1051 EXPECT_JSON_VALID(configFile);
1052 }
1053 // Invalid: test devices with no id.
1054 {
1055 json configFile = validConfigFile;
1056 configFile["chassis"][0]["devices"][0].erase("id");
1057 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001058 "'id' is a required property");
Bob Kinga2ba2df2020-02-04 14:38:44 +08001059 }
1060 // Invalid: test devices with no is_regulator.
1061 {
1062 json configFile = validConfigFile;
1063 configFile["chassis"][0]["devices"][0].erase("is_regulator");
1064 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001065 "'is_regulator' is a required property");
Bob Kinga2ba2df2020-02-04 14:38:44 +08001066 }
1067 // Invalid: test devices with no fru.
1068 {
1069 json configFile = validConfigFile;
1070 configFile["chassis"][0]["devices"][0].erase("fru");
1071 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001072 "'fru' is a required property");
Bob Kinga2ba2df2020-02-04 14:38:44 +08001073 }
1074 // Invalid: test devices with no i2c_interface.
1075 {
1076 json configFile = validConfigFile;
1077 configFile["chassis"][0]["devices"][0].erase("i2c_interface");
1078 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001079 "'i2c_interface' is a required property");
Bob Kinga2ba2df2020-02-04 14:38:44 +08001080 }
Shawn McCarney846dde52021-08-14 12:47:44 -05001081 // Invalid: is_regulator=false: phase_fault_detection specified
1082 {
1083 json configFile = validConfigFile;
1084 configFile["chassis"][0]["devices"][0]["is_regulator"] = false;
1085 configFile["chassis"][0]["devices"][0].erase("rails");
1086 configFile["chassis"][0]["devices"][0]["phase_fault_detection"]
1087 ["rule_id"] = "detect_phase_faults_rule";
1088 EXPECT_JSON_INVALID(configFile, "Validation failed.", "");
1089 }
1090 // Invalid: is_regulator=false: rails specified
1091 {
1092 json configFile = validConfigFile;
1093 configFile["chassis"][0]["devices"][0]["is_regulator"] = false;
1094 EXPECT_JSON_INVALID(configFile, "Validation failed.", "");
1095 }
1096 // Invalid: is_regulator=false: phase_fault_detection and rails specified
1097 {
1098 json configFile = validConfigFile;
1099 configFile["chassis"][0]["devices"][0]["is_regulator"] = false;
1100 configFile["chassis"][0]["devices"][0]["phase_fault_detection"]
1101 ["rule_id"] = "detect_phase_faults_rule";
1102 EXPECT_JSON_INVALID(configFile, "Validation failed.", "");
1103 }
Bob Kinga2ba2df2020-02-04 14:38:44 +08001104 // Invalid: test devices with property comments wrong type.
1105 {
1106 json configFile = validConfigFile;
1107 configFile["chassis"][0]["devices"][0]["comments"] = true;
1108 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001109 "True is not of type 'array'");
Bob Kinga2ba2df2020-02-04 14:38:44 +08001110 }
1111 // Invalid: test devices with property id wrong type.
1112 {
1113 json configFile = validConfigFile;
1114 configFile["chassis"][0]["devices"][0]["id"] = true;
1115 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001116 "True is not of type 'string'");
Bob Kinga2ba2df2020-02-04 14:38:44 +08001117 }
1118 // Invalid: test devices with property is_regulator wrong type.
1119 {
1120 json configFile = validConfigFile;
1121 configFile["chassis"][0]["devices"][0]["is_regulator"] = 1;
1122 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001123 "1 is not of type 'boolean'");
Bob Kinga2ba2df2020-02-04 14:38:44 +08001124 }
1125 // Invalid: test devices with property fru wrong type.
1126 {
1127 json configFile = validConfigFile;
1128 configFile["chassis"][0]["devices"][0]["fru"] = true;
1129 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001130 "True is not of type 'string'");
Bob Kinga2ba2df2020-02-04 14:38:44 +08001131 }
1132 // Invalid: test devices with property i2c_interface wrong type.
1133 {
1134 json configFile = validConfigFile;
1135 configFile["chassis"][0]["devices"][0]["i2c_interface"] = true;
1136 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001137 "True is not of type 'object'");
Bob Kinga2ba2df2020-02-04 14:38:44 +08001138 }
1139 // Invalid: test devices with property presence_detection wrong
1140 // type.
1141 {
1142 json configFile = validConfigFile;
1143 configFile["chassis"][0]["devices"][0]["presence_detection"] = true;
1144 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001145 "True is not of type 'object'");
Bob Kinga2ba2df2020-02-04 14:38:44 +08001146 }
1147 // Invalid: test devices with property configuration wrong type.
1148 {
1149 json configFile = validConfigFile;
1150 configFile["chassis"][0]["devices"][0]["configuration"] = 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 }
Shawn McCarney846dde52021-08-14 12:47:44 -05001154 // Invalid: test devices with property phase_fault_detection wrong type.
1155 {
1156 json configFile = validConfigFile;
1157 configFile["chassis"][0]["devices"][0]["phase_fault_detection"] = true;
1158 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1159 "True is not of type 'object'");
1160 }
Bob Kinga2ba2df2020-02-04 14:38:44 +08001161 // Invalid: test devices with property rails wrong type.
1162 {
1163 json configFile = validConfigFile;
1164 configFile["chassis"][0]["devices"][0]["rails"] = true;
1165 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001166 "True is not of type 'array'");
Bob Kinga2ba2df2020-02-04 14:38:44 +08001167 }
1168 // Invalid: test devices with property comments empty array.
1169 {
1170 json configFile = validConfigFile;
1171 configFile["chassis"][0]["devices"][0]["comments"] = json::array();
1172 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1173 "[] is too short");
1174 }
1175 // Invalid: test devices with property fru length less than 1.
1176 {
1177 json configFile = validConfigFile;
1178 configFile["chassis"][0]["devices"][0]["fru"] = "";
1179 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001180 "'' is too short");
Bob Kinga2ba2df2020-02-04 14:38:44 +08001181 }
1182 // Invalid: test devices with property id wrong format.
1183 {
1184 json configFile = validConfigFile;
1185 configFile["chassis"][0]["devices"][0]["id"] = "id#";
1186 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001187 "'id#' does not match '^[A-Za-z0-9_]+$'");
Bob Kinga2ba2df2020-02-04 14:38:44 +08001188 }
1189 // Invalid: test devices with property rails empty array.
1190 {
1191 json configFile = validConfigFile;
1192 configFile["chassis"][0]["devices"][0]["rails"] = json::array();
1193 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1194 "[] is too short");
1195 }
1196}
Shawn McCarney846dde52021-08-14 12:47:44 -05001197
1198TEST(ValidateRegulatorsConfigTest, I2CCaptureBytes)
1199{
1200 json initialFile = validConfigFile;
1201 initialFile["rules"][0]["actions"][1]["i2c_capture_bytes"]["register"] =
1202 "0xA0";
1203 initialFile["rules"][0]["actions"][1]["i2c_capture_bytes"]["count"] = 2;
1204
1205 // Valid: All required properties
1206 {
1207 json configFile = initialFile;
1208 EXPECT_JSON_VALID(configFile);
1209 }
1210
1211 // Invalid: register not specified
1212 {
1213 json configFile = initialFile;
1214 configFile["rules"][0]["actions"][1]["i2c_capture_bytes"].erase(
1215 "register");
1216 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1217 "'register' is a required property");
1218 }
1219
1220 // Invalid: count not specified
1221 {
1222 json configFile = initialFile;
1223 configFile["rules"][0]["actions"][1]["i2c_capture_bytes"].erase(
1224 "count");
1225 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1226 "'count' is a required property");
1227 }
1228
1229 // Invalid: invalid property specified
1230 {
1231 json configFile = initialFile;
1232 configFile["rules"][0]["actions"][1]["i2c_capture_bytes"]["foo"] = true;
1233 EXPECT_JSON_INVALID(
1234 configFile, "Validation failed.",
1235 "Additional properties are not allowed ('foo' was unexpected)");
1236 }
1237
1238 // Invalid: register has wrong data type
1239 {
1240 json configFile = initialFile;
1241 configFile["rules"][0]["actions"][1]["i2c_capture_bytes"]["register"] =
1242 1;
1243 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1244 "1 is not of type 'string'");
1245 }
1246
1247 // Invalid: register has wrong format
1248 {
1249 json configFile = initialFile;
1250 configFile["rules"][0]["actions"][1]["i2c_capture_bytes"]["register"] =
1251 "0xA00";
1252 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1253 "'0xA00' does not match '^0x[0-9A-Fa-f]{2}$'");
1254 }
1255
1256 // Invalid: count has wrong data type
1257 {
1258 json configFile = initialFile;
1259 configFile["rules"][0]["actions"][1]["i2c_capture_bytes"]["count"] =
1260 3.1;
1261 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1262 "3.1 is not of type 'integer'");
1263 }
1264
1265 // Invalid: count < 1
1266 {
1267 json configFile = initialFile;
1268 configFile["rules"][0]["actions"][1]["i2c_capture_bytes"]["count"] = 0;
1269 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1270 "0 is less than the minimum of 1");
1271 }
1272}
1273
Bob King4ab8cbb2020-01-21 11:10:48 +08001274TEST(ValidateRegulatorsConfigTest, I2CCompareBit)
1275{
1276 json i2cCompareBitFile = validConfigFile;
1277 i2cCompareBitFile["rules"][0]["actions"][1]["i2c_compare_bit"]["register"] =
1278 "0xA0";
1279 i2cCompareBitFile["rules"][0]["actions"][1]["i2c_compare_bit"]["position"] =
1280 3;
1281 i2cCompareBitFile["rules"][0]["actions"][1]["i2c_compare_bit"]["value"] = 1;
1282 // Valid: test rule actions i2c_compare_bit.
1283 {
1284 json configFile = i2cCompareBitFile;
1285 EXPECT_JSON_VALID(configFile);
1286 }
1287 // Invalid: test i2c_compare_bit with no register.
1288 {
1289 json configFile = i2cCompareBitFile;
1290 configFile["rules"][0]["actions"][1]["i2c_compare_bit"].erase(
1291 "register");
1292 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001293 "'register' is a required property");
Bob King4ab8cbb2020-01-21 11:10:48 +08001294 }
1295 // Invalid: test i2c_compare_bit with no position.
1296 {
1297 json configFile = i2cCompareBitFile;
1298 configFile["rules"][0]["actions"][1]["i2c_compare_bit"].erase(
1299 "position");
1300 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001301 "'position' is a required property");
Bob King4ab8cbb2020-01-21 11:10:48 +08001302 }
1303 // Invalid: test i2c_compare_bit with no value.
1304 {
1305 json configFile = i2cCompareBitFile;
1306 configFile["rules"][0]["actions"][1]["i2c_compare_bit"].erase("value");
1307 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001308 "'value' is a required property");
Bob King4ab8cbb2020-01-21 11:10:48 +08001309 }
1310 // Invalid: test i2c_compare_bit with register wrong type.
1311 {
1312 json configFile = i2cCompareBitFile;
1313 configFile["rules"][0]["actions"][1]["i2c_compare_bit"]["register"] = 1;
1314 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001315 "1 is not of type 'string'");
Bob King4ab8cbb2020-01-21 11:10:48 +08001316 }
1317 // Invalid: test i2c_compare_bit with register wrong format.
1318 {
1319 json configFile = i2cCompareBitFile;
1320 configFile["rules"][0]["actions"][1]["i2c_compare_bit"]["register"] =
1321 "0xA00";
1322 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001323 "'0xA00' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King4ab8cbb2020-01-21 11:10:48 +08001324 }
1325 // Invalid: test i2c_compare_bit with position wrong type.
1326 {
1327 json configFile = i2cCompareBitFile;
1328 configFile["rules"][0]["actions"][1]["i2c_compare_bit"]["position"] =
1329 3.1;
1330 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001331 "3.1 is not of type 'integer'");
Bob King4ab8cbb2020-01-21 11:10:48 +08001332 }
1333 // Invalid: test i2c_compare_bit with position greater than 7.
1334 {
1335 json configFile = i2cCompareBitFile;
1336 configFile["rules"][0]["actions"][1]["i2c_compare_bit"]["position"] = 8;
1337 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1338 "8 is greater than the maximum of 7");
1339 }
1340 // Invalid: test i2c_compare_bit with position less than 0.
1341 {
1342 json configFile = i2cCompareBitFile;
1343 configFile["rules"][0]["actions"][1]["i2c_compare_bit"]["position"] =
1344 -1;
1345 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1346 "-1 is less than the minimum of 0");
1347 }
1348 // Invalid: test i2c_compare_bit with value wrong type.
1349 {
1350 json configFile = i2cCompareBitFile;
1351 configFile["rules"][0]["actions"][1]["i2c_compare_bit"]["value"] = "1";
1352 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001353 "'1' is not of type 'integer'");
Bob King4ab8cbb2020-01-21 11:10:48 +08001354 }
1355 // Invalid: test i2c_compare_bit with value greater than 1.
1356 {
1357 json configFile = i2cCompareBitFile;
1358 configFile["rules"][0]["actions"][1]["i2c_compare_bit"]["value"] = 2;
1359 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1360 "2 is greater than the maximum of 1");
1361 }
1362 // Invalid: test i2c_compare_bit with value less than 0.
1363 {
1364 json configFile = i2cCompareBitFile;
1365 configFile["rules"][0]["actions"][1]["i2c_compare_bit"]["value"] = -1;
1366 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1367 "-1 is less than the minimum of 0");
1368 }
1369}
Shawn McCarney846dde52021-08-14 12:47:44 -05001370
Bob King514023d2020-01-21 11:13:05 +08001371TEST(ValidateRegulatorsConfigTest, I2CCompareByte)
1372{
1373 json i2cCompareByteFile = validConfigFile;
1374 i2cCompareByteFile["rules"][0]["actions"][1]["i2c_compare_byte"]
1375 ["register"] = "0x82";
1376 i2cCompareByteFile["rules"][0]["actions"][1]["i2c_compare_byte"]["value"] =
1377 "0x40";
1378 i2cCompareByteFile["rules"][0]["actions"][1]["i2c_compare_byte"]["mask"] =
1379 "0x7F";
1380 // Valid: test i2c_compare_byte with all properties.
1381 {
1382 json configFile = i2cCompareByteFile;
1383 EXPECT_JSON_VALID(configFile);
1384 }
1385 // Valid: test i2c_compare_byte with all required properties.
1386 {
1387 json configFile = i2cCompareByteFile;
1388 configFile["rules"][0]["actions"][1]["i2c_compare_byte"].erase("mask");
1389 EXPECT_JSON_VALID(configFile);
1390 }
1391 // Invalid: test i2c_compare_byte with no register.
1392 {
1393 json configFile = i2cCompareByteFile;
1394 configFile["rules"][0]["actions"][1]["i2c_compare_byte"].erase(
1395 "register");
1396 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001397 "'register' is a required property");
Bob King514023d2020-01-21 11:13:05 +08001398 }
1399 // Invalid: test i2c_compare_byte with no value.
1400 {
1401 json configFile = i2cCompareByteFile;
1402 configFile["rules"][0]["actions"][1]["i2c_compare_byte"].erase("value");
1403 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001404 "'value' is a required property");
Bob King514023d2020-01-21 11:13:05 +08001405 }
1406 // Invalid: test i2c_compare_byte with property register wrong type.
1407 {
1408 json configFile = i2cCompareByteFile;
1409 configFile["rules"][0]["actions"][1]["i2c_compare_byte"]["register"] =
1410 1;
1411 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001412 "1 is not of type 'string'");
Bob King514023d2020-01-21 11:13:05 +08001413 }
1414 // Invalid: test i2c_compare_byte with property value wrong type.
1415 {
1416 json configFile = i2cCompareByteFile;
1417 configFile["rules"][0]["actions"][1]["i2c_compare_byte"]["value"] = 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 mask wrong type.
1422 {
1423 json configFile = i2cCompareByteFile;
1424 configFile["rules"][0]["actions"][1]["i2c_compare_byte"]["mask"] = 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 register more than 2 hex
1429 // digits.
1430 {
1431 json configFile = i2cCompareByteFile;
1432 configFile["rules"][0]["actions"][1]["i2c_compare_byte"]["register"] =
1433 "0x820";
1434 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001435 "'0x820' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King514023d2020-01-21 11:13:05 +08001436 }
1437 // Invalid: test i2c_compare_byte with property value more than 2 hex
1438 // digits.
1439 {
1440 json configFile = i2cCompareByteFile;
1441 configFile["rules"][0]["actions"][1]["i2c_compare_byte"]["value"] =
1442 "0x820";
1443 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001444 "'0x820' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King514023d2020-01-21 11:13:05 +08001445 }
1446 // Invalid: test i2c_compare_byte with property mask more than 2 hex digits.
1447 {
1448 json configFile = i2cCompareByteFile;
1449 configFile["rules"][0]["actions"][1]["i2c_compare_byte"]["mask"] =
1450 "0x820";
1451 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001452 "'0x820' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King514023d2020-01-21 11:13:05 +08001453 }
1454 // Invalid: test i2c_compare_byte with property register less than 2 hex
1455 // digits.
1456 {
1457 json configFile = i2cCompareByteFile;
1458 configFile["rules"][0]["actions"][1]["i2c_compare_byte"]["register"] =
1459 "0x8";
1460 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001461 "'0x8' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King514023d2020-01-21 11:13:05 +08001462 }
1463 // Invalid: test i2c_compare_byte with property value less than 2 hex
1464 // digits.
1465 {
1466 json configFile = i2cCompareByteFile;
1467 configFile["rules"][0]["actions"][1]["i2c_compare_byte"]["value"] =
1468 "0x8";
1469 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001470 "'0x8' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King514023d2020-01-21 11:13:05 +08001471 }
1472 // Invalid: test i2c_compare_byte with property mask less than 2 hex digits.
1473 {
1474 json configFile = i2cCompareByteFile;
1475 configFile["rules"][0]["actions"][1]["i2c_compare_byte"]["mask"] =
1476 "0x8";
1477 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001478 "'0x8' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King514023d2020-01-21 11:13:05 +08001479 }
1480 // Invalid: test i2c_compare_byte with property register no leading prefix.
1481 {
1482 json configFile = i2cCompareByteFile;
1483 configFile["rules"][0]["actions"][1]["i2c_compare_byte"]["register"] =
1484 "82";
1485 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001486 "'82' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King514023d2020-01-21 11:13:05 +08001487 }
1488 // Invalid: test i2c_compare_byte with property value no leading prefix.
1489 {
1490 json configFile = i2cCompareByteFile;
1491 configFile["rules"][0]["actions"][1]["i2c_compare_byte"]["value"] =
1492 "82";
1493 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001494 "'82' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King514023d2020-01-21 11:13:05 +08001495 }
1496 // Invalid: test i2c_compare_byte with property mask no leading prefix.
1497 {
1498 json configFile = i2cCompareByteFile;
1499 configFile["rules"][0]["actions"][1]["i2c_compare_byte"]["mask"] = "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 register invalid hex digit.
1504 {
1505 json configFile = i2cCompareByteFile;
1506 configFile["rules"][0]["actions"][1]["i2c_compare_byte"]["register"] =
1507 "0xG1";
1508 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001509 "'0xG1' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King514023d2020-01-21 11:13:05 +08001510 }
1511 // Invalid: test i2c_compare_byte with property value invalid hex digit.
1512 {
1513 json configFile = i2cCompareByteFile;
1514 configFile["rules"][0]["actions"][1]["i2c_compare_byte"]["value"] =
1515 "0xG1";
1516 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001517 "'0xG1' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King514023d2020-01-21 11:13:05 +08001518 }
1519 // Invalid: test i2c_compare_byte with property mask invalid hex digit.
1520 {
1521 json configFile = i2cCompareByteFile;
1522 configFile["rules"][0]["actions"][1]["i2c_compare_byte"]["mask"] =
1523 "0xG1";
1524 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001525 "'0xG1' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King514023d2020-01-21 11:13:05 +08001526 }
1527}
Shawn McCarney846dde52021-08-14 12:47:44 -05001528
Bob Kingfb162bb2020-01-21 11:28:07 +08001529TEST(ValidateRegulatorsConfigTest, I2CCompareBytes)
1530{
1531 json i2cCompareBytesFile = validConfigFile;
1532 i2cCompareBytesFile["rules"][0]["actions"][1]["i2c_compare_bytes"]
1533 ["register"] = "0x82";
1534 i2cCompareBytesFile["rules"][0]["actions"][1]["i2c_compare_bytes"]
1535 ["values"] = {"0x02", "0x73"};
1536 i2cCompareBytesFile["rules"][0]["actions"][1]["i2c_compare_bytes"]
1537 ["masks"] = {"0x7F", "0x7F"};
1538 // Valid: test i2c_compare_bytes.
1539 {
1540 json configFile = i2cCompareBytesFile;
1541 EXPECT_JSON_VALID(configFile);
1542 }
1543 // Valid: test i2c_compare_bytes with all required properties.
1544 {
1545 json configFile = i2cCompareBytesFile;
1546 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"].erase(
1547 "masks");
1548 EXPECT_JSON_VALID(configFile);
1549 }
1550 // Invalid: test i2c_compare_bytes with no register.
1551 {
1552 json configFile = i2cCompareBytesFile;
1553 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"].erase(
1554 "register");
1555 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001556 "'register' is a required property");
Bob Kingfb162bb2020-01-21 11:28:07 +08001557 }
1558 // Invalid: test i2c_compare_bytes with no values.
1559 {
1560 json configFile = i2cCompareBytesFile;
1561 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"].erase(
1562 "values");
1563 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001564 "'values' is a required property");
Bob Kingfb162bb2020-01-21 11:28:07 +08001565 }
1566 // Invalid: test i2c_compare_bytes with property values as empty array.
1567 {
1568 json configFile = i2cCompareBytesFile;
1569 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["values"] =
1570 json::array();
1571 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1572 "[] is too short");
1573 }
1574 // Invalid: test i2c_compare_bytes with property masks as empty array.
1575 {
1576 json configFile = i2cCompareBytesFile;
1577 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["masks"] =
1578 json::array();
1579 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1580 "[] is too short");
1581 }
1582 // Invalid: test i2c_compare_bytes with property register wrong type.
1583 {
1584 json configFile = i2cCompareBytesFile;
1585 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["register"] =
1586 1;
1587 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001588 "1 is not of type 'string'");
Bob Kingfb162bb2020-01-21 11:28:07 +08001589 }
1590 // Invalid: test i2c_compare_bytes with property values wrong type.
1591 {
1592 json configFile = i2cCompareBytesFile;
1593 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["values"] = 1;
1594 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001595 "1 is not of type 'array'");
Bob Kingfb162bb2020-01-21 11:28:07 +08001596 }
1597 // Invalid: test i2c_compare_bytes with property masks wrong type.
1598 {
1599 json configFile = i2cCompareBytesFile;
1600 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["masks"] = 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 register more than 2 hex
1605 // digits.
1606 {
1607 json configFile = i2cCompareBytesFile;
1608 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["register"] =
1609 "0x820";
1610 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001611 "'0x820' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob Kingfb162bb2020-01-21 11:28:07 +08001612 }
1613 // Invalid: test i2c_compare_bytes with property values more than 2 hex
1614 // digits.
1615 {
1616 json configFile = i2cCompareBytesFile;
1617 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["values"][0] =
1618 "0x820";
1619 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001620 "'0x820' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob Kingfb162bb2020-01-21 11:28:07 +08001621 }
1622 // Invalid: test i2c_compare_bytes with property masks more than 2 hex
1623 // digits.
1624 {
1625 json configFile = i2cCompareBytesFile;
1626 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["masks"][0] =
1627 "0x820";
1628 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001629 "'0x820' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob Kingfb162bb2020-01-21 11:28:07 +08001630 }
1631 // Invalid: test i2c_compare_bytes with property register less than 2 hex
1632 // digits.
1633 {
1634 json configFile = i2cCompareBytesFile;
1635 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["register"] =
1636 "0x8";
1637 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001638 "'0x8' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob Kingfb162bb2020-01-21 11:28:07 +08001639 }
1640 // Invalid: test i2c_compare_bytes with property values less than 2 hex
1641 // digits.
1642 {
1643 json configFile = i2cCompareBytesFile;
1644 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["values"][0] =
1645 "0x8";
1646 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001647 "'0x8' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob Kingfb162bb2020-01-21 11:28:07 +08001648 }
1649 // Invalid: test i2c_compare_bytes with property masks less than 2 hex
1650 // digits.
1651 {
1652 json configFile = i2cCompareBytesFile;
1653 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["masks"][0] =
1654 "0x8";
1655 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001656 "'0x8' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob Kingfb162bb2020-01-21 11:28:07 +08001657 }
1658 // Invalid: test i2c_compare_bytes with property register no leading prefix.
1659 {
1660 json configFile = i2cCompareBytesFile;
1661 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["register"] =
1662 "82";
1663 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001664 "'82' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob Kingfb162bb2020-01-21 11:28:07 +08001665 }
1666 // Invalid: test i2c_compare_bytes with property values no leading prefix.
1667 {
1668 json configFile = i2cCompareBytesFile;
1669 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["values"][0] =
1670 "82";
1671 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001672 "'82' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob Kingfb162bb2020-01-21 11:28:07 +08001673 }
1674 // Invalid: test i2c_compare_bytes with property masks no leading prefix.
1675 {
1676 json configFile = i2cCompareBytesFile;
1677 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["masks"][0] =
1678 "82";
1679 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001680 "'82' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob Kingfb162bb2020-01-21 11:28:07 +08001681 }
1682 // Invalid: test i2c_compare_bytes with property register invalid hex digit.
1683 {
1684 json configFile = i2cCompareBytesFile;
1685 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["register"] =
1686 "0xG1";
1687 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001688 "'0xG1' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob Kingfb162bb2020-01-21 11:28:07 +08001689 }
1690 // Invalid: test i2c_compare_bytes with property values invalid hex digit.
1691 {
1692 json configFile = i2cCompareBytesFile;
1693 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["values"][0] =
1694 "0xG1";
1695 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001696 "'0xG1' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob Kingfb162bb2020-01-21 11:28:07 +08001697 }
1698 // Invalid: test i2c_compare_bytes with property masks invalid hex digit.
1699 {
1700 json configFile = i2cCompareBytesFile;
1701 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["masks"][0] =
1702 "0xG1";
1703 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001704 "'0xG1' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob Kingfb162bb2020-01-21 11:28:07 +08001705 }
1706}
Shawn McCarney846dde52021-08-14 12:47:44 -05001707
Bob Kingca93f1f2020-01-31 11:21:16 +08001708TEST(ValidateRegulatorsConfigTest, I2CInterface)
1709{
1710 // Valid: test i2c_interface.
1711 {
1712 json configFile = validConfigFile;
1713 EXPECT_JSON_VALID(configFile);
1714 }
1715 // Invalid: testi2c_interface with no bus.
1716 {
1717 json configFile = validConfigFile;
1718 configFile["chassis"][0]["devices"][0]["i2c_interface"].erase("bus");
1719 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001720 "'bus' is a required property");
Bob Kingca93f1f2020-01-31 11:21:16 +08001721 }
1722 // Invalid: test i2c_interface with no address.
1723 {
1724 json configFile = validConfigFile;
1725 configFile["chassis"][0]["devices"][0]["i2c_interface"].erase(
1726 "address");
1727 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001728 "'address' is a required property");
Bob Kingca93f1f2020-01-31 11:21:16 +08001729 }
1730 // Invalid: test i2c_interface with property bus wrong type.
1731 {
1732 json configFile = validConfigFile;
1733 configFile["chassis"][0]["devices"][0]["i2c_interface"]["bus"] = true;
1734 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001735 "True is not of type 'integer'");
Bob Kingca93f1f2020-01-31 11:21:16 +08001736 }
1737 // Invalid: test i2c_interface with property address wrong
1738 // type.
1739 {
1740 json configFile = validConfigFile;
1741 configFile["chassis"][0]["devices"][0]["i2c_interface"]["address"] =
1742 true;
1743 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001744 "True is not of type 'string'");
Bob Kingca93f1f2020-01-31 11:21:16 +08001745 }
1746 // Invalid: test i2c_interface with property bus less than
1747 // 0.
1748 {
1749 json configFile = validConfigFile;
1750 configFile["chassis"][0]["devices"][0]["i2c_interface"]["bus"] = -1;
1751 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1752 "-1 is less than the minimum of 0");
1753 }
1754 // Invalid: test i2c_interface with property address wrong
1755 // format.
1756 {
1757 json configFile = validConfigFile;
1758 configFile["chassis"][0]["devices"][0]["i2c_interface"]["address"] =
1759 "0x700";
1760 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001761 "'0x700' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob Kingca93f1f2020-01-31 11:21:16 +08001762 }
1763}
Shawn McCarney846dde52021-08-14 12:47:44 -05001764
Bob King188db7d2020-01-31 13:01:01 +08001765TEST(ValidateRegulatorsConfigTest, I2CWriteBit)
1766{
1767 json i2cWriteBitFile = validConfigFile;
1768 i2cWriteBitFile["rules"][0]["actions"][1]["i2c_write_bit"]["register"] =
1769 "0xA0";
1770 i2cWriteBitFile["rules"][0]["actions"][1]["i2c_write_bit"]["position"] = 3;
1771 i2cWriteBitFile["rules"][0]["actions"][1]["i2c_write_bit"]["value"] = 1;
1772 // Valid: test rule actions i2c_write_bit.
1773 {
1774 json configFile = i2cWriteBitFile;
1775 EXPECT_JSON_VALID(configFile);
1776 }
1777 // Invalid: test i2c_write_bit with no register.
1778 {
1779 json configFile = i2cWriteBitFile;
1780 configFile["rules"][0]["actions"][1]["i2c_write_bit"].erase("register");
1781 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001782 "'register' is a required property");
Bob King188db7d2020-01-31 13:01:01 +08001783 }
1784 // Invalid: test i2c_write_bit with no position.
1785 {
1786 json configFile = i2cWriteBitFile;
1787 configFile["rules"][0]["actions"][1]["i2c_write_bit"].erase("position");
1788 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001789 "'position' is a required property");
Bob King188db7d2020-01-31 13:01:01 +08001790 }
1791 // Invalid: test i2c_write_bit with no value.
1792 {
1793 json configFile = i2cWriteBitFile;
1794 configFile["rules"][0]["actions"][1]["i2c_write_bit"].erase("value");
1795 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001796 "'value' is a required property");
Bob King188db7d2020-01-31 13:01:01 +08001797 }
1798 // Invalid: test i2c_write_bit with register wrong type.
1799 {
1800 json configFile = i2cWriteBitFile;
1801 configFile["rules"][0]["actions"][1]["i2c_write_bit"]["register"] = 1;
1802 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001803 "1 is not of type 'string'");
Bob King188db7d2020-01-31 13:01:01 +08001804 }
1805 // Invalid: test i2c_write_bit with register wrong format.
1806 {
1807 json configFile = i2cWriteBitFile;
1808 configFile["rules"][0]["actions"][1]["i2c_write_bit"]["register"] =
1809 "0xA00";
1810 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001811 "'0xA00' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08001812 }
1813 // Invalid: test i2c_write_bit with position wrong type.
1814 {
1815 json configFile = i2cWriteBitFile;
1816 configFile["rules"][0]["actions"][1]["i2c_write_bit"]["position"] = 3.1;
1817 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001818 "3.1 is not of type 'integer'");
Bob King188db7d2020-01-31 13:01:01 +08001819 }
1820 // Invalid: test i2c_write_bit with position greater than 7.
1821 {
1822 json configFile = i2cWriteBitFile;
1823 configFile["rules"][0]["actions"][1]["i2c_write_bit"]["position"] = 8;
1824 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1825 "8 is greater than the maximum of 7");
1826 }
1827 // Invalid: test i2c_write_bit with position less than 0.
1828 {
1829 json configFile = i2cWriteBitFile;
1830 configFile["rules"][0]["actions"][1]["i2c_write_bit"]["position"] = -1;
1831 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1832 "-1 is less than the minimum of 0");
1833 }
1834 // Invalid: test i2c_write_bit with value wrong type.
1835 {
1836 json configFile = i2cWriteBitFile;
1837 configFile["rules"][0]["actions"][1]["i2c_write_bit"]["value"] = "1";
1838 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001839 "'1' is not of type 'integer'");
Bob King188db7d2020-01-31 13:01:01 +08001840 }
1841 // Invalid: test i2c_write_bit with value greater than 1.
1842 {
1843 json configFile = i2cWriteBitFile;
1844 configFile["rules"][0]["actions"][1]["i2c_write_bit"]["value"] = 2;
1845 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1846 "2 is greater than the maximum of 1");
1847 }
1848 // Invalid: test i2c_write_bit with value less than 0.
1849 {
1850 json configFile = i2cWriteBitFile;
1851 configFile["rules"][0]["actions"][1]["i2c_write_bit"]["value"] = -1;
1852 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1853 "-1 is less than the minimum of 0");
1854 }
1855}
Shawn McCarney846dde52021-08-14 12:47:44 -05001856
Bob King188db7d2020-01-31 13:01:01 +08001857TEST(ValidateRegulatorsConfigTest, I2CWriteByte)
1858{
1859 json i2cWriteByteFile = validConfigFile;
1860 i2cWriteByteFile["rules"][0]["actions"][1]["i2c_write_byte"]["register"] =
1861 "0x82";
1862 i2cWriteByteFile["rules"][0]["actions"][1]["i2c_write_byte"]["value"] =
1863 "0x40";
1864 i2cWriteByteFile["rules"][0]["actions"][1]["i2c_write_byte"]["mask"] =
1865 "0x7F";
1866 // Valid: test i2c_write_byte with all properties.
1867 {
1868 json configFile = i2cWriteByteFile;
1869 EXPECT_JSON_VALID(configFile);
1870 }
1871 // Valid: test i2c_write_byte with all required properties.
1872 {
1873 json configFile = i2cWriteByteFile;
1874 configFile["rules"][0]["actions"][1]["i2c_write_byte"].erase("mask");
1875 EXPECT_JSON_VALID(configFile);
1876 }
1877 // Invalid: test i2c_write_byte with no register.
1878 {
1879 json configFile = i2cWriteByteFile;
1880 configFile["rules"][0]["actions"][1]["i2c_write_byte"].erase(
1881 "register");
1882 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001883 "'register' is a required property");
Bob King188db7d2020-01-31 13:01:01 +08001884 }
1885 // Invalid: test i2c_write_byte with no value.
1886 {
1887 json configFile = i2cWriteByteFile;
1888 configFile["rules"][0]["actions"][1]["i2c_write_byte"].erase("value");
1889 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001890 "'value' is a required property");
Bob King188db7d2020-01-31 13:01:01 +08001891 }
1892 // Invalid: test i2c_write_byte with property register wrong type.
1893 {
1894 json configFile = i2cWriteByteFile;
1895 configFile["rules"][0]["actions"][1]["i2c_write_byte"]["register"] = 1;
1896 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001897 "1 is not of type 'string'");
Bob King188db7d2020-01-31 13:01:01 +08001898 }
1899 // Invalid: test i2c_write_byte with property value wrong type.
1900 {
1901 json configFile = i2cWriteByteFile;
1902 configFile["rules"][0]["actions"][1]["i2c_write_byte"]["value"] = 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 mask wrong type.
1907 {
1908 json configFile = i2cWriteByteFile;
1909 configFile["rules"][0]["actions"][1]["i2c_write_byte"]["mask"] = 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 register more than 2 hex
1914 // digits.
1915 {
1916 json configFile = i2cWriteByteFile;
1917 configFile["rules"][0]["actions"][1]["i2c_write_byte"]["register"] =
1918 "0x820";
1919 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001920 "'0x820' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08001921 }
1922 // Invalid: test i2c_write_byte with property value more than 2 hex
1923 // digits.
1924 {
1925 json configFile = i2cWriteByteFile;
1926 configFile["rules"][0]["actions"][1]["i2c_write_byte"]["value"] =
1927 "0x820";
1928 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001929 "'0x820' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08001930 }
1931 // Invalid: test i2c_write_byte with property mask more than 2 hex digits.
1932 {
1933 json configFile = i2cWriteByteFile;
1934 configFile["rules"][0]["actions"][1]["i2c_write_byte"]["mask"] =
1935 "0x820";
1936 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001937 "'0x820' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08001938 }
1939 // Invalid: test i2c_write_byte with property register less than 2 hex
1940 // digits.
1941 {
1942 json configFile = i2cWriteByteFile;
1943 configFile["rules"][0]["actions"][1]["i2c_write_byte"]["register"] =
1944 "0x8";
1945 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001946 "'0x8' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08001947 }
1948 // Invalid: test i2c_write_byte with property value less than 2 hex
1949 // digits.
1950 {
1951 json configFile = i2cWriteByteFile;
1952 configFile["rules"][0]["actions"][1]["i2c_write_byte"]["value"] = "0x8";
1953 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001954 "'0x8' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08001955 }
1956 // Invalid: test i2c_write_byte with property mask less than 2 hex digits.
1957 {
1958 json configFile = i2cWriteByteFile;
1959 configFile["rules"][0]["actions"][1]["i2c_write_byte"]["mask"] = "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 register no leading prefix.
1964 {
1965 json configFile = i2cWriteByteFile;
1966 configFile["rules"][0]["actions"][1]["i2c_write_byte"]["register"] =
1967 "82";
1968 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001969 "'82' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08001970 }
1971 // Invalid: test i2c_write_byte with property value no leading prefix.
1972 {
1973 json configFile = i2cWriteByteFile;
1974 configFile["rules"][0]["actions"][1]["i2c_write_byte"]["value"] = "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 mask no leading prefix.
1979 {
1980 json configFile = i2cWriteByteFile;
1981 configFile["rules"][0]["actions"][1]["i2c_write_byte"]["mask"] = "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 register invalid hex digit.
1986 {
1987 json configFile = i2cWriteByteFile;
1988 configFile["rules"][0]["actions"][1]["i2c_write_byte"]["register"] =
1989 "0xG1";
1990 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001991 "'0xG1' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08001992 }
1993 // Invalid: test i2c_write_byte with property value invalid hex digit.
1994 {
1995 json configFile = i2cWriteByteFile;
1996 configFile["rules"][0]["actions"][1]["i2c_write_byte"]["value"] =
1997 "0xG1";
1998 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001999 "'0xG1' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08002000 }
2001 // Invalid: test i2c_write_byte with property mask invalid hex digit.
2002 {
2003 json configFile = i2cWriteByteFile;
2004 configFile["rules"][0]["actions"][1]["i2c_write_byte"]["mask"] = "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}
Shawn McCarney846dde52021-08-14 12:47:44 -05002009
Bob King188db7d2020-01-31 13:01:01 +08002010TEST(ValidateRegulatorsConfigTest, I2CWriteBytes)
2011{
2012 json i2cWriteBytesFile = validConfigFile;
2013 i2cWriteBytesFile["rules"][0]["actions"][1]["i2c_write_bytes"]["register"] =
2014 "0x82";
2015 i2cWriteBytesFile["rules"][0]["actions"][1]["i2c_write_bytes"]["values"] = {
2016 "0x02", "0x73"};
2017 i2cWriteBytesFile["rules"][0]["actions"][1]["i2c_write_bytes"]["masks"] = {
2018 "0x7F", "0x7F"};
2019 // Valid: test i2c_write_bytes.
2020 {
2021 json configFile = i2cWriteBytesFile;
2022 EXPECT_JSON_VALID(configFile);
2023 }
2024 // Valid: test i2c_write_bytes with all required properties.
2025 {
2026 json configFile = i2cWriteBytesFile;
2027 configFile["rules"][0]["actions"][1]["i2c_write_bytes"].erase("masks");
2028 EXPECT_JSON_VALID(configFile);
2029 }
2030 // Invalid: test i2c_write_bytes with no register.
2031 {
2032 json configFile = i2cWriteBytesFile;
2033 configFile["rules"][0]["actions"][1]["i2c_write_bytes"].erase(
2034 "register");
2035 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002036 "'register' is a required property");
Bob King188db7d2020-01-31 13:01:01 +08002037 }
2038 // Invalid: test i2c_write_bytes with no values.
2039 {
2040 json configFile = i2cWriteBytesFile;
2041 configFile["rules"][0]["actions"][1]["i2c_write_bytes"].erase("values");
2042 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002043 "'values' is a required property");
Bob King188db7d2020-01-31 13:01:01 +08002044 }
2045 // Invalid: test i2c_write_bytes with property values as empty array.
2046 {
2047 json configFile = i2cWriteBytesFile;
2048 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["values"] =
2049 json::array();
2050 EXPECT_JSON_INVALID(configFile, "Validation failed.",
2051 "[] is too short");
2052 }
2053 // Invalid: test i2c_write_bytes with property masks as empty array.
2054 {
2055 json configFile = i2cWriteBytesFile;
2056 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["masks"] =
2057 json::array();
2058 EXPECT_JSON_INVALID(configFile, "Validation failed.",
2059 "[] is too short");
2060 }
2061 // Invalid: test i2c_write_bytes with property register wrong type.
2062 {
2063 json configFile = i2cWriteBytesFile;
2064 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["register"] = 1;
2065 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002066 "1 is not of type 'string'");
Bob King188db7d2020-01-31 13:01:01 +08002067 }
2068 // Invalid: test i2c_write_bytes with property values wrong type.
2069 {
2070 json configFile = i2cWriteBytesFile;
2071 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["values"] = 1;
2072 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002073 "1 is not of type 'array'");
Bob King188db7d2020-01-31 13:01:01 +08002074 }
2075 // Invalid: test i2c_write_bytes with property masks wrong type.
2076 {
2077 json configFile = i2cWriteBytesFile;
2078 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["masks"] = 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 register more than 2 hex
2083 // digits.
2084 {
2085 json configFile = i2cWriteBytesFile;
2086 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["register"] =
2087 "0x820";
2088 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002089 "'0x820' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08002090 }
2091 // Invalid: test i2c_write_bytes with property values more than 2 hex
2092 // digits.
2093 {
2094 json configFile = i2cWriteBytesFile;
2095 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["values"][0] =
2096 "0x820";
2097 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002098 "'0x820' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08002099 }
2100 // Invalid: test i2c_write_bytes with property masks more than 2 hex
2101 // digits.
2102 {
2103 json configFile = i2cWriteBytesFile;
2104 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["masks"][0] =
2105 "0x820";
2106 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002107 "'0x820' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08002108 }
2109 // Invalid: test i2c_write_bytes with property register less than 2 hex
2110 // digits.
2111 {
2112 json configFile = i2cWriteBytesFile;
2113 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["register"] =
2114 "0x8";
2115 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002116 "'0x8' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08002117 }
2118 // Invalid: test i2c_write_bytes with property values less than 2 hex
2119 // digits.
2120 {
2121 json configFile = i2cWriteBytesFile;
2122 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["values"][0] =
2123 "0x8";
2124 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002125 "'0x8' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08002126 }
2127 // Invalid: test i2c_write_bytes with property masks less than 2 hex
2128 // digits.
2129 {
2130 json configFile = i2cWriteBytesFile;
2131 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["masks"][0] =
2132 "0x8";
2133 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002134 "'0x8' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08002135 }
2136 // Invalid: test i2c_write_bytes with property register no leading prefix.
2137 {
2138 json configFile = i2cWriteBytesFile;
2139 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["register"] =
2140 "82";
2141 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002142 "'82' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08002143 }
2144 // Invalid: test i2c_write_bytes with property values no leading prefix.
2145 {
2146 json configFile = i2cWriteBytesFile;
2147 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["values"][0] =
2148 "82";
2149 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002150 "'82' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08002151 }
2152 // Invalid: test i2c_write_bytes with property masks no leading prefix.
2153 {
2154 json configFile = i2cWriteBytesFile;
2155 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["masks"][0] =
2156 "82";
2157 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002158 "'82' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08002159 }
2160 // Invalid: test i2c_write_bytes with property register invalid hex digit.
2161 {
2162 json configFile = i2cWriteBytesFile;
2163 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["register"] =
2164 "0xG1";
2165 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002166 "'0xG1' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08002167 }
2168 // Invalid: test i2c_write_bytes with property values invalid hex digit.
2169 {
2170 json configFile = i2cWriteBytesFile;
2171 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["values"][0] =
2172 "0xG1";
2173 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002174 "'0xG1' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08002175 }
2176 // Invalid: test i2c_write_bytes with property masks invalid hex digit.
2177 {
2178 json configFile = i2cWriteBytesFile;
2179 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["masks"][0] =
2180 "0xG1";
2181 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002182 "'0xG1' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08002183 }
2184}
Shawn McCarney846dde52021-08-14 12:47:44 -05002185
Bob Kingead0b052020-01-21 11:29:03 +08002186TEST(ValidateRegulatorsConfigTest, If)
2187{
2188 json ifFile = validConfigFile;
Shawn McCarney846dde52021-08-14 12:47:44 -05002189 ifFile["rules"][4]["actions"][0]["if"]["condition"]["run_rule"] =
Bob King2d27dcf2020-02-11 15:00:50 +08002190 "set_voltage_rule";
Shawn McCarney846dde52021-08-14 12:47:44 -05002191 ifFile["rules"][4]["actions"][0]["if"]["then"][0]["run_rule"] =
Bob King2d27dcf2020-02-11 15:00:50 +08002192 "read_sensors_rule";
Shawn McCarney846dde52021-08-14 12:47:44 -05002193 ifFile["rules"][4]["actions"][0]["if"]["else"][0]["run_rule"] =
Bob King2d27dcf2020-02-11 15:00:50 +08002194 "read_sensors_rule";
Shawn McCarney846dde52021-08-14 12:47:44 -05002195 ifFile["rules"][4]["id"] = "rule_if";
Bob Kingead0b052020-01-21 11:29:03 +08002196 // Valid: test if.
2197 {
2198 json configFile = ifFile;
2199 EXPECT_JSON_VALID(configFile);
2200 }
2201 // Valid: test if with required properties.
2202 {
2203 json configFile = ifFile;
Shawn McCarney846dde52021-08-14 12:47:44 -05002204 configFile["rules"][4]["actions"][0]["if"].erase("else");
Bob Kingead0b052020-01-21 11:29:03 +08002205 EXPECT_JSON_VALID(configFile);
2206 }
2207 // Invalid: test if with no property condition.
2208 {
2209 json configFile = ifFile;
Shawn McCarney846dde52021-08-14 12:47:44 -05002210 configFile["rules"][4]["actions"][0]["if"].erase("condition");
Bob Kingead0b052020-01-21 11:29:03 +08002211 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002212 "'condition' is a required property");
Bob Kingead0b052020-01-21 11:29:03 +08002213 }
2214 // Invalid: test if with no property then.
2215 {
2216 json configFile = ifFile;
Shawn McCarney846dde52021-08-14 12:47:44 -05002217 configFile["rules"][4]["actions"][0]["if"].erase("then");
Bob Kingead0b052020-01-21 11:29:03 +08002218 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002219 "'then' is a required property");
Bob Kingead0b052020-01-21 11:29:03 +08002220 }
2221 // Invalid: test if with property then empty array.
2222 {
2223 json configFile = ifFile;
Shawn McCarney846dde52021-08-14 12:47:44 -05002224 configFile["rules"][4]["actions"][0]["if"]["then"] = json::array();
Bob Kingead0b052020-01-21 11:29:03 +08002225 EXPECT_JSON_INVALID(configFile, "Validation failed.",
2226 "[] is too short");
2227 }
2228 // Invalid: test if with property else empty array.
2229 {
2230 json configFile = ifFile;
Shawn McCarney846dde52021-08-14 12:47:44 -05002231 configFile["rules"][4]["actions"][0]["if"]["else"] = 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 condition wrong type.
2236 {
2237 json configFile = ifFile;
Shawn McCarney846dde52021-08-14 12:47:44 -05002238 configFile["rules"][4]["actions"][0]["if"]["condition"] = 1;
Bob Kingead0b052020-01-21 11:29:03 +08002239 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002240 "1 is not of type 'object'");
Bob Kingead0b052020-01-21 11:29:03 +08002241 }
2242 // Invalid: test if with property then wrong type.
2243 {
2244 json configFile = ifFile;
Shawn McCarney846dde52021-08-14 12:47:44 -05002245 configFile["rules"][4]["actions"][0]["if"]["then"] = 1;
Bob Kingead0b052020-01-21 11:29:03 +08002246 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002247 "1 is not of type 'array'");
Bob Kingead0b052020-01-21 11:29:03 +08002248 }
2249 // Invalid: test if with property else wrong type.
2250 {
2251 json configFile = ifFile;
Shawn McCarney846dde52021-08-14 12:47:44 -05002252 configFile["rules"][4]["actions"][0]["if"]["else"] = 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}
Shawn McCarney846dde52021-08-14 12:47:44 -05002257
2258TEST(ValidateRegulatorsConfigTest, LogPhaseFault)
2259{
2260 json initialFile = validConfigFile;
2261 initialFile["rules"][0]["actions"][1]["log_phase_fault"]["type"] = "n";
2262
2263 // Valid: All required properties
2264 {
2265 json configFile = initialFile;
2266 EXPECT_JSON_VALID(configFile);
2267 }
2268
2269 // Invalid: type not specified
2270 {
2271 json configFile = initialFile;
2272 configFile["rules"][0]["actions"][1]["log_phase_fault"].erase("type");
2273 EXPECT_JSON_INVALID(configFile, "Validation failed.",
2274 "'type' is a required property");
2275 }
2276
2277 // Invalid: invalid property specified
2278 {
2279 json configFile = initialFile;
2280 configFile["rules"][0]["actions"][1]["log_phase_fault"]["foo"] = true;
2281 EXPECT_JSON_INVALID(
2282 configFile, "Validation failed.",
2283 "Additional properties are not allowed ('foo' was unexpected)");
2284 }
2285
2286 // Invalid: type has wrong data type
2287 {
2288 json configFile = initialFile;
2289 configFile["rules"][0]["actions"][1]["log_phase_fault"]["type"] = true;
2290 EXPECT_JSON_INVALID(configFile, "Validation failed.",
2291 "True is not of type 'string'");
2292 }
2293
2294 // Invalid: type has invalid value
2295 {
2296 json configFile = initialFile;
2297 configFile["rules"][0]["actions"][1]["log_phase_fault"]["type"] = "n+2";
2298 EXPECT_JSON_INVALID(configFile, "Validation failed.",
2299 "'n+2' is not one of ['n+1', 'n']");
2300 }
2301}
2302
Bob Kingbfe9fe72020-01-21 11:29:57 +08002303TEST(ValidateRegulatorsConfigTest, Not)
2304{
2305 json notFile = validConfigFile;
2306 notFile["rules"][0]["actions"][1]["not"]["i2c_compare_byte"]["register"] =
2307 "0xA0";
2308 notFile["rules"][0]["actions"][1]["not"]["i2c_compare_byte"]["value"] =
2309 "0xFF";
2310 // Valid: test not.
2311 {
2312 json configFile = notFile;
2313 EXPECT_JSON_VALID(configFile);
2314 }
2315 // Invalid: test not with wrong type.
2316 {
2317 json configFile = notFile;
2318 configFile["rules"][0]["actions"][1]["not"] = 1;
2319 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002320 "1 is not of type 'object'");
Bob Kingbfe9fe72020-01-21 11:29:57 +08002321 }
2322}
Shawn McCarney846dde52021-08-14 12:47:44 -05002323
Bob Kingcfc29d02020-01-21 11:30:50 +08002324TEST(ValidateRegulatorsConfigTest, Or)
2325{
2326 json orFile = validConfigFile;
2327 orFile["rules"][0]["actions"][1]["or"][0]["i2c_compare_byte"]["register"] =
2328 "0xA0";
2329 orFile["rules"][0]["actions"][1]["or"][0]["i2c_compare_byte"]["value"] =
2330 "0x00";
2331 orFile["rules"][0]["actions"][1]["or"][1]["i2c_compare_byte"]["register"] =
2332 "0xA1";
2333 orFile["rules"][0]["actions"][1]["or"][1]["i2c_compare_byte"]["value"] =
2334 "0x00";
2335 // Valid: test or.
2336 {
2337 json configFile = orFile;
2338 EXPECT_JSON_VALID(configFile);
2339 }
2340 // Invalid: test or with empty array.
2341 {
2342 json configFile = orFile;
2343 configFile["rules"][0]["actions"][1]["or"] = json::array();
2344 EXPECT_JSON_INVALID(configFile, "Validation failed.",
2345 "[] is too short");
2346 }
2347 // Invalid: test or with wrong type.
2348 {
2349 json configFile = orFile;
2350 configFile["rules"][0]["actions"][1]["or"] = 1;
2351 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002352 "1 is not of type 'array'");
Bob Kingcfc29d02020-01-21 11:30:50 +08002353 }
2354}
Shawn McCarney846dde52021-08-14 12:47:44 -05002355
2356TEST(ValidateRegulatorsConfigTest, PhaseFaultDetection)
2357{
2358 json initialFile = validConfigFile;
2359 initialFile["chassis"][0]["devices"][0]["phase_fault_detection"]
2360 ["rule_id"] = "detect_phase_faults_rule";
2361
2362 // Valid: comments specified
2363 {
2364 json configFile = initialFile;
2365 configFile["chassis"][0]["devices"][0]["phase_fault_detection"]
2366 ["comments"][0] = "Detect phase faults";
2367 EXPECT_JSON_VALID(configFile);
2368 }
2369
2370 // Valid: device_id specified
2371 {
2372 json configFile = initialFile;
2373 configFile["chassis"][0]["devices"][0]["phase_fault_detection"]
2374 ["device_id"] = "vdd_regulator";
2375 EXPECT_JSON_VALID(configFile);
2376 }
2377
2378 // Valid: rule_id specified
2379 {
2380 json configFile = initialFile;
2381 EXPECT_JSON_VALID(configFile);
2382 }
2383
2384 // Valid: actions specified
2385 {
2386 json configFile = initialFile;
2387 configFile["chassis"][0]["devices"][0]["phase_fault_detection"].erase(
2388 "rule_id");
2389 configFile["chassis"][0]["devices"][0]["phase_fault_detection"]
2390 ["actions"][0]["run_rule"] = "detect_phase_faults_rule";
2391 EXPECT_JSON_VALID(configFile);
2392 }
2393
2394 // Invalid: rule_id and actions specified
2395 {
2396 json configFile = initialFile;
2397 configFile["chassis"][0]["devices"][0]["phase_fault_detection"]
2398 ["actions"][0]["run_rule"] = "detect_phase_faults_rule";
2399 EXPECT_JSON_INVALID(configFile, "Validation failed.", "");
2400 }
2401
2402 // Invalid: neither rule_id nor actions specified
2403 {
2404 json configFile = initialFile;
2405 configFile["chassis"][0]["devices"][0]["phase_fault_detection"].erase(
2406 "rule_id");
2407 EXPECT_JSON_INVALID(configFile, "Validation failed.",
2408 "'rule_id' is a required property");
2409 }
2410
2411 // Invalid: comments has wrong data type
2412 {
2413 json configFile = initialFile;
2414 configFile["chassis"][0]["devices"][0]["phase_fault_detection"]
2415 ["comments"] = true;
2416 EXPECT_JSON_INVALID(configFile, "Validation failed.",
2417 "True is not of type 'array'");
2418 }
2419
2420 // Invalid: device_id has wrong data type
2421 {
2422 json configFile = initialFile;
2423 configFile["chassis"][0]["devices"][0]["phase_fault_detection"]
2424 ["device_id"] = true;
2425 EXPECT_JSON_INVALID(configFile, "Validation failed.",
2426 "True is not of type 'string'");
2427 }
2428
2429 // Invalid: rule_id has wrong data type
2430 {
2431 json configFile = initialFile;
2432 configFile["chassis"][0]["devices"][0]["phase_fault_detection"]
2433 ["rule_id"] = true;
2434 EXPECT_JSON_INVALID(configFile, "Validation failed.",
2435 "True is not of type 'string'");
2436 }
2437
2438 // Invalid: actions has wrong data type
2439 {
2440 json configFile = initialFile;
2441 configFile["chassis"][0]["devices"][0]["phase_fault_detection"].erase(
2442 "rule_id");
2443 configFile["chassis"][0]["devices"][0]["phase_fault_detection"]
2444 ["actions"] = true;
2445 EXPECT_JSON_INVALID(configFile, "Validation failed.",
2446 "True is not of type 'array'");
2447 }
2448
2449 // Invalid: device_id has invalid format
2450 {
2451 json configFile = initialFile;
2452 configFile["chassis"][0]["devices"][0]["phase_fault_detection"]
2453 ["device_id"] = "id@";
2454 EXPECT_JSON_INVALID(configFile, "Validation failed.",
2455 "'id@' does not match '^[A-Za-z0-9_]+$'");
2456 }
2457
2458 // Invalid: rule_id has invalid format
2459 {
2460 json configFile = initialFile;
2461 configFile["chassis"][0]["devices"][0]["phase_fault_detection"]
2462 ["rule_id"] = "id@";
2463 EXPECT_JSON_INVALID(configFile, "Validation failed.",
2464 "'id@' does not match '^[A-Za-z0-9_]+$'");
2465 }
2466
2467 // Invalid: comments array is empty
2468 {
2469 json configFile = initialFile;
2470 configFile["chassis"][0]["devices"][0]["phase_fault_detection"]
2471 ["comments"] = json::array();
2472 EXPECT_JSON_INVALID(configFile, "Validation failed.",
2473 "[] is too short");
2474 }
2475
2476 // Invalid: actions array is empty
2477 {
2478 json configFile = initialFile;
2479 configFile["chassis"][0]["devices"][0]["phase_fault_detection"].erase(
2480 "rule_id");
2481 configFile["chassis"][0]["devices"][0]["phase_fault_detection"]
2482 ["actions"] = json::array();
2483 EXPECT_JSON_INVALID(configFile, "Validation failed.",
2484 "[] is too short");
2485 }
2486}
2487
Bob Kingd6618092020-01-21 11:31:46 +08002488TEST(ValidateRegulatorsConfigTest, PmbusReadSensor)
2489{
2490 json pmbusReadSensorFile = validConfigFile;
2491 pmbusReadSensorFile["rules"][0]["actions"][1]["pmbus_read_sensor"]["type"] =
2492 "vout";
2493 pmbusReadSensorFile["rules"][0]["actions"][1]["pmbus_read_sensor"]
2494 ["command"] = "0x8B";
2495 pmbusReadSensorFile["rules"][0]["actions"][1]["pmbus_read_sensor"]
2496 ["format"] = "linear_16";
2497 pmbusReadSensorFile["rules"][0]["actions"][1]["pmbus_read_sensor"]
2498 ["exponent"] = -8;
2499 // Valid: test pmbus_read_sensor.
2500 {
2501 json configFile = pmbusReadSensorFile;
2502 EXPECT_JSON_VALID(configFile);
2503 }
2504 // Valid: test pmbus_read_sensor with required properties.
2505 {
2506 json configFile = pmbusReadSensorFile;
2507 configFile["rules"][0]["actions"][1]["pmbus_read_sensor"].erase(
2508 "exponent");
2509 EXPECT_JSON_VALID(configFile);
2510 }
2511 // Invalid: test pmbus_read_sensor with no type.
2512 {
2513 json configFile = pmbusReadSensorFile;
2514 configFile["rules"][0]["actions"][1]["pmbus_read_sensor"].erase("type");
2515 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002516 "'type' is a required property");
Bob Kingd6618092020-01-21 11:31:46 +08002517 }
2518 // Invalid: test pmbus_read_sensor with no command.
2519 {
2520 json configFile = pmbusReadSensorFile;
2521 configFile["rules"][0]["actions"][1]["pmbus_read_sensor"].erase(
2522 "command");
2523 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002524 "'command' is a required property");
Bob Kingd6618092020-01-21 11:31:46 +08002525 }
2526 // Invalid: test pmbus_read_sensor with no format.
2527 {
2528 json configFile = pmbusReadSensorFile;
2529 configFile["rules"][0]["actions"][1]["pmbus_read_sensor"].erase(
2530 "format");
2531 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002532 "'format' is a required property");
Bob Kingd6618092020-01-21 11:31:46 +08002533 }
2534 // Invalid: test pmbus_read_sensor with property type wrong type.
2535 {
2536 json configFile = pmbusReadSensorFile;
2537 configFile["rules"][0]["actions"][1]["pmbus_read_sensor"]["type"] =
2538 true;
Bob King358c4172020-03-16 13:57:08 +08002539 EXPECT_JSON_INVALID(configFile, "Validation failed.",
2540 "True is not of type 'string'");
Bob Kingd6618092020-01-21 11:31:46 +08002541 }
2542 // Invalid: test pmbus_read_sensor with property command wrong type.
2543 {
2544 json configFile = pmbusReadSensorFile;
2545 configFile["rules"][0]["actions"][1]["pmbus_read_sensor"]["command"] =
2546 true;
2547 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002548 "True is not of type 'string'");
Bob Kingd6618092020-01-21 11:31:46 +08002549 }
2550 // Invalid: test pmbus_read_sensor with property format wrong type.
2551 {
2552 json configFile = pmbusReadSensorFile;
2553 configFile["rules"][0]["actions"][1]["pmbus_read_sensor"]["format"] =
2554 true;
2555 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002556 "True is not of type 'string'");
Bob Kingd6618092020-01-21 11:31:46 +08002557 }
2558 // Invalid: test pmbus_read_sensor with property exponent wrong type.
2559 {
2560 json configFile = pmbusReadSensorFile;
2561 configFile["rules"][0]["actions"][1]["pmbus_read_sensor"]["exponent"] =
2562 true;
2563 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002564 "True is not of type 'integer'");
Bob Kingd6618092020-01-21 11:31:46 +08002565 }
2566 // Invalid: test pmbus_read_sensor with property type wrong format.
2567 {
2568 json configFile = pmbusReadSensorFile;
2569 configFile["rules"][0]["actions"][1]["pmbus_read_sensor"]["type"] =
2570 "foo";
2571 EXPECT_JSON_INVALID(
2572 configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002573 "'foo' is not one of ['iout', 'iout_peak', 'iout_valley', "
2574 "'pout', 'temperature', 'temperature_peak', 'vout', "
2575 "'vout_peak', 'vout_valley']");
Bob Kingd6618092020-01-21 11:31:46 +08002576 }
2577 // Invalid: test pmbus_read_sensor with property command wrong format.
2578 {
2579 json configFile = pmbusReadSensorFile;
2580 configFile["rules"][0]["actions"][1]["pmbus_read_sensor"]["command"] =
2581 "0x8B0";
2582 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002583 "'0x8B0' does not match '^0x[0-9a-fA-F]{2}$'");
Bob Kingd6618092020-01-21 11:31:46 +08002584 }
2585 // Invalid: test pmbus_read_sensor with property format wrong format.
2586 {
2587 json configFile = pmbusReadSensorFile;
2588 configFile["rules"][0]["actions"][1]["pmbus_read_sensor"]["format"] =
2589 "foo";
Bob King358c4172020-03-16 13:57:08 +08002590 EXPECT_JSON_INVALID(configFile, "Validation failed.",
2591 "'foo' is not one of ['linear_11', 'linear_16']");
Bob Kingd6618092020-01-21 11:31:46 +08002592 }
2593}
Shawn McCarney846dde52021-08-14 12:47:44 -05002594
Bob King02179c62020-01-21 11:32:36 +08002595TEST(ValidateRegulatorsConfigTest, PmbusWriteVoutCommand)
2596{
2597 json pmbusWriteVoutCommandFile = validConfigFile;
2598 pmbusWriteVoutCommandFile["rules"][0]["actions"][1]
2599 ["pmbus_write_vout_command"]["volts"] = 1.03;
2600 pmbusWriteVoutCommandFile["rules"][0]["actions"][1]
2601 ["pmbus_write_vout_command"]["format"] = "linear";
2602 pmbusWriteVoutCommandFile["rules"][0]["actions"][1]
2603 ["pmbus_write_vout_command"]["exponent"] = -8;
2604 pmbusWriteVoutCommandFile["rules"][0]["actions"][1]
2605 ["pmbus_write_vout_command"]["is_verified"] = true;
2606 // Valid: test pmbus_write_vout_command.
2607 {
2608 json configFile = pmbusWriteVoutCommandFile;
2609 EXPECT_JSON_VALID(configFile);
2610 }
2611 // Valid: test pmbus_write_vout_command with required properties.
2612 {
2613 json configFile = pmbusWriteVoutCommandFile;
2614 configFile["rules"][0]["actions"][1]["pmbus_write_vout_command"].erase(
2615 "volts");
2616 configFile["rules"][0]["actions"][1]["pmbus_write_vout_command"].erase(
2617 "exponent");
2618 configFile["rules"][0]["actions"][1]["pmbus_write_vout_command"].erase(
2619 "is_verified");
2620 EXPECT_JSON_VALID(configFile);
2621 }
2622 // Invalid: test pmbus_write_vout_command with no format.
2623 {
2624 json configFile = pmbusWriteVoutCommandFile;
2625 configFile["rules"][0]["actions"][1]["pmbus_write_vout_command"].erase(
2626 "format");
2627 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002628 "'format' is a required property");
Bob King02179c62020-01-21 11:32:36 +08002629 }
2630 // Invalid: test pmbus_write_vout_command with property volts wrong type.
2631 {
2632 json configFile = pmbusWriteVoutCommandFile;
2633 configFile["rules"][0]["actions"][1]["pmbus_write_vout_command"]
2634 ["volts"] = true;
2635 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002636 "True is not of type 'number'");
Bob King02179c62020-01-21 11:32:36 +08002637 }
2638 // Invalid: test pmbus_write_vout_command with property format wrong type.
2639 {
2640 json configFile = pmbusWriteVoutCommandFile;
2641 configFile["rules"][0]["actions"][1]["pmbus_write_vout_command"]
2642 ["format"] = true;
2643 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002644 "True is not of type 'string'");
Bob King02179c62020-01-21 11:32:36 +08002645 }
2646 // Invalid: test pmbus_write_vout_command with property exponent wrong type.
2647 {
2648 json configFile = pmbusWriteVoutCommandFile;
2649 configFile["rules"][0]["actions"][1]["pmbus_write_vout_command"]
2650 ["exponent"] = 1.3;
2651 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002652 "1.3 is not of type 'integer'");
Bob King02179c62020-01-21 11:32:36 +08002653 }
2654 // Invalid: test pmbus_write_vout_command with property is_verified wrong
2655 // type.
2656 {
2657 json configFile = pmbusWriteVoutCommandFile;
2658 configFile["rules"][0]["actions"][1]["pmbus_write_vout_command"]
2659 ["is_verified"] = 1;
2660 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002661 "1 is not of type 'boolean'");
Bob King02179c62020-01-21 11:32:36 +08002662 }
2663 // Invalid: test pmbus_write_vout_command with property format wrong format.
2664 {
2665 json configFile = pmbusWriteVoutCommandFile;
2666 configFile["rules"][0]["actions"][1]["pmbus_write_vout_command"]
2667 ["format"] = "foo";
2668 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002669 "'foo' is not one of ['linear']");
Bob King02179c62020-01-21 11:32:36 +08002670 }
2671}
Shawn McCarney846dde52021-08-14 12:47:44 -05002672
Bob King99d8fa12020-01-31 11:23:40 +08002673TEST(ValidateRegulatorsConfigTest, PresenceDetection)
2674{
2675 json presenceDetectionFile = validConfigFile;
Bob King99d8fa12020-01-31 11:23:40 +08002676 presenceDetectionFile["chassis"][0]["devices"][0]["presence_detection"]
Shawn McCarney846dde52021-08-14 12:47:44 -05002677 ["comments"][0] =
2678 "Regulator is only present if CPU3 is present";
2679 presenceDetectionFile["chassis"][0]["devices"][0]["presence_detection"]
2680 ["rule_id"] = "detect_presence_rule";
Bob King99d8fa12020-01-31 11:23:40 +08002681 // Valid: test presence_detection with only property rule_id.
2682 {
2683 json configFile = presenceDetectionFile;
2684 EXPECT_JSON_VALID(configFile);
2685 }
2686 // Valid: test presence_detection with only property actions.
2687 {
2688 json configFile = presenceDetectionFile;
2689 configFile["chassis"][0]["devices"][0]["presence_detection"].erase(
2690 "rule_id");
2691 configFile["chassis"][0]["devices"][0]["presence_detection"]["actions"]
2692 [0]["compare_presence"]["fru"] =
Bob Kinga76898f2020-10-13 15:08:33 +08002693 "system/chassis/motherboard/cpu3";
Bob King99d8fa12020-01-31 11:23:40 +08002694 configFile["chassis"][0]["devices"][0]["presence_detection"]["actions"]
2695 [0]["compare_presence"]["value"] = true;
2696 configFile["chassis"][0]["devices"][0]["presence_detection"].erase(
2697 "comments");
2698 EXPECT_JSON_VALID(configFile);
2699 }
2700 // Invalid: test presence_detection with both property rule_id and actions.
2701 {
2702 json configFile = presenceDetectionFile;
2703 configFile["chassis"][0]["devices"][0]["presence_detection"]["actions"]
2704 [0]["compare_presence"]["fru"] =
Bob Kinga76898f2020-10-13 15:08:33 +08002705 "system/chassis/motherboard/cpu3";
Bob King99d8fa12020-01-31 11:23:40 +08002706 configFile["chassis"][0]["devices"][0]["presence_detection"]["actions"]
2707 [0]["compare_presence"]["value"] = true;
Shawn McCarney846dde52021-08-14 12:47:44 -05002708 EXPECT_JSON_INVALID(configFile, "Validation failed.", "");
Bob King99d8fa12020-01-31 11:23:40 +08002709 }
2710 // Invalid: test presence_detection with no rule_id and actions.
2711 {
2712 json configFile = presenceDetectionFile;
2713 configFile["chassis"][0]["devices"][0]["presence_detection"].erase(
2714 "rule_id");
2715 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002716 "'rule_id' is a required property");
Bob King99d8fa12020-01-31 11:23:40 +08002717 }
2718 // Invalid: test presence_detection with property comments wrong type.
2719 {
2720 json configFile = presenceDetectionFile;
2721 configFile["chassis"][0]["devices"][0]["presence_detection"]
2722 ["comments"] = true;
2723 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002724 "True is not of type 'array'");
Bob King99d8fa12020-01-31 11:23:40 +08002725 }
2726 // Invalid: test presence_detection with property rule_id wrong type.
2727 {
2728 json configFile = presenceDetectionFile;
2729 configFile["chassis"][0]["devices"][0]["presence_detection"]
2730 ["rule_id"] = true;
2731 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002732 "True is not of type 'string'");
Bob King99d8fa12020-01-31 11:23:40 +08002733 }
2734 // Invalid: test presence_detection with property actions wrong type.
2735 {
2736 json configFile = presenceDetectionFile;
2737 configFile["chassis"][0]["devices"][0]["presence_detection"].erase(
2738 "rule_id");
2739 configFile["chassis"][0]["devices"][0]["presence_detection"]
2740 ["actions"] = true;
2741 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002742 "True is not of type 'array'");
Bob King99d8fa12020-01-31 11:23:40 +08002743 }
2744 // Invalid: test presence_detection with property rule_id wrong format.
2745 {
2746 json configFile = presenceDetectionFile;
2747 configFile["chassis"][0]["devices"][0]["presence_detection"]
2748 ["rule_id"] = "id@";
2749 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002750 "'id@' does not match '^[A-Za-z0-9_]+$'");
Bob King99d8fa12020-01-31 11:23:40 +08002751 }
2752 // Invalid: test presence_detection with property comments empty array.
2753 {
2754 json configFile = presenceDetectionFile;
2755 configFile["chassis"][0]["devices"][0]["presence_detection"]
2756 ["comments"] = json::array();
2757 EXPECT_JSON_INVALID(configFile, "Validation failed.",
2758 "[] is too short");
2759 }
2760 // Invalid: test presence_detection with property actions empty array.
2761 {
2762 json configFile = presenceDetectionFile;
2763 configFile["chassis"][0]["devices"][0]["presence_detection"].erase(
2764 "rule_id");
2765 configFile["chassis"][0]["devices"][0]["presence_detection"]
2766 ["actions"] = json::array();
2767 EXPECT_JSON_INVALID(configFile, "Validation failed.",
2768 "[] is too short");
2769 }
2770}
Shawn McCarney846dde52021-08-14 12:47:44 -05002771
Bob Kinge9260b52020-01-21 11:46:13 +08002772TEST(ValidateRegulatorsConfigTest, Rail)
2773{
2774 // Valid: test rail.
2775 {
2776 json configFile = validConfigFile;
2777 EXPECT_JSON_VALID(configFile);
2778 }
2779 // Valid: test rail with required properties.
2780 {
2781 json configFile = validConfigFile;
2782 configFile["chassis"][0]["devices"][0]["rails"][0].erase("comments");
2783 configFile["chassis"][0]["devices"][0]["rails"][0].erase(
2784 "configuration");
2785 configFile["chassis"][0]["devices"][0]["rails"][0].erase(
2786 "sensor_monitoring");
2787 EXPECT_JSON_VALID(configFile);
2788 }
2789 // Invalid: test rail with no id.
2790 {
2791 json configFile = validConfigFile;
2792 configFile["chassis"][0]["devices"][0]["rails"][0].erase("id");
2793 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002794 "'id' is a required property");
Bob Kinge9260b52020-01-21 11:46:13 +08002795 }
2796 // Invalid: test rail with comments wrong type.
2797 {
2798 json configFile = validConfigFile;
2799 configFile["chassis"][0]["devices"][0]["rails"][0]["comments"] = true;
2800 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002801 "True is not of type 'array'");
Bob Kinge9260b52020-01-21 11:46:13 +08002802 }
2803 // Invalid: test rail with id wrong type.
2804 {
2805 json configFile = validConfigFile;
2806 configFile["chassis"][0]["devices"][0]["rails"][0]["id"] = true;
2807 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002808 "True is not of type 'string'");
Bob Kinge9260b52020-01-21 11:46:13 +08002809 }
2810 // Invalid: test rail with configuration wrong type.
2811 {
2812 json configFile = validConfigFile;
2813 configFile["chassis"][0]["devices"][0]["rails"][0]["configuration"] =
2814 true;
2815 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002816 "True is not of type 'object'");
Bob Kinge9260b52020-01-21 11:46:13 +08002817 }
2818 // Invalid: test rail with sensor_monitoring wrong type.
2819 {
2820 json configFile = validConfigFile;
2821 configFile["chassis"][0]["devices"][0]["rails"][0]
2822 ["sensor_monitoring"] = true;
2823 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002824 "True is not of type 'object'");
Bob Kinge9260b52020-01-21 11:46:13 +08002825 }
2826 // Invalid: test rail with comments empty array.
2827 {
2828 json configFile = validConfigFile;
2829 configFile["chassis"][0]["devices"][0]["rails"][0]["comments"] =
2830 json::array();
2831 EXPECT_JSON_INVALID(configFile, "Validation failed.",
2832 "[] is too short");
2833 }
2834 // Invalid: test rail with id wrong format.
2835 {
2836 json configFile = validConfigFile;
2837 configFile["chassis"][0]["devices"][0]["rails"][0]["id"] = "id~";
2838 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002839 "'id~' does not match '^[A-Za-z0-9_]+$'");
Bob Kinge9260b52020-01-21 11:46:13 +08002840 }
2841}
Shawn McCarney846dde52021-08-14 12:47:44 -05002842
Bob King64df7da2020-01-31 12:04:12 +08002843TEST(ValidateRegulatorsConfigTest, Rule)
2844{
2845 // valid test comments property, id property,
2846 // action property specified.
2847 {
2848 json configFile = validConfigFile;
2849 EXPECT_JSON_VALID(configFile);
2850 }
2851
2852 // valid test rule with no comments
2853 {
2854 json configFile = validConfigFile;
2855 configFile["rules"][0].erase("comments");
2856 EXPECT_JSON_VALID(configFile);
2857 }
2858
2859 // invalid test comments property has invalid value type
2860 {
2861 json configFile = validConfigFile;
2862 configFile["rules"][0]["comments"] = {1};
2863 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002864 "1 is not of type 'string'");
Bob King64df7da2020-01-31 12:04:12 +08002865 }
2866
2867 // invalid test rule with no ID
2868 {
2869 json configFile = validConfigFile;
2870 configFile["rules"][0].erase("id");
2871 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002872 "'id' is a required property");
Bob King64df7da2020-01-31 12:04:12 +08002873 }
2874
2875 // invalid test id property has invalid value type (not string)
2876 {
2877 json configFile = validConfigFile;
2878 configFile["rules"][0]["id"] = true;
2879 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002880 "True is not of type 'string'");
Bob King64df7da2020-01-31 12:04:12 +08002881 }
2882
2883 // invalid test id property has invalid value
2884 {
2885 json configFile = validConfigFile;
2886 configFile["rules"][0]["id"] = "foo%";
2887 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002888 "'foo%' does not match '^[A-Za-z0-9_]+$'");
Bob King64df7da2020-01-31 12:04:12 +08002889 }
2890
2891 // invalid test rule with no actions property
2892 {
2893 json configFile = validConfigFile;
2894 configFile["rules"][0].erase("actions");
2895 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002896 "'actions' is a required property");
Bob King64df7da2020-01-31 12:04:12 +08002897 }
2898
2899 // valid test rule with multiple actions
2900 {
2901 json configFile = validConfigFile;
Bob King63d795f2020-02-11 15:22:09 +08002902 configFile["rules"][0]["actions"][1]["run_rule"] = "read_sensors_rule";
Bob King64df7da2020-01-31 12:04:12 +08002903 EXPECT_JSON_VALID(configFile);
2904 }
2905
2906 // invalid test actions property has invalid value type (not an array)
2907 {
2908 json configFile = validConfigFile;
2909 configFile["rules"][0]["actions"] = 1;
2910 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002911 "1 is not of type 'array'");
Bob King64df7da2020-01-31 12:04:12 +08002912 }
2913
2914 // invalid test actions property has invalid value of action
2915 {
2916 json configFile = validConfigFile;
2917 configFile["rules"][0]["actions"][0] = "foo";
2918 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002919 "'foo' is not of type 'object'");
Bob King64df7da2020-01-31 12:04:12 +08002920 }
2921
2922 // invalid test actions property has empty array
2923 {
2924 json configFile = validConfigFile;
2925 configFile["rules"][0]["actions"] = json::array();
2926 EXPECT_JSON_INVALID(configFile, "Validation failed.",
2927 "[] is too short");
2928 }
2929}
Shawn McCarney846dde52021-08-14 12:47:44 -05002930
Bob Kinge86c2e52020-01-21 11:33:32 +08002931TEST(ValidateRegulatorsConfigTest, RunRule)
2932{
2933 json runRuleFile = validConfigFile;
Bob King7d3a9f12020-02-11 15:34:52 +08002934 runRuleFile["rules"][0]["actions"][1]["run_rule"] = "read_sensors_rule";
Bob Kinge86c2e52020-01-21 11:33:32 +08002935 // Valid: test run_rule.
2936 {
2937 json configFile = runRuleFile;
2938 EXPECT_JSON_VALID(configFile);
2939 }
2940 // Invalid: test run_rule wrong type.
2941 {
2942 json configFile = runRuleFile;
2943 configFile["rules"][0]["actions"][1]["run_rule"] = true;
2944 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002945 "True is not of type 'string'");
Bob Kinge86c2e52020-01-21 11:33:32 +08002946 }
2947 // Invalid: test run_rule wrong format.
2948 {
2949 json configFile = runRuleFile;
2950 configFile["rules"][0]["actions"][1]["run_rule"] = "set_voltage_rule%";
2951 EXPECT_JSON_INVALID(
2952 configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002953 "'set_voltage_rule%' does not match '^[A-Za-z0-9_]+$'");
Bob Kinge86c2e52020-01-21 11:33:32 +08002954 }
2955}
Shawn McCarney846dde52021-08-14 12:47:44 -05002956
Bob Kingfcc2a2f2020-01-31 11:29:45 +08002957TEST(ValidateRegulatorsConfigTest, SensorMonitoring)
2958{
2959 // Valid: test rails sensor_monitoring with only property rule id.
2960 {
2961 json configFile = validConfigFile;
2962 EXPECT_JSON_VALID(configFile);
2963 }
2964 // Valid: test rails sensor_monitoring with only property actions.
2965 {
2966 json configFile = validConfigFile;
2967 configFile["chassis"][0]["devices"][0]["rails"][0]["sensor_monitoring"]
2968 .erase("rule_id");
2969 configFile["chassis"][0]["devices"][0]["rails"][0]["sensor_monitoring"]
2970 ["actions"][0]["compare_presence"]["fru"] =
Bob Kinga76898f2020-10-13 15:08:33 +08002971 "system/chassis/motherboard/cpu3";
Bob Kingfcc2a2f2020-01-31 11:29:45 +08002972 configFile["chassis"][0]["devices"][0]["rails"][0]["sensor_monitoring"]
2973 ["actions"][0]["compare_presence"]["value"] = true;
2974 configFile["chassis"][0]["devices"][0]["rails"][0]["sensor_monitoring"]
2975 ["comments"][0] = "comments";
2976 EXPECT_JSON_VALID(configFile);
2977 }
2978 // Invalid: test rails sensor_monitoring with both property rule_id and
2979 // actions.
2980 {
2981 json configFile = validConfigFile;
2982 configFile["chassis"][0]["devices"][0]["rails"][0]["sensor_monitoring"]
2983 ["actions"][0]["compare_presence"]["fru"] =
Bob Kinga76898f2020-10-13 15:08:33 +08002984 "system/chassis/motherboard/cpu3";
Bob Kingfcc2a2f2020-01-31 11:29:45 +08002985 configFile["chassis"][0]["devices"][0]["rails"][0]["sensor_monitoring"]
2986 ["actions"][0]["compare_presence"]["value"] = true;
Shawn McCarney846dde52021-08-14 12:47:44 -05002987 EXPECT_JSON_INVALID(configFile, "Validation failed.", "");
Bob Kingfcc2a2f2020-01-31 11:29:45 +08002988 }
2989 // Invalid: test rails sensor_monitoring with no rule_id and actions.
2990 {
2991 json configFile = validConfigFile;
2992 configFile["chassis"][0]["devices"][0]["rails"][0]["sensor_monitoring"]
2993 .erase("rule_id");
2994 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002995 "'rule_id' is a required property");
Bob Kingfcc2a2f2020-01-31 11:29:45 +08002996 }
2997 // Invalid: test rails sensor_monitoring with property comments wrong type.
2998 {
2999 json configFile = validConfigFile;
3000 configFile["chassis"][0]["devices"][0]["rails"][0]["sensor_monitoring"]
3001 ["comments"] = true;
3002 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08003003 "True is not of type 'array'");
Bob Kingfcc2a2f2020-01-31 11:29:45 +08003004 }
3005 // Invalid: test rails sensor_monitoring with property rule_id wrong type.
3006 {
3007 json configFile = validConfigFile;
3008 configFile["chassis"][0]["devices"][0]["rails"][0]["sensor_monitoring"]
3009 ["rule_id"] = true;
3010 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08003011 "True is not of type 'string'");
Bob Kingfcc2a2f2020-01-31 11:29:45 +08003012 }
3013 // Invalid: test rails sensor_monitoring with property actions wrong type.
3014 {
3015 json configFile = validConfigFile;
3016 configFile["chassis"][0]["devices"][0]["rails"][0]["sensor_monitoring"]
3017 .erase("rule_id");
3018 configFile["chassis"][0]["devices"][0]["rails"][0]["sensor_monitoring"]
3019 ["actions"] = true;
3020 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08003021 "True is not of type 'array'");
Bob Kingfcc2a2f2020-01-31 11:29:45 +08003022 }
3023 // Invalid: test rails sensor_monitoring with property rule_id wrong format.
3024 {
3025 json configFile = validConfigFile;
3026 configFile["chassis"][0]["devices"][0]["rails"][0]["sensor_monitoring"]
3027 ["rule_id"] = "id@";
3028 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08003029 "'id@' does not match '^[A-Za-z0-9_]+$'");
Bob Kingfcc2a2f2020-01-31 11:29:45 +08003030 }
3031 // Invalid: test rails sensor_monitoring with property comments empty array.
3032 {
3033 json configFile = validConfigFile;
3034 configFile["chassis"][0]["devices"][0]["rails"][0]["sensor_monitoring"]
3035 ["comments"] = json::array();
3036 EXPECT_JSON_INVALID(configFile, "Validation failed.",
3037 "[] is too short");
3038 }
3039 // Invalid: test rails sensor_monitoring with property actions empty array.
3040 {
3041 json configFile = validConfigFile;
3042 configFile["chassis"][0]["devices"][0]["rails"][0]["sensor_monitoring"]
3043 .erase("rule_id");
3044 configFile["chassis"][0]["devices"][0]["rails"][0]["sensor_monitoring"]
3045 ["actions"] = json::array();
3046 EXPECT_JSON_INVALID(configFile, "Validation failed.",
3047 "[] is too short");
3048 }
3049}
Shawn McCarney846dde52021-08-14 12:47:44 -05003050
Bob King68230aa2020-01-21 11:34:33 +08003051TEST(ValidateRegulatorsConfigTest, SetDevice)
3052{
3053 json setDeviceFile = validConfigFile;
Bob King7d3a9f12020-02-11 15:34:52 +08003054 setDeviceFile["rules"][0]["actions"][1]["set_device"] = "vdd_regulator";
Bob King68230aa2020-01-21 11:34:33 +08003055 // Valid: test set_device.
3056 {
3057 json configFile = setDeviceFile;
3058 EXPECT_JSON_VALID(configFile);
3059 }
3060 // Invalid: test set_device wrong type.
3061 {
3062 json configFile = setDeviceFile;
3063 configFile["rules"][0]["actions"][1]["set_device"] = true;
3064 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08003065 "True is not of type 'string'");
Bob King68230aa2020-01-21 11:34:33 +08003066 }
3067 // Invalid: test set_device wrong format.
3068 {
3069 json configFile = setDeviceFile;
3070 configFile["rules"][0]["actions"][1]["set_device"] = "io_expander2%";
Bob King358c4172020-03-16 13:57:08 +08003071 EXPECT_JSON_INVALID(configFile, "Validation failed.",
3072 "'io_expander2%' does not match '^[A-Za-z0-9_]+$'");
Bob King68230aa2020-01-21 11:34:33 +08003073 }
3074}
Shawn McCarney846dde52021-08-14 12:47:44 -05003075
Bob King3643cc02020-01-31 11:32:56 +08003076TEST(ValidateRegulatorsConfigTest, DuplicateRuleID)
3077{
3078 // Invalid: test duplicate ID in rule.
3079 {
3080 json configFile = validConfigFile;
Shawn McCarney846dde52021-08-14 12:47:44 -05003081 configFile["rules"][4]["id"] = "set_voltage_rule";
3082 configFile["rules"][4]["actions"][0]["pmbus_write_vout_command"]
Bob King3643cc02020-01-31 11:32:56 +08003083 ["format"] = "linear";
3084 EXPECT_JSON_INVALID(configFile, "Error: Duplicate rule ID.", "");
3085 }
3086}
Shawn McCarney846dde52021-08-14 12:47:44 -05003087
Bob King3643cc02020-01-31 11:32:56 +08003088TEST(ValidateRegulatorsConfigTest, DuplicateChassisNumber)
3089{
3090 // Invalid: test duplicate number in chassis.
3091 {
3092 json configFile = validConfigFile;
3093 configFile["chassis"][1]["number"] = 1;
Shawn McCarney4c88a4c2021-09-21 15:29:24 -05003094 configFile["chassis"][1]["inventory_path"] = "system/chassis2";
Bob King3643cc02020-01-31 11:32:56 +08003095 EXPECT_JSON_INVALID(configFile, "Error: Duplicate chassis number.", "");
3096 }
3097}
Shawn McCarney846dde52021-08-14 12:47:44 -05003098
Bob King3643cc02020-01-31 11:32:56 +08003099TEST(ValidateRegulatorsConfigTest, DuplicateDeviceID)
3100{
3101 // Invalid: test duplicate ID in device.
3102 {
3103 json configFile = validConfigFile;
3104 configFile["chassis"][0]["devices"][1]["id"] = "vdd_regulator";
3105 configFile["chassis"][0]["devices"][1]["is_regulator"] = true;
3106 configFile["chassis"][0]["devices"][1]["fru"] =
Bob Kinga76898f2020-10-13 15:08:33 +08003107 "system/chassis/motherboard/regulator1";
Bob King3643cc02020-01-31 11:32:56 +08003108 configFile["chassis"][0]["devices"][1]["i2c_interface"]["bus"] = 2;
3109 configFile["chassis"][0]["devices"][1]["i2c_interface"]["address"] =
3110 "0x71";
3111 EXPECT_JSON_INVALID(configFile, "Error: Duplicate device ID.", "");
3112 }
3113}
Shawn McCarney846dde52021-08-14 12:47:44 -05003114
Bob King3643cc02020-01-31 11:32:56 +08003115TEST(ValidateRegulatorsConfigTest, DuplicateRailID)
3116{
3117 // Invalid: test duplicate ID in rail.
3118 {
3119 json configFile = validConfigFile;
3120 configFile["chassis"][0]["devices"][0]["rails"][1]["id"] = "vdd";
3121 EXPECT_JSON_INVALID(configFile, "Error: Duplicate rail ID.", "");
3122 }
3123}
Shawn McCarney846dde52021-08-14 12:47:44 -05003124
Bob King78793102020-03-13 13:16:09 +08003125TEST(ValidateRegulatorsConfigTest, DuplicateObjectID)
3126{
3127 // Invalid: test duplicate object ID in device and rail.
3128 {
3129 json configFile = validConfigFile;
3130 configFile["chassis"][0]["devices"][0]["rails"][1]["id"] =
3131 "vdd_regulator";
3132 EXPECT_JSON_INVALID(configFile, "Error: Duplicate ID.", "");
3133 }
3134 // Invalid: test duplicate object ID in device and rule.
3135 {
3136 json configFile = validConfigFile;
Shawn McCarney846dde52021-08-14 12:47:44 -05003137 configFile["rules"][4]["id"] = "vdd_regulator";
3138 configFile["rules"][4]["actions"][0]["pmbus_write_vout_command"]
Bob King78793102020-03-13 13:16:09 +08003139 ["format"] = "linear";
3140 EXPECT_JSON_INVALID(configFile, "Error: Duplicate ID.", "");
3141 }
3142 // Invalid: test duplicate object ID in rule and rail.
3143 {
3144 json configFile = validConfigFile;
3145 configFile["chassis"][0]["devices"][0]["rails"][1]["id"] =
3146 "set_voltage_rule";
3147 EXPECT_JSON_INVALID(configFile, "Error: Duplicate ID.", "");
3148 }
3149}
Shawn McCarney846dde52021-08-14 12:47:44 -05003150
Bob King3643cc02020-01-31 11:32:56 +08003151TEST(ValidateRegulatorsConfigTest, InfiniteLoops)
3152{
3153 // Invalid: test run_rule with infinite loop (rules run each other).
3154 {
3155 json configFile = validConfigFile;
Shawn McCarney846dde52021-08-14 12:47:44 -05003156 configFile["rules"][4]["actions"][0]["run_rule"] = "set_voltage_rule2";
3157 configFile["rules"][4]["id"] = "set_voltage_rule1";
3158 configFile["rules"][5]["actions"][0]["run_rule"] = "set_voltage_rule1";
3159 configFile["rules"][5]["id"] = "set_voltage_rule2";
Bob King3643cc02020-01-31 11:32:56 +08003160 EXPECT_JSON_INVALID(configFile,
3161 "Infinite loop caused by run_rule actions.", "");
3162 }
3163 // Invalid: test run_rule with infinite loop (rule runs itself).
3164 {
3165 json configFile = validConfigFile;
Shawn McCarney846dde52021-08-14 12:47:44 -05003166 configFile["rules"][4]["actions"][0]["run_rule"] = "set_voltage_rule1";
3167 configFile["rules"][4]["id"] = "set_voltage_rule1";
Bob King3643cc02020-01-31 11:32:56 +08003168 EXPECT_JSON_INVALID(configFile,
3169 "Infinite loop caused by run_rule actions.", "");
3170 }
3171 // Invalid: test run_rule with infinite loop (indirect loop).
3172 {
3173 json configFile = validConfigFile;
Shawn McCarney846dde52021-08-14 12:47:44 -05003174 configFile["rules"][4]["actions"][0]["run_rule"] = "set_voltage_rule2";
3175 configFile["rules"][4]["id"] = "set_voltage_rule1";
3176 configFile["rules"][5]["actions"][0]["run_rule"] = "set_voltage_rule3";
3177 configFile["rules"][5]["id"] = "set_voltage_rule2";
3178 configFile["rules"][6]["actions"][0]["run_rule"] = "set_voltage_rule1";
3179 configFile["rules"][6]["id"] = "set_voltage_rule3";
Bob King3643cc02020-01-31 11:32:56 +08003180 EXPECT_JSON_INVALID(configFile,
3181 "Infinite loop caused by run_rule actions.", "");
3182 }
3183}
Shawn McCarney846dde52021-08-14 12:47:44 -05003184
Bob Kingf88203a2020-02-18 13:26:07 +08003185TEST(ValidateRegulatorsConfigTest, RunRuleValueExists)
3186{
3187 // Invalid: test run_rule actions specify a rule ID that does not exist.
3188 {
3189 json configFile = validConfigFile;
Shawn McCarney846dde52021-08-14 12:47:44 -05003190 configFile["rules"][4]["actions"][0]["run_rule"] = "set_voltage_rule2";
3191 configFile["rules"][4]["id"] = "set_voltage_rule1";
Bob Kingf88203a2020-02-18 13:26:07 +08003192 EXPECT_JSON_INVALID(configFile, "Error: Rule ID does not exist.", "");
3193 }
3194}
Shawn McCarney846dde52021-08-14 12:47:44 -05003195
Bob King13b2ad92020-02-18 13:31:39 +08003196TEST(ValidateRegulatorsConfigTest, SetDeviceValueExists)
3197{
3198 // Invalid: test set_device actions specify a device ID that does not exist.
3199 {
3200 json configFile = validConfigFile;
Shawn McCarney846dde52021-08-14 12:47:44 -05003201 configFile["rules"][4]["actions"][0]["set_device"] = "vdd_regulator2";
3202 configFile["rules"][4]["id"] = "set_voltage_rule1";
Bob King13b2ad92020-02-18 13:31:39 +08003203 EXPECT_JSON_INVALID(configFile, "Error: Device ID does not exist.", "");
3204 }
3205}
Shawn McCarney846dde52021-08-14 12:47:44 -05003206
Bob King21b09be2020-02-18 13:33:09 +08003207TEST(ValidateRegulatorsConfigTest, RuleIDExists)
3208{
3209 // Invalid: test rule_id property in configuration specifies a rule ID that
3210 // does not exist.
3211 {
3212 json configFile = validConfigFile;
3213 configFile["chassis"][0]["devices"][0]["configuration"]["rule_id"] =
3214 "set_voltage_rule2";
3215 EXPECT_JSON_INVALID(configFile, "Error: Rule ID does not exist.", "");
3216 }
3217 // Invalid: test rule_id property in presence_detection specifies a rule ID
3218 // that does not exist.
3219 {
3220 json configFile = validConfigFile;
3221 configFile["chassis"][0]["devices"][0]["presence_detection"]
Shawn McCarney5d4a9c72021-08-19 18:45:59 -05003222 ["rule_id"] = "detect_presence_rule2";
3223 EXPECT_JSON_INVALID(configFile, "Error: Rule ID does not exist.", "");
3224 }
3225 // Invalid: test rule_id property in phase_fault_detection specifies a rule
3226 // ID that does not exist.
3227 {
3228 json configFile = validConfigFile;
3229 configFile["chassis"][0]["devices"][0]["phase_fault_detection"]
3230 ["rule_id"] = "detect_phase_faults_rule2";
Bob King21b09be2020-02-18 13:33:09 +08003231 EXPECT_JSON_INVALID(configFile, "Error: Rule ID does not exist.", "");
3232 }
3233 // Invalid: test rule_id property in sensor_monitoring specifies a rule ID
3234 // that does not exist.
3235 {
3236 json configFile = validConfigFile;
3237 configFile["chassis"][0]["devices"][0]["rails"][0]["sensor_monitoring"]
Shawn McCarney5d4a9c72021-08-19 18:45:59 -05003238 ["rule_id"] = "read_sensors_rule2";
Bob King21b09be2020-02-18 13:33:09 +08003239 EXPECT_JSON_INVALID(configFile, "Error: Rule ID does not exist.", "");
3240 }
3241}
Shawn McCarney846dde52021-08-14 12:47:44 -05003242
Shawn McCarney5d4a9c72021-08-19 18:45:59 -05003243TEST(ValidateRegulatorsConfigTest, DeviceIDExists)
3244{
3245 // Invalid: test device_id property in phase_fault_detection specifies a
3246 // device ID that does not exist.
3247 {
3248 json configFile = validConfigFile;
3249 configFile["chassis"][0]["devices"][0]["phase_fault_detection"]
3250 ["device_id"] = "vdd_regulator2";
3251 configFile["chassis"][0]["devices"][0]["phase_fault_detection"]
3252 ["rule_id"] = "detect_phase_faults_rule";
3253 EXPECT_JSON_INVALID(configFile, "Error: Device ID does not exist.", "");
3254 }
3255}
3256
Bob Kingdc72b622020-02-18 13:36:18 +08003257TEST(ValidateRegulatorsConfigTest, NumberOfElementsInMasks)
3258{
3259 // Invalid: test number of elements in masks not equal to number in values
3260 // in i2c_compare_bytes.
3261 {
3262 json configFile = validConfigFile;
3263 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["register"] =
3264 "0x82";
3265 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["values"] = {
3266 "0x02", "0x73"};
3267 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["masks"] = {
3268 "0x7F"};
3269 EXPECT_JSON_INVALID(configFile,
3270 "Error: Invalid i2c_compare_bytes action.", "");
3271 }
3272 // Invalid: test number of elements in masks not equal to number in values
3273 // in i2c_write_bytes.
3274 {
3275 json configFile = validConfigFile;
3276 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["register"] =
3277 "0x82";
3278 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["values"] = {
3279 "0x02", "0x73"};
3280 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["masks"] = {
3281 "0x7F"};
3282 EXPECT_JSON_INVALID(configFile,
3283 "Error: Invalid i2c_write_bytes action.", "");
3284 }
3285}
Shawn McCarney846dde52021-08-14 12:47:44 -05003286
Bob Kinged009652020-02-20 14:54:13 +08003287TEST(ValidateRegulatorsConfigTest, CommandLineSyntax)
3288{
Bob Kinga57e0812020-03-12 10:47:42 +08003289 std::string validateTool =
3290 " ../phosphor-regulators/tools/validate-regulators-config.py ";
Bob Kinged009652020-02-20 14:54:13 +08003291 std::string schema = " -s ";
Bob Kinga57e0812020-03-12 10:47:42 +08003292 std::string schemaFile =
3293 " ../phosphor-regulators/schema/config_schema.json ";
Bob Kinged009652020-02-20 14:54:13 +08003294 std::string configuration = " -c ";
3295 std::string command;
3296 std::string errorMessage;
3297 std::string outputMessage;
3298 std::string outputMessageHelp =
3299 "usage: validate-regulators-config.py [-h] [-s SCHEMA_FILE]";
3300 int valid = 0;
3301
Shawn McCarney0f6ebad2020-09-04 16:43:00 -05003302 TemporaryFile tmpFile;
3303 std::string fileName = tmpFile.getPath().string();
Bob Kinga57e0812020-03-12 10:47:42 +08003304 writeDataToFile(validConfigFile, fileName);
Bob Kinged009652020-02-20 14:54:13 +08003305 // Valid: -s specified
3306 {
3307 command = validateTool + "-s " + schemaFile + configuration + fileName;
3308 expectCommandLineSyntax(errorMessage, outputMessage, command, valid);
3309 }
3310 // Valid: --schema-file specified
3311 {
3312 command = validateTool + "--schema-file " + schemaFile + configuration +
3313 fileName;
3314 expectCommandLineSyntax(errorMessage, outputMessage, command, valid);
3315 }
3316 // Valid: -c specified
3317 {
3318 command = validateTool + schema + schemaFile + "-c " + fileName;
3319 expectCommandLineSyntax(errorMessage, outputMessage, command, valid);
3320 }
3321 // Valid: --configuration-file specified
3322 {
3323 command = validateTool + schema + schemaFile + "--configuration-file " +
3324 fileName;
3325 expectCommandLineSyntax(errorMessage, outputMessage, command, valid);
3326 }
3327 // Valid: -h specified
3328 {
3329 command = validateTool + "-h ";
3330 expectCommandLineSyntax(errorMessage, outputMessageHelp, command,
3331 valid);
3332 }
3333 // Valid: --help specified
3334 {
3335 command = validateTool + "--help ";
3336 expectCommandLineSyntax(errorMessage, outputMessageHelp, command,
3337 valid);
3338 }
3339 // Invalid: -c/--configuration-file not specified
3340 {
3341 command = validateTool + schema + schemaFile;
3342 expectCommandLineSyntax("Error: Configuration file is required.",
3343 outputMessageHelp, command, 1);
3344 }
3345 // Invalid: -s/--schema-file not specified
3346 {
3347 command = validateTool + configuration + fileName;
3348 expectCommandLineSyntax("Error: Schema file is required.",
3349 outputMessageHelp, command, 1);
3350 }
Bob Kingb7552f02020-10-15 14:34:17 +08003351 // Invalid: -c specified more than once
3352 {
3353 command = validateTool + schema + schemaFile + "-c -c " + fileName;
3354 expectCommandLineSyntax(outputMessageHelp, outputMessage, command, 2);
3355 }
Bob Kinged009652020-02-20 14:54:13 +08003356 // Invalid: -s specified more than once
3357 {
3358 command =
3359 validateTool + "-s -s " + schemaFile + configuration + fileName;
3360 expectCommandLineSyntax(outputMessageHelp, outputMessage, command, 2);
3361 }
Bob Kinged009652020-02-20 14:54:13 +08003362 // Invalid: No file name specified after -c
3363 {
3364 command = validateTool + schema + schemaFile + configuration;
3365 expectCommandLineSyntax(outputMessageHelp, outputMessage, command, 2);
3366 }
3367 // Invalid: No file name specified after -s
3368 {
3369 command = validateTool + schema + configuration + fileName;
3370 expectCommandLineSyntax(outputMessageHelp, outputMessage, command, 2);
3371 }
3372 // Invalid: File specified after -c does not exist
3373 {
3374 command = validateTool + schema + schemaFile + configuration +
3375 "../notExistFile";
Bob Kingb7552f02020-10-15 14:34:17 +08003376 expectCommandLineSyntax("Error: Configuration file does not exist.",
3377 outputMessageHelp, command, 1);
Bob Kinged009652020-02-20 14:54:13 +08003378 }
3379 // Invalid: File specified after -s does not exist
3380 {
3381 command = validateTool + schema + "../notExistFile " + configuration +
3382 fileName;
Bob Kingb7552f02020-10-15 14:34:17 +08003383 expectCommandLineSyntax("Error: Schema file does not exist.",
3384 outputMessageHelp, command, 1);
3385 }
3386 // Invalid: File specified after -c is not right data format
3387 {
3388 TemporaryFile wrongFormatFile;
3389 std::string wrongFormatFileName = wrongFormatFile.getPath().string();
3390 std::ofstream out(wrongFormatFileName);
3391 out << "foo";
3392 out.close();
3393 command = validateTool + schema + schemaFile + configuration +
3394 wrongFormatFileName;
Bob Kinged009652020-02-20 14:54:13 +08003395 expectCommandLineSyntax(
Bob Kingb7552f02020-10-15 14:34:17 +08003396 "Error: Configuration file is not in the JSON format.",
3397 outputMessageHelp, command, 1);
Bob Kinged009652020-02-20 14:54:13 +08003398 }
3399 // Invalid: File specified after -s is not right data format
3400 {
Shawn McCarney0f6ebad2020-09-04 16:43:00 -05003401 TemporaryFile wrongFormatFile;
3402 std::string wrongFormatFileName = wrongFormatFile.getPath().string();
Bob Kinga57e0812020-03-12 10:47:42 +08003403 std::ofstream out(wrongFormatFileName);
Bob Kinged009652020-02-20 14:54:13 +08003404 out << "foo";
3405 out.close();
Bob Kinga57e0812020-03-12 10:47:42 +08003406 command = validateTool + schema + wrongFormatFileName + configuration +
3407 fileName;
Bob Kingb7552f02020-10-15 14:34:17 +08003408 expectCommandLineSyntax("Error: Schema file is not in the JSON format.",
3409 outputMessageHelp, command, 1);
Bob Kinged009652020-02-20 14:54:13 +08003410 }
3411 // Invalid: File specified after -c is not readable
3412 {
Shawn McCarney0f6ebad2020-09-04 16:43:00 -05003413 TemporaryFile notReadableFile;
3414 std::string notReadableFileName = notReadableFile.getPath().string();
Bob Kinga57e0812020-03-12 10:47:42 +08003415 writeDataToFile(validConfigFile, notReadableFileName);
Bob Kinged009652020-02-20 14:54:13 +08003416 command = validateTool + schema + schemaFile + configuration +
Bob Kinga57e0812020-03-12 10:47:42 +08003417 notReadableFileName;
3418 chmod(notReadableFileName.c_str(), 0222);
Bob Kingb7552f02020-10-15 14:34:17 +08003419 expectCommandLineSyntax("Error: Configuration file is not readable.",
3420 outputMessageHelp, command, 1);
Bob Kinged009652020-02-20 14:54:13 +08003421 }
3422 // Invalid: File specified after -s is not readable
3423 {
Shawn McCarney0f6ebad2020-09-04 16:43:00 -05003424 TemporaryFile notReadableFile;
3425 std::string notReadableFileName = notReadableFile.getPath().string();
Bob Kinga57e0812020-03-12 10:47:42 +08003426 writeDataToFile(validConfigFile, notReadableFileName);
3427 command = validateTool + schema + notReadableFileName + configuration +
3428 fileName;
3429 chmod(notReadableFileName.c_str(), 0222);
Bob Kingb7552f02020-10-15 14:34:17 +08003430 expectCommandLineSyntax("Error: Schema file is not readable.",
3431 outputMessageHelp, command, 1);
Bob Kinged009652020-02-20 14:54:13 +08003432 }
3433 // Invalid: Unexpected parameter specified (like -g)
3434 {
3435 command = validateTool + schema + schemaFile + configuration +
3436 fileName + " -g";
3437 expectCommandLineSyntax(outputMessageHelp, outputMessage, command, 2);
3438 }
Bob Kinged009652020-02-20 14:54:13 +08003439}