blob: 987a4924de886dffcb0da2872252065942b11a0f [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 McCarney80c0b042020-03-27 12:08:53 -050016#include "tmp_file.hpp"
17
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,
78 "devices": [
79 {
80 "comments": [ "IR35221 regulator producing the Vdd rail" ],
81 "id": "vdd_regulator",
82 "is_regulator": true,
83 "fru": "/system/chassis/motherboard/regulator1",
84 "i2c_interface": {
85 "bus": 1,
86 "address": "0x70"
87 },
88 "rails": [
89 {
90 "comments": [ "Vdd rail" ],
91 "id": "vdd",
92 "configuration": {
93 "volts": 1.03,
94 "rule_id": "set_voltage_rule"
95 },
96 "sensor_monitoring": {
97 "rule_id": "read_sensors_rule"
98 }
99 }
100 ]
101 }
102 ]
103 }
104 ]
105 }
106)"_json;
107
Bob King386d33f2019-12-26 17:28:56 +0800108std::string getValidationToolCommand(const std::string& configFileName)
109{
Bob Kinga57e0812020-03-12 10:47:42 +0800110 std::string command =
111 "../phosphor-regulators/tools/validate-regulators-config.py -s \
112 ../phosphor-regulators/schema/config_schema.json -c ";
Bob King386d33f2019-12-26 17:28:56 +0800113 command += configFileName;
114 return command;
115}
116
Bob Kinga57e0812020-03-12 10:47:42 +0800117int runToolForOutputWithCommand(std::string command,
118 std::string& standardOutput,
119 std::string& standardError)
Bob King386d33f2019-12-26 17:28:56 +0800120{
121 // run the validation tool with the temporary file and return the output
122 // of the validation tool.
Bob Kinga57e0812020-03-12 10:47:42 +0800123 TmpFile tmpFile;
124 command += " 2> " + tmpFile.getName();
Bob King386d33f2019-12-26 17:28:56 +0800125 // get the jsonschema print from validation tool.
126 char buffer[256];
Bob Kinga57e0812020-03-12 10:47:42 +0800127 std::string result;
Bob King386d33f2019-12-26 17:28:56 +0800128 // to get the stdout from the validation tool.
129 FILE* pipe = popen(command.c_str(), "r");
130 if (!pipe)
131 {
132 throw std::runtime_error("popen() failed!");
133 }
134 while (!std::feof(pipe))
135 {
136 if (fgets(buffer, sizeof buffer, pipe) != NULL)
137 {
138 result += buffer;
139 }
140 }
141 int returnValue = pclose(pipe);
142 // Check if pclose() failed
143 if (returnValue == -1)
144 {
145 // unable to close pipe. Print error and exit function.
146 throw std::runtime_error("pclose() failed!");
147 }
148 std::string firstLine = result.substr(0, result.find('\n'));
Bob Kinga57e0812020-03-12 10:47:42 +0800149 standardOutput = firstLine;
Bob King386d33f2019-12-26 17:28:56 +0800150 // Get command exit status from return value
151 int exitStatus = WEXITSTATUS(returnValue);
Bob Kinga57e0812020-03-12 10:47:42 +0800152
153 // Read the standardError from tmpFile.
154 std::ifstream input(tmpFile.getName().c_str());
155 std::string line;
156
157 if (std::getline(input, line))
158 {
159 standardError = line;
160 }
161
Bob King386d33f2019-12-26 17:28:56 +0800162 return exitStatus;
163}
164
Bob Kinged009652020-02-20 14:54:13 +0800165int runToolForOutput(const std::string& configFileName, std::string& output,
Bob Kinga57e0812020-03-12 10:47:42 +0800166 std::string& error)
Bob Kinged009652020-02-20 14:54:13 +0800167{
168 std::string command = getValidationToolCommand(configFileName);
Bob Kinga57e0812020-03-12 10:47:42 +0800169 return runToolForOutputWithCommand(command, output, error);
Bob Kinged009652020-02-20 14:54:13 +0800170}
171
Bob King386d33f2019-12-26 17:28:56 +0800172void expectFileValid(const std::string& configFileName)
173{
Bob Kinged009652020-02-20 14:54:13 +0800174 std::string errorMessage;
175 std::string outputMessage;
Bob Kinga57e0812020-03-12 10:47:42 +0800176 EXPECT_EQ(runToolForOutput(configFileName, outputMessage, errorMessage), 0);
Bob King386d33f2019-12-26 17:28:56 +0800177 EXPECT_EQ(errorMessage, "");
178 EXPECT_EQ(outputMessage, "");
179}
180
181void expectFileInvalid(const std::string& configFileName,
182 const std::string& expectedErrorMessage,
183 const std::string& expectedOutputMessage)
184{
Bob Kinged009652020-02-20 14:54:13 +0800185 std::string errorMessage;
186 std::string outputMessage;
Bob Kinga57e0812020-03-12 10:47:42 +0800187 EXPECT_EQ(runToolForOutput(configFileName, outputMessage, errorMessage), 1);
Bob King386d33f2019-12-26 17:28:56 +0800188 EXPECT_EQ(errorMessage, expectedErrorMessage);
189 EXPECT_EQ(outputMessage, expectedOutputMessage);
190}
191
Bob Kinga57e0812020-03-12 10:47:42 +0800192void writeDataToFile(const json configFileJson, std::string fileName)
Bob King386d33f2019-12-26 17:28:56 +0800193{
Bob King386d33f2019-12-26 17:28:56 +0800194 std::string jsonData = configFileJson.dump();
195 std::ofstream out(fileName);
196 out << jsonData;
197 out.close();
Bob Kinged009652020-02-20 14:54:13 +0800198}
199
200void expectJsonValid(const json configFileJson)
201{
202 std::string fileName;
Bob Kinga57e0812020-03-12 10:47:42 +0800203 TmpFile tmpFile;
204 fileName = tmpFile.getName();
205 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{
214 std::string fileName;
Bob Kinga57e0812020-03-12 10:47:42 +0800215 TmpFile tmpFile;
216 fileName = tmpFile.getName();
217 writeDataToFile(configFileJson, fileName);
Bob King386d33f2019-12-26 17:28:56 +0800218
219 EXPECT_FILE_INVALID(fileName, expectedErrorMessage, expectedOutputMessage);
Bob King386d33f2019-12-26 17:28:56 +0800220}
221
Bob Kinged009652020-02-20 14:54:13 +0800222void expectCommandLineSyntax(const std::string& expectedErrorMessage,
223 const std::string& expectedOutputMessage,
224 std::string command, int status)
225{
226 std::string errorMessage;
227 std::string outputMessage;
Bob Kinga57e0812020-03-12 10:47:42 +0800228 EXPECT_EQ(runToolForOutputWithCommand(command, outputMessage, errorMessage),
229 status);
Bob Kinged009652020-02-20 14:54:13 +0800230 EXPECT_EQ(errorMessage, expectedErrorMessage);
231 EXPECT_EQ(outputMessage, expectedOutputMessage);
232}
233
Bob King3afa7112020-03-19 09:35:31 +0800234TEST(ValidateRegulatorsConfigTest, Action)
235{
236 // Valid: Comments property not specified
237 {
238 json configFile = validConfigFile;
239 EXPECT_JSON_VALID(configFile);
240 }
241 // Valid: Comments property specified
242 {
243 json configFile = validConfigFile;
244 configFile["rules"][0]["actions"][0]["comments"][0] =
245 "Set VOUT_COMMAND";
246 EXPECT_JSON_VALID(configFile);
247 }
248 // Valid: and action type specified
249 {
250 json configFile = validConfigFile;
251 json andAction =
252 R"(
253 {
254 "and": [
255 { "i2c_compare_byte": { "register": "0xA0", "value": "0x00" } },
256 { "i2c_compare_byte": { "register": "0xA1", "value": "0x00" } }
257 ]
258 }
259 )"_json;
260 configFile["rules"][0]["actions"].push_back(andAction);
261 EXPECT_JSON_VALID(configFile);
262 }
263 // Valid: compare_presence action type specified
264 {
265 json configFile = validConfigFile;
266 configFile["rules"][0]["actions"][1]["compare_presence"]["fru"] =
267 "/system/chassis/motherboard/regulator2";
268 configFile["rules"][0]["actions"][1]["compare_presence"]["value"] =
269 true;
270 EXPECT_JSON_VALID(configFile);
271 }
272 // Valid: compare_vpd action type specified
273 {
274 json configFile = validConfigFile;
275 configFile["rules"][0]["actions"][1]["compare_vpd"]["fru"] =
276 "/system/chassis/motherboard/regulator2";
277 configFile["rules"][0]["actions"][1]["compare_vpd"]["keyword"] = "CCIN";
278 configFile["rules"][0]["actions"][1]["compare_vpd"]["value"] = "2D35";
279 EXPECT_JSON_VALID(configFile);
280 }
281 // Valid: i2c_compare_bit action type specified
282 {
283 json configFile = validConfigFile;
284 configFile["rules"][0]["actions"][1]["i2c_compare_bit"]["register"] =
285 "0xA0";
286 configFile["rules"][0]["actions"][1]["i2c_compare_bit"]["position"] = 3;
287 configFile["rules"][0]["actions"][1]["i2c_compare_bit"]["value"] = 1;
288 EXPECT_JSON_VALID(configFile);
289 }
290 // Valid: i2c_compare_byte action type specified
291 {
292 json configFile = validConfigFile;
293 configFile["rules"][0]["actions"][1]["i2c_compare_byte"]["register"] =
294 "0x82";
295 configFile["rules"][0]["actions"][1]["i2c_compare_byte"]["value"] =
296 "0x40";
297 configFile["rules"][0]["actions"][1]["i2c_compare_byte"]["mask"] =
298 "0x7F";
299 EXPECT_JSON_VALID(configFile);
300 }
301 // Valid: i2c_compare_bytes action type specified
302 {
303 json configFile = validConfigFile;
304 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["register"] =
305 "0x82";
306 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["values"] = {
307 "0x02", "0x73"};
308 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["masks"] = {
309 "0x7F", "0x7F"};
310 EXPECT_JSON_VALID(configFile);
311 }
312 // Valid: i2c_write_bit action type specified
313 {
314 json configFile = validConfigFile;
315 configFile["rules"][0]["actions"][1]["i2c_write_bit"]["register"] =
316 "0xA0";
317 configFile["rules"][0]["actions"][1]["i2c_write_bit"]["position"] = 3;
318 configFile["rules"][0]["actions"][1]["i2c_write_bit"]["value"] = 1;
319 EXPECT_JSON_VALID(configFile);
320 }
321 // Valid: i2c_write_byte action type specified
322 {
323 json configFile = validConfigFile;
324 configFile["rules"][0]["actions"][1]["i2c_write_byte"]["register"] =
325 "0x82";
326 configFile["rules"][0]["actions"][1]["i2c_write_byte"]["value"] =
327 "0x40";
328 configFile["rules"][0]["actions"][1]["i2c_write_byte"]["mask"] = "0x7F";
329 EXPECT_JSON_VALID(configFile);
330 }
331 // Valid: i2c_write_bytes action type specified
332 {
333 json configFile = validConfigFile;
334 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["register"] =
335 "0x82";
336 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["values"] = {
337 "0x02", "0x73"};
338 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["masks"] = {
339 "0x7F", "0x7F"};
340 EXPECT_JSON_VALID(configFile);
341 }
342 // Valid: if action type specified
343 {
344 json configFile = validConfigFile;
345 configFile["rules"][2]["actions"][0]["if"]["condition"]["run_rule"] =
346 "set_voltage_rule";
347 configFile["rules"][2]["actions"][0]["if"]["then"][0]["run_rule"] =
348 "read_sensors_rule";
349 configFile["rules"][2]["actions"][0]["if"]["else"][0]["run_rule"] =
350 "read_sensors_rule";
351 configFile["rules"][2]["id"] = "rule_if";
352 EXPECT_JSON_VALID(configFile);
353 }
354 // Valid: not action type specified
355 {
356 json configFile = validConfigFile;
357 configFile["rules"][0]["actions"][1]["not"]["i2c_compare_byte"]
358 ["register"] = "0xA0";
359 configFile["rules"][0]["actions"][1]["not"]["i2c_compare_byte"]
360 ["value"] = "0xFF";
361 EXPECT_JSON_VALID(configFile);
362 }
363 // Valid: or action type specified
364 {
365 json configFile = validConfigFile;
366 configFile["rules"][0]["actions"][1]["or"][0]["i2c_compare_byte"]
367 ["register"] = "0xA0";
368 configFile["rules"][0]["actions"][1]["or"][0]["i2c_compare_byte"]
369 ["value"] = "0x00";
370 configFile["rules"][0]["actions"][1]["or"][1]["i2c_compare_byte"]
371 ["register"] = "0xA1";
372 configFile["rules"][0]["actions"][1]["or"][1]["i2c_compare_byte"]
373 ["value"] = "0x00";
374 EXPECT_JSON_VALID(configFile);
375 }
376 // Valid: pmbus_read_sensor and pmbus_write_vout_command action type
377 // specified
378 {
379 EXPECT_JSON_VALID(validConfigFile);
380 }
381 // Valid: run_rule action type specified
382 {
383 json configFile = validConfigFile;
384 configFile["rules"][0]["actions"][1]["run_rule"] = "read_sensors_rule";
385 EXPECT_JSON_VALID(configFile);
386 }
387 // Valid: set_device action type specified
388 {
389 json configFile = validConfigFile;
390 configFile["rules"][0]["actions"][1]["set_device"] = "vdd_regulator";
391 EXPECT_JSON_VALID(configFile);
392 }
393 // Invalid: Wrong data type for comments (should be array of string)
394 {
395 json configFile = validConfigFile;
396 configFile["rules"][0]["actions"][0]["comments"] = true;
397 EXPECT_JSON_INVALID(configFile, "Validation failed.",
398 "True is not of type 'array'");
399 }
400 // Invalid: Wrong data type for action type (such as "i2c_write_byte": true)
401 {
402 json configFile = validConfigFile;
403 configFile["rules"][0]["actions"][1]["i2c_write_byte"] = true;
404 EXPECT_JSON_INVALID(configFile, "Validation failed.",
405 "True is not of type 'object'");
406 }
407 // Invalid: Empty comments array
408 {
409 json configFile = validConfigFile;
410 configFile["rules"][0]["actions"][0]["comments"] = json::array();
411 EXPECT_JSON_INVALID(configFile, "Validation failed.",
412 "[] is too short");
413 }
414 // Invalid: Comments array has wrong element type (should be string)
415 {
416 json configFile = validConfigFile;
417 configFile["rules"][0]["actions"][0]["comments"][0] = true;
418 EXPECT_JSON_INVALID(configFile, "Validation failed.",
419 "True is not of type 'string'");
420 }
421 // Invalid: No action type specified
422 {
423 json configFile = validConfigFile;
424 configFile["rules"][0]["actions"][1]["comments"][0] =
425 "Check if bit 3 is on";
426 EXPECT_JSON_INVALID(configFile, "Validation failed.",
427 "'and' is a required property");
428 }
429 // Invalid: Multiple action types specified (such as both 'compare_presence'
430 // and 'pmbus_write_vout_command')
431 {
432 json configFile = validConfigFile;
433 configFile["rules"][0]["actions"][0]["compare_presence"]["value"] =
434 true;
435 EXPECT_JSON_INVALID(
436 configFile, "Validation failed.",
437 "{'compare_presence': {'value': True}, 'pmbus_write_vout_command': "
438 "{'format': 'linear'}} is valid under each of {'required': "
439 "['pmbus_write_vout_command']}, {'required': "
440 "['compare_presence']}");
441 }
442 // Invalid: Unexpected property specified (like 'foo')
443 {
444 json configFile = validConfigFile;
445 configFile["rules"][0]["actions"][1]["foo"] = "foo";
446 EXPECT_JSON_INVALID(
447 configFile, "Validation failed.",
448 "Additional properties are not allowed ('foo' was unexpected)");
449 }
450}
Bob Kingbeaf6532020-01-21 11:03:49 +0800451TEST(ValidateRegulatorsConfigTest, And)
452{
453 // Valid.
454 {
455 json configFile = validConfigFile;
456 json andAction =
457 R"(
458 {
459 "and": [
460 { "i2c_compare_byte": { "register": "0xA0", "value": "0x00" } },
461 { "i2c_compare_byte": { "register": "0xA1", "value": "0x00" } }
462 ]
463 }
464 )"_json;
465 configFile["rules"][0]["actions"].push_back(andAction);
466 EXPECT_JSON_VALID(configFile);
467 }
468
469 // Invalid: actions property value is an empty array.
470 {
471 json configFile = validConfigFile;
472 json andAction =
473 R"(
474 {
475 "and": []
476 }
477 )"_json;
478 configFile["rules"][0]["actions"].push_back(andAction);
479 EXPECT_JSON_INVALID(configFile, "Validation failed.",
480 "[] is too short");
481 }
482
483 // Invalid: actions property has incorrect value data type.
484 {
485 json configFile = validConfigFile;
486 json andAction =
487 R"(
488 {
489 "and": true
490 }
491 )"_json;
492 configFile["rules"][0]["actions"].push_back(andAction);
493 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800494 "True is not of type 'array'");
Bob Kingbeaf6532020-01-21 11:03:49 +0800495 }
496
497 // Invalid: actions property value contains wrong element type
498 {
499 json configFile = validConfigFile;
500 json andAction =
501 R"(
502 {
503 "and": ["foo"]
504 }
505 )"_json;
506 configFile["rules"][0]["actions"].push_back(andAction);
507 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800508 "'foo' is not of type 'object'");
Bob Kingbeaf6532020-01-21 11:03:49 +0800509 }
510}
Bob King3728f562020-01-21 11:35:31 +0800511TEST(ValidateRegulatorsConfigTest, Chassis)
512{
513 // Valid: test chassis.
514 {
515 json configFile = validConfigFile;
516 EXPECT_JSON_VALID(configFile);
517 }
518 // Valid: test chassis with required properties.
519 {
520 json configFile = validConfigFile;
521 configFile["chassis"][0].erase("comments");
522 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 }
546 // Invalid: test chassis with property devices wrong type.
547 {
548 json configFile = validConfigFile;
549 configFile["chassis"][0]["devices"] = true;
550 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800551 "True is not of type 'array'");
Bob King3728f562020-01-21 11:35:31 +0800552 }
553 // Invalid: test chassis with property comments empty array.
554 {
555 json configFile = validConfigFile;
556 configFile["chassis"][0]["comments"] = json::array();
557 EXPECT_JSON_INVALID(configFile, "Validation failed.",
558 "[] is too short");
559 }
560 // Invalid: test chassis with property devices empty array.
561 {
562 json configFile = validConfigFile;
563 configFile["chassis"][0]["devices"] = json::array();
564 EXPECT_JSON_INVALID(configFile, "Validation failed.",
565 "[] is too short");
566 }
567 // Invalid: test chassis with property number less than 1.
568 {
569 json configFile = validConfigFile;
570 configFile["chassis"][0]["number"] = 0;
571 EXPECT_JSON_INVALID(configFile, "Validation failed.",
572 "0 is less than the minimum of 1");
573 }
574}
Bob Kingbf1cbea2020-01-21 11:08:50 +0800575TEST(ValidateRegulatorsConfigTest, ComparePresence)
576{
577 json comparePresenceFile = validConfigFile;
578 comparePresenceFile["rules"][0]["actions"][1]["compare_presence"]["fru"] =
579 "/system/chassis/motherboard/regulator2";
580 comparePresenceFile["rules"][0]["actions"][1]["compare_presence"]["value"] =
581 true;
582 // Valid.
583 {
584 json configFile = comparePresenceFile;
585 EXPECT_JSON_VALID(configFile);
586 }
587
588 // Invalid: no FRU property.
589 {
590 json configFile = comparePresenceFile;
591 configFile["rules"][0]["actions"][1]["compare_presence"].erase("fru");
592 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800593 "'fru' is a required property");
Bob Kingbf1cbea2020-01-21 11:08:50 +0800594 }
595
596 // Invalid: FRU property length is string less than 1.
597 {
598 json configFile = comparePresenceFile;
599 configFile["rules"][0]["actions"][1]["compare_presence"]["fru"] = "";
600 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800601 "'' is too short");
Bob Kingbf1cbea2020-01-21 11:08:50 +0800602 }
603
604 // Invalid: no value property.
605 {
606 json configFile = comparePresenceFile;
607 configFile["rules"][0]["actions"][1]["compare_presence"].erase("value");
608 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800609 "'value' is a required property");
Bob Kingbf1cbea2020-01-21 11:08:50 +0800610 }
611
612 // Invalid: value property type is not boolean.
613 {
614 json configFile = comparePresenceFile;
615 configFile["rules"][0]["actions"][1]["compare_presence"]["value"] = "1";
616 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800617 "'1' is not of type 'boolean'");
Bob Kingbf1cbea2020-01-21 11:08:50 +0800618 }
619
620 // Invalid: FRU property type is not string.
621 {
622 json configFile = comparePresenceFile;
623 configFile["rules"][0]["actions"][1]["compare_presence"]["fru"] = 1;
624 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800625 "1 is not of type 'string'");
Bob Kingbf1cbea2020-01-21 11:08:50 +0800626 }
627}
Bob Kingf8b77a02020-01-21 11:09:47 +0800628TEST(ValidateRegulatorsConfigTest, CompareVpd)
629{
630 json compareVpdFile = validConfigFile;
631 compareVpdFile["rules"][0]["actions"][1]["compare_vpd"]["fru"] =
632 "/system/chassis/motherboard/regulator2";
633 compareVpdFile["rules"][0]["actions"][1]["compare_vpd"]["keyword"] = "CCIN";
634 compareVpdFile["rules"][0]["actions"][1]["compare_vpd"]["value"] = "2D35";
635
636 // Valid.
637 {
638 json configFile = compareVpdFile;
639 EXPECT_JSON_VALID(configFile);
640 }
641
642 // Invalid: no FRU property.
643 {
644 json configFile = compareVpdFile;
645 configFile["rules"][0]["actions"][1]["compare_vpd"].erase("fru");
646 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800647 "'fru' is a required property");
Bob Kingf8b77a02020-01-21 11:09:47 +0800648 }
649
650 // Invalid: no keyword property.
651 {
652 json configFile = compareVpdFile;
653 configFile["rules"][0]["actions"][1]["compare_vpd"].erase("keyword");
654 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800655 "'keyword' is a required property");
Bob Kingf8b77a02020-01-21 11:09:47 +0800656 }
657
658 // Invalid: no value property.
659 {
660 json configFile = compareVpdFile;
661 configFile["rules"][0]["actions"][1]["compare_vpd"].erase("value");
662 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800663 "'value' is a required property");
Bob Kingf8b77a02020-01-21 11:09:47 +0800664 }
665
666 // Invalid: property FRU wrong type.
667 {
668 json configFile = compareVpdFile;
669 configFile["rules"][0]["actions"][1]["compare_vpd"]["fru"] = 1;
670 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800671 "1 is not of type 'string'");
Bob Kingf8b77a02020-01-21 11:09:47 +0800672 }
673
674 // Invalid: property FRU is string less than 1.
675 {
676 json configFile = compareVpdFile;
677 configFile["rules"][0]["actions"][1]["compare_vpd"]["fru"] = "";
678 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800679 "'' is too short");
Bob Kingf8b77a02020-01-21 11:09:47 +0800680 }
681
682 // Invalid: property keyword is not "CCIN", "Manufacturer", "Model",
683 // "PartNumber"
684 {
685 json configFile = compareVpdFile;
686 configFile["rules"][0]["actions"][1]["compare_vpd"]["keyword"] =
687 "Number";
688 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800689 "'Number' is not one of ['CCIN', "
690 "'Manufacturer', 'Model', 'PartNumber']");
Bob Kingf8b77a02020-01-21 11:09:47 +0800691 }
692
693 // Invalid: property value wrong type.
694 {
695 json configFile = compareVpdFile;
696 configFile["rules"][0]["actions"][1]["compare_vpd"]["value"] = 1;
697 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800698 "1 is not of type 'string'");
Bob Kingf8b77a02020-01-21 11:09:47 +0800699 }
700}
Bob King20057412020-03-16 16:50:17 +0800701TEST(ValidateRegulatorsConfigTest, ConfigFile)
702{
703 // Valid: Only required properties specified
704 {
705 json configFile;
706 configFile["chassis"][0]["number"] = 1;
707 EXPECT_JSON_VALID(configFile);
708 }
709 // Valid: All properties specified
710 {
711 json configFile = validConfigFile;
712 EXPECT_JSON_VALID(configFile);
713 }
714 // Invalid: Required chassis property not specified
715 {
716 json configFile = validConfigFile;
717 configFile.erase("chassis");
718 EXPECT_JSON_INVALID(configFile, "Validation failed.",
719 "'chassis' is a required property");
720 }
721 // Invalid: Wrong data type for comments
722 {
723 json configFile = validConfigFile;
724 configFile["comments"] = true;
725 EXPECT_JSON_INVALID(configFile, "Validation failed.",
726 "True is not of type 'array'");
727 }
728 // Invalid: Wrong data type for rules
729 {
730 json configFile = validConfigFile;
731 configFile["rules"] = true;
732 EXPECT_JSON_INVALID(configFile, "Validation failed.",
733 "True is not of type 'array'");
734 }
735 // Invalid: Wrong data type for chassis
736 {
737 json configFile = validConfigFile;
738 configFile["chassis"] = true;
739 EXPECT_JSON_INVALID(configFile, "Validation failed.",
740 "True is not of type 'array'");
741 }
742 // Invalid: Empty comments array;
743 {
744 json configFile = validConfigFile;
745 configFile["comments"] = json::array();
746 EXPECT_JSON_INVALID(configFile, "Validation failed.",
747 "[] is too short");
748 }
749 // Invalid: Empty rules array
750 {
751 json configFile = validConfigFile;
752 configFile["rules"] = json::array();
753 EXPECT_JSON_INVALID(configFile, "Validation failed.",
754 "[] is too short");
755 }
756 // Invalid: Empty chassis array
757 {
758 json configFile = validConfigFile;
759 configFile["chassis"] = json::array();
760 EXPECT_JSON_INVALID(configFile, "Validation failed.",
761 "[] is too short");
762 }
763 // Invalid: Comments array has wrong element type (should be string)
764 {
765 json configFile = validConfigFile;
766 configFile["comments"][0] = true;
767 EXPECT_JSON_INVALID(configFile, "Validation failed.",
768 "True is not of type 'string'");
769 }
770 // Invalid: Rules array has wrong element type (should be rule)
771 {
772 json configFile = validConfigFile;
773 configFile["rules"][0] = true;
774 EXPECT_JSON_INVALID(configFile, "Validation failed.",
775 "True is not of type 'object'");
776 }
777 // Invalid: Chassis array has wrong element type (should be chassis)
778 {
779 json configFile = validConfigFile;
780 configFile["chassis"][0] = true;
781 EXPECT_JSON_INVALID(configFile, "Validation failed.",
782 "True is not of type 'object'");
783 }
784 // Invalid: Unexpected property specified
785 {
786 json configFile = validConfigFile;
787 configFile["foo"] = json::array();
788 EXPECT_JSON_INVALID(
789 configFile, "Validation failed.",
790 "Additional properties are not allowed ('foo' was unexpected)");
791 }
792}
Bob King4c67a3a2020-02-07 09:48:11 +0800793TEST(ValidateRegulatorsConfigTest, Configuration)
794{
795 json configurationFile = validConfigFile;
796 configurationFile["chassis"][0]["devices"][0]["configuration"]["comments"]
797 [0] = "Set rail to 1.25V using standard rule";
798 configurationFile["chassis"][0]["devices"][0]["configuration"]["volts"] =
799 1.25;
800 configurationFile["chassis"][0]["devices"][0]["configuration"]["rule_id"] =
801 "set_voltage_rule";
802 // Valid: test configuration with property rule_id and with no actions.
803 {
804 json configFile = configurationFile;
Bob King78793102020-03-13 13:16:09 +0800805 configFile["chassis"][0]["devices"][0]["configuration"]["comments"][1] =
806 "test multiple array elements in comments.";
Bob King4c67a3a2020-02-07 09:48:11 +0800807 EXPECT_JSON_VALID(configFile);
808 }
809 // Valid: test configuration with property actions and with no rule_id.
810 {
811 json configFile = configurationFile;
812 configFile["chassis"][0]["devices"][0]["configuration"].erase(
813 "rule_id");
814 configFile["chassis"][0]["devices"][0]["configuration"]["actions"][0]
815 ["compare_presence"]["fru"] =
816 "/system/chassis/motherboard/cpu3";
817 configFile["chassis"][0]["devices"][0]["configuration"]["actions"][0]
818 ["compare_presence"]["value"] = true;
819 EXPECT_JSON_VALID(configFile);
820 }
821 // Valid: comments not specified (optional property).
822 {
823 json configFile = configurationFile;
824 configFile["chassis"][0]["devices"][0]["configuration"].erase(
825 "comments");
826 EXPECT_JSON_VALID(configFile);
827 }
828 // Valid: volts not specified (optional property).
829 {
830 json configFile = configurationFile;
831 configFile["chassis"][0]["devices"][0]["configuration"].erase("volts");
832 EXPECT_JSON_VALID(configFile);
833 }
834 // Valid: configuration is property of a rail (vs. a device).
835 {
836 json configFile = validConfigFile;
837 configFile["chassis"][0]["devices"][0]["rails"][0]["configuration"]
838 ["comments"][0] = "Set rail to 1.25V using standard rule";
839 configFile["chassis"][0]["devices"][0]["rails"][0]["configuration"]
840 ["volts"] = 1.25;
841 configFile["chassis"][0]["devices"][0]["rails"][0]["configuration"]
842 ["rule_id"] = "set_voltage_rule";
843 EXPECT_JSON_VALID(configFile);
844 }
845 // Invalid: comments property has wrong data type (not an array).
846 {
847 json configFile = configurationFile;
848 configFile["chassis"][0]["devices"][0]["configuration"]["comments"] = 1;
849 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800850 "1 is not of type 'array'");
Bob King4c67a3a2020-02-07 09:48:11 +0800851 }
852 // Invalid: test configuration with both actions and rule_id properties.
853 {
854 json configFile = configurationFile;
855 configFile["chassis"][0]["devices"][0]["configuration"]["actions"][0]
856 ["compare_presence"]["fru"] =
857 "/system/chassis/motherboard/cpu3";
858 configFile["chassis"][0]["devices"][0]["configuration"]["actions"][0]
859 ["compare_presence"]["value"] = true;
860 EXPECT_JSON_INVALID(
861 configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800862 "{'actions': [{'compare_presence': {'fru': "
863 "'/system/chassis/motherboard/cpu3', 'value': True}}], 'comments': "
864 "['Set rail to 1.25V using standard rule'], 'rule_id': "
865 "'set_voltage_rule', 'volts': 1.25} is valid under each of "
866 "{'required': ['actions']}, {'required': ['rule_id']}");
Bob King4c67a3a2020-02-07 09:48:11 +0800867 }
868 // Invalid: test configuration with no rule_id and actions.
869 {
870 json configFile = configurationFile;
871 configFile["chassis"][0]["devices"][0]["configuration"].erase(
872 "rule_id");
873 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800874 "'rule_id' is a required property");
Bob King4c67a3a2020-02-07 09:48:11 +0800875 }
876 // Invalid: test configuration with property volts wrong type.
877 {
878 json configFile = configurationFile;
879 configFile["chassis"][0]["devices"][0]["configuration"]["volts"] = true;
880 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800881 "True is not of type 'number'");
Bob King4c67a3a2020-02-07 09:48:11 +0800882 }
883 // Invalid: test configuration with property rule_id wrong type.
884 {
885 json configFile = configurationFile;
886 configFile["chassis"][0]["devices"][0]["configuration"]["rule_id"] =
887 true;
888 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800889 "True is not of type 'string'");
Bob King4c67a3a2020-02-07 09:48:11 +0800890 }
891 // Invalid: test configuration with property actions wrong type.
892 {
893 json configFile = configurationFile;
894 configFile["chassis"][0]["devices"][0]["configuration"].erase(
895 "rule_id");
896 configFile["chassis"][0]["devices"][0]["configuration"]["actions"] =
897 true;
898 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800899 "True is not of type 'array'");
Bob King4c67a3a2020-02-07 09:48:11 +0800900 }
901 // Invalid: test configuration with property comments empty array.
902 {
903 json configFile = configurationFile;
904 configFile["chassis"][0]["devices"][0]["configuration"]["comments"] =
905 json::array();
906 EXPECT_JSON_INVALID(configFile, "Validation failed.",
907 "[] is too short");
908 }
909 // Invalid: test configuration with property rule_id wrong format.
910 {
911 json configFile = configurationFile;
912 configFile["chassis"][0]["devices"][0]["configuration"]["rule_id"] =
913 "id!";
914 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800915 "'id!' does not match '^[A-Za-z0-9_]+$'");
Bob King4c67a3a2020-02-07 09:48:11 +0800916 }
917 // Invalid: test configuration with property actions empty array.
918 {
919 json configFile = configurationFile;
920 configFile["chassis"][0]["devices"][0]["configuration"].erase(
921 "rule_id");
922 configFile["chassis"][0]["devices"][0]["configuration"]["actions"] =
923 json::array();
924 EXPECT_JSON_INVALID(configFile, "Validation failed.",
925 "[] is too short");
926 }
927}
Bob Kinga2ba2df2020-02-04 14:38:44 +0800928TEST(ValidateRegulatorsConfigTest, Device)
929{
930
931 // Valid: test devices.
932 {
933 json configFile = validConfigFile;
934 EXPECT_JSON_VALID(configFile);
935 }
936 // Valid: test devices with required properties.
937 {
938 json configFile = validConfigFile;
939 configFile["chassis"][0]["devices"][0].erase("comments");
940 configFile["chassis"][0]["devices"][0].erase("presence_detection");
941 configFile["chassis"][0]["devices"][0].erase("configuration");
942 configFile["chassis"][0]["devices"][0].erase("rails");
943 EXPECT_JSON_VALID(configFile);
944 }
945 // Invalid: test devices with no id.
946 {
947 json configFile = validConfigFile;
948 configFile["chassis"][0]["devices"][0].erase("id");
949 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800950 "'id' is a required property");
Bob Kinga2ba2df2020-02-04 14:38:44 +0800951 }
952 // Invalid: test devices with no is_regulator.
953 {
954 json configFile = validConfigFile;
955 configFile["chassis"][0]["devices"][0].erase("is_regulator");
956 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800957 "'is_regulator' is a required property");
Bob Kinga2ba2df2020-02-04 14:38:44 +0800958 }
959 // Invalid: test devices with no fru.
960 {
961 json configFile = validConfigFile;
962 configFile["chassis"][0]["devices"][0].erase("fru");
963 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800964 "'fru' is a required property");
Bob Kinga2ba2df2020-02-04 14:38:44 +0800965 }
966 // Invalid: test devices with no i2c_interface.
967 {
968 json configFile = validConfigFile;
969 configFile["chassis"][0]["devices"][0].erase("i2c_interface");
970 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800971 "'i2c_interface' is a required property");
Bob Kinga2ba2df2020-02-04 14:38:44 +0800972 }
973 // Invalid: test devices with property comments wrong type.
974 {
975 json configFile = validConfigFile;
976 configFile["chassis"][0]["devices"][0]["comments"] = true;
977 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800978 "True is not of type 'array'");
Bob Kinga2ba2df2020-02-04 14:38:44 +0800979 }
980 // Invalid: test devices with property id wrong type.
981 {
982 json configFile = validConfigFile;
983 configFile["chassis"][0]["devices"][0]["id"] = true;
984 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800985 "True is not of type 'string'");
Bob Kinga2ba2df2020-02-04 14:38:44 +0800986 }
987 // Invalid: test devices with property is_regulator wrong type.
988 {
989 json configFile = validConfigFile;
990 configFile["chassis"][0]["devices"][0]["is_regulator"] = 1;
991 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800992 "1 is not of type 'boolean'");
Bob Kinga2ba2df2020-02-04 14:38:44 +0800993 }
994 // Invalid: test devices with property fru wrong type.
995 {
996 json configFile = validConfigFile;
997 configFile["chassis"][0]["devices"][0]["fru"] = true;
998 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800999 "True is not of type 'string'");
Bob Kinga2ba2df2020-02-04 14:38:44 +08001000 }
1001 // Invalid: test devices with property i2c_interface wrong type.
1002 {
1003 json configFile = validConfigFile;
1004 configFile["chassis"][0]["devices"][0]["i2c_interface"] = true;
1005 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001006 "True is not of type 'object'");
Bob Kinga2ba2df2020-02-04 14:38:44 +08001007 }
1008 // Invalid: test devices with property presence_detection wrong
1009 // type.
1010 {
1011 json configFile = validConfigFile;
1012 configFile["chassis"][0]["devices"][0]["presence_detection"] = true;
1013 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001014 "True is not of type 'object'");
Bob Kinga2ba2df2020-02-04 14:38:44 +08001015 }
1016 // Invalid: test devices with property configuration wrong type.
1017 {
1018 json configFile = validConfigFile;
1019 configFile["chassis"][0]["devices"][0]["configuration"] = true;
1020 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001021 "True is not of type 'object'");
Bob Kinga2ba2df2020-02-04 14:38:44 +08001022 }
1023 // Invalid: test devices with property rails wrong type.
1024 {
1025 json configFile = validConfigFile;
1026 configFile["chassis"][0]["devices"][0]["rails"] = true;
1027 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001028 "True is not of type 'array'");
Bob Kinga2ba2df2020-02-04 14:38:44 +08001029 }
1030 // Invalid: test devices with property comments empty array.
1031 {
1032 json configFile = validConfigFile;
1033 configFile["chassis"][0]["devices"][0]["comments"] = json::array();
1034 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1035 "[] is too short");
1036 }
1037 // Invalid: test devices with property fru length less than 1.
1038 {
1039 json configFile = validConfigFile;
1040 configFile["chassis"][0]["devices"][0]["fru"] = "";
1041 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001042 "'' is too short");
Bob Kinga2ba2df2020-02-04 14:38:44 +08001043 }
1044 // Invalid: test devices with property id wrong format.
1045 {
1046 json configFile = validConfigFile;
1047 configFile["chassis"][0]["devices"][0]["id"] = "id#";
1048 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001049 "'id#' does not match '^[A-Za-z0-9_]+$'");
Bob Kinga2ba2df2020-02-04 14:38:44 +08001050 }
1051 // Invalid: test devices with property rails empty array.
1052 {
1053 json configFile = validConfigFile;
1054 configFile["chassis"][0]["devices"][0]["rails"] = json::array();
1055 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1056 "[] is too short");
1057 }
1058}
Bob King4ab8cbb2020-01-21 11:10:48 +08001059TEST(ValidateRegulatorsConfigTest, I2CCompareBit)
1060{
1061 json i2cCompareBitFile = validConfigFile;
1062 i2cCompareBitFile["rules"][0]["actions"][1]["i2c_compare_bit"]["register"] =
1063 "0xA0";
1064 i2cCompareBitFile["rules"][0]["actions"][1]["i2c_compare_bit"]["position"] =
1065 3;
1066 i2cCompareBitFile["rules"][0]["actions"][1]["i2c_compare_bit"]["value"] = 1;
1067 // Valid: test rule actions i2c_compare_bit.
1068 {
1069 json configFile = i2cCompareBitFile;
1070 EXPECT_JSON_VALID(configFile);
1071 }
1072 // Invalid: test i2c_compare_bit with no register.
1073 {
1074 json configFile = i2cCompareBitFile;
1075 configFile["rules"][0]["actions"][1]["i2c_compare_bit"].erase(
1076 "register");
1077 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001078 "'register' is a required property");
Bob King4ab8cbb2020-01-21 11:10:48 +08001079 }
1080 // Invalid: test i2c_compare_bit with no position.
1081 {
1082 json configFile = i2cCompareBitFile;
1083 configFile["rules"][0]["actions"][1]["i2c_compare_bit"].erase(
1084 "position");
1085 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001086 "'position' is a required property");
Bob King4ab8cbb2020-01-21 11:10:48 +08001087 }
1088 // Invalid: test i2c_compare_bit with no value.
1089 {
1090 json configFile = i2cCompareBitFile;
1091 configFile["rules"][0]["actions"][1]["i2c_compare_bit"].erase("value");
1092 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001093 "'value' is a required property");
Bob King4ab8cbb2020-01-21 11:10:48 +08001094 }
1095 // Invalid: test i2c_compare_bit with register wrong type.
1096 {
1097 json configFile = i2cCompareBitFile;
1098 configFile["rules"][0]["actions"][1]["i2c_compare_bit"]["register"] = 1;
1099 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001100 "1 is not of type 'string'");
Bob King4ab8cbb2020-01-21 11:10:48 +08001101 }
1102 // Invalid: test i2c_compare_bit with register wrong format.
1103 {
1104 json configFile = i2cCompareBitFile;
1105 configFile["rules"][0]["actions"][1]["i2c_compare_bit"]["register"] =
1106 "0xA00";
1107 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001108 "'0xA00' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King4ab8cbb2020-01-21 11:10:48 +08001109 }
1110 // Invalid: test i2c_compare_bit with position wrong type.
1111 {
1112 json configFile = i2cCompareBitFile;
1113 configFile["rules"][0]["actions"][1]["i2c_compare_bit"]["position"] =
1114 3.1;
1115 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001116 "3.1 is not of type 'integer'");
Bob King4ab8cbb2020-01-21 11:10:48 +08001117 }
1118 // Invalid: test i2c_compare_bit with position greater than 7.
1119 {
1120 json configFile = i2cCompareBitFile;
1121 configFile["rules"][0]["actions"][1]["i2c_compare_bit"]["position"] = 8;
1122 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1123 "8 is greater than the maximum of 7");
1124 }
1125 // Invalid: test i2c_compare_bit with position less than 0.
1126 {
1127 json configFile = i2cCompareBitFile;
1128 configFile["rules"][0]["actions"][1]["i2c_compare_bit"]["position"] =
1129 -1;
1130 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1131 "-1 is less than the minimum of 0");
1132 }
1133 // Invalid: test i2c_compare_bit with value wrong type.
1134 {
1135 json configFile = i2cCompareBitFile;
1136 configFile["rules"][0]["actions"][1]["i2c_compare_bit"]["value"] = "1";
1137 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001138 "'1' is not of type 'integer'");
Bob King4ab8cbb2020-01-21 11:10:48 +08001139 }
1140 // Invalid: test i2c_compare_bit with value greater than 1.
1141 {
1142 json configFile = i2cCompareBitFile;
1143 configFile["rules"][0]["actions"][1]["i2c_compare_bit"]["value"] = 2;
1144 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1145 "2 is greater than the maximum of 1");
1146 }
1147 // Invalid: test i2c_compare_bit with value less than 0.
1148 {
1149 json configFile = i2cCompareBitFile;
1150 configFile["rules"][0]["actions"][1]["i2c_compare_bit"]["value"] = -1;
1151 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1152 "-1 is less than the minimum of 0");
1153 }
1154}
Bob King514023d2020-01-21 11:13:05 +08001155TEST(ValidateRegulatorsConfigTest, I2CCompareByte)
1156{
1157 json i2cCompareByteFile = validConfigFile;
1158 i2cCompareByteFile["rules"][0]["actions"][1]["i2c_compare_byte"]
1159 ["register"] = "0x82";
1160 i2cCompareByteFile["rules"][0]["actions"][1]["i2c_compare_byte"]["value"] =
1161 "0x40";
1162 i2cCompareByteFile["rules"][0]["actions"][1]["i2c_compare_byte"]["mask"] =
1163 "0x7F";
1164 // Valid: test i2c_compare_byte with all properties.
1165 {
1166 json configFile = i2cCompareByteFile;
1167 EXPECT_JSON_VALID(configFile);
1168 }
1169 // Valid: test i2c_compare_byte with all required properties.
1170 {
1171 json configFile = i2cCompareByteFile;
1172 configFile["rules"][0]["actions"][1]["i2c_compare_byte"].erase("mask");
1173 EXPECT_JSON_VALID(configFile);
1174 }
1175 // Invalid: test i2c_compare_byte with no register.
1176 {
1177 json configFile = i2cCompareByteFile;
1178 configFile["rules"][0]["actions"][1]["i2c_compare_byte"].erase(
1179 "register");
1180 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001181 "'register' is a required property");
Bob King514023d2020-01-21 11:13:05 +08001182 }
1183 // Invalid: test i2c_compare_byte with no value.
1184 {
1185 json configFile = i2cCompareByteFile;
1186 configFile["rules"][0]["actions"][1]["i2c_compare_byte"].erase("value");
1187 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001188 "'value' is a required property");
Bob King514023d2020-01-21 11:13:05 +08001189 }
1190 // Invalid: test i2c_compare_byte with property register wrong type.
1191 {
1192 json configFile = i2cCompareByteFile;
1193 configFile["rules"][0]["actions"][1]["i2c_compare_byte"]["register"] =
1194 1;
1195 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001196 "1 is not of type 'string'");
Bob King514023d2020-01-21 11:13:05 +08001197 }
1198 // Invalid: test i2c_compare_byte with property value wrong type.
1199 {
1200 json configFile = i2cCompareByteFile;
1201 configFile["rules"][0]["actions"][1]["i2c_compare_byte"]["value"] = 1;
1202 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001203 "1 is not of type 'string'");
Bob King514023d2020-01-21 11:13:05 +08001204 }
1205 // Invalid: test i2c_compare_byte with property mask wrong type.
1206 {
1207 json configFile = i2cCompareByteFile;
1208 configFile["rules"][0]["actions"][1]["i2c_compare_byte"]["mask"] = 1;
1209 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001210 "1 is not of type 'string'");
Bob King514023d2020-01-21 11:13:05 +08001211 }
1212 // Invalid: test i2c_compare_byte with property register more than 2 hex
1213 // digits.
1214 {
1215 json configFile = i2cCompareByteFile;
1216 configFile["rules"][0]["actions"][1]["i2c_compare_byte"]["register"] =
1217 "0x820";
1218 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001219 "'0x820' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King514023d2020-01-21 11:13:05 +08001220 }
1221 // Invalid: test i2c_compare_byte with property value more than 2 hex
1222 // digits.
1223 {
1224 json configFile = i2cCompareByteFile;
1225 configFile["rules"][0]["actions"][1]["i2c_compare_byte"]["value"] =
1226 "0x820";
1227 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001228 "'0x820' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King514023d2020-01-21 11:13:05 +08001229 }
1230 // Invalid: test i2c_compare_byte with property mask more than 2 hex digits.
1231 {
1232 json configFile = i2cCompareByteFile;
1233 configFile["rules"][0]["actions"][1]["i2c_compare_byte"]["mask"] =
1234 "0x820";
1235 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001236 "'0x820' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King514023d2020-01-21 11:13:05 +08001237 }
1238 // Invalid: test i2c_compare_byte with property register less than 2 hex
1239 // digits.
1240 {
1241 json configFile = i2cCompareByteFile;
1242 configFile["rules"][0]["actions"][1]["i2c_compare_byte"]["register"] =
1243 "0x8";
1244 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001245 "'0x8' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King514023d2020-01-21 11:13:05 +08001246 }
1247 // Invalid: test i2c_compare_byte with property value less than 2 hex
1248 // digits.
1249 {
1250 json configFile = i2cCompareByteFile;
1251 configFile["rules"][0]["actions"][1]["i2c_compare_byte"]["value"] =
1252 "0x8";
1253 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001254 "'0x8' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King514023d2020-01-21 11:13:05 +08001255 }
1256 // Invalid: test i2c_compare_byte with property mask less than 2 hex digits.
1257 {
1258 json configFile = i2cCompareByteFile;
1259 configFile["rules"][0]["actions"][1]["i2c_compare_byte"]["mask"] =
1260 "0x8";
1261 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001262 "'0x8' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King514023d2020-01-21 11:13:05 +08001263 }
1264 // Invalid: test i2c_compare_byte with property register no leading prefix.
1265 {
1266 json configFile = i2cCompareByteFile;
1267 configFile["rules"][0]["actions"][1]["i2c_compare_byte"]["register"] =
1268 "82";
1269 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001270 "'82' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King514023d2020-01-21 11:13:05 +08001271 }
1272 // Invalid: test i2c_compare_byte with property value no leading prefix.
1273 {
1274 json configFile = i2cCompareByteFile;
1275 configFile["rules"][0]["actions"][1]["i2c_compare_byte"]["value"] =
1276 "82";
1277 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001278 "'82' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King514023d2020-01-21 11:13:05 +08001279 }
1280 // Invalid: test i2c_compare_byte with property mask no leading prefix.
1281 {
1282 json configFile = i2cCompareByteFile;
1283 configFile["rules"][0]["actions"][1]["i2c_compare_byte"]["mask"] = "82";
1284 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001285 "'82' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King514023d2020-01-21 11:13:05 +08001286 }
1287 // Invalid: test i2c_compare_byte with property register invalid hex digit.
1288 {
1289 json configFile = i2cCompareByteFile;
1290 configFile["rules"][0]["actions"][1]["i2c_compare_byte"]["register"] =
1291 "0xG1";
1292 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001293 "'0xG1' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King514023d2020-01-21 11:13:05 +08001294 }
1295 // Invalid: test i2c_compare_byte with property value invalid hex digit.
1296 {
1297 json configFile = i2cCompareByteFile;
1298 configFile["rules"][0]["actions"][1]["i2c_compare_byte"]["value"] =
1299 "0xG1";
1300 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001301 "'0xG1' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King514023d2020-01-21 11:13:05 +08001302 }
1303 // Invalid: test i2c_compare_byte with property mask invalid hex digit.
1304 {
1305 json configFile = i2cCompareByteFile;
1306 configFile["rules"][0]["actions"][1]["i2c_compare_byte"]["mask"] =
1307 "0xG1";
1308 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001309 "'0xG1' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King514023d2020-01-21 11:13:05 +08001310 }
1311}
Bob Kingfb162bb2020-01-21 11:28:07 +08001312TEST(ValidateRegulatorsConfigTest, I2CCompareBytes)
1313{
1314 json i2cCompareBytesFile = validConfigFile;
1315 i2cCompareBytesFile["rules"][0]["actions"][1]["i2c_compare_bytes"]
1316 ["register"] = "0x82";
1317 i2cCompareBytesFile["rules"][0]["actions"][1]["i2c_compare_bytes"]
1318 ["values"] = {"0x02", "0x73"};
1319 i2cCompareBytesFile["rules"][0]["actions"][1]["i2c_compare_bytes"]
1320 ["masks"] = {"0x7F", "0x7F"};
1321 // Valid: test i2c_compare_bytes.
1322 {
1323 json configFile = i2cCompareBytesFile;
1324 EXPECT_JSON_VALID(configFile);
1325 }
1326 // Valid: test i2c_compare_bytes with all required properties.
1327 {
1328 json configFile = i2cCompareBytesFile;
1329 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"].erase(
1330 "masks");
1331 EXPECT_JSON_VALID(configFile);
1332 }
1333 // Invalid: test i2c_compare_bytes with no register.
1334 {
1335 json configFile = i2cCompareBytesFile;
1336 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"].erase(
1337 "register");
1338 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001339 "'register' is a required property");
Bob Kingfb162bb2020-01-21 11:28:07 +08001340 }
1341 // Invalid: test i2c_compare_bytes with no values.
1342 {
1343 json configFile = i2cCompareBytesFile;
1344 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"].erase(
1345 "values");
1346 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001347 "'values' is a required property");
Bob Kingfb162bb2020-01-21 11:28:07 +08001348 }
1349 // Invalid: test i2c_compare_bytes with property values as empty array.
1350 {
1351 json configFile = i2cCompareBytesFile;
1352 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["values"] =
1353 json::array();
1354 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1355 "[] is too short");
1356 }
1357 // Invalid: test i2c_compare_bytes with property masks as empty array.
1358 {
1359 json configFile = i2cCompareBytesFile;
1360 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["masks"] =
1361 json::array();
1362 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1363 "[] is too short");
1364 }
1365 // Invalid: test i2c_compare_bytes with property register wrong type.
1366 {
1367 json configFile = i2cCompareBytesFile;
1368 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["register"] =
1369 1;
1370 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001371 "1 is not of type 'string'");
Bob Kingfb162bb2020-01-21 11:28:07 +08001372 }
1373 // Invalid: test i2c_compare_bytes with property values wrong type.
1374 {
1375 json configFile = i2cCompareBytesFile;
1376 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["values"] = 1;
1377 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001378 "1 is not of type 'array'");
Bob Kingfb162bb2020-01-21 11:28:07 +08001379 }
1380 // Invalid: test i2c_compare_bytes with property masks wrong type.
1381 {
1382 json configFile = i2cCompareBytesFile;
1383 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["masks"] = 1;
1384 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001385 "1 is not of type 'array'");
Bob Kingfb162bb2020-01-21 11:28:07 +08001386 }
1387 // Invalid: test i2c_compare_bytes with property register more than 2 hex
1388 // digits.
1389 {
1390 json configFile = i2cCompareBytesFile;
1391 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["register"] =
1392 "0x820";
1393 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001394 "'0x820' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob Kingfb162bb2020-01-21 11:28:07 +08001395 }
1396 // Invalid: test i2c_compare_bytes with property values more than 2 hex
1397 // digits.
1398 {
1399 json configFile = i2cCompareBytesFile;
1400 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["values"][0] =
1401 "0x820";
1402 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001403 "'0x820' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob Kingfb162bb2020-01-21 11:28:07 +08001404 }
1405 // Invalid: test i2c_compare_bytes with property masks more than 2 hex
1406 // digits.
1407 {
1408 json configFile = i2cCompareBytesFile;
1409 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["masks"][0] =
1410 "0x820";
1411 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001412 "'0x820' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob Kingfb162bb2020-01-21 11:28:07 +08001413 }
1414 // Invalid: test i2c_compare_bytes with property register less than 2 hex
1415 // digits.
1416 {
1417 json configFile = i2cCompareBytesFile;
1418 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["register"] =
1419 "0x8";
1420 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001421 "'0x8' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob Kingfb162bb2020-01-21 11:28:07 +08001422 }
1423 // Invalid: test i2c_compare_bytes with property values less than 2 hex
1424 // digits.
1425 {
1426 json configFile = i2cCompareBytesFile;
1427 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["values"][0] =
1428 "0x8";
1429 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001430 "'0x8' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob Kingfb162bb2020-01-21 11:28:07 +08001431 }
1432 // Invalid: test i2c_compare_bytes with property masks less than 2 hex
1433 // digits.
1434 {
1435 json configFile = i2cCompareBytesFile;
1436 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["masks"][0] =
1437 "0x8";
1438 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001439 "'0x8' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob Kingfb162bb2020-01-21 11:28:07 +08001440 }
1441 // Invalid: test i2c_compare_bytes with property register no leading prefix.
1442 {
1443 json configFile = i2cCompareBytesFile;
1444 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["register"] =
1445 "82";
1446 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001447 "'82' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob Kingfb162bb2020-01-21 11:28:07 +08001448 }
1449 // Invalid: test i2c_compare_bytes with property values no leading prefix.
1450 {
1451 json configFile = i2cCompareBytesFile;
1452 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["values"][0] =
1453 "82";
1454 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001455 "'82' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob Kingfb162bb2020-01-21 11:28:07 +08001456 }
1457 // Invalid: test i2c_compare_bytes with property masks no leading prefix.
1458 {
1459 json configFile = i2cCompareBytesFile;
1460 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["masks"][0] =
1461 "82";
1462 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001463 "'82' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob Kingfb162bb2020-01-21 11:28:07 +08001464 }
1465 // Invalid: test i2c_compare_bytes with property register invalid hex digit.
1466 {
1467 json configFile = i2cCompareBytesFile;
1468 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["register"] =
1469 "0xG1";
1470 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001471 "'0xG1' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob Kingfb162bb2020-01-21 11:28:07 +08001472 }
1473 // Invalid: test i2c_compare_bytes with property values invalid hex digit.
1474 {
1475 json configFile = i2cCompareBytesFile;
1476 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["values"][0] =
1477 "0xG1";
1478 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001479 "'0xG1' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob Kingfb162bb2020-01-21 11:28:07 +08001480 }
1481 // Invalid: test i2c_compare_bytes with property masks invalid hex digit.
1482 {
1483 json configFile = i2cCompareBytesFile;
1484 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["masks"][0] =
1485 "0xG1";
1486 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001487 "'0xG1' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob Kingfb162bb2020-01-21 11:28:07 +08001488 }
1489}
Bob Kingca93f1f2020-01-31 11:21:16 +08001490TEST(ValidateRegulatorsConfigTest, I2CInterface)
1491{
1492 // Valid: test i2c_interface.
1493 {
1494 json configFile = validConfigFile;
1495 EXPECT_JSON_VALID(configFile);
1496 }
1497 // Invalid: testi2c_interface with no bus.
1498 {
1499 json configFile = validConfigFile;
1500 configFile["chassis"][0]["devices"][0]["i2c_interface"].erase("bus");
1501 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001502 "'bus' is a required property");
Bob Kingca93f1f2020-01-31 11:21:16 +08001503 }
1504 // Invalid: test i2c_interface with no address.
1505 {
1506 json configFile = validConfigFile;
1507 configFile["chassis"][0]["devices"][0]["i2c_interface"].erase(
1508 "address");
1509 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001510 "'address' is a required property");
Bob Kingca93f1f2020-01-31 11:21:16 +08001511 }
1512 // Invalid: test i2c_interface with property bus wrong type.
1513 {
1514 json configFile = validConfigFile;
1515 configFile["chassis"][0]["devices"][0]["i2c_interface"]["bus"] = true;
1516 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001517 "True is not of type 'integer'");
Bob Kingca93f1f2020-01-31 11:21:16 +08001518 }
1519 // Invalid: test i2c_interface with property address wrong
1520 // type.
1521 {
1522 json configFile = validConfigFile;
1523 configFile["chassis"][0]["devices"][0]["i2c_interface"]["address"] =
1524 true;
1525 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001526 "True is not of type 'string'");
Bob Kingca93f1f2020-01-31 11:21:16 +08001527 }
1528 // Invalid: test i2c_interface with property bus less than
1529 // 0.
1530 {
1531 json configFile = validConfigFile;
1532 configFile["chassis"][0]["devices"][0]["i2c_interface"]["bus"] = -1;
1533 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1534 "-1 is less than the minimum of 0");
1535 }
1536 // Invalid: test i2c_interface with property address wrong
1537 // format.
1538 {
1539 json configFile = validConfigFile;
1540 configFile["chassis"][0]["devices"][0]["i2c_interface"]["address"] =
1541 "0x700";
1542 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001543 "'0x700' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob Kingca93f1f2020-01-31 11:21:16 +08001544 }
1545}
Bob King188db7d2020-01-31 13:01:01 +08001546TEST(ValidateRegulatorsConfigTest, I2CWriteBit)
1547{
1548 json i2cWriteBitFile = validConfigFile;
1549 i2cWriteBitFile["rules"][0]["actions"][1]["i2c_write_bit"]["register"] =
1550 "0xA0";
1551 i2cWriteBitFile["rules"][0]["actions"][1]["i2c_write_bit"]["position"] = 3;
1552 i2cWriteBitFile["rules"][0]["actions"][1]["i2c_write_bit"]["value"] = 1;
1553 // Valid: test rule actions i2c_write_bit.
1554 {
1555 json configFile = i2cWriteBitFile;
1556 EXPECT_JSON_VALID(configFile);
1557 }
1558 // Invalid: test i2c_write_bit with no register.
1559 {
1560 json configFile = i2cWriteBitFile;
1561 configFile["rules"][0]["actions"][1]["i2c_write_bit"].erase("register");
1562 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001563 "'register' is a required property");
Bob King188db7d2020-01-31 13:01:01 +08001564 }
1565 // Invalid: test i2c_write_bit with no position.
1566 {
1567 json configFile = i2cWriteBitFile;
1568 configFile["rules"][0]["actions"][1]["i2c_write_bit"].erase("position");
1569 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001570 "'position' is a required property");
Bob King188db7d2020-01-31 13:01:01 +08001571 }
1572 // Invalid: test i2c_write_bit with no value.
1573 {
1574 json configFile = i2cWriteBitFile;
1575 configFile["rules"][0]["actions"][1]["i2c_write_bit"].erase("value");
1576 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001577 "'value' is a required property");
Bob King188db7d2020-01-31 13:01:01 +08001578 }
1579 // Invalid: test i2c_write_bit with register wrong type.
1580 {
1581 json configFile = i2cWriteBitFile;
1582 configFile["rules"][0]["actions"][1]["i2c_write_bit"]["register"] = 1;
1583 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001584 "1 is not of type 'string'");
Bob King188db7d2020-01-31 13:01:01 +08001585 }
1586 // Invalid: test i2c_write_bit with register wrong format.
1587 {
1588 json configFile = i2cWriteBitFile;
1589 configFile["rules"][0]["actions"][1]["i2c_write_bit"]["register"] =
1590 "0xA00";
1591 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001592 "'0xA00' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08001593 }
1594 // Invalid: test i2c_write_bit with position wrong type.
1595 {
1596 json configFile = i2cWriteBitFile;
1597 configFile["rules"][0]["actions"][1]["i2c_write_bit"]["position"] = 3.1;
1598 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001599 "3.1 is not of type 'integer'");
Bob King188db7d2020-01-31 13:01:01 +08001600 }
1601 // Invalid: test i2c_write_bit with position greater than 7.
1602 {
1603 json configFile = i2cWriteBitFile;
1604 configFile["rules"][0]["actions"][1]["i2c_write_bit"]["position"] = 8;
1605 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1606 "8 is greater than the maximum of 7");
1607 }
1608 // Invalid: test i2c_write_bit with position less than 0.
1609 {
1610 json configFile = i2cWriteBitFile;
1611 configFile["rules"][0]["actions"][1]["i2c_write_bit"]["position"] = -1;
1612 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1613 "-1 is less than the minimum of 0");
1614 }
1615 // Invalid: test i2c_write_bit with value wrong type.
1616 {
1617 json configFile = i2cWriteBitFile;
1618 configFile["rules"][0]["actions"][1]["i2c_write_bit"]["value"] = "1";
1619 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001620 "'1' is not of type 'integer'");
Bob King188db7d2020-01-31 13:01:01 +08001621 }
1622 // Invalid: test i2c_write_bit with value greater than 1.
1623 {
1624 json configFile = i2cWriteBitFile;
1625 configFile["rules"][0]["actions"][1]["i2c_write_bit"]["value"] = 2;
1626 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1627 "2 is greater than the maximum of 1");
1628 }
1629 // Invalid: test i2c_write_bit with value less than 0.
1630 {
1631 json configFile = i2cWriteBitFile;
1632 configFile["rules"][0]["actions"][1]["i2c_write_bit"]["value"] = -1;
1633 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1634 "-1 is less than the minimum of 0");
1635 }
1636}
1637TEST(ValidateRegulatorsConfigTest, I2CWriteByte)
1638{
1639 json i2cWriteByteFile = validConfigFile;
1640 i2cWriteByteFile["rules"][0]["actions"][1]["i2c_write_byte"]["register"] =
1641 "0x82";
1642 i2cWriteByteFile["rules"][0]["actions"][1]["i2c_write_byte"]["value"] =
1643 "0x40";
1644 i2cWriteByteFile["rules"][0]["actions"][1]["i2c_write_byte"]["mask"] =
1645 "0x7F";
1646 // Valid: test i2c_write_byte with all properties.
1647 {
1648 json configFile = i2cWriteByteFile;
1649 EXPECT_JSON_VALID(configFile);
1650 }
1651 // Valid: test i2c_write_byte with all required properties.
1652 {
1653 json configFile = i2cWriteByteFile;
1654 configFile["rules"][0]["actions"][1]["i2c_write_byte"].erase("mask");
1655 EXPECT_JSON_VALID(configFile);
1656 }
1657 // Invalid: test i2c_write_byte with no register.
1658 {
1659 json configFile = i2cWriteByteFile;
1660 configFile["rules"][0]["actions"][1]["i2c_write_byte"].erase(
1661 "register");
1662 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001663 "'register' is a required property");
Bob King188db7d2020-01-31 13:01:01 +08001664 }
1665 // Invalid: test i2c_write_byte with no value.
1666 {
1667 json configFile = i2cWriteByteFile;
1668 configFile["rules"][0]["actions"][1]["i2c_write_byte"].erase("value");
1669 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001670 "'value' is a required property");
Bob King188db7d2020-01-31 13:01:01 +08001671 }
1672 // Invalid: test i2c_write_byte with property register wrong type.
1673 {
1674 json configFile = i2cWriteByteFile;
1675 configFile["rules"][0]["actions"][1]["i2c_write_byte"]["register"] = 1;
1676 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001677 "1 is not of type 'string'");
Bob King188db7d2020-01-31 13:01:01 +08001678 }
1679 // Invalid: test i2c_write_byte with property value wrong type.
1680 {
1681 json configFile = i2cWriteByteFile;
1682 configFile["rules"][0]["actions"][1]["i2c_write_byte"]["value"] = 1;
1683 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001684 "1 is not of type 'string'");
Bob King188db7d2020-01-31 13:01:01 +08001685 }
1686 // Invalid: test i2c_write_byte with property mask wrong type.
1687 {
1688 json configFile = i2cWriteByteFile;
1689 configFile["rules"][0]["actions"][1]["i2c_write_byte"]["mask"] = 1;
1690 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001691 "1 is not of type 'string'");
Bob King188db7d2020-01-31 13:01:01 +08001692 }
1693 // Invalid: test i2c_write_byte with property register more than 2 hex
1694 // digits.
1695 {
1696 json configFile = i2cWriteByteFile;
1697 configFile["rules"][0]["actions"][1]["i2c_write_byte"]["register"] =
1698 "0x820";
1699 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001700 "'0x820' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08001701 }
1702 // Invalid: test i2c_write_byte with property value more than 2 hex
1703 // digits.
1704 {
1705 json configFile = i2cWriteByteFile;
1706 configFile["rules"][0]["actions"][1]["i2c_write_byte"]["value"] =
1707 "0x820";
1708 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001709 "'0x820' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08001710 }
1711 // Invalid: test i2c_write_byte with property mask more than 2 hex digits.
1712 {
1713 json configFile = i2cWriteByteFile;
1714 configFile["rules"][0]["actions"][1]["i2c_write_byte"]["mask"] =
1715 "0x820";
1716 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001717 "'0x820' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08001718 }
1719 // Invalid: test i2c_write_byte with property register less than 2 hex
1720 // digits.
1721 {
1722 json configFile = i2cWriteByteFile;
1723 configFile["rules"][0]["actions"][1]["i2c_write_byte"]["register"] =
1724 "0x8";
1725 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001726 "'0x8' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08001727 }
1728 // Invalid: test i2c_write_byte with property value less than 2 hex
1729 // digits.
1730 {
1731 json configFile = i2cWriteByteFile;
1732 configFile["rules"][0]["actions"][1]["i2c_write_byte"]["value"] = "0x8";
1733 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001734 "'0x8' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08001735 }
1736 // Invalid: test i2c_write_byte with property mask less than 2 hex digits.
1737 {
1738 json configFile = i2cWriteByteFile;
1739 configFile["rules"][0]["actions"][1]["i2c_write_byte"]["mask"] = "0x8";
1740 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001741 "'0x8' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08001742 }
1743 // Invalid: test i2c_write_byte with property register no leading prefix.
1744 {
1745 json configFile = i2cWriteByteFile;
1746 configFile["rules"][0]["actions"][1]["i2c_write_byte"]["register"] =
1747 "82";
1748 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001749 "'82' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08001750 }
1751 // Invalid: test i2c_write_byte with property value no leading prefix.
1752 {
1753 json configFile = i2cWriteByteFile;
1754 configFile["rules"][0]["actions"][1]["i2c_write_byte"]["value"] = "82";
1755 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001756 "'82' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08001757 }
1758 // Invalid: test i2c_write_byte with property mask no leading prefix.
1759 {
1760 json configFile = i2cWriteByteFile;
1761 configFile["rules"][0]["actions"][1]["i2c_write_byte"]["mask"] = "82";
1762 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001763 "'82' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08001764 }
1765 // Invalid: test i2c_write_byte with property register invalid hex digit.
1766 {
1767 json configFile = i2cWriteByteFile;
1768 configFile["rules"][0]["actions"][1]["i2c_write_byte"]["register"] =
1769 "0xG1";
1770 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001771 "'0xG1' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08001772 }
1773 // Invalid: test i2c_write_byte with property value invalid hex digit.
1774 {
1775 json configFile = i2cWriteByteFile;
1776 configFile["rules"][0]["actions"][1]["i2c_write_byte"]["value"] =
1777 "0xG1";
1778 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001779 "'0xG1' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08001780 }
1781 // Invalid: test i2c_write_byte with property mask invalid hex digit.
1782 {
1783 json configFile = i2cWriteByteFile;
1784 configFile["rules"][0]["actions"][1]["i2c_write_byte"]["mask"] = "0xG1";
1785 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001786 "'0xG1' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08001787 }
1788}
1789TEST(ValidateRegulatorsConfigTest, I2CWriteBytes)
1790{
1791 json i2cWriteBytesFile = validConfigFile;
1792 i2cWriteBytesFile["rules"][0]["actions"][1]["i2c_write_bytes"]["register"] =
1793 "0x82";
1794 i2cWriteBytesFile["rules"][0]["actions"][1]["i2c_write_bytes"]["values"] = {
1795 "0x02", "0x73"};
1796 i2cWriteBytesFile["rules"][0]["actions"][1]["i2c_write_bytes"]["masks"] = {
1797 "0x7F", "0x7F"};
1798 // Valid: test i2c_write_bytes.
1799 {
1800 json configFile = i2cWriteBytesFile;
1801 EXPECT_JSON_VALID(configFile);
1802 }
1803 // Valid: test i2c_write_bytes with all required properties.
1804 {
1805 json configFile = i2cWriteBytesFile;
1806 configFile["rules"][0]["actions"][1]["i2c_write_bytes"].erase("masks");
1807 EXPECT_JSON_VALID(configFile);
1808 }
1809 // Invalid: test i2c_write_bytes with no register.
1810 {
1811 json configFile = i2cWriteBytesFile;
1812 configFile["rules"][0]["actions"][1]["i2c_write_bytes"].erase(
1813 "register");
1814 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001815 "'register' is a required property");
Bob King188db7d2020-01-31 13:01:01 +08001816 }
1817 // Invalid: test i2c_write_bytes with no values.
1818 {
1819 json configFile = i2cWriteBytesFile;
1820 configFile["rules"][0]["actions"][1]["i2c_write_bytes"].erase("values");
1821 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001822 "'values' is a required property");
Bob King188db7d2020-01-31 13:01:01 +08001823 }
1824 // Invalid: test i2c_write_bytes with property values as empty array.
1825 {
1826 json configFile = i2cWriteBytesFile;
1827 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["values"] =
1828 json::array();
1829 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1830 "[] is too short");
1831 }
1832 // Invalid: test i2c_write_bytes with property masks as empty array.
1833 {
1834 json configFile = i2cWriteBytesFile;
1835 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["masks"] =
1836 json::array();
1837 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1838 "[] is too short");
1839 }
1840 // Invalid: test i2c_write_bytes with property register wrong type.
1841 {
1842 json configFile = i2cWriteBytesFile;
1843 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["register"] = 1;
1844 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001845 "1 is not of type 'string'");
Bob King188db7d2020-01-31 13:01:01 +08001846 }
1847 // Invalid: test i2c_write_bytes with property values wrong type.
1848 {
1849 json configFile = i2cWriteBytesFile;
1850 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["values"] = 1;
1851 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001852 "1 is not of type 'array'");
Bob King188db7d2020-01-31 13:01:01 +08001853 }
1854 // Invalid: test i2c_write_bytes with property masks wrong type.
1855 {
1856 json configFile = i2cWriteBytesFile;
1857 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["masks"] = 1;
1858 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001859 "1 is not of type 'array'");
Bob King188db7d2020-01-31 13:01:01 +08001860 }
1861 // Invalid: test i2c_write_bytes with property register more than 2 hex
1862 // digits.
1863 {
1864 json configFile = i2cWriteBytesFile;
1865 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["register"] =
1866 "0x820";
1867 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001868 "'0x820' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08001869 }
1870 // Invalid: test i2c_write_bytes with property values more than 2 hex
1871 // digits.
1872 {
1873 json configFile = i2cWriteBytesFile;
1874 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["values"][0] =
1875 "0x820";
1876 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001877 "'0x820' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08001878 }
1879 // Invalid: test i2c_write_bytes with property masks more than 2 hex
1880 // digits.
1881 {
1882 json configFile = i2cWriteBytesFile;
1883 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["masks"][0] =
1884 "0x820";
1885 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001886 "'0x820' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08001887 }
1888 // Invalid: test i2c_write_bytes with property register less than 2 hex
1889 // digits.
1890 {
1891 json configFile = i2cWriteBytesFile;
1892 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["register"] =
1893 "0x8";
1894 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001895 "'0x8' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08001896 }
1897 // Invalid: test i2c_write_bytes with property values less than 2 hex
1898 // digits.
1899 {
1900 json configFile = i2cWriteBytesFile;
1901 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["values"][0] =
1902 "0x8";
1903 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001904 "'0x8' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08001905 }
1906 // Invalid: test i2c_write_bytes with property masks less than 2 hex
1907 // digits.
1908 {
1909 json configFile = i2cWriteBytesFile;
1910 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["masks"][0] =
1911 "0x8";
1912 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001913 "'0x8' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08001914 }
1915 // Invalid: test i2c_write_bytes with property register no leading prefix.
1916 {
1917 json configFile = i2cWriteBytesFile;
1918 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["register"] =
1919 "82";
1920 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001921 "'82' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08001922 }
1923 // Invalid: test i2c_write_bytes with property values no leading prefix.
1924 {
1925 json configFile = i2cWriteBytesFile;
1926 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["values"][0] =
1927 "82";
1928 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001929 "'82' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08001930 }
1931 // Invalid: test i2c_write_bytes with property masks no leading prefix.
1932 {
1933 json configFile = i2cWriteBytesFile;
1934 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["masks"][0] =
1935 "82";
1936 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001937 "'82' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08001938 }
1939 // Invalid: test i2c_write_bytes with property register invalid hex digit.
1940 {
1941 json configFile = i2cWriteBytesFile;
1942 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["register"] =
1943 "0xG1";
1944 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001945 "'0xG1' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08001946 }
1947 // Invalid: test i2c_write_bytes with property values invalid hex digit.
1948 {
1949 json configFile = i2cWriteBytesFile;
1950 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["values"][0] =
1951 "0xG1";
1952 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001953 "'0xG1' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08001954 }
1955 // Invalid: test i2c_write_bytes with property masks invalid hex digit.
1956 {
1957 json configFile = i2cWriteBytesFile;
1958 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["masks"][0] =
1959 "0xG1";
1960 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001961 "'0xG1' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08001962 }
1963}
Bob Kingead0b052020-01-21 11:29:03 +08001964TEST(ValidateRegulatorsConfigTest, If)
1965{
1966 json ifFile = validConfigFile;
Bob King2d27dcf2020-02-11 15:00:50 +08001967 ifFile["rules"][2]["actions"][0]["if"]["condition"]["run_rule"] =
1968 "set_voltage_rule";
1969 ifFile["rules"][2]["actions"][0]["if"]["then"][0]["run_rule"] =
1970 "read_sensors_rule";
1971 ifFile["rules"][2]["actions"][0]["if"]["else"][0]["run_rule"] =
1972 "read_sensors_rule";
1973 ifFile["rules"][2]["id"] = "rule_if";
Bob Kingead0b052020-01-21 11:29:03 +08001974 // Valid: test if.
1975 {
1976 json configFile = ifFile;
1977 EXPECT_JSON_VALID(configFile);
1978 }
1979 // Valid: test if with required properties.
1980 {
1981 json configFile = ifFile;
Bob King2d27dcf2020-02-11 15:00:50 +08001982 configFile["rules"][2]["actions"][0]["if"].erase("else");
Bob Kingead0b052020-01-21 11:29:03 +08001983 EXPECT_JSON_VALID(configFile);
1984 }
1985 // Invalid: test if with no property condition.
1986 {
1987 json configFile = ifFile;
Bob King2d27dcf2020-02-11 15:00:50 +08001988 configFile["rules"][2]["actions"][0]["if"].erase("condition");
Bob Kingead0b052020-01-21 11:29:03 +08001989 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001990 "'condition' is a required property");
Bob Kingead0b052020-01-21 11:29:03 +08001991 }
1992 // Invalid: test if with no property then.
1993 {
1994 json configFile = ifFile;
Bob King2d27dcf2020-02-11 15:00:50 +08001995 configFile["rules"][2]["actions"][0]["if"].erase("then");
Bob Kingead0b052020-01-21 11:29:03 +08001996 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001997 "'then' is a required property");
Bob Kingead0b052020-01-21 11:29:03 +08001998 }
1999 // Invalid: test if with property then empty array.
2000 {
2001 json configFile = ifFile;
Bob King2d27dcf2020-02-11 15:00:50 +08002002 configFile["rules"][2]["actions"][0]["if"]["then"] = json::array();
Bob Kingead0b052020-01-21 11:29:03 +08002003 EXPECT_JSON_INVALID(configFile, "Validation failed.",
2004 "[] is too short");
2005 }
2006 // Invalid: test if with property else empty array.
2007 {
2008 json configFile = ifFile;
Bob King2d27dcf2020-02-11 15:00:50 +08002009 configFile["rules"][2]["actions"][0]["if"]["else"] = json::array();
Bob Kingead0b052020-01-21 11:29:03 +08002010 EXPECT_JSON_INVALID(configFile, "Validation failed.",
2011 "[] is too short");
2012 }
2013 // Invalid: test if with property condition wrong type.
2014 {
2015 json configFile = ifFile;
Bob King2d27dcf2020-02-11 15:00:50 +08002016 configFile["rules"][2]["actions"][0]["if"]["condition"] = 1;
Bob Kingead0b052020-01-21 11:29:03 +08002017 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002018 "1 is not of type 'object'");
Bob Kingead0b052020-01-21 11:29:03 +08002019 }
2020 // Invalid: test if with property then wrong type.
2021 {
2022 json configFile = ifFile;
Bob King2d27dcf2020-02-11 15:00:50 +08002023 configFile["rules"][2]["actions"][0]["if"]["then"] = 1;
Bob Kingead0b052020-01-21 11:29:03 +08002024 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002025 "1 is not of type 'array'");
Bob Kingead0b052020-01-21 11:29:03 +08002026 }
2027 // Invalid: test if with property else wrong type.
2028 {
2029 json configFile = ifFile;
Bob King2d27dcf2020-02-11 15:00:50 +08002030 configFile["rules"][2]["actions"][0]["if"]["else"] = 1;
Bob Kingead0b052020-01-21 11:29:03 +08002031 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002032 "1 is not of type 'array'");
Bob Kingead0b052020-01-21 11:29:03 +08002033 }
2034}
Bob Kingbfe9fe72020-01-21 11:29:57 +08002035TEST(ValidateRegulatorsConfigTest, Not)
2036{
2037 json notFile = validConfigFile;
2038 notFile["rules"][0]["actions"][1]["not"]["i2c_compare_byte"]["register"] =
2039 "0xA0";
2040 notFile["rules"][0]["actions"][1]["not"]["i2c_compare_byte"]["value"] =
2041 "0xFF";
2042 // Valid: test not.
2043 {
2044 json configFile = notFile;
2045 EXPECT_JSON_VALID(configFile);
2046 }
2047 // Invalid: test not with wrong type.
2048 {
2049 json configFile = notFile;
2050 configFile["rules"][0]["actions"][1]["not"] = 1;
2051 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002052 "1 is not of type 'object'");
Bob Kingbfe9fe72020-01-21 11:29:57 +08002053 }
2054}
Bob Kingcfc29d02020-01-21 11:30:50 +08002055TEST(ValidateRegulatorsConfigTest, Or)
2056{
2057 json orFile = validConfigFile;
2058 orFile["rules"][0]["actions"][1]["or"][0]["i2c_compare_byte"]["register"] =
2059 "0xA0";
2060 orFile["rules"][0]["actions"][1]["or"][0]["i2c_compare_byte"]["value"] =
2061 "0x00";
2062 orFile["rules"][0]["actions"][1]["or"][1]["i2c_compare_byte"]["register"] =
2063 "0xA1";
2064 orFile["rules"][0]["actions"][1]["or"][1]["i2c_compare_byte"]["value"] =
2065 "0x00";
2066 // Valid: test or.
2067 {
2068 json configFile = orFile;
2069 EXPECT_JSON_VALID(configFile);
2070 }
2071 // Invalid: test or with empty array.
2072 {
2073 json configFile = orFile;
2074 configFile["rules"][0]["actions"][1]["or"] = json::array();
2075 EXPECT_JSON_INVALID(configFile, "Validation failed.",
2076 "[] is too short");
2077 }
2078 // Invalid: test or with wrong type.
2079 {
2080 json configFile = orFile;
2081 configFile["rules"][0]["actions"][1]["or"] = 1;
2082 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002083 "1 is not of type 'array'");
Bob Kingcfc29d02020-01-21 11:30:50 +08002084 }
2085}
Bob Kingd6618092020-01-21 11:31:46 +08002086TEST(ValidateRegulatorsConfigTest, PmbusReadSensor)
2087{
2088 json pmbusReadSensorFile = validConfigFile;
2089 pmbusReadSensorFile["rules"][0]["actions"][1]["pmbus_read_sensor"]["type"] =
2090 "vout";
2091 pmbusReadSensorFile["rules"][0]["actions"][1]["pmbus_read_sensor"]
2092 ["command"] = "0x8B";
2093 pmbusReadSensorFile["rules"][0]["actions"][1]["pmbus_read_sensor"]
2094 ["format"] = "linear_16";
2095 pmbusReadSensorFile["rules"][0]["actions"][1]["pmbus_read_sensor"]
2096 ["exponent"] = -8;
2097 // Valid: test pmbus_read_sensor.
2098 {
2099 json configFile = pmbusReadSensorFile;
2100 EXPECT_JSON_VALID(configFile);
2101 }
2102 // Valid: test pmbus_read_sensor with required properties.
2103 {
2104 json configFile = pmbusReadSensorFile;
2105 configFile["rules"][0]["actions"][1]["pmbus_read_sensor"].erase(
2106 "exponent");
2107 EXPECT_JSON_VALID(configFile);
2108 }
2109 // Invalid: test pmbus_read_sensor with no type.
2110 {
2111 json configFile = pmbusReadSensorFile;
2112 configFile["rules"][0]["actions"][1]["pmbus_read_sensor"].erase("type");
2113 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002114 "'type' is a required property");
Bob Kingd6618092020-01-21 11:31:46 +08002115 }
2116 // Invalid: test pmbus_read_sensor with no command.
2117 {
2118 json configFile = pmbusReadSensorFile;
2119 configFile["rules"][0]["actions"][1]["pmbus_read_sensor"].erase(
2120 "command");
2121 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002122 "'command' is a required property");
Bob Kingd6618092020-01-21 11:31:46 +08002123 }
2124 // Invalid: test pmbus_read_sensor with no format.
2125 {
2126 json configFile = pmbusReadSensorFile;
2127 configFile["rules"][0]["actions"][1]["pmbus_read_sensor"].erase(
2128 "format");
2129 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002130 "'format' is a required property");
Bob Kingd6618092020-01-21 11:31:46 +08002131 }
2132 // Invalid: test pmbus_read_sensor with property type wrong type.
2133 {
2134 json configFile = pmbusReadSensorFile;
2135 configFile["rules"][0]["actions"][1]["pmbus_read_sensor"]["type"] =
2136 true;
Bob King358c4172020-03-16 13:57:08 +08002137 EXPECT_JSON_INVALID(configFile, "Validation failed.",
2138 "True is not of type 'string'");
Bob Kingd6618092020-01-21 11:31:46 +08002139 }
2140 // Invalid: test pmbus_read_sensor with property command wrong type.
2141 {
2142 json configFile = pmbusReadSensorFile;
2143 configFile["rules"][0]["actions"][1]["pmbus_read_sensor"]["command"] =
2144 true;
2145 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002146 "True is not of type 'string'");
Bob Kingd6618092020-01-21 11:31:46 +08002147 }
2148 // Invalid: test pmbus_read_sensor with property format wrong type.
2149 {
2150 json configFile = pmbusReadSensorFile;
2151 configFile["rules"][0]["actions"][1]["pmbus_read_sensor"]["format"] =
2152 true;
2153 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002154 "True is not of type 'string'");
Bob Kingd6618092020-01-21 11:31:46 +08002155 }
2156 // Invalid: test pmbus_read_sensor with property exponent wrong type.
2157 {
2158 json configFile = pmbusReadSensorFile;
2159 configFile["rules"][0]["actions"][1]["pmbus_read_sensor"]["exponent"] =
2160 true;
2161 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002162 "True is not of type 'integer'");
Bob Kingd6618092020-01-21 11:31:46 +08002163 }
2164 // Invalid: test pmbus_read_sensor with property type wrong format.
2165 {
2166 json configFile = pmbusReadSensorFile;
2167 configFile["rules"][0]["actions"][1]["pmbus_read_sensor"]["type"] =
2168 "foo";
2169 EXPECT_JSON_INVALID(
2170 configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002171 "'foo' is not one of ['iout', 'iout_peak', 'iout_valley', "
2172 "'pout', 'temperature', 'temperature_peak', 'vout', "
2173 "'vout_peak', 'vout_valley']");
Bob Kingd6618092020-01-21 11:31:46 +08002174 }
2175 // Invalid: test pmbus_read_sensor with property command wrong format.
2176 {
2177 json configFile = pmbusReadSensorFile;
2178 configFile["rules"][0]["actions"][1]["pmbus_read_sensor"]["command"] =
2179 "0x8B0";
2180 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002181 "'0x8B0' does not match '^0x[0-9a-fA-F]{2}$'");
Bob Kingd6618092020-01-21 11:31:46 +08002182 }
2183 // Invalid: test pmbus_read_sensor with property format wrong format.
2184 {
2185 json configFile = pmbusReadSensorFile;
2186 configFile["rules"][0]["actions"][1]["pmbus_read_sensor"]["format"] =
2187 "foo";
Bob King358c4172020-03-16 13:57:08 +08002188 EXPECT_JSON_INVALID(configFile, "Validation failed.",
2189 "'foo' is not one of ['linear_11', 'linear_16']");
Bob Kingd6618092020-01-21 11:31:46 +08002190 }
2191}
Bob King02179c62020-01-21 11:32:36 +08002192TEST(ValidateRegulatorsConfigTest, PmbusWriteVoutCommand)
2193{
2194 json pmbusWriteVoutCommandFile = validConfigFile;
2195 pmbusWriteVoutCommandFile["rules"][0]["actions"][1]
2196 ["pmbus_write_vout_command"]["volts"] = 1.03;
2197 pmbusWriteVoutCommandFile["rules"][0]["actions"][1]
2198 ["pmbus_write_vout_command"]["format"] = "linear";
2199 pmbusWriteVoutCommandFile["rules"][0]["actions"][1]
2200 ["pmbus_write_vout_command"]["exponent"] = -8;
2201 pmbusWriteVoutCommandFile["rules"][0]["actions"][1]
2202 ["pmbus_write_vout_command"]["is_verified"] = true;
2203 // Valid: test pmbus_write_vout_command.
2204 {
2205 json configFile = pmbusWriteVoutCommandFile;
2206 EXPECT_JSON_VALID(configFile);
2207 }
2208 // Valid: test pmbus_write_vout_command with required properties.
2209 {
2210 json configFile = pmbusWriteVoutCommandFile;
2211 configFile["rules"][0]["actions"][1]["pmbus_write_vout_command"].erase(
2212 "volts");
2213 configFile["rules"][0]["actions"][1]["pmbus_write_vout_command"].erase(
2214 "exponent");
2215 configFile["rules"][0]["actions"][1]["pmbus_write_vout_command"].erase(
2216 "is_verified");
2217 EXPECT_JSON_VALID(configFile);
2218 }
2219 // Invalid: test pmbus_write_vout_command with no format.
2220 {
2221 json configFile = pmbusWriteVoutCommandFile;
2222 configFile["rules"][0]["actions"][1]["pmbus_write_vout_command"].erase(
2223 "format");
2224 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002225 "'format' is a required property");
Bob King02179c62020-01-21 11:32:36 +08002226 }
2227 // Invalid: test pmbus_write_vout_command with property volts wrong type.
2228 {
2229 json configFile = pmbusWriteVoutCommandFile;
2230 configFile["rules"][0]["actions"][1]["pmbus_write_vout_command"]
2231 ["volts"] = true;
2232 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002233 "True is not of type 'number'");
Bob King02179c62020-01-21 11:32:36 +08002234 }
2235 // Invalid: test pmbus_write_vout_command with property format wrong type.
2236 {
2237 json configFile = pmbusWriteVoutCommandFile;
2238 configFile["rules"][0]["actions"][1]["pmbus_write_vout_command"]
2239 ["format"] = true;
2240 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002241 "True is not of type 'string'");
Bob King02179c62020-01-21 11:32:36 +08002242 }
2243 // Invalid: test pmbus_write_vout_command with property exponent wrong type.
2244 {
2245 json configFile = pmbusWriteVoutCommandFile;
2246 configFile["rules"][0]["actions"][1]["pmbus_write_vout_command"]
2247 ["exponent"] = 1.3;
2248 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002249 "1.3 is not of type 'integer'");
Bob King02179c62020-01-21 11:32:36 +08002250 }
2251 // Invalid: test pmbus_write_vout_command with property is_verified wrong
2252 // type.
2253 {
2254 json configFile = pmbusWriteVoutCommandFile;
2255 configFile["rules"][0]["actions"][1]["pmbus_write_vout_command"]
2256 ["is_verified"] = 1;
2257 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002258 "1 is not of type 'boolean'");
Bob King02179c62020-01-21 11:32:36 +08002259 }
2260 // Invalid: test pmbus_write_vout_command with property format wrong format.
2261 {
2262 json configFile = pmbusWriteVoutCommandFile;
2263 configFile["rules"][0]["actions"][1]["pmbus_write_vout_command"]
2264 ["format"] = "foo";
2265 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002266 "'foo' is not one of ['linear']");
Bob King02179c62020-01-21 11:32:36 +08002267 }
2268}
Bob King99d8fa12020-01-31 11:23:40 +08002269TEST(ValidateRegulatorsConfigTest, PresenceDetection)
2270{
2271 json presenceDetectionFile = validConfigFile;
2272 presenceDetectionFile
2273 ["chassis"][0]["devices"][0]["presence_detection"]["comments"][0] =
2274 "Regulator is only present on the FooBar backplane";
2275 presenceDetectionFile["chassis"][0]["devices"][0]["presence_detection"]
Bob Kingf4ff1162020-02-11 15:13:38 +08002276 ["rule_id"] = "set_voltage_rule";
Bob King99d8fa12020-01-31 11:23:40 +08002277 // Valid: test presence_detection with only property rule_id.
2278 {
2279 json configFile = presenceDetectionFile;
2280 EXPECT_JSON_VALID(configFile);
2281 }
2282 // Valid: test presence_detection with only property actions.
2283 {
2284 json configFile = presenceDetectionFile;
2285 configFile["chassis"][0]["devices"][0]["presence_detection"].erase(
2286 "rule_id");
2287 configFile["chassis"][0]["devices"][0]["presence_detection"]["actions"]
2288 [0]["compare_presence"]["fru"] =
2289 "/system/chassis/motherboard/cpu3";
2290 configFile["chassis"][0]["devices"][0]["presence_detection"]["actions"]
2291 [0]["compare_presence"]["value"] = true;
2292 configFile["chassis"][0]["devices"][0]["presence_detection"].erase(
2293 "comments");
2294 EXPECT_JSON_VALID(configFile);
2295 }
2296 // Invalid: test presence_detection with both property rule_id and actions.
2297 {
2298 json configFile = presenceDetectionFile;
2299 configFile["chassis"][0]["devices"][0]["presence_detection"]["actions"]
2300 [0]["compare_presence"]["fru"] =
2301 "/system/chassis/motherboard/cpu3";
2302 configFile["chassis"][0]["devices"][0]["presence_detection"]["actions"]
2303 [0]["compare_presence"]["value"] = true;
2304 EXPECT_JSON_INVALID(
2305 configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002306 "{'actions': [{'compare_presence': {'fru': "
2307 "'/system/chassis/motherboard/cpu3', 'value': True}}], 'comments': "
2308 "['Regulator is only present on the FooBar backplane'], 'rule_id': "
2309 "'set_voltage_rule'} is valid under each of {'required': "
2310 "['actions']}, {'required': ['rule_id']}");
Bob King99d8fa12020-01-31 11:23:40 +08002311 }
2312 // Invalid: test presence_detection with no rule_id and actions.
2313 {
2314 json configFile = presenceDetectionFile;
2315 configFile["chassis"][0]["devices"][0]["presence_detection"].erase(
2316 "rule_id");
2317 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002318 "'rule_id' is a required property");
Bob King99d8fa12020-01-31 11:23:40 +08002319 }
2320 // Invalid: test presence_detection with property comments wrong type.
2321 {
2322 json configFile = presenceDetectionFile;
2323 configFile["chassis"][0]["devices"][0]["presence_detection"]
2324 ["comments"] = true;
2325 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002326 "True is not of type 'array'");
Bob King99d8fa12020-01-31 11:23:40 +08002327 }
2328 // Invalid: test presence_detection with property rule_id wrong type.
2329 {
2330 json configFile = presenceDetectionFile;
2331 configFile["chassis"][0]["devices"][0]["presence_detection"]
2332 ["rule_id"] = true;
2333 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002334 "True is not of type 'string'");
Bob King99d8fa12020-01-31 11:23:40 +08002335 }
2336 // Invalid: test presence_detection with property actions wrong type.
2337 {
2338 json configFile = presenceDetectionFile;
2339 configFile["chassis"][0]["devices"][0]["presence_detection"].erase(
2340 "rule_id");
2341 configFile["chassis"][0]["devices"][0]["presence_detection"]
2342 ["actions"] = true;
2343 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002344 "True is not of type 'array'");
Bob King99d8fa12020-01-31 11:23:40 +08002345 }
2346 // Invalid: test presence_detection with property rule_id wrong format.
2347 {
2348 json configFile = presenceDetectionFile;
2349 configFile["chassis"][0]["devices"][0]["presence_detection"]
2350 ["rule_id"] = "id@";
2351 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002352 "'id@' does not match '^[A-Za-z0-9_]+$'");
Bob King99d8fa12020-01-31 11:23:40 +08002353 }
2354 // Invalid: test presence_detection with property comments empty array.
2355 {
2356 json configFile = presenceDetectionFile;
2357 configFile["chassis"][0]["devices"][0]["presence_detection"]
2358 ["comments"] = json::array();
2359 EXPECT_JSON_INVALID(configFile, "Validation failed.",
2360 "[] is too short");
2361 }
2362 // Invalid: test presence_detection with property actions empty array.
2363 {
2364 json configFile = presenceDetectionFile;
2365 configFile["chassis"][0]["devices"][0]["presence_detection"].erase(
2366 "rule_id");
2367 configFile["chassis"][0]["devices"][0]["presence_detection"]
2368 ["actions"] = json::array();
2369 EXPECT_JSON_INVALID(configFile, "Validation failed.",
2370 "[] is too short");
2371 }
2372}
Bob Kinge9260b52020-01-21 11:46:13 +08002373TEST(ValidateRegulatorsConfigTest, Rail)
2374{
2375 // Valid: test rail.
2376 {
2377 json configFile = validConfigFile;
2378 EXPECT_JSON_VALID(configFile);
2379 }
2380 // Valid: test rail with required properties.
2381 {
2382 json configFile = validConfigFile;
2383 configFile["chassis"][0]["devices"][0]["rails"][0].erase("comments");
2384 configFile["chassis"][0]["devices"][0]["rails"][0].erase(
2385 "configuration");
2386 configFile["chassis"][0]["devices"][0]["rails"][0].erase(
2387 "sensor_monitoring");
2388 EXPECT_JSON_VALID(configFile);
2389 }
2390 // Invalid: test rail with no id.
2391 {
2392 json configFile = validConfigFile;
2393 configFile["chassis"][0]["devices"][0]["rails"][0].erase("id");
2394 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002395 "'id' is a required property");
Bob Kinge9260b52020-01-21 11:46:13 +08002396 }
2397 // Invalid: test rail with comments wrong type.
2398 {
2399 json configFile = validConfigFile;
2400 configFile["chassis"][0]["devices"][0]["rails"][0]["comments"] = true;
2401 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002402 "True is not of type 'array'");
Bob Kinge9260b52020-01-21 11:46:13 +08002403 }
2404 // Invalid: test rail with id wrong type.
2405 {
2406 json configFile = validConfigFile;
2407 configFile["chassis"][0]["devices"][0]["rails"][0]["id"] = true;
2408 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002409 "True is not of type 'string'");
Bob Kinge9260b52020-01-21 11:46:13 +08002410 }
2411 // Invalid: test rail with configuration wrong type.
2412 {
2413 json configFile = validConfigFile;
2414 configFile["chassis"][0]["devices"][0]["rails"][0]["configuration"] =
2415 true;
2416 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002417 "True is not of type 'object'");
Bob Kinge9260b52020-01-21 11:46:13 +08002418 }
2419 // Invalid: test rail with sensor_monitoring wrong type.
2420 {
2421 json configFile = validConfigFile;
2422 configFile["chassis"][0]["devices"][0]["rails"][0]
2423 ["sensor_monitoring"] = true;
2424 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002425 "True is not of type 'object'");
Bob Kinge9260b52020-01-21 11:46:13 +08002426 }
2427 // Invalid: test rail with comments empty array.
2428 {
2429 json configFile = validConfigFile;
2430 configFile["chassis"][0]["devices"][0]["rails"][0]["comments"] =
2431 json::array();
2432 EXPECT_JSON_INVALID(configFile, "Validation failed.",
2433 "[] is too short");
2434 }
2435 // Invalid: test rail with id wrong format.
2436 {
2437 json configFile = validConfigFile;
2438 configFile["chassis"][0]["devices"][0]["rails"][0]["id"] = "id~";
2439 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002440 "'id~' does not match '^[A-Za-z0-9_]+$'");
Bob Kinge9260b52020-01-21 11:46:13 +08002441 }
2442}
Bob King64df7da2020-01-31 12:04:12 +08002443TEST(ValidateRegulatorsConfigTest, Rule)
2444{
2445 // valid test comments property, id property,
2446 // action property specified.
2447 {
2448 json configFile = validConfigFile;
2449 EXPECT_JSON_VALID(configFile);
2450 }
2451
2452 // valid test rule with no comments
2453 {
2454 json configFile = validConfigFile;
2455 configFile["rules"][0].erase("comments");
2456 EXPECT_JSON_VALID(configFile);
2457 }
2458
2459 // invalid test comments property has invalid value type
2460 {
2461 json configFile = validConfigFile;
2462 configFile["rules"][0]["comments"] = {1};
2463 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002464 "1 is not of type 'string'");
Bob King64df7da2020-01-31 12:04:12 +08002465 }
2466
2467 // invalid test rule with no ID
2468 {
2469 json configFile = validConfigFile;
2470 configFile["rules"][0].erase("id");
2471 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002472 "'id' is a required property");
Bob King64df7da2020-01-31 12:04:12 +08002473 }
2474
2475 // invalid test id property has invalid value type (not string)
2476 {
2477 json configFile = validConfigFile;
2478 configFile["rules"][0]["id"] = true;
2479 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002480 "True is not of type 'string'");
Bob King64df7da2020-01-31 12:04:12 +08002481 }
2482
2483 // invalid test id property has invalid value
2484 {
2485 json configFile = validConfigFile;
2486 configFile["rules"][0]["id"] = "foo%";
2487 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002488 "'foo%' does not match '^[A-Za-z0-9_]+$'");
Bob King64df7da2020-01-31 12:04:12 +08002489 }
2490
2491 // invalid test rule with no actions property
2492 {
2493 json configFile = validConfigFile;
2494 configFile["rules"][0].erase("actions");
2495 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002496 "'actions' is a required property");
Bob King64df7da2020-01-31 12:04:12 +08002497 }
2498
2499 // valid test rule with multiple actions
2500 {
2501 json configFile = validConfigFile;
Bob King63d795f2020-02-11 15:22:09 +08002502 configFile["rules"][0]["actions"][1]["run_rule"] = "read_sensors_rule";
Bob King64df7da2020-01-31 12:04:12 +08002503 EXPECT_JSON_VALID(configFile);
2504 }
2505
2506 // invalid test actions property has invalid value type (not an array)
2507 {
2508 json configFile = validConfigFile;
2509 configFile["rules"][0]["actions"] = 1;
2510 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002511 "1 is not of type 'array'");
Bob King64df7da2020-01-31 12:04:12 +08002512 }
2513
2514 // invalid test actions property has invalid value of action
2515 {
2516 json configFile = validConfigFile;
2517 configFile["rules"][0]["actions"][0] = "foo";
2518 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002519 "'foo' is not of type 'object'");
Bob King64df7da2020-01-31 12:04:12 +08002520 }
2521
2522 // invalid test actions property has empty array
2523 {
2524 json configFile = validConfigFile;
2525 configFile["rules"][0]["actions"] = json::array();
2526 EXPECT_JSON_INVALID(configFile, "Validation failed.",
2527 "[] is too short");
2528 }
2529}
Bob Kinge86c2e52020-01-21 11:33:32 +08002530TEST(ValidateRegulatorsConfigTest, RunRule)
2531{
2532 json runRuleFile = validConfigFile;
Bob King7d3a9f12020-02-11 15:34:52 +08002533 runRuleFile["rules"][0]["actions"][1]["run_rule"] = "read_sensors_rule";
Bob Kinge86c2e52020-01-21 11:33:32 +08002534 // Valid: test run_rule.
2535 {
2536 json configFile = runRuleFile;
2537 EXPECT_JSON_VALID(configFile);
2538 }
2539 // Invalid: test run_rule wrong type.
2540 {
2541 json configFile = runRuleFile;
2542 configFile["rules"][0]["actions"][1]["run_rule"] = true;
2543 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002544 "True is not of type 'string'");
Bob Kinge86c2e52020-01-21 11:33:32 +08002545 }
2546 // Invalid: test run_rule wrong format.
2547 {
2548 json configFile = runRuleFile;
2549 configFile["rules"][0]["actions"][1]["run_rule"] = "set_voltage_rule%";
2550 EXPECT_JSON_INVALID(
2551 configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002552 "'set_voltage_rule%' does not match '^[A-Za-z0-9_]+$'");
Bob Kinge86c2e52020-01-21 11:33:32 +08002553 }
2554}
Bob Kingfcc2a2f2020-01-31 11:29:45 +08002555TEST(ValidateRegulatorsConfigTest, SensorMonitoring)
2556{
2557 // Valid: test rails sensor_monitoring with only property rule id.
2558 {
2559 json configFile = validConfigFile;
2560 EXPECT_JSON_VALID(configFile);
2561 }
2562 // Valid: test rails sensor_monitoring with only property actions.
2563 {
2564 json configFile = validConfigFile;
2565 configFile["chassis"][0]["devices"][0]["rails"][0]["sensor_monitoring"]
2566 .erase("rule_id");
2567 configFile["chassis"][0]["devices"][0]["rails"][0]["sensor_monitoring"]
2568 ["actions"][0]["compare_presence"]["fru"] =
2569 "/system/chassis/motherboard/cpu3";
2570 configFile["chassis"][0]["devices"][0]["rails"][0]["sensor_monitoring"]
2571 ["actions"][0]["compare_presence"]["value"] = true;
2572 configFile["chassis"][0]["devices"][0]["rails"][0]["sensor_monitoring"]
2573 ["comments"][0] = "comments";
2574 EXPECT_JSON_VALID(configFile);
2575 }
2576 // Invalid: test rails sensor_monitoring with both property rule_id and
2577 // actions.
2578 {
2579 json configFile = validConfigFile;
2580 configFile["chassis"][0]["devices"][0]["rails"][0]["sensor_monitoring"]
2581 ["actions"][0]["compare_presence"]["fru"] =
2582 "/system/chassis/motherboard/cpu3";
2583 configFile["chassis"][0]["devices"][0]["rails"][0]["sensor_monitoring"]
2584 ["actions"][0]["compare_presence"]["value"] = true;
2585 EXPECT_JSON_INVALID(
2586 configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002587 "{'actions': [{'compare_presence': {'fru': "
2588 "'/system/chassis/motherboard/cpu3', 'value': True}}], 'rule_id': "
2589 "'read_sensors_rule'} is valid under each of {'required': "
2590 "['actions']}, {'required': ['rule_id']}");
Bob Kingfcc2a2f2020-01-31 11:29:45 +08002591 }
2592 // Invalid: test rails sensor_monitoring with no rule_id and actions.
2593 {
2594 json configFile = validConfigFile;
2595 configFile["chassis"][0]["devices"][0]["rails"][0]["sensor_monitoring"]
2596 .erase("rule_id");
2597 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002598 "'rule_id' is a required property");
Bob Kingfcc2a2f2020-01-31 11:29:45 +08002599 }
2600 // Invalid: test rails sensor_monitoring with property comments wrong type.
2601 {
2602 json configFile = validConfigFile;
2603 configFile["chassis"][0]["devices"][0]["rails"][0]["sensor_monitoring"]
2604 ["comments"] = true;
2605 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002606 "True is not of type 'array'");
Bob Kingfcc2a2f2020-01-31 11:29:45 +08002607 }
2608 // Invalid: test rails sensor_monitoring with property rule_id wrong type.
2609 {
2610 json configFile = validConfigFile;
2611 configFile["chassis"][0]["devices"][0]["rails"][0]["sensor_monitoring"]
2612 ["rule_id"] = true;
2613 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002614 "True is not of type 'string'");
Bob Kingfcc2a2f2020-01-31 11:29:45 +08002615 }
2616 // Invalid: test rails sensor_monitoring with property actions wrong type.
2617 {
2618 json configFile = validConfigFile;
2619 configFile["chassis"][0]["devices"][0]["rails"][0]["sensor_monitoring"]
2620 .erase("rule_id");
2621 configFile["chassis"][0]["devices"][0]["rails"][0]["sensor_monitoring"]
2622 ["actions"] = true;
2623 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002624 "True is not of type 'array'");
Bob Kingfcc2a2f2020-01-31 11:29:45 +08002625 }
2626 // Invalid: test rails sensor_monitoring with property rule_id wrong format.
2627 {
2628 json configFile = validConfigFile;
2629 configFile["chassis"][0]["devices"][0]["rails"][0]["sensor_monitoring"]
2630 ["rule_id"] = "id@";
2631 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002632 "'id@' does not match '^[A-Za-z0-9_]+$'");
Bob Kingfcc2a2f2020-01-31 11:29:45 +08002633 }
2634 // Invalid: test rails sensor_monitoring with property comments empty array.
2635 {
2636 json configFile = validConfigFile;
2637 configFile["chassis"][0]["devices"][0]["rails"][0]["sensor_monitoring"]
2638 ["comments"] = json::array();
2639 EXPECT_JSON_INVALID(configFile, "Validation failed.",
2640 "[] is too short");
2641 }
2642 // Invalid: test rails sensor_monitoring with property actions empty array.
2643 {
2644 json configFile = validConfigFile;
2645 configFile["chassis"][0]["devices"][0]["rails"][0]["sensor_monitoring"]
2646 .erase("rule_id");
2647 configFile["chassis"][0]["devices"][0]["rails"][0]["sensor_monitoring"]
2648 ["actions"] = json::array();
2649 EXPECT_JSON_INVALID(configFile, "Validation failed.",
2650 "[] is too short");
2651 }
2652}
Bob King68230aa2020-01-21 11:34:33 +08002653TEST(ValidateRegulatorsConfigTest, SetDevice)
2654{
2655 json setDeviceFile = validConfigFile;
Bob King7d3a9f12020-02-11 15:34:52 +08002656 setDeviceFile["rules"][0]["actions"][1]["set_device"] = "vdd_regulator";
Bob King68230aa2020-01-21 11:34:33 +08002657 // Valid: test set_device.
2658 {
2659 json configFile = setDeviceFile;
2660 EXPECT_JSON_VALID(configFile);
2661 }
2662 // Invalid: test set_device wrong type.
2663 {
2664 json configFile = setDeviceFile;
2665 configFile["rules"][0]["actions"][1]["set_device"] = true;
2666 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002667 "True is not of type 'string'");
Bob King68230aa2020-01-21 11:34:33 +08002668 }
2669 // Invalid: test set_device wrong format.
2670 {
2671 json configFile = setDeviceFile;
2672 configFile["rules"][0]["actions"][1]["set_device"] = "io_expander2%";
Bob King358c4172020-03-16 13:57:08 +08002673 EXPECT_JSON_INVALID(configFile, "Validation failed.",
2674 "'io_expander2%' does not match '^[A-Za-z0-9_]+$'");
Bob King68230aa2020-01-21 11:34:33 +08002675 }
2676}
Bob King3643cc02020-01-31 11:32:56 +08002677TEST(ValidateRegulatorsConfigTest, DuplicateRuleID)
2678{
2679 // Invalid: test duplicate ID in rule.
2680 {
2681 json configFile = validConfigFile;
Bob Kingb3e48bc2020-02-18 09:59:09 +08002682 configFile["rules"][2]["id"] = "set_voltage_rule";
2683 configFile["rules"][2]["actions"][0]["pmbus_write_vout_command"]
Bob King3643cc02020-01-31 11:32:56 +08002684 ["format"] = "linear";
2685 EXPECT_JSON_INVALID(configFile, "Error: Duplicate rule ID.", "");
2686 }
2687}
2688TEST(ValidateRegulatorsConfigTest, DuplicateChassisNumber)
2689{
2690 // Invalid: test duplicate number in chassis.
2691 {
2692 json configFile = validConfigFile;
2693 configFile["chassis"][1]["number"] = 1;
2694 EXPECT_JSON_INVALID(configFile, "Error: Duplicate chassis number.", "");
2695 }
2696}
2697TEST(ValidateRegulatorsConfigTest, DuplicateDeviceID)
2698{
2699 // Invalid: test duplicate ID in device.
2700 {
2701 json configFile = validConfigFile;
2702 configFile["chassis"][0]["devices"][1]["id"] = "vdd_regulator";
2703 configFile["chassis"][0]["devices"][1]["is_regulator"] = true;
2704 configFile["chassis"][0]["devices"][1]["fru"] =
2705 "/system/chassis/motherboard/regulator1";
2706 configFile["chassis"][0]["devices"][1]["i2c_interface"]["bus"] = 2;
2707 configFile["chassis"][0]["devices"][1]["i2c_interface"]["address"] =
2708 "0x71";
2709 EXPECT_JSON_INVALID(configFile, "Error: Duplicate device ID.", "");
2710 }
2711}
2712TEST(ValidateRegulatorsConfigTest, DuplicateRailID)
2713{
2714 // Invalid: test duplicate ID in rail.
2715 {
2716 json configFile = validConfigFile;
2717 configFile["chassis"][0]["devices"][0]["rails"][1]["id"] = "vdd";
2718 EXPECT_JSON_INVALID(configFile, "Error: Duplicate rail ID.", "");
2719 }
2720}
Bob King78793102020-03-13 13:16:09 +08002721TEST(ValidateRegulatorsConfigTest, DuplicateObjectID)
2722{
2723 // Invalid: test duplicate object ID in device and rail.
2724 {
2725 json configFile = validConfigFile;
2726 configFile["chassis"][0]["devices"][0]["rails"][1]["id"] =
2727 "vdd_regulator";
2728 EXPECT_JSON_INVALID(configFile, "Error: Duplicate ID.", "");
2729 }
2730 // Invalid: test duplicate object ID in device and rule.
2731 {
2732 json configFile = validConfigFile;
2733 configFile["rules"][2]["id"] = "vdd_regulator";
2734 configFile["rules"][2]["actions"][0]["pmbus_write_vout_command"]
2735 ["format"] = "linear";
2736 EXPECT_JSON_INVALID(configFile, "Error: Duplicate ID.", "");
2737 }
2738 // Invalid: test duplicate object ID in rule and rail.
2739 {
2740 json configFile = validConfigFile;
2741 configFile["chassis"][0]["devices"][0]["rails"][1]["id"] =
2742 "set_voltage_rule";
2743 EXPECT_JSON_INVALID(configFile, "Error: Duplicate ID.", "");
2744 }
2745}
Bob King3643cc02020-01-31 11:32:56 +08002746TEST(ValidateRegulatorsConfigTest, InfiniteLoops)
2747{
2748 // Invalid: test run_rule with infinite loop (rules run each other).
2749 {
2750 json configFile = validConfigFile;
2751 configFile["rules"][2]["actions"][0]["run_rule"] = "set_voltage_rule2";
2752 configFile["rules"][2]["id"] = "set_voltage_rule1";
2753 configFile["rules"][3]["actions"][0]["run_rule"] = "set_voltage_rule1";
2754 configFile["rules"][3]["id"] = "set_voltage_rule2";
2755 EXPECT_JSON_INVALID(configFile,
2756 "Infinite loop caused by run_rule actions.", "");
2757 }
2758 // Invalid: test run_rule with infinite loop (rule runs itself).
2759 {
2760 json configFile = validConfigFile;
2761 configFile["rules"][2]["actions"][0]["run_rule"] = "set_voltage_rule1";
2762 configFile["rules"][2]["id"] = "set_voltage_rule1";
2763 EXPECT_JSON_INVALID(configFile,
2764 "Infinite loop caused by run_rule actions.", "");
2765 }
2766 // Invalid: test run_rule with infinite loop (indirect loop).
2767 {
2768 json configFile = validConfigFile;
2769 configFile["rules"][2]["actions"][0]["run_rule"] = "set_voltage_rule2";
2770 configFile["rules"][2]["id"] = "set_voltage_rule1";
2771 configFile["rules"][3]["actions"][0]["run_rule"] = "set_voltage_rule3";
2772 configFile["rules"][3]["id"] = "set_voltage_rule2";
2773 configFile["rules"][4]["actions"][0]["run_rule"] = "set_voltage_rule1";
2774 configFile["rules"][4]["id"] = "set_voltage_rule3";
2775 EXPECT_JSON_INVALID(configFile,
2776 "Infinite loop caused by run_rule actions.", "");
2777 }
2778}
Bob Kingf88203a2020-02-18 13:26:07 +08002779TEST(ValidateRegulatorsConfigTest, RunRuleValueExists)
2780{
2781 // Invalid: test run_rule actions specify a rule ID that does not exist.
2782 {
2783 json configFile = validConfigFile;
2784 configFile["rules"][2]["actions"][0]["run_rule"] = "set_voltage_rule2";
2785 configFile["rules"][2]["id"] = "set_voltage_rule1";
2786 EXPECT_JSON_INVALID(configFile, "Error: Rule ID does not exist.", "");
2787 }
2788}
Bob King13b2ad92020-02-18 13:31:39 +08002789TEST(ValidateRegulatorsConfigTest, SetDeviceValueExists)
2790{
2791 // Invalid: test set_device actions specify a device ID that does not exist.
2792 {
2793 json configFile = validConfigFile;
2794 configFile["rules"][2]["actions"][0]["set_device"] = "vdd_regulator2";
2795 configFile["rules"][2]["id"] = "set_voltage_rule1";
2796 EXPECT_JSON_INVALID(configFile, "Error: Device ID does not exist.", "");
2797 }
2798}
Bob King21b09be2020-02-18 13:33:09 +08002799TEST(ValidateRegulatorsConfigTest, RuleIDExists)
2800{
2801 // Invalid: test rule_id property in configuration specifies a rule ID that
2802 // does not exist.
2803 {
2804 json configFile = validConfigFile;
2805 configFile["chassis"][0]["devices"][0]["configuration"]["rule_id"] =
2806 "set_voltage_rule2";
2807 EXPECT_JSON_INVALID(configFile, "Error: Rule ID does not exist.", "");
2808 }
2809 // Invalid: test rule_id property in presence_detection specifies a rule ID
2810 // that does not exist.
2811 {
2812 json configFile = validConfigFile;
2813 configFile["chassis"][0]["devices"][0]["presence_detection"]
2814 ["rule_id"] = "set_voltage_rule2";
2815 EXPECT_JSON_INVALID(configFile, "Error: Rule ID does not exist.", "");
2816 }
2817 // Invalid: test rule_id property in sensor_monitoring specifies a rule ID
2818 // that does not exist.
2819 {
2820 json configFile = validConfigFile;
2821 configFile["chassis"][0]["devices"][0]["rails"][0]["sensor_monitoring"]
2822 ["rule_id"] = "set_voltage_rule2";
2823 EXPECT_JSON_INVALID(configFile, "Error: Rule ID does not exist.", "");
2824 }
2825}
Bob Kingdc72b622020-02-18 13:36:18 +08002826TEST(ValidateRegulatorsConfigTest, NumberOfElementsInMasks)
2827{
2828 // Invalid: test number of elements in masks not equal to number in values
2829 // in i2c_compare_bytes.
2830 {
2831 json configFile = validConfigFile;
2832 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["register"] =
2833 "0x82";
2834 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["values"] = {
2835 "0x02", "0x73"};
2836 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["masks"] = {
2837 "0x7F"};
2838 EXPECT_JSON_INVALID(configFile,
2839 "Error: Invalid i2c_compare_bytes action.", "");
2840 }
2841 // Invalid: test number of elements in masks not equal to number in values
2842 // in i2c_write_bytes.
2843 {
2844 json configFile = validConfigFile;
2845 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["register"] =
2846 "0x82";
2847 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["values"] = {
2848 "0x02", "0x73"};
2849 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["masks"] = {
2850 "0x7F"};
2851 EXPECT_JSON_INVALID(configFile,
2852 "Error: Invalid i2c_write_bytes action.", "");
2853 }
2854}
Bob Kinged009652020-02-20 14:54:13 +08002855TEST(ValidateRegulatorsConfigTest, CommandLineSyntax)
2856{
Bob Kinga57e0812020-03-12 10:47:42 +08002857 std::string validateTool =
2858 " ../phosphor-regulators/tools/validate-regulators-config.py ";
Bob Kinged009652020-02-20 14:54:13 +08002859 std::string schema = " -s ";
Bob Kinga57e0812020-03-12 10:47:42 +08002860 std::string schemaFile =
2861 " ../phosphor-regulators/schema/config_schema.json ";
Bob Kinged009652020-02-20 14:54:13 +08002862 std::string configuration = " -c ";
2863 std::string command;
2864 std::string errorMessage;
2865 std::string outputMessage;
2866 std::string outputMessageHelp =
2867 "usage: validate-regulators-config.py [-h] [-s SCHEMA_FILE]";
2868 int valid = 0;
2869
2870 std::string fileName;
Bob Kinga57e0812020-03-12 10:47:42 +08002871 TmpFile tmpFile;
2872 fileName = tmpFile.getName();
2873 writeDataToFile(validConfigFile, fileName);
Bob Kinged009652020-02-20 14:54:13 +08002874 // Valid: -s specified
2875 {
2876 command = validateTool + "-s " + schemaFile + configuration + fileName;
2877 expectCommandLineSyntax(errorMessage, outputMessage, command, valid);
2878 }
2879 // Valid: --schema-file specified
2880 {
2881 command = validateTool + "--schema-file " + schemaFile + configuration +
2882 fileName;
2883 expectCommandLineSyntax(errorMessage, outputMessage, command, valid);
2884 }
2885 // Valid: -c specified
2886 {
2887 command = validateTool + schema + schemaFile + "-c " + fileName;
2888 expectCommandLineSyntax(errorMessage, outputMessage, command, valid);
2889 }
2890 // Valid: --configuration-file specified
2891 {
2892 command = validateTool + schema + schemaFile + "--configuration-file " +
2893 fileName;
2894 expectCommandLineSyntax(errorMessage, outputMessage, command, valid);
2895 }
2896 // Valid: -h specified
2897 {
2898 command = validateTool + "-h ";
2899 expectCommandLineSyntax(errorMessage, outputMessageHelp, command,
2900 valid);
2901 }
2902 // Valid: --help specified
2903 {
2904 command = validateTool + "--help ";
2905 expectCommandLineSyntax(errorMessage, outputMessageHelp, command,
2906 valid);
2907 }
2908 // Invalid: -c/--configuration-file not specified
2909 {
2910 command = validateTool + schema + schemaFile;
2911 expectCommandLineSyntax("Error: Configuration file is required.",
2912 outputMessageHelp, command, 1);
2913 }
2914 // Invalid: -s/--schema-file not specified
2915 {
2916 command = validateTool + configuration + fileName;
2917 expectCommandLineSyntax("Error: Schema file is required.",
2918 outputMessageHelp, command, 1);
2919 }
2920 // Invalid: -s specified more than once
2921 {
2922 command =
2923 validateTool + "-s -s " + schemaFile + configuration + fileName;
2924 expectCommandLineSyntax(outputMessageHelp, outputMessage, command, 2);
2925 }
2926 // Invalid: -c specified more than once
2927 {
2928 command = validateTool + schema + schemaFile + "-c -c " + fileName;
2929 expectCommandLineSyntax(outputMessageHelp, outputMessage, command, 2);
2930 }
2931 // Invalid: No file name specified after -c
2932 {
2933 command = validateTool + schema + schemaFile + configuration;
2934 expectCommandLineSyntax(outputMessageHelp, outputMessage, command, 2);
2935 }
2936 // Invalid: No file name specified after -s
2937 {
2938 command = validateTool + schema + configuration + fileName;
2939 expectCommandLineSyntax(outputMessageHelp, outputMessage, command, 2);
2940 }
2941 // Invalid: File specified after -c does not exist
2942 {
2943 command = validateTool + schema + schemaFile + configuration +
2944 "../notExistFile";
2945 expectCommandLineSyntax(
2946 "Traceback (most recent call last):", outputMessage, command, 1);
2947 }
2948 // Invalid: File specified after -s does not exist
2949 {
2950 command = validateTool + schema + "../notExistFile " + configuration +
2951 fileName;
2952 expectCommandLineSyntax(
2953 "Traceback (most recent call last):", outputMessage, command, 1);
2954 }
2955 // Invalid: File specified after -s is not right data format
2956 {
Bob Kinga57e0812020-03-12 10:47:42 +08002957 std::string wrongFormatFileName;
2958 TmpFile wrongFormatFile;
2959 wrongFormatFileName = wrongFormatFile.getName();
2960 std::ofstream out(wrongFormatFileName);
Bob Kinged009652020-02-20 14:54:13 +08002961 out << "foo";
2962 out.close();
Bob Kinga57e0812020-03-12 10:47:42 +08002963 command = validateTool + schema + wrongFormatFileName + configuration +
2964 fileName;
Bob Kinged009652020-02-20 14:54:13 +08002965 expectCommandLineSyntax(
2966 "Traceback (most recent call last):", outputMessage, command, 1);
Bob Kinged009652020-02-20 14:54:13 +08002967 }
2968 // Invalid: File specified after -c is not readable
2969 {
Bob Kinga57e0812020-03-12 10:47:42 +08002970 std::string notReadableFileName;
2971 TmpFile notReadableFile;
2972 notReadableFileName = notReadableFile.getName();
2973 writeDataToFile(validConfigFile, notReadableFileName);
Bob Kinged009652020-02-20 14:54:13 +08002974 command = validateTool + schema + schemaFile + configuration +
Bob Kinga57e0812020-03-12 10:47:42 +08002975 notReadableFileName;
2976 chmod(notReadableFileName.c_str(), 0222);
Bob Kinged009652020-02-20 14:54:13 +08002977 expectCommandLineSyntax(
2978 "Traceback (most recent call last):", outputMessage, command, 1);
Bob Kinged009652020-02-20 14:54:13 +08002979 }
2980 // Invalid: File specified after -s is not readable
2981 {
Bob Kinga57e0812020-03-12 10:47:42 +08002982 std::string notReadableFileName;
2983 TmpFile notReadableFile;
2984 notReadableFileName = notReadableFile.getName();
2985 writeDataToFile(validConfigFile, notReadableFileName);
2986 command = validateTool + schema + notReadableFileName + configuration +
2987 fileName;
2988 chmod(notReadableFileName.c_str(), 0222);
Bob Kinged009652020-02-20 14:54:13 +08002989 expectCommandLineSyntax(
2990 "Traceback (most recent call last):", outputMessage, command, 1);
Bob Kinged009652020-02-20 14:54:13 +08002991 }
2992 // Invalid: Unexpected parameter specified (like -g)
2993 {
2994 command = validateTool + schema + schemaFile + configuration +
2995 fileName + " -g";
2996 expectCommandLineSyntax(outputMessageHelp, outputMessage, command, 2);
2997 }
Bob Kinged009652020-02-20 14:54:13 +08002998}