Avi Drissman | 8ba1bad | 2022-09-13 19:22:36 | [diff] [blame] | 1 | // Copyright 2020 The Chromium Authors |
Karthika Pai | a264586a | 2020-10-27 23:32:01 | [diff] [blame] | 2 | // Use of this source code is governed by a BSD-style license that can be |
| 3 | // found in the LICENSE file. |
| 4 | |
| 5 | #include "components/variations/variations_test_utils.h" |
| 6 | |
Karthika Pai | a264586a | 2020-10-27 23:32:01 | [diff] [blame] | 7 | #include "base/base64.h" |
Caitlin Fischer | 6920a08 | 2021-06-29 05:25:24 | [diff] [blame] | 8 | #include "base/command_line.h" |
Karthika Pai | a264586a | 2020-10-27 23:32:01 | [diff] [blame] | 9 | #include "base/feature_list.h" |
Roger McFarlane | 3da6db273 | 2021-10-06 13:41:04 | [diff] [blame] | 10 | #include "components/metrics/clean_exit_beacon.h" |
| 11 | #include "components/metrics/metrics_pref_names.h" |
| 12 | #include "components/prefs/pref_service.h" |
Steven Holte | f08a336 | 2022-09-15 07:33:06 | [diff] [blame] | 13 | #include "components/variations/client_filterable_state.h" |
Luc Nguyen | 1180c66 | 2022-02-08 20:38:59 | [diff] [blame] | 14 | #include "components/variations/field_trial_config/fieldtrial_testing_config.h" |
Roger McFarlane | 3da6db273 | 2021-10-06 13:41:04 | [diff] [blame] | 15 | #include "components/variations/pref_names.h" |
Karthika Pai | a264586a | 2020-10-27 23:32:01 | [diff] [blame] | 16 | #include "components/variations/proto/client_variations.pb.h" |
Karthika Pai | a264586a | 2020-10-27 23:32:01 | [diff] [blame] | 17 | #include "components/variations/variations_associated_data.h" |
Caitlin Fischer | 6920a08 | 2021-06-29 05:25:24 | [diff] [blame] | 18 | #include "components/variations/variations_switches.h" |
Caitlin Fischer | d7651aed | 2021-07-13 03:20:40 | [diff] [blame] | 19 | #include "third_party/zlib/google/compression_utils.h" |
Karthika Pai | a264586a | 2020-10-27 23:32:01 | [diff] [blame] | 20 | |
| 21 | namespace variations { |
Roger McFarlane | 3da6db273 | 2021-10-06 13:41:04 | [diff] [blame] | 22 | namespace { |
Karthika Pai | a264586a | 2020-10-27 23:32:01 | [diff] [blame] | 23 | |
Steven Holte | e34ff1a | 2022-09-15 00:06:56 | [diff] [blame] | 24 | // kTestSeed is a simple VariationsSeed containing: |
| 25 | // serial_number: "test" |
| 26 | // study: { |
| 27 | // name: "UMA-Uniformity-Trial-50-Percent" |
| 28 | // consistency: PERMANENT |
| 29 | // experiment: { |
| 30 | // name: "default" |
| 31 | // probability_weight: 1 |
| 32 | // } |
| 33 | // experiment: { |
| 34 | // name: "group_01" |
| 35 | // probability_weight: 1 |
| 36 | // } |
| 37 | // } |
| 38 | |
| 39 | const char* kTestSeed_StudyNames[] = {"UMA-Uniformity-Trial-50-Percent"}; |
Roger McFarlane | 3da6db273 | 2021-10-06 13:41:04 | [diff] [blame] | 40 | |
| 41 | const char kTestSeed_Base64UncompressedData[] = |
Steven Holte | e34ff1a | 2022-09-15 00:06:56 | [diff] [blame] | 42 | "CgR0ZXN0Ej4KH1VNQS1Vbmlmb3JtaXR5LVRyaWFsLTUwLVBlcmNlbnQ4AUoLCgdkZWZhdWx0EA" |
| 43 | "FKDAoIZ3JvdXBfMDEQAQ=="; |
Caitlin Fischer | 7b55ee1 | 2021-07-14 16:05:29 | [diff] [blame] | 44 | |
Roger McFarlane | 3da6db273 | 2021-10-06 13:41:04 | [diff] [blame] | 45 | const char kTestSeed_Base64CompressedData[] = |
Steven Holte | e34ff1a | 2022-09-15 00:06:56 | [diff] [blame] | 46 | "H4sIAAAAAAAA/+JiKUktLhGy45IP9XXUDc3LTMsvys0sqdQNKcpMzNE1NdANSC1KTs0rsWD04u" |
| 47 | "ZiT0lNSyzNKRFg9OLh4kgvyi8tiDcwFGAEBAAA//90/JgERgAAAA=="; |
Caitlin Fischer | 6920a08 | 2021-06-29 05:25:24 | [diff] [blame] | 48 | |
Roger McFarlane | 3da6db273 | 2021-10-06 13:41:04 | [diff] [blame] | 49 | const char kTestSeed_Base64Signature[] = |
Steven Holte | e34ff1a | 2022-09-15 00:06:56 | [diff] [blame] | 50 | "MEUCIQD5AEAzk5qEuE3xOZl+xSZR15Ac1RJpsXMiou7i5W0sMAIgRn++ngh03HaMGC+Pjl9NOu" |
| 51 | "Doxf83qsSwycF2PSS1nYQ="; |
Caitlin Fischer | 6920a08 | 2021-06-29 05:25:24 | [diff] [blame] | 52 | |
Roger McFarlane | 3da6db273 | 2021-10-06 13:41:04 | [diff] [blame] | 53 | const char* kCrashingSeed_StudyNames[] = {"CrashingStudy"}; |
| 54 | |
Steven Holte | e34ff1a | 2022-09-15 00:06:56 | [diff] [blame] | 55 | // kCrashingSeed is a VariationsSeed that triggers a crash for testing: |
| 56 | // serial_number: "35ed2d9e354b414befdf930a734094019c0162f1" |
| 57 | // study: { |
| 58 | // name: "CrashingStudy" |
| 59 | // consistency: PERMANENT |
| 60 | // experiment: { |
| 61 | // name: "EnabledLaunch" |
| 62 | // probability_weight: 100 |
| 63 | // feature_association: { |
| 64 | // enable_feature: "ForceFieldTrialSetupCrashForTesting" |
| 65 | // } |
| 66 | // } |
| 67 | // experiment: { |
| 68 | // name: "ForcedOn_ForceFieldTrialSetupCrashForTesting" |
| 69 | // probability_weight: 0 |
| 70 | // feature_association: { |
| 71 | // forcing_feature_on: "ForceFieldTrialSetupCrashForTesting" |
| 72 | // } |
| 73 | // } |
| 74 | // experiment: { |
| 75 | // name: "ForcedOff_ForceFieldTrialSetupCrashForTesting" |
| 76 | // probability_weight: 0 |
| 77 | // feature_association: { |
| 78 | // forcing_feature_off: "ForceFieldTrialSetupCrashForTesting" |
| 79 | // } |
| 80 | // } |
| 81 | // filter: { |
| 82 | // min_version: "91.*" |
| 83 | // channel: CANARY |
| 84 | // channel: DEV |
| 85 | // channel: BETA |
| 86 | // channel: STABLE |
| 87 | // platform: PLATFORM_ANDROID |
| 88 | // platform: PLATFORM_IOS |
| 89 | // platform: PLATFORM_ANDROID_WEBVIEW |
| 90 | // platform: PLATFORM_WINDOWS |
| 91 | // platform: PLATFORM_MAC |
| 92 | // platform: PLATFORM_LINUX |
| 93 | // platform: PLATFORM_CHROMEOS |
| 94 | // platform: PLATFORM_CHROMEOS_LACROS |
| 95 | // } |
| 96 | // } |
| 97 | // version: "hash/4aa56a1dc30dfc767615248d6fee29830198b276" |
| 98 | |
Roger McFarlane | 3da6db273 | 2021-10-06 13:41:04 | [diff] [blame] | 99 | const char kCrashingSeed_Base64UncompressedData[] = |
| 100 | "CigzNWVkMmQ5ZTM1NGI0MTRiZWZkZjkzMGE3MzQwOTQwMTljMDE2MmYxEp4CCg1DcmFzaGluZ1" |
| 101 | "N0dWR5OAFKOAoNRW5hYmxlZExhdW5jaBBkYiUKI0ZvcmNlRmllbGRUcmlhbFNldHVwQ3Jhc2hG" |
| 102 | "b3JUZXN0aW5nSlcKLEZvcmNlZE9uX0ZvcmNlRmllbGRUcmlhbFNldHVwQ3Jhc2hGb3JUZXN0aW" |
| 103 | "5nEABiJRojRm9yY2VGaWVsZFRyaWFsU2V0dXBDcmFzaEZvclRlc3RpbmdKWAotRm9yY2VkT2Zm" |
| 104 | "X0ZvcmNlRmllbGRUcmlhbFNldHVwQ3Jhc2hGb3JUZXN0aW5nEABiJSIjRm9yY2VGaWVsZFRyaW" |
| 105 | "FsU2V0dXBDcmFzaEZvclRlc3RpbmdSHhIEOTEuKiAAIAEgAiADKAQoBSgGKAAoASgCKAMoCSIt" |
| 106 | "aGFzaC80YWE1NmExZGMzMGRmYzc2NzYxNTI0OGQ2ZmVlMjk4MzAxOThiMjc2"; |
| 107 | |
| 108 | const char kCrashingSeed_Base64CompressedData[] = |
| 109 | "H4sIAAAAAAAAAI3QwUvDMBTH8babwgKDsaMHKZNBEKdJk6bJWbbDEAQ30JskeS+2UKp07cF/" |
| 110 | "Zn+rZfgH9Py+73P4ESpyhAwMilw6yaXDAMEIZgshmZGMG8+4ygJfnhMyf27tqayar0PXw6+" |
| 111 | "O95rMt411NcKL7RtfLsCtyd3uu/W4q7CGY1vZ+oBd/" |
| 112 | "3P5HA5HPHUDsH8nD5cMXpvPEf0icuubUfAH2fzDIYyVV2Pkt9vl1PDH+zRK4zRJJ3RKr+" |
| 113 | "g1jWhMEzqhs9WmHPonaW2uLAcvGARfqELxPJMaVEDMjBbDotplhfoDs9NLbnoBAAA="; |
| 114 | |
| 115 | const char kCrashingSeed_Base64Signature[] = |
| 116 | "MEQCIEn1+VsBfNA93dxzpk+BLhdO91kMQnofxfTK5Uo8vDi8AiAnTCFCIPgEGWNOKzuKfNWn6" |
| 117 | "emB6pnGWjSTbI/pvfxHnw=="; |
| 118 | |
Luc Nguyen | 1180c66 | 2022-02-08 20:38:59 | [diff] [blame] | 119 | // Create mock testing config equivalent to: |
| 120 | // { |
| 121 | // "UnitTest": [ |
| 122 | // { |
| 123 | // "platforms": [ |
| 124 | // "android", |
| 125 | // "android_weblayer", |
| 126 | // "android_webview", |
| 127 | // "chromeos", |
| 128 | // "chromeos_lacros", |
| 129 | // "fuchsia", |
| 130 | // "ios", |
| 131 | // "linux", |
| 132 | // "mac", |
| 133 | // "windows" |
| 134 | // ], |
| 135 | // "experiments": [ |
| 136 | // { |
| 137 | // "name": "Enabled", |
| 138 | // "params": { |
| 139 | // "x": "1" |
| 140 | // }, |
| 141 | // "enable_features": [ |
| 142 | // "UnitTestEnabled" |
| 143 | // ] |
| 144 | // } |
| 145 | // ] |
| 146 | // } |
| 147 | // ] |
| 148 | // } |
| 149 | |
| 150 | const Study::Platform array_kFieldTrialConfig_platforms_0[] = { |
| 151 | Study::PLATFORM_ANDROID, |
| 152 | Study::PLATFORM_ANDROID_WEBLAYER, |
| 153 | Study::PLATFORM_ANDROID_WEBVIEW, |
| 154 | Study::PLATFORM_CHROMEOS, |
| 155 | Study::PLATFORM_CHROMEOS_LACROS, |
| 156 | Study::PLATFORM_FUCHSIA, |
| 157 | Study::PLATFORM_IOS, |
| 158 | Study::PLATFORM_LINUX, |
| 159 | Study::PLATFORM_MAC, |
| 160 | Study::PLATFORM_WINDOWS, |
| 161 | }; |
| 162 | |
| 163 | const char* enable_features_0[] = {"UnitTestEnabled"}; |
| 164 | const FieldTrialTestingExperimentParams array_kFieldTrialConfig_params_0[] = { |
| 165 | { |
| 166 | "x", |
| 167 | "1", |
| 168 | }, |
| 169 | }; |
| 170 | |
| 171 | const FieldTrialTestingExperiment array_kFieldTrialConfig_experiments_0[] = { |
| 172 | {/*name=*/"Enabled", |
| 173 | /*platforms=*/array_kFieldTrialConfig_platforms_0, |
| 174 | /*platforms_size=*/10, |
| 175 | /*form_factors=*/{}, |
| 176 | /*form_factors_size=*/0, |
| 177 | /*is_low_end_device=*/absl::nullopt, |
| 178 | /*min_os_version=*/nullptr, |
| 179 | /*params=*/array_kFieldTrialConfig_params_0, |
| 180 | /*params_size=*/1, |
| 181 | /*enable_features=*/enable_features_0, |
| 182 | /*enable_features_size=*/1, |
| 183 | /*disable_features=*/nullptr, |
| 184 | /*disable_features_size=*/0, |
| 185 | /*forcing_flag=*/nullptr, |
| 186 | /*override_ui_string=*/nullptr, |
| 187 | /*override_ui_string_size=*/0}, |
| 188 | }; |
| 189 | |
| 190 | const FieldTrialTestingStudy array_kFieldTrialConfig_studies[] = { |
| 191 | {/*name=*/"UnitTest", |
| 192 | /*experiments=*/array_kFieldTrialConfig_experiments_0, |
| 193 | /*experiments_size=*/1}, |
| 194 | }; |
| 195 | |
Roger McFarlane | 3da6db273 | 2021-10-06 13:41:04 | [diff] [blame] | 196 | } // namespace |
| 197 | |
| 198 | const SignedSeedData kTestSeedData{ |
| 199 | kTestSeed_StudyNames, kTestSeed_Base64UncompressedData, |
| 200 | kTestSeed_Base64CompressedData, kTestSeed_Base64Signature}; |
| 201 | |
| 202 | const SignedSeedData kCrashingSeedData{ |
| 203 | kCrashingSeed_StudyNames, kCrashingSeed_Base64UncompressedData, |
| 204 | kCrashingSeed_Base64CompressedData, kCrashingSeed_Base64Signature}; |
| 205 | |
| 206 | const SignedSeedPrefKeys kSafeSeedPrefKeys{prefs::kVariationsSafeCompressedSeed, |
| 207 | prefs::kVariationsSafeSeedSignature}; |
| 208 | |
| 209 | const SignedSeedPrefKeys kRegularSeedPrefKeys{prefs::kVariationsCompressedSeed, |
| 210 | prefs::kVariationsSeedSignature}; |
| 211 | |
| 212 | SignedSeedData::SignedSeedData(base::span<const char*> in_study_names, |
| 213 | const char* in_base64_uncompressed_data, |
| 214 | const char* in_base64_compressed_data, |
| 215 | const char* in_base64_signature) |
| 216 | : study_names(std::move(in_study_names)), |
| 217 | base64_uncompressed_data(in_base64_uncompressed_data), |
| 218 | base64_compressed_data(in_base64_compressed_data), |
| 219 | base64_signature(in_base64_signature) {} |
| 220 | |
| 221 | SignedSeedData::~SignedSeedData() = default; |
| 222 | |
| 223 | SignedSeedData::SignedSeedData(const SignedSeedData&) = default; |
| 224 | SignedSeedData::SignedSeedData(SignedSeedData&&) = default; |
| 225 | SignedSeedData& SignedSeedData::operator=(const SignedSeedData&) = default; |
| 226 | SignedSeedData& SignedSeedData::operator=(SignedSeedData&&) = default; |
Caitlin Fischer | d7651aed | 2021-07-13 03:20:40 | [diff] [blame] | 227 | |
Caitlin Fischer | 6920a08 | 2021-06-29 05:25:24 | [diff] [blame] | 228 | void DisableTestingConfig() { |
| 229 | base::CommandLine::ForCurrentProcess()->AppendSwitch( |
| 230 | switches::kDisableFieldTrialTestingConfig); |
| 231 | } |
| 232 | |
Luc Nguyen | 1180c66 | 2022-02-08 20:38:59 | [diff] [blame] | 233 | void EnableTestingConfig() { |
| 234 | base::CommandLine::ForCurrentProcess()->AppendSwitch( |
| 235 | switches::kEnableFieldTrialTestingConfig); |
| 236 | } |
| 237 | |
Karthika Pai | a264586a | 2020-10-27 23:32:01 | [diff] [blame] | 238 | bool ExtractVariationIds(const std::string& variations, |
| 239 | std::set<VariationID>* variation_ids, |
| 240 | std::set<VariationID>* trigger_ids) { |
| 241 | std::string serialized_proto; |
| 242 | if (!base::Base64Decode(variations, &serialized_proto)) |
| 243 | return false; |
| 244 | ClientVariations proto; |
| 245 | if (!proto.ParseFromString(serialized_proto)) |
| 246 | return false; |
| 247 | for (int i = 0; i < proto.variation_id_size(); ++i) |
| 248 | variation_ids->insert(proto.variation_id(i)); |
| 249 | for (int i = 0; i < proto.trigger_variation_id_size(); ++i) |
| 250 | trigger_ids->insert(proto.trigger_variation_id(i)); |
| 251 | return true; |
| 252 | } |
| 253 | |
| 254 | scoped_refptr<base::FieldTrial> CreateTrialAndAssociateId( |
| 255 | const std::string& trial_name, |
| 256 | const std::string& default_group_name, |
| 257 | IDCollectionKey key, |
| 258 | VariationID id) { |
| 259 | AssociateGoogleVariationID(key, trial_name, default_group_name, id); |
| 260 | scoped_refptr<base::FieldTrial> trial( |
| 261 | base::FieldTrialList::CreateFieldTrial(trial_name, default_group_name)); |
| 262 | DCHECK(trial); |
| 263 | |
| 264 | if (trial) { |
| 265 | // Ensure the trial is registered under the correct key so we can look it |
| 266 | // up. |
Steven Holte | f155160 | 2022-09-03 06:38:38 | [diff] [blame] | 267 | trial->Activate(); |
Karthika Pai | a264586a | 2020-10-27 23:32:01 | [diff] [blame] | 268 | } |
| 269 | |
| 270 | return trial; |
| 271 | } |
| 272 | |
Roger McFarlane | 3da6db273 | 2021-10-06 13:41:04 | [diff] [blame] | 273 | void SimulateCrash(PrefService* local_state) { |
| 274 | local_state->SetBoolean(metrics::prefs::kStabilityExitedCleanly, false); |
| 275 | metrics::CleanExitBeacon::SkipCleanShutdownStepsForTesting(); |
| 276 | } |
| 277 | |
| 278 | void WriteSeedData(PrefService* local_state, |
| 279 | const SignedSeedData& seed_data, |
| 280 | const SignedSeedPrefKeys& pref_keys) { |
| 281 | local_state->SetString(pref_keys.base64_compressed_data_key, |
| 282 | seed_data.base64_compressed_data); |
| 283 | local_state->SetString(pref_keys.base64_signature_key, |
| 284 | seed_data.base64_signature); |
| 285 | local_state->CommitPendingWrite(); |
| 286 | } |
| 287 | |
| 288 | bool FieldTrialListHasAllStudiesFrom(const SignedSeedData& seed_data) { |
| 289 | return base::ranges::all_of(seed_data.study_names, [](const char* study) { |
| 290 | return base::FieldTrialList::TrialExists(study); |
| 291 | }); |
| 292 | } |
| 293 | |
Luc Nguyen | 1180c66 | 2022-02-08 20:38:59 | [diff] [blame] | 294 | void ResetVariations() { |
| 295 | testing::ClearAllVariationIDs(); |
| 296 | testing::ClearAllVariationParams(); |
| 297 | } |
| 298 | |
| 299 | const FieldTrialTestingConfig kTestingConfig = { |
| 300 | array_kFieldTrialConfig_studies, |
| 301 | 1, |
| 302 | }; |
| 303 | |
Steven Holte | f08a336 | 2022-09-15 07:33:06 | [diff] [blame] | 304 | std::unique_ptr<ClientFilterableState> CreateDummyClientFilterableState() { |
| 305 | auto client_state = std::make_unique<ClientFilterableState>( |
| 306 | base::BindOnce([] { return false; })); |
| 307 | client_state->locale = "en-CA"; |
| 308 | client_state->reference_date = base::Time::Now(); |
| 309 | client_state->version = base::Version("20.0.0.0"); |
| 310 | client_state->channel = Study::STABLE; |
| 311 | client_state->form_factor = Study::PHONE; |
| 312 | client_state->platform = Study::PLATFORM_ANDROID; |
| 313 | return client_state; |
| 314 | } |
| 315 | |
Steven Holte | a84bc22 | 2022-09-29 07:11:46 | [diff] [blame] | 316 | MockEntropyProviders::MockEntropyProviders( |
| 317 | MockEntropyProviders::Results results, |
Steven Holte | 896279f | 2022-10-21 20:32:30 | [diff] [blame^] | 318 | uint32_t low_entropy_domain) |
Steven Holte | a84bc22 | 2022-09-29 07:11:46 | [diff] [blame] | 319 | : EntropyProviders(results.high_entropy.has_value() ? "client_id" : "", |
Steven Holte | 896279f | 2022-10-21 20:32:30 | [diff] [blame^] | 320 | {0, low_entropy_domain}), |
Steven Holte | a84bc22 | 2022-09-29 07:11:46 | [diff] [blame] | 321 | low_provider_(results.low_entropy), |
| 322 | high_provider_(results.high_entropy.value_or(0)) {} |
| 323 | |
| 324 | MockEntropyProviders::~MockEntropyProviders() = default; |
| 325 | |
| 326 | const base::FieldTrial::EntropyProvider& MockEntropyProviders::low_entropy() |
| 327 | const { |
| 328 | return low_provider_; |
| 329 | } |
| 330 | |
| 331 | const base::FieldTrial::EntropyProvider& MockEntropyProviders::default_entropy() |
| 332 | const { |
| 333 | if (default_entropy_is_high_entropy()) { |
| 334 | return high_provider_; |
| 335 | } |
| 336 | return low_provider_; |
| 337 | } |
| 338 | |
Caitlin Fischer | 6920a08 | 2021-06-29 05:25:24 | [diff] [blame] | 339 | } // namespace variations |