1//
2// Copyright (C) 2013 The Android Open Source Project
3//
4// Licensed under the Apache License, Version 2.0 (the "License");
5// you may not use this file except in compliance with the License.
6// You may obtain a copy of the License at
7//
8//      http://www.apache.org/licenses/LICENSE-2.0
9//
10// Unless required by applicable law or agreed to in writing, software
11// distributed under the License is distributed on an "AS IS" BASIS,
12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13// See the License for the specific language governing permissions and
14// limitations under the License.
15//
16
17#include "shill/traffic_monitor.h"
18
19#include <string>
20#include <vector>
21
22#include <base/bind.h>
23#include <base/strings/stringprintf.h>
24#include <gtest/gtest.h>
25#include <netinet/in.h>
26
27#include "shill/mock_connection_info_reader.h"
28#include "shill/mock_device.h"
29#include "shill/mock_event_dispatcher.h"
30#include "shill/mock_ipconfig.h"
31#include "shill/mock_socket_info_reader.h"
32#include "shill/nice_mock_control.h"
33
34using base::Bind;
35using base::StringPrintf;
36using base::Unretained;
37using std::string;
38using std::vector;
39using testing::_;
40using testing::Mock;
41using testing::NiceMock;
42using testing::Return;
43using testing::ReturnRef;
44using testing::Test;
45
46namespace shill {
47
48class TrafficMonitorTest : public Test {
49 public:
50  static const char kLocalIpAddr[];
51  static const uint16_t kLocalPort1;
52  static const uint16_t kLocalPort2;
53  static const uint16_t kLocalPort3;
54  static const uint16_t kLocalPort4;
55  static const uint16_t kLocalPort5;
56  static const char kRemoteIpAddr[];
57  static const uint16_t kRemotePort;
58  static const uint64_t kTxQueueLength1;
59  static const uint64_t kTxQueueLength2;
60  static const uint64_t kTxQueueLength3;
61  static const uint64_t kTxQueueLength4;
62
63  TrafficMonitorTest()
64      : device_(new MockDevice(&control_,
65                               &dispatcher_,
66                               nullptr,
67                               nullptr,
68                               "netdev0",
69                               "00:11:22:33:44:55",
70                               1)),
71        ipconfig_(new MockIPConfig(&control_, "netdev0")),
72        mock_socket_info_reader_(new MockSocketInfoReader),
73        mock_connection_info_reader_(new MockConnectionInfoReader),
74        monitor_(device_, &dispatcher_),
75        local_addr_(IPAddress::kFamilyIPv4),
76        remote_addr_(IPAddress::kFamilyIPv4) {
77    local_addr_.SetAddressFromString(kLocalIpAddr);
78    remote_addr_.SetAddressFromString(kRemoteIpAddr);
79  }
80
81  MOCK_METHOD1(OnNoOutgoingPackets, void(int));
82
83 protected:
84  virtual void SetUp() {
85    monitor_.socket_info_reader_.reset(
86        mock_socket_info_reader_);  // Passes ownership
87    monitor_.connection_info_reader_.reset(
88        mock_connection_info_reader_);  // Passes ownership
89
90    device_->set_ipconfig(ipconfig_);
91    ipconfig_properties_.address = kLocalIpAddr;
92    EXPECT_CALL(*ipconfig_.get(), properties())
93        .WillRepeatedly(ReturnRef(ipconfig_properties_));
94  }
95
96  void VerifyStopped() {
97    EXPECT_TRUE(monitor_.sample_traffic_callback_.IsCancelled());
98    EXPECT_EQ(0, monitor_.accummulated_congested_tx_queues_samples_);
99  }
100
101  void VerifyStarted() {
102    EXPECT_FALSE(monitor_.sample_traffic_callback_.IsCancelled());
103  }
104
105  void SetupMockSocketInfos(const vector<SocketInfo>& socket_infos) {
106    mock_socket_infos_ = socket_infos;
107    EXPECT_CALL(*mock_socket_info_reader_, LoadTcpSocketInfo(_))
108        .WillRepeatedly(
109            Invoke(this, &TrafficMonitorTest::MockLoadTcpSocketInfo));
110  }
111
112  void SetupMockConnectionInfos(
113      const vector<ConnectionInfo>& connection_infos) {
114    mock_connection_infos_ = connection_infos;
115    EXPECT_CALL(*mock_connection_info_reader_, LoadConnectionInfo(_))
116        .WillRepeatedly(
117            Invoke(this, &TrafficMonitorTest::MockLoadConnectionInfo));
118  }
119
120  bool MockLoadTcpSocketInfo(vector<SocketInfo>* info_list) {
121    *info_list = mock_socket_infos_;
122    return true;
123  }
124
125  bool MockLoadConnectionInfo(vector<ConnectionInfo>* info_list) {
126    *info_list = mock_connection_infos_;
127    return true;
128  }
129
130  string FormatIPPort(const IPAddress& ip, const uint16_t port) {
131    return StringPrintf("%s:%d", ip.ToString().c_str(), port);
132  }
133
134  NiceMockControl control_;
135  NiceMock<MockEventDispatcher> dispatcher_;
136  scoped_refptr<MockDevice> device_;
137  scoped_refptr<MockIPConfig> ipconfig_;
138  IPConfig::Properties ipconfig_properties_;
139  MockSocketInfoReader* mock_socket_info_reader_;
140  MockConnectionInfoReader* mock_connection_info_reader_;
141  TrafficMonitor monitor_;
142  vector<SocketInfo> mock_socket_infos_;
143  vector<ConnectionInfo> mock_connection_infos_;
144  IPAddress local_addr_;
145  IPAddress remote_addr_;
146};
147
148// static
149const char TrafficMonitorTest::kLocalIpAddr[] = "127.0.0.1";
150const uint16_t TrafficMonitorTest::kLocalPort1 = 1234;
151const uint16_t TrafficMonitorTest::kLocalPort2 = 2345;
152const uint16_t TrafficMonitorTest::kLocalPort3 = 3456;
153const uint16_t TrafficMonitorTest::kLocalPort4 = 4567;
154const uint16_t TrafficMonitorTest::kLocalPort5 = 4567;
155const char TrafficMonitorTest::kRemoteIpAddr[] = "192.168.1.1";
156const uint16_t TrafficMonitorTest::kRemotePort = 5678;
157const uint64_t TrafficMonitorTest::kTxQueueLength1 = 111;
158const uint64_t TrafficMonitorTest::kTxQueueLength2 = 222;
159const uint64_t TrafficMonitorTest::kTxQueueLength3 = 333;
160const uint64_t TrafficMonitorTest::kTxQueueLength4 = 444;
161
162TEST_F(TrafficMonitorTest, StartAndStop) {
163  // Stop without start
164  monitor_.Stop();
165  VerifyStopped();
166
167  // Normal start
168  monitor_.Start();
169  VerifyStarted();
170
171  // Stop after start
172  monitor_.Stop();
173  VerifyStopped();
174
175  // Stop again without start
176  monitor_.Stop();
177  VerifyStopped();
178}
179
180TEST_F(TrafficMonitorTest, BuildIPPortToTxQueueLengthValid) {
181  vector<SocketInfo> socket_infos;
182  socket_infos.push_back(
183      SocketInfo(SocketInfo::kConnectionStateEstablished,
184                 local_addr_,
185                 TrafficMonitorTest::kLocalPort1,
186                 remote_addr_,
187                 TrafficMonitorTest::kRemotePort,
188                 TrafficMonitorTest::kTxQueueLength1,
189                 0,
190                 SocketInfo::kTimerStateRetransmitTimerPending));
191  TrafficMonitor::IPPortToTxQueueLengthMap tx_queue_lengths;
192  monitor_.BuildIPPortToTxQueueLength(socket_infos, &tx_queue_lengths);
193  EXPECT_EQ(1, tx_queue_lengths.size());
194  string ip_port = FormatIPPort(local_addr_, TrafficMonitorTest::kLocalPort1);
195  EXPECT_EQ(TrafficMonitorTest::kTxQueueLength1, tx_queue_lengths[ip_port]);
196}
197
198TEST_F(TrafficMonitorTest, BuildIPPortToTxQueueLengthInvalidDevice) {
199  vector<SocketInfo> socket_infos;
200  IPAddress foreign_ip_addr(IPAddress::kFamilyIPv4);
201  foreign_ip_addr.SetAddressFromString("192.167.1.1");
202  socket_infos.push_back(
203      SocketInfo(SocketInfo::kConnectionStateEstablished,
204                 foreign_ip_addr,
205                 TrafficMonitorTest::kLocalPort1,
206                 remote_addr_,
207                 TrafficMonitorTest::kRemotePort,
208                 TrafficMonitorTest::kTxQueueLength1,
209                 0,
210                 SocketInfo::kTimerStateRetransmitTimerPending));
211  TrafficMonitor::IPPortToTxQueueLengthMap tx_queue_lengths;
212  monitor_.BuildIPPortToTxQueueLength(socket_infos, &tx_queue_lengths);
213  EXPECT_EQ(0, tx_queue_lengths.size());
214}
215
216TEST_F(TrafficMonitorTest, BuildIPPortToTxQueueLengthZero) {
217  vector<SocketInfo> socket_infos;
218  socket_infos.push_back(
219      SocketInfo(SocketInfo::kConnectionStateEstablished,
220                 local_addr_,
221                 TrafficMonitorTest::kLocalPort1,
222                 remote_addr_,
223                 TrafficMonitorTest::kRemotePort,
224                 0,
225                 0,
226                 SocketInfo::kTimerStateRetransmitTimerPending));
227  TrafficMonitor::IPPortToTxQueueLengthMap tx_queue_lengths;
228  monitor_.BuildIPPortToTxQueueLength(socket_infos, &tx_queue_lengths);
229  EXPECT_EQ(0, tx_queue_lengths.size());
230}
231
232TEST_F(TrafficMonitorTest, BuildIPPortToTxQueueLengthInvalidConnectionState) {
233  vector<SocketInfo> socket_infos;
234  socket_infos.push_back(
235      SocketInfo(SocketInfo::kConnectionStateSynSent,
236                 local_addr_,
237                 TrafficMonitorTest::kLocalPort1,
238                 remote_addr_,
239                 TrafficMonitorTest::kRemotePort,
240                 TrafficMonitorTest::kTxQueueLength1,
241                 0,
242                 SocketInfo::kTimerStateRetransmitTimerPending));
243  TrafficMonitor::IPPortToTxQueueLengthMap tx_queue_lengths;
244  monitor_.BuildIPPortToTxQueueLength(socket_infos, &tx_queue_lengths);
245  EXPECT_EQ(0, tx_queue_lengths.size());
246}
247
248TEST_F(TrafficMonitorTest, BuildIPPortToTxQueueLengthInvalidTimerState) {
249  vector<SocketInfo> socket_infos;
250  socket_infos.push_back(
251      SocketInfo(SocketInfo::kConnectionStateEstablished,
252                 local_addr_,
253                 TrafficMonitorTest::kLocalPort1,
254                 remote_addr_,
255                 TrafficMonitorTest::kRemotePort,
256                 TrafficMonitorTest::kTxQueueLength1,
257                 0,
258                 SocketInfo::kTimerStateNoTimerPending));
259  TrafficMonitor::IPPortToTxQueueLengthMap tx_queue_lengths;
260  monitor_.BuildIPPortToTxQueueLength(socket_infos, &tx_queue_lengths);
261  EXPECT_EQ(0, tx_queue_lengths.size());
262}
263
264TEST_F(TrafficMonitorTest, BuildIPPortToTxQueueLengthMultipleEntries) {
265  vector<SocketInfo> socket_infos;
266  socket_infos.push_back(
267      SocketInfo(SocketInfo::kConnectionStateSynSent,
268                 local_addr_,
269                 TrafficMonitorTest::kLocalPort1,
270                 remote_addr_,
271                 TrafficMonitorTest::kRemotePort,
272                 TrafficMonitorTest::kTxQueueLength1,
273                 0,
274                 SocketInfo::kTimerStateNoTimerPending));
275  socket_infos.push_back(
276      SocketInfo(SocketInfo::kConnectionStateEstablished,
277                 local_addr_,
278                 TrafficMonitorTest::kLocalPort2,
279                 remote_addr_,
280                 TrafficMonitorTest::kRemotePort,
281                 TrafficMonitorTest::kTxQueueLength2,
282                 0,
283                 SocketInfo::kTimerStateRetransmitTimerPending));
284  socket_infos.push_back(
285      SocketInfo(SocketInfo::kConnectionStateEstablished,
286                 local_addr_,
287                 TrafficMonitorTest::kLocalPort3,
288                 remote_addr_,
289                 TrafficMonitorTest::kRemotePort,
290                 TrafficMonitorTest::kTxQueueLength3,
291                 0,
292                 SocketInfo::kTimerStateRetransmitTimerPending));
293  socket_infos.push_back(
294      SocketInfo(SocketInfo::kConnectionStateEstablished,
295                 local_addr_,
296                 TrafficMonitorTest::kLocalPort4,
297                 remote_addr_,
298                 TrafficMonitorTest::kRemotePort,
299                 TrafficMonitorTest::kTxQueueLength4,
300                 0,
301                 SocketInfo::kTimerStateNoTimerPending));
302  socket_infos.push_back(
303      SocketInfo(SocketInfo::kConnectionStateEstablished,
304                 local_addr_,
305                 TrafficMonitorTest::kLocalPort5,
306                 remote_addr_,
307                 TrafficMonitorTest::kRemotePort,
308                 0,
309                 0,
310                 SocketInfo::kTimerStateRetransmitTimerPending));
311  TrafficMonitor::IPPortToTxQueueLengthMap tx_queue_lengths;
312  monitor_.BuildIPPortToTxQueueLength(socket_infos, &tx_queue_lengths);
313  EXPECT_EQ(2, tx_queue_lengths.size());
314  string ip_port = FormatIPPort(local_addr_, TrafficMonitorTest::kLocalPort2);
315  EXPECT_EQ(kTxQueueLength2, tx_queue_lengths[ip_port]);
316  ip_port = FormatIPPort(local_addr_, TrafficMonitorTest::kLocalPort3);
317  EXPECT_EQ(kTxQueueLength3, tx_queue_lengths[ip_port]);
318}
319
320TEST_F(TrafficMonitorTest, SampleTrafficStuckTxQueueSameQueueLength) {
321  vector<SocketInfo> socket_infos;
322  socket_infos.push_back(
323      SocketInfo(SocketInfo::kConnectionStateEstablished,
324                 local_addr_,
325                 TrafficMonitorTest::kLocalPort1,
326                 remote_addr_,
327                 TrafficMonitorTest::kRemotePort,
328                 TrafficMonitorTest::kTxQueueLength1,
329                 0,
330                 SocketInfo::kTimerStateRetransmitTimerPending));
331  SetupMockSocketInfos(socket_infos);
332  monitor_.set_network_problem_detected_callback(
333      Bind(&TrafficMonitorTest::OnNoOutgoingPackets, Unretained(this)));
334  EXPECT_CALL(*this, OnNoOutgoingPackets(_)).Times(0);
335  monitor_.SampleTraffic();
336  Mock::VerifyAndClearExpectations(this);
337
338  // Mimic same queue length by using same mock socket info.
339  EXPECT_CALL(*this, OnNoOutgoingPackets(
340      TrafficMonitor::kNetworkProblemCongestedTxQueue));
341  monitor_.SampleTraffic();
342  Mock::VerifyAndClearExpectations(this);
343
344  // Perform another sampling pass and make sure the callback is only
345  // triggered once.
346  EXPECT_CALL(*this, OnNoOutgoingPackets(_)).Times(0);
347  monitor_.SampleTraffic();
348}
349
350TEST_F(TrafficMonitorTest, SampleTrafficStuckTxQueueIncreasingQueueLength) {
351  vector<SocketInfo> socket_infos;
352  socket_infos.push_back(
353      SocketInfo(SocketInfo::kConnectionStateEstablished,
354                 local_addr_,
355                 TrafficMonitorTest::kLocalPort1,
356                 remote_addr_,
357                 TrafficMonitorTest::kRemotePort,
358                 TrafficMonitorTest::kTxQueueLength1,
359                 0,
360                 SocketInfo::kTimerStateRetransmitTimerPending));
361  SetupMockSocketInfos(socket_infos);
362  monitor_.set_network_problem_detected_callback(
363      Bind(&TrafficMonitorTest::OnNoOutgoingPackets, Unretained(this)));
364  EXPECT_CALL(*this, OnNoOutgoingPackets(_)).Times(0);
365  monitor_.SampleTraffic();
366  Mock::VerifyAndClearExpectations(this);
367
368  socket_infos.clear();
369  socket_infos.push_back(
370      SocketInfo(SocketInfo::kConnectionStateEstablished,
371                 local_addr_,
372                 TrafficMonitorTest::kLocalPort1,
373                 remote_addr_,
374                 TrafficMonitorTest::kRemotePort,
375                 TrafficMonitorTest::kTxQueueLength1 + 1,
376                 0,
377                 SocketInfo::kTimerStateRetransmitTimerPending));
378  SetupMockSocketInfos(socket_infos);
379  EXPECT_CALL(*this, OnNoOutgoingPackets(
380      TrafficMonitor::kNetworkProblemCongestedTxQueue));
381  monitor_.SampleTraffic();
382}
383
384TEST_F(TrafficMonitorTest, SampleTrafficStuckTxQueueVariousQueueLengths) {
385  vector<SocketInfo> socket_infos;
386  socket_infos.push_back(
387      SocketInfo(SocketInfo::kConnectionStateEstablished,
388                 local_addr_,
389                 TrafficMonitorTest::kLocalPort1,
390                 remote_addr_,
391                 TrafficMonitorTest::kRemotePort,
392                 TrafficMonitorTest::kTxQueueLength2,
393                 0,
394                 SocketInfo::kTimerStateRetransmitTimerPending));
395  SetupMockSocketInfos(socket_infos);
396  monitor_.set_network_problem_detected_callback(
397      Bind(&TrafficMonitorTest::OnNoOutgoingPackets, Unretained(this)));
398  EXPECT_CALL(*this, OnNoOutgoingPackets(_)).Times(0);
399  monitor_.SampleTraffic();
400  Mock::VerifyAndClearExpectations(this);
401
402  socket_infos.clear();
403  socket_infos.push_back(
404      SocketInfo(SocketInfo::kConnectionStateEstablished,
405                 local_addr_,
406                 TrafficMonitorTest::kLocalPort1,
407                 remote_addr_,
408                 TrafficMonitorTest::kRemotePort,
409                 TrafficMonitorTest::kTxQueueLength1,
410                 0,
411                 SocketInfo::kTimerStateRetransmitTimerPending));
412  SetupMockSocketInfos(socket_infos);
413  EXPECT_CALL(*this, OnNoOutgoingPackets(_)).Times(0);
414  monitor_.SampleTraffic();
415  Mock::VerifyAndClearExpectations(this);
416
417  socket_infos.clear();
418  socket_infos.push_back(
419      SocketInfo(SocketInfo::kConnectionStateEstablished,
420                 local_addr_,
421                 TrafficMonitorTest::kLocalPort1,
422                 remote_addr_,
423                 TrafficMonitorTest::kRemotePort,
424                 TrafficMonitorTest::kTxQueueLength2,
425                 0,
426                 SocketInfo::kTimerStateRetransmitTimerPending));
427  SetupMockSocketInfos(socket_infos);
428  EXPECT_CALL(*this, OnNoOutgoingPackets(
429      TrafficMonitor::kNetworkProblemCongestedTxQueue));
430  monitor_.SampleTraffic();
431}
432
433TEST_F(TrafficMonitorTest, SampleTrafficUnstuckTxQueueZeroQueueLength) {
434  vector<SocketInfo> socket_infos;
435  socket_infos.push_back(
436      SocketInfo(SocketInfo::kConnectionStateEstablished,
437                 local_addr_,
438                 TrafficMonitorTest::kLocalPort1,
439                 remote_addr_,
440                 TrafficMonitorTest::kRemotePort,
441                 TrafficMonitorTest::kTxQueueLength1,
442                 0,
443                 SocketInfo::kTimerStateRetransmitTimerPending));
444  SetupMockSocketInfos(socket_infos);
445  monitor_.set_network_problem_detected_callback(
446      Bind(&TrafficMonitorTest::OnNoOutgoingPackets, Unretained(this)));
447  EXPECT_CALL(*this, OnNoOutgoingPackets(_)).Times(0);
448  monitor_.SampleTraffic();
449
450  socket_infos.clear();
451  socket_infos.push_back(
452      SocketInfo(SocketInfo::kConnectionStateEstablished,
453                 local_addr_,
454                 TrafficMonitorTest::kLocalPort1,
455                 remote_addr_,
456                 TrafficMonitorTest::kRemotePort,
457                 0,
458                 0,
459                 SocketInfo::kTimerStateRetransmitTimerPending));
460  SetupMockSocketInfos(socket_infos);
461  monitor_.SampleTraffic();
462  EXPECT_EQ(0, monitor_.accummulated_congested_tx_queues_samples_);
463}
464
465TEST_F(TrafficMonitorTest, SampleTrafficUnstuckTxQueueNoConnection) {
466  vector<SocketInfo> socket_infos;
467  socket_infos.push_back(
468      SocketInfo(SocketInfo::kConnectionStateEstablished,
469                 local_addr_,
470                 TrafficMonitorTest::kLocalPort1,
471                 remote_addr_,
472                 TrafficMonitorTest::kRemotePort,
473                 TrafficMonitorTest::kTxQueueLength1,
474                 0,
475                 SocketInfo::kTimerStateRetransmitTimerPending));
476  SetupMockSocketInfos(socket_infos);
477  monitor_.set_network_problem_detected_callback(
478      Bind(&TrafficMonitorTest::OnNoOutgoingPackets, Unretained(this)));
479  EXPECT_CALL(*this, OnNoOutgoingPackets(_)).Times(0);
480  monitor_.SampleTraffic();
481
482  socket_infos.clear();
483  SetupMockSocketInfos(socket_infos);
484  monitor_.SampleTraffic();
485  EXPECT_EQ(0, monitor_.accummulated_congested_tx_queues_samples_);
486}
487
488TEST_F(TrafficMonitorTest, SampleTrafficUnstuckTxQueueStateChanged) {
489  vector<SocketInfo> socket_infos;
490  socket_infos.push_back(
491      SocketInfo(SocketInfo::kConnectionStateEstablished,
492                 local_addr_,
493                 TrafficMonitorTest::kLocalPort1,
494                 remote_addr_,
495                 TrafficMonitorTest::kRemotePort,
496                 TrafficMonitorTest::kTxQueueLength1,
497                 0,
498                 SocketInfo::kTimerStateRetransmitTimerPending));
499  SetupMockSocketInfos(socket_infos);
500  monitor_.set_network_problem_detected_callback(
501      Bind(&TrafficMonitorTest::OnNoOutgoingPackets, Unretained(this)));
502  EXPECT_CALL(*this, OnNoOutgoingPackets(_)).Times(0);
503  monitor_.SampleTraffic();
504
505  socket_infos.clear();
506  socket_infos.push_back(
507      SocketInfo(SocketInfo::kConnectionStateClose,
508                 local_addr_,
509                 TrafficMonitorTest::kLocalPort1,
510                 remote_addr_,
511                 TrafficMonitorTest::kRemotePort,
512                 0,
513                 0,
514                 SocketInfo::kTimerStateNoTimerPending));
515  SetupMockSocketInfos(socket_infos);
516  monitor_.SampleTraffic();
517  EXPECT_EQ(0, monitor_.accummulated_congested_tx_queues_samples_);
518}
519
520TEST_F(TrafficMonitorTest, SampleTrafficDnsTimedOut) {
521  vector<ConnectionInfo> connection_infos;
522  connection_infos.push_back(
523    ConnectionInfo(IPPROTO_UDP,
524                   TrafficMonitor::kDnsTimedOutThresholdSeconds - 1,
525                   true, local_addr_, TrafficMonitorTest::kLocalPort1,
526                   remote_addr_, TrafficMonitor::kDnsPort,
527                   remote_addr_, TrafficMonitor::kDnsPort,
528                   local_addr_, TrafficMonitorTest::kLocalPort1));
529  SetupMockConnectionInfos(connection_infos);
530  monitor_.set_network_problem_detected_callback(
531      Bind(&TrafficMonitorTest::OnNoOutgoingPackets, Unretained(this)));
532  // Make sure the no routing event is not fired before the threshold is
533  // exceeded.
534  EXPECT_CALL(*this, OnNoOutgoingPackets(_)).Times(0);
535  for (int count = 1; count < TrafficMonitor::kMinimumFailedSamplesToTrigger;
536       ++count) {
537    monitor_.SampleTraffic();
538  }
539  Mock::VerifyAndClearExpectations(this);
540
541  // This call should cause the threshold to exceed.
542  EXPECT_CALL(*this, OnNoOutgoingPackets(
543      TrafficMonitor::kNetworkProblemDNSFailure)).Times(1);
544  monitor_.SampleTraffic();
545  Mock::VerifyAndClearExpectations(this);
546
547  // Make sure the event is only fired once.
548  EXPECT_CALL(*this, OnNoOutgoingPackets(_)).Times(0);
549  monitor_.SampleTraffic();
550}
551
552TEST_F(TrafficMonitorTest, SampleTrafficDnsOutstanding) {
553  vector<ConnectionInfo> connection_infos;
554  connection_infos.push_back(
555    ConnectionInfo(IPPROTO_UDP,
556                   TrafficMonitor::kDnsTimedOutThresholdSeconds + 1,
557                   true, local_addr_, TrafficMonitorTest::kLocalPort1,
558                   remote_addr_, TrafficMonitor::kDnsPort,
559                   remote_addr_, TrafficMonitor::kDnsPort,
560                   local_addr_, TrafficMonitorTest::kLocalPort1));
561  SetupMockConnectionInfos(connection_infos);
562  monitor_.set_network_problem_detected_callback(
563      Bind(&TrafficMonitorTest::OnNoOutgoingPackets, Unretained(this)));
564  EXPECT_CALL(*this, OnNoOutgoingPackets(_)).Times(0);
565  for (int count = 0; count < TrafficMonitor::kMinimumFailedSamplesToTrigger;
566       ++count) {
567    monitor_.SampleTraffic();
568  }
569}
570
571TEST_F(TrafficMonitorTest, SampleTrafficDnsSuccessful) {
572  vector<ConnectionInfo> connection_infos;
573  connection_infos.push_back(
574    ConnectionInfo(IPPROTO_UDP,
575                   TrafficMonitor::kDnsTimedOutThresholdSeconds - 1,
576                   false, local_addr_, TrafficMonitorTest::kLocalPort1,
577                   remote_addr_, TrafficMonitor::kDnsPort,
578                   remote_addr_, TrafficMonitor::kDnsPort,
579                   local_addr_, TrafficMonitorTest::kLocalPort1));
580  SetupMockConnectionInfos(connection_infos);
581  monitor_.set_network_problem_detected_callback(
582      Bind(&TrafficMonitorTest::OnNoOutgoingPackets, Unretained(this)));
583  EXPECT_CALL(*this, OnNoOutgoingPackets(_)).Times(0);
584  for (int count = 1; count < TrafficMonitor::kMinimumFailedSamplesToTrigger;
585       ++count) {
586    monitor_.SampleTraffic();
587  }
588}
589
590TEST_F(TrafficMonitorTest, SampleTrafficDnsFailureThenSuccess) {
591  vector<ConnectionInfo> connection_infos;
592  connection_infos.push_back(
593    ConnectionInfo(IPPROTO_UDP,
594                   TrafficMonitor::kDnsTimedOutThresholdSeconds - 1,
595                   true, local_addr_, TrafficMonitorTest::kLocalPort1,
596                   remote_addr_, TrafficMonitor::kDnsPort,
597                   remote_addr_, TrafficMonitor::kDnsPort,
598                   local_addr_, TrafficMonitorTest::kLocalPort1));
599  SetupMockConnectionInfos(connection_infos);
600  monitor_.set_network_problem_detected_callback(
601      Bind(&TrafficMonitorTest::OnNoOutgoingPackets, Unretained(this)));
602  EXPECT_CALL(*this, OnNoOutgoingPackets(_)).Times(0);
603  for (int count = 1; count < TrafficMonitor::kMinimumFailedSamplesToTrigger;
604       ++count) {
605    monitor_.SampleTraffic();
606  }
607  Mock::VerifyAndClearExpectations(this);
608
609  connection_infos.clear();
610  connection_infos.push_back(
611    ConnectionInfo(IPPROTO_UDP,
612                   TrafficMonitor::kDnsTimedOutThresholdSeconds - 1,
613                   false, local_addr_, TrafficMonitorTest::kLocalPort1,
614                   remote_addr_, TrafficMonitor::kDnsPort,
615                   remote_addr_, TrafficMonitor::kDnsPort,
616                   local_addr_, TrafficMonitorTest::kLocalPort1));
617  SetupMockConnectionInfos(connection_infos);
618  EXPECT_CALL(*this, OnNoOutgoingPackets(_)).Times(0);
619  monitor_.SampleTraffic();
620  EXPECT_EQ(0, monitor_.accummulated_dns_failures_samples_);
621}
622
623TEST_F(TrafficMonitorTest, SampleTrafficDnsTimedOutInvalidProtocol) {
624  vector<ConnectionInfo> connection_infos;
625  connection_infos.push_back(
626    ConnectionInfo(IPPROTO_TCP,
627                   TrafficMonitor::kDnsTimedOutThresholdSeconds - 1,
628                   true, local_addr_, TrafficMonitorTest::kLocalPort1,
629                   remote_addr_, TrafficMonitor::kDnsPort,
630                   remote_addr_, TrafficMonitor::kDnsPort,
631                   local_addr_, TrafficMonitorTest::kLocalPort1));
632  SetupMockConnectionInfos(connection_infos);
633  monitor_.set_network_problem_detected_callback(
634      Bind(&TrafficMonitorTest::OnNoOutgoingPackets, Unretained(this)));
635  EXPECT_CALL(*this, OnNoOutgoingPackets(_)).Times(0);
636  for (int count = 0; count < TrafficMonitor::kMinimumFailedSamplesToTrigger;
637       ++count) {
638    monitor_.SampleTraffic();
639  }
640}
641
642TEST_F(TrafficMonitorTest, SampleTrafficDnsTimedOutInvalidSourceIp) {
643  vector<ConnectionInfo> connection_infos;
644  connection_infos.push_back(
645    ConnectionInfo(IPPROTO_UDP,
646                   TrafficMonitor::kDnsTimedOutThresholdSeconds - 1,
647                   true, remote_addr_, TrafficMonitorTest::kLocalPort1,
648                   remote_addr_, TrafficMonitor::kDnsPort,
649                   remote_addr_, TrafficMonitor::kDnsPort,
650                   remote_addr_, TrafficMonitorTest::kLocalPort1));
651  SetupMockConnectionInfos(connection_infos);
652  monitor_.set_network_problem_detected_callback(
653      Bind(&TrafficMonitorTest::OnNoOutgoingPackets, Unretained(this)));
654  EXPECT_CALL(*this, OnNoOutgoingPackets(_)).Times(0);
655  for (int count = 0; count < TrafficMonitor::kMinimumFailedSamplesToTrigger;
656       ++count) {
657    monitor_.SampleTraffic();
658  }
659}
660
661TEST_F(TrafficMonitorTest, SampleTrafficDnsTimedOutOutsideTimeWindow) {
662  vector<ConnectionInfo> connection_infos;
663  connection_infos.push_back(
664    ConnectionInfo(IPPROTO_UDP,
665                   TrafficMonitor::kDnsTimedOutThresholdSeconds -
666                   TrafficMonitor::kSamplingIntervalMilliseconds / 1000,
667                   true, remote_addr_, TrafficMonitorTest::kLocalPort1,
668                   remote_addr_, TrafficMonitor::kDnsPort,
669                   remote_addr_, TrafficMonitor::kDnsPort,
670                   remote_addr_, TrafficMonitorTest::kLocalPort1));
671  SetupMockConnectionInfos(connection_infos);
672  monitor_.set_network_problem_detected_callback(
673      Bind(&TrafficMonitorTest::OnNoOutgoingPackets, Unretained(this)));
674  EXPECT_CALL(*this, OnNoOutgoingPackets(_)).Times(0);
675  for (int count = 0; count < TrafficMonitor::kMinimumFailedSamplesToTrigger;
676       ++count) {
677    monitor_.SampleTraffic();
678  }
679}
680
681TEST_F(TrafficMonitorTest, SampleTrafficNonDnsTimedOut) {
682  const uint16_t kNonDnsPort = 54;
683  vector<ConnectionInfo> connection_infos;
684  connection_infos.push_back(
685    ConnectionInfo(IPPROTO_UDP,
686                   TrafficMonitor::kDnsTimedOutThresholdSeconds - 1,
687                   true, local_addr_, TrafficMonitorTest::kLocalPort1,
688                   remote_addr_, kNonDnsPort,
689                   remote_addr_, kNonDnsPort,
690                   local_addr_, TrafficMonitorTest::kLocalPort1));
691  SetupMockConnectionInfos(connection_infos);
692  monitor_.set_network_problem_detected_callback(
693      Bind(&TrafficMonitorTest::OnNoOutgoingPackets, Unretained(this)));
694  EXPECT_CALL(*this, OnNoOutgoingPackets(_)).Times(0);
695  for (int count = 0; count < TrafficMonitor::kMinimumFailedSamplesToTrigger;
696       ++count) {
697    monitor_.SampleTraffic();
698  }
699}
700
701TEST_F(TrafficMonitorTest, SampleTrafficDnsStatsReset) {
702  vector<ConnectionInfo> connection_infos;
703  SetupMockConnectionInfos(connection_infos);
704  monitor_.accummulated_dns_failures_samples_ = 1;
705  monitor_.SampleTraffic();
706  EXPECT_EQ(0, monitor_.accummulated_dns_failures_samples_);
707}
708
709}  // namespace shill
710