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