2f648fd8373ea920b649daa889a44a6cb267a260
[platform/upstream/connectedhomeip.git] / third_party / pigweed / repo / pw_log_rpc / 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_rpc/log_queue.h"
16
17 #include "gtest/gtest.h"
18 #include "pw_log/levels.h"
19 #include "pw_log_rpc_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(Status::OK,
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<ConstByteSpan> 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());
104   VerifyLogEntry(log_decoder,
105                  kTokenizedMessage,
106                  kFlags,
107                  kLevel,
108                  kLine,
109                  kTokenizedThread,
110                  kTimestamp);
111 }
112
113 TEST(LogQueue, MultiplePushPopTokenizedMessage) {
114   constexpr int kEntryCount = 3;
115
116   std::byte log_buffer[1024];
117   LogQueueWithEncodeBuffer<kEncodeBufferSize> log_queue(log_buffer);
118
119   for (int i = 0; i < kEntryCount; i++) {
120     EXPECT_EQ(Status::OK,
121               log_queue.PushTokenizedMessage(
122                   std::as_bytes(std::span(kTokenizedMessage)),
123                   kFlags,
124                   kLevel,
125                   kLine + (i << 3),
126                   kTokenizedThread,
127                   kTimestamp + i));
128   }
129
130   std::byte log_entry[kEncodeBufferSize];
131   for (int i = 0; i < kEntryCount; i++) {
132     Result<ConstByteSpan> pop_result = log_queue.Pop(std::span(log_entry));
133     EXPECT_TRUE(pop_result.ok());
134
135     pw::protobuf::Decoder log_decoder(pop_result.value());
136     VerifyLogEntry(log_decoder,
137                    kTokenizedMessage,
138                    kFlags,
139                    kLevel,
140                    kLine + (i << 3),
141                    kTokenizedThread,
142                    kTimestamp + i);
143   }
144 }
145
146 TEST(LogQueue, PopMultiple) {
147   constexpr int kEntryCount = 3;
148
149   std::byte log_buffer[kLogBufferSize];
150   LogQueueWithEncodeBuffer<kEncodeBufferSize> log_queue(log_buffer);
151
152   for (int i = 0; i < kEntryCount; i++) {
153     EXPECT_EQ(Status::OK,
154               log_queue.PushTokenizedMessage(
155                   std::as_bytes(std::span(kTokenizedMessage)),
156                   kFlags,
157                   kLevel,
158                   kLine + (i << 3),
159                   kTokenizedThread,
160                   kTimestamp + i));
161   }
162
163   std::byte log_entries[kLogBufferSize];
164   Result<ConstByteSpan> pop_result = log_queue.PopMultiple(log_entries);
165   EXPECT_TRUE(pop_result.ok());
166
167   pw::protobuf::Decoder log_decoder(pop_result.value());
168   for (int i = 0; i < kEntryCount; i++) {
169     VerifyLogEntry(log_decoder,
170                    kTokenizedMessage,
171                    kFlags,
172                    kLevel,
173                    kLine + (i << 3),
174                    kTokenizedThread,
175                    kTimestamp + i);
176   }
177 }
178
179 TEST(LogQueue, TooSmallEncodeBuffer) {
180   constexpr size_t kSmallBuffer = 1;
181
182   std::byte log_buffer[kLogBufferSize];
183   LogQueueWithEncodeBuffer<kSmallBuffer> log_queue(log_buffer);
184   EXPECT_EQ(Status::INTERNAL,
185             log_queue.PushTokenizedMessage(
186                 std::as_bytes(std::span(kTokenizedMessage)),
187                 kFlags,
188                 kLevel,
189                 kLine,
190                 kTokenizedThread,
191                 kTimestamp));
192 }
193
194 TEST(LogQueue, TooSmallLogBuffer) {
195   constexpr size_t kSmallerThanPreamble = 1;
196   constexpr size_t kEntryCount = 100;
197
198   // Expect OUT_OF_RANGE when the buffer is smaller than a preamble.
199   std::byte log_buffer[kLogBufferSize];
200   LogQueueWithEncodeBuffer<kEncodeBufferSize> log_queue_small(
201       std::span(log_buffer, kSmallerThanPreamble));
202   EXPECT_EQ(Status::OUT_OF_RANGE,
203             log_queue_small.PushTokenizedMessage(
204                 std::as_bytes(std::span(kTokenizedMessage)),
205                 kFlags,
206                 kLevel,
207                 kLine,
208                 kTokenizedThread,
209                 kTimestamp));
210
211   // Expect RESOURCE_EXHAUSTED when there's not enough space for the chunk.
212   LogQueueWithEncodeBuffer<kEncodeBufferSize> log_queue_medium(log_buffer);
213   for (size_t i = 0; i < kEntryCount; i++) {
214     log_queue_medium.PushTokenizedMessage(
215         std::as_bytes(std::span(kTokenizedMessage)),
216         kFlags,
217         kLevel,
218         kLine,
219         kTokenizedThread,
220         kTimestamp);
221   }
222   EXPECT_EQ(Status::RESOURCE_EXHAUSTED,
223             log_queue_medium.PushTokenizedMessage(
224                 std::as_bytes(std::span(kTokenizedMessage)),
225                 kFlags,
226                 kLevel,
227                 kLine,
228                 kTokenizedThread,
229                 kTimestamp));
230 }
231
232 }  // namespace pw::log_rpc