xref: /openbmc/phosphor-state-manager/test/systemd_parser.cpp (revision 437f0b27d51fbfdeb65f2d4ec8f0dd26bdbfbc37)
1693eaed0SAndrew Geissler #include <systemd_target_parser.hpp>
2693eaed0SAndrew Geissler 
3693eaed0SAndrew Geissler #include <cstdio>
4693eaed0SAndrew Geissler #include <cstdlib>
5693eaed0SAndrew Geissler #include <filesystem>
6e426b589SAndrew Geissler #include <iostream>
7e426b589SAndrew Geissler 
8e426b589SAndrew Geissler #include <gtest/gtest.h>
9693eaed0SAndrew Geissler 
10693eaed0SAndrew Geissler namespace fs = std::filesystem;
11693eaed0SAndrew Geissler 
12693eaed0SAndrew Geissler // Enable debug by default for debug when needed
13693eaed0SAndrew Geissler bool gVerbose = true;
14693eaed0SAndrew Geissler 
TEST(TargetJsonParser,BasicGoodPath)15693eaed0SAndrew Geissler TEST(TargetJsonParser, BasicGoodPath)
16693eaed0SAndrew Geissler {
17693eaed0SAndrew Geissler     auto defaultData1 = R"(
18693eaed0SAndrew Geissler         {
19693eaed0SAndrew Geissler             "targets" : {
20693eaed0SAndrew Geissler                 "multi-user.target" : {
21693eaed0SAndrew Geissler                     "errorsToMonitor": ["default"],
22693eaed0SAndrew Geissler                     "errorToLog": "xyz.openbmc_project.State.BMC.Error.MultiUserTargetFailure"},
23693eaed0SAndrew Geissler                 "obmc-chassis-poweron@0.target" : {
24693eaed0SAndrew Geissler                     "errorsToMonitor": ["timeout", "failed"],
25693eaed0SAndrew Geissler                     "errorToLog": "xyz.openbmc_project.State.Chassis.Error.PowerOnTargetFailure"}
26693eaed0SAndrew Geissler                 }
27693eaed0SAndrew Geissler         }
28693eaed0SAndrew Geissler     )"_json;
29693eaed0SAndrew Geissler 
30693eaed0SAndrew Geissler     auto defaultData2 = R"(
31693eaed0SAndrew Geissler         {
32693eaed0SAndrew Geissler             "targets" : {
33693eaed0SAndrew Geissler                 "obmc-host-start@0.target" : {
34693eaed0SAndrew Geissler                     "errorsToMonitor": ["default"],
35693eaed0SAndrew Geissler                     "errorToLog": "xyz.openbmc_project.State.Host.Error.HostStartFailure"},
36693eaed0SAndrew Geissler                 "obmc-host-stop@0.target" : {
37693eaed0SAndrew Geissler                     "errorsToMonitor": ["dependency"],
38693eaed0SAndrew Geissler                     "errorToLog": "xyz.openbmc_project.State.Host.Error.HostStopFailure"}
39693eaed0SAndrew Geissler                 }
40693eaed0SAndrew Geissler         }
41693eaed0SAndrew Geissler     )"_json;
42693eaed0SAndrew Geissler 
43693eaed0SAndrew Geissler     std::FILE* tmpf = fopen("/tmp/good_file1.json", "w");
44693eaed0SAndrew Geissler     std::fputs(defaultData1.dump().c_str(), tmpf);
45693eaed0SAndrew Geissler     std::fclose(tmpf);
46693eaed0SAndrew Geissler 
47693eaed0SAndrew Geissler     tmpf = fopen("/tmp/good_file2.json", "w");
48693eaed0SAndrew Geissler     std::fputs(defaultData2.dump().c_str(), tmpf);
49693eaed0SAndrew Geissler     std::fclose(tmpf);
50693eaed0SAndrew Geissler 
51693eaed0SAndrew Geissler     std::vector<std::string> filePaths;
52*437f0b27SPavithra Barithaya     filePaths.emplace_back("/tmp/good_file1.json");
53*437f0b27SPavithra Barithaya     filePaths.emplace_back("/tmp/good_file2.json");
54693eaed0SAndrew Geissler 
55693eaed0SAndrew Geissler     TargetErrorData targetData = parseFiles(filePaths);
56693eaed0SAndrew Geissler 
57693eaed0SAndrew Geissler     EXPECT_EQ(targetData.size(), 4);
58693eaed0SAndrew Geissler     EXPECT_NE(targetData.find("multi-user.target"), targetData.end());
59693eaed0SAndrew Geissler     EXPECT_NE(targetData.find("obmc-chassis-poweron@0.target"),
60693eaed0SAndrew Geissler               targetData.end());
61693eaed0SAndrew Geissler     EXPECT_NE(targetData.find("obmc-host-start@0.target"), targetData.end());
62693eaed0SAndrew Geissler     EXPECT_NE(targetData.find("obmc-host-stop@0.target"), targetData.end());
63693eaed0SAndrew Geissler     targetEntry tgt = targetData["obmc-chassis-poweron@0.target"];
64693eaed0SAndrew Geissler     EXPECT_EQ(tgt.errorToLog,
65693eaed0SAndrew Geissler               "xyz.openbmc_project.State.Chassis.Error.PowerOnTargetFailure");
66693eaed0SAndrew Geissler     EXPECT_EQ(tgt.errorsToMonitor.size(), 2);
6775a2614fSAndrew Geissler     // Check a target with "default" for errorsToMonitor, should have 3 defaults
6875a2614fSAndrew Geissler     tgt = targetData["obmc-host-start@0.target"];
6975a2614fSAndrew Geissler     EXPECT_EQ(tgt.errorsToMonitor.size(), 3);
70693eaed0SAndrew Geissler 
71693eaed0SAndrew Geissler     std::remove("/tmp/good_file1.json");
72693eaed0SAndrew Geissler     std::remove("/tmp/good_file2.json");
73693eaed0SAndrew Geissler }
74693eaed0SAndrew Geissler 
TEST(TargetJsonParser,InvalidErrorToMonitor)75693eaed0SAndrew Geissler TEST(TargetJsonParser, InvalidErrorToMonitor)
76693eaed0SAndrew Geissler {
77693eaed0SAndrew Geissler     auto invalidDataError = R"(
78693eaed0SAndrew Geissler         {
79693eaed0SAndrew Geissler             "targets" : {
80693eaed0SAndrew Geissler                 "obmc-chassis-poweron@0.target" : {
81693eaed0SAndrew Geissler                     "errorsToMonitor": ["timeout", "invalid"],
82693eaed0SAndrew Geissler                     "errorToLog": "xyz.openbmc_project.State.Chassis.Error.PowerOnTargetFailure"}
83693eaed0SAndrew Geissler                 }
84693eaed0SAndrew Geissler         }
85693eaed0SAndrew Geissler     )"_json;
86693eaed0SAndrew Geissler 
87693eaed0SAndrew Geissler     std::FILE* tmpf = fopen("/tmp/invalid_error_file.json", "w");
88693eaed0SAndrew Geissler     std::fputs(invalidDataError.dump().c_str(), tmpf);
89693eaed0SAndrew Geissler     std::fclose(tmpf);
90693eaed0SAndrew Geissler 
91693eaed0SAndrew Geissler     std::vector<std::string> filePaths;
92*437f0b27SPavithra Barithaya     filePaths.emplace_back("/tmp/invalid_error_file.json");
93693eaed0SAndrew Geissler 
94693eaed0SAndrew Geissler     // Verify exception thrown on invalid errorsToMonitor
95693eaed0SAndrew Geissler     EXPECT_THROW(TargetErrorData targetData = parseFiles(filePaths),
96693eaed0SAndrew Geissler                  std::out_of_range);
97693eaed0SAndrew Geissler     std::remove("/tmp/invalid_error_file.json");
98693eaed0SAndrew Geissler }
99693eaed0SAndrew Geissler 
TEST(TargetJsonParser,InvalidFileFormat)100693eaed0SAndrew Geissler TEST(TargetJsonParser, InvalidFileFormat)
101693eaed0SAndrew Geissler {
102693eaed0SAndrew Geissler     std::FILE* tmpf = fopen("/tmp/invalid_json_file.json", "w");
10366a93fc8SPavithra Barithaya     std::fputs(R"({"targets":{"missing closing quote}})", tmpf);
104693eaed0SAndrew Geissler     fclose(tmpf);
105693eaed0SAndrew Geissler 
106693eaed0SAndrew Geissler     std::vector<std::string> filePaths;
107*437f0b27SPavithra Barithaya     filePaths.emplace_back("/tmp/invalid_json_file.json");
108693eaed0SAndrew Geissler 
109693eaed0SAndrew Geissler     // Verify exception thrown on invalid json file format
110693eaed0SAndrew Geissler     EXPECT_THROW(TargetErrorData targetData = parseFiles(filePaths),
111693eaed0SAndrew Geissler                  nlohmann::detail::parse_error);
112693eaed0SAndrew Geissler     std::remove("/tmp/invalid_json_file.json");
113693eaed0SAndrew Geissler }
11475a2614fSAndrew Geissler 
TEST(TargetJsonParser,NotJustDefault)11575a2614fSAndrew Geissler TEST(TargetJsonParser, NotJustDefault)
11675a2614fSAndrew Geissler {
11775a2614fSAndrew Geissler     auto notJustDefault = R"(
11875a2614fSAndrew Geissler         {
11975a2614fSAndrew Geissler             "targets" : {
12075a2614fSAndrew Geissler                 "obmc-chassis-poweron@0.target" : {
12175a2614fSAndrew Geissler                     "errorsToMonitor": ["timeout", "default"],
12275a2614fSAndrew Geissler                     "errorToLog": "xyz.openbmc_project.State.Chassis.Error.PowerOnTargetFailure"}
12375a2614fSAndrew Geissler                 }
12475a2614fSAndrew Geissler         }
12575a2614fSAndrew Geissler     )"_json;
12675a2614fSAndrew Geissler 
12775a2614fSAndrew Geissler     std::FILE* tmpf = fopen("/tmp/not_just_default_file.json", "w");
12875a2614fSAndrew Geissler     std::fputs(notJustDefault.dump().c_str(), tmpf);
12975a2614fSAndrew Geissler     std::fclose(tmpf);
13075a2614fSAndrew Geissler 
13175a2614fSAndrew Geissler     std::vector<std::string> filePaths;
132*437f0b27SPavithra Barithaya     filePaths.emplace_back("/tmp/not_just_default_file.json");
13375a2614fSAndrew Geissler 
13475a2614fSAndrew Geissler     // Verify exception thrown on invalid errorsToMonitor
13575a2614fSAndrew Geissler     EXPECT_THROW(TargetErrorData targetData = parseFiles(filePaths),
13675a2614fSAndrew Geissler                  std::invalid_argument);
13775a2614fSAndrew Geissler     std::remove("/tmp/not_just_default_file.json");
13875a2614fSAndrew Geissler }
139