blob: 04fa8fb711a7bf5435ec2aa72cd59c85bf678199 [file] [log] [blame]
Armando Montanez0bcae732020-05-27 13:28:11 -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
15#include "pw_stream/memory_stream.h"
16
17#include "gtest/gtest.h"
18#include "pw_preprocessor/compiler.h"
19
20namespace pw::stream {
21namespace {
22
23// Size of the in-memory buffer to use for this test.
24constexpr size_t kSinkBufferSize = 1013;
25
26struct TestStruct {
27 uint8_t day;
28 uint8_t month;
29 uint16_t year;
30};
31
32constexpr TestStruct kExpectedStruct = {.day = 18, .month = 5, .year = 2020};
33
Wyatt Hepler7b62e932021-08-10 23:57:10 -070034class MemoryWriterTest : public ::testing::Test {
35 protected:
Rob Mohrbe7f7f22021-12-20 12:56:24 -080036 MemoryWriterTest() : memory_buffer_ {}
37 {}
Wyatt Hepler7b62e932021-08-10 23:57:10 -070038 std::array<std::byte, kSinkBufferSize> memory_buffer_;
39};
Armando Montanez0bcae732020-05-27 13:28:11 -070040
Wyatt Hepler7b62e932021-08-10 23:57:10 -070041TEST_F(MemoryWriterTest, BytesWritten) {
42 MemoryWriter memory_writer(memory_buffer_);
Armando Montanez0bcae732020-05-27 13:28:11 -070043 EXPECT_EQ(memory_writer.bytes_written(), 0u);
44 Status status =
45 memory_writer.Write(&kExpectedStruct, sizeof(kExpectedStruct));
Wyatt Hepler1b3da3a2021-01-07 13:26:57 -080046 EXPECT_EQ(status, OkStatus());
Armando Montanez0bcae732020-05-27 13:28:11 -070047 EXPECT_EQ(memory_writer.bytes_written(), sizeof(kExpectedStruct));
Prashanth Swaminathan5b5d9dd2021-06-11 15:59:25 -070048}
49
Wyatt Hepler7b62e932021-08-10 23:57:10 -070050TEST_F(MemoryWriterTest, BytesWrittenOnConstruction) {
Prashanth Swaminathan5b5d9dd2021-06-11 15:59:25 -070051 constexpr size_t bytes_written = kSinkBufferSize / 2;
Wyatt Hepler7b62e932021-08-10 23:57:10 -070052 std::memset(memory_buffer_.data(), 1u, bytes_written);
53 MemoryWriter memory_writer(memory_buffer_, bytes_written);
Prashanth Swaminathan5b5d9dd2021-06-11 15:59:25 -070054 EXPECT_EQ(memory_writer.bytes_written(), bytes_written);
Wyatt Heplerbcefd362021-11-17 11:12:24 -080055 EXPECT_EQ(memcmp(memory_writer.data(), memory_buffer_.data(), bytes_written),
Prashanth Swaminathan5b5d9dd2021-06-11 15:59:25 -070056 0);
57}
Armando Montanez0bcae732020-05-27 13:28:11 -070058
Wyatt Hepler7b62e932021-08-10 23:57:10 -070059TEST_F(MemoryWriterTest, ValidateContents) {
60 MemoryWriter memory_writer(memory_buffer_);
Armando Montanez0bcae732020-05-27 13:28:11 -070061 EXPECT_TRUE(
62 memory_writer.Write(&kExpectedStruct, sizeof(kExpectedStruct)).ok());
63
Wyatt Heplere2cbadf2020-06-22 11:21:45 -070064 std::span<const std::byte> written_data = memory_writer.WrittenData();
Armando Montanez0bcae732020-05-27 13:28:11 -070065 EXPECT_EQ(written_data.size_bytes(), sizeof(kExpectedStruct));
66 TestStruct temp;
67 std::memcpy(&temp, written_data.data(), written_data.size_bytes());
68 EXPECT_EQ(memcmp(&temp, &kExpectedStruct, sizeof(kExpectedStruct)), 0);
69}
70
Wyatt Hepler7b62e932021-08-10 23:57:10 -070071TEST_F(MemoryWriterTest, MultipleWrites) {
Armando Montanez0bcae732020-05-27 13:28:11 -070072 constexpr size_t kTempBufferSize = 72;
73 std::byte buffer[kTempBufferSize] = {};
Armando Montanez0bcae732020-05-27 13:28:11 -070074
Wyatt Hepler7b62e932021-08-10 23:57:10 -070075 for (std::byte& value : memory_buffer_) {
David Rogers6d4f6302020-07-22 14:27:41 -070076 value = std::byte(0);
77 }
Wyatt Hepler7b62e932021-08-10 23:57:10 -070078 MemoryWriter memory_writer(memory_buffer_);
Armando Montanez0bcae732020-05-27 13:28:11 -070079
David Rogers6d4f6302020-07-22 14:27:41 -070080 size_t counter = 0;
81 while (memory_writer.ConservativeWriteLimit() >= kTempBufferSize) {
Armando Montanez0bcae732020-05-27 13:28:11 -070082 for (size_t i = 0; i < sizeof(buffer); ++i) {
83 buffer[i] = std::byte(counter++);
84 }
Wyatt Hepler1b3da3a2021-01-07 13:26:57 -080085 EXPECT_EQ(memory_writer.Write(std::span(buffer)), OkStatus());
David Rogers6d4f6302020-07-22 14:27:41 -070086 }
Armando Montanez0bcae732020-05-27 13:28:11 -070087
David Rogers6d4f6302020-07-22 14:27:41 -070088 EXPECT_GT(memory_writer.ConservativeWriteLimit(), 0u);
89 EXPECT_LT(memory_writer.ConservativeWriteLimit(), kTempBufferSize);
Armando Montanez0bcae732020-05-27 13:28:11 -070090
Wyatt Heplerd78f7c62020-09-28 14:27:32 -070091 EXPECT_EQ(memory_writer.Write(std::span(buffer)),
92 Status::ResourceExhausted());
David Rogers6d4f6302020-07-22 14:27:41 -070093 EXPECT_EQ(memory_writer.bytes_written(), counter);
Armando Montanez0bcae732020-05-27 13:28:11 -070094
95 counter = 0;
Wyatt Heplerbcefd362021-11-17 11:12:24 -080096 for (const std::byte& value : memory_writer) {
Armando Montanez0bcae732020-05-27 13:28:11 -070097 EXPECT_EQ(value, std::byte(counter++));
98 }
99}
100
Wyatt Hepler7b62e932021-08-10 23:57:10 -0700101TEST_F(MemoryWriterTest, FullWriter) {
David Rogers6d4f6302020-07-22 14:27:41 -0700102 constexpr size_t kTempBufferSize = 32;
103 std::byte buffer[kTempBufferSize] = {};
104 const int fill_byte = 0x25;
105 memset(buffer, fill_byte, sizeof(buffer));
106
Wyatt Hepler7b62e932021-08-10 23:57:10 -0700107 for (std::byte& value : memory_buffer_) {
David Rogers6d4f6302020-07-22 14:27:41 -0700108 value = std::byte(0);
109 }
Wyatt Hepler7b62e932021-08-10 23:57:10 -0700110 MemoryWriter memory_writer(memory_buffer_);
David Rogers6d4f6302020-07-22 14:27:41 -0700111
112 while (memory_writer.ConservativeWriteLimit() > 0) {
113 size_t bytes_to_write =
114 std::min(sizeof(buffer), memory_writer.ConservativeWriteLimit());
115 EXPECT_EQ(memory_writer.Write(std::span(buffer, bytes_to_write)),
Wyatt Hepler1b3da3a2021-01-07 13:26:57 -0800116 OkStatus());
David Rogers6d4f6302020-07-22 14:27:41 -0700117 }
118
119 EXPECT_EQ(memory_writer.ConservativeWriteLimit(), 0u);
120
Wyatt Heplerd78f7c62020-09-28 14:27:32 -0700121 EXPECT_EQ(memory_writer.Write(std::span(buffer)), Status::OutOfRange());
Wyatt Hepler7b62e932021-08-10 23:57:10 -0700122 EXPECT_EQ(memory_writer.bytes_written(), memory_buffer_.size());
David Rogers6d4f6302020-07-22 14:27:41 -0700123
Wyatt Heplerbcefd362021-11-17 11:12:24 -0800124 for (const std::byte& value : memory_writer) {
David Rogers6d4f6302020-07-22 14:27:41 -0700125 EXPECT_EQ(value, std::byte(fill_byte));
126 }
127}
128
Wyatt Hepler7b62e932021-08-10 23:57:10 -0700129TEST_F(MemoryWriterTest, EmptyData) {
Armando Montanez0bcae732020-05-27 13:28:11 -0700130 std::byte buffer[5] = {};
131
Wyatt Hepler7b62e932021-08-10 23:57:10 -0700132 MemoryWriter memory_writer(memory_buffer_);
Wyatt Hepler1b3da3a2021-01-07 13:26:57 -0800133 EXPECT_EQ(memory_writer.Write(buffer, 0), OkStatus());
Armando Montanez0bcae732020-05-27 13:28:11 -0700134 EXPECT_EQ(memory_writer.bytes_written(), 0u);
135}
136
Wyatt Hepler7b62e932021-08-10 23:57:10 -0700137TEST_F(MemoryWriterTest, ValidateContents_SingleByteWrites) {
138 MemoryWriter memory_writer(memory_buffer_);
shaneajgfdb2e502020-07-13 16:18:59 -0400139 EXPECT_TRUE(memory_writer.Write(std::byte{0x01}).ok());
140 EXPECT_EQ(memory_writer.bytes_written(), 1u);
141 EXPECT_EQ(memory_writer.data()[0], std::byte{0x01});
142
143 EXPECT_TRUE(memory_writer.Write(std::byte{0x7E}).ok());
144 EXPECT_EQ(memory_writer.bytes_written(), 2u);
145 EXPECT_EQ(memory_writer.data()[1], std::byte{0x7E});
146}
147
Wyatt Hepler7b62e932021-08-10 23:57:10 -0700148TEST_F(MemoryWriterTest, OverlappingBuffer) {
Armando Montanezf82d95b2021-04-08 12:00:09 -0700149 constexpr std::string_view kTestString("This is staged into the same buffer");
150 // Write at a five-byte offset from the start of the destination buffer.
Wyatt Hepler7b62e932021-08-10 23:57:10 -0700151 std::byte* const kOverlappingStart = memory_buffer_.data() + 5;
Armando Montanezf82d95b2021-04-08 12:00:09 -0700152 std::memcpy(kOverlappingStart, kTestString.data(), kTestString.size());
Wyatt Hepler7b62e932021-08-10 23:57:10 -0700153 MemoryWriter memory_writer(memory_buffer_);
Armando Montanezf82d95b2021-04-08 12:00:09 -0700154 EXPECT_TRUE(memory_writer.Write(kOverlappingStart, kTestString.size()).ok());
155 EXPECT_TRUE(memory_writer.Write(std::byte(0)).ok());
156 EXPECT_EQ(memory_writer.bytes_written(), kTestString.size() + 1);
157
Wyatt Heplerbcefd362021-11-17 11:12:24 -0800158 EXPECT_STREQ(reinterpret_cast<const char*>(memory_writer.data()),
159 kTestString.data());
160}
161
162TEST_F(MemoryWriterTest, Clear) {
163 MemoryWriter writer(memory_buffer_);
164 EXPECT_EQ(OkStatus(), writer.Write(std::byte{1}));
165 ASSERT_FALSE(writer.empty());
166 writer.clear();
167 EXPECT_TRUE(writer.empty());
168
169 EXPECT_EQ(OkStatus(), writer.Write(std::byte{99}));
170 EXPECT_EQ(writer[0], std::byte{99});
Armando Montanezf82d95b2021-04-08 12:00:09 -0700171}
172
Wyatt Hepler7b62e932021-08-10 23:57:10 -0700173TEST_F(MemoryWriterTest, Seek_To0) {
174 MemoryWriter writer(memory_buffer_);
175 EXPECT_EQ(OkStatus(), writer.Seek(0));
176}
177
178TEST_F(MemoryWriterTest, Tell_StartsAt0) {
179 MemoryWriter writer(memory_buffer_);
180 EXPECT_EQ(0u, writer.Tell());
181}
182
183TEST_F(MemoryWriterTest, Tell_UpdatesOnSeek) {
184 MemoryWriter writer(memory_buffer_);
185 ASSERT_EQ(OkStatus(), writer.Seek(2, Stream::kCurrent));
186 EXPECT_EQ(2u, writer.Tell());
187}
188
189TEST_F(MemoryWriterTest, Tell_UpdatesOnRead) {
190 MemoryWriter writer(memory_buffer_);
191 std::byte buffer[4] = {};
192 ASSERT_EQ(OkStatus(), writer.Write(buffer));
193 EXPECT_EQ(4u, writer.Tell());
194}
195
Ewout van Bekkume4d7b692020-10-15 13:12:30 -0700196#define TESTING_CHECK_FAILURES_IS_SUPPORTED 0
197#if TESTING_CHECK_FAILURES_IS_SUPPORTED
Armando Montanez0bcae732020-05-27 13:28:11 -0700198
199// TODO(amontanez): Ensure that this test triggers an assert.
Wyatt Hepler7b62e932021-08-10 23:57:10 -0700200TEST_F(MemoryWriterTest, NullPointer) {
201 MemoryWriter memory_writer(memory_buffer_);
Armando Montanez0bcae732020-05-27 13:28:11 -0700202 memory_writer.Write(nullptr, 21);
203}
204
David Rogers795fecf2020-07-28 00:36:45 -0700205// TODO(davidrogers): Ensure that this test triggers an assert.
206TEST(MemoryReader, NullSpan) {
Wyatt Hepler7b62e932021-08-10 23:57:10 -0700207 std::byte memory_buffer[32];
David Rogers795fecf2020-07-28 00:36:45 -0700208 ByteSpan dest(nullptr, 5);
209 MemoryReader memory_reader(memory_buffer);
210 memory_reader.Read(dest);
211}
212
213// TODO(davidrogers): Ensure that this test triggers an assert.
214TEST(MemoryReader, NullPointer) {
Wyatt Hepler7b62e932021-08-10 23:57:10 -0700215 std::byte memory_buffer[32];
David Rogers795fecf2020-07-28 00:36:45 -0700216 MemoryReader memory_reader(memory_buffer);
217 memory_reader.Read(nullptr, 21);
218}
219
Ewout van Bekkume4d7b692020-10-15 13:12:30 -0700220#endif // TESTING_CHECK_FAILURES_IS_SUPPORTED
Armando Montanez0bcae732020-05-27 13:28:11 -0700221
David Rogers795fecf2020-07-28 00:36:45 -0700222TEST(MemoryReader, SingleFullRead) {
223 constexpr size_t kTempBufferSize = 32;
224
225 std::array<std::byte, kTempBufferSize> source;
226 std::array<std::byte, kTempBufferSize> dest;
227
228 uint8_t counter = 0;
229 for (std::byte& value : source) {
230 value = std::byte(counter++);
231 }
232
233 MemoryReader memory_reader(source);
234
235 // Read exactly the available bytes.
236 EXPECT_EQ(memory_reader.ConservativeReadLimit(), dest.size());
237 Result<ByteSpan> result = memory_reader.Read(dest);
Wyatt Hepler1b3da3a2021-01-07 13:26:57 -0800238 EXPECT_EQ(result.status(), OkStatus());
David Rogers795fecf2020-07-28 00:36:45 -0700239 EXPECT_EQ(result.value().size_bytes(), dest.size());
240
241 ASSERT_EQ(source.size(), result.value().size_bytes());
242 for (size_t i = 0; i < source.size(); i++) {
243 EXPECT_EQ(source[i], result.value()[i]);
244 }
245
246 // Shoud be no byte remaining.
247 EXPECT_EQ(memory_reader.ConservativeReadLimit(), 0u);
248 result = memory_reader.Read(dest);
Wyatt Heplerd78f7c62020-09-28 14:27:32 -0700249 EXPECT_EQ(result.status(), Status::OutOfRange());
David Rogers795fecf2020-07-28 00:36:45 -0700250}
251
252TEST(MemoryReader, EmptySpanRead) {
253 constexpr size_t kTempBufferSize = 32;
254 std::array<std::byte, kTempBufferSize> source;
255
256 // Use a span with nullptr and zero length;
257 ByteSpan dest(nullptr, 0);
258 EXPECT_EQ(dest.size_bytes(), 0u);
259
260 MemoryReader memory_reader(source);
261
262 // Read exactly the available bytes.
263 Result<ByteSpan> result = memory_reader.Read(dest);
Wyatt Hepler1b3da3a2021-01-07 13:26:57 -0800264 EXPECT_EQ(result.status(), OkStatus());
David Rogers795fecf2020-07-28 00:36:45 -0700265 EXPECT_EQ(result.value().size_bytes(), 0u);
266 EXPECT_EQ(result.value().data(), dest.data());
267
268 // Shoud be original bytes remaining.
269 EXPECT_EQ(memory_reader.ConservativeReadLimit(), source.size());
270}
271
272TEST(MemoryReader, SinglePartialRead) {
273 constexpr size_t kTempBufferSize = 32;
274 std::array<std::byte, kTempBufferSize> source;
275 std::array<std::byte, kTempBufferSize * 2> dest;
276
277 uint8_t counter = 0;
278 for (std::byte& value : source) {
279 value = std::byte(counter++);
280 }
281
282 MemoryReader memory_reader(source);
283
284 // Try and read double the bytes available. Use the pointer/size version of
285 // the API.
286 Result<ByteSpan> result = memory_reader.Read(dest.data(), dest.size());
Wyatt Hepler1b3da3a2021-01-07 13:26:57 -0800287 EXPECT_EQ(result.status(), OkStatus());
David Rogers795fecf2020-07-28 00:36:45 -0700288 EXPECT_EQ(result.value().size_bytes(), source.size());
289
290 ASSERT_EQ(source.size(), result.value().size_bytes());
291 for (size_t i = 0; i < source.size(); i++) {
292 EXPECT_EQ(source[i], result.value()[i]);
293 }
294
295 // Shoud be no byte remaining.
296 EXPECT_EQ(memory_reader.ConservativeReadLimit(), 0u);
297 result = memory_reader.Read(dest);
Wyatt Heplerd78f7c62020-09-28 14:27:32 -0700298 EXPECT_EQ(result.status(), Status::OutOfRange());
David Rogers795fecf2020-07-28 00:36:45 -0700299}
300
301TEST(MemoryReader, MultipleReads) {
302 constexpr size_t kTempBufferSize = 32;
303
304 std::array<std::byte, kTempBufferSize * 5> source;
305 std::array<std::byte, kTempBufferSize> dest;
306
307 uint8_t counter = 0;
308
309 for (std::byte& value : source) {
310 value = std::byte(counter++);
311 }
312
313 MemoryReader memory_reader(source);
314
315 size_t source_chunk_base = 0;
316
317 while (memory_reader.ConservativeReadLimit() > 0) {
318 size_t read_limit = memory_reader.ConservativeReadLimit();
319
320 // Try and read a chunk of bytes.
321 Result<ByteSpan> result = memory_reader.Read(dest);
Wyatt Hepler1b3da3a2021-01-07 13:26:57 -0800322 EXPECT_EQ(result.status(), OkStatus());
David Rogers795fecf2020-07-28 00:36:45 -0700323 EXPECT_EQ(result.value().size_bytes(), dest.size());
324 EXPECT_EQ(memory_reader.ConservativeReadLimit(),
325 read_limit - result.value().size_bytes());
326
327 // Verify the chunk of byte that was read.
328 for (size_t i = 0; i < result.value().size_bytes(); i++) {
329 EXPECT_EQ(source[source_chunk_base + i], result.value()[i]);
330 }
331 source_chunk_base += result.value().size_bytes();
332 }
333}
334
Wyatt Hepler7b62e932021-08-10 23:57:10 -0700335TEST(MemoryReader, Seek) {
336 constexpr std::string_view data = "0123456789";
337 MemoryReader reader(std::as_bytes(std::span(data)));
338
339 char buffer[5] = {}; // Leave a null terminator at the end.
340 ASSERT_EQ(OkStatus(), reader.Read(buffer, sizeof(buffer) - 1).status());
341 EXPECT_STREQ(buffer, "0123");
342
343 ASSERT_EQ(OkStatus(), reader.Seek(1));
344 ASSERT_EQ(OkStatus(), reader.Read(buffer, sizeof(buffer) - 1).status());
345 EXPECT_STREQ(buffer, "1234");
346
347 ASSERT_EQ(OkStatus(), reader.Seek(0));
348 ASSERT_EQ(OkStatus(), reader.Read(buffer, sizeof(buffer) - 1).status());
349 EXPECT_STREQ(buffer, "0123");
350}
351
352TEST(MemoryReader, Tell_StartsAt0) {
353 MemoryReader reader(std::as_bytes(std::span("\3\2\1")));
354 EXPECT_EQ(0u, reader.Tell());
355}
356
357TEST(MemoryReader, Tell_UpdatesOnSeek) {
358 MemoryReader reader(std::as_bytes(std::span("\3\2\1")));
359 ASSERT_EQ(OkStatus(), reader.Seek(2, Stream::kCurrent));
360 EXPECT_EQ(2u, reader.Tell());
361}
362
363TEST(MemoryReader, Tell_UpdatesOnRead) {
364 MemoryReader reader(std::as_bytes(std::span("\3\2\1")));
365 std::byte buffer[4];
366 ASSERT_EQ(OkStatus(), reader.Read(buffer).status());
367 EXPECT_EQ(4u, reader.Tell());
368}
369
Armando Montanez0bcae732020-05-27 13:28:11 -0700370} // namespace
David Rogers6d4f6302020-07-22 14:27:41 -0700371} // namespace pw::stream