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