blob: a7042a8c14066cca553bea952b066b4b413f3efa [file] [log] [blame]
Keir Mierleaf5e3582019-12-30 13:11:05 -08001// 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(pwbug/88): Add verification of the actually logged statements.
20
Keir Mierle750bb582020-01-22 17:07:07 -080021// clang-format off
Keir Mierleaf5e3582019-12-30 13:11:05 -080022#define PW_LOG_MODULE_NAME "TST"
Keir Mierlec4725d72020-06-04 12:17:38 -070023#define PW_LOG_LEVEL PW_LOG_LEVEL_DEBUG
Keir Mierle750bb582020-01-22 17:07:07 -080024#include "pw_log/log.h"
Wyatt Hepler0cdb1a32021-03-05 14:16:13 -080025#include "pw_log/short.h"
26#include "pw_log/shorter.h"
Keir Mierle750bb582020-01-22 17:07:07 -080027// clang-format on
Keir Mierleaf5e3582019-12-30 13:11:05 -080028
29#include "gtest/gtest.h"
Keir Mierleaf5e3582019-12-30 13:11:05 -080030
31// TODO(pwbug/86): Test unsigned integer logging (32 and 64 bit); test pointer
32// logging.
33
34void LoggingFromFunction() { PW_LOG_INFO("From a function!"); }
35
36const int N = 3;
37
38TEST(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
46TEST(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
54TEST(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
62TEST(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
70TEST(BasicLog, CriticalLevel) {
71 PW_LOG_CRITICAL("Critical, emergency log. Device should not reboot");
72}
73
74TEST(BasicLog, ManualLevel) {
75 PW_LOG(PW_LOG_LEVEL_DEBUG, 0, "A manual DEBUG-level message");
76 PW_LOG(PW_LOG_LEVEL_DEBUG, 1, "A manual DEBUG-level message; with a flag");
77
78 PW_LOG(PW_LOG_LEVEL_INFO, 0, "A manual INFO-level message");
79 PW_LOG(PW_LOG_LEVEL_INFO, 1, "A manual INFO-level message; with a flag");
80
81 PW_LOG(PW_LOG_LEVEL_WARN, 0, "A manual WARN-level message");
82 PW_LOG(PW_LOG_LEVEL_WARN, 1, "A manual WARN-level message; with a flag");
83
84 PW_LOG(PW_LOG_LEVEL_ERROR, 0, "A manual ERROR-level message");
85 PW_LOG(PW_LOG_LEVEL_ERROR, 1, "A manual ERROR-level message; with a flag");
86
87 PW_LOG(PW_LOG_LEVEL_CRITICAL, 0, "A manual CRITICAL-level message");
88 PW_LOG(
89 PW_LOG_LEVEL_CRITICAL, 1, "A manual CRITICAL-level message; with a flag");
90}
91
92TEST(BasicLog, FromAFunction) { LoggingFromFunction(); }
93
94TEST(BasicLog, CustomLogLevels) {
95 // Log levels other than the standard ones work; what each backend does is
96 // implementation defined.
97 PW_LOG(0, 0, "Custom log level: 0");
98 PW_LOG(1, 0, "Custom log level: 1");
99 PW_LOG(2, 0, "Custom log level: 2");
100 PW_LOG(3, 0, "Custom log level: 3");
101 PW_LOG(100, 0, "Custom log level: 100");
102}
103
104#define TEST_FAILED_LOG "IF THIS MESSAGE WAS LOGGED, THE TEST FAILED"
105
106TEST(BasicLog, FilteringByLevel) {
107#undef PW_LOG_SKIP_LOGS_WITH_LEVEL_LT
108#define PW_LOG_SKIP_LOGS_WITH_LEVEL_LT PW_LOG_LEVEL_ERROR
109
110 PW_LOG_DEBUG(TEST_FAILED_LOG);
111 PW_LOG_INFO(TEST_FAILED_LOG);
112 PW_LOG_WARN(TEST_FAILED_LOG);
113
114 PW_LOG_ERROR("This log should appear as error status (and that's good)");
115
116#undef PW_LOG_SKIP_LOGS_WITH_LEVEL_LT
117#define PW_LOG_SKIP_LOGS_WITH_LEVEL_LT 0
118}
119
120TEST(BasicLog, FilteringByFlags) {
121#undef PW_LOG_SKIP_LOGS_WITH_FLAGS
122#define PW_LOG_SKIP_LOGS_WITH_FLAGS 1
123
124 // Flag is set so these should all get zapped.
125 PW_LOG(PW_LOG_LEVEL_INFO, 1, TEST_FAILED_LOG);
126 PW_LOG(PW_LOG_LEVEL_ERROR, 1, TEST_FAILED_LOG);
127
128 // However, a different flag bit should still log.
129 PW_LOG(PW_LOG_LEVEL_INFO, 1 << 1, "This flagged log is intended to appear");
130 PW_LOG(PW_LOG_LEVEL_ERROR, 1 << 1, "This flagged log is intended to appear");
131
132#undef PW_LOG_SKIP_LOGS_WITH_FLAGS
133#define PW_LOG_SKIP_LOGS_WITH_FLAGS 0
134}
135
136TEST(BasicLog, ChangingTheModuleName) {
137#undef PW_LOG_MODULE_NAME
138#define PW_LOG_MODULE_NAME "PQR"
139 PW_LOG_INFO("This has a custom module name");
140 PW_LOG_INFO("So does this");
141}
142
Keir Mierle750bb582020-01-22 17:07:07 -0800143TEST(BasicLog, ShortNames) {
144 LOG(PW_LOG_LEVEL_INFO, 0, "Shrt lg");
145 LOG_DEBUG("A debug log: %d", 1);
146 LOG_INFO("An info log: %d", 2);
147 LOG_WARN("A warning log: %d", 3);
148 LOG_ERROR("An error log: %d", 4);
149 LOG_CRITICAL("A critical log: %d", 4);
150}
151
152TEST(BasicLog, UltraShortNames) {
153 LOG(PW_LOG_LEVEL_INFO, 0, "Shrt lg");
154 DBG("A debug log: %d", 1);
155 INF("An info log: %d", 2);
156 WRN("A warning log: %d", 3);
157 ERR("An error log: %d", 4);
158 CRT("A critical log: %d", 4);
159}
160
Wyatt Hepler33a1e5a2020-05-01 18:14:23 -0700161extern "C" void BasicLogTestPlainC();
Keir Mierleaf5e3582019-12-30 13:11:05 -0800162
163TEST(BasicLog, FromPlainC) { BasicLogTestPlainC(); }
Wyatt Hepler33a1e5a2020-05-01 18:14:23 -0700164
165// Test that adding to the format string compiles correctly. If PW_COMMA_ARGS is
166// used in PW_LOG_INFO and the other wrappers in pw_log/log.h, then these
167// functions tests fail to compile, because the arguments end up out-of-order.
168
169#undef PW_LOG
170#define PW_LOG(level, flags, message, ...) \
171 DoNothingFakeFunction("%d/%d/%d: incoming transmission [" message "]", \
172 level, \
173 __LINE__, \
174 flags PW_COMMA_ARGS(__VA_ARGS__))
175
176void DoNothingFakeFunction(const char*, ...) PW_PRINTF_FORMAT(1, 2);
177
178void DoNothingFakeFunction(const char*, ...) {}
179
180TEST(CustomFormatString, DebugLevel) {
181 PW_LOG_DEBUG("This log statement should be at DEBUG level; no args");
182 for (int i = 0; i < N; ++i) {
183 PW_LOG_DEBUG("Counting: %d", i);
184 }
185 PW_LOG_DEBUG("Here is a string: %s; with another string %s", "foo", "bar");
186}
187
188TEST(CustomFormatString, InfoLevel) {
189 PW_LOG_INFO("This log statement should be at INFO level; no args");
190 for (int i = 0; i < N; ++i) {
191 PW_LOG_INFO("Counting: %d", i);
192 }
193 PW_LOG_INFO("Here is a string: %s; with another string %s", "foo", "bar");
194}
195
196TEST(CustomFormatString, WarnLevel) {
197 PW_LOG_WARN("This log statement should be at WARN level; no args");
198 for (int i = 0; i < N; ++i) {
199 PW_LOG_WARN("Counting: %d", i);
200 }
201 PW_LOG_WARN("Here is a string: %s; with another string %s", "foo", "bar");
202}
203
204TEST(CustomFormatString, ErrorLevel) {
205 PW_LOG_ERROR("This log statement should be at ERROR level; no args");
206 for (int i = 0; i < N; ++i) {
207 PW_LOG_ERROR("Counting: %d", i);
208 }
209 PW_LOG_ERROR("Here is a string: %s; with another string %s", "foo", "bar");
210}
211
212TEST(CustomFormatString, CriticalLevel) {
213 PW_LOG_CRITICAL("Critical, emergency log. Device should not reboot");
214}