network_emulation_manager.cc (6033B)
1 /* 2 * Copyright (c) 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 #include "api/test/network_emulation_manager.h" 11 12 #include <cstddef> 13 #include <cstdint> 14 #include <memory> 15 #include <string> 16 #include <utility> 17 18 #include "absl/strings/string_view.h" 19 #include "api/test/network_emulation/leaky_bucket_network_queue.h" 20 #include "api/test/network_emulation/network_queue.h" 21 #include "api/test/simulated_network.h" 22 #include "api/units/data_rate.h" 23 #include "rtc_base/checks.h" 24 #include "test/network/simulated_network.h" 25 26 namespace webrtc { 27 28 bool AbslParseFlag(absl::string_view text, TimeMode* mode, std::string* error) { 29 if (text == "realtime") { 30 *mode = TimeMode::kRealTime; 31 return true; 32 } 33 if (text == "simulated") { 34 *mode = TimeMode::kSimulated; 35 return true; 36 } 37 *error = 38 "Unknown value for TimeMode enum. Options are 'realtime' or 'simulated'"; 39 return false; 40 } 41 42 std::string AbslUnparseFlag(TimeMode mode) { 43 switch (mode) { 44 case TimeMode::kRealTime: 45 return "realtime"; 46 case TimeMode::kSimulated: 47 return "simulated"; 48 } 49 RTC_CHECK_NOTREACHED(); 50 return "unknown"; 51 } 52 53 NetworkEmulationManager::SimulatedNetworkNode::Builder& 54 NetworkEmulationManager::SimulatedNetworkNode::Builder::config( 55 BuiltInNetworkBehaviorConfig config) { 56 config_ = config; 57 return *this; 58 } 59 60 NetworkEmulationManager::SimulatedNetworkNode::Builder& 61 NetworkEmulationManager::SimulatedNetworkNode::Builder::queue_factory( 62 NetworkQueueFactory& queue_factory) { 63 queue_factory_ = &queue_factory; 64 return *this; 65 } 66 67 NetworkEmulationManager::SimulatedNetworkNode::Builder& 68 NetworkEmulationManager::SimulatedNetworkNode::Builder::delay_ms( 69 int queue_delay_ms) { 70 config_.queue_delay_ms = queue_delay_ms; 71 return *this; 72 } 73 74 NetworkEmulationManager::SimulatedNetworkNode::Builder& 75 NetworkEmulationManager::SimulatedNetworkNode::Builder::capacity( 76 DataRate link_capacity) { 77 config_.link_capacity = link_capacity; 78 return *this; 79 } 80 81 NetworkEmulationManager::SimulatedNetworkNode::Builder& 82 NetworkEmulationManager::SimulatedNetworkNode::Builder::capacity_kbps( 83 int link_capacity_kbps) { 84 if (link_capacity_kbps > 0) { 85 config_.link_capacity = DataRate::KilobitsPerSec(link_capacity_kbps); 86 } else { 87 config_.link_capacity = DataRate::Infinity(); 88 } 89 return *this; 90 } 91 92 NetworkEmulationManager::SimulatedNetworkNode::Builder& 93 NetworkEmulationManager::SimulatedNetworkNode::Builder::capacity_Mbps( 94 int link_capacity_Mbps) { 95 if (link_capacity_Mbps > 0) { 96 config_.link_capacity = DataRate::KilobitsPerSec(link_capacity_Mbps * 1000); 97 } else { 98 config_.link_capacity = DataRate::Infinity(); 99 } 100 return *this; 101 } 102 103 NetworkEmulationManager::SimulatedNetworkNode::Builder& 104 NetworkEmulationManager::SimulatedNetworkNode::Builder::loss(double loss_rate) { 105 config_.loss_percent = loss_rate * 100; 106 return *this; 107 } 108 109 NetworkEmulationManager::SimulatedNetworkNode::Builder& 110 NetworkEmulationManager::SimulatedNetworkNode::Builder::packet_queue_length( 111 int max_queue_length_in_packets) { 112 config_.queue_length_packets = max_queue_length_in_packets; 113 return *this; 114 } 115 116 NetworkEmulationManager::SimulatedNetworkNode::Builder& 117 NetworkEmulationManager::SimulatedNetworkNode::Builder:: 118 delay_standard_deviation_ms(int delay_standard_deviation_ms) { 119 config_.delay_standard_deviation_ms = delay_standard_deviation_ms; 120 return *this; 121 } 122 123 NetworkEmulationManager::SimulatedNetworkNode::Builder& 124 NetworkEmulationManager::SimulatedNetworkNode::Builder::allow_reordering() { 125 config_.allow_reordering = true; 126 return *this; 127 } 128 129 NetworkEmulationManager::SimulatedNetworkNode::Builder& 130 NetworkEmulationManager::SimulatedNetworkNode::Builder::avg_burst_loss_length( 131 int avg_burst_loss_length) { 132 config_.avg_burst_loss_length = avg_burst_loss_length; 133 return *this; 134 } 135 136 NetworkEmulationManager::SimulatedNetworkNode::Builder& 137 NetworkEmulationManager::SimulatedNetworkNode::Builder::packet_overhead( 138 int packet_overhead) { 139 config_.packet_overhead = packet_overhead; 140 return *this; 141 } 142 143 NetworkEmulationManager::SimulatedNetworkNode 144 NetworkEmulationManager::SimulatedNetworkNode::Builder::Build( 145 uint64_t random_seed) const { 146 RTC_CHECK(net_); 147 return Build(net_, random_seed); 148 } 149 150 NetworkEmulationManager::SimulatedNetworkNode 151 NetworkEmulationManager::SimulatedNetworkNode::Builder::Build( 152 NetworkEmulationManager* net, 153 uint64_t random_seed) const { 154 RTC_CHECK(net); 155 RTC_CHECK(net_ == nullptr || net_ == net); 156 std::unique_ptr<NetworkQueue> network_queue; 157 if (queue_factory_ != nullptr) { 158 network_queue = queue_factory_->CreateQueue(); 159 } else { 160 network_queue = std::make_unique<LeakyBucketNetworkQueue>(); 161 } 162 SimulatedNetworkNode res; 163 auto behavior = std::make_unique<SimulatedNetwork>(config_, random_seed, 164 std::move(network_queue)); 165 res.simulation = behavior.get(); 166 res.node = net->CreateEmulatedNode(std::move(behavior)); 167 return res; 168 } 169 170 std::pair<EmulatedNetworkManagerInterface*, EmulatedNetworkManagerInterface*> 171 NetworkEmulationManager::CreateEndpointPairWithTwoWayRoutes( 172 const BuiltInNetworkBehaviorConfig& config) { 173 auto* alice_node = CreateEmulatedNode(config); 174 auto* bob_node = CreateEmulatedNode(config); 175 176 auto* alice_endpoint = CreateEndpoint(EmulatedEndpointConfig()); 177 auto* bob_endpoint = CreateEndpoint(EmulatedEndpointConfig()); 178 179 CreateRoute(alice_endpoint, {alice_node}, bob_endpoint); 180 CreateRoute(bob_endpoint, {bob_node}, alice_endpoint); 181 182 return { 183 CreateEmulatedNetworkManagerInterface({alice_endpoint}), 184 CreateEmulatedNetworkManagerInterface({bob_endpoint}), 185 }; 186 } 187 } // namespace webrtc