| /* |
| * Copyright (c) 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 "api/test/network_emulation_manager.h" |
| |
| #include <cstdint> |
| #include <memory> |
| #include <string> |
| #include <utility> |
| |
| #include "absl/strings/string_view.h" |
| #include "api/test/simulated_network.h" |
| #include "api/units/data_rate.h" |
| #include "rtc_base/checks.h" |
| #include "test/network/simulated_network.h" |
| |
| namespace webrtc { |
| |
| bool AbslParseFlag(absl::string_view text, TimeMode* mode, std::string* error) { |
| if (text == "realtime") { |
| *mode = TimeMode::kRealTime; |
| return true; |
| } |
| if (text == "simulated") { |
| *mode = TimeMode::kSimulated; |
| return true; |
| } |
| *error = |
| "Unknown value for TimeMode enum. Options are 'realtime' or 'simulated'"; |
| return false; |
| } |
| |
| std::string AbslUnparseFlag(TimeMode mode) { |
| switch (mode) { |
| case TimeMode::kRealTime: |
| return "realtime"; |
| case TimeMode::kSimulated: |
| return "simulated"; |
| } |
| RTC_CHECK_NOTREACHED(); |
| return "unknown"; |
| } |
| |
| NetworkEmulationManager::SimulatedNetworkNode::Builder& |
| NetworkEmulationManager::SimulatedNetworkNode::Builder::config( |
| BuiltInNetworkBehaviorConfig config) { |
| config_ = config; |
| return *this; |
| } |
| |
| NetworkEmulationManager::SimulatedNetworkNode::Builder& |
| NetworkEmulationManager::SimulatedNetworkNode::Builder::delay_ms( |
| int queue_delay_ms) { |
| config_.queue_delay_ms = queue_delay_ms; |
| return *this; |
| } |
| |
| NetworkEmulationManager::SimulatedNetworkNode::Builder& |
| NetworkEmulationManager::SimulatedNetworkNode::Builder::capacity( |
| DataRate link_capacity) { |
| config_.link_capacity = link_capacity; |
| return *this; |
| } |
| |
| NetworkEmulationManager::SimulatedNetworkNode::Builder& |
| NetworkEmulationManager::SimulatedNetworkNode::Builder::capacity_kbps( |
| int link_capacity_kbps) { |
| if (link_capacity_kbps > 0) { |
| config_.link_capacity = DataRate::KilobitsPerSec(link_capacity_kbps); |
| } else { |
| config_.link_capacity = DataRate::Infinity(); |
| } |
| return *this; |
| } |
| |
| NetworkEmulationManager::SimulatedNetworkNode::Builder& |
| NetworkEmulationManager::SimulatedNetworkNode::Builder::capacity_Mbps( |
| int link_capacity_Mbps) { |
| if (link_capacity_Mbps > 0) { |
| config_.link_capacity = DataRate::KilobitsPerSec(link_capacity_Mbps * 1000); |
| } else { |
| config_.link_capacity = DataRate::Infinity(); |
| } |
| return *this; |
| } |
| |
| NetworkEmulationManager::SimulatedNetworkNode::Builder& |
| NetworkEmulationManager::SimulatedNetworkNode::Builder::loss(double loss_rate) { |
| config_.loss_percent = loss_rate * 100; |
| return *this; |
| } |
| |
| NetworkEmulationManager::SimulatedNetworkNode::Builder& |
| NetworkEmulationManager::SimulatedNetworkNode::Builder::packet_queue_length( |
| int max_queue_length_in_packets) { |
| config_.queue_length_packets = max_queue_length_in_packets; |
| return *this; |
| } |
| |
| NetworkEmulationManager::SimulatedNetworkNode::Builder& |
| NetworkEmulationManager::SimulatedNetworkNode::Builder:: |
| delay_standard_deviation_ms(int delay_standard_deviation_ms) { |
| config_.delay_standard_deviation_ms = delay_standard_deviation_ms; |
| return *this; |
| } |
| |
| NetworkEmulationManager::SimulatedNetworkNode::Builder& |
| NetworkEmulationManager::SimulatedNetworkNode::Builder::allow_reordering() { |
| config_.allow_reordering = true; |
| return *this; |
| } |
| |
| NetworkEmulationManager::SimulatedNetworkNode::Builder& |
| NetworkEmulationManager::SimulatedNetworkNode::Builder::avg_burst_loss_length( |
| int avg_burst_loss_length) { |
| config_.avg_burst_loss_length = avg_burst_loss_length; |
| return *this; |
| } |
| |
| NetworkEmulationManager::SimulatedNetworkNode::Builder& |
| NetworkEmulationManager::SimulatedNetworkNode::Builder::packet_overhead( |
| int packet_overhead) { |
| config_.packet_overhead = packet_overhead; |
| return *this; |
| } |
| |
| NetworkEmulationManager::SimulatedNetworkNode |
| NetworkEmulationManager::SimulatedNetworkNode::Builder::Build( |
| uint64_t random_seed) const { |
| RTC_CHECK(net_); |
| return Build(net_, random_seed); |
| } |
| |
| NetworkEmulationManager::SimulatedNetworkNode |
| NetworkEmulationManager::SimulatedNetworkNode::Builder::Build( |
| NetworkEmulationManager* net, |
| uint64_t random_seed) const { |
| RTC_CHECK(net); |
| RTC_CHECK(net_ == nullptr || net_ == net); |
| SimulatedNetworkNode res; |
| auto behavior = std::make_unique<SimulatedNetwork>(config_, random_seed); |
| res.simulation = behavior.get(); |
| res.node = net->CreateEmulatedNode(std::move(behavior)); |
| return res; |
| } |
| |
| std::pair<EmulatedNetworkManagerInterface*, EmulatedNetworkManagerInterface*> |
| NetworkEmulationManager::CreateEndpointPairWithTwoWayRoutes( |
| const BuiltInNetworkBehaviorConfig& config) { |
| auto* alice_node = CreateEmulatedNode(config); |
| auto* bob_node = CreateEmulatedNode(config); |
| |
| auto* alice_endpoint = CreateEndpoint(EmulatedEndpointConfig()); |
| auto* bob_endpoint = CreateEndpoint(EmulatedEndpointConfig()); |
| |
| CreateRoute(alice_endpoint, {alice_node}, bob_endpoint); |
| CreateRoute(bob_endpoint, {bob_node}, alice_endpoint); |
| |
| return { |
| CreateEmulatedNetworkManagerInterface({alice_endpoint}), |
| CreateEmulatedNetworkManagerInterface({bob_endpoint}), |
| }; |
| } |
| } // namespace webrtc |