1 /*
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
11 #include "test/network/cross_traffic.h"
12
13 #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 "rtc_base/network_constants.h"
24 #include "test/gmock.h"
25 #include "test/gtest.h"
26 #include "test/network/network_emulation_manager.h"
27 #include "test/time_controller/simulated_time_controller.h"
28
29 namespace webrtc {
30 namespace test {
31 namespace {
32
33 constexpr uint32_t kTestIpAddress = 0xC0A80011; // 192.168.0.17
34
35 class CountingReceiver : public EmulatedNetworkReceiverInterface {
36 public:
OnPacketReceived(EmulatedIpPacket packet)37 void OnPacketReceived(EmulatedIpPacket packet) override {
38 packets_count_++;
39 total_packets_size_ += packet.size();
40 }
41
42 std::atomic<int> packets_count_{0};
43 std::atomic<uint64_t> total_packets_size_{0};
44 };
45 struct TrafficCounterFixture {
46 SimulatedClock clock{0};
47 CountingReceiver counter;
48 TaskQueueForTest task_queue_;
49 EmulatedEndpointImpl endpoint{/*id=*/1,
50 rtc::IPAddress(kTestIpAddress),
51 /*is_enabled=*/true,
52 /*type=*/rtc::AdapterType::ADAPTER_TYPE_UNKNOWN,
53 &task_queue_,
54 &clock};
55 };
56
57 } // namespace
58
TEST(CrossTrafficTest,TriggerPacketBurst)59 TEST(CrossTrafficTest, TriggerPacketBurst) {
60 TrafficCounterFixture fixture;
61 TrafficRoute traffic(&fixture.clock, &fixture.counter, &fixture.endpoint);
62 traffic.TriggerPacketBurst(100, 1000);
63
64 EXPECT_EQ(fixture.counter.packets_count_, 100);
65 EXPECT_EQ(fixture.counter.total_packets_size_, 100 * 1000ul);
66 }
67
TEST(CrossTrafficTest,PulsedPeaksCrossTraffic)68 TEST(CrossTrafficTest, PulsedPeaksCrossTraffic) {
69 TrafficCounterFixture fixture;
70 TrafficRoute traffic(&fixture.clock, &fixture.counter, &fixture.endpoint);
71
72 PulsedPeaksConfig config;
73 config.peak_rate = DataRate::KilobitsPerSec(1000);
74 config.min_packet_size = DataSize::Bytes(1);
75 config.min_packet_interval = TimeDelta::Millis(25);
76 config.send_duration = TimeDelta::Millis(500);
77 config.hold_duration = TimeDelta::Millis(250);
78 PulsedPeaksCrossTraffic pulsed_peaks(config, &traffic);
79 const auto kRunTime = TimeDelta::Seconds(1);
80 while (fixture.clock.TimeInMilliseconds() < kRunTime.ms()) {
81 pulsed_peaks.Process(Timestamp::Millis(fixture.clock.TimeInMilliseconds()));
82 fixture.clock.AdvanceTimeMilliseconds(1);
83 }
84
85 RTC_LOG(INFO) << fixture.counter.packets_count_ << " packets; "
86 << fixture.counter.total_packets_size_ << " bytes";
87 // Using 50% duty cycle.
88 const auto kExpectedDataSent = kRunTime * config.peak_rate * 0.5;
89 EXPECT_NEAR(fixture.counter.total_packets_size_, kExpectedDataSent.bytes(),
90 kExpectedDataSent.bytes() * 0.1);
91 }
92
TEST(CrossTrafficTest,RandomWalkCrossTraffic)93 TEST(CrossTrafficTest, RandomWalkCrossTraffic) {
94 TrafficCounterFixture fixture;
95 TrafficRoute traffic(&fixture.clock, &fixture.counter, &fixture.endpoint);
96
97 RandomWalkConfig config;
98 config.peak_rate = DataRate::KilobitsPerSec(1000);
99 config.min_packet_size = DataSize::Bytes(1);
100 config.min_packet_interval = TimeDelta::Millis(25);
101 config.update_interval = TimeDelta::Millis(500);
102 config.variance = 0.0;
103 config.bias = 1.0;
104
105 RandomWalkCrossTraffic random_walk(config, &traffic);
106 const auto kRunTime = TimeDelta::Seconds(1);
107 while (fixture.clock.TimeInMilliseconds() < kRunTime.ms()) {
108 random_walk.Process(Timestamp::Millis(fixture.clock.TimeInMilliseconds()));
109 fixture.clock.AdvanceTimeMilliseconds(1);
110 }
111
112 RTC_LOG(INFO) << fixture.counter.packets_count_ << " packets; "
113 << fixture.counter.total_packets_size_ << " bytes";
114 // Sending at peak rate since bias = 1.
115 const auto kExpectedDataSent = kRunTime * config.peak_rate;
116 EXPECT_NEAR(fixture.counter.total_packets_size_, kExpectedDataSent.bytes(),
117 kExpectedDataSent.bytes() * 0.1);
118 }
119
TEST(TcpMessageRouteTest,DeliveredOnLossyNetwork)120 TEST(TcpMessageRouteTest, DeliveredOnLossyNetwork) {
121 NetworkEmulationManagerImpl net(TimeMode::kSimulated);
122 BuiltInNetworkBehaviorConfig send;
123 // 800 kbps means that the 100 kB message would be delivered in ca 1 second
124 // under ideal conditions and no overhead.
125 send.link_capacity_kbps = 100 * 8;
126 send.loss_percent = 50;
127 send.queue_delay_ms = 100;
128 send.delay_standard_deviation_ms = 20;
129 send.allow_reordering = true;
130 auto ret = send;
131 ret.loss_percent = 10;
132
133 auto* tcp_route =
134 net.CreateTcpRoute(net.CreateRoute({net.CreateEmulatedNode(send)}),
135 net.CreateRoute({net.CreateEmulatedNode(ret)}));
136 int deliver_count = 0;
137 // 100 kB is more than what fits into a single packet.
138 constexpr size_t kMessageSize = 100000;
139
140 tcp_route->SendMessage(kMessageSize, [&] {
141 RTC_LOG(LS_INFO) << "Received at " << ToString(net.Now());
142 deliver_count++;
143 });
144
145 // If there was no loss, we would have delivered the message in ca 1 second,
146 // with 50% it should take much longer.
147 net.time_controller()->AdvanceTime(TimeDelta::Seconds(5));
148 ASSERT_EQ(deliver_count, 0);
149 // But given enough time the messsage will be delivered, but only once.
150 net.time_controller()->AdvanceTime(TimeDelta::Seconds(60));
151 EXPECT_EQ(deliver_count, 1);
152 }
153
154 } // namespace test
155 } // namespace webrtc
156