1*5494e21dSAlexander Hansen #include "event_log.hpp"
2*5494e21dSAlexander Hansen
3*5494e21dSAlexander Hansen #include <nlohmann/json.hpp>
4*5494e21dSAlexander Hansen
5*5494e21dSAlexander Hansen #include <cerrno>
6*5494e21dSAlexander Hansen #include <cstddef>
7*5494e21dSAlexander Hansen #include <ctime>
8*5494e21dSAlexander Hansen #include <string>
9*5494e21dSAlexander Hansen #include <string_view>
10*5494e21dSAlexander Hansen #include <vector>
11*5494e21dSAlexander Hansen
12*5494e21dSAlexander Hansen #include <gmock/gmock.h>
13*5494e21dSAlexander Hansen #include <gtest/gtest.h>
14*5494e21dSAlexander Hansen
15*5494e21dSAlexander Hansen namespace redfish::event_log
16*5494e21dSAlexander Hansen {
17*5494e21dSAlexander Hansen namespace
18*5494e21dSAlexander Hansen {
19*5494e21dSAlexander Hansen
TEST(RedfishEventLog,GetUniqueEntryIDSuccess)20*5494e21dSAlexander Hansen TEST(RedfishEventLog, GetUniqueEntryIDSuccess)
21*5494e21dSAlexander Hansen {
22*5494e21dSAlexander Hansen bool success = false;
23*5494e21dSAlexander Hansen std::string entryID;
24*5494e21dSAlexander Hansen std::string example = "2000-01-02T03:04:05";
25*5494e21dSAlexander Hansen success = getUniqueEntryID(example, entryID);
26*5494e21dSAlexander Hansen
27*5494e21dSAlexander Hansen ASSERT_EQ(success, true);
28*5494e21dSAlexander Hansen
29*5494e21dSAlexander Hansen // assert the prefix since the specific number can depend on timezone
30*5494e21dSAlexander Hansen ASSERT_TRUE(entryID.starts_with("946"));
31*5494e21dSAlexander Hansen }
32*5494e21dSAlexander Hansen
TEST(RedfishEventLog,GetUniqueEntryIDUnique)33*5494e21dSAlexander Hansen TEST(RedfishEventLog, GetUniqueEntryIDUnique)
34*5494e21dSAlexander Hansen {
35*5494e21dSAlexander Hansen bool success = false;
36*5494e21dSAlexander Hansen std::string entryID1;
37*5494e21dSAlexander Hansen std::string entryID2;
38*5494e21dSAlexander Hansen std::string example = "2000-08-02T03:04:05";
39*5494e21dSAlexander Hansen
40*5494e21dSAlexander Hansen success = getUniqueEntryID(example, entryID1);
41*5494e21dSAlexander Hansen ASSERT_EQ(success, true);
42*5494e21dSAlexander Hansen success = getUniqueEntryID(example, entryID2);
43*5494e21dSAlexander Hansen ASSERT_EQ(success, true);
44*5494e21dSAlexander Hansen
45*5494e21dSAlexander Hansen // when calling a second time with the same argument
46*5494e21dSAlexander Hansen // there should be an underscore
47*5494e21dSAlexander Hansen ASSERT_TRUE(entryID2.contains("_"));
48*5494e21dSAlexander Hansen
49*5494e21dSAlexander Hansen // only one '_' allowed
50*5494e21dSAlexander Hansen ASSERT_THAT(entryID2, testing::MatchesRegex("^[0-9]+_[0-9]+$"));
51*5494e21dSAlexander Hansen }
52*5494e21dSAlexander Hansen
TEST(RedfishEventLog,GetUniqueEntryIDIndex)53*5494e21dSAlexander Hansen TEST(RedfishEventLog, GetUniqueEntryIDIndex)
54*5494e21dSAlexander Hansen {
55*5494e21dSAlexander Hansen std::string entryID1;
56*5494e21dSAlexander Hansen std::string entryID2;
57*5494e21dSAlexander Hansen std::string entryID3;
58*5494e21dSAlexander Hansen std::string example = "2000-08-02T03:04:05";
59*5494e21dSAlexander Hansen
60*5494e21dSAlexander Hansen getUniqueEntryID(example, entryID1);
61*5494e21dSAlexander Hansen getUniqueEntryID(example, entryID2);
62*5494e21dSAlexander Hansen getUniqueEntryID(example, entryID3);
63*5494e21dSAlexander Hansen
64*5494e21dSAlexander Hansen const size_t index = entryID2.find('_');
65*5494e21dSAlexander Hansen
66*5494e21dSAlexander Hansen ASSERT_NE(index, std::string::npos);
67*5494e21dSAlexander Hansen
68*5494e21dSAlexander Hansen const long n1 = std::stol(entryID2.substr(index + 1));
69*5494e21dSAlexander Hansen
70*5494e21dSAlexander Hansen // unique index for repeated timestamp is >= 0
71*5494e21dSAlexander Hansen ASSERT_GE(n1, 0);
72*5494e21dSAlexander Hansen
73*5494e21dSAlexander Hansen const long n2 = std::stol(entryID3.substr(entryID3.find('_') + 1));
74*5494e21dSAlexander Hansen
75*5494e21dSAlexander Hansen // unique index is monotonic increasing
76*5494e21dSAlexander Hansen ASSERT_TRUE(n2 > n1);
77*5494e21dSAlexander Hansen }
78*5494e21dSAlexander Hansen
TEST(RedfishEventLog,GetEventLogParamsSuccess)79*5494e21dSAlexander Hansen TEST(RedfishEventLog, GetEventLogParamsSuccess)
80*5494e21dSAlexander Hansen {
81*5494e21dSAlexander Hansen int status = 0;
82*5494e21dSAlexander Hansen std::string logEntry = "32938 3,hello";
83*5494e21dSAlexander Hansen
84*5494e21dSAlexander Hansen std::string timestamp;
85*5494e21dSAlexander Hansen std::string messageID;
86*5494e21dSAlexander Hansen std::vector<std::string> messageArgs;
87*5494e21dSAlexander Hansen
88*5494e21dSAlexander Hansen status = getEventLogParams(logEntry, timestamp, messageID, messageArgs);
89*5494e21dSAlexander Hansen
90*5494e21dSAlexander Hansen ASSERT_EQ(status, 0);
91*5494e21dSAlexander Hansen
92*5494e21dSAlexander Hansen ASSERT_EQ(timestamp, "32938");
93*5494e21dSAlexander Hansen ASSERT_EQ(messageID, "3");
94*5494e21dSAlexander Hansen ASSERT_EQ(messageArgs.size(), 1);
95*5494e21dSAlexander Hansen ASSERT_EQ(messageArgs[0], "hello");
96*5494e21dSAlexander Hansen }
97*5494e21dSAlexander Hansen
TEST(RedfishEventLog,GetEventLogParamsFailNoTimestamp)98*5494e21dSAlexander Hansen TEST(RedfishEventLog, GetEventLogParamsFailNoTimestamp)
99*5494e21dSAlexander Hansen {
100*5494e21dSAlexander Hansen int status = 0;
101*5494e21dSAlexander Hansen std::string logEntry = "3,hello";
102*5494e21dSAlexander Hansen
103*5494e21dSAlexander Hansen std::string timestamp;
104*5494e21dSAlexander Hansen std::string messageID;
105*5494e21dSAlexander Hansen std::vector<std::string> messageArgs;
106*5494e21dSAlexander Hansen
107*5494e21dSAlexander Hansen status = getEventLogParams(logEntry, timestamp, messageID, messageArgs);
108*5494e21dSAlexander Hansen
109*5494e21dSAlexander Hansen ASSERT_EQ(status, -EINVAL);
110*5494e21dSAlexander Hansen }
111*5494e21dSAlexander Hansen
TEST(RedfishEventLog,GetEventLogParamsFailNoComma)112*5494e21dSAlexander Hansen TEST(RedfishEventLog, GetEventLogParamsFailNoComma)
113*5494e21dSAlexander Hansen {
114*5494e21dSAlexander Hansen int status = 0;
115*5494e21dSAlexander Hansen std::string logEntry = "malformed";
116*5494e21dSAlexander Hansen
117*5494e21dSAlexander Hansen std::string timestamp;
118*5494e21dSAlexander Hansen std::string messageID;
119*5494e21dSAlexander Hansen std::vector<std::string> messageArgs;
120*5494e21dSAlexander Hansen
121*5494e21dSAlexander Hansen status = getEventLogParams(logEntry, timestamp, messageID, messageArgs);
122*5494e21dSAlexander Hansen
123*5494e21dSAlexander Hansen ASSERT_EQ(status, -EINVAL);
124*5494e21dSAlexander Hansen }
125*5494e21dSAlexander Hansen
TEST(RedfishEventLog,FormatEventLogEntrySuccess)126*5494e21dSAlexander Hansen TEST(RedfishEventLog, FormatEventLogEntrySuccess)
127*5494e21dSAlexander Hansen {
128*5494e21dSAlexander Hansen int status = 0;
129*5494e21dSAlexander Hansen std::string logEntryID = "23849423_3";
130*5494e21dSAlexander Hansen std::string messageID = "OpenBMC.0.1.PowerSupplyFanFailed";
131*5494e21dSAlexander Hansen std::vector<std::string_view> messageArgs = {"PSU 1", "FAN 2"};
132*5494e21dSAlexander Hansen std::string timestamp = "my-timestamp";
133*5494e21dSAlexander Hansen std::string customText = "customText";
134*5494e21dSAlexander Hansen
135*5494e21dSAlexander Hansen nlohmann::json::object_t logEntryJson;
136*5494e21dSAlexander Hansen status = formatEventLogEntry(logEntryID, messageID, messageArgs, timestamp,
137*5494e21dSAlexander Hansen customText, logEntryJson);
138*5494e21dSAlexander Hansen
139*5494e21dSAlexander Hansen ASSERT_EQ(status, 0);
140*5494e21dSAlexander Hansen
141*5494e21dSAlexander Hansen ASSERT_TRUE(logEntryJson.contains("EventId"));
142*5494e21dSAlexander Hansen ASSERT_EQ(logEntryJson["EventId"], "23849423_3");
143*5494e21dSAlexander Hansen
144*5494e21dSAlexander Hansen ASSERT_TRUE(logEntryJson.contains("Message"));
145*5494e21dSAlexander Hansen ASSERT_EQ(logEntryJson["Message"], "Power supply PSU 1 fan FAN 2 failed.");
146*5494e21dSAlexander Hansen
147*5494e21dSAlexander Hansen ASSERT_TRUE(logEntryJson.contains("MessageId"));
148*5494e21dSAlexander Hansen ASSERT_EQ(logEntryJson["MessageId"], "OpenBMC.0.1.PowerSupplyFanFailed");
149*5494e21dSAlexander Hansen
150*5494e21dSAlexander Hansen ASSERT_TRUE(logEntryJson.contains("MessageArgs"));
151*5494e21dSAlexander Hansen ASSERT_EQ(logEntryJson["MessageArgs"].size(), 2);
152*5494e21dSAlexander Hansen ASSERT_EQ(logEntryJson["MessageArgs"][0], "PSU 1");
153*5494e21dSAlexander Hansen ASSERT_EQ(logEntryJson["MessageArgs"][1], "FAN 2");
154*5494e21dSAlexander Hansen
155*5494e21dSAlexander Hansen ASSERT_TRUE(logEntryJson.contains("EventTimestamp"));
156*5494e21dSAlexander Hansen
157*5494e21dSAlexander Hansen // May need to fix this, it should not pass like this.
158*5494e21dSAlexander Hansen ASSERT_EQ(logEntryJson["EventTimestamp"], "my-timestamp");
159*5494e21dSAlexander Hansen
160*5494e21dSAlexander Hansen ASSERT_TRUE(logEntryJson.contains("Context"));
161*5494e21dSAlexander Hansen ASSERT_EQ(logEntryJson["Context"], "customText");
162*5494e21dSAlexander Hansen }
163*5494e21dSAlexander Hansen
TEST(RedfishEventLog,FormatEventLogEntryFail)164*5494e21dSAlexander Hansen TEST(RedfishEventLog, FormatEventLogEntryFail)
165*5494e21dSAlexander Hansen {
166*5494e21dSAlexander Hansen int status = 0;
167*5494e21dSAlexander Hansen std::string logEntryID = "malformed";
168*5494e21dSAlexander Hansen std::string messageID;
169*5494e21dSAlexander Hansen std::vector<std::string_view> messageArgs;
170*5494e21dSAlexander Hansen std::string timestamp;
171*5494e21dSAlexander Hansen std::string customText;
172*5494e21dSAlexander Hansen
173*5494e21dSAlexander Hansen nlohmann::json::object_t logEntryJson;
174*5494e21dSAlexander Hansen status = formatEventLogEntry(logEntryID, messageID, messageArgs, timestamp,
175*5494e21dSAlexander Hansen customText, logEntryJson);
176*5494e21dSAlexander Hansen
177*5494e21dSAlexander Hansen ASSERT_EQ(status, -1);
178*5494e21dSAlexander Hansen }
179*5494e21dSAlexander Hansen
180*5494e21dSAlexander Hansen } // namespace
181*5494e21dSAlexander Hansen } // namespace redfish::event_log
182