blob: 0c1bb46302c22dec3a79f36b13c6b79fb4fcd22f [file] [log] [blame]
Artem Titovd3666b22019-02-11 14:40:17 +01001/*
2 * Copyright 2019 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
Jonas Olssona4d87372019-07-05 19:08:33 +020011#include "test/network/cross_traffic.h"
12
Artem Titovd3666b22019-02-11 14:40:17 +010013#include <atomic>
14#include <memory>
15#include <utility>
16#include <vector>
17
18#include "absl/memory/memory.h"
Artem Titovd2dd7322021-01-21 17:28:17 +010019#include "absl/types/optional.h"
Artem Titovcbe6e8a2020-09-22 15:45:00 +020020#include "api/test/network_emulation_manager.h"
Artem Titovd3666b22019-02-11 14:40:17 +010021#include "api/test/simulated_network.h"
22#include "call/simulated_network.h"
23#include "rtc_base/event.h"
24#include "rtc_base/logging.h"
Artem Titov1e023392020-01-23 15:46:45 +010025#include "rtc_base/network_constants.h"
Artem Titovd3666b22019-02-11 14:40:17 +010026#include "test/gmock.h"
27#include "test/gtest.h"
Sebastian Janssondcc910a2019-11-12 16:36:34 +010028#include "test/network/network_emulation_manager.h"
Andrey Logvinf9ee0e02021-01-14 09:50:32 +000029#include "test/network/traffic_route.h"
Sebastian Janssondcc910a2019-11-12 16:36:34 +010030#include "test/time_controller/simulated_time_controller.h"
Artem Titovd3666b22019-02-11 14:40:17 +010031
32namespace webrtc {
33namespace test {
34namespace {
35
Niels Möller7536bc52019-10-04 13:54:39 +020036constexpr uint32_t kTestIpAddress = 0xC0A80011; // 192.168.0.17
37
Sebastian Jansson4124dab2019-04-01 14:33:53 +020038class CountingReceiver : public EmulatedNetworkReceiverInterface {
Artem Titovd3666b22019-02-11 14:40:17 +010039 public:
Sebastian Jansson4124dab2019-04-01 14:33:53 +020040 void OnPacketReceived(EmulatedIpPacket packet) override {
41 packets_count_++;
42 total_packets_size_ += packet.size();
Artem Titovd3666b22019-02-11 14:40:17 +010043 }
44
Artem Titovd3666b22019-02-11 14:40:17 +010045 std::atomic<int> packets_count_{0};
46 std::atomic<uint64_t> total_packets_size_{0};
47};
Sebastian Jansson4124dab2019-04-01 14:33:53 +020048struct TrafficCounterFixture {
49 SimulatedClock clock{0};
50 CountingReceiver counter;
Artem Titovff393122019-04-05 11:19:52 +020051 TaskQueueForTest task_queue_;
Artem Titov3d37e062021-02-19 20:26:32 +010052 EmulatedEndpointImpl endpoint{EmulatedEndpointImpl::Options{
53 /*id=*/1,
54 rtc::IPAddress(kTestIpAddress),
55 EmulatedEndpointConfig(),
56 },
57 /*is_enabled=*/true, &task_queue_, &clock};
Sebastian Jansson4124dab2019-04-01 14:33:53 +020058};
Artem Titovd3666b22019-02-11 14:40:17 +010059
60} // namespace
61
62TEST(CrossTrafficTest, TriggerPacketBurst) {
Sebastian Jansson4124dab2019-04-01 14:33:53 +020063 TrafficCounterFixture fixture;
Andrey Logvinf9ee0e02021-01-14 09:50:32 +000064 CrossTrafficRouteImpl traffic(&fixture.clock, &fixture.counter,
65 &fixture.endpoint);
Sebastian Jansson4124dab2019-04-01 14:33:53 +020066 traffic.TriggerPacketBurst(100, 1000);
Artem Titovd3666b22019-02-11 14:40:17 +010067
Sebastian Jansson4124dab2019-04-01 14:33:53 +020068 EXPECT_EQ(fixture.counter.packets_count_, 100);
69 EXPECT_EQ(fixture.counter.total_packets_size_, 100 * 1000ul);
Artem Titovd3666b22019-02-11 14:40:17 +010070}
71
72TEST(CrossTrafficTest, PulsedPeaksCrossTraffic) {
Sebastian Jansson4124dab2019-04-01 14:33:53 +020073 TrafficCounterFixture fixture;
Andrey Logvinf9ee0e02021-01-14 09:50:32 +000074 CrossTrafficRouteImpl traffic(&fixture.clock, &fixture.counter,
75 &fixture.endpoint);
Artem Titovd3666b22019-02-11 14:40:17 +010076
77 PulsedPeaksConfig config;
Danil Chapovalovcad3e0e2020-02-17 18:46:07 +010078 config.peak_rate = DataRate::KilobitsPerSec(1000);
79 config.min_packet_size = DataSize::Bytes(1);
Danil Chapovalov0c626af2020-02-10 11:16:00 +010080 config.min_packet_interval = TimeDelta::Millis(25);
81 config.send_duration = TimeDelta::Millis(500);
82 config.hold_duration = TimeDelta::Millis(250);
Sebastian Jansson4124dab2019-04-01 14:33:53 +020083 PulsedPeaksCrossTraffic pulsed_peaks(config, &traffic);
Danil Chapovalov0c626af2020-02-10 11:16:00 +010084 const auto kRunTime = TimeDelta::Seconds(1);
Sebastian Jansson4124dab2019-04-01 14:33:53 +020085 while (fixture.clock.TimeInMilliseconds() < kRunTime.ms()) {
Danil Chapovalov0c626af2020-02-10 11:16:00 +010086 pulsed_peaks.Process(Timestamp::Millis(fixture.clock.TimeInMilliseconds()));
Sebastian Jansson4124dab2019-04-01 14:33:53 +020087 fixture.clock.AdvanceTimeMilliseconds(1);
88 }
Artem Titovd3666b22019-02-11 14:40:17 +010089
Harald Alvestrand97597c02021-11-04 12:01:23 +000090 RTC_LOG(LS_INFO) << fixture.counter.packets_count_ << " packets; "
91 << fixture.counter.total_packets_size_ << " bytes";
Artem Titovd3666b22019-02-11 14:40:17 +010092 // Using 50% duty cycle.
93 const auto kExpectedDataSent = kRunTime * config.peak_rate * 0.5;
Sebastian Jansson4124dab2019-04-01 14:33:53 +020094 EXPECT_NEAR(fixture.counter.total_packets_size_, kExpectedDataSent.bytes(),
Artem Titovd3666b22019-02-11 14:40:17 +010095 kExpectedDataSent.bytes() * 0.1);
96}
97
98TEST(CrossTrafficTest, RandomWalkCrossTraffic) {
Sebastian Jansson4124dab2019-04-01 14:33:53 +020099 TrafficCounterFixture fixture;
Andrey Logvinf9ee0e02021-01-14 09:50:32 +0000100 CrossTrafficRouteImpl traffic(&fixture.clock, &fixture.counter,
101 &fixture.endpoint);
Artem Titovd3666b22019-02-11 14:40:17 +0100102
103 RandomWalkConfig config;
Danil Chapovalovcad3e0e2020-02-17 18:46:07 +0100104 config.peak_rate = DataRate::KilobitsPerSec(1000);
105 config.min_packet_size = DataSize::Bytes(1);
Danil Chapovalov0c626af2020-02-10 11:16:00 +0100106 config.min_packet_interval = TimeDelta::Millis(25);
107 config.update_interval = TimeDelta::Millis(500);
Artem Titovd3666b22019-02-11 14:40:17 +0100108 config.variance = 0.0;
109 config.bias = 1.0;
Sebastian Jansson4124dab2019-04-01 14:33:53 +0200110
111 RandomWalkCrossTraffic random_walk(config, &traffic);
Danil Chapovalov0c626af2020-02-10 11:16:00 +0100112 const auto kRunTime = TimeDelta::Seconds(1);
Sebastian Jansson4124dab2019-04-01 14:33:53 +0200113 while (fixture.clock.TimeInMilliseconds() < kRunTime.ms()) {
Danil Chapovalov0c626af2020-02-10 11:16:00 +0100114 random_walk.Process(Timestamp::Millis(fixture.clock.TimeInMilliseconds()));
Sebastian Jansson4124dab2019-04-01 14:33:53 +0200115 fixture.clock.AdvanceTimeMilliseconds(1);
116 }
Artem Titovd3666b22019-02-11 14:40:17 +0100117
Harald Alvestrand97597c02021-11-04 12:01:23 +0000118 RTC_LOG(LS_INFO) << fixture.counter.packets_count_ << " packets; "
119 << fixture.counter.total_packets_size_ << " bytes";
Artem Titovd3666b22019-02-11 14:40:17 +0100120 // Sending at peak rate since bias = 1.
121 const auto kExpectedDataSent = kRunTime * config.peak_rate;
Sebastian Jansson4124dab2019-04-01 14:33:53 +0200122 EXPECT_NEAR(fixture.counter.total_packets_size_, kExpectedDataSent.bytes(),
Artem Titovd3666b22019-02-11 14:40:17 +0100123 kExpectedDataSent.bytes() * 0.1);
124}
125
Sebastian Janssondcc910a2019-11-12 16:36:34 +0100126TEST(TcpMessageRouteTest, DeliveredOnLossyNetwork) {
Sebastian Jansson6ce033a2020-01-22 10:12:56 +0100127 NetworkEmulationManagerImpl net(TimeMode::kSimulated);
Sebastian Janssondcc910a2019-11-12 16:36:34 +0100128 BuiltInNetworkBehaviorConfig send;
129 // 800 kbps means that the 100 kB message would be delivered in ca 1 second
130 // under ideal conditions and no overhead.
131 send.link_capacity_kbps = 100 * 8;
132 send.loss_percent = 50;
133 send.queue_delay_ms = 100;
134 send.delay_standard_deviation_ms = 20;
135 send.allow_reordering = true;
136 auto ret = send;
137 ret.loss_percent = 10;
138
Sebastian Jansson50f86862019-11-13 14:10:07 +0100139 auto* tcp_route =
140 net.CreateTcpRoute(net.CreateRoute({net.CreateEmulatedNode(send)}),
141 net.CreateRoute({net.CreateEmulatedNode(ret)}));
Sebastian Janssondcc910a2019-11-12 16:36:34 +0100142 int deliver_count = 0;
143 // 100 kB is more than what fits into a single packet.
144 constexpr size_t kMessageSize = 100000;
145
146 tcp_route->SendMessage(kMessageSize, [&] {
Sebastian Jansson6ce033a2020-01-22 10:12:56 +0100147 RTC_LOG(LS_INFO) << "Received at " << ToString(net.Now());
Sebastian Janssondcc910a2019-11-12 16:36:34 +0100148 deliver_count++;
149 });
150
151 // If there was no loss, we would have delivered the message in ca 1 second,
152 // with 50% it should take much longer.
Danil Chapovalov0c626af2020-02-10 11:16:00 +0100153 net.time_controller()->AdvanceTime(TimeDelta::Seconds(5));
Sebastian Janssondcc910a2019-11-12 16:36:34 +0100154 ASSERT_EQ(deliver_count, 0);
155 // But given enough time the messsage will be delivered, but only once.
Danil Chapovalov0c626af2020-02-10 11:16:00 +0100156 net.time_controller()->AdvanceTime(TimeDelta::Seconds(60));
Sebastian Janssondcc910a2019-11-12 16:36:34 +0100157 EXPECT_EQ(deliver_count, 1);
158}
159
Artem Titovd3666b22019-02-11 14:40:17 +0100160} // namespace test
161} // namespace webrtc