1 // Copyright 2019 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 "base/macros.h"
6 #include "base/metrics/field_trial.h"
7 #include "base/run_loop.h"
8 #include "base/test/mock_entropy_provider.h"
9 #include "content/browser/startup_helper.h"
10 #include "content/public/browser/network_service_instance.h"
11 #include "content/public/common/network_service_util.h"
12 #include "content/public/test/content_browser_test.h"
13 #include "mojo/public/cpp/bindings/remote.h"
14 #include "services/network/public/mojom/network_service_test.mojom.h"
15 #include "testing/gtest/include/gtest/gtest.h"
16 
17 namespace content {
18 
19 namespace {
20 
21 const char kFieldTrialName[] = "UniqueFieldTrialName";
22 const char kFieldTrialGroup[] = "UniqueFieldTrialGroupName";
23 
24 class TestFieldTrialListObserver : public base::FieldTrialList::Observer {
25  public:
TestFieldTrialListObserver()26   TestFieldTrialListObserver() { base::FieldTrialList::AddObserver(this); }
27 
~TestFieldTrialListObserver()28   ~TestFieldTrialListObserver() override {
29     base::FieldTrialList::RemoveObserver(this);
30   }
31 
WaitForTrialGroupToBeFinalized()32   void WaitForTrialGroupToBeFinalized() { run_loop_.Run(); }
33 
34   // base::FieldTrialList::Observer:
OnFieldTrialGroupFinalized(const std::string & trial_name,const std::string & group_name)35   void OnFieldTrialGroupFinalized(const std::string& trial_name,
36                                   const std::string& group_name) override {
37     if (trial_name == kFieldTrialName) {
38       EXPECT_EQ(kFieldTrialGroup, group_name);
39       run_loop_.Quit();
40     }
41   }
42 
43  private:
44   base::RunLoop run_loop_;
45 
46   DISALLOW_COPY_AND_ASSIGN(TestFieldTrialListObserver);
47 };
48 
49 }  // namespace
50 
51 class NetworkFieldTrialBrowserTest : public ContentBrowserTest {
52  public:
NetworkFieldTrialBrowserTest()53   NetworkFieldTrialBrowserTest()
54       : field_trial_list_(SetUpFieldTrialsAndFeatureList()) {
55     // The field trial needs to be created before the NetworkService is created
56     // so that the NetworkService will automatically be informed of its
57     // existence.
58     base::MockEntropyProvider entropy_provider;
59     base::FieldTrial* trial =
60         base::FieldTrialList::FactoryGetFieldTrialWithRandomizationSeed(
61             kFieldTrialName, 1 /* total_probability */, kFieldTrialGroup,
62             base::FieldTrial::ONE_TIME_RANDOMIZED, 0 /* randomization_seed */,
63             nullptr /* default_group_number */, &entropy_provider);
64     EXPECT_TRUE(trial);
65   }
66 
67   ~NetworkFieldTrialBrowserTest() override = default;
68 
69  private:
70   std::unique_ptr<base::FieldTrialList> field_trial_list_;
71 
72   DISALLOW_COPY_AND_ASSIGN(NetworkFieldTrialBrowserTest);
73 };
74 
75 // Test that when the network process activates a field trial, the browser
76 // process is informed. See https://crbug.com/1018329
IN_PROC_BROWSER_TEST_F(NetworkFieldTrialBrowserTest,FieldTrialRegistered)77 IN_PROC_BROWSER_TEST_F(NetworkFieldTrialBrowserTest, FieldTrialRegistered) {
78   // The network::mojom::NetworkServiceTest interface is only available when the
79   // network service is out of process.
80   if (!IsOutOfProcessNetworkService())
81     return;
82 
83   EXPECT_FALSE(base::FieldTrialList::IsTrialActive(kFieldTrialName));
84 
85   // Tell the network service to activate the field trial and wait for it to
86   // inform the browser process about it.
87   TestFieldTrialListObserver observer;
88   mojo::Remote<network::mojom::NetworkServiceTest> network_service_test;
89   GetNetworkService()->BindTestInterface(
90       network_service_test.BindNewPipeAndPassReceiver());
91   network_service_test->ActivateFieldTrial(kFieldTrialName);
92   observer.WaitForTrialGroupToBeFinalized();
93 
94   EXPECT_TRUE(base::FieldTrialList::IsTrialActive(kFieldTrialName));
95 }
96 
97 }  // namespace content
98