xref: /openbmc/bmcweb/test/redfish-core/include/event_log_test.cpp (revision 4a19a7b5e62ad2569913d944c84c19f1005c922f)
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