1 // Copyright 2021 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 #define PW_LOG_MODULE_NAME "log module name!"
16
17 // Configure the module so that the test runs against known values.
18 #undef PW_LOG_TOKENIZED_LEVEL_BITS
19 #undef PW_LOG_TOKENIZED_MODULE_BITS
20 #undef PW_LOG_TOKENIZED_FLAG_BITS
21 #undef PW_LOG_TOKENIZED_LINE_BITS
22
23 #define PW_LOG_TOKENIZED_LEVEL_BITS 3
24 #define PW_LOG_TOKENIZED_MODULE_BITS 16
25 #define PW_LOG_TOKENIZED_FLAG_BITS 2
26 #define PW_LOG_TOKENIZED_LINE_BITS 11
27
28 #include "pw_log_tokenized/log_tokenized.h"
29
30 #include "gtest/gtest.h"
31 #include "pw_log_tokenized_private/test_utils.h"
32
33 namespace pw::log_tokenized {
34 namespace {
35
TEST(LogTokenized,FormatString)36 TEST(LogTokenized, FormatString) {
37 PW_LOG_TOKENIZED_TO_GLOBAL_HANDLER_WITH_PAYLOAD(
38 63, PW_LOG_MODULE_NAME, 1023, "hello %d", 1);
39 EXPECT_STREQ(last_log.format_string,
40 "■msg♦hello %d■module♦log module name!■file♦" __FILE__);
41 }
42
43 constexpr uintptr_t kModuleToken =
44 PW_TOKENIZER_STRING_TOKEN(PW_LOG_MODULE_NAME) &
45 ((1u << PW_LOG_TOKENIZED_MODULE_BITS) - 1);
46
TEST(LogTokenized,LogMetadata_LevelTooLarge_Clamps)47 TEST(LogTokenized, LogMetadata_LevelTooLarge_Clamps) {
48 auto check_metadata = [] {
49 Metadata metadata = Metadata(last_log.metadata);
50 EXPECT_EQ(metadata.level(), 7u);
51 EXPECT_EQ(metadata.flags(), 0u);
52 EXPECT_EQ(metadata.module(), kModuleToken);
53 EXPECT_EQ(metadata.line_number(), 1000u);
54 };
55
56 #line 1000
57 PW_LOG_TOKENIZED_TO_GLOBAL_HANDLER_WITH_PAYLOAD(8, PW_LOG_MODULE_NAME, 0, "");
58 check_metadata();
59
60 pw_log_tokenized_Test_LogMetadata_LevelTooLarge_Clamps();
61 check_metadata();
62 }
63
TEST(LogTokenized,LogMetadata_TooManyFlags_Truncates)64 TEST(LogTokenized, LogMetadata_TooManyFlags_Truncates) {
65 auto check_metadata = [] {
66 Metadata metadata = Metadata(last_log.metadata);
67 EXPECT_EQ(metadata.level(), 1u);
68 EXPECT_EQ(metadata.flags(), 0b11u);
69 EXPECT_EQ(metadata.module(), kModuleToken);
70 EXPECT_EQ(metadata.line_number(), 1100u);
71 };
72
73 // Keep statements on a single line, since GCC and Clang disagree about which
74 // line number to assign to multi-line macros.
75 // clang-format off
76 #line 1100
77 PW_LOG_TOKENIZED_TO_GLOBAL_HANDLER_WITH_PAYLOAD(1, PW_LOG_MODULE_NAME, 0xFFFFFFFF, "hello");
78 // clang-format on
79 check_metadata();
80
81 pw_log_tokenized_Test_LogMetadata_TooManyFlags_Truncates();
82 check_metadata();
83 }
84
TEST(LogTokenized,LogMetadata_VariousValues)85 TEST(LogTokenized, LogMetadata_VariousValues) {
86 auto check_metadata = [] {
87 Metadata metadata = Metadata(last_log.metadata);
88 EXPECT_EQ(metadata.level(), 6u);
89 EXPECT_EQ(metadata.flags(), 3u);
90 EXPECT_EQ(metadata.module(), kModuleToken);
91 EXPECT_EQ(last_log.arg_count, 1u);
92 EXPECT_EQ(metadata.line_number(), 1200u);
93 };
94
95 // clang-format off
96 #line 1200
97 PW_LOG_TOKENIZED_TO_GLOBAL_HANDLER_WITH_PAYLOAD(6, PW_LOG_MODULE_NAME, 3, "hello%s", "?");
98 // clang-format on
99 check_metadata();
100
101 pw_log_tokenized_Test_LogMetadata_LogMetadata_VariousValues();
102 check_metadata();
103 }
104
TEST(LogTokenized,LogMetadata_Zero)105 TEST(LogTokenized, LogMetadata_Zero) {
106 auto check_metadata = [] {
107 Metadata metadata = Metadata(last_log.metadata);
108 EXPECT_EQ(metadata.level(), 0u);
109 EXPECT_EQ(metadata.flags(), 0u);
110 EXPECT_EQ(metadata.module(), kModuleToken);
111 EXPECT_EQ(last_log.arg_count, 0u);
112 EXPECT_EQ(metadata.line_number(), 1300u);
113 };
114
115 #line 1300
116 PW_LOG_TOKENIZED_TO_GLOBAL_HANDLER_WITH_PAYLOAD(0, PW_LOG_MODULE_NAME, 0, "");
117 check_metadata();
118
119 pw_log_tokenized_Test_LogMetadata_LogMetadata_Zero();
120 check_metadata();
121 }
122
TEST(LogTokenized,LogMetadata_MaxValues)123 TEST(LogTokenized, LogMetadata_MaxValues) {
124 #line 2047
125 PW_LOG_TOKENIZED_TO_GLOBAL_HANDLER_WITH_PAYLOAD(7, "name", 3, "hello %d", 1);
126
127 Metadata metadata = Metadata(last_log.metadata);
128 EXPECT_EQ(metadata.line_number(), 2047u);
129 EXPECT_EQ(metadata.level(), 7u);
130 EXPECT_EQ(metadata.flags(), 3u);
131 EXPECT_EQ(metadata.module(),
132 PW_TOKENIZER_STRING_TOKEN("name") &
133 ((1u << PW_LOG_TOKENIZED_MODULE_BITS) - 1));
134 EXPECT_EQ(last_log.arg_count, 1u);
135 }
136
TEST(LogTokenized,LogMetadata_LineNumberTooLarge_IsZero)137 TEST(LogTokenized, LogMetadata_LineNumberTooLarge_IsZero) {
138 #line 2048 // At 11 bits, the largest representable line is 2047
139 PW_LOG_TOKENIZED_TO_GLOBAL_HANDLER_WITH_PAYLOAD(
140 7, PW_LOG_MODULE_NAME, 3, "hello %d", 1);
141 EXPECT_EQ(Metadata(last_log.metadata).line_number(), 0u);
142
143 #line 2049
144 PW_LOG_TOKENIZED_TO_GLOBAL_HANDLER_WITH_PAYLOAD(
145 7, PW_LOG_MODULE_NAME, 3, "hello %d", 1);
146 EXPECT_EQ(Metadata(last_log.metadata).line_number(), 0u);
147
148 #line 99999
149 PW_LOG_TOKENIZED_TO_GLOBAL_HANDLER_WITH_PAYLOAD(
150 7, PW_LOG_MODULE_NAME, 3, "hello %d", 1);
151 EXPECT_EQ(Metadata(last_log.metadata).line_number(), 0u);
152 }
153
154 } // namespace
155 } // namespace pw::log_tokenized
156