Adds feedback generator.
This is a useful tool to use for unittests of code that uses TransportFeedback as input. Bug: webrtc:10498 Change-Id: I171b22841eb9e16a5d5b785ff45ae9df5a6ccd7f Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/137423 Commit-Queue: Sebastian Jansson <srte@webrtc.org> Reviewed-by: Jonas Olsson <jonasolsson@webrtc.org> Cr-Commit-Position: refs/heads/master@{#27975}
This commit is contained in:

committed by
Commit Bot

parent
df5731e44d
commit
3525f86c42
@ -85,6 +85,30 @@ rtc_static_library("goog_cc") {
|
||||
}
|
||||
|
||||
if (rtc_include_tests) {
|
||||
rtc_source_set("test_feedback_generator_interface") {
|
||||
testonly = true
|
||||
sources = [
|
||||
"test/feedback_generator_interface.h",
|
||||
]
|
||||
deps = [
|
||||
":network_control",
|
||||
"..:simulated_network_api",
|
||||
]
|
||||
}
|
||||
rtc_source_set("test_feedback_generator") {
|
||||
testonly = true
|
||||
sources = [
|
||||
"test/create_feedback_generator.cc",
|
||||
"test/create_feedback_generator.h",
|
||||
]
|
||||
visibility = [ "*" ]
|
||||
deps = [
|
||||
":network_control",
|
||||
":test_feedback_generator_interface",
|
||||
"../../test/scenario/network:feedback_generator",
|
||||
"//third_party/abseil-cpp/absl/memory",
|
||||
]
|
||||
}
|
||||
rtc_source_set("network_control_test") {
|
||||
testonly = true
|
||||
sources = [
|
||||
|
23
api/transport/test/create_feedback_generator.cc
Normal file
23
api/transport/test/create_feedback_generator.cc
Normal file
@ -0,0 +1,23 @@
|
||||
/*
|
||||
* Copyright 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/transport/test/create_feedback_generator.h"
|
||||
|
||||
#include "absl/memory/memory.h"
|
||||
|
||||
#include "test/scenario/network/feedback_generator.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
std::unique_ptr<FeedbackGenerator> CreateFeedbackGenerator(
|
||||
FeedbackGenerator::Config confg) {
|
||||
return absl::make_unique<FeedbackGeneratorImpl>(confg);
|
||||
}
|
||||
|
||||
} // namespace webrtc
|
21
api/transport/test/create_feedback_generator.h
Normal file
21
api/transport/test/create_feedback_generator.h
Normal file
@ -0,0 +1,21 @@
|
||||
/*
|
||||
* Copyright 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.
|
||||
*/
|
||||
#ifndef API_TRANSPORT_TEST_CREATE_FEEDBACK_GENERATOR_H_
|
||||
#define API_TRANSPORT_TEST_CREATE_FEEDBACK_GENERATOR_H_
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "api/transport/test/feedback_generator_interface.h"
|
||||
|
||||
namespace webrtc {
|
||||
std::unique_ptr<FeedbackGenerator> CreateFeedbackGenerator(
|
||||
FeedbackGenerator::Config confg);
|
||||
} // namespace webrtc
|
||||
#endif // API_TRANSPORT_TEST_CREATE_FEEDBACK_GENERATOR_H_
|
37
api/transport/test/feedback_generator_interface.h
Normal file
37
api/transport/test/feedback_generator_interface.h
Normal file
@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright 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.
|
||||
*/
|
||||
#ifndef API_TRANSPORT_TEST_FEEDBACK_GENERATOR_INTERFACE_H_
|
||||
#define API_TRANSPORT_TEST_FEEDBACK_GENERATOR_INTERFACE_H_
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "api/test/simulated_network.h"
|
||||
#include "api/transport/network_types.h"
|
||||
|
||||
namespace webrtc {
|
||||
class FeedbackGenerator {
|
||||
public:
|
||||
struct Config {
|
||||
BuiltInNetworkBehaviorConfig send_link;
|
||||
BuiltInNetworkBehaviorConfig return_link;
|
||||
TimeDelta feedback_interval = TimeDelta::ms(50);
|
||||
DataSize feedback_packet_size = DataSize::bytes(20);
|
||||
};
|
||||
virtual ~FeedbackGenerator() = default;
|
||||
virtual Timestamp Now() = 0;
|
||||
virtual void Sleep(TimeDelta duration) = 0;
|
||||
virtual void SendPacket(size_t size) = 0;
|
||||
virtual std::vector<TransportPacketsFeedback> PopFeedback() = 0;
|
||||
virtual void SetSendConfig(BuiltInNetworkBehaviorConfig config) = 0;
|
||||
virtual void SetReturnConfig(BuiltInNetworkBehaviorConfig config) = 0;
|
||||
virtual void SetSendLinkCapacity(DataRate capacity) = 0;
|
||||
};
|
||||
} // namespace webrtc
|
||||
#endif // API_TRANSPORT_TEST_FEEDBACK_GENERATOR_INTERFACE_H_
|
@ -122,10 +122,38 @@ rtc_source_set("cross_traffic_unittest") {
|
||||
]
|
||||
}
|
||||
|
||||
rtc_source_set("feedback_generator") {
|
||||
testonly = true
|
||||
sources = [
|
||||
"feedback_generator.cc",
|
||||
"feedback_generator.h",
|
||||
]
|
||||
deps = [
|
||||
"../../../api/transport:test_feedback_generator_interface",
|
||||
"../../../call:simulated_network",
|
||||
"../../../rtc_base:checks",
|
||||
"../../../test/scenario/network:emulated_network",
|
||||
"../../../test/time_controller",
|
||||
"//third_party/abseil-cpp/absl/memory",
|
||||
]
|
||||
}
|
||||
|
||||
rtc_source_set("feedback_generator_unittest") {
|
||||
testonly = true
|
||||
sources = [
|
||||
"feedback_generator_unittest.cc",
|
||||
]
|
||||
deps = [
|
||||
"../../../api/transport:test_feedback_generator",
|
||||
"../../../test:test_support",
|
||||
]
|
||||
}
|
||||
|
||||
rtc_source_set("network_emulation_unittests") {
|
||||
testonly = true
|
||||
deps = [
|
||||
":cross_traffic_unittest",
|
||||
":feedback_generator_unittest",
|
||||
":network_emulation_pc_unittest",
|
||||
":network_emulation_unittest",
|
||||
]
|
||||
|
99
test/scenario/network/feedback_generator.cc
Normal file
99
test/scenario/network/feedback_generator.cc
Normal file
@ -0,0 +1,99 @@
|
||||
/*
|
||||
* Copyright 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 "test/scenario/network/feedback_generator.h"
|
||||
|
||||
#include "absl/memory/memory.h"
|
||||
#include "rtc_base/checks.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
FeedbackGeneratorImpl::FeedbackGeneratorImpl(
|
||||
FeedbackGeneratorImpl::Config config)
|
||||
: conf_(config),
|
||||
time_controller_{Timestamp::seconds(100000)},
|
||||
net_{&time_controller_},
|
||||
send_link_{new SimulatedNetwork(conf_.send_link)},
|
||||
ret_link_{new SimulatedNetwork(conf_.return_link)},
|
||||
send_ep_{net_.CreateEndpoint(EmulatedEndpointConfig())},
|
||||
ret_ep_{net_.CreateEndpoint(EmulatedEndpointConfig())},
|
||||
send_route_{net_.CreateRoute(
|
||||
send_ep_,
|
||||
{net_.CreateEmulatedNode(absl::WrapUnique(send_link_))},
|
||||
ret_ep_)},
|
||||
ret_route_{net_.CreateRoute(
|
||||
ret_ep_,
|
||||
{net_.CreateEmulatedNode(absl::WrapUnique(ret_link_))},
|
||||
send_ep_)},
|
||||
send_addr_{rtc::SocketAddress(send_ep_->GetPeerLocalAddress(), 0)},
|
||||
ret_addr_{rtc::SocketAddress(ret_ep_->GetPeerLocalAddress(), 0)},
|
||||
received_packet_handler_{send_route_,
|
||||
[&](SentPacket packet, Timestamp arrival_time) {
|
||||
OnPacketReceived(std::move(packet),
|
||||
arrival_time);
|
||||
}},
|
||||
received_feedback_handler_{
|
||||
ret_route_,
|
||||
[&](TransportPacketsFeedback packet, Timestamp arrival_time) {
|
||||
packet.feedback_time = arrival_time;
|
||||
feedback_.push_back(packet);
|
||||
}} {}
|
||||
|
||||
Timestamp FeedbackGeneratorImpl::Now() {
|
||||
return Timestamp::ms(time_controller_.GetClock()->TimeInMilliseconds());
|
||||
}
|
||||
|
||||
void FeedbackGeneratorImpl::Sleep(TimeDelta duration) {
|
||||
time_controller_.Sleep(duration);
|
||||
}
|
||||
|
||||
void FeedbackGeneratorImpl::SendPacket(size_t size) {
|
||||
SentPacket sent;
|
||||
sent.send_time = Now();
|
||||
sent.size = DataSize::bytes(size);
|
||||
received_packet_handler_.SendPacket(send_ep_, size, sent);
|
||||
}
|
||||
|
||||
std::vector<TransportPacketsFeedback> FeedbackGeneratorImpl::PopFeedback() {
|
||||
std::vector<TransportPacketsFeedback> ret;
|
||||
ret.swap(feedback_);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void FeedbackGeneratorImpl::SetSendConfig(BuiltInNetworkBehaviorConfig config) {
|
||||
conf_.send_link = config;
|
||||
send_link_->SetConfig(conf_.send_link);
|
||||
}
|
||||
|
||||
void FeedbackGeneratorImpl::SetReturnConfig(
|
||||
BuiltInNetworkBehaviorConfig config) {
|
||||
conf_.return_link = config;
|
||||
ret_link_->SetConfig(conf_.return_link);
|
||||
}
|
||||
|
||||
void FeedbackGeneratorImpl::SetSendLinkCapacity(DataRate capacity) {
|
||||
conf_.send_link.link_capacity_kbps = capacity.kbps<int>();
|
||||
send_link_->SetConfig(conf_.send_link);
|
||||
}
|
||||
|
||||
void FeedbackGeneratorImpl::OnPacketReceived(SentPacket packet,
|
||||
Timestamp arrival_time) {
|
||||
PacketResult result;
|
||||
result.sent_packet = packet;
|
||||
result.receive_time = arrival_time;
|
||||
builder_.packet_feedbacks.push_back(result);
|
||||
Timestamp first_recv = builder_.packet_feedbacks.front().receive_time;
|
||||
if (Now() - first_recv > conf_.feedback_interval) {
|
||||
received_feedback_handler_.SendPacket(
|
||||
ret_ep_, conf_.feedback_packet_size.bytes<size_t>(), builder_);
|
||||
builder_ = {};
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace webrtc
|
93
test/scenario/network/feedback_generator.h
Normal file
93
test/scenario/network/feedback_generator.h
Normal file
@ -0,0 +1,93 @@
|
||||
/*
|
||||
* Copyright 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.
|
||||
*/
|
||||
#ifndef TEST_SCENARIO_NETWORK_FEEDBACK_GENERATOR_H_
|
||||
#define TEST_SCENARIO_NETWORK_FEEDBACK_GENERATOR_H_
|
||||
|
||||
#include <map>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "api/transport/test/feedback_generator_interface.h"
|
||||
#include "call/simulated_network.h"
|
||||
#include "test/scenario/network/network_emulation.h"
|
||||
#include "test/scenario/network/network_emulation_manager.h"
|
||||
#include "test/time_controller/simulated_time_controller.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
template <typename FakePacketType>
|
||||
class FakePacketRoute : public EmulatedNetworkReceiverInterface {
|
||||
public:
|
||||
FakePacketRoute(EmulatedRoute* route,
|
||||
std::function<void(FakePacketType, Timestamp)> action)
|
||||
: route_(route),
|
||||
action_(std::move(action)),
|
||||
send_addr_(route_->from->GetPeerLocalAddress(), 0),
|
||||
recv_addr_(route_->to->GetPeerLocalAddress(),
|
||||
*route_->to->BindReceiver(0, this)) {}
|
||||
|
||||
void SendPacket(EmulatedEndpoint* from, size_t size, FakePacketType packet) {
|
||||
RTC_CHECK_GE(size, sizeof(int));
|
||||
sent_.emplace(next_packet_id_, packet);
|
||||
rtc::CopyOnWriteBuffer buf(size);
|
||||
reinterpret_cast<int*>(buf.data())[0] = next_packet_id_++;
|
||||
from->SendPacket(send_addr_, recv_addr_, buf);
|
||||
}
|
||||
|
||||
void OnPacketReceived(EmulatedIpPacket packet) override {
|
||||
int packet_id = reinterpret_cast<int*>(packet.data.data())[0];
|
||||
action_(std::move(sent_[packet_id]), packet.arrival_time);
|
||||
sent_.erase(packet_id);
|
||||
}
|
||||
|
||||
private:
|
||||
EmulatedRoute* const route_;
|
||||
const std::function<void(FakePacketType, Timestamp)> action_;
|
||||
const rtc::SocketAddress send_addr_;
|
||||
const rtc::SocketAddress recv_addr_;
|
||||
|
||||
int next_packet_id_ = 0;
|
||||
std::map<int, FakePacketType> sent_;
|
||||
};
|
||||
|
||||
class FeedbackGeneratorImpl : public FeedbackGenerator {
|
||||
public:
|
||||
explicit FeedbackGeneratorImpl(Config config);
|
||||
Timestamp Now() override;
|
||||
void Sleep(TimeDelta duration) override;
|
||||
void SendPacket(size_t size) override;
|
||||
std::vector<TransportPacketsFeedback> PopFeedback() override;
|
||||
|
||||
void SetSendConfig(BuiltInNetworkBehaviorConfig config) override;
|
||||
void SetReturnConfig(BuiltInNetworkBehaviorConfig config) override;
|
||||
|
||||
void SetSendLinkCapacity(DataRate capacity) override;
|
||||
|
||||
private:
|
||||
void OnPacketReceived(SentPacket packet, Timestamp arrival_time);
|
||||
Config conf_;
|
||||
GlobalSimulatedTimeController time_controller_;
|
||||
::webrtc::test::NetworkEmulationManagerImpl net_;
|
||||
SimulatedNetwork* const send_link_;
|
||||
SimulatedNetwork* const ret_link_;
|
||||
EmulatedEndpoint* const send_ep_;
|
||||
EmulatedEndpoint* const ret_ep_;
|
||||
EmulatedRoute* const send_route_;
|
||||
EmulatedRoute* const ret_route_;
|
||||
const rtc::SocketAddress send_addr_;
|
||||
const rtc::SocketAddress ret_addr_;
|
||||
FakePacketRoute<SentPacket> received_packet_handler_;
|
||||
FakePacketRoute<TransportPacketsFeedback> received_feedback_handler_;
|
||||
|
||||
TransportPacketsFeedback builder_;
|
||||
std::vector<TransportPacketsFeedback> feedback_;
|
||||
};
|
||||
} // namespace webrtc
|
||||
#endif // TEST_SCENARIO_NETWORK_FEEDBACK_GENERATOR_H_
|
31
test/scenario/network/feedback_generator_unittest.cc
Normal file
31
test/scenario/network/feedback_generator_unittest.cc
Normal file
@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Copyright 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/transport/test/create_feedback_generator.h"
|
||||
#include "test/gtest.h"
|
||||
|
||||
namespace webrtc {
|
||||
TEST(FeedbackGeneratorTest, ReportsFeedbackForSentPackets) {
|
||||
size_t kPacketSize = 1000;
|
||||
auto gen = CreateFeedbackGenerator(FeedbackGenerator::Config());
|
||||
for (int i = 0; i < 10; ++i) {
|
||||
gen->SendPacket(kPacketSize);
|
||||
gen->Sleep(TimeDelta::ms(50));
|
||||
}
|
||||
auto feedback_list = gen->PopFeedback();
|
||||
EXPECT_GT(feedback_list.size(), 0u);
|
||||
for (const auto& feedback : feedback_list) {
|
||||
EXPECT_GT(feedback.packet_feedbacks.size(), 0u);
|
||||
for (const auto& packet : feedback.packet_feedbacks) {
|
||||
EXPECT_EQ(packet.sent_packet.size.bytes<size_t>(), kPacketSize);
|
||||
}
|
||||
}
|
||||
}
|
||||
} // namespace webrtc
|
Reference in New Issue
Block a user