OLD | NEW |
1 /* | 1 /* |
2 * Copyright (c) 2014 The WebRTC project authors. All Rights Reserved. | 2 * Copyright (c) 2014 The WebRTC project authors. All Rights Reserved. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license | 4 * Use of this source code is governed by a BSD-style license |
5 * that can be found in the LICENSE file in the root of the source | 5 * that can be found in the LICENSE file in the root of the source |
6 * tree. An additional intellectual property rights grant can be found | 6 * tree. An additional intellectual property rights grant can be found |
7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
9 */ | 9 */ |
10 | 10 |
11 #include "webrtc/test/field_trial.h" | 11 #include "webrtc/test/field_trial.h" |
12 | 12 |
13 #include <algorithm> | 13 #include <algorithm> |
14 #include <cassert> | 14 #include <cassert> |
15 #include <cstdio> | 15 #include <cstdio> |
16 #include <cstdlib> | 16 #include <cstdlib> |
17 #include <map> | 17 #include <map> |
18 #include <string> | 18 #include <string> |
19 | 19 |
20 #include "webrtc/system_wrappers/include/field_trial.h" | 20 #include "webrtc/system_wrappers/include/field_trial.h" |
| 21 #include "webrtc/system_wrappers/include/field_trial_default.h" |
21 | 22 |
22 namespace webrtc { | 23 namespace webrtc { |
23 namespace { | 24 namespace { |
24 // Clients of this library have show a clear intent to setup field trials by | |
25 // linking with it. As so try to crash if they forget to call | |
26 // InitFieldTrialsFromString before webrtc tries to access a field trial. | |
27 bool field_trials_initiated_ = false; | 25 bool field_trials_initiated_ = false; |
28 std::map<std::string, std::string> field_trials_; | |
29 } // namespace | 26 } // namespace |
30 | 27 |
31 namespace field_trial { | |
32 std::string FindFullName(const std::string& trial_name) { | |
33 assert(field_trials_initiated_); | |
34 std::map<std::string, std::string>::const_iterator it = | |
35 field_trials_.find(trial_name); | |
36 if (it == field_trials_.end()) | |
37 return std::string(); | |
38 return it->second; | |
39 } | |
40 } // namespace field_trial | |
41 | |
42 namespace test { | 28 namespace test { |
43 // Note: this code is copied from src/base/metrics/field_trial.cc since the aim | 29 // Note: this code is copied from src/base/metrics/field_trial.cc since the aim |
44 // is to mimic chromium --force-fieldtrials. | 30 // is to mimic chromium --force-fieldtrials. |
45 void InitFieldTrialsFromString(const std::string& trials_string) { | 31 void InitFieldTrialsFromString(const std::string& trials_string) { |
46 static const char kPersistentStringSeparator = '/'; | 32 static const char kPersistentStringSeparator = '/'; |
47 | 33 |
48 // Catch an error if this is called more than once. | 34 // Catch an error if this is called more than once. |
49 assert(!field_trials_initiated_); | 35 assert(!field_trials_initiated_); |
50 field_trials_initiated_ = true; | 36 field_trials_initiated_ = true; |
51 | 37 |
52 if (trials_string.empty()) | 38 if (trials_string.empty()) |
53 return; | 39 return; |
54 | 40 |
55 size_t next_item = 0; | 41 size_t next_item = 0; |
| 42 std::map<std::string, std::string> field_trials; |
56 while (next_item < trials_string.length()) { | 43 while (next_item < trials_string.length()) { |
57 size_t name_end = trials_string.find(kPersistentStringSeparator, next_item); | 44 size_t name_end = trials_string.find(kPersistentStringSeparator, next_item); |
58 if (name_end == trials_string.npos || next_item == name_end) | 45 if (name_end == trials_string.npos || next_item == name_end) |
59 break; | 46 break; |
60 size_t group_name_end = trials_string.find(kPersistentStringSeparator, | 47 size_t group_name_end = trials_string.find(kPersistentStringSeparator, |
61 name_end + 1); | 48 name_end + 1); |
62 if (group_name_end == trials_string.npos || name_end + 1 == group_name_end) | 49 if (group_name_end == trials_string.npos || name_end + 1 == group_name_end) |
63 break; | 50 break; |
64 std::string name(trials_string, next_item, name_end - next_item); | 51 std::string name(trials_string, next_item, name_end - next_item); |
65 std::string group_name(trials_string, name_end + 1, | 52 std::string group_name(trials_string, name_end + 1, |
66 group_name_end - name_end - 1); | 53 group_name_end - name_end - 1); |
67 next_item = group_name_end + 1; | 54 next_item = group_name_end + 1; |
68 | 55 |
69 // Fail if duplicate with different group name. | 56 // Fail if duplicate with different group name. |
70 if (field_trials_.find(name) != field_trials_.end() && | 57 if (field_trials.find(name) != field_trials.end() && |
71 field_trials_.find(name)->second != group_name) | 58 field_trials.find(name)->second != group_name) { |
72 break; | 59 break; |
| 60 } |
73 | 61 |
74 field_trials_[name] = group_name; | 62 field_trials[name] = group_name; |
75 | 63 |
76 // Successfully parsed all field trials from the string. | 64 // Successfully parsed all field trials from the string. |
77 if (next_item == trials_string.length()) | 65 if (next_item == trials_string.length()) { |
| 66 webrtc::field_trial::InitFieldTrialsFromString(trials_string.c_str()); |
78 return; | 67 return; |
| 68 } |
79 } | 69 } |
80 // Using fprintf as LOG does not print when this is called early in main. | 70 // Using fprintf as LOG does not print when this is called early in main. |
81 fprintf(stderr, "Invalid field trials string.\n"); | 71 fprintf(stderr, "Invalid field trials string.\n"); |
82 | 72 |
83 // Using abort so it crashes in both debug and release mode. | 73 // Using abort so it crashes in both debug and release mode. |
84 abort(); | 74 abort(); |
85 } | 75 } |
86 | 76 |
87 ScopedFieldTrials::ScopedFieldTrials(const std::string& config) | 77 ScopedFieldTrials::ScopedFieldTrials(const std::string& config) |
88 : previous_field_trials_(field_trials_) { | 78 : previous_field_trials_(webrtc::field_trial::GetFieldTrialString()) { |
89 assert(field_trials_initiated_); | 79 assert(field_trials_initiated_); |
90 field_trials_initiated_ = false; | 80 field_trials_initiated_ = false; |
91 field_trials_.clear(); | 81 current_field_trials_ = config; |
92 InitFieldTrialsFromString(config); | 82 InitFieldTrialsFromString(current_field_trials_); |
93 } | 83 } |
94 | 84 |
95 ScopedFieldTrials::~ScopedFieldTrials() { | 85 ScopedFieldTrials::~ScopedFieldTrials() { |
96 // Should still be initialized, since InitFieldTrials is called from ctor. | 86 // Should still be initialized, since InitFieldTrials is called from ctor. |
97 // That's why we don't restore the flag. | 87 // That's why we don't restore the flag. |
98 assert(field_trials_initiated_); | 88 assert(field_trials_initiated_); |
99 field_trials_ = previous_field_trials_; | 89 webrtc::field_trial::InitFieldTrialsFromString(previous_field_trials_); |
100 } | 90 } |
101 | 91 |
102 } // namespace test | 92 } // namespace test |
103 } // namespace webrtc | 93 } // namespace webrtc |
OLD | NEW |