blob: 94a2dffd1eedc8da10fb5bf66ff12f2e87bb79fa [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"
19#include "api/test/simulated_network.h"
20#include "call/simulated_network.h"
21#include "rtc_base/event.h"
22#include "rtc_base/logging.h"
23#include "test/gmock.h"
24#include "test/gtest.h"
Sebastian Janssondcc910a2019-11-12 16:36:34 +010025#include "test/network/network_emulation_manager.h"
26#include "test/time_controller/simulated_time_controller.h"
Artem Titovd3666b22019-02-11 14:40:17 +010027
28namespace webrtc {
29namespace test {
30namespace {
31
Niels Möller7536bc52019-10-04 13:54:39 +020032constexpr uint32_t kTestIpAddress = 0xC0A80011; // 192.168.0.17
33
Sebastian Jansson4124dab2019-04-01 14:33:53 +020034class CountingReceiver : public EmulatedNetworkReceiverInterface {
Artem Titovd3666b22019-02-11 14:40:17 +010035 public:
Sebastian Jansson4124dab2019-04-01 14:33:53 +020036 void OnPacketReceived(EmulatedIpPacket packet) override {
37 packets_count_++;
38 total_packets_size_ += packet.size();
Artem Titovd3666b22019-02-11 14:40:17 +010039 }
40
Artem Titovd3666b22019-02-11 14:40:17 +010041 std::atomic<int> packets_count_{0};
42 std::atomic<uint64_t> total_packets_size_{0};
43};
Sebastian Jansson4124dab2019-04-01 14:33:53 +020044struct TrafficCounterFixture {
45 SimulatedClock clock{0};
46 CountingReceiver counter;
Artem Titovff393122019-04-05 11:19:52 +020047 TaskQueueForTest task_queue_;
Niels Möller7536bc52019-10-04 13:54:39 +020048 EmulatedEndpoint endpoint{/*id=*/1, rtc::IPAddress(kTestIpAddress),
49 /*is_enabled=*/true, &task_queue_, &clock};
Sebastian Jansson4124dab2019-04-01 14:33:53 +020050};
Artem Titovd3666b22019-02-11 14:40:17 +010051
52} // namespace
53
54TEST(CrossTrafficTest, TriggerPacketBurst) {
Sebastian Jansson4124dab2019-04-01 14:33:53 +020055 TrafficCounterFixture fixture;
56 TrafficRoute traffic(&fixture.clock, &fixture.counter, &fixture.endpoint);
57 traffic.TriggerPacketBurst(100, 1000);
Artem Titovd3666b22019-02-11 14:40:17 +010058
Sebastian Jansson4124dab2019-04-01 14:33:53 +020059 EXPECT_EQ(fixture.counter.packets_count_, 100);
60 EXPECT_EQ(fixture.counter.total_packets_size_, 100 * 1000ul);
Artem Titovd3666b22019-02-11 14:40:17 +010061}
62
63TEST(CrossTrafficTest, PulsedPeaksCrossTraffic) {
Sebastian Jansson4124dab2019-04-01 14:33:53 +020064 TrafficCounterFixture fixture;
65 TrafficRoute traffic(&fixture.clock, &fixture.counter, &fixture.endpoint);
Artem Titovd3666b22019-02-11 14:40:17 +010066
67 PulsedPeaksConfig config;
68 config.peak_rate = DataRate::kbps(1000);
69 config.min_packet_size = DataSize::bytes(1);
70 config.min_packet_interval = TimeDelta::ms(25);
71 config.send_duration = TimeDelta::ms(500);
72 config.hold_duration = TimeDelta::ms(250);
Sebastian Jansson4124dab2019-04-01 14:33:53 +020073 PulsedPeaksCrossTraffic pulsed_peaks(config, &traffic);
Artem Titovd3666b22019-02-11 14:40:17 +010074 const auto kRunTime = TimeDelta::seconds(1);
Sebastian Jansson4124dab2019-04-01 14:33:53 +020075 while (fixture.clock.TimeInMilliseconds() < kRunTime.ms()) {
76 pulsed_peaks.Process(Timestamp::ms(fixture.clock.TimeInMilliseconds()));
77 fixture.clock.AdvanceTimeMilliseconds(1);
78 }
Artem Titovd3666b22019-02-11 14:40:17 +010079
Sebastian Jansson4124dab2019-04-01 14:33:53 +020080 RTC_LOG(INFO) << fixture.counter.packets_count_ << " packets; "
81 << fixture.counter.total_packets_size_ << " bytes";
Artem Titovd3666b22019-02-11 14:40:17 +010082 // Using 50% duty cycle.
83 const auto kExpectedDataSent = kRunTime * config.peak_rate * 0.5;
Sebastian Jansson4124dab2019-04-01 14:33:53 +020084 EXPECT_NEAR(fixture.counter.total_packets_size_, kExpectedDataSent.bytes(),
Artem Titovd3666b22019-02-11 14:40:17 +010085 kExpectedDataSent.bytes() * 0.1);
86}
87
88TEST(CrossTrafficTest, RandomWalkCrossTraffic) {
Sebastian Jansson4124dab2019-04-01 14:33:53 +020089 TrafficCounterFixture fixture;
90 TrafficRoute traffic(&fixture.clock, &fixture.counter, &fixture.endpoint);
Artem Titovd3666b22019-02-11 14:40:17 +010091
92 RandomWalkConfig config;
93 config.peak_rate = DataRate::kbps(1000);
94 config.min_packet_size = DataSize::bytes(1);
95 config.min_packet_interval = TimeDelta::ms(25);
96 config.update_interval = TimeDelta::ms(500);
97 config.variance = 0.0;
98 config.bias = 1.0;
Sebastian Jansson4124dab2019-04-01 14:33:53 +020099
100 RandomWalkCrossTraffic random_walk(config, &traffic);
Artem Titovd3666b22019-02-11 14:40:17 +0100101 const auto kRunTime = TimeDelta::seconds(1);
Sebastian Jansson4124dab2019-04-01 14:33:53 +0200102 while (fixture.clock.TimeInMilliseconds() < kRunTime.ms()) {
103 random_walk.Process(Timestamp::ms(fixture.clock.TimeInMilliseconds()));
104 fixture.clock.AdvanceTimeMilliseconds(1);
105 }
Artem Titovd3666b22019-02-11 14:40:17 +0100106
Sebastian Jansson4124dab2019-04-01 14:33:53 +0200107 RTC_LOG(INFO) << fixture.counter.packets_count_ << " packets; "
108 << fixture.counter.total_packets_size_ << " bytes";
Artem Titovd3666b22019-02-11 14:40:17 +0100109 // Sending at peak rate since bias = 1.
110 const auto kExpectedDataSent = kRunTime * config.peak_rate;
Sebastian Jansson4124dab2019-04-01 14:33:53 +0200111 EXPECT_NEAR(fixture.counter.total_packets_size_, kExpectedDataSent.bytes(),
Artem Titovd3666b22019-02-11 14:40:17 +0100112 kExpectedDataSent.bytes() * 0.1);
113}
114
Sebastian Janssondcc910a2019-11-12 16:36:34 +0100115TEST(TcpMessageRouteTest, DeliveredOnLossyNetwork) {
116 GlobalSimulatedTimeController time(Timestamp::seconds(0));
117 NetworkEmulationManagerImpl net(&time);
118 BuiltInNetworkBehaviorConfig send;
119 // 800 kbps means that the 100 kB message would be delivered in ca 1 second
120 // under ideal conditions and no overhead.
121 send.link_capacity_kbps = 100 * 8;
122 send.loss_percent = 50;
123 send.queue_delay_ms = 100;
124 send.delay_standard_deviation_ms = 20;
125 send.allow_reordering = true;
126 auto ret = send;
127 ret.loss_percent = 10;
128
Sebastian Jansson50f86862019-11-13 14:10:07 +0100129 auto* tcp_route =
130 net.CreateTcpRoute(net.CreateRoute({net.CreateEmulatedNode(send)}),
131 net.CreateRoute({net.CreateEmulatedNode(ret)}));
Sebastian Janssondcc910a2019-11-12 16:36:34 +0100132 int deliver_count = 0;
133 // 100 kB is more than what fits into a single packet.
134 constexpr size_t kMessageSize = 100000;
135
136 tcp_route->SendMessage(kMessageSize, [&] {
137 RTC_LOG(LS_INFO) << "Received at "
138 << ToString(time.GetClock()->CurrentTime());
139 deliver_count++;
140 });
141
142 // If there was no loss, we would have delivered the message in ca 1 second,
143 // with 50% it should take much longer.
144 time.Sleep(TimeDelta::seconds(5));
145 ASSERT_EQ(deliver_count, 0);
146 // But given enough time the messsage will be delivered, but only once.
147 time.Sleep(TimeDelta::seconds(60));
148 EXPECT_EQ(deliver_count, 1);
149}
150
Artem Titovd3666b22019-02-11 14:40:17 +0100151} // namespace test
152} // namespace webrtc