Keir Mierle | af5e358 | 2019-12-30 13:11:05 -0800 | [diff] [blame] | 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(pwbug/88): Add verification of the actually logged statements. |
| 20 | |
Keir Mierle | 750bb58 | 2020-01-22 17:07:07 -0800 | [diff] [blame] | 21 | // clang-format off |
Keir Mierle | af5e358 | 2019-12-30 13:11:05 -0800 | [diff] [blame] | 22 | #define PW_LOG_MODULE_NAME "TST" |
Keir Mierle | c4725d7 | 2020-06-04 12:17:38 -0700 | [diff] [blame] | 23 | #define PW_LOG_LEVEL PW_LOG_LEVEL_DEBUG |
Keir Mierle | 750bb58 | 2020-01-22 17:07:07 -0800 | [diff] [blame] | 24 | #include "pw_log/log.h" |
Wyatt Hepler | 0cdb1a3 | 2021-03-05 14:16:13 -0800 | [diff] [blame] | 25 | #include "pw_log/short.h" |
| 26 | #include "pw_log/shorter.h" |
Keir Mierle | 750bb58 | 2020-01-22 17:07:07 -0800 | [diff] [blame] | 27 | // clang-format on |
Keir Mierle | af5e358 | 2019-12-30 13:11:05 -0800 | [diff] [blame] | 28 | |
| 29 | #include "gtest/gtest.h" |
Keir Mierle | af5e358 | 2019-12-30 13:11:05 -0800 | [diff] [blame] | 30 | |
| 31 | // TODO(pwbug/86): Test unsigned integer logging (32 and 64 bit); test pointer |
| 32 | // logging. |
| 33 | |
| 34 | void LoggingFromFunction() { PW_LOG_INFO("From a function!"); } |
| 35 | |
| 36 | const int N = 3; |
| 37 | |
| 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 | |
| 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 | |
| 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 | |
| 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 | |
| 70 | TEST(BasicLog, CriticalLevel) { |
| 71 | PW_LOG_CRITICAL("Critical, emergency log. Device should not reboot"); |
| 72 | } |
| 73 | |
| 74 | TEST(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 | |
| 92 | TEST(BasicLog, FromAFunction) { LoggingFromFunction(); } |
| 93 | |
| 94 | TEST(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 | |
| 106 | TEST(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 | |
| 120 | TEST(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 | |
| 136 | TEST(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 Mierle | 750bb58 | 2020-01-22 17:07:07 -0800 | [diff] [blame] | 143 | TEST(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 | |
| 152 | TEST(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 Hepler | 33a1e5a | 2020-05-01 18:14:23 -0700 | [diff] [blame] | 161 | extern "C" void BasicLogTestPlainC(); |
Keir Mierle | af5e358 | 2019-12-30 13:11:05 -0800 | [diff] [blame] | 162 | |
| 163 | TEST(BasicLog, FromPlainC) { BasicLogTestPlainC(); } |
Wyatt Hepler | 33a1e5a | 2020-05-01 18:14:23 -0700 | [diff] [blame] | 164 | |
| 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 | |
| 176 | void DoNothingFakeFunction(const char*, ...) PW_PRINTF_FORMAT(1, 2); |
| 177 | |
| 178 | void DoNothingFakeFunction(const char*, ...) {} |
| 179 | |
| 180 | TEST(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 | |
| 188 | TEST(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 | |
| 196 | TEST(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 | |
| 204 | TEST(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 | |
| 212 | TEST(CustomFormatString, CriticalLevel) { |
| 213 | PW_LOG_CRITICAL("Critical, emergency log. Device should not reboot"); |
| 214 | } |