| // Copyright 2016 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "net/nqe/observation_buffer.h" |
| |
| #include <map> |
| #include <string> |
| #include <utility> |
| #include <vector> |
| |
| #include "base/logging.h" |
| #include "base/macros.h" |
| #include "base/test/simple_test_tick_clock.h" |
| #include "base/time/time.h" |
| #include "net/nqe/network_quality_estimator_params.h" |
| #include "net/nqe/network_quality_observation.h" |
| #include "net/nqe/network_quality_observation_source.h" |
| #include "starboard/types.h" |
| #include "testing/gtest/include/gtest/gtest.h" |
| |
| namespace net { |
| |
| namespace nqe { |
| |
| namespace internal { |
| |
| namespace { |
| |
| // Verify that the buffer size is never exceeded. |
| TEST(NetworkQualityObservationBufferTest, BoundedBuffer) { |
| std::map<std::string, std::string> variation_params; |
| NetworkQualityEstimatorParams params(variation_params); |
| base::SimpleTestTickClock tick_clock; |
| tick_clock.Advance(base::TimeDelta::FromMinutes(1)); |
| ObservationBuffer observation_buffer(¶ms, &tick_clock, 1.0, 1.0); |
| const base::TimeTicks now = |
| base::TimeTicks() + base::TimeDelta::FromSeconds(1); |
| for (int i = 1; i <= 1000; ++i) { |
| observation_buffer.AddObservation( |
| Observation(i, now, INT32_MIN, NETWORK_QUALITY_OBSERVATION_SOURCE_TCP)); |
| // The number of entries should be at most the maximum buffer size. |
| EXPECT_GE(300u, observation_buffer.Size()); |
| } |
| } |
| |
| // Verify that the percentiles are monotonically non-decreasing when a weight is |
| // applied. |
| TEST(NetworkQualityObservationBufferTest, GetPercentileWithWeights) { |
| std::map<std::string, std::string> variation_params; |
| NetworkQualityEstimatorParams params(variation_params); |
| base::SimpleTestTickClock tick_clock; |
| tick_clock.Advance(base::TimeDelta::FromMinutes(1)); |
| |
| ObservationBuffer observation_buffer(¶ms, &tick_clock, 0.98, 1.0); |
| const base::TimeTicks now = tick_clock.NowTicks(); |
| for (int i = 1; i <= 100; ++i) { |
| tick_clock.Advance(base::TimeDelta::FromSeconds(1)); |
| observation_buffer.AddObservation( |
| Observation(i, tick_clock.NowTicks(), INT32_MIN, |
| NETWORK_QUALITY_OBSERVATION_SOURCE_TCP)); |
| } |
| EXPECT_EQ(100U, observation_buffer.Size()); |
| |
| int32_t result_lowest = INT32_MAX; |
| int32_t result_highest = INT32_MIN; |
| |
| for (int i = 1; i <= 100; ++i) { |
| size_t observations_count = 0; |
| // Verify that i'th percentile is more than i-1'th percentile. |
| base::Optional<int32_t> result_i = observation_buffer.GetPercentile( |
| now, INT32_MIN, i, &observations_count); |
| EXPECT_EQ(100u, observations_count); |
| ASSERT_TRUE(result_i.has_value()); |
| result_lowest = std::min(result_lowest, result_i.value()); |
| |
| result_highest = std::max(result_highest, result_i.value()); |
| |
| base::Optional<int32_t> result_i_1 = observation_buffer.GetPercentile( |
| now, INT32_MIN, i - 1, &observations_count); |
| EXPECT_EQ(100u, observations_count); |
| ASSERT_TRUE(result_i_1.has_value()); |
| |
| EXPECT_LE(result_i_1.value(), result_i.value()); |
| } |
| EXPECT_LT(result_lowest, result_highest); |
| } |
| |
| // Verifies that the percentiles are correctly computed. All observations have |
| // the same timestamp. |
| TEST(NetworkQualityObservationBufferTest, PercentileSameTimestamps) { |
| 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(¶ms, &tick_clock, 0.5, 1.0); |
| ASSERT_EQ(0u, buffer.Size()); |
| ASSERT_LT(0u, buffer.Capacity()); |
| |
| const base::TimeTicks now = tick_clock.NowTicks(); |
| |
| size_t observations_count = 0; |
| // Percentiles should be unavailable when no observations are available. |
| EXPECT_FALSE( |
| buffer |
| .GetPercentile(base::TimeTicks(), INT32_MIN, 50, |
| &observations_count) |
| .has_value()); |
| EXPECT_EQ(0u, observations_count); |
| |
| // Insert samples from {1,2,3,..., 100}. First insert odd samples, then even |
| // samples. This helps in verifying that the order of samples does not matter. |
| for (int i = 1; i <= 99; i += 2) { |
| buffer.AddObservation(Observation(i, now, INT32_MIN, |
| NETWORK_QUALITY_OBSERVATION_SOURCE_HTTP)); |
| EXPECT_TRUE(buffer.GetPercentile(base::TimeTicks(), INT32_MIN, 50, nullptr) |
| .has_value()); |
| ASSERT_EQ(static_cast<size_t>(i / 2 + 1), buffer.Size()); |
| } |
| |
| for (int i = 2; i <= 100; i += 2) { |
| buffer.AddObservation(Observation(i, now, INT32_MIN, |
| NETWORK_QUALITY_OBSERVATION_SOURCE_HTTP)); |
| EXPECT_TRUE(buffer.GetPercentile(base::TimeTicks(), INT32_MIN, 50, nullptr) |
| .has_value()); |
| ASSERT_EQ(static_cast<size_t>(i / 2 + 50), buffer.Size()); |
| } |
| |
| ASSERT_EQ(100u, buffer.Size()); |
| |
| for (int i = 0; i <= 100; ++i) { |
| // Checks if the difference between actual result and the computed result is |
| // less than 1. This is required because computed percentiles may be |
| // slightly different from what is expected due to floating point |
| // computation errors and integer rounding off errors. |
| base::Optional<int32_t> result = buffer.GetPercentile( |
| base::TimeTicks(), INT32_MIN, i, &observations_count); |
| EXPECT_EQ(100u, observations_count); |
| EXPECT_TRUE(result.has_value()); |
| EXPECT_NEAR(result.value(), i, 1.0); |
| } |
| |
| EXPECT_FALSE( |
| buffer |
| .GetPercentile(now + base::TimeDelta::FromSeconds(1), INT32_MIN, 50, |
| &observations_count) |
| .has_value()); |
| EXPECT_EQ(0u, observations_count); |
| |
| // Percentiles should be unavailable when no observations are available. |
| buffer.Clear(); |
| EXPECT_FALSE( |
| buffer |
| .GetPercentile(base::TimeTicks(), INT32_MIN, 50, |
| &observations_count) |
| .has_value()); |
| EXPECT_EQ(0u, observations_count); |
| } |
| |
| // Verifies that the percentiles are correctly computed. Observations have |
| // different timestamps with half the observations being very old and the rest |
| // of them being very recent. Percentiles should factor in recent observations |
| // much more heavily than older samples. |
| TEST(NetworkQualityObservationBufferTest, PercentileDifferentTimestamps) { |
| 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(¶ms, &tick_clock, 0.5, 1.0); |
| const base::TimeTicks now = tick_clock.NowTicks(); |
| const base::TimeTicks very_old = now - base::TimeDelta::FromDays(7); |
| |
| size_t observations_count; |
| |
| // Network quality should be unavailable when no observations are available. |
| EXPECT_FALSE( |
| buffer |
| .GetPercentile(base::TimeTicks(), INT32_MIN, 50, |
| &observations_count) |
| .has_value()); |
| EXPECT_EQ(0u, observations_count); |
| |
| // First 50 samples have very old timestamps. |
| for (int i = 1; i <= 50; ++i) { |
| buffer.AddObservation(Observation(i, very_old, INT32_MIN, |
| NETWORK_QUALITY_OBSERVATION_SOURCE_HTTP)); |
| } |
| |
| // Next 50 (i.e., from 51 to 100) have recent timestamps. |
| for (int i = 51; i <= 100; ++i) { |
| buffer.AddObservation(Observation(i, now, INT32_MIN, |
| NETWORK_QUALITY_OBSERVATION_SOURCE_HTTP)); |
| } |
| |
| // Older samples have very little weight. So, all percentiles are >= 51 |
| // (lowest value among recent observations). |
| for (int i = 1; i < 100; ++i) { |
| // Checks if the difference between the two integers is less than 1. This is |
| // required because computed percentiles may be slightly different from |
| // what is expected due to floating point computation errors and integer |
| // rounding off errors. |
| base::Optional<int32_t> result = |
| buffer.GetPercentile(very_old, INT32_MIN, i, &observations_count); |
| EXPECT_TRUE(result.has_value()); |
| EXPECT_NEAR(result.value(), 51 + 0.49 * i, 1); |
| EXPECT_EQ(100u, observations_count); |
| } |
| |
| EXPECT_FALSE(buffer.GetPercentile(now + base::TimeDelta::FromSeconds(1), |
| INT32_MIN, 50, &observations_count)); |
| EXPECT_EQ(0u, observations_count); |
| } |
| |
| // Verifies that the percentiles are correctly computed. All observations have |
| // same timestamp with half the observations taken at low RSSI, and half the |
| // observations with high RSSI. Percentiles should be computed based on the |
| // current RSSI and the RSSI of the observations. |
| TEST(NetworkQualityObservationBufferTest, PercentileDifferentRSSI) { |
| 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(¶ms, &tick_clock, 1.0, 0.25); |
| const base::TimeTicks now = tick_clock.NowTicks(); |
| int32_t high_rssi = 4; |
| int32_t low_rssi = 0; |
| |
| // Network quality should be unavailable when no observations are available. |
| EXPECT_FALSE(buffer.GetPercentile(base::TimeTicks(), INT32_MIN, 50, nullptr) |
| .has_value()); |
| |
| // First 50 samples have very low RSSI. |
| for (int i = 1; i <= 50; ++i) { |
| buffer.AddObservation( |
| Observation(i, now, low_rssi, NETWORK_QUALITY_OBSERVATION_SOURCE_HTTP)); |
| } |
| |
| // Next 50 (i.e., from 51 to 100) have high RSSI. |
| for (int i = 51; i <= 100; ++i) { |
| buffer.AddObservation(Observation(i, now, high_rssi, |
| NETWORK_QUALITY_OBSERVATION_SOURCE_HTTP)); |
| } |
| |
| // When the current RSSI is |high_rssi|, higher weight should be assigned |
| // to observations that were taken at |high_rssi|. |
| for (int i = 1; i < 100; ++i) { |
| base::Optional<int32_t> result = |
| buffer.GetPercentile(now, high_rssi, i, nullptr); |
| EXPECT_TRUE(result.has_value()); |
| EXPECT_NEAR(result.value(), 51 + 0.49 * i, 2); |
| } |
| |
| // When the current RSSI is |low_rssi|, higher weight should be assigned |
| // to observations that were taken at |low_rssi|. |
| for (int i = 1; i < 100; ++i) { |
| base::Optional<int32_t> result = |
| buffer.GetPercentile(now, low_rssi, i, nullptr); |
| EXPECT_TRUE(result.has_value()); |
| EXPECT_NEAR(result.value(), i / 2, 2); |
| } |
| } |
| |
| // Verifies that the percentiles are correctly computed when some of the |
| // observation sources are disallowed. All observations have the same timestamp. |
| TEST(NetworkQualityObservationBufferTest, RemoveObservations) { |
| 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(¶ms, &tick_clock, 0.5, 1.0); |
| const base::TimeTicks now = tick_clock.NowTicks(); |
| |
| // Insert samples from {1,2,3,..., 100}. First insert odd samples, then even |
| // samples. This helps in verifying that the order of samples does not matter. |
| for (int i = 1; i <= 99; i += 2) { |
| buffer.AddObservation(Observation(i, now, INT32_MIN, |
| NETWORK_QUALITY_OBSERVATION_SOURCE_HTTP)); |
| } |
| EXPECT_EQ(50u, buffer.Size()); |
| |
| // Add samples for TCP and QUIC observations which should not be taken into |
| // account when computing the percentile. |
| for (int i = 1; i <= 99; i += 2) { |
| buffer.AddObservation(Observation(10000, now, INT32_MIN, |
| NETWORK_QUALITY_OBSERVATION_SOURCE_TCP)); |
| buffer.AddObservation(Observation(10000, now, INT32_MIN, |
| NETWORK_QUALITY_OBSERVATION_SOURCE_QUIC)); |
| } |
| EXPECT_EQ(150u, buffer.Size()); |
| |
| for (int i = 2; i <= 100; i += 2) { |
| buffer.AddObservation(Observation(i, now, INT32_MIN, |
| NETWORK_QUALITY_OBSERVATION_SOURCE_HTTP)); |
| } |
| EXPECT_EQ(200u, buffer.Size()); |
| |
| bool deleted_observation_sources[NETWORK_QUALITY_OBSERVATION_SOURCE_MAX] = { |
| false}; |
| |
| // Since all entries in |deleted_observation_sources| are set to false, no |
| // observations should be deleted. |
| buffer.RemoveObservationsWithSource(deleted_observation_sources); |
| EXPECT_EQ(200u, buffer.Size()); |
| |
| // 50 TCP and 50 QUIC observations should be deleted. |
| deleted_observation_sources[NETWORK_QUALITY_OBSERVATION_SOURCE_TCP] = true; |
| deleted_observation_sources[NETWORK_QUALITY_OBSERVATION_SOURCE_QUIC] = true; |
| buffer.RemoveObservationsWithSource(deleted_observation_sources); |
| EXPECT_EQ(100u, buffer.Size()); |
| |
| for (int i = 0; i <= 100; ++i) { |
| // Checks if the difference between the two integers is less than 1. This is |
| // required because computed percentiles may be slightly different from |
| // what is expected due to floating point computation errors and integer |
| // rounding off errors. |
| base::Optional<int32_t> result = |
| buffer.GetPercentile(base::TimeTicks(), INT32_MIN, i, |
| nullptr); |
| EXPECT_TRUE(result.has_value()); |
| EXPECT_NEAR(result.value(), i, 1); |
| } |
| |
| deleted_observation_sources[NETWORK_QUALITY_OBSERVATION_SOURCE_HTTP] = true; |
| buffer.RemoveObservationsWithSource(deleted_observation_sources); |
| EXPECT_EQ(0u, buffer.Size()); |
| } |
| |
| TEST(NetworkQualityObservationBufferTest, TestGetMedianRTTSince) { |
| 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(¶ms, &tick_clock, 0.5, 1.0); |
| base::TimeTicks now = tick_clock.NowTicks(); |
| base::TimeTicks old = now - base::TimeDelta::FromMilliseconds(1); |
| ASSERT_NE(old, now); |
| |
| // First sample has very old timestamp. |
| buffer.AddObservation( |
| Observation(1, old, INT32_MIN, NETWORK_QUALITY_OBSERVATION_SOURCE_HTTP)); |
| |
| buffer.AddObservation(Observation(100, now, INT32_MIN, |
| NETWORK_QUALITY_OBSERVATION_SOURCE_HTTP)); |
| |
| const struct { |
| base::TimeTicks start_timestamp; |
| bool expect_network_quality_available; |
| base::TimeDelta expected_url_request_rtt; |
| } tests[] = { |
| {now + base::TimeDelta::FromSeconds(10), false, |
| base::TimeDelta::FromMilliseconds(0)}, |
| {now, true, base::TimeDelta::FromMilliseconds(100)}, |
| {now - base::TimeDelta::FromMicroseconds(500), true, |
| base::TimeDelta::FromMilliseconds(100)}, |
| |
| }; |
| |
| for (const auto& test : tests) { |
| base::Optional<int32_t> url_request_rtt = |
| buffer.GetPercentile(test.start_timestamp, INT32_MIN, 50, nullptr); |
| EXPECT_EQ(test.expect_network_quality_available, |
| url_request_rtt.has_value()); |
| |
| if (test.expect_network_quality_available) { |
| EXPECT_EQ(test.expected_url_request_rtt.InMillisecondsF(), |
| url_request_rtt.value()); |
| } |
| } |
| } |
| |
| // 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(¶ms, &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(¶ms, &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(¶ms, &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 internal |
| |
| } // namespace nqe |
| |
| } // namespace net |