// Copyright 2018 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 "services/network/resource_scheduler_params_manager.h"

#include <map>
#include <string>

#include "base/metrics/field_trial.h"
#include "base/metrics/field_trial_param_associator.h"
#include "base/metrics/field_trial_params.h"
#include "base/strings/string_number_conversions.h"
#include "base/test/scoped_feature_list.h"
#include "net/nqe/network_quality_estimator_params.h"
#include "services/network/public/cpp/features.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace network {

namespace {

// Should remain synchronized with the values in
// resouce_scheduler_params_manager.cc.
constexpr base::TimeDelta kLowerBoundQueuingDuration =
    base::TimeDelta::FromSeconds(15);
constexpr base::TimeDelta kUpperBoundQueuingDuration =
    base::TimeDelta::FromSeconds(120);
constexpr int kHttpRttMultiplierForQueuingDuration = 30;

class ResourceSchedulerParamsManagerTest : public testing::Test {
 public:
  ResourceSchedulerParamsManagerTest() : field_trial_list_(nullptr) {}

  ~ResourceSchedulerParamsManagerTest() override {}

  void ReadConfigTestHelper(size_t num_ranges) {
    const char kTrialName[] = "TrialName";
    const char kGroupName[] = "GroupName";

    base::FieldTrialParamAssociator::GetInstance()->ClearAllParamsForTesting();
    base::test::ScopedFeatureList scoped_feature_list;
    std::map<std::string, std::string> params;
    int index = 1;
    net::EffectiveConnectionType effective_connection_type =
        net::EFFECTIVE_CONNECTION_TYPE_SLOW_2G;
    while (effective_connection_type <
           net::EFFECTIVE_CONNECTION_TYPE_SLOW_2G + num_ranges) {
      std::string index_str = base::NumberToString(index);
      params["EffectiveConnectionType" + index_str] =
          net::GetNameForEffectiveConnectionType(effective_connection_type);
      params["MaxDelayableRequests" + index_str] = index_str + "0";
      params["NonDelayableWeight" + index_str] = "0";
      effective_connection_type = static_cast<net::EffectiveConnectionType>(
          static_cast<int>(effective_connection_type) + 1);
      ++index;
    }

    base::AssociateFieldTrialParams(kTrialName, kGroupName, params);
    base::FieldTrial* field_trial =
        base::FieldTrialList::CreateFieldTrial(kTrialName, kGroupName);
    std::unique_ptr<base::FeatureList> feature_list(
        std::make_unique<base::FeatureList>());
    feature_list->RegisterFieldTrialOverride(
        features::kThrottleDelayable.name,
        base::FeatureList::OVERRIDE_ENABLE_FEATURE, field_trial);
    scoped_feature_list.InitWithFeatureList(std::move(feature_list));

    ResourceSchedulerParamsManager resource_scheduler_params_manager;

    effective_connection_type = net::EFFECTIVE_CONNECTION_TYPE_SLOW_2G;
    while (effective_connection_type < net::EFFECTIVE_CONNECTION_TYPE_LAST) {
      if (effective_connection_type <
          net::EFFECTIVE_CONNECTION_TYPE_SLOW_2G + num_ranges) {
        int index = static_cast<int>(effective_connection_type) - 1;
        EXPECT_EQ(index * 10u, resource_scheduler_params_manager
                                   .GetParamsForEffectiveConnectionType(
                                       effective_connection_type)
                                   .max_delayable_requests);
        EXPECT_EQ(0, resource_scheduler_params_manager
                         .GetParamsForEffectiveConnectionType(
                             effective_connection_type)
                         .non_delayable_weight);
      } else {
        VerifyDefaultParams(resource_scheduler_params_manager,
                            effective_connection_type);
      }
      effective_connection_type = static_cast<net::EffectiveConnectionType>(
          static_cast<int>(effective_connection_type) + 1);
    }
  }

