xref: /aosp_15_r20/external/pigweed/pw_channel/loopback_channel_test.cc (revision 61c4878ac05f98d0ceed94b57d316916de578985)
1*61c4878aSAndroid Build Coastguard Worker // Copyright 2024 The Pigweed Authors
2*61c4878aSAndroid Build Coastguard Worker //
3*61c4878aSAndroid Build Coastguard Worker // Licensed under the Apache License, Version 2.0 (the "License"); you may not
4*61c4878aSAndroid Build Coastguard Worker // use this file except in compliance with the License. You may obtain a copy of
5*61c4878aSAndroid Build Coastguard Worker // the License at
6*61c4878aSAndroid Build Coastguard Worker //
7*61c4878aSAndroid Build Coastguard Worker //     https://www.apache.org/licenses/LICENSE-2.0
8*61c4878aSAndroid Build Coastguard Worker //
9*61c4878aSAndroid Build Coastguard Worker // Unless required by applicable law or agreed to in writing, software
10*61c4878aSAndroid Build Coastguard Worker // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11*61c4878aSAndroid Build Coastguard Worker // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12*61c4878aSAndroid Build Coastguard Worker // License for the specific language governing permissions and limitations under
13*61c4878aSAndroid Build Coastguard Worker // the License.
14*61c4878aSAndroid Build Coastguard Worker 
15*61c4878aSAndroid Build Coastguard Worker #include "pw_channel/loopback_channel.h"
16*61c4878aSAndroid Build Coastguard Worker 
17*61c4878aSAndroid Build Coastguard Worker #include "pw_allocator/testing.h"
18*61c4878aSAndroid Build Coastguard Worker #include "pw_assert/check.h"
19*61c4878aSAndroid Build Coastguard Worker #include "pw_async2/dispatcher.h"
20*61c4878aSAndroid Build Coastguard Worker #include "pw_bytes/suffix.h"
21*61c4878aSAndroid Build Coastguard Worker #include "pw_channel/channel.h"
22*61c4878aSAndroid Build Coastguard Worker #include "pw_multibuf/simple_allocator_for_test.h"
23*61c4878aSAndroid Build Coastguard Worker #include "pw_status/status.h"
24*61c4878aSAndroid Build Coastguard Worker 
25*61c4878aSAndroid Build Coastguard Worker namespace {
26*61c4878aSAndroid Build Coastguard Worker 
27*61c4878aSAndroid Build Coastguard Worker using ::pw::async2::Context;
28*61c4878aSAndroid Build Coastguard Worker using ::pw::async2::Dispatcher;
29*61c4878aSAndroid Build Coastguard Worker using ::pw::async2::Pending;
30*61c4878aSAndroid Build Coastguard Worker using ::pw::async2::Poll;
31*61c4878aSAndroid Build Coastguard Worker using ::pw::async2::Ready;
32*61c4878aSAndroid Build Coastguard Worker using ::pw::async2::Task;
33*61c4878aSAndroid Build Coastguard Worker using ::pw::operator""_b;
34*61c4878aSAndroid Build Coastguard Worker using ::pw::channel::DatagramReader;
35*61c4878aSAndroid Build Coastguard Worker using ::pw::channel::LoopbackByteChannel;
36*61c4878aSAndroid Build Coastguard Worker using ::pw::channel::LoopbackDatagramChannel;
37*61c4878aSAndroid Build Coastguard Worker using ::pw::channel::ReliableByteReader;
38*61c4878aSAndroid Build Coastguard Worker using ::pw::multibuf::test::SimpleAllocatorForTest;
39*61c4878aSAndroid Build Coastguard Worker 
40*61c4878aSAndroid Build Coastguard Worker template <typename ChannelKind>
41*61c4878aSAndroid Build Coastguard Worker class ReaderTask : public Task {
42*61c4878aSAndroid Build Coastguard Worker  public:
ReaderTask(ChannelKind & channel)43*61c4878aSAndroid Build Coastguard Worker   ReaderTask(ChannelKind& channel) : channel_(channel) {}
44*61c4878aSAndroid Build Coastguard Worker 
45*61c4878aSAndroid Build Coastguard Worker   int poll_count = 0;
46*61c4878aSAndroid Build Coastguard Worker   int read_count = 0;
47*61c4878aSAndroid Build Coastguard Worker   int bytes_read_count = 0;
48*61c4878aSAndroid Build Coastguard Worker 
49*61c4878aSAndroid Build Coastguard Worker  private:
DoPend(Context & cx)50*61c4878aSAndroid Build Coastguard Worker   Poll<> DoPend(Context& cx) final {
51*61c4878aSAndroid Build Coastguard Worker     ++poll_count;
52*61c4878aSAndroid Build Coastguard Worker     while (true) {
53*61c4878aSAndroid Build Coastguard Worker       auto result = channel_.PendRead(cx);
54*61c4878aSAndroid Build Coastguard Worker       if (result.IsPending()) {
55*61c4878aSAndroid Build Coastguard Worker         return Pending();
56*61c4878aSAndroid Build Coastguard Worker       }
57*61c4878aSAndroid Build Coastguard Worker       if (!result->ok()) {
58*61c4878aSAndroid Build Coastguard Worker         // We hit an error-- call it quits.
59*61c4878aSAndroid Build Coastguard Worker         return Ready();
60*61c4878aSAndroid Build Coastguard Worker       }
61*61c4878aSAndroid Build Coastguard Worker       ++read_count;
62*61c4878aSAndroid Build Coastguard Worker       bytes_read_count += (**result).size();
63*61c4878aSAndroid Build Coastguard Worker     }
64*61c4878aSAndroid Build Coastguard Worker   }
65*61c4878aSAndroid Build Coastguard Worker 
66*61c4878aSAndroid Build Coastguard Worker   ChannelKind& channel_;
67*61c4878aSAndroid Build Coastguard Worker };
68*61c4878aSAndroid Build Coastguard Worker 
TEST(LoopbackDatagramChannel,LoopsEmptyDatagrams)69*61c4878aSAndroid Build Coastguard Worker TEST(LoopbackDatagramChannel, LoopsEmptyDatagrams) {
70*61c4878aSAndroid Build Coastguard Worker   SimpleAllocatorForTest alloc;
71*61c4878aSAndroid Build Coastguard Worker   LoopbackDatagramChannel channel(alloc);
72*61c4878aSAndroid Build Coastguard Worker   ReaderTask<DatagramReader> read_task(channel.channel());
73*61c4878aSAndroid Build Coastguard Worker 
74*61c4878aSAndroid Build Coastguard Worker   Dispatcher dispatcher;
75*61c4878aSAndroid Build Coastguard Worker   dispatcher.Post(read_task);
76*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(dispatcher.RunUntilStalled(), Pending());
77*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(read_task.poll_count, 1);
78*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(read_task.read_count, 0);
79*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(read_task.bytes_read_count, 0);
80*61c4878aSAndroid Build Coastguard Worker 
81*61c4878aSAndroid Build Coastguard Worker   PW_TEST_EXPECT_OK(channel.StageWrite(alloc.BufWith({})));
82*61c4878aSAndroid Build Coastguard Worker 
83*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(dispatcher.RunUntilStalled(), Pending());
84*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(read_task.poll_count, 2);
85*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(read_task.read_count, 1);
86*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(read_task.bytes_read_count, 0);
87*61c4878aSAndroid Build Coastguard Worker }
88*61c4878aSAndroid Build Coastguard Worker 
TEST(LoopbackDatagramChannel,LoopsDatagrams)89*61c4878aSAndroid Build Coastguard Worker TEST(LoopbackDatagramChannel, LoopsDatagrams) {
90*61c4878aSAndroid Build Coastguard Worker   SimpleAllocatorForTest alloc;
91*61c4878aSAndroid Build Coastguard Worker   LoopbackDatagramChannel channel(alloc);
92*61c4878aSAndroid Build Coastguard Worker   ReaderTask<DatagramReader> read_task(channel.channel());
93*61c4878aSAndroid Build Coastguard Worker 
94*61c4878aSAndroid Build Coastguard Worker   Dispatcher dispatcher;
95*61c4878aSAndroid Build Coastguard Worker   dispatcher.Post(read_task);
96*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(dispatcher.RunUntilStalled(), Pending());
97*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(read_task.poll_count, 1);
98*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(read_task.read_count, 0);
99*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(read_task.bytes_read_count, 0);
100*61c4878aSAndroid Build Coastguard Worker 
101*61c4878aSAndroid Build Coastguard Worker   PW_TEST_EXPECT_OK(channel.StageWrite(alloc.BufWith({1_b, 2_b, 3_b})));
102*61c4878aSAndroid Build Coastguard Worker 
103*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(dispatcher.RunUntilStalled(), Pending());
104*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(read_task.poll_count, 2);
105*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(read_task.read_count, 1);
106*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(read_task.bytes_read_count, 3);
107*61c4878aSAndroid Build Coastguard Worker }
108*61c4878aSAndroid Build Coastguard Worker 
TEST(LoopbackByteChannel,IgnoresEmptyWrites)109*61c4878aSAndroid Build Coastguard Worker TEST(LoopbackByteChannel, IgnoresEmptyWrites) {
110*61c4878aSAndroid Build Coastguard Worker   SimpleAllocatorForTest alloc;
111*61c4878aSAndroid Build Coastguard Worker   LoopbackByteChannel channel(alloc);
112*61c4878aSAndroid Build Coastguard Worker   ReaderTask<ReliableByteReader> read_task(channel.channel());
113*61c4878aSAndroid Build Coastguard Worker 
114*61c4878aSAndroid Build Coastguard Worker   Dispatcher dispatcher;
115*61c4878aSAndroid Build Coastguard Worker   dispatcher.Post(read_task);
116*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(dispatcher.RunUntilStalled(), Pending());
117*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(read_task.poll_count, 1);
118*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(read_task.read_count, 0);
119*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(read_task.bytes_read_count, 0);
120*61c4878aSAndroid Build Coastguard Worker 
121*61c4878aSAndroid Build Coastguard Worker   PW_TEST_EXPECT_OK(channel.StageWrite(alloc.BufWith({})));
122*61c4878aSAndroid Build Coastguard Worker 
123*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(dispatcher.RunUntilStalled(), Pending());
124*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(read_task.poll_count, 1);
125*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(read_task.read_count, 0);
126*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(read_task.bytes_read_count, 0);
127*61c4878aSAndroid Build Coastguard Worker }
128*61c4878aSAndroid Build Coastguard Worker 
TEST(LoopbackByteChannel,LoopsData)129*61c4878aSAndroid Build Coastguard Worker TEST(LoopbackByteChannel, LoopsData) {
130*61c4878aSAndroid Build Coastguard Worker   SimpleAllocatorForTest alloc;
131*61c4878aSAndroid Build Coastguard Worker   LoopbackByteChannel channel(alloc);
132*61c4878aSAndroid Build Coastguard Worker   ReaderTask<ReliableByteReader> read_task(channel.channel());
133*61c4878aSAndroid Build Coastguard Worker 
134*61c4878aSAndroid Build Coastguard Worker   Dispatcher dispatcher;
135*61c4878aSAndroid Build Coastguard Worker   dispatcher.Post(read_task);
136*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(dispatcher.RunUntilStalled(), Pending());
137*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(read_task.poll_count, 1);
138*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(read_task.read_count, 0);
139*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(read_task.bytes_read_count, 0);
140*61c4878aSAndroid Build Coastguard Worker 
141*61c4878aSAndroid Build Coastguard Worker   PW_TEST_EXPECT_OK(channel.StageWrite(alloc.BufWith({1_b, 2_b, 3_b})));
142*61c4878aSAndroid Build Coastguard Worker 
143*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(dispatcher.RunUntilStalled(), Pending());
144*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(read_task.poll_count, 2);
145*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(read_task.read_count, 1);
146*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(read_task.bytes_read_count, 3);
147*61c4878aSAndroid Build Coastguard Worker }
148*61c4878aSAndroid Build Coastguard Worker 
149*61c4878aSAndroid Build Coastguard Worker }  // namespace
150