scoped_feature_list.h 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. // Copyright 2016 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #ifndef BASE_TEST_SCOPED_FEATURE_LIST_H_
  5. #define BASE_TEST_SCOPED_FEATURE_LIST_H_
  6. #include <map>
  7. #include <memory>
  8. #include <string>
  9. #include <vector>
  10. #include "base/feature_list.h"
  11. #include "base/memory/ref_counted.h"
  12. #include "base/metrics/field_trial.h"
  13. #include "base/metrics/field_trial_params.h"
  14. namespace base {
  15. namespace test {
  16. // ScopedFeatureList resets the global FeatureList instance to a new empty
  17. // instance and restores the original instance upon destruction. When using the
  18. // non-deprecated APIs, a corresponding FieldTrialList is also created.
  19. //
  20. // Note: Re-using the same object is not allowed. To reset the feature
  21. // list and initialize it anew, destroy an existing scoped list and init
  22. // a new one.
  23. //
  24. // If multiple instances of this class are used in a nested fashion, they
  25. // should be destroyed in the opposite order of their Init*() methods being
  26. // called.
  27. //
  28. // ScopedFeatureList needs to be initialized (via one of Init*() methods)
  29. // before running code that inspects the state of features, such as in the
  30. // constructor of the test harness.
  31. //
  32. // WARNING: To be clear, in multithreaded test environments (such as browser
  33. // tests) there may background threads using FeatureList before the test body is
  34. // even entered. In these cases it is imperative that ScopedFeatureList be
  35. // initialized BEFORE those threads are started, hence the recommendation to do
  36. // initialization in the test harness's constructor.
  37. class ScopedFeatureList final {
  38. public:
  39. ScopedFeatureList();
  40. ~ScopedFeatureList();
  41. struct FeatureAndParams {
  42. FeatureAndParams(const Feature& feature, const FieldTrialParams& params);
  43. ~FeatureAndParams();
  44. FeatureAndParams(const FeatureAndParams& other);
  45. const Feature& feature;
  46. const FieldTrialParams params;
  47. };
  48. // Resets the instance to a non-initialized state.
  49. void Reset();
  50. // Initializes and registers a FeatureList instance without any additional
  51. // enabled or disabled features. Existing state, if any, will be kept. This is
  52. // equivalent to calling InitWithFeatures({}, {}).
  53. void Init();
  54. // WARNING: This method will reset any globally configured features to their
  55. // default values, which can hide feature interaction bugs. Please use
  56. // sparingly. https://crbug.com/713390
  57. // Initializes and registers the given FeatureList instance.
  58. void InitWithFeatureList(std::unique_ptr<FeatureList> feature_list);
  59. // WARNING: This method will reset any globally configured features to their
  60. // default values, which can hide feature interaction bugs. Please use
  61. // sparingly. https://crbug.com/713390
  62. // Initializes and registers a FeatureList instance with only the given
  63. // enabled and disabled features (comma-separated names). If feature params
  64. // are provided in the |enable_features|, this also associates features to
  65. // their params.
  66. void InitFromCommandLine(const std::string& enable_features,
  67. const std::string& disable_features);
  68. // Initializes and registers a FeatureList instance based on present
  69. // FeatureList and overridden with the given enabled and disabled features.
  70. // Any feature overrides already present in the global FeatureList will
  71. // continue to apply, unless they conflict with the overrides passed into this
  72. // method. This is important for testing potentially unexpected feature
  73. // interactions.
  74. void InitWithFeatures(const std::vector<Feature>& enabled_features,
  75. const std::vector<Feature>& disabled_features);
  76. // Initializes and registers a FeatureList instance based on present
  77. // FeatureList and overridden with single enabled feature.
  78. void InitAndEnableFeature(const Feature& feature);
  79. // Initializes and registers a FeatureList instance based on present
  80. // FeatureList and overridden with single enabled feature and associated field
  81. // trial parameters.
  82. // Note: this creates a scoped global field trial list if there is not
  83. // currently one.
  84. void InitAndEnableFeatureWithParameters(
  85. const Feature& feature,
  86. const FieldTrialParams& feature_parameters);
  87. // Initializes and registers a FeatureList instance based on present
  88. // FeatureList and overridden with the given enabled features and the
  89. // specified field trial parameters, and the given disabled features.
  90. // Note: This creates a scoped global field trial list if there is not
  91. // currently one.
  92. void InitWithFeaturesAndParameters(
  93. const std::vector<FeatureAndParams>& enabled_features,
  94. const std::vector<Feature>& disabled_features);
  95. // Initializes and registers a FeatureList instance based on present
  96. // FeatureList and overridden with single disabled feature.
  97. void InitAndDisableFeature(const Feature& feature);
  98. // Initializes and registers a FeatureList instance based on present
  99. // FeatureList and overriden with a single feature either enabled or
  100. // disabled depending on |enabled|.
  101. void InitWithFeatureState(const Feature& feature, bool enabled);
  102. private:
  103. // Initializes and registers a FeatureList instance based on present
  104. // FeatureList and overridden with the given enabled and disabled features.
  105. // Any feature overrides already present in the global FeatureList will
  106. // continue to apply, unless they conflict with the overrides passed into this
  107. // method.
  108. // Features to enable may be specified through either |enabled_features| or
  109. // |enabled_feature_and_params|, but not both (i.e. one of these must be
  110. // empty).
  111. void InitWithFeaturesImpl(
  112. const std::vector<Feature>& enabled_features,
  113. const std::vector<FeatureAndParams>& enabled_features_and_params,
  114. const std::vector<Feature>& disabled_features);
  115. // Initializes and registers a FeatureList instance based on present
  116. // FeatureList and overridden with single enabled feature and associated field
  117. // trial override.
  118. // |trial| is expected to outlive the ScopedFeatureList.
  119. void InitAndEnableFeatureWithFieldTrialOverride(const Feature& feature,
  120. FieldTrial* trial);
  121. bool init_called_ = false;
  122. std::unique_ptr<FeatureList> original_feature_list_;
  123. base::FieldTrialList* original_field_trial_list_ = nullptr;
  124. std::string original_params_;
  125. std::unique_ptr<base::FieldTrialList> field_trial_list_;
  126. DISALLOW_COPY_AND_ASSIGN(ScopedFeatureList);
  127. };
  128. } // namespace test
  129. } // namespace base
  130. #endif // BASE_TEST_SCOPED_FEATURE_LIST_H_