1 /** 2 * Copyright c 2020 IBM Corporation 3 * 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 */ 16 #include <errno.h> 17 #include <stdio.h> 18 #include <stdlib.h> 19 #include <sys/wait.h> 20 21 #include <nlohmann/json.hpp> 22 23 #include <fstream> 24 25 #include <gtest/gtest.h> 26 27 #define EXPECT_FILE_VALID(configFile) expectFileValid(configFile) 28 #define EXPECT_FILE_INVALID(configFile, expectedErrorMessage, \ 29 expectedOutputMessage) \ 30 expectFileInvalid(configFile, expectedErrorMessage, expectedOutputMessage) 31 #define EXPECT_JSON_VALID(configFileJson) expectJsonValid(configFileJson) 32 #define EXPECT_JSON_INVALID(configFileJson, expectedErrorMessage, \ 33 expectedOutputMessage) \ 34 expectJsonInvalid(configFileJson, expectedErrorMessage, \ 35 expectedOutputMessage) 36 37 using json = nlohmann::json; 38 39 const json validConfigFile = R"( 40 { 41 "comments": [ "Config file for a FooBar one-chassis system" ], 42 43 "rules": [ 44 { 45 "comments": [ "Sets output voltage for a PMBus regulator rail" ], 46 "id": "set_voltage_rule", 47 "actions": [ 48 { 49 "pmbus_write_vout_command": { 50 "format": "linear" 51 } 52 } 53 ] 54 }, 55 { 56 "comments": [ "Reads sensors from a PMBus regulator rail" ], 57 "id": "read_sensors_rule", 58 "actions": [ 59 { 60 "comments": [ "Read output voltage from READ_VOUT." ], 61 "pmbus_read_sensor": { 62 "type": "vout", 63 "command": "0x8B", 64 "format": "linear_16" 65 } 66 } 67 ] 68 } 69 ], 70 71 "chassis": [ 72 { 73 "comments": [ "Chassis number 1 containing CPUs and memory" ], 74 "number": 1, 75 "devices": [ 76 { 77 "comments": [ "IR35221 regulator producing the Vdd rail" ], 78 "id": "vdd_regulator", 79 "is_regulator": true, 80 "fru": "/system/chassis/motherboard/regulator1", 81 "i2c_interface": { 82 "bus": 1, 83 "address": "0x70" 84 }, 85 "rails": [ 86 { 87 "comments": [ "Vdd rail" ], 88 "id": "vdd", 89 "configuration": { 90 "volts": 1.03, 91 "rule_id": "set_voltage_rule" 92 }, 93 "sensor_monitoring": { 94 "rule_id": "read_sensors_rule" 95 } 96 } 97 ] 98 } 99 ] 100 } 101 ] 102 } 103 )"_json; 104 105 std::string createTmpFile() 106 { 107 // create temporary file using mkstemp under /tmp/. random name for XXXXXX 108 char fileName[] = "/tmp/temp-XXXXXX"; 109 int fd = mkstemp(fileName); 110 if (fd == -1) 111 { 112 perror("Can't create temporary file"); 113 } 114 close(fd); 115 return fileName; 116 } 117 118 std::string getValidationToolCommand(const std::string& configFileName) 119 { 120 std::string command = "python ../tools/validate-regulators-config.py -s \ 121 ../schema/config_schema.json -c "; 122 command += configFileName; 123 return command; 124 } 125 126 int runToolForOutput(const std::string& configFileName, std::string& output, 127 bool isReadingStderr = false) 128 { 129 // run the validation tool with the temporary file and return the output 130 // of the validation tool. 131 std::string command = getValidationToolCommand(configFileName); 132 // reading the stderr while isReadingStderr is true. 133 if (isReadingStderr == true) 134 { 135 command += " 2>&1 >/dev/null"; 136 } 137 // get the jsonschema print from validation tool. 138 char buffer[256]; 139 std::string result = ""; 140 // to get the stdout from the validation tool. 141 FILE* pipe = popen(command.c_str(), "r"); 142 if (!pipe) 143 { 144 throw std::runtime_error("popen() failed!"); 145 } 146 while (!std::feof(pipe)) 147 { 148 if (fgets(buffer, sizeof buffer, pipe) != NULL) 149 { 150 result += buffer; 151 } 152 } 153 int returnValue = pclose(pipe); 154 // Check if pclose() failed 155 if (returnValue == -1) 156 { 157 // unable to close pipe. Print error and exit function. 158 throw std::runtime_error("pclose() failed!"); 159 } 160 std::string firstLine = result.substr(0, result.find('\n')); 161 output = firstLine; 162 // Get command exit status from return value 163 int exitStatus = WEXITSTATUS(returnValue); 164 return exitStatus; 165 } 166 167 void expectFileValid(const std::string& configFileName) 168 { 169 std::string errorMessage = ""; 170 std::string outputMessage = ""; 171 EXPECT_EQ(runToolForOutput(configFileName, errorMessage, true), 0); 172 EXPECT_EQ(runToolForOutput(configFileName, outputMessage), 0); 173 EXPECT_EQ(errorMessage, ""); 174 EXPECT_EQ(outputMessage, ""); 175 } 176 177 void expectFileInvalid(const std::string& configFileName, 178 const std::string& expectedErrorMessage, 179 const std::string& expectedOutputMessage) 180 { 181 std::string errorMessage = ""; 182 std::string outputMessage = ""; 183 EXPECT_EQ(runToolForOutput(configFileName, errorMessage, true), 1); 184 EXPECT_EQ(runToolForOutput(configFileName, outputMessage), 1); 185 EXPECT_EQ(errorMessage, expectedErrorMessage); 186 EXPECT_EQ(outputMessage, expectedOutputMessage); 187 } 188 189 void expectJsonValid(const json configFileJson) 190 { 191 std::string fileName; 192 fileName = createTmpFile(); 193 std::string jsonData = configFileJson.dump(); 194 std::ofstream out(fileName); 195 out << jsonData; 196 out.close(); 197 198 EXPECT_FILE_VALID(fileName); 199 unlink(fileName.c_str()); 200 } 201 202 void expectJsonInvalid(const json configFileJson, 203 const std::string& expectedErrorMessage, 204 const std::string& expectedOutputMessage) 205 { 206 std::string fileName; 207 fileName = createTmpFile(); 208 std::string jsonData = configFileJson.dump(); 209 std::ofstream out(fileName); 210 out << jsonData; 211 out.close(); 212 213 EXPECT_FILE_INVALID(fileName, expectedErrorMessage, expectedOutputMessage); 214 unlink(fileName.c_str()); 215 } 216 217 TEST(ValidateRegulatorsConfigTest, And) 218 { 219 // Valid. 220 { 221 json configFile = validConfigFile; 222 json andAction = 223 R"( 224 { 225 "and": [ 226 { "i2c_compare_byte": { "register": "0xA0", "value": "0x00" } }, 227 { "i2c_compare_byte": { "register": "0xA1", "value": "0x00" } } 228 ] 229 } 230 )"_json; 231 configFile["rules"][0]["actions"].push_back(andAction); 232 EXPECT_JSON_VALID(configFile); 233 } 234 235 // Invalid: actions property value is an empty array. 236 { 237 json configFile = validConfigFile; 238 json andAction = 239 R"( 240 { 241 "and": [] 242 } 243 )"_json; 244 configFile["rules"][0]["actions"].push_back(andAction); 245 EXPECT_JSON_INVALID(configFile, "Validation failed.", 246 "[] is too short"); 247 } 248 249 // Invalid: actions property has incorrect value data type. 250 { 251 json configFile = validConfigFile; 252 json andAction = 253 R"( 254 { 255 "and": true 256 } 257 )"_json; 258 configFile["rules"][0]["actions"].push_back(andAction); 259 EXPECT_JSON_INVALID(configFile, "Validation failed.", 260 "True is not of type u'array'"); 261 } 262 263 // Invalid: actions property value contains wrong element type 264 { 265 json configFile = validConfigFile; 266 json andAction = 267 R"( 268 { 269 "and": ["foo"] 270 } 271 )"_json; 272 configFile["rules"][0]["actions"].push_back(andAction); 273 EXPECT_JSON_INVALID(configFile, "Validation failed.", 274 "u'foo' is not of type u'object'"); 275 } 276 } 277 TEST(ValidateRegulatorsConfigTest, Chassis) 278 { 279 // Valid: test chassis. 280 { 281 json configFile = validConfigFile; 282 EXPECT_JSON_VALID(configFile); 283 } 284 // Valid: test chassis with required properties. 285 { 286 json configFile = validConfigFile; 287 configFile["chassis"][0].erase("comments"); 288 configFile["chassis"][0].erase("devices"); 289 EXPECT_JSON_VALID(configFile); 290 } 291 // Invalid: test chassis with no number. 292 { 293 json configFile = validConfigFile; 294 configFile["chassis"][0].erase("number"); 295 EXPECT_JSON_INVALID(configFile, "Validation failed.", 296 "u'number' is a required property"); 297 } 298 // Invalid: test chassis with property comments wrong type. 299 { 300 json configFile = validConfigFile; 301 configFile["chassis"][0]["comments"] = true; 302 EXPECT_JSON_INVALID(configFile, "Validation failed.", 303 "True is not of type u'array'"); 304 } 305 // Invalid: test chassis with property number wrong type. 306 { 307 json configFile = validConfigFile; 308 configFile["chassis"][0]["number"] = 1.3; 309 EXPECT_JSON_INVALID(configFile, "Validation failed.", 310 "1.3 is not of type u'integer'"); 311 } 312 // Invalid: test chassis with property devices wrong type. 313 { 314 json configFile = validConfigFile; 315 configFile["chassis"][0]["devices"] = true; 316 EXPECT_JSON_INVALID(configFile, "Validation failed.", 317 "True is not of type u'array'"); 318 } 319 // Invalid: test chassis with property comments empty array. 320 { 321 json configFile = validConfigFile; 322 configFile["chassis"][0]["comments"] = json::array(); 323 EXPECT_JSON_INVALID(configFile, "Validation failed.", 324 "[] is too short"); 325 } 326 // Invalid: test chassis with property devices empty array. 327 { 328 json configFile = validConfigFile; 329 configFile["chassis"][0]["devices"] = json::array(); 330 EXPECT_JSON_INVALID(configFile, "Validation failed.", 331 "[] is too short"); 332 } 333 // Invalid: test chassis with property number less than 1. 334 { 335 json configFile = validConfigFile; 336 configFile["chassis"][0]["number"] = 0; 337 EXPECT_JSON_INVALID(configFile, "Validation failed.", 338 "0 is less than the minimum of 1"); 339 } 340 } 341 TEST(ValidateRegulatorsConfigTest, ComparePresence) 342 { 343 json comparePresenceFile = validConfigFile; 344 comparePresenceFile["rules"][0]["actions"][1]["compare_presence"]["fru"] = 345 "/system/chassis/motherboard/regulator2"; 346 comparePresenceFile["rules"][0]["actions"][1]["compare_presence"]["value"] = 347 true; 348 // Valid. 349 { 350 json configFile = comparePresenceFile; 351 EXPECT_JSON_VALID(configFile); 352 } 353 354 // Invalid: no FRU property. 355 { 356 json configFile = comparePresenceFile; 357 configFile["rules"][0]["actions"][1]["compare_presence"].erase("fru"); 358 EXPECT_JSON_INVALID(configFile, "Validation failed.", 359 "u'fru' is a required property"); 360 } 361 362 // Invalid: FRU property length is string less than 1. 363 { 364 json configFile = comparePresenceFile; 365 configFile["rules"][0]["actions"][1]["compare_presence"]["fru"] = ""; 366 EXPECT_JSON_INVALID(configFile, "Validation failed.", 367 "u'' is too short"); 368 } 369 370 // Invalid: no value property. 371 { 372 json configFile = comparePresenceFile; 373 configFile["rules"][0]["actions"][1]["compare_presence"].erase("value"); 374 EXPECT_JSON_INVALID(configFile, "Validation failed.", 375 "u'value' is a required property"); 376 } 377 378 // Invalid: value property type is not boolean. 379 { 380 json configFile = comparePresenceFile; 381 configFile["rules"][0]["actions"][1]["compare_presence"]["value"] = "1"; 382 EXPECT_JSON_INVALID(configFile, "Validation failed.", 383 "u'1' is not of type u'boolean'"); 384 } 385 386 // Invalid: FRU property type is not string. 387 { 388 json configFile = comparePresenceFile; 389 configFile["rules"][0]["actions"][1]["compare_presence"]["fru"] = 1; 390 EXPECT_JSON_INVALID(configFile, "Validation failed.", 391 "1 is not of type u'string'"); 392 } 393 } 394 TEST(ValidateRegulatorsConfigTest, CompareVpd) 395 { 396 json compareVpdFile = validConfigFile; 397 compareVpdFile["rules"][0]["actions"][1]["compare_vpd"]["fru"] = 398 "/system/chassis/motherboard/regulator2"; 399 compareVpdFile["rules"][0]["actions"][1]["compare_vpd"]["keyword"] = "CCIN"; 400 compareVpdFile["rules"][0]["actions"][1]["compare_vpd"]["value"] = "2D35"; 401 402 // Valid. 403 { 404 json configFile = compareVpdFile; 405 EXPECT_JSON_VALID(configFile); 406 } 407 408 // Invalid: no FRU property. 409 { 410 json configFile = compareVpdFile; 411 configFile["rules"][0]["actions"][1]["compare_vpd"].erase("fru"); 412 EXPECT_JSON_INVALID(configFile, "Validation failed.", 413 "u'fru' is a required property"); 414 } 415 416 // Invalid: no keyword property. 417 { 418 json configFile = compareVpdFile; 419 configFile["rules"][0]["actions"][1]["compare_vpd"].erase("keyword"); 420 EXPECT_JSON_INVALID(configFile, "Validation failed.", 421 "u'keyword' is a required property"); 422 } 423 424 // Invalid: no value property. 425 { 426 json configFile = compareVpdFile; 427 configFile["rules"][0]["actions"][1]["compare_vpd"].erase("value"); 428 EXPECT_JSON_INVALID(configFile, "Validation failed.", 429 "u'value' is a required property"); 430 } 431 432 // Invalid: property FRU wrong type. 433 { 434 json configFile = compareVpdFile; 435 configFile["rules"][0]["actions"][1]["compare_vpd"]["fru"] = 1; 436 EXPECT_JSON_INVALID(configFile, "Validation failed.", 437 "1 is not of type u'string'"); 438 } 439 440 // Invalid: property FRU is string less than 1. 441 { 442 json configFile = compareVpdFile; 443 configFile["rules"][0]["actions"][1]["compare_vpd"]["fru"] = ""; 444 EXPECT_JSON_INVALID(configFile, "Validation failed.", 445 "u'' is too short"); 446 } 447 448 // Invalid: property keyword is not "CCIN", "Manufacturer", "Model", 449 // "PartNumber" 450 { 451 json configFile = compareVpdFile; 452 configFile["rules"][0]["actions"][1]["compare_vpd"]["keyword"] = 453 "Number"; 454 EXPECT_JSON_INVALID(configFile, "Validation failed.", 455 "u'Number' is not one of [u'CCIN', " 456 "u'Manufacturer', u'Model', u'PartNumber']"); 457 } 458 459 // Invalid: property value wrong type. 460 { 461 json configFile = compareVpdFile; 462 configFile["rules"][0]["actions"][1]["compare_vpd"]["value"] = 1; 463 EXPECT_JSON_INVALID(configFile, "Validation failed.", 464 "1 is not of type u'string'"); 465 } 466 } 467 TEST(ValidateRegulatorsConfigTest, Configuration) 468 { 469 json configurationFile = validConfigFile; 470 configurationFile["chassis"][0]["devices"][0]["configuration"]["comments"] 471 [0] = "Set rail to 1.25V using standard rule"; 472 configurationFile["chassis"][0]["devices"][0]["configuration"]["volts"] = 473 1.25; 474 configurationFile["chassis"][0]["devices"][0]["configuration"]["rule_id"] = 475 "set_voltage_rule"; 476 // Valid: test configuration with property rule_id and with no actions. 477 { 478 json configFile = configurationFile; 479 EXPECT_JSON_VALID(configFile); 480 } 481 // Valid: test configuration with property actions and with no rule_id. 482 { 483 json configFile = configurationFile; 484 configFile["chassis"][0]["devices"][0]["configuration"].erase( 485 "rule_id"); 486 configFile["chassis"][0]["devices"][0]["configuration"]["actions"][0] 487 ["compare_presence"]["fru"] = 488 "/system/chassis/motherboard/cpu3"; 489 configFile["chassis"][0]["devices"][0]["configuration"]["actions"][0] 490 ["compare_presence"]["value"] = true; 491 EXPECT_JSON_VALID(configFile); 492 } 493 // Valid: comments not specified (optional property). 494 { 495 json configFile = configurationFile; 496 configFile["chassis"][0]["devices"][0]["configuration"].erase( 497 "comments"); 498 EXPECT_JSON_VALID(configFile); 499 } 500 // Valid: volts not specified (optional property). 501 { 502 json configFile = configurationFile; 503 configFile["chassis"][0]["devices"][0]["configuration"].erase("volts"); 504 EXPECT_JSON_VALID(configFile); 505 } 506 // Valid: configuration is property of a rail (vs. a device). 507 { 508 json configFile = validConfigFile; 509 configFile["chassis"][0]["devices"][0]["rails"][0]["configuration"] 510 ["comments"][0] = "Set rail to 1.25V using standard rule"; 511 configFile["chassis"][0]["devices"][0]["rails"][0]["configuration"] 512 ["volts"] = 1.25; 513 configFile["chassis"][0]["devices"][0]["rails"][0]["configuration"] 514 ["rule_id"] = "set_voltage_rule"; 515 EXPECT_JSON_VALID(configFile); 516 } 517 // Invalid: comments property has wrong data type (not an array). 518 { 519 json configFile = configurationFile; 520 configFile["chassis"][0]["devices"][0]["configuration"]["comments"] = 1; 521 EXPECT_JSON_INVALID(configFile, "Validation failed.", 522 "1 is not of type u'array'"); 523 } 524 // Invalid: test configuration with both actions and rule_id properties. 525 { 526 json configFile = configurationFile; 527 configFile["chassis"][0]["devices"][0]["configuration"]["actions"][0] 528 ["compare_presence"]["fru"] = 529 "/system/chassis/motherboard/cpu3"; 530 configFile["chassis"][0]["devices"][0]["configuration"]["actions"][0] 531 ["compare_presence"]["value"] = true; 532 EXPECT_JSON_INVALID( 533 configFile, "Validation failed.", 534 "{u'volts': 1.25, u'comments': [u'Set rail to 1.25V using standard " 535 "rule'], u'actions': [{u'compare_presence': {u'value': True, " 536 "u'fru': u'/system/chassis/motherboard/cpu3'}}], u'rule_id': " 537 "u'set_voltage_rule'} is valid under each of {u'required': " 538 "[u'actions']}, {u'required': [u'rule_id']}"); 539 } 540 // Invalid: test configuration with no rule_id and actions. 541 { 542 json configFile = configurationFile; 543 configFile["chassis"][0]["devices"][0]["configuration"].erase( 544 "rule_id"); 545 EXPECT_JSON_INVALID(configFile, "Validation failed.", 546 "u'rule_id' is a required property"); 547 } 548 // Invalid: test configuration with property volts wrong type. 549 { 550 json configFile = configurationFile; 551 configFile["chassis"][0]["devices"][0]["configuration"]["volts"] = true; 552 EXPECT_JSON_INVALID(configFile, "Validation failed.", 553 "True is not of type u'number'"); 554 } 555 // Invalid: test configuration with property rule_id wrong type. 556 { 557 json configFile = configurationFile; 558 configFile["chassis"][0]["devices"][0]["configuration"]["rule_id"] = 559 true; 560 EXPECT_JSON_INVALID(configFile, "Validation failed.", 561 "True is not of type u'string'"); 562 } 563 // Invalid: test configuration with property actions wrong type. 564 { 565 json configFile = configurationFile; 566 configFile["chassis"][0]["devices"][0]["configuration"].erase( 567 "rule_id"); 568 configFile["chassis"][0]["devices"][0]["configuration"]["actions"] = 569 true; 570 EXPECT_JSON_INVALID(configFile, "Validation failed.", 571 "True is not of type u'array'"); 572 } 573 // Invalid: test configuration with property comments empty array. 574 { 575 json configFile = configurationFile; 576 configFile["chassis"][0]["devices"][0]["configuration"]["comments"] = 577 json::array(); 578 EXPECT_JSON_INVALID(configFile, "Validation failed.", 579 "[] is too short"); 580 } 581 // Invalid: test configuration with property rule_id wrong format. 582 { 583 json configFile = configurationFile; 584 configFile["chassis"][0]["devices"][0]["configuration"]["rule_id"] = 585 "id!"; 586 EXPECT_JSON_INVALID(configFile, "Validation failed.", 587 "u'id!' does not match u'^[A-Za-z0-9_]+$'"); 588 } 589 // Invalid: test configuration with property actions empty array. 590 { 591 json configFile = configurationFile; 592 configFile["chassis"][0]["devices"][0]["configuration"].erase( 593 "rule_id"); 594 configFile["chassis"][0]["devices"][0]["configuration"]["actions"] = 595 json::array(); 596 EXPECT_JSON_INVALID(configFile, "Validation failed.", 597 "[] is too short"); 598 } 599 } 600 TEST(ValidateRegulatorsConfigTest, Device) 601 { 602 603 // Valid: test devices. 604 { 605 json configFile = validConfigFile; 606 EXPECT_JSON_VALID(configFile); 607 } 608 // Valid: test devices with required properties. 609 { 610 json configFile = validConfigFile; 611 configFile["chassis"][0]["devices"][0].erase("comments"); 612 configFile["chassis"][0]["devices"][0].erase("presence_detection"); 613 configFile["chassis"][0]["devices"][0].erase("configuration"); 614 configFile["chassis"][0]["devices"][0].erase("rails"); 615 EXPECT_JSON_VALID(configFile); 616 } 617 // Invalid: test devices with no id. 618 { 619 json configFile = validConfigFile; 620 configFile["chassis"][0]["devices"][0].erase("id"); 621 EXPECT_JSON_INVALID(configFile, "Validation failed.", 622 "u'id' is a required property"); 623 } 624 // Invalid: test devices with no is_regulator. 625 { 626 json configFile = validConfigFile; 627 configFile["chassis"][0]["devices"][0].erase("is_regulator"); 628 EXPECT_JSON_INVALID(configFile, "Validation failed.", 629 "u'is_regulator' is a required property"); 630 } 631 // Invalid: test devices with no fru. 632 { 633 json configFile = validConfigFile; 634 configFile["chassis"][0]["devices"][0].erase("fru"); 635 EXPECT_JSON_INVALID(configFile, "Validation failed.", 636 "u'fru' is a required property"); 637 } 638 // Invalid: test devices with no i2c_interface. 639 { 640 json configFile = validConfigFile; 641 configFile["chassis"][0]["devices"][0].erase("i2c_interface"); 642 EXPECT_JSON_INVALID(configFile, "Validation failed.", 643 "u'i2c_interface' is a required property"); 644 } 645 // Invalid: test devices with property comments wrong type. 646 { 647 json configFile = validConfigFile; 648 configFile["chassis"][0]["devices"][0]["comments"] = true; 649 EXPECT_JSON_INVALID(configFile, "Validation failed.", 650 "True is not of type u'array'"); 651 } 652 // Invalid: test devices with property id wrong type. 653 { 654 json configFile = validConfigFile; 655 configFile["chassis"][0]["devices"][0]["id"] = true; 656 EXPECT_JSON_INVALID(configFile, "Validation failed.", 657 "True is not of type u'string'"); 658 } 659 // Invalid: test devices with property is_regulator wrong type. 660 { 661 json configFile = validConfigFile; 662 configFile["chassis"][0]["devices"][0]["is_regulator"] = 1; 663 EXPECT_JSON_INVALID(configFile, "Validation failed.", 664 "1 is not of type u'boolean'"); 665 } 666 // Invalid: test devices with property fru wrong type. 667 { 668 json configFile = validConfigFile; 669 configFile["chassis"][0]["devices"][0]["fru"] = true; 670 EXPECT_JSON_INVALID(configFile, "Validation failed.", 671 "True is not of type u'string'"); 672 } 673 // Invalid: test devices with property i2c_interface wrong type. 674 { 675 json configFile = validConfigFile; 676 configFile["chassis"][0]["devices"][0]["i2c_interface"] = true; 677 EXPECT_JSON_INVALID(configFile, "Validation failed.", 678 "True is not of type u'object'"); 679 } 680 // Invalid: test devices with property presence_detection wrong 681 // type. 682 { 683 json configFile = validConfigFile; 684 configFile["chassis"][0]["devices"][0]["presence_detection"] = true; 685 EXPECT_JSON_INVALID(configFile, "Validation failed.", 686 "True is not of type u'object'"); 687 } 688 // Invalid: test devices with property configuration wrong type. 689 { 690 json configFile = validConfigFile; 691 configFile["chassis"][0]["devices"][0]["configuration"] = true; 692 EXPECT_JSON_INVALID(configFile, "Validation failed.", 693 "True is not of type u'object'"); 694 } 695 // Invalid: test devices with property rails wrong type. 696 { 697 json configFile = validConfigFile; 698 configFile["chassis"][0]["devices"][0]["rails"] = true; 699 EXPECT_JSON_INVALID(configFile, "Validation failed.", 700 "True is not of type u'array'"); 701 } 702 // Invalid: test devices with property comments empty array. 703 { 704 json configFile = validConfigFile; 705 configFile["chassis"][0]["devices"][0]["comments"] = json::array(); 706 EXPECT_JSON_INVALID(configFile, "Validation failed.", 707 "[] is too short"); 708 } 709 // Invalid: test devices with property fru length less than 1. 710 { 711 json configFile = validConfigFile; 712 configFile["chassis"][0]["devices"][0]["fru"] = ""; 713 EXPECT_JSON_INVALID(configFile, "Validation failed.", 714 "u'' is too short"); 715 } 716 // Invalid: test devices with property id wrong format. 717 { 718 json configFile = validConfigFile; 719 configFile["chassis"][0]["devices"][0]["id"] = "id#"; 720 EXPECT_JSON_INVALID(configFile, "Validation failed.", 721 "u'id#' does not match u'^[A-Za-z0-9_]+$'"); 722 } 723 // Invalid: test devices with property rails empty array. 724 { 725 json configFile = validConfigFile; 726 configFile["chassis"][0]["devices"][0]["rails"] = json::array(); 727 EXPECT_JSON_INVALID(configFile, "Validation failed.", 728 "[] is too short"); 729 } 730 } 731 TEST(ValidateRegulatorsConfigTest, I2CCompareBit) 732 { 733 json i2cCompareBitFile = validConfigFile; 734 i2cCompareBitFile["rules"][0]["actions"][1]["i2c_compare_bit"]["register"] = 735 "0xA0"; 736 i2cCompareBitFile["rules"][0]["actions"][1]["i2c_compare_bit"]["position"] = 737 3; 738 i2cCompareBitFile["rules"][0]["actions"][1]["i2c_compare_bit"]["value"] = 1; 739 // Valid: test rule actions i2c_compare_bit. 740 { 741 json configFile = i2cCompareBitFile; 742 EXPECT_JSON_VALID(configFile); 743 } 744 // Invalid: test i2c_compare_bit with no register. 745 { 746 json configFile = i2cCompareBitFile; 747 configFile["rules"][0]["actions"][1]["i2c_compare_bit"].erase( 748 "register"); 749 EXPECT_JSON_INVALID(configFile, "Validation failed.", 750 "u'register' is a required property"); 751 } 752 // Invalid: test i2c_compare_bit with no position. 753 { 754 json configFile = i2cCompareBitFile; 755 configFile["rules"][0]["actions"][1]["i2c_compare_bit"].erase( 756 "position"); 757 EXPECT_JSON_INVALID(configFile, "Validation failed.", 758 "u'position' is a required property"); 759 } 760 // Invalid: test i2c_compare_bit with no value. 761 { 762 json configFile = i2cCompareBitFile; 763 configFile["rules"][0]["actions"][1]["i2c_compare_bit"].erase("value"); 764 EXPECT_JSON_INVALID(configFile, "Validation failed.", 765 "u'value' is a required property"); 766 } 767 // Invalid: test i2c_compare_bit with register wrong type. 768 { 769 json configFile = i2cCompareBitFile; 770 configFile["rules"][0]["actions"][1]["i2c_compare_bit"]["register"] = 1; 771 EXPECT_JSON_INVALID(configFile, "Validation failed.", 772 "1 is not of type u'string'"); 773 } 774 // Invalid: test i2c_compare_bit with register wrong format. 775 { 776 json configFile = i2cCompareBitFile; 777 configFile["rules"][0]["actions"][1]["i2c_compare_bit"]["register"] = 778 "0xA00"; 779 EXPECT_JSON_INVALID(configFile, "Validation failed.", 780 "u'0xA00' does not match u'^0x[0-9A-Fa-f]{2}$'"); 781 } 782 // Invalid: test i2c_compare_bit with position wrong type. 783 { 784 json configFile = i2cCompareBitFile; 785 configFile["rules"][0]["actions"][1]["i2c_compare_bit"]["position"] = 786 3.1; 787 EXPECT_JSON_INVALID(configFile, "Validation failed.", 788 "3.1 is not of type u'integer'"); 789 } 790 // Invalid: test i2c_compare_bit with position greater than 7. 791 { 792 json configFile = i2cCompareBitFile; 793 configFile["rules"][0]["actions"][1]["i2c_compare_bit"]["position"] = 8; 794 EXPECT_JSON_INVALID(configFile, "Validation failed.", 795 "8 is greater than the maximum of 7"); 796 } 797 // Invalid: test i2c_compare_bit with position less than 0. 798 { 799 json configFile = i2cCompareBitFile; 800 configFile["rules"][0]["actions"][1]["i2c_compare_bit"]["position"] = 801 -1; 802 EXPECT_JSON_INVALID(configFile, "Validation failed.", 803 "-1 is less than the minimum of 0"); 804 } 805 // Invalid: test i2c_compare_bit with value wrong type. 806 { 807 json configFile = i2cCompareBitFile; 808 configFile["rules"][0]["actions"][1]["i2c_compare_bit"]["value"] = "1"; 809 EXPECT_JSON_INVALID(configFile, "Validation failed.", 810 "u'1' is not of type u'integer'"); 811 } 812 // Invalid: test i2c_compare_bit with value greater than 1. 813 { 814 json configFile = i2cCompareBitFile; 815 configFile["rules"][0]["actions"][1]["i2c_compare_bit"]["value"] = 2; 816 EXPECT_JSON_INVALID(configFile, "Validation failed.", 817 "2 is greater than the maximum of 1"); 818 } 819 // Invalid: test i2c_compare_bit with value less than 0. 820 { 821 json configFile = i2cCompareBitFile; 822 configFile["rules"][0]["actions"][1]["i2c_compare_bit"]["value"] = -1; 823 EXPECT_JSON_INVALID(configFile, "Validation failed.", 824 "-1 is less than the minimum of 0"); 825 } 826 } 827 TEST(ValidateRegulatorsConfigTest, I2CCompareByte) 828 { 829 json i2cCompareByteFile = validConfigFile; 830 i2cCompareByteFile["rules"][0]["actions"][1]["i2c_compare_byte"] 831 ["register"] = "0x82"; 832 i2cCompareByteFile["rules"][0]["actions"][1]["i2c_compare_byte"]["value"] = 833 "0x40"; 834 i2cCompareByteFile["rules"][0]["actions"][1]["i2c_compare_byte"]["mask"] = 835 "0x7F"; 836 // Valid: test i2c_compare_byte with all properties. 837 { 838 json configFile = i2cCompareByteFile; 839 EXPECT_JSON_VALID(configFile); 840 } 841 // Valid: test i2c_compare_byte with all required properties. 842 { 843 json configFile = i2cCompareByteFile; 844 configFile["rules"][0]["actions"][1]["i2c_compare_byte"].erase("mask"); 845 EXPECT_JSON_VALID(configFile); 846 } 847 // Invalid: test i2c_compare_byte with no register. 848 { 849 json configFile = i2cCompareByteFile; 850 configFile["rules"][0]["actions"][1]["i2c_compare_byte"].erase( 851 "register"); 852 EXPECT_JSON_INVALID(configFile, "Validation failed.", 853 "u'register' is a required property"); 854 } 855 // Invalid: test i2c_compare_byte with no value. 856 { 857 json configFile = i2cCompareByteFile; 858 configFile["rules"][0]["actions"][1]["i2c_compare_byte"].erase("value"); 859 EXPECT_JSON_INVALID(configFile, "Validation failed.", 860 "u'value' is a required property"); 861 } 862 // Invalid: test i2c_compare_byte with property register wrong type. 863 { 864 json configFile = i2cCompareByteFile; 865 configFile["rules"][0]["actions"][1]["i2c_compare_byte"]["register"] = 866 1; 867 EXPECT_JSON_INVALID(configFile, "Validation failed.", 868 "1 is not of type u'string'"); 869 } 870 // Invalid: test i2c_compare_byte with property value wrong type. 871 { 872 json configFile = i2cCompareByteFile; 873 configFile["rules"][0]["actions"][1]["i2c_compare_byte"]["value"] = 1; 874 EXPECT_JSON_INVALID(configFile, "Validation failed.", 875 "1 is not of type u'string'"); 876 } 877 // Invalid: test i2c_compare_byte with property mask wrong type. 878 { 879 json configFile = i2cCompareByteFile; 880 configFile["rules"][0]["actions"][1]["i2c_compare_byte"]["mask"] = 1; 881 EXPECT_JSON_INVALID(configFile, "Validation failed.", 882 "1 is not of type u'string'"); 883 } 884 // Invalid: test i2c_compare_byte with property register more than 2 hex 885 // digits. 886 { 887 json configFile = i2cCompareByteFile; 888 configFile["rules"][0]["actions"][1]["i2c_compare_byte"]["register"] = 889 "0x820"; 890 EXPECT_JSON_INVALID(configFile, "Validation failed.", 891 "u'0x820' does not match u'^0x[0-9A-Fa-f]{2}$'"); 892 } 893 // Invalid: test i2c_compare_byte with property value more than 2 hex 894 // digits. 895 { 896 json configFile = i2cCompareByteFile; 897 configFile["rules"][0]["actions"][1]["i2c_compare_byte"]["value"] = 898 "0x820"; 899 EXPECT_JSON_INVALID(configFile, "Validation failed.", 900 "u'0x820' does not match u'^0x[0-9A-Fa-f]{2}$'"); 901 } 902 // Invalid: test i2c_compare_byte with property mask more than 2 hex digits. 903 { 904 json configFile = i2cCompareByteFile; 905 configFile["rules"][0]["actions"][1]["i2c_compare_byte"]["mask"] = 906 "0x820"; 907 EXPECT_JSON_INVALID(configFile, "Validation failed.", 908 "u'0x820' does not match u'^0x[0-9A-Fa-f]{2}$'"); 909 } 910 // Invalid: test i2c_compare_byte with property register less than 2 hex 911 // digits. 912 { 913 json configFile = i2cCompareByteFile; 914 configFile["rules"][0]["actions"][1]["i2c_compare_byte"]["register"] = 915 "0x8"; 916 EXPECT_JSON_INVALID(configFile, "Validation failed.", 917 "u'0x8' does not match u'^0x[0-9A-Fa-f]{2}$'"); 918 } 919 // Invalid: test i2c_compare_byte with property value less than 2 hex 920 // digits. 921 { 922 json configFile = i2cCompareByteFile; 923 configFile["rules"][0]["actions"][1]["i2c_compare_byte"]["value"] = 924 "0x8"; 925 EXPECT_JSON_INVALID(configFile, "Validation failed.", 926 "u'0x8' does not match u'^0x[0-9A-Fa-f]{2}$'"); 927 } 928 // Invalid: test i2c_compare_byte with property mask less than 2 hex digits. 929 { 930 json configFile = i2cCompareByteFile; 931 configFile["rules"][0]["actions"][1]["i2c_compare_byte"]["mask"] = 932 "0x8"; 933 EXPECT_JSON_INVALID(configFile, "Validation failed.", 934 "u'0x8' does not match u'^0x[0-9A-Fa-f]{2}$'"); 935 } 936 // Invalid: test i2c_compare_byte with property register no leading prefix. 937 { 938 json configFile = i2cCompareByteFile; 939 configFile["rules"][0]["actions"][1]["i2c_compare_byte"]["register"] = 940 "82"; 941 EXPECT_JSON_INVALID(configFile, "Validation failed.", 942 "u'82' does not match u'^0x[0-9A-Fa-f]{2}$'"); 943 } 944 // Invalid: test i2c_compare_byte with property value no leading prefix. 945 { 946 json configFile = i2cCompareByteFile; 947 configFile["rules"][0]["actions"][1]["i2c_compare_byte"]["value"] = 948 "82"; 949 EXPECT_JSON_INVALID(configFile, "Validation failed.", 950 "u'82' does not match u'^0x[0-9A-Fa-f]{2}$'"); 951 } 952 // Invalid: test i2c_compare_byte with property mask no leading prefix. 953 { 954 json configFile = i2cCompareByteFile; 955 configFile["rules"][0]["actions"][1]["i2c_compare_byte"]["mask"] = "82"; 956 EXPECT_JSON_INVALID(configFile, "Validation failed.", 957 "u'82' does not match u'^0x[0-9A-Fa-f]{2}$'"); 958 } 959 // Invalid: test i2c_compare_byte with property register invalid hex digit. 960 { 961 json configFile = i2cCompareByteFile; 962 configFile["rules"][0]["actions"][1]["i2c_compare_byte"]["register"] = 963 "0xG1"; 964 EXPECT_JSON_INVALID(configFile, "Validation failed.", 965 "u'0xG1' does not match u'^0x[0-9A-Fa-f]{2}$'"); 966 } 967 // Invalid: test i2c_compare_byte with property value invalid hex digit. 968 { 969 json configFile = i2cCompareByteFile; 970 configFile["rules"][0]["actions"][1]["i2c_compare_byte"]["value"] = 971 "0xG1"; 972 EXPECT_JSON_INVALID(configFile, "Validation failed.", 973 "u'0xG1' does not match u'^0x[0-9A-Fa-f]{2}$'"); 974 } 975 // Invalid: test i2c_compare_byte with property mask invalid hex digit. 976 { 977 json configFile = i2cCompareByteFile; 978 configFile["rules"][0]["actions"][1]["i2c_compare_byte"]["mask"] = 979 "0xG1"; 980 EXPECT_JSON_INVALID(configFile, "Validation failed.", 981 "u'0xG1' does not match u'^0x[0-9A-Fa-f]{2}$'"); 982 } 983 } 984 TEST(ValidateRegulatorsConfigTest, I2CCompareBytes) 985 { 986 json i2cCompareBytesFile = validConfigFile; 987 i2cCompareBytesFile["rules"][0]["actions"][1]["i2c_compare_bytes"] 988 ["register"] = "0x82"; 989 i2cCompareBytesFile["rules"][0]["actions"][1]["i2c_compare_bytes"] 990 ["values"] = {"0x02", "0x73"}; 991 i2cCompareBytesFile["rules"][0]["actions"][1]["i2c_compare_bytes"] 992 ["masks"] = {"0x7F", "0x7F"}; 993 // Valid: test i2c_compare_bytes. 994 { 995 json configFile = i2cCompareBytesFile; 996 EXPECT_JSON_VALID(configFile); 997 } 998 // Valid: test i2c_compare_bytes with all required properties. 999 { 1000 json configFile = i2cCompareBytesFile; 1001 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"].erase( 1002 "masks"); 1003 EXPECT_JSON_VALID(configFile); 1004 } 1005 // Invalid: test i2c_compare_bytes with no register. 1006 { 1007 json configFile = i2cCompareBytesFile; 1008 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"].erase( 1009 "register"); 1010 EXPECT_JSON_INVALID(configFile, "Validation failed.", 1011 "u'register' is a required property"); 1012 } 1013 // Invalid: test i2c_compare_bytes with no values. 1014 { 1015 json configFile = i2cCompareBytesFile; 1016 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"].erase( 1017 "values"); 1018 EXPECT_JSON_INVALID(configFile, "Validation failed.", 1019 "u'values' is a required property"); 1020 } 1021 // Invalid: test i2c_compare_bytes with property values as empty array. 1022 { 1023 json configFile = i2cCompareBytesFile; 1024 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["values"] = 1025 json::array(); 1026 EXPECT_JSON_INVALID(configFile, "Validation failed.", 1027 "[] is too short"); 1028 } 1029 // Invalid: test i2c_compare_bytes with property masks as empty array. 1030 { 1031 json configFile = i2cCompareBytesFile; 1032 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["masks"] = 1033 json::array(); 1034 EXPECT_JSON_INVALID(configFile, "Validation failed.", 1035 "[] is too short"); 1036 } 1037 // Invalid: test i2c_compare_bytes with property register wrong type. 1038 { 1039 json configFile = i2cCompareBytesFile; 1040 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["register"] = 1041 1; 1042 EXPECT_JSON_INVALID(configFile, "Validation failed.", 1043 "1 is not of type u'string'"); 1044 } 1045 // Invalid: test i2c_compare_bytes with property values wrong type. 1046 { 1047 json configFile = i2cCompareBytesFile; 1048 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["values"] = 1; 1049 EXPECT_JSON_INVALID(configFile, "Validation failed.", 1050 "1 is not of type u'array'"); 1051 } 1052 // Invalid: test i2c_compare_bytes with property masks wrong type. 1053 { 1054 json configFile = i2cCompareBytesFile; 1055 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["masks"] = 1; 1056 EXPECT_JSON_INVALID(configFile, "Validation failed.", 1057 "1 is not of type u'array'"); 1058 } 1059 // Invalid: test i2c_compare_bytes with property register more than 2 hex 1060 // digits. 1061 { 1062 json configFile = i2cCompareBytesFile; 1063 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["register"] = 1064 "0x820"; 1065 EXPECT_JSON_INVALID(configFile, "Validation failed.", 1066 "u'0x820' does not match u'^0x[0-9A-Fa-f]{2}$'"); 1067 } 1068 // Invalid: test i2c_compare_bytes with property values more than 2 hex 1069 // digits. 1070 { 1071 json configFile = i2cCompareBytesFile; 1072 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["values"][0] = 1073 "0x820"; 1074 EXPECT_JSON_INVALID(configFile, "Validation failed.", 1075 "u'0x820' does not match u'^0x[0-9A-Fa-f]{2}$'"); 1076 } 1077 // Invalid: test i2c_compare_bytes with property masks more than 2 hex 1078 // digits. 1079 { 1080 json configFile = i2cCompareBytesFile; 1081 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["masks"][0] = 1082 "0x820"; 1083 EXPECT_JSON_INVALID(configFile, "Validation failed.", 1084 "u'0x820' does not match u'^0x[0-9A-Fa-f]{2}$'"); 1085 } 1086 // Invalid: test i2c_compare_bytes with property register less than 2 hex 1087 // digits. 1088 { 1089 json configFile = i2cCompareBytesFile; 1090 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["register"] = 1091 "0x8"; 1092 EXPECT_JSON_INVALID(configFile, "Validation failed.", 1093 "u'0x8' does not match u'^0x[0-9A-Fa-f]{2}$'"); 1094 } 1095 // Invalid: test i2c_compare_bytes with property values less than 2 hex 1096 // digits. 1097 { 1098 json configFile = i2cCompareBytesFile; 1099 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["values"][0] = 1100 "0x8"; 1101 EXPECT_JSON_INVALID(configFile, "Validation failed.", 1102 "u'0x8' does not match u'^0x[0-9A-Fa-f]{2}$'"); 1103 } 1104 // Invalid: test i2c_compare_bytes with property masks less than 2 hex 1105 // digits. 1106 { 1107 json configFile = i2cCompareBytesFile; 1108 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["masks"][0] = 1109 "0x8"; 1110 EXPECT_JSON_INVALID(configFile, "Validation failed.", 1111 "u'0x8' does not match u'^0x[0-9A-Fa-f]{2}$'"); 1112 } 1113 // Invalid: test i2c_compare_bytes with property register no leading prefix. 1114 { 1115 json configFile = i2cCompareBytesFile; 1116 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["register"] = 1117 "82"; 1118 EXPECT_JSON_INVALID(configFile, "Validation failed.", 1119 "u'82' does not match u'^0x[0-9A-Fa-f]{2}$'"); 1120 } 1121 // Invalid: test i2c_compare_bytes with property values no leading prefix. 1122 { 1123 json configFile = i2cCompareBytesFile; 1124 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["values"][0] = 1125 "82"; 1126 EXPECT_JSON_INVALID(configFile, "Validation failed.", 1127 "u'82' does not match u'^0x[0-9A-Fa-f]{2}$'"); 1128 } 1129 // Invalid: test i2c_compare_bytes with property masks no leading prefix. 1130 { 1131 json configFile = i2cCompareBytesFile; 1132 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["masks"][0] = 1133 "82"; 1134 EXPECT_JSON_INVALID(configFile, "Validation failed.", 1135 "u'82' does not match u'^0x[0-9A-Fa-f]{2}$'"); 1136 } 1137 // Invalid: test i2c_compare_bytes with property register invalid hex digit. 1138 { 1139 json configFile = i2cCompareBytesFile; 1140 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["register"] = 1141 "0xG1"; 1142 EXPECT_JSON_INVALID(configFile, "Validation failed.", 1143 "u'0xG1' does not match u'^0x[0-9A-Fa-f]{2}$'"); 1144 } 1145 // Invalid: test i2c_compare_bytes with property values invalid hex digit. 1146 { 1147 json configFile = i2cCompareBytesFile; 1148 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["values"][0] = 1149 "0xG1"; 1150 EXPECT_JSON_INVALID(configFile, "Validation failed.", 1151 "u'0xG1' does not match u'^0x[0-9A-Fa-f]{2}$'"); 1152 } 1153 // Invalid: test i2c_compare_bytes with property masks invalid hex digit. 1154 { 1155 json configFile = i2cCompareBytesFile; 1156 configFile["rules"][0]["actions"][1]["i2c_compare_bytes"]["masks"][0] = 1157 "0xG1"; 1158 EXPECT_JSON_INVALID(configFile, "Validation failed.", 1159 "u'0xG1' does not match u'^0x[0-9A-Fa-f]{2}$'"); 1160 } 1161 } 1162 TEST(ValidateRegulatorsConfigTest, I2CInterface) 1163 { 1164 // Valid: test i2c_interface. 1165 { 1166 json configFile = validConfigFile; 1167 EXPECT_JSON_VALID(configFile); 1168 } 1169 // Invalid: testi2c_interface with no bus. 1170 { 1171 json configFile = validConfigFile; 1172 configFile["chassis"][0]["devices"][0]["i2c_interface"].erase("bus"); 1173 EXPECT_JSON_INVALID(configFile, "Validation failed.", 1174 "u'bus' is a required property"); 1175 } 1176 // Invalid: test i2c_interface with no address. 1177 { 1178 json configFile = validConfigFile; 1179 configFile["chassis"][0]["devices"][0]["i2c_interface"].erase( 1180 "address"); 1181 EXPECT_JSON_INVALID(configFile, "Validation failed.", 1182 "u'address' is a required property"); 1183 } 1184 // Invalid: test i2c_interface with property bus wrong type. 1185 { 1186 json configFile = validConfigFile; 1187 configFile["chassis"][0]["devices"][0]["i2c_interface"]["bus"] = true; 1188 EXPECT_JSON_INVALID(configFile, "Validation failed.", 1189 "True is not of type u'integer'"); 1190 } 1191 // Invalid: test i2c_interface with property address wrong 1192 // type. 1193 { 1194 json configFile = validConfigFile; 1195 configFile["chassis"][0]["devices"][0]["i2c_interface"]["address"] = 1196 true; 1197 EXPECT_JSON_INVALID(configFile, "Validation failed.", 1198 "True is not of type u'string'"); 1199 } 1200 // Invalid: test i2c_interface with property bus less than 1201 // 0. 1202 { 1203 json configFile = validConfigFile; 1204 configFile["chassis"][0]["devices"][0]["i2c_interface"]["bus"] = -1; 1205 EXPECT_JSON_INVALID(configFile, "Validation failed.", 1206 "-1 is less than the minimum of 0"); 1207 } 1208 // Invalid: test i2c_interface with property address wrong 1209 // format. 1210 { 1211 json configFile = validConfigFile; 1212 configFile["chassis"][0]["devices"][0]["i2c_interface"]["address"] = 1213 "0x700"; 1214 EXPECT_JSON_INVALID(configFile, "Validation failed.", 1215 "u'0x700' does not match u'^0x[0-9A-Fa-f]{2}$'"); 1216 } 1217 } 1218 TEST(ValidateRegulatorsConfigTest, I2CWriteBit) 1219 { 1220 json i2cWriteBitFile = validConfigFile; 1221 i2cWriteBitFile["rules"][0]["actions"][1]["i2c_write_bit"]["register"] = 1222 "0xA0"; 1223 i2cWriteBitFile["rules"][0]["actions"][1]["i2c_write_bit"]["position"] = 3; 1224 i2cWriteBitFile["rules"][0]["actions"][1]["i2c_write_bit"]["value"] = 1; 1225 // Valid: test rule actions i2c_write_bit. 1226 { 1227 json configFile = i2cWriteBitFile; 1228 EXPECT_JSON_VALID(configFile); 1229 } 1230 // Invalid: test i2c_write_bit with no register. 1231 { 1232 json configFile = i2cWriteBitFile; 1233 configFile["rules"][0]["actions"][1]["i2c_write_bit"].erase("register"); 1234 EXPECT_JSON_INVALID(configFile, "Validation failed.", 1235 "u'register' is a required property"); 1236 } 1237 // Invalid: test i2c_write_bit with no position. 1238 { 1239 json configFile = i2cWriteBitFile; 1240 configFile["rules"][0]["actions"][1]["i2c_write_bit"].erase("position"); 1241 EXPECT_JSON_INVALID(configFile, "Validation failed.", 1242 "u'position' is a required property"); 1243 } 1244 // Invalid: test i2c_write_bit with no value. 1245 { 1246 json configFile = i2cWriteBitFile; 1247 configFile["rules"][0]["actions"][1]["i2c_write_bit"].erase("value"); 1248 EXPECT_JSON_INVALID(configFile, "Validation failed.", 1249 "u'value' is a required property"); 1250 } 1251 // Invalid: test i2c_write_bit with register wrong type. 1252 { 1253 json configFile = i2cWriteBitFile; 1254 configFile["rules"][0]["actions"][1]["i2c_write_bit"]["register"] = 1; 1255 EXPECT_JSON_INVALID(configFile, "Validation failed.", 1256 "1 is not of type u'string'"); 1257 } 1258 // Invalid: test i2c_write_bit with register wrong format. 1259 { 1260 json configFile = i2cWriteBitFile; 1261 configFile["rules"][0]["actions"][1]["i2c_write_bit"]["register"] = 1262 "0xA00"; 1263 EXPECT_JSON_INVALID(configFile, "Validation failed.", 1264 "u'0xA00' does not match u'^0x[0-9A-Fa-f]{2}$'"); 1265 } 1266 // Invalid: test i2c_write_bit with position wrong type. 1267 { 1268 json configFile = i2cWriteBitFile; 1269 configFile["rules"][0]["actions"][1]["i2c_write_bit"]["position"] = 3.1; 1270 EXPECT_JSON_INVALID(configFile, "Validation failed.", 1271 "3.1 is not of type u'integer'"); 1272 } 1273 // Invalid: test i2c_write_bit with position greater than 7. 1274 { 1275 json configFile = i2cWriteBitFile; 1276 configFile["rules"][0]["actions"][1]["i2c_write_bit"]["position"] = 8; 1277 EXPECT_JSON_INVALID(configFile, "Validation failed.", 1278 "8 is greater than the maximum of 7"); 1279 } 1280 // Invalid: test i2c_write_bit with position less than 0. 1281 { 1282 json configFile = i2cWriteBitFile; 1283 configFile["rules"][0]["actions"][1]["i2c_write_bit"]["position"] = -1; 1284 EXPECT_JSON_INVALID(configFile, "Validation failed.", 1285 "-1 is less than the minimum of 0"); 1286 } 1287 // Invalid: test i2c_write_bit with value wrong type. 1288 { 1289 json configFile = i2cWriteBitFile; 1290 configFile["rules"][0]["actions"][1]["i2c_write_bit"]["value"] = "1"; 1291 EXPECT_JSON_INVALID(configFile, "Validation failed.", 1292 "u'1' is not of type u'integer'"); 1293 } 1294 // Invalid: test i2c_write_bit with value greater than 1. 1295 { 1296 json configFile = i2cWriteBitFile; 1297 configFile["rules"][0]["actions"][1]["i2c_write_bit"]["value"] = 2; 1298 EXPECT_JSON_INVALID(configFile, "Validation failed.", 1299 "2 is greater than the maximum of 1"); 1300 } 1301 // Invalid: test i2c_write_bit with value less than 0. 1302 { 1303 json configFile = i2cWriteBitFile; 1304 configFile["rules"][0]["actions"][1]["i2c_write_bit"]["value"] = -1; 1305 EXPECT_JSON_INVALID(configFile, "Validation failed.", 1306 "-1 is less than the minimum of 0"); 1307 } 1308 } 1309 TEST(ValidateRegulatorsConfigTest, I2CWriteByte) 1310 { 1311 json i2cWriteByteFile = validConfigFile; 1312 i2cWriteByteFile["rules"][0]["actions"][1]["i2c_write_byte"]["register"] = 1313 "0x82"; 1314 i2cWriteByteFile["rules"][0]["actions"][1]["i2c_write_byte"]["value"] = 1315 "0x40"; 1316 i2cWriteByteFile["rules"][0]["actions"][1]["i2c_write_byte"]["mask"] = 1317 "0x7F"; 1318 // Valid: test i2c_write_byte with all properties. 1319 { 1320 json configFile = i2cWriteByteFile; 1321 EXPECT_JSON_VALID(configFile); 1322 } 1323 // Valid: test i2c_write_byte with all required properties. 1324 { 1325 json configFile = i2cWriteByteFile; 1326 configFile["rules"][0]["actions"][1]["i2c_write_byte"].erase("mask"); 1327 EXPECT_JSON_VALID(configFile); 1328 } 1329 // Invalid: test i2c_write_byte with no register. 1330 { 1331 json configFile = i2cWriteByteFile; 1332 configFile["rules"][0]["actions"][1]["i2c_write_byte"].erase( 1333 "register"); 1334 EXPECT_JSON_INVALID(configFile, "Validation failed.", 1335 "u'register' is a required property"); 1336 } 1337 // Invalid: test i2c_write_byte with no value. 1338 { 1339 json configFile = i2cWriteByteFile; 1340 configFile["rules"][0]["actions"][1]["i2c_write_byte"].erase("value"); 1341 EXPECT_JSON_INVALID(configFile, "Validation failed.", 1342 "u'value' is a required property"); 1343 } 1344 // Invalid: test i2c_write_byte with property register wrong type. 1345 { 1346 json configFile = i2cWriteByteFile; 1347 configFile["rules"][0]["actions"][1]["i2c_write_byte"]["register"] = 1; 1348 EXPECT_JSON_INVALID(configFile, "Validation failed.", 1349 "1 is not of type u'string'"); 1350 } 1351 // Invalid: test i2c_write_byte with property value wrong type. 1352 { 1353 json configFile = i2cWriteByteFile; 1354 configFile["rules"][0]["actions"][1]["i2c_write_byte"]["value"] = 1; 1355 EXPECT_JSON_INVALID(configFile, "Validation failed.", 1356 "1 is not of type u'string'"); 1357 } 1358 // Invalid: test i2c_write_byte with property mask wrong type. 1359 { 1360 json configFile = i2cWriteByteFile; 1361 configFile["rules"][0]["actions"][1]["i2c_write_byte"]["mask"] = 1; 1362 EXPECT_JSON_INVALID(configFile, "Validation failed.", 1363 "1 is not of type u'string'"); 1364 } 1365 // Invalid: test i2c_write_byte with property register more than 2 hex 1366 // digits. 1367 { 1368 json configFile = i2cWriteByteFile; 1369 configFile["rules"][0]["actions"][1]["i2c_write_byte"]["register"] = 1370 "0x820"; 1371 EXPECT_JSON_INVALID(configFile, "Validation failed.", 1372 "u'0x820' does not match u'^0x[0-9A-Fa-f]{2}$'"); 1373 } 1374 // Invalid: test i2c_write_byte with property value more than 2 hex 1375 // digits. 1376 { 1377 json configFile = i2cWriteByteFile; 1378 configFile["rules"][0]["actions"][1]["i2c_write_byte"]["value"] = 1379 "0x820"; 1380 EXPECT_JSON_INVALID(configFile, "Validation failed.", 1381 "u'0x820' does not match u'^0x[0-9A-Fa-f]{2}$'"); 1382 } 1383 // Invalid: test i2c_write_byte with property mask more than 2 hex digits. 1384 { 1385 json configFile = i2cWriteByteFile; 1386 configFile["rules"][0]["actions"][1]["i2c_write_byte"]["mask"] = 1387 "0x820"; 1388 EXPECT_JSON_INVALID(configFile, "Validation failed.", 1389 "u'0x820' does not match u'^0x[0-9A-Fa-f]{2}$'"); 1390 } 1391 // Invalid: test i2c_write_byte with property register less than 2 hex 1392 // digits. 1393 { 1394 json configFile = i2cWriteByteFile; 1395 configFile["rules"][0]["actions"][1]["i2c_write_byte"]["register"] = 1396 "0x8"; 1397 EXPECT_JSON_INVALID(configFile, "Validation failed.", 1398 "u'0x8' does not match u'^0x[0-9A-Fa-f]{2}$'"); 1399 } 1400 // Invalid: test i2c_write_byte with property value less than 2 hex 1401 // digits. 1402 { 1403 json configFile = i2cWriteByteFile; 1404 configFile["rules"][0]["actions"][1]["i2c_write_byte"]["value"] = "0x8"; 1405 EXPECT_JSON_INVALID(configFile, "Validation failed.", 1406 "u'0x8' does not match u'^0x[0-9A-Fa-f]{2}$'"); 1407 } 1408 // Invalid: test i2c_write_byte with property mask less than 2 hex digits. 1409 { 1410 json configFile = i2cWriteByteFile; 1411 configFile["rules"][0]["actions"][1]["i2c_write_byte"]["mask"] = "0x8"; 1412 EXPECT_JSON_INVALID(configFile, "Validation failed.", 1413 "u'0x8' does not match u'^0x[0-9A-Fa-f]{2}$'"); 1414 } 1415 // Invalid: test i2c_write_byte with property register no leading prefix. 1416 { 1417 json configFile = i2cWriteByteFile; 1418 configFile["rules"][0]["actions"][1]["i2c_write_byte"]["register"] = 1419 "82"; 1420 EXPECT_JSON_INVALID(configFile, "Validation failed.", 1421 "u'82' does not match u'^0x[0-9A-Fa-f]{2}$'"); 1422 } 1423 // Invalid: test i2c_write_byte with property value no leading prefix. 1424 { 1425 json configFile = i2cWriteByteFile; 1426 configFile["rules"][0]["actions"][1]["i2c_write_byte"]["value"] = "82"; 1427 EXPECT_JSON_INVALID(configFile, "Validation failed.", 1428 "u'82' does not match u'^0x[0-9A-Fa-f]{2}$'"); 1429 } 1430 // Invalid: test i2c_write_byte with property mask no leading prefix. 1431 { 1432 json configFile = i2cWriteByteFile; 1433 configFile["rules"][0]["actions"][1]["i2c_write_byte"]["mask"] = "82"; 1434 EXPECT_JSON_INVALID(configFile, "Validation failed.", 1435 "u'82' does not match u'^0x[0-9A-Fa-f]{2}$'"); 1436 } 1437 // Invalid: test i2c_write_byte with property register invalid hex digit. 1438 { 1439 json configFile = i2cWriteByteFile; 1440 configFile["rules"][0]["actions"][1]["i2c_write_byte"]["register"] = 1441 "0xG1"; 1442 EXPECT_JSON_INVALID(configFile, "Validation failed.", 1443 "u'0xG1' does not match u'^0x[0-9A-Fa-f]{2}$'"); 1444 } 1445 // Invalid: test i2c_write_byte with property value invalid hex digit. 1446 { 1447 json configFile = i2cWriteByteFile; 1448 configFile["rules"][0]["actions"][1]["i2c_write_byte"]["value"] = 1449 "0xG1"; 1450 EXPECT_JSON_INVALID(configFile, "Validation failed.", 1451 "u'0xG1' does not match u'^0x[0-9A-Fa-f]{2}$'"); 1452 } 1453 // Invalid: test i2c_write_byte with property mask invalid hex digit. 1454 { 1455 json configFile = i2cWriteByteFile; 1456 configFile["rules"][0]["actions"][1]["i2c_write_byte"]["mask"] = "0xG1"; 1457 EXPECT_JSON_INVALID(configFile, "Validation failed.", 1458 "u'0xG1' does not match u'^0x[0-9A-Fa-f]{2}$'"); 1459 } 1460 } 1461 TEST(ValidateRegulatorsConfigTest, I2CWriteBytes) 1462 { 1463 json i2cWriteBytesFile = validConfigFile; 1464 i2cWriteBytesFile["rules"][0]["actions"][1]["i2c_write_bytes"]["register"] = 1465 "0x82"; 1466 i2cWriteBytesFile["rules"][0]["actions"][1]["i2c_write_bytes"]["values"] = { 1467 "0x02", "0x73"}; 1468 i2cWriteBytesFile["rules"][0]["actions"][1]["i2c_write_bytes"]["masks"] = { 1469 "0x7F", "0x7F"}; 1470 // Valid: test i2c_write_bytes. 1471 { 1472 json configFile = i2cWriteBytesFile; 1473 EXPECT_JSON_VALID(configFile); 1474 } 1475 // Valid: test i2c_write_bytes with all required properties. 1476 { 1477 json configFile = i2cWriteBytesFile; 1478 configFile["rules"][0]["actions"][1]["i2c_write_bytes"].erase("masks"); 1479 EXPECT_JSON_VALID(configFile); 1480 } 1481 // Invalid: test i2c_write_bytes with no register. 1482 { 1483 json configFile = i2cWriteBytesFile; 1484 configFile["rules"][0]["actions"][1]["i2c_write_bytes"].erase( 1485 "register"); 1486 EXPECT_JSON_INVALID(configFile, "Validation failed.", 1487 "u'register' is a required property"); 1488 } 1489 // Invalid: test i2c_write_bytes with no values. 1490 { 1491 json configFile = i2cWriteBytesFile; 1492 configFile["rules"][0]["actions"][1]["i2c_write_bytes"].erase("values"); 1493 EXPECT_JSON_INVALID(configFile, "Validation failed.", 1494 "u'values' is a required property"); 1495 } 1496 // Invalid: test i2c_write_bytes with property values as empty array. 1497 { 1498 json configFile = i2cWriteBytesFile; 1499 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["values"] = 1500 json::array(); 1501 EXPECT_JSON_INVALID(configFile, "Validation failed.", 1502 "[] is too short"); 1503 } 1504 // Invalid: test i2c_write_bytes with property masks as empty array. 1505 { 1506 json configFile = i2cWriteBytesFile; 1507 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["masks"] = 1508 json::array(); 1509 EXPECT_JSON_INVALID(configFile, "Validation failed.", 1510 "[] is too short"); 1511 } 1512 // Invalid: test i2c_write_bytes with property register wrong type. 1513 { 1514 json configFile = i2cWriteBytesFile; 1515 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["register"] = 1; 1516 EXPECT_JSON_INVALID(configFile, "Validation failed.", 1517 "1 is not of type u'string'"); 1518 } 1519 // Invalid: test i2c_write_bytes with property values wrong type. 1520 { 1521 json configFile = i2cWriteBytesFile; 1522 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["values"] = 1; 1523 EXPECT_JSON_INVALID(configFile, "Validation failed.", 1524 "1 is not of type u'array'"); 1525 } 1526 // Invalid: test i2c_write_bytes with property masks wrong type. 1527 { 1528 json configFile = i2cWriteBytesFile; 1529 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["masks"] = 1; 1530 EXPECT_JSON_INVALID(configFile, "Validation failed.", 1531 "1 is not of type u'array'"); 1532 } 1533 // Invalid: test i2c_write_bytes with property register more than 2 hex 1534 // digits. 1535 { 1536 json configFile = i2cWriteBytesFile; 1537 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["register"] = 1538 "0x820"; 1539 EXPECT_JSON_INVALID(configFile, "Validation failed.", 1540 "u'0x820' does not match u'^0x[0-9A-Fa-f]{2}$'"); 1541 } 1542 // Invalid: test i2c_write_bytes with property values more than 2 hex 1543 // digits. 1544 { 1545 json configFile = i2cWriteBytesFile; 1546 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["values"][0] = 1547 "0x820"; 1548 EXPECT_JSON_INVALID(configFile, "Validation failed.", 1549 "u'0x820' does not match u'^0x[0-9A-Fa-f]{2}$'"); 1550 } 1551 // Invalid: test i2c_write_bytes with property masks more than 2 hex 1552 // digits. 1553 { 1554 json configFile = i2cWriteBytesFile; 1555 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["masks"][0] = 1556 "0x820"; 1557 EXPECT_JSON_INVALID(configFile, "Validation failed.", 1558 "u'0x820' does not match u'^0x[0-9A-Fa-f]{2}$'"); 1559 } 1560 // Invalid: test i2c_write_bytes with property register less than 2 hex 1561 // digits. 1562 { 1563 json configFile = i2cWriteBytesFile; 1564 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["register"] = 1565 "0x8"; 1566 EXPECT_JSON_INVALID(configFile, "Validation failed.", 1567 "u'0x8' does not match u'^0x[0-9A-Fa-f]{2}$'"); 1568 } 1569 // Invalid: test i2c_write_bytes with property values less than 2 hex 1570 // digits. 1571 { 1572 json configFile = i2cWriteBytesFile; 1573 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["values"][0] = 1574 "0x8"; 1575 EXPECT_JSON_INVALID(configFile, "Validation failed.", 1576 "u'0x8' does not match u'^0x[0-9A-Fa-f]{2}$'"); 1577 } 1578 // Invalid: test i2c_write_bytes with property masks less than 2 hex 1579 // digits. 1580 { 1581 json configFile = i2cWriteBytesFile; 1582 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["masks"][0] = 1583 "0x8"; 1584 EXPECT_JSON_INVALID(configFile, "Validation failed.", 1585 "u'0x8' does not match u'^0x[0-9A-Fa-f]{2}$'"); 1586 } 1587 // Invalid: test i2c_write_bytes with property register no leading prefix. 1588 { 1589 json configFile = i2cWriteBytesFile; 1590 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["register"] = 1591 "82"; 1592 EXPECT_JSON_INVALID(configFile, "Validation failed.", 1593 "u'82' does not match u'^0x[0-9A-Fa-f]{2}$'"); 1594 } 1595 // Invalid: test i2c_write_bytes with property values no leading prefix. 1596 { 1597 json configFile = i2cWriteBytesFile; 1598 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["values"][0] = 1599 "82"; 1600 EXPECT_JSON_INVALID(configFile, "Validation failed.", 1601 "u'82' does not match u'^0x[0-9A-Fa-f]{2}$'"); 1602 } 1603 // Invalid: test i2c_write_bytes with property masks no leading prefix. 1604 { 1605 json configFile = i2cWriteBytesFile; 1606 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["masks"][0] = 1607 "82"; 1608 EXPECT_JSON_INVALID(configFile, "Validation failed.", 1609 "u'82' does not match u'^0x[0-9A-Fa-f]{2}$'"); 1610 } 1611 // Invalid: test i2c_write_bytes with property register invalid hex digit. 1612 { 1613 json configFile = i2cWriteBytesFile; 1614 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["register"] = 1615 "0xG1"; 1616 EXPECT_JSON_INVALID(configFile, "Validation failed.", 1617 "u'0xG1' does not match u'^0x[0-9A-Fa-f]{2}$'"); 1618 } 1619 // Invalid: test i2c_write_bytes with property values invalid hex digit. 1620 { 1621 json configFile = i2cWriteBytesFile; 1622 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["values"][0] = 1623 "0xG1"; 1624 EXPECT_JSON_INVALID(configFile, "Validation failed.", 1625 "u'0xG1' does not match u'^0x[0-9A-Fa-f]{2}$'"); 1626 } 1627 // Invalid: test i2c_write_bytes with property masks invalid hex digit. 1628 { 1629 json configFile = i2cWriteBytesFile; 1630 configFile["rules"][0]["actions"][1]["i2c_write_bytes"]["masks"][0] = 1631 "0xG1"; 1632 EXPECT_JSON_INVALID(configFile, "Validation failed.", 1633 "u'0xG1' does not match u'^0x[0-9A-Fa-f]{2}$'"); 1634 } 1635 } 1636 TEST(ValidateRegulatorsConfigTest, If) 1637 { 1638 json ifFile = validConfigFile; 1639 ifFile["rules"][2]["actions"][0]["if"]["condition"]["run_rule"] = 1640 "set_voltage_rule"; 1641 ifFile["rules"][2]["actions"][0]["if"]["then"][0]["run_rule"] = 1642 "read_sensors_rule"; 1643 ifFile["rules"][2]["actions"][0]["if"]["else"][0]["run_rule"] = 1644 "read_sensors_rule"; 1645 ifFile["rules"][2]["id"] = "rule_if"; 1646 // Valid: test if. 1647 { 1648 json configFile = ifFile; 1649 EXPECT_JSON_VALID(configFile); 1650 } 1651 // Valid: test if with required properties. 1652 { 1653 json configFile = ifFile; 1654 configFile["rules"][2]["actions"][0]["if"].erase("else"); 1655 EXPECT_JSON_VALID(configFile); 1656 } 1657 // Invalid: test if with no property condition. 1658 { 1659 json configFile = ifFile; 1660 configFile["rules"][2]["actions"][0]["if"].erase("condition"); 1661 EXPECT_JSON_INVALID(configFile, "Validation failed.", 1662 "u'condition' is a required property"); 1663 } 1664 // Invalid: test if with no property then. 1665 { 1666 json configFile = ifFile; 1667 configFile["rules"][2]["actions"][0]["if"].erase("then"); 1668 EXPECT_JSON_INVALID(configFile, "Validation failed.", 1669 "u'then' is a required property"); 1670 } 1671 // Invalid: test if with property then empty array. 1672 { 1673 json configFile = ifFile; 1674 configFile["rules"][2]["actions"][0]["if"]["then"] = json::array(); 1675 EXPECT_JSON_INVALID(configFile, "Validation failed.", 1676 "[] is too short"); 1677 } 1678 // Invalid: test if with property else empty array. 1679 { 1680 json configFile = ifFile; 1681 configFile["rules"][2]["actions"][0]["if"]["else"] = json::array(); 1682 EXPECT_JSON_INVALID(configFile, "Validation failed.", 1683 "[] is too short"); 1684 } 1685 // Invalid: test if with property condition wrong type. 1686 { 1687 json configFile = ifFile; 1688 configFile["rules"][2]["actions"][0]["if"]["condition"] = 1; 1689 EXPECT_JSON_INVALID(configFile, "Validation failed.", 1690 "1 is not of type u'object'"); 1691 } 1692 // Invalid: test if with property then wrong type. 1693 { 1694 json configFile = ifFile; 1695 configFile["rules"][2]["actions"][0]["if"]["then"] = 1; 1696 EXPECT_JSON_INVALID(configFile, "Validation failed.", 1697 "1 is not of type u'array'"); 1698 } 1699 // Invalid: test if with property else wrong type. 1700 { 1701 json configFile = ifFile; 1702 configFile["rules"][2]["actions"][0]["if"]["else"] = 1; 1703 EXPECT_JSON_INVALID(configFile, "Validation failed.", 1704 "1 is not of type u'array'"); 1705 } 1706 } 1707 TEST(ValidateRegulatorsConfigTest, Not) 1708 { 1709 json notFile = validConfigFile; 1710 notFile["rules"][0]["actions"][1]["not"]["i2c_compare_byte"]["register"] = 1711 "0xA0"; 1712 notFile["rules"][0]["actions"][1]["not"]["i2c_compare_byte"]["value"] = 1713 "0xFF"; 1714 // Valid: test not. 1715 { 1716 json configFile = notFile; 1717 EXPECT_JSON_VALID(configFile); 1718 } 1719 // Invalid: test not with wrong type. 1720 { 1721 json configFile = notFile; 1722 configFile["rules"][0]["actions"][1]["not"] = 1; 1723 EXPECT_JSON_INVALID(configFile, "Validation failed.", 1724 "1 is not of type u'object'"); 1725 } 1726 } 1727 TEST(ValidateRegulatorsConfigTest, Or) 1728 { 1729 json orFile = validConfigFile; 1730 orFile["rules"][0]["actions"][1]["or"][0]["i2c_compare_byte"]["register"] = 1731 "0xA0"; 1732 orFile["rules"][0]["actions"][1]["or"][0]["i2c_compare_byte"]["value"] = 1733 "0x00"; 1734 orFile["rules"][0]["actions"][1]["or"][1]["i2c_compare_byte"]["register"] = 1735 "0xA1"; 1736 orFile["rules"][0]["actions"][1]["or"][1]["i2c_compare_byte"]["value"] = 1737 "0x00"; 1738 // Valid: test or. 1739 { 1740 json configFile = orFile; 1741 EXPECT_JSON_VALID(configFile); 1742 } 1743 // Invalid: test or with empty array. 1744 { 1745 json configFile = orFile; 1746 configFile["rules"][0]["actions"][1]["or"] = json::array(); 1747 EXPECT_JSON_INVALID(configFile, "Validation failed.", 1748 "[] is too short"); 1749 } 1750 // Invalid: test or with wrong type. 1751 { 1752 json configFile = orFile; 1753 configFile["rules"][0]["actions"][1]["or"] = 1; 1754 EXPECT_JSON_INVALID(configFile, "Validation failed.", 1755 "1 is not of type u'array'"); 1756 } 1757 } 1758 TEST(ValidateRegulatorsConfigTest, PmbusReadSensor) 1759 { 1760 json pmbusReadSensorFile = validConfigFile; 1761 pmbusReadSensorFile["rules"][0]["actions"][1]["pmbus_read_sensor"]["type"] = 1762 "vout"; 1763 pmbusReadSensorFile["rules"][0]["actions"][1]["pmbus_read_sensor"] 1764 ["command"] = "0x8B"; 1765 pmbusReadSensorFile["rules"][0]["actions"][1]["pmbus_read_sensor"] 1766 ["format"] = "linear_16"; 1767 pmbusReadSensorFile["rules"][0]["actions"][1]["pmbus_read_sensor"] 1768 ["exponent"] = -8; 1769 // Valid: test pmbus_read_sensor. 1770 { 1771 json configFile = pmbusReadSensorFile; 1772 EXPECT_JSON_VALID(configFile); 1773 } 1774 // Valid: test pmbus_read_sensor with required properties. 1775 { 1776 json configFile = pmbusReadSensorFile; 1777 configFile["rules"][0]["actions"][1]["pmbus_read_sensor"].erase( 1778 "exponent"); 1779 EXPECT_JSON_VALID(configFile); 1780 } 1781 // Invalid: test pmbus_read_sensor with no type. 1782 { 1783 json configFile = pmbusReadSensorFile; 1784 configFile["rules"][0]["actions"][1]["pmbus_read_sensor"].erase("type"); 1785 EXPECT_JSON_INVALID(configFile, "Validation failed.", 1786 "u'type' is a required property"); 1787 } 1788 // Invalid: test pmbus_read_sensor with no command. 1789 { 1790 json configFile = pmbusReadSensorFile; 1791 configFile["rules"][0]["actions"][1]["pmbus_read_sensor"].erase( 1792 "command"); 1793 EXPECT_JSON_INVALID(configFile, "Validation failed.", 1794 "u'command' is a required property"); 1795 } 1796 // Invalid: test pmbus_read_sensor with no format. 1797 { 1798 json configFile = pmbusReadSensorFile; 1799 configFile["rules"][0]["actions"][1]["pmbus_read_sensor"].erase( 1800 "format"); 1801 EXPECT_JSON_INVALID(configFile, "Validation failed.", 1802 "u'format' is a required property"); 1803 } 1804 // Invalid: test pmbus_read_sensor with property type wrong type. 1805 { 1806 json configFile = pmbusReadSensorFile; 1807 configFile["rules"][0]["actions"][1]["pmbus_read_sensor"]["type"] = 1808 true; 1809 EXPECT_JSON_INVALID( 1810 configFile, "Validation failed.", 1811 "True is not one of [u'iout', u'iout_peak', u'iout_valley', " 1812 "u'pout', u'temperature', u'temperature_peak', u'vout', " 1813 "u'vout_peak', u'vout_valley']"); 1814 } 1815 // Invalid: test pmbus_read_sensor with property command wrong type. 1816 { 1817 json configFile = pmbusReadSensorFile; 1818 configFile["rules"][0]["actions"][1]["pmbus_read_sensor"]["command"] = 1819 true; 1820 EXPECT_JSON_INVALID(configFile, "Validation failed.", 1821 "True is not of type u'string'"); 1822 } 1823 // Invalid: test pmbus_read_sensor with property format wrong type. 1824 { 1825 json configFile = pmbusReadSensorFile; 1826 configFile["rules"][0]["actions"][1]["pmbus_read_sensor"]["format"] = 1827 true; 1828 EXPECT_JSON_INVALID(configFile, "Validation failed.", 1829 "True is not one of [u'linear_11', u'linear_16']"); 1830 } 1831 // Invalid: test pmbus_read_sensor with property exponent wrong type. 1832 { 1833 json configFile = pmbusReadSensorFile; 1834 configFile["rules"][0]["actions"][1]["pmbus_read_sensor"]["exponent"] = 1835 true; 1836 EXPECT_JSON_INVALID(configFile, "Validation failed.", 1837 "True is not of type u'integer'"); 1838 } 1839 // Invalid: test pmbus_read_sensor with property type wrong format. 1840 { 1841 json configFile = pmbusReadSensorFile; 1842 configFile["rules"][0]["actions"][1]["pmbus_read_sensor"]["type"] = 1843 "foo"; 1844 EXPECT_JSON_INVALID( 1845 configFile, "Validation failed.", 1846 "u'foo' is not one of [u'iout', u'iout_peak', u'iout_valley', " 1847 "u'pout', u'temperature', u'temperature_peak', u'vout', " 1848 "u'vout_peak', u'vout_valley']"); 1849 } 1850 // Invalid: test pmbus_read_sensor with property command wrong format. 1851 { 1852 json configFile = pmbusReadSensorFile; 1853 configFile["rules"][0]["actions"][1]["pmbus_read_sensor"]["command"] = 1854 "0x8B0"; 1855 EXPECT_JSON_INVALID(configFile, "Validation failed.", 1856 "u'0x8B0' does not match u'^0x[0-9a-fA-F]{2}$'"); 1857 } 1858 // Invalid: test pmbus_read_sensor with property format wrong format. 1859 { 1860 json configFile = pmbusReadSensorFile; 1861 configFile["rules"][0]["actions"][1]["pmbus_read_sensor"]["format"] = 1862 "foo"; 1863 EXPECT_JSON_INVALID( 1864 configFile, "Validation failed.", 1865 "u'foo' is not one of [u'linear_11', u'linear_16']"); 1866 } 1867 } 1868 TEST(ValidateRegulatorsConfigTest, PmbusWriteVoutCommand) 1869 { 1870 json pmbusWriteVoutCommandFile = validConfigFile; 1871 pmbusWriteVoutCommandFile["rules"][0]["actions"][1] 1872 ["pmbus_write_vout_command"]["volts"] = 1.03; 1873 pmbusWriteVoutCommandFile["rules"][0]["actions"][1] 1874 ["pmbus_write_vout_command"]["format"] = "linear"; 1875 pmbusWriteVoutCommandFile["rules"][0]["actions"][1] 1876 ["pmbus_write_vout_command"]["exponent"] = -8; 1877 pmbusWriteVoutCommandFile["rules"][0]["actions"][1] 1878 ["pmbus_write_vout_command"]["is_verified"] = true; 1879 // Valid: test pmbus_write_vout_command. 1880 { 1881 json configFile = pmbusWriteVoutCommandFile; 1882 EXPECT_JSON_VALID(configFile); 1883 } 1884 // Valid: test pmbus_write_vout_command with required properties. 1885 { 1886 json configFile = pmbusWriteVoutCommandFile; 1887 configFile["rules"][0]["actions"][1]["pmbus_write_vout_command"].erase( 1888 "volts"); 1889 configFile["rules"][0]["actions"][1]["pmbus_write_vout_command"].erase( 1890 "exponent"); 1891 configFile["rules"][0]["actions"][1]["pmbus_write_vout_command"].erase( 1892 "is_verified"); 1893 EXPECT_JSON_VALID(configFile); 1894 } 1895 // Invalid: test pmbus_write_vout_command with no format. 1896 { 1897 json configFile = pmbusWriteVoutCommandFile; 1898 configFile["rules"][0]["actions"][1]["pmbus_write_vout_command"].erase( 1899 "format"); 1900 EXPECT_JSON_INVALID(configFile, "Validation failed.", 1901 "u'format' is a required property"); 1902 } 1903 // Invalid: test pmbus_write_vout_command with property volts wrong type. 1904 { 1905 json configFile = pmbusWriteVoutCommandFile; 1906 configFile["rules"][0]["actions"][1]["pmbus_write_vout_command"] 1907 ["volts"] = true; 1908 EXPECT_JSON_INVALID(configFile, "Validation failed.", 1909 "True is not of type u'number'"); 1910 } 1911 // Invalid: test pmbus_write_vout_command with property format wrong type. 1912 { 1913 json configFile = pmbusWriteVoutCommandFile; 1914 configFile["rules"][0]["actions"][1]["pmbus_write_vout_command"] 1915 ["format"] = true; 1916 EXPECT_JSON_INVALID(configFile, "Validation failed.", 1917 "True is not one of [u'linear']"); 1918 } 1919 // Invalid: test pmbus_write_vout_command with property exponent wrong type. 1920 { 1921 json configFile = pmbusWriteVoutCommandFile; 1922 configFile["rules"][0]["actions"][1]["pmbus_write_vout_command"] 1923 ["exponent"] = 1.3; 1924 EXPECT_JSON_INVALID(configFile, "Validation failed.", 1925 "1.3 is not of type u'integer'"); 1926 } 1927 // Invalid: test pmbus_write_vout_command with property is_verified wrong 1928 // type. 1929 { 1930 json configFile = pmbusWriteVoutCommandFile; 1931 configFile["rules"][0]["actions"][1]["pmbus_write_vout_command"] 1932 ["is_verified"] = 1; 1933 EXPECT_JSON_INVALID(configFile, "Validation failed.", 1934 "1 is not of type u'boolean'"); 1935 } 1936 // Invalid: test pmbus_write_vout_command with property format wrong format. 1937 { 1938 json configFile = pmbusWriteVoutCommandFile; 1939 configFile["rules"][0]["actions"][1]["pmbus_write_vout_command"] 1940 ["format"] = "foo"; 1941 EXPECT_JSON_INVALID(configFile, "Validation failed.", 1942 "u'foo' is not one of [u'linear']"); 1943 } 1944 } 1945 TEST(ValidateRegulatorsConfigTest, PresenceDetection) 1946 { 1947 json presenceDetectionFile = validConfigFile; 1948 presenceDetectionFile 1949 ["chassis"][0]["devices"][0]["presence_detection"]["comments"][0] = 1950 "Regulator is only present on the FooBar backplane"; 1951 presenceDetectionFile["chassis"][0]["devices"][0]["presence_detection"] 1952 ["rule_id"] = "set_voltage_rule"; 1953 // Valid: test presence_detection with only property rule_id. 1954 { 1955 json configFile = presenceDetectionFile; 1956 EXPECT_JSON_VALID(configFile); 1957 } 1958 // Valid: test presence_detection with only property actions. 1959 { 1960 json configFile = presenceDetectionFile; 1961 configFile["chassis"][0]["devices"][0]["presence_detection"].erase( 1962 "rule_id"); 1963 configFile["chassis"][0]["devices"][0]["presence_detection"]["actions"] 1964 [0]["compare_presence"]["fru"] = 1965 "/system/chassis/motherboard/cpu3"; 1966 configFile["chassis"][0]["devices"][0]["presence_detection"]["actions"] 1967 [0]["compare_presence"]["value"] = true; 1968 configFile["chassis"][0]["devices"][0]["presence_detection"].erase( 1969 "comments"); 1970 EXPECT_JSON_VALID(configFile); 1971 } 1972 // Invalid: test presence_detection with both property rule_id and actions. 1973 { 1974 json configFile = presenceDetectionFile; 1975 configFile["chassis"][0]["devices"][0]["presence_detection"]["actions"] 1976 [0]["compare_presence"]["fru"] = 1977 "/system/chassis/motherboard/cpu3"; 1978 configFile["chassis"][0]["devices"][0]["presence_detection"]["actions"] 1979 [0]["compare_presence"]["value"] = true; 1980 EXPECT_JSON_INVALID( 1981 configFile, "Validation failed.", 1982 "{u'comments': [u'Regulator is only present on the FooBar " 1983 "backplane'], u'actions': [{u'compare_presence': {u'value': True, " 1984 "u'fru': u'/system/chassis/motherboard/cpu3'}}], u'rule_id': " 1985 "u'set_voltage_rule'} is valid under each of " 1986 "{u'required': [u'actions']}, {u'required': [u'rule_id']}"); 1987 } 1988 // Invalid: test presence_detection with no rule_id and actions. 1989 { 1990 json configFile = presenceDetectionFile; 1991 configFile["chassis"][0]["devices"][0]["presence_detection"].erase( 1992 "rule_id"); 1993 EXPECT_JSON_INVALID(configFile, "Validation failed.", 1994 "u'rule_id' is a required property"); 1995 } 1996 // Invalid: test presence_detection with property comments wrong type. 1997 { 1998 json configFile = presenceDetectionFile; 1999 configFile["chassis"][0]["devices"][0]["presence_detection"] 2000 ["comments"] = true; 2001 EXPECT_JSON_INVALID(configFile, "Validation failed.", 2002 "True is not of type u'array'"); 2003 } 2004 // Invalid: test presence_detection with property rule_id wrong type. 2005 { 2006 json configFile = presenceDetectionFile; 2007 configFile["chassis"][0]["devices"][0]["presence_detection"] 2008 ["rule_id"] = true; 2009 EXPECT_JSON_INVALID(configFile, "Validation failed.", 2010 "True is not of type u'string'"); 2011 } 2012 // Invalid: test presence_detection with property actions wrong type. 2013 { 2014 json configFile = presenceDetectionFile; 2015 configFile["chassis"][0]["devices"][0]["presence_detection"].erase( 2016 "rule_id"); 2017 configFile["chassis"][0]["devices"][0]["presence_detection"] 2018 ["actions"] = true; 2019 EXPECT_JSON_INVALID(configFile, "Validation failed.", 2020 "True is not of type u'array'"); 2021 } 2022 // Invalid: test presence_detection with property rule_id wrong format. 2023 { 2024 json configFile = presenceDetectionFile; 2025 configFile["chassis"][0]["devices"][0]["presence_detection"] 2026 ["rule_id"] = "id@"; 2027 EXPECT_JSON_INVALID(configFile, "Validation failed.", 2028 "u'id@' does not match u'^[A-Za-z0-9_]+$'"); 2029 } 2030 // Invalid: test presence_detection with property comments empty array. 2031 { 2032 json configFile = presenceDetectionFile; 2033 configFile["chassis"][0]["devices"][0]["presence_detection"] 2034 ["comments"] = json::array(); 2035 EXPECT_JSON_INVALID(configFile, "Validation failed.", 2036 "[] is too short"); 2037 } 2038 // Invalid: test presence_detection with property actions empty array. 2039 { 2040 json configFile = presenceDetectionFile; 2041 configFile["chassis"][0]["devices"][0]["presence_detection"].erase( 2042 "rule_id"); 2043 configFile["chassis"][0]["devices"][0]["presence_detection"] 2044 ["actions"] = json::array(); 2045 EXPECT_JSON_INVALID(configFile, "Validation failed.", 2046 "[] is too short"); 2047 } 2048 } 2049 TEST(ValidateRegulatorsConfigTest, Rail) 2050 { 2051 // Valid: test rail. 2052 { 2053 json configFile = validConfigFile; 2054 EXPECT_JSON_VALID(configFile); 2055 } 2056 // Valid: test rail with required properties. 2057 { 2058 json configFile = validConfigFile; 2059 configFile["chassis"][0]["devices"][0]["rails"][0].erase("comments"); 2060 configFile["chassis"][0]["devices"][0]["rails"][0].erase( 2061 "configuration"); 2062 configFile["chassis"][0]["devices"][0]["rails"][0].erase( 2063 "sensor_monitoring"); 2064 EXPECT_JSON_VALID(configFile); 2065 } 2066 // Invalid: test rail with no id. 2067 { 2068 json configFile = validConfigFile; 2069 configFile["chassis"][0]["devices"][0]["rails"][0].erase("id"); 2070 EXPECT_JSON_INVALID(configFile, "Validation failed.", 2071 "u'id' is a required property"); 2072 } 2073 // Invalid: test rail with comments wrong type. 2074 { 2075 json configFile = validConfigFile; 2076 configFile["chassis"][0]["devices"][0]["rails"][0]["comments"] = true; 2077 EXPECT_JSON_INVALID(configFile, "Validation failed.", 2078 "True is not of type u'array'"); 2079 } 2080 // Invalid: test rail with id wrong type. 2081 { 2082 json configFile = validConfigFile; 2083 configFile["chassis"][0]["devices"][0]["rails"][0]["id"] = true; 2084 EXPECT_JSON_INVALID(configFile, "Validation failed.", 2085 "True is not of type u'string'"); 2086 } 2087 // Invalid: test rail with configuration wrong type. 2088 { 2089 json configFile = validConfigFile; 2090 configFile["chassis"][0]["devices"][0]["rails"][0]["configuration"] = 2091 true; 2092 EXPECT_JSON_INVALID(configFile, "Validation failed.", 2093 "True is not of type u'object'"); 2094 } 2095 // Invalid: test rail with sensor_monitoring wrong type. 2096 { 2097 json configFile = validConfigFile; 2098 configFile["chassis"][0]["devices"][0]["rails"][0] 2099 ["sensor_monitoring"] = true; 2100 EXPECT_JSON_INVALID(configFile, "Validation failed.", 2101 "True is not of type u'object'"); 2102 } 2103 // Invalid: test rail with comments empty array. 2104 { 2105 json configFile = validConfigFile; 2106 configFile["chassis"][0]["devices"][0]["rails"][0]["comments"] = 2107 json::array(); 2108 EXPECT_JSON_INVALID(configFile, "Validation failed.", 2109 "[] is too short"); 2110 } 2111 // Invalid: test rail with id wrong format. 2112 { 2113 json configFile = validConfigFile; 2114 configFile["chassis"][0]["devices"][0]["rails"][0]["id"] = "id~"; 2115 EXPECT_JSON_INVALID(configFile, "Validation failed.", 2116 "u'id~' does not match u'^[A-Za-z0-9_]+$'"); 2117 } 2118 } 2119 TEST(ValidateRegulatorsConfigTest, Rule) 2120 { 2121 // valid test comments property, id property, 2122 // action property specified. 2123 { 2124 json configFile = validConfigFile; 2125 EXPECT_JSON_VALID(configFile); 2126 } 2127 2128 // valid test rule with no comments 2129 { 2130 json configFile = validConfigFile; 2131 configFile["rules"][0].erase("comments"); 2132 EXPECT_JSON_VALID(configFile); 2133 } 2134 2135 // invalid test comments property has invalid value type 2136 { 2137 json configFile = validConfigFile; 2138 configFile["rules"][0]["comments"] = {1}; 2139 EXPECT_JSON_INVALID(configFile, "Validation failed.", 2140 "1 is not of type u'string'"); 2141 } 2142 2143 // invalid test rule with no ID 2144 { 2145 json configFile = validConfigFile; 2146 configFile["rules"][0].erase("id"); 2147 EXPECT_JSON_INVALID(configFile, "Validation failed.", 2148 "u'id' is a required property"); 2149 } 2150 2151 // invalid test id property has invalid value type (not string) 2152 { 2153 json configFile = validConfigFile; 2154 configFile["rules"][0]["id"] = true; 2155 EXPECT_JSON_INVALID(configFile, "Validation failed.", 2156 "True is not of type u'string'"); 2157 } 2158 2159 // invalid test id property has invalid value 2160 { 2161 json configFile = validConfigFile; 2162 configFile["rules"][0]["id"] = "foo%"; 2163 EXPECT_JSON_INVALID(configFile, "Validation failed.", 2164 "u'foo%' does not match u'^[A-Za-z0-9_]+$'"); 2165 } 2166 2167 // invalid test rule with no actions property 2168 { 2169 json configFile = validConfigFile; 2170 configFile["rules"][0].erase("actions"); 2171 EXPECT_JSON_INVALID(configFile, "Validation failed.", 2172 "u'actions' is a required property"); 2173 } 2174 2175 // valid test rule with multiple actions 2176 { 2177 json configFile = validConfigFile; 2178 configFile["rules"][0]["actions"][1]["run_rule"] = "read_sensors_rule"; 2179 EXPECT_JSON_VALID(configFile); 2180 } 2181 2182 // invalid test actions property has invalid value type (not an array) 2183 { 2184 json configFile = validConfigFile; 2185 configFile["rules"][0]["actions"] = 1; 2186 EXPECT_JSON_INVALID(configFile, "Validation failed.", 2187 "1 is not of type u'array'"); 2188 } 2189 2190 // invalid test actions property has invalid value of action 2191 { 2192 json configFile = validConfigFile; 2193 configFile["rules"][0]["actions"][0] = "foo"; 2194 EXPECT_JSON_INVALID(configFile, "Validation failed.", 2195 "u'foo' is not of type u'object'"); 2196 } 2197 2198 // invalid test actions property has empty array 2199 { 2200 json configFile = validConfigFile; 2201 configFile["rules"][0]["actions"] = json::array(); 2202 EXPECT_JSON_INVALID(configFile, "Validation failed.", 2203 "[] is too short"); 2204 } 2205 } 2206 TEST(ValidateRegulatorsConfigTest, RunRule) 2207 { 2208 json runRuleFile = validConfigFile; 2209 runRuleFile["rules"][0]["actions"][1]["run_rule"] = "read_sensors_rule"; 2210 // Valid: test run_rule. 2211 { 2212 json configFile = runRuleFile; 2213 EXPECT_JSON_VALID(configFile); 2214 } 2215 // Invalid: test run_rule wrong type. 2216 { 2217 json configFile = runRuleFile; 2218 configFile["rules"][0]["actions"][1]["run_rule"] = true; 2219 EXPECT_JSON_INVALID(configFile, "Validation failed.", 2220 "True is not of type u'string'"); 2221 } 2222 // Invalid: test run_rule wrong format. 2223 { 2224 json configFile = runRuleFile; 2225 configFile["rules"][0]["actions"][1]["run_rule"] = "set_voltage_rule%"; 2226 EXPECT_JSON_INVALID( 2227 configFile, "Validation failed.", 2228 "u'set_voltage_rule%' does not match u'^[A-Za-z0-9_]+$'"); 2229 } 2230 } 2231 TEST(ValidateRegulatorsConfigTest, SensorMonitoring) 2232 { 2233 // Valid: test rails sensor_monitoring with only property rule id. 2234 { 2235 json configFile = validConfigFile; 2236 EXPECT_JSON_VALID(configFile); 2237 } 2238 // Valid: test rails sensor_monitoring with only property actions. 2239 { 2240 json configFile = validConfigFile; 2241 configFile["chassis"][0]["devices"][0]["rails"][0]["sensor_monitoring"] 2242 .erase("rule_id"); 2243 configFile["chassis"][0]["devices"][0]["rails"][0]["sensor_monitoring"] 2244 ["actions"][0]["compare_presence"]["fru"] = 2245 "/system/chassis/motherboard/cpu3"; 2246 configFile["chassis"][0]["devices"][0]["rails"][0]["sensor_monitoring"] 2247 ["actions"][0]["compare_presence"]["value"] = true; 2248 configFile["chassis"][0]["devices"][0]["rails"][0]["sensor_monitoring"] 2249 ["comments"][0] = "comments"; 2250 EXPECT_JSON_VALID(configFile); 2251 } 2252 // Invalid: test rails sensor_monitoring with both property rule_id and 2253 // actions. 2254 { 2255 json configFile = validConfigFile; 2256 configFile["chassis"][0]["devices"][0]["rails"][0]["sensor_monitoring"] 2257 ["actions"][0]["compare_presence"]["fru"] = 2258 "/system/chassis/motherboard/cpu3"; 2259 configFile["chassis"][0]["devices"][0]["rails"][0]["sensor_monitoring"] 2260 ["actions"][0]["compare_presence"]["value"] = true; 2261 EXPECT_JSON_INVALID( 2262 configFile, "Validation failed.", 2263 "{u'rule_id': u'read_sensors_rule', u'actions': " 2264 "[{u'compare_presence': {u'value': True, u'fru': " 2265 "u'/system/chassis/motherboard/cpu3'}}]} is valid under each of " 2266 "{u'required': [u'actions']}, {u'required': [u'rule_id']}"); 2267 } 2268 // Invalid: test rails sensor_monitoring with no rule_id and actions. 2269 { 2270 json configFile = validConfigFile; 2271 configFile["chassis"][0]["devices"][0]["rails"][0]["sensor_monitoring"] 2272 .erase("rule_id"); 2273 EXPECT_JSON_INVALID(configFile, "Validation failed.", 2274 "u'rule_id' is a required property"); 2275 } 2276 // Invalid: test rails sensor_monitoring with property comments wrong type. 2277 { 2278 json configFile = validConfigFile; 2279 configFile["chassis"][0]["devices"][0]["rails"][0]["sensor_monitoring"] 2280 ["comments"] = true; 2281 EXPECT_JSON_INVALID(configFile, "Validation failed.", 2282 "True is not of type u'array'"); 2283 } 2284 // Invalid: test rails sensor_monitoring with property rule_id wrong type. 2285 { 2286 json configFile = validConfigFile; 2287 configFile["chassis"][0]["devices"][0]["rails"][0]["sensor_monitoring"] 2288 ["rule_id"] = true; 2289 EXPECT_JSON_INVALID(configFile, "Validation failed.", 2290 "True is not of type u'string'"); 2291 } 2292 // Invalid: test rails sensor_monitoring with property actions wrong type. 2293 { 2294 json configFile = validConfigFile; 2295 configFile["chassis"][0]["devices"][0]["rails"][0]["sensor_monitoring"] 2296 .erase("rule_id"); 2297 configFile["chassis"][0]["devices"][0]["rails"][0]["sensor_monitoring"] 2298 ["actions"] = true; 2299 EXPECT_JSON_INVALID(configFile, "Validation failed.", 2300 "True is not of type u'array'"); 2301 } 2302 // Invalid: test rails sensor_monitoring with property rule_id wrong format. 2303 { 2304 json configFile = validConfigFile; 2305 configFile["chassis"][0]["devices"][0]["rails"][0]["sensor_monitoring"] 2306 ["rule_id"] = "id@"; 2307 EXPECT_JSON_INVALID(configFile, "Validation failed.", 2308 "u'id@' does not match u'^[A-Za-z0-9_]+$'"); 2309 } 2310 // Invalid: test rails sensor_monitoring with property comments empty array. 2311 { 2312 json configFile = validConfigFile; 2313 configFile["chassis"][0]["devices"][0]["rails"][0]["sensor_monitoring"] 2314 ["comments"] = json::array(); 2315 EXPECT_JSON_INVALID(configFile, "Validation failed.", 2316 "[] is too short"); 2317 } 2318 // Invalid: test rails sensor_monitoring with property actions empty array. 2319 { 2320 json configFile = validConfigFile; 2321 configFile["chassis"][0]["devices"][0]["rails"][0]["sensor_monitoring"] 2322 .erase("rule_id"); 2323 configFile["chassis"][0]["devices"][0]["rails"][0]["sensor_monitoring"] 2324 ["actions"] = json::array(); 2325 EXPECT_JSON_INVALID(configFile, "Validation failed.", 2326 "[] is too short"); 2327 } 2328 } 2329 TEST(ValidateRegulatorsConfigTest, SetDevice) 2330 { 2331 json setDeviceFile = validConfigFile; 2332 setDeviceFile["rules"][0]["actions"][1]["set_device"] = "vdd_regulator"; 2333 // Valid: test set_device. 2334 { 2335 json configFile = setDeviceFile; 2336 EXPECT_JSON_VALID(configFile); 2337 } 2338 // Invalid: test set_device wrong type. 2339 { 2340 json configFile = setDeviceFile; 2341 configFile["rules"][0]["actions"][1]["set_device"] = true; 2342 EXPECT_JSON_INVALID(configFile, "Validation failed.", 2343 "True is not of type u'string'"); 2344 } 2345 // Invalid: test set_device wrong format. 2346 { 2347 json configFile = setDeviceFile; 2348 configFile["rules"][0]["actions"][1]["set_device"] = "io_expander2%"; 2349 EXPECT_JSON_INVALID( 2350 configFile, "Validation failed.", 2351 "u'io_expander2%' does not match u'^[A-Za-z0-9_]+$'"); 2352 } 2353 } 2354 TEST(ValidateRegulatorsConfigTest, DuplicateRuleID) 2355 { 2356 // Invalid: test duplicate ID in rule. 2357 { 2358 json configFile = validConfigFile; 2359 configFile["rules"][2]["id"] = "set_voltage_rule"; 2360 configFile["rules"][2]["actions"][0]["pmbus_write_vout_command"] 2361 ["format"] = "linear"; 2362 EXPECT_JSON_INVALID(configFile, "Error: Duplicate rule ID.", ""); 2363 } 2364 } 2365 TEST(ValidateRegulatorsConfigTest, DuplicateChassisNumber) 2366 { 2367 // Invalid: test duplicate number in chassis. 2368 { 2369 json configFile = validConfigFile; 2370 configFile["chassis"][1]["number"] = 1; 2371 EXPECT_JSON_INVALID(configFile, "Error: Duplicate chassis number.", ""); 2372 } 2373 } 2374 TEST(ValidateRegulatorsConfigTest, DuplicateDeviceID) 2375 { 2376 // Invalid: test duplicate ID in device. 2377 { 2378 json configFile = validConfigFile; 2379 configFile["chassis"][0]["devices"][1]["id"] = "vdd_regulator"; 2380 configFile["chassis"][0]["devices"][1]["is_regulator"] = true; 2381 configFile["chassis"][0]["devices"][1]["fru"] = 2382 "/system/chassis/motherboard/regulator1"; 2383 configFile["chassis"][0]["devices"][1]["i2c_interface"]["bus"] = 2; 2384 configFile["chassis"][0]["devices"][1]["i2c_interface"]["address"] = 2385 "0x71"; 2386 EXPECT_JSON_INVALID(configFile, "Error: Duplicate device ID.", ""); 2387 } 2388 } 2389 TEST(ValidateRegulatorsConfigTest, DuplicateRailID) 2390 { 2391 // Invalid: test duplicate ID in rail. 2392 { 2393 json configFile = validConfigFile; 2394 configFile["chassis"][0]["devices"][0]["rails"][1]["id"] = "vdd"; 2395 EXPECT_JSON_INVALID(configFile, "Error: Duplicate rail ID.", ""); 2396 } 2397 } 2398 TEST(ValidateRegulatorsConfigTest, InfiniteLoops) 2399 { 2400 // Invalid: test run_rule with infinite loop (rules run each other). 2401 { 2402 json configFile = validConfigFile; 2403 configFile["rules"][2]["actions"][0]["run_rule"] = "set_voltage_rule2"; 2404 configFile["rules"][2]["id"] = "set_voltage_rule1"; 2405 configFile["rules"][3]["actions"][0]["run_rule"] = "set_voltage_rule1"; 2406 configFile["rules"][3]["id"] = "set_voltage_rule2"; 2407 EXPECT_JSON_INVALID(configFile, 2408 "Infinite loop caused by run_rule actions.", ""); 2409 } 2410 // Invalid: test run_rule with infinite loop (rule runs itself). 2411 { 2412 json configFile = validConfigFile; 2413 configFile["rules"][2]["actions"][0]["run_rule"] = "set_voltage_rule1"; 2414 configFile["rules"][2]["id"] = "set_voltage_rule1"; 2415 EXPECT_JSON_INVALID(configFile, 2416 "Infinite loop caused by run_rule actions.", ""); 2417 } 2418 // Invalid: test run_rule with infinite loop (indirect loop). 2419 { 2420 json configFile = validConfigFile; 2421 configFile["rules"][2]["actions"][0]["run_rule"] = "set_voltage_rule2"; 2422 configFile["rules"][2]["id"] = "set_voltage_rule1"; 2423 configFile["rules"][3]["actions"][0]["run_rule"] = "set_voltage_rule3"; 2424 configFile["rules"][3]["id"] = "set_voltage_rule2"; 2425 configFile["rules"][4]["actions"][0]["run_rule"] = "set_voltage_rule1"; 2426 configFile["rules"][4]["id"] = "set_voltage_rule3"; 2427 EXPECT_JSON_INVALID(configFile, 2428 "Infinite loop caused by run_rule actions.", ""); 2429 } 2430 } 2431