This was generated by Running $ for i in test/network/*.cc; do ./tools_webrtc/iwyu/apply-include-cleaner $i; done $ for i in test/network/*.h; do ./tools_webrtc/iwyu/apply-include-cleaner $i; done $ python3 ./tools_webrtc/gn_check_autofix.py -C out/Default manually removing <sys/socket.h> include as suspicious. manually modifying test/DEPS file. Bug: webrtc:42226242 Change-Id: Ifda037e1385996ac3b68190c7e30e5309356ebb1 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/376382 Reviewed-by: Per Kjellander <perkj@webrtc.org> Commit-Queue: Danil Chapovalov <danilchap@webrtc.org> Reviewed-by: Artem Titov <titovartem@webrtc.org> Cr-Commit-Position: refs/heads/main@{#43857}
148 lines
5.4 KiB
C++
148 lines
5.4 KiB
C++
/*
|
|
* Copyright (c) 2024 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/schedulable_network_behavior.h"
|
|
|
|
#include <algorithm>
|
|
#include <cstdint>
|
|
#include <utility>
|
|
|
|
#include "absl/functional/any_invocable.h"
|
|
#include "api/sequence_checker.h"
|
|
#include "api/task_queue/task_queue_base.h"
|
|
#include "api/test/network_emulation/network_config_schedule.pb.h"
|
|
#include "api/test/simulated_network.h"
|
|
#include "api/units/data_rate.h"
|
|
#include "api/units/time_delta.h"
|
|
#include "api/units/timestamp.h"
|
|
#include "rtc_base/checks.h"
|
|
#include "rtc_base/task_utils/repeating_task.h"
|
|
#include "system_wrappers/include/clock.h"
|
|
#include "test/network/simulated_network.h"
|
|
|
|
namespace webrtc {
|
|
|
|
namespace {
|
|
|
|
using ::webrtc::BuiltInNetworkBehaviorConfig;
|
|
|
|
void UpdateConfigFromSchedule(
|
|
const network_behaviour::NetworkConfigScheduleItem& schedule_item,
|
|
BuiltInNetworkBehaviorConfig& config) {
|
|
if (schedule_item.has_queue_length_packets()) {
|
|
config.queue_length_packets = schedule_item.queue_length_packets();
|
|
}
|
|
if (schedule_item.has_queue_delay_ms()) {
|
|
config.queue_delay_ms = schedule_item.queue_delay_ms();
|
|
}
|
|
if (schedule_item.has_link_capacity_kbps()) {
|
|
config.link_capacity =
|
|
DataRate::KilobitsPerSec(schedule_item.link_capacity_kbps());
|
|
}
|
|
if (schedule_item.has_loss_percent()) {
|
|
config.loss_percent = schedule_item.loss_percent();
|
|
}
|
|
if (schedule_item.has_delay_standard_deviation_ms()) {
|
|
config.delay_standard_deviation_ms =
|
|
schedule_item.delay_standard_deviation_ms();
|
|
}
|
|
if (schedule_item.has_allow_reordering()) {
|
|
config.allow_reordering = schedule_item.allow_reordering();
|
|
}
|
|
if (schedule_item.has_avg_burst_loss_length()) {
|
|
config.avg_burst_loss_length = schedule_item.avg_burst_loss_length();
|
|
}
|
|
if (schedule_item.has_packet_overhead()) {
|
|
config.packet_overhead = schedule_item.packet_overhead();
|
|
}
|
|
}
|
|
|
|
BuiltInNetworkBehaviorConfig GetInitialConfig(
|
|
const network_behaviour::NetworkConfigSchedule& schedule) {
|
|
BuiltInNetworkBehaviorConfig config;
|
|
if (!schedule.item().empty()) {
|
|
UpdateConfigFromSchedule(schedule.item(0), config);
|
|
}
|
|
return config;
|
|
}
|
|
|
|
} // namespace
|
|
|
|
SchedulableNetworkBehavior::SchedulableNetworkBehavior(
|
|
network_behaviour::NetworkConfigSchedule schedule,
|
|
uint64_t random_seed,
|
|
webrtc::Clock& clock,
|
|
absl::AnyInvocable<bool(webrtc::Timestamp)> start_callback)
|
|
: SimulatedNetwork(GetInitialConfig(schedule), random_seed),
|
|
schedule_(std::move(schedule)),
|
|
start_condition_(std::move(start_callback)),
|
|
clock_(clock),
|
|
config_(GetInitialConfig(schedule_)) {
|
|
if (schedule_.item().size() > 1) {
|
|
next_schedule_index_ = 1;
|
|
}
|
|
sequence_checker_.Detach();
|
|
}
|
|
|
|
bool SchedulableNetworkBehavior::EnqueuePacket(
|
|
webrtc::PacketInFlightInfo packet_info) {
|
|
RTC_DCHECK_RUN_ON(&sequence_checker_);
|
|
if (first_send_time_.IsInfinite() &&
|
|
start_condition_(webrtc::Timestamp::Micros(packet_info.send_time_us))) {
|
|
first_send_time_ = webrtc::Timestamp::Micros(packet_info.send_time_us);
|
|
if (schedule_.item().size() > 1) {
|
|
RTC_CHECK_LT(next_schedule_index_, schedule_.item().size());
|
|
webrtc::TimeDelta delay =
|
|
webrtc::TimeDelta::Millis(schedule_.item()[next_schedule_index_]
|
|
.time_since_first_sent_packet_ms());
|
|
schedule_task_ = RepeatingTaskHandle::DelayedStart(
|
|
webrtc::TaskQueueBase::Current(), delay,
|
|
[this] { return UpdateConfigAndReschedule(); });
|
|
}
|
|
}
|
|
return SimulatedNetwork::EnqueuePacket(packet_info);
|
|
}
|
|
|
|
TimeDelta SchedulableNetworkBehavior::UpdateConfigAndReschedule() {
|
|
RTC_DCHECK_RUN_ON(&sequence_checker_);
|
|
Timestamp reschedule_time = clock_.CurrentTime();
|
|
RTC_CHECK_LT(next_schedule_index_, schedule_.item().size());
|
|
|
|
auto next_config = schedule_.item()[next_schedule_index_];
|
|
UpdateConfigFromSchedule(next_config, config_);
|
|
SimulatedNetwork::SetConfig(config_, reschedule_time);
|
|
next_schedule_index_ = ++next_schedule_index_ % schedule_.item().size();
|
|
webrtc::TimeDelta delay = webrtc::TimeDelta::Zero();
|
|
webrtc::TimeDelta time_since_first_sent_packet =
|
|
reschedule_time - first_send_time_;
|
|
if (next_schedule_index_ != 0) {
|
|
delay = std::max(TimeDelta::Millis(schedule_.item()[next_schedule_index_]
|
|
.time_since_first_sent_packet_ms()) -
|
|
(time_since_first_sent_packet - wrap_time_delta_),
|
|
TimeDelta::Zero());
|
|
} else if (!schedule_.has_repeat_schedule_after_last_ms()) {
|
|
// No more schedule items.
|
|
schedule_task_.Stop();
|
|
return TimeDelta::Zero(); // This is ignored.
|
|
} else {
|
|
// Wrap around to the first schedule item.
|
|
wrap_time_delta_ +=
|
|
TimeDelta::Millis(schedule_.repeat_schedule_after_last_ms()) +
|
|
TimeDelta::Millis(schedule_.item()[schedule_.item().size() - 1]
|
|
.time_since_first_sent_packet_ms());
|
|
delay =
|
|
webrtc::TimeDelta::Millis(schedule_.repeat_schedule_after_last_ms());
|
|
RTC_DCHECK_GE(delay, TimeDelta::Zero());
|
|
}
|
|
|
|
return delay;
|
|
}
|
|
|
|
} // namespace webrtc
|