• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #include "pw_bluetooth_sapphire/internal/host/l2cap/mock_channel_test.h"
16 
17 #include "pw_bluetooth_sapphire/internal/host/testing/gtest_helpers.h"
18 #include "pw_bluetooth_sapphire/internal/host/testing/test_helpers.h"
19 
20 namespace bt::l2cap::testing {
21 
Transaction(const ByteBuffer & expected,const std::vector<const ByteBuffer * > & replies,ExpectationMetadata meta)22 MockChannelTest::Transaction::Transaction(
23     const ByteBuffer& expected,
24     const std::vector<const ByteBuffer*>& replies,
25     ExpectationMetadata meta)
26     : expected_({DynamicByteBuffer(expected), meta}) {
27   for (const ByteBuffer* buffer : replies) {
28     replies_.push(DynamicByteBuffer(*buffer));
29   }
30 }
31 
Match(const ByteBuffer & packet)32 bool MockChannelTest::Transaction::Match(const ByteBuffer& packet) {
33   return ContainersEqual(expected_.data, packet);
34 }
35 
TearDown()36 void MockChannelTest::TearDown() {
37   while (!transactions_.empty()) {
38     Transaction& transaction = transactions_.front();
39     ExpectationMetadata meta = transaction.expected().meta;
40     ADD_FAILURE_AT(meta.file, meta.line)
41         << "Didn't receive expected outbound packet (" << meta.expectation
42         << ") {" << ByteContainerToString(transaction.expected().data) << "}";
43     transactions_.pop();
44   }
45 }
46 
QueueTransaction(const ByteBuffer & expected,const std::vector<const ByteBuffer * > & replies,ExpectationMetadata meta)47 void MockChannelTest::QueueTransaction(
48     const ByteBuffer& expected,
49     const std::vector<const ByteBuffer*>& replies,
50     ExpectationMetadata meta) {
51   transactions_.emplace(expected, replies, meta);
52 }
53 
CreateFakeChannel(const ChannelOptions & options)54 FakeChannel::WeakPtr MockChannelTest::CreateFakeChannel(
55     const ChannelOptions& options) {
56   fake_chan_ = std::make_unique<FakeChannel>(
57       options.id,
58       options.remote_id,
59       options.conn_handle,
60       options.link_type,
61       ChannelInfo::MakeBasicMode(options.mtu, options.mtu));
62   fake_chan_->SetSendCallback(
63       fit::bind_member<&MockChannelTest::OnPacketSent>(this));
64   return fake_chan_->AsWeakPtr();
65 }
66 
OnPacketSent(std::unique_ptr<ByteBuffer> packet)67 void MockChannelTest::OnPacketSent(std::unique_ptr<ByteBuffer> packet) {
68   if (packet_callback_) {
69     packet_callback_(*packet);
70   }
71 
72   ASSERT_FALSE(transactions_.empty()) << "Received unexpected packet: { "
73                                       << ByteContainerToString(*packet) << "}";
74 
75   Transaction expected = std::move(transactions_.front());
76   transactions_.pop();
77   if (!expected.Match(packet->view())) {
78     auto meta = expected.expected().meta;
79     GTEST_FAIL_AT(meta.file, meta.line)
80         << "Expected packet (" << meta.expectation << ")";
81   }
82 
83   while (!expected.replies().empty()) {
84     auto reply = std::move(expected.replies().front());
85     expected.replies().pop();
86     // Post tasks to simulate real inbound packets, which are asynchronous.
87     (void)heap_dispatcher().Post(
88         [this, reply = std::move(reply)](pw::async::Context /*ctx*/,
89                                          pw::Status status) {
90           if (status.ok()) {
91             fake_chan_->Receive(reply);
92           }
93         });
94   }
95 }
96 
97 }  // namespace bt::l2cap::testing
98