Fix for x86_64 build fail
[platform/upstream/connectedhomeip.git] / third_party / pigweed / repo / pw_log_multisink / log_queue_test.cc
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 #include "pw_log_multisink/log_queue.h"
16
17 #include "gtest/gtest.h"
18 #include "pw_log/levels.h"
19 #include "pw_log_proto/log.pwpb.h"
20 #include "pw_protobuf/decoder.h"
21
22 namespace pw::log_rpc {
23 namespace {
24
25 constexpr size_t kEncodeBufferSize = 512;
26
27 constexpr const char kTokenizedMessage[] = "msg_token";
28 constexpr uint32_t kFlags = 0xF;
29 constexpr uint32_t kLevel = 0b010;
30 constexpr uint32_t kLine = 0b101011000;
31 constexpr uint32_t kTokenizedThread = 0xF;
32 constexpr int64_t kTimestamp = 0;
33
34 constexpr size_t kLogBufferSize = kEncodeBufferSize * 3;
35
36 void VerifyLogEntry(pw::protobuf::Decoder& log_decoder,
37                     const char* expected_tokenized_message,
38                     const uint32_t expected_flags,
39                     const uint32_t expected_level,
40                     const uint32_t expected_line,
41                     const uint32_t expected_tokenized_thread,
42                     const int64_t expected_timestamp) {
43   ConstByteSpan log_entry_message;
44   EXPECT_TRUE(log_decoder.Next().ok());  // preamble
45   EXPECT_EQ(1U, log_decoder.FieldNumber());
46   EXPECT_TRUE(log_decoder.ReadBytes(&log_entry_message).ok());
47
48   pw::protobuf::Decoder entry_decoder(log_entry_message);
49   ConstByteSpan tokenized_message;
50   EXPECT_TRUE(entry_decoder.Next().ok());  // tokenized_message
51   EXPECT_EQ(1U, entry_decoder.FieldNumber());
52   EXPECT_TRUE(entry_decoder.ReadBytes(&tokenized_message).ok());
53   EXPECT_TRUE(std::memcmp(tokenized_message.begin(),
54                           (const void*)expected_tokenized_message,
55                           tokenized_message.size()) == 0);
56
57   uint32_t line_level;
58   EXPECT_TRUE(entry_decoder.Next().ok());  // line_level
59   EXPECT_EQ(2U, entry_decoder.FieldNumber());
60   EXPECT_TRUE(entry_decoder.ReadUint32(&line_level).ok());
61   EXPECT_EQ(expected_level, line_level & PW_LOG_LEVEL_BITMASK);
62   EXPECT_EQ(expected_line,
63             (line_level & ~PW_LOG_LEVEL_BITMASK) >> PW_LOG_LEVEL_BITWIDTH);
64
65   uint32_t flags;
66   EXPECT_TRUE(entry_decoder.Next().ok());  // flags
67   EXPECT_EQ(3U, entry_decoder.FieldNumber());
68   EXPECT_TRUE(entry_decoder.ReadUint32(&flags).ok());
69   EXPECT_EQ(expected_flags, flags);
70
71   uint32_t tokenized_thread;
72   EXPECT_TRUE(entry_decoder.Next().ok());  // tokenized_thread
73   EXPECT_EQ(4U, entry_decoder.FieldNumber());
74   EXPECT_TRUE(entry_decoder.ReadUint32(&tokenized_thread).ok());
75   EXPECT_EQ(expected_tokenized_thread, tokenized_thread);
76
77   int64_t timestamp;
78   EXPECT_TRUE(entry_decoder.Next().ok());  // timestamp
79   EXPECT_EQ(5U, entry_decoder.FieldNumber());
80   EXPECT_TRUE(entry_decoder.ReadInt64(&timestamp).ok());
81   EXPECT_EQ(expected_timestamp, timestamp);
82 }
83
84 }  // namespace
85
86 TEST(LogQueue, SinglePushPopTokenizedMessage) {
87   std::byte log_buffer[kLogBufferSize];
88   LogQueueWithEncodeBuffer<kEncodeBufferSize> log_queue(log_buffer);
89
90   EXPECT_EQ(OkStatus(),
91             log_queue.PushTokenizedMessage(
92                 std::as_bytes(std::span(kTokenizedMessage)),
93                 kFlags,
94                 kLevel,
95                 kLine,
96                 kTokenizedThread,
97                 kTimestamp));
98
99   std::byte log_entry[kEncodeBufferSize];
100   Result<LogEntries> pop_result = log_queue.Pop(std::span(log_entry));
101   EXPECT_TRUE(pop_result.ok());
102
103   pw::protobuf::Decoder log_decoder(pop_result.value().entries);
104   EXPECT_EQ(pop_result.value().entry_count, 1U);
105   VerifyLogEntry(log_decoder,
106                  kTokenizedMessage,
107                  kFlags,
108                  kLevel,
109                  kLine,
110                  kTokenizedThread,
111                  kTimestamp);
112 }
113
114 TEST(LogQueue, MultiplePushPopTokenizedMessage) {
115   constexpr size_t kEntryCount = 3;
116
117   std::byte log_buffer[1024];
118   LogQueueWithEncodeBuffer<kEncodeBufferSize> log_queue(log_buffer);
119
120   for (size_t i = 0; i < kEntryCount; i++) {
121     EXPECT_EQ(OkStatus(),
122               log_queue.PushTokenizedMessage(
123                   std::as_bytes(std::span(kTokenizedMessage)),
124                   kFlags,
125                   kLevel,
126                   kLine + (i << 3),
127                   kTokenizedThread,
128                   kTimestamp + i));
129   }
130
131   std::byte log_entry[kEncodeBufferSize];
132   for (size_t i = 0; i < kEntryCount; i++) {
133     Result<LogEntries> pop_result = log_queue.Pop(std::span(log_entry));
134     EXPECT_TRUE(pop_result.ok());
135
136     pw::protobuf::Decoder log_decoder(pop_result.value().entries);
137     EXPECT_EQ(pop_result.value().entry_count, 1U);
138     VerifyLogEntry(log_decoder,
139                    kTokenizedMessage,
140                    kFlags,
141                    kLevel,
142                    kLine + (i << 3),
143                    kTokenizedThread,
144                    kTimestamp + i);
145   }
146 }
147
148 TEST(LogQueue, PopMultiple) {
149   constexpr size_t kEntryCount = 3;
150
151   std::byte log_buffer[kLogBufferSize];
152   LogQueueWithEncodeBuffer<kEncodeBufferSize> log_queue(log_buffer);
153
154   for (size_t i = 0; i < kEntryCount; i++) {
155     EXPECT_EQ(OkStatus(),
156               log_queue.PushTokenizedMessage(
157                   std::as_bytes(std::span(kTokenizedMessage)),
158                   kFlags,
159                   kLevel,
160                   kLine + (i << 3),
161                   kTokenizedThread,
162                   kTimestamp + i));
163   }
164
165   std::byte log_entries[kLogBufferSize];
166   Result<LogEntries> pop_result = log_queue.PopMultiple(log_entries);
167   EXPECT_TRUE(pop_result.ok());
168
169   pw::protobuf::Decoder log_decoder(pop_result.value().entries);
170   EXPECT_EQ(pop_result.value().entry_count, kEntryCount);
171   for (size_t i = 0; i < kEntryCount; i++) {
172     VerifyLogEntry(log_decoder,
173                    kTokenizedMessage,
174                    kFlags,
175                    kLevel,
176                    kLine + (i << 3),
177                    kTokenizedThread,
178                    kTimestamp + i);
179   }
180 }
181
182 TEST(LogQueue, TooSmallEncodeBuffer) {
183   constexpr size_t kSmallBuffer = 1;
184
185   std::byte log_buffer[kLogBufferSize];
186   LogQueueWithEncodeBuffer<kSmallBuffer> log_queue(log_buffer);
187   EXPECT_EQ(Status::Internal(),
188             log_queue.PushTokenizedMessage(
189                 std::as_bytes(std::span(kTokenizedMessage)),
190                 kFlags,
191                 kLevel,
192                 kLine,
193                 kTokenizedThread,
194                 kTimestamp));
195 }
196
197 TEST(LogQueue, TooSmallLogBuffer) {
198   constexpr size_t kSmallerThanPreamble = 1;
199   constexpr size_t kEntryCount = 100;
200
201   // Expect OUT_OF_RANGE when the buffer is smaller than a preamble.
202   std::byte log_buffer[kLogBufferSize];
203   LogQueueWithEncodeBuffer<kEncodeBufferSize> log_queue_small(
204       std::span(log_buffer, kSmallerThanPreamble));
205   EXPECT_EQ(Status::OutOfRange(),
206             log_queue_small.PushTokenizedMessage(
207                 std::as_bytes(std::span(kTokenizedMessage)),
208                 kFlags,
209                 kLevel,
210                 kLine,
211                 kTokenizedThread,
212                 kTimestamp));
213
214   // Expect RESOURCE_EXHAUSTED when there's not enough space for the chunk.
215   LogQueueWithEncodeBuffer<kEncodeBufferSize> log_queue_medium(log_buffer);
216   for (size_t i = 0; i < kEntryCount; i++) {
217     log_queue_medium.PushTokenizedMessage(
218         std::as_bytes(std::span(kTokenizedMessage)),
219         kFlags,
220         kLevel,
221         kLine,
222         kTokenizedThread,
223         kTimestamp);
224   }
225   EXPECT_EQ(Status::ResourceExhausted(),
226             log_queue_medium.PushTokenizedMessage(
227                 std::as_bytes(std::span(kTokenizedMessage)),
228                 kFlags,
229                 kLevel,
230                 kLine,
231                 kTokenizedThread,
232                 kTimestamp));
233 }
234
235 }  // namespace pw::log_rpc