blob: 93adb31b448cb3e7e4ebc52d26cab170607254c8 [file] [log] [blame]
// Copyright 2017 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/network_quality_estimator_params.h"
#include <map>
#include <string>
#include "net/base/network_change_notifier.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace net {
namespace nqe {
namespace internal {
namespace {
// Tests if |weight_multiplier_per_second()| returns correct value for various
// values of half life parameter.
TEST(NetworkQualityEstimatorParamsTest, HalfLifeParam) {
std::map<std::string, std::string> variation_params;
const struct {
std::string description;
std::string variation_params_value;
double expected_weight_multiplier;
} tests[] = {
{"Half life parameter is not set, default value should be used",
std::string(), 0.988},
{"Half life parameter is set to negative, default value should be used",
"-100", 0.988},
{"Half life parameter is set to zero, default value should be used", "0",
0.988},
{"Half life parameter is set correctly", "10", 0.933},
};
for (const auto& test : tests) {
variation_params["HalfLifeSeconds"] = test.variation_params_value;
NetworkQualityEstimatorParams params(variation_params);
EXPECT_NEAR(test.expected_weight_multiplier,
params.weight_multiplier_per_second(), 0.001)
<< test.description;
}
}
// Test that the typical network qualities are set correctly.
TEST(NetworkQualityEstimatorParamsTest, TypicalNetworkQualities) {
std::map<std::string, std::string> variation_params;
NetworkQualityEstimatorParams params(variation_params);
// Typical network quality should not be set for Unknown and Offline.
for (size_t i = EFFECTIVE_CONNECTION_TYPE_UNKNOWN;
i <= EFFECTIVE_CONNECTION_TYPE_OFFLINE; ++i) {
EffectiveConnectionType ect = static_cast<EffectiveConnectionType>(i);
EXPECT_EQ(nqe::internal::InvalidRTT(),
params.TypicalNetworkQuality(ect).http_rtt());
EXPECT_EQ(nqe::internal::InvalidRTT(),
params.TypicalNetworkQuality(ect).transport_rtt());
}
// Typical network quality should be set for other effective connection
// types.
for (size_t i = EFFECTIVE_CONNECTION_TYPE_SLOW_2G;
i <= EFFECTIVE_CONNECTION_TYPE_3G; ++i) {
EffectiveConnectionType ect = static_cast<EffectiveConnectionType>(i);
// The typical RTT for an effective connection type should be at least as
// much as the threshold RTT.
EXPECT_NE(nqe::internal::InvalidRTT(),
params.TypicalNetworkQuality(ect).http_rtt());
EXPECT_GT(params.TypicalNetworkQuality(ect).http_rtt(),
params.ConnectionThreshold(ect).http_rtt());
EXPECT_NE(nqe::internal::InvalidRTT(),
params.TypicalNetworkQuality(ect).transport_rtt());
EXPECT_GT(params.TypicalNetworkQuality(ect).transport_rtt(),
params.ConnectionThreshold(ect).transport_rtt());
// The typical throughput for an effective connection type should not be
// more than the threshold throughput.
if (params.ConnectionThreshold(ect).downstream_throughput_kbps() !=
nqe::internal::INVALID_RTT_THROUGHPUT) {
EXPECT_LT(params.TypicalNetworkQuality(ect).downstream_throughput_kbps(),
params.ConnectionThreshold(ect).downstream_throughput_kbps());
}
}
// The typical network quality of 4G connection should be at least as fast
// as the threshold for 3G connection.
EXPECT_LT(
params.TypicalNetworkQuality(EFFECTIVE_CONNECTION_TYPE_4G).http_rtt(),
params.ConnectionThreshold(EFFECTIVE_CONNECTION_TYPE_3G).http_rtt());
EXPECT_LT(
params.TypicalNetworkQuality(EFFECTIVE_CONNECTION_TYPE_4G)
.transport_rtt(),
params.ConnectionThreshold(EFFECTIVE_CONNECTION_TYPE_3G).transport_rtt());
if (params.ConnectionThreshold(EFFECTIVE_CONNECTION_TYPE_3G)
.downstream_throughput_kbps() !=
nqe::internal::INVALID_RTT_THROUGHPUT) {
EXPECT_GT(params.TypicalNetworkQuality(EFFECTIVE_CONNECTION_TYPE_4G)
.downstream_throughput_kbps(),
params.ConnectionThreshold(EFFECTIVE_CONNECTION_TYPE_3G)
.downstream_throughput_kbps());
}
}
TEST(NetworkQualityEstimatorParamsTest, ObtainAlgorithmToUseFromParams) {
const struct {
bool set_variation_param;
std::string algorithm;
NetworkQualityEstimatorParams::EffectiveConnectionTypeAlgorithm
expected_algorithm;
} tests[] = {
{false, "",
NetworkQualityEstimatorParams::EffectiveConnectionTypeAlgorithm::
HTTP_RTT_AND_DOWNSTREAM_THROUGHOUT},
{true, "",
NetworkQualityEstimatorParams::EffectiveConnectionTypeAlgorithm::
HTTP_RTT_AND_DOWNSTREAM_THROUGHOUT},
{true, "HttpRTTAndDownstreamThroughput",
NetworkQualityEstimatorParams::EffectiveConnectionTypeAlgorithm::
HTTP_RTT_AND_DOWNSTREAM_THROUGHOUT},
{true, "TransportRTTOrDownstreamThroughput",
NetworkQualityEstimatorParams::EffectiveConnectionTypeAlgorithm::
TRANSPORT_RTT_OR_DOWNSTREAM_THROUGHOUT},
};
for (const auto& test : tests) {
std::map<std::string, std::string> variation_params;
if (test.set_variation_param)
variation_params["effective_connection_type_algorithm"] = test.algorithm;
NetworkQualityEstimatorParams params(variation_params);
EXPECT_EQ(test.expected_algorithm,
params.GetEffectiveConnectionTypeAlgorithm())
<< test.algorithm;
}
}
// Verify that for a given connection type, the default network quality values
// lie in the same range of ECT as the value returned by GetDefaultECT().
TEST(NetworkQualityEstimatorParamsTest, GetDefaultECT) {
std::map<std::string, std::string> variation_params;
NetworkQualityEstimatorParams params(variation_params);
for (size_t i = 0; i < NetworkChangeNotifier::ConnectionType::CONNECTION_LAST;
++i) {
NetworkChangeNotifier::ConnectionType connection_type =
static_cast<NetworkChangeNotifier::ConnectionType>(i);
EffectiveConnectionType ect = params.GetDefaultECT(connection_type);
EXPECT_LE(EFFECTIVE_CONNECTION_TYPE_2G, ect);
const nqe::internal::NetworkQuality& default_nq =
params.DefaultObservation(connection_type);
// Now verify that |default_nq| corresponds to |ect|.
if (ect == EFFECTIVE_CONNECTION_TYPE_4G) {
// If the expected effective connection type is 4G, then RTT values in
// |default_nq| should be lower than the threshold for ECT of 3G.
const nqe::internal::NetworkQuality& threshold_3g =
params.ConnectionThreshold(EFFECTIVE_CONNECTION_TYPE_3G);
EXPECT_LT(default_nq.http_rtt(), threshold_3g.http_rtt());
EXPECT_LT(default_nq.transport_rtt(), threshold_3g.transport_rtt());
EXPECT_TRUE(default_nq.downstream_throughput_kbps() >
threshold_3g.downstream_throughput_kbps() ||
threshold_3g.downstream_throughput_kbps() < 0);
} else {
// If the expected effective connection type is |ect|, then RTT values in
// |default_nq| should be (i) higher than the threshold for ECT of |ect|
// (ii) Lower than the threshold for |slower_ect|.
const nqe::internal::NetworkQuality& threshold_ect =
params.ConnectionThreshold(ect);
EffectiveConnectionType slower_ect =
static_cast<EffectiveConnectionType>(static_cast<int>(ect) - 1);
const nqe::internal::NetworkQuality& threshold_slower_ect =
params.ConnectionThreshold(slower_ect);
EXPECT_GT(default_nq.http_rtt(), threshold_ect.http_rtt());
EXPECT_GT(default_nq.transport_rtt(), threshold_ect.transport_rtt());
EXPECT_TRUE(default_nq.downstream_throughput_kbps() <
threshold_ect.downstream_throughput_kbps() ||
threshold_ect.downstream_throughput_kbps() < 0);
EXPECT_LT(default_nq.http_rtt(), threshold_slower_ect.http_rtt());
EXPECT_LT(default_nq.transport_rtt(),
threshold_slower_ect.transport_rtt());
EXPECT_TRUE(default_nq.downstream_throughput_kbps() >
threshold_slower_ect.downstream_throughput_kbps() ||
threshold_slower_ect.downstream_throughput_kbps() < 0);
}
}
}
} // namespace
} // namespace internal
} // namespace nqe
} // namespace net