blob: f9d9739949c9305f08b05afce79b200c83d47d1a [file] [log] [blame]
Andrew Geissler328889d2016-10-10 12:43:48 -05001// A basic unit test that runs on a BMC (qemu or hardware)
2
Michael Tritze0eb1dd2017-02-19 20:57:46 -06003#include <getopt.h>
Andrew Geissler328889d2016-10-10 12:43:48 -05004#include <iostream>
Andrew Geissler328889d2016-10-10 12:43:48 -05005#include <systemd/sd-journal.h>
Andrew Geisslerc830e0f2016-10-18 12:51:29 -05006#include <sstream>
Saqib Khan2bb15192017-02-13 13:19:55 -06007#include <phosphor-logging/elog.hpp>
8#include <phosphor-logging/log.hpp>
Andrew Geissler328889d2016-10-10 12:43:48 -05009
10using namespace phosphor;
11using namespace logging;
12
Michael Tritze0eb1dd2017-02-19 20:57:46 -060013const char *usage = "Usage: logging-test [OPTION] \n\n\
14Options: \n\
15[NONE] Default test case. \n\
16-h, --help Display this usage text. \n\
17-c, --commit <string> Commit desired error. \n\n\
18Valid errors to commit: \n\
19AutoTestSimple\n";
20
Andrew Geissler328889d2016-10-10 12:43:48 -050021// validate the journal metadata equals the input value
22int validate_journal(const char *i_entry, const char *i_value)
23{
24 sd_journal *journal;
25 const void *data;
26 size_t l;
27 int rc;
28 bool validated = false;
29
30 rc = sd_journal_open(&journal, SD_JOURNAL_LOCAL_ONLY);
31 if (rc < 0) {
32 std::cerr << "Failed to open journal: " << strerror(-rc) << "\n";
33 return 1;
34 }
35 rc = sd_journal_query_unique(journal, i_entry);
36 if (rc < 0) {
37 std::cerr << "Failed to query journal: " << strerror(-rc) << "\n";
38 return 1;
39 }
40 SD_JOURNAL_FOREACH_UNIQUE(journal, data, l)
41 {
42 std::string journ_entry((const char*)data);
43 std::cout << journ_entry << "\n";
44 if(journ_entry.find(i_value) != std::string::npos)
45 {
46 std::cout << "We found it!\n";
47 validated = true;
48 break;
49 }
50 }
51
52 sd_journal_close(journal);
53
54 rc = (validated) ? 0 : 1;
55 if(rc)
56 {
Andrew Geisslerc830e0f2016-10-18 12:51:29 -050057 std::cerr << "Failed to find " << i_entry << " with value " << i_value
58 <<" in journal!" << "\n";
Andrew Geissler328889d2016-10-10 12:43:48 -050059 }
60
61 return rc;
62}
63
Michael Tritze0eb1dd2017-02-19 20:57:46 -060064int elog_test()
Andrew Geissler328889d2016-10-10 12:43:48 -050065{
66 // TEST 1 - Basic log
67 log<level::DEBUG>("Basic phosphor logging test");
68
69 // TEST 2 - Log with metadata field
70 const char *file_name = "phosphor_logging_test.txt";
71 int number = 0xFEFE;
72 log<level::DEBUG>("phosphor logging test with attribute",
73 entry("FILE_NAME_WITH_NUM_TEST=%s_%x", file_name, number));
74
75 // Now read back and verify our data made it into the journal
76 int rc = validate_journal("FILE_NAME_WITH_NUM_TEST",
77 "phosphor_logging_test.txt_fefe");
78 if(rc)
79 return(rc);
80
81 // TEST 3 - Create error log with 2 meta data fields (rvalue and lvalue)
82 number = 0x1234;
83 const char *test_string = "/tmp/test_string/";
Andrew Geissler6d910ad2016-10-16 20:49:14 -050084 try
85 {
Deepak Kodihalli5221e1b2017-03-03 00:02:09 -060086 elog<example::xyz::openbmc_project::Example::Elog::TestErrorOne>(
87 example::xyz::openbmc_project::Example::Elog::
Adriana Kobylak465aaec2017-02-20 11:58:03 -060088 TestErrorOne::ERRNUM(number),
Deepak Kodihalli5221e1b2017-03-03 00:02:09 -060089 example::xyz::openbmc_project::Example::Elog::
Adriana Kobylak465aaec2017-02-20 11:58:03 -060090 TestErrorOne::FILE_PATH(test_string),
Deepak Kodihalli5221e1b2017-03-03 00:02:09 -060091 example::xyz::openbmc_project::Example::Elog::
Adriana Kobylak465aaec2017-02-20 11:58:03 -060092 TestErrorOne::FILE_NAME("elog_test_3.txt"),
Deepak Kodihalli5221e1b2017-03-03 00:02:09 -060093 example::xyz::openbmc_project::Example::Elog::
Adriana Kobylak465aaec2017-02-20 11:58:03 -060094 TestErrorTwo::DEV_ADDR(0xDEADDEAD),
Deepak Kodihalli5221e1b2017-03-03 00:02:09 -060095 example::xyz::openbmc_project::Example::Elog::
Adriana Kobylak465aaec2017-02-20 11:58:03 -060096 TestErrorTwo::DEV_ID(100),
Deepak Kodihalli5221e1b2017-03-03 00:02:09 -060097 example::xyz::openbmc_project::Example::Elog::
Adriana Kobylak465aaec2017-02-20 11:58:03 -060098 TestErrorTwo::DEV_NAME("test case 3"));
Andrew Geissler6d910ad2016-10-16 20:49:14 -050099 }
Deepak Kodihalli5221e1b2017-03-03 00:02:09 -0600100 catch (elogException<example::xyz::openbmc_project::Example::Elog::
Adriana Kobylak465aaec2017-02-20 11:58:03 -0600101 TestErrorOne>& e)
Andrew Geissler6d910ad2016-10-16 20:49:14 -0500102 {
103 std::cout << "elog exception caught: " << e.what() << std::endl;
104 }
Andrew Geissler328889d2016-10-10 12:43:48 -0500105
Andrew Geisslerdf048c12016-11-10 16:50:35 -0600106 // Reduce our error namespaces
Deepak Kodihalli5221e1b2017-03-03 00:02:09 -0600107 using namespace example::xyz::openbmc_project::Example::Elog;
Andrew Geisslerdf048c12016-11-10 16:50:35 -0600108
Andrew Geissler328889d2016-10-10 12:43:48 -0500109 // Now read back and verify our data made it into the journal
Andrew Geisslerc830e0f2016-10-18 12:51:29 -0500110 std::stringstream stream;
111 stream << std::hex << number;
Andrew Geisslerf1f2cfa2016-11-21 15:16:45 -0600112 rc = validate_journal(TestErrorOne::ERRNUM::str_short,
Andrew Geisslerc830e0f2016-10-18 12:51:29 -0500113 std::string(stream.str()).c_str());
Andrew Geissler328889d2016-10-10 12:43:48 -0500114 if(rc)
115 return(rc);
116
Andrew Geisslerf1f2cfa2016-11-21 15:16:45 -0600117 rc = validate_journal(TestErrorOne::FILE_PATH::str_short,
Andrew Geissler328889d2016-10-10 12:43:48 -0500118 test_string);
119 if(rc)
120 return(rc);
121
Andrew Geisslerf1f2cfa2016-11-21 15:16:45 -0600122 rc = validate_journal(TestErrorOne::FILE_NAME::str_short,
Andrew Geissler328889d2016-10-10 12:43:48 -0500123 "elog_test_3.txt");
124 if(rc)
125 return(rc);
126
Deepak Kodihalliac784cc2017-01-20 02:59:22 -0600127 rc = validate_journal(TestErrorTwo::DEV_ADDR::str_short,
128 "0xDEADDEAD");
129 if(rc)
130 return(rc);
131
132 rc = validate_journal(TestErrorTwo::DEV_ID::str_short,
133 "100");
134 if(rc)
135 return(rc);
136
137 rc = validate_journal(TestErrorTwo::DEV_NAME::str_short,
138 "test case 3");
139 if(rc)
140 return(rc);
141
Andrew Geissler328889d2016-10-10 12:43:48 -0500142 // TEST 4 - Create error log with previous entry use
Andrew Geisslerc830e0f2016-10-18 12:51:29 -0500143 number = 0x9876;
Andrew Geissler6d910ad2016-10-16 20:49:14 -0500144 try
145 {
Andrew Geisslerf1f2cfa2016-11-21 15:16:45 -0600146 elog<TestErrorOne>(TestErrorOne::ERRNUM(number),
147 prev_entry<TestErrorOne::FILE_PATH>(),
Deepak Kodihallif2462f02017-01-19 03:40:12 -0600148 TestErrorOne::FILE_NAME("elog_test_4.txt"),
Deepak Kodihalliac784cc2017-01-20 02:59:22 -0600149 TestErrorTwo::DEV_ADDR(0xDEADDEAD),
150 TestErrorTwo::DEV_ID(100),
Deepak Kodihallif2462f02017-01-19 03:40:12 -0600151 TestErrorTwo::DEV_NAME("test case 4"));
Andrew Geissler6d910ad2016-10-16 20:49:14 -0500152 }
153 catch (elogExceptionBase& e)
154 {
155 std::cout << "elog exception caught: " << e.what() << std::endl;
156 }
Andrew Geisslerc830e0f2016-10-18 12:51:29 -0500157
Andrew Geissler328889d2016-10-10 12:43:48 -0500158 // Now read back and verify our data made it into the journal
Andrew Geisslerc830e0f2016-10-18 12:51:29 -0500159 stream.str("");
160 stream << std::hex << number;
Andrew Geisslerf1f2cfa2016-11-21 15:16:45 -0600161 rc = validate_journal(TestErrorOne::ERRNUM::str_short,
Andrew Geisslerc830e0f2016-10-18 12:51:29 -0500162 std::string(stream.str()).c_str());
Andrew Geissler328889d2016-10-10 12:43:48 -0500163 if(rc)
164 return(rc);
165
166 // This should just be equal to what we put in test 3
Andrew Geisslerf1f2cfa2016-11-21 15:16:45 -0600167 rc = validate_journal(TestErrorOne::FILE_PATH::str_short,
Andrew Geissler328889d2016-10-10 12:43:48 -0500168 test_string);
169 if(rc)
170 return(rc);
171
Andrew Geisslerf1f2cfa2016-11-21 15:16:45 -0600172 rc = validate_journal(TestErrorOne::FILE_NAME::str_short,
Andrew Geissler328889d2016-10-10 12:43:48 -0500173 "elog_test_4.txt");
174 if(rc)
175 return(rc);
176
Deepak Kodihalliac784cc2017-01-20 02:59:22 -0600177 rc = validate_journal(TestErrorTwo::DEV_ADDR::str_short,
178 "0xDEADDEAD");
179 if(rc)
180 return(rc);
181
182 rc = validate_journal(TestErrorTwo::DEV_ID::str_short,
183 "100");
184 if(rc)
185 return(rc);
186
187 rc = validate_journal(TestErrorTwo::DEV_NAME::str_short,
188 "test case 4");
189 if(rc)
190 return(rc);
191
Andrew Geissler328889d2016-10-10 12:43:48 -0500192 // Compile fail tests
193
194 // Simple test to prove we fail to compile due to missing param
Andrew Geisslerf1f2cfa2016-11-21 15:16:45 -0600195 //elog<TestErrorOne>(TestErrorOne::ERRNUM(1),
196 // TestErrorOne::FILE_PATH("test"));
Andrew Geissler328889d2016-10-10 12:43:48 -0500197
198 // Simple test to prove we fail to compile due to invalid param
Andrew Geisslerf1f2cfa2016-11-21 15:16:45 -0600199 //elog<TestErrorOne>(TestErrorOne::ERRNUM(1),
200 // TestErrorOne::FILE_PATH("test"),
201 // TestErrorOne::FILE_NAME(1));
Andrew Geissler328889d2016-10-10 12:43:48 -0500202
203 return 0;
204}
Michael Tritze0eb1dd2017-02-19 20:57:46 -0600205
206void commitError(const char *text)
207{
208 if (strcmp(text, "AutoTestSimple") == 0)
209 {
210 try
211 {
212 elog<example::xyz::openbmc_project::Example::Elog::
Deepak Kodihalli98a18342017-03-15 09:19:34 -0500213 AutoTestSimple>(
Michael Tritze0eb1dd2017-02-19 20:57:46 -0600214 example::xyz::openbmc_project::Example::Elog::
Deepak Kodihalli98a18342017-03-15 09:19:34 -0500215 AutoTestSimple::STRING("FOO"));
Michael Tritze0eb1dd2017-02-19 20:57:46 -0600216 }
217 catch (elogException<example::xyz::openbmc_project::Example::Elog::
Deepak Kodihalli98a18342017-03-15 09:19:34 -0500218 AutoTestSimple>& e)
Michael Tritze0eb1dd2017-02-19 20:57:46 -0600219 {
220 std::cout << "elog exception caught: " << e.what() << std::endl;
221 commit(e.name());
222 }
223 }
224
225 return;
226}
227
228int main(int argc, char *argv[])
229{
230 char arg;
231
232 if (argc == 1)
233 return elog_test();
234
235 static struct option long_options[] =
236 {
237 {"help", no_argument, 0, 'h'},
238 {"commit", required_argument, 0, 'c'},
239 {0, 0, 0, 0}
240 };
241 int option_index = 0;
242
243 while((arg=getopt_long(argc,argv,"hc:",long_options,&option_index)) != -1)
244 {
245 switch (arg)
246 {
247 case 'c':
248 commitError(optarg);
249 return 0;
250
251 case 'h':
252 case '?':
253 std::cerr << usage;
254 return 1;
255
256 }
257 }
258
259 return 0;
260
261}