1 // Copyright 2023 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 #pragma once
16 #include <pw_async/fake_dispatcher_fixture.h>
17 
18 #include <memory>
19 
20 #include "pw_bluetooth_sapphire/internal/host/common/macros.h"
21 #include "pw_bluetooth_sapphire/internal/host/hci-spec/protocol.h"
22 #include "pw_bluetooth_sapphire/internal/host/l2cap/fake_channel.h"
23 #include "pw_bluetooth_sapphire/internal/host/l2cap/l2cap_defs.h"
24 
25 namespace bt::l2cap::testing {
26 
27 // Provides a common GTest harness base class for protocols tests that operate
28 // over a L2CAP channel. This harness provides:
29 //
30 //   * A simple way to initialize and access a FakeChannel.
31 //   * Basic command<->response expectation.
32 class FakeChannelTest : public pw::async::test::FakeDispatcherFixture {
33  public:
34   FakeChannelTest() = default;
35   ~FakeChannelTest() override = default;
36 
37  protected:
38   struct ChannelOptions {
39     explicit ChannelOptions(ChannelId id, uint16_t mtu = kDefaultMTU)
ChannelOptionsChannelOptions40         : ChannelOptions(id, id, mtu) {}
ChannelOptionsChannelOptions41     ChannelOptions(ChannelId id, ChannelId remote_id, uint16_t mtu)
42         : id(id), remote_id(remote_id), mtu(mtu) {}
43 
44     ChannelId id;
45     ChannelId remote_id;
46     uint16_t mtu;
47     hci_spec::ConnectionHandle conn_handle = 0x0001;
48     bt::LinkType link_type = bt::LinkType::kLE;
49   };
50 
51   void SetUp() override;
52 
53   // Creates a new FakeChannel and returns it. A WeakPtr to the returned
54   // channel is stored internally so that the returned channel can be accessed
55   // by tests even if its ownership is passed outside of the test harness.
56   std::unique_ptr<FakeChannel> CreateFakeChannel(const ChannelOptions& options);
57 
58   // Runs the event loop and returns true if |expected| is received within a 10
59   // second period.
60   //
61   // Returns false if no such response is received or no FakeChannel has been
62   // initialized via CreateFakeChannel().
63   //
64   // NOTE: This overwrites the underlying FakeChannel's "send callback" by
65   // calling FakeChannel::SetSendCallback().
66   bool Expect(const ByteBuffer& expected);
67 
68   // Emulates the receipt of |packet| and returns true if a response that
69   // matches |expected_response| is sent back over the underlying FakeChannel.
70   // Returns false if no such response is received or no FakeChannel has been
71   // initialized via CreateFakeChannel().
72   //
73   // NOTE: This overwrites the underlying FakeChannel's "send callback" by
74   // calling FakeChannel::SetSendCallback().
75   bool ReceiveAndExpect(const ByteBuffer& packet,
76                         const ByteBuffer& expected_response);
77 
fake_chan()78   FakeChannel::WeakPtr fake_chan() const { return fake_chan_; }
79 
set_fake_chan(FakeChannel::WeakPtr chan)80   void set_fake_chan(FakeChannel::WeakPtr chan) { fake_chan_ = chan; }
81 
82  private:
83   // Helper that sets a reception expectation callback with |expected| then
84   // sends |packet| if it is not std::nullopt, returning whether |expected| was
85   // received when the test loop run until idle.
86   bool ExpectAfterMaybeReceiving(std::optional<BufferView> packet,
87                                  const ByteBuffer& expected);
88 
89   FakeChannel::WeakPtr fake_chan_;
90 
91   BT_DISALLOW_COPY_AND_ASSIGN_ALLOW_MOVE(FakeChannelTest);
92 };
93 
94 }  // namespace bt::l2cap::testing
95