Add TCP fairness test.
BUG=4548 R=pbos@webrtc.org Review URL: https://webrtc-codereview.appspot.com/43199004 Cr-Commit-Position: refs/heads/master@{#9026}
This commit is contained in:
parent
b0b54259c3
commit
1d19893f3a
@ -239,97 +239,14 @@ TEST_P(BweSimulation, SelfFairnessTest) {
|
||||
|
||||
TEST_P(BweSimulation, PacedSelfFairnessTest) {
|
||||
VerboseLogging(true);
|
||||
const int kAllFlowIds[] = {0, 1, 2};
|
||||
const size_t kNumFlows = sizeof(kAllFlowIds) / sizeof(kAllFlowIds[0]);
|
||||
rtc::scoped_ptr<PeriodicKeyFrameSource> sources[kNumFlows];
|
||||
rtc::scoped_ptr<PacedVideoSender> senders[kNumFlows];
|
||||
|
||||
for (size_t i = 0; i < kNumFlows; ++i) {
|
||||
// Streams started 20 seconds apart to give them different advantage when
|
||||
// competing for the bandwidth.
|
||||
sources[i].reset(new PeriodicKeyFrameSource(kAllFlowIds[i], 30, 300, 0,
|
||||
i * 20000, 1000));
|
||||
senders[i].reset(
|
||||
new PacedVideoSender(&uplink_, sources[i].get(), GetParam()));
|
||||
}
|
||||
|
||||
ChokeFilter choke(&uplink_, CreateFlowIds(kAllFlowIds, kNumFlows));
|
||||
choke.SetCapacity(1000);
|
||||
|
||||
rtc::scoped_ptr<RateCounterFilter> rate_counters[kNumFlows];
|
||||
for (size_t i = 0; i < kNumFlows; ++i) {
|
||||
rate_counters[i].reset(new RateCounterFilter(
|
||||
&uplink_, CreateFlowIds(&kAllFlowIds[i], 1), "receiver_input"));
|
||||
}
|
||||
|
||||
RateCounterFilter total_utilization(
|
||||
&uplink_, CreateFlowIds(kAllFlowIds, kNumFlows), "total_utilization");
|
||||
|
||||
rtc::scoped_ptr<PacketReceiver> receivers[kNumFlows];
|
||||
for (size_t i = 0; i < kNumFlows; ++i) {
|
||||
receivers[i].reset(new PacketReceiver(&uplink_, kAllFlowIds[i], GetParam(),
|
||||
i == 0, false));
|
||||
}
|
||||
|
||||
RunFor(30 * 60 * 1000);
|
||||
srand(Clock::GetRealTimeClock()->TimeInMicroseconds());
|
||||
RunFairnessTest(GetParam(), 4, 0, 2000);
|
||||
}
|
||||
|
||||
TEST_P(BweSimulation, PacedTcpFairnessTest) {
|
||||
VerboseLogging(true);
|
||||
|
||||
const int kAllFlowIds[] = {0, 1};
|
||||
const size_t kNumFlows = sizeof(kAllFlowIds) / sizeof(kAllFlowIds[0]);
|
||||
|
||||
const int kAllMediaFlowIds[] = {0};
|
||||
const size_t kNumMediaFlows =
|
||||
sizeof(kAllMediaFlowIds) / sizeof(kAllMediaFlowIds[0]);
|
||||
|
||||
const int kAllTcpFlowIds[] = {1};
|
||||
const size_t kNumTcpFlows =
|
||||
sizeof(kAllTcpFlowIds) / sizeof(kAllTcpFlowIds[0]);
|
||||
|
||||
rtc::scoped_ptr<PeriodicKeyFrameSource> sources[kNumFlows];
|
||||
rtc::scoped_ptr<PacketSender> senders[kNumFlows + kNumTcpFlows];
|
||||
|
||||
for (size_t i = 0; i < kNumMediaFlows; ++i) {
|
||||
// Streams started 20 seconds apart to give them different advantage when
|
||||
// competing for the bandwidth.
|
||||
sources[i].reset(new PeriodicKeyFrameSource(kAllMediaFlowIds[i], 30, 300, 0,
|
||||
i * 20000, 1000));
|
||||
senders[i].reset(
|
||||
new PacedVideoSender(&uplink_, sources[i].get(), GetParam()));
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < kNumTcpFlows; ++i) {
|
||||
senders[kNumMediaFlows + i].reset(
|
||||
new TcpSender(&uplink_, kAllTcpFlowIds[i]));
|
||||
}
|
||||
|
||||
ChokeFilter choke(&uplink_, CreateFlowIds(kAllFlowIds, kNumFlows));
|
||||
choke.SetCapacity(1000);
|
||||
choke.SetMaxDelay(1000);
|
||||
|
||||
rtc::scoped_ptr<RateCounterFilter> rate_counters[kNumFlows];
|
||||
for (size_t i = 0; i < kNumFlows; ++i) {
|
||||
rate_counters[i].reset(new RateCounterFilter(
|
||||
&uplink_, CreateFlowIds(&kAllFlowIds[i], 1), "receiver_input"));
|
||||
}
|
||||
|
||||
RateCounterFilter total_utilization(
|
||||
&uplink_, CreateFlowIds(kAllFlowIds, kNumFlows), "total_utilization");
|
||||
|
||||
rtc::scoped_ptr<PacketReceiver> receivers[kNumFlows];
|
||||
for (size_t i = 0; i < kNumMediaFlows; ++i) {
|
||||
receivers[i].reset(new PacketReceiver(&uplink_, kAllMediaFlowIds[i],
|
||||
GetParam(), i == 0, false));
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < kNumTcpFlows; ++i) {
|
||||
receivers[kNumMediaFlows + i].reset(new PacketReceiver(
|
||||
&uplink_, kAllTcpFlowIds[i], kTcpEstimator, false, false));
|
||||
}
|
||||
|
||||
RunFor(30 * 60 * 1000);
|
||||
srand(Clock::GetRealTimeClock()->TimeInMicroseconds());
|
||||
RunFairnessTest(GetParam(), 1, 1, 3000);
|
||||
}
|
||||
#endif // BWE_TEST_LOGGING_COMPILE_TIME_ENABLE
|
||||
} // namespace bwe
|
||||
|
@ -89,6 +89,16 @@
|
||||
'test/estimators/tcp.cc',
|
||||
'test/estimators/tcp.h',
|
||||
],
|
||||
'conditions': [
|
||||
['enable_bwe_test_logging==1', {
|
||||
'defines': [ 'BWE_TEST_LOGGING_COMPILE_TIME_ENABLE=1' ],
|
||||
}, {
|
||||
'defines': [ 'BWE_TEST_LOGGING_COMPILE_TIME_ENABLE=0' ],
|
||||
'sources!': [
|
||||
'remote_bitrate_estimator/test/bwe_test_logging.cc'
|
||||
],
|
||||
}],
|
||||
],
|
||||
},
|
||||
{
|
||||
'target_name': 'bwe_tools_util',
|
||||
|
@ -15,7 +15,6 @@
|
||||
#include "webrtc/modules/remote_bitrate_estimator/test/packet_receiver.h"
|
||||
#include "webrtc/modules/remote_bitrate_estimator/test/packet_sender.h"
|
||||
#include "webrtc/test/testsupport/fileutils.h"
|
||||
#include "webrtc/test/testsupport/perf_test.h"
|
||||
|
||||
using std::string;
|
||||
|
||||
@ -241,43 +240,6 @@ class BweFeedbackTest
|
||||
BweFeedbackTest() : BweTest() {}
|
||||
virtual ~BweFeedbackTest() {}
|
||||
|
||||
void PrintResults(double max_throughput_kbps,
|
||||
Stats<double> throughput_kbps,
|
||||
Stats<double> delay_ms,
|
||||
std::vector<Stats<double>> flow_throughput_kbps) {
|
||||
double utilization = throughput_kbps.GetMean() / max_throughput_kbps;
|
||||
webrtc::test::PrintResult("BwePerformance",
|
||||
GetTestName(),
|
||||
"Utilization",
|
||||
utilization * 100.0,
|
||||
"%",
|
||||
false);
|
||||
std::stringstream ss;
|
||||
ss << throughput_kbps.GetStdDev() / throughput_kbps.GetMean();
|
||||
webrtc::test::PrintResult("BwePerformance",
|
||||
GetTestName(),
|
||||
"Utilization var coeff",
|
||||
ss.str(),
|
||||
"",
|
||||
false);
|
||||
webrtc::test::PrintResult("BwePerformance",
|
||||
GetTestName(),
|
||||
"Average delay",
|
||||
delay_ms.AsString(),
|
||||
"ms",
|
||||
false);
|
||||
double fairness_index = 0.0;
|
||||
double squared_bitrate_sum = 0.0;
|
||||
for (Stats<double> flow : flow_throughput_kbps) {
|
||||
squared_bitrate_sum += flow.GetMean() * flow.GetMean();
|
||||
fairness_index += flow.GetMean();
|
||||
}
|
||||
fairness_index *= fairness_index;
|
||||
fairness_index /= flow_throughput_kbps.size() * squared_bitrate_sum;
|
||||
webrtc::test::PrintResult("BwePerformance", GetTestName(), "Fairness",
|
||||
fairness_index * 100, "%", false);
|
||||
}
|
||||
|
||||
protected:
|
||||
void SetUp() override { BweTest::SetUp(); }
|
||||
|
||||
@ -361,45 +323,12 @@ TEST_P(BweFeedbackTest, DISABLED_GoogleWifiTrace3Mbps) {
|
||||
|
||||
TEST_P(BweFeedbackTest, PacedSelfFairnessTest) {
|
||||
srand(Clock::GetRealTimeClock()->TimeInMicroseconds());
|
||||
const int kAllFlowIds[] = {0, 1, 2, 3};
|
||||
const size_t kNumFlows = sizeof(kAllFlowIds) / sizeof(kAllFlowIds[0]);
|
||||
rtc::scoped_ptr<VideoSource> sources[kNumFlows];
|
||||
rtc::scoped_ptr<PacketSender> senders[kNumFlows];
|
||||
RunFairnessTest(GetParam(), 4, 0, 3000);
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < kNumFlows; ++i) {
|
||||
// Streams started woth ramdp, pffsets tp give them different advantage when
|
||||
// competing for the bandwidth.
|
||||
sources[i].reset(new AdaptiveVideoSource(kAllFlowIds[i], 30, 300, 0,
|
||||
i * (rand() % 40000)));
|
||||
senders[i].reset(
|
||||
new PacedVideoSender(&uplink_, sources[i].get(), GetParam()));
|
||||
}
|
||||
|
||||
ChokeFilter choke(&uplink_, CreateFlowIds(kAllFlowIds, kNumFlows));
|
||||
choke.SetCapacity(3000);
|
||||
choke.SetMaxDelay(1000);
|
||||
|
||||
rtc::scoped_ptr<RateCounterFilter> rate_counters[kNumFlows];
|
||||
for (size_t i = 0; i < kNumFlows; ++i) {
|
||||
rate_counters[i].reset(new RateCounterFilter(
|
||||
&uplink_, CreateFlowIds(&kAllFlowIds[i], 1), "receiver_input"));
|
||||
}
|
||||
|
||||
RateCounterFilter total_utilization(
|
||||
&uplink_, CreateFlowIds(kAllFlowIds, kNumFlows), "total_utilization");
|
||||
|
||||
rtc::scoped_ptr<PacketReceiver> receivers[kNumFlows];
|
||||
for (size_t i = 0; i < kNumFlows; ++i) {
|
||||
receivers[i].reset(new PacketReceiver(&uplink_, kAllFlowIds[i], GetParam(),
|
||||
i == 0, false));
|
||||
}
|
||||
RunFor(15 * 60 * 1000);
|
||||
|
||||
std::vector<Stats<double>> flow_throughput_kbps;
|
||||
for (size_t i = 0; i < kNumFlows; ++i)
|
||||
flow_throughput_kbps.push_back(rate_counters[i]->GetBitrateStats());
|
||||
PrintResults(3000, total_utilization.GetBitrateStats(), choke.GetDelayStats(),
|
||||
flow_throughput_kbps);
|
||||
TEST_P(BweFeedbackTest, TcpFairnessTest) {
|
||||
srand(Clock::GetRealTimeClock()->TimeInMicroseconds());
|
||||
RunFairnessTest(GetParam(), 1, 1, 2000);
|
||||
}
|
||||
} // namespace bwe
|
||||
} // namespace testing
|
||||
|
@ -17,6 +17,7 @@
|
||||
#include "webrtc/modules/remote_bitrate_estimator/test/packet_receiver.h"
|
||||
#include "webrtc/modules/remote_bitrate_estimator/test/packet_sender.h"
|
||||
#include "webrtc/system_wrappers/interface/clock.h"
|
||||
#include "webrtc/test/testsupport/perf_test.h"
|
||||
|
||||
using std::string;
|
||||
using std::vector;
|
||||
@ -175,6 +176,108 @@ string BweTest::GetTestName() const {
|
||||
::testing::UnitTest::GetInstance()->current_test_info();
|
||||
return string(test_info->name());
|
||||
}
|
||||
|
||||
void BweTest::PrintResults(
|
||||
double max_throughput_kbps,
|
||||
Stats<double> throughput_kbps,
|
||||
Stats<double> delay_ms,
|
||||
std::vector<Stats<double>> flow_throughput_kbps) {
|
||||
double utilization = throughput_kbps.GetMean() / max_throughput_kbps;
|
||||
webrtc::test::PrintResult("BwePerformance", GetTestName(), "Utilization",
|
||||
utilization * 100.0, "%", false);
|
||||
std::stringstream ss;
|
||||
ss << throughput_kbps.GetStdDev() / throughput_kbps.GetMean();
|
||||
webrtc::test::PrintResult("BwePerformance", GetTestName(),
|
||||
"Utilization var coeff", ss.str(), "", false);
|
||||
webrtc::test::PrintResult("BwePerformance", GetTestName(), "Average delay",
|
||||
delay_ms.AsString(), "ms", false);
|
||||
double fairness_index = 0.0;
|
||||
double squared_bitrate_sum = 0.0;
|
||||
for (Stats<double> flow : flow_throughput_kbps) {
|
||||
squared_bitrate_sum += flow.GetMean() * flow.GetMean();
|
||||
fairness_index += flow.GetMean();
|
||||
}
|
||||
fairness_index *= fairness_index;
|
||||
fairness_index /= flow_throughput_kbps.size() * squared_bitrate_sum;
|
||||
webrtc::test::PrintResult("BwePerformance", GetTestName(), "Fairness",
|
||||
fairness_index * 100, "%", false);
|
||||
}
|
||||
|
||||
void BweTest::RunFairnessTest(BandwidthEstimatorType bwe_type,
|
||||
size_t num_media_flows,
|
||||
size_t num_tcp_flows,
|
||||
int capacity_kbps) {
|
||||
std::set<int> all_flow_ids;
|
||||
std::set<int> media_flow_ids;
|
||||
std::set<int> tcp_flow_ids;
|
||||
int next_flow_id = 0;
|
||||
for (size_t i = 0; i < num_media_flows; ++i) {
|
||||
media_flow_ids.insert(next_flow_id);
|
||||
all_flow_ids.insert(next_flow_id);
|
||||
++next_flow_id;
|
||||
}
|
||||
for (size_t i = 0; i < num_tcp_flows; ++i) {
|
||||
tcp_flow_ids.insert(next_flow_id);
|
||||
all_flow_ids.insert(next_flow_id);
|
||||
++next_flow_id;
|
||||
}
|
||||
|
||||
std::vector<VideoSource*> sources;
|
||||
std::vector<PacketSender*> senders;
|
||||
|
||||
size_t i = 0;
|
||||
for (int media_flow : media_flow_ids) {
|
||||
// Streams started 20 seconds apart to give them different advantage when
|
||||
// competing for the bandwidth.
|
||||
sources.push_back(new AdaptiveVideoSource(media_flow, 30, 300, 0,
|
||||
i++ * (rand() % 40000)));
|
||||
senders.push_back(new PacedVideoSender(&uplink_, sources.back(), bwe_type));
|
||||
}
|
||||
|
||||
for (int tcp_flow : tcp_flow_ids)
|
||||
senders.push_back(new TcpSender(&uplink_, tcp_flow));
|
||||
|
||||
ChokeFilter choke(&uplink_, all_flow_ids);
|
||||
choke.SetCapacity(capacity_kbps);
|
||||
// choke.SetMaxDelay(1000);
|
||||
|
||||
std::vector<RateCounterFilter*> rate_counters;
|
||||
for (int flow : all_flow_ids) {
|
||||
rate_counters.push_back(
|
||||
new RateCounterFilter(&uplink_, flow, "receiver_input"));
|
||||
}
|
||||
|
||||
RateCounterFilter total_utilization(&uplink_, all_flow_ids,
|
||||
"total_utilization");
|
||||
|
||||
std::vector<PacketReceiver*> receivers;
|
||||
i = 0;
|
||||
for (int media_flow : media_flow_ids) {
|
||||
receivers.push_back(
|
||||
new PacketReceiver(&uplink_, media_flow, bwe_type, i++ == 0, false));
|
||||
}
|
||||
for (int tcp_flow : tcp_flow_ids) {
|
||||
receivers.push_back(
|
||||
new PacketReceiver(&uplink_, tcp_flow, kTcpEstimator, false, false));
|
||||
}
|
||||
|
||||
RunFor(15 * 60 * 1000);
|
||||
|
||||
std::vector<Stats<double>> flow_throughput_kbps;
|
||||
for (i = 0; i < all_flow_ids.size(); ++i)
|
||||
flow_throughput_kbps.push_back(rate_counters[i]->GetBitrateStats());
|
||||
PrintResults(capacity_kbps, total_utilization.GetBitrateStats(),
|
||||
choke.GetDelayStats(), flow_throughput_kbps);
|
||||
|
||||
for (VideoSource* source : sources)
|
||||
delete source;
|
||||
for (PacketSender* sender : senders)
|
||||
delete sender;
|
||||
for (RateCounterFilter* rate_counter : rate_counters)
|
||||
delete rate_counter;
|
||||
for (PacketReceiver* receiver : receivers)
|
||||
delete receiver;
|
||||
}
|
||||
} // namespace bwe
|
||||
} // namespace testing
|
||||
} // namespace webrtc
|
||||
|
@ -17,6 +17,7 @@
|
||||
#include "testing/gtest/include/gtest/gtest.h"
|
||||
#include "webrtc/base/constructormagic.h"
|
||||
#include "webrtc/modules/remote_bitrate_estimator/include/remote_bitrate_estimator.h"
|
||||
#include "webrtc/modules/remote_bitrate_estimator/test/bwe.h"
|
||||
#include "webrtc/modules/remote_bitrate_estimator/test/bwe_test_framework.h"
|
||||
|
||||
namespace webrtc {
|
||||
@ -75,6 +76,16 @@ class BweTest {
|
||||
void RunFor(int64_t time_ms);
|
||||
std::string GetTestName() const;
|
||||
|
||||
void PrintResults(double max_throughput_kbps,
|
||||
Stats<double> throughput_kbps,
|
||||
Stats<double> delay_ms,
|
||||
std::vector<Stats<double>> flow_throughput_kbps);
|
||||
|
||||
void RunFairnessTest(BandwidthEstimatorType bwe_type,
|
||||
size_t num_media_flows,
|
||||
size_t num_tcp_flows,
|
||||
int capacity_kbps);
|
||||
|
||||
Link downlink_;
|
||||
Link uplink_;
|
||||
|
||||
|
@ -235,7 +235,10 @@ RateCounterFilter::RateCounterFilter(PacketProcessorListener* listener,
|
||||
rate_counter_(new RateCounter()),
|
||||
packets_per_second_stats_(),
|
||||
kbps_stats_(),
|
||||
name_(name) {
|
||||
name_() {
|
||||
std::stringstream ss;
|
||||
ss << name << "_" << flow_id;
|
||||
name_ = ss.str();
|
||||
}
|
||||
|
||||
RateCounterFilter::RateCounterFilter(PacketProcessorListener* listener,
|
||||
@ -245,9 +248,9 @@ RateCounterFilter::RateCounterFilter(PacketProcessorListener* listener,
|
||||
rate_counter_(new RateCounter()),
|
||||
packets_per_second_stats_(),
|
||||
kbps_stats_(),
|
||||
name_(name) {
|
||||
name_() {
|
||||
std::stringstream ss;
|
||||
ss << name_ << "_";
|
||||
ss << name << "_";
|
||||
for (int flow_id : flow_ids) {
|
||||
ss << flow_id << ",";
|
||||
}
|
||||
|
@ -312,15 +312,8 @@ void TcpSender::UpdateCongestionControl(const FeedbackPacket* fb) {
|
||||
}
|
||||
|
||||
bool TcpSender::LossEvent(const std::vector<uint16_t>& acked_packets) {
|
||||
int missing = 0;
|
||||
for (int i = last_acked_seq_num_ + 1; i <= acked_packets.back(); ++i) {
|
||||
if (std::find(acked_packets.begin(), acked_packets.end(), i) ==
|
||||
acked_packets.end()) {
|
||||
++missing;
|
||||
}
|
||||
}
|
||||
in_flight_ -= missing;
|
||||
return missing > 0;
|
||||
uint16_t expected = acked_packets.back() - last_acked_seq_num_;
|
||||
return expected - static_cast<uint16_t>(acked_packets.size()) > 0;
|
||||
}
|
||||
|
||||
Packets TcpSender::GeneratePackets(size_t num_packets) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user