• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *  Copyright (c) 2014 The WebRTC project authors. All Rights Reserved.
3  *
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
6  *  tree. An additional intellectual property rights grant can be found
7  *  in the file PATENTS.  All contributing project authors may
8  *  be found in the AUTHORS file in the root of the source tree.
9  */
10 
11 #include "webrtc/test/field_trial.h"
12 
13 #include <algorithm>
14 #include <cassert>
15 #include <cstdio>
16 #include <cstdlib>
17 #include <map>
18 #include <string>
19 
20 #include "webrtc/system_wrappers/interface/field_trial.h"
21 
22 namespace webrtc {
23 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;
28 std::map<std::string, std::string> field_trials_;
29 }  // namespace
30 
31 namespace field_trial {
FindFullName(const std::string & trial_name)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 {
43 // Note: this code is copied from src/base/metrics/field_trial.cc since the aim
44 // is to mimic chromium --force-fieldtrials.
InitFieldTrialsFromString(const std::string & trials_string)45 void InitFieldTrialsFromString(const std::string& trials_string) {
46   static const char kPersistentStringSeparator = '/';
47 
48   // Catch an error if this is called more than once.
49   assert(field_trials_initiated_ == false);
50   field_trials_initiated_ = true;
51 
52   if (trials_string.empty()) return;
53 
54   size_t next_item = 0;
55   while (next_item < trials_string.length()) {
56     size_t name_end = trials_string.find(kPersistentStringSeparator, next_item);
57     if (name_end == trials_string.npos || next_item == name_end)
58       break;
59     size_t group_name_end = trials_string.find(kPersistentStringSeparator,
60                                                name_end + 1);
61     if (group_name_end == trials_string.npos || name_end + 1 == group_name_end)
62       break;
63     std::string name(trials_string, next_item, name_end - next_item);
64     std::string group_name(trials_string, name_end + 1,
65                            group_name_end - name_end - 1);
66     next_item = group_name_end + 1;
67 
68     // Fail if duplicate with different group name.
69     if (field_trials_.find(name) != field_trials_.end() &&
70         field_trials_.find(name)->second != group_name)
71       break;
72 
73     field_trials_[name] = group_name;
74 
75     // Successfully parsed all field trials from the string.
76     if (next_item == trials_string.length())
77       return;
78   }
79   // LOG does not prints when this is called early on main.
80   fprintf(stderr, "Invalid field trials string.\n");
81 
82   // Using abort so it crashs both in debug and release mode.
83   abort();
84 }
85 }  // namespace test
86 }  // namespace webrtc
87