OLD | NEW |
| (Empty) |
1 // Copyright 2016 The Chromium Authors. All rights reserved. | |
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 "chrome/common/variations/child_process_field_trial_syncer.h" | |
6 | |
7 #include <string> | |
8 #include <utility> | |
9 #include <vector> | |
10 | |
11 #include "base/base_switches.h" | |
12 #include "base/command_line.h" | |
13 #include "base/message_loop/message_loop.h" | |
14 #include "base/metrics/field_trial.h" | |
15 #include "base/run_loop.h" | |
16 #include "testing/gtest/include/gtest/gtest.h" | |
17 | |
18 namespace chrome_variations { | |
19 | |
20 namespace { | |
21 | |
22 // TestFieldTrialObserver to listen to be notified by the child process syncer. | |
23 class TestFieldTrialObserver : public base::FieldTrialList::Observer { | |
24 public: | |
25 TestFieldTrialObserver() {} | |
26 ~TestFieldTrialObserver() override {} | |
27 | |
28 // base::FieldTrial::Observer: | |
29 void OnFieldTrialGroupFinalized(const std::string& trial_name, | |
30 const std::string& group_name) override { | |
31 observed_entries_.push_back(std::make_pair(trial_name, group_name)); | |
32 } | |
33 | |
34 size_t observed_entries_count() const { return observed_entries_.size(); } | |
35 | |
36 std::pair<std::string, std::string> get_observed_entry(int i) const { | |
37 return observed_entries_[i]; | |
38 } | |
39 | |
40 private: | |
41 std::vector<std::pair<std::string, std::string>> observed_entries_; | |
42 | |
43 DISALLOW_COPY_AND_ASSIGN(TestFieldTrialObserver); | |
44 }; | |
45 | |
46 // Needed because make_pair("a", "b") doesn't convert to std::string pair. | |
47 std::pair<std::string, std::string> MakeStringPair(const std::string& a, | |
48 const std::string& b) { | |
49 return std::make_pair(a, b); | |
50 } | |
51 | |
52 } // namespace | |
53 | |
54 TEST(ChildProcessFieldTrialSyncerTest, FieldTrialState) { | |
55 base::MessageLoop message_loop; | |
56 base::FieldTrialList field_trial_list(nullptr); | |
57 base::FieldTrialList::CreateTrialsFromCommandLine( | |
58 *base::CommandLine::ForCurrentProcess(), "field_trial_handle_switch"); | |
59 | |
60 base::FieldTrial* trial1 = base::FieldTrialList::CreateFieldTrial("A", "G1"); | |
61 base::FieldTrial* trial2 = base::FieldTrialList::CreateFieldTrial("B", "G2"); | |
62 base::FieldTrial* trial3 = base::FieldTrialList::CreateFieldTrial("C", "G3"); | |
63 // Activate trial3 before command line is produced. | |
64 trial1->group(); | |
65 | |
66 std::string states_string; | |
67 base::FieldTrialList::AllStatesToString(&states_string); | |
68 | |
69 base::CommandLine::ForCurrentProcess()->AppendSwitchASCII( | |
70 switches::kForceFieldTrials, states_string); | |
71 EXPECT_EQ("*A/G1/B/G2/C/G3/", states_string); | |
72 | |
73 // Active trial 2 before creating the syncer. | |
74 trial2->group(); | |
75 | |
76 TestFieldTrialObserver observer; | |
77 ChildProcessFieldTrialSyncer syncer(&observer); | |
78 syncer.InitFieldTrialObserving(*base::CommandLine::ForCurrentProcess()); | |
79 | |
80 // The observer should be notified of activated entries that were not activate | |
81 // on the command line. In this case, trial 2. (Trial 1 was already active via | |
82 // command line and so its state shouldn't be notified.) | |
83 ASSERT_EQ(1U, observer.observed_entries_count()); | |
84 EXPECT_EQ(MakeStringPair("B", "G2"), observer.get_observed_entry(0)); | |
85 | |
86 // Now, activate trial 3, which should also get reflected. | |
87 trial3->group(); | |
88 // Notifications from field trial activation actually happen via posted tasks, | |
89 // so invoke the run loop. | |
90 base::RunLoop().RunUntilIdle(); | |
91 | |
92 ASSERT_EQ(2U, observer.observed_entries_count()); | |
93 EXPECT_EQ(MakeStringPair("C", "G3"), observer.get_observed_entry(1)); | |
94 } | |
95 | |
96 } // namespace chrome_variations | |
OLD | NEW |