xref: /aosp_15_r20/external/pigweed/pw_log_tokenized/log_tokenized_test.cc (revision 61c4878ac05f98d0ceed94b57d316916de578985)
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 "pw_log_tokenized/base64.h"
31 #include "pw_log_tokenized_private/test_utils.h"
32 #include "pw_unit_test/framework.h"
33 
34 namespace pw::log_tokenized {
35 namespace {
36 
TEST(LogTokenized,FormatString_LogModuleName)37 TEST(LogTokenized, FormatString_LogModuleName) {
38   PW_LOG_TOKENIZED_TO_GLOBAL_HANDLER_WITH_PAYLOAD(
39       63, PW_LOG_MODULE_NAME, 1023, "hello %d", 1);
40   EXPECT_STREQ(last_log.format_string,
41                "■msg♦hello %d■module♦log module name!■file♦" __FILE__);
42 }
43 
TEST(LogTokenized,FormatString_OtherModuleNames)44 TEST(LogTokenized, FormatString_OtherModuleNames) {
45   PW_LOG_TOKENIZED_TO_GLOBAL_HANDLER_WITH_PAYLOAD(1, "", 1, "goodbye");
46   EXPECT_STREQ(last_log.format_string, "■msg♦goodbye■module♦■file♦" __FILE__);
47 
48   PW_LOG_TOKENIZED_TO_GLOBAL_HANDLER_WITH_PAYLOAD(
49       63, "OTHER MODULE!", 123, "goodbye");
50   EXPECT_STREQ(last_log.format_string,
51                "■msg♦goodbye■module♦OTHER MODULE!■file♦" __FILE__);
52 }
53 
54 constexpr uintptr_t kModuleToken =
55     PW_TOKENIZER_STRING_TOKEN(PW_LOG_MODULE_NAME) &
56     ((1u << PW_LOG_TOKENIZED_MODULE_BITS) - 1);
57 
TEST(LogTokenized,Base64)58 TEST(LogTokenized, Base64) {
59   constexpr uint8_t kBinary[6]{1, 2, 3, 4, 5, 6};
60   constexpr const char* kBase64Expected = "$AQIDBAUG";  // calculated in Python
61 
62   InlineBasicString result_1 = PrefixedBase64Encode(as_bytes(span(kBinary)));
63   EXPECT_EQ(result_1, kBase64Expected);
64   EXPECT_EQ(result_1.capacity(), kBase64EncodedBufferSizeBytes);
65 
66   InlineBasicString result_2 = PrefixedBase64Encode(kBinary, sizeof(kBinary));
67   EXPECT_EQ(result_2, kBase64Expected);
68 
69   InlineBasicString result_3 = PrefixedBase64Encode(
70       reinterpret_cast<const std::byte*>(kBinary), sizeof(kBinary));
71   EXPECT_EQ(result_3, kBase64Expected);
72 }
73 
TEST(LogTokenized,LogMetadata_LevelTooLarge_Clamps)74 TEST(LogTokenized, LogMetadata_LevelTooLarge_Clamps) {
75   auto check_metadata = [] {
76     Metadata metadata = Metadata(last_log.metadata);
77     EXPECT_EQ(metadata.level(), 7u);
78     EXPECT_EQ(metadata.flags(), 0u);
79     EXPECT_EQ(metadata.module(), kModuleToken);
80     EXPECT_EQ(metadata.line_number(), 1000u);
81   };
82 
83 #line 1000
84   PW_LOG_TOKENIZED_TO_GLOBAL_HANDLER_WITH_PAYLOAD(8, PW_LOG_MODULE_NAME, 0, "");
85   check_metadata();
86 
87   pw_log_tokenized_Test_LogMetadata_LevelTooLarge_Clamps();
88   check_metadata();
89 }
90 
TEST(LogTokenized,LogMetadata_TooManyFlags_Truncates)91 TEST(LogTokenized, LogMetadata_TooManyFlags_Truncates) {
92   auto check_metadata = [] {
93     Metadata metadata = Metadata(last_log.metadata);
94     EXPECT_EQ(metadata.level(), 1u);
95     EXPECT_EQ(metadata.flags(), 0b11u);
96     EXPECT_EQ(metadata.module(), kModuleToken);
97     EXPECT_EQ(metadata.line_number(), 1100u);
98   };
99 
100   // Keep statements on a single line, since GCC and Clang disagree about which
101   // line number to assign to multi-line macros.
102   // clang-format off
103 #line 1100
104   PW_LOG_TOKENIZED_TO_GLOBAL_HANDLER_WITH_PAYLOAD(1, PW_LOG_MODULE_NAME, 0xFFFFFFFF, "hello");
105   // clang-format on
106   check_metadata();
107 
108   pw_log_tokenized_Test_LogMetadata_TooManyFlags_Truncates();
109   check_metadata();
110 }
111 
TEST(LogTokenized,LogMetadata_VariousValues)112 TEST(LogTokenized, LogMetadata_VariousValues) {
113   auto check_metadata = [] {
114     Metadata metadata = Metadata(last_log.metadata);
115     EXPECT_EQ(metadata.level(), 6u);
116     EXPECT_EQ(metadata.flags(), 3u);
117     EXPECT_EQ(metadata.module(), kModuleToken);
118     EXPECT_EQ(last_log.arg_count, 1u);
119     EXPECT_EQ(metadata.line_number(), 1200u);
120   };
121 
122   // clang-format off
123 #line 1200
124   PW_LOG_TOKENIZED_TO_GLOBAL_HANDLER_WITH_PAYLOAD(6, PW_LOG_MODULE_NAME, 3, "hello%s", "?");
125   // clang-format on
126   check_metadata();
127 
128   pw_log_tokenized_Test_LogMetadata_LogMetadata_VariousValues();
129   check_metadata();
130 }
131 
TEST(LogTokenized,LogMetadata_Zero)132 TEST(LogTokenized, LogMetadata_Zero) {
133   auto check_metadata = [] {
134     Metadata metadata = Metadata(last_log.metadata);
135     EXPECT_EQ(metadata.level(), 0u);
136     EXPECT_EQ(metadata.flags(), 0u);
137     EXPECT_EQ(metadata.module(), kModuleToken);
138     EXPECT_EQ(last_log.arg_count, 0u);
139     EXPECT_EQ(metadata.line_number(), 1300u);
140   };
141 
142 #line 1300
143   PW_LOG_TOKENIZED_TO_GLOBAL_HANDLER_WITH_PAYLOAD(0, PW_LOG_MODULE_NAME, 0, "");
144   check_metadata();
145 
146   pw_log_tokenized_Test_LogMetadata_LogMetadata_Zero();
147   check_metadata();
148 }
149 
TEST(LogTokenized,LogMetadata_MaxValues)150 TEST(LogTokenized, LogMetadata_MaxValues) {
151 #line 2047
152   PW_LOG_TOKENIZED_TO_GLOBAL_HANDLER_WITH_PAYLOAD(7, "name", 3, "hello %d", 1);
153 
154   Metadata metadata = Metadata(last_log.metadata);
155   EXPECT_EQ(metadata.line_number(), 2047u);
156   EXPECT_EQ(metadata.level(), 7u);
157   EXPECT_EQ(metadata.flags(), 3u);
158   EXPECT_EQ(metadata.module(),
159             PW_TOKENIZER_STRING_TOKEN("name") &
160                 ((1u << PW_LOG_TOKENIZED_MODULE_BITS) - 1));
161   EXPECT_EQ(last_log.arg_count, 1u);
162 }
163 
TEST(LogTokenized,LogMetadata_LineNumberTooLarge_IsZero)164 TEST(LogTokenized, LogMetadata_LineNumberTooLarge_IsZero) {
165 #line 2048  // At 11 bits, the largest representable line is 2047
166   PW_LOG_TOKENIZED_TO_GLOBAL_HANDLER_WITH_PAYLOAD(
167       7, PW_LOG_MODULE_NAME, 3, "hello %d", 1);
168   EXPECT_EQ(Metadata(last_log.metadata).line_number(), 0u);
169 
170 #line 2049
171   PW_LOG_TOKENIZED_TO_GLOBAL_HANDLER_WITH_PAYLOAD(
172       7, PW_LOG_MODULE_NAME, 3, "hello %d", 1);
173   EXPECT_EQ(Metadata(last_log.metadata).line_number(), 0u);
174 
175 #line 99999
176   PW_LOG_TOKENIZED_TO_GLOBAL_HANDLER_WITH_PAYLOAD(
177       7, PW_LOG_MODULE_NAME, 3, "hello %d", 1);
178   EXPECT_EQ(Metadata(last_log.metadata).line_number(), 0u);
179 }
180 
181 }  // namespace
182 }  // namespace pw::log_tokenized
183