blob: 92aff99ecc3fe849deae9ae11834216965a8165d [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 ]
Bob King386d33f2019-12-26 17:28:56 +080071 }
72 ],
73
74 "chassis": [
75 {
76 "comments": [ "Chassis number 1 containing CPUs and memory" ],
77 "number": 1,
Shawn McCarneyecbeeea2021-04-29 21:08:18 -050078 "inventory_path": "system/chassis",
Bob King386d33f2019-12-26 17:28:56 +080079 "devices": [
80 {
81 "comments": [ "IR35221 regulator producing the Vdd rail" ],
82 "id": "vdd_regulator",
83 "is_regulator": true,
Bob Kinga76898f2020-10-13 15:08:33 +080084 "fru": "system/chassis/motherboard/regulator1",
Bob King386d33f2019-12-26 17:28:56 +080085 "i2c_interface": {
86 "bus": 1,
87 "address": "0x70"
88 },
89 "rails": [
90 {
91 "comments": [ "Vdd rail" ],
92 "id": "vdd",
93 "configuration": {
94 "volts": 1.03,
95 "rule_id": "set_voltage_rule"
96 },
97 "sensor_monitoring": {
98 "rule_id": "read_sensors_rule"
99 }
100 }
101 ]
102 }
103 ]
104 }
105 ]
106 }
107)"_json;
108
Bob King386d33f2019-12-26 17:28:56 +0800109std::string getValidationToolCommand(const std::string& configFileName)
110{
Bob Kinga57e0812020-03-12 10:47:42 +0800111 std::string command =
112 "../phosphor-regulators/tools/validate-regulators-config.py -s \
113 ../phosphor-regulators/schema/config_schema.json -c ";
Bob King386d33f2019-12-26 17:28:56 +0800114 command += configFileName;
115 return command;
116}
117
Bob Kinga57e0812020-03-12 10:47:42 +0800118int runToolForOutputWithCommand(std::string command,
119 std::string& standardOutput,
120 std::string& standardError)
Bob King386d33f2019-12-26 17:28:56 +0800121{
122 // run the validation tool with the temporary file and return the output
123 // of the validation tool.
Shawn McCarney0f6ebad2020-09-04 16:43:00 -0500124 TemporaryFile tmpFile;
125 command += " 2> " + tmpFile.getPath().string();
Bob King386d33f2019-12-26 17:28:56 +0800126 // get the jsonschema print from validation tool.
127 char buffer[256];
Bob Kinga57e0812020-03-12 10:47:42 +0800128 std::string result;
Bob King386d33f2019-12-26 17:28:56 +0800129 // to get the stdout from the validation tool.
130 FILE* pipe = popen(command.c_str(), "r");
131 if (!pipe)
132 {
133 throw std::runtime_error("popen() failed!");
134 }
135 while (!std::feof(pipe))
136 {
137 if (fgets(buffer, sizeof buffer, pipe) != NULL)
138 {
139 result += buffer;
140 }
141 }
142 int returnValue = pclose(pipe);
143 // Check if pclose() failed
144 if (returnValue == -1)
145 {
146 // unable to close pipe. Print error and exit function.
147 throw std::runtime_error("pclose() failed!");
148 }
149 std::string firstLine = result.substr(0, result.find('\n'));
Bob Kinga57e0812020-03-12 10:47:42 +0800150 standardOutput = firstLine;
Bob King386d33f2019-12-26 17:28:56 +0800151 // Get command exit status from return value
152 int exitStatus = WEXITSTATUS(returnValue);
Bob Kinga57e0812020-03-12 10:47:42 +0800153
154 // Read the standardError from tmpFile.
Shawn McCarney0f6ebad2020-09-04 16:43:00 -0500155 std::ifstream input(tmpFile.getPath());
Bob Kinga57e0812020-03-12 10:47:42 +0800156 std::string line;
157
158 if (std::getline(input, line))
159 {
160 standardError = line;
161 }
162
Bob King386d33f2019-12-26 17:28:56 +0800163 return exitStatus;
164}
165
Bob Kinged009652020-02-20 14:54:13 +0800166int runToolForOutput(const std::string& configFileName, std::string& output,
Bob Kinga57e0812020-03-12 10:47:42 +0800167 std::string& error)
Bob Kinged009652020-02-20 14:54:13 +0800168{
169 std::string command = getValidationToolCommand(configFileName);
Bob Kinga57e0812020-03-12 10:47:42 +0800170 return runToolForOutputWithCommand(command, output, error);
Bob Kinged009652020-02-20 14:54:13 +0800171}
172
Bob King386d33f2019-12-26 17:28:56 +0800173void expectFileValid(const std::string& configFileName)
174{
Bob Kinged009652020-02-20 14:54:13 +0800175 std::string errorMessage;
176 std::string outputMessage;
Bob Kinga57e0812020-03-12 10:47:42 +0800177 EXPECT_EQ(runToolForOutput(configFileName, outputMessage, errorMessage), 0);
Bob King386d33f2019-12-26 17:28:56 +0800178 EXPECT_EQ(errorMessage, "");
179 EXPECT_EQ(outputMessage, "");
180}
181
182void expectFileInvalid(const std::string& configFileName,
183 const std::string& expectedErrorMessage,
184 const std::string& expectedOutputMessage)
185{
Bob Kinged009652020-02-20 14:54:13 +0800186 std::string errorMessage;
187 std::string outputMessage;
Bob Kinga57e0812020-03-12 10:47:42 +0800188 EXPECT_EQ(runToolForOutput(configFileName, outputMessage, errorMessage), 1);
Bob King386d33f2019-12-26 17:28:56 +0800189 EXPECT_EQ(errorMessage, expectedErrorMessage);
190 EXPECT_EQ(outputMessage, expectedOutputMessage);
191}
192
Bob Kinga57e0812020-03-12 10:47:42 +0800193void writeDataToFile(const json configFileJson, std::string fileName)
Bob King386d33f2019-12-26 17:28:56 +0800194{
Bob King386d33f2019-12-26 17:28:56 +0800195 std::string jsonData = configFileJson.dump();
196 std::ofstream out(fileName);
197 out << jsonData;
198 out.close();
Bob Kinged009652020-02-20 14:54:13 +0800199}
200
201void expectJsonValid(const json configFileJson)
202{
Shawn McCarney0f6ebad2020-09-04 16:43:00 -0500203 TemporaryFile tmpFile;
204 std::string fileName = tmpFile.getPath().string();
Bob Kinga57e0812020-03-12 10:47:42 +0800205 writeDataToFile(configFileJson, fileName);
Bob Kinged009652020-02-20 14:54:13 +0800206
Bob King386d33f2019-12-26 17:28:56 +0800207 EXPECT_FILE_VALID(fileName);
Bob King386d33f2019-12-26 17:28:56 +0800208}
209
210void expectJsonInvalid(const json configFileJson,
211 const std::string& expectedErrorMessage,
212 const std::string& expectedOutputMessage)
213{
Shawn McCarney0f6ebad2020-09-04 16:43:00 -0500214 TemporaryFile tmpFile;
215 std::string fileName = tmpFile.getPath().string();
Bob Kinga57e0812020-03-12 10:47:42 +0800216 writeDataToFile(configFileJson, fileName);
Bob King386d33f2019-12-26 17:28:56 +0800217
218 EXPECT_FILE_INVALID(fileName, expectedErrorMessage, expectedOutputMessage);
Bob King386d33f2019-12-26 17:28:56 +0800219}
220
Bob Kinged009652020-02-20 14:54:13 +0800221void expectCommandLineSyntax(const std::string& expectedErrorMessage,
222 const std::string& expectedOutputMessage,
Shawn McCarney525e20c2020-04-14 11:05:39 -0500223 const std::string& command, int status)
Bob Kinged009652020-02-20 14:54:13 +0800224{
225 std::string errorMessage;
226 std::string outputMessage;
Bob Kinga57e0812020-03-12 10:47:42 +0800227 EXPECT_EQ(runToolForOutputWithCommand(command, outputMessage, errorMessage),
228 status);
Bob Kinged009652020-02-20 14:54:13 +0800229 EXPECT_EQ(errorMessage, expectedErrorMessage);
230 EXPECT_EQ(outputMessage, expectedOutputMessage);
231}
232
Bob King3afa7112020-03-19 09:35:31 +0800233TEST(ValidateRegulatorsConfigTest, Action)
234{
235 // Valid: Comments property not specified
236 {
237 json configFile = validConfigFile;
238 EXPECT_JSON_VALID(configFile);
239 }
240 // Valid: Comments property specified
241 {
242 json configFile = validConfigFile;
243 configFile["rules"][0]["actions"][0]["comments"][0] =
244 "Set VOUT_COMMAND";
245 EXPECT_JSON_VALID(configFile);
246 }
247 // Valid: and action type specified
248 {
249 json configFile = validConfigFile;
250 json andAction =
251 R"(
252 {
253 "and": [
254 { "i2c_compare_byte": { "register": "0xA0", "value": "0x00" } },
255 { "i2c_compare_byte": { "register": "0xA1", "value": "0x00" } }
256 ]
257 }
258 )"_json;
259 configFile["rules"][0]["actions"].push_back(andAction);
260 EXPECT_JSON_VALID(configFile);
261 }
262 // Valid: compare_presence action type specified
263 {
264 json configFile = validConfigFile;
265 configFile["rules"][0]["actions"][1]["compare_presence"]["fru"] =
Bob Kinga76898f2020-10-13 15:08:33 +0800266 "system/chassis/motherboard/regulator2";
Bob King3afa7112020-03-19 09:35:31 +0800267 configFile["rules"][0]["actions"][1]["compare_presence"]["value"] =
268 true;
269 EXPECT_JSON_VALID(configFile);
270 }
271 // Valid: compare_vpd action type specified
272 {
273 json configFile = validConfigFile;
274 configFile["rules"][0]["actions"][1]["compare_vpd"]["fru"] =
Bob Kinga76898f2020-10-13 15:08:33 +0800275 "system/chassis/motherboard/regulator2";
Bob King3afa7112020-03-19 09:35:31 +0800276 configFile["rules"][0]["actions"][1]["compare_vpd"]["keyword"] = "CCIN";
277 configFile["rules"][0]["actions"][1]["compare_vpd"]["value"] = "2D35";
278 EXPECT_JSON_VALID(configFile);
279 }
280 // Valid: i2c_compare_bit action type specified
281 {
282 json configFile = validConfigFile;
283 configFile["rules"][0]["actions"][1]["i2c_compare_bit"]["register"] =
284 "0xA0";
285 configFile["rules"][0]["actions"][1]["i2c_compare_bit"]["position"] = 3;
286 configFile["rules"][0]["actions"][1]["i2c_compare_bit"]["value"] = 1;
287 EXPECT_JSON_VALID(configFile);
288 }
289 // Valid: i2c_compare_byte action type specified
290 {
291 json configFile = validConfigFile;
292 configFile["rules"][0]["actions"][1]["i2c_compare_byte"]["register"] =
293 "0x82";
294 configFile["rules"][0]["actions"][1]["i2c_compare_byte"]["value"] =
295 "0x40";
296 configFile["rules"][0]["actions"][1]["i2c_compare_byte"]["mask"] =
297 "0x7F";
298 EXPECT_JSON_VALID(configFile);
299 }
300 // Valid: i2c_compare_bytes action type specified
301 {
302 json configFile = validConfigFile;
303 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["register"] =
304 "0x82";
305 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["values"] = {
306 "0x02", "0x73"};
307 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["masks"] = {
308 "0x7F", "0x7F"};
309 EXPECT_JSON_VALID(configFile);
310 }
311 // Valid: i2c_write_bit action type specified
312 {
313 json configFile = validConfigFile;
314 configFile["rules"][0]["actions"][1]["i2c_write_bit"]["register"] =
315 "0xA0";
316 configFile["rules"][0]["actions"][1]["i2c_write_bit"]["position"] = 3;
317 configFile["rules"][0]["actions"][1]["i2c_write_bit"]["value"] = 1;
318 EXPECT_JSON_VALID(configFile);
319 }
320 // Valid: i2c_write_byte action type specified
321 {
322 json configFile = validConfigFile;
323 configFile["rules"][0]["actions"][1]["i2c_write_byte"]["register"] =
324 "0x82";
325 configFile["rules"][0]["actions"][1]["i2c_write_byte"]["value"] =
326 "0x40";
327 configFile["rules"][0]["actions"][1]["i2c_write_byte"]["mask"] = "0x7F";
328 EXPECT_JSON_VALID(configFile);
329 }
330 // Valid: i2c_write_bytes action type specified
331 {
332 json configFile = validConfigFile;
333 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["register"] =
334 "0x82";
335 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["values"] = {
336 "0x02", "0x73"};
337 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["masks"] = {
338 "0x7F", "0x7F"};
339 EXPECT_JSON_VALID(configFile);
340 }
341 // Valid: if action type specified
342 {
343 json configFile = validConfigFile;
344 configFile["rules"][2]["actions"][0]["if"]["condition"]["run_rule"] =
345 "set_voltage_rule";
346 configFile["rules"][2]["actions"][0]["if"]["then"][0]["run_rule"] =
347 "read_sensors_rule";
348 configFile["rules"][2]["actions"][0]["if"]["else"][0]["run_rule"] =
349 "read_sensors_rule";
350 configFile["rules"][2]["id"] = "rule_if";
351 EXPECT_JSON_VALID(configFile);
352 }
353 // Valid: not action type specified
354 {
355 json configFile = validConfigFile;
356 configFile["rules"][0]["actions"][1]["not"]["i2c_compare_byte"]
357 ["register"] = "0xA0";
358 configFile["rules"][0]["actions"][1]["not"]["i2c_compare_byte"]
359 ["value"] = "0xFF";
360 EXPECT_JSON_VALID(configFile);
361 }
362 // Valid: or action type specified
363 {
364 json configFile = validConfigFile;
365 configFile["rules"][0]["actions"][1]["or"][0]["i2c_compare_byte"]
366 ["register"] = "0xA0";
367 configFile["rules"][0]["actions"][1]["or"][0]["i2c_compare_byte"]
368 ["value"] = "0x00";
369 configFile["rules"][0]["actions"][1]["or"][1]["i2c_compare_byte"]
370 ["register"] = "0xA1";
371 configFile["rules"][0]["actions"][1]["or"][1]["i2c_compare_byte"]
372 ["value"] = "0x00";
373 EXPECT_JSON_VALID(configFile);
374 }
375 // Valid: pmbus_read_sensor and pmbus_write_vout_command action type
376 // specified
377 {
378 EXPECT_JSON_VALID(validConfigFile);
379 }
380 // Valid: run_rule action type specified
381 {
382 json configFile = validConfigFile;
383 configFile["rules"][0]["actions"][1]["run_rule"] = "read_sensors_rule";
384 EXPECT_JSON_VALID(configFile);
385 }
386 // Valid: set_device action type specified
387 {
388 json configFile = validConfigFile;
389 configFile["rules"][0]["actions"][1]["set_device"] = "vdd_regulator";
390 EXPECT_JSON_VALID(configFile);
391 }
392 // Invalid: Wrong data type for comments (should be array of string)
393 {
394 json configFile = validConfigFile;
395 configFile["rules"][0]["actions"][0]["comments"] = true;
396 EXPECT_JSON_INVALID(configFile, "Validation failed.",
397 "True is not of type 'array'");
398 }
399 // Invalid: Wrong data type for action type (such as "i2c_write_byte": true)
400 {
401 json configFile = validConfigFile;
402 configFile["rules"][0]["actions"][1]["i2c_write_byte"] = true;
403 EXPECT_JSON_INVALID(configFile, "Validation failed.",
404 "True is not of type 'object'");
405 }
406 // Invalid: Empty comments array
407 {
408 json configFile = validConfigFile;
409 configFile["rules"][0]["actions"][0]["comments"] = json::array();
410 EXPECT_JSON_INVALID(configFile, "Validation failed.",
411 "[] is too short");
412 }
413 // Invalid: Comments array has wrong element type (should be string)
414 {
415 json configFile = validConfigFile;
416 configFile["rules"][0]["actions"][0]["comments"][0] = true;
417 EXPECT_JSON_INVALID(configFile, "Validation failed.",
418 "True is not of type 'string'");
419 }
420 // Invalid: No action type specified
421 {
422 json configFile = validConfigFile;
423 configFile["rules"][0]["actions"][1]["comments"][0] =
424 "Check if bit 3 is on";
425 EXPECT_JSON_INVALID(configFile, "Validation failed.",
426 "'and' is a required property");
427 }
428 // Invalid: Multiple action types specified (such as both 'compare_presence'
429 // and 'pmbus_write_vout_command')
430 {
431 json configFile = validConfigFile;
432 configFile["rules"][0]["actions"][0]["compare_presence"]["value"] =
433 true;
434 EXPECT_JSON_INVALID(
435 configFile, "Validation failed.",
436 "{'compare_presence': {'value': True}, 'pmbus_write_vout_command': "
437 "{'format': 'linear'}} is valid under each of {'required': "
438 "['pmbus_write_vout_command']}, {'required': "
439 "['compare_presence']}");
440 }
441 // Invalid: Unexpected property specified (like 'foo')
442 {
443 json configFile = validConfigFile;
444 configFile["rules"][0]["actions"][1]["foo"] = "foo";
445 EXPECT_JSON_INVALID(
446 configFile, "Validation failed.",
447 "Additional properties are not allowed ('foo' was unexpected)");
448 }
449}
Bob Kingbeaf6532020-01-21 11:03:49 +0800450TEST(ValidateRegulatorsConfigTest, And)
451{
452 // Valid.
453 {
454 json configFile = validConfigFile;
455 json andAction =
456 R"(
457 {
458 "and": [
459 { "i2c_compare_byte": { "register": "0xA0", "value": "0x00" } },
460 { "i2c_compare_byte": { "register": "0xA1", "value": "0x00" } }
461 ]
462 }
463 )"_json;
464 configFile["rules"][0]["actions"].push_back(andAction);
465 EXPECT_JSON_VALID(configFile);
466 }
467
468 // Invalid: actions property value is an empty array.
469 {
470 json configFile = validConfigFile;
471 json andAction =
472 R"(
473 {
474 "and": []
475 }
476 )"_json;
477 configFile["rules"][0]["actions"].push_back(andAction);
478 EXPECT_JSON_INVALID(configFile, "Validation failed.",
479 "[] is too short");
480 }
481
482 // Invalid: actions property has incorrect value data type.
483 {
484 json configFile = validConfigFile;
485 json andAction =
486 R"(
487 {
488 "and": true
489 }
490 )"_json;
491 configFile["rules"][0]["actions"].push_back(andAction);
492 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800493 "True is not of type 'array'");
Bob Kingbeaf6532020-01-21 11:03:49 +0800494 }
495
496 // Invalid: actions property value contains wrong element type
497 {
498 json configFile = validConfigFile;
499 json andAction =
500 R"(
501 {
502 "and": ["foo"]
503 }
504 )"_json;
505 configFile["rules"][0]["actions"].push_back(andAction);
506 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800507 "'foo' is not of type 'object'");
Bob Kingbeaf6532020-01-21 11:03:49 +0800508 }
509}
Bob King3728f562020-01-21 11:35:31 +0800510TEST(ValidateRegulatorsConfigTest, Chassis)
511{
512 // Valid: test chassis.
513 {
514 json configFile = validConfigFile;
515 EXPECT_JSON_VALID(configFile);
516 }
Shawn McCarneyecbeeea2021-04-29 21:08:18 -0500517 // Valid: test chassis with only required properties.
Bob King3728f562020-01-21 11:35:31 +0800518 {
519 json configFile = validConfigFile;
520 configFile["chassis"][0].erase("comments");
Shawn McCarneyecbeeea2021-04-29 21:08:18 -0500521 configFile["chassis"][0].erase("inventory_path");
Bob King3728f562020-01-21 11:35:31 +0800522 configFile["chassis"][0].erase("devices");
523 EXPECT_JSON_VALID(configFile);
524 }
525 // Invalid: test chassis with no number.
526 {
527 json configFile = validConfigFile;
528 configFile["chassis"][0].erase("number");
529 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800530 "'number' is a required property");
Bob King3728f562020-01-21 11:35:31 +0800531 }
532 // Invalid: test chassis with property comments wrong type.
533 {
534 json configFile = validConfigFile;
535 configFile["chassis"][0]["comments"] = true;
536 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800537 "True is not of type 'array'");
Bob King3728f562020-01-21 11:35:31 +0800538 }
539 // Invalid: test chassis with property number wrong type.
540 {
541 json configFile = validConfigFile;
542 configFile["chassis"][0]["number"] = 1.3;
543 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800544 "1.3 is not of type 'integer'");
Bob King3728f562020-01-21 11:35:31 +0800545 }
Shawn McCarneyecbeeea2021-04-29 21:08:18 -0500546 // Invalid: test chassis with property inventory_path wrong type.
547 {
548 json configFile = validConfigFile;
549 configFile["chassis"][0]["inventory_path"] = 2;
550 EXPECT_JSON_INVALID(configFile, "Validation failed.",
551 "2 is not of type 'string'");
552 }
Bob King3728f562020-01-21 11:35:31 +0800553 // Invalid: test chassis with property devices wrong type.
554 {
555 json configFile = validConfigFile;
556 configFile["chassis"][0]["devices"] = true;
557 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800558 "True is not of type 'array'");
Bob King3728f562020-01-21 11:35:31 +0800559 }
560 // Invalid: test chassis with property comments empty array.
561 {
562 json configFile = validConfigFile;
563 configFile["chassis"][0]["comments"] = json::array();
564 EXPECT_JSON_INVALID(configFile, "Validation failed.",
565 "[] is too short");
566 }
567 // Invalid: test chassis with property devices empty array.
568 {
569 json configFile = validConfigFile;
570 configFile["chassis"][0]["devices"] = json::array();
571 EXPECT_JSON_INVALID(configFile, "Validation failed.",
572 "[] is too short");
573 }
574 // Invalid: test chassis with property number less than 1.
575 {
576 json configFile = validConfigFile;
577 configFile["chassis"][0]["number"] = 0;
578 EXPECT_JSON_INVALID(configFile, "Validation failed.",
579 "0 is less than the minimum of 1");
580 }
Shawn McCarneyecbeeea2021-04-29 21:08:18 -0500581 // Invalid: test chassis with property inventory_path empty string.
582 {
583 json configFile = validConfigFile;
584 configFile["chassis"][0]["inventory_path"] = "";
585 EXPECT_JSON_INVALID(configFile, "Validation failed.",
586 "'' is too short");
587 }
Bob King3728f562020-01-21 11:35:31 +0800588}
Bob Kingbf1cbea2020-01-21 11:08:50 +0800589TEST(ValidateRegulatorsConfigTest, ComparePresence)
590{
591 json comparePresenceFile = validConfigFile;
592 comparePresenceFile["rules"][0]["actions"][1]["compare_presence"]["fru"] =
Bob Kinga76898f2020-10-13 15:08:33 +0800593 "system/chassis/motherboard/regulator2";
Bob Kingbf1cbea2020-01-21 11:08:50 +0800594 comparePresenceFile["rules"][0]["actions"][1]["compare_presence"]["value"] =
595 true;
596 // Valid.
597 {
598 json configFile = comparePresenceFile;
599 EXPECT_JSON_VALID(configFile);
600 }
601
602 // Invalid: no FRU property.
603 {
604 json configFile = comparePresenceFile;
605 configFile["rules"][0]["actions"][1]["compare_presence"].erase("fru");
606 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800607 "'fru' is a required property");
Bob Kingbf1cbea2020-01-21 11:08:50 +0800608 }
609
610 // Invalid: FRU property length is string less than 1.
611 {
612 json configFile = comparePresenceFile;
613 configFile["rules"][0]["actions"][1]["compare_presence"]["fru"] = "";
614 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800615 "'' is too short");
Bob Kingbf1cbea2020-01-21 11:08:50 +0800616 }
617
618 // Invalid: no value property.
619 {
620 json configFile = comparePresenceFile;
621 configFile["rules"][0]["actions"][1]["compare_presence"].erase("value");
622 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800623 "'value' is a required property");
Bob Kingbf1cbea2020-01-21 11:08:50 +0800624 }
625
626 // Invalid: value property type is not boolean.
627 {
628 json configFile = comparePresenceFile;
629 configFile["rules"][0]["actions"][1]["compare_presence"]["value"] = "1";
630 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800631 "'1' is not of type 'boolean'");
Bob Kingbf1cbea2020-01-21 11:08:50 +0800632 }
633
634 // Invalid: FRU property type is not string.
635 {
636 json configFile = comparePresenceFile;
637 configFile["rules"][0]["actions"][1]["compare_presence"]["fru"] = 1;
638 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800639 "1 is not of type 'string'");
Bob Kingbf1cbea2020-01-21 11:08:50 +0800640 }
641}
Bob Kingf8b77a02020-01-21 11:09:47 +0800642TEST(ValidateRegulatorsConfigTest, CompareVpd)
643{
644 json compareVpdFile = validConfigFile;
645 compareVpdFile["rules"][0]["actions"][1]["compare_vpd"]["fru"] =
Bob Kinga76898f2020-10-13 15:08:33 +0800646 "system/chassis/motherboard/regulator2";
Bob Kingf8b77a02020-01-21 11:09:47 +0800647 compareVpdFile["rules"][0]["actions"][1]["compare_vpd"]["keyword"] = "CCIN";
648 compareVpdFile["rules"][0]["actions"][1]["compare_vpd"]["value"] = "2D35";
649
650 // Valid.
651 {
652 json configFile = compareVpdFile;
653 EXPECT_JSON_VALID(configFile);
654 }
Matt Spinleraacc2aa2021-05-25 09:31:35 -0600655 // Valid, using byte_values.
656 {
657 json configFile = compareVpdFile;
658 configFile["rules"][0]["actions"][1]["compare_vpd"].erase("value");
659 configFile["rules"][0]["actions"][1]["compare_vpd"]["byte_values"] = {
660 "0x01", "0x02"};
661 EXPECT_JSON_VALID(configFile);
662 }
Bob Kingf8b77a02020-01-21 11:09:47 +0800663
664 // Invalid: no FRU property.
665 {
666 json configFile = compareVpdFile;
667 configFile["rules"][0]["actions"][1]["compare_vpd"].erase("fru");
668 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800669 "'fru' is a required property");
Bob Kingf8b77a02020-01-21 11:09:47 +0800670 }
671
672 // Invalid: no keyword property.
673 {
674 json configFile = compareVpdFile;
675 configFile["rules"][0]["actions"][1]["compare_vpd"].erase("keyword");
676 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800677 "'keyword' is a required property");
Bob Kingf8b77a02020-01-21 11:09:47 +0800678 }
679
680 // Invalid: no value property.
681 {
682 json configFile = compareVpdFile;
683 configFile["rules"][0]["actions"][1]["compare_vpd"].erase("value");
684 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800685 "'value' is a required property");
Bob Kingf8b77a02020-01-21 11:09:47 +0800686 }
687
688 // Invalid: property FRU wrong type.
689 {
690 json configFile = compareVpdFile;
691 configFile["rules"][0]["actions"][1]["compare_vpd"]["fru"] = 1;
692 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800693 "1 is not of type 'string'");
Bob Kingf8b77a02020-01-21 11:09:47 +0800694 }
695
696 // Invalid: property FRU is string less than 1.
697 {
698 json configFile = compareVpdFile;
699 configFile["rules"][0]["actions"][1]["compare_vpd"]["fru"] = "";
700 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800701 "'' is too short");
Bob Kingf8b77a02020-01-21 11:09:47 +0800702 }
703
704 // Invalid: property keyword is not "CCIN", "Manufacturer", "Model",
Matt Spinleraacc2aa2021-05-25 09:31:35 -0600705 // "PartNumber", "HW"
Bob Kingf8b77a02020-01-21 11:09:47 +0800706 {
707 json configFile = compareVpdFile;
708 configFile["rules"][0]["actions"][1]["compare_vpd"]["keyword"] =
709 "Number";
710 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800711 "'Number' is not one of ['CCIN', "
Matt Spinleraacc2aa2021-05-25 09:31:35 -0600712 "'Manufacturer', 'Model', 'PartNumber', 'HW']");
Bob Kingf8b77a02020-01-21 11:09:47 +0800713 }
714
715 // Invalid: property value wrong type.
716 {
717 json configFile = compareVpdFile;
718 configFile["rules"][0]["actions"][1]["compare_vpd"]["value"] = 1;
719 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800720 "1 is not of type 'string'");
Bob Kingf8b77a02020-01-21 11:09:47 +0800721 }
Matt Spinleraacc2aa2021-05-25 09:31:35 -0600722
723 // Invalid: property byte_values has wrong type
724 {
725 json configFile = compareVpdFile;
726 configFile["rules"][0]["actions"][1]["compare_vpd"].erase("value");
727 configFile["rules"][0]["actions"][1]["compare_vpd"]["byte_values"] =
728 "0x50";
729 EXPECT_JSON_INVALID(configFile, "Validation failed.",
730 "'0x50' is not of type 'array'");
731 }
732
733 // Invalid: property byte_values is empty
734 {
735 json configFile = compareVpdFile;
736 configFile["rules"][0]["actions"][1]["compare_vpd"].erase("value");
737 configFile["rules"][0]["actions"][1]["compare_vpd"]["byte_values"] =
738 json::array();
739 EXPECT_JSON_INVALID(configFile, "Validation failed.",
740 "[] is too short");
741 }
742
743 // Invalid: properties byte_values and value both exist
744 {
745 json configFile = compareVpdFile;
746 configFile["rules"][0]["actions"][1]["compare_vpd"]["byte_values"] = {
747 "0x01", "0x02"};
748 EXPECT_JSON_INVALID(
749 configFile, "Validation failed.",
750 "{'byte_values': ['0x01', '0x02'], 'fru': "
751 "'system/chassis/motherboard/regulator2', 'keyword': 'CCIN', "
752 "'value': '2D35'} is valid under each of {'required': "
753 "['byte_values']}, {'required': ['value']}");
754 }
Bob Kingf8b77a02020-01-21 11:09:47 +0800755}
Bob King20057412020-03-16 16:50:17 +0800756TEST(ValidateRegulatorsConfigTest, ConfigFile)
757{
758 // Valid: Only required properties specified
759 {
760 json configFile;
761 configFile["chassis"][0]["number"] = 1;
762 EXPECT_JSON_VALID(configFile);
763 }
764 // Valid: All properties specified
765 {
766 json configFile = validConfigFile;
767 EXPECT_JSON_VALID(configFile);
768 }
769 // Invalid: Required chassis property not specified
770 {
771 json configFile = validConfigFile;
772 configFile.erase("chassis");
773 EXPECT_JSON_INVALID(configFile, "Validation failed.",
774 "'chassis' is a required property");
775 }
776 // Invalid: Wrong data type for comments
777 {
778 json configFile = validConfigFile;
779 configFile["comments"] = true;
780 EXPECT_JSON_INVALID(configFile, "Validation failed.",
781 "True is not of type 'array'");
782 }
783 // Invalid: Wrong data type for rules
784 {
785 json configFile = validConfigFile;
786 configFile["rules"] = true;
787 EXPECT_JSON_INVALID(configFile, "Validation failed.",
788 "True is not of type 'array'");
789 }
790 // Invalid: Wrong data type for chassis
791 {
792 json configFile = validConfigFile;
793 configFile["chassis"] = true;
794 EXPECT_JSON_INVALID(configFile, "Validation failed.",
795 "True is not of type 'array'");
796 }
797 // Invalid: Empty comments array;
798 {
799 json configFile = validConfigFile;
800 configFile["comments"] = json::array();
801 EXPECT_JSON_INVALID(configFile, "Validation failed.",
802 "[] is too short");
803 }
804 // Invalid: Empty rules array
805 {
806 json configFile = validConfigFile;
807 configFile["rules"] = json::array();
808 EXPECT_JSON_INVALID(configFile, "Validation failed.",
809 "[] is too short");
810 }
811 // Invalid: Empty chassis array
812 {
813 json configFile = validConfigFile;
814 configFile["chassis"] = json::array();
815 EXPECT_JSON_INVALID(configFile, "Validation failed.",
816 "[] is too short");
817 }
818 // Invalid: Comments array has wrong element type (should be string)
819 {
820 json configFile = validConfigFile;
821 configFile["comments"][0] = true;
822 EXPECT_JSON_INVALID(configFile, "Validation failed.",
823 "True is not of type 'string'");
824 }
825 // Invalid: Rules array has wrong element type (should be rule)
826 {
827 json configFile = validConfigFile;
828 configFile["rules"][0] = true;
829 EXPECT_JSON_INVALID(configFile, "Validation failed.",
830 "True is not of type 'object'");
831 }
832 // Invalid: Chassis array has wrong element type (should be chassis)
833 {
834 json configFile = validConfigFile;
835 configFile["chassis"][0] = true;
836 EXPECT_JSON_INVALID(configFile, "Validation failed.",
837 "True is not of type 'object'");
838 }
839 // Invalid: Unexpected property specified
840 {
841 json configFile = validConfigFile;
842 configFile["foo"] = json::array();
843 EXPECT_JSON_INVALID(
844 configFile, "Validation failed.",
845 "Additional properties are not allowed ('foo' was unexpected)");
846 }
847}
Bob King4c67a3a2020-02-07 09:48:11 +0800848TEST(ValidateRegulatorsConfigTest, Configuration)
849{
850 json configurationFile = validConfigFile;
851 configurationFile["chassis"][0]["devices"][0]["configuration"]["comments"]
852 [0] = "Set rail to 1.25V using standard rule";
853 configurationFile["chassis"][0]["devices"][0]["configuration"]["volts"] =
854 1.25;
855 configurationFile["chassis"][0]["devices"][0]["configuration"]["rule_id"] =
856 "set_voltage_rule";
857 // Valid: test configuration with property rule_id and with no actions.
858 {
859 json configFile = configurationFile;
Bob King78793102020-03-13 13:16:09 +0800860 configFile["chassis"][0]["devices"][0]["configuration"]["comments"][1] =
861 "test multiple array elements in comments.";
Bob King4c67a3a2020-02-07 09:48:11 +0800862 EXPECT_JSON_VALID(configFile);
863 }
864 // Valid: test configuration with property actions and with no rule_id.
865 {
866 json configFile = configurationFile;
867 configFile["chassis"][0]["devices"][0]["configuration"].erase(
868 "rule_id");
869 configFile["chassis"][0]["devices"][0]["configuration"]["actions"][0]
870 ["compare_presence"]["fru"] =
Bob Kinga76898f2020-10-13 15:08:33 +0800871 "system/chassis/motherboard/cpu3";
Bob King4c67a3a2020-02-07 09:48:11 +0800872 configFile["chassis"][0]["devices"][0]["configuration"]["actions"][0]
873 ["compare_presence"]["value"] = true;
874 EXPECT_JSON_VALID(configFile);
875 }
876 // Valid: comments not specified (optional property).
877 {
878 json configFile = configurationFile;
879 configFile["chassis"][0]["devices"][0]["configuration"].erase(
880 "comments");
881 EXPECT_JSON_VALID(configFile);
882 }
883 // Valid: volts not specified (optional property).
884 {
885 json configFile = configurationFile;
886 configFile["chassis"][0]["devices"][0]["configuration"].erase("volts");
887 EXPECT_JSON_VALID(configFile);
888 }
889 // Valid: configuration is property of a rail (vs. a device).
890 {
891 json configFile = validConfigFile;
892 configFile["chassis"][0]["devices"][0]["rails"][0]["configuration"]
893 ["comments"][0] = "Set rail to 1.25V using standard rule";
894 configFile["chassis"][0]["devices"][0]["rails"][0]["configuration"]
895 ["volts"] = 1.25;
896 configFile["chassis"][0]["devices"][0]["rails"][0]["configuration"]
897 ["rule_id"] = "set_voltage_rule";
898 EXPECT_JSON_VALID(configFile);
899 }
900 // Invalid: comments property has wrong data type (not an array).
901 {
902 json configFile = configurationFile;
903 configFile["chassis"][0]["devices"][0]["configuration"]["comments"] = 1;
904 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800905 "1 is not of type 'array'");
Bob King4c67a3a2020-02-07 09:48:11 +0800906 }
907 // Invalid: test configuration with both actions and rule_id properties.
908 {
909 json configFile = configurationFile;
910 configFile["chassis"][0]["devices"][0]["configuration"]["actions"][0]
911 ["compare_presence"]["fru"] =
Bob Kinga76898f2020-10-13 15:08:33 +0800912 "system/chassis/motherboard/cpu3";
Bob King4c67a3a2020-02-07 09:48:11 +0800913 configFile["chassis"][0]["devices"][0]["configuration"]["actions"][0]
914 ["compare_presence"]["value"] = true;
915 EXPECT_JSON_INVALID(
916 configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800917 "{'actions': [{'compare_presence': {'fru': "
Bob Kinga76898f2020-10-13 15:08:33 +0800918 "'system/chassis/motherboard/cpu3', 'value': True}}], 'comments': "
Bob King358c4172020-03-16 13:57:08 +0800919 "['Set rail to 1.25V using standard rule'], 'rule_id': "
920 "'set_voltage_rule', 'volts': 1.25} is valid under each of "
921 "{'required': ['actions']}, {'required': ['rule_id']}");
Bob King4c67a3a2020-02-07 09:48:11 +0800922 }
923 // Invalid: test configuration with no rule_id and actions.
924 {
925 json configFile = configurationFile;
926 configFile["chassis"][0]["devices"][0]["configuration"].erase(
927 "rule_id");
928 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800929 "'rule_id' is a required property");
Bob King4c67a3a2020-02-07 09:48:11 +0800930 }
931 // Invalid: test configuration with property volts wrong type.
932 {
933 json configFile = configurationFile;
934 configFile["chassis"][0]["devices"][0]["configuration"]["volts"] = true;
935 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800936 "True is not of type 'number'");
Bob King4c67a3a2020-02-07 09:48:11 +0800937 }
938 // Invalid: test configuration with property rule_id wrong type.
939 {
940 json configFile = configurationFile;
941 configFile["chassis"][0]["devices"][0]["configuration"]["rule_id"] =
942 true;
943 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800944 "True is not of type 'string'");
Bob King4c67a3a2020-02-07 09:48:11 +0800945 }
946 // Invalid: test configuration with property actions wrong type.
947 {
948 json configFile = configurationFile;
949 configFile["chassis"][0]["devices"][0]["configuration"].erase(
950 "rule_id");
951 configFile["chassis"][0]["devices"][0]["configuration"]["actions"] =
952 true;
953 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800954 "True is not of type 'array'");
Bob King4c67a3a2020-02-07 09:48:11 +0800955 }
956 // Invalid: test configuration with property comments empty array.
957 {
958 json configFile = configurationFile;
959 configFile["chassis"][0]["devices"][0]["configuration"]["comments"] =
960 json::array();
961 EXPECT_JSON_INVALID(configFile, "Validation failed.",
962 "[] is too short");
963 }
964 // Invalid: test configuration with property rule_id wrong format.
965 {
966 json configFile = configurationFile;
967 configFile["chassis"][0]["devices"][0]["configuration"]["rule_id"] =
968 "id!";
969 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800970 "'id!' does not match '^[A-Za-z0-9_]+$'");
Bob King4c67a3a2020-02-07 09:48:11 +0800971 }
972 // Invalid: test configuration with property actions empty array.
973 {
974 json configFile = configurationFile;
975 configFile["chassis"][0]["devices"][0]["configuration"].erase(
976 "rule_id");
977 configFile["chassis"][0]["devices"][0]["configuration"]["actions"] =
978 json::array();
979 EXPECT_JSON_INVALID(configFile, "Validation failed.",
980 "[] is too short");
981 }
982}
Bob Kinga2ba2df2020-02-04 14:38:44 +0800983TEST(ValidateRegulatorsConfigTest, Device)
984{
985
986 // Valid: test devices.
987 {
988 json configFile = validConfigFile;
989 EXPECT_JSON_VALID(configFile);
990 }
991 // Valid: test devices with required properties.
992 {
993 json configFile = validConfigFile;
994 configFile["chassis"][0]["devices"][0].erase("comments");
995 configFile["chassis"][0]["devices"][0].erase("presence_detection");
996 configFile["chassis"][0]["devices"][0].erase("configuration");
997 configFile["chassis"][0]["devices"][0].erase("rails");
998 EXPECT_JSON_VALID(configFile);
999 }
1000 // Invalid: test devices with no id.
1001 {
1002 json configFile = validConfigFile;
1003 configFile["chassis"][0]["devices"][0].erase("id");
1004 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001005 "'id' is a required property");
Bob Kinga2ba2df2020-02-04 14:38:44 +08001006 }
1007 // Invalid: test devices with no is_regulator.
1008 {
1009 json configFile = validConfigFile;
1010 configFile["chassis"][0]["devices"][0].erase("is_regulator");
1011 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001012 "'is_regulator' is a required property");
Bob Kinga2ba2df2020-02-04 14:38:44 +08001013 }
1014 // Invalid: test devices with no fru.
1015 {
1016 json configFile = validConfigFile;
1017 configFile["chassis"][0]["devices"][0].erase("fru");
1018 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001019 "'fru' is a required property");
Bob Kinga2ba2df2020-02-04 14:38:44 +08001020 }
1021 // Invalid: test devices with no i2c_interface.
1022 {
1023 json configFile = validConfigFile;
1024 configFile["chassis"][0]["devices"][0].erase("i2c_interface");
1025 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001026 "'i2c_interface' is a required property");
Bob Kinga2ba2df2020-02-04 14:38:44 +08001027 }
1028 // Invalid: test devices with property comments wrong type.
1029 {
1030 json configFile = validConfigFile;
1031 configFile["chassis"][0]["devices"][0]["comments"] = true;
1032 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001033 "True is not of type 'array'");
Bob Kinga2ba2df2020-02-04 14:38:44 +08001034 }
1035 // Invalid: test devices with property id wrong type.
1036 {
1037 json configFile = validConfigFile;
1038 configFile["chassis"][0]["devices"][0]["id"] = true;
1039 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001040 "True is not of type 'string'");
Bob Kinga2ba2df2020-02-04 14:38:44 +08001041 }
1042 // Invalid: test devices with property is_regulator wrong type.
1043 {
1044 json configFile = validConfigFile;
1045 configFile["chassis"][0]["devices"][0]["is_regulator"] = 1;
1046 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001047 "1 is not of type 'boolean'");
Bob Kinga2ba2df2020-02-04 14:38:44 +08001048 }
1049 // Invalid: test devices with property fru wrong type.
1050 {
1051 json configFile = validConfigFile;
1052 configFile["chassis"][0]["devices"][0]["fru"] = true;
1053 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001054 "True is not of type 'string'");
Bob Kinga2ba2df2020-02-04 14:38:44 +08001055 }
1056 // Invalid: test devices with property i2c_interface wrong type.
1057 {
1058 json configFile = validConfigFile;
1059 configFile["chassis"][0]["devices"][0]["i2c_interface"] = true;
1060 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001061 "True is not of type 'object'");
Bob Kinga2ba2df2020-02-04 14:38:44 +08001062 }
1063 // Invalid: test devices with property presence_detection wrong
1064 // type.
1065 {
1066 json configFile = validConfigFile;
1067 configFile["chassis"][0]["devices"][0]["presence_detection"] = true;
1068 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001069 "True is not of type 'object'");
Bob Kinga2ba2df2020-02-04 14:38:44 +08001070 }
1071 // Invalid: test devices with property configuration wrong type.
1072 {
1073 json configFile = validConfigFile;
1074 configFile["chassis"][0]["devices"][0]["configuration"] = true;
1075 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001076 "True is not of type 'object'");
Bob Kinga2ba2df2020-02-04 14:38:44 +08001077 }
1078 // Invalid: test devices with property rails wrong type.
1079 {
1080 json configFile = validConfigFile;
1081 configFile["chassis"][0]["devices"][0]["rails"] = true;
1082 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001083 "True is not of type 'array'");
Bob Kinga2ba2df2020-02-04 14:38:44 +08001084 }
1085 // Invalid: test devices with property comments empty array.
1086 {
1087 json configFile = validConfigFile;
1088 configFile["chassis"][0]["devices"][0]["comments"] = json::array();
1089 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1090 "[] is too short");
1091 }
1092 // Invalid: test devices with property fru length less than 1.
1093 {
1094 json configFile = validConfigFile;
1095 configFile["chassis"][0]["devices"][0]["fru"] = "";
1096 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001097 "'' is too short");
Bob Kinga2ba2df2020-02-04 14:38:44 +08001098 }
1099 // Invalid: test devices with property id wrong format.
1100 {
1101 json configFile = validConfigFile;
1102 configFile["chassis"][0]["devices"][0]["id"] = "id#";
1103 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001104 "'id#' does not match '^[A-Za-z0-9_]+$'");
Bob Kinga2ba2df2020-02-04 14:38:44 +08001105 }
1106 // Invalid: test devices with property rails empty array.
1107 {
1108 json configFile = validConfigFile;
1109 configFile["chassis"][0]["devices"][0]["rails"] = json::array();
1110 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1111 "[] is too short");
1112 }
1113}
Bob King4ab8cbb2020-01-21 11:10:48 +08001114TEST(ValidateRegulatorsConfigTest, I2CCompareBit)
1115{
1116 json i2cCompareBitFile = validConfigFile;
1117 i2cCompareBitFile["rules"][0]["actions"][1]["i2c_compare_bit"]["register"] =
1118 "0xA0";
1119 i2cCompareBitFile["rules"][0]["actions"][1]["i2c_compare_bit"]["position"] =
1120 3;
1121 i2cCompareBitFile["rules"][0]["actions"][1]["i2c_compare_bit"]["value"] = 1;
1122 // Valid: test rule actions i2c_compare_bit.
1123 {
1124 json configFile = i2cCompareBitFile;
1125 EXPECT_JSON_VALID(configFile);
1126 }
1127 // Invalid: test i2c_compare_bit with no register.
1128 {
1129 json configFile = i2cCompareBitFile;
1130 configFile["rules"][0]["actions"][1]["i2c_compare_bit"].erase(
1131 "register");
1132 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001133 "'register' is a required property");
Bob King4ab8cbb2020-01-21 11:10:48 +08001134 }
1135 // Invalid: test i2c_compare_bit with no position.
1136 {
1137 json configFile = i2cCompareBitFile;
1138 configFile["rules"][0]["actions"][1]["i2c_compare_bit"].erase(
1139 "position");
1140 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001141 "'position' is a required property");
Bob King4ab8cbb2020-01-21 11:10:48 +08001142 }
1143 // Invalid: test i2c_compare_bit with no value.
1144 {
1145 json configFile = i2cCompareBitFile;
1146 configFile["rules"][0]["actions"][1]["i2c_compare_bit"].erase("value");
1147 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001148 "'value' is a required property");
Bob King4ab8cbb2020-01-21 11:10:48 +08001149 }
1150 // Invalid: test i2c_compare_bit with register wrong type.
1151 {
1152 json configFile = i2cCompareBitFile;
1153 configFile["rules"][0]["actions"][1]["i2c_compare_bit"]["register"] = 1;
1154 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001155 "1 is not of type 'string'");
Bob King4ab8cbb2020-01-21 11:10:48 +08001156 }
1157 // Invalid: test i2c_compare_bit with register wrong format.
1158 {
1159 json configFile = i2cCompareBitFile;
1160 configFile["rules"][0]["actions"][1]["i2c_compare_bit"]["register"] =
1161 "0xA00";
1162 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001163 "'0xA00' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King4ab8cbb2020-01-21 11:10:48 +08001164 }
1165 // Invalid: test i2c_compare_bit with position wrong type.
1166 {
1167 json configFile = i2cCompareBitFile;
1168 configFile["rules"][0]["actions"][1]["i2c_compare_bit"]["position"] =
1169 3.1;
1170 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001171 "3.1 is not of type 'integer'");
Bob King4ab8cbb2020-01-21 11:10:48 +08001172 }
1173 // Invalid: test i2c_compare_bit with position greater than 7.
1174 {
1175 json configFile = i2cCompareBitFile;
1176 configFile["rules"][0]["actions"][1]["i2c_compare_bit"]["position"] = 8;
1177 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1178 "8 is greater than the maximum of 7");
1179 }
1180 // Invalid: test i2c_compare_bit with position less than 0.
1181 {
1182 json configFile = i2cCompareBitFile;
1183 configFile["rules"][0]["actions"][1]["i2c_compare_bit"]["position"] =
1184 -1;
1185 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1186 "-1 is less than the minimum of 0");
1187 }
1188 // Invalid: test i2c_compare_bit with value wrong type.
1189 {
1190 json configFile = i2cCompareBitFile;
1191 configFile["rules"][0]["actions"][1]["i2c_compare_bit"]["value"] = "1";
1192 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001193 "'1' is not of type 'integer'");
Bob King4ab8cbb2020-01-21 11:10:48 +08001194 }
1195 // Invalid: test i2c_compare_bit with value greater than 1.
1196 {
1197 json configFile = i2cCompareBitFile;
1198 configFile["rules"][0]["actions"][1]["i2c_compare_bit"]["value"] = 2;
1199 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1200 "2 is greater than the maximum of 1");
1201 }
1202 // Invalid: test i2c_compare_bit with value less than 0.
1203 {
1204 json configFile = i2cCompareBitFile;
1205 configFile["rules"][0]["actions"][1]["i2c_compare_bit"]["value"] = -1;
1206 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1207 "-1 is less than the minimum of 0");
1208 }
1209}
Bob King514023d2020-01-21 11:13:05 +08001210TEST(ValidateRegulatorsConfigTest, I2CCompareByte)
1211{
1212 json i2cCompareByteFile = validConfigFile;
1213 i2cCompareByteFile["rules"][0]["actions"][1]["i2c_compare_byte"]
1214 ["register"] = "0x82";
1215 i2cCompareByteFile["rules"][0]["actions"][1]["i2c_compare_byte"]["value"] =
1216 "0x40";
1217 i2cCompareByteFile["rules"][0]["actions"][1]["i2c_compare_byte"]["mask"] =
1218 "0x7F";
1219 // Valid: test i2c_compare_byte with all properties.
1220 {
1221 json configFile = i2cCompareByteFile;
1222 EXPECT_JSON_VALID(configFile);
1223 }
1224 // Valid: test i2c_compare_byte with all required properties.
1225 {
1226 json configFile = i2cCompareByteFile;
1227 configFile["rules"][0]["actions"][1]["i2c_compare_byte"].erase("mask");
1228 EXPECT_JSON_VALID(configFile);
1229 }
1230 // Invalid: test i2c_compare_byte with no register.
1231 {
1232 json configFile = i2cCompareByteFile;
1233 configFile["rules"][0]["actions"][1]["i2c_compare_byte"].erase(
1234 "register");
1235 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001236 "'register' is a required property");
Bob King514023d2020-01-21 11:13:05 +08001237 }
1238 // Invalid: test i2c_compare_byte with no value.
1239 {
1240 json configFile = i2cCompareByteFile;
1241 configFile["rules"][0]["actions"][1]["i2c_compare_byte"].erase("value");
1242 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001243 "'value' is a required property");
Bob King514023d2020-01-21 11:13:05 +08001244 }
1245 // Invalid: test i2c_compare_byte with property register wrong type.
1246 {
1247 json configFile = i2cCompareByteFile;
1248 configFile["rules"][0]["actions"][1]["i2c_compare_byte"]["register"] =
1249 1;
1250 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001251 "1 is not of type 'string'");
Bob King514023d2020-01-21 11:13:05 +08001252 }
1253 // Invalid: test i2c_compare_byte with property value wrong type.
1254 {
1255 json configFile = i2cCompareByteFile;
1256 configFile["rules"][0]["actions"][1]["i2c_compare_byte"]["value"] = 1;
1257 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001258 "1 is not of type 'string'");
Bob King514023d2020-01-21 11:13:05 +08001259 }
1260 // Invalid: test i2c_compare_byte with property mask wrong type.
1261 {
1262 json configFile = i2cCompareByteFile;
1263 configFile["rules"][0]["actions"][1]["i2c_compare_byte"]["mask"] = 1;
1264 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001265 "1 is not of type 'string'");
Bob King514023d2020-01-21 11:13:05 +08001266 }
1267 // Invalid: test i2c_compare_byte with property register more than 2 hex
1268 // digits.
1269 {
1270 json configFile = i2cCompareByteFile;
1271 configFile["rules"][0]["actions"][1]["i2c_compare_byte"]["register"] =
1272 "0x820";
1273 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001274 "'0x820' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King514023d2020-01-21 11:13:05 +08001275 }
1276 // Invalid: test i2c_compare_byte with property value more than 2 hex
1277 // digits.
1278 {
1279 json configFile = i2cCompareByteFile;
1280 configFile["rules"][0]["actions"][1]["i2c_compare_byte"]["value"] =
1281 "0x820";
1282 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001283 "'0x820' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King514023d2020-01-21 11:13:05 +08001284 }
1285 // Invalid: test i2c_compare_byte with property mask more than 2 hex digits.
1286 {
1287 json configFile = i2cCompareByteFile;
1288 configFile["rules"][0]["actions"][1]["i2c_compare_byte"]["mask"] =
1289 "0x820";
1290 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001291 "'0x820' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King514023d2020-01-21 11:13:05 +08001292 }
1293 // Invalid: test i2c_compare_byte with property register less than 2 hex
1294 // digits.
1295 {
1296 json configFile = i2cCompareByteFile;
1297 configFile["rules"][0]["actions"][1]["i2c_compare_byte"]["register"] =
1298 "0x8";
1299 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001300 "'0x8' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King514023d2020-01-21 11:13:05 +08001301 }
1302 // Invalid: test i2c_compare_byte with property value less than 2 hex
1303 // digits.
1304 {
1305 json configFile = i2cCompareByteFile;
1306 configFile["rules"][0]["actions"][1]["i2c_compare_byte"]["value"] =
1307 "0x8";
1308 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001309 "'0x8' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King514023d2020-01-21 11:13:05 +08001310 }
1311 // Invalid: test i2c_compare_byte with property mask less than 2 hex digits.
1312 {
1313 json configFile = i2cCompareByteFile;
1314 configFile["rules"][0]["actions"][1]["i2c_compare_byte"]["mask"] =
1315 "0x8";
1316 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001317 "'0x8' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King514023d2020-01-21 11:13:05 +08001318 }
1319 // Invalid: test i2c_compare_byte with property register no leading prefix.
1320 {
1321 json configFile = i2cCompareByteFile;
1322 configFile["rules"][0]["actions"][1]["i2c_compare_byte"]["register"] =
1323 "82";
1324 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001325 "'82' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King514023d2020-01-21 11:13:05 +08001326 }
1327 // Invalid: test i2c_compare_byte with property value no leading prefix.
1328 {
1329 json configFile = i2cCompareByteFile;
1330 configFile["rules"][0]["actions"][1]["i2c_compare_byte"]["value"] =
1331 "82";
1332 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001333 "'82' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King514023d2020-01-21 11:13:05 +08001334 }
1335 // Invalid: test i2c_compare_byte with property mask no leading prefix.
1336 {
1337 json configFile = i2cCompareByteFile;
1338 configFile["rules"][0]["actions"][1]["i2c_compare_byte"]["mask"] = "82";
1339 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001340 "'82' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King514023d2020-01-21 11:13:05 +08001341 }
1342 // Invalid: test i2c_compare_byte with property register invalid hex digit.
1343 {
1344 json configFile = i2cCompareByteFile;
1345 configFile["rules"][0]["actions"][1]["i2c_compare_byte"]["register"] =
1346 "0xG1";
1347 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001348 "'0xG1' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King514023d2020-01-21 11:13:05 +08001349 }
1350 // Invalid: test i2c_compare_byte with property value invalid hex digit.
1351 {
1352 json configFile = i2cCompareByteFile;
1353 configFile["rules"][0]["actions"][1]["i2c_compare_byte"]["value"] =
1354 "0xG1";
1355 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001356 "'0xG1' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King514023d2020-01-21 11:13:05 +08001357 }
1358 // Invalid: test i2c_compare_byte with property mask invalid hex digit.
1359 {
1360 json configFile = i2cCompareByteFile;
1361 configFile["rules"][0]["actions"][1]["i2c_compare_byte"]["mask"] =
1362 "0xG1";
1363 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001364 "'0xG1' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King514023d2020-01-21 11:13:05 +08001365 }
1366}
Bob Kingfb162bb2020-01-21 11:28:07 +08001367TEST(ValidateRegulatorsConfigTest, I2CCompareBytes)
1368{
1369 json i2cCompareBytesFile = validConfigFile;
1370 i2cCompareBytesFile["rules"][0]["actions"][1]["i2c_compare_bytes"]
1371 ["register"] = "0x82";
1372 i2cCompareBytesFile["rules"][0]["actions"][1]["i2c_compare_bytes"]
1373 ["values"] = {"0x02", "0x73"};
1374 i2cCompareBytesFile["rules"][0]["actions"][1]["i2c_compare_bytes"]
1375 ["masks"] = {"0x7F", "0x7F"};
1376 // Valid: test i2c_compare_bytes.
1377 {
1378 json configFile = i2cCompareBytesFile;
1379 EXPECT_JSON_VALID(configFile);
1380 }
1381 // Valid: test i2c_compare_bytes with all required properties.
1382 {
1383 json configFile = i2cCompareBytesFile;
1384 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"].erase(
1385 "masks");
1386 EXPECT_JSON_VALID(configFile);
1387 }
1388 // Invalid: test i2c_compare_bytes with no register.
1389 {
1390 json configFile = i2cCompareBytesFile;
1391 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"].erase(
1392 "register");
1393 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001394 "'register' is a required property");
Bob Kingfb162bb2020-01-21 11:28:07 +08001395 }
1396 // Invalid: test i2c_compare_bytes with no values.
1397 {
1398 json configFile = i2cCompareBytesFile;
1399 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"].erase(
1400 "values");
1401 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001402 "'values' is a required property");
Bob Kingfb162bb2020-01-21 11:28:07 +08001403 }
1404 // Invalid: test i2c_compare_bytes with property values as empty array.
1405 {
1406 json configFile = i2cCompareBytesFile;
1407 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["values"] =
1408 json::array();
1409 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1410 "[] is too short");
1411 }
1412 // Invalid: test i2c_compare_bytes with property masks as empty array.
1413 {
1414 json configFile = i2cCompareBytesFile;
1415 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["masks"] =
1416 json::array();
1417 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1418 "[] is too short");
1419 }
1420 // Invalid: test i2c_compare_bytes with property register wrong type.
1421 {
1422 json configFile = i2cCompareBytesFile;
1423 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["register"] =
1424 1;
1425 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001426 "1 is not of type 'string'");
Bob Kingfb162bb2020-01-21 11:28:07 +08001427 }
1428 // Invalid: test i2c_compare_bytes with property values wrong type.
1429 {
1430 json configFile = i2cCompareBytesFile;
1431 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["values"] = 1;
1432 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001433 "1 is not of type 'array'");
Bob Kingfb162bb2020-01-21 11:28:07 +08001434 }
1435 // Invalid: test i2c_compare_bytes with property masks wrong type.
1436 {
1437 json configFile = i2cCompareBytesFile;
1438 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["masks"] = 1;
1439 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001440 "1 is not of type 'array'");
Bob Kingfb162bb2020-01-21 11:28:07 +08001441 }
1442 // Invalid: test i2c_compare_bytes with property register more than 2 hex
1443 // digits.
1444 {
1445 json configFile = i2cCompareBytesFile;
1446 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["register"] =
1447 "0x820";
1448 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001449 "'0x820' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob Kingfb162bb2020-01-21 11:28:07 +08001450 }
1451 // Invalid: test i2c_compare_bytes with property values more than 2 hex
1452 // digits.
1453 {
1454 json configFile = i2cCompareBytesFile;
1455 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["values"][0] =
1456 "0x820";
1457 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001458 "'0x820' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob Kingfb162bb2020-01-21 11:28:07 +08001459 }
1460 // Invalid: test i2c_compare_bytes with property masks more than 2 hex
1461 // digits.
1462 {
1463 json configFile = i2cCompareBytesFile;
1464 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["masks"][0] =
1465 "0x820";
1466 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001467 "'0x820' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob Kingfb162bb2020-01-21 11:28:07 +08001468 }
1469 // Invalid: test i2c_compare_bytes with property register less than 2 hex
1470 // digits.
1471 {
1472 json configFile = i2cCompareBytesFile;
1473 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["register"] =
1474 "0x8";
1475 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001476 "'0x8' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob Kingfb162bb2020-01-21 11:28:07 +08001477 }
1478 // Invalid: test i2c_compare_bytes with property values less than 2 hex
1479 // digits.
1480 {
1481 json configFile = i2cCompareBytesFile;
1482 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["values"][0] =
1483 "0x8";
1484 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001485 "'0x8' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob Kingfb162bb2020-01-21 11:28:07 +08001486 }
1487 // Invalid: test i2c_compare_bytes with property masks less than 2 hex
1488 // digits.
1489 {
1490 json configFile = i2cCompareBytesFile;
1491 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["masks"][0] =
1492 "0x8";
1493 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001494 "'0x8' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob Kingfb162bb2020-01-21 11:28:07 +08001495 }
1496 // Invalid: test i2c_compare_bytes with property register no leading prefix.
1497 {
1498 json configFile = i2cCompareBytesFile;
1499 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["register"] =
1500 "82";
1501 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001502 "'82' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob Kingfb162bb2020-01-21 11:28:07 +08001503 }
1504 // Invalid: test i2c_compare_bytes with property values no leading prefix.
1505 {
1506 json configFile = i2cCompareBytesFile;
1507 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["values"][0] =
1508 "82";
1509 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001510 "'82' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob Kingfb162bb2020-01-21 11:28:07 +08001511 }
1512 // Invalid: test i2c_compare_bytes with property masks no leading prefix.
1513 {
1514 json configFile = i2cCompareBytesFile;
1515 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["masks"][0] =
1516 "82";
1517 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001518 "'82' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob Kingfb162bb2020-01-21 11:28:07 +08001519 }
1520 // Invalid: test i2c_compare_bytes with property register invalid hex digit.
1521 {
1522 json configFile = i2cCompareBytesFile;
1523 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["register"] =
1524 "0xG1";
1525 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001526 "'0xG1' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob Kingfb162bb2020-01-21 11:28:07 +08001527 }
1528 // Invalid: test i2c_compare_bytes with property values invalid hex digit.
1529 {
1530 json configFile = i2cCompareBytesFile;
1531 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["values"][0] =
1532 "0xG1";
1533 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001534 "'0xG1' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob Kingfb162bb2020-01-21 11:28:07 +08001535 }
1536 // Invalid: test i2c_compare_bytes with property masks invalid hex digit.
1537 {
1538 json configFile = i2cCompareBytesFile;
1539 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["masks"][0] =
1540 "0xG1";
1541 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001542 "'0xG1' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob Kingfb162bb2020-01-21 11:28:07 +08001543 }
1544}
Bob Kingca93f1f2020-01-31 11:21:16 +08001545TEST(ValidateRegulatorsConfigTest, I2CInterface)
1546{
1547 // Valid: test i2c_interface.
1548 {
1549 json configFile = validConfigFile;
1550 EXPECT_JSON_VALID(configFile);
1551 }
1552 // Invalid: testi2c_interface with no bus.
1553 {
1554 json configFile = validConfigFile;
1555 configFile["chassis"][0]["devices"][0]["i2c_interface"].erase("bus");
1556 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001557 "'bus' is a required property");
Bob Kingca93f1f2020-01-31 11:21:16 +08001558 }
1559 // Invalid: test i2c_interface with no address.
1560 {
1561 json configFile = validConfigFile;
1562 configFile["chassis"][0]["devices"][0]["i2c_interface"].erase(
1563 "address");
1564 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001565 "'address' is a required property");
Bob Kingca93f1f2020-01-31 11:21:16 +08001566 }
1567 // Invalid: test i2c_interface with property bus wrong type.
1568 {
1569 json configFile = validConfigFile;
1570 configFile["chassis"][0]["devices"][0]["i2c_interface"]["bus"] = true;
1571 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001572 "True is not of type 'integer'");
Bob Kingca93f1f2020-01-31 11:21:16 +08001573 }
1574 // Invalid: test i2c_interface with property address wrong
1575 // type.
1576 {
1577 json configFile = validConfigFile;
1578 configFile["chassis"][0]["devices"][0]["i2c_interface"]["address"] =
1579 true;
1580 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001581 "True is not of type 'string'");
Bob Kingca93f1f2020-01-31 11:21:16 +08001582 }
1583 // Invalid: test i2c_interface with property bus less than
1584 // 0.
1585 {
1586 json configFile = validConfigFile;
1587 configFile["chassis"][0]["devices"][0]["i2c_interface"]["bus"] = -1;
1588 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1589 "-1 is less than the minimum of 0");
1590 }
1591 // Invalid: test i2c_interface with property address wrong
1592 // format.
1593 {
1594 json configFile = validConfigFile;
1595 configFile["chassis"][0]["devices"][0]["i2c_interface"]["address"] =
1596 "0x700";
1597 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001598 "'0x700' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob Kingca93f1f2020-01-31 11:21:16 +08001599 }
1600}
Bob King188db7d2020-01-31 13:01:01 +08001601TEST(ValidateRegulatorsConfigTest, I2CWriteBit)
1602{
1603 json i2cWriteBitFile = validConfigFile;
1604 i2cWriteBitFile["rules"][0]["actions"][1]["i2c_write_bit"]["register"] =
1605 "0xA0";
1606 i2cWriteBitFile["rules"][0]["actions"][1]["i2c_write_bit"]["position"] = 3;
1607 i2cWriteBitFile["rules"][0]["actions"][1]["i2c_write_bit"]["value"] = 1;
1608 // Valid: test rule actions i2c_write_bit.
1609 {
1610 json configFile = i2cWriteBitFile;
1611 EXPECT_JSON_VALID(configFile);
1612 }
1613 // Invalid: test i2c_write_bit with no register.
1614 {
1615 json configFile = i2cWriteBitFile;
1616 configFile["rules"][0]["actions"][1]["i2c_write_bit"].erase("register");
1617 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001618 "'register' is a required property");
Bob King188db7d2020-01-31 13:01:01 +08001619 }
1620 // Invalid: test i2c_write_bit with no position.
1621 {
1622 json configFile = i2cWriteBitFile;
1623 configFile["rules"][0]["actions"][1]["i2c_write_bit"].erase("position");
1624 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001625 "'position' is a required property");
Bob King188db7d2020-01-31 13:01:01 +08001626 }
1627 // Invalid: test i2c_write_bit with no value.
1628 {
1629 json configFile = i2cWriteBitFile;
1630 configFile["rules"][0]["actions"][1]["i2c_write_bit"].erase("value");
1631 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001632 "'value' is a required property");
Bob King188db7d2020-01-31 13:01:01 +08001633 }
1634 // Invalid: test i2c_write_bit with register wrong type.
1635 {
1636 json configFile = i2cWriteBitFile;
1637 configFile["rules"][0]["actions"][1]["i2c_write_bit"]["register"] = 1;
1638 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001639 "1 is not of type 'string'");
Bob King188db7d2020-01-31 13:01:01 +08001640 }
1641 // Invalid: test i2c_write_bit with register wrong format.
1642 {
1643 json configFile = i2cWriteBitFile;
1644 configFile["rules"][0]["actions"][1]["i2c_write_bit"]["register"] =
1645 "0xA00";
1646 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001647 "'0xA00' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08001648 }
1649 // Invalid: test i2c_write_bit with position wrong type.
1650 {
1651 json configFile = i2cWriteBitFile;
1652 configFile["rules"][0]["actions"][1]["i2c_write_bit"]["position"] = 3.1;
1653 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001654 "3.1 is not of type 'integer'");
Bob King188db7d2020-01-31 13:01:01 +08001655 }
1656 // Invalid: test i2c_write_bit with position greater than 7.
1657 {
1658 json configFile = i2cWriteBitFile;
1659 configFile["rules"][0]["actions"][1]["i2c_write_bit"]["position"] = 8;
1660 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1661 "8 is greater than the maximum of 7");
1662 }
1663 // Invalid: test i2c_write_bit with position less than 0.
1664 {
1665 json configFile = i2cWriteBitFile;
1666 configFile["rules"][0]["actions"][1]["i2c_write_bit"]["position"] = -1;
1667 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1668 "-1 is less than the minimum of 0");
1669 }
1670 // Invalid: test i2c_write_bit with value wrong type.
1671 {
1672 json configFile = i2cWriteBitFile;
1673 configFile["rules"][0]["actions"][1]["i2c_write_bit"]["value"] = "1";
1674 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001675 "'1' is not of type 'integer'");
Bob King188db7d2020-01-31 13:01:01 +08001676 }
1677 // Invalid: test i2c_write_bit with value greater than 1.
1678 {
1679 json configFile = i2cWriteBitFile;
1680 configFile["rules"][0]["actions"][1]["i2c_write_bit"]["value"] = 2;
1681 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1682 "2 is greater than the maximum of 1");
1683 }
1684 // Invalid: test i2c_write_bit with value less than 0.
1685 {
1686 json configFile = i2cWriteBitFile;
1687 configFile["rules"][0]["actions"][1]["i2c_write_bit"]["value"] = -1;
1688 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1689 "-1 is less than the minimum of 0");
1690 }
1691}
1692TEST(ValidateRegulatorsConfigTest, I2CWriteByte)
1693{
1694 json i2cWriteByteFile = validConfigFile;
1695 i2cWriteByteFile["rules"][0]["actions"][1]["i2c_write_byte"]["register"] =
1696 "0x82";
1697 i2cWriteByteFile["rules"][0]["actions"][1]["i2c_write_byte"]["value"] =
1698 "0x40";
1699 i2cWriteByteFile["rules"][0]["actions"][1]["i2c_write_byte"]["mask"] =
1700 "0x7F";
1701 // Valid: test i2c_write_byte with all properties.
1702 {
1703 json configFile = i2cWriteByteFile;
1704 EXPECT_JSON_VALID(configFile);
1705 }
1706 // Valid: test i2c_write_byte with all required properties.
1707 {
1708 json configFile = i2cWriteByteFile;
1709 configFile["rules"][0]["actions"][1]["i2c_write_byte"].erase("mask");
1710 EXPECT_JSON_VALID(configFile);
1711 }
1712 // Invalid: test i2c_write_byte with no register.
1713 {
1714 json configFile = i2cWriteByteFile;
1715 configFile["rules"][0]["actions"][1]["i2c_write_byte"].erase(
1716 "register");
1717 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001718 "'register' is a required property");
Bob King188db7d2020-01-31 13:01:01 +08001719 }
1720 // Invalid: test i2c_write_byte with no value.
1721 {
1722 json configFile = i2cWriteByteFile;
1723 configFile["rules"][0]["actions"][1]["i2c_write_byte"].erase("value");
1724 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001725 "'value' is a required property");
Bob King188db7d2020-01-31 13:01:01 +08001726 }
1727 // Invalid: test i2c_write_byte with property register wrong type.
1728 {
1729 json configFile = i2cWriteByteFile;
1730 configFile["rules"][0]["actions"][1]["i2c_write_byte"]["register"] = 1;
1731 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001732 "1 is not of type 'string'");
Bob King188db7d2020-01-31 13:01:01 +08001733 }
1734 // Invalid: test i2c_write_byte with property value wrong type.
1735 {
1736 json configFile = i2cWriteByteFile;
1737 configFile["rules"][0]["actions"][1]["i2c_write_byte"]["value"] = 1;
1738 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001739 "1 is not of type 'string'");
Bob King188db7d2020-01-31 13:01:01 +08001740 }
1741 // Invalid: test i2c_write_byte with property mask wrong type.
1742 {
1743 json configFile = i2cWriteByteFile;
1744 configFile["rules"][0]["actions"][1]["i2c_write_byte"]["mask"] = 1;
1745 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001746 "1 is not of type 'string'");
Bob King188db7d2020-01-31 13:01:01 +08001747 }
1748 // Invalid: test i2c_write_byte with property register more than 2 hex
1749 // digits.
1750 {
1751 json configFile = i2cWriteByteFile;
1752 configFile["rules"][0]["actions"][1]["i2c_write_byte"]["register"] =
1753 "0x820";
1754 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001755 "'0x820' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08001756 }
1757 // Invalid: test i2c_write_byte with property value more than 2 hex
1758 // digits.
1759 {
1760 json configFile = i2cWriteByteFile;
1761 configFile["rules"][0]["actions"][1]["i2c_write_byte"]["value"] =
1762 "0x820";
1763 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001764 "'0x820' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08001765 }
1766 // Invalid: test i2c_write_byte with property mask more than 2 hex digits.
1767 {
1768 json configFile = i2cWriteByteFile;
1769 configFile["rules"][0]["actions"][1]["i2c_write_byte"]["mask"] =
1770 "0x820";
1771 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001772 "'0x820' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08001773 }
1774 // Invalid: test i2c_write_byte with property register less than 2 hex
1775 // digits.
1776 {
1777 json configFile = i2cWriteByteFile;
1778 configFile["rules"][0]["actions"][1]["i2c_write_byte"]["register"] =
1779 "0x8";
1780 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001781 "'0x8' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08001782 }
1783 // Invalid: test i2c_write_byte with property value less than 2 hex
1784 // digits.
1785 {
1786 json configFile = i2cWriteByteFile;
1787 configFile["rules"][0]["actions"][1]["i2c_write_byte"]["value"] = "0x8";
1788 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001789 "'0x8' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08001790 }
1791 // Invalid: test i2c_write_byte with property mask less than 2 hex digits.
1792 {
1793 json configFile = i2cWriteByteFile;
1794 configFile["rules"][0]["actions"][1]["i2c_write_byte"]["mask"] = "0x8";
1795 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001796 "'0x8' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08001797 }
1798 // Invalid: test i2c_write_byte with property register no leading prefix.
1799 {
1800 json configFile = i2cWriteByteFile;
1801 configFile["rules"][0]["actions"][1]["i2c_write_byte"]["register"] =
1802 "82";
1803 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001804 "'82' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08001805 }
1806 // Invalid: test i2c_write_byte with property value no leading prefix.
1807 {
1808 json configFile = i2cWriteByteFile;
1809 configFile["rules"][0]["actions"][1]["i2c_write_byte"]["value"] = "82";
1810 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001811 "'82' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08001812 }
1813 // Invalid: test i2c_write_byte with property mask no leading prefix.
1814 {
1815 json configFile = i2cWriteByteFile;
1816 configFile["rules"][0]["actions"][1]["i2c_write_byte"]["mask"] = "82";
1817 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001818 "'82' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08001819 }
1820 // Invalid: test i2c_write_byte with property register invalid hex digit.
1821 {
1822 json configFile = i2cWriteByteFile;
1823 configFile["rules"][0]["actions"][1]["i2c_write_byte"]["register"] =
1824 "0xG1";
1825 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001826 "'0xG1' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08001827 }
1828 // Invalid: test i2c_write_byte with property value invalid hex digit.
1829 {
1830 json configFile = i2cWriteByteFile;
1831 configFile["rules"][0]["actions"][1]["i2c_write_byte"]["value"] =
1832 "0xG1";
1833 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001834 "'0xG1' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08001835 }
1836 // Invalid: test i2c_write_byte with property mask invalid hex digit.
1837 {
1838 json configFile = i2cWriteByteFile;
1839 configFile["rules"][0]["actions"][1]["i2c_write_byte"]["mask"] = "0xG1";
1840 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001841 "'0xG1' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08001842 }
1843}
1844TEST(ValidateRegulatorsConfigTest, I2CWriteBytes)
1845{
1846 json i2cWriteBytesFile = validConfigFile;
1847 i2cWriteBytesFile["rules"][0]["actions"][1]["i2c_write_bytes"]["register"] =
1848 "0x82";
1849 i2cWriteBytesFile["rules"][0]["actions"][1]["i2c_write_bytes"]["values"] = {
1850 "0x02", "0x73"};
1851 i2cWriteBytesFile["rules"][0]["actions"][1]["i2c_write_bytes"]["masks"] = {
1852 "0x7F", "0x7F"};
1853 // Valid: test i2c_write_bytes.
1854 {
1855 json configFile = i2cWriteBytesFile;
1856 EXPECT_JSON_VALID(configFile);
1857 }
1858 // Valid: test i2c_write_bytes with all required properties.
1859 {
1860 json configFile = i2cWriteBytesFile;
1861 configFile["rules"][0]["actions"][1]["i2c_write_bytes"].erase("masks");
1862 EXPECT_JSON_VALID(configFile);
1863 }
1864 // Invalid: test i2c_write_bytes with no register.
1865 {
1866 json configFile = i2cWriteBytesFile;
1867 configFile["rules"][0]["actions"][1]["i2c_write_bytes"].erase(
1868 "register");
1869 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001870 "'register' is a required property");
Bob King188db7d2020-01-31 13:01:01 +08001871 }
1872 // Invalid: test i2c_write_bytes with no values.
1873 {
1874 json configFile = i2cWriteBytesFile;
1875 configFile["rules"][0]["actions"][1]["i2c_write_bytes"].erase("values");
1876 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001877 "'values' is a required property");
Bob King188db7d2020-01-31 13:01:01 +08001878 }
1879 // Invalid: test i2c_write_bytes with property values as empty array.
1880 {
1881 json configFile = i2cWriteBytesFile;
1882 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["values"] =
1883 json::array();
1884 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1885 "[] is too short");
1886 }
1887 // Invalid: test i2c_write_bytes with property masks as empty array.
1888 {
1889 json configFile = i2cWriteBytesFile;
1890 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["masks"] =
1891 json::array();
1892 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1893 "[] is too short");
1894 }
1895 // Invalid: test i2c_write_bytes with property register wrong type.
1896 {
1897 json configFile = i2cWriteBytesFile;
1898 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["register"] = 1;
1899 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001900 "1 is not of type 'string'");
Bob King188db7d2020-01-31 13:01:01 +08001901 }
1902 // Invalid: test i2c_write_bytes with property values wrong type.
1903 {
1904 json configFile = i2cWriteBytesFile;
1905 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["values"] = 1;
1906 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001907 "1 is not of type 'array'");
Bob King188db7d2020-01-31 13:01:01 +08001908 }
1909 // Invalid: test i2c_write_bytes with property masks wrong type.
1910 {
1911 json configFile = i2cWriteBytesFile;
1912 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["masks"] = 1;
1913 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001914 "1 is not of type 'array'");
Bob King188db7d2020-01-31 13:01:01 +08001915 }
1916 // Invalid: test i2c_write_bytes with property register more than 2 hex
1917 // digits.
1918 {
1919 json configFile = i2cWriteBytesFile;
1920 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["register"] =
1921 "0x820";
1922 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001923 "'0x820' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08001924 }
1925 // Invalid: test i2c_write_bytes with property values more than 2 hex
1926 // digits.
1927 {
1928 json configFile = i2cWriteBytesFile;
1929 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["values"][0] =
1930 "0x820";
1931 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001932 "'0x820' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08001933 }
1934 // Invalid: test i2c_write_bytes with property masks more than 2 hex
1935 // digits.
1936 {
1937 json configFile = i2cWriteBytesFile;
1938 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["masks"][0] =
1939 "0x820";
1940 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001941 "'0x820' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08001942 }
1943 // Invalid: test i2c_write_bytes with property register less than 2 hex
1944 // digits.
1945 {
1946 json configFile = i2cWriteBytesFile;
1947 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["register"] =
1948 "0x8";
1949 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001950 "'0x8' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08001951 }
1952 // Invalid: test i2c_write_bytes with property values less than 2 hex
1953 // digits.
1954 {
1955 json configFile = i2cWriteBytesFile;
1956 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["values"][0] =
1957 "0x8";
1958 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001959 "'0x8' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08001960 }
1961 // Invalid: test i2c_write_bytes with property masks less than 2 hex
1962 // digits.
1963 {
1964 json configFile = i2cWriteBytesFile;
1965 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["masks"][0] =
1966 "0x8";
1967 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001968 "'0x8' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08001969 }
1970 // Invalid: test i2c_write_bytes with property register no leading prefix.
1971 {
1972 json configFile = i2cWriteBytesFile;
1973 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["register"] =
1974 "82";
1975 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001976 "'82' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08001977 }
1978 // Invalid: test i2c_write_bytes with property values no leading prefix.
1979 {
1980 json configFile = i2cWriteBytesFile;
1981 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["values"][0] =
1982 "82";
1983 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001984 "'82' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08001985 }
1986 // Invalid: test i2c_write_bytes with property masks no leading prefix.
1987 {
1988 json configFile = i2cWriteBytesFile;
1989 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["masks"][0] =
1990 "82";
1991 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001992 "'82' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08001993 }
1994 // Invalid: test i2c_write_bytes with property register invalid hex digit.
1995 {
1996 json configFile = i2cWriteBytesFile;
1997 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["register"] =
1998 "0xG1";
1999 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002000 "'0xG1' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08002001 }
2002 // Invalid: test i2c_write_bytes with property values invalid hex digit.
2003 {
2004 json configFile = i2cWriteBytesFile;
2005 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["values"][0] =
2006 "0xG1";
2007 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002008 "'0xG1' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08002009 }
2010 // Invalid: test i2c_write_bytes with property masks invalid hex digit.
2011 {
2012 json configFile = i2cWriteBytesFile;
2013 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["masks"][0] =
2014 "0xG1";
2015 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002016 "'0xG1' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08002017 }
2018}
Bob Kingead0b052020-01-21 11:29:03 +08002019TEST(ValidateRegulatorsConfigTest, If)
2020{
2021 json ifFile = validConfigFile;
Bob King2d27dcf2020-02-11 15:00:50 +08002022 ifFile["rules"][2]["actions"][0]["if"]["condition"]["run_rule"] =
2023 "set_voltage_rule";
2024 ifFile["rules"][2]["actions"][0]["if"]["then"][0]["run_rule"] =
2025 "read_sensors_rule";
2026 ifFile["rules"][2]["actions"][0]["if"]["else"][0]["run_rule"] =
2027 "read_sensors_rule";
2028 ifFile["rules"][2]["id"] = "rule_if";
Bob Kingead0b052020-01-21 11:29:03 +08002029 // Valid: test if.
2030 {
2031 json configFile = ifFile;
2032 EXPECT_JSON_VALID(configFile);
2033 }
2034 // Valid: test if with required properties.
2035 {
2036 json configFile = ifFile;
Bob King2d27dcf2020-02-11 15:00:50 +08002037 configFile["rules"][2]["actions"][0]["if"].erase("else");
Bob Kingead0b052020-01-21 11:29:03 +08002038 EXPECT_JSON_VALID(configFile);
2039 }
2040 // Invalid: test if with no property condition.
2041 {
2042 json configFile = ifFile;
Bob King2d27dcf2020-02-11 15:00:50 +08002043 configFile["rules"][2]["actions"][0]["if"].erase("condition");
Bob Kingead0b052020-01-21 11:29:03 +08002044 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002045 "'condition' is a required property");
Bob Kingead0b052020-01-21 11:29:03 +08002046 }
2047 // Invalid: test if with no property then.
2048 {
2049 json configFile = ifFile;
Bob King2d27dcf2020-02-11 15:00:50 +08002050 configFile["rules"][2]["actions"][0]["if"].erase("then");
Bob Kingead0b052020-01-21 11:29:03 +08002051 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002052 "'then' is a required property");
Bob Kingead0b052020-01-21 11:29:03 +08002053 }
2054 // Invalid: test if with property then empty array.
2055 {
2056 json configFile = ifFile;
Bob King2d27dcf2020-02-11 15:00:50 +08002057 configFile["rules"][2]["actions"][0]["if"]["then"] = json::array();
Bob Kingead0b052020-01-21 11:29:03 +08002058 EXPECT_JSON_INVALID(configFile, "Validation failed.",
2059 "[] is too short");
2060 }
2061 // Invalid: test if with property else empty array.
2062 {
2063 json configFile = ifFile;
Bob King2d27dcf2020-02-11 15:00:50 +08002064 configFile["rules"][2]["actions"][0]["if"]["else"] = json::array();
Bob Kingead0b052020-01-21 11:29:03 +08002065 EXPECT_JSON_INVALID(configFile, "Validation failed.",
2066 "[] is too short");
2067 }
2068 // Invalid: test if with property condition wrong type.
2069 {
2070 json configFile = ifFile;
Bob King2d27dcf2020-02-11 15:00:50 +08002071 configFile["rules"][2]["actions"][0]["if"]["condition"] = 1;
Bob Kingead0b052020-01-21 11:29:03 +08002072 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002073 "1 is not of type 'object'");
Bob Kingead0b052020-01-21 11:29:03 +08002074 }
2075 // Invalid: test if with property then wrong type.
2076 {
2077 json configFile = ifFile;
Bob King2d27dcf2020-02-11 15:00:50 +08002078 configFile["rules"][2]["actions"][0]["if"]["then"] = 1;
Bob Kingead0b052020-01-21 11:29:03 +08002079 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002080 "1 is not of type 'array'");
Bob Kingead0b052020-01-21 11:29:03 +08002081 }
2082 // Invalid: test if with property else wrong type.
2083 {
2084 json configFile = ifFile;
Bob King2d27dcf2020-02-11 15:00:50 +08002085 configFile["rules"][2]["actions"][0]["if"]["else"] = 1;
Bob Kingead0b052020-01-21 11:29:03 +08002086 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002087 "1 is not of type 'array'");
Bob Kingead0b052020-01-21 11:29:03 +08002088 }
2089}
Bob Kingbfe9fe72020-01-21 11:29:57 +08002090TEST(ValidateRegulatorsConfigTest, Not)
2091{
2092 json notFile = validConfigFile;
2093 notFile["rules"][0]["actions"][1]["not"]["i2c_compare_byte"]["register"] =
2094 "0xA0";
2095 notFile["rules"][0]["actions"][1]["not"]["i2c_compare_byte"]["value"] =
2096 "0xFF";
2097 // Valid: test not.
2098 {
2099 json configFile = notFile;
2100 EXPECT_JSON_VALID(configFile);
2101 }
2102 // Invalid: test not with wrong type.
2103 {
2104 json configFile = notFile;
2105 configFile["rules"][0]["actions"][1]["not"] = 1;
2106 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002107 "1 is not of type 'object'");
Bob Kingbfe9fe72020-01-21 11:29:57 +08002108 }
2109}
Bob Kingcfc29d02020-01-21 11:30:50 +08002110TEST(ValidateRegulatorsConfigTest, Or)
2111{
2112 json orFile = validConfigFile;
2113 orFile["rules"][0]["actions"][1]["or"][0]["i2c_compare_byte"]["register"] =
2114 "0xA0";
2115 orFile["rules"][0]["actions"][1]["or"][0]["i2c_compare_byte"]["value"] =
2116 "0x00";
2117 orFile["rules"][0]["actions"][1]["or"][1]["i2c_compare_byte"]["register"] =
2118 "0xA1";
2119 orFile["rules"][0]["actions"][1]["or"][1]["i2c_compare_byte"]["value"] =
2120 "0x00";
2121 // Valid: test or.
2122 {
2123 json configFile = orFile;
2124 EXPECT_JSON_VALID(configFile);
2125 }
2126 // Invalid: test or with empty array.
2127 {
2128 json configFile = orFile;
2129 configFile["rules"][0]["actions"][1]["or"] = json::array();
2130 EXPECT_JSON_INVALID(configFile, "Validation failed.",
2131 "[] is too short");
2132 }
2133 // Invalid: test or with wrong type.
2134 {
2135 json configFile = orFile;
2136 configFile["rules"][0]["actions"][1]["or"] = 1;
2137 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002138 "1 is not of type 'array'");
Bob Kingcfc29d02020-01-21 11:30:50 +08002139 }
2140}
Bob Kingd6618092020-01-21 11:31:46 +08002141TEST(ValidateRegulatorsConfigTest, PmbusReadSensor)
2142{
2143 json pmbusReadSensorFile = validConfigFile;
2144 pmbusReadSensorFile["rules"][0]["actions"][1]["pmbus_read_sensor"]["type"] =
2145 "vout";
2146 pmbusReadSensorFile["rules"][0]["actions"][1]["pmbus_read_sensor"]
2147 ["command"] = "0x8B";
2148 pmbusReadSensorFile["rules"][0]["actions"][1]["pmbus_read_sensor"]
2149 ["format"] = "linear_16";
2150 pmbusReadSensorFile["rules"][0]["actions"][1]["pmbus_read_sensor"]
2151 ["exponent"] = -8;
2152 // Valid: test pmbus_read_sensor.
2153 {
2154 json configFile = pmbusReadSensorFile;
2155 EXPECT_JSON_VALID(configFile);
2156 }
2157 // Valid: test pmbus_read_sensor with required properties.
2158 {
2159 json configFile = pmbusReadSensorFile;
2160 configFile["rules"][0]["actions"][1]["pmbus_read_sensor"].erase(
2161 "exponent");
2162 EXPECT_JSON_VALID(configFile);
2163 }
2164 // Invalid: test pmbus_read_sensor with no type.
2165 {
2166 json configFile = pmbusReadSensorFile;
2167 configFile["rules"][0]["actions"][1]["pmbus_read_sensor"].erase("type");
2168 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002169 "'type' is a required property");
Bob Kingd6618092020-01-21 11:31:46 +08002170 }
2171 // Invalid: test pmbus_read_sensor with no command.
2172 {
2173 json configFile = pmbusReadSensorFile;
2174 configFile["rules"][0]["actions"][1]["pmbus_read_sensor"].erase(
2175 "command");
2176 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002177 "'command' is a required property");
Bob Kingd6618092020-01-21 11:31:46 +08002178 }
2179 // Invalid: test pmbus_read_sensor with no format.
2180 {
2181 json configFile = pmbusReadSensorFile;
2182 configFile["rules"][0]["actions"][1]["pmbus_read_sensor"].erase(
2183 "format");
2184 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002185 "'format' is a required property");
Bob Kingd6618092020-01-21 11:31:46 +08002186 }
2187 // Invalid: test pmbus_read_sensor with property type wrong type.
2188 {
2189 json configFile = pmbusReadSensorFile;
2190 configFile["rules"][0]["actions"][1]["pmbus_read_sensor"]["type"] =
2191 true;
Bob King358c4172020-03-16 13:57:08 +08002192 EXPECT_JSON_INVALID(configFile, "Validation failed.",
2193 "True is not of type 'string'");
Bob Kingd6618092020-01-21 11:31:46 +08002194 }
2195 // Invalid: test pmbus_read_sensor with property command wrong type.
2196 {
2197 json configFile = pmbusReadSensorFile;
2198 configFile["rules"][0]["actions"][1]["pmbus_read_sensor"]["command"] =
2199 true;
2200 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002201 "True is not of type 'string'");
Bob Kingd6618092020-01-21 11:31:46 +08002202 }
2203 // Invalid: test pmbus_read_sensor with property format wrong type.
2204 {
2205 json configFile = pmbusReadSensorFile;
2206 configFile["rules"][0]["actions"][1]["pmbus_read_sensor"]["format"] =
2207 true;
2208 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002209 "True is not of type 'string'");
Bob Kingd6618092020-01-21 11:31:46 +08002210 }
2211 // Invalid: test pmbus_read_sensor with property exponent wrong type.
2212 {
2213 json configFile = pmbusReadSensorFile;
2214 configFile["rules"][0]["actions"][1]["pmbus_read_sensor"]["exponent"] =
2215 true;
2216 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002217 "True is not of type 'integer'");
Bob Kingd6618092020-01-21 11:31:46 +08002218 }
2219 // Invalid: test pmbus_read_sensor with property type wrong format.
2220 {
2221 json configFile = pmbusReadSensorFile;
2222 configFile["rules"][0]["actions"][1]["pmbus_read_sensor"]["type"] =
2223 "foo";
2224 EXPECT_JSON_INVALID(
2225 configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002226 "'foo' is not one of ['iout', 'iout_peak', 'iout_valley', "
2227 "'pout', 'temperature', 'temperature_peak', 'vout', "
2228 "'vout_peak', 'vout_valley']");
Bob Kingd6618092020-01-21 11:31:46 +08002229 }
2230 // Invalid: test pmbus_read_sensor with property command wrong format.
2231 {
2232 json configFile = pmbusReadSensorFile;
2233 configFile["rules"][0]["actions"][1]["pmbus_read_sensor"]["command"] =
2234 "0x8B0";
2235 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002236 "'0x8B0' does not match '^0x[0-9a-fA-F]{2}$'");
Bob Kingd6618092020-01-21 11:31:46 +08002237 }
2238 // Invalid: test pmbus_read_sensor with property format wrong format.
2239 {
2240 json configFile = pmbusReadSensorFile;
2241 configFile["rules"][0]["actions"][1]["pmbus_read_sensor"]["format"] =
2242 "foo";
Bob King358c4172020-03-16 13:57:08 +08002243 EXPECT_JSON_INVALID(configFile, "Validation failed.",
2244 "'foo' is not one of ['linear_11', 'linear_16']");
Bob Kingd6618092020-01-21 11:31:46 +08002245 }
2246}
Bob King02179c62020-01-21 11:32:36 +08002247TEST(ValidateRegulatorsConfigTest, PmbusWriteVoutCommand)
2248{
2249 json pmbusWriteVoutCommandFile = validConfigFile;
2250 pmbusWriteVoutCommandFile["rules"][0]["actions"][1]
2251 ["pmbus_write_vout_command"]["volts"] = 1.03;
2252 pmbusWriteVoutCommandFile["rules"][0]["actions"][1]
2253 ["pmbus_write_vout_command"]["format"] = "linear";
2254 pmbusWriteVoutCommandFile["rules"][0]["actions"][1]
2255 ["pmbus_write_vout_command"]["exponent"] = -8;
2256 pmbusWriteVoutCommandFile["rules"][0]["actions"][1]
2257 ["pmbus_write_vout_command"]["is_verified"] = true;
2258 // Valid: test pmbus_write_vout_command.
2259 {
2260 json configFile = pmbusWriteVoutCommandFile;
2261 EXPECT_JSON_VALID(configFile);
2262 }
2263 // Valid: test pmbus_write_vout_command with required properties.
2264 {
2265 json configFile = pmbusWriteVoutCommandFile;
2266 configFile["rules"][0]["actions"][1]["pmbus_write_vout_command"].erase(
2267 "volts");
2268 configFile["rules"][0]["actions"][1]["pmbus_write_vout_command"].erase(
2269 "exponent");
2270 configFile["rules"][0]["actions"][1]["pmbus_write_vout_command"].erase(
2271 "is_verified");
2272 EXPECT_JSON_VALID(configFile);
2273 }
2274 // Invalid: test pmbus_write_vout_command with no format.
2275 {
2276 json configFile = pmbusWriteVoutCommandFile;
2277 configFile["rules"][0]["actions"][1]["pmbus_write_vout_command"].erase(
2278 "format");
2279 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002280 "'format' is a required property");
Bob King02179c62020-01-21 11:32:36 +08002281 }
2282 // Invalid: test pmbus_write_vout_command with property volts wrong type.
2283 {
2284 json configFile = pmbusWriteVoutCommandFile;
2285 configFile["rules"][0]["actions"][1]["pmbus_write_vout_command"]
2286 ["volts"] = true;
2287 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002288 "True is not of type 'number'");
Bob King02179c62020-01-21 11:32:36 +08002289 }
2290 // Invalid: test pmbus_write_vout_command with property format wrong type.
2291 {
2292 json configFile = pmbusWriteVoutCommandFile;
2293 configFile["rules"][0]["actions"][1]["pmbus_write_vout_command"]
2294 ["format"] = true;
2295 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002296 "True is not of type 'string'");
Bob King02179c62020-01-21 11:32:36 +08002297 }
2298 // Invalid: test pmbus_write_vout_command with property exponent wrong type.
2299 {
2300 json configFile = pmbusWriteVoutCommandFile;
2301 configFile["rules"][0]["actions"][1]["pmbus_write_vout_command"]
2302 ["exponent"] = 1.3;
2303 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002304 "1.3 is not of type 'integer'");
Bob King02179c62020-01-21 11:32:36 +08002305 }
2306 // Invalid: test pmbus_write_vout_command with property is_verified wrong
2307 // type.
2308 {
2309 json configFile = pmbusWriteVoutCommandFile;
2310 configFile["rules"][0]["actions"][1]["pmbus_write_vout_command"]
2311 ["is_verified"] = 1;
2312 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002313 "1 is not of type 'boolean'");
Bob King02179c62020-01-21 11:32:36 +08002314 }
2315 // Invalid: test pmbus_write_vout_command with property format wrong format.
2316 {
2317 json configFile = pmbusWriteVoutCommandFile;
2318 configFile["rules"][0]["actions"][1]["pmbus_write_vout_command"]
2319 ["format"] = "foo";
2320 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002321 "'foo' is not one of ['linear']");
Bob King02179c62020-01-21 11:32:36 +08002322 }
2323}
Bob King99d8fa12020-01-31 11:23:40 +08002324TEST(ValidateRegulatorsConfigTest, PresenceDetection)
2325{
2326 json presenceDetectionFile = validConfigFile;
2327 presenceDetectionFile
2328 ["chassis"][0]["devices"][0]["presence_detection"]["comments"][0] =
2329 "Regulator is only present on the FooBar backplane";
2330 presenceDetectionFile["chassis"][0]["devices"][0]["presence_detection"]
Bob Kingf4ff1162020-02-11 15:13:38 +08002331 ["rule_id"] = "set_voltage_rule";
Bob King99d8fa12020-01-31 11:23:40 +08002332 // Valid: test presence_detection with only property rule_id.
2333 {
2334 json configFile = presenceDetectionFile;
2335 EXPECT_JSON_VALID(configFile);
2336 }
2337 // Valid: test presence_detection with only property actions.
2338 {
2339 json configFile = presenceDetectionFile;
2340 configFile["chassis"][0]["devices"][0]["presence_detection"].erase(
2341 "rule_id");
2342 configFile["chassis"][0]["devices"][0]["presence_detection"]["actions"]
2343 [0]["compare_presence"]["fru"] =
Bob Kinga76898f2020-10-13 15:08:33 +08002344 "system/chassis/motherboard/cpu3";
Bob King99d8fa12020-01-31 11:23:40 +08002345 configFile["chassis"][0]["devices"][0]["presence_detection"]["actions"]
2346 [0]["compare_presence"]["value"] = true;
2347 configFile["chassis"][0]["devices"][0]["presence_detection"].erase(
2348 "comments");
2349 EXPECT_JSON_VALID(configFile);
2350 }
2351 // Invalid: test presence_detection with both property rule_id and actions.
2352 {
2353 json configFile = presenceDetectionFile;
2354 configFile["chassis"][0]["devices"][0]["presence_detection"]["actions"]
2355 [0]["compare_presence"]["fru"] =
Bob Kinga76898f2020-10-13 15:08:33 +08002356 "system/chassis/motherboard/cpu3";
Bob King99d8fa12020-01-31 11:23:40 +08002357 configFile["chassis"][0]["devices"][0]["presence_detection"]["actions"]
2358 [0]["compare_presence"]["value"] = true;
2359 EXPECT_JSON_INVALID(
2360 configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002361 "{'actions': [{'compare_presence': {'fru': "
Bob Kinga76898f2020-10-13 15:08:33 +08002362 "'system/chassis/motherboard/cpu3', 'value': True}}], 'comments': "
Bob King358c4172020-03-16 13:57:08 +08002363 "['Regulator is only present on the FooBar backplane'], 'rule_id': "
2364 "'set_voltage_rule'} is valid under each of {'required': "
2365 "['actions']}, {'required': ['rule_id']}");
Bob King99d8fa12020-01-31 11:23:40 +08002366 }
2367 // Invalid: test presence_detection with no rule_id and actions.
2368 {
2369 json configFile = presenceDetectionFile;
2370 configFile["chassis"][0]["devices"][0]["presence_detection"].erase(
2371 "rule_id");
2372 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002373 "'rule_id' is a required property");
Bob King99d8fa12020-01-31 11:23:40 +08002374 }
2375 // Invalid: test presence_detection with property comments wrong type.
2376 {
2377 json configFile = presenceDetectionFile;
2378 configFile["chassis"][0]["devices"][0]["presence_detection"]
2379 ["comments"] = true;
2380 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002381 "True is not of type 'array'");
Bob King99d8fa12020-01-31 11:23:40 +08002382 }
2383 // Invalid: test presence_detection with property rule_id wrong type.
2384 {
2385 json configFile = presenceDetectionFile;
2386 configFile["chassis"][0]["devices"][0]["presence_detection"]
2387 ["rule_id"] = true;
2388 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002389 "True is not of type 'string'");
Bob King99d8fa12020-01-31 11:23:40 +08002390 }
2391 // Invalid: test presence_detection with property actions wrong type.
2392 {
2393 json configFile = presenceDetectionFile;
2394 configFile["chassis"][0]["devices"][0]["presence_detection"].erase(
2395 "rule_id");
2396 configFile["chassis"][0]["devices"][0]["presence_detection"]
2397 ["actions"] = true;
2398 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002399 "True is not of type 'array'");
Bob King99d8fa12020-01-31 11:23:40 +08002400 }
2401 // Invalid: test presence_detection with property rule_id wrong format.
2402 {
2403 json configFile = presenceDetectionFile;
2404 configFile["chassis"][0]["devices"][0]["presence_detection"]
2405 ["rule_id"] = "id@";
2406 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002407 "'id@' does not match '^[A-Za-z0-9_]+$'");
Bob King99d8fa12020-01-31 11:23:40 +08002408 }
2409 // Invalid: test presence_detection with property comments empty array.
2410 {
2411 json configFile = presenceDetectionFile;
2412 configFile["chassis"][0]["devices"][0]["presence_detection"]
2413 ["comments"] = json::array();
2414 EXPECT_JSON_INVALID(configFile, "Validation failed.",
2415 "[] is too short");
2416 }
2417 // Invalid: test presence_detection with property actions empty array.
2418 {
2419 json configFile = presenceDetectionFile;
2420 configFile["chassis"][0]["devices"][0]["presence_detection"].erase(
2421 "rule_id");
2422 configFile["chassis"][0]["devices"][0]["presence_detection"]
2423 ["actions"] = json::array();
2424 EXPECT_JSON_INVALID(configFile, "Validation failed.",
2425 "[] is too short");
2426 }
2427}
Bob Kinge9260b52020-01-21 11:46:13 +08002428TEST(ValidateRegulatorsConfigTest, Rail)
2429{
2430 // Valid: test rail.
2431 {
2432 json configFile = validConfigFile;
2433 EXPECT_JSON_VALID(configFile);
2434 }
2435 // Valid: test rail with required properties.
2436 {
2437 json configFile = validConfigFile;
2438 configFile["chassis"][0]["devices"][0]["rails"][0].erase("comments");
2439 configFile["chassis"][0]["devices"][0]["rails"][0].erase(
2440 "configuration");
2441 configFile["chassis"][0]["devices"][0]["rails"][0].erase(
2442 "sensor_monitoring");
2443 EXPECT_JSON_VALID(configFile);
2444 }
2445 // Invalid: test rail with no id.
2446 {
2447 json configFile = validConfigFile;
2448 configFile["chassis"][0]["devices"][0]["rails"][0].erase("id");
2449 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002450 "'id' is a required property");
Bob Kinge9260b52020-01-21 11:46:13 +08002451 }
2452 // Invalid: test rail with comments wrong type.
2453 {
2454 json configFile = validConfigFile;
2455 configFile["chassis"][0]["devices"][0]["rails"][0]["comments"] = true;
2456 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002457 "True is not of type 'array'");
Bob Kinge9260b52020-01-21 11:46:13 +08002458 }
2459 // Invalid: test rail with id wrong type.
2460 {
2461 json configFile = validConfigFile;
2462 configFile["chassis"][0]["devices"][0]["rails"][0]["id"] = true;
2463 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002464 "True is not of type 'string'");
Bob Kinge9260b52020-01-21 11:46:13 +08002465 }
2466 // Invalid: test rail with configuration wrong type.
2467 {
2468 json configFile = validConfigFile;
2469 configFile["chassis"][0]["devices"][0]["rails"][0]["configuration"] =
2470 true;
2471 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002472 "True is not of type 'object'");
Bob Kinge9260b52020-01-21 11:46:13 +08002473 }
2474 // Invalid: test rail with sensor_monitoring wrong type.
2475 {
2476 json configFile = validConfigFile;
2477 configFile["chassis"][0]["devices"][0]["rails"][0]
2478 ["sensor_monitoring"] = true;
2479 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002480 "True is not of type 'object'");
Bob Kinge9260b52020-01-21 11:46:13 +08002481 }
2482 // Invalid: test rail with comments empty array.
2483 {
2484 json configFile = validConfigFile;
2485 configFile["chassis"][0]["devices"][0]["rails"][0]["comments"] =
2486 json::array();
2487 EXPECT_JSON_INVALID(configFile, "Validation failed.",
2488 "[] is too short");
2489 }
2490 // Invalid: test rail with id wrong format.
2491 {
2492 json configFile = validConfigFile;
2493 configFile["chassis"][0]["devices"][0]["rails"][0]["id"] = "id~";
2494 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002495 "'id~' does not match '^[A-Za-z0-9_]+$'");
Bob Kinge9260b52020-01-21 11:46:13 +08002496 }
2497}
Bob King64df7da2020-01-31 12:04:12 +08002498TEST(ValidateRegulatorsConfigTest, Rule)
2499{
2500 // valid test comments property, id property,
2501 // action property specified.
2502 {
2503 json configFile = validConfigFile;
2504 EXPECT_JSON_VALID(configFile);
2505 }
2506
2507 // valid test rule with no comments
2508 {
2509 json configFile = validConfigFile;
2510 configFile["rules"][0].erase("comments");
2511 EXPECT_JSON_VALID(configFile);
2512 }
2513
2514 // invalid test comments property has invalid value type
2515 {
2516 json configFile = validConfigFile;
2517 configFile["rules"][0]["comments"] = {1};
2518 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002519 "1 is not of type 'string'");
Bob King64df7da2020-01-31 12:04:12 +08002520 }
2521
2522 // invalid test rule with no ID
2523 {
2524 json configFile = validConfigFile;
2525 configFile["rules"][0].erase("id");
2526 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002527 "'id' is a required property");
Bob King64df7da2020-01-31 12:04:12 +08002528 }
2529
2530 // invalid test id property has invalid value type (not string)
2531 {
2532 json configFile = validConfigFile;
2533 configFile["rules"][0]["id"] = true;
2534 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002535 "True is not of type 'string'");
Bob King64df7da2020-01-31 12:04:12 +08002536 }
2537
2538 // invalid test id property has invalid value
2539 {
2540 json configFile = validConfigFile;
2541 configFile["rules"][0]["id"] = "foo%";
2542 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002543 "'foo%' does not match '^[A-Za-z0-9_]+$'");
Bob King64df7da2020-01-31 12:04:12 +08002544 }
2545
2546 // invalid test rule with no actions property
2547 {
2548 json configFile = validConfigFile;
2549 configFile["rules"][0].erase("actions");
2550 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002551 "'actions' is a required property");
Bob King64df7da2020-01-31 12:04:12 +08002552 }
2553
2554 // valid test rule with multiple actions
2555 {
2556 json configFile = validConfigFile;
Bob King63d795f2020-02-11 15:22:09 +08002557 configFile["rules"][0]["actions"][1]["run_rule"] = "read_sensors_rule";
Bob King64df7da2020-01-31 12:04:12 +08002558 EXPECT_JSON_VALID(configFile);
2559 }
2560
2561 // invalid test actions property has invalid value type (not an array)
2562 {
2563 json configFile = validConfigFile;
2564 configFile["rules"][0]["actions"] = 1;
2565 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002566 "1 is not of type 'array'");
Bob King64df7da2020-01-31 12:04:12 +08002567 }
2568
2569 // invalid test actions property has invalid value of action
2570 {
2571 json configFile = validConfigFile;
2572 configFile["rules"][0]["actions"][0] = "foo";
2573 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002574 "'foo' is not of type 'object'");
Bob King64df7da2020-01-31 12:04:12 +08002575 }
2576
2577 // invalid test actions property has empty array
2578 {
2579 json configFile = validConfigFile;
2580 configFile["rules"][0]["actions"] = json::array();
2581 EXPECT_JSON_INVALID(configFile, "Validation failed.",
2582 "[] is too short");
2583 }
2584}
Bob Kinge86c2e52020-01-21 11:33:32 +08002585TEST(ValidateRegulatorsConfigTest, RunRule)
2586{
2587 json runRuleFile = validConfigFile;
Bob King7d3a9f12020-02-11 15:34:52 +08002588 runRuleFile["rules"][0]["actions"][1]["run_rule"] = "read_sensors_rule";
Bob Kinge86c2e52020-01-21 11:33:32 +08002589 // Valid: test run_rule.
2590 {
2591 json configFile = runRuleFile;
2592 EXPECT_JSON_VALID(configFile);
2593 }
2594 // Invalid: test run_rule wrong type.
2595 {
2596 json configFile = runRuleFile;
2597 configFile["rules"][0]["actions"][1]["run_rule"] = true;
2598 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002599 "True is not of type 'string'");
Bob Kinge86c2e52020-01-21 11:33:32 +08002600 }
2601 // Invalid: test run_rule wrong format.
2602 {
2603 json configFile = runRuleFile;
2604 configFile["rules"][0]["actions"][1]["run_rule"] = "set_voltage_rule%";
2605 EXPECT_JSON_INVALID(
2606 configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002607 "'set_voltage_rule%' does not match '^[A-Za-z0-9_]+$'");
Bob Kinge86c2e52020-01-21 11:33:32 +08002608 }
2609}
Bob Kingfcc2a2f2020-01-31 11:29:45 +08002610TEST(ValidateRegulatorsConfigTest, SensorMonitoring)
2611{
2612 // Valid: test rails sensor_monitoring with only property rule id.
2613 {
2614 json configFile = validConfigFile;
2615 EXPECT_JSON_VALID(configFile);
2616 }
2617 // Valid: test rails sensor_monitoring with only property actions.
2618 {
2619 json configFile = validConfigFile;
2620 configFile["chassis"][0]["devices"][0]["rails"][0]["sensor_monitoring"]
2621 .erase("rule_id");
2622 configFile["chassis"][0]["devices"][0]["rails"][0]["sensor_monitoring"]
2623 ["actions"][0]["compare_presence"]["fru"] =
Bob Kinga76898f2020-10-13 15:08:33 +08002624 "system/chassis/motherboard/cpu3";
Bob Kingfcc2a2f2020-01-31 11:29:45 +08002625 configFile["chassis"][0]["devices"][0]["rails"][0]["sensor_monitoring"]
2626 ["actions"][0]["compare_presence"]["value"] = true;
2627 configFile["chassis"][0]["devices"][0]["rails"][0]["sensor_monitoring"]
2628 ["comments"][0] = "comments";
2629 EXPECT_JSON_VALID(configFile);
2630 }
2631 // Invalid: test rails sensor_monitoring with both property rule_id and
2632 // actions.
2633 {
2634 json configFile = validConfigFile;
2635 configFile["chassis"][0]["devices"][0]["rails"][0]["sensor_monitoring"]
2636 ["actions"][0]["compare_presence"]["fru"] =
Bob Kinga76898f2020-10-13 15:08:33 +08002637 "system/chassis/motherboard/cpu3";
Bob Kingfcc2a2f2020-01-31 11:29:45 +08002638 configFile["chassis"][0]["devices"][0]["rails"][0]["sensor_monitoring"]
2639 ["actions"][0]["compare_presence"]["value"] = true;
2640 EXPECT_JSON_INVALID(
2641 configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002642 "{'actions': [{'compare_presence': {'fru': "
Bob Kinga76898f2020-10-13 15:08:33 +08002643 "'system/chassis/motherboard/cpu3', 'value': True}}], 'rule_id': "
Bob King358c4172020-03-16 13:57:08 +08002644 "'read_sensors_rule'} is valid under each of {'required': "
2645 "['actions']}, {'required': ['rule_id']}");
Bob Kingfcc2a2f2020-01-31 11:29:45 +08002646 }
2647 // Invalid: test rails sensor_monitoring with no rule_id and actions.
2648 {
2649 json configFile = validConfigFile;
2650 configFile["chassis"][0]["devices"][0]["rails"][0]["sensor_monitoring"]
2651 .erase("rule_id");
2652 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002653 "'rule_id' is a required property");
Bob Kingfcc2a2f2020-01-31 11:29:45 +08002654 }
2655 // Invalid: test rails sensor_monitoring with property comments wrong type.
2656 {
2657 json configFile = validConfigFile;
2658 configFile["chassis"][0]["devices"][0]["rails"][0]["sensor_monitoring"]
2659 ["comments"] = true;
2660 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002661 "True is not of type 'array'");
Bob Kingfcc2a2f2020-01-31 11:29:45 +08002662 }
2663 // Invalid: test rails sensor_monitoring with property rule_id wrong type.
2664 {
2665 json configFile = validConfigFile;
2666 configFile["chassis"][0]["devices"][0]["rails"][0]["sensor_monitoring"]
2667 ["rule_id"] = true;
2668 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002669 "True is not of type 'string'");
Bob Kingfcc2a2f2020-01-31 11:29:45 +08002670 }
2671 // Invalid: test rails sensor_monitoring with property actions wrong type.
2672 {
2673 json configFile = validConfigFile;
2674 configFile["chassis"][0]["devices"][0]["rails"][0]["sensor_monitoring"]
2675 .erase("rule_id");
2676 configFile["chassis"][0]["devices"][0]["rails"][0]["sensor_monitoring"]
2677 ["actions"] = true;
2678 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002679 "True is not of type 'array'");
Bob Kingfcc2a2f2020-01-31 11:29:45 +08002680 }
2681 // Invalid: test rails sensor_monitoring with property rule_id wrong format.
2682 {
2683 json configFile = validConfigFile;
2684 configFile["chassis"][0]["devices"][0]["rails"][0]["sensor_monitoring"]
2685 ["rule_id"] = "id@";
2686 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002687 "'id@' does not match '^[A-Za-z0-9_]+$'");
Bob Kingfcc2a2f2020-01-31 11:29:45 +08002688 }
2689 // Invalid: test rails sensor_monitoring with property comments empty array.
2690 {
2691 json configFile = validConfigFile;
2692 configFile["chassis"][0]["devices"][0]["rails"][0]["sensor_monitoring"]
2693 ["comments"] = json::array();
2694 EXPECT_JSON_INVALID(configFile, "Validation failed.",
2695 "[] is too short");
2696 }
2697 // Invalid: test rails sensor_monitoring with property actions empty array.
2698 {
2699 json configFile = validConfigFile;
2700 configFile["chassis"][0]["devices"][0]["rails"][0]["sensor_monitoring"]
2701 .erase("rule_id");
2702 configFile["chassis"][0]["devices"][0]["rails"][0]["sensor_monitoring"]
2703 ["actions"] = json::array();
2704 EXPECT_JSON_INVALID(configFile, "Validation failed.",
2705 "[] is too short");
2706 }
2707}
Bob King68230aa2020-01-21 11:34:33 +08002708TEST(ValidateRegulatorsConfigTest, SetDevice)
2709{
2710 json setDeviceFile = validConfigFile;
Bob King7d3a9f12020-02-11 15:34:52 +08002711 setDeviceFile["rules"][0]["actions"][1]["set_device"] = "vdd_regulator";
Bob King68230aa2020-01-21 11:34:33 +08002712 // Valid: test set_device.
2713 {
2714 json configFile = setDeviceFile;
2715 EXPECT_JSON_VALID(configFile);
2716 }
2717 // Invalid: test set_device wrong type.
2718 {
2719 json configFile = setDeviceFile;
2720 configFile["rules"][0]["actions"][1]["set_device"] = true;
2721 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002722 "True is not of type 'string'");
Bob King68230aa2020-01-21 11:34:33 +08002723 }
2724 // Invalid: test set_device wrong format.
2725 {
2726 json configFile = setDeviceFile;
2727 configFile["rules"][0]["actions"][1]["set_device"] = "io_expander2%";
Bob King358c4172020-03-16 13:57:08 +08002728 EXPECT_JSON_INVALID(configFile, "Validation failed.",
2729 "'io_expander2%' does not match '^[A-Za-z0-9_]+$'");
Bob King68230aa2020-01-21 11:34:33 +08002730 }
2731}
Bob King3643cc02020-01-31 11:32:56 +08002732TEST(ValidateRegulatorsConfigTest, DuplicateRuleID)
2733{
2734 // Invalid: test duplicate ID in rule.
2735 {
2736 json configFile = validConfigFile;
Bob Kingb3e48bc2020-02-18 09:59:09 +08002737 configFile["rules"][2]["id"] = "set_voltage_rule";
2738 configFile["rules"][2]["actions"][0]["pmbus_write_vout_command"]
Bob King3643cc02020-01-31 11:32:56 +08002739 ["format"] = "linear";
2740 EXPECT_JSON_INVALID(configFile, "Error: Duplicate rule ID.", "");
2741 }
2742}
2743TEST(ValidateRegulatorsConfigTest, DuplicateChassisNumber)
2744{
2745 // Invalid: test duplicate number in chassis.
2746 {
2747 json configFile = validConfigFile;
2748 configFile["chassis"][1]["number"] = 1;
2749 EXPECT_JSON_INVALID(configFile, "Error: Duplicate chassis number.", "");
2750 }
2751}
2752TEST(ValidateRegulatorsConfigTest, DuplicateDeviceID)
2753{
2754 // Invalid: test duplicate ID in device.
2755 {
2756 json configFile = validConfigFile;
2757 configFile["chassis"][0]["devices"][1]["id"] = "vdd_regulator";
2758 configFile["chassis"][0]["devices"][1]["is_regulator"] = true;
2759 configFile["chassis"][0]["devices"][1]["fru"] =
Bob Kinga76898f2020-10-13 15:08:33 +08002760 "system/chassis/motherboard/regulator1";
Bob King3643cc02020-01-31 11:32:56 +08002761 configFile["chassis"][0]["devices"][1]["i2c_interface"]["bus"] = 2;
2762 configFile["chassis"][0]["devices"][1]["i2c_interface"]["address"] =
2763 "0x71";
2764 EXPECT_JSON_INVALID(configFile, "Error: Duplicate device ID.", "");
2765 }
2766}
2767TEST(ValidateRegulatorsConfigTest, DuplicateRailID)
2768{
2769 // Invalid: test duplicate ID in rail.
2770 {
2771 json configFile = validConfigFile;
2772 configFile["chassis"][0]["devices"][0]["rails"][1]["id"] = "vdd";
2773 EXPECT_JSON_INVALID(configFile, "Error: Duplicate rail ID.", "");
2774 }
2775}
Bob King78793102020-03-13 13:16:09 +08002776TEST(ValidateRegulatorsConfigTest, DuplicateObjectID)
2777{
2778 // Invalid: test duplicate object ID in device and rail.
2779 {
2780 json configFile = validConfigFile;
2781 configFile["chassis"][0]["devices"][0]["rails"][1]["id"] =
2782 "vdd_regulator";
2783 EXPECT_JSON_INVALID(configFile, "Error: Duplicate ID.", "");
2784 }
2785 // Invalid: test duplicate object ID in device and rule.
2786 {
2787 json configFile = validConfigFile;
2788 configFile["rules"][2]["id"] = "vdd_regulator";
2789 configFile["rules"][2]["actions"][0]["pmbus_write_vout_command"]
2790 ["format"] = "linear";
2791 EXPECT_JSON_INVALID(configFile, "Error: Duplicate ID.", "");
2792 }
2793 // Invalid: test duplicate object ID in rule and rail.
2794 {
2795 json configFile = validConfigFile;
2796 configFile["chassis"][0]["devices"][0]["rails"][1]["id"] =
2797 "set_voltage_rule";
2798 EXPECT_JSON_INVALID(configFile, "Error: Duplicate ID.", "");
2799 }
2800}
Bob King3643cc02020-01-31 11:32:56 +08002801TEST(ValidateRegulatorsConfigTest, InfiniteLoops)
2802{
2803 // Invalid: test run_rule with infinite loop (rules run each other).
2804 {
2805 json configFile = validConfigFile;
2806 configFile["rules"][2]["actions"][0]["run_rule"] = "set_voltage_rule2";
2807 configFile["rules"][2]["id"] = "set_voltage_rule1";
2808 configFile["rules"][3]["actions"][0]["run_rule"] = "set_voltage_rule1";
2809 configFile["rules"][3]["id"] = "set_voltage_rule2";
2810 EXPECT_JSON_INVALID(configFile,
2811 "Infinite loop caused by run_rule actions.", "");
2812 }
2813 // Invalid: test run_rule with infinite loop (rule runs itself).
2814 {
2815 json configFile = validConfigFile;
2816 configFile["rules"][2]["actions"][0]["run_rule"] = "set_voltage_rule1";
2817 configFile["rules"][2]["id"] = "set_voltage_rule1";
2818 EXPECT_JSON_INVALID(configFile,
2819 "Infinite loop caused by run_rule actions.", "");
2820 }
2821 // Invalid: test run_rule with infinite loop (indirect loop).
2822 {
2823 json configFile = validConfigFile;
2824 configFile["rules"][2]["actions"][0]["run_rule"] = "set_voltage_rule2";
2825 configFile["rules"][2]["id"] = "set_voltage_rule1";
2826 configFile["rules"][3]["actions"][0]["run_rule"] = "set_voltage_rule3";
2827 configFile["rules"][3]["id"] = "set_voltage_rule2";
2828 configFile["rules"][4]["actions"][0]["run_rule"] = "set_voltage_rule1";
2829 configFile["rules"][4]["id"] = "set_voltage_rule3";
2830 EXPECT_JSON_INVALID(configFile,
2831 "Infinite loop caused by run_rule actions.", "");
2832 }
2833}
Bob Kingf88203a2020-02-18 13:26:07 +08002834TEST(ValidateRegulatorsConfigTest, RunRuleValueExists)
2835{
2836 // Invalid: test run_rule actions specify a rule ID that does not exist.
2837 {
2838 json configFile = validConfigFile;
2839 configFile["rules"][2]["actions"][0]["run_rule"] = "set_voltage_rule2";
2840 configFile["rules"][2]["id"] = "set_voltage_rule1";
2841 EXPECT_JSON_INVALID(configFile, "Error: Rule ID does not exist.", "");
2842 }
2843}
Bob King13b2ad92020-02-18 13:31:39 +08002844TEST(ValidateRegulatorsConfigTest, SetDeviceValueExists)
2845{
2846 // Invalid: test set_device actions specify a device ID that does not exist.
2847 {
2848 json configFile = validConfigFile;
2849 configFile["rules"][2]["actions"][0]["set_device"] = "vdd_regulator2";
2850 configFile["rules"][2]["id"] = "set_voltage_rule1";
2851 EXPECT_JSON_INVALID(configFile, "Error: Device ID does not exist.", "");
2852 }
2853}
Bob King21b09be2020-02-18 13:33:09 +08002854TEST(ValidateRegulatorsConfigTest, RuleIDExists)
2855{
2856 // Invalid: test rule_id property in configuration specifies a rule ID that
2857 // does not exist.
2858 {
2859 json configFile = validConfigFile;
2860 configFile["chassis"][0]["devices"][0]["configuration"]["rule_id"] =
2861 "set_voltage_rule2";
2862 EXPECT_JSON_INVALID(configFile, "Error: Rule ID does not exist.", "");
2863 }
2864 // Invalid: test rule_id property in presence_detection specifies a rule ID
2865 // that does not exist.
2866 {
2867 json configFile = validConfigFile;
2868 configFile["chassis"][0]["devices"][0]["presence_detection"]
2869 ["rule_id"] = "set_voltage_rule2";
2870 EXPECT_JSON_INVALID(configFile, "Error: Rule ID does not exist.", "");
2871 }
2872 // Invalid: test rule_id property in sensor_monitoring specifies a rule ID
2873 // that does not exist.
2874 {
2875 json configFile = validConfigFile;
2876 configFile["chassis"][0]["devices"][0]["rails"][0]["sensor_monitoring"]
2877 ["rule_id"] = "set_voltage_rule2";
2878 EXPECT_JSON_INVALID(configFile, "Error: Rule ID does not exist.", "");
2879 }
2880}
Bob Kingdc72b622020-02-18 13:36:18 +08002881TEST(ValidateRegulatorsConfigTest, NumberOfElementsInMasks)
2882{
2883 // Invalid: test number of elements in masks not equal to number in values
2884 // in i2c_compare_bytes.
2885 {
2886 json configFile = validConfigFile;
2887 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["register"] =
2888 "0x82";
2889 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["values"] = {
2890 "0x02", "0x73"};
2891 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["masks"] = {
2892 "0x7F"};
2893 EXPECT_JSON_INVALID(configFile,
2894 "Error: Invalid i2c_compare_bytes action.", "");
2895 }
2896 // Invalid: test number of elements in masks not equal to number in values
2897 // in i2c_write_bytes.
2898 {
2899 json configFile = validConfigFile;
2900 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["register"] =
2901 "0x82";
2902 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["values"] = {
2903 "0x02", "0x73"};
2904 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["masks"] = {
2905 "0x7F"};
2906 EXPECT_JSON_INVALID(configFile,
2907 "Error: Invalid i2c_write_bytes action.", "");
2908 }
2909}
Bob Kinged009652020-02-20 14:54:13 +08002910TEST(ValidateRegulatorsConfigTest, CommandLineSyntax)
2911{
Bob Kinga57e0812020-03-12 10:47:42 +08002912 std::string validateTool =
2913 " ../phosphor-regulators/tools/validate-regulators-config.py ";
Bob Kinged009652020-02-20 14:54:13 +08002914 std::string schema = " -s ";
Bob Kinga57e0812020-03-12 10:47:42 +08002915 std::string schemaFile =
2916 " ../phosphor-regulators/schema/config_schema.json ";
Bob Kinged009652020-02-20 14:54:13 +08002917 std::string configuration = " -c ";
2918 std::string command;
2919 std::string errorMessage;
2920 std::string outputMessage;
2921 std::string outputMessageHelp =
2922 "usage: validate-regulators-config.py [-h] [-s SCHEMA_FILE]";
2923 int valid = 0;
2924
Shawn McCarney0f6ebad2020-09-04 16:43:00 -05002925 TemporaryFile tmpFile;
2926 std::string fileName = tmpFile.getPath().string();
Bob Kinga57e0812020-03-12 10:47:42 +08002927 writeDataToFile(validConfigFile, fileName);
Bob Kinged009652020-02-20 14:54:13 +08002928 // Valid: -s specified
2929 {
2930 command = validateTool + "-s " + schemaFile + configuration + fileName;
2931 expectCommandLineSyntax(errorMessage, outputMessage, command, valid);
2932 }
2933 // Valid: --schema-file specified
2934 {
2935 command = validateTool + "--schema-file " + schemaFile + configuration +
2936 fileName;
2937 expectCommandLineSyntax(errorMessage, outputMessage, command, valid);
2938 }
2939 // Valid: -c specified
2940 {
2941 command = validateTool + schema + schemaFile + "-c " + fileName;
2942 expectCommandLineSyntax(errorMessage, outputMessage, command, valid);
2943 }
2944 // Valid: --configuration-file specified
2945 {
2946 command = validateTool + schema + schemaFile + "--configuration-file " +
2947 fileName;
2948 expectCommandLineSyntax(errorMessage, outputMessage, command, valid);
2949 }
2950 // Valid: -h specified
2951 {
2952 command = validateTool + "-h ";
2953 expectCommandLineSyntax(errorMessage, outputMessageHelp, command,
2954 valid);
2955 }
2956 // Valid: --help specified
2957 {
2958 command = validateTool + "--help ";
2959 expectCommandLineSyntax(errorMessage, outputMessageHelp, command,
2960 valid);
2961 }
2962 // Invalid: -c/--configuration-file not specified
2963 {
2964 command = validateTool + schema + schemaFile;
2965 expectCommandLineSyntax("Error: Configuration file is required.",
2966 outputMessageHelp, command, 1);
2967 }
2968 // Invalid: -s/--schema-file not specified
2969 {
2970 command = validateTool + configuration + fileName;
2971 expectCommandLineSyntax("Error: Schema file is required.",
2972 outputMessageHelp, command, 1);
2973 }
Bob Kingb7552f02020-10-15 14:34:17 +08002974 // Invalid: -c specified more than once
2975 {
2976 command = validateTool + schema + schemaFile + "-c -c " + fileName;
2977 expectCommandLineSyntax(outputMessageHelp, outputMessage, command, 2);
2978 }
Bob Kinged009652020-02-20 14:54:13 +08002979 // Invalid: -s specified more than once
2980 {
2981 command =
2982 validateTool + "-s -s " + schemaFile + configuration + fileName;
2983 expectCommandLineSyntax(outputMessageHelp, outputMessage, command, 2);
2984 }
Bob Kinged009652020-02-20 14:54:13 +08002985 // Invalid: No file name specified after -c
2986 {
2987 command = validateTool + schema + schemaFile + configuration;
2988 expectCommandLineSyntax(outputMessageHelp, outputMessage, command, 2);
2989 }
2990 // Invalid: No file name specified after -s
2991 {
2992 command = validateTool + schema + configuration + fileName;
2993 expectCommandLineSyntax(outputMessageHelp, outputMessage, command, 2);
2994 }
2995 // Invalid: File specified after -c does not exist
2996 {
2997 command = validateTool + schema + schemaFile + configuration +
2998 "../notExistFile";
Bob Kingb7552f02020-10-15 14:34:17 +08002999 expectCommandLineSyntax("Error: Configuration file does not exist.",
3000 outputMessageHelp, command, 1);
Bob Kinged009652020-02-20 14:54:13 +08003001 }
3002 // Invalid: File specified after -s does not exist
3003 {
3004 command = validateTool + schema + "../notExistFile " + configuration +
3005 fileName;
Bob Kingb7552f02020-10-15 14:34:17 +08003006 expectCommandLineSyntax("Error: Schema file does not exist.",
3007 outputMessageHelp, command, 1);
3008 }
3009 // Invalid: File specified after -c is not right data format
3010 {
3011 TemporaryFile wrongFormatFile;
3012 std::string wrongFormatFileName = wrongFormatFile.getPath().string();
3013 std::ofstream out(wrongFormatFileName);
3014 out << "foo";
3015 out.close();
3016 command = validateTool + schema + schemaFile + configuration +
3017 wrongFormatFileName;
Bob Kinged009652020-02-20 14:54:13 +08003018 expectCommandLineSyntax(
Bob Kingb7552f02020-10-15 14:34:17 +08003019 "Error: Configuration file is not in the JSON format.",
3020 outputMessageHelp, command, 1);
Bob Kinged009652020-02-20 14:54:13 +08003021 }
3022 // Invalid: File specified after -s is not right data format
3023 {
Shawn McCarney0f6ebad2020-09-04 16:43:00 -05003024 TemporaryFile wrongFormatFile;
3025 std::string wrongFormatFileName = wrongFormatFile.getPath().string();
Bob Kinga57e0812020-03-12 10:47:42 +08003026 std::ofstream out(wrongFormatFileName);
Bob Kinged009652020-02-20 14:54:13 +08003027 out << "foo";
3028 out.close();
Bob Kinga57e0812020-03-12 10:47:42 +08003029 command = validateTool + schema + wrongFormatFileName + configuration +
3030 fileName;
Bob Kingb7552f02020-10-15 14:34:17 +08003031 expectCommandLineSyntax("Error: Schema file is not in the JSON format.",
3032 outputMessageHelp, command, 1);
Bob Kinged009652020-02-20 14:54:13 +08003033 }
3034 // Invalid: File specified after -c is not readable
3035 {
Shawn McCarney0f6ebad2020-09-04 16:43:00 -05003036 TemporaryFile notReadableFile;
3037 std::string notReadableFileName = notReadableFile.getPath().string();
Bob Kinga57e0812020-03-12 10:47:42 +08003038 writeDataToFile(validConfigFile, notReadableFileName);
Bob Kinged009652020-02-20 14:54:13 +08003039 command = validateTool + schema + schemaFile + configuration +
Bob Kinga57e0812020-03-12 10:47:42 +08003040 notReadableFileName;
3041 chmod(notReadableFileName.c_str(), 0222);
Bob Kingb7552f02020-10-15 14:34:17 +08003042 expectCommandLineSyntax("Error: Configuration file is not readable.",
3043 outputMessageHelp, command, 1);
Bob Kinged009652020-02-20 14:54:13 +08003044 }
3045 // Invalid: File specified after -s is not readable
3046 {
Shawn McCarney0f6ebad2020-09-04 16:43:00 -05003047 TemporaryFile notReadableFile;
3048 std::string notReadableFileName = notReadableFile.getPath().string();
Bob Kinga57e0812020-03-12 10:47:42 +08003049 writeDataToFile(validConfigFile, notReadableFileName);
3050 command = validateTool + schema + notReadableFileName + configuration +
3051 fileName;
3052 chmod(notReadableFileName.c_str(), 0222);
Bob Kingb7552f02020-10-15 14:34:17 +08003053 expectCommandLineSyntax("Error: Schema file is not readable.",
3054 outputMessageHelp, command, 1);
Bob Kinged009652020-02-20 14:54:13 +08003055 }
3056 // Invalid: Unexpected parameter specified (like -g)
3057 {
3058 command = validateTool + schema + schemaFile + configuration +
3059 fileName + " -g";
3060 expectCommandLineSyntax(outputMessageHelp, outputMessage, command, 2);
3061 }
Bob Kinged009652020-02-20 14:54:13 +08003062}