1 // Copyright 2017 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 <map>
6 #include <memory>
7
8 #include "base/command_line.h"
9 #include "base/metrics/field_trial.h"
10 #include "base/run_loop.h"
11 #include "base/values.h"
12 #include "chrome/browser/browser_process.h"
13 #include "chrome/browser/net/system_network_context_manager.h"
14 #include "chrome/common/chrome_switches.h"
15 #include "chrome/test/base/in_process_browser_test.h"
16 #include "components/variations/variations_associated_data.h"
17 #include "content/public/browser/browser_thread.h"
18 #include "content/public/test/browser_test.h"
19 #include "net/base/features.h"
20 #include "net/nqe/network_quality_estimator.h"
21 #include "net/test/embedded_test_server/embedded_test_server.h"
22 #include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
23 #include "services/network/public/cpp/network_quality_tracker.h"
24 #include "testing/gtest/include/gtest/gtest.h"
25 #include "url/gurl.h"
26
27 namespace {
28
29 class TestNetworkQualityObserver
30 : public network::NetworkQualityTracker::EffectiveConnectionTypeObserver {
31 public:
TestNetworkQualityObserver(network::NetworkQualityTracker * tracker)32 explicit TestNetworkQualityObserver(network::NetworkQualityTracker* tracker)
33 : run_loop_wait_effective_connection_type_(
34 net::EFFECTIVE_CONNECTION_TYPE_UNKNOWN),
35 tracker_(tracker),
36 effective_connection_type_(net::EFFECTIVE_CONNECTION_TYPE_UNKNOWN) {
37 tracker_->AddEffectiveConnectionTypeObserver(this);
38 }
39
~TestNetworkQualityObserver()40 ~TestNetworkQualityObserver() override {
41 tracker_->RemoveEffectiveConnectionTypeObserver(this);
42 }
43
44 // NetworkQualityTracker::EffectiveConnectionTypeObserver implementation:
OnEffectiveConnectionTypeChanged(net::EffectiveConnectionType type)45 void OnEffectiveConnectionTypeChanged(
46 net::EffectiveConnectionType type) override {
47 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
48
49 net::EffectiveConnectionType queried_type =
50 tracker_->GetEffectiveConnectionType();
51 EXPECT_EQ(type, queried_type);
52
53 effective_connection_type_ = type;
54 if (effective_connection_type_ != run_loop_wait_effective_connection_type_)
55 return;
56 if (run_loop_)
57 run_loop_->Quit();
58 }
59
WaitForNotification(net::EffectiveConnectionType run_loop_wait_effective_connection_type)60 void WaitForNotification(
61 net::EffectiveConnectionType run_loop_wait_effective_connection_type) {
62 if (effective_connection_type_ == run_loop_wait_effective_connection_type)
63 return;
64 ASSERT_NE(net::EFFECTIVE_CONNECTION_TYPE_UNKNOWN,
65 run_loop_wait_effective_connection_type);
66 run_loop_.reset(new base::RunLoop());
67 run_loop_wait_effective_connection_type_ =
68 run_loop_wait_effective_connection_type;
69 run_loop_->Run();
70 run_loop_.reset();
71 }
72
73 private:
74 net::EffectiveConnectionType run_loop_wait_effective_connection_type_;
75 std::unique_ptr<base::RunLoop> run_loop_;
76 network::NetworkQualityTracker* tracker_;
77 net::EffectiveConnectionType effective_connection_type_;
78
79 DISALLOW_COPY_AND_ASSIGN(TestNetworkQualityObserver);
80 };
81
CheckEffectiveConnectionType(net::EffectiveConnectionType expected)82 void CheckEffectiveConnectionType(net::EffectiveConnectionType expected) {
83 TestNetworkQualityObserver network_quality_observer(
84 g_browser_process->network_quality_tracker());
85 network_quality_observer.WaitForNotification(expected);
86 }
87
88 class NetworkQualityEstimatorBrowserTest : public InProcessBrowserTest {
89 public:
NetworkQualityEstimatorBrowserTest()90 NetworkQualityEstimatorBrowserTest() {}
~NetworkQualityEstimatorBrowserTest()91 ~NetworkQualityEstimatorBrowserTest() override {}
92
SetUp()93 void SetUp() override {
94 // Must start listening (And get a port for the proxy) before calling
95 // SetUp(). Use two phase EmbeddedTestServer setup for proxy tests.
96 ASSERT_TRUE(embedded_test_server()->InitializeAndListen());
97 InProcessBrowserTest::SetUp();
98 }
99
SetUpOnMainThread()100 void SetUpOnMainThread() override {
101 embedded_test_server()->StartAcceptingConnections();
102 }
103
TearDown()104 void TearDown() override {
105 // Need to stop this before |connection_listener_| is destroyed.
106 EXPECT_TRUE(embedded_test_server()->ShutdownAndWaitUntilComplete());
107 InProcessBrowserTest::TearDown();
108 }
109 };
110
111 class NetworkQualityEstimatorEctCommandLineBrowserTest
112 : public NetworkQualityEstimatorBrowserTest {
113 public:
NetworkQualityEstimatorEctCommandLineBrowserTest()114 NetworkQualityEstimatorEctCommandLineBrowserTest() {}
~NetworkQualityEstimatorEctCommandLineBrowserTest()115 ~NetworkQualityEstimatorEctCommandLineBrowserTest() override {}
116
SetUpCommandLine(base::CommandLine * command_line)117 void SetUpCommandLine(base::CommandLine* command_line) override {
118 command_line->AppendSwitchASCII("--force-effective-connection-type",
119 "Slow-2G");
120 }
121 };
122
IN_PROC_BROWSER_TEST_F(NetworkQualityEstimatorEctCommandLineBrowserTest,ForceECTFromCommandLine)123 IN_PROC_BROWSER_TEST_F(NetworkQualityEstimatorEctCommandLineBrowserTest,
124 ForceECTFromCommandLine) {
125 CheckEffectiveConnectionType(net::EFFECTIVE_CONNECTION_TYPE_SLOW_2G);
126 }
127
128 class NetworkQualityEstimatorEctFieldTrialBrowserTest
129 : public NetworkQualityEstimatorBrowserTest {
130 public:
NetworkQualityEstimatorEctFieldTrialBrowserTest()131 NetworkQualityEstimatorEctFieldTrialBrowserTest() {}
~NetworkQualityEstimatorEctFieldTrialBrowserTest()132 ~NetworkQualityEstimatorEctFieldTrialBrowserTest() override {}
133
SetUpCommandLine(base::CommandLine * command_line)134 void SetUpCommandLine(base::CommandLine* command_line) override {
135 variations::testing::ClearAllVariationParams();
136 std::map<std::string, std::string> variation_params;
137 variation_params["force_effective_connection_type"] = "2G";
138 scoped_feature_list_.InitAndEnableFeatureWithParameters(
139 net::features::kNetworkQualityEstimator, variation_params);
140 }
141
142 private:
143 base::test::ScopedFeatureList scoped_feature_list_;
144 };
145
IN_PROC_BROWSER_TEST_F(NetworkQualityEstimatorEctFieldTrialBrowserTest,ForceECTUsingFieldTrial)146 IN_PROC_BROWSER_TEST_F(NetworkQualityEstimatorEctFieldTrialBrowserTest,
147 ForceECTUsingFieldTrial) {
148 CheckEffectiveConnectionType(net::EFFECTIVE_CONNECTION_TYPE_2G);
149 }
150
151 class NetworkQualityEstimatorEctFieldTrialAndCommandLineBrowserTest
152 : public NetworkQualityEstimatorEctFieldTrialBrowserTest {
153 public:
NetworkQualityEstimatorEctFieldTrialAndCommandLineBrowserTest()154 NetworkQualityEstimatorEctFieldTrialAndCommandLineBrowserTest() {}
~NetworkQualityEstimatorEctFieldTrialAndCommandLineBrowserTest()155 ~NetworkQualityEstimatorEctFieldTrialAndCommandLineBrowserTest() override {}
156
SetUpCommandLine(base::CommandLine * command_line)157 void SetUpCommandLine(base::CommandLine* command_line) override {
158 NetworkQualityEstimatorEctFieldTrialBrowserTest::SetUpCommandLine(
159 command_line);
160 command_line->AppendSwitchASCII("--force-effective-connection-type",
161 "Slow-2G");
162 }
163 };
164
IN_PROC_BROWSER_TEST_F(NetworkQualityEstimatorEctFieldTrialAndCommandLineBrowserTest,ECTFromCommandLineOverridesFieldTrial)165 IN_PROC_BROWSER_TEST_F(
166 NetworkQualityEstimatorEctFieldTrialAndCommandLineBrowserTest,
167 ECTFromCommandLineOverridesFieldTrial) {
168 CheckEffectiveConnectionType(net::EFFECTIVE_CONNECTION_TYPE_SLOW_2G);
169 }
170
171 } // namespace
172