1 #include <systemd_target_parser.hpp> 2 #include <gtest/gtest.h> 3 4 #include <iostream> 5 #include <cstdio> 6 #include <cstdlib> 7 #include <filesystem> 8 9 namespace fs = std::filesystem; 10 11 // Enable debug by default for debug when needed 12 bool gVerbose = true; 13 14 TEST(TargetJsonParser, BasicGoodPath) 15 { 16 auto defaultData1 = R"( 17 { 18 "targets" : { 19 "multi-user.target" : { 20 "errorsToMonitor": ["default"], 21 "errorToLog": "xyz.openbmc_project.State.BMC.Error.MultiUserTargetFailure"}, 22 "obmc-chassis-poweron@0.target" : { 23 "errorsToMonitor": ["timeout", "failed"], 24 "errorToLog": "xyz.openbmc_project.State.Chassis.Error.PowerOnTargetFailure"} 25 } 26 } 27 )"_json; 28 29 auto defaultData2 = R"( 30 { 31 "targets" : { 32 "obmc-host-start@0.target" : { 33 "errorsToMonitor": ["default"], 34 "errorToLog": "xyz.openbmc_project.State.Host.Error.HostStartFailure"}, 35 "obmc-host-stop@0.target" : { 36 "errorsToMonitor": ["dependency"], 37 "errorToLog": "xyz.openbmc_project.State.Host.Error.HostStopFailure"} 38 } 39 } 40 )"_json; 41 42 std::FILE* tmpf = fopen("/tmp/good_file1.json", "w"); 43 std::fputs(defaultData1.dump().c_str(), tmpf); 44 std::fclose(tmpf); 45 46 tmpf = fopen("/tmp/good_file2.json", "w"); 47 std::fputs(defaultData2.dump().c_str(), tmpf); 48 std::fclose(tmpf); 49 50 std::vector<std::string> filePaths; 51 filePaths.push_back("/tmp/good_file1.json"); 52 filePaths.push_back("/tmp/good_file2.json"); 53 54 TargetErrorData targetData = parseFiles(filePaths); 55 56 EXPECT_EQ(targetData.size(), 4); 57 EXPECT_NE(targetData.find("multi-user.target"), targetData.end()); 58 EXPECT_NE(targetData.find("obmc-chassis-poweron@0.target"), 59 targetData.end()); 60 EXPECT_NE(targetData.find("obmc-host-start@0.target"), targetData.end()); 61 EXPECT_NE(targetData.find("obmc-host-stop@0.target"), targetData.end()); 62 targetEntry tgt = targetData["obmc-chassis-poweron@0.target"]; 63 EXPECT_EQ(tgt.errorToLog, 64 "xyz.openbmc_project.State.Chassis.Error.PowerOnTargetFailure"); 65 EXPECT_EQ(tgt.errorsToMonitor.size(), 2); 66 67 std::remove("/tmp/good_file1.json"); 68 std::remove("/tmp/good_file2.json"); 69 } 70 71 TEST(TargetJsonParser, InvalidErrorToMonitor) 72 { 73 auto invalidDataError = R"( 74 { 75 "targets" : { 76 "obmc-chassis-poweron@0.target" : { 77 "errorsToMonitor": ["timeout", "invalid"], 78 "errorToLog": "xyz.openbmc_project.State.Chassis.Error.PowerOnTargetFailure"} 79 } 80 } 81 )"_json; 82 83 std::FILE* tmpf = fopen("/tmp/invalid_error_file.json", "w"); 84 std::fputs(invalidDataError.dump().c_str(), tmpf); 85 std::fclose(tmpf); 86 87 std::vector<std::string> filePaths; 88 filePaths.push_back("/tmp/invalid_error_file.json"); 89 90 // Verify exception thrown on invalid errorsToMonitor 91 EXPECT_THROW(TargetErrorData targetData = parseFiles(filePaths), 92 std::out_of_range); 93 std::remove("/tmp/invalid_error_file.json"); 94 } 95 96 TEST(TargetJsonParser, InvalidFileFormat) 97 { 98 std::FILE* tmpf = fopen("/tmp/invalid_json_file.json", "w"); 99 std::fputs("{\"targets\":{\"missing closing quote}}", tmpf); 100 fclose(tmpf); 101 102 std::vector<std::string> filePaths; 103 filePaths.push_back("/tmp/invalid_json_file.json"); 104 105 // Verify exception thrown on invalid json file format 106 EXPECT_THROW(TargetErrorData targetData = parseFiles(filePaths), 107 nlohmann::detail::parse_error); 108 std::remove("/tmp/invalid_json_file.json"); 109 } 110