  void VerifyDefaultParams(
      const ResourceSchedulerParamsManager& resource_scheduler_params_manager,
      net::EffectiveConnectionType effective_connection_type) const {
    switch (effective_connection_type) {
      case net::EFFECTIVE_CONNECTION_TYPE_UNKNOWN:
      case net::EFFECTIVE_CONNECTION_TYPE_OFFLINE:
      case net::EFFECTIVE_CONNECTION_TYPE_4G:
        EXPECT_EQ(10u, resource_scheduler_params_manager
                           .GetParamsForEffectiveConnectionType(
                               effective_connection_type)
                           .max_delayable_requests);
        EXPECT_EQ(0.0, resource_scheduler_params_manager
                           .GetParamsForEffectiveConnectionType(
                               effective_connection_type)
                           .non_delayable_weight);
        EXPECT_FALSE(
            resource_scheduler_params_manager
                .GetParamsForEffectiveConnectionType(effective_connection_type)
                .delay_requests_on_multiplexed_connections);
        EXPECT_TRUE(
            resource_scheduler_params_manager
                .GetParamsForEffectiveConnectionType(effective_connection_type)
                .max_queuing_time.has_value());
        return;

      case net::EFFECTIVE_CONNECTION_TYPE_3G:
        EXPECT_EQ(8u, resource_scheduler_params_manager
                          .GetParamsForEffectiveConnectionType(
                              effective_connection_type)
                          .max_delayable_requests);
        EXPECT_EQ(3.0, resource_scheduler_params_manager
                           .GetParamsForEffectiveConnectionType(
                               effective_connection_type)
                           .non_delayable_weight);
        EXPECT_TRUE(
            resource_scheduler_params_manager
                .GetParamsForEffectiveConnectionType(effective_connection_type)
                .delay_requests_on_multiplexed_connections);
        EXPECT_TRUE(
            resource_scheduler_params_manager
                .GetParamsForEffectiveConnectionType(effective_connection_type)
                .max_queuing_time.has_value());
        return;

      case net::EFFECTIVE_CONNECTION_TYPE_SLOW_2G:
      case net::EFFECTIVE_CONNECTION_TYPE_2G:
        EXPECT_EQ(8u, resource_scheduler_params_manager
                          .GetParamsForEffectiveConnectionType(
                              effective_connection_type)
                          .max_delayable_requests);
        EXPECT_EQ(3.0, resource_scheduler_params_manager
                           .GetParamsForEffectiveConnectionType(
                               effective_connection_type)
                           .non_delayable_weight);
        EXPECT_TRUE(
            resource_scheduler_params_manager
                .GetParamsForEffectiveConnectionType(effective_connection_type)
                .delay_requests_on_multiplexed_connections);
        EXPECT_TRUE(
            resource_scheduler_params_manager
                .GetParamsForEffectiveConnectionType(effective_connection_type)
                .max_queuing_time.has_value());
        return;

      case net::EFFECTIVE_CONNECTION_TYPE_LAST:
        NOTREACHED();
        return;
    }
  }

