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_config_schedule_proto",
|
||||||
"../..:network_emulation_manager_api",
|
"../..:network_emulation_manager_api",
|
||||||
"../../../test/network:schedulable_network_behavior",
|
"../../../test/network:schedulable_network_behavior",
|
||||||
|
"../../units:timestamp",
|
||||||
|
"//third_party/abseil-cpp/absl/functional:any_invocable",
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -12,8 +12,10 @@
|
|||||||
#include <memory>
|
#include <memory>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
|
#include "absl/functional/any_invocable.h"
|
||||||
#include "api/test/network_emulation/network_config_schedule.pb.h"
|
#include "api/test/network_emulation/network_config_schedule.pb.h"
|
||||||
#include "api/test/network_emulation_manager.h"
|
#include "api/test/network_emulation_manager.h"
|
||||||
|
#include "api/units/timestamp.h"
|
||||||
#include "test/network/schedulable_network_behavior.h"
|
#include "test/network/schedulable_network_behavior.h"
|
||||||
|
|
||||||
namespace webrtc {
|
namespace webrtc {
|
||||||
@ -21,10 +23,18 @@ namespace webrtc {
|
|||||||
SchedulableNetworkNodeBuilder::SchedulableNetworkNodeBuilder(
|
SchedulableNetworkNodeBuilder::SchedulableNetworkNodeBuilder(
|
||||||
webrtc::NetworkEmulationManager& net,
|
webrtc::NetworkEmulationManager& net,
|
||||||
network_behaviour::NetworkConfigSchedule schedule)
|
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() {
|
webrtc::EmulatedNetworkNode* SchedulableNetworkNodeBuilder::Build() {
|
||||||
return net_.CreateEmulatedNode(std::make_unique<SchedulableNetworkBehavior>(
|
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
|
} // namespace webrtc
|
||||||
|
|||||||
@ -10,8 +10,10 @@
|
|||||||
#ifndef API_TEST_NETWORK_EMULATION_SCHEDULABLE_NETWORK_NODE_BUILDER_H_
|
#ifndef API_TEST_NETWORK_EMULATION_SCHEDULABLE_NETWORK_NODE_BUILDER_H_
|
||||||
#define 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/network_config_schedule.pb.h"
|
||||||
#include "api/test/network_emulation_manager.h"
|
#include "api/test/network_emulation_manager.h"
|
||||||
|
#include "api/units/timestamp.h"
|
||||||
|
|
||||||
namespace webrtc {
|
namespace webrtc {
|
||||||
|
|
||||||
@ -20,12 +22,20 @@ class SchedulableNetworkNodeBuilder {
|
|||||||
SchedulableNetworkNodeBuilder(
|
SchedulableNetworkNodeBuilder(
|
||||||
webrtc::NetworkEmulationManager& net,
|
webrtc::NetworkEmulationManager& net,
|
||||||
network_behaviour::NetworkConfigSchedule schedule);
|
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();
|
webrtc::EmulatedNetworkNode* Build();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
webrtc::NetworkEmulationManager& net_;
|
webrtc::NetworkEmulationManager& net_;
|
||||||
network_behaviour::NetworkConfigSchedule schedule_;
|
network_behaviour::NetworkConfigSchedule schedule_;
|
||||||
|
absl::AnyInvocable<bool(webrtc::Timestamp)> start_condition_;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace webrtc
|
} // namespace webrtc
|
||||||
|
|||||||
@ -265,6 +265,7 @@ if (rtc_enable_protobuf) {
|
|||||||
"../../rtc_base:macromagic",
|
"../../rtc_base:macromagic",
|
||||||
"../../rtc_base/task_utils:repeating_task",
|
"../../rtc_base/task_utils:repeating_task",
|
||||||
"../../system_wrappers",
|
"../../system_wrappers",
|
||||||
|
"//third_party/abseil-cpp/absl/functional:any_invocable",
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -11,8 +11,8 @@
|
|||||||
|
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
|
#include "absl/functional/any_invocable.h"
|
||||||
#include "api/sequence_checker.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/network_emulation/network_config_schedule.pb.h"
|
||||||
#include "api/test/simulated_network.h"
|
#include "api/test/simulated_network.h"
|
||||||
#include "api/units/data_rate.h"
|
#include "api/units/data_rate.h"
|
||||||
@ -72,9 +72,11 @@ BuiltInNetworkBehaviorConfig GetInitialConfig(
|
|||||||
|
|
||||||
SchedulableNetworkBehavior::SchedulableNetworkBehavior(
|
SchedulableNetworkBehavior::SchedulableNetworkBehavior(
|
||||||
network_behaviour::NetworkConfigSchedule schedule,
|
network_behaviour::NetworkConfigSchedule schedule,
|
||||||
webrtc::Clock& clock)
|
webrtc::Clock& clock,
|
||||||
|
absl::AnyInvocable<bool(webrtc::Timestamp)> start_callback)
|
||||||
: SimulatedNetwork(GetInitialConfig(schedule)),
|
: SimulatedNetwork(GetInitialConfig(schedule)),
|
||||||
schedule_(std::move(schedule)),
|
schedule_(std::move(schedule)),
|
||||||
|
start_condition_(std::move(start_callback)),
|
||||||
clock_(clock),
|
clock_(clock),
|
||||||
config_(GetInitialConfig(schedule_)) {
|
config_(GetInitialConfig(schedule_)) {
|
||||||
if (schedule_.item().size() > 1) {
|
if (schedule_.item().size() > 1) {
|
||||||
@ -86,7 +88,8 @@ SchedulableNetworkBehavior::SchedulableNetworkBehavior(
|
|||||||
bool SchedulableNetworkBehavior::EnqueuePacket(
|
bool SchedulableNetworkBehavior::EnqueuePacket(
|
||||||
webrtc::PacketInFlightInfo packet_info) {
|
webrtc::PacketInFlightInfo packet_info) {
|
||||||
RTC_DCHECK_RUN_ON(&sequence_checker_);
|
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);
|
first_send_time_ = webrtc::Timestamp::Micros(packet_info.send_time_us);
|
||||||
if (schedule_.item().size() > 1) {
|
if (schedule_.item().size() > 1) {
|
||||||
RTC_CHECK_LT(next_schedule_index_, schedule_.item().size());
|
RTC_CHECK_LT(next_schedule_index_, schedule_.item().size());
|
||||||
|
|||||||
@ -11,6 +11,7 @@
|
|||||||
#ifndef TEST_NETWORK_SCHEDULABLE_NETWORK_BEHAVIOR_H_
|
#ifndef TEST_NETWORK_SCHEDULABLE_NETWORK_BEHAVIOR_H_
|
||||||
#define 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/sequence_checker.h"
|
||||||
#include "api/test/network_emulation/network_config_schedule.pb.h"
|
#include "api/test/network_emulation/network_config_schedule.pb.h"
|
||||||
#include "api/test/simulated_network.h"
|
#include "api/test/simulated_network.h"
|
||||||
@ -27,8 +28,11 @@ namespace webrtc {
|
|||||||
// specified with a schedule proto.
|
// specified with a schedule proto.
|
||||||
class SchedulableNetworkBehavior : public SimulatedNetwork {
|
class SchedulableNetworkBehavior : public SimulatedNetwork {
|
||||||
public:
|
public:
|
||||||
SchedulableNetworkBehavior(network_behaviour::NetworkConfigSchedule schedule,
|
SchedulableNetworkBehavior(
|
||||||
Clock& clock);
|
network_behaviour::NetworkConfigSchedule schedule,
|
||||||
|
Clock& clock,
|
||||||
|
absl::AnyInvocable<bool(webrtc::Timestamp)> start_condition =
|
||||||
|
[](webrtc::Timestamp) { return true; });
|
||||||
|
|
||||||
bool EnqueuePacket(PacketInFlightInfo packet_info) override;
|
bool EnqueuePacket(PacketInFlightInfo packet_info) override;
|
||||||
|
|
||||||
@ -37,6 +41,10 @@ class SchedulableNetworkBehavior : public SimulatedNetwork {
|
|||||||
|
|
||||||
SequenceChecker sequence_checker_;
|
SequenceChecker sequence_checker_;
|
||||||
const network_behaviour::NetworkConfigSchedule schedule_;
|
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 first_send_time_ RTC_GUARDED_BY(&sequence_checker_) =
|
||||||
Timestamp::MinusInfinity();
|
Timestamp::MinusInfinity();
|
||||||
|
|
||||||
|
|||||||
@ -27,6 +27,8 @@ namespace {
|
|||||||
|
|
||||||
using ::testing::Mock;
|
using ::testing::Mock;
|
||||||
using ::testing::MockFunction;
|
using ::testing::MockFunction;
|
||||||
|
using ::testing::Return;
|
||||||
|
using ::testing::Sequence;
|
||||||
using ::testing::SizeIs;
|
using ::testing::SizeIs;
|
||||||
|
|
||||||
class SchedulableNetworkBehaviorTestFixture {
|
class SchedulableNetworkBehaviorTestFixture {
|
||||||
@ -147,6 +149,50 @@ TEST(SchedulableNetworkBehaviorTest,
|
|||||||
.us());
|
.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) {
|
TEST(SchedulableNetworkBehaviorTest, ScheduleWithRepeat) {
|
||||||
SchedulableNetworkBehaviorTestFixture fixture;
|
SchedulableNetworkBehaviorTestFixture fixture;
|
||||||
network_behaviour::NetworkConfigSchedule schedule;
|
network_behaviour::NetworkConfigSchedule schedule;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user