variations_test_utils.cc 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248
  1. // Copyright 2020 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. #include "components/variations/variations_test_utils.h"
  5. #include "base/base64.h"
  6. #include "base/command_line.h"
  7. #include "base/feature_list.h"
  8. #include "components/metrics/clean_exit_beacon.h"
  9. #include "components/metrics/metrics_pref_names.h"
  10. #include "components/prefs/pref_service.h"
  11. #include "components/variations/field_trial_config/fieldtrial_testing_config.h"
  12. #include "components/variations/pref_names.h"
  13. #include "components/variations/proto/client_variations.pb.h"
  14. #include "components/variations/variations_associated_data.h"
  15. #include "components/variations/variations_switches.h"
  16. #include "third_party/zlib/google/compression_utils.h"
  17. namespace variations {
  18. namespace {
  19. const char* kTestSeed_StudyNames[] = {"UMA-Uniformity-Trial-10-Percent"};
  20. const char kTestSeed_Base64UncompressedData[] =
  21. "CigxZDI5NDY0ZmIzZDc4ZmYxNTU2ZTViNTUxYzY0NDdjYmM3NGU1ZmQwEr0BCh9VTUEtVW5pZm"
  22. "9ybWl0eS1UcmlhbC0xMC1QZXJjZW50GICckqUFOAFCB2RlZmF1bHRKCwoHZGVmYXVsdBABSgwK"
  23. "CGdyb3VwXzAxEAFKDAoIZ3JvdXBfMDIQAUoMCghncm91cF8wMxABSgwKCGdyb3VwXzA0EAFKDA"
  24. "oIZ3JvdXBfMDUQAUoMCghncm91cF8wNhABSgwKCGdyb3VwXzA3EAFKDAoIZ3JvdXBfMDgQAUoM"
  25. "Cghncm91cF8wORAB";
  26. const char kTestSeed_Base64CompressedData[] =
  27. "H4sIAAAAAAAAAOPSMEwxsjQxM0lLMk4xt0hLMzQ1NUs1TTI1NUw2MzExT05KNjdJNU1LMRDay8"
  28. "glH+rrqBual5mWX5SbWVKpG1KUmZija2igG5BalJyaVyLRMGfSUlYLRif2lNS0xNKcEi9uLhhT"
  29. "gNGLh4sjvSi/tCDewBCFZ4TCM0bhmaDwTFF4Zig8cxSeBQrPUoARAEVeJPrqAAAA";
  30. const char kTestSeed_Base64Signature[] =
  31. "MEQCIDD1IVxjzWYncun+9IGzqYjZvqxxujQEayJULTlbTGA/AiAr0oVmEgVUQZBYq5VLOSvy96"
  32. "JkMYgzTkHPwbv7K/CmgA==";
  33. const char* kCrashingSeed_StudyNames[] = {"CrashingStudy"};
  34. const char kCrashingSeed_Base64UncompressedData[] =
  35. "CigzNWVkMmQ5ZTM1NGI0MTRiZWZkZjkzMGE3MzQwOTQwMTljMDE2MmYxEp4CCg1DcmFzaGluZ1"
  36. "N0dWR5OAFKOAoNRW5hYmxlZExhdW5jaBBkYiUKI0ZvcmNlRmllbGRUcmlhbFNldHVwQ3Jhc2hG"
  37. "b3JUZXN0aW5nSlcKLEZvcmNlZE9uX0ZvcmNlRmllbGRUcmlhbFNldHVwQ3Jhc2hGb3JUZXN0aW"
  38. "5nEABiJRojRm9yY2VGaWVsZFRyaWFsU2V0dXBDcmFzaEZvclRlc3RpbmdKWAotRm9yY2VkT2Zm"
  39. "X0ZvcmNlRmllbGRUcmlhbFNldHVwQ3Jhc2hGb3JUZXN0aW5nEABiJSIjRm9yY2VGaWVsZFRyaW"
  40. "FsU2V0dXBDcmFzaEZvclRlc3RpbmdSHhIEOTEuKiAAIAEgAiADKAQoBSgGKAAoASgCKAMoCSIt"
  41. "aGFzaC80YWE1NmExZGMzMGRmYzc2NzYxNTI0OGQ2ZmVlMjk4MzAxOThiMjc2";
  42. const char kCrashingSeed_Base64CompressedData[] =
  43. "H4sIAAAAAAAAAI3QwUvDMBTH8babwgKDsaMHKZNBEKdJk6bJWbbDEAQ30JskeS+2UKp07cF/"
  44. "Zn+rZfgH9Py+73P4ESpyhAwMilw6yaXDAMEIZgshmZGMG8+4ygJfnhMyf27tqayar0PXw6+"
  45. "O95rMt411NcKL7RtfLsCtyd3uu/W4q7CGY1vZ+oBd/"
  46. "3P5HA5HPHUDsH8nD5cMXpvPEf0icuubUfAH2fzDIYyVV2Pkt9vl1PDH+zRK4zRJJ3RKr+"
  47. "g1jWhMEzqhs9WmHPonaW2uLAcvGARfqELxPJMaVEDMjBbDotplhfoDs9NLbnoBAAA=";
  48. const char kCrashingSeed_Base64Signature[] =
  49. "MEQCIEn1+VsBfNA93dxzpk+BLhdO91kMQnofxfTK5Uo8vDi8AiAnTCFCIPgEGWNOKzuKfNWn6"
  50. "emB6pnGWjSTbI/pvfxHnw==";
  51. // Create mock testing config equivalent to:
  52. // {
  53. // "UnitTest": [
  54. // {
  55. // "platforms": [
  56. // "android",
  57. // "android_weblayer",
  58. // "android_webview",
  59. // "chromeos",
  60. // "chromeos_lacros",
  61. // "fuchsia",
  62. // "ios",
  63. // "linux",
  64. // "mac",
  65. // "windows"
  66. // ],
  67. // "experiments": [
  68. // {
  69. // "name": "Enabled",
  70. // "params": {
  71. // "x": "1"
  72. // },
  73. // "enable_features": [
  74. // "UnitTestEnabled"
  75. // ]
  76. // }
  77. // ]
  78. // }
  79. // ]
  80. // }
  81. const Study::Platform array_kFieldTrialConfig_platforms_0[] = {
  82. Study::PLATFORM_ANDROID,
  83. Study::PLATFORM_ANDROID_WEBLAYER,
  84. Study::PLATFORM_ANDROID_WEBVIEW,
  85. Study::PLATFORM_CHROMEOS,
  86. Study::PLATFORM_CHROMEOS_LACROS,
  87. Study::PLATFORM_FUCHSIA,
  88. Study::PLATFORM_IOS,
  89. Study::PLATFORM_LINUX,
  90. Study::PLATFORM_MAC,
  91. Study::PLATFORM_WINDOWS,
  92. };
  93. const char* enable_features_0[] = {"UnitTestEnabled"};
  94. const FieldTrialTestingExperimentParams array_kFieldTrialConfig_params_0[] = {
  95. {
  96. "x",
  97. "1",
  98. },
  99. };
  100. const FieldTrialTestingExperiment array_kFieldTrialConfig_experiments_0[] = {
  101. {/*name=*/"Enabled",
  102. /*platforms=*/array_kFieldTrialConfig_platforms_0,
  103. /*platforms_size=*/10,
  104. /*form_factors=*/{},
  105. /*form_factors_size=*/0,
  106. /*is_low_end_device=*/absl::nullopt,
  107. /*min_os_version=*/nullptr,
  108. /*params=*/array_kFieldTrialConfig_params_0,
  109. /*params_size=*/1,
  110. /*enable_features=*/enable_features_0,
  111. /*enable_features_size=*/1,
  112. /*disable_features=*/nullptr,
  113. /*disable_features_size=*/0,
  114. /*forcing_flag=*/nullptr,
  115. /*override_ui_string=*/nullptr,
  116. /*override_ui_string_size=*/0},
  117. };
  118. const FieldTrialTestingStudy array_kFieldTrialConfig_studies[] = {
  119. {/*name=*/"UnitTest",
  120. /*experiments=*/array_kFieldTrialConfig_experiments_0,
  121. /*experiments_size=*/1},
  122. };
  123. } // namespace
  124. const SignedSeedData kTestSeedData{
  125. kTestSeed_StudyNames, kTestSeed_Base64UncompressedData,
  126. kTestSeed_Base64CompressedData, kTestSeed_Base64Signature};
  127. const SignedSeedData kCrashingSeedData{
  128. kCrashingSeed_StudyNames, kCrashingSeed_Base64UncompressedData,
  129. kCrashingSeed_Base64CompressedData, kCrashingSeed_Base64Signature};
  130. const SignedSeedPrefKeys kSafeSeedPrefKeys{prefs::kVariationsSafeCompressedSeed,
  131. prefs::kVariationsSafeSeedSignature};
  132. const SignedSeedPrefKeys kRegularSeedPrefKeys{prefs::kVariationsCompressedSeed,
  133. prefs::kVariationsSeedSignature};
  134. SignedSeedData::SignedSeedData(base::span<const char*> in_study_names,
  135. const char* in_base64_uncompressed_data,
  136. const char* in_base64_compressed_data,
  137. const char* in_base64_signature)
  138. : study_names(std::move(in_study_names)),
  139. base64_uncompressed_data(in_base64_uncompressed_data),
  140. base64_compressed_data(in_base64_compressed_data),
  141. base64_signature(in_base64_signature) {}
  142. SignedSeedData::~SignedSeedData() = default;
  143. SignedSeedData::SignedSeedData(const SignedSeedData&) = default;
  144. SignedSeedData::SignedSeedData(SignedSeedData&&) = default;
  145. SignedSeedData& SignedSeedData::operator=(const SignedSeedData&) = default;
  146. SignedSeedData& SignedSeedData::operator=(SignedSeedData&&) = default;
  147. void DisableTestingConfig() {
  148. base::CommandLine::ForCurrentProcess()->AppendSwitch(
  149. switches::kDisableFieldTrialTestingConfig);
  150. }
  151. void EnableTestingConfig() {
  152. base::CommandLine::ForCurrentProcess()->AppendSwitch(
  153. switches::kEnableFieldTrialTestingConfig);
  154. }
  155. bool ExtractVariationIds(const std::string& variations,
  156. std::set<VariationID>* variation_ids,
  157. std::set<VariationID>* trigger_ids) {
  158. std::string serialized_proto;
  159. if (!base::Base64Decode(variations, &serialized_proto))
  160. return false;
  161. ClientVariations proto;
  162. if (!proto.ParseFromString(serialized_proto))
  163. return false;
  164. for (int i = 0; i < proto.variation_id_size(); ++i)
  165. variation_ids->insert(proto.variation_id(i));
  166. for (int i = 0; i < proto.trigger_variation_id_size(); ++i)
  167. trigger_ids->insert(proto.trigger_variation_id(i));
  168. return true;
  169. }
  170. scoped_refptr<base::FieldTrial> CreateTrialAndAssociateId(
  171. const std::string& trial_name,
  172. const std::string& default_group_name,
  173. IDCollectionKey key,
  174. VariationID id) {
  175. AssociateGoogleVariationID(key, trial_name, default_group_name, id);
  176. scoped_refptr<base::FieldTrial> trial(
  177. base::FieldTrialList::CreateFieldTrial(trial_name, default_group_name));
  178. DCHECK(trial);
  179. if (trial) {
  180. // Ensure the trial is registered under the correct key so we can look it
  181. // up.
  182. trial->group();
  183. }
  184. return trial;
  185. }
  186. void SimulateCrash(PrefService* local_state) {
  187. local_state->SetBoolean(metrics::prefs::kStabilityExitedCleanly, false);
  188. metrics::CleanExitBeacon::SkipCleanShutdownStepsForTesting();
  189. }
  190. void WriteSeedData(PrefService* local_state,
  191. const SignedSeedData& seed_data,
  192. const SignedSeedPrefKeys& pref_keys) {
  193. local_state->SetString(pref_keys.base64_compressed_data_key,
  194. seed_data.base64_compressed_data);
  195. local_state->SetString(pref_keys.base64_signature_key,
  196. seed_data.base64_signature);
  197. local_state->CommitPendingWrite();
  198. }
  199. bool FieldTrialListHasAllStudiesFrom(const SignedSeedData& seed_data) {
  200. return base::ranges::all_of(seed_data.study_names, [](const char* study) {
  201. return base::FieldTrialList::TrialExists(study);
  202. });
  203. }
  204. void ResetVariations() {
  205. testing::ClearAllVariationIDs();
  206. testing::ClearAllVariationParams();
  207. }
  208. const FieldTrialTestingConfig kTestingConfig = {
  209. array_kFieldTrialConfig_studies,
  210. 1,
  211. };
  212. } // namespace variations