blob: 695790bb2a78570939b07d62ea64847c7e7a8873 [file] [log] [blame]
Ben Chanb061f892013-02-27 17:46:55 -08001// Copyright (c) 2013 The Chromium OS 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 "shill/traffic_monitor.h"
6
7#include <base/bind.h>
Thieu Le03026662013-04-04 10:45:11 -07008#include <base/stringprintf.h>
Ben Chanb061f892013-02-27 17:46:55 -08009#include <gtest/gtest.h>
10
11#include "shill/mock_device.h"
12#include "shill/mock_event_dispatcher.h"
Thieu Le03026662013-04-04 10:45:11 -070013#include "shill/mock_ipconfig.h"
14#include "shill/mock_socket_info_reader.h"
Ben Chanb061f892013-02-27 17:46:55 -080015#include "shill/nice_mock_control.h"
16
Thieu Le03026662013-04-04 10:45:11 -070017using base::Bind;
18using base::StringPrintf;
19using base::Unretained;
20using std::string;
21using std::vector;
22using testing::_;
23using testing::Mock;
Ben Chanb061f892013-02-27 17:46:55 -080024using testing::NiceMock;
25using testing::Return;
Thieu Le03026662013-04-04 10:45:11 -070026using testing::ReturnRef;
Ben Chanb061f892013-02-27 17:46:55 -080027using testing::Test;
28
29namespace shill {
30
Ben Chanb061f892013-02-27 17:46:55 -080031class TrafficMonitorTest : public Test {
32 public:
Thieu Le03026662013-04-04 10:45:11 -070033 static const string kLocalIpAddr;
34 static const uint16 kLocalPort1;
35 static const uint16 kLocalPort2;
36 static const uint16 kLocalPort3;
37 static const uint16 kLocalPort4;
38 static const uint16 kLocalPort5;
39 static const string kRemoteIpAddr;
40 static const uint16 kRemotePort;
41 static const uint64 kTxQueueLength1;
42 static const uint64 kTxQueueLength2;
43 static const uint64 kTxQueueLength3;
44 static const uint64 kTxQueueLength4;
45
Ben Chanb061f892013-02-27 17:46:55 -080046 TrafficMonitorTest()
47 : device_(new MockDevice(&control_,
48 &dispatcher_,
49 reinterpret_cast<Metrics *>(NULL),
50 reinterpret_cast<Manager *>(NULL),
51 "netdev0",
52 "00:11:22:33:44:55",
53 1)),
Thieu Le03026662013-04-04 10:45:11 -070054 ipconfig_(new MockIPConfig(&control_, "netdev0")),
55 mock_socket_info_reader_(new MockSocketInfoReader),
56 monitor_(device_, &dispatcher_),
57 local_addr_(IPAddress::kFamilyIPv4),
58 remote_addr_(IPAddress::kFamilyIPv4) {
59 local_addr_.SetAddressFromString(kLocalIpAddr);
60 remote_addr_.SetAddressFromString(kRemoteIpAddr);
Ben Chanb061f892013-02-27 17:46:55 -080061 }
62
Thieu Le03026662013-04-04 10:45:11 -070063 MOCK_METHOD0(OnNoOutgoingPackets, void());
64
Ben Chanb061f892013-02-27 17:46:55 -080065 protected:
Thieu Le03026662013-04-04 10:45:11 -070066 virtual void SetUp() {
67 monitor_.socket_info_reader_.reset(
68 mock_socket_info_reader_); // Passes ownership
69
70 ipconfig_properties_.address = kLocalIpAddr;
71 EXPECT_CALL(*ipconfig_.get(), properties())
72 .WillRepeatedly(ReturnRef(ipconfig_properties_));
73 EXPECT_CALL(*device_.get(), ipconfig())
74 .WillRepeatedly(ReturnRef(ipconfig_));
75 }
76
77 void VerifyStopped() {
78 EXPECT_TRUE(monitor_.sample_traffic_callback_.IsCancelled());
79 EXPECT_EQ(0, monitor_.accummulated_failure_samples_);
80 }
81
82 void VerifyStarted() {
83 EXPECT_FALSE(monitor_.sample_traffic_callback_.IsCancelled());
84 }
85
86 void SetupMockSocketInfos(const vector<SocketInfo> &socket_infos) {
87 mock_socket_infos_ = socket_infos;
88 EXPECT_CALL(*mock_socket_info_reader_, LoadTcpSocketInfo(_))
89 .WillRepeatedly(
90 Invoke(this, &TrafficMonitorTest::MockLoadTcpSocketInfo));
91 }
92
93 bool MockLoadTcpSocketInfo(vector<SocketInfo> *info_list) {
94 *info_list = mock_socket_infos_;
95 return true;
96 }
97
98 string FormatIPPort(const IPAddress &ip, const uint16 port) {
99 return StringPrintf("%s:%d", ip.ToString().c_str(), port);
Ben Chanb061f892013-02-27 17:46:55 -0800100 }
101
102 NiceMockControl control_;
103 NiceMock<MockEventDispatcher> dispatcher_;
104 scoped_refptr<MockDevice> device_;
Thieu Le03026662013-04-04 10:45:11 -0700105 scoped_refptr<MockIPConfig> ipconfig_;
106 IPConfig::Properties ipconfig_properties_;
107 MockSocketInfoReader *mock_socket_info_reader_;
Ben Chanb061f892013-02-27 17:46:55 -0800108 TrafficMonitor monitor_;
Thieu Le03026662013-04-04 10:45:11 -0700109 vector<SocketInfo> mock_socket_infos_;
110 IPAddress local_addr_;
111 IPAddress remote_addr_;
Ben Chanb061f892013-02-27 17:46:55 -0800112};
113
Thieu Le03026662013-04-04 10:45:11 -0700114// static
115const string TrafficMonitorTest::kLocalIpAddr = "127.0.0.1";
116const uint16 TrafficMonitorTest::kLocalPort1 = 1234;
117const uint16 TrafficMonitorTest::kLocalPort2 = 2345;
118const uint16 TrafficMonitorTest::kLocalPort3 = 3456;
119const uint16 TrafficMonitorTest::kLocalPort4 = 4567;
120const uint16 TrafficMonitorTest::kLocalPort5 = 4567;
121const string TrafficMonitorTest::kRemoteIpAddr = "192.168.1.1";
122const uint16 TrafficMonitorTest::kRemotePort = 5678;
123const uint64 TrafficMonitorTest::kTxQueueLength1 = 111;
124const uint64 TrafficMonitorTest::kTxQueueLength2 = 222;
125const uint64 TrafficMonitorTest::kTxQueueLength3 = 333;
126const uint64 TrafficMonitorTest::kTxQueueLength4 = 444;
127
Ben Chanb061f892013-02-27 17:46:55 -0800128TEST_F(TrafficMonitorTest, StartAndStop) {
Thieu Le03026662013-04-04 10:45:11 -0700129 // Stop without start
130 monitor_.Stop();
131 VerifyStopped();
Ben Chanb061f892013-02-27 17:46:55 -0800132
Thieu Le03026662013-04-04 10:45:11 -0700133 // Normal start
Ben Chanb061f892013-02-27 17:46:55 -0800134 monitor_.Start();
Thieu Le03026662013-04-04 10:45:11 -0700135 VerifyStarted();
Ben Chanb061f892013-02-27 17:46:55 -0800136
Thieu Le03026662013-04-04 10:45:11 -0700137 // Stop after start
138 monitor_.Stop();
139 VerifyStopped();
Ben Chanb061f892013-02-27 17:46:55 -0800140
Thieu Le03026662013-04-04 10:45:11 -0700141 // Stop again without start
142 monitor_.Stop();
143 VerifyStopped();
Ben Chanb061f892013-02-27 17:46:55 -0800144}
145
Thieu Le03026662013-04-04 10:45:11 -0700146TEST_F(TrafficMonitorTest, BuildIPPortToTxQueueLengthValid) {
147 vector<SocketInfo> socket_infos;
148 socket_infos.push_back(
149 SocketInfo(SocketInfo::kConnectionStateEstablished,
150 local_addr_,
151 TrafficMonitorTest::kLocalPort1,
152 remote_addr_,
153 TrafficMonitorTest::kRemotePort,
154 TrafficMonitorTest::kTxQueueLength1,
155 0,
156 SocketInfo::kTimerStateRetransmitTimerPending));
157 TrafficMonitor::IPPortToTxQueueLengthMap tx_queue_lengths;
158 monitor_.BuildIPPortToTxQueueLength(socket_infos, &tx_queue_lengths);
159 EXPECT_EQ(1, tx_queue_lengths.size());
160 string ip_port = FormatIPPort(local_addr_, TrafficMonitorTest::kLocalPort1);
161 EXPECT_EQ(TrafficMonitorTest::kTxQueueLength1, tx_queue_lengths[ip_port]);
162}
Ben Chanb061f892013-02-27 17:46:55 -0800163
Thieu Le03026662013-04-04 10:45:11 -0700164TEST_F(TrafficMonitorTest, BuildIPPortToTxQueueLengthInvalidDevice) {
165 vector<SocketInfo> socket_infos;
166 IPAddress foreign_ip_addr(IPAddress::kFamilyIPv4);
167 foreign_ip_addr.SetAddressFromString("192.167.1.1");
168 socket_infos.push_back(
169 SocketInfo(SocketInfo::kConnectionStateEstablished,
170 foreign_ip_addr,
171 TrafficMonitorTest::kLocalPort1,
172 remote_addr_,
173 TrafficMonitorTest::kRemotePort,
174 TrafficMonitorTest::kTxQueueLength1,
175 0,
176 SocketInfo::kTimerStateRetransmitTimerPending));
177 TrafficMonitor::IPPortToTxQueueLengthMap tx_queue_lengths;
178 monitor_.BuildIPPortToTxQueueLength(socket_infos, &tx_queue_lengths);
179 EXPECT_EQ(0, tx_queue_lengths.size());
180}
Ben Chanb061f892013-02-27 17:46:55 -0800181
Thieu Le03026662013-04-04 10:45:11 -0700182TEST_F(TrafficMonitorTest, BuildIPPortToTxQueueLengthZero) {
183 vector<SocketInfo> socket_infos;
184 socket_infos.push_back(
185 SocketInfo(SocketInfo::kConnectionStateEstablished,
186 local_addr_,
187 TrafficMonitorTest::kLocalPort1,
188 remote_addr_,
189 TrafficMonitorTest::kRemotePort,
190 0,
191 0,
192 SocketInfo::kTimerStateRetransmitTimerPending));
193 TrafficMonitor::IPPortToTxQueueLengthMap tx_queue_lengths;
194 monitor_.BuildIPPortToTxQueueLength(socket_infos, &tx_queue_lengths);
195 EXPECT_EQ(0, tx_queue_lengths.size());
196}
Ben Chanb061f892013-02-27 17:46:55 -0800197
Thieu Le03026662013-04-04 10:45:11 -0700198TEST_F(TrafficMonitorTest, BuildIPPortToTxQueueLengthInvalidConnectionState) {
199 vector<SocketInfo> socket_infos;
200 socket_infos.push_back(
201 SocketInfo(SocketInfo::kConnectionStateSynSent,
202 local_addr_,
203 TrafficMonitorTest::kLocalPort1,
204 remote_addr_,
205 TrafficMonitorTest::kRemotePort,
206 TrafficMonitorTest::kTxQueueLength1,
207 0,
208 SocketInfo::kTimerStateRetransmitTimerPending));
209 TrafficMonitor::IPPortToTxQueueLengthMap tx_queue_lengths;
210 monitor_.BuildIPPortToTxQueueLength(socket_infos, &tx_queue_lengths);
211 EXPECT_EQ(0, tx_queue_lengths.size());
212}
Ben Chanb061f892013-02-27 17:46:55 -0800213
Thieu Le03026662013-04-04 10:45:11 -0700214TEST_F(TrafficMonitorTest, BuildIPPortToTxQueueLengthInvalidTimerState) {
215 vector<SocketInfo> socket_infos;
216 socket_infos.push_back(
217 SocketInfo(SocketInfo::kConnectionStateEstablished,
218 local_addr_,
219 TrafficMonitorTest::kLocalPort1,
220 remote_addr_,
221 TrafficMonitorTest::kRemotePort,
222 TrafficMonitorTest::kTxQueueLength1,
223 0,
224 SocketInfo::kTimerStateNoTimerPending));
225 TrafficMonitor::IPPortToTxQueueLengthMap tx_queue_lengths;
226 monitor_.BuildIPPortToTxQueueLength(socket_infos, &tx_queue_lengths);
227 EXPECT_EQ(0, tx_queue_lengths.size());
228}
Ben Chanb061f892013-02-27 17:46:55 -0800229
Thieu Le03026662013-04-04 10:45:11 -0700230TEST_F(TrafficMonitorTest, BuildIPPortToTxQueueLengthMultipleEntries) {
231 vector<SocketInfo> socket_infos;
232 socket_infos.push_back(
233 SocketInfo(SocketInfo::kConnectionStateSynSent,
234 local_addr_,
235 TrafficMonitorTest::kLocalPort1,
236 remote_addr_,
237 TrafficMonitorTest::kRemotePort,
238 TrafficMonitorTest::kTxQueueLength1,
239 0,
240 SocketInfo::kTimerStateNoTimerPending));
241 socket_infos.push_back(
242 SocketInfo(SocketInfo::kConnectionStateEstablished,
243 local_addr_,
244 TrafficMonitorTest::kLocalPort2,
245 remote_addr_,
246 TrafficMonitorTest::kRemotePort,
247 TrafficMonitorTest::kTxQueueLength2,
248 0,
249 SocketInfo::kTimerStateRetransmitTimerPending));
250 socket_infos.push_back(
251 SocketInfo(SocketInfo::kConnectionStateEstablished,
252 local_addr_,
253 TrafficMonitorTest::kLocalPort3,
254 remote_addr_,
255 TrafficMonitorTest::kRemotePort,
256 TrafficMonitorTest::kTxQueueLength3,
257 0,
258 SocketInfo::kTimerStateRetransmitTimerPending));
259 socket_infos.push_back(
260 SocketInfo(SocketInfo::kConnectionStateEstablished,
261 local_addr_,
262 TrafficMonitorTest::kLocalPort4,
263 remote_addr_,
264 TrafficMonitorTest::kRemotePort,
265 TrafficMonitorTest::kTxQueueLength4,
266 0,
267 SocketInfo::kTimerStateNoTimerPending));
268 socket_infos.push_back(
269 SocketInfo(SocketInfo::kConnectionStateEstablished,
270 local_addr_,
271 TrafficMonitorTest::kLocalPort5,
272 remote_addr_,
273 TrafficMonitorTest::kRemotePort,
274 0,
275 0,
276 SocketInfo::kTimerStateRetransmitTimerPending));
277 TrafficMonitor::IPPortToTxQueueLengthMap tx_queue_lengths;
278 monitor_.BuildIPPortToTxQueueLength(socket_infos, &tx_queue_lengths);
279 EXPECT_EQ(2, tx_queue_lengths.size());
280 string ip_port = FormatIPPort(local_addr_, TrafficMonitorTest::kLocalPort2);
281 EXPECT_EQ(kTxQueueLength2, tx_queue_lengths[ip_port]);
282 ip_port = FormatIPPort(local_addr_, TrafficMonitorTest::kLocalPort3);
283 EXPECT_EQ(kTxQueueLength3, tx_queue_lengths[ip_port]);
284}
285
286TEST_F(TrafficMonitorTest, SampleTrafficStuckTxQueueSameQueueLength) {
287 vector<SocketInfo> socket_infos;
288 socket_infos.push_back(
289 SocketInfo(SocketInfo::kConnectionStateEstablished,
290 local_addr_,
291 TrafficMonitorTest::kLocalPort1,
292 remote_addr_,
293 TrafficMonitorTest::kRemotePort,
294 TrafficMonitorTest::kTxQueueLength1,
295 0,
296 SocketInfo::kTimerStateRetransmitTimerPending));
297 SetupMockSocketInfos(socket_infos);
298 monitor_.set_tcp_out_traffic_not_routed_callback(
299 Bind(&TrafficMonitorTest::OnNoOutgoingPackets, Unretained(this)));
300 EXPECT_CALL(*this, OnNoOutgoingPackets()).Times(0);
301 monitor_.SampleTraffic();
302 Mock::VerifyAndClearExpectations(this);
303
304 // Mimic same queue length by using same mock socket info.
305 EXPECT_CALL(*this, OnNoOutgoingPackets());
306 monitor_.SampleTraffic();
307 Mock::VerifyAndClearExpectations(this);
308
309 // Perform another sampling pass and make sure the callback is only
310 // triggered once.
311 EXPECT_CALL(*this, OnNoOutgoingPackets()).Times(0);
312 monitor_.SampleTraffic();
313}
314
315TEST_F(TrafficMonitorTest, SampleTrafficStuckTxQueueIncreasingQueueLength) {
316 vector<SocketInfo> socket_infos;
317 socket_infos.push_back(
318 SocketInfo(SocketInfo::kConnectionStateEstablished,
319 local_addr_,
320 TrafficMonitorTest::kLocalPort1,
321 remote_addr_,
322 TrafficMonitorTest::kRemotePort,
323 TrafficMonitorTest::kTxQueueLength1,
324 0,
325 SocketInfo::kTimerStateRetransmitTimerPending));
326 SetupMockSocketInfos(socket_infos);
327 monitor_.set_tcp_out_traffic_not_routed_callback(
328 Bind(&TrafficMonitorTest::OnNoOutgoingPackets, Unretained(this)));
329 EXPECT_CALL(*this, OnNoOutgoingPackets()).Times(0);
330 monitor_.SampleTraffic();
331 Mock::VerifyAndClearExpectations(this);
332
333 socket_infos.clear();
334 socket_infos.push_back(
335 SocketInfo(SocketInfo::kConnectionStateEstablished,
336 local_addr_,
337 TrafficMonitorTest::kLocalPort1,
338 remote_addr_,
339 TrafficMonitorTest::kRemotePort,
340 TrafficMonitorTest::kTxQueueLength1 + 1,
341 0,
342 SocketInfo::kTimerStateRetransmitTimerPending));
343 SetupMockSocketInfos(socket_infos);
344 EXPECT_CALL(*this, OnNoOutgoingPackets());
345 monitor_.SampleTraffic();
346}
347
348TEST_F(TrafficMonitorTest, SampleTrafficStuckTxQueueVariousQueueLengths) {
349 vector<SocketInfo> socket_infos;
350 socket_infos.push_back(
351 SocketInfo(SocketInfo::kConnectionStateEstablished,
352 local_addr_,
353 TrafficMonitorTest::kLocalPort1,
354 remote_addr_,
355 TrafficMonitorTest::kRemotePort,
356 TrafficMonitorTest::kTxQueueLength2,
357 0,
358 SocketInfo::kTimerStateRetransmitTimerPending));
359 SetupMockSocketInfos(socket_infos);
360 monitor_.set_tcp_out_traffic_not_routed_callback(
361 Bind(&TrafficMonitorTest::OnNoOutgoingPackets, Unretained(this)));
362 EXPECT_CALL(*this, OnNoOutgoingPackets()).Times(0);
363 monitor_.SampleTraffic();
364 Mock::VerifyAndClearExpectations(this);
365
366 socket_infos.clear();
367 socket_infos.push_back(
368 SocketInfo(SocketInfo::kConnectionStateEstablished,
369 local_addr_,
370 TrafficMonitorTest::kLocalPort1,
371 remote_addr_,
372 TrafficMonitorTest::kRemotePort,
373 TrafficMonitorTest::kTxQueueLength1,
374 0,
375 SocketInfo::kTimerStateRetransmitTimerPending));
376 SetupMockSocketInfos(socket_infos);
377 EXPECT_CALL(*this, OnNoOutgoingPackets()).Times(0);
378 monitor_.SampleTraffic();
379 Mock::VerifyAndClearExpectations(this);
380
381 socket_infos.clear();
382 socket_infos.push_back(
383 SocketInfo(SocketInfo::kConnectionStateEstablished,
384 local_addr_,
385 TrafficMonitorTest::kLocalPort1,
386 remote_addr_,
387 TrafficMonitorTest::kRemotePort,
388 TrafficMonitorTest::kTxQueueLength2,
389 0,
390 SocketInfo::kTimerStateRetransmitTimerPending));
391 SetupMockSocketInfos(socket_infos);
392 EXPECT_CALL(*this, OnNoOutgoingPackets());
393 monitor_.SampleTraffic();
394}
395
396TEST_F(TrafficMonitorTest, SampleTrafficUnstuckTxQueueZeroQueueLength) {
397 vector<SocketInfo> socket_infos;
398 socket_infos.push_back(
399 SocketInfo(SocketInfo::kConnectionStateEstablished,
400 local_addr_,
401 TrafficMonitorTest::kLocalPort1,
402 remote_addr_,
403 TrafficMonitorTest::kRemotePort,
404 TrafficMonitorTest::kTxQueueLength1,
405 0,
406 SocketInfo::kTimerStateRetransmitTimerPending));
407 SetupMockSocketInfos(socket_infos);
408 monitor_.set_tcp_out_traffic_not_routed_callback(
409 Bind(&TrafficMonitorTest::OnNoOutgoingPackets, Unretained(this)));
410 EXPECT_CALL(*this, OnNoOutgoingPackets()).Times(0);
411 monitor_.SampleTraffic();
412
413 socket_infos.clear();
414 socket_infos.push_back(
415 SocketInfo(SocketInfo::kConnectionStateEstablished,
416 local_addr_,
417 TrafficMonitorTest::kLocalPort1,
418 remote_addr_,
419 TrafficMonitorTest::kRemotePort,
420 0,
421 0,
422 SocketInfo::kTimerStateRetransmitTimerPending));
423 SetupMockSocketInfos(socket_infos);
424 monitor_.SampleTraffic();
425 EXPECT_EQ(0, monitor_.accummulated_failure_samples_);
426}
427
428TEST_F(TrafficMonitorTest, SampleTrafficUnstuckTxQueueNoConnection) {
429 vector<SocketInfo> socket_infos;
430 socket_infos.push_back(
431 SocketInfo(SocketInfo::kConnectionStateEstablished,
432 local_addr_,
433 TrafficMonitorTest::kLocalPort1,
434 remote_addr_,
435 TrafficMonitorTest::kRemotePort,
436 TrafficMonitorTest::kTxQueueLength1,
437 0,
438 SocketInfo::kTimerStateRetransmitTimerPending));
439 SetupMockSocketInfos(socket_infos);
440 monitor_.set_tcp_out_traffic_not_routed_callback(
441 Bind(&TrafficMonitorTest::OnNoOutgoingPackets, Unretained(this)));
442 EXPECT_CALL(*this, OnNoOutgoingPackets()).Times(0);
443 monitor_.SampleTraffic();
444
445 socket_infos.clear();
446 SetupMockSocketInfos(socket_infos);
447 monitor_.SampleTraffic();
448 EXPECT_EQ(0, monitor_.accummulated_failure_samples_);
449}
450
451TEST_F(TrafficMonitorTest, SampleTrafficUnstuckTxQueueStateChanged) {
452 vector<SocketInfo> socket_infos;
453 socket_infos.push_back(
454 SocketInfo(SocketInfo::kConnectionStateEstablished,
455 local_addr_,
456 TrafficMonitorTest::kLocalPort1,
457 remote_addr_,
458 TrafficMonitorTest::kRemotePort,
459 TrafficMonitorTest::kTxQueueLength1,
460 0,
461 SocketInfo::kTimerStateRetransmitTimerPending));
462 SetupMockSocketInfos(socket_infos);
463 monitor_.set_tcp_out_traffic_not_routed_callback(
464 Bind(&TrafficMonitorTest::OnNoOutgoingPackets, Unretained(this)));
465 EXPECT_CALL(*this, OnNoOutgoingPackets()).Times(0);
466 monitor_.SampleTraffic();
467
468 socket_infos.clear();
469 socket_infos.push_back(
470 SocketInfo(SocketInfo::kConnectionStateClose,
471 local_addr_,
472 TrafficMonitorTest::kLocalPort1,
473 remote_addr_,
474 TrafficMonitorTest::kRemotePort,
475 0,
476 0,
477 SocketInfo::kTimerStateNoTimerPending));
478 SetupMockSocketInfos(socket_infos);
479 monitor_.SampleTraffic();
480 EXPECT_EQ(0, monitor_.accummulated_failure_samples_);
Ben Chanb061f892013-02-27 17:46:55 -0800481}
482
483} // namespace shill