1 // Copyright 2025 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_bluetooth_proxy/internal/multibuf_writer.h"
16
17 #include <array>
18
19 #include "pw_containers/to_array.h"
20 #include "pw_multibuf/simple_allocator_for_test.h"
21 #include "pw_span/cast.h"
22 #include "pw_unit_test/framework.h"
23
24 namespace pw::bluetooth::proxy {
25 namespace {
26
27 using pw::containers::to_array;
28
29 class MultiBufWriterTest : public testing::Test {
30 protected:
31 pw::multibuf::test::SimpleAllocatorForTest</*kDataSizeBytes=*/512,
32 /*kMetaSizeBytes=*/512>
33 allocator;
34 };
35
TEST_F(MultiBufWriterTest,CanCreate)36 TEST_F(MultiBufWriterTest, CanCreate) {
37 pw::Result<MultiBufWriter> writer = MultiBufWriter::Create(allocator, 8u);
38 PW_TEST_ASSERT_OK(writer);
39 EXPECT_FALSE(writer->IsComplete());
40 EXPECT_EQ(writer->U8Span().size(), 0u);
41 }
42
TEST_F(MultiBufWriterTest,CanWrite)43 TEST_F(MultiBufWriterTest, CanWrite) {
44 pw::Result<MultiBufWriter> writer = MultiBufWriter::Create(allocator, 8u);
45 PW_TEST_ASSERT_OK(writer);
46
47 static constexpr auto kExpectedData =
48 to_array<uint8_t>({0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88});
49
50 // Write first chunk
51 PW_TEST_EXPECT_OK(writer->Write(to_array<uint8_t>({0x11, 0x22, 0x33, 0x44})));
52 EXPECT_FALSE(writer->IsComplete());
53 EXPECT_EQ(writer->U8Span().size(), 4u);
54
55 // Write second chunk
56 PW_TEST_EXPECT_OK(writer->Write(to_array<uint8_t>({0x55, 0x66, 0x77, 0x88})));
57 EXPECT_TRUE(writer->IsComplete());
58 EXPECT_EQ(writer->U8Span().size(), 8u);
59 EXPECT_TRUE(std::equal(writer->U8Span().begin(),
60 writer->U8Span().end(),
61 kExpectedData.begin(),
62 kExpectedData.end()));
63 }
64
TEST_F(MultiBufWriterTest,CannotWriteMoreThanRemains)65 TEST_F(MultiBufWriterTest, CannotWriteMoreThanRemains) {
66 pw::Result<MultiBufWriter> writer = MultiBufWriter::Create(allocator, 5u);
67 PW_TEST_ASSERT_OK(writer);
68
69 // Write first chunk
70 PW_TEST_EXPECT_OK(writer->Write(to_array<uint8_t>({0x11, 0x22, 0x33, 0x44})));
71 EXPECT_FALSE(writer->IsComplete());
72 EXPECT_EQ(writer->U8Span().size(), 4u);
73
74 // Cannot write second chunk (one byte too big)
75 EXPECT_EQ(writer->Write(to_array<uint8_t>({0x55, 0x66})),
76 Status::ResourceExhausted());
77 EXPECT_FALSE(writer->IsComplete());
78 EXPECT_EQ(writer->U8Span().size(), 4u);
79 }
80
TEST_F(MultiBufWriterTest,CanTakeMultiBuf)81 TEST_F(MultiBufWriterTest, CanTakeMultiBuf) {
82 pw::Result<MultiBufWriter> writer = MultiBufWriter::Create(allocator, 8u);
83 PW_TEST_ASSERT_OK(writer);
84
85 static constexpr auto kData =
86 to_array<uint8_t>({0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88});
87
88 PW_TEST_EXPECT_OK(writer->Write(kData));
89 ASSERT_TRUE(writer->IsComplete());
90
91 // Take the MultiBuf from the MultiBufWriter
92 multibuf::MultiBuf mbuf = std::move(writer->TakeMultiBuf());
93 EXPECT_EQ(mbuf.size(), 8u);
94
95 std::optional<ByteSpan> mbuf_span = mbuf.ContiguousSpan();
96 ASSERT_TRUE(bool(mbuf_span));
97 pw::span<uint8_t> mbuf_u8_span = pw::span_cast<uint8_t>(*mbuf_span);
98 EXPECT_TRUE(std::equal(
99 mbuf_u8_span.begin(), mbuf_u8_span.end(), kData.begin(), kData.end()));
100
101 // IsComplete() returns true
102 EXPECT_TRUE(writer->IsComplete());
103
104 // Can no longer write
105 EXPECT_NE(writer->Write(kData), OkStatus());
106
107 // Calling it again results in an empty multibuf.
108 multibuf::MultiBuf mbuf2 = std::move(writer->TakeMultiBuf());
109 EXPECT_EQ(mbuf2.size(), 0u);
110 }
111
112 } // namespace
113 } // namespace pw::bluetooth::proxy
114