1 // Copyright 2017 The Chromium Authors
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 "components/metrics/net/network_metrics_provider.h"
6
7 #include <memory>
8
9 #include "base/functional/callback.h"
10 #include "base/memory/ptr_util.h"
11 #include "base/run_loop.h"
12 #include "build/build_config.h"
13 #include "build/chromeos_buildflags.h"
14 #include "services/network/test/test_network_connection_tracker.h"
15 #include "testing/gtest/include/gtest/gtest.h"
16 #include "third_party/metrics_proto/system_profile.pb.h"
17
18 #if BUILDFLAG(IS_CHROMEOS_ASH)
19 #include "chromeos/ash/components/network/network_handler_test_helper.h"
20 #endif // BUILDFLAG(IS_CHROMEOS_ASH)
21
22 #if BUILDFLAG(IS_IOS)
23 #include "ios/web/public/test/web_task_environment.h"
24 #else // !BUILDFLAG(IS_IOS)
25 #include "content/public/test/browser_task_environment.h"
26 #endif // BUILDFLAG(IS_IOS)
27
28 namespace metrics {
29
30 class NetworkMetricsProviderTest : public testing::Test {
31 public:
32 NetworkMetricsProviderTest(const NetworkMetricsProviderTest&) = delete;
33 NetworkMetricsProviderTest& operator=(const NetworkMetricsProviderTest&) =
34 delete;
35
36 protected:
37 NetworkMetricsProviderTest() = default;
38 ~NetworkMetricsProviderTest() override = default;
39
40 private:
41 #if BUILDFLAG(IS_IOS)
42 web::WebTaskEnvironment task_environment_{
43 web::WebTaskEnvironment::MainThreadType::IO};
44 #else
45 content::BrowserTaskEnvironment task_environment_{
46 content::BrowserTaskEnvironment::IO_MAINLOOP};
47 #endif
48 #if BUILDFLAG(IS_CHROMEOS_ASH)
49 ash::NetworkHandlerTestHelper network_handler_test_helper_;
50 #endif // BUILDFLAG(IS_CHROMEOS_ASH)
51 };
52
53 // Verifies that the effective connection type is correctly set.
TEST_F(NetworkMetricsProviderTest,EffectiveConnectionType)54 TEST_F(NetworkMetricsProviderTest, EffectiveConnectionType) {
55 NetworkMetricsProvider network_metrics_provider(
56 network::TestNetworkConnectionTracker::CreateAsyncGetter());
57 base::RunLoop().RunUntilIdle();
58
59 EXPECT_EQ(net::EFFECTIVE_CONNECTION_TYPE_UNKNOWN,
60 network_metrics_provider.effective_connection_type_);
61 EXPECT_EQ(net::EFFECTIVE_CONNECTION_TYPE_UNKNOWN,
62 network_metrics_provider.min_effective_connection_type_);
63 EXPECT_EQ(net::EFFECTIVE_CONNECTION_TYPE_UNKNOWN,
64 network_metrics_provider.max_effective_connection_type_);
65 SystemProfileProto system_profile;
66 network_metrics_provider.ProvideSystemProfileMetrics(&system_profile);
67 EXPECT_EQ(SystemProfileProto::Network::EFFECTIVE_CONNECTION_TYPE_UNKNOWN,
68 system_profile.network().min_effective_connection_type());
69 EXPECT_EQ(SystemProfileProto::Network::EFFECTIVE_CONNECTION_TYPE_UNKNOWN,
70 system_profile.network().max_effective_connection_type());
71
72 network_metrics_provider.OnEffectiveConnectionTypeChanged(
73 net::EFFECTIVE_CONNECTION_TYPE_2G);
74 EXPECT_EQ(net::EFFECTIVE_CONNECTION_TYPE_2G,
75 network_metrics_provider.effective_connection_type_);
76 EXPECT_EQ(net::EFFECTIVE_CONNECTION_TYPE_2G,
77 network_metrics_provider.min_effective_connection_type_);
78 EXPECT_EQ(net::EFFECTIVE_CONNECTION_TYPE_2G,
79 network_metrics_provider.max_effective_connection_type_);
80 network_metrics_provider.ProvideSystemProfileMetrics(&system_profile);
81 EXPECT_EQ(SystemProfileProto::Network::EFFECTIVE_CONNECTION_TYPE_2G,
82 system_profile.network().min_effective_connection_type());
83 EXPECT_EQ(SystemProfileProto::Network::EFFECTIVE_CONNECTION_TYPE_2G,
84 system_profile.network().max_effective_connection_type());
85
86 network_metrics_provider.OnEffectiveConnectionTypeChanged(
87 net::EFFECTIVE_CONNECTION_TYPE_SLOW_2G);
88 EXPECT_EQ(net::EFFECTIVE_CONNECTION_TYPE_SLOW_2G,
89 network_metrics_provider.effective_connection_type_);
90 EXPECT_EQ(net::EFFECTIVE_CONNECTION_TYPE_SLOW_2G,
91 network_metrics_provider.min_effective_connection_type_);
92 EXPECT_EQ(net::EFFECTIVE_CONNECTION_TYPE_2G,
93 network_metrics_provider.max_effective_connection_type_);
94 network_metrics_provider.ProvideSystemProfileMetrics(&system_profile);
95 // Effective connection type changed from 2G to SLOW_2G during the lifetime of
96 // the log. Minimum value of ECT must be different from the maximum value.
97 EXPECT_EQ(SystemProfileProto::Network::EFFECTIVE_CONNECTION_TYPE_SLOW_2G,
98 system_profile.network().min_effective_connection_type());
99 EXPECT_EQ(SystemProfileProto::Network::EFFECTIVE_CONNECTION_TYPE_2G,
100 system_profile.network().max_effective_connection_type());
101
102 // Getting the system profile again should return the current effective
103 // connection type.
104 network_metrics_provider.ProvideSystemProfileMetrics(&system_profile);
105 EXPECT_EQ(SystemProfileProto::Network::EFFECTIVE_CONNECTION_TYPE_SLOW_2G,
106 system_profile.network().min_effective_connection_type());
107 EXPECT_EQ(SystemProfileProto::Network::EFFECTIVE_CONNECTION_TYPE_SLOW_2G,
108 system_profile.network().max_effective_connection_type());
109 }
110
111 // Verifies that the effective connection type is not set to UNKNOWN when there
112 // is a change in the connection type.
TEST_F(NetworkMetricsProviderTest,ECTAmbiguousOnConnectionTypeChange)113 TEST_F(NetworkMetricsProviderTest, ECTAmbiguousOnConnectionTypeChange) {
114 NetworkMetricsProvider network_metrics_provider(
115 network::TestNetworkConnectionTracker::CreateAsyncGetter());
116 base::RunLoop().RunUntilIdle();
117
118 EXPECT_EQ(net::EFFECTIVE_CONNECTION_TYPE_UNKNOWN,
119 network_metrics_provider.effective_connection_type_);
120 EXPECT_EQ(net::EFFECTIVE_CONNECTION_TYPE_UNKNOWN,
121 network_metrics_provider.min_effective_connection_type_);
122 EXPECT_EQ(net::EFFECTIVE_CONNECTION_TYPE_UNKNOWN,
123 network_metrics_provider.max_effective_connection_type_);
124
125 network_metrics_provider.OnEffectiveConnectionTypeChanged(
126 net::EFFECTIVE_CONNECTION_TYPE_2G);
127 EXPECT_EQ(net::EFFECTIVE_CONNECTION_TYPE_2G,
128 network_metrics_provider.effective_connection_type_);
129 EXPECT_EQ(net::EFFECTIVE_CONNECTION_TYPE_2G,
130 network_metrics_provider.min_effective_connection_type_);
131 EXPECT_EQ(net::EFFECTIVE_CONNECTION_TYPE_2G,
132 network_metrics_provider.max_effective_connection_type_);
133
134 // There is no change in the connection type. Effective connection types
135 // should be reported as 2G.
136 SystemProfileProto system_profile;
137 network_metrics_provider.ProvideSystemProfileMetrics(&system_profile);
138 EXPECT_EQ(SystemProfileProto::Network::EFFECTIVE_CONNECTION_TYPE_2G,
139 system_profile.network().min_effective_connection_type());
140 EXPECT_EQ(SystemProfileProto::Network::EFFECTIVE_CONNECTION_TYPE_2G,
141 system_profile.network().max_effective_connection_type());
142
143 // Even with change in the connection type, effective connection types
144 // should be reported as 2G.
145 network_metrics_provider.OnConnectionChanged(
146 network::mojom::ConnectionType::CONNECTION_2G);
147 network_metrics_provider.ProvideSystemProfileMetrics(&system_profile);
148 EXPECT_EQ(SystemProfileProto::Network::EFFECTIVE_CONNECTION_TYPE_2G,
149 system_profile.network().min_effective_connection_type());
150 EXPECT_EQ(SystemProfileProto::Network::EFFECTIVE_CONNECTION_TYPE_2G,
151 system_profile.network().max_effective_connection_type());
152 }
153
154 // Verifies that the effective connection type is not set to UNKNOWN when the
155 // connection type is OFFLINE.
TEST_F(NetworkMetricsProviderTest,ECTNotAmbiguousOnUnknownOrOffline)156 TEST_F(NetworkMetricsProviderTest, ECTNotAmbiguousOnUnknownOrOffline) {
157 for (net::EffectiveConnectionType force_ect :
158 {net::EFFECTIVE_CONNECTION_TYPE_UNKNOWN,
159 net::EFFECTIVE_CONNECTION_TYPE_OFFLINE}) {
160 NetworkMetricsProvider network_metrics_provider(
161 network::TestNetworkConnectionTracker::CreateAsyncGetter());
162 base::RunLoop().RunUntilIdle();
163
164 network_metrics_provider.OnEffectiveConnectionTypeChanged(
165 net::EFFECTIVE_CONNECTION_TYPE_2G);
166
167 SystemProfileProto system_profile;
168 network_metrics_provider.ProvideSystemProfileMetrics(&system_profile);
169
170 network_metrics_provider.OnEffectiveConnectionTypeChanged(force_ect);
171
172 network_metrics_provider.ProvideSystemProfileMetrics(&system_profile);
173 EXPECT_EQ(SystemProfileProto::Network::EFFECTIVE_CONNECTION_TYPE_2G,
174 system_profile.network().min_effective_connection_type());
175 EXPECT_EQ(SystemProfileProto::Network::EFFECTIVE_CONNECTION_TYPE_2G,
176 system_profile.network().max_effective_connection_type());
177
178 network_metrics_provider.OnEffectiveConnectionTypeChanged(
179 net::EFFECTIVE_CONNECTION_TYPE_4G);
180 network_metrics_provider.ProvideSystemProfileMetrics(&system_profile);
181 EXPECT_EQ(SystemProfileProto::Network::EFFECTIVE_CONNECTION_TYPE_4G,
182 system_profile.network().min_effective_connection_type());
183 EXPECT_EQ(SystemProfileProto::Network::EFFECTIVE_CONNECTION_TYPE_4G,
184 system_profile.network().max_effective_connection_type());
185 }
186 }
187
188 // Verifies that the connection type is ambiguous boolean is correctly set.
TEST_F(NetworkMetricsProviderTest,ConnectionTypeIsAmbiguous)189 TEST_F(NetworkMetricsProviderTest, ConnectionTypeIsAmbiguous) {
190 NetworkMetricsProvider network_metrics_provider(
191 network::TestNetworkConnectionTracker::CreateAsyncGetter());
192
193 EXPECT_EQ(network::mojom::ConnectionType::CONNECTION_UNKNOWN,
194 network_metrics_provider.connection_type_);
195 EXPECT_FALSE(network_metrics_provider.connection_type_is_ambiguous_);
196 EXPECT_FALSE(
197 network_metrics_provider.network_connection_tracker_initialized_);
198
199 // When a connection type change callback is received, network change notifier
200 // should be marked as initialized.
201 network_metrics_provider.OnConnectionChanged(
202 network::mojom::ConnectionType::CONNECTION_2G);
203 EXPECT_EQ(network::mojom::ConnectionType::CONNECTION_2G,
204 network_metrics_provider.connection_type_);
205 // Connection type should not be marked as ambiguous when a delayed connection
206 // type change callback is received due to delayed initialization of the
207 // network change notifier.
208 EXPECT_FALSE(network_metrics_provider.connection_type_is_ambiguous_);
209 EXPECT_TRUE(network_metrics_provider.network_connection_tracker_initialized_);
210
211 // On collection of the system profile, |connection_type_is_ambiguous_| should
212 // stay false, and |network_connection_tracker_initialized_| should remain
213 // true.
214 SystemProfileProto system_profile;
215 network_metrics_provider.ProvideSystemProfileMetrics(&system_profile);
216 EXPECT_FALSE(network_metrics_provider.connection_type_is_ambiguous_);
217 EXPECT_TRUE(network_metrics_provider.network_connection_tracker_initialized_);
218 EXPECT_FALSE(system_profile.network().connection_type_is_ambiguous());
219 EXPECT_EQ(SystemProfileProto::Network::CONNECTION_2G,
220 system_profile.network().connection_type());
221
222 network_metrics_provider.OnConnectionChanged(
223 network::mojom::ConnectionType::CONNECTION_3G);
224 EXPECT_TRUE(network_metrics_provider.connection_type_is_ambiguous_);
225 EXPECT_TRUE(network_metrics_provider.network_connection_tracker_initialized_);
226
227 // On collection of the system profile, |connection_type_is_ambiguous_| should
228 // be reset to false, and |network_connection_tracker_initialized_| should
229 // remain true.
230 network_metrics_provider.ProvideSystemProfileMetrics(&system_profile);
231 EXPECT_FALSE(network_metrics_provider.connection_type_is_ambiguous_);
232 EXPECT_TRUE(network_metrics_provider.network_connection_tracker_initialized_);
233 EXPECT_TRUE(system_profile.network().connection_type_is_ambiguous());
234 EXPECT_EQ(SystemProfileProto::Network::CONNECTION_3G,
235 system_profile.network().connection_type());
236 }
237
238 } // namespace metrics
239