blob: 87d1da99c01b8f617a26b184a4c498366133493c [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 <systemd/sd-journal.h>
Patrick Venturef18bf832018-10-26 18:14:00 -07005
Patrick Venturef18bf832018-10-26 18:14:00 -07006#include <phosphor-logging/elog-errors.hpp>
Saqib Khan2bb15192017-02-13 13:19:55 -06007#include <phosphor-logging/elog.hpp>
8#include <phosphor-logging/log.hpp>
Patrick Venturef18bf832018-10-26 18:14:00 -07009#include <sdbusplus/exception.hpp>
Patrick Williams2544b412022-10-04 08:41:06 -050010
11#include <cstring>
12#include <iostream>
Patrick Venturef18bf832018-10-26 18:14:00 -070013#include <sstream>
Andrew Geissler328889d2016-10-10 12:43:48 -050014
15using namespace phosphor;
16using namespace logging;
17
Patrick Venturef18bf832018-10-26 18:14:00 -070018const char* usage = "Usage: logging-test [OPTION] \n\n\
Michael Tritze0eb1dd2017-02-19 20:57:46 -060019Options: \n\
20[NONE] Default test case. \n\
21-h, --help Display this usage text. \n\
22-c, --commit <string> Commit desired error. \n\n\
23Valid errors to commit: \n\
Marri Devender Rao54932102017-04-04 04:16:35 -050024AutoTestSimple, AutoTestCreateAndCommit\n";
Michael Tritze0eb1dd2017-02-19 20:57:46 -060025
Andrew Geissler328889d2016-10-10 12:43:48 -050026// validate the journal metadata equals the input value
Patrick Venturef18bf832018-10-26 18:14:00 -070027int validate_journal(const char* i_entry, const char* i_value)
Andrew Geissler328889d2016-10-10 12:43:48 -050028{
Patrick Venturef18bf832018-10-26 18:14:00 -070029 sd_journal* journal;
30 const void* data;
Andrew Geissler328889d2016-10-10 12:43:48 -050031 size_t l;
32 int rc;
33 bool validated = false;
34
35 rc = sd_journal_open(&journal, SD_JOURNAL_LOCAL_ONLY);
Patrick Venturef18bf832018-10-26 18:14:00 -070036 if (rc < 0)
37 {
38 std::cerr << "Failed to open journal: " << strerror(-rc) << "\n";
39 return 1;
Andrew Geissler328889d2016-10-10 12:43:48 -050040 }
41 rc = sd_journal_query_unique(journal, i_entry);
Patrick Venturef18bf832018-10-26 18:14:00 -070042 if (rc < 0)
43 {
44 std::cerr << "Failed to query journal: " << strerror(-rc) << "\n";
45 return 1;
Andrew Geissler328889d2016-10-10 12:43:48 -050046 }
47 SD_JOURNAL_FOREACH_UNIQUE(journal, data, l)
48 {
49 std::string journ_entry((const char*)data);
50 std::cout << journ_entry << "\n";
Patrick Venturef18bf832018-10-26 18:14:00 -070051 if (journ_entry.find(i_value) != std::string::npos)
Andrew Geissler328889d2016-10-10 12:43:48 -050052 {
53 std::cout << "We found it!\n";
54 validated = true;
55 break;
56 }
57 }
58
59 sd_journal_close(journal);
60
61 rc = (validated) ? 0 : 1;
Patrick Venturef18bf832018-10-26 18:14:00 -070062 if (rc)
Andrew Geissler328889d2016-10-10 12:43:48 -050063 {
Andrew Geisslerc830e0f2016-10-18 12:51:29 -050064 std::cerr << "Failed to find " << i_entry << " with value " << i_value
Patrick Venturef18bf832018-10-26 18:14:00 -070065 << " in journal!"
66 << "\n";
Andrew Geissler328889d2016-10-10 12:43:48 -050067 }
68
69 return rc;
70}
71
Michael Tritze0eb1dd2017-02-19 20:57:46 -060072int elog_test()
Andrew Geissler328889d2016-10-10 12:43:48 -050073{
74 // TEST 1 - Basic log
75 log<level::DEBUG>("Basic phosphor logging test");
76
77 // TEST 2 - Log with metadata field
Patrick Venturef18bf832018-10-26 18:14:00 -070078 const char* file_name = "phosphor_logging_test.txt";
Andrew Geissler328889d2016-10-10 12:43:48 -050079 int number = 0xFEFE;
Patrick Venturef18bf832018-10-26 18:14:00 -070080 log<level::DEBUG>(
81 "phosphor logging test with attribute",
82 entry("FILE_NAME_WITH_NUM_TEST=%s_%x", file_name, number));
Andrew Geissler328889d2016-10-10 12:43:48 -050083
84 // Now read back and verify our data made it into the journal
85 int rc = validate_journal("FILE_NAME_WITH_NUM_TEST",
86 "phosphor_logging_test.txt_fefe");
Patrick Venturef18bf832018-10-26 18:14:00 -070087 if (rc)
88 return (rc);
Andrew Geissler328889d2016-10-10 12:43:48 -050089
90 // TEST 3 - Create error log with 2 meta data fields (rvalue and lvalue)
91 number = 0x1234;
Patrick Venturef18bf832018-10-26 18:14:00 -070092 const char* test_string = "/tmp/test_string/";
Andrew Geissler6d910ad2016-10-16 20:49:14 -050093 try
94 {
Willy Tu6ddbf692023-09-05 10:54:16 -070095 elog<example::xyz::openbmc_project::example::elog::TestErrorOne>(
96 example::xyz::openbmc_project::example::elog::TestErrorOne::ERRNUM(
Patrick Venturef18bf832018-10-26 18:14:00 -070097 number),
Willy Tu6ddbf692023-09-05 10:54:16 -070098 example::xyz::openbmc_project::example::elog::TestErrorOne::
Patrick Venturef18bf832018-10-26 18:14:00 -070099 FILE_PATH(test_string),
Willy Tu6ddbf692023-09-05 10:54:16 -0700100 example::xyz::openbmc_project::example::elog::TestErrorOne::
Patrick Venturef18bf832018-10-26 18:14:00 -0700101 FILE_NAME("elog_test_3.txt"),
Willy Tu6ddbf692023-09-05 10:54:16 -0700102 example::xyz::openbmc_project::example::elog::TestErrorTwo::
Patrick Venturef18bf832018-10-26 18:14:00 -0700103 DEV_ADDR(0xDEADDEAD),
Willy Tu6ddbf692023-09-05 10:54:16 -0700104 example::xyz::openbmc_project::example::elog::TestErrorTwo::DEV_ID(
Patrick Venturef18bf832018-10-26 18:14:00 -0700105 100),
Willy Tu6ddbf692023-09-05 10:54:16 -0700106 example::xyz::openbmc_project::example::elog::TestErrorTwo::
Patrick Venturef18bf832018-10-26 18:14:00 -0700107 DEV_NAME("test case 3"));
Andrew Geissler6d910ad2016-10-16 20:49:14 -0500108 }
Willy Tu6ddbf692023-09-05 10:54:16 -0700109 catch (const example::xyz::openbmc_project::example::elog::TestErrorOne& e)
Andrew Geissler6d910ad2016-10-16 20:49:14 -0500110 {
111 std::cout << "elog exception caught: " << e.what() << std::endl;
112 }
Andrew Geissler328889d2016-10-10 12:43:48 -0500113
Andrew Geisslerdf048c12016-11-10 16:50:35 -0600114 // Reduce our error namespaces
Willy Tu6ddbf692023-09-05 10:54:16 -0700115 using namespace example::xyz::openbmc_project::example::elog;
Andrew Geisslerdf048c12016-11-10 16:50:35 -0600116
Andrew Geissler328889d2016-10-10 12:43:48 -0500117 // Now read back and verify our data made it into the journal
Andrew Geisslerc830e0f2016-10-18 12:51:29 -0500118 std::stringstream stream;
119 stream << std::hex << number;
Andrew Geisslerf1f2cfa2016-11-21 15:16:45 -0600120 rc = validate_journal(TestErrorOne::ERRNUM::str_short,
Andrew Geisslerc830e0f2016-10-18 12:51:29 -0500121 std::string(stream.str()).c_str());
Patrick Venturef18bf832018-10-26 18:14:00 -0700122 if (rc)
123 return (rc);
Andrew Geissler328889d2016-10-10 12:43:48 -0500124
Patrick Venturef18bf832018-10-26 18:14:00 -0700125 rc = validate_journal(TestErrorOne::FILE_PATH::str_short, test_string);
126 if (rc)
127 return (rc);
Andrew Geissler328889d2016-10-10 12:43:48 -0500128
Patrick Williams075c7922024-08-16 15:19:49 -0400129 rc =
130 validate_journal(TestErrorOne::FILE_NAME::str_short, "elog_test_3.txt");
Patrick Venturef18bf832018-10-26 18:14:00 -0700131 if (rc)
132 return (rc);
Andrew Geissler328889d2016-10-10 12:43:48 -0500133
Patrick Venturef18bf832018-10-26 18:14:00 -0700134 rc = validate_journal(TestErrorTwo::DEV_ADDR::str_short, "0xDEADDEAD");
135 if (rc)
136 return (rc);
Deepak Kodihalliac784cc2017-01-20 02:59:22 -0600137
Patrick Venturef18bf832018-10-26 18:14:00 -0700138 rc = validate_journal(TestErrorTwo::DEV_ID::str_short, "100");
139 if (rc)
140 return (rc);
Deepak Kodihalliac784cc2017-01-20 02:59:22 -0600141
Patrick Venturef18bf832018-10-26 18:14:00 -0700142 rc = validate_journal(TestErrorTwo::DEV_NAME::str_short, "test case 3");
143 if (rc)
144 return (rc);
Deepak Kodihalliac784cc2017-01-20 02:59:22 -0600145
Andrew Geissler328889d2016-10-10 12:43:48 -0500146 // TEST 4 - Create error log with previous entry use
Andrew Geisslerc830e0f2016-10-18 12:51:29 -0500147 number = 0x9876;
Andrew Geissler6d910ad2016-10-16 20:49:14 -0500148 try
149 {
Patrick Venturef18bf832018-10-26 18:14:00 -0700150 elog<TestErrorOne>(
151 TestErrorOne::ERRNUM(number), prev_entry<TestErrorOne::FILE_PATH>(),
152 TestErrorOne::FILE_NAME("elog_test_4.txt"),
153 TestErrorTwo::DEV_ADDR(0xDEADDEAD), TestErrorTwo::DEV_ID(100),
154 TestErrorTwo::DEV_NAME("test case 4"));
Andrew Geissler6d910ad2016-10-16 20:49:14 -0500155 }
Patrick Williams66491c62021-10-06 12:23:37 -0500156 catch (const sdbusplus::exception_t& e)
Andrew Geissler6d910ad2016-10-16 20:49:14 -0500157 {
158 std::cout << "elog exception caught: " << e.what() << std::endl;
159 }
Andrew Geisslerc830e0f2016-10-18 12:51:29 -0500160
Andrew Geissler328889d2016-10-10 12:43:48 -0500161 // Now read back and verify our data made it into the journal
Andrew Geisslerc830e0f2016-10-18 12:51:29 -0500162 stream.str("");
163 stream << std::hex << number;
Andrew Geisslerf1f2cfa2016-11-21 15:16:45 -0600164 rc = validate_journal(TestErrorOne::ERRNUM::str_short,
Andrew Geisslerc830e0f2016-10-18 12:51:29 -0500165 std::string(stream.str()).c_str());
Patrick Venturef18bf832018-10-26 18:14:00 -0700166 if (rc)
167 return (rc);
Andrew Geissler328889d2016-10-10 12:43:48 -0500168
169 // This should just be equal to what we put in test 3
Patrick Venturef18bf832018-10-26 18:14:00 -0700170 rc = validate_journal(TestErrorOne::FILE_PATH::str_short, test_string);
171 if (rc)
172 return (rc);
Andrew Geissler328889d2016-10-10 12:43:48 -0500173
Patrick Williams075c7922024-08-16 15:19:49 -0400174 rc =
175 validate_journal(TestErrorOne::FILE_NAME::str_short, "elog_test_4.txt");
Patrick Venturef18bf832018-10-26 18:14:00 -0700176 if (rc)
177 return (rc);
Andrew Geissler328889d2016-10-10 12:43:48 -0500178
Patrick Venturef18bf832018-10-26 18:14:00 -0700179 rc = validate_journal(TestErrorTwo::DEV_ADDR::str_short, "0xDEADDEAD");
180 if (rc)
181 return (rc);
Deepak Kodihalliac784cc2017-01-20 02:59:22 -0600182
Patrick Venturef18bf832018-10-26 18:14:00 -0700183 rc = validate_journal(TestErrorTwo::DEV_ID::str_short, "100");
184 if (rc)
185 return (rc);
Deepak Kodihalliac784cc2017-01-20 02:59:22 -0600186
Patrick Venturef18bf832018-10-26 18:14:00 -0700187 rc = validate_journal(TestErrorTwo::DEV_NAME::str_short, "test case 4");
188 if (rc)
189 return (rc);
Deepak Kodihalliac784cc2017-01-20 02:59:22 -0600190
Andrew Geissler328889d2016-10-10 12:43:48 -0500191 // Compile fail tests
192
193 // Simple test to prove we fail to compile due to missing param
Patrick Venturef18bf832018-10-26 18:14:00 -0700194 // elog<TestErrorOne>(TestErrorOne::ERRNUM(1),
Andrew Geisslerf1f2cfa2016-11-21 15:16:45 -0600195 // TestErrorOne::FILE_PATH("test"));
Andrew Geissler328889d2016-10-10 12:43:48 -0500196
197 // Simple test to prove we fail to compile due to invalid param
Patrick Venturef18bf832018-10-26 18:14:00 -0700198 // elog<TestErrorOne>(TestErrorOne::ERRNUM(1),
Andrew Geisslerf1f2cfa2016-11-21 15:16:45 -0600199 // TestErrorOne::FILE_PATH("test"),
200 // TestErrorOne::FILE_NAME(1));
Andrew Geissler328889d2016-10-10 12:43:48 -0500201
202 return 0;
203}
Michael Tritze0eb1dd2017-02-19 20:57:46 -0600204
Patrick Venturef18bf832018-10-26 18:14:00 -0700205void commitError(const char* text)
Michael Tritze0eb1dd2017-02-19 20:57:46 -0600206{
Patrick Venture30047bf2018-11-01 18:52:15 -0700207 if (std::strcmp(text, "AutoTestSimple") == 0)
Michael Tritze0eb1dd2017-02-19 20:57:46 -0600208 {
209 try
210 {
Willy Tu6ddbf692023-09-05 10:54:16 -0700211 elog<example::xyz::openbmc_project::example::elog::AutoTestSimple>(
212 example::xyz::openbmc_project::example::elog::AutoTestSimple::
Patrick Venturef18bf832018-10-26 18:14:00 -0700213 STRING("FOO"));
Michael Tritze0eb1dd2017-02-19 20:57:46 -0600214 }
Patrick Williams66491c62021-10-06 12:23:37 -0500215 catch (
Willy Tu6ddbf692023-09-05 10:54:16 -0700216 const example::xyz::openbmc_project::example::elog::AutoTestSimple&
Patrick Williams66491c62021-10-06 12:23:37 -0500217 e)
Michael Tritze0eb1dd2017-02-19 20:57:46 -0600218 {
219 std::cout << "elog exception caught: " << e.what() << std::endl;
220 commit(e.name());
221 }
222 }
Patrick Venture30047bf2018-11-01 18:52:15 -0700223 else if (std::strcmp(text, "AutoTestCreateAndCommit") == 0)
Marri Devender Rao54932102017-04-04 04:16:35 -0500224 {
Willy Tu6ddbf692023-09-05 10:54:16 -0700225 report<example::xyz::openbmc_project::example::elog::AutoTestSimple>(
226 example::xyz::openbmc_project::example::elog::AutoTestSimple::
Patrick Venturef18bf832018-10-26 18:14:00 -0700227 STRING("FOO"));
Marri Devender Rao54932102017-04-04 04:16:35 -0500228 }
Michael Tritze0eb1dd2017-02-19 20:57:46 -0600229
230 return;
231}
232
Patrick Venturef18bf832018-10-26 18:14:00 -0700233int main(int argc, char* argv[])
Michael Tritze0eb1dd2017-02-19 20:57:46 -0600234{
Patrick Williams9936b8a2021-04-21 21:45:19 -0500235 int arg;
Michael Tritze0eb1dd2017-02-19 20:57:46 -0600236
237 if (argc == 1)
238 return elog_test();
239
Patrick Venturef18bf832018-10-26 18:14:00 -0700240 static struct option long_options[] = {
241 {"help", no_argument, 0, 'h'},
242 {"commit", required_argument, 0, 'c'},
243 {0, 0, 0, 0}};
Michael Tritze0eb1dd2017-02-19 20:57:46 -0600244 int option_index = 0;
245
Patrick Venturef18bf832018-10-26 18:14:00 -0700246 while ((arg = getopt_long(argc, argv, "hc:", long_options,
247 &option_index)) != -1)
Michael Tritze0eb1dd2017-02-19 20:57:46 -0600248 {
249 switch (arg)
250 {
251 case 'c':
252 commitError(optarg);
253 return 0;
Michael Tritze0eb1dd2017-02-19 20:57:46 -0600254 case 'h':
255 case '?':
256 std::cerr << usage;
257 return 1;
Michael Tritze0eb1dd2017-02-19 20:57:46 -0600258 }
259 }
260
261 return 0;
Michael Tritze0eb1dd2017-02-19 20:57:46 -0600262}