Commit 8c958098 authored by Tarun Bansal's avatar Tarun Bansal Committed by Commit Bot

Network Quality Estimator: Remove logic to compute increase in RTT

In Network Quality Estimator (NQE), remove the logic to compute
increase in RTT since this is not being used anymore.

Change-Id: Icf1785cf5a11152c529ac40da7da43110dce382e
Bug: 895878
Reviewed-on: https://chromium-review.googlesource.com/c/1279946
Commit-Queue: Tarun Bansal <tbansal@chromium.org>
Reviewed-by: default avatarRyan Sturm <ryansturm@chromium.org>
Cr-Commit-Position: refs/heads/master@{#600117}
parent 5307906d
...@@ -239,7 +239,6 @@ NetworkQualityEstimator::NetworkQualityEstimator( ...@@ -239,7 +239,6 @@ NetworkQualityEstimator::NetworkQualityEstimator(
transport_rtt_observation_count_last_ect_computation_(0), transport_rtt_observation_count_last_ect_computation_(0),
new_rtt_observations_since_last_ect_computation_(0), new_rtt_observations_since_last_ect_computation_(0),
new_throughput_observations_since_last_ect_computation_(0), new_throughput_observations_since_last_ect_computation_(0),
increase_in_transport_rtt_updater_posted_(false),
effective_connection_type_(EFFECTIVE_CONNECTION_TYPE_UNKNOWN), effective_connection_type_(EFFECTIVE_CONNECTION_TYPE_UNKNOWN),
cached_estimate_applied_(false), cached_estimate_applied_(false),
net_log_(NetLogWithSource::Make( net_log_(NetLogWithSource::Make(
...@@ -929,120 +928,6 @@ void NetworkQualityEstimator::ComputeBandwidthDelayProduct() { ...@@ -929,120 +928,6 @@ void NetworkQualityEstimator::ComputeBandwidthDelayProduct() {
bandwidth_delay_product_kbits_.value()); bandwidth_delay_product_kbits_.value());
} }
void NetworkQualityEstimator::IncreaseInTransportRTTUpdater() {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
increase_in_transport_rtt_ = ComputeIncreaseInTransportRTT();
// Stop the timer if there was no recent data and |increase_in_transport_rtt_|
// could not be computed. This is fine because |increase_in_transport_rtt| can
// only be computed if there is recent transport RTT data, and the timer is
// restarted when there is a new observation.
if (!increase_in_transport_rtt_) {
increase_in_transport_rtt_updater_posted_ = false;
return;
}
increase_in_transport_rtt_updater_posted_ = true;
base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
FROM_HERE,
base::Bind(&NetworkQualityEstimator::IncreaseInTransportRTTUpdater,
weak_ptr_factory_.GetWeakPtr()),
params_->increase_in_transport_rtt_logging_interval());
}
base::Optional<int32_t> NetworkQualityEstimator::ComputeIncreaseInTransportRTT()
const {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
base::TimeTicks now = tick_clock_->NowTicks();
// The time after which the observations are considered to be recent enough to
// be a good proxy for the current level of congestion.
base::TimeTicks recent_start_time = now - params_->recent_time_threshold();
// Get the median transport RTT observed over the last 5 seconds for each
// remote host. This is an estimate of the current RTT which will be compared
// to the baseline obtained from historical data to detect an increase in RTT.
std::map<nqe::internal::IPHash, int32_t> recent_median_rtts;
std::map<nqe::internal::IPHash, size_t> recent_observation_counts;
rtt_ms_observations_[nqe::internal::OBSERVATION_CATEGORY_TRANSPORT]
.GetPercentileForEachHostWithCounts(recent_start_time, 50, base::nullopt,
&recent_median_rtts,
&recent_observation_counts);
if (recent_median_rtts.empty())
return base::nullopt;
// The time after which the observations are used to calculate the baseline.
// This is needed because the general network characteristics could have
// changed over time.
base::TimeTicks history_start_time =
now - params_->historical_time_threshold();
// Create a set of the remote hosts seen in the recent observations so that
// the data can be filtered while calculating the percentiles.
std::set<nqe::internal::IPHash> recent_hosts_set;
for (const auto& recent_median_rtts_for_host : recent_median_rtts)
recent_hosts_set.insert(recent_median_rtts_for_host.first);
// Get the minimum transport RTT observed over 1 minute for each remote host.
// This is an estimate of the true RTT which will be used as a baseline value
// to detect an increase in RTT. The minimum value is used here because the
// observed values cannot be lower than the true RTT. The median is used for
// the recent data to reduce noise in the calculation.
std::map<nqe::internal::IPHash, int32_t> historical_min_rtts;
std::map<nqe::internal::IPHash, size_t> historical_observation_counts;
rtt_ms_observations_[nqe::internal::OBSERVATION_CATEGORY_TRANSPORT]
.GetPercentileForEachHostWithCounts(
history_start_time, 0, recent_hosts_set, &historical_min_rtts,
&historical_observation_counts);
// Calculate the total observation counts for the hosts common to the recent
// data and the historical data.
size_t total_historical_count = 0;
size_t total_recent_count = 0;
for (const auto& recent_median_rtts_for_host : recent_median_rtts) {
nqe::internal::IPHash host = recent_median_rtts_for_host.first;
total_historical_count += historical_observation_counts[host];
total_recent_count += recent_observation_counts[host];
}
// Compute the increases in transport RTT for each remote host. Also compute
// the weight for each remote host based on the number of observations.
double total_weight = 0.0;
std::vector<nqe::internal::WeightedObservation> weighted_rtts;
for (auto& host : recent_hosts_set) {
// The relative weight signifies the amount of confidence in the data. The
// weight is higher if there were more observations. A regularization term
// of |1 / recent_hosts_set.size()| is added so that if one particular
// remote host has a lot of observations, the results do not get skewed.
double weight =
1.0 / recent_hosts_set.size() +
std::min(static_cast<double>(recent_observation_counts[host]) /
total_recent_count,
static_cast<double>(historical_observation_counts[host]) /
total_historical_count);
weighted_rtts.push_back(nqe::internal::WeightedObservation(
recent_median_rtts[host] - historical_min_rtts[host], weight));
total_weight += weight;
}
// Sort the increases in RTT for percentile computation.
std::sort(weighted_rtts.begin(), weighted_rtts.end());
// Calculate the weighted 50th percentile increase in transport RTT.
double desired_weight = 0.5 * total_weight;
for (nqe::internal::WeightedObservation wo : weighted_rtts) {
desired_weight -= wo.weight;
if (desired_weight <= 0)
return wo.value;
}
// Calculation will reach here when the 50th percentile is the last value.
return weighted_rtts.back().value;
}
void NetworkQualityEstimator::ComputeEffectiveConnectionType() { void NetworkQualityEstimator::ComputeEffectiveConnectionType() {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
...@@ -1530,11 +1415,6 @@ void NetworkQualityEstimator::OnUpdatedTransportRTTAvailable( ...@@ -1530,11 +1415,6 @@ void NetworkQualityEstimator::OnUpdatedTransportRTTAvailable(
current_network_id_.signal_strength, current_network_id_.signal_strength,
ProtocolSourceToObservationSource(protocol), host); ProtocolSourceToObservationSource(protocol), host);
AddAndNotifyObserversOfRTT(observation); AddAndNotifyObserversOfRTT(observation);
// Post a task to compute and update the increase in RTT if not already
// posted.
if (!increase_in_transport_rtt_updater_posted_)
IncreaseInTransportRTTUpdater();
} }
void NetworkQualityEstimator::AddAndNotifyObserversOfRTT( void NetworkQualityEstimator::AddAndNotifyObserversOfRTT(
......
...@@ -372,10 +372,6 @@ class NET_EXPORT NetworkQualityEstimator ...@@ -372,10 +372,6 @@ class NET_EXPORT NetworkQualityEstimator
// |observed_http_rtt| with the expected HTTP and transport RTT. // |observed_http_rtt| with the expected HTTP and transport RTT.
bool IsHangingRequest(base::TimeDelta observed_http_rtt) const; bool IsHangingRequest(base::TimeDelta observed_http_rtt) const;
base::Optional<int32_t> ComputeIncreaseInTransportRTTForTests() {
return ComputeIncreaseInTransportRTT();
}
// Returns the current network signal strength by querying the platform APIs. // Returns the current network signal strength by querying the platform APIs.
// Set to INT32_MIN when the value is unavailable. Otherwise, must be between // Set to INT32_MIN when the value is unavailable. Otherwise, must be between
// 0 and 4 (both inclusive). This may take into account many different radio // 0 and 4 (both inclusive). This may take into account many different radio
...@@ -421,11 +417,6 @@ class NET_EXPORT NetworkQualityEstimator ...@@ -421,11 +417,6 @@ class NET_EXPORT NetworkQualityEstimator
FRIEND_TEST_ALL_PREFIXES(NetworkQualityEstimatorTest, FRIEND_TEST_ALL_PREFIXES(NetworkQualityEstimatorTest,
ForceEffectiveConnectionTypeThroughFieldTrial); ForceEffectiveConnectionTypeThroughFieldTrial);
FRIEND_TEST_ALL_PREFIXES(NetworkQualityEstimatorTest, TestBDPComputation); FRIEND_TEST_ALL_PREFIXES(NetworkQualityEstimatorTest, TestBDPComputation);
FRIEND_TEST_ALL_PREFIXES(NetworkQualityEstimatorTest,
TestComputeIncreaseInTransportRTTFullHostsOverlap);
FRIEND_TEST_ALL_PREFIXES(
NetworkQualityEstimatorTest,
TestComputeIncreaseInTransportRTTPartialHostsOverlap);
FRIEND_TEST_ALL_PREFIXES(NetworkQualityEstimatorTest, FRIEND_TEST_ALL_PREFIXES(NetworkQualityEstimatorTest,
ObservationDiscardedIfCachedEstimateAvailable); ObservationDiscardedIfCachedEstimateAvailable);
FRIEND_TEST_ALL_PREFIXES(NetworkQualityEstimatorTest, FRIEND_TEST_ALL_PREFIXES(NetworkQualityEstimatorTest,
...@@ -528,17 +519,6 @@ class NET_EXPORT NetworkQualityEstimator ...@@ -528,17 +519,6 @@ class NET_EXPORT NetworkQualityEstimator
// |GetBandwidthDelayProductKbits|. // |GetBandwidthDelayProductKbits|.
void ComputeBandwidthDelayProduct(); void ComputeBandwidthDelayProduct();
// Computes the current increase in transport RTT in milliseconds over the
// baseline transport RTT due to congestion. This value can be interpreted as
// the additional delay caused due to an increase in queue length in the last
// mile. The baseline is computed using the transport RTT observations in the
// past 60 seconds. The current RTT is computed using the observations in the
// past 5 seconds. Returns an empty optional when there was no recent data.
base::Optional<int32_t> ComputeIncreaseInTransportRTT() const;
// Periodically updates |increase_in_transport_rtt_| by posting delayed tasks.
void IncreaseInTransportRTTUpdater();
// Gathers metrics for the next connection type. Called when there is a change // Gathers metrics for the next connection type. Called when there is a change
// in the connection type. // in the connection type.
void GatherEstimatesForNextConnectionType(); void GatherEstimatesForNextConnectionType();
...@@ -648,12 +628,6 @@ class NET_EXPORT NetworkQualityEstimator ...@@ -648,12 +628,6 @@ class NET_EXPORT NetworkQualityEstimator
// Current estimate of the bandwidth delay product (BDP) in kilobits. // Current estimate of the bandwidth delay product (BDP) in kilobits.
base::Optional<int32_t> bandwidth_delay_product_kbits_; base::Optional<int32_t> bandwidth_delay_product_kbits_;
// Current estimate of the increase in the transport RTT due to congestion.
base::Optional<int32_t> increase_in_transport_rtt_;
// This is true if there is a task posted for |IncreaseInTransportRTTUpdater|.
bool increase_in_transport_rtt_updater_posted_;
// Current effective connection type. It is updated on connection change // Current effective connection type. It is updated on connection change
// events. It is also updated every time there is network traffic (provided // events. It is also updated every time there is network traffic (provided
// the last computation was more than // the last computation was more than
......
...@@ -2716,87 +2716,6 @@ TEST_F(NetworkQualityEstimatorTest, TestBDPComputation) { ...@@ -2716,87 +2716,6 @@ TEST_F(NetworkQualityEstimatorTest, TestBDPComputation) {
(int32_t)(std::pow(2, 2) * std::pow(3, 8) / 1000)); (int32_t)(std::pow(2, 2) * std::pow(3, 8) / 1000));
} }
TEST_F(NetworkQualityEstimatorTest,
TestComputeIncreaseInTransportRTTFullHostsOverlap) {
base::SimpleTestTickClock tick_clock;
tick_clock.Advance(base::TimeDelta::FromMinutes(1));
std::map<std::string, std::string> variation_params;
variation_params["add_default_platform_observations"] = "false";
TestNetworkQualityEstimator estimator(variation_params);
estimator.SetTickClockForTesting(&tick_clock);
base::TimeTicks now = tick_clock.NowTicks();
base::TimeTicks recent = now - base::TimeDelta::FromMilliseconds(2500);
base::TimeTicks historical = now - base::TimeDelta::FromSeconds(20);
// Add historical observations. The 0 percentile for |host| is |10 * host|
// ms.
for (int host = 1; host <= 3; ++host) {
for (int rtt = 10 * host; rtt <= 10 * host + 20; ++rtt) {
estimator
.rtt_ms_observations_[nqe::internal::OBSERVATION_CATEGORY_TRANSPORT]
.AddObservation(NetworkQualityEstimator::Observation(
rtt, historical, INT32_MIN,
NETWORK_QUALITY_OBSERVATION_SOURCE_TCP,
static_cast<uint64_t>(host)));
}
}
// Add recent observations. The 50 percentile for |host| is |10 * host + 10|
// ms. The difference between them is expected to be 10 ms.
for (int host = 1; host <= 3; ++host) {
for (int rtt = 10 * host + 5; rtt <= 10 * host + 15; ++rtt) {
estimator
.rtt_ms_observations_[nqe::internal::OBSERVATION_CATEGORY_TRANSPORT]
.AddObservation(NetworkQualityEstimator::Observation(
rtt, recent, INT32_MIN, NETWORK_QUALITY_OBSERVATION_SOURCE_TCP,
static_cast<uint64_t>(host)));
}
}
EXPECT_EQ(10, estimator.ComputeIncreaseInTransportRTTForTests().value_or(0));
}
TEST_F(NetworkQualityEstimatorTest,
TestComputeIncreaseInTransportRTTPartialHostsOverlap) {
base::SimpleTestTickClock tick_clock;
tick_clock.Advance(base::TimeDelta::FromMinutes(1));
std::map<std::string, std::string> variation_params;
variation_params["add_default_platform_observations"] = "false";
TestNetworkQualityEstimator estimator(variation_params);
estimator.SetTickClockForTesting(&tick_clock);
base::TimeTicks now = tick_clock.NowTicks();
base::TimeTicks recent = now - base::TimeDelta::FromMilliseconds(2500);
base::TimeTicks historical = now - base::TimeDelta::FromSeconds(20);
// Add historical observations for hosts 1 and 2 with minimum RTT as
// |10 * host|.
for (int host = 1; host <= 2; ++host) {
for (int rtt = 10 * host; rtt <= 10 * host + 20; ++rtt) {
estimator.AddAndNotifyObserversOfRTT(NetworkQualityEstimator::Observation(
rtt, historical, INT32_MIN, NETWORK_QUALITY_OBSERVATION_SOURCE_TCP,
static_cast<uint64_t>(host)));
}
}
// Add recent observations, with median RTT as |10 + host| over the
// historical minimum for hosts 2 and 3.
for (int host = 2; host <= 3; ++host) {
for (int rtt = 11 * host + 5; rtt <= 11 * host + 15; ++rtt) {
estimator.AddAndNotifyObserversOfRTT(NetworkQualityEstimator::Observation(
rtt, recent, INT32_MIN, NETWORK_QUALITY_OBSERVATION_SOURCE_TCP,
static_cast<uint64_t>(host)));
}
}
// Only host 2 should have contributed to the calculation. Hence, the median
// should be |10 + 2 = 12|.
EXPECT_EQ(12, estimator.ComputeIncreaseInTransportRTTForTests().value_or(0));
}
// Verifies that when the cached network qualities from the prefs are available, // Verifies that when the cached network qualities from the prefs are available,
// then estimates from the platform or the external estimate provider are not // then estimates from the platform or the external estimate provider are not
// used. // used.
......
...@@ -112,62 +112,6 @@ base::Optional<int32_t> ObservationBuffer::GetPercentile( ...@@ -112,62 +112,6 @@ base::Optional<int32_t> ObservationBuffer::GetPercentile(
return weighted_observations.at(weighted_observations.size() - 1).value; return weighted_observations.at(weighted_observations.size() - 1).value;
} }
void ObservationBuffer::GetPercentileForEachHostWithCounts(
base::TimeTicks begin_timestamp,
int percentile,
const base::Optional<std::set<IPHash>>& host_filter,
std::map<IPHash, int32_t>* host_keyed_percentiles,
std::map<IPHash, size_t>* host_keyed_counts) const {
DCHECK_GE(Capacity(), Size());
DCHECK_LE(0, percentile);
DCHECK_GE(100, percentile);
host_keyed_percentiles->clear();
host_keyed_counts->clear();
// Filter the observations based on timestamp, and the
// presence of a valid host tag. Split the observations into a map keyed by
// the remote host to make it easy to calculate percentiles for each host.
std::map<IPHash, std::vector<int32_t>> host_keyed_observations;
for (const auto& observation : observations_) {
// Look at only those observations which have a |host|.
if (!observation.host())
continue;
IPHash host = observation.host().value();
if (host_filter && (host_filter->find(host) == host_filter->end()))
continue;
// Filter the observations recorded before |begin_timestamp|.
if (observation.timestamp() < begin_timestamp)
continue;
// Skip 0 values of RTT.
if (observation.value() < 1)
continue;
// Create the map entry if it did not already exist. Does nothing if
// |host| was seen before.
host_keyed_observations.emplace(host, std::vector<int32_t>());
host_keyed_observations[host].push_back(observation.value());
}
if (host_keyed_observations.empty())
return;
// Calculate the percentile values for each host.
for (auto& host_observations : host_keyed_observations) {
IPHash host = host_observations.first;
auto& observations = host_observations.second;
std::sort(observations.begin(), observations.end());
size_t count = observations.size();
DCHECK_GT(count, 0u);
(*host_keyed_counts)[host] = count;
int percentile_index = ((count - 1) * percentile) / 100;
(*host_keyed_percentiles)[host] = observations[percentile_index];
}
}
void ObservationBuffer::RemoveObservationsWithSource( void ObservationBuffer::RemoveObservationsWithSource(
bool deleted_observation_sources[NETWORK_QUALITY_OBSERVATION_SOURCE_MAX]) { bool deleted_observation_sources[NETWORK_QUALITY_OBSERVATION_SOURCE_MAX]) {
base::EraseIf(observations_, base::EraseIf(observations_,
......
...@@ -83,19 +83,6 @@ class NET_EXPORT_PRIVATE ObservationBuffer { ...@@ -83,19 +83,6 @@ class NET_EXPORT_PRIVATE ObservationBuffer {
tick_clock_ = tick_clock; tick_clock_ = tick_clock;
} }
// Computes percentiles separately for each host. Observations without
// a host tag are skipped. Only data from the hosts present in |host_filter|
// are considered. Observations before |begin_timestamp| are skipped. The
// percentile value for each host is returned in |host_keyed_percentiles|. The
// number of valid observations for each host used for the computation is
// returned in |host_keyed_counts|.
void GetPercentileForEachHostWithCounts(
base::TimeTicks begin_timestamp,
int percentile,
const base::Optional<std::set<IPHash>>& host_filter,
std::map<IPHash, int32_t>* host_keyed_percentiles,
std::map<IPHash, size_t>* host_keyed_counts) const;
// Removes all observations from the buffer whose corresponding entry in // Removes all observations from the buffer whose corresponding entry in
// |deleted_observation_sources| is set to true. For example, if index 1 and // |deleted_observation_sources| is set to true. For example, if index 1 and
// 3 in |deleted_observation_sources| are set to true, then all observations // 3 in |deleted_observation_sources| are set to true, then all observations
......
...@@ -370,174 +370,6 @@ TEST(NetworkQualityObservationBufferTest, TestGetMedianRTTSince) { ...@@ -370,174 +370,6 @@ TEST(NetworkQualityObservationBufferTest, TestGetMedianRTTSince) {
} }
} }
// Test that time filtering works and the remote hosts are split correctly.
TEST(NetworkQualityObservationBufferTest,
RestGetPercentileForEachRemoteHostSinceTimeStamp) {
std::map<std::string, std::string> variation_params;
NetworkQualityEstimatorParams params(variation_params);
base::SimpleTestTickClock tick_clock;
tick_clock.Advance(base::TimeDelta::FromMinutes(1));
const uint64_t new_host = 0x101010UL;
const int32_t new_host_observation = 1000;
const size_t new_host_num_obs = 10;
const uint64_t old_host = 0x202020UL;
const int32_t old_host_observation = 2000;
const size_t old_host_num_obs = 20;
ObservationBuffer buffer(&params, &tick_clock, 0.5, 1.0);
base::TimeTicks now = tick_clock.NowTicks();
for (unsigned int i = 0; i < old_host_num_obs; ++i) {
buffer.AddObservation(Observation(
old_host_observation, now - base::TimeDelta::FromSeconds(100),
INT32_MIN, NETWORK_QUALITY_OBSERVATION_SOURCE_HTTP, old_host));
}
for (unsigned int i = 0; i < new_host_num_obs; ++i) {
buffer.AddObservation(Observation(new_host_observation, now, INT32_MIN,
NETWORK_QUALITY_OBSERVATION_SOURCE_HTTP,
new_host));
}
std::map<uint64_t, int32_t> host_keyed_percentiles;
std::map<uint64_t, size_t> host_keyed_counts;
buffer.GetPercentileForEachHostWithCounts(
now - base::TimeDelta::FromSeconds(50), 50, base::nullopt,
&host_keyed_percentiles, &host_keyed_counts);
EXPECT_EQ(1u, host_keyed_percentiles.size());
EXPECT_EQ(1u, host_keyed_counts.size());
EXPECT_EQ(new_host_observation, host_keyed_percentiles[new_host]);
EXPECT_EQ(new_host_num_obs, host_keyed_counts[new_host]);
host_keyed_percentiles.clear();
host_keyed_counts.clear();
buffer.GetPercentileForEachHostWithCounts(
now - base::TimeDelta::FromSeconds(150), 50, base::nullopt,
&host_keyed_percentiles, &host_keyed_counts);
EXPECT_EQ(2u, host_keyed_percentiles.size());
EXPECT_EQ(2u, host_keyed_counts.size());
EXPECT_EQ(new_host_observation, host_keyed_percentiles[new_host]);
EXPECT_EQ(new_host_num_obs, host_keyed_counts[new_host]);
EXPECT_EQ(old_host_observation, host_keyed_percentiles[old_host]);
EXPECT_EQ(old_host_num_obs, host_keyed_counts[old_host]);
}
// Test that the result is split correctly for multiple remote hosts and that
// the count for each host is correct.
TEST(NetworkQualityObservationBufferTest,
RestGetPercentileForEachRemoteHostCounts) {
std::map<std::string, std::string> variation_params;
NetworkQualityEstimatorParams params(variation_params);
base::SimpleTestTickClock tick_clock;
tick_clock.Advance(base::TimeDelta::FromMinutes(1));
ObservationBuffer buffer(&params, &tick_clock, 0.5, 1.0);
base::TimeTicks now = tick_clock.NowTicks();
const size_t num_remote_hosts = 5;
// Add |2*i| observations having value |4*i| for host |i|.
for (unsigned int host_index = 1; host_index <= num_remote_hosts;
++host_index) {
for (unsigned int count = 1; count <= 2 * host_index; ++count) {
buffer.AddObservation(Observation(4 * host_index, now, INT32_MIN,
NETWORK_QUALITY_OBSERVATION_SOURCE_HTTP,
static_cast<uint64_t>(host_index)));
}
}
std::map<uint64_t, int32_t> host_keyed_percentiles;
std::map<uint64_t, size_t> host_keyed_counts;
buffer.GetPercentileForEachHostWithCounts(
base::TimeTicks(), 50, base::nullopt, &host_keyed_percentiles,
&host_keyed_counts);
EXPECT_EQ(num_remote_hosts, host_keyed_percentiles.size());
EXPECT_EQ(num_remote_hosts, host_keyed_counts.size());
for (unsigned int host_index = 1; host_index <= num_remote_hosts;
++host_index) {
EXPECT_EQ(2u * host_index,
host_keyed_counts[static_cast<uint64_t>(host_index)]);
EXPECT_EQ(static_cast<int32_t>(4 * host_index),
host_keyed_percentiles[static_cast<uint64_t>(host_index)]);
}
}
// Test that the percentiles are computed correctly for different remote hosts.
TEST(NetworkQualityObservationBufferTest,
RestGetPercentileForEachRemoteHostComputation) {
std::map<std::string, std::string> variation_params;
NetworkQualityEstimatorParams params(variation_params);
base::SimpleTestTickClock tick_clock;
tick_clock.Advance(base::TimeDelta::FromMinutes(1));
ObservationBuffer buffer(&params, &tick_clock, 0.5, 1.0);
base::TimeTicks now = tick_clock.NowTicks();
const size_t num_hosts = 3;
// For three different remote hosts, add observations such that the 50
// percentiles are different.
for (unsigned int host_index = 1; host_index <= num_hosts; host_index++) {
// Add |20 * host_index + 1| observations for host |host_index|.
for (unsigned int observation_value = 90 * host_index;
observation_value <= 110 * host_index; observation_value++) {
buffer.AddObservation(Observation(observation_value, now, INT32_MIN,
NETWORK_QUALITY_OBSERVATION_SOURCE_HTTP,
static_cast<uint64_t>(host_index)));
}
}
std::map<uint64_t, int32_t> host_keyed_percentiles;
std::map<uint64_t, size_t> host_keyed_counts;
// Test the computation of the median.
buffer.GetPercentileForEachHostWithCounts(
base::TimeTicks(), 50, base::nullopt, &host_keyed_percentiles,
&host_keyed_counts);
EXPECT_EQ(num_hosts, host_keyed_percentiles.size());
EXPECT_EQ(num_hosts, host_keyed_counts.size());
// The median must be equal to |100 * i| and the count must be equal to
// |20 * i + 1| for host |i|.
for (unsigned int host_index = 1; host_index <= num_hosts; host_index++) {
EXPECT_EQ(100u * host_index,
static_cast<uint32_t>(
host_keyed_percentiles[static_cast<uint64_t>(host_index)]));
EXPECT_EQ(static_cast<size_t>(20 * host_index + 1),
host_keyed_counts[static_cast<uint64_t>(host_index)]);
}
// Test the computation of 0th percentile.
buffer.GetPercentileForEachHostWithCounts(base::TimeTicks(), 0, base::nullopt,
&host_keyed_percentiles,
&host_keyed_counts);
EXPECT_EQ(num_hosts, host_keyed_percentiles.size());
EXPECT_EQ(num_hosts, host_keyed_counts.size());
// The 0 percentile must be equal to |90 * i| and the count must be equal to
// |20 * i| for host |i|.
for (unsigned int host_index = 1; host_index <= num_hosts; host_index++) {
EXPECT_EQ(90u * host_index,
static_cast<uint32_t>(
host_keyed_percentiles[static_cast<uint64_t>(host_index)]));
EXPECT_EQ(static_cast<size_t>(20 * host_index + 1),
host_keyed_counts[static_cast<uint64_t>(host_index)]);
}
// Test the computation of 100th percentile.
buffer.GetPercentileForEachHostWithCounts(
base::TimeTicks(), 100, base::nullopt, &host_keyed_percentiles,
&host_keyed_counts);
EXPECT_EQ(num_hosts, host_keyed_percentiles.size());
EXPECT_EQ(num_hosts, host_keyed_counts.size());
// The 0 percentile must be equal to |90 * i| and the count must be equal to
// |20 * i| for host |i|.
for (int host_index = 1; host_index <= 3; host_index++) {
EXPECT_EQ(110 * host_index,
host_keyed_percentiles[static_cast<uint64_t>(host_index)]);
EXPECT_EQ(static_cast<size_t>(20 * host_index + 1),
host_keyed_counts[static_cast<uint64_t>(host_index)]);
}
}
} // namespace } // namespace
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment