blob: fc75706ae9730e7fe22e325299af9fdb60c39dec [file] [log] [blame]
Prashanth Swaminathanfce26ba2020-09-25 13:36:07 -07001// 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
Prashanth Swaminathan5ef2aa22020-11-10 09:57:46 -080015#include "pw_log_multisink/log_queue.h"
Prashanth Swaminathanfce26ba2020-09-25 13:36:07 -070016
17#include "gtest/gtest.h"
18#include "pw_log/levels.h"
Prashanth Swaminathan652977d2020-10-16 13:18:05 -070019#include "pw_log_proto/log.pwpb.h"
Prashanth Swaminathanfce26ba2020-09-25 13:36:07 -070020#include "pw_protobuf/decoder.h"
21
22namespace pw::log_rpc {
23namespace {
24
25constexpr size_t kEncodeBufferSize = 512;
26
27constexpr const char kTokenizedMessage[] = "msg_token";
28constexpr uint32_t kFlags = 0xF;
29constexpr uint32_t kLevel = 0b010;
30constexpr uint32_t kLine = 0b101011000;
31constexpr uint32_t kTokenizedThread = 0xF;
32constexpr int64_t kTimestamp = 0;
33
34constexpr size_t kLogBufferSize = kEncodeBufferSize * 3;
35
36void 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(),
Ewout van Bekkum2f20c132020-10-15 11:06:15 -070054 (const void*)expected_tokenized_message,
Prashanth Swaminathanfce26ba2020-09-25 13:36:07 -070055 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
86TEST(LogQueue, SinglePushPopTokenizedMessage) {
87 std::byte log_buffer[kLogBufferSize];
88 LogQueueWithEncodeBuffer<kEncodeBufferSize> log_queue(log_buffer);
89
Wyatt Hepler1b3da3a2021-01-07 13:26:57 -080090 EXPECT_EQ(OkStatus(),
Prashanth Swaminathanfce26ba2020-09-25 13:36:07 -070091 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];
Prashanth Swaminathan652977d2020-10-16 13:18:05 -0700100 Result<LogEntries> pop_result = log_queue.Pop(std::span(log_entry));
Prashanth Swaminathanfce26ba2020-09-25 13:36:07 -0700101 EXPECT_TRUE(pop_result.ok());
102
Prashanth Swaminathan652977d2020-10-16 13:18:05 -0700103 pw::protobuf::Decoder log_decoder(pop_result.value().entries);
104 EXPECT_EQ(pop_result.value().entry_count, 1U);
Prashanth Swaminathanfce26ba2020-09-25 13:36:07 -0700105 VerifyLogEntry(log_decoder,
106 kTokenizedMessage,
107 kFlags,
108 kLevel,
109 kLine,
110 kTokenizedThread,
111 kTimestamp);
112}
113
114TEST(LogQueue, MultiplePushPopTokenizedMessage) {
Prashanth Swaminathan652977d2020-10-16 13:18:05 -0700115 constexpr size_t kEntryCount = 3;
Prashanth Swaminathanfce26ba2020-09-25 13:36:07 -0700116
117 std::byte log_buffer[1024];
118 LogQueueWithEncodeBuffer<kEncodeBufferSize> log_queue(log_buffer);
119
Prashanth Swaminathan652977d2020-10-16 13:18:05 -0700120 for (size_t i = 0; i < kEntryCount; i++) {
Wyatt Hepler1b3da3a2021-01-07 13:26:57 -0800121 EXPECT_EQ(OkStatus(),
Prashanth Swaminathanfce26ba2020-09-25 13:36:07 -0700122 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];
Prashanth Swaminathan652977d2020-10-16 13:18:05 -0700132 for (size_t i = 0; i < kEntryCount; i++) {
133 Result<LogEntries> pop_result = log_queue.Pop(std::span(log_entry));
Prashanth Swaminathanfce26ba2020-09-25 13:36:07 -0700134 EXPECT_TRUE(pop_result.ok());
135
Prashanth Swaminathan652977d2020-10-16 13:18:05 -0700136 pw::protobuf::Decoder log_decoder(pop_result.value().entries);
137 EXPECT_EQ(pop_result.value().entry_count, 1U);
Prashanth Swaminathanfce26ba2020-09-25 13:36:07 -0700138 VerifyLogEntry(log_decoder,
139 kTokenizedMessage,
140 kFlags,
141 kLevel,
142 kLine + (i << 3),
143 kTokenizedThread,
144 kTimestamp + i);
145 }
146}
147
148TEST(LogQueue, PopMultiple) {
Prashanth Swaminathan652977d2020-10-16 13:18:05 -0700149 constexpr size_t kEntryCount = 3;
Prashanth Swaminathanfce26ba2020-09-25 13:36:07 -0700150
151 std::byte log_buffer[kLogBufferSize];
152 LogQueueWithEncodeBuffer<kEncodeBufferSize> log_queue(log_buffer);
153
Prashanth Swaminathan652977d2020-10-16 13:18:05 -0700154 for (size_t i = 0; i < kEntryCount; i++) {
Wyatt Hepler1b3da3a2021-01-07 13:26:57 -0800155 EXPECT_EQ(OkStatus(),
Prashanth Swaminathanfce26ba2020-09-25 13:36:07 -0700156 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];
Prashanth Swaminathan652977d2020-10-16 13:18:05 -0700166 Result<LogEntries> pop_result = log_queue.PopMultiple(log_entries);
Prashanth Swaminathanfce26ba2020-09-25 13:36:07 -0700167 EXPECT_TRUE(pop_result.ok());
168
Prashanth Swaminathan652977d2020-10-16 13:18:05 -0700169 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++) {
Prashanth Swaminathanfce26ba2020-09-25 13:36:07 -0700172 VerifyLogEntry(log_decoder,
173 kTokenizedMessage,
174 kFlags,
175 kLevel,
176 kLine + (i << 3),
177 kTokenizedThread,
178 kTimestamp + i);
179 }
180}
181
182TEST(LogQueue, TooSmallEncodeBuffer) {
183 constexpr size_t kSmallBuffer = 1;
184
185 std::byte log_buffer[kLogBufferSize];
186 LogQueueWithEncodeBuffer<kSmallBuffer> log_queue(log_buffer);
Wyatt Heplerf276c6b2020-11-11 21:13:38 -0800187 EXPECT_EQ(Status::Internal(),
Prashanth Swaminathanfce26ba2020-09-25 13:36:07 -0700188 log_queue.PushTokenizedMessage(
189 std::as_bytes(std::span(kTokenizedMessage)),
190 kFlags,
191 kLevel,
192 kLine,
193 kTokenizedThread,
194 kTimestamp));
195}
196
197TEST(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));
Wyatt Heplerf276c6b2020-11-11 21:13:38 -0800205 EXPECT_EQ(Status::OutOfRange(),
Prashanth Swaminathanfce26ba2020-09-25 13:36:07 -0700206 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 }
Wyatt Heplerf276c6b2020-11-11 21:13:38 -0800225 EXPECT_EQ(Status::ResourceExhausted(),
Prashanth Swaminathanfce26ba2020-09-25 13:36:07 -0700226 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