blob: 76c5c940ca9b5d14503d6b6bc8825578c9bdfd0c [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_);
Darin Petkov58f0b6d2012-06-12 12:52:30 +020054 metrics_.collect_bootstats_ = false;
Thieu Le48e6d6d2011-12-06 00:40:27 +000055 }
56
57 protected:
Thieu Leb84ba342012-03-02 15:15:19 -080058 void ExpectCommonPostReady(Metrics::WiFiChannel channel,
59 Metrics::WiFiNetworkPhyMode mode,
60 Metrics::WiFiSecurity security) {
61 EXPECT_CALL(library_, SendEnumToUMA("Network.Shill.Wifi.Channel",
62 channel,
63 Metrics::kMetricNetworkChannelMax));
64 EXPECT_CALL(library_, SendEnumToUMA("Network.Shill.Wifi.PhyMode",
65 mode,
66 Metrics::kWiFiNetworkPhyModeMax));
67 EXPECT_CALL(library_, SendEnumToUMA("Network.Shill.Wifi.Security",
68 security,
69 Metrics::kWiFiSecurityMax));
70 }
71
Thieu Le48e6d6d2011-12-06 00:40:27 +000072 Metrics metrics_; // This must be destroyed after service_ and wifi_service_
73 MetricsLibraryMock library_;
74 scoped_refptr<MockService> service_;
75 WiFiRefPtr wifi_;
76 const std::vector<uint8_t> ssid_;
77 scoped_refptr<MockWiFiService> wifi_service_;
78};
79
80TEST_F(MetricsTest, TimeToConfig) {
81 EXPECT_CALL(library_, SendToUMA("Network.Shill.Unknown.TimeToConfig",
82 Ge(0),
Thieu Lea20cbc22012-01-09 22:01:43 +000083 Metrics::kTimerHistogramMillisecondsMin,
84 Metrics::kTimerHistogramMillisecondsMax,
Thieu Le48e6d6d2011-12-06 00:40:27 +000085 Metrics::kTimerHistogramNumBuckets));
86 metrics_.RegisterService(service_);
87 metrics_.NotifyServiceStateChanged(service_, Service::kStateConfiguring);
Paul Stewart20088d82012-02-16 06:58:55 -080088 metrics_.NotifyServiceStateChanged(service_, Service::kStateConnected);
Thieu Le48e6d6d2011-12-06 00:40:27 +000089}
90
91TEST_F(MetricsTest, TimeToPortal) {
92 EXPECT_CALL(library_, SendToUMA("Network.Shill.Unknown.TimeToPortal",
93 Ge(0),
Thieu Lea20cbc22012-01-09 22:01:43 +000094 Metrics::kTimerHistogramMillisecondsMin,
95 Metrics::kTimerHistogramMillisecondsMax,
Thieu Le48e6d6d2011-12-06 00:40:27 +000096 Metrics::kTimerHistogramNumBuckets));
97 metrics_.RegisterService(service_);
Paul Stewart20088d82012-02-16 06:58:55 -080098 metrics_.NotifyServiceStateChanged(service_, Service::kStateConnected);
Thieu Le48e6d6d2011-12-06 00:40:27 +000099 metrics_.NotifyServiceStateChanged(service_, Service::kStatePortal);
100}
101
102TEST_F(MetricsTest, TimeToOnline) {
103 EXPECT_CALL(library_, SendToUMA("Network.Shill.Unknown.TimeToOnline",
104 Ge(0),
Thieu Lea20cbc22012-01-09 22:01:43 +0000105 Metrics::kTimerHistogramMillisecondsMin,
106 Metrics::kTimerHistogramMillisecondsMax,
Thieu Le48e6d6d2011-12-06 00:40:27 +0000107 Metrics::kTimerHistogramNumBuckets));
108 metrics_.RegisterService(service_);
Paul Stewart20088d82012-02-16 06:58:55 -0800109 metrics_.NotifyServiceStateChanged(service_, Service::kStateConnected);
Thieu Le48e6d6d2011-12-06 00:40:27 +0000110 metrics_.NotifyServiceStateChanged(service_, Service::kStateOnline);
111}
112
113TEST_F(MetricsTest, ServiceFailure) {
114 EXPECT_CALL(*service_.get(), failure())
Paul Stewartf2d60912012-07-15 08:37:30 -0700115 .WillRepeatedly(Return(Service::kFailureBadPassphrase));
Thieu Le48e6d6d2011-12-06 00:40:27 +0000116 EXPECT_CALL(library_, SendEnumToUMA(Metrics::kMetricNetworkServiceErrors,
Paul Stewartf2d60912012-07-15 08:37:30 -0700117 Service::kFailureBadPassphrase,
Thieu Le48e6d6d2011-12-06 00:40:27 +0000118 Metrics::kMetricNetworkServiceErrorsMax));
119 metrics_.RegisterService(service_);
120 metrics_.NotifyServiceStateChanged(service_, Service::kStateFailure);
121}
122
123TEST_F(MetricsTest, WiFiServiceTimeToJoin) {
124 EXPECT_CALL(library_, SendToUMA("Network.Shill.Wifi.TimeToJoin",
125 Ge(0),
Thieu Lea20cbc22012-01-09 22:01:43 +0000126 Metrics::kTimerHistogramMillisecondsMin,
127 Metrics::kTimerHistogramMillisecondsMax,
Thieu Le48e6d6d2011-12-06 00:40:27 +0000128 Metrics::kTimerHistogramNumBuckets));
129 metrics_.RegisterService(wifi_service_);
130 metrics_.NotifyServiceStateChanged(wifi_service_, Service::kStateAssociating);
131 metrics_.NotifyServiceStateChanged(wifi_service_, Service::kStateConfiguring);
132}
133
Thieu Lead1ec2c2012-01-05 23:39:48 +0000134TEST_F(MetricsTest, WiFiServicePostReady) {
Thieu Leb84ba342012-03-02 15:15:19 -0800135 base::TimeDelta non_zero_time_delta = base::TimeDelta::FromMilliseconds(1);
136 chromeos_metrics::TimerMock *mock_time_resume_to_ready_timer =
137 new chromeos_metrics::TimerMock;
138 metrics_.set_time_resume_to_ready_timer(mock_time_resume_to_ready_timer);
139
140 ExpectCommonPostReady(Metrics::kWiFiChannel2412,
141 Metrics::kWiFiNetworkPhyMode11a,
142 Metrics::kWiFiSecurityWep);
143 EXPECT_CALL(library_, SendToUMA("Network.Shill.Wifi.TimeResumeToReady",
144 _, _, _, _)).Times(0);
Thieu Le48e6d6d2011-12-06 00:40:27 +0000145 wifi_service_->frequency_ = 2412;
Thieu Lead1ec2c2012-01-05 23:39:48 +0000146 wifi_service_->physical_mode_ = Metrics::kWiFiNetworkPhyMode11a;
147 wifi_service_->security_ = flimflam::kSecurityWep;
Thieu Le48e6d6d2011-12-06 00:40:27 +0000148 metrics_.RegisterService(wifi_service_);
Paul Stewart20088d82012-02-16 06:58:55 -0800149 metrics_.NotifyServiceStateChanged(wifi_service_, Service::kStateConnected);
Thieu Leb84ba342012-03-02 15:15:19 -0800150 Mock::VerifyAndClearExpectations(&library_);
151
152 // Simulate a system suspend, resume and an AP reconnect.
153 ExpectCommonPostReady(Metrics::kWiFiChannel2412,
154 Metrics::kWiFiNetworkPhyMode11a,
155 Metrics::kWiFiSecurityWep);
156 EXPECT_CALL(library_, SendToUMA("Network.Shill.Wifi.TimeResumeToReady",
157 Ge(0),
158 Metrics::kTimerHistogramMillisecondsMin,
159 Metrics::kTimerHistogramMillisecondsMax,
160 Metrics::kTimerHistogramNumBuckets));
161 EXPECT_CALL(*mock_time_resume_to_ready_timer, GetElapsedTime(_)).
162 WillOnce(DoAll(SetArgumentPointee<0>(non_zero_time_delta), Return(true)));
163 metrics_.NotifyPowerStateChange(PowerManagerProxyDelegate::kMem);
164 metrics_.NotifyPowerStateChange(PowerManagerProxyDelegate::kOn);
165 metrics_.NotifyServiceStateChanged(wifi_service_, Service::kStateConnected);
166 Mock::VerifyAndClearExpectations(&library_);
167 Mock::VerifyAndClearExpectations(mock_time_resume_to_ready_timer);
168
169 // Make sure subsequent connects do not count towards TimeResumeToReady.
170 ExpectCommonPostReady(Metrics::kWiFiChannel2412,
171 Metrics::kWiFiNetworkPhyMode11a,
172 Metrics::kWiFiSecurityWep);
173 EXPECT_CALL(library_, SendToUMA("Network.Shill.Wifi.TimeResumeToReady",
174 _, _, _, _)).Times(0);
175 metrics_.NotifyServiceStateChanged(wifi_service_, Service::kStateConnected);
Thieu Le48e6d6d2011-12-06 00:40:27 +0000176}
177
178TEST_F(MetricsTest, FrequencyToChannel) {
179 EXPECT_EQ(Metrics::kWiFiChannelUndef, metrics_.WiFiFrequencyToChannel(2411));
180 EXPECT_EQ(Metrics::kWiFiChannel2412, metrics_.WiFiFrequencyToChannel(2412));
181 EXPECT_EQ(Metrics::kWiFiChannel2472, metrics_.WiFiFrequencyToChannel(2472));
182 EXPECT_EQ(Metrics::kWiFiChannelUndef, metrics_.WiFiFrequencyToChannel(2473));
183 EXPECT_EQ(Metrics::kWiFiChannel2484, metrics_.WiFiFrequencyToChannel(2484));
184 EXPECT_EQ(Metrics::kWiFiChannelUndef, metrics_.WiFiFrequencyToChannel(5169));
185 EXPECT_EQ(Metrics::kWiFiChannel5170, metrics_.WiFiFrequencyToChannel(5170));
186 EXPECT_EQ(Metrics::kWiFiChannel5190, metrics_.WiFiFrequencyToChannel(5190));
187 EXPECT_EQ(Metrics::kWiFiChannel5180, metrics_.WiFiFrequencyToChannel(5180));
188 EXPECT_EQ(Metrics::kWiFiChannel5200, metrics_.WiFiFrequencyToChannel(5200));
189 EXPECT_EQ(Metrics::kWiFiChannel5230, metrics_.WiFiFrequencyToChannel(5230));
190 EXPECT_EQ(Metrics::kWiFiChannelUndef, metrics_.WiFiFrequencyToChannel(5231));
191 EXPECT_EQ(Metrics::kWiFiChannelUndef, metrics_.WiFiFrequencyToChannel(5239));
192 EXPECT_EQ(Metrics::kWiFiChannel5240, metrics_.WiFiFrequencyToChannel(5240));
193 EXPECT_EQ(Metrics::kWiFiChannelUndef, metrics_.WiFiFrequencyToChannel(5241));
194 EXPECT_EQ(Metrics::kWiFiChannel5320, metrics_.WiFiFrequencyToChannel(5320));
195 EXPECT_EQ(Metrics::kWiFiChannelUndef, metrics_.WiFiFrequencyToChannel(5321));
196 EXPECT_EQ(Metrics::kWiFiChannelUndef, metrics_.WiFiFrequencyToChannel(5499));
197 EXPECT_EQ(Metrics::kWiFiChannel5500, metrics_.WiFiFrequencyToChannel(5500));
198 EXPECT_EQ(Metrics::kWiFiChannelUndef, metrics_.WiFiFrequencyToChannel(5501));
199 EXPECT_EQ(Metrics::kWiFiChannel5700, metrics_.WiFiFrequencyToChannel(5700));
200 EXPECT_EQ(Metrics::kWiFiChannelUndef, metrics_.WiFiFrequencyToChannel(5701));
201 EXPECT_EQ(Metrics::kWiFiChannelUndef, metrics_.WiFiFrequencyToChannel(5744));
202 EXPECT_EQ(Metrics::kWiFiChannel5745, metrics_.WiFiFrequencyToChannel(5745));
203 EXPECT_EQ(Metrics::kWiFiChannelUndef, metrics_.WiFiFrequencyToChannel(5746));
204 EXPECT_EQ(Metrics::kWiFiChannel5825, metrics_.WiFiFrequencyToChannel(5825));
205 EXPECT_EQ(Metrics::kWiFiChannelUndef, metrics_.WiFiFrequencyToChannel(5826));
206}
207
Thieu Lea20cbc22012-01-09 22:01:43 +0000208TEST_F(MetricsTest, TimeOnlineTimeToDrop) {
209 chromeos_metrics::TimerMock *mock_time_online_timer =
210 new chromeos_metrics::TimerMock;
211 metrics_.set_time_online_timer(mock_time_online_timer);
212 chromeos_metrics::TimerMock *mock_time_to_drop_timer =
213 new chromeos_metrics::TimerMock;
214 metrics_.set_time_to_drop_timer(mock_time_to_drop_timer);
215 EXPECT_CALL(*service_.get(), technology()).
216 WillOnce(Return(Technology::kEthernet));
217 EXPECT_CALL(library_, SendToUMA("Network.Shill.Ethernet.TimeOnline",
218 Ge(0),
219 Metrics::kMetricTimeOnlineSecondsMin,
220 Metrics::kMetricTimeOnlineSecondsMax,
221 Metrics::kTimerHistogramNumBuckets));
222 EXPECT_CALL(library_, SendToUMA(Metrics::kMetricTimeToDropSeconds,
223 Ge(0),
224 Metrics::kMetricTimeToDropSecondsMin,
225 Metrics::kMetricTimeToDropSecondsMax,
226 Metrics::kTimerHistogramNumBuckets)).Times(0);
227 EXPECT_CALL(*mock_time_online_timer, Start()).Times(2);
228 EXPECT_CALL(*mock_time_to_drop_timer, Start());
229 metrics_.NotifyDefaultServiceChanged(service_);
230 metrics_.NotifyDefaultServiceChanged(wifi_service_);
231
232 EXPECT_CALL(*mock_time_online_timer, Start());
233 EXPECT_CALL(*mock_time_to_drop_timer, Start()).Times(0);
234 EXPECT_CALL(library_, SendToUMA("Network.Shill.Wifi.TimeOnline",
235 Ge(0),
236 Metrics::kMetricTimeOnlineSecondsMin,
237 Metrics::kMetricTimeOnlineSecondsMax,
238 Metrics::kTimerHistogramNumBuckets));
239 EXPECT_CALL(library_, SendToUMA(Metrics::kMetricTimeToDropSeconds,
240 Ge(0),
241 Metrics::kMetricTimeToDropSecondsMin,
242 Metrics::kMetricTimeToDropSecondsMax,
243 Metrics::kTimerHistogramNumBuckets));
244 metrics_.NotifyDefaultServiceChanged(NULL);
245}
246
Thieu Le67370f62012-02-14 23:01:42 +0000247TEST_F(MetricsTest, Disconnect) {
248 EXPECT_CALL(*service_.get(), technology()).
249 WillRepeatedly(Return(Technology::kWifi));
250 EXPECT_CALL(*service_.get(), explicitly_disconnected()).
251 WillOnce(Return(false));
252 EXPECT_CALL(library_, SendToUMA("Network.Shill.Wifi.Disconnect",
253 false,
254 Metrics::kMetricDisconnectMin,
255 Metrics::kMetricDisconnectMax,
256 Metrics::kMetricDisconnectNumBuckets));
257 metrics_.NotifyServiceDisconnect(service_);
258
259 EXPECT_CALL(*service_.get(), explicitly_disconnected()).
260 WillOnce(Return(true));
261 EXPECT_CALL(library_, SendToUMA("Network.Shill.Wifi.Disconnect",
262 true,
263 Metrics::kMetricDisconnectMin,
264 Metrics::kMetricDisconnectMax,
265 Metrics::kMetricDisconnectNumBuckets));
266 metrics_.NotifyServiceDisconnect(service_);
267}
268
Thieu Le85e050b2012-03-13 15:04:38 -0700269TEST_F(MetricsTest, PortalDetectionResultToEnum) {
270 PortalDetector::Result result(PortalDetector::kPhaseDNS,
271 PortalDetector::kStatusFailure, 0, true);
272 EXPECT_EQ(Metrics::kPortalResultDNSFailure,
273 Metrics::PortalDetectionResultToEnum(result));
274
275 result.phase = PortalDetector::kPhaseDNS;
276 result.status = PortalDetector::kStatusTimeout;
277 EXPECT_EQ(Metrics::kPortalResultDNSTimeout,
278 Metrics::PortalDetectionResultToEnum(result));
279
280 result.phase = PortalDetector::kPhaseConnection;
281 result.status = PortalDetector::kStatusFailure;
282 EXPECT_EQ(Metrics::kPortalResultConnectionFailure,
283 Metrics::PortalDetectionResultToEnum(result));
284
285 result.phase = PortalDetector::kPhaseConnection;
286 result.status = PortalDetector::kStatusTimeout;
287 EXPECT_EQ(Metrics::kPortalResultConnectionTimeout,
288 Metrics::PortalDetectionResultToEnum(result));
289
290 result.phase = PortalDetector::kPhaseHTTP;
291 result.status = PortalDetector::kStatusFailure;
292 EXPECT_EQ(Metrics::kPortalResultHTTPFailure,
293 Metrics::PortalDetectionResultToEnum(result));
294
295 result.phase = PortalDetector::kPhaseHTTP;
296 result.status = PortalDetector::kStatusTimeout;
297 EXPECT_EQ(Metrics::kPortalResultHTTPTimeout,
298 Metrics::PortalDetectionResultToEnum(result));
299
300 result.phase = PortalDetector::kPhaseContent;
301 result.status = PortalDetector::kStatusSuccess;
302 EXPECT_EQ(Metrics::kPortalResultSuccess,
303 Metrics::PortalDetectionResultToEnum(result));
304
305 result.phase = PortalDetector::kPhaseContent;
306 result.status = PortalDetector::kStatusFailure;
307 EXPECT_EQ(Metrics::kPortalResultContentFailure,
308 Metrics::PortalDetectionResultToEnum(result));
309
310 result.phase = PortalDetector::kPhaseContent;
311 result.status = PortalDetector::kStatusTimeout;
312 EXPECT_EQ(Metrics::kPortalResultContentTimeout,
313 Metrics::PortalDetectionResultToEnum(result));
314
315 result.phase = PortalDetector::kPhaseUnknown;
316 result.status = PortalDetector::kStatusFailure;
317 EXPECT_EQ(Metrics::kPortalResultUnknown,
318 Metrics::PortalDetectionResultToEnum(result));
319}
320
321#ifndef NDEBUG
322
323typedef MetricsTest MetricsDeathTest;
324
325TEST_F(MetricsDeathTest, PortalDetectionResultToEnumDNSSuccess) {
326 PortalDetector::Result result(PortalDetector::kPhaseDNS,
327 PortalDetector::kStatusSuccess, 0, true);
328 EXPECT_DEATH(Metrics::PortalDetectionResultToEnum(result),
329 "Final result status 1 is not allowed in the DNS phase");
330}
331
332TEST_F(MetricsDeathTest, PortalDetectionResultToEnumConnectionSuccess) {
333 PortalDetector::Result result(PortalDetector::kPhaseConnection,
334 PortalDetector::kStatusSuccess, 0, true);
335 EXPECT_DEATH(Metrics::PortalDetectionResultToEnum(result),
336 "Final result status 1 is not allowed in the Connection phase");
337}
338
339TEST_F(MetricsDeathTest, PortalDetectionResultToEnumHTTPSuccess) {
340 PortalDetector::Result result(PortalDetector::kPhaseHTTP,
341 PortalDetector::kStatusSuccess, 0, true);
342 EXPECT_DEATH(Metrics::PortalDetectionResultToEnum(result),
343 "Final result status 1 is not allowed in the HTTP phase");
344}
345
346#endif // NDEBUG
347
Thieu Le48e6d6d2011-12-06 00:40:27 +0000348} // namespace shill