xref: /aosp_15_r20/external/webrtc/net/dcsctp/socket/mock_dcsctp_socket_callbacks.h (revision d9f758449e529ab9291ac668be2861e7a55c2422)
1 /*
2  *  Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
3  *
4  *  Use of this source code is governed by a BSD-style license
5  *  that can be found in the LICENSE file in the root of the source
6  *  tree. An additional intellectual property rights grant can be found
7  *  in the file PATENTS.  All contributing project authors may
8  *  be found in the AUTHORS file in the root of the source tree.
9  */
10 #ifndef NET_DCSCTP_SOCKET_MOCK_DCSCTP_SOCKET_CALLBACKS_H_
11 #define NET_DCSCTP_SOCKET_MOCK_DCSCTP_SOCKET_CALLBACKS_H_
12 
13 #include <cstdint>
14 #include <deque>
15 #include <memory>
16 #include <string>
17 #include <utility>
18 #include <vector>
19 
20 #include "absl/strings/string_view.h"
21 #include "absl/types/optional.h"
22 #include "api/array_view.h"
23 #include "api/task_queue/task_queue_base.h"
24 #include "net/dcsctp/public/dcsctp_message.h"
25 #include "net/dcsctp/public/dcsctp_socket.h"
26 #include "net/dcsctp/public/timeout.h"
27 #include "net/dcsctp/public/types.h"
28 #include "net/dcsctp/timer/fake_timeout.h"
29 #include "rtc_base/logging.h"
30 #include "rtc_base/random.h"
31 #include "test/gmock.h"
32 
33 namespace dcsctp {
34 
35 namespace internal {
36 // It can be argued if a mocked random number generator should be deterministic
37 // or if it should be have as a "real" random number generator. In this
38 // implementation, each instantiation of `MockDcSctpSocketCallbacks` will have
39 // their `GetRandomInt` return different sequences, but each instantiation will
40 // always generate the same sequence of random numbers. This to make it easier
41 // to compare logs from tests, but still to let e.g. two different sockets (used
42 // in the same test) get different random numbers, so that they don't start e.g.
43 // on the same sequence number. While that isn't an issue in the protocol, it
44 // just makes debugging harder as the two sockets would look exactly the same.
45 //
46 // In a real implementation of `DcSctpSocketCallbacks` the random number
47 // generator backing `GetRandomInt` should be seeded externally and correctly.
GetUniqueSeed()48 inline int GetUniqueSeed() {
49   static int seed = 0;
50   return ++seed;
51 }
52 }  // namespace internal
53 
54 class MockDcSctpSocketCallbacks : public DcSctpSocketCallbacks {
55  public:
56   explicit MockDcSctpSocketCallbacks(absl::string_view name = "")
57       : log_prefix_(name.empty() ? "" : std::string(name) + ": "),
58         random_(internal::GetUniqueSeed()),
59         timeout_manager_([this]() { return now_; }) {
60     ON_CALL(*this, SendPacketWithStatus)
61         .WillByDefault([this](rtc::ArrayView<const uint8_t> data) {
62           sent_packets_.emplace_back(
63               std::vector<uint8_t>(data.begin(), data.end()));
64           return SendPacketStatus::kSuccess;
65         });
66     ON_CALL(*this, OnMessageReceived)
67         .WillByDefault([this](DcSctpMessage message) {
68           received_messages_.emplace_back(std::move(message));
69         });
70 
71     ON_CALL(*this, OnError)
72         .WillByDefault([this](ErrorKind error, absl::string_view message) {
73           RTC_LOG(LS_WARNING)
74               << log_prefix_ << "Socket error: " << ToString(error) << "; "
75               << message;
76         });
77     ON_CALL(*this, OnAborted)
78         .WillByDefault([this](ErrorKind error, absl::string_view message) {
79           RTC_LOG(LS_WARNING)
80               << log_prefix_ << "Socket abort: " << ToString(error) << "; "
81               << message;
82         });
83     ON_CALL(*this, TimeMillis).WillByDefault([this]() { return now_; });
84   }
85 
86   MOCK_METHOD(SendPacketStatus,
87               SendPacketWithStatus,
88               (rtc::ArrayView<const uint8_t> data),
89               (override));
90 
CreateTimeout(webrtc::TaskQueueBase::DelayPrecision precision)91   std::unique_ptr<Timeout> CreateTimeout(
92       webrtc::TaskQueueBase::DelayPrecision precision) override {
93     // The fake timeout manager does not implement |precision|.
94     return timeout_manager_.CreateTimeout();
95   }
96 
97   MOCK_METHOD(TimeMs, TimeMillis, (), (override));
GetRandomInt(uint32_t low,uint32_t high)98   uint32_t GetRandomInt(uint32_t low, uint32_t high) override {
99     return random_.Rand(low, high);
100   }
101 
102   MOCK_METHOD(void, OnMessageReceived, (DcSctpMessage message), (override));
103   MOCK_METHOD(void,
104               OnError,
105               (ErrorKind error, absl::string_view message),
106               (override));
107   MOCK_METHOD(void,
108               OnAborted,
109               (ErrorKind error, absl::string_view message),
110               (override));
111   MOCK_METHOD(void, OnConnected, (), (override));
112   MOCK_METHOD(void, OnClosed, (), (override));
113   MOCK_METHOD(void, OnConnectionRestarted, (), (override));
114   MOCK_METHOD(void,
115               OnStreamsResetFailed,
116               (rtc::ArrayView<const StreamID> outgoing_streams,
117                absl::string_view reason),
118               (override));
119   MOCK_METHOD(void,
120               OnStreamsResetPerformed,
121               (rtc::ArrayView<const StreamID> outgoing_streams),
122               (override));
123   MOCK_METHOD(void,
124               OnIncomingStreamsReset,
125               (rtc::ArrayView<const StreamID> incoming_streams),
126               (override));
127   MOCK_METHOD(void, OnBufferedAmountLow, (StreamID stream_id), (override));
128   MOCK_METHOD(void, OnTotalBufferedAmountLow, (), (override));
129   MOCK_METHOD(void,
130               OnLifecycleMessageExpired,
131               (LifecycleId lifecycle_id, bool maybe_delivered),
132               (override));
133   MOCK_METHOD(void,
134               OnLifecycleMessageFullySent,
135               (LifecycleId lifecycle_id),
136               (override));
137   MOCK_METHOD(void,
138               OnLifecycleMessageDelivered,
139               (LifecycleId lifecycle_id),
140               (override));
141   MOCK_METHOD(void, OnLifecycleEnd, (LifecycleId lifecycle_id), (override));
142 
HasPacket()143   bool HasPacket() const { return !sent_packets_.empty(); }
144 
ConsumeSentPacket()145   std::vector<uint8_t> ConsumeSentPacket() {
146     if (sent_packets_.empty()) {
147       return {};
148     }
149     std::vector<uint8_t> ret = std::move(sent_packets_.front());
150     sent_packets_.pop_front();
151     return ret;
152   }
ConsumeReceivedMessage()153   absl::optional<DcSctpMessage> ConsumeReceivedMessage() {
154     if (received_messages_.empty()) {
155       return absl::nullopt;
156     }
157     DcSctpMessage ret = std::move(received_messages_.front());
158     received_messages_.pop_front();
159     return ret;
160   }
161 
AdvanceTime(DurationMs duration_ms)162   void AdvanceTime(DurationMs duration_ms) { now_ = now_ + duration_ms; }
SetTime(TimeMs now)163   void SetTime(TimeMs now) { now_ = now; }
164 
GetNextExpiredTimeout()165   absl::optional<TimeoutID> GetNextExpiredTimeout() {
166     return timeout_manager_.GetNextExpiredTimeout();
167   }
168 
169  private:
170   const std::string log_prefix_;
171   TimeMs now_ = TimeMs(0);
172   webrtc::Random random_;
173   FakeTimeoutManager timeout_manager_;
174   std::deque<std::vector<uint8_t>> sent_packets_;
175   std::deque<DcSctpMessage> received_messages_;
176 };
177 }  // namespace dcsctp
178 
179 #endif  // NET_DCSCTP_SOCKET_MOCK_DCSCTP_SOCKET_CALLBACKS_H_
180