blob: 3c4aa6c3dbecb5b1c71d5f8bda945b774f3eeb6c [file] [log] [blame]
Thieu Le3426c8f2012-01-11 17:35:11 -08001// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
Thieu Le48e6d6d2011-12-06 00:40:27 +00002// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "shill/metrics.h"
6
7#include <chromeos/dbus/service_constants.h>
8#include <metrics/metrics_library_mock.h>
Thieu Lea20cbc22012-01-09 22:01:43 +00009#include <metrics/timer_mock.h>
Thieu Le48e6d6d2011-12-06 00:40:27 +000010
11#include "shill/mock_service.h"
12#include "shill/mock_wifi_service.h"
13#include "shill/property_store_unittest.h"
14
15using testing::_;
Thieu Leb84ba342012-03-02 15:15:19 -080016using testing::DoAll;
Thieu Le48e6d6d2011-12-06 00:40:27 +000017using testing::Ge;
Thieu Leb84ba342012-03-02 15:15:19 -080018using testing::Mock;
Thieu Le48e6d6d2011-12-06 00:40:27 +000019using testing::Return;
Thieu Leb84ba342012-03-02 15:15:19 -080020using testing::SetArgumentPointee;
Thieu Le48e6d6d2011-12-06 00:40:27 +000021using testing::Test;
22
23namespace shill {
24
25class MetricsTest : public PropertyStoreTest {
26 public:
27 MetricsTest()
28 : service_(new MockService(control_interface(),
29 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -080030 &metrics_,
Thieu Le48e6d6d2011-12-06 00:40:27 +000031 manager())),
32 wifi_(new WiFi(control_interface(),
33 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -080034 &metrics_,
Thieu Le48e6d6d2011-12-06 00:40:27 +000035 manager(),
36 "wlan0",
37 "000102030405",
38 0)),
39 wifi_service_(new MockWiFiService(control_interface(),
40 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -080041 &metrics_,
Thieu Le48e6d6d2011-12-06 00:40:27 +000042 manager(),
43 wifi_,
44 ssid_,
45 flimflam::kModeManaged,
46 flimflam::kSecurityNone,
47 false)) {
48 }
49
50 virtual ~MetricsTest() {}
51
52 virtual void SetUp() {
53 metrics_.set_library(&library_);
Thieu Le48e6d6d2011-12-06 00:40:27 +000054 }
55
56 protected:
Thieu Leb84ba342012-03-02 15:15:19 -080057 void ExpectCommonPostReady(Metrics::WiFiChannel channel,
58 Metrics::WiFiNetworkPhyMode mode,
59 Metrics::WiFiSecurity security) {
60 EXPECT_CALL(library_, SendEnumToUMA("Network.Shill.Wifi.Channel",
61 channel,
62 Metrics::kMetricNetworkChannelMax));
63 EXPECT_CALL(library_, SendEnumToUMA("Network.Shill.Wifi.PhyMode",
64 mode,
65 Metrics::kWiFiNetworkPhyModeMax));
66 EXPECT_CALL(library_, SendEnumToUMA("Network.Shill.Wifi.Security",
67 security,
68 Metrics::kWiFiSecurityMax));
69 }
70
Thieu Le48e6d6d2011-12-06 00:40:27 +000071 Metrics metrics_; // This must be destroyed after service_ and wifi_service_
72 MetricsLibraryMock library_;
73 scoped_refptr<MockService> service_;
74 WiFiRefPtr wifi_;
75 const std::vector<uint8_t> ssid_;
76 scoped_refptr<MockWiFiService> wifi_service_;
77};
78
79TEST_F(MetricsTest, TimeToConfig) {
80 EXPECT_CALL(library_, SendToUMA("Network.Shill.Unknown.TimeToConfig",
81 Ge(0),
Thieu Lea20cbc22012-01-09 22:01:43 +000082 Metrics::kTimerHistogramMillisecondsMin,
83 Metrics::kTimerHistogramMillisecondsMax,
Thieu Le48e6d6d2011-12-06 00:40:27 +000084 Metrics::kTimerHistogramNumBuckets));
85 metrics_.RegisterService(service_);
86 metrics_.NotifyServiceStateChanged(service_, Service::kStateConfiguring);
Paul Stewart20088d82012-02-16 06:58:55 -080087 metrics_.NotifyServiceStateChanged(service_, Service::kStateConnected);
Thieu Le48e6d6d2011-12-06 00:40:27 +000088}
89
90TEST_F(MetricsTest, TimeToPortal) {
91 EXPECT_CALL(library_, SendToUMA("Network.Shill.Unknown.TimeToPortal",
92 Ge(0),
Thieu Lea20cbc22012-01-09 22:01:43 +000093 Metrics::kTimerHistogramMillisecondsMin,
94 Metrics::kTimerHistogramMillisecondsMax,
Thieu Le48e6d6d2011-12-06 00:40:27 +000095 Metrics::kTimerHistogramNumBuckets));
96 metrics_.RegisterService(service_);
Paul Stewart20088d82012-02-16 06:58:55 -080097 metrics_.NotifyServiceStateChanged(service_, Service::kStateConnected);
Thieu Le48e6d6d2011-12-06 00:40:27 +000098 metrics_.NotifyServiceStateChanged(service_, Service::kStatePortal);
99}
100
101TEST_F(MetricsTest, TimeToOnline) {
102 EXPECT_CALL(library_, SendToUMA("Network.Shill.Unknown.TimeToOnline",
103 Ge(0),
Thieu Lea20cbc22012-01-09 22:01:43 +0000104 Metrics::kTimerHistogramMillisecondsMin,
105 Metrics::kTimerHistogramMillisecondsMax,
Thieu Le48e6d6d2011-12-06 00:40:27 +0000106 Metrics::kTimerHistogramNumBuckets));
107 metrics_.RegisterService(service_);
Paul Stewart20088d82012-02-16 06:58:55 -0800108 metrics_.NotifyServiceStateChanged(service_, Service::kStateConnected);
Thieu Le48e6d6d2011-12-06 00:40:27 +0000109 metrics_.NotifyServiceStateChanged(service_, Service::kStateOnline);
110}
111
112TEST_F(MetricsTest, ServiceFailure) {
113 EXPECT_CALL(*service_.get(), failure())
114 .WillRepeatedly(Return(Service::kFailureBadCredentials));
115 EXPECT_CALL(library_, SendEnumToUMA(Metrics::kMetricNetworkServiceErrors,
116 Service::kFailureBadCredentials,
117 Metrics::kMetricNetworkServiceErrorsMax));
118 metrics_.RegisterService(service_);
119 metrics_.NotifyServiceStateChanged(service_, Service::kStateFailure);
120}
121
122TEST_F(MetricsTest, WiFiServiceTimeToJoin) {
123 EXPECT_CALL(library_, SendToUMA("Network.Shill.Wifi.TimeToJoin",
124 Ge(0),
Thieu Lea20cbc22012-01-09 22:01:43 +0000125 Metrics::kTimerHistogramMillisecondsMin,
126 Metrics::kTimerHistogramMillisecondsMax,
Thieu Le48e6d6d2011-12-06 00:40:27 +0000127 Metrics::kTimerHistogramNumBuckets));
128 metrics_.RegisterService(wifi_service_);
129 metrics_.NotifyServiceStateChanged(wifi_service_, Service::kStateAssociating);
130 metrics_.NotifyServiceStateChanged(wifi_service_, Service::kStateConfiguring);
131}
132
Thieu Lead1ec2c2012-01-05 23:39:48 +0000133TEST_F(MetricsTest, WiFiServicePostReady) {
Thieu Leb84ba342012-03-02 15:15:19 -0800134 base::TimeDelta non_zero_time_delta = base::TimeDelta::FromMilliseconds(1);
135 chromeos_metrics::TimerMock *mock_time_resume_to_ready_timer =
136 new chromeos_metrics::TimerMock;
137 metrics_.set_time_resume_to_ready_timer(mock_time_resume_to_ready_timer);
138
139 ExpectCommonPostReady(Metrics::kWiFiChannel2412,
140 Metrics::kWiFiNetworkPhyMode11a,
141 Metrics::kWiFiSecurityWep);
142 EXPECT_CALL(library_, SendToUMA("Network.Shill.Wifi.TimeResumeToReady",
143 _, _, _, _)).Times(0);
Thieu Le48e6d6d2011-12-06 00:40:27 +0000144 wifi_service_->frequency_ = 2412;
Thieu Lead1ec2c2012-01-05 23:39:48 +0000145 wifi_service_->physical_mode_ = Metrics::kWiFiNetworkPhyMode11a;
146 wifi_service_->security_ = flimflam::kSecurityWep;
Thieu Le48e6d6d2011-12-06 00:40:27 +0000147 metrics_.RegisterService(wifi_service_);
Paul Stewart20088d82012-02-16 06:58:55 -0800148 metrics_.NotifyServiceStateChanged(wifi_service_, Service::kStateConnected);
Thieu Leb84ba342012-03-02 15:15:19 -0800149 Mock::VerifyAndClearExpectations(&library_);
150
151 // Simulate a system suspend, resume and an AP reconnect.
152 ExpectCommonPostReady(Metrics::kWiFiChannel2412,
153 Metrics::kWiFiNetworkPhyMode11a,
154 Metrics::kWiFiSecurityWep);
155 EXPECT_CALL(library_, SendToUMA("Network.Shill.Wifi.TimeResumeToReady",
156 Ge(0),
157 Metrics::kTimerHistogramMillisecondsMin,
158 Metrics::kTimerHistogramMillisecondsMax,
159 Metrics::kTimerHistogramNumBuckets));
160 EXPECT_CALL(*mock_time_resume_to_ready_timer, GetElapsedTime(_)).
161 WillOnce(DoAll(SetArgumentPointee<0>(non_zero_time_delta), Return(true)));
162 metrics_.NotifyPowerStateChange(PowerManagerProxyDelegate::kMem);
163 metrics_.NotifyPowerStateChange(PowerManagerProxyDelegate::kOn);
164 metrics_.NotifyServiceStateChanged(wifi_service_, Service::kStateConnected);
165 Mock::VerifyAndClearExpectations(&library_);
166 Mock::VerifyAndClearExpectations(mock_time_resume_to_ready_timer);
167
168 // Make sure subsequent connects do not count towards TimeResumeToReady.
169 ExpectCommonPostReady(Metrics::kWiFiChannel2412,
170 Metrics::kWiFiNetworkPhyMode11a,
171 Metrics::kWiFiSecurityWep);
172 EXPECT_CALL(library_, SendToUMA("Network.Shill.Wifi.TimeResumeToReady",
173 _, _, _, _)).Times(0);
174 metrics_.NotifyServiceStateChanged(wifi_service_, Service::kStateConnected);
Thieu Le48e6d6d2011-12-06 00:40:27 +0000175}
176
177TEST_F(MetricsTest, FrequencyToChannel) {
178 EXPECT_EQ(Metrics::kWiFiChannelUndef, metrics_.WiFiFrequencyToChannel(2411));
179 EXPECT_EQ(Metrics::kWiFiChannel2412, metrics_.WiFiFrequencyToChannel(2412));
180 EXPECT_EQ(Metrics::kWiFiChannel2472, metrics_.WiFiFrequencyToChannel(2472));
181 EXPECT_EQ(Metrics::kWiFiChannelUndef, metrics_.WiFiFrequencyToChannel(2473));
182 EXPECT_EQ(Metrics::kWiFiChannel2484, metrics_.WiFiFrequencyToChannel(2484));
183 EXPECT_EQ(Metrics::kWiFiChannelUndef, metrics_.WiFiFrequencyToChannel(5169));
184 EXPECT_EQ(Metrics::kWiFiChannel5170, metrics_.WiFiFrequencyToChannel(5170));
185 EXPECT_EQ(Metrics::kWiFiChannel5190, metrics_.WiFiFrequencyToChannel(5190));
186 EXPECT_EQ(Metrics::kWiFiChannel5180, metrics_.WiFiFrequencyToChannel(5180));
187 EXPECT_EQ(Metrics::kWiFiChannel5200, metrics_.WiFiFrequencyToChannel(5200));
188 EXPECT_EQ(Metrics::kWiFiChannel5230, metrics_.WiFiFrequencyToChannel(5230));
189 EXPECT_EQ(Metrics::kWiFiChannelUndef, metrics_.WiFiFrequencyToChannel(5231));
190 EXPECT_EQ(Metrics::kWiFiChannelUndef, metrics_.WiFiFrequencyToChannel(5239));
191 EXPECT_EQ(Metrics::kWiFiChannel5240, metrics_.WiFiFrequencyToChannel(5240));
192 EXPECT_EQ(Metrics::kWiFiChannelUndef, metrics_.WiFiFrequencyToChannel(5241));
193 EXPECT_EQ(Metrics::kWiFiChannel5320, metrics_.WiFiFrequencyToChannel(5320));
194 EXPECT_EQ(Metrics::kWiFiChannelUndef, metrics_.WiFiFrequencyToChannel(5321));
195 EXPECT_EQ(Metrics::kWiFiChannelUndef, metrics_.WiFiFrequencyToChannel(5499));
196 EXPECT_EQ(Metrics::kWiFiChannel5500, metrics_.WiFiFrequencyToChannel(5500));
197 EXPECT_EQ(Metrics::kWiFiChannelUndef, metrics_.WiFiFrequencyToChannel(5501));
198 EXPECT_EQ(Metrics::kWiFiChannel5700, metrics_.WiFiFrequencyToChannel(5700));
199 EXPECT_EQ(Metrics::kWiFiChannelUndef, metrics_.WiFiFrequencyToChannel(5701));
200 EXPECT_EQ(Metrics::kWiFiChannelUndef, metrics_.WiFiFrequencyToChannel(5744));
201 EXPECT_EQ(Metrics::kWiFiChannel5745, metrics_.WiFiFrequencyToChannel(5745));
202 EXPECT_EQ(Metrics::kWiFiChannelUndef, metrics_.WiFiFrequencyToChannel(5746));
203 EXPECT_EQ(Metrics::kWiFiChannel5825, metrics_.WiFiFrequencyToChannel(5825));
204 EXPECT_EQ(Metrics::kWiFiChannelUndef, metrics_.WiFiFrequencyToChannel(5826));
205}
206
Thieu Lea20cbc22012-01-09 22:01:43 +0000207TEST_F(MetricsTest, TimeOnlineTimeToDrop) {
208 chromeos_metrics::TimerMock *mock_time_online_timer =
209 new chromeos_metrics::TimerMock;
210 metrics_.set_time_online_timer(mock_time_online_timer);
211 chromeos_metrics::TimerMock *mock_time_to_drop_timer =
212 new chromeos_metrics::TimerMock;
213 metrics_.set_time_to_drop_timer(mock_time_to_drop_timer);
214 EXPECT_CALL(*service_.get(), technology()).
215 WillOnce(Return(Technology::kEthernet));
216 EXPECT_CALL(library_, SendToUMA("Network.Shill.Ethernet.TimeOnline",
217 Ge(0),
218 Metrics::kMetricTimeOnlineSecondsMin,
219 Metrics::kMetricTimeOnlineSecondsMax,
220 Metrics::kTimerHistogramNumBuckets));
221 EXPECT_CALL(library_, SendToUMA(Metrics::kMetricTimeToDropSeconds,
222 Ge(0),
223 Metrics::kMetricTimeToDropSecondsMin,
224 Metrics::kMetricTimeToDropSecondsMax,
225 Metrics::kTimerHistogramNumBuckets)).Times(0);
226 EXPECT_CALL(*mock_time_online_timer, Start()).Times(2);
227 EXPECT_CALL(*mock_time_to_drop_timer, Start());
228 metrics_.NotifyDefaultServiceChanged(service_);
229 metrics_.NotifyDefaultServiceChanged(wifi_service_);
230
231 EXPECT_CALL(*mock_time_online_timer, Start());
232 EXPECT_CALL(*mock_time_to_drop_timer, Start()).Times(0);
233 EXPECT_CALL(library_, SendToUMA("Network.Shill.Wifi.TimeOnline",
234 Ge(0),
235 Metrics::kMetricTimeOnlineSecondsMin,
236 Metrics::kMetricTimeOnlineSecondsMax,
237 Metrics::kTimerHistogramNumBuckets));
238 EXPECT_CALL(library_, SendToUMA(Metrics::kMetricTimeToDropSeconds,
239 Ge(0),
240 Metrics::kMetricTimeToDropSecondsMin,
241 Metrics::kMetricTimeToDropSecondsMax,
242 Metrics::kTimerHistogramNumBuckets));
243 metrics_.NotifyDefaultServiceChanged(NULL);
244}
245
Thieu Le67370f62012-02-14 23:01:42 +0000246TEST_F(MetricsTest, Disconnect) {
247 EXPECT_CALL(*service_.get(), technology()).
248 WillRepeatedly(Return(Technology::kWifi));
249 EXPECT_CALL(*service_.get(), explicitly_disconnected()).
250 WillOnce(Return(false));
251 EXPECT_CALL(library_, SendToUMA("Network.Shill.Wifi.Disconnect",
252 false,
253 Metrics::kMetricDisconnectMin,
254 Metrics::kMetricDisconnectMax,
255 Metrics::kMetricDisconnectNumBuckets));
256 metrics_.NotifyServiceDisconnect(service_);
257
258 EXPECT_CALL(*service_.get(), explicitly_disconnected()).
259 WillOnce(Return(true));
260 EXPECT_CALL(library_, SendToUMA("Network.Shill.Wifi.Disconnect",
261 true,
262 Metrics::kMetricDisconnectMin,
263 Metrics::kMetricDisconnectMax,
264 Metrics::kMetricDisconnectNumBuckets));
265 metrics_.NotifyServiceDisconnect(service_);
266}
267
Thieu Le85e050b2012-03-13 15:04:38 -0700268TEST_F(MetricsTest, PortalDetectionResultToEnum) {
269 PortalDetector::Result result(PortalDetector::kPhaseDNS,
270 PortalDetector::kStatusFailure, 0, true);
271 EXPECT_EQ(Metrics::kPortalResultDNSFailure,
272 Metrics::PortalDetectionResultToEnum(result));
273
274 result.phase = PortalDetector::kPhaseDNS;
275 result.status = PortalDetector::kStatusTimeout;
276 EXPECT_EQ(Metrics::kPortalResultDNSTimeout,
277 Metrics::PortalDetectionResultToEnum(result));
278
279 result.phase = PortalDetector::kPhaseConnection;
280 result.status = PortalDetector::kStatusFailure;
281 EXPECT_EQ(Metrics::kPortalResultConnectionFailure,
282 Metrics::PortalDetectionResultToEnum(result));
283
284 result.phase = PortalDetector::kPhaseConnection;
285 result.status = PortalDetector::kStatusTimeout;
286 EXPECT_EQ(Metrics::kPortalResultConnectionTimeout,
287 Metrics::PortalDetectionResultToEnum(result));
288
289 result.phase = PortalDetector::kPhaseHTTP;
290 result.status = PortalDetector::kStatusFailure;
291 EXPECT_EQ(Metrics::kPortalResultHTTPFailure,
292 Metrics::PortalDetectionResultToEnum(result));
293
294 result.phase = PortalDetector::kPhaseHTTP;
295 result.status = PortalDetector::kStatusTimeout;
296 EXPECT_EQ(Metrics::kPortalResultHTTPTimeout,
297 Metrics::PortalDetectionResultToEnum(result));
298
299 result.phase = PortalDetector::kPhaseContent;
300 result.status = PortalDetector::kStatusSuccess;
301 EXPECT_EQ(Metrics::kPortalResultSuccess,
302 Metrics::PortalDetectionResultToEnum(result));
303
304 result.phase = PortalDetector::kPhaseContent;
305 result.status = PortalDetector::kStatusFailure;
306 EXPECT_EQ(Metrics::kPortalResultContentFailure,
307 Metrics::PortalDetectionResultToEnum(result));
308
309 result.phase = PortalDetector::kPhaseContent;
310 result.status = PortalDetector::kStatusTimeout;
311 EXPECT_EQ(Metrics::kPortalResultContentTimeout,
312 Metrics::PortalDetectionResultToEnum(result));
313
314 result.phase = PortalDetector::kPhaseUnknown;
315 result.status = PortalDetector::kStatusFailure;
316 EXPECT_EQ(Metrics::kPortalResultUnknown,
317 Metrics::PortalDetectionResultToEnum(result));
318}
319
320#ifndef NDEBUG
321
322typedef MetricsTest MetricsDeathTest;
323
324TEST_F(MetricsDeathTest, PortalDetectionResultToEnumDNSSuccess) {
325 PortalDetector::Result result(PortalDetector::kPhaseDNS,
326 PortalDetector::kStatusSuccess, 0, true);
327 EXPECT_DEATH(Metrics::PortalDetectionResultToEnum(result),
328 "Final result status 1 is not allowed in the DNS phase");
329}
330
331TEST_F(MetricsDeathTest, PortalDetectionResultToEnumConnectionSuccess) {
332 PortalDetector::Result result(PortalDetector::kPhaseConnection,
333 PortalDetector::kStatusSuccess, 0, true);
334 EXPECT_DEATH(Metrics::PortalDetectionResultToEnum(result),
335 "Final result status 1 is not allowed in the Connection phase");
336}
337
338TEST_F(MetricsDeathTest, PortalDetectionResultToEnumHTTPSuccess) {
339 PortalDetector::Result result(PortalDetector::kPhaseHTTP,
340 PortalDetector::kStatusSuccess, 0, true);
341 EXPECT_DEATH(Metrics::PortalDetectionResultToEnum(result),
342 "Final result status 1 is not allowed in the HTTP phase");
343}
344
345#endif // NDEBUG
346
Thieu Le48e6d6d2011-12-06 00:40:27 +0000347} // namespace shill