 private:
  base::FieldTrialList field_trial_list_;
  DISALLOW_COPY_AND_ASSIGN(ResourceSchedulerParamsManagerTest);
};

TEST_F(ResourceSchedulerParamsManagerTest, VerifyAllDefaultParams) {
  ResourceSchedulerParamsManager resource_scheduler_params_manager;

  for (int effective_connection_type = net::EFFECTIVE_CONNECTION_TYPE_UNKNOWN;
       effective_connection_type < net::EFFECTIVE_CONNECTION_TYPE_LAST;
       ++effective_connection_type) {
    VerifyDefaultParams(
        resource_scheduler_params_manager,
        static_cast<net::EffectiveConnectionType>(effective_connection_type));
  }
}

// Verify that the params are parsed correctly when
// kDelayRequestsOnMultiplexedConnections is enabled.
TEST_F(ResourceSchedulerParamsManagerTest,
       DelayRequestsOnMultiplexedConnections) {
  ResourceSchedulerParamsManager resource_scheduler_params_manager;

  for (int effective_connection_type = net::EFFECTIVE_CONNECTION_TYPE_UNKNOWN;
       effective_connection_type < net::EFFECTIVE_CONNECTION_TYPE_LAST;
       ++effective_connection_type) {
    net::EffectiveConnectionType ect =
        static_cast<net::EffectiveConnectionType>(effective_connection_type);
    if (effective_connection_type == net::EFFECTIVE_CONNECTION_TYPE_SLOW_2G ||
        effective_connection_type == net::EFFECTIVE_CONNECTION_TYPE_2G ||
        effective_connection_type == net::EFFECTIVE_CONNECTION_TYPE_3G) {
      EXPECT_EQ(8u, resource_scheduler_params_manager
                        .GetParamsForEffectiveConnectionType(ect)
                        .max_delayable_requests);
      EXPECT_EQ(3.0, resource_scheduler_params_manager
                         .GetParamsForEffectiveConnectionType(ect)
                         .non_delayable_weight);
      EXPECT_TRUE(resource_scheduler_params_manager
                      .GetParamsForEffectiveConnectionType(ect)
                      .delay_requests_on_multiplexed_connections);
      EXPECT_TRUE(resource_scheduler_params_manager
                      .GetParamsForEffectiveConnectionType(ect)
                      .max_queuing_time.has_value());

    } else {
      VerifyDefaultParams(
          resource_scheduler_params_manager,
          static_cast<net::EffectiveConnectionType>(effective_connection_type));
    }
  }
}

// Verify that the params are parsed correctly when
// kDelayRequestsOnMultiplexedConnections is disabled.
TEST_F(ResourceSchedulerParamsManagerTest,
       DisableDelayRequestsOnMultiplexedConnections) {
  base::test::ScopedFeatureList scoped_feature_list;
  scoped_feature_list.InitAndDisableFeature(
      features::kDelayRequestsOnMultiplexedConnections);

  ResourceSchedulerParamsManager resource_scheduler_params_manager;

  for (int effective_connection_type = net::EFFECTIVE_CONNECTION_TYPE_UNKNOWN;
       effective_connection_type < net::EFFECTIVE_CONNECTION_TYPE_LAST;
       ++effective_connection_type) {
    net::EffectiveConnectionType ect =
        static_cast<net::EffectiveConnectionType>(effective_connection_type);
    if (effective_connection_type == net::EFFECTIVE_CONNECTION_TYPE_SLOW_2G ||
        effective_connection_type == net::EFFECTIVE_CONNECTION_TYPE_2G ||
        effective_connection_type == net::EFFECTIVE_CONNECTION_TYPE_3G) {
      EXPECT_EQ(8u, resource_scheduler_params_manager
                        .GetParamsForEffectiveConnectionType(ect)
                        .max_delayable_requests);
      EXPECT_EQ(3.0, resource_scheduler_params_manager
                         .GetParamsForEffectiveConnectionType(ect)
                         .non_delayable_weight);
      EXPECT_FALSE(resource_scheduler_params_manager
                       .GetParamsForEffectiveConnectionType(ect)
                       .delay_requests_on_multiplexed_connections);
      EXPECT_TRUE(resource_scheduler_params_manager
                      .GetParamsForEffectiveConnectionType(ect)
                      .max_queuing_time.has_value());

    } else {
      VerifyDefaultParams(
          resource_scheduler_params_manager,
          static_cast<net::EffectiveConnectionType>(effective_connection_type));
    }
  }
}

TEST_F(ResourceSchedulerParamsManagerTest, MaxQueuingTime) {
  base::FieldTrialParamAssociator::GetInstance()->ClearAllParamsForTesting();
  const std::string kTrialName = "TrialFoo";
  const std::string kGroupName = "GroupFoo";  // Value not used
  base::test::ScopedFeatureList scoped_feature_list;

  scoped_refptr<base::FieldTrial> trial =
      base::FieldTrialList::CreateFieldTrial(kTrialName, kGroupName);

  ResourceSchedulerParamsManager resource_scheduler_params_manager;

  for (int effective_connection_type = net::EFFECTIVE_CONNECTION_TYPE_UNKNOWN;
       effective_connection_type < net::EFFECTIVE_CONNECTION_TYPE_LAST;
       ++effective_connection_type) {
    net::EffectiveConnectionType ect =
        static_cast<net::EffectiveConnectionType>(effective_connection_type);
    base::TimeDelta typical_http_rtt =
        net::NetworkQualityEstimatorParams::GetDefaultTypicalHttpRtt(ect);

    if (effective_connection_type == net::EFFECTIVE_CONNECTION_TYPE_SLOW_2G ||
        effective_connection_type == net::EFFECTIVE_CONNECTION_TYPE_2G) {
      EXPECT_EQ(8u, resource_scheduler_params_manager
                        .GetParamsForEffectiveConnectionType(ect)
                        .max_delayable_requests);
      EXPECT_EQ(3.0, resource_scheduler_params_manager
                         .GetParamsForEffectiveConnectionType(ect)
                         .non_delayable_weight);
      EXPECT_TRUE(resource_scheduler_params_manager
                      .GetParamsForEffectiveConnectionType(ect)
                      .delay_requests_on_multiplexed_connections);
      EXPECT_EQ(typical_http_rtt * kHttpRttMultiplierForQueuingDuration,
                resource_scheduler_params_manager
                    .GetParamsForEffectiveConnectionType(ect)
                    .max_queuing_time);

    } else if (effective_connection_type == net::EFFECTIVE_CONNECTION_TYPE_3G) {
      EXPECT_EQ(8u, resource_scheduler_params_manager
                        .GetParamsForEffectiveConnectionType(ect)
                        .max_delayable_requests);
      EXPECT_EQ(3.0, resource_scheduler_params_manager
                         .GetParamsForEffectiveConnectionType(ect)
                         .non_delayable_weight);
      EXPECT_TRUE(resource_scheduler_params_manager
                      .GetParamsForEffectiveConnectionType(ect)
                      .delay_requests_on_multiplexed_connections);
      EXPECT_EQ(kLowerBoundQueuingDuration,
                resource_scheduler_params_manager
                    .GetParamsForEffectiveConnectionType(ect)
                    .max_queuing_time);

    } else if (effective_connection_type == net::EFFECTIVE_CONNECTION_TYPE_4G) {
      EXPECT_EQ(10u, resource_scheduler_params_manager
                         .GetParamsForEffectiveConnectionType(ect)
                         .max_delayable_requests);
      EXPECT_EQ(0.0, resource_scheduler_params_manager
                         .GetParamsForEffectiveConnectionType(ect)
                         .non_delayable_weight);
      EXPECT_FALSE(resource_scheduler_params_manager
                       .GetParamsForEffectiveConnectionType(ect)
                       .delay_requests_on_multiplexed_connections);
      EXPECT_EQ(kLowerBoundQueuingDuration,
                resource_scheduler_params_manager
                    .GetParamsForEffectiveConnectionType(ect)
                    .max_queuing_time);
    } else {
      EXPECT_EQ(10u, resource_scheduler_params_manager
                         .GetParamsForEffectiveConnectionType(ect)
                         .max_delayable_requests);
      EXPECT_EQ(0.0, resource_scheduler_params_manager
                         .GetParamsForEffectiveConnectionType(ect)
                         .non_delayable_weight);
      EXPECT_FALSE(resource_scheduler_params_manager
                       .GetParamsForEffectiveConnectionType(ect)
                       .delay_requests_on_multiplexed_connections);
      EXPECT_EQ(kUpperBoundQueuingDuration,
                resource_scheduler_params_manager
                    .GetParamsForEffectiveConnectionType(ect)
                    .max_queuing_time);
    }
  }
}

// Verify that the params are parsed correctly when
// kDelayRequestsOnMultiplexedConnections and kThrottleDelayable are enabled.
TEST_F(ResourceSchedulerParamsManagerTest, MultipleFieldTrialsEnabled) {
  base::FieldTrialParamAssociator::GetInstance()->ClearAllParamsForTesting();
  const std::string kTrialNameMultiplex = "TrialMultiplex";
  const std::string kTrialNameThrottleDelayable = "TrialThrottleDelayable";
  const std::string kGroupName = "GroupFoo";  // Value not used

  base::test::ScopedFeatureList scoped_feature_list;

  // Configure kDelayRequestsOnMultiplexedConnections experiment params.
  std::map<std::string, std::string> params_multiplex;
  params_multiplex["MaxEffectiveConnectionType"] = "3G";
  scoped_refptr<base::FieldTrial> trial_multiplex =
      base::FieldTrialList::CreateFieldTrial(kTrialNameMultiplex, kGroupName);
  ASSERT_TRUE(
      base::FieldTrialParamAssociator::GetInstance()->AssociateFieldTrialParams(
          kTrialNameMultiplex, kGroupName, params_multiplex));
  std::unique_ptr<base::FeatureList> feature_list(new base::FeatureList);
  feature_list->RegisterFieldTrialOverride(
      features::kDelayRequestsOnMultiplexedConnections.name,
      base::FeatureList::OVERRIDE_ENABLE_FEATURE, trial_multiplex.get());

  // Configure kThrottleDelayable experiment params.
  std::map<std::string, std::string> params_throttle_delayable;
  params_throttle_delayable["EffectiveConnectionType1"] = "3G";
  params_throttle_delayable["MaxDelayableRequests1"] = "12";
  params_throttle_delayable["NonDelayableWeight1"] = "3.0";
  params_throttle_delayable["EffectiveConnectionType2"] = "4G";
  params_throttle_delayable["MaxDelayableRequests2"] = "14";
  params_throttle_delayable["NonDelayableWeight2"] = "4.0";
  ASSERT_TRUE(base::AssociateFieldTrialParams(
      kTrialNameThrottleDelayable, kGroupName, params_throttle_delayable));
  base::FieldTrial* trial_throttle_delayable =
      base::FieldTrialList::CreateFieldTrial(kTrialNameThrottleDelayable,
                                             kGroupName);
  feature_list->RegisterFieldTrialOverride(
      features::kThrottleDelayable.name,
      base::FeatureList::OVERRIDE_ENABLE_FEATURE, trial_throttle_delayable);
  scoped_feature_list.InitWithFeatureList(std::move(feature_list));

  ResourceSchedulerParamsManager resource_scheduler_params_manager;

  // Verify the parsed params.
  for (int effective_connection_type = net::EFFECTIVE_CONNECTION_TYPE_UNKNOWN;
       effective_connection_type < net::EFFECTIVE_CONNECTION_TYPE_LAST;
       ++effective_connection_type) {
    net::EffectiveConnectionType ect =
        static_cast<net::EffectiveConnectionType>(effective_connection_type);
    if (effective_connection_type == net::EFFECTIVE_CONNECTION_TYPE_SLOW_2G ||
        effective_connection_type == net::EFFECTIVE_CONNECTION_TYPE_2G) {
      EXPECT_EQ(8u, resource_scheduler_params_manager
                        .GetParamsForEffectiveConnectionType(ect)
                        .max_delayable_requests);
      EXPECT_EQ(3.0, resource_scheduler_params_manager
                         .GetParamsForEffectiveConnectionType(ect)
                         .non_delayable_weight);
      EXPECT_TRUE(resource_scheduler_params_manager
                      .GetParamsForEffectiveConnectionType(ect)
                      .delay_requests_on_multiplexed_connections);
      EXPECT_TRUE(resource_scheduler_params_manager
                      .GetParamsForEffectiveConnectionType(ect)
                      .max_queuing_time.has_value());

    } else if (effective_connection_type == net::EFFECTIVE_CONNECTION_TYPE_3G) {
      EXPECT_EQ(12u, resource_scheduler_params_manager
                         .GetParamsForEffectiveConnectionType(ect)
                         .max_delayable_requests);
      EXPECT_EQ(3.0, resource_scheduler_params_manager
                         .GetParamsForEffectiveConnectionType(ect)
                         .non_delayable_weight);
      EXPECT_TRUE(resource_scheduler_params_manager
                      .GetParamsForEffectiveConnectionType(ect)
                      .delay_requests_on_multiplexed_connections);
      EXPECT_TRUE(resource_scheduler_params_manager
                      .GetParamsForEffectiveConnectionType(ect)
                      .max_queuing_time.has_value());

    } else if (effective_connection_type == net::EFFECTIVE_CONNECTION_TYPE_4G) {
      EXPECT_EQ(14u, resource_scheduler_params_manager
                         .GetParamsForEffectiveConnectionType(ect)
                         .max_delayable_requests);
      EXPECT_EQ(4.0, resource_scheduler_params_manager
                         .GetParamsForEffectiveConnectionType(ect)
                         .non_delayable_weight);
      EXPECT_FALSE(resource_scheduler_params_manager
                       .GetParamsForEffectiveConnectionType(ect)
                       .delay_requests_on_multiplexed_connections);
      EXPECT_TRUE(resource_scheduler_params_manager
                      .GetParamsForEffectiveConnectionType(ect)
                      .max_queuing_time.has_value());

    } else {
      VerifyDefaultParams(resource_scheduler_params_manager, ect);
    }
  }
}

// Test that a configuration with bad strings does not break the parser, and
// the parser stops reading the configuration after it encounters the first
// missing index.
TEST_F(ResourceSchedulerParamsManagerTest, ReadInvalidConfigTest) {
  base::FieldTrialParamAssociator::GetInstance()->ClearAllParamsForTesting();
  const char kTrialName[] = "TrialName";
  const char kGroupName[] = "GroupName";

  base::test::ScopedFeatureList scoped_feature_list;
  std::map<std::string, std::string> params;
  // Skip configuration parameters for index 2 to test that the parser stops
  // when it cannot find the parameters for an index.
  for (int range_index : {1, 3, 4}) {
    std::string index_str = base::NumberToString(range_index);
    params["EffectiveConnectionType" + index_str] = "Slow-2G";
    params["MaxDelayableRequests" + index_str] = index_str + "0";
    params["NonDelayableWeight" + index_str] = "0";
  }
  // Add some bad configuration strigs to ensure that the parser does not break.
  params["BadConfigParam1"] = "100";
  params["BadConfigParam2"] = "100";

  base::AssociateFieldTrialParams(kTrialName, kGroupName, params);
  base::FieldTrial* field_trial =
      base::FieldTrialList::CreateFieldTrial(kTrialName, kGroupName);
  std::unique_ptr<base::FeatureList> feature_list(
      std::make_unique<base::FeatureList>());
  feature_list->RegisterFieldTrialOverride(
      features::kThrottleDelayable.name,
      base::FeatureList::OVERRIDE_ENABLE_FEATURE, field_trial);
  scoped_feature_list.InitWithFeatureList(std::move(feature_list));

  ResourceSchedulerParamsManager resource_scheduler_params_manager;

  // Only the first configuration parameter must be read because a match was not
  // found for index 2. The configuration parameters with index 3 and 4 must be
  // ignored, even though they are valid configuration parameters.
  EXPECT_EQ(10u, resource_scheduler_params_manager
                     .GetParamsForEffectiveConnectionType(
                         net::EFFECTIVE_CONNECTION_TYPE_SLOW_2G)
                     .max_delayable_requests);
  EXPECT_EQ(0.0, resource_scheduler_params_manager
                     .GetParamsForEffectiveConnectionType(
                         net::EFFECTIVE_CONNECTION_TYPE_SLOW_2G)
                     .non_delayable_weight);

  VerifyDefaultParams(resource_scheduler_params_manager,
                      net::EFFECTIVE_CONNECTION_TYPE_2G);
  VerifyDefaultParams(resource_scheduler_params_manager,
                      net::EFFECTIVE_CONNECTION_TYPE_3G);
  VerifyDefaultParams(resource_scheduler_params_manager,
                      net::EFFECTIVE_CONNECTION_TYPE_4G);
}

// Test that a configuration with 2 ranges is read correctly.
TEST_F(ResourceSchedulerParamsManagerTest, ReadValidConfigTest2) {
  ReadConfigTestHelper(2);
}

// Test that a configuration with 3 ranges is read correctly.
TEST_F(ResourceSchedulerParamsManagerTest, ReadValidConfigTest3) {
  ReadConfigTestHelper(3);
}

TEST_F(ResourceSchedulerParamsManagerTest, ThrottleDelayableDisabled) {
  base::FieldTrialParamAssociator::GetInstance()->ClearAllParamsForTesting();

  const char kTrialName[] = "TrialName";
  const char kGroupName[] = "GroupName";

  base::FieldTrial* field_trial =
      base::FieldTrialList::CreateFieldTrial(kTrialName, kGroupName);

  base::test::ScopedFeatureList scoped_feature_list;

  std::unique_ptr<base::FeatureList> feature_list(
      std::make_unique<base::FeatureList>());

  feature_list->RegisterFieldTrialOverride(
      "ThrottleDelayable", base::FeatureList::OVERRIDE_DISABLE_FEATURE,
      field_trial);
  scoped_feature_list.InitWithFeatureList(std::move(feature_list));

  ResourceSchedulerParamsManager resource_scheduler_params_manager;

  VerifyDefaultParams(resource_scheduler_params_manager,
                      net::EFFECTIVE_CONNECTION_TYPE_SLOW_2G);
  VerifyDefaultParams(resource_scheduler_params_manager,
                      net::EFFECTIVE_CONNECTION_TYPE_2G);
  VerifyDefaultParams(resource_scheduler_params_manager,
                      net::EFFECTIVE_CONNECTION_TYPE_3G);
  VerifyDefaultParams(resource_scheduler_params_manager,
                      net::EFFECTIVE_CONNECTION_TYPE_4G);
}

TEST_F(ResourceSchedulerParamsManagerTest,
       MaxDelayableRequestsAndNonDelayableWeightSet) {
  base::test::ScopedFeatureList scoped_feature_list;

  std::map<std::string, std::string> params;

  params["EffectiveConnectionType1"] = "Slow-2G";
  size_t max_delayable_requests_slow_2g = 2u;
  double non_delayable_weight_slow_2g = 2.0;
  params["MaxDelayableRequests1"] =
      base::NumberToString(max_delayable_requests_slow_2g);
  params["NonDelayableWeight1"] =
      base::NumberToString(non_delayable_weight_slow_2g);

  params["EffectiveConnectionType2"] = "3G";
  size_t max_delayable_requests_3g = 4u;
  double non_delayable_weight_3g = 0.0;
  params["MaxDelayableRequests2"] =
      base::NumberToString(max_delayable_requests_3g);
  params["NonDelayableWeight2"] = base::NumberToString(non_delayable_weight_3g);

  base::FieldTrialParamAssociator::GetInstance()->ClearAllParamsForTesting();
  const char kTrialName[] = "TrialName";
  const char kGroupName[] = "GroupName";

  ASSERT_TRUE(base::AssociateFieldTrialParams(kTrialName, kGroupName, params));
  base::FieldTrial* field_trial =
      base::FieldTrialList::CreateFieldTrial(kTrialName, kGroupName);
  ASSERT_TRUE(field_trial);

  std::unique_ptr<base::FeatureList> feature_list(
      std::make_unique<base::FeatureList>());

  feature_list->RegisterFieldTrialOverride(
      "ThrottleDelayable", base::FeatureList::OVERRIDE_ENABLE_FEATURE,
      field_trial);
  scoped_feature_list.InitWithFeatureList(std::move(feature_list));

  ResourceSchedulerParamsManager resource_scheduler_params_manager;

  EXPECT_EQ(max_delayable_requests_slow_2g,
            resource_scheduler_params_manager
                .GetParamsForEffectiveConnectionType(
                    net::EFFECTIVE_CONNECTION_TYPE_SLOW_2G)
                .max_delayable_requests);
  EXPECT_EQ(non_delayable_weight_slow_2g,
            resource_scheduler_params_manager
                .GetParamsForEffectiveConnectionType(
                    net::EFFECTIVE_CONNECTION_TYPE_SLOW_2G)
                .non_delayable_weight);
  EXPECT_TRUE(resource_scheduler_params_manager
                  .GetParamsForEffectiveConnectionType(
                      net::EFFECTIVE_CONNECTION_TYPE_SLOW_2G)
                  .max_queuing_time.has_value());

  VerifyDefaultParams(resource_scheduler_params_manager,
                      net::EFFECTIVE_CONNECTION_TYPE_2G);

  EXPECT_EQ(max_delayable_requests_3g,
            resource_scheduler_params_manager
                .GetParamsForEffectiveConnectionType(
                    net::EFFECTIVE_CONNECTION_TYPE_3G)
                .max_delayable_requests);
  EXPECT_EQ(non_delayable_weight_3g, resource_scheduler_params_manager
                                         .GetParamsForEffectiveConnectionType(
                                             net::EFFECTIVE_CONNECTION_TYPE_3G)
                                         .non_delayable_weight);
  EXPECT_TRUE(resource_scheduler_params_manager
                  .GetParamsForEffectiveConnectionType(
                      net::EFFECTIVE_CONNECTION_TYPE_3G)
                  .max_queuing_time.has_value());

  VerifyDefaultParams(resource_scheduler_params_manager,
                      net::EFFECTIVE_CONNECTION_TYPE_4G);
}

}  // unnamed namespace

}  // namespace network
