| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/common/variations/uniformity_field_trials.h" | 5 #include "chrome/common/variations/uniformity_field_trials.h" |
| 6 | 6 |
| 7 #include <string> | 7 #include <string> |
| 8 | 8 |
| 9 #include "base/metrics/field_trial.h" | 9 #include "base/metrics/field_trial.h" |
| 10 #include "base/strings/stringprintf.h" | 10 #include "base/strings/stringprintf.h" |
| 11 #include "base/time/time.h" | 11 #include "base/time/time.h" |
| 12 #include "chrome/common/variations/variation_ids.h" | 12 #include "chrome/common/variations/variation_ids.h" |
| 13 #include "components/variations/variations_associated_data.h" | 13 #include "components/variations/variations_associated_data.h" |
| 14 | 14 |
| 15 namespace chrome_variations { | 15 namespace chrome_variations { |
| 16 | 16 |
| 17 namespace { | 17 namespace { |
| 18 | 18 |
| 19 // Set up a uniformity field trial. |one_time_randomized| indicates if the | 19 // Set up a uniformity field trial. |one_time_randomized| indicates if the |
| 20 // field trial is one-time randomized or session-randomized. |trial_name_string| | 20 // field trial is one-time randomized or session-randomized. |trial_name_string| |
| 21 // must contain a "%d" since the percentage of the group will be inserted in | 21 // must contain a "%d" since the percentage of the group will be inserted in |
| 22 // the trial name. |num_trial_groups| must be a divisor of 100 (e.g. 5, 20) | 22 // the trial name. |num_trial_groups| must be a divisor of 100 (e.g. 5, 20) |
| 23 void SetupSingleUniformityFieldTrial( | 23 void SetupSingleUniformityFieldTrial( |
| 24 base::FieldTrial::RandomizationType randomization_type, | 24 base::FieldTrial::RandomizationType randomization_type, |
| 25 const std::string& trial_name_string, | 25 const std::string& trial_name_string, |
| 26 const variations::VariationID trial_base_id, | 26 const VariationID trial_base_id, |
| 27 int num_trial_groups) { | 27 int num_trial_groups) { |
| 28 // Probability per group remains constant for all uniformity trials, what | 28 // Probability per group remains constant for all uniformity trials, what |
| 29 // changes is the probability divisor. | 29 // changes is the probability divisor. |
| 30 static const base::FieldTrial::Probability kProbabilityPerGroup = 1; | 30 static const base::FieldTrial::Probability kProbabilityPerGroup = 1; |
| 31 const std::string kDefaultGroupName = "default"; | 31 const std::string kDefaultGroupName = "default"; |
| 32 const base::FieldTrial::Probability divisor = num_trial_groups; | 32 const base::FieldTrial::Probability divisor = num_trial_groups; |
| 33 | 33 |
| 34 DCHECK_EQ(100 % num_trial_groups, 0); | 34 DCHECK_EQ(100 % num_trial_groups, 0); |
| 35 const int group_percent = 100 / num_trial_groups; | 35 const int group_percent = 100 / num_trial_groups; |
| 36 const std::string trial_name = base::StringPrintf(trial_name_string.c_str(), | 36 const std::string trial_name = base::StringPrintf(trial_name_string.c_str(), |
| 37 group_percent); | 37 group_percent); |
| 38 | 38 |
| 39 DVLOG(1) << "Trial name = " << trial_name; | 39 DVLOG(1) << "Trial name = " << trial_name; |
| 40 | 40 |
| 41 scoped_refptr<base::FieldTrial> trial( | 41 scoped_refptr<base::FieldTrial> trial( |
| 42 base::FieldTrialList::FactoryGetFieldTrial( | 42 base::FieldTrialList::FactoryGetFieldTrial( |
| 43 trial_name, divisor, kDefaultGroupName, 2015, 1, 1, | 43 trial_name, divisor, kDefaultGroupName, 2015, 1, 1, |
| 44 randomization_type, NULL)); | 44 randomization_type, NULL)); |
| 45 variations::AssociateGoogleVariationID(variations::GOOGLE_UPDATE_SERVICE, | 45 AssociateGoogleVariationID(GOOGLE_UPDATE_SERVICE, trial_name, |
| 46 trial_name, kDefaultGroupName, | 46 kDefaultGroupName, trial_base_id); |
| 47 trial_base_id); | |
| 48 | 47 |
| 49 // Loop starts with group 1 because the field trial automatically creates a | 48 // Loop starts with group 1 because the field trial automatically creates a |
| 50 // default group, which would be group 0. | 49 // default group, which would be group 0. |
| 51 for (int group_number = 1; group_number < num_trial_groups; ++group_number) { | 50 for (int group_number = 1; group_number < num_trial_groups; ++group_number) { |
| 52 const std::string group_name = | 51 const std::string group_name = |
| 53 base::StringPrintf("group_%02d", group_number); | 52 base::StringPrintf("group_%02d", group_number); |
| 54 DVLOG(1) << " Group name = " << group_name; | 53 DVLOG(1) << " Group name = " << group_name; |
| 55 trial->AppendGroup(group_name, kProbabilityPerGroup); | 54 trial->AppendGroup(group_name, kProbabilityPerGroup); |
| 56 variations::AssociateGoogleVariationID( | 55 AssociateGoogleVariationID( |
| 57 variations::GOOGLE_UPDATE_SERVICE, trial_name, group_name, | 56 GOOGLE_UPDATE_SERVICE, trial_name, group_name, |
| 58 static_cast<variations::VariationID>(trial_base_id + group_number)); | 57 static_cast<VariationID>(trial_base_id + group_number)); |
| 59 } | 58 } |
| 60 | 59 |
| 61 // Now that all groups have been appended, call group() on the trial to | 60 // Now that all groups have been appended, call group() on the trial to |
| 62 // ensure that our trial is registered. This resolves an off-by-one issue | 61 // ensure that our trial is registered. This resolves an off-by-one issue |
| 63 // where the default group never gets chosen if we don't "use" the trial. | 62 // where the default group never gets chosen if we don't "use" the trial. |
| 64 const int chosen_group = trial->group(); | 63 const int chosen_group = trial->group(); |
| 65 DVLOG(1) << "Chosen Group: " << chosen_group; | 64 DVLOG(1) << "Chosen Group: " << chosen_group; |
| 66 } | 65 } |
| 67 | 66 |
| 68 // Setup a 50% uniformity trial for new installs only. This is accomplished by | 67 // Setup a 50% uniformity trial for new installs only. This is accomplished by |
| (...skipping 29 matching lines...) Expand all Loading... |
| 98 trial->group(); | 97 trial->group(); |
| 99 | 98 |
| 100 // One field trial will be created for each entry in this array. The i'th | 99 // One field trial will be created for each entry in this array. The i'th |
| 101 // field trial will have |trial_sizes[i]| groups in it, including the default | 100 // field trial will have |trial_sizes[i]| groups in it, including the default |
| 102 // group. Each group will have a probability of 1/|trial_sizes[i]|. | 101 // group. Each group will have a probability of 1/|trial_sizes[i]|. |
| 103 const int num_trial_groups[] = { 100, 20, 10, 5, 2 }; | 102 const int num_trial_groups[] = { 100, 20, 10, 5, 2 }; |
| 104 | 103 |
| 105 // Declare our variation ID bases along side this array so we can loop over it | 104 // Declare our variation ID bases along side this array so we can loop over it |
| 106 // and assign the IDs appropriately. So for example, the 1 percent experiments | 105 // and assign the IDs appropriately. So for example, the 1 percent experiments |
| 107 // should have a size of 100 (100/100 = 1). | 106 // should have a size of 100 (100/100 = 1). |
| 108 const variations::VariationID trial_base_ids[] = { | 107 const VariationID trial_base_ids[] = { |
| 109 UNIFORMITY_1_PERCENT_BASE, | 108 UNIFORMITY_1_PERCENT_BASE, |
| 110 UNIFORMITY_5_PERCENT_BASE, | 109 UNIFORMITY_5_PERCENT_BASE, |
| 111 UNIFORMITY_10_PERCENT_BASE, | 110 UNIFORMITY_10_PERCENT_BASE, |
| 112 UNIFORMITY_20_PERCENT_BASE, | 111 UNIFORMITY_20_PERCENT_BASE, |
| 113 UNIFORMITY_50_PERCENT_BASE | 112 UNIFORMITY_50_PERCENT_BASE |
| 114 }; | 113 }; |
| 115 | 114 |
| 116 const std::string kOneTimeRandomizedTrialName = | 115 const std::string kOneTimeRandomizedTrialName = |
| 117 "UMA-Uniformity-Trial-%d-Percent"; | 116 "UMA-Uniformity-Trial-%d-Percent"; |
| 118 for (size_t i = 0; i < arraysize(num_trial_groups); ++i) { | 117 for (size_t i = 0; i < arraysize(num_trial_groups); ++i) { |
| 119 SetupSingleUniformityFieldTrial(base::FieldTrial::ONE_TIME_RANDOMIZED, | 118 SetupSingleUniformityFieldTrial(base::FieldTrial::ONE_TIME_RANDOMIZED, |
| 120 kOneTimeRandomizedTrialName, | 119 kOneTimeRandomizedTrialName, |
| 121 trial_base_ids[i], num_trial_groups[i]); | 120 trial_base_ids[i], num_trial_groups[i]); |
| 122 } | 121 } |
| 123 | 122 |
| 124 // Setup a 5% session-randomized uniformity trial. | 123 // Setup a 5% session-randomized uniformity trial. |
| 125 const std::string kSessionRandomizedTrialName = | 124 const std::string kSessionRandomizedTrialName = |
| 126 "UMA-Session-Randomized-Uniformity-Trial-%d-Percent"; | 125 "UMA-Session-Randomized-Uniformity-Trial-%d-Percent"; |
| 127 SetupSingleUniformityFieldTrial( | 126 SetupSingleUniformityFieldTrial( |
| 128 base::FieldTrial::SESSION_RANDOMIZED, kSessionRandomizedTrialName, | 127 base::FieldTrial::SESSION_RANDOMIZED, kSessionRandomizedTrialName, |
| 129 UNIFORMITY_SESSION_RANDOMIZED_5_PERCENT_BASE, 20); | 128 UNIFORMITY_SESSION_RANDOMIZED_5_PERCENT_BASE, 20); |
| 130 | 129 |
| 131 SetupNewInstallUniformityTrial(install_date); | 130 SetupNewInstallUniformityTrial(install_date); |
| 132 } | 131 } |
| 133 | 132 |
| 134 } // namespace chrome_variations | 133 } // namespace chrome_variations |
| OLD | NEW |