• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 // TODO: b/235291136 - Test unsigned integer logging (32 and 64 bit); test
32 // pointer logging.
33 
LoggingFromFunction()34 void LoggingFromFunction() { PW_LOG_INFO("From a function!"); }
35 
36 const int N = 3;
37 
TEST(BasicLog,DebugLevel)38 TEST(BasicLog, DebugLevel) {
39   PW_LOG_DEBUG("This log statement should be at DEBUG level; no args");
40   for (int i = 0; i < N; ++i) {
41     PW_LOG_DEBUG("Counting: %d", i);
42   }
43   PW_LOG_DEBUG("Here is a string: %s; with another string %s", "foo", "bar");
44 }
45 
TEST(BasicLog,InfoLevel)46 TEST(BasicLog, InfoLevel) {
47   PW_LOG_INFO("This log statement should be at INFO level; no args");
48   for (int i = 0; i < N; ++i) {
49     PW_LOG_INFO("Counting: %d", i);
50   }
51   PW_LOG_INFO("Here is a string: %s; with another string %s", "foo", "bar");
52 }
53 
TEST(BasicLog,WarnLevel)54 TEST(BasicLog, WarnLevel) {
55   PW_LOG_WARN("This log statement should be at WARN level; no args");
56   for (int i = 0; i < N; ++i) {
57     PW_LOG_WARN("Counting: %d", i);
58   }
59   PW_LOG_WARN("Here is a string: %s; with another string %s", "foo", "bar");
60 }
61 
TEST(BasicLog,ErrorLevel)62 TEST(BasicLog, ErrorLevel) {
63   PW_LOG_ERROR("This log statement should be at ERROR level; no args");
64   for (int i = 0; i < N; ++i) {
65     PW_LOG_ERROR("Counting: %d", i);
66   }
67   PW_LOG_ERROR("Here is a string: %s; with another string %s", "foo", "bar");
68 }
69 
TEST(BasicLog,CriticalLevel)70 TEST(BasicLog, CriticalLevel) {
71   PW_LOG_CRITICAL("Critical, emergency log. Device should not reboot");
72 }
73 
TEST(BasicLog,ManualLevel)74 TEST(BasicLog, ManualLevel) {
75   PW_LOG(PW_LOG_LEVEL_DEBUG,
76          PW_LOG_MODULE_NAME,
77          0,
78          "A manual DEBUG-level message");
79   PW_LOG(PW_LOG_LEVEL_DEBUG,
80          PW_LOG_MODULE_NAME,
81          1,
82          "A manual DEBUG-level message; with a flag");
83 
84   PW_LOG(
85       PW_LOG_LEVEL_INFO, PW_LOG_MODULE_NAME, 0, "A manual INFO-level message");
86   PW_LOG(PW_LOG_LEVEL_INFO,
87          PW_LOG_MODULE_NAME,
88          1,
89          "A manual INFO-level message; with a flag");
90 
91   PW_LOG(
92       PW_LOG_LEVEL_WARN, PW_LOG_MODULE_NAME, 0, "A manual WARN-level message");
93   PW_LOG(PW_LOG_LEVEL_WARN,
94          PW_LOG_MODULE_NAME,
95          1,
96          "A manual WARN-level message; with a flag");
97 
98   PW_LOG(PW_LOG_LEVEL_ERROR,
99          PW_LOG_MODULE_NAME,
100          0,
101          "A manual ERROR-level message");
102   PW_LOG(PW_LOG_LEVEL_ERROR,
103          PW_LOG_MODULE_NAME,
104          1,
105          "A manual ERROR-level message; with a flag");
106 
107   PW_LOG(PW_LOG_LEVEL_CRITICAL,
108          PW_LOG_MODULE_NAME,
109          0,
110          "A manual CRITICAL-level message");
111   PW_LOG(PW_LOG_LEVEL_CRITICAL,
112          PW_LOG_MODULE_NAME,
113          1,
114          "A manual CRITICAL-level message; with a flag");
115 }
116 
TEST(BasicLog,FromAFunction)117 TEST(BasicLog, FromAFunction) { LoggingFromFunction(); }
118 
TEST(BasicLog,CustomLogLevels)119 TEST(BasicLog, CustomLogLevels) {
120   // Log levels other than the standard ones work; what each backend does is
121   // implementation defined.
122   PW_LOG(0, "", 0, "Custom log level: 0");
123   PW_LOG(1, "", 0, "Custom log level: 1");
124   PW_LOG(2, "", 0, "Custom log level: 2");
125   PW_LOG(3, "", 0, "Custom log level: 3");
126   PW_LOG(100, "", 0, "Custom log level: 100");
127 }
128 
129 #define TEST_FAILED_LOG "IF THIS MESSAGE WAS LOGGED, THE TEST FAILED"
130 
TEST(BasicLog,FilteringByLevel)131 TEST(BasicLog, FilteringByLevel) {
132 #undef PW_LOG_SKIP_LOGS_WITH_LEVEL_LT
133 #define PW_LOG_SKIP_LOGS_WITH_LEVEL_LT PW_LOG_LEVEL_ERROR
134 
135   PW_LOG_DEBUG(TEST_FAILED_LOG);
136   PW_LOG_INFO(TEST_FAILED_LOG);
137   PW_LOG_WARN(TEST_FAILED_LOG);
138 
139   PW_LOG_ERROR("This log should appear as error status (and that's good)");
140 
141 #undef PW_LOG_SKIP_LOGS_WITH_LEVEL_LT
142 #define PW_LOG_SKIP_LOGS_WITH_LEVEL_LT 0
143 }
144 
TEST(BasicLog,FilteringByFlags)145 TEST(BasicLog, FilteringByFlags) {
146 #undef PW_LOG_SKIP_LOGS_WITH_FLAGS
147 #define PW_LOG_SKIP_LOGS_WITH_FLAGS 1
148 
149   // Flag is set so these should all get zapped.
150   PW_LOG(PW_LOG_LEVEL_INFO, PW_LOG_MODULE_NAME, 1, TEST_FAILED_LOG);
151   PW_LOG(PW_LOG_LEVEL_ERROR, PW_LOG_MODULE_NAME, 1, TEST_FAILED_LOG);
152 
153   // However, a different flag bit should still log.
154   PW_LOG(PW_LOG_LEVEL_INFO,
155          PW_LOG_MODULE_NAME,
156          1 << 1,
157          "This flagged log is intended to appear");
158   PW_LOG(PW_LOG_LEVEL_ERROR,
159          PW_LOG_MODULE_NAME,
160          1 << 1,
161          "This flagged log is intended to appear");
162 
163 #undef PW_LOG_SKIP_LOGS_WITH_FLAGS
164 #define PW_LOG_SKIP_LOGS_WITH_FLAGS 0
165 }
166 
TEST(BasicLog,ChangingTheModuleName)167 TEST(BasicLog, ChangingTheModuleName) {
168 #undef PW_LOG_MODULE_NAME
169 #define PW_LOG_MODULE_NAME "PQR"
170   PW_LOG_INFO("This has a custom module name");
171   PW_LOG_INFO("So does this");
172 }
173 
TEST(BasicLog,ShortNames)174 TEST(BasicLog, ShortNames) {
175   LOG(PW_LOG_LEVEL_INFO, PW_LOG_MODULE_NAME, 0, "Shrt lg");
176   LOG_DEBUG("A debug log: %d", 1);
177   LOG_INFO("An info log: %d", 2);
178   LOG_WARN("A warning log: %d", 3);
179   LOG_ERROR("An error log: %d", 4);
180   LOG_CRITICAL("A critical log: %d", 4);
181 }
182 
TEST(BasicLog,UltraShortNames)183 TEST(BasicLog, UltraShortNames) {
184   LOG(PW_LOG_LEVEL_INFO, PW_LOG_MODULE_NAME, 0, "Shrt lg");
185   DBG("A debug log: %d", 1);
186   INF("An info log: %d", 2);
187   WRN("A warning log: %d", 3);
188   ERR("An error log: %d", 4);
189   CRT("A critical log: %d", 4);
190 }
191 
192 extern "C" void BasicLogTestPlainC();
193 
TEST(BasicLog,FromPlainC)194 TEST(BasicLog, FromPlainC) { BasicLogTestPlainC(); }
195 
196 // Test that adding to the format string compiles correctly. If PW_COMMA_ARGS is
197 // used in PW_LOG_INFO and the other wrappers in pw_log/log.h, then these
198 // functions tests fail to compile, because the arguments end up out-of-order.
199 
200 #undef PW_LOG
201 #define PW_LOG(level, module, flags, message, ...)                       \
202   DoNothingFakeFunction(module,                                          \
203                         "%d/%d/%d: incoming transmission [" message "]", \
204                         level,                                           \
205                         __LINE__,                                        \
206                         flags PW_COMMA_ARGS(__VA_ARGS__))
207 
208 void DoNothingFakeFunction(const char*, const char*, ...)
209     PW_PRINTF_FORMAT(2, 3);
210 
DoNothingFakeFunction(const char *,const char *,...)211 void DoNothingFakeFunction(const char*, const char*, ...) {}
212 
TEST(CustomFormatString,DebugLevel)213 TEST(CustomFormatString, DebugLevel) {
214   PW_LOG_DEBUG("This log statement should be at DEBUG level; no args");
215   for (int i = 0; i < N; ++i) {
216     PW_LOG_DEBUG("Counting: %d", i);
217   }
218   PW_LOG_DEBUG("Here is a string: %s; with another string %s", "foo", "bar");
219 }
220 
TEST(CustomFormatString,InfoLevel)221 TEST(CustomFormatString, InfoLevel) {
222   PW_LOG_INFO("This log statement should be at INFO level; no args");
223   for (int i = 0; i < N; ++i) {
224     PW_LOG_INFO("Counting: %d", i);
225   }
226   PW_LOG_INFO("Here is a string: %s; with another string %s", "foo", "bar");
227 }
228 
TEST(CustomFormatString,WarnLevel)229 TEST(CustomFormatString, WarnLevel) {
230   PW_LOG_WARN("This log statement should be at WARN level; no args");
231   for (int i = 0; i < N; ++i) {
232     PW_LOG_WARN("Counting: %d", i);
233   }
234   PW_LOG_WARN("Here is a string: %s; with another string %s", "foo", "bar");
235 }
236 
TEST(CustomFormatString,ErrorLevel)237 TEST(CustomFormatString, ErrorLevel) {
238   PW_LOG_ERROR("This log statement should be at ERROR level; no args");
239   for (int i = 0; i < N; ++i) {
240     PW_LOG_ERROR("Counting: %d", i);
241   }
242   PW_LOG_ERROR("Here is a string: %s; with another string %s", "foo", "bar");
243 }
244 
TEST(CustomFormatString,CriticalLevel)245 TEST(CustomFormatString, CriticalLevel) {
246   PW_LOG_CRITICAL("Critical, emergency log. Device should not reboot");
247 }
248