xref: /aosp_15_r20/external/pigweed/pw_log/basic_log_test.cc (revision 61c4878ac05f98d0ceed94b57d316916de578985)
1 // Copyright 2020 The Pigweed Authors
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License"); you may not
4 // use this file except in compliance with the License. You may obtain a copy of
5 // the License at
6 //
7 //     https://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11 // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12 // License for the specific language governing permissions and limitations under
13 // the License.
14 
15 // This is mostly a compile test to verify that the log backend is able to
16 // compile the constructs  promised by the logging facade; and that when run,
17 // there is no crash.
18 //
19 // TODO: b/235289499 - Add verification of the actually logged statements.
20 
21 // clang-format off
22 #define PW_LOG_MODULE_NAME "TST"
23 #define PW_LOG_LEVEL PW_LOG_LEVEL_DEBUG
24 #include "pw_log/log.h"
25 #include "pw_log/short.h"
26 #include "pw_log/shorter.h"
27 // clang-format on
28 
29 #include "pw_unit_test/framework.h"
30 
31 namespace {
32 
33 // TODO: b/235291136 - Test unsigned integer logging (32 and 64 bit); test
34 // pointer logging.
35 
LoggingFromFunction()36 void LoggingFromFunction() { PW_LOG_INFO("From a function!"); }
37 
38 const int N = 3;
39 
TEST(BasicLog,DebugLevel)40 TEST(BasicLog, DebugLevel) {
41   PW_LOG_DEBUG("This log statement should be at DEBUG level; no args");
42   for (int i = 0; i < N; ++i) {
43     PW_LOG_DEBUG("Counting: %d", i);
44   }
45   PW_LOG_DEBUG("Here is a string: %s; with another string %s", "foo", "bar");
46 }
47 
TEST(BasicLog,InfoLevel)48 TEST(BasicLog, InfoLevel) {
49   PW_LOG_INFO("This log statement should be at INFO level; no args");
50   for (int i = 0; i < N; ++i) {
51     PW_LOG_INFO("Counting: %d", i);
52   }
53   PW_LOG_INFO("Here is a string: %s; with another string %s", "foo", "bar");
54 }
55 
TEST(BasicLog,WarnLevel)56 TEST(BasicLog, WarnLevel) {
57   PW_LOG_WARN("This log statement should be at WARN level; no args");
58   for (int i = 0; i < N; ++i) {
59     PW_LOG_WARN("Counting: %d", i);
60   }
61   PW_LOG_WARN("Here is a string: %s; with another string %s", "foo", "bar");
62 }
63 
TEST(BasicLog,ErrorLevel)64 TEST(BasicLog, ErrorLevel) {
65   PW_LOG_ERROR("This log statement should be at ERROR level; no args");
66   for (int i = 0; i < N; ++i) {
67     PW_LOG_ERROR("Counting: %d", i);
68   }
69   PW_LOG_ERROR("Here is a string: %s; with another string %s", "foo", "bar");
70 }
71 
TEST(BasicLog,CriticalLevel)72 TEST(BasicLog, CriticalLevel) {
73   PW_LOG_CRITICAL("Critical, emergency log. Device should not reboot");
74 }
75 
TEST(BasicLog,ManualLevel)76 TEST(BasicLog, ManualLevel) {
77   PW_LOG(PW_LOG_LEVEL_DEBUG,
78          PW_LOG_LEVEL,
79          PW_LOG_MODULE_NAME,
80          0,
81          "A manual DEBUG-level message");
82   PW_LOG(PW_LOG_LEVEL_DEBUG,
83          PW_LOG_LEVEL,
84          PW_LOG_MODULE_NAME,
85          1,
86          "A manual DEBUG-level message; with a flag");
87 
88   PW_LOG(PW_LOG_LEVEL_INFO,
89          PW_LOG_LEVEL,
90          PW_LOG_MODULE_NAME,
91          0,
92          "A manual INFO-level message");
93   PW_LOG(PW_LOG_LEVEL_INFO,
94          PW_LOG_LEVEL,
95          PW_LOG_MODULE_NAME,
96          1,
97          "A manual INFO-level message; with a flag");
98 
99   PW_LOG(PW_LOG_LEVEL_WARN,
100          PW_LOG_LEVEL,
101          PW_LOG_MODULE_NAME,
102          0,
103          "A manual WARN-level message");
104   PW_LOG(PW_LOG_LEVEL_WARN,
105          PW_LOG_LEVEL,
106          PW_LOG_MODULE_NAME,
107          1,
108          "A manual WARN-level message; with a flag");
109 
110   PW_LOG(PW_LOG_LEVEL_ERROR,
111          PW_LOG_LEVEL,
112          PW_LOG_MODULE_NAME,
113          0,
114          "A manual ERROR-level message");
115   PW_LOG(PW_LOG_LEVEL_ERROR,
116          PW_LOG_LEVEL,
117          PW_LOG_MODULE_NAME,
118          1,
119          "A manual ERROR-level message; with a flag");
120 
121   PW_LOG(PW_LOG_LEVEL_CRITICAL,
122          PW_LOG_LEVEL,
123          PW_LOG_MODULE_NAME,
124          0,
125          "A manual CRITICAL-level message");
126   PW_LOG(PW_LOG_LEVEL_CRITICAL,
127          PW_LOG_LEVEL,
128          PW_LOG_MODULE_NAME,
129          1,
130          "A manual CRITICAL-level message; with a flag");
131 }
132 
TEST(BasicLog,FromAFunction)133 TEST(BasicLog, FromAFunction) { LoggingFromFunction(); }
134 
TEST(BasicLog,CustomLogLevels)135 TEST(BasicLog, CustomLogLevels) {
136   // Log levels other than the standard ones work; what each backend does is
137   // implementation defined.
138   PW_LOG(0, PW_LOG_LEVEL, "", 0, "Custom log level: 0");
139   PW_LOG(1, PW_LOG_LEVEL, "", 0, "Custom log level: 1");
140   PW_LOG(2, PW_LOG_LEVEL, "", 0, "Custom log level: 2");
141   PW_LOG(3, PW_LOG_LEVEL, "", 0, "Custom log level: 3");
142   PW_LOG(100, PW_LOG_LEVEL, "", 0, "Custom log level: 100");
143 }
144 
145 #define TEST_FAILED_LOG "IF THIS MESSAGE WAS LOGGED, THE TEST FAILED"
146 
TEST(BasicLog,FilteringByLevel)147 TEST(BasicLog, FilteringByLevel) {
148 #undef PW_LOG_SKIP_LOGS_WITH_LEVEL_LT
149 #define PW_LOG_SKIP_LOGS_WITH_LEVEL_LT PW_LOG_LEVEL_ERROR
150 
151   PW_LOG_DEBUG(TEST_FAILED_LOG);
152   PW_LOG_INFO(TEST_FAILED_LOG);
153   PW_LOG_WARN(TEST_FAILED_LOG);
154 
155   PW_LOG_ERROR("This log should appear as error status (and that's good)");
156 
157 #undef PW_LOG_SKIP_LOGS_WITH_LEVEL_LT
158 #define PW_LOG_SKIP_LOGS_WITH_LEVEL_LT 0
159 }
160 
TEST(BasicLog,FilteringByFlags)161 TEST(BasicLog, FilteringByFlags) {
162 #undef PW_LOG_SKIP_LOGS_WITH_FLAGS
163 #define PW_LOG_SKIP_LOGS_WITH_FLAGS 1
164 
165   // Flag is set so these should all get zapped.
166   PW_LOG(
167       PW_LOG_LEVEL_INFO, PW_LOG_LEVEL, PW_LOG_MODULE_NAME, 1, TEST_FAILED_LOG);
168   PW_LOG(
169       PW_LOG_LEVEL_ERROR, PW_LOG_LEVEL, PW_LOG_MODULE_NAME, 1, TEST_FAILED_LOG);
170 
171   // However, a different flag bit should still log.
172   PW_LOG(PW_LOG_LEVEL_INFO,
173          PW_LOG_LEVEL,
174          PW_LOG_MODULE_NAME,
175          1 << 1,
176          "This flagged log is intended to appear");
177   PW_LOG(PW_LOG_LEVEL_ERROR,
178          PW_LOG_LEVEL,
179          PW_LOG_MODULE_NAME,
180          1 << 1,
181          "This flagged log is intended to appear");
182 
183 #undef PW_LOG_SKIP_LOGS_WITH_FLAGS
184 #define PW_LOG_SKIP_LOGS_WITH_FLAGS 0
185 }
186 
TEST(BasicLog,ChangingTheModuleName)187 TEST(BasicLog, ChangingTheModuleName) {
188 #undef PW_LOG_MODULE_NAME
189 #define PW_LOG_MODULE_NAME "PQR"
190   PW_LOG_INFO("This has a custom module name");
191   PW_LOG_INFO("So does this");
192 }
193 
TEST(BasicLog,ShortNames)194 TEST(BasicLog, ShortNames) {
195   LOG(PW_LOG_LEVEL_INFO, PW_LOG_LEVEL, PW_LOG_MODULE_NAME, 0, "Shrt lg");
196   LOG_DEBUG("A debug log: %d", 1);
197   LOG_INFO("An info log: %d", 2);
198   LOG_WARN("A warning log: %d", 3);
199   LOG_ERROR("An error log: %d", 4);
200   LOG_CRITICAL("A critical log: %d", 4);
201 }
202 
TEST(BasicLog,UltraShortNames)203 TEST(BasicLog, UltraShortNames) {
204   LOG(PW_LOG_LEVEL_INFO, PW_LOG_LEVEL, PW_LOG_MODULE_NAME, 0, "Shrt lg");
205   DBG("A debug log: %d", 1);
206   INF("An info log: %d", 2);
207   WRN("A warning log: %d", 3);
208   ERR("An error log: %d", 4);
209   CRT("A critical log: %d", 4);
210 }
211 
212 extern "C" void BasicLogTestPlainC();
213 
TEST(BasicLog,FromPlainC)214 TEST(BasicLog, FromPlainC) { BasicLogTestPlainC(); }
215 
216 // Test that adding to the format string compiles correctly. If PW_COMMA_ARGS is
217 // used in PW_LOG_INFO and the other wrappers in pw_log/log.h, then these
218 // functions tests fail to compile, because the arguments end up out-of-order.
219 
220 #undef PW_LOG
221 #define PW_LOG(level, verbosity, module, flags, message, ...)            \
222   DoNothingFakeFunction(module,                                          \
223                         "%d/%d/%d: incoming transmission [" message "]", \
224                         level,                                           \
225                         __LINE__,                                        \
226                         flags PW_COMMA_ARGS(__VA_ARGS__))
227 
228 void DoNothingFakeFunction(const char*, const char*, ...)
229     PW_PRINTF_FORMAT(2, 3);
230 
DoNothingFakeFunction(const char *,const char *,...)231 void DoNothingFakeFunction(const char*, const char*, ...) {}
232 
TEST(CustomFormatString,DebugLevel)233 TEST(CustomFormatString, DebugLevel) {
234   PW_LOG_DEBUG("This log statement should be at DEBUG level; no args");
235   for (int i = 0; i < N; ++i) {
236     PW_LOG_DEBUG("Counting: %d", i);
237   }
238   PW_LOG_DEBUG("Here is a string: %s; with another string %s", "foo", "bar");
239 }
240 
TEST(CustomFormatString,InfoLevel)241 TEST(CustomFormatString, InfoLevel) {
242   PW_LOG_INFO("This log statement should be at INFO level; no args");
243   for (int i = 0; i < N; ++i) {
244     PW_LOG_INFO("Counting: %d", i);
245   }
246   PW_LOG_INFO("Here is a string: %s; with another string %s", "foo", "bar");
247 }
248 
TEST(CustomFormatString,WarnLevel)249 TEST(CustomFormatString, WarnLevel) {
250   PW_LOG_WARN("This log statement should be at WARN level; no args");
251   for (int i = 0; i < N; ++i) {
252     PW_LOG_WARN("Counting: %d", i);
253   }
254   PW_LOG_WARN("Here is a string: %s; with another string %s", "foo", "bar");
255 }
256 
TEST(CustomFormatString,ErrorLevel)257 TEST(CustomFormatString, ErrorLevel) {
258   PW_LOG_ERROR("This log statement should be at ERROR level; no args");
259   for (int i = 0; i < N; ++i) {
260     PW_LOG_ERROR("Counting: %d", i);
261   }
262   PW_LOG_ERROR("Here is a string: %s; with another string %s", "foo", "bar");
263 }
264 
TEST(CustomFormatString,CriticalLevel)265 TEST(CustomFormatString, CriticalLevel) {
266   PW_LOG_CRITICAL("Critical, emergency log. Device should not reboot");
267 }
268 
269 }  // namespace
270