blob: e62a88c174778baeba9717b17dda909c2a8182b9 [file] [log] [blame]
Bob King386d33f2019-12-26 17:28:56 +08001/**
Bob King0dcbdf52020-01-20 17:19:39 +08002 * Copyright c 2020 IBM Corporation
Bob King386d33f2019-12-26 17:28:56 +08003 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
Shawn McCarney0f6ebad2020-09-04 16:43:00 -050016#include "temporary_file.hpp"
Shawn McCarney80c0b042020-03-27 12:08:53 -050017
18#include <stdio.h> // for popen(), pclose(), fgets()
19#include <sys/stat.h> // for chmod()
20#include <sys/wait.h> // for WEXITSTATUS
Bob King386d33f2019-12-26 17:28:56 +080021
Bob King386d33f2019-12-26 17:28:56 +080022#include <nlohmann/json.hpp>
23
Shawn McCarney80c0b042020-03-27 12:08:53 -050024#include <cstdio>
Bob King0dcbdf52020-01-20 17:19:39 +080025#include <fstream>
26
Bob King386d33f2019-12-26 17:28:56 +080027#include <gtest/gtest.h>
28
29#define EXPECT_FILE_VALID(configFile) expectFileValid(configFile)
30#define EXPECT_FILE_INVALID(configFile, expectedErrorMessage, \
31 expectedOutputMessage) \
32 expectFileInvalid(configFile, expectedErrorMessage, expectedOutputMessage)
33#define EXPECT_JSON_VALID(configFileJson) expectJsonValid(configFileJson)
34#define EXPECT_JSON_INVALID(configFileJson, expectedErrorMessage, \
35 expectedOutputMessage) \
36 expectJsonInvalid(configFileJson, expectedErrorMessage, \
37 expectedOutputMessage)
38
Shawn McCarney80c0b042020-03-27 12:08:53 -050039using namespace phosphor::power::regulators;
Bob King386d33f2019-12-26 17:28:56 +080040using json = nlohmann::json;
41
42const json validConfigFile = R"(
43 {
44 "comments": [ "Config file for a FooBar one-chassis system" ],
45
46 "rules": [
47 {
48 "comments": [ "Sets output voltage for a PMBus regulator rail" ],
49 "id": "set_voltage_rule",
50 "actions": [
51 {
52 "pmbus_write_vout_command": {
53 "format": "linear"
54 }
55 }
56 ]
Bob Kingb3e48bc2020-02-18 09:59:09 +080057 },
58 {
59 "comments": [ "Reads sensors from a PMBus regulator rail" ],
60 "id": "read_sensors_rule",
61 "actions": [
62 {
63 "comments": [ "Read output voltage from READ_VOUT." ],
64 "pmbus_read_sensor": {
65 "type": "vout",
66 "command": "0x8B",
67 "format": "linear_16"
68 }
69 }
70 ]
Bob King386d33f2019-12-26 17:28:56 +080071 }
72 ],
73
74 "chassis": [
75 {
76 "comments": [ "Chassis number 1 containing CPUs and memory" ],
77 "number": 1,
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.
Shawn McCarney0f6ebad2020-09-04 16:43:00 -0500123 TemporaryFile tmpFile;
124 command += " 2> " + tmpFile.getPath().string();
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.
Shawn McCarney0f6ebad2020-09-04 16:43:00 -0500154 std::ifstream input(tmpFile.getPath());
Bob Kinga57e0812020-03-12 10:47:42 +0800155 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{
Shawn McCarney0f6ebad2020-09-04 16:43:00 -0500202 TemporaryFile tmpFile;
203 std::string fileName = tmpFile.getPath().string();
Bob Kinga57e0812020-03-12 10:47:42 +0800204 writeDataToFile(configFileJson, fileName);
Bob Kinged009652020-02-20 14:54:13 +0800205
Bob King386d33f2019-12-26 17:28:56 +0800206 EXPECT_FILE_VALID(fileName);
Bob King386d33f2019-12-26 17:28:56 +0800207}
208
209void expectJsonInvalid(const json configFileJson,
210 const std::string& expectedErrorMessage,
211 const std::string& expectedOutputMessage)
212{
Shawn McCarney0f6ebad2020-09-04 16:43:00 -0500213 TemporaryFile tmpFile;
214 std::string fileName = tmpFile.getPath().string();
Bob Kinga57e0812020-03-12 10:47:42 +0800215 writeDataToFile(configFileJson, fileName);
Bob King386d33f2019-12-26 17:28:56 +0800216
217 EXPECT_FILE_INVALID(fileName, expectedErrorMessage, expectedOutputMessage);
Bob King386d33f2019-12-26 17:28:56 +0800218}
219
Bob Kinged009652020-02-20 14:54:13 +0800220void expectCommandLineSyntax(const std::string& expectedErrorMessage,
221 const std::string& expectedOutputMessage,
Shawn McCarney525e20c2020-04-14 11:05:39 -0500222 const std::string& command, int status)
Bob Kinged009652020-02-20 14:54:13 +0800223{
224 std::string errorMessage;
225 std::string outputMessage;
Bob Kinga57e0812020-03-12 10:47:42 +0800226 EXPECT_EQ(runToolForOutputWithCommand(command, outputMessage, errorMessage),
227 status);
Bob Kinged009652020-02-20 14:54:13 +0800228 EXPECT_EQ(errorMessage, expectedErrorMessage);
229 EXPECT_EQ(outputMessage, expectedOutputMessage);
230}
231
Bob King3afa7112020-03-19 09:35:31 +0800232TEST(ValidateRegulatorsConfigTest, Action)
233{
234 // Valid: Comments property not specified
235 {
236 json configFile = validConfigFile;
237 EXPECT_JSON_VALID(configFile);
238 }
239 // Valid: Comments property specified
240 {
241 json configFile = validConfigFile;
242 configFile["rules"][0]["actions"][0]["comments"][0] =
243 "Set VOUT_COMMAND";
244 EXPECT_JSON_VALID(configFile);
245 }
246 // Valid: and action type specified
247 {
248 json configFile = validConfigFile;
249 json andAction =
250 R"(
251 {
252 "and": [
253 { "i2c_compare_byte": { "register": "0xA0", "value": "0x00" } },
254 { "i2c_compare_byte": { "register": "0xA1", "value": "0x00" } }
255 ]
256 }
257 )"_json;
258 configFile["rules"][0]["actions"].push_back(andAction);
259 EXPECT_JSON_VALID(configFile);
260 }
261 // Valid: compare_presence action type specified
262 {
263 json configFile = validConfigFile;
264 configFile["rules"][0]["actions"][1]["compare_presence"]["fru"] =
265 "/system/chassis/motherboard/regulator2";
266 configFile["rules"][0]["actions"][1]["compare_presence"]["value"] =
267 true;
268 EXPECT_JSON_VALID(configFile);
269 }
270 // Valid: compare_vpd action type specified
271 {
272 json configFile = validConfigFile;
273 configFile["rules"][0]["actions"][1]["compare_vpd"]["fru"] =
274 "/system/chassis/motherboard/regulator2";
275 configFile["rules"][0]["actions"][1]["compare_vpd"]["keyword"] = "CCIN";
276 configFile["rules"][0]["actions"][1]["compare_vpd"]["value"] = "2D35";
277 EXPECT_JSON_VALID(configFile);
278 }
279 // Valid: i2c_compare_bit action type specified
280 {
281 json configFile = validConfigFile;
282 configFile["rules"][0]["actions"][1]["i2c_compare_bit"]["register"] =
283 "0xA0";
284 configFile["rules"][0]["actions"][1]["i2c_compare_bit"]["position"] = 3;
285 configFile["rules"][0]["actions"][1]["i2c_compare_bit"]["value"] = 1;
286 EXPECT_JSON_VALID(configFile);
287 }
288 // Valid: i2c_compare_byte action type specified
289 {
290 json configFile = validConfigFile;
291 configFile["rules"][0]["actions"][1]["i2c_compare_byte"]["register"] =
292 "0x82";
293 configFile["rules"][0]["actions"][1]["i2c_compare_byte"]["value"] =
294 "0x40";
295 configFile["rules"][0]["actions"][1]["i2c_compare_byte"]["mask"] =
296 "0x7F";
297 EXPECT_JSON_VALID(configFile);
298 }
299 // Valid: i2c_compare_bytes action type specified
300 {
301 json configFile = validConfigFile;
302 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["register"] =
303 "0x82";
304 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["values"] = {
305 "0x02", "0x73"};
306 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["masks"] = {
307 "0x7F", "0x7F"};
308 EXPECT_JSON_VALID(configFile);
309 }
310 // Valid: i2c_write_bit action type specified
311 {
312 json configFile = validConfigFile;
313 configFile["rules"][0]["actions"][1]["i2c_write_bit"]["register"] =
314 "0xA0";
315 configFile["rules"][0]["actions"][1]["i2c_write_bit"]["position"] = 3;
316 configFile["rules"][0]["actions"][1]["i2c_write_bit"]["value"] = 1;
317 EXPECT_JSON_VALID(configFile);
318 }
319 // Valid: i2c_write_byte action type specified
320 {
321 json configFile = validConfigFile;
322 configFile["rules"][0]["actions"][1]["i2c_write_byte"]["register"] =
323 "0x82";
324 configFile["rules"][0]["actions"][1]["i2c_write_byte"]["value"] =
325 "0x40";
326 configFile["rules"][0]["actions"][1]["i2c_write_byte"]["mask"] = "0x7F";
327 EXPECT_JSON_VALID(configFile);
328 }
329 // Valid: i2c_write_bytes action type specified
330 {
331 json configFile = validConfigFile;
332 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["register"] =
333 "0x82";
334 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["values"] = {
335 "0x02", "0x73"};
336 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["masks"] = {
337 "0x7F", "0x7F"};
338 EXPECT_JSON_VALID(configFile);
339 }
340 // Valid: if action type specified
341 {
342 json configFile = validConfigFile;
343 configFile["rules"][2]["actions"][0]["if"]["condition"]["run_rule"] =
344 "set_voltage_rule";
345 configFile["rules"][2]["actions"][0]["if"]["then"][0]["run_rule"] =
346 "read_sensors_rule";
347 configFile["rules"][2]["actions"][0]["if"]["else"][0]["run_rule"] =
348 "read_sensors_rule";
349 configFile["rules"][2]["id"] = "rule_if";
350 EXPECT_JSON_VALID(configFile);
351 }
352 // Valid: not action type specified
353 {
354 json configFile = validConfigFile;
355 configFile["rules"][0]["actions"][1]["not"]["i2c_compare_byte"]
356 ["register"] = "0xA0";
357 configFile["rules"][0]["actions"][1]["not"]["i2c_compare_byte"]
358 ["value"] = "0xFF";
359 EXPECT_JSON_VALID(configFile);
360 }
361 // Valid: or action type specified
362 {
363 json configFile = validConfigFile;
364 configFile["rules"][0]["actions"][1]["or"][0]["i2c_compare_byte"]
365 ["register"] = "0xA0";
366 configFile["rules"][0]["actions"][1]["or"][0]["i2c_compare_byte"]
367 ["value"] = "0x00";
368 configFile["rules"][0]["actions"][1]["or"][1]["i2c_compare_byte"]
369 ["register"] = "0xA1";
370 configFile["rules"][0]["actions"][1]["or"][1]["i2c_compare_byte"]
371 ["value"] = "0x00";
372 EXPECT_JSON_VALID(configFile);
373 }
374 // Valid: pmbus_read_sensor and pmbus_write_vout_command action type
375 // specified
376 {
377 EXPECT_JSON_VALID(validConfigFile);
378 }
379 // Valid: run_rule action type specified
380 {
381 json configFile = validConfigFile;
382 configFile["rules"][0]["actions"][1]["run_rule"] = "read_sensors_rule";
383 EXPECT_JSON_VALID(configFile);
384 }
385 // Valid: set_device action type specified
386 {
387 json configFile = validConfigFile;
388 configFile["rules"][0]["actions"][1]["set_device"] = "vdd_regulator";
389 EXPECT_JSON_VALID(configFile);
390 }
391 // Invalid: Wrong data type for comments (should be array of string)
392 {
393 json configFile = validConfigFile;
394 configFile["rules"][0]["actions"][0]["comments"] = true;
395 EXPECT_JSON_INVALID(configFile, "Validation failed.",
396 "True is not of type 'array'");
397 }
398 // Invalid: Wrong data type for action type (such as "i2c_write_byte": true)
399 {
400 json configFile = validConfigFile;
401 configFile["rules"][0]["actions"][1]["i2c_write_byte"] = true;
402 EXPECT_JSON_INVALID(configFile, "Validation failed.",
403 "True is not of type 'object'");
404 }
405 // Invalid: Empty comments array
406 {
407 json configFile = validConfigFile;
408 configFile["rules"][0]["actions"][0]["comments"] = json::array();
409 EXPECT_JSON_INVALID(configFile, "Validation failed.",
410 "[] is too short");
411 }
412 // Invalid: Comments array has wrong element type (should be string)
413 {
414 json configFile = validConfigFile;
415 configFile["rules"][0]["actions"][0]["comments"][0] = true;
416 EXPECT_JSON_INVALID(configFile, "Validation failed.",
417 "True is not of type 'string'");
418 }
419 // Invalid: No action type specified
420 {
421 json configFile = validConfigFile;
422 configFile["rules"][0]["actions"][1]["comments"][0] =
423 "Check if bit 3 is on";
424 EXPECT_JSON_INVALID(configFile, "Validation failed.",
425 "'and' is a required property");
426 }
427 // Invalid: Multiple action types specified (such as both 'compare_presence'
428 // and 'pmbus_write_vout_command')
429 {
430 json configFile = validConfigFile;
431 configFile["rules"][0]["actions"][0]["compare_presence"]["value"] =
432 true;
433 EXPECT_JSON_INVALID(
434 configFile, "Validation failed.",
435 "{'compare_presence': {'value': True}, 'pmbus_write_vout_command': "
436 "{'format': 'linear'}} is valid under each of {'required': "
437 "['pmbus_write_vout_command']}, {'required': "
438 "['compare_presence']}");
439 }
440 // Invalid: Unexpected property specified (like 'foo')
441 {
442 json configFile = validConfigFile;
443 configFile["rules"][0]["actions"][1]["foo"] = "foo";
444 EXPECT_JSON_INVALID(
445 configFile, "Validation failed.",
446 "Additional properties are not allowed ('foo' was unexpected)");
447 }
448}
Bob Kingbeaf6532020-01-21 11:03:49 +0800449TEST(ValidateRegulatorsConfigTest, And)
450{
451 // Valid.
452 {
453 json configFile = validConfigFile;
454 json andAction =
455 R"(
456 {
457 "and": [
458 { "i2c_compare_byte": { "register": "0xA0", "value": "0x00" } },
459 { "i2c_compare_byte": { "register": "0xA1", "value": "0x00" } }
460 ]
461 }
462 )"_json;
463 configFile["rules"][0]["actions"].push_back(andAction);
464 EXPECT_JSON_VALID(configFile);
465 }
466
467 // Invalid: actions property value is an empty array.
468 {
469 json configFile = validConfigFile;
470 json andAction =
471 R"(
472 {
473 "and": []
474 }
475 )"_json;
476 configFile["rules"][0]["actions"].push_back(andAction);
477 EXPECT_JSON_INVALID(configFile, "Validation failed.",
478 "[] is too short");
479 }
480
481 // Invalid: actions property has incorrect value data type.
482 {
483 json configFile = validConfigFile;
484 json andAction =
485 R"(
486 {
487 "and": true
488 }
489 )"_json;
490 configFile["rules"][0]["actions"].push_back(andAction);
491 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800492 "True is not of type 'array'");
Bob Kingbeaf6532020-01-21 11:03:49 +0800493 }
494
495 // Invalid: actions property value contains wrong element type
496 {
497 json configFile = validConfigFile;
498 json andAction =
499 R"(
500 {
501 "and": ["foo"]
502 }
503 )"_json;
504 configFile["rules"][0]["actions"].push_back(andAction);
505 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800506 "'foo' is not of type 'object'");
Bob Kingbeaf6532020-01-21 11:03:49 +0800507 }
508}
Bob King3728f562020-01-21 11:35:31 +0800509TEST(ValidateRegulatorsConfigTest, Chassis)
510{
511 // Valid: test chassis.
512 {
513 json configFile = validConfigFile;
514 EXPECT_JSON_VALID(configFile);
515 }
516 // Valid: test chassis with required properties.
517 {
518 json configFile = validConfigFile;
519 configFile["chassis"][0].erase("comments");
520 configFile["chassis"][0].erase("devices");
521 EXPECT_JSON_VALID(configFile);
522 }
523 // Invalid: test chassis with no number.
524 {
525 json configFile = validConfigFile;
526 configFile["chassis"][0].erase("number");
527 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800528 "'number' is a required property");
Bob King3728f562020-01-21 11:35:31 +0800529 }
530 // Invalid: test chassis with property comments wrong type.
531 {
532 json configFile = validConfigFile;
533 configFile["chassis"][0]["comments"] = true;
534 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800535 "True is not of type 'array'");
Bob King3728f562020-01-21 11:35:31 +0800536 }
537 // Invalid: test chassis with property number wrong type.
538 {
539 json configFile = validConfigFile;
540 configFile["chassis"][0]["number"] = 1.3;
541 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800542 "1.3 is not of type 'integer'");
Bob King3728f562020-01-21 11:35:31 +0800543 }
544 // Invalid: test chassis with property devices wrong type.
545 {
546 json configFile = validConfigFile;
547 configFile["chassis"][0]["devices"] = true;
548 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800549 "True is not of type 'array'");
Bob King3728f562020-01-21 11:35:31 +0800550 }
551 // Invalid: test chassis with property comments empty array.
552 {
553 json configFile = validConfigFile;
554 configFile["chassis"][0]["comments"] = json::array();
555 EXPECT_JSON_INVALID(configFile, "Validation failed.",
556 "[] is too short");
557 }
558 // Invalid: test chassis with property devices empty array.
559 {
560 json configFile = validConfigFile;
561 configFile["chassis"][0]["devices"] = json::array();
562 EXPECT_JSON_INVALID(configFile, "Validation failed.",
563 "[] is too short");
564 }
565 // Invalid: test chassis with property number less than 1.
566 {
567 json configFile = validConfigFile;
568 configFile["chassis"][0]["number"] = 0;
569 EXPECT_JSON_INVALID(configFile, "Validation failed.",
570 "0 is less than the minimum of 1");
571 }
572}
Bob Kingbf1cbea2020-01-21 11:08:50 +0800573TEST(ValidateRegulatorsConfigTest, ComparePresence)
574{
575 json comparePresenceFile = validConfigFile;
576 comparePresenceFile["rules"][0]["actions"][1]["compare_presence"]["fru"] =
577 "/system/chassis/motherboard/regulator2";
578 comparePresenceFile["rules"][0]["actions"][1]["compare_presence"]["value"] =
579 true;
580 // Valid.
581 {
582 json configFile = comparePresenceFile;
583 EXPECT_JSON_VALID(configFile);
584 }
585
586 // Invalid: no FRU property.
587 {
588 json configFile = comparePresenceFile;
589 configFile["rules"][0]["actions"][1]["compare_presence"].erase("fru");
590 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800591 "'fru' is a required property");
Bob Kingbf1cbea2020-01-21 11:08:50 +0800592 }
593
594 // Invalid: FRU property length is string less than 1.
595 {
596 json configFile = comparePresenceFile;
597 configFile["rules"][0]["actions"][1]["compare_presence"]["fru"] = "";
598 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800599 "'' is too short");
Bob Kingbf1cbea2020-01-21 11:08:50 +0800600 }
601
602 // Invalid: no value property.
603 {
604 json configFile = comparePresenceFile;
605 configFile["rules"][0]["actions"][1]["compare_presence"].erase("value");
606 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800607 "'value' is a required property");
Bob Kingbf1cbea2020-01-21 11:08:50 +0800608 }
609
610 // Invalid: value property type is not boolean.
611 {
612 json configFile = comparePresenceFile;
613 configFile["rules"][0]["actions"][1]["compare_presence"]["value"] = "1";
614 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800615 "'1' is not of type 'boolean'");
Bob Kingbf1cbea2020-01-21 11:08:50 +0800616 }
617
618 // Invalid: FRU property type is not string.
619 {
620 json configFile = comparePresenceFile;
621 configFile["rules"][0]["actions"][1]["compare_presence"]["fru"] = 1;
622 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800623 "1 is not of type 'string'");
Bob Kingbf1cbea2020-01-21 11:08:50 +0800624 }
625}
Bob Kingf8b77a02020-01-21 11:09:47 +0800626TEST(ValidateRegulatorsConfigTest, CompareVpd)
627{
628 json compareVpdFile = validConfigFile;
629 compareVpdFile["rules"][0]["actions"][1]["compare_vpd"]["fru"] =
630 "/system/chassis/motherboard/regulator2";
631 compareVpdFile["rules"][0]["actions"][1]["compare_vpd"]["keyword"] = "CCIN";
632 compareVpdFile["rules"][0]["actions"][1]["compare_vpd"]["value"] = "2D35";
633
634 // Valid.
635 {
636 json configFile = compareVpdFile;
637 EXPECT_JSON_VALID(configFile);
638 }
639
640 // Invalid: no FRU property.
641 {
642 json configFile = compareVpdFile;
643 configFile["rules"][0]["actions"][1]["compare_vpd"].erase("fru");
644 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800645 "'fru' is a required property");
Bob Kingf8b77a02020-01-21 11:09:47 +0800646 }
647
648 // Invalid: no keyword property.
649 {
650 json configFile = compareVpdFile;
651 configFile["rules"][0]["actions"][1]["compare_vpd"].erase("keyword");
652 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800653 "'keyword' is a required property");
Bob Kingf8b77a02020-01-21 11:09:47 +0800654 }
655
656 // Invalid: no value property.
657 {
658 json configFile = compareVpdFile;
659 configFile["rules"][0]["actions"][1]["compare_vpd"].erase("value");
660 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800661 "'value' is a required property");
Bob Kingf8b77a02020-01-21 11:09:47 +0800662 }
663
664 // Invalid: property FRU wrong type.
665 {
666 json configFile = compareVpdFile;
667 configFile["rules"][0]["actions"][1]["compare_vpd"]["fru"] = 1;
668 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800669 "1 is not of type 'string'");
Bob Kingf8b77a02020-01-21 11:09:47 +0800670 }
671
672 // Invalid: property FRU is string less than 1.
673 {
674 json configFile = compareVpdFile;
675 configFile["rules"][0]["actions"][1]["compare_vpd"]["fru"] = "";
676 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800677 "'' is too short");
Bob Kingf8b77a02020-01-21 11:09:47 +0800678 }
679
680 // Invalid: property keyword is not "CCIN", "Manufacturer", "Model",
681 // "PartNumber"
682 {
683 json configFile = compareVpdFile;
684 configFile["rules"][0]["actions"][1]["compare_vpd"]["keyword"] =
685 "Number";
686 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800687 "'Number' is not one of ['CCIN', "
688 "'Manufacturer', 'Model', 'PartNumber']");
Bob Kingf8b77a02020-01-21 11:09:47 +0800689 }
690
691 // Invalid: property value wrong type.
692 {
693 json configFile = compareVpdFile;
694 configFile["rules"][0]["actions"][1]["compare_vpd"]["value"] = 1;
695 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800696 "1 is not of type 'string'");
Bob Kingf8b77a02020-01-21 11:09:47 +0800697 }
698}
Bob King20057412020-03-16 16:50:17 +0800699TEST(ValidateRegulatorsConfigTest, ConfigFile)
700{
701 // Valid: Only required properties specified
702 {
703 json configFile;
704 configFile["chassis"][0]["number"] = 1;
705 EXPECT_JSON_VALID(configFile);
706 }
707 // Valid: All properties specified
708 {
709 json configFile = validConfigFile;
710 EXPECT_JSON_VALID(configFile);
711 }
712 // Invalid: Required chassis property not specified
713 {
714 json configFile = validConfigFile;
715 configFile.erase("chassis");
716 EXPECT_JSON_INVALID(configFile, "Validation failed.",
717 "'chassis' is a required property");
718 }
719 // Invalid: Wrong data type for comments
720 {
721 json configFile = validConfigFile;
722 configFile["comments"] = true;
723 EXPECT_JSON_INVALID(configFile, "Validation failed.",
724 "True is not of type 'array'");
725 }
726 // Invalid: Wrong data type for rules
727 {
728 json configFile = validConfigFile;
729 configFile["rules"] = true;
730 EXPECT_JSON_INVALID(configFile, "Validation failed.",
731 "True is not of type 'array'");
732 }
733 // Invalid: Wrong data type for chassis
734 {
735 json configFile = validConfigFile;
736 configFile["chassis"] = true;
737 EXPECT_JSON_INVALID(configFile, "Validation failed.",
738 "True is not of type 'array'");
739 }
740 // Invalid: Empty comments array;
741 {
742 json configFile = validConfigFile;
743 configFile["comments"] = json::array();
744 EXPECT_JSON_INVALID(configFile, "Validation failed.",
745 "[] is too short");
746 }
747 // Invalid: Empty rules array
748 {
749 json configFile = validConfigFile;
750 configFile["rules"] = json::array();
751 EXPECT_JSON_INVALID(configFile, "Validation failed.",
752 "[] is too short");
753 }
754 // Invalid: Empty chassis array
755 {
756 json configFile = validConfigFile;
757 configFile["chassis"] = json::array();
758 EXPECT_JSON_INVALID(configFile, "Validation failed.",
759 "[] is too short");
760 }
761 // Invalid: Comments array has wrong element type (should be string)
762 {
763 json configFile = validConfigFile;
764 configFile["comments"][0] = true;
765 EXPECT_JSON_INVALID(configFile, "Validation failed.",
766 "True is not of type 'string'");
767 }
768 // Invalid: Rules array has wrong element type (should be rule)
769 {
770 json configFile = validConfigFile;
771 configFile["rules"][0] = true;
772 EXPECT_JSON_INVALID(configFile, "Validation failed.",
773 "True is not of type 'object'");
774 }
775 // Invalid: Chassis array has wrong element type (should be chassis)
776 {
777 json configFile = validConfigFile;
778 configFile["chassis"][0] = true;
779 EXPECT_JSON_INVALID(configFile, "Validation failed.",
780 "True is not of type 'object'");
781 }
782 // Invalid: Unexpected property specified
783 {
784 json configFile = validConfigFile;
785 configFile["foo"] = json::array();
786 EXPECT_JSON_INVALID(
787 configFile, "Validation failed.",
788 "Additional properties are not allowed ('foo' was unexpected)");
789 }
790}
Bob King4c67a3a2020-02-07 09:48:11 +0800791TEST(ValidateRegulatorsConfigTest, Configuration)
792{
793 json configurationFile = validConfigFile;
794 configurationFile["chassis"][0]["devices"][0]["configuration"]["comments"]
795 [0] = "Set rail to 1.25V using standard rule";
796 configurationFile["chassis"][0]["devices"][0]["configuration"]["volts"] =
797 1.25;
798 configurationFile["chassis"][0]["devices"][0]["configuration"]["rule_id"] =
799 "set_voltage_rule";
800 // Valid: test configuration with property rule_id and with no actions.
801 {
802 json configFile = configurationFile;
Bob King78793102020-03-13 13:16:09 +0800803 configFile["chassis"][0]["devices"][0]["configuration"]["comments"][1] =
804 "test multiple array elements in comments.";
Bob King4c67a3a2020-02-07 09:48:11 +0800805 EXPECT_JSON_VALID(configFile);
806 }
807 // Valid: test configuration with property actions and with no rule_id.
808 {
809 json configFile = configurationFile;
810 configFile["chassis"][0]["devices"][0]["configuration"].erase(
811 "rule_id");
812 configFile["chassis"][0]["devices"][0]["configuration"]["actions"][0]
813 ["compare_presence"]["fru"] =
814 "/system/chassis/motherboard/cpu3";
815 configFile["chassis"][0]["devices"][0]["configuration"]["actions"][0]
816 ["compare_presence"]["value"] = true;
817 EXPECT_JSON_VALID(configFile);
818 }
819 // Valid: comments not specified (optional property).
820 {
821 json configFile = configurationFile;
822 configFile["chassis"][0]["devices"][0]["configuration"].erase(
823 "comments");
824 EXPECT_JSON_VALID(configFile);
825 }
826 // Valid: volts not specified (optional property).
827 {
828 json configFile = configurationFile;
829 configFile["chassis"][0]["devices"][0]["configuration"].erase("volts");
830 EXPECT_JSON_VALID(configFile);
831 }
832 // Valid: configuration is property of a rail (vs. a device).
833 {
834 json configFile = validConfigFile;
835 configFile["chassis"][0]["devices"][0]["rails"][0]["configuration"]
836 ["comments"][0] = "Set rail to 1.25V using standard rule";
837 configFile["chassis"][0]["devices"][0]["rails"][0]["configuration"]
838 ["volts"] = 1.25;
839 configFile["chassis"][0]["devices"][0]["rails"][0]["configuration"]
840 ["rule_id"] = "set_voltage_rule";
841 EXPECT_JSON_VALID(configFile);
842 }
843 // Invalid: comments property has wrong data type (not an array).
844 {
845 json configFile = configurationFile;
846 configFile["chassis"][0]["devices"][0]["configuration"]["comments"] = 1;
847 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800848 "1 is not of type 'array'");
Bob King4c67a3a2020-02-07 09:48:11 +0800849 }
850 // Invalid: test configuration with both actions and rule_id properties.
851 {
852 json configFile = configurationFile;
853 configFile["chassis"][0]["devices"][0]["configuration"]["actions"][0]
854 ["compare_presence"]["fru"] =
855 "/system/chassis/motherboard/cpu3";
856 configFile["chassis"][0]["devices"][0]["configuration"]["actions"][0]
857 ["compare_presence"]["value"] = true;
858 EXPECT_JSON_INVALID(
859 configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800860 "{'actions': [{'compare_presence': {'fru': "
861 "'/system/chassis/motherboard/cpu3', 'value': True}}], 'comments': "
862 "['Set rail to 1.25V using standard rule'], 'rule_id': "
863 "'set_voltage_rule', 'volts': 1.25} is valid under each of "
864 "{'required': ['actions']}, {'required': ['rule_id']}");
Bob King4c67a3a2020-02-07 09:48:11 +0800865 }
866 // Invalid: test configuration with no rule_id and actions.
867 {
868 json configFile = configurationFile;
869 configFile["chassis"][0]["devices"][0]["configuration"].erase(
870 "rule_id");
871 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800872 "'rule_id' is a required property");
Bob King4c67a3a2020-02-07 09:48:11 +0800873 }
874 // Invalid: test configuration with property volts wrong type.
875 {
876 json configFile = configurationFile;
877 configFile["chassis"][0]["devices"][0]["configuration"]["volts"] = true;
878 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800879 "True is not of type 'number'");
Bob King4c67a3a2020-02-07 09:48:11 +0800880 }
881 // Invalid: test configuration with property rule_id wrong type.
882 {
883 json configFile = configurationFile;
884 configFile["chassis"][0]["devices"][0]["configuration"]["rule_id"] =
885 true;
886 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800887 "True is not of type 'string'");
Bob King4c67a3a2020-02-07 09:48:11 +0800888 }
889 // Invalid: test configuration with property actions wrong type.
890 {
891 json configFile = configurationFile;
892 configFile["chassis"][0]["devices"][0]["configuration"].erase(
893 "rule_id");
894 configFile["chassis"][0]["devices"][0]["configuration"]["actions"] =
895 true;
896 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800897 "True is not of type 'array'");
Bob King4c67a3a2020-02-07 09:48:11 +0800898 }
899 // Invalid: test configuration with property comments empty array.
900 {
901 json configFile = configurationFile;
902 configFile["chassis"][0]["devices"][0]["configuration"]["comments"] =
903 json::array();
904 EXPECT_JSON_INVALID(configFile, "Validation failed.",
905 "[] is too short");
906 }
907 // Invalid: test configuration with property rule_id wrong format.
908 {
909 json configFile = configurationFile;
910 configFile["chassis"][0]["devices"][0]["configuration"]["rule_id"] =
911 "id!";
912 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800913 "'id!' does not match '^[A-Za-z0-9_]+$'");
Bob King4c67a3a2020-02-07 09:48:11 +0800914 }
915 // Invalid: test configuration with property actions empty array.
916 {
917 json configFile = configurationFile;
918 configFile["chassis"][0]["devices"][0]["configuration"].erase(
919 "rule_id");
920 configFile["chassis"][0]["devices"][0]["configuration"]["actions"] =
921 json::array();
922 EXPECT_JSON_INVALID(configFile, "Validation failed.",
923 "[] is too short");
924 }
925}
Bob Kinga2ba2df2020-02-04 14:38:44 +0800926TEST(ValidateRegulatorsConfigTest, Device)
927{
928
929 // Valid: test devices.
930 {
931 json configFile = validConfigFile;
932 EXPECT_JSON_VALID(configFile);
933 }
934 // Valid: test devices with required properties.
935 {
936 json configFile = validConfigFile;
937 configFile["chassis"][0]["devices"][0].erase("comments");
938 configFile["chassis"][0]["devices"][0].erase("presence_detection");
939 configFile["chassis"][0]["devices"][0].erase("configuration");
940 configFile["chassis"][0]["devices"][0].erase("rails");
941 EXPECT_JSON_VALID(configFile);
942 }
943 // Invalid: test devices with no id.
944 {
945 json configFile = validConfigFile;
946 configFile["chassis"][0]["devices"][0].erase("id");
947 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800948 "'id' is a required property");
Bob Kinga2ba2df2020-02-04 14:38:44 +0800949 }
950 // Invalid: test devices with no is_regulator.
951 {
952 json configFile = validConfigFile;
953 configFile["chassis"][0]["devices"][0].erase("is_regulator");
954 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800955 "'is_regulator' is a required property");
Bob Kinga2ba2df2020-02-04 14:38:44 +0800956 }
957 // Invalid: test devices with no fru.
958 {
959 json configFile = validConfigFile;
960 configFile["chassis"][0]["devices"][0].erase("fru");
961 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800962 "'fru' is a required property");
Bob Kinga2ba2df2020-02-04 14:38:44 +0800963 }
964 // Invalid: test devices with no i2c_interface.
965 {
966 json configFile = validConfigFile;
967 configFile["chassis"][0]["devices"][0].erase("i2c_interface");
968 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800969 "'i2c_interface' is a required property");
Bob Kinga2ba2df2020-02-04 14:38:44 +0800970 }
971 // Invalid: test devices with property comments wrong type.
972 {
973 json configFile = validConfigFile;
974 configFile["chassis"][0]["devices"][0]["comments"] = true;
975 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800976 "True is not of type 'array'");
Bob Kinga2ba2df2020-02-04 14:38:44 +0800977 }
978 // Invalid: test devices with property id wrong type.
979 {
980 json configFile = validConfigFile;
981 configFile["chassis"][0]["devices"][0]["id"] = true;
982 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800983 "True is not of type 'string'");
Bob Kinga2ba2df2020-02-04 14:38:44 +0800984 }
985 // Invalid: test devices with property is_regulator wrong type.
986 {
987 json configFile = validConfigFile;
988 configFile["chassis"][0]["devices"][0]["is_regulator"] = 1;
989 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800990 "1 is not of type 'boolean'");
Bob Kinga2ba2df2020-02-04 14:38:44 +0800991 }
992 // Invalid: test devices with property fru wrong type.
993 {
994 json configFile = validConfigFile;
995 configFile["chassis"][0]["devices"][0]["fru"] = true;
996 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +0800997 "True is not of type 'string'");
Bob Kinga2ba2df2020-02-04 14:38:44 +0800998 }
999 // Invalid: test devices with property i2c_interface wrong type.
1000 {
1001 json configFile = validConfigFile;
1002 configFile["chassis"][0]["devices"][0]["i2c_interface"] = true;
1003 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001004 "True is not of type 'object'");
Bob Kinga2ba2df2020-02-04 14:38:44 +08001005 }
1006 // Invalid: test devices with property presence_detection wrong
1007 // type.
1008 {
1009 json configFile = validConfigFile;
1010 configFile["chassis"][0]["devices"][0]["presence_detection"] = true;
1011 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001012 "True is not of type 'object'");
Bob Kinga2ba2df2020-02-04 14:38:44 +08001013 }
1014 // Invalid: test devices with property configuration wrong type.
1015 {
1016 json configFile = validConfigFile;
1017 configFile["chassis"][0]["devices"][0]["configuration"] = true;
1018 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001019 "True is not of type 'object'");
Bob Kinga2ba2df2020-02-04 14:38:44 +08001020 }
1021 // Invalid: test devices with property rails wrong type.
1022 {
1023 json configFile = validConfigFile;
1024 configFile["chassis"][0]["devices"][0]["rails"] = true;
1025 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001026 "True is not of type 'array'");
Bob Kinga2ba2df2020-02-04 14:38:44 +08001027 }
1028 // Invalid: test devices with property comments empty array.
1029 {
1030 json configFile = validConfigFile;
1031 configFile["chassis"][0]["devices"][0]["comments"] = json::array();
1032 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1033 "[] is too short");
1034 }
1035 // Invalid: test devices with property fru length less than 1.
1036 {
1037 json configFile = validConfigFile;
1038 configFile["chassis"][0]["devices"][0]["fru"] = "";
1039 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001040 "'' is too short");
Bob Kinga2ba2df2020-02-04 14:38:44 +08001041 }
1042 // Invalid: test devices with property id wrong format.
1043 {
1044 json configFile = validConfigFile;
1045 configFile["chassis"][0]["devices"][0]["id"] = "id#";
1046 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001047 "'id#' does not match '^[A-Za-z0-9_]+$'");
Bob Kinga2ba2df2020-02-04 14:38:44 +08001048 }
1049 // Invalid: test devices with property rails empty array.
1050 {
1051 json configFile = validConfigFile;
1052 configFile["chassis"][0]["devices"][0]["rails"] = json::array();
1053 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1054 "[] is too short");
1055 }
1056}
Bob King4ab8cbb2020-01-21 11:10:48 +08001057TEST(ValidateRegulatorsConfigTest, I2CCompareBit)
1058{
1059 json i2cCompareBitFile = validConfigFile;
1060 i2cCompareBitFile["rules"][0]["actions"][1]["i2c_compare_bit"]["register"] =
1061 "0xA0";
1062 i2cCompareBitFile["rules"][0]["actions"][1]["i2c_compare_bit"]["position"] =
1063 3;
1064 i2cCompareBitFile["rules"][0]["actions"][1]["i2c_compare_bit"]["value"] = 1;
1065 // Valid: test rule actions i2c_compare_bit.
1066 {
1067 json configFile = i2cCompareBitFile;
1068 EXPECT_JSON_VALID(configFile);
1069 }
1070 // Invalid: test i2c_compare_bit with no register.
1071 {
1072 json configFile = i2cCompareBitFile;
1073 configFile["rules"][0]["actions"][1]["i2c_compare_bit"].erase(
1074 "register");
1075 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001076 "'register' is a required property");
Bob King4ab8cbb2020-01-21 11:10:48 +08001077 }
1078 // Invalid: test i2c_compare_bit with no position.
1079 {
1080 json configFile = i2cCompareBitFile;
1081 configFile["rules"][0]["actions"][1]["i2c_compare_bit"].erase(
1082 "position");
1083 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001084 "'position' is a required property");
Bob King4ab8cbb2020-01-21 11:10:48 +08001085 }
1086 // Invalid: test i2c_compare_bit with no value.
1087 {
1088 json configFile = i2cCompareBitFile;
1089 configFile["rules"][0]["actions"][1]["i2c_compare_bit"].erase("value");
1090 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001091 "'value' is a required property");
Bob King4ab8cbb2020-01-21 11:10:48 +08001092 }
1093 // Invalid: test i2c_compare_bit with register wrong type.
1094 {
1095 json configFile = i2cCompareBitFile;
1096 configFile["rules"][0]["actions"][1]["i2c_compare_bit"]["register"] = 1;
1097 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001098 "1 is not of type 'string'");
Bob King4ab8cbb2020-01-21 11:10:48 +08001099 }
1100 // Invalid: test i2c_compare_bit with register wrong format.
1101 {
1102 json configFile = i2cCompareBitFile;
1103 configFile["rules"][0]["actions"][1]["i2c_compare_bit"]["register"] =
1104 "0xA00";
1105 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001106 "'0xA00' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King4ab8cbb2020-01-21 11:10:48 +08001107 }
1108 // Invalid: test i2c_compare_bit with position wrong type.
1109 {
1110 json configFile = i2cCompareBitFile;
1111 configFile["rules"][0]["actions"][1]["i2c_compare_bit"]["position"] =
1112 3.1;
1113 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001114 "3.1 is not of type 'integer'");
Bob King4ab8cbb2020-01-21 11:10:48 +08001115 }
1116 // Invalid: test i2c_compare_bit with position greater than 7.
1117 {
1118 json configFile = i2cCompareBitFile;
1119 configFile["rules"][0]["actions"][1]["i2c_compare_bit"]["position"] = 8;
1120 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1121 "8 is greater than the maximum of 7");
1122 }
1123 // Invalid: test i2c_compare_bit with position less than 0.
1124 {
1125 json configFile = i2cCompareBitFile;
1126 configFile["rules"][0]["actions"][1]["i2c_compare_bit"]["position"] =
1127 -1;
1128 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1129 "-1 is less than the minimum of 0");
1130 }
1131 // Invalid: test i2c_compare_bit with value wrong type.
1132 {
1133 json configFile = i2cCompareBitFile;
1134 configFile["rules"][0]["actions"][1]["i2c_compare_bit"]["value"] = "1";
1135 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001136 "'1' is not of type 'integer'");
Bob King4ab8cbb2020-01-21 11:10:48 +08001137 }
1138 // Invalid: test i2c_compare_bit with value greater than 1.
1139 {
1140 json configFile = i2cCompareBitFile;
1141 configFile["rules"][0]["actions"][1]["i2c_compare_bit"]["value"] = 2;
1142 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1143 "2 is greater than the maximum of 1");
1144 }
1145 // Invalid: test i2c_compare_bit with value less than 0.
1146 {
1147 json configFile = i2cCompareBitFile;
1148 configFile["rules"][0]["actions"][1]["i2c_compare_bit"]["value"] = -1;
1149 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1150 "-1 is less than the minimum of 0");
1151 }
1152}
Bob King514023d2020-01-21 11:13:05 +08001153TEST(ValidateRegulatorsConfigTest, I2CCompareByte)
1154{
1155 json i2cCompareByteFile = validConfigFile;
1156 i2cCompareByteFile["rules"][0]["actions"][1]["i2c_compare_byte"]
1157 ["register"] = "0x82";
1158 i2cCompareByteFile["rules"][0]["actions"][1]["i2c_compare_byte"]["value"] =
1159 "0x40";
1160 i2cCompareByteFile["rules"][0]["actions"][1]["i2c_compare_byte"]["mask"] =
1161 "0x7F";
1162 // Valid: test i2c_compare_byte with all properties.
1163 {
1164 json configFile = i2cCompareByteFile;
1165 EXPECT_JSON_VALID(configFile);
1166 }
1167 // Valid: test i2c_compare_byte with all required properties.
1168 {
1169 json configFile = i2cCompareByteFile;
1170 configFile["rules"][0]["actions"][1]["i2c_compare_byte"].erase("mask");
1171 EXPECT_JSON_VALID(configFile);
1172 }
1173 // Invalid: test i2c_compare_byte with no register.
1174 {
1175 json configFile = i2cCompareByteFile;
1176 configFile["rules"][0]["actions"][1]["i2c_compare_byte"].erase(
1177 "register");
1178 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001179 "'register' is a required property");
Bob King514023d2020-01-21 11:13:05 +08001180 }
1181 // Invalid: test i2c_compare_byte with no value.
1182 {
1183 json configFile = i2cCompareByteFile;
1184 configFile["rules"][0]["actions"][1]["i2c_compare_byte"].erase("value");
1185 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001186 "'value' is a required property");
Bob King514023d2020-01-21 11:13:05 +08001187 }
1188 // Invalid: test i2c_compare_byte with property register wrong type.
1189 {
1190 json configFile = i2cCompareByteFile;
1191 configFile["rules"][0]["actions"][1]["i2c_compare_byte"]["register"] =
1192 1;
1193 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001194 "1 is not of type 'string'");
Bob King514023d2020-01-21 11:13:05 +08001195 }
1196 // Invalid: test i2c_compare_byte with property value wrong type.
1197 {
1198 json configFile = i2cCompareByteFile;
1199 configFile["rules"][0]["actions"][1]["i2c_compare_byte"]["value"] = 1;
1200 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001201 "1 is not of type 'string'");
Bob King514023d2020-01-21 11:13:05 +08001202 }
1203 // Invalid: test i2c_compare_byte with property mask wrong type.
1204 {
1205 json configFile = i2cCompareByteFile;
1206 configFile["rules"][0]["actions"][1]["i2c_compare_byte"]["mask"] = 1;
1207 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001208 "1 is not of type 'string'");
Bob King514023d2020-01-21 11:13:05 +08001209 }
1210 // Invalid: test i2c_compare_byte with property register more than 2 hex
1211 // digits.
1212 {
1213 json configFile = i2cCompareByteFile;
1214 configFile["rules"][0]["actions"][1]["i2c_compare_byte"]["register"] =
1215 "0x820";
1216 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001217 "'0x820' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King514023d2020-01-21 11:13:05 +08001218 }
1219 // Invalid: test i2c_compare_byte with property value more than 2 hex
1220 // digits.
1221 {
1222 json configFile = i2cCompareByteFile;
1223 configFile["rules"][0]["actions"][1]["i2c_compare_byte"]["value"] =
1224 "0x820";
1225 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001226 "'0x820' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King514023d2020-01-21 11:13:05 +08001227 }
1228 // Invalid: test i2c_compare_byte with property mask more than 2 hex digits.
1229 {
1230 json configFile = i2cCompareByteFile;
1231 configFile["rules"][0]["actions"][1]["i2c_compare_byte"]["mask"] =
1232 "0x820";
1233 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001234 "'0x820' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King514023d2020-01-21 11:13:05 +08001235 }
1236 // Invalid: test i2c_compare_byte with property register less than 2 hex
1237 // digits.
1238 {
1239 json configFile = i2cCompareByteFile;
1240 configFile["rules"][0]["actions"][1]["i2c_compare_byte"]["register"] =
1241 "0x8";
1242 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001243 "'0x8' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King514023d2020-01-21 11:13:05 +08001244 }
1245 // Invalid: test i2c_compare_byte with property value less than 2 hex
1246 // digits.
1247 {
1248 json configFile = i2cCompareByteFile;
1249 configFile["rules"][0]["actions"][1]["i2c_compare_byte"]["value"] =
1250 "0x8";
1251 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001252 "'0x8' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King514023d2020-01-21 11:13:05 +08001253 }
1254 // Invalid: test i2c_compare_byte with property mask less than 2 hex digits.
1255 {
1256 json configFile = i2cCompareByteFile;
1257 configFile["rules"][0]["actions"][1]["i2c_compare_byte"]["mask"] =
1258 "0x8";
1259 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001260 "'0x8' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King514023d2020-01-21 11:13:05 +08001261 }
1262 // Invalid: test i2c_compare_byte with property register no leading prefix.
1263 {
1264 json configFile = i2cCompareByteFile;
1265 configFile["rules"][0]["actions"][1]["i2c_compare_byte"]["register"] =
1266 "82";
1267 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001268 "'82' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King514023d2020-01-21 11:13:05 +08001269 }
1270 // Invalid: test i2c_compare_byte with property value no leading prefix.
1271 {
1272 json configFile = i2cCompareByteFile;
1273 configFile["rules"][0]["actions"][1]["i2c_compare_byte"]["value"] =
1274 "82";
1275 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001276 "'82' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King514023d2020-01-21 11:13:05 +08001277 }
1278 // Invalid: test i2c_compare_byte with property mask no leading prefix.
1279 {
1280 json configFile = i2cCompareByteFile;
1281 configFile["rules"][0]["actions"][1]["i2c_compare_byte"]["mask"] = "82";
1282 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001283 "'82' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King514023d2020-01-21 11:13:05 +08001284 }
1285 // Invalid: test i2c_compare_byte with property register invalid hex digit.
1286 {
1287 json configFile = i2cCompareByteFile;
1288 configFile["rules"][0]["actions"][1]["i2c_compare_byte"]["register"] =
1289 "0xG1";
1290 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001291 "'0xG1' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King514023d2020-01-21 11:13:05 +08001292 }
1293 // Invalid: test i2c_compare_byte with property value invalid hex digit.
1294 {
1295 json configFile = i2cCompareByteFile;
1296 configFile["rules"][0]["actions"][1]["i2c_compare_byte"]["value"] =
1297 "0xG1";
1298 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001299 "'0xG1' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King514023d2020-01-21 11:13:05 +08001300 }
1301 // Invalid: test i2c_compare_byte with property mask invalid hex digit.
1302 {
1303 json configFile = i2cCompareByteFile;
1304 configFile["rules"][0]["actions"][1]["i2c_compare_byte"]["mask"] =
1305 "0xG1";
1306 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001307 "'0xG1' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King514023d2020-01-21 11:13:05 +08001308 }
1309}
Bob Kingfb162bb2020-01-21 11:28:07 +08001310TEST(ValidateRegulatorsConfigTest, I2CCompareBytes)
1311{
1312 json i2cCompareBytesFile = validConfigFile;
1313 i2cCompareBytesFile["rules"][0]["actions"][1]["i2c_compare_bytes"]
1314 ["register"] = "0x82";
1315 i2cCompareBytesFile["rules"][0]["actions"][1]["i2c_compare_bytes"]
1316 ["values"] = {"0x02", "0x73"};
1317 i2cCompareBytesFile["rules"][0]["actions"][1]["i2c_compare_bytes"]
1318 ["masks"] = {"0x7F", "0x7F"};
1319 // Valid: test i2c_compare_bytes.
1320 {
1321 json configFile = i2cCompareBytesFile;
1322 EXPECT_JSON_VALID(configFile);
1323 }
1324 // Valid: test i2c_compare_bytes with all required properties.
1325 {
1326 json configFile = i2cCompareBytesFile;
1327 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"].erase(
1328 "masks");
1329 EXPECT_JSON_VALID(configFile);
1330 }
1331 // Invalid: test i2c_compare_bytes with no register.
1332 {
1333 json configFile = i2cCompareBytesFile;
1334 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"].erase(
1335 "register");
1336 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001337 "'register' is a required property");
Bob Kingfb162bb2020-01-21 11:28:07 +08001338 }
1339 // Invalid: test i2c_compare_bytes with no values.
1340 {
1341 json configFile = i2cCompareBytesFile;
1342 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"].erase(
1343 "values");
1344 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001345 "'values' is a required property");
Bob Kingfb162bb2020-01-21 11:28:07 +08001346 }
1347 // Invalid: test i2c_compare_bytes with property values as empty array.
1348 {
1349 json configFile = i2cCompareBytesFile;
1350 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["values"] =
1351 json::array();
1352 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1353 "[] is too short");
1354 }
1355 // Invalid: test i2c_compare_bytes with property masks as empty array.
1356 {
1357 json configFile = i2cCompareBytesFile;
1358 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["masks"] =
1359 json::array();
1360 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1361 "[] is too short");
1362 }
1363 // Invalid: test i2c_compare_bytes with property register wrong type.
1364 {
1365 json configFile = i2cCompareBytesFile;
1366 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["register"] =
1367 1;
1368 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001369 "1 is not of type 'string'");
Bob Kingfb162bb2020-01-21 11:28:07 +08001370 }
1371 // Invalid: test i2c_compare_bytes with property values wrong type.
1372 {
1373 json configFile = i2cCompareBytesFile;
1374 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["values"] = 1;
1375 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001376 "1 is not of type 'array'");
Bob Kingfb162bb2020-01-21 11:28:07 +08001377 }
1378 // Invalid: test i2c_compare_bytes with property masks wrong type.
1379 {
1380 json configFile = i2cCompareBytesFile;
1381 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["masks"] = 1;
1382 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001383 "1 is not of type 'array'");
Bob Kingfb162bb2020-01-21 11:28:07 +08001384 }
1385 // Invalid: test i2c_compare_bytes with property register more than 2 hex
1386 // digits.
1387 {
1388 json configFile = i2cCompareBytesFile;
1389 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["register"] =
1390 "0x820";
1391 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001392 "'0x820' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob Kingfb162bb2020-01-21 11:28:07 +08001393 }
1394 // Invalid: test i2c_compare_bytes with property values more than 2 hex
1395 // digits.
1396 {
1397 json configFile = i2cCompareBytesFile;
1398 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["values"][0] =
1399 "0x820";
1400 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001401 "'0x820' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob Kingfb162bb2020-01-21 11:28:07 +08001402 }
1403 // Invalid: test i2c_compare_bytes with property masks more than 2 hex
1404 // digits.
1405 {
1406 json configFile = i2cCompareBytesFile;
1407 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["masks"][0] =
1408 "0x820";
1409 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001410 "'0x820' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob Kingfb162bb2020-01-21 11:28:07 +08001411 }
1412 // Invalid: test i2c_compare_bytes with property register less than 2 hex
1413 // digits.
1414 {
1415 json configFile = i2cCompareBytesFile;
1416 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["register"] =
1417 "0x8";
1418 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001419 "'0x8' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob Kingfb162bb2020-01-21 11:28:07 +08001420 }
1421 // Invalid: test i2c_compare_bytes with property values less than 2 hex
1422 // digits.
1423 {
1424 json configFile = i2cCompareBytesFile;
1425 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["values"][0] =
1426 "0x8";
1427 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001428 "'0x8' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob Kingfb162bb2020-01-21 11:28:07 +08001429 }
1430 // Invalid: test i2c_compare_bytes with property masks less than 2 hex
1431 // digits.
1432 {
1433 json configFile = i2cCompareBytesFile;
1434 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["masks"][0] =
1435 "0x8";
1436 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001437 "'0x8' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob Kingfb162bb2020-01-21 11:28:07 +08001438 }
1439 // Invalid: test i2c_compare_bytes with property register no leading prefix.
1440 {
1441 json configFile = i2cCompareBytesFile;
1442 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["register"] =
1443 "82";
1444 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001445 "'82' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob Kingfb162bb2020-01-21 11:28:07 +08001446 }
1447 // Invalid: test i2c_compare_bytes with property values no leading prefix.
1448 {
1449 json configFile = i2cCompareBytesFile;
1450 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["values"][0] =
1451 "82";
1452 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001453 "'82' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob Kingfb162bb2020-01-21 11:28:07 +08001454 }
1455 // Invalid: test i2c_compare_bytes with property masks no leading prefix.
1456 {
1457 json configFile = i2cCompareBytesFile;
1458 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["masks"][0] =
1459 "82";
1460 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001461 "'82' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob Kingfb162bb2020-01-21 11:28:07 +08001462 }
1463 // Invalid: test i2c_compare_bytes with property register invalid hex digit.
1464 {
1465 json configFile = i2cCompareBytesFile;
1466 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["register"] =
1467 "0xG1";
1468 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001469 "'0xG1' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob Kingfb162bb2020-01-21 11:28:07 +08001470 }
1471 // Invalid: test i2c_compare_bytes with property values invalid hex digit.
1472 {
1473 json configFile = i2cCompareBytesFile;
1474 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["values"][0] =
1475 "0xG1";
1476 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001477 "'0xG1' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob Kingfb162bb2020-01-21 11:28:07 +08001478 }
1479 // Invalid: test i2c_compare_bytes with property masks invalid hex digit.
1480 {
1481 json configFile = i2cCompareBytesFile;
1482 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["masks"][0] =
1483 "0xG1";
1484 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001485 "'0xG1' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob Kingfb162bb2020-01-21 11:28:07 +08001486 }
1487}
Bob Kingca93f1f2020-01-31 11:21:16 +08001488TEST(ValidateRegulatorsConfigTest, I2CInterface)
1489{
1490 // Valid: test i2c_interface.
1491 {
1492 json configFile = validConfigFile;
1493 EXPECT_JSON_VALID(configFile);
1494 }
1495 // Invalid: testi2c_interface with no bus.
1496 {
1497 json configFile = validConfigFile;
1498 configFile["chassis"][0]["devices"][0]["i2c_interface"].erase("bus");
1499 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001500 "'bus' is a required property");
Bob Kingca93f1f2020-01-31 11:21:16 +08001501 }
1502 // Invalid: test i2c_interface with no address.
1503 {
1504 json configFile = validConfigFile;
1505 configFile["chassis"][0]["devices"][0]["i2c_interface"].erase(
1506 "address");
1507 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001508 "'address' is a required property");
Bob Kingca93f1f2020-01-31 11:21:16 +08001509 }
1510 // Invalid: test i2c_interface with property bus wrong type.
1511 {
1512 json configFile = validConfigFile;
1513 configFile["chassis"][0]["devices"][0]["i2c_interface"]["bus"] = true;
1514 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001515 "True is not of type 'integer'");
Bob Kingca93f1f2020-01-31 11:21:16 +08001516 }
1517 // Invalid: test i2c_interface with property address wrong
1518 // type.
1519 {
1520 json configFile = validConfigFile;
1521 configFile["chassis"][0]["devices"][0]["i2c_interface"]["address"] =
1522 true;
1523 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001524 "True is not of type 'string'");
Bob Kingca93f1f2020-01-31 11:21:16 +08001525 }
1526 // Invalid: test i2c_interface with property bus less than
1527 // 0.
1528 {
1529 json configFile = validConfigFile;
1530 configFile["chassis"][0]["devices"][0]["i2c_interface"]["bus"] = -1;
1531 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1532 "-1 is less than the minimum of 0");
1533 }
1534 // Invalid: test i2c_interface with property address wrong
1535 // format.
1536 {
1537 json configFile = validConfigFile;
1538 configFile["chassis"][0]["devices"][0]["i2c_interface"]["address"] =
1539 "0x700";
1540 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001541 "'0x700' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob Kingca93f1f2020-01-31 11:21:16 +08001542 }
1543}
Bob King188db7d2020-01-31 13:01:01 +08001544TEST(ValidateRegulatorsConfigTest, I2CWriteBit)
1545{
1546 json i2cWriteBitFile = validConfigFile;
1547 i2cWriteBitFile["rules"][0]["actions"][1]["i2c_write_bit"]["register"] =
1548 "0xA0";
1549 i2cWriteBitFile["rules"][0]["actions"][1]["i2c_write_bit"]["position"] = 3;
1550 i2cWriteBitFile["rules"][0]["actions"][1]["i2c_write_bit"]["value"] = 1;
1551 // Valid: test rule actions i2c_write_bit.
1552 {
1553 json configFile = i2cWriteBitFile;
1554 EXPECT_JSON_VALID(configFile);
1555 }
1556 // Invalid: test i2c_write_bit with no register.
1557 {
1558 json configFile = i2cWriteBitFile;
1559 configFile["rules"][0]["actions"][1]["i2c_write_bit"].erase("register");
1560 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001561 "'register' is a required property");
Bob King188db7d2020-01-31 13:01:01 +08001562 }
1563 // Invalid: test i2c_write_bit with no position.
1564 {
1565 json configFile = i2cWriteBitFile;
1566 configFile["rules"][0]["actions"][1]["i2c_write_bit"].erase("position");
1567 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001568 "'position' is a required property");
Bob King188db7d2020-01-31 13:01:01 +08001569 }
1570 // Invalid: test i2c_write_bit with no value.
1571 {
1572 json configFile = i2cWriteBitFile;
1573 configFile["rules"][0]["actions"][1]["i2c_write_bit"].erase("value");
1574 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001575 "'value' is a required property");
Bob King188db7d2020-01-31 13:01:01 +08001576 }
1577 // Invalid: test i2c_write_bit with register wrong type.
1578 {
1579 json configFile = i2cWriteBitFile;
1580 configFile["rules"][0]["actions"][1]["i2c_write_bit"]["register"] = 1;
1581 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001582 "1 is not of type 'string'");
Bob King188db7d2020-01-31 13:01:01 +08001583 }
1584 // Invalid: test i2c_write_bit with register wrong format.
1585 {
1586 json configFile = i2cWriteBitFile;
1587 configFile["rules"][0]["actions"][1]["i2c_write_bit"]["register"] =
1588 "0xA00";
1589 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001590 "'0xA00' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08001591 }
1592 // Invalid: test i2c_write_bit with position wrong type.
1593 {
1594 json configFile = i2cWriteBitFile;
1595 configFile["rules"][0]["actions"][1]["i2c_write_bit"]["position"] = 3.1;
1596 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001597 "3.1 is not of type 'integer'");
Bob King188db7d2020-01-31 13:01:01 +08001598 }
1599 // Invalid: test i2c_write_bit with position greater than 7.
1600 {
1601 json configFile = i2cWriteBitFile;
1602 configFile["rules"][0]["actions"][1]["i2c_write_bit"]["position"] = 8;
1603 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1604 "8 is greater than the maximum of 7");
1605 }
1606 // Invalid: test i2c_write_bit with position less than 0.
1607 {
1608 json configFile = i2cWriteBitFile;
1609 configFile["rules"][0]["actions"][1]["i2c_write_bit"]["position"] = -1;
1610 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1611 "-1 is less than the minimum of 0");
1612 }
1613 // Invalid: test i2c_write_bit with value wrong type.
1614 {
1615 json configFile = i2cWriteBitFile;
1616 configFile["rules"][0]["actions"][1]["i2c_write_bit"]["value"] = "1";
1617 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001618 "'1' is not of type 'integer'");
Bob King188db7d2020-01-31 13:01:01 +08001619 }
1620 // Invalid: test i2c_write_bit with value greater than 1.
1621 {
1622 json configFile = i2cWriteBitFile;
1623 configFile["rules"][0]["actions"][1]["i2c_write_bit"]["value"] = 2;
1624 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1625 "2 is greater than the maximum of 1");
1626 }
1627 // Invalid: test i2c_write_bit with value less than 0.
1628 {
1629 json configFile = i2cWriteBitFile;
1630 configFile["rules"][0]["actions"][1]["i2c_write_bit"]["value"] = -1;
1631 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1632 "-1 is less than the minimum of 0");
1633 }
1634}
1635TEST(ValidateRegulatorsConfigTest, I2CWriteByte)
1636{
1637 json i2cWriteByteFile = validConfigFile;
1638 i2cWriteByteFile["rules"][0]["actions"][1]["i2c_write_byte"]["register"] =
1639 "0x82";
1640 i2cWriteByteFile["rules"][0]["actions"][1]["i2c_write_byte"]["value"] =
1641 "0x40";
1642 i2cWriteByteFile["rules"][0]["actions"][1]["i2c_write_byte"]["mask"] =
1643 "0x7F";
1644 // Valid: test i2c_write_byte with all properties.
1645 {
1646 json configFile = i2cWriteByteFile;
1647 EXPECT_JSON_VALID(configFile);
1648 }
1649 // Valid: test i2c_write_byte with all required properties.
1650 {
1651 json configFile = i2cWriteByteFile;
1652 configFile["rules"][0]["actions"][1]["i2c_write_byte"].erase("mask");
1653 EXPECT_JSON_VALID(configFile);
1654 }
1655 // Invalid: test i2c_write_byte with no register.
1656 {
1657 json configFile = i2cWriteByteFile;
1658 configFile["rules"][0]["actions"][1]["i2c_write_byte"].erase(
1659 "register");
1660 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001661 "'register' is a required property");
Bob King188db7d2020-01-31 13:01:01 +08001662 }
1663 // Invalid: test i2c_write_byte with no value.
1664 {
1665 json configFile = i2cWriteByteFile;
1666 configFile["rules"][0]["actions"][1]["i2c_write_byte"].erase("value");
1667 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001668 "'value' is a required property");
Bob King188db7d2020-01-31 13:01:01 +08001669 }
1670 // Invalid: test i2c_write_byte with property register wrong type.
1671 {
1672 json configFile = i2cWriteByteFile;
1673 configFile["rules"][0]["actions"][1]["i2c_write_byte"]["register"] = 1;
1674 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001675 "1 is not of type 'string'");
Bob King188db7d2020-01-31 13:01:01 +08001676 }
1677 // Invalid: test i2c_write_byte with property value wrong type.
1678 {
1679 json configFile = i2cWriteByteFile;
1680 configFile["rules"][0]["actions"][1]["i2c_write_byte"]["value"] = 1;
1681 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001682 "1 is not of type 'string'");
Bob King188db7d2020-01-31 13:01:01 +08001683 }
1684 // Invalid: test i2c_write_byte with property mask wrong type.
1685 {
1686 json configFile = i2cWriteByteFile;
1687 configFile["rules"][0]["actions"][1]["i2c_write_byte"]["mask"] = 1;
1688 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001689 "1 is not of type 'string'");
Bob King188db7d2020-01-31 13:01:01 +08001690 }
1691 // Invalid: test i2c_write_byte with property register more than 2 hex
1692 // digits.
1693 {
1694 json configFile = i2cWriteByteFile;
1695 configFile["rules"][0]["actions"][1]["i2c_write_byte"]["register"] =
1696 "0x820";
1697 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001698 "'0x820' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08001699 }
1700 // Invalid: test i2c_write_byte with property value more than 2 hex
1701 // digits.
1702 {
1703 json configFile = i2cWriteByteFile;
1704 configFile["rules"][0]["actions"][1]["i2c_write_byte"]["value"] =
1705 "0x820";
1706 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001707 "'0x820' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08001708 }
1709 // Invalid: test i2c_write_byte with property mask more than 2 hex digits.
1710 {
1711 json configFile = i2cWriteByteFile;
1712 configFile["rules"][0]["actions"][1]["i2c_write_byte"]["mask"] =
1713 "0x820";
1714 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001715 "'0x820' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08001716 }
1717 // Invalid: test i2c_write_byte with property register less than 2 hex
1718 // digits.
1719 {
1720 json configFile = i2cWriteByteFile;
1721 configFile["rules"][0]["actions"][1]["i2c_write_byte"]["register"] =
1722 "0x8";
1723 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001724 "'0x8' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08001725 }
1726 // Invalid: test i2c_write_byte with property value less than 2 hex
1727 // digits.
1728 {
1729 json configFile = i2cWriteByteFile;
1730 configFile["rules"][0]["actions"][1]["i2c_write_byte"]["value"] = "0x8";
1731 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001732 "'0x8' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08001733 }
1734 // Invalid: test i2c_write_byte with property mask less than 2 hex digits.
1735 {
1736 json configFile = i2cWriteByteFile;
1737 configFile["rules"][0]["actions"][1]["i2c_write_byte"]["mask"] = "0x8";
1738 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001739 "'0x8' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08001740 }
1741 // Invalid: test i2c_write_byte with property register no leading prefix.
1742 {
1743 json configFile = i2cWriteByteFile;
1744 configFile["rules"][0]["actions"][1]["i2c_write_byte"]["register"] =
1745 "82";
1746 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001747 "'82' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08001748 }
1749 // Invalid: test i2c_write_byte with property value no leading prefix.
1750 {
1751 json configFile = i2cWriteByteFile;
1752 configFile["rules"][0]["actions"][1]["i2c_write_byte"]["value"] = "82";
1753 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001754 "'82' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08001755 }
1756 // Invalid: test i2c_write_byte with property mask no leading prefix.
1757 {
1758 json configFile = i2cWriteByteFile;
1759 configFile["rules"][0]["actions"][1]["i2c_write_byte"]["mask"] = "82";
1760 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001761 "'82' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08001762 }
1763 // Invalid: test i2c_write_byte with property register invalid hex digit.
1764 {
1765 json configFile = i2cWriteByteFile;
1766 configFile["rules"][0]["actions"][1]["i2c_write_byte"]["register"] =
1767 "0xG1";
1768 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001769 "'0xG1' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08001770 }
1771 // Invalid: test i2c_write_byte with property value invalid hex digit.
1772 {
1773 json configFile = i2cWriteByteFile;
1774 configFile["rules"][0]["actions"][1]["i2c_write_byte"]["value"] =
1775 "0xG1";
1776 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001777 "'0xG1' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08001778 }
1779 // Invalid: test i2c_write_byte with property mask invalid hex digit.
1780 {
1781 json configFile = i2cWriteByteFile;
1782 configFile["rules"][0]["actions"][1]["i2c_write_byte"]["mask"] = "0xG1";
1783 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001784 "'0xG1' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08001785 }
1786}
1787TEST(ValidateRegulatorsConfigTest, I2CWriteBytes)
1788{
1789 json i2cWriteBytesFile = validConfigFile;
1790 i2cWriteBytesFile["rules"][0]["actions"][1]["i2c_write_bytes"]["register"] =
1791 "0x82";
1792 i2cWriteBytesFile["rules"][0]["actions"][1]["i2c_write_bytes"]["values"] = {
1793 "0x02", "0x73"};
1794 i2cWriteBytesFile["rules"][0]["actions"][1]["i2c_write_bytes"]["masks"] = {
1795 "0x7F", "0x7F"};
1796 // Valid: test i2c_write_bytes.
1797 {
1798 json configFile = i2cWriteBytesFile;
1799 EXPECT_JSON_VALID(configFile);
1800 }
1801 // Valid: test i2c_write_bytes with all required properties.
1802 {
1803 json configFile = i2cWriteBytesFile;
1804 configFile["rules"][0]["actions"][1]["i2c_write_bytes"].erase("masks");
1805 EXPECT_JSON_VALID(configFile);
1806 }
1807 // Invalid: test i2c_write_bytes with no register.
1808 {
1809 json configFile = i2cWriteBytesFile;
1810 configFile["rules"][0]["actions"][1]["i2c_write_bytes"].erase(
1811 "register");
1812 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001813 "'register' is a required property");
Bob King188db7d2020-01-31 13:01:01 +08001814 }
1815 // Invalid: test i2c_write_bytes with no values.
1816 {
1817 json configFile = i2cWriteBytesFile;
1818 configFile["rules"][0]["actions"][1]["i2c_write_bytes"].erase("values");
1819 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001820 "'values' is a required property");
Bob King188db7d2020-01-31 13:01:01 +08001821 }
1822 // Invalid: test i2c_write_bytes with property values as empty array.
1823 {
1824 json configFile = i2cWriteBytesFile;
1825 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["values"] =
1826 json::array();
1827 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1828 "[] is too short");
1829 }
1830 // Invalid: test i2c_write_bytes with property masks as empty array.
1831 {
1832 json configFile = i2cWriteBytesFile;
1833 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["masks"] =
1834 json::array();
1835 EXPECT_JSON_INVALID(configFile, "Validation failed.",
1836 "[] is too short");
1837 }
1838 // Invalid: test i2c_write_bytes with property register wrong type.
1839 {
1840 json configFile = i2cWriteBytesFile;
1841 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["register"] = 1;
1842 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001843 "1 is not of type 'string'");
Bob King188db7d2020-01-31 13:01:01 +08001844 }
1845 // Invalid: test i2c_write_bytes with property values wrong type.
1846 {
1847 json configFile = i2cWriteBytesFile;
1848 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["values"] = 1;
1849 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001850 "1 is not of type 'array'");
Bob King188db7d2020-01-31 13:01:01 +08001851 }
1852 // Invalid: test i2c_write_bytes with property masks wrong type.
1853 {
1854 json configFile = i2cWriteBytesFile;
1855 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["masks"] = 1;
1856 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001857 "1 is not of type 'array'");
Bob King188db7d2020-01-31 13:01:01 +08001858 }
1859 // Invalid: test i2c_write_bytes with property register more than 2 hex
1860 // digits.
1861 {
1862 json configFile = i2cWriteBytesFile;
1863 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["register"] =
1864 "0x820";
1865 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001866 "'0x820' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08001867 }
1868 // Invalid: test i2c_write_bytes with property values more than 2 hex
1869 // digits.
1870 {
1871 json configFile = i2cWriteBytesFile;
1872 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["values"][0] =
1873 "0x820";
1874 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001875 "'0x820' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08001876 }
1877 // Invalid: test i2c_write_bytes with property masks more than 2 hex
1878 // digits.
1879 {
1880 json configFile = i2cWriteBytesFile;
1881 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["masks"][0] =
1882 "0x820";
1883 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001884 "'0x820' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08001885 }
1886 // Invalid: test i2c_write_bytes with property register less than 2 hex
1887 // digits.
1888 {
1889 json configFile = i2cWriteBytesFile;
1890 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["register"] =
1891 "0x8";
1892 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001893 "'0x8' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08001894 }
1895 // Invalid: test i2c_write_bytes with property values less than 2 hex
1896 // digits.
1897 {
1898 json configFile = i2cWriteBytesFile;
1899 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["values"][0] =
1900 "0x8";
1901 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001902 "'0x8' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08001903 }
1904 // Invalid: test i2c_write_bytes with property masks less than 2 hex
1905 // digits.
1906 {
1907 json configFile = i2cWriteBytesFile;
1908 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["masks"][0] =
1909 "0x8";
1910 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001911 "'0x8' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08001912 }
1913 // Invalid: test i2c_write_bytes with property register no leading prefix.
1914 {
1915 json configFile = i2cWriteBytesFile;
1916 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["register"] =
1917 "82";
1918 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001919 "'82' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08001920 }
1921 // Invalid: test i2c_write_bytes with property values no leading prefix.
1922 {
1923 json configFile = i2cWriteBytesFile;
1924 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["values"][0] =
1925 "82";
1926 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001927 "'82' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08001928 }
1929 // Invalid: test i2c_write_bytes with property masks no leading prefix.
1930 {
1931 json configFile = i2cWriteBytesFile;
1932 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["masks"][0] =
1933 "82";
1934 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001935 "'82' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08001936 }
1937 // Invalid: test i2c_write_bytes with property register invalid hex digit.
1938 {
1939 json configFile = i2cWriteBytesFile;
1940 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["register"] =
1941 "0xG1";
1942 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001943 "'0xG1' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08001944 }
1945 // Invalid: test i2c_write_bytes with property values invalid hex digit.
1946 {
1947 json configFile = i2cWriteBytesFile;
1948 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["values"][0] =
1949 "0xG1";
1950 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001951 "'0xG1' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08001952 }
1953 // Invalid: test i2c_write_bytes with property masks invalid hex digit.
1954 {
1955 json configFile = i2cWriteBytesFile;
1956 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["masks"][0] =
1957 "0xG1";
1958 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001959 "'0xG1' does not match '^0x[0-9A-Fa-f]{2}$'");
Bob King188db7d2020-01-31 13:01:01 +08001960 }
1961}
Bob Kingead0b052020-01-21 11:29:03 +08001962TEST(ValidateRegulatorsConfigTest, If)
1963{
1964 json ifFile = validConfigFile;
Bob King2d27dcf2020-02-11 15:00:50 +08001965 ifFile["rules"][2]["actions"][0]["if"]["condition"]["run_rule"] =
1966 "set_voltage_rule";
1967 ifFile["rules"][2]["actions"][0]["if"]["then"][0]["run_rule"] =
1968 "read_sensors_rule";
1969 ifFile["rules"][2]["actions"][0]["if"]["else"][0]["run_rule"] =
1970 "read_sensors_rule";
1971 ifFile["rules"][2]["id"] = "rule_if";
Bob Kingead0b052020-01-21 11:29:03 +08001972 // Valid: test if.
1973 {
1974 json configFile = ifFile;
1975 EXPECT_JSON_VALID(configFile);
1976 }
1977 // Valid: test if with required properties.
1978 {
1979 json configFile = ifFile;
Bob King2d27dcf2020-02-11 15:00:50 +08001980 configFile["rules"][2]["actions"][0]["if"].erase("else");
Bob Kingead0b052020-01-21 11:29:03 +08001981 EXPECT_JSON_VALID(configFile);
1982 }
1983 // Invalid: test if with no property condition.
1984 {
1985 json configFile = ifFile;
Bob King2d27dcf2020-02-11 15:00:50 +08001986 configFile["rules"][2]["actions"][0]["if"].erase("condition");
Bob Kingead0b052020-01-21 11:29:03 +08001987 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001988 "'condition' is a required property");
Bob Kingead0b052020-01-21 11:29:03 +08001989 }
1990 // Invalid: test if with no property then.
1991 {
1992 json configFile = ifFile;
Bob King2d27dcf2020-02-11 15:00:50 +08001993 configFile["rules"][2]["actions"][0]["if"].erase("then");
Bob Kingead0b052020-01-21 11:29:03 +08001994 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08001995 "'then' is a required property");
Bob Kingead0b052020-01-21 11:29:03 +08001996 }
1997 // Invalid: test if with property then empty array.
1998 {
1999 json configFile = ifFile;
Bob King2d27dcf2020-02-11 15:00:50 +08002000 configFile["rules"][2]["actions"][0]["if"]["then"] = json::array();
Bob Kingead0b052020-01-21 11:29:03 +08002001 EXPECT_JSON_INVALID(configFile, "Validation failed.",
2002 "[] is too short");
2003 }
2004 // Invalid: test if with property else empty array.
2005 {
2006 json configFile = ifFile;
Bob King2d27dcf2020-02-11 15:00:50 +08002007 configFile["rules"][2]["actions"][0]["if"]["else"] = json::array();
Bob Kingead0b052020-01-21 11:29:03 +08002008 EXPECT_JSON_INVALID(configFile, "Validation failed.",
2009 "[] is too short");
2010 }
2011 // Invalid: test if with property condition wrong type.
2012 {
2013 json configFile = ifFile;
Bob King2d27dcf2020-02-11 15:00:50 +08002014 configFile["rules"][2]["actions"][0]["if"]["condition"] = 1;
Bob Kingead0b052020-01-21 11:29:03 +08002015 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002016 "1 is not of type 'object'");
Bob Kingead0b052020-01-21 11:29:03 +08002017 }
2018 // Invalid: test if with property then wrong type.
2019 {
2020 json configFile = ifFile;
Bob King2d27dcf2020-02-11 15:00:50 +08002021 configFile["rules"][2]["actions"][0]["if"]["then"] = 1;
Bob Kingead0b052020-01-21 11:29:03 +08002022 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002023 "1 is not of type 'array'");
Bob Kingead0b052020-01-21 11:29:03 +08002024 }
2025 // Invalid: test if with property else wrong type.
2026 {
2027 json configFile = ifFile;
Bob King2d27dcf2020-02-11 15:00:50 +08002028 configFile["rules"][2]["actions"][0]["if"]["else"] = 1;
Bob Kingead0b052020-01-21 11:29:03 +08002029 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002030 "1 is not of type 'array'");
Bob Kingead0b052020-01-21 11:29:03 +08002031 }
2032}
Bob Kingbfe9fe72020-01-21 11:29:57 +08002033TEST(ValidateRegulatorsConfigTest, Not)
2034{
2035 json notFile = validConfigFile;
2036 notFile["rules"][0]["actions"][1]["not"]["i2c_compare_byte"]["register"] =
2037 "0xA0";
2038 notFile["rules"][0]["actions"][1]["not"]["i2c_compare_byte"]["value"] =
2039 "0xFF";
2040 // Valid: test not.
2041 {
2042 json configFile = notFile;
2043 EXPECT_JSON_VALID(configFile);
2044 }
2045 // Invalid: test not with wrong type.
2046 {
2047 json configFile = notFile;
2048 configFile["rules"][0]["actions"][1]["not"] = 1;
2049 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002050 "1 is not of type 'object'");
Bob Kingbfe9fe72020-01-21 11:29:57 +08002051 }
2052}
Bob Kingcfc29d02020-01-21 11:30:50 +08002053TEST(ValidateRegulatorsConfigTest, Or)
2054{
2055 json orFile = validConfigFile;
2056 orFile["rules"][0]["actions"][1]["or"][0]["i2c_compare_byte"]["register"] =
2057 "0xA0";
2058 orFile["rules"][0]["actions"][1]["or"][0]["i2c_compare_byte"]["value"] =
2059 "0x00";
2060 orFile["rules"][0]["actions"][1]["or"][1]["i2c_compare_byte"]["register"] =
2061 "0xA1";
2062 orFile["rules"][0]["actions"][1]["or"][1]["i2c_compare_byte"]["value"] =
2063 "0x00";
2064 // Valid: test or.
2065 {
2066 json configFile = orFile;
2067 EXPECT_JSON_VALID(configFile);
2068 }
2069 // Invalid: test or with empty array.
2070 {
2071 json configFile = orFile;
2072 configFile["rules"][0]["actions"][1]["or"] = json::array();
2073 EXPECT_JSON_INVALID(configFile, "Validation failed.",
2074 "[] is too short");
2075 }
2076 // Invalid: test or with wrong type.
2077 {
2078 json configFile = orFile;
2079 configFile["rules"][0]["actions"][1]["or"] = 1;
2080 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002081 "1 is not of type 'array'");
Bob Kingcfc29d02020-01-21 11:30:50 +08002082 }
2083}
Bob Kingd6618092020-01-21 11:31:46 +08002084TEST(ValidateRegulatorsConfigTest, PmbusReadSensor)
2085{
2086 json pmbusReadSensorFile = validConfigFile;
2087 pmbusReadSensorFile["rules"][0]["actions"][1]["pmbus_read_sensor"]["type"] =
2088 "vout";
2089 pmbusReadSensorFile["rules"][0]["actions"][1]["pmbus_read_sensor"]
2090 ["command"] = "0x8B";
2091 pmbusReadSensorFile["rules"][0]["actions"][1]["pmbus_read_sensor"]
2092 ["format"] = "linear_16";
2093 pmbusReadSensorFile["rules"][0]["actions"][1]["pmbus_read_sensor"]
2094 ["exponent"] = -8;
2095 // Valid: test pmbus_read_sensor.
2096 {
2097 json configFile = pmbusReadSensorFile;
2098 EXPECT_JSON_VALID(configFile);
2099 }
2100 // Valid: test pmbus_read_sensor with required properties.
2101 {
2102 json configFile = pmbusReadSensorFile;
2103 configFile["rules"][0]["actions"][1]["pmbus_read_sensor"].erase(
2104 "exponent");
2105 EXPECT_JSON_VALID(configFile);
2106 }
2107 // Invalid: test pmbus_read_sensor with no type.
2108 {
2109 json configFile = pmbusReadSensorFile;
2110 configFile["rules"][0]["actions"][1]["pmbus_read_sensor"].erase("type");
2111 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002112 "'type' is a required property");
Bob Kingd6618092020-01-21 11:31:46 +08002113 }
2114 // Invalid: test pmbus_read_sensor with no command.
2115 {
2116 json configFile = pmbusReadSensorFile;
2117 configFile["rules"][0]["actions"][1]["pmbus_read_sensor"].erase(
2118 "command");
2119 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002120 "'command' is a required property");
Bob Kingd6618092020-01-21 11:31:46 +08002121 }
2122 // Invalid: test pmbus_read_sensor with no format.
2123 {
2124 json configFile = pmbusReadSensorFile;
2125 configFile["rules"][0]["actions"][1]["pmbus_read_sensor"].erase(
2126 "format");
2127 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002128 "'format' is a required property");
Bob Kingd6618092020-01-21 11:31:46 +08002129 }
2130 // Invalid: test pmbus_read_sensor with property type wrong type.
2131 {
2132 json configFile = pmbusReadSensorFile;
2133 configFile["rules"][0]["actions"][1]["pmbus_read_sensor"]["type"] =
2134 true;
Bob King358c4172020-03-16 13:57:08 +08002135 EXPECT_JSON_INVALID(configFile, "Validation failed.",
2136 "True is not of type 'string'");
Bob Kingd6618092020-01-21 11:31:46 +08002137 }
2138 // Invalid: test pmbus_read_sensor with property command wrong type.
2139 {
2140 json configFile = pmbusReadSensorFile;
2141 configFile["rules"][0]["actions"][1]["pmbus_read_sensor"]["command"] =
2142 true;
2143 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002144 "True is not of type 'string'");
Bob Kingd6618092020-01-21 11:31:46 +08002145 }
2146 // Invalid: test pmbus_read_sensor with property format wrong type.
2147 {
2148 json configFile = pmbusReadSensorFile;
2149 configFile["rules"][0]["actions"][1]["pmbus_read_sensor"]["format"] =
2150 true;
2151 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002152 "True is not of type 'string'");
Bob Kingd6618092020-01-21 11:31:46 +08002153 }
2154 // Invalid: test pmbus_read_sensor with property exponent wrong type.
2155 {
2156 json configFile = pmbusReadSensorFile;
2157 configFile["rules"][0]["actions"][1]["pmbus_read_sensor"]["exponent"] =
2158 true;
2159 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002160 "True is not of type 'integer'");
Bob Kingd6618092020-01-21 11:31:46 +08002161 }
2162 // Invalid: test pmbus_read_sensor with property type wrong format.
2163 {
2164 json configFile = pmbusReadSensorFile;
2165 configFile["rules"][0]["actions"][1]["pmbus_read_sensor"]["type"] =
2166 "foo";
2167 EXPECT_JSON_INVALID(
2168 configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002169 "'foo' is not one of ['iout', 'iout_peak', 'iout_valley', "
2170 "'pout', 'temperature', 'temperature_peak', 'vout', "
2171 "'vout_peak', 'vout_valley']");
Bob Kingd6618092020-01-21 11:31:46 +08002172 }
2173 // Invalid: test pmbus_read_sensor with property command wrong format.
2174 {
2175 json configFile = pmbusReadSensorFile;
2176 configFile["rules"][0]["actions"][1]["pmbus_read_sensor"]["command"] =
2177 "0x8B0";
2178 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002179 "'0x8B0' does not match '^0x[0-9a-fA-F]{2}$'");
Bob Kingd6618092020-01-21 11:31:46 +08002180 }
2181 // Invalid: test pmbus_read_sensor with property format wrong format.
2182 {
2183 json configFile = pmbusReadSensorFile;
2184 configFile["rules"][0]["actions"][1]["pmbus_read_sensor"]["format"] =
2185 "foo";
Bob King358c4172020-03-16 13:57:08 +08002186 EXPECT_JSON_INVALID(configFile, "Validation failed.",
2187 "'foo' is not one of ['linear_11', 'linear_16']");
Bob Kingd6618092020-01-21 11:31:46 +08002188 }
2189}
Bob King02179c62020-01-21 11:32:36 +08002190TEST(ValidateRegulatorsConfigTest, PmbusWriteVoutCommand)
2191{
2192 json pmbusWriteVoutCommandFile = validConfigFile;
2193 pmbusWriteVoutCommandFile["rules"][0]["actions"][1]
2194 ["pmbus_write_vout_command"]["volts"] = 1.03;
2195 pmbusWriteVoutCommandFile["rules"][0]["actions"][1]
2196 ["pmbus_write_vout_command"]["format"] = "linear";
2197 pmbusWriteVoutCommandFile["rules"][0]["actions"][1]
2198 ["pmbus_write_vout_command"]["exponent"] = -8;
2199 pmbusWriteVoutCommandFile["rules"][0]["actions"][1]
2200 ["pmbus_write_vout_command"]["is_verified"] = true;
2201 // Valid: test pmbus_write_vout_command.
2202 {
2203 json configFile = pmbusWriteVoutCommandFile;
2204 EXPECT_JSON_VALID(configFile);
2205 }
2206 // Valid: test pmbus_write_vout_command with required properties.
2207 {
2208 json configFile = pmbusWriteVoutCommandFile;
2209 configFile["rules"][0]["actions"][1]["pmbus_write_vout_command"].erase(
2210 "volts");
2211 configFile["rules"][0]["actions"][1]["pmbus_write_vout_command"].erase(
2212 "exponent");
2213 configFile["rules"][0]["actions"][1]["pmbus_write_vout_command"].erase(
2214 "is_verified");
2215 EXPECT_JSON_VALID(configFile);
2216 }
2217 // Invalid: test pmbus_write_vout_command with no format.
2218 {
2219 json configFile = pmbusWriteVoutCommandFile;
2220 configFile["rules"][0]["actions"][1]["pmbus_write_vout_command"].erase(
2221 "format");
2222 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002223 "'format' is a required property");
Bob King02179c62020-01-21 11:32:36 +08002224 }
2225 // Invalid: test pmbus_write_vout_command with property volts wrong type.
2226 {
2227 json configFile = pmbusWriteVoutCommandFile;
2228 configFile["rules"][0]["actions"][1]["pmbus_write_vout_command"]
2229 ["volts"] = true;
2230 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002231 "True is not of type 'number'");
Bob King02179c62020-01-21 11:32:36 +08002232 }
2233 // Invalid: test pmbus_write_vout_command with property format wrong type.
2234 {
2235 json configFile = pmbusWriteVoutCommandFile;
2236 configFile["rules"][0]["actions"][1]["pmbus_write_vout_command"]
2237 ["format"] = true;
2238 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002239 "True is not of type 'string'");
Bob King02179c62020-01-21 11:32:36 +08002240 }
2241 // Invalid: test pmbus_write_vout_command with property exponent wrong type.
2242 {
2243 json configFile = pmbusWriteVoutCommandFile;
2244 configFile["rules"][0]["actions"][1]["pmbus_write_vout_command"]
2245 ["exponent"] = 1.3;
2246 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002247 "1.3 is not of type 'integer'");
Bob King02179c62020-01-21 11:32:36 +08002248 }
2249 // Invalid: test pmbus_write_vout_command with property is_verified wrong
2250 // type.
2251 {
2252 json configFile = pmbusWriteVoutCommandFile;
2253 configFile["rules"][0]["actions"][1]["pmbus_write_vout_command"]
2254 ["is_verified"] = 1;
2255 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002256 "1 is not of type 'boolean'");
Bob King02179c62020-01-21 11:32:36 +08002257 }
2258 // Invalid: test pmbus_write_vout_command with property format wrong format.
2259 {
2260 json configFile = pmbusWriteVoutCommandFile;
2261 configFile["rules"][0]["actions"][1]["pmbus_write_vout_command"]
2262 ["format"] = "foo";
2263 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002264 "'foo' is not one of ['linear']");
Bob King02179c62020-01-21 11:32:36 +08002265 }
2266}
Bob King99d8fa12020-01-31 11:23:40 +08002267TEST(ValidateRegulatorsConfigTest, PresenceDetection)
2268{
2269 json presenceDetectionFile = validConfigFile;
2270 presenceDetectionFile
2271 ["chassis"][0]["devices"][0]["presence_detection"]["comments"][0] =
2272 "Regulator is only present on the FooBar backplane";
2273 presenceDetectionFile["chassis"][0]["devices"][0]["presence_detection"]
Bob Kingf4ff1162020-02-11 15:13:38 +08002274 ["rule_id"] = "set_voltage_rule";
Bob King99d8fa12020-01-31 11:23:40 +08002275 // Valid: test presence_detection with only property rule_id.
2276 {
2277 json configFile = presenceDetectionFile;
2278 EXPECT_JSON_VALID(configFile);
2279 }
2280 // Valid: test presence_detection with only property actions.
2281 {
2282 json configFile = presenceDetectionFile;
2283 configFile["chassis"][0]["devices"][0]["presence_detection"].erase(
2284 "rule_id");
2285 configFile["chassis"][0]["devices"][0]["presence_detection"]["actions"]
2286 [0]["compare_presence"]["fru"] =
2287 "/system/chassis/motherboard/cpu3";
2288 configFile["chassis"][0]["devices"][0]["presence_detection"]["actions"]
2289 [0]["compare_presence"]["value"] = true;
2290 configFile["chassis"][0]["devices"][0]["presence_detection"].erase(
2291 "comments");
2292 EXPECT_JSON_VALID(configFile);
2293 }
2294 // Invalid: test presence_detection with both property rule_id and actions.
2295 {
2296 json configFile = presenceDetectionFile;
2297 configFile["chassis"][0]["devices"][0]["presence_detection"]["actions"]
2298 [0]["compare_presence"]["fru"] =
2299 "/system/chassis/motherboard/cpu3";
2300 configFile["chassis"][0]["devices"][0]["presence_detection"]["actions"]
2301 [0]["compare_presence"]["value"] = true;
2302 EXPECT_JSON_INVALID(
2303 configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002304 "{'actions': [{'compare_presence': {'fru': "
2305 "'/system/chassis/motherboard/cpu3', 'value': True}}], 'comments': "
2306 "['Regulator is only present on the FooBar backplane'], 'rule_id': "
2307 "'set_voltage_rule'} is valid under each of {'required': "
2308 "['actions']}, {'required': ['rule_id']}");
Bob King99d8fa12020-01-31 11:23:40 +08002309 }
2310 // Invalid: test presence_detection with no rule_id and actions.
2311 {
2312 json configFile = presenceDetectionFile;
2313 configFile["chassis"][0]["devices"][0]["presence_detection"].erase(
2314 "rule_id");
2315 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002316 "'rule_id' is a required property");
Bob King99d8fa12020-01-31 11:23:40 +08002317 }
2318 // Invalid: test presence_detection with property comments wrong type.
2319 {
2320 json configFile = presenceDetectionFile;
2321 configFile["chassis"][0]["devices"][0]["presence_detection"]
2322 ["comments"] = true;
2323 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002324 "True is not of type 'array'");
Bob King99d8fa12020-01-31 11:23:40 +08002325 }
2326 // Invalid: test presence_detection with property rule_id wrong type.
2327 {
2328 json configFile = presenceDetectionFile;
2329 configFile["chassis"][0]["devices"][0]["presence_detection"]
2330 ["rule_id"] = true;
2331 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002332 "True is not of type 'string'");
Bob King99d8fa12020-01-31 11:23:40 +08002333 }
2334 // Invalid: test presence_detection with property actions wrong type.
2335 {
2336 json configFile = presenceDetectionFile;
2337 configFile["chassis"][0]["devices"][0]["presence_detection"].erase(
2338 "rule_id");
2339 configFile["chassis"][0]["devices"][0]["presence_detection"]
2340 ["actions"] = true;
2341 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002342 "True is not of type 'array'");
Bob King99d8fa12020-01-31 11:23:40 +08002343 }
2344 // Invalid: test presence_detection with property rule_id wrong format.
2345 {
2346 json configFile = presenceDetectionFile;
2347 configFile["chassis"][0]["devices"][0]["presence_detection"]
2348 ["rule_id"] = "id@";
2349 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002350 "'id@' does not match '^[A-Za-z0-9_]+$'");
Bob King99d8fa12020-01-31 11:23:40 +08002351 }
2352 // Invalid: test presence_detection with property comments empty array.
2353 {
2354 json configFile = presenceDetectionFile;
2355 configFile["chassis"][0]["devices"][0]["presence_detection"]
2356 ["comments"] = json::array();
2357 EXPECT_JSON_INVALID(configFile, "Validation failed.",
2358 "[] is too short");
2359 }
2360 // Invalid: test presence_detection with property actions empty array.
2361 {
2362 json configFile = presenceDetectionFile;
2363 configFile["chassis"][0]["devices"][0]["presence_detection"].erase(
2364 "rule_id");
2365 configFile["chassis"][0]["devices"][0]["presence_detection"]
2366 ["actions"] = json::array();
2367 EXPECT_JSON_INVALID(configFile, "Validation failed.",
2368 "[] is too short");
2369 }
2370}
Bob Kinge9260b52020-01-21 11:46:13 +08002371TEST(ValidateRegulatorsConfigTest, Rail)
2372{
2373 // Valid: test rail.
2374 {
2375 json configFile = validConfigFile;
2376 EXPECT_JSON_VALID(configFile);
2377 }
2378 // Valid: test rail with required properties.
2379 {
2380 json configFile = validConfigFile;
2381 configFile["chassis"][0]["devices"][0]["rails"][0].erase("comments");
2382 configFile["chassis"][0]["devices"][0]["rails"][0].erase(
2383 "configuration");
2384 configFile["chassis"][0]["devices"][0]["rails"][0].erase(
2385 "sensor_monitoring");
2386 EXPECT_JSON_VALID(configFile);
2387 }
2388 // Invalid: test rail with no id.
2389 {
2390 json configFile = validConfigFile;
2391 configFile["chassis"][0]["devices"][0]["rails"][0].erase("id");
2392 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002393 "'id' is a required property");
Bob Kinge9260b52020-01-21 11:46:13 +08002394 }
2395 // Invalid: test rail with comments wrong type.
2396 {
2397 json configFile = validConfigFile;
2398 configFile["chassis"][0]["devices"][0]["rails"][0]["comments"] = true;
2399 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002400 "True is not of type 'array'");
Bob Kinge9260b52020-01-21 11:46:13 +08002401 }
2402 // Invalid: test rail with id wrong type.
2403 {
2404 json configFile = validConfigFile;
2405 configFile["chassis"][0]["devices"][0]["rails"][0]["id"] = true;
2406 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002407 "True is not of type 'string'");
Bob Kinge9260b52020-01-21 11:46:13 +08002408 }
2409 // Invalid: test rail with configuration wrong type.
2410 {
2411 json configFile = validConfigFile;
2412 configFile["chassis"][0]["devices"][0]["rails"][0]["configuration"] =
2413 true;
2414 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002415 "True is not of type 'object'");
Bob Kinge9260b52020-01-21 11:46:13 +08002416 }
2417 // Invalid: test rail with sensor_monitoring wrong type.
2418 {
2419 json configFile = validConfigFile;
2420 configFile["chassis"][0]["devices"][0]["rails"][0]
2421 ["sensor_monitoring"] = true;
2422 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002423 "True is not of type 'object'");
Bob Kinge9260b52020-01-21 11:46:13 +08002424 }
2425 // Invalid: test rail with comments empty array.
2426 {
2427 json configFile = validConfigFile;
2428 configFile["chassis"][0]["devices"][0]["rails"][0]["comments"] =
2429 json::array();
2430 EXPECT_JSON_INVALID(configFile, "Validation failed.",
2431 "[] is too short");
2432 }
2433 // Invalid: test rail with id wrong format.
2434 {
2435 json configFile = validConfigFile;
2436 configFile["chassis"][0]["devices"][0]["rails"][0]["id"] = "id~";
2437 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002438 "'id~' does not match '^[A-Za-z0-9_]+$'");
Bob Kinge9260b52020-01-21 11:46:13 +08002439 }
2440}
Bob King64df7da2020-01-31 12:04:12 +08002441TEST(ValidateRegulatorsConfigTest, Rule)
2442{
2443 // valid test comments property, id property,
2444 // action property specified.
2445 {
2446 json configFile = validConfigFile;
2447 EXPECT_JSON_VALID(configFile);
2448 }
2449
2450 // valid test rule with no comments
2451 {
2452 json configFile = validConfigFile;
2453 configFile["rules"][0].erase("comments");
2454 EXPECT_JSON_VALID(configFile);
2455 }
2456
2457 // invalid test comments property has invalid value type
2458 {
2459 json configFile = validConfigFile;
2460 configFile["rules"][0]["comments"] = {1};
2461 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002462 "1 is not of type 'string'");
Bob King64df7da2020-01-31 12:04:12 +08002463 }
2464
2465 // invalid test rule with no ID
2466 {
2467 json configFile = validConfigFile;
2468 configFile["rules"][0].erase("id");
2469 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002470 "'id' is a required property");
Bob King64df7da2020-01-31 12:04:12 +08002471 }
2472
2473 // invalid test id property has invalid value type (not string)
2474 {
2475 json configFile = validConfigFile;
2476 configFile["rules"][0]["id"] = true;
2477 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002478 "True is not of type 'string'");
Bob King64df7da2020-01-31 12:04:12 +08002479 }
2480
2481 // invalid test id property has invalid value
2482 {
2483 json configFile = validConfigFile;
2484 configFile["rules"][0]["id"] = "foo%";
2485 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002486 "'foo%' does not match '^[A-Za-z0-9_]+$'");
Bob King64df7da2020-01-31 12:04:12 +08002487 }
2488
2489 // invalid test rule with no actions property
2490 {
2491 json configFile = validConfigFile;
2492 configFile["rules"][0].erase("actions");
2493 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002494 "'actions' is a required property");
Bob King64df7da2020-01-31 12:04:12 +08002495 }
2496
2497 // valid test rule with multiple actions
2498 {
2499 json configFile = validConfigFile;
Bob King63d795f2020-02-11 15:22:09 +08002500 configFile["rules"][0]["actions"][1]["run_rule"] = "read_sensors_rule";
Bob King64df7da2020-01-31 12:04:12 +08002501 EXPECT_JSON_VALID(configFile);
2502 }
2503
2504 // invalid test actions property has invalid value type (not an array)
2505 {
2506 json configFile = validConfigFile;
2507 configFile["rules"][0]["actions"] = 1;
2508 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002509 "1 is not of type 'array'");
Bob King64df7da2020-01-31 12:04:12 +08002510 }
2511
2512 // invalid test actions property has invalid value of action
2513 {
2514 json configFile = validConfigFile;
2515 configFile["rules"][0]["actions"][0] = "foo";
2516 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002517 "'foo' is not of type 'object'");
Bob King64df7da2020-01-31 12:04:12 +08002518 }
2519
2520 // invalid test actions property has empty array
2521 {
2522 json configFile = validConfigFile;
2523 configFile["rules"][0]["actions"] = json::array();
2524 EXPECT_JSON_INVALID(configFile, "Validation failed.",
2525 "[] is too short");
2526 }
2527}
Bob Kinge86c2e52020-01-21 11:33:32 +08002528TEST(ValidateRegulatorsConfigTest, RunRule)
2529{
2530 json runRuleFile = validConfigFile;
Bob King7d3a9f12020-02-11 15:34:52 +08002531 runRuleFile["rules"][0]["actions"][1]["run_rule"] = "read_sensors_rule";
Bob Kinge86c2e52020-01-21 11:33:32 +08002532 // Valid: test run_rule.
2533 {
2534 json configFile = runRuleFile;
2535 EXPECT_JSON_VALID(configFile);
2536 }
2537 // Invalid: test run_rule wrong type.
2538 {
2539 json configFile = runRuleFile;
2540 configFile["rules"][0]["actions"][1]["run_rule"] = true;
2541 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002542 "True is not of type 'string'");
Bob Kinge86c2e52020-01-21 11:33:32 +08002543 }
2544 // Invalid: test run_rule wrong format.
2545 {
2546 json configFile = runRuleFile;
2547 configFile["rules"][0]["actions"][1]["run_rule"] = "set_voltage_rule%";
2548 EXPECT_JSON_INVALID(
2549 configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002550 "'set_voltage_rule%' does not match '^[A-Za-z0-9_]+$'");
Bob Kinge86c2e52020-01-21 11:33:32 +08002551 }
2552}
Bob Kingfcc2a2f2020-01-31 11:29:45 +08002553TEST(ValidateRegulatorsConfigTest, SensorMonitoring)
2554{
2555 // Valid: test rails sensor_monitoring with only property rule id.
2556 {
2557 json configFile = validConfigFile;
2558 EXPECT_JSON_VALID(configFile);
2559 }
2560 // Valid: test rails sensor_monitoring with only property actions.
2561 {
2562 json configFile = validConfigFile;
2563 configFile["chassis"][0]["devices"][0]["rails"][0]["sensor_monitoring"]
2564 .erase("rule_id");
2565 configFile["chassis"][0]["devices"][0]["rails"][0]["sensor_monitoring"]
2566 ["actions"][0]["compare_presence"]["fru"] =
2567 "/system/chassis/motherboard/cpu3";
2568 configFile["chassis"][0]["devices"][0]["rails"][0]["sensor_monitoring"]
2569 ["actions"][0]["compare_presence"]["value"] = true;
2570 configFile["chassis"][0]["devices"][0]["rails"][0]["sensor_monitoring"]
2571 ["comments"][0] = "comments";
2572 EXPECT_JSON_VALID(configFile);
2573 }
2574 // Invalid: test rails sensor_monitoring with both property rule_id and
2575 // actions.
2576 {
2577 json configFile = validConfigFile;
2578 configFile["chassis"][0]["devices"][0]["rails"][0]["sensor_monitoring"]
2579 ["actions"][0]["compare_presence"]["fru"] =
2580 "/system/chassis/motherboard/cpu3";
2581 configFile["chassis"][0]["devices"][0]["rails"][0]["sensor_monitoring"]
2582 ["actions"][0]["compare_presence"]["value"] = true;
2583 EXPECT_JSON_INVALID(
2584 configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002585 "{'actions': [{'compare_presence': {'fru': "
2586 "'/system/chassis/motherboard/cpu3', 'value': True}}], 'rule_id': "
2587 "'read_sensors_rule'} is valid under each of {'required': "
2588 "['actions']}, {'required': ['rule_id']}");
Bob Kingfcc2a2f2020-01-31 11:29:45 +08002589 }
2590 // Invalid: test rails sensor_monitoring with no rule_id and actions.
2591 {
2592 json configFile = validConfigFile;
2593 configFile["chassis"][0]["devices"][0]["rails"][0]["sensor_monitoring"]
2594 .erase("rule_id");
2595 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002596 "'rule_id' is a required property");
Bob Kingfcc2a2f2020-01-31 11:29:45 +08002597 }
2598 // Invalid: test rails sensor_monitoring with property comments wrong type.
2599 {
2600 json configFile = validConfigFile;
2601 configFile["chassis"][0]["devices"][0]["rails"][0]["sensor_monitoring"]
2602 ["comments"] = true;
2603 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002604 "True is not of type 'array'");
Bob Kingfcc2a2f2020-01-31 11:29:45 +08002605 }
2606 // Invalid: test rails sensor_monitoring with property rule_id wrong type.
2607 {
2608 json configFile = validConfigFile;
2609 configFile["chassis"][0]["devices"][0]["rails"][0]["sensor_monitoring"]
2610 ["rule_id"] = true;
2611 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002612 "True is not of type 'string'");
Bob Kingfcc2a2f2020-01-31 11:29:45 +08002613 }
2614 // Invalid: test rails sensor_monitoring with property actions wrong type.
2615 {
2616 json configFile = validConfigFile;
2617 configFile["chassis"][0]["devices"][0]["rails"][0]["sensor_monitoring"]
2618 .erase("rule_id");
2619 configFile["chassis"][0]["devices"][0]["rails"][0]["sensor_monitoring"]
2620 ["actions"] = true;
2621 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002622 "True is not of type 'array'");
Bob Kingfcc2a2f2020-01-31 11:29:45 +08002623 }
2624 // Invalid: test rails sensor_monitoring with property rule_id wrong format.
2625 {
2626 json configFile = validConfigFile;
2627 configFile["chassis"][0]["devices"][0]["rails"][0]["sensor_monitoring"]
2628 ["rule_id"] = "id@";
2629 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002630 "'id@' does not match '^[A-Za-z0-9_]+$'");
Bob Kingfcc2a2f2020-01-31 11:29:45 +08002631 }
2632 // Invalid: test rails sensor_monitoring with property comments empty array.
2633 {
2634 json configFile = validConfigFile;
2635 configFile["chassis"][0]["devices"][0]["rails"][0]["sensor_monitoring"]
2636 ["comments"] = json::array();
2637 EXPECT_JSON_INVALID(configFile, "Validation failed.",
2638 "[] is too short");
2639 }
2640 // Invalid: test rails sensor_monitoring with property actions empty array.
2641 {
2642 json configFile = validConfigFile;
2643 configFile["chassis"][0]["devices"][0]["rails"][0]["sensor_monitoring"]
2644 .erase("rule_id");
2645 configFile["chassis"][0]["devices"][0]["rails"][0]["sensor_monitoring"]
2646 ["actions"] = json::array();
2647 EXPECT_JSON_INVALID(configFile, "Validation failed.",
2648 "[] is too short");
2649 }
2650}
Bob King68230aa2020-01-21 11:34:33 +08002651TEST(ValidateRegulatorsConfigTest, SetDevice)
2652{
2653 json setDeviceFile = validConfigFile;
Bob King7d3a9f12020-02-11 15:34:52 +08002654 setDeviceFile["rules"][0]["actions"][1]["set_device"] = "vdd_regulator";
Bob King68230aa2020-01-21 11:34:33 +08002655 // Valid: test set_device.
2656 {
2657 json configFile = setDeviceFile;
2658 EXPECT_JSON_VALID(configFile);
2659 }
2660 // Invalid: test set_device wrong type.
2661 {
2662 json configFile = setDeviceFile;
2663 configFile["rules"][0]["actions"][1]["set_device"] = true;
2664 EXPECT_JSON_INVALID(configFile, "Validation failed.",
Bob King358c4172020-03-16 13:57:08 +08002665 "True is not of type 'string'");
Bob King68230aa2020-01-21 11:34:33 +08002666 }
2667 // Invalid: test set_device wrong format.
2668 {
2669 json configFile = setDeviceFile;
2670 configFile["rules"][0]["actions"][1]["set_device"] = "io_expander2%";
Bob King358c4172020-03-16 13:57:08 +08002671 EXPECT_JSON_INVALID(configFile, "Validation failed.",
2672 "'io_expander2%' does not match '^[A-Za-z0-9_]+$'");
Bob King68230aa2020-01-21 11:34:33 +08002673 }
2674}
Bob King3643cc02020-01-31 11:32:56 +08002675TEST(ValidateRegulatorsConfigTest, DuplicateRuleID)
2676{
2677 // Invalid: test duplicate ID in rule.
2678 {
2679 json configFile = validConfigFile;
Bob Kingb3e48bc2020-02-18 09:59:09 +08002680 configFile["rules"][2]["id"] = "set_voltage_rule";
2681 configFile["rules"][2]["actions"][0]["pmbus_write_vout_command"]
Bob King3643cc02020-01-31 11:32:56 +08002682 ["format"] = "linear";
2683 EXPECT_JSON_INVALID(configFile, "Error: Duplicate rule ID.", "");
2684 }
2685}
2686TEST(ValidateRegulatorsConfigTest, DuplicateChassisNumber)
2687{
2688 // Invalid: test duplicate number in chassis.
2689 {
2690 json configFile = validConfigFile;
2691 configFile["chassis"][1]["number"] = 1;
2692 EXPECT_JSON_INVALID(configFile, "Error: Duplicate chassis number.", "");
2693 }
2694}
2695TEST(ValidateRegulatorsConfigTest, DuplicateDeviceID)
2696{
2697 // Invalid: test duplicate ID in device.
2698 {
2699 json configFile = validConfigFile;
2700 configFile["chassis"][0]["devices"][1]["id"] = "vdd_regulator";
2701 configFile["chassis"][0]["devices"][1]["is_regulator"] = true;
2702 configFile["chassis"][0]["devices"][1]["fru"] =
2703 "/system/chassis/motherboard/regulator1";
2704 configFile["chassis"][0]["devices"][1]["i2c_interface"]["bus"] = 2;
2705 configFile["chassis"][0]["devices"][1]["i2c_interface"]["address"] =
2706 "0x71";
2707 EXPECT_JSON_INVALID(configFile, "Error: Duplicate device ID.", "");
2708 }
2709}
2710TEST(ValidateRegulatorsConfigTest, DuplicateRailID)
2711{
2712 // Invalid: test duplicate ID in rail.
2713 {
2714 json configFile = validConfigFile;
2715 configFile["chassis"][0]["devices"][0]["rails"][1]["id"] = "vdd";
2716 EXPECT_JSON_INVALID(configFile, "Error: Duplicate rail ID.", "");
2717 }
2718}
Bob King78793102020-03-13 13:16:09 +08002719TEST(ValidateRegulatorsConfigTest, DuplicateObjectID)
2720{
2721 // Invalid: test duplicate object ID in device and rail.
2722 {
2723 json configFile = validConfigFile;
2724 configFile["chassis"][0]["devices"][0]["rails"][1]["id"] =
2725 "vdd_regulator";
2726 EXPECT_JSON_INVALID(configFile, "Error: Duplicate ID.", "");
2727 }
2728 // Invalid: test duplicate object ID in device and rule.
2729 {
2730 json configFile = validConfigFile;
2731 configFile["rules"][2]["id"] = "vdd_regulator";
2732 configFile["rules"][2]["actions"][0]["pmbus_write_vout_command"]
2733 ["format"] = "linear";
2734 EXPECT_JSON_INVALID(configFile, "Error: Duplicate ID.", "");
2735 }
2736 // Invalid: test duplicate object ID in rule and rail.
2737 {
2738 json configFile = validConfigFile;
2739 configFile["chassis"][0]["devices"][0]["rails"][1]["id"] =
2740 "set_voltage_rule";
2741 EXPECT_JSON_INVALID(configFile, "Error: Duplicate ID.", "");
2742 }
2743}
Bob King3643cc02020-01-31 11:32:56 +08002744TEST(ValidateRegulatorsConfigTest, InfiniteLoops)
2745{
2746 // Invalid: test run_rule with infinite loop (rules run each other).
2747 {
2748 json configFile = validConfigFile;
2749 configFile["rules"][2]["actions"][0]["run_rule"] = "set_voltage_rule2";
2750 configFile["rules"][2]["id"] = "set_voltage_rule1";
2751 configFile["rules"][3]["actions"][0]["run_rule"] = "set_voltage_rule1";
2752 configFile["rules"][3]["id"] = "set_voltage_rule2";
2753 EXPECT_JSON_INVALID(configFile,
2754 "Infinite loop caused by run_rule actions.", "");
2755 }
2756 // Invalid: test run_rule with infinite loop (rule runs itself).
2757 {
2758 json configFile = validConfigFile;
2759 configFile["rules"][2]["actions"][0]["run_rule"] = "set_voltage_rule1";
2760 configFile["rules"][2]["id"] = "set_voltage_rule1";
2761 EXPECT_JSON_INVALID(configFile,
2762 "Infinite loop caused by run_rule actions.", "");
2763 }
2764 // Invalid: test run_rule with infinite loop (indirect loop).
2765 {
2766 json configFile = validConfigFile;
2767 configFile["rules"][2]["actions"][0]["run_rule"] = "set_voltage_rule2";
2768 configFile["rules"][2]["id"] = "set_voltage_rule1";
2769 configFile["rules"][3]["actions"][0]["run_rule"] = "set_voltage_rule3";
2770 configFile["rules"][3]["id"] = "set_voltage_rule2";
2771 configFile["rules"][4]["actions"][0]["run_rule"] = "set_voltage_rule1";
2772 configFile["rules"][4]["id"] = "set_voltage_rule3";
2773 EXPECT_JSON_INVALID(configFile,
2774 "Infinite loop caused by run_rule actions.", "");
2775 }
2776}
Bob Kingf88203a2020-02-18 13:26:07 +08002777TEST(ValidateRegulatorsConfigTest, RunRuleValueExists)
2778{
2779 // Invalid: test run_rule actions specify a rule ID that does not exist.
2780 {
2781 json configFile = validConfigFile;
2782 configFile["rules"][2]["actions"][0]["run_rule"] = "set_voltage_rule2";
2783 configFile["rules"][2]["id"] = "set_voltage_rule1";
2784 EXPECT_JSON_INVALID(configFile, "Error: Rule ID does not exist.", "");
2785 }
2786}
Bob King13b2ad92020-02-18 13:31:39 +08002787TEST(ValidateRegulatorsConfigTest, SetDeviceValueExists)
2788{
2789 // Invalid: test set_device actions specify a device ID that does not exist.
2790 {
2791 json configFile = validConfigFile;
2792 configFile["rules"][2]["actions"][0]["set_device"] = "vdd_regulator2";
2793 configFile["rules"][2]["id"] = "set_voltage_rule1";
2794 EXPECT_JSON_INVALID(configFile, "Error: Device ID does not exist.", "");
2795 }
2796}
Bob King21b09be2020-02-18 13:33:09 +08002797TEST(ValidateRegulatorsConfigTest, RuleIDExists)
2798{
2799 // Invalid: test rule_id property in configuration specifies a rule ID that
2800 // does not exist.
2801 {
2802 json configFile = validConfigFile;
2803 configFile["chassis"][0]["devices"][0]["configuration"]["rule_id"] =
2804 "set_voltage_rule2";
2805 EXPECT_JSON_INVALID(configFile, "Error: Rule ID does not exist.", "");
2806 }
2807 // Invalid: test rule_id property in presence_detection specifies a rule ID
2808 // that does not exist.
2809 {
2810 json configFile = validConfigFile;
2811 configFile["chassis"][0]["devices"][0]["presence_detection"]
2812 ["rule_id"] = "set_voltage_rule2";
2813 EXPECT_JSON_INVALID(configFile, "Error: Rule ID does not exist.", "");
2814 }
2815 // Invalid: test rule_id property in sensor_monitoring specifies a rule ID
2816 // that does not exist.
2817 {
2818 json configFile = validConfigFile;
2819 configFile["chassis"][0]["devices"][0]["rails"][0]["sensor_monitoring"]
2820 ["rule_id"] = "set_voltage_rule2";
2821 EXPECT_JSON_INVALID(configFile, "Error: Rule ID does not exist.", "");
2822 }
2823}
Bob Kingdc72b622020-02-18 13:36:18 +08002824TEST(ValidateRegulatorsConfigTest, NumberOfElementsInMasks)
2825{
2826 // Invalid: test number of elements in masks not equal to number in values
2827 // in i2c_compare_bytes.
2828 {
2829 json configFile = validConfigFile;
2830 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["register"] =
2831 "0x82";
2832 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["values"] = {
2833 "0x02", "0x73"};
2834 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["masks"] = {
2835 "0x7F"};
2836 EXPECT_JSON_INVALID(configFile,
2837 "Error: Invalid i2c_compare_bytes action.", "");
2838 }
2839 // Invalid: test number of elements in masks not equal to number in values
2840 // in i2c_write_bytes.
2841 {
2842 json configFile = validConfigFile;
2843 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["register"] =
2844 "0x82";
2845 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["values"] = {
2846 "0x02", "0x73"};
2847 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["masks"] = {
2848 "0x7F"};
2849 EXPECT_JSON_INVALID(configFile,
2850 "Error: Invalid i2c_write_bytes action.", "");
2851 }
2852}
Bob Kinged009652020-02-20 14:54:13 +08002853TEST(ValidateRegulatorsConfigTest, CommandLineSyntax)
2854{
Bob Kinga57e0812020-03-12 10:47:42 +08002855 std::string validateTool =
2856 " ../phosphor-regulators/tools/validate-regulators-config.py ";
Bob Kinged009652020-02-20 14:54:13 +08002857 std::string schema = " -s ";
Bob Kinga57e0812020-03-12 10:47:42 +08002858 std::string schemaFile =
2859 " ../phosphor-regulators/schema/config_schema.json ";
Bob Kinged009652020-02-20 14:54:13 +08002860 std::string configuration = " -c ";
2861 std::string command;
2862 std::string errorMessage;
2863 std::string outputMessage;
2864 std::string outputMessageHelp =
2865 "usage: validate-regulators-config.py [-h] [-s SCHEMA_FILE]";
2866 int valid = 0;
2867
Shawn McCarney0f6ebad2020-09-04 16:43:00 -05002868 TemporaryFile tmpFile;
2869 std::string fileName = tmpFile.getPath().string();
Bob Kinga57e0812020-03-12 10:47:42 +08002870 writeDataToFile(validConfigFile, fileName);
Bob Kinged009652020-02-20 14:54:13 +08002871 // Valid: -s specified
2872 {
2873 command = validateTool + "-s " + schemaFile + configuration + fileName;
2874 expectCommandLineSyntax(errorMessage, outputMessage, command, valid);
2875 }
2876 // Valid: --schema-file specified
2877 {
2878 command = validateTool + "--schema-file " + schemaFile + configuration +
2879 fileName;
2880 expectCommandLineSyntax(errorMessage, outputMessage, command, valid);
2881 }
2882 // Valid: -c specified
2883 {
2884 command = validateTool + schema + schemaFile + "-c " + fileName;
2885 expectCommandLineSyntax(errorMessage, outputMessage, command, valid);
2886 }
2887 // Valid: --configuration-file specified
2888 {
2889 command = validateTool + schema + schemaFile + "--configuration-file " +
2890 fileName;
2891 expectCommandLineSyntax(errorMessage, outputMessage, command, valid);
2892 }
2893 // Valid: -h specified
2894 {
2895 command = validateTool + "-h ";
2896 expectCommandLineSyntax(errorMessage, outputMessageHelp, command,
2897 valid);
2898 }
2899 // Valid: --help specified
2900 {
2901 command = validateTool + "--help ";
2902 expectCommandLineSyntax(errorMessage, outputMessageHelp, command,
2903 valid);
2904 }
2905 // Invalid: -c/--configuration-file not specified
2906 {
2907 command = validateTool + schema + schemaFile;
2908 expectCommandLineSyntax("Error: Configuration file is required.",
2909 outputMessageHelp, command, 1);
2910 }
2911 // Invalid: -s/--schema-file not specified
2912 {
2913 command = validateTool + configuration + fileName;
2914 expectCommandLineSyntax("Error: Schema file is required.",
2915 outputMessageHelp, command, 1);
2916 }
2917 // Invalid: -s specified more than once
2918 {
2919 command =
2920 validateTool + "-s -s " + schemaFile + configuration + fileName;
2921 expectCommandLineSyntax(outputMessageHelp, outputMessage, command, 2);
2922 }
2923 // Invalid: -c specified more than once
2924 {
2925 command = validateTool + schema + schemaFile + "-c -c " + fileName;
2926 expectCommandLineSyntax(outputMessageHelp, outputMessage, command, 2);
2927 }
2928 // Invalid: No file name specified after -c
2929 {
2930 command = validateTool + schema + schemaFile + configuration;
2931 expectCommandLineSyntax(outputMessageHelp, outputMessage, command, 2);
2932 }
2933 // Invalid: No file name specified after -s
2934 {
2935 command = validateTool + schema + configuration + fileName;
2936 expectCommandLineSyntax(outputMessageHelp, outputMessage, command, 2);
2937 }
2938 // Invalid: File specified after -c does not exist
2939 {
2940 command = validateTool + schema + schemaFile + configuration +
2941 "../notExistFile";
2942 expectCommandLineSyntax(
2943 "Traceback (most recent call last):", outputMessage, command, 1);
2944 }
2945 // Invalid: File specified after -s does not exist
2946 {
2947 command = validateTool + schema + "../notExistFile " + configuration +
2948 fileName;
2949 expectCommandLineSyntax(
2950 "Traceback (most recent call last):", outputMessage, command, 1);
2951 }
2952 // Invalid: File specified after -s is not right data format
2953 {
Shawn McCarney0f6ebad2020-09-04 16:43:00 -05002954 TemporaryFile wrongFormatFile;
2955 std::string wrongFormatFileName = wrongFormatFile.getPath().string();
Bob Kinga57e0812020-03-12 10:47:42 +08002956 std::ofstream out(wrongFormatFileName);
Bob Kinged009652020-02-20 14:54:13 +08002957 out << "foo";
2958 out.close();
Bob Kinga57e0812020-03-12 10:47:42 +08002959 command = validateTool + schema + wrongFormatFileName + configuration +
2960 fileName;
Bob Kinged009652020-02-20 14:54:13 +08002961 expectCommandLineSyntax(
2962 "Traceback (most recent call last):", outputMessage, command, 1);
Bob Kinged009652020-02-20 14:54:13 +08002963 }
2964 // Invalid: File specified after -c is not readable
2965 {
Shawn McCarney0f6ebad2020-09-04 16:43:00 -05002966 TemporaryFile notReadableFile;
2967 std::string notReadableFileName = notReadableFile.getPath().string();
Bob Kinga57e0812020-03-12 10:47:42 +08002968 writeDataToFile(validConfigFile, notReadableFileName);
Bob Kinged009652020-02-20 14:54:13 +08002969 command = validateTool + schema + schemaFile + configuration +
Bob Kinga57e0812020-03-12 10:47:42 +08002970 notReadableFileName;
2971 chmod(notReadableFileName.c_str(), 0222);
Bob Kinged009652020-02-20 14:54:13 +08002972 expectCommandLineSyntax(
2973 "Traceback (most recent call last):", outputMessage, command, 1);
Bob Kinged009652020-02-20 14:54:13 +08002974 }
2975 // Invalid: File specified after -s is not readable
2976 {
Shawn McCarney0f6ebad2020-09-04 16:43:00 -05002977 TemporaryFile notReadableFile;
2978 std::string notReadableFileName = notReadableFile.getPath().string();
Bob Kinga57e0812020-03-12 10:47:42 +08002979 writeDataToFile(validConfigFile, notReadableFileName);
2980 command = validateTool + schema + notReadableFileName + configuration +
2981 fileName;
2982 chmod(notReadableFileName.c_str(), 0222);
Bob Kinged009652020-02-20 14:54:13 +08002983 expectCommandLineSyntax(
2984 "Traceback (most recent call last):", outputMessage, command, 1);
Bob Kinged009652020-02-20 14:54:13 +08002985 }
2986 // Invalid: Unexpected parameter specified (like -g)
2987 {
2988 command = validateTool + schema + schemaFile + configuration +
2989 fileName + " -g";
2990 expectCommandLineSyntax(outputMessageHelp, outputMessage, command, 2);
2991 }
Bob Kinged009652020-02-20 14:54:13 +08002992}