blob: 56b5cb8f484753700a31f159a051e02ee56c8427 [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
Alex Deymocddd2d02014-11-10 19:55:35 -08005#include "shill/traffic_monitor.h"
6
Alex Vakulenko8a532292014-06-16 17:18:44 -07007#include <string>
8#include <vector>
9
Ben Chanb061f892013-02-27 17:46:55 -080010#include <base/bind.h>
Ben Chana0ddf462014-02-06 11:32:42 -080011#include <base/strings/stringprintf.h>
Ben Chanb061f892013-02-27 17:46:55 -080012#include <gtest/gtest.h>
Thieu Lefa7960e2013-04-15 13:14:55 -070013#include <netinet/in.h>
Ben Chanb061f892013-02-27 17:46:55 -080014
Thieu Lefa7960e2013-04-15 13:14:55 -070015#include "shill/mock_connection_info_reader.h"
Alex Vakulenkoa41ab512014-07-23 14:24:23 -070016#include "shill/mock_device.h"
Ben Chanb061f892013-02-27 17:46:55 -080017#include "shill/mock_event_dispatcher.h"
Thieu Le03026662013-04-04 10:45:11 -070018#include "shill/mock_ipconfig.h"
19#include "shill/mock_socket_info_reader.h"
Ben Chanb061f892013-02-27 17:46:55 -080020#include "shill/nice_mock_control.h"
21
Thieu Le03026662013-04-04 10:45:11 -070022using base::Bind;
23using base::StringPrintf;
24using base::Unretained;
25using std::string;
26using std::vector;
27using testing::_;
28using testing::Mock;
Ben Chanb061f892013-02-27 17:46:55 -080029using testing::NiceMock;
30using testing::Return;
Thieu Le03026662013-04-04 10:45:11 -070031using testing::ReturnRef;
Ben Chanb061f892013-02-27 17:46:55 -080032using testing::Test;
33
34namespace shill {
35
Ben Chanb061f892013-02-27 17:46:55 -080036class TrafficMonitorTest : public Test {
37 public:
Ben Chan98a6b092014-07-07 23:37:11 -070038 static const char kLocalIpAddr[];
Ben Chan7fab8972014-08-10 17:14:46 -070039 static const uint16_t kLocalPort1;
40 static const uint16_t kLocalPort2;
41 static const uint16_t kLocalPort3;
42 static const uint16_t kLocalPort4;
43 static const uint16_t kLocalPort5;
Ben Chan98a6b092014-07-07 23:37:11 -070044 static const char kRemoteIpAddr[];
Ben Chan7fab8972014-08-10 17:14:46 -070045 static const uint16_t kRemotePort;
46 static const uint64_t kTxQueueLength1;
47 static const uint64_t kTxQueueLength2;
48 static const uint64_t kTxQueueLength3;
49 static const uint64_t kTxQueueLength4;
Thieu Le03026662013-04-04 10:45:11 -070050
Ben Chanb061f892013-02-27 17:46:55 -080051 TrafficMonitorTest()
52 : device_(new MockDevice(&control_,
53 &dispatcher_,
Ben Chancc225ef2014-09-30 13:26:51 -070054 nullptr,
55 nullptr,
Ben Chanb061f892013-02-27 17:46:55 -080056 "netdev0",
57 "00:11:22:33:44:55",
58 1)),
Thieu Le03026662013-04-04 10:45:11 -070059 ipconfig_(new MockIPConfig(&control_, "netdev0")),
60 mock_socket_info_reader_(new MockSocketInfoReader),
Thieu Lefa7960e2013-04-15 13:14:55 -070061 mock_connection_info_reader_(new MockConnectionInfoReader),
Thieu Le03026662013-04-04 10:45:11 -070062 monitor_(device_, &dispatcher_),
63 local_addr_(IPAddress::kFamilyIPv4),
64 remote_addr_(IPAddress::kFamilyIPv4) {
65 local_addr_.SetAddressFromString(kLocalIpAddr);
66 remote_addr_.SetAddressFromString(kRemoteIpAddr);
Ben Chanb061f892013-02-27 17:46:55 -080067 }
68
Peter Qiudc335f82014-05-15 10:33:17 -070069 MOCK_METHOD1(OnNoOutgoingPackets, void(int));
Thieu Le03026662013-04-04 10:45:11 -070070
Ben Chanb061f892013-02-27 17:46:55 -080071 protected:
Thieu Le03026662013-04-04 10:45:11 -070072 virtual void SetUp() {
73 monitor_.socket_info_reader_.reset(
74 mock_socket_info_reader_); // Passes ownership
Thieu Lefa7960e2013-04-15 13:14:55 -070075 monitor_.connection_info_reader_.reset(
76 mock_connection_info_reader_); // Passes ownership
Thieu Le03026662013-04-04 10:45:11 -070077
Gaurav Shah61c0eac2013-04-09 17:09:42 -070078 device_->set_ipconfig(ipconfig_);
Thieu Le03026662013-04-04 10:45:11 -070079 ipconfig_properties_.address = kLocalIpAddr;
80 EXPECT_CALL(*ipconfig_.get(), properties())
81 .WillRepeatedly(ReturnRef(ipconfig_properties_));
Thieu Le03026662013-04-04 10:45:11 -070082 }
83
84 void VerifyStopped() {
85 EXPECT_TRUE(monitor_.sample_traffic_callback_.IsCancelled());
Thieu Lefa7960e2013-04-15 13:14:55 -070086 EXPECT_EQ(0, monitor_.accummulated_congested_tx_queues_samples_);
Thieu Le03026662013-04-04 10:45:11 -070087 }
88
89 void VerifyStarted() {
90 EXPECT_FALSE(monitor_.sample_traffic_callback_.IsCancelled());
91 }
92
Paul Stewart3b30ca52015-06-16 13:13:10 -070093 void SetupMockSocketInfos(const vector<SocketInfo>& socket_infos) {
Thieu Le03026662013-04-04 10:45:11 -070094 mock_socket_infos_ = socket_infos;
95 EXPECT_CALL(*mock_socket_info_reader_, LoadTcpSocketInfo(_))
96 .WillRepeatedly(
97 Invoke(this, &TrafficMonitorTest::MockLoadTcpSocketInfo));
98 }
99
Thieu Lefa7960e2013-04-15 13:14:55 -0700100 void SetupMockConnectionInfos(
Paul Stewart3b30ca52015-06-16 13:13:10 -0700101 const vector<ConnectionInfo>& connection_infos) {
Thieu Lefa7960e2013-04-15 13:14:55 -0700102 mock_connection_infos_ = connection_infos;
103 EXPECT_CALL(*mock_connection_info_reader_, LoadConnectionInfo(_))
104 .WillRepeatedly(
105 Invoke(this, &TrafficMonitorTest::MockLoadConnectionInfo));
106 }
107
Paul Stewart3b30ca52015-06-16 13:13:10 -0700108 bool MockLoadTcpSocketInfo(vector<SocketInfo>* info_list) {
Thieu Le03026662013-04-04 10:45:11 -0700109 *info_list = mock_socket_infos_;
110 return true;
111 }
112
Paul Stewart3b30ca52015-06-16 13:13:10 -0700113 bool MockLoadConnectionInfo(vector<ConnectionInfo>* info_list) {
Thieu Lefa7960e2013-04-15 13:14:55 -0700114 *info_list = mock_connection_infos_;
115 return true;
116 }
117
Paul Stewart3b30ca52015-06-16 13:13:10 -0700118 string FormatIPPort(const IPAddress& ip, const uint16_t port) {
Thieu Le03026662013-04-04 10:45:11 -0700119 return StringPrintf("%s:%d", ip.ToString().c_str(), port);
Ben Chanb061f892013-02-27 17:46:55 -0800120 }
121
122 NiceMockControl control_;
123 NiceMock<MockEventDispatcher> dispatcher_;
124 scoped_refptr<MockDevice> device_;
Thieu Le03026662013-04-04 10:45:11 -0700125 scoped_refptr<MockIPConfig> ipconfig_;
126 IPConfig::Properties ipconfig_properties_;
Paul Stewart3b30ca52015-06-16 13:13:10 -0700127 MockSocketInfoReader* mock_socket_info_reader_;
128 MockConnectionInfoReader* mock_connection_info_reader_;
Ben Chanb061f892013-02-27 17:46:55 -0800129 TrafficMonitor monitor_;
Thieu Le03026662013-04-04 10:45:11 -0700130 vector<SocketInfo> mock_socket_infos_;
Thieu Lefa7960e2013-04-15 13:14:55 -0700131 vector<ConnectionInfo> mock_connection_infos_;
Thieu Le03026662013-04-04 10:45:11 -0700132 IPAddress local_addr_;
133 IPAddress remote_addr_;
Ben Chanb061f892013-02-27 17:46:55 -0800134};
135
Thieu Le03026662013-04-04 10:45:11 -0700136// static
Ben Chan98a6b092014-07-07 23:37:11 -0700137const char TrafficMonitorTest::kLocalIpAddr[] = "127.0.0.1";
Ben Chan7fab8972014-08-10 17:14:46 -0700138const uint16_t TrafficMonitorTest::kLocalPort1 = 1234;
139const uint16_t TrafficMonitorTest::kLocalPort2 = 2345;
140const uint16_t TrafficMonitorTest::kLocalPort3 = 3456;
141const uint16_t TrafficMonitorTest::kLocalPort4 = 4567;
142const uint16_t TrafficMonitorTest::kLocalPort5 = 4567;
Ben Chan98a6b092014-07-07 23:37:11 -0700143const char TrafficMonitorTest::kRemoteIpAddr[] = "192.168.1.1";
Ben Chan7fab8972014-08-10 17:14:46 -0700144const uint16_t TrafficMonitorTest::kRemotePort = 5678;
145const uint64_t TrafficMonitorTest::kTxQueueLength1 = 111;
146const uint64_t TrafficMonitorTest::kTxQueueLength2 = 222;
147const uint64_t TrafficMonitorTest::kTxQueueLength3 = 333;
148const uint64_t TrafficMonitorTest::kTxQueueLength4 = 444;
Thieu Le03026662013-04-04 10:45:11 -0700149
Ben Chanb061f892013-02-27 17:46:55 -0800150TEST_F(TrafficMonitorTest, StartAndStop) {
Thieu Le03026662013-04-04 10:45:11 -0700151 // Stop without start
152 monitor_.Stop();
153 VerifyStopped();
Ben Chanb061f892013-02-27 17:46:55 -0800154
Thieu Le03026662013-04-04 10:45:11 -0700155 // Normal start
Ben Chanb061f892013-02-27 17:46:55 -0800156 monitor_.Start();
Thieu Le03026662013-04-04 10:45:11 -0700157 VerifyStarted();
Ben Chanb061f892013-02-27 17:46:55 -0800158
Thieu Le03026662013-04-04 10:45:11 -0700159 // Stop after start
160 monitor_.Stop();
161 VerifyStopped();
Ben Chanb061f892013-02-27 17:46:55 -0800162
Thieu Le03026662013-04-04 10:45:11 -0700163 // Stop again without start
164 monitor_.Stop();
165 VerifyStopped();
Ben Chanb061f892013-02-27 17:46:55 -0800166}
167
Thieu Le03026662013-04-04 10:45:11 -0700168TEST_F(TrafficMonitorTest, BuildIPPortToTxQueueLengthValid) {
169 vector<SocketInfo> socket_infos;
170 socket_infos.push_back(
171 SocketInfo(SocketInfo::kConnectionStateEstablished,
172 local_addr_,
173 TrafficMonitorTest::kLocalPort1,
174 remote_addr_,
175 TrafficMonitorTest::kRemotePort,
176 TrafficMonitorTest::kTxQueueLength1,
177 0,
178 SocketInfo::kTimerStateRetransmitTimerPending));
179 TrafficMonitor::IPPortToTxQueueLengthMap tx_queue_lengths;
180 monitor_.BuildIPPortToTxQueueLength(socket_infos, &tx_queue_lengths);
181 EXPECT_EQ(1, tx_queue_lengths.size());
182 string ip_port = FormatIPPort(local_addr_, TrafficMonitorTest::kLocalPort1);
183 EXPECT_EQ(TrafficMonitorTest::kTxQueueLength1, tx_queue_lengths[ip_port]);
184}
Ben Chanb061f892013-02-27 17:46:55 -0800185
Thieu Le03026662013-04-04 10:45:11 -0700186TEST_F(TrafficMonitorTest, BuildIPPortToTxQueueLengthInvalidDevice) {
187 vector<SocketInfo> socket_infos;
188 IPAddress foreign_ip_addr(IPAddress::kFamilyIPv4);
189 foreign_ip_addr.SetAddressFromString("192.167.1.1");
190 socket_infos.push_back(
191 SocketInfo(SocketInfo::kConnectionStateEstablished,
192 foreign_ip_addr,
193 TrafficMonitorTest::kLocalPort1,
194 remote_addr_,
195 TrafficMonitorTest::kRemotePort,
196 TrafficMonitorTest::kTxQueueLength1,
197 0,
198 SocketInfo::kTimerStateRetransmitTimerPending));
199 TrafficMonitor::IPPortToTxQueueLengthMap tx_queue_lengths;
200 monitor_.BuildIPPortToTxQueueLength(socket_infos, &tx_queue_lengths);
201 EXPECT_EQ(0, tx_queue_lengths.size());
202}
Ben Chanb061f892013-02-27 17:46:55 -0800203
Thieu Le03026662013-04-04 10:45:11 -0700204TEST_F(TrafficMonitorTest, BuildIPPortToTxQueueLengthZero) {
205 vector<SocketInfo> socket_infos;
206 socket_infos.push_back(
207 SocketInfo(SocketInfo::kConnectionStateEstablished,
208 local_addr_,
209 TrafficMonitorTest::kLocalPort1,
210 remote_addr_,
211 TrafficMonitorTest::kRemotePort,
212 0,
213 0,
214 SocketInfo::kTimerStateRetransmitTimerPending));
215 TrafficMonitor::IPPortToTxQueueLengthMap tx_queue_lengths;
216 monitor_.BuildIPPortToTxQueueLength(socket_infos, &tx_queue_lengths);
217 EXPECT_EQ(0, tx_queue_lengths.size());
218}
Ben Chanb061f892013-02-27 17:46:55 -0800219
Thieu Le03026662013-04-04 10:45:11 -0700220TEST_F(TrafficMonitorTest, BuildIPPortToTxQueueLengthInvalidConnectionState) {
221 vector<SocketInfo> socket_infos;
222 socket_infos.push_back(
223 SocketInfo(SocketInfo::kConnectionStateSynSent,
224 local_addr_,
225 TrafficMonitorTest::kLocalPort1,
226 remote_addr_,
227 TrafficMonitorTest::kRemotePort,
228 TrafficMonitorTest::kTxQueueLength1,
229 0,
230 SocketInfo::kTimerStateRetransmitTimerPending));
231 TrafficMonitor::IPPortToTxQueueLengthMap tx_queue_lengths;
232 monitor_.BuildIPPortToTxQueueLength(socket_infos, &tx_queue_lengths);
233 EXPECT_EQ(0, tx_queue_lengths.size());
234}
Ben Chanb061f892013-02-27 17:46:55 -0800235
Thieu Le03026662013-04-04 10:45:11 -0700236TEST_F(TrafficMonitorTest, BuildIPPortToTxQueueLengthInvalidTimerState) {
237 vector<SocketInfo> socket_infos;
238 socket_infos.push_back(
239 SocketInfo(SocketInfo::kConnectionStateEstablished,
240 local_addr_,
241 TrafficMonitorTest::kLocalPort1,
242 remote_addr_,
243 TrafficMonitorTest::kRemotePort,
244 TrafficMonitorTest::kTxQueueLength1,
245 0,
246 SocketInfo::kTimerStateNoTimerPending));
247 TrafficMonitor::IPPortToTxQueueLengthMap tx_queue_lengths;
248 monitor_.BuildIPPortToTxQueueLength(socket_infos, &tx_queue_lengths);
249 EXPECT_EQ(0, tx_queue_lengths.size());
250}
Ben Chanb061f892013-02-27 17:46:55 -0800251
Thieu Le03026662013-04-04 10:45:11 -0700252TEST_F(TrafficMonitorTest, BuildIPPortToTxQueueLengthMultipleEntries) {
253 vector<SocketInfo> socket_infos;
254 socket_infos.push_back(
255 SocketInfo(SocketInfo::kConnectionStateSynSent,
256 local_addr_,
257 TrafficMonitorTest::kLocalPort1,
258 remote_addr_,
259 TrafficMonitorTest::kRemotePort,
260 TrafficMonitorTest::kTxQueueLength1,
261 0,
262 SocketInfo::kTimerStateNoTimerPending));
263 socket_infos.push_back(
264 SocketInfo(SocketInfo::kConnectionStateEstablished,
265 local_addr_,
266 TrafficMonitorTest::kLocalPort2,
267 remote_addr_,
268 TrafficMonitorTest::kRemotePort,
269 TrafficMonitorTest::kTxQueueLength2,
270 0,
271 SocketInfo::kTimerStateRetransmitTimerPending));
272 socket_infos.push_back(
273 SocketInfo(SocketInfo::kConnectionStateEstablished,
274 local_addr_,
275 TrafficMonitorTest::kLocalPort3,
276 remote_addr_,
277 TrafficMonitorTest::kRemotePort,
278 TrafficMonitorTest::kTxQueueLength3,
279 0,
280 SocketInfo::kTimerStateRetransmitTimerPending));
281 socket_infos.push_back(
282 SocketInfo(SocketInfo::kConnectionStateEstablished,
283 local_addr_,
284 TrafficMonitorTest::kLocalPort4,
285 remote_addr_,
286 TrafficMonitorTest::kRemotePort,
287 TrafficMonitorTest::kTxQueueLength4,
288 0,
289 SocketInfo::kTimerStateNoTimerPending));
290 socket_infos.push_back(
291 SocketInfo(SocketInfo::kConnectionStateEstablished,
292 local_addr_,
293 TrafficMonitorTest::kLocalPort5,
294 remote_addr_,
295 TrafficMonitorTest::kRemotePort,
296 0,
297 0,
298 SocketInfo::kTimerStateRetransmitTimerPending));
299 TrafficMonitor::IPPortToTxQueueLengthMap tx_queue_lengths;
300 monitor_.BuildIPPortToTxQueueLength(socket_infos, &tx_queue_lengths);
301 EXPECT_EQ(2, tx_queue_lengths.size());
302 string ip_port = FormatIPPort(local_addr_, TrafficMonitorTest::kLocalPort2);
303 EXPECT_EQ(kTxQueueLength2, tx_queue_lengths[ip_port]);
304 ip_port = FormatIPPort(local_addr_, TrafficMonitorTest::kLocalPort3);
305 EXPECT_EQ(kTxQueueLength3, tx_queue_lengths[ip_port]);
306}
307
308TEST_F(TrafficMonitorTest, SampleTrafficStuckTxQueueSameQueueLength) {
309 vector<SocketInfo> socket_infos;
310 socket_infos.push_back(
311 SocketInfo(SocketInfo::kConnectionStateEstablished,
312 local_addr_,
313 TrafficMonitorTest::kLocalPort1,
314 remote_addr_,
315 TrafficMonitorTest::kRemotePort,
316 TrafficMonitorTest::kTxQueueLength1,
317 0,
318 SocketInfo::kTimerStateRetransmitTimerPending));
319 SetupMockSocketInfos(socket_infos);
Peter Qiudc335f82014-05-15 10:33:17 -0700320 monitor_.set_network_problem_detected_callback(
Thieu Le03026662013-04-04 10:45:11 -0700321 Bind(&TrafficMonitorTest::OnNoOutgoingPackets, Unretained(this)));
Peter Qiudc335f82014-05-15 10:33:17 -0700322 EXPECT_CALL(*this, OnNoOutgoingPackets(_)).Times(0);
Thieu Le03026662013-04-04 10:45:11 -0700323 monitor_.SampleTraffic();
324 Mock::VerifyAndClearExpectations(this);
325
326 // Mimic same queue length by using same mock socket info.
Peter Qiudc335f82014-05-15 10:33:17 -0700327 EXPECT_CALL(*this, OnNoOutgoingPackets(
328 TrafficMonitor::kNetworkProblemCongestedTxQueue));
Thieu Le03026662013-04-04 10:45:11 -0700329 monitor_.SampleTraffic();
330 Mock::VerifyAndClearExpectations(this);
331
332 // Perform another sampling pass and make sure the callback is only
333 // triggered once.
Peter Qiudc335f82014-05-15 10:33:17 -0700334 EXPECT_CALL(*this, OnNoOutgoingPackets(_)).Times(0);
Thieu Le03026662013-04-04 10:45:11 -0700335 monitor_.SampleTraffic();
336}
337
338TEST_F(TrafficMonitorTest, SampleTrafficStuckTxQueueIncreasingQueueLength) {
339 vector<SocketInfo> socket_infos;
340 socket_infos.push_back(
341 SocketInfo(SocketInfo::kConnectionStateEstablished,
342 local_addr_,
343 TrafficMonitorTest::kLocalPort1,
344 remote_addr_,
345 TrafficMonitorTest::kRemotePort,
346 TrafficMonitorTest::kTxQueueLength1,
347 0,
348 SocketInfo::kTimerStateRetransmitTimerPending));
349 SetupMockSocketInfos(socket_infos);
Peter Qiudc335f82014-05-15 10:33:17 -0700350 monitor_.set_network_problem_detected_callback(
Thieu Le03026662013-04-04 10:45:11 -0700351 Bind(&TrafficMonitorTest::OnNoOutgoingPackets, Unretained(this)));
Peter Qiudc335f82014-05-15 10:33:17 -0700352 EXPECT_CALL(*this, OnNoOutgoingPackets(_)).Times(0);
Thieu Le03026662013-04-04 10:45:11 -0700353 monitor_.SampleTraffic();
354 Mock::VerifyAndClearExpectations(this);
355
356 socket_infos.clear();
357 socket_infos.push_back(
358 SocketInfo(SocketInfo::kConnectionStateEstablished,
359 local_addr_,
360 TrafficMonitorTest::kLocalPort1,
361 remote_addr_,
362 TrafficMonitorTest::kRemotePort,
363 TrafficMonitorTest::kTxQueueLength1 + 1,
364 0,
365 SocketInfo::kTimerStateRetransmitTimerPending));
366 SetupMockSocketInfos(socket_infos);
Peter Qiudc335f82014-05-15 10:33:17 -0700367 EXPECT_CALL(*this, OnNoOutgoingPackets(
368 TrafficMonitor::kNetworkProblemCongestedTxQueue));
Thieu Le03026662013-04-04 10:45:11 -0700369 monitor_.SampleTraffic();
370}
371
372TEST_F(TrafficMonitorTest, SampleTrafficStuckTxQueueVariousQueueLengths) {
373 vector<SocketInfo> socket_infos;
374 socket_infos.push_back(
375 SocketInfo(SocketInfo::kConnectionStateEstablished,
376 local_addr_,
377 TrafficMonitorTest::kLocalPort1,
378 remote_addr_,
379 TrafficMonitorTest::kRemotePort,
380 TrafficMonitorTest::kTxQueueLength2,
381 0,
382 SocketInfo::kTimerStateRetransmitTimerPending));
383 SetupMockSocketInfos(socket_infos);
Peter Qiudc335f82014-05-15 10:33:17 -0700384 monitor_.set_network_problem_detected_callback(
Thieu Le03026662013-04-04 10:45:11 -0700385 Bind(&TrafficMonitorTest::OnNoOutgoingPackets, Unretained(this)));
Peter Qiudc335f82014-05-15 10:33:17 -0700386 EXPECT_CALL(*this, OnNoOutgoingPackets(_)).Times(0);
Thieu Le03026662013-04-04 10:45:11 -0700387 monitor_.SampleTraffic();
388 Mock::VerifyAndClearExpectations(this);
389
390 socket_infos.clear();
391 socket_infos.push_back(
392 SocketInfo(SocketInfo::kConnectionStateEstablished,
393 local_addr_,
394 TrafficMonitorTest::kLocalPort1,
395 remote_addr_,
396 TrafficMonitorTest::kRemotePort,
397 TrafficMonitorTest::kTxQueueLength1,
398 0,
399 SocketInfo::kTimerStateRetransmitTimerPending));
400 SetupMockSocketInfos(socket_infos);
Peter Qiudc335f82014-05-15 10:33:17 -0700401 EXPECT_CALL(*this, OnNoOutgoingPackets(_)).Times(0);
Thieu Le03026662013-04-04 10:45:11 -0700402 monitor_.SampleTraffic();
403 Mock::VerifyAndClearExpectations(this);
404
405 socket_infos.clear();
406 socket_infos.push_back(
407 SocketInfo(SocketInfo::kConnectionStateEstablished,
408 local_addr_,
409 TrafficMonitorTest::kLocalPort1,
410 remote_addr_,
411 TrafficMonitorTest::kRemotePort,
412 TrafficMonitorTest::kTxQueueLength2,
413 0,
414 SocketInfo::kTimerStateRetransmitTimerPending));
415 SetupMockSocketInfos(socket_infos);
Peter Qiudc335f82014-05-15 10:33:17 -0700416 EXPECT_CALL(*this, OnNoOutgoingPackets(
417 TrafficMonitor::kNetworkProblemCongestedTxQueue));
Thieu Le03026662013-04-04 10:45:11 -0700418 monitor_.SampleTraffic();
419}
420
421TEST_F(TrafficMonitorTest, SampleTrafficUnstuckTxQueueZeroQueueLength) {
422 vector<SocketInfo> socket_infos;
423 socket_infos.push_back(
424 SocketInfo(SocketInfo::kConnectionStateEstablished,
425 local_addr_,
426 TrafficMonitorTest::kLocalPort1,
427 remote_addr_,
428 TrafficMonitorTest::kRemotePort,
429 TrafficMonitorTest::kTxQueueLength1,
430 0,
431 SocketInfo::kTimerStateRetransmitTimerPending));
432 SetupMockSocketInfos(socket_infos);
Peter Qiudc335f82014-05-15 10:33:17 -0700433 monitor_.set_network_problem_detected_callback(
Thieu Le03026662013-04-04 10:45:11 -0700434 Bind(&TrafficMonitorTest::OnNoOutgoingPackets, Unretained(this)));
Peter Qiudc335f82014-05-15 10:33:17 -0700435 EXPECT_CALL(*this, OnNoOutgoingPackets(_)).Times(0);
Thieu Le03026662013-04-04 10:45:11 -0700436 monitor_.SampleTraffic();
437
438 socket_infos.clear();
439 socket_infos.push_back(
440 SocketInfo(SocketInfo::kConnectionStateEstablished,
441 local_addr_,
442 TrafficMonitorTest::kLocalPort1,
443 remote_addr_,
444 TrafficMonitorTest::kRemotePort,
445 0,
446 0,
447 SocketInfo::kTimerStateRetransmitTimerPending));
448 SetupMockSocketInfos(socket_infos);
449 monitor_.SampleTraffic();
Thieu Lefa7960e2013-04-15 13:14:55 -0700450 EXPECT_EQ(0, monitor_.accummulated_congested_tx_queues_samples_);
Thieu Le03026662013-04-04 10:45:11 -0700451}
452
453TEST_F(TrafficMonitorTest, SampleTrafficUnstuckTxQueueNoConnection) {
454 vector<SocketInfo> socket_infos;
455 socket_infos.push_back(
456 SocketInfo(SocketInfo::kConnectionStateEstablished,
457 local_addr_,
458 TrafficMonitorTest::kLocalPort1,
459 remote_addr_,
460 TrafficMonitorTest::kRemotePort,
461 TrafficMonitorTest::kTxQueueLength1,
462 0,
463 SocketInfo::kTimerStateRetransmitTimerPending));
464 SetupMockSocketInfos(socket_infos);
Peter Qiudc335f82014-05-15 10:33:17 -0700465 monitor_.set_network_problem_detected_callback(
Thieu Le03026662013-04-04 10:45:11 -0700466 Bind(&TrafficMonitorTest::OnNoOutgoingPackets, Unretained(this)));
Peter Qiudc335f82014-05-15 10:33:17 -0700467 EXPECT_CALL(*this, OnNoOutgoingPackets(_)).Times(0);
Thieu Le03026662013-04-04 10:45:11 -0700468 monitor_.SampleTraffic();
469
470 socket_infos.clear();
471 SetupMockSocketInfos(socket_infos);
472 monitor_.SampleTraffic();
Thieu Lefa7960e2013-04-15 13:14:55 -0700473 EXPECT_EQ(0, monitor_.accummulated_congested_tx_queues_samples_);
Thieu Le03026662013-04-04 10:45:11 -0700474}
475
476TEST_F(TrafficMonitorTest, SampleTrafficUnstuckTxQueueStateChanged) {
477 vector<SocketInfo> socket_infos;
478 socket_infos.push_back(
479 SocketInfo(SocketInfo::kConnectionStateEstablished,
480 local_addr_,
481 TrafficMonitorTest::kLocalPort1,
482 remote_addr_,
483 TrafficMonitorTest::kRemotePort,
484 TrafficMonitorTest::kTxQueueLength1,
485 0,
486 SocketInfo::kTimerStateRetransmitTimerPending));
487 SetupMockSocketInfos(socket_infos);
Peter Qiudc335f82014-05-15 10:33:17 -0700488 monitor_.set_network_problem_detected_callback(
Thieu Le03026662013-04-04 10:45:11 -0700489 Bind(&TrafficMonitorTest::OnNoOutgoingPackets, Unretained(this)));
Peter Qiudc335f82014-05-15 10:33:17 -0700490 EXPECT_CALL(*this, OnNoOutgoingPackets(_)).Times(0);
Thieu Le03026662013-04-04 10:45:11 -0700491 monitor_.SampleTraffic();
492
493 socket_infos.clear();
494 socket_infos.push_back(
495 SocketInfo(SocketInfo::kConnectionStateClose,
496 local_addr_,
497 TrafficMonitorTest::kLocalPort1,
498 remote_addr_,
499 TrafficMonitorTest::kRemotePort,
500 0,
501 0,
502 SocketInfo::kTimerStateNoTimerPending));
503 SetupMockSocketInfos(socket_infos);
504 monitor_.SampleTraffic();
Thieu Lefa7960e2013-04-15 13:14:55 -0700505 EXPECT_EQ(0, monitor_.accummulated_congested_tx_queues_samples_);
506}
507
508TEST_F(TrafficMonitorTest, SampleTrafficDnsTimedOut) {
509 vector<ConnectionInfo> connection_infos;
510 connection_infos.push_back(
511 ConnectionInfo(IPPROTO_UDP,
512 TrafficMonitor::kDnsTimedOutThresholdSeconds - 1,
513 true, local_addr_, TrafficMonitorTest::kLocalPort1,
514 remote_addr_, TrafficMonitor::kDnsPort,
515 remote_addr_, TrafficMonitor::kDnsPort,
516 local_addr_, TrafficMonitorTest::kLocalPort1));
517 SetupMockConnectionInfos(connection_infos);
Peter Qiudc335f82014-05-15 10:33:17 -0700518 monitor_.set_network_problem_detected_callback(
Thieu Lefa7960e2013-04-15 13:14:55 -0700519 Bind(&TrafficMonitorTest::OnNoOutgoingPackets, Unretained(this)));
520 // Make sure the no routing event is not fired before the threshold is
521 // exceeded.
Peter Qiudc335f82014-05-15 10:33:17 -0700522 EXPECT_CALL(*this, OnNoOutgoingPackets(_)).Times(0);
Thieu Lefa7960e2013-04-15 13:14:55 -0700523 for (int count = 1; count < TrafficMonitor::kMinimumFailedSamplesToTrigger;
524 ++count) {
525 monitor_.SampleTraffic();
526 }
527 Mock::VerifyAndClearExpectations(this);
528
529 // This call should cause the threshold to exceed.
Peter Qiudc335f82014-05-15 10:33:17 -0700530 EXPECT_CALL(*this, OnNoOutgoingPackets(
531 TrafficMonitor::kNetworkProblemDNSFailure)).Times(1);
Thieu Lefa7960e2013-04-15 13:14:55 -0700532 monitor_.SampleTraffic();
533 Mock::VerifyAndClearExpectations(this);
534
535 // Make sure the event is only fired once.
Peter Qiudc335f82014-05-15 10:33:17 -0700536 EXPECT_CALL(*this, OnNoOutgoingPackets(_)).Times(0);
Thieu Lefa7960e2013-04-15 13:14:55 -0700537 monitor_.SampleTraffic();
538}
539
540TEST_F(TrafficMonitorTest, SampleTrafficDnsOutstanding) {
541 vector<ConnectionInfo> connection_infos;
542 connection_infos.push_back(
543 ConnectionInfo(IPPROTO_UDP,
544 TrafficMonitor::kDnsTimedOutThresholdSeconds + 1,
545 true, local_addr_, TrafficMonitorTest::kLocalPort1,
546 remote_addr_, TrafficMonitor::kDnsPort,
547 remote_addr_, TrafficMonitor::kDnsPort,
548 local_addr_, TrafficMonitorTest::kLocalPort1));
549 SetupMockConnectionInfos(connection_infos);
Peter Qiudc335f82014-05-15 10:33:17 -0700550 monitor_.set_network_problem_detected_callback(
Thieu Lefa7960e2013-04-15 13:14:55 -0700551 Bind(&TrafficMonitorTest::OnNoOutgoingPackets, Unretained(this)));
Peter Qiudc335f82014-05-15 10:33:17 -0700552 EXPECT_CALL(*this, OnNoOutgoingPackets(_)).Times(0);
Thieu Lefa7960e2013-04-15 13:14:55 -0700553 for (int count = 0; count < TrafficMonitor::kMinimumFailedSamplesToTrigger;
554 ++count) {
555 monitor_.SampleTraffic();
556 }
557}
558
559TEST_F(TrafficMonitorTest, SampleTrafficDnsSuccessful) {
560 vector<ConnectionInfo> connection_infos;
561 connection_infos.push_back(
562 ConnectionInfo(IPPROTO_UDP,
563 TrafficMonitor::kDnsTimedOutThresholdSeconds - 1,
564 false, local_addr_, TrafficMonitorTest::kLocalPort1,
565 remote_addr_, TrafficMonitor::kDnsPort,
566 remote_addr_, TrafficMonitor::kDnsPort,
567 local_addr_, TrafficMonitorTest::kLocalPort1));
568 SetupMockConnectionInfos(connection_infos);
Peter Qiudc335f82014-05-15 10:33:17 -0700569 monitor_.set_network_problem_detected_callback(
Thieu Lefa7960e2013-04-15 13:14:55 -0700570 Bind(&TrafficMonitorTest::OnNoOutgoingPackets, Unretained(this)));
Peter Qiudc335f82014-05-15 10:33:17 -0700571 EXPECT_CALL(*this, OnNoOutgoingPackets(_)).Times(0);
Thieu Lefa7960e2013-04-15 13:14:55 -0700572 for (int count = 1; count < TrafficMonitor::kMinimumFailedSamplesToTrigger;
573 ++count) {
574 monitor_.SampleTraffic();
575 }
576}
577
578TEST_F(TrafficMonitorTest, SampleTrafficDnsFailureThenSuccess) {
579 vector<ConnectionInfo> connection_infos;
580 connection_infos.push_back(
581 ConnectionInfo(IPPROTO_UDP,
582 TrafficMonitor::kDnsTimedOutThresholdSeconds - 1,
583 true, local_addr_, TrafficMonitorTest::kLocalPort1,
584 remote_addr_, TrafficMonitor::kDnsPort,
585 remote_addr_, TrafficMonitor::kDnsPort,
586 local_addr_, TrafficMonitorTest::kLocalPort1));
587 SetupMockConnectionInfos(connection_infos);
Peter Qiudc335f82014-05-15 10:33:17 -0700588 monitor_.set_network_problem_detected_callback(
Thieu Lefa7960e2013-04-15 13:14:55 -0700589 Bind(&TrafficMonitorTest::OnNoOutgoingPackets, Unretained(this)));
Peter Qiudc335f82014-05-15 10:33:17 -0700590 EXPECT_CALL(*this, OnNoOutgoingPackets(_)).Times(0);
Thieu Lefa7960e2013-04-15 13:14:55 -0700591 for (int count = 1; count < TrafficMonitor::kMinimumFailedSamplesToTrigger;
592 ++count) {
593 monitor_.SampleTraffic();
594 }
595 Mock::VerifyAndClearExpectations(this);
596
597 connection_infos.clear();
598 connection_infos.push_back(
599 ConnectionInfo(IPPROTO_UDP,
600 TrafficMonitor::kDnsTimedOutThresholdSeconds - 1,
601 false, local_addr_, TrafficMonitorTest::kLocalPort1,
602 remote_addr_, TrafficMonitor::kDnsPort,
603 remote_addr_, TrafficMonitor::kDnsPort,
604 local_addr_, TrafficMonitorTest::kLocalPort1));
605 SetupMockConnectionInfos(connection_infos);
Peter Qiudc335f82014-05-15 10:33:17 -0700606 EXPECT_CALL(*this, OnNoOutgoingPackets(_)).Times(0);
Thieu Lefa7960e2013-04-15 13:14:55 -0700607 monitor_.SampleTraffic();
608 EXPECT_EQ(0, monitor_.accummulated_dns_failures_samples_);
609}
610
611TEST_F(TrafficMonitorTest, SampleTrafficDnsTimedOutInvalidProtocol) {
612 vector<ConnectionInfo> connection_infos;
613 connection_infos.push_back(
614 ConnectionInfo(IPPROTO_TCP,
615 TrafficMonitor::kDnsTimedOutThresholdSeconds - 1,
616 true, local_addr_, TrafficMonitorTest::kLocalPort1,
617 remote_addr_, TrafficMonitor::kDnsPort,
618 remote_addr_, TrafficMonitor::kDnsPort,
619 local_addr_, TrafficMonitorTest::kLocalPort1));
620 SetupMockConnectionInfos(connection_infos);
Peter Qiudc335f82014-05-15 10:33:17 -0700621 monitor_.set_network_problem_detected_callback(
Thieu Lefa7960e2013-04-15 13:14:55 -0700622 Bind(&TrafficMonitorTest::OnNoOutgoingPackets, Unretained(this)));
Peter Qiudc335f82014-05-15 10:33:17 -0700623 EXPECT_CALL(*this, OnNoOutgoingPackets(_)).Times(0);
Thieu Lefa7960e2013-04-15 13:14:55 -0700624 for (int count = 0; count < TrafficMonitor::kMinimumFailedSamplesToTrigger;
625 ++count) {
626 monitor_.SampleTraffic();
627 }
628}
629
630TEST_F(TrafficMonitorTest, SampleTrafficDnsTimedOutInvalidSourceIp) {
631 vector<ConnectionInfo> connection_infos;
632 connection_infos.push_back(
633 ConnectionInfo(IPPROTO_UDP,
634 TrafficMonitor::kDnsTimedOutThresholdSeconds - 1,
635 true, remote_addr_, TrafficMonitorTest::kLocalPort1,
636 remote_addr_, TrafficMonitor::kDnsPort,
637 remote_addr_, TrafficMonitor::kDnsPort,
638 remote_addr_, TrafficMonitorTest::kLocalPort1));
639 SetupMockConnectionInfos(connection_infos);
Peter Qiudc335f82014-05-15 10:33:17 -0700640 monitor_.set_network_problem_detected_callback(
Thieu Lefa7960e2013-04-15 13:14:55 -0700641 Bind(&TrafficMonitorTest::OnNoOutgoingPackets, Unretained(this)));
Peter Qiudc335f82014-05-15 10:33:17 -0700642 EXPECT_CALL(*this, OnNoOutgoingPackets(_)).Times(0);
Thieu Lefa7960e2013-04-15 13:14:55 -0700643 for (int count = 0; count < TrafficMonitor::kMinimumFailedSamplesToTrigger;
644 ++count) {
645 monitor_.SampleTraffic();
646 }
647}
648
649TEST_F(TrafficMonitorTest, SampleTrafficDnsTimedOutOutsideTimeWindow) {
650 vector<ConnectionInfo> connection_infos;
651 connection_infos.push_back(
652 ConnectionInfo(IPPROTO_UDP,
653 TrafficMonitor::kDnsTimedOutThresholdSeconds -
654 TrafficMonitor::kSamplingIntervalMilliseconds / 1000,
655 true, remote_addr_, TrafficMonitorTest::kLocalPort1,
656 remote_addr_, TrafficMonitor::kDnsPort,
657 remote_addr_, TrafficMonitor::kDnsPort,
658 remote_addr_, TrafficMonitorTest::kLocalPort1));
659 SetupMockConnectionInfos(connection_infos);
Peter Qiudc335f82014-05-15 10:33:17 -0700660 monitor_.set_network_problem_detected_callback(
Thieu Lefa7960e2013-04-15 13:14:55 -0700661 Bind(&TrafficMonitorTest::OnNoOutgoingPackets, Unretained(this)));
Peter Qiudc335f82014-05-15 10:33:17 -0700662 EXPECT_CALL(*this, OnNoOutgoingPackets(_)).Times(0);
Thieu Lefa7960e2013-04-15 13:14:55 -0700663 for (int count = 0; count < TrafficMonitor::kMinimumFailedSamplesToTrigger;
664 ++count) {
665 monitor_.SampleTraffic();
666 }
667}
668
669TEST_F(TrafficMonitorTest, SampleTrafficNonDnsTimedOut) {
Ben Chan7fab8972014-08-10 17:14:46 -0700670 const uint16_t kNonDnsPort = 54;
Thieu Lefa7960e2013-04-15 13:14:55 -0700671 vector<ConnectionInfo> connection_infos;
672 connection_infos.push_back(
673 ConnectionInfo(IPPROTO_UDP,
674 TrafficMonitor::kDnsTimedOutThresholdSeconds - 1,
675 true, local_addr_, TrafficMonitorTest::kLocalPort1,
676 remote_addr_, kNonDnsPort,
677 remote_addr_, kNonDnsPort,
678 local_addr_, TrafficMonitorTest::kLocalPort1));
679 SetupMockConnectionInfos(connection_infos);
Peter Qiudc335f82014-05-15 10:33:17 -0700680 monitor_.set_network_problem_detected_callback(
Thieu Lefa7960e2013-04-15 13:14:55 -0700681 Bind(&TrafficMonitorTest::OnNoOutgoingPackets, Unretained(this)));
Peter Qiudc335f82014-05-15 10:33:17 -0700682 EXPECT_CALL(*this, OnNoOutgoingPackets(_)).Times(0);
Thieu Lefa7960e2013-04-15 13:14:55 -0700683 for (int count = 0; count < TrafficMonitor::kMinimumFailedSamplesToTrigger;
684 ++count) {
685 monitor_.SampleTraffic();
686 }
687}
688
689TEST_F(TrafficMonitorTest, SampleTrafficDnsStatsReset) {
690 vector<ConnectionInfo> connection_infos;
691 SetupMockConnectionInfos(connection_infos);
692 monitor_.accummulated_dns_failures_samples_ = 1;
693 monitor_.SampleTraffic();
694 EXPECT_EQ(0, monitor_.accummulated_dns_failures_samples_);
Ben Chanb061f892013-02-27 17:46:55 -0800695}
696
697} // namespace shill