xref: /aosp_15_r20/external/pigweed/pw_stream/memory_stream_test.cc (revision 61c4878ac05f98d0ceed94b57d316916de578985)
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_stream/memory_stream.h"
16 
17 #include <cstring>
18 
19 #include "pw_preprocessor/compiler.h"
20 #include "pw_unit_test/framework.h"
21 
22 namespace pw::stream {
23 namespace {
24 
25 // Size of the in-memory buffer to use for this test.
26 constexpr size_t kSinkBufferSize = 1013;
27 
28 struct TestStruct {
29   uint8_t day;
30   uint8_t month;
31   uint16_t year;
32 };
33 
34 constexpr TestStruct kExpectedStruct = {.day = 18, .month = 5, .year = 2020};
35 
36 class MemoryWriterTest : public ::testing::Test {
37  protected:
MemoryWriterTest()38   MemoryWriterTest() : memory_buffer_{} {}
39   std::array<std::byte, kSinkBufferSize> memory_buffer_;
40 };
41 
TEST_F(MemoryWriterTest,BytesWritten)42 TEST_F(MemoryWriterTest, BytesWritten) {
43   MemoryWriter memory_writer(memory_buffer_);
44   EXPECT_EQ(memory_writer.bytes_written(), 0u);
45   Status status =
46       memory_writer.Write(&kExpectedStruct, sizeof(kExpectedStruct));
47   EXPECT_EQ(status, OkStatus());
48   EXPECT_EQ(memory_writer.bytes_written(), sizeof(kExpectedStruct));
49 }
50 
TEST_F(MemoryWriterTest,BytesWrittenOnConstruction)51 TEST_F(MemoryWriterTest, BytesWrittenOnConstruction) {
52   constexpr size_t bytes_written = kSinkBufferSize / 2;
53   std::memset(memory_buffer_.data(), 1u, bytes_written);
54   MemoryWriter memory_writer(memory_buffer_, bytes_written);
55   EXPECT_EQ(memory_writer.bytes_written(), bytes_written);
56   EXPECT_EQ(memcmp(memory_writer.data(), memory_buffer_.data(), bytes_written),
57             0);
58 }
59 
TEST_F(MemoryWriterTest,ValidateContents)60 TEST_F(MemoryWriterTest, ValidateContents) {
61   MemoryWriter memory_writer(memory_buffer_);
62   EXPECT_TRUE(
63       memory_writer.Write(&kExpectedStruct, sizeof(kExpectedStruct)).ok());
64 
65   span<const std::byte> written_data = memory_writer.WrittenData();
66   EXPECT_EQ(written_data.size_bytes(), sizeof(kExpectedStruct));
67   TestStruct temp;
68   std::memcpy(&temp, written_data.data(), written_data.size_bytes());
69   EXPECT_EQ(memcmp(&temp, &kExpectedStruct, sizeof(kExpectedStruct)), 0);
70 }
71 
TEST_F(MemoryWriterTest,MultipleWrites)72 TEST_F(MemoryWriterTest, MultipleWrites) {
73   constexpr size_t kTempBufferSize = 72;
74   std::byte buffer[kTempBufferSize] = {};
75 
76   for (std::byte& value : memory_buffer_) {
77     value = std::byte(0);
78   }
79   MemoryWriter memory_writer(memory_buffer_);
80 
81   size_t counter = 0;
82   while (memory_writer.ConservativeWriteLimit() >= kTempBufferSize) {
83     for (size_t i = 0; i < sizeof(buffer); ++i) {
84       buffer[i] = std::byte(counter++);
85     }
86     EXPECT_EQ(memory_writer.Write(span(buffer)), OkStatus());
87   }
88 
89   EXPECT_GT(memory_writer.ConservativeWriteLimit(), 0u);
90   EXPECT_LT(memory_writer.ConservativeWriteLimit(), kTempBufferSize);
91 
92   EXPECT_EQ(memory_writer.Write(span(buffer)), Status::ResourceExhausted());
93   EXPECT_EQ(memory_writer.bytes_written(), counter);
94 
95   counter = 0;
96   for (const std::byte& value : memory_writer) {
97     EXPECT_EQ(value, std::byte(counter++));
98   }
99 }
100 
TEST_F(MemoryWriterTest,FullWriter)101 TEST_F(MemoryWriterTest, FullWriter) {
102   constexpr size_t kTempBufferSize = 32;
103   std::byte buffer[kTempBufferSize] = {};
104   const int fill_byte = 0x25;
105   memset(buffer, fill_byte, sizeof(buffer));
106 
107   for (std::byte& value : memory_buffer_) {
108     value = std::byte(0);
109   }
110   MemoryWriter memory_writer(memory_buffer_);
111 
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(span(buffer, bytes_to_write)), OkStatus());
116   }
117 
118   EXPECT_EQ(memory_writer.ConservativeWriteLimit(), 0u);
119 
120   EXPECT_EQ(memory_writer.Write(span(buffer)), Status::OutOfRange());
121   EXPECT_EQ(memory_writer.bytes_written(), memory_buffer_.size());
122 
123   for (const std::byte& value : memory_writer) {
124     EXPECT_EQ(value, std::byte(fill_byte));
125   }
126 }
127 
TEST_F(MemoryWriterTest,EmptyData)128 TEST_F(MemoryWriterTest, EmptyData) {
129   std::byte buffer[5] = {};
130 
131   MemoryWriter memory_writer(memory_buffer_);
132   EXPECT_EQ(memory_writer.Write(buffer, 0), OkStatus());
133   EXPECT_EQ(memory_writer.bytes_written(), 0u);
134 }
135 
TEST_F(MemoryWriterTest,ValidateContents_SingleByteWrites)136 TEST_F(MemoryWriterTest, ValidateContents_SingleByteWrites) {
137   MemoryWriter memory_writer(memory_buffer_);
138   EXPECT_TRUE(memory_writer.Write(std::byte{0x01}).ok());
139   EXPECT_EQ(memory_writer.bytes_written(), 1u);
140   EXPECT_EQ(memory_writer.data()[0], std::byte{0x01});
141 
142   EXPECT_TRUE(memory_writer.Write(std::byte{0x7E}).ok());
143   EXPECT_EQ(memory_writer.bytes_written(), 2u);
144   EXPECT_EQ(memory_writer.data()[1], std::byte{0x7E});
145 }
146 
TEST_F(MemoryWriterTest,OverlappingBuffer)147 TEST_F(MemoryWriterTest, OverlappingBuffer) {
148   constexpr std::string_view kTestString("This is staged into the same buffer");
149   // Write at a five-byte offset from the start of the destination buffer.
150   std::byte* const kOverlappingStart = memory_buffer_.data() + 5;
151   std::memcpy(kOverlappingStart, kTestString.data(), kTestString.size());
152   MemoryWriter memory_writer(memory_buffer_);
153   EXPECT_TRUE(memory_writer.Write(kOverlappingStart, kTestString.size()).ok());
154   EXPECT_TRUE(memory_writer.Write(std::byte(0)).ok());
155   EXPECT_EQ(memory_writer.bytes_written(), kTestString.size() + 1);
156 
157   EXPECT_STREQ(reinterpret_cast<const char*>(memory_writer.data()),
158                kTestString.data());
159 }
160 
TEST_F(MemoryWriterTest,Clear)161 TEST_F(MemoryWriterTest, Clear) {
162   MemoryWriter writer(memory_buffer_);
163   EXPECT_EQ(OkStatus(), writer.Write(std::byte{1}));
164   ASSERT_FALSE(writer.empty());
165   writer.clear();
166   EXPECT_TRUE(writer.empty());
167 
168   EXPECT_EQ(OkStatus(), writer.Write(std::byte{99}));
169   EXPECT_EQ(writer[0], std::byte{99});
170 }
171 
TEST_F(MemoryWriterTest,Seek_To0)172 TEST_F(MemoryWriterTest, Seek_To0) {
173   MemoryWriter writer(memory_buffer_);
174   EXPECT_EQ(OkStatus(), writer.Seek(0));
175 }
176 
TEST_F(MemoryWriterTest,Tell_StartsAt0)177 TEST_F(MemoryWriterTest, Tell_StartsAt0) {
178   MemoryWriter writer(memory_buffer_);
179   EXPECT_EQ(0u, writer.Tell());
180 }
181 
TEST_F(MemoryWriterTest,Tell_UpdatesOnSeek)182 TEST_F(MemoryWriterTest, Tell_UpdatesOnSeek) {
183   MemoryWriter writer(memory_buffer_);
184   ASSERT_EQ(OkStatus(), writer.Seek(2, Stream::kCurrent));
185   EXPECT_EQ(2u, writer.Tell());
186 }
187 
TEST_F(MemoryWriterTest,Tell_UpdatesOnRead)188 TEST_F(MemoryWriterTest, Tell_UpdatesOnRead) {
189   MemoryWriter writer(memory_buffer_);
190   std::byte buffer[4] = {};
191   ASSERT_EQ(OkStatus(), writer.Write(buffer));
192   EXPECT_EQ(4u, writer.Tell());
193 }
194 
195 #define TESTING_CHECK_FAILURES_IS_SUPPORTED 0
196 #if TESTING_CHECK_FAILURES_IS_SUPPORTED
197 
198 // TODO(amontanez): Ensure that this test triggers an assert.
TEST_F(MemoryWriterTest,NullPointer)199 TEST_F(MemoryWriterTest, NullPointer) {
200   MemoryWriter memory_writer(memory_buffer_);
201   memory_writer.Write(nullptr, 21);
202 }
203 
204 // TODO(davidrogers): Ensure that this test triggers an assert.
TEST(MemoryReader,NullSpan)205 TEST(MemoryReader, NullSpan) {
206   std::byte memory_buffer[32];
207   ByteSpan dest(nullptr, 5);
208   MemoryReader memory_reader(memory_buffer);
209   memory_reader.Read(dest);
210 }
211 
212 // TODO(davidrogers): Ensure that this test triggers an assert.
TEST(MemoryReader,NullPointer)213 TEST(MemoryReader, NullPointer) {
214   std::byte memory_buffer[32];
215   MemoryReader memory_reader(memory_buffer);
216   memory_reader.Read(nullptr, 21);
217 }
218 
219 #endif  // TESTING_CHECK_FAILURES_IS_SUPPORTED
220 
TEST(MemoryReader,SingleFullRead)221 TEST(MemoryReader, SingleFullRead) {
222   constexpr size_t kTempBufferSize = 32;
223 
224   std::array<std::byte, kTempBufferSize> source;
225   std::array<std::byte, kTempBufferSize> dest;
226 
227   uint8_t counter = 0;
228   for (std::byte& value : source) {
229     value = std::byte(counter++);
230   }
231 
232   MemoryReader memory_reader(source);
233 
234   // Read exactly the available bytes.
235   EXPECT_EQ(memory_reader.ConservativeReadLimit(), dest.size());
236   Result<ByteSpan> result = memory_reader.Read(dest);
237   EXPECT_EQ(result.status(), OkStatus());
238   EXPECT_EQ(result.value().size_bytes(), dest.size());
239 
240   ASSERT_EQ(source.size(), result.value().size_bytes());
241   for (size_t i = 0; i < source.size(); i++) {
242     EXPECT_EQ(source[i], result.value()[i]);
243   }
244 
245   // Shoud be no byte remaining.
246   EXPECT_EQ(memory_reader.ConservativeReadLimit(), 0u);
247   result = memory_reader.Read(dest);
248   EXPECT_EQ(result.status(), Status::OutOfRange());
249 }
250 
TEST(MemoryReader,EmptySpanRead)251 TEST(MemoryReader, EmptySpanRead) {
252   constexpr size_t kTempBufferSize = 32;
253   std::array<std::byte, kTempBufferSize> source;
254 
255   // Use a span with nullptr and zero length;
256   ByteSpan dest;
257   EXPECT_EQ(dest.size_bytes(), 0u);
258 
259   MemoryReader memory_reader(source);
260 
261   // Read exactly the available bytes.
262   Result<ByteSpan> result = memory_reader.Read(dest);
263   EXPECT_EQ(result.status(), OkStatus());
264   EXPECT_EQ(result.value().size_bytes(), 0u);
265   EXPECT_EQ(result.value().data(), dest.data());
266 
267   // Shoud be original bytes remaining.
268   EXPECT_EQ(memory_reader.ConservativeReadLimit(), source.size());
269 }
270 
TEST(MemoryReader,SinglePartialRead)271 TEST(MemoryReader, SinglePartialRead) {
272   constexpr size_t kTempBufferSize = 32;
273   std::array<std::byte, kTempBufferSize> source;
274   std::array<std::byte, kTempBufferSize * 2> dest;
275 
276   uint8_t counter = 0;
277   for (std::byte& value : source) {
278     value = std::byte(counter++);
279   }
280 
281   MemoryReader memory_reader(source);
282 
283   // Try and read double the bytes available. Use the pointer/size version of
284   // the API.
285   Result<ByteSpan> result = memory_reader.Read(dest.data(), dest.size());
286   EXPECT_EQ(result.status(), OkStatus());
287   EXPECT_EQ(result.value().size_bytes(), source.size());
288 
289   ASSERT_EQ(source.size(), result.value().size_bytes());
290   for (size_t i = 0; i < source.size(); i++) {
291     EXPECT_EQ(source[i], result.value()[i]);
292   }
293 
294   // Shoud be no byte remaining.
295   EXPECT_EQ(memory_reader.ConservativeReadLimit(), 0u);
296   result = memory_reader.Read(dest);
297   EXPECT_EQ(result.status(), Status::OutOfRange());
298 }
299 
TEST(MemoryReader,MultipleReads)300 TEST(MemoryReader, MultipleReads) {
301   constexpr size_t kTempBufferSize = 32;
302 
303   std::array<std::byte, kTempBufferSize * 5> source;
304   std::array<std::byte, kTempBufferSize> dest;
305 
306   uint8_t counter = 0;
307 
308   for (std::byte& value : source) {
309     value = std::byte(counter++);
310   }
311 
312   MemoryReader memory_reader(source);
313 
314   size_t source_chunk_base = 0;
315 
316   while (memory_reader.ConservativeReadLimit() > 0) {
317     size_t read_limit = memory_reader.ConservativeReadLimit();
318 
319     // Try and read a chunk of bytes.
320     Result<ByteSpan> result = memory_reader.Read(dest);
321     EXPECT_EQ(result.status(), OkStatus());
322     EXPECT_EQ(result.value().size_bytes(), dest.size());
323     EXPECT_EQ(memory_reader.ConservativeReadLimit(),
324               read_limit - result.value().size_bytes());
325 
326     // Verify the chunk of byte that was read.
327     for (size_t i = 0; i < result.value().size_bytes(); i++) {
328       EXPECT_EQ(source[source_chunk_base + i], result.value()[i]);
329     }
330     source_chunk_base += result.value().size_bytes();
331   }
332 }
333 
TEST(MemoryReader,Seek)334 TEST(MemoryReader, Seek) {
335   constexpr std::string_view data = "0123456789";
336   MemoryReader reader(as_bytes(span(data)));
337 
338   char buffer[5] = {};  // Leave a null terminator at the end.
339   ASSERT_EQ(OkStatus(), reader.Read(buffer, sizeof(buffer) - 1).status());
340   EXPECT_STREQ(buffer, "0123");
341 
342   ASSERT_EQ(OkStatus(), reader.Seek(1));
343   ASSERT_EQ(OkStatus(), reader.Read(buffer, sizeof(buffer) - 1).status());
344   EXPECT_STREQ(buffer, "1234");
345 
346   ASSERT_EQ(OkStatus(), reader.Seek(0));
347   ASSERT_EQ(OkStatus(), reader.Read(buffer, sizeof(buffer) - 1).status());
348   EXPECT_STREQ(buffer, "0123");
349 }
350 
TEST(MemoryReader,Tell_StartsAt0)351 TEST(MemoryReader, Tell_StartsAt0) {
352   MemoryReader reader(as_bytes(span("\3\2\1")));
353   EXPECT_EQ(0u, reader.Tell());
354 }
355 
TEST(MemoryReader,Tell_UpdatesOnSeek)356 TEST(MemoryReader, Tell_UpdatesOnSeek) {
357   MemoryReader reader(as_bytes(span("\3\2\1")));
358   ASSERT_EQ(OkStatus(), reader.Seek(2, Stream::kCurrent));
359   EXPECT_EQ(2u, reader.Tell());
360 }
361 
TEST(MemoryReader,Tell_UpdatesOnRead)362 TEST(MemoryReader, Tell_UpdatesOnRead) {
363   MemoryReader reader(as_bytes(span("\3\2\1")));
364   std::byte buffer[4];
365   ASSERT_EQ(OkStatus(), reader.Read(buffer).status());
366   EXPECT_EQ(4u, reader.Tell());
367 }
368 
369 }  // namespace
370 }  // namespace pw::stream
371