Implement delayed start of Scheduled network configuration
Before the schedule starts an absl::AnyInvocvable is executed every time a packet is enqued. The incocable should return true, if the schedule should be started. The pupose is to allow tests to not start a schedule until ICE and DTLs is connected. Bug: webrtc:42224804 Change-Id: I61bd63508830f7c27d86f982299ce2be180ff460 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/354464 Reviewed-by: Björn Terelius <terelius@webrtc.org> Commit-Queue: Per Kjellander <perkj@webrtc.org> Cr-Commit-Position: refs/heads/main@{#42479}
This commit is contained in:
parent
2da85bc19a
commit
da485a1b46
@ -26,6 +26,8 @@ if (rtc_enable_protobuf) {
|
||||
":network_config_schedule_proto",
|
||||
"../..:network_emulation_manager_api",
|
||||
"../../../test/network:schedulable_network_behavior",
|
||||
"../../units:timestamp",
|
||||
"//third_party/abseil-cpp/absl/functional:any_invocable",
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@ -12,8 +12,10 @@
|
||||
#include <memory>
|
||||
#include <utility>
|
||||
|
||||
#include "absl/functional/any_invocable.h"
|
||||
#include "api/test/network_emulation/network_config_schedule.pb.h"
|
||||
#include "api/test/network_emulation_manager.h"
|
||||
#include "api/units/timestamp.h"
|
||||
#include "test/network/schedulable_network_behavior.h"
|
||||
|
||||
namespace webrtc {
|
||||
@ -21,10 +23,18 @@ namespace webrtc {
|
||||
SchedulableNetworkNodeBuilder::SchedulableNetworkNodeBuilder(
|
||||
webrtc::NetworkEmulationManager& net,
|
||||
network_behaviour::NetworkConfigSchedule schedule)
|
||||
: net_(net), schedule_(std::move(schedule)) {}
|
||||
: net_(net),
|
||||
schedule_(std::move(schedule)),
|
||||
start_condition_([](webrtc::Timestamp) { return true; }) {}
|
||||
|
||||
void SchedulableNetworkNodeBuilder::set_start_condition(
|
||||
absl::AnyInvocable<bool(webrtc::Timestamp)> start_condition) {
|
||||
start_condition_ = std::move(start_condition);
|
||||
}
|
||||
|
||||
webrtc::EmulatedNetworkNode* SchedulableNetworkNodeBuilder::Build() {
|
||||
return net_.CreateEmulatedNode(std::make_unique<SchedulableNetworkBehavior>(
|
||||
std::move(schedule_), *net_.time_controller()->GetClock()));
|
||||
std::move(schedule_), *net_.time_controller()->GetClock(),
|
||||
std::move(start_condition_)));
|
||||
}
|
||||
} // namespace webrtc
|
||||
|
||||
@ -10,8 +10,10 @@
|
||||
#ifndef API_TEST_NETWORK_EMULATION_SCHEDULABLE_NETWORK_NODE_BUILDER_H_
|
||||
#define API_TEST_NETWORK_EMULATION_SCHEDULABLE_NETWORK_NODE_BUILDER_H_
|
||||
|
||||
#include "absl/functional/any_invocable.h"
|
||||
#include "api/test/network_emulation/network_config_schedule.pb.h"
|
||||
#include "api/test/network_emulation_manager.h"
|
||||
#include "api/units/timestamp.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
@ -20,12 +22,20 @@ class SchedulableNetworkNodeBuilder {
|
||||
SchedulableNetworkNodeBuilder(
|
||||
webrtc::NetworkEmulationManager& net,
|
||||
network_behaviour::NetworkConfigSchedule schedule);
|
||||
// set_start_condition allows a test to control when the schedule start.
|
||||
// `start_condition` is invoked every time a packet is enqueued on the network
|
||||
// until the first time `start_condition` returns true. Until then, the first
|
||||
// NetworkConfigScheduleItem is used. There is no guarantee on which
|
||||
// thread/task queue that will be used.
|
||||
void set_start_condition(
|
||||
absl::AnyInvocable<bool(webrtc::Timestamp)> start_condition);
|
||||
|
||||
webrtc::EmulatedNetworkNode* Build();
|
||||
|
||||
private:
|
||||
webrtc::NetworkEmulationManager& net_;
|
||||
network_behaviour::NetworkConfigSchedule schedule_;
|
||||
absl::AnyInvocable<bool(webrtc::Timestamp)> start_condition_;
|
||||
};
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
@ -265,6 +265,7 @@ if (rtc_enable_protobuf) {
|
||||
"../../rtc_base:macromagic",
|
||||
"../../rtc_base/task_utils:repeating_task",
|
||||
"../../system_wrappers",
|
||||
"//third_party/abseil-cpp/absl/functional:any_invocable",
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
@ -11,8 +11,8 @@
|
||||
|
||||
#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"
|
||||
@ -72,9 +72,11 @@ BuiltInNetworkBehaviorConfig GetInitialConfig(
|
||||
|
||||
SchedulableNetworkBehavior::SchedulableNetworkBehavior(
|
||||
network_behaviour::NetworkConfigSchedule schedule,
|
||||
webrtc::Clock& clock)
|
||||
webrtc::Clock& clock,
|
||||
absl::AnyInvocable<bool(webrtc::Timestamp)> start_callback)
|
||||
: SimulatedNetwork(GetInitialConfig(schedule)),
|
||||
schedule_(std::move(schedule)),
|
||||
start_condition_(std::move(start_callback)),
|
||||
clock_(clock),
|
||||
config_(GetInitialConfig(schedule_)) {
|
||||
if (schedule_.item().size() > 1) {
|
||||
@ -86,7 +88,8 @@ SchedulableNetworkBehavior::SchedulableNetworkBehavior(
|
||||
bool SchedulableNetworkBehavior::EnqueuePacket(
|
||||
webrtc::PacketInFlightInfo packet_info) {
|
||||
RTC_DCHECK_RUN_ON(&sequence_checker_);
|
||||
if (first_send_time_.IsMinusInfinity()) {
|
||||
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());
|
||||
|
||||
@ -11,6 +11,7 @@
|
||||
#ifndef TEST_NETWORK_SCHEDULABLE_NETWORK_BEHAVIOR_H_
|
||||
#define TEST_NETWORK_SCHEDULABLE_NETWORK_BEHAVIOR_H_
|
||||
|
||||
#include "absl/functional/any_invocable.h"
|
||||
#include "api/sequence_checker.h"
|
||||
#include "api/test/network_emulation/network_config_schedule.pb.h"
|
||||
#include "api/test/simulated_network.h"
|
||||
@ -27,8 +28,11 @@ namespace webrtc {
|
||||
// specified with a schedule proto.
|
||||
class SchedulableNetworkBehavior : public SimulatedNetwork {
|
||||
public:
|
||||
SchedulableNetworkBehavior(network_behaviour::NetworkConfigSchedule schedule,
|
||||
Clock& clock);
|
||||
SchedulableNetworkBehavior(
|
||||
network_behaviour::NetworkConfigSchedule schedule,
|
||||
Clock& clock,
|
||||
absl::AnyInvocable<bool(webrtc::Timestamp)> start_condition =
|
||||
[](webrtc::Timestamp) { return true; });
|
||||
|
||||
bool EnqueuePacket(PacketInFlightInfo packet_info) override;
|
||||
|
||||
@ -37,6 +41,10 @@ class SchedulableNetworkBehavior : public SimulatedNetwork {
|
||||
|
||||
SequenceChecker sequence_checker_;
|
||||
const network_behaviour::NetworkConfigSchedule schedule_;
|
||||
absl::AnyInvocable<bool(webrtc::Timestamp)> start_condition_
|
||||
RTC_GUARDED_BY(&sequence_checker_);
|
||||
// Send time of the first packet enqueued after `start_condition_` return
|
||||
// true.
|
||||
Timestamp first_send_time_ RTC_GUARDED_BY(&sequence_checker_) =
|
||||
Timestamp::MinusInfinity();
|
||||
|
||||
|
||||
@ -27,6 +27,8 @@ namespace {
|
||||
|
||||
using ::testing::Mock;
|
||||
using ::testing::MockFunction;
|
||||
using ::testing::Return;
|
||||
using ::testing::Sequence;
|
||||
using ::testing::SizeIs;
|
||||
|
||||
class SchedulableNetworkBehaviorTestFixture {
|
||||
@ -147,6 +149,50 @@ TEST(SchedulableNetworkBehaviorTest,
|
||||
.us());
|
||||
}
|
||||
|
||||
TEST(SchedulableNetworkBehaviorTest, ScheduleStartedWhenStartConditionTrue) {
|
||||
SchedulableNetworkBehaviorTestFixture fixture;
|
||||
network_behaviour::NetworkConfigSchedule schedule;
|
||||
auto initial_config = schedule.add_item();
|
||||
initial_config->set_link_capacity_kbps(0);
|
||||
auto item = schedule.add_item();
|
||||
item->set_time_since_first_sent_packet_ms(1);
|
||||
item->set_link_capacity_kbps(1000000);
|
||||
|
||||
MockFunction<bool(Timestamp)> start_condition;
|
||||
webrtc::Timestamp first_packet_send_time = fixture.TimeNow();
|
||||
webrtc::Timestamp second_packet_send_time =
|
||||
fixture.TimeNow() + TimeDelta::Millis(100);
|
||||
Sequence s;
|
||||
EXPECT_CALL(start_condition, Call(first_packet_send_time))
|
||||
.InSequence(s)
|
||||
.WillOnce(Return(false));
|
||||
// Expect schedule to start when the second packet is sent.
|
||||
EXPECT_CALL(start_condition, Call(second_packet_send_time))
|
||||
.InSequence(s)
|
||||
.WillOnce(Return(true));
|
||||
SchedulableNetworkBehavior network_behaviour(schedule, fixture.clock(),
|
||||
start_condition.AsStdFunction());
|
||||
|
||||
EXPECT_TRUE(network_behaviour.EnqueuePacket(
|
||||
{/*size=*/1000 / 8,
|
||||
/*send_time_us=*/first_packet_send_time.us(),
|
||||
/*packet_id=*/1}));
|
||||
EXPECT_FALSE(network_behaviour.NextDeliveryTimeUs().has_value());
|
||||
// Move passed the normal schedule change time. Still dont expect a delivery
|
||||
// time.
|
||||
fixture.AdvanceTime(TimeDelta::Millis(100));
|
||||
EXPECT_FALSE(network_behaviour.NextDeliveryTimeUs().has_value());
|
||||
|
||||
EXPECT_TRUE(network_behaviour.EnqueuePacket(
|
||||
{/*size=*/1000 / 8,
|
||||
/*send_time_us=*/second_packet_send_time.us(),
|
||||
/*packet_id=*/2}));
|
||||
|
||||
EXPECT_FALSE(network_behaviour.NextDeliveryTimeUs().has_value());
|
||||
fixture.AdvanceTime(TimeDelta::Millis(1));
|
||||
EXPECT_TRUE(network_behaviour.NextDeliveryTimeUs().has_value());
|
||||
}
|
||||
|
||||
TEST(SchedulableNetworkBehaviorTest, ScheduleWithRepeat) {
|
||||
SchedulableNetworkBehaviorTestFixture fixture;
|
||||
network_behaviour::NetworkConfigSchedule schedule;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user