blob: 09a8bbb6c2b6e695af0026568c1a0455ad053eff [file] [log] [blame]
Victor Boivie82ccdd32021-05-30 19:25:031/*
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#include <cstdint>
11#include <deque>
12#include <memory>
Florent Castelli8037fc62024-08-29 13:00:4013#include <optional>
Victor Boivie82ccdd32021-05-30 19:25:0314#include <string>
15#include <utility>
16#include <vector>
17
18#include "absl/memory/memory.h"
19#include "absl/strings/string_view.h"
Victor Boivie82ccdd32021-05-30 19:25:0320#include "api/array_view.h"
Danil Chapovalov6ba4b632022-08-17 14:51:3621#include "api/task_queue/pending_task_safety_flag.h"
Henrik Boströmb951dc62022-01-26 17:38:1322#include "api/task_queue/task_queue_base.h"
Victor Boivie82ccdd32021-05-30 19:25:0323#include "api/test/create_network_emulation_manager.h"
24#include "api/test/network_emulation_manager.h"
Per K5566b912024-05-15 15:53:0225#include "api/units/data_rate.h"
Victor Boivie82ccdd32021-05-30 19:25:0326#include "api/units/time_delta.h"
Victor Boivie82ccdd32021-05-30 19:25:0327#include "net/dcsctp/public/dcsctp_options.h"
28#include "net/dcsctp/public/dcsctp_socket.h"
29#include "net/dcsctp/public/types.h"
30#include "net/dcsctp/socket/dcsctp_socket.h"
31#include "net/dcsctp/testing/testing_macros.h"
32#include "net/dcsctp/timer/task_queue_timeout.h"
33#include "rtc_base/copy_on_write_buffer.h"
34#include "rtc_base/gunit.h"
35#include "rtc_base/logging.h"
Dor Hen1921fa52024-08-13 12:43:4736#include "rtc_base/random.h"
Victor Boivie82ccdd32021-05-30 19:25:0337#include "rtc_base/socket_address.h"
38#include "rtc_base/strings/string_format.h"
Victor Boivie82ccdd32021-05-30 19:25:0339#include "rtc_base/time_utils.h"
40#include "test/gmock.h"
41
Victor Boivieec19d5e2021-10-28 12:45:2042#if !defined(WEBRTC_ANDROID) && defined(NDEBUG) && \
43 !defined(THREAD_SANITIZER) && !defined(MEMORY_SANITIZER)
Victor Boivie82ccdd32021-05-30 19:25:0344#define DCSCTP_NDEBUG_TEST(t) t
45#else
Victor Boivieec19d5e2021-10-28 12:45:2046// In debug mode, and when MSAN or TSAN sanitizers are enabled, these tests are
47// too expensive to run due to extensive consistency checks that iterate on all
48// outstanding chunks. Same with low-end Android devices, which have
49// difficulties with these tests.
Victor Boivie82ccdd32021-05-30 19:25:0350#define DCSCTP_NDEBUG_TEST(t) DISABLED_##t
51#endif
52
53namespace dcsctp {
54namespace {
55using ::testing::AllOf;
56using ::testing::Ge;
57using ::testing::Le;
58using ::testing::SizeIs;
Per K5566b912024-05-15 15:53:0259using ::webrtc::DataRate;
Victor Boivie82cbbcc2023-11-08 15:31:4460using ::webrtc::TimeDelta;
61using ::webrtc::Timestamp;
Victor Boivie82ccdd32021-05-30 19:25:0362
63constexpr StreamID kStreamId(1);
64constexpr PPID kPpid(53);
65constexpr size_t kSmallPayloadSize = 10;
66constexpr size_t kLargePayloadSize = 10000;
67constexpr size_t kHugePayloadSize = 262144;
68constexpr size_t kBufferedAmountLowThreshold = kLargePayloadSize * 2;
Danil Chapovalov6ba4b632022-08-17 14:51:3669constexpr webrtc::TimeDelta kPrintBandwidthDuration =
70 webrtc::TimeDelta::Seconds(1);
Victor Boivie82ccdd32021-05-30 19:25:0371constexpr webrtc::TimeDelta kBenchmarkRuntime(webrtc::TimeDelta::Seconds(10));
72constexpr webrtc::TimeDelta kAWhile(webrtc::TimeDelta::Seconds(1));
73
74inline int GetUniqueSeed() {
75 static int seed = 0;
76 return ++seed;
77}
78
79DcSctpOptions MakeOptionsForTest() {
80 DcSctpOptions options;
81
82 // Throughput numbers are affected by the MTU. Ensure it's constant.
83 options.mtu = 1200;
84
85 // By disabling the heartbeat interval, there will no timers at all running
86 // when the socket is idle, which makes it easy to just continue the test
87 // until there are no more scheduled tasks. Note that it _will_ run for longer
88 // than necessary as timers aren't cancelled when they are stopped (as that's
89 // not supported), but it's still simulated time and passes quickly.
90 options.heartbeat_interval = DurationMs(0);
91 return options;
92}
93
94// When doing throughput tests, knowing what each actor should do.
95enum class ActorMode {
96 kAtRest,
97 kThroughputSender,
98 kThroughputReceiver,
99 kLimitedRetransmissionSender,
100};
101
Victor Boivie82ccdd32021-05-30 19:25:03102// An abstraction around EmulatedEndpoint, representing a bound socket that
103// will send its packet to a given destination.
104class BoundSocket : public webrtc::EmulatedNetworkReceiverInterface {
105 public:
106 void Bind(webrtc::EmulatedEndpoint* endpoint) {
107 endpoint_ = endpoint;
108 uint16_t port = endpoint->BindReceiver(0, this).value();
109 source_address_ =
Evan Shrubsole64b076f42025-03-12 12:56:28110 webrtc::SocketAddress(endpoint_->GetPeerLocalAddress(), port);
Victor Boivie82ccdd32021-05-30 19:25:03111 }
112
113 void SetDestination(const BoundSocket& socket) {
114 dest_address_ = socket.source_address_;
115 }
116
Evan Shrubsole8b7780b2025-04-15 14:55:02117 void SetReceiver(std::function<void(webrtc::CopyOnWriteBuffer)> receiver) {
Victor Boivie82ccdd32021-05-30 19:25:03118 receiver_ = std::move(receiver);
119 }
120
Evan Shrubsole8b7780b2025-04-15 14:55:02121 void SendPacket(webrtc::ArrayView<const uint8_t> data) {
Victor Boivie82ccdd32021-05-30 19:25:03122 endpoint_->SendPacket(source_address_, dest_address_,
Evan Shrubsole8b7780b2025-04-15 14:55:02123 webrtc::CopyOnWriteBuffer(data.data(), data.size()));
Victor Boivie82ccdd32021-05-30 19:25:03124 }
125
126 private:
127 // Implementation of `webrtc::EmulatedNetworkReceiverInterface`.
128 void OnPacketReceived(webrtc::EmulatedIpPacket packet) override {
129 receiver_(std::move(packet.data));
130 }
131
Evan Shrubsole8b7780b2025-04-15 14:55:02132 std::function<void(webrtc::CopyOnWriteBuffer)> receiver_;
Victor Boivie82ccdd32021-05-30 19:25:03133 webrtc::EmulatedEndpoint* endpoint_ = nullptr;
Evan Shrubsole64b076f42025-03-12 12:56:28134 webrtc::SocketAddress source_address_;
135 webrtc::SocketAddress dest_address_;
Victor Boivie82ccdd32021-05-30 19:25:03136};
137
138// Sends at a constant rate but with random packet sizes.
Danil Chapovalov6ba4b632022-08-17 14:51:36139class SctpActor : public DcSctpSocketCallbacks {
Victor Boivie82ccdd32021-05-30 19:25:03140 public:
141 SctpActor(absl::string_view name,
142 BoundSocket& emulated_socket,
143 const DcSctpOptions& sctp_options)
144 : log_prefix_(std::string(name) + ": "),
Evan Shrubsole6a9a1ae2025-03-21 12:54:15145 thread_(webrtc::Thread::Current()),
Victor Boivie82ccdd32021-05-30 19:25:03146 emulated_socket_(emulated_socket),
147 timeout_factory_(
148 *thread_,
Victor Boivie82cbbcc2023-11-08 15:31:44149 [this]() { return TimeMs(Now().ms()); },
Victor Boivie82ccdd32021-05-30 19:25:03150 [this](dcsctp::TimeoutID timeout_id) {
151 sctp_socket_.HandleTimeout(timeout_id);
152 }),
153 random_(GetUniqueSeed()),
154 sctp_socket_(name, *this, nullptr, sctp_options),
Victor Boivie82cbbcc2023-11-08 15:31:44155 last_bandwidth_printout_(Now()) {
Evan Shrubsole8b7780b2025-04-15 14:55:02156 emulated_socket.SetReceiver([this](webrtc::CopyOnWriteBuffer buf) {
Victor Boivie82ccdd32021-05-30 19:25:03157 // The receiver will be executed on the NetworkEmulation task queue, but
158 // the dcSCTP socket is owned by `thread_` and is not thread-safe.
Danil Chapovalovecf88f42022-07-06 09:05:30159 thread_->PostTask([this, buf] { this->sctp_socket_.ReceivePacket(buf); });
Victor Boivie82ccdd32021-05-30 19:25:03160 });
161 }
162
Danil Chapovalov6ba4b632022-08-17 14:51:36163 void PrintBandwidth() {
Victor Boivie82cbbcc2023-11-08 15:31:44164 Timestamp now = Now();
165 TimeDelta duration = now - last_bandwidth_printout_;
Victor Boivie82ccdd32021-05-30 19:25:03166
Danil Chapovalov6ba4b632022-08-17 14:51:36167 double bitrate_mbps =
Victor Boivie82cbbcc2023-11-08 15:31:44168 static_cast<double>(received_bytes_ * 8) / duration.ms() / 1000;
Danil Chapovalov6ba4b632022-08-17 14:51:36169 RTC_LOG(LS_INFO) << log_prefix()
Evan Shrubsole418a8c22025-02-18 13:10:10170 << webrtc::StringFormat("Received %0.2f Mbps",
171 bitrate_mbps);
Victor Boivie82ccdd32021-05-30 19:25:03172
Danil Chapovalov6ba4b632022-08-17 14:51:36173 received_bitrate_mbps_.push_back(bitrate_mbps);
174 received_bytes_ = 0;
175 last_bandwidth_printout_ = now;
176 // Print again in a second.
177 if (mode_ == ActorMode::kThroughputReceiver) {
178 thread_->PostDelayedTask(
179 SafeTask(safety_.flag(), [this] { PrintBandwidth(); }),
180 kPrintBandwidthDuration);
Victor Boivie82ccdd32021-05-30 19:25:03181 }
182 }
183
Evan Shrubsole8b7780b2025-04-15 14:55:02184 void SendPacket(webrtc::ArrayView<const uint8_t> data) override {
Victor Boivie82ccdd32021-05-30 19:25:03185 emulated_socket_.SendPacket(data);
186 }
187
Henrik Boströmb951dc62022-01-26 17:38:13188 std::unique_ptr<Timeout> CreateTimeout(
189 webrtc::TaskQueueBase::DelayPrecision precision) override {
190 return timeout_factory_.CreateTimeout(precision);
Victor Boivie82ccdd32021-05-30 19:25:03191 }
192
Evan Shrubsole652c7712025-03-21 09:47:35193 Timestamp Now() override { return Timestamp::Millis(webrtc::TimeMillis()); }
Victor Boivie82ccdd32021-05-30 19:25:03194
195 uint32_t GetRandomInt(uint32_t low, uint32_t high) override {
196 return random_.Rand(low, high);
197 }
198
199 void OnMessageReceived(DcSctpMessage message) override {
200 received_bytes_ += message.payload().size();
201 last_received_message_ = std::move(message);
202 }
203
204 void OnError(ErrorKind error, absl::string_view message) override {
205 RTC_LOG(LS_WARNING) << log_prefix() << "Socket error: " << ToString(error)
206 << "; " << message;
207 }
208
209 void OnAborted(ErrorKind error, absl::string_view message) override {
210 RTC_LOG(LS_ERROR) << log_prefix() << "Socket abort: " << ToString(error)
211 << "; " << message;
212 }
213
214 void OnConnected() override {}
215
216 void OnClosed() override {}
217
218 void OnConnectionRestarted() override {}
219
Dor Henda7b7ca2024-11-20 10:15:38220 void OnStreamsResetFailed(
Evan Shrubsole8b7780b2025-04-15 14:55:02221 webrtc::ArrayView<const StreamID> /* outgoing_streams */,
Dor Henda7b7ca2024-11-20 10:15:38222 absl::string_view /* reason */) override {}
Victor Boivie82ccdd32021-05-30 19:25:03223
224 void OnStreamsResetPerformed(
Evan Shrubsole8b7780b2025-04-15 14:55:02225 webrtc::ArrayView<const StreamID> /* outgoing_streams */) override {}
Victor Boivie82ccdd32021-05-30 19:25:03226
227 void OnIncomingStreamsReset(
Evan Shrubsole8b7780b2025-04-15 14:55:02228 webrtc::ArrayView<const StreamID> /* incoming_streams */) override {}
Victor Boivie82ccdd32021-05-30 19:25:03229
230 void NotifyOutgoingMessageBufferEmpty() override {}
231
Dor Henda7b7ca2024-11-20 10:15:38232 void OnBufferedAmountLow(StreamID /* stream_id */) override {
Victor Boivie82ccdd32021-05-30 19:25:03233 if (mode_ == ActorMode::kThroughputSender) {
234 std::vector<uint8_t> payload(kHugePayloadSize);
235 sctp_socket_.Send(DcSctpMessage(kStreamId, kPpid, std::move(payload)),
236 SendOptions());
237
238 } else if (mode_ == ActorMode::kLimitedRetransmissionSender) {
239 while (sctp_socket_.buffered_amount(kStreamId) <
240 kBufferedAmountLowThreshold * 2) {
241 SendOptions send_options;
242 send_options.max_retransmissions = 0;
243 sctp_socket_.Send(
244 DcSctpMessage(kStreamId, kPpid,
245 std::vector<uint8_t>(kLargePayloadSize)),
246 send_options);
247
Florent Castelli8037fc62024-08-29 13:00:40248 send_options.max_retransmissions = std::nullopt;
Victor Boivie82ccdd32021-05-30 19:25:03249 sctp_socket_.Send(
250 DcSctpMessage(kStreamId, kPpid,
251 std::vector<uint8_t>(kSmallPayloadSize)),
252 send_options);
253 }
254 }
255 }
256
Florent Castelli8037fc62024-08-29 13:00:40257 std::optional<DcSctpMessage> ConsumeReceivedMessage() {
Victor Boivie82ccdd32021-05-30 19:25:03258 if (!last_received_message_.has_value()) {
Florent Castelli8037fc62024-08-29 13:00:40259 return std::nullopt;
Victor Boivie82ccdd32021-05-30 19:25:03260 }
261 DcSctpMessage ret = *std::move(last_received_message_);
Florent Castelli8037fc62024-08-29 13:00:40262 last_received_message_ = std::nullopt;
Victor Boivie82ccdd32021-05-30 19:25:03263 return ret;
264 }
265
266 DcSctpSocket& sctp_socket() { return sctp_socket_; }
267
268 void SetActorMode(ActorMode mode) {
269 mode_ = mode;
270 if (mode_ == ActorMode::kThroughputSender) {
271 sctp_socket_.SetBufferedAmountLowThreshold(kStreamId,
272 kBufferedAmountLowThreshold);
273 std::vector<uint8_t> payload(kHugePayloadSize);
274 sctp_socket_.Send(DcSctpMessage(kStreamId, kPpid, std::move(payload)),
275 SendOptions());
276
277 } else if (mode_ == ActorMode::kLimitedRetransmissionSender) {
278 sctp_socket_.SetBufferedAmountLowThreshold(kStreamId,
279 kBufferedAmountLowThreshold);
280 std::vector<uint8_t> payload(kHugePayloadSize);
281 sctp_socket_.Send(DcSctpMessage(kStreamId, kPpid, std::move(payload)),
282 SendOptions());
283
284 } else if (mode == ActorMode::kThroughputReceiver) {
Danil Chapovalov6ba4b632022-08-17 14:51:36285 thread_->PostDelayedTask(
286 SafeTask(safety_.flag(), [this] { PrintBandwidth(); }),
287 kPrintBandwidthDuration);
Victor Boivie82ccdd32021-05-30 19:25:03288 }
289 }
290
291 // Returns the average bitrate, stripping the first `remove_first_n` that
292 // represent the time it took to ramp up the congestion control algorithm.
293 double avg_received_bitrate_mbps(size_t remove_first_n = 3) const {
294 std::vector<double> bitrates = received_bitrate_mbps_;
295 bitrates.erase(bitrates.begin(), bitrates.begin() + remove_first_n);
Victor Boivie82ccdd32021-05-30 19:25:03296
297 double sum = 0;
298 for (double bitrate : bitrates) {
299 sum += bitrate;
300 }
301
302 return sum / bitrates.size();
303 }
304
305 private:
306 std::string log_prefix() const {
Evan Shrubsole0ebd67f2025-02-19 10:06:32307 webrtc::StringBuilder sb;
Victor Boivie82ccdd32021-05-30 19:25:03308 sb << log_prefix_;
Evan Shrubsole652c7712025-03-21 09:47:35309 sb << webrtc::TimeMillis();
Victor Boivie82ccdd32021-05-30 19:25:03310 sb << ": ";
311 return sb.Release();
312 }
313
314 ActorMode mode_ = ActorMode::kAtRest;
315 const std::string log_prefix_;
Evan Shrubsole6a9a1ae2025-03-21 12:54:15316 webrtc::Thread* thread_;
Victor Boivie82ccdd32021-05-30 19:25:03317 BoundSocket& emulated_socket_;
318 TaskQueueTimeoutFactory timeout_factory_;
319 webrtc::Random random_;
320 DcSctpSocket sctp_socket_;
321 size_t received_bytes_ = 0;
Florent Castelli8037fc62024-08-29 13:00:40322 std::optional<DcSctpMessage> last_received_message_;
Victor Boivie82cbbcc2023-11-08 15:31:44323 Timestamp last_bandwidth_printout_;
Victor Boivie82ccdd32021-05-30 19:25:03324 // Per-second received bitrates, in Mbps
325 std::vector<double> received_bitrate_mbps_;
Danil Chapovalov6ba4b632022-08-17 14:51:36326 webrtc::ScopedTaskSafety safety_;
Victor Boivie82ccdd32021-05-30 19:25:03327};
328
329class DcSctpSocketNetworkTest : public testing::Test {
330 protected:
331 DcSctpSocketNetworkTest()
332 : options_(MakeOptionsForTest()),
333 emulation_(webrtc::CreateNetworkEmulationManager(
Sergey Sukhanov26a082c2024-05-08 11:38:00334 {.time_mode = webrtc::TimeMode::kSimulated})) {}
Victor Boivie82ccdd32021-05-30 19:25:03335
336 void MakeNetwork(const webrtc::BuiltInNetworkBehaviorConfig& config) {
337 webrtc::EmulatedEndpoint* endpoint_a =
338 emulation_->CreateEndpoint(webrtc::EmulatedEndpointConfig());
339 webrtc::EmulatedEndpoint* endpoint_z =
340 emulation_->CreateEndpoint(webrtc::EmulatedEndpointConfig());
341
342 webrtc::EmulatedNetworkNode* node1 = emulation_->CreateEmulatedNode(config);
343 webrtc::EmulatedNetworkNode* node2 = emulation_->CreateEmulatedNode(config);
344
345 emulation_->CreateRoute(endpoint_a, {node1}, endpoint_z);
346 emulation_->CreateRoute(endpoint_z, {node2}, endpoint_a);
347
348 emulated_socket_a_.Bind(endpoint_a);
349 emulated_socket_z_.Bind(endpoint_z);
350
351 emulated_socket_a_.SetDestination(emulated_socket_z_);
352 emulated_socket_z_.SetDestination(emulated_socket_a_);
353 }
354
355 void Sleep(webrtc::TimeDelta duration) {
356 // Sleep in one-millisecond increments, to let timers expire when expected.
357 for (int i = 0; i < duration.ms(); ++i) {
358 emulation_->time_controller()->AdvanceTime(webrtc::TimeDelta::Millis(1));
359 }
360 }
361
362 DcSctpOptions options_;
363 std::unique_ptr<webrtc::NetworkEmulationManager> emulation_;
364 BoundSocket emulated_socket_a_;
365 BoundSocket emulated_socket_z_;
366};
367
368TEST_F(DcSctpSocketNetworkTest, CanConnectAndShutdown) {
369 webrtc::BuiltInNetworkBehaviorConfig pipe_config;
370 MakeNetwork(pipe_config);
371
372 SctpActor sender("A", emulated_socket_a_, options_);
373 SctpActor receiver("Z", emulated_socket_z_, options_);
374 EXPECT_THAT(sender.sctp_socket().state(), SocketState::kClosed);
375
376 sender.sctp_socket().Connect();
377 Sleep(kAWhile);
378 EXPECT_THAT(sender.sctp_socket().state(), SocketState::kConnected);
379
380 sender.sctp_socket().Shutdown();
381 Sleep(kAWhile);
382 EXPECT_THAT(sender.sctp_socket().state(), SocketState::kClosed);
383}
384
385TEST_F(DcSctpSocketNetworkTest, CanSendLargeMessage) {
386 webrtc::BuiltInNetworkBehaviorConfig pipe_config;
387 pipe_config.queue_delay_ms = 30;
388 MakeNetwork(pipe_config);
389
390 SctpActor sender("A", emulated_socket_a_, options_);
391 SctpActor receiver("Z", emulated_socket_z_, options_);
392 sender.sctp_socket().Connect();
393
394 constexpr size_t kPayloadSize = 100 * 1024;
395
396 std::vector<uint8_t> payload(kPayloadSize);
397 sender.sctp_socket().Send(DcSctpMessage(kStreamId, kPpid, payload),
398 SendOptions());
399
400 Sleep(kAWhile);
401
402 ASSERT_HAS_VALUE_AND_ASSIGN(DcSctpMessage message,
403 receiver.ConsumeReceivedMessage());
404
405 EXPECT_THAT(message.payload(), SizeIs(kPayloadSize));
406
407 sender.sctp_socket().Shutdown();
408 Sleep(kAWhile);
409}
410
411TEST_F(DcSctpSocketNetworkTest, CanSendMessagesReliablyWithLowBandwidth) {
412 webrtc::BuiltInNetworkBehaviorConfig pipe_config;
413 pipe_config.queue_delay_ms = 30;
Per K5566b912024-05-15 15:53:02414 pipe_config.link_capacity = DataRate::KilobitsPerSec(1000);
Victor Boivie82ccdd32021-05-30 19:25:03415 MakeNetwork(pipe_config);
416
417 SctpActor sender("A", emulated_socket_a_, options_);
418 SctpActor receiver("Z", emulated_socket_z_, options_);
419 sender.sctp_socket().Connect();
420
421 sender.SetActorMode(ActorMode::kThroughputSender);
422 receiver.SetActorMode(ActorMode::kThroughputReceiver);
423
424 Sleep(kBenchmarkRuntime);
425 sender.SetActorMode(ActorMode::kAtRest);
426 receiver.SetActorMode(ActorMode::kAtRest);
427
428 Sleep(kAWhile);
429
430 sender.sctp_socket().Shutdown();
431
432 Sleep(kAWhile);
433
434 // Verify that the bitrates are in the range of 0.5-1.0 Mbps.
435 double bitrate = receiver.avg_received_bitrate_mbps();
436 EXPECT_THAT(bitrate, AllOf(Ge(0.5), Le(1.0)));
437}
438
439TEST_F(DcSctpSocketNetworkTest,
440 DCSCTP_NDEBUG_TEST(CanSendMessagesReliablyWithMediumBandwidth)) {
441 webrtc::BuiltInNetworkBehaviorConfig pipe_config;
442 pipe_config.queue_delay_ms = 30;
Per K5566b912024-05-15 15:53:02443 pipe_config.link_capacity = DataRate::KilobitsPerSec(18000);
Victor Boivie82ccdd32021-05-30 19:25:03444 MakeNetwork(pipe_config);
445
446 SctpActor sender("A", emulated_socket_a_, options_);
447 SctpActor receiver("Z", emulated_socket_z_, options_);
448 sender.sctp_socket().Connect();
449
450 sender.SetActorMode(ActorMode::kThroughputSender);
451 receiver.SetActorMode(ActorMode::kThroughputReceiver);
452
453 Sleep(kBenchmarkRuntime);
454 sender.SetActorMode(ActorMode::kAtRest);
455 receiver.SetActorMode(ActorMode::kAtRest);
456
457 Sleep(kAWhile);
458
459 sender.sctp_socket().Shutdown();
460
461 Sleep(kAWhile);
462
463 // Verify that the bitrates are in the range of 16-18 Mbps.
464 double bitrate = receiver.avg_received_bitrate_mbps();
465 EXPECT_THAT(bitrate, AllOf(Ge(16), Le(18)));
466}
467
468TEST_F(DcSctpSocketNetworkTest, CanSendMessagesReliablyWithMuchPacketLoss) {
469 webrtc::BuiltInNetworkBehaviorConfig config;
470 config.queue_delay_ms = 30;
471 config.loss_percent = 1;
472 MakeNetwork(config);
473
474 SctpActor sender("A", emulated_socket_a_, options_);
475 SctpActor receiver("Z", emulated_socket_z_, options_);
476 sender.sctp_socket().Connect();
477
478 sender.SetActorMode(ActorMode::kThroughputSender);
479 receiver.SetActorMode(ActorMode::kThroughputReceiver);
480
481 Sleep(kBenchmarkRuntime);
482 sender.SetActorMode(ActorMode::kAtRest);
483 receiver.SetActorMode(ActorMode::kAtRest);
484
485 Sleep(kAWhile);
486
487 sender.sctp_socket().Shutdown();
488
489 Sleep(kAWhile);
490
491 // TCP calculator gives: 1200 MTU, 60ms RTT and 1% packet loss -> 1.6Mbps.
492 // This test is doing slightly better (doesn't have any additional header
493 // overhead etc). Verify that the bitrates are in the range of 1.5-2.5 Mbps.
494 double bitrate = receiver.avg_received_bitrate_mbps();
495 EXPECT_THAT(bitrate, AllOf(Ge(1.5), Le(2.5)));
496}
497
498TEST_F(DcSctpSocketNetworkTest, DCSCTP_NDEBUG_TEST(HasHighBandwidth)) {
499 webrtc::BuiltInNetworkBehaviorConfig pipe_config;
500 pipe_config.queue_delay_ms = 30;
501 MakeNetwork(pipe_config);
502
503 SctpActor sender("A", emulated_socket_a_, options_);
504 SctpActor receiver("Z", emulated_socket_z_, options_);
505 sender.sctp_socket().Connect();
506
507 sender.SetActorMode(ActorMode::kThroughputSender);
508 receiver.SetActorMode(ActorMode::kThroughputReceiver);
509
510 Sleep(kBenchmarkRuntime);
511
512 sender.SetActorMode(ActorMode::kAtRest);
513 receiver.SetActorMode(ActorMode::kAtRest);
514 Sleep(kAWhile);
515
516 sender.sctp_socket().Shutdown();
517 Sleep(kAWhile);
518
519 // Verify that the bitrate is in the range of 540-640 Mbps
520 double bitrate = receiver.avg_received_bitrate_mbps();
Mirko Bonadei3b205da2022-08-09 08:24:17521 EXPECT_THAT(bitrate, AllOf(Ge(520), Le(640)));
Victor Boivie82ccdd32021-05-30 19:25:03522}
523} // namespace
524} // namespace dcsctp