summaryrefslogtreecommitdiffstats
path: root/third_party/libwebrtc/test/network/cross_traffic_unittest.cc
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/libwebrtc/test/network/cross_traffic_unittest.cc')
-rw-r--r--third_party/libwebrtc/test/network/cross_traffic_unittest.cc163
1 files changed, 163 insertions, 0 deletions
diff --git a/third_party/libwebrtc/test/network/cross_traffic_unittest.cc b/third_party/libwebrtc/test/network/cross_traffic_unittest.cc
new file mode 100644
index 0000000000..36aff67bb2
--- /dev/null
+++ b/third_party/libwebrtc/test/network/cross_traffic_unittest.cc
@@ -0,0 +1,163 @@
+/*
+ * Copyright 2019 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "test/network/cross_traffic.h"
+
+#include <atomic>
+#include <memory>
+#include <utility>
+#include <vector>
+
+#include "absl/memory/memory.h"
+#include "absl/types/optional.h"
+#include "api/test/network_emulation_manager.h"
+#include "api/test/simulated_network.h"
+#include "call/simulated_network.h"
+#include "rtc_base/event.h"
+#include "rtc_base/logging.h"
+#include "rtc_base/network_constants.h"
+#include "test/gmock.h"
+#include "test/gtest.h"
+#include "test/network/network_emulation_manager.h"
+#include "test/network/traffic_route.h"
+#include "test/time_controller/simulated_time_controller.h"
+
+namespace webrtc {
+namespace test {
+namespace {
+
+constexpr uint32_t kTestIpAddress = 0xC0A80011; // 192.168.0.17
+
+class CountingReceiver : public EmulatedNetworkReceiverInterface {
+ public:
+ void OnPacketReceived(EmulatedIpPacket packet) override {
+ packets_count_++;
+ total_packets_size_ += packet.size();
+ }
+
+ std::atomic<int> packets_count_{0};
+ std::atomic<uint64_t> total_packets_size_{0};
+};
+struct TrafficCounterFixture {
+ SimulatedClock clock{0};
+ CountingReceiver counter;
+ TaskQueueForTest task_queue_;
+ EmulatedEndpointImpl endpoint{EmulatedEndpointImpl::Options{
+ /*id=*/1,
+ rtc::IPAddress(kTestIpAddress),
+ EmulatedEndpointConfig(),
+ EmulatedNetworkStatsGatheringMode::kDefault,
+ },
+ /*is_enabled=*/true, &task_queue_, &clock};
+};
+
+} // namespace
+
+TEST(CrossTrafficTest, TriggerPacketBurst) {
+ TrafficCounterFixture fixture;
+ CrossTrafficRouteImpl traffic(&fixture.clock, &fixture.counter,
+ &fixture.endpoint);
+ traffic.TriggerPacketBurst(100, 1000);
+
+ EXPECT_EQ(fixture.counter.packets_count_, 100);
+ EXPECT_EQ(fixture.counter.total_packets_size_, 100 * 1000ul);
+}
+
+TEST(CrossTrafficTest, PulsedPeaksCrossTraffic) {
+ TrafficCounterFixture fixture;
+ CrossTrafficRouteImpl traffic(&fixture.clock, &fixture.counter,
+ &fixture.endpoint);
+
+ PulsedPeaksConfig config;
+ config.peak_rate = DataRate::KilobitsPerSec(1000);
+ config.min_packet_size = DataSize::Bytes(1);
+ config.min_packet_interval = TimeDelta::Millis(25);
+ config.send_duration = TimeDelta::Millis(500);
+ config.hold_duration = TimeDelta::Millis(250);
+ PulsedPeaksCrossTraffic pulsed_peaks(config, &traffic);
+ const auto kRunTime = TimeDelta::Seconds(1);
+ while (fixture.clock.TimeInMilliseconds() < kRunTime.ms()) {
+ pulsed_peaks.Process(Timestamp::Millis(fixture.clock.TimeInMilliseconds()));
+ fixture.clock.AdvanceTimeMilliseconds(1);
+ }
+
+ RTC_LOG(LS_INFO) << fixture.counter.packets_count_ << " packets; "
+ << fixture.counter.total_packets_size_ << " bytes";
+ // Using 50% duty cycle.
+ const auto kExpectedDataSent = kRunTime * config.peak_rate * 0.5;
+ EXPECT_NEAR(fixture.counter.total_packets_size_, kExpectedDataSent.bytes(),
+ kExpectedDataSent.bytes() * 0.1);
+}
+
+TEST(CrossTrafficTest, RandomWalkCrossTraffic) {
+ TrafficCounterFixture fixture;
+ CrossTrafficRouteImpl traffic(&fixture.clock, &fixture.counter,
+ &fixture.endpoint);
+
+ RandomWalkConfig config;
+ config.peak_rate = DataRate::KilobitsPerSec(1000);
+ config.min_packet_size = DataSize::Bytes(1);
+ config.min_packet_interval = TimeDelta::Millis(25);
+ config.update_interval = TimeDelta::Millis(500);
+ config.variance = 0.0;
+ config.bias = 1.0;
+
+ RandomWalkCrossTraffic random_walk(config, &traffic);
+ const auto kRunTime = TimeDelta::Seconds(1);
+ while (fixture.clock.TimeInMilliseconds() < kRunTime.ms()) {
+ random_walk.Process(Timestamp::Millis(fixture.clock.TimeInMilliseconds()));
+ fixture.clock.AdvanceTimeMilliseconds(1);
+ }
+
+ RTC_LOG(LS_INFO) << fixture.counter.packets_count_ << " packets; "
+ << fixture.counter.total_packets_size_ << " bytes";
+ // Sending at peak rate since bias = 1.
+ const auto kExpectedDataSent = kRunTime * config.peak_rate;
+ EXPECT_NEAR(fixture.counter.total_packets_size_, kExpectedDataSent.bytes(),
+ kExpectedDataSent.bytes() * 0.1);
+}
+
+TEST(TcpMessageRouteTest, DeliveredOnLossyNetwork) {
+ NetworkEmulationManagerImpl net(TimeMode::kSimulated,
+ EmulatedNetworkStatsGatheringMode::kDefault);
+ BuiltInNetworkBehaviorConfig send;
+ // 800 kbps means that the 100 kB message would be delivered in ca 1 second
+ // under ideal conditions and no overhead.
+ send.link_capacity_kbps = 100 * 8;
+ send.loss_percent = 50;
+ send.queue_delay_ms = 100;
+ send.delay_standard_deviation_ms = 20;
+ send.allow_reordering = true;
+ auto ret = send;
+ ret.loss_percent = 10;
+
+ auto* tcp_route =
+ net.CreateTcpRoute(net.CreateRoute({net.CreateEmulatedNode(send)}),
+ net.CreateRoute({net.CreateEmulatedNode(ret)}));
+ int deliver_count = 0;
+ // 100 kB is more than what fits into a single packet.
+ constexpr size_t kMessageSize = 100000;
+
+ tcp_route->SendMessage(kMessageSize, [&] {
+ RTC_LOG(LS_INFO) << "Received at " << ToString(net.Now());
+ deliver_count++;
+ });
+
+ // If there was no loss, we would have delivered the message in ca 1 second,
+ // with 50% it should take much longer.
+ net.time_controller()->AdvanceTime(TimeDelta::Seconds(5));
+ ASSERT_EQ(deliver_count, 0);
+ // But given enough time the messsage will be delivered, but only once.
+ net.time_controller()->AdvanceTime(TimeDelta::Seconds(60));
+ EXPECT_EQ(deliver_count, 1);
+}
+
+} // namespace test
+} // namespace webrtc