Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(54)

Side by Side Diff: chrome/common/variations/variations_util.cc

Issue 2259443003: Capture All Groups in the Field Trial For Testing Studies (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: CR Feedback Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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/variations_util.h" 5 #include "chrome/common/variations/variations_util.h"
6 6
7 #include <stddef.h> 7 #include <stddef.h>
8 8
9 #include <string> 9 #include <string>
10 #include <vector> 10 #include <vector>
11 11
12 #include "base/feature_list.h" 12 #include "base/feature_list.h"
13 #include "base/metrics/field_trial.h" 13 #include "base/metrics/field_trial.h"
14 #include "base/strings/string_split.h" 14 #include "base/strings/string_split.h"
15 #include "base/strings/stringprintf.h" 15 #include "base/strings/stringprintf.h"
16 #include "chrome/common/variations/fieldtrial_testing_config.h" 16 #include "chrome/common/variations/fieldtrial_testing_config.h"
17 #include "components/variations/variations_associated_data.h" 17 #include "components/variations/variations_associated_data.h"
18 #include "net/base/escape.h" 18 #include "net/base/escape.h"
19 19
20 namespace chrome_variations { 20 namespace chrome_variations {
21 21
22 namespace { 22 namespace {
23 23
24 std::string EscapeValue(const std::string& value) { 24 std::string EscapeValue(const std::string& value) {
25 return net::UnescapeURLComponent( 25 return net::UnescapeURLComponent(
26 value, net::UnescapeRule::PATH_SEPARATORS | 26 value, net::UnescapeRule::PATH_SEPARATORS |
27 net::UnescapeRule::URL_SPECIAL_CHARS_EXCEPT_PATH_SEPARATORS); 27 net::UnescapeRule::URL_SPECIAL_CHARS_EXCEPT_PATH_SEPARATORS);
28 } 28 }
29 29
30 void AssociateParamsFromGroup(const std::string& trial_name,
31 const FieldTrialTestingGroup& group,
32 base::FeatureList* feature_list) {
33 if (group.params_size != 0) {
34 std::map<std::string, std::string> params;
35 for (size_t i = 0; i < group.params_size; ++i) {
36 const FieldTrialTestingGroupParams& param = group.params[i];
37 params[param.key] = param.value;
38 }
39 variations::AssociateVariationParams(trial_name, group.name, params);
40 }
41 base::FieldTrial* trial =
42 base::FieldTrialList::CreateFieldTrial(trial_name, group.name);
43
44 if (!trial) {
45 DLOG(WARNING) << "Field trial config trial skipped: " << trial_name
46 << "." << group.name
47 << " (it is overridden from chrome://flags)";
48 return;
49 }
50
51 for (size_t i = 0; i < group.enable_features_size; ++i) {
52 feature_list->RegisterFieldTrialOverride(
53 group.enable_features[i], base::FeatureList::OVERRIDE_ENABLE_FEATURE,
54 trial);
55 }
56 for (size_t i = 0; i < group.disable_features_size; ++i) {
57 feature_list->RegisterFieldTrialOverride(
58 group.disable_features[i],
59 base::FeatureList::OVERRIDE_DISABLE_FEATURE, trial);
60 }
61 }
62
30 } // namespace 63 } // namespace
31 64
32 bool AssociateParamsFromString(const std::string& varations_string) { 65 bool AssociateParamsFromString(const std::string& varations_string) {
33 // Format: Trial1.Group1:k1/v1/k2/v2,Trial2.Group2:k1/v1/k2/v2 66 // Format: Trial1.Group1:k1/v1/k2/v2,Trial2.Group2:k1/v1/k2/v2
34 std::set<std::pair<std::string, std::string>> trial_groups; 67 std::set<std::pair<std::string, std::string>> trial_groups;
35 for (const base::StringPiece& experiment_group : base::SplitStringPiece( 68 for (const base::StringPiece& experiment_group : base::SplitStringPiece(
36 varations_string, ",", 69 varations_string, ",",
37 base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL)) { 70 base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL)) {
38 std::vector<base::StringPiece> experiment = base::SplitStringPiece( 71 std::vector<base::StringPiece> experiment = base::SplitStringPiece(
39 experiment_group, ":", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL); 72 experiment_group, ":", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
40 if (experiment.size() != 2) { 73 if (experiment.size() != 2) {
41 DLOG(ERROR) << "Experiment and params should be separated by ':'"; 74 DLOG(ERROR) << "Experiment and params should be separated by ':'";
42 return false; 75 return false;
43 } 76 }
44 77
45 std::vector<std::string> group_parts = base::SplitString( 78 std::vector<std::string> group_parts = base::SplitString(
46 experiment[0], ".", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL); 79 experiment[0], ".", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
47 if (group_parts.size() != 2) { 80 if (group_parts.size() != 2) {
48 DLOG(ERROR) << "Study and group name should be separated by '.'"; 81 DLOG(ERROR) << "Trial and group name should be separated by '.'";
49 return false; 82 return false;
50 } 83 }
51 84
52 std::vector<std::string> key_values = base::SplitString( 85 std::vector<std::string> key_values = base::SplitString(
53 experiment[1], "/", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL); 86 experiment[1], "/", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
54 if (key_values.size() % 2 != 0) { 87 if (key_values.size() % 2 != 0) {
55 DLOG(ERROR) << "Param name and param value should be separated by '/'"; 88 DLOG(ERROR) << "Param name and param value should be separated by '/'";
56 return false; 89 return false;
57 } 90 }
58 std::string trial = EscapeValue(group_parts[0]); 91 std::string trial = EscapeValue(group_parts[0]);
59 std::string group = EscapeValue(group_parts[1]); 92 std::string group = EscapeValue(group_parts[1]);
60 auto trial_group = std::make_pair(trial, group); 93 auto trial_group = std::make_pair(trial, group);
61 if (trial_groups.find(trial_group) != trial_groups.end()) { 94 if (trial_groups.find(trial_group) != trial_groups.end()) {
62 DLOG(ERROR) << base::StringPrintf( 95 DLOG(ERROR) << base::StringPrintf(
63 "A (study, group) pair listed more than once. (%s, %s)", 96 "A (trial, group) pair listed more than once. (%s, %s)",
64 trial.c_str(), group.c_str()); 97 trial.c_str(), group.c_str());
65 return false; 98 return false;
66 } 99 }
67 trial_groups.insert(trial_group); 100 trial_groups.insert(trial_group);
68 std::map<std::string, std::string> params; 101 std::map<std::string, std::string> params;
69 for (size_t i = 0; i < key_values.size(); i += 2) { 102 for (size_t i = 0; i < key_values.size(); i += 2) {
70 std::string key = EscapeValue(key_values[i]); 103 std::string key = EscapeValue(key_values[i]);
71 std::string value = EscapeValue(key_values[i + 1]); 104 std::string value = EscapeValue(key_values[i + 1]);
72 params[key] = value; 105 params[key] = value;
73 } 106 }
74 variations::AssociateVariationParams(trial, group, params); 107 variations::AssociateVariationParams(trial, group, params);
75 } 108 }
76 return true; 109 return true;
77 } 110 }
78 111
79 void AssociateParamsFromFieldTrialConfig(const FieldTrialTestingConfig& config, 112 void AssociateParamsFromFieldTrialConfig(const FieldTrialTestingConfig& config,
80 base::FeatureList* feature_list) { 113 base::FeatureList* feature_list) {
81 for (size_t i = 0; i < config.groups_size; ++i) { 114 for (size_t i = 0; i < config.trials_size; ++i) {
82 const FieldTrialTestingGroup& group = config.groups[i]; 115 const FieldTrialTestingTrial& trial = config.trials[i];
83 if (group.params_size != 0) { 116 if (trial.groups_size > 0) {
84 std::map<std::string, std::string> params; 117 AssociateParamsFromGroup(trial.name, trial.groups[0], feature_list);
85 for (size_t j = 0; j < group.params_size; ++j) { 118 } else {
86 const FieldTrialGroupParams& param = group.params[j]; 119 DLOG(ERROR) << "Unexpected empty trial: " << trial.name;
87 params[param.key] = param.value;
88 }
89 variations::AssociateVariationParams(group.study, group.group_name,
90 params);
91 }
92 base::FieldTrial* trial =
93 base::FieldTrialList::CreateFieldTrial(group.study, group.group_name);
94
95 if (!trial) {
96 DLOG(WARNING) << "Field trial config study skipped: " << group.study
97 << "." << group.group_name
98 << " (it is overridden from chrome://flags)";
99 continue;
100 }
101
102 for (size_t j = 0; j < group.enable_features_size; ++j) {
103 feature_list->RegisterFieldTrialOverride(
104 group.enable_features[j], base::FeatureList::OVERRIDE_ENABLE_FEATURE,
105 trial);
106 }
107 for (size_t j = 0; j < group.disable_features_size; ++j) {
108 feature_list->RegisterFieldTrialOverride(
109 group.disable_features[j],
110 base::FeatureList::OVERRIDE_DISABLE_FEATURE, trial);
111 } 120 }
112 } 121 }
113 } 122 }
114 123
115 void AssociateDefaultFieldTrialConfig(base::FeatureList* feature_list) { 124 void AssociateDefaultFieldTrialConfig(base::FeatureList* feature_list) {
116 AssociateParamsFromFieldTrialConfig(kFieldTrialConfig, feature_list); 125 AssociateParamsFromFieldTrialConfig(kFieldTrialConfig, feature_list);
117 } 126 }
118 127
119 } // namespace chrome_variations 128 } // namespace chrome_variations
OLDNEW
« no previous file with comments | « chrome/common/variations/fieldtrial_testing_config_schema.json ('k') | chrome/common/variations/variations_util_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698