blob: 3132720518d38750b38a171cccf5bfc4c7ab064c [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>
8#include <gtest/gtest.h>
9
10#include "shill/mock_device.h"
11#include "shill/mock_event_dispatcher.h"
12#include "shill/nice_mock_control.h"
13
14using testing::NiceMock;
15using testing::Return;
16using testing::Test;
17
18namespace shill {
19
20class CallbackChecker {
21 public:
22 CallbackChecker() : invocation_count_(0) {}
23 ~CallbackChecker() {}
24 void InvokeCallback() { ++invocation_count_; }
25 int invocation_count() const { return invocation_count_; }
26
27 private:
28 int invocation_count_;
29
30 DISALLOW_COPY_AND_ASSIGN(CallbackChecker);
31};
32
33class TrafficMonitorTest : public Test {
34 public:
35 TrafficMonitorTest()
36 : device_(new MockDevice(&control_,
37 &dispatcher_,
38 reinterpret_cast<Metrics *>(NULL),
39 reinterpret_cast<Manager *>(NULL),
40 "netdev0",
41 "00:11:22:33:44:55",
42 1)),
43 monitor_(device_, &dispatcher_) {
44 }
45
46 protected:
47 void ExpectStopped() {
48 EXPECT_EQ(0, monitor_.last_receive_byte_count_);
49 EXPECT_EQ(0, monitor_.last_transmit_byte_count_);
50 EXPECT_EQ(0, monitor_.no_traffic_count_);
51 EXPECT_EQ(0, monitor_.no_incoming_traffic_count_);
52 EXPECT_FALSE(monitor_.no_incoming_traffic_callback_invoked_);
53 }
54
55 NiceMockControl control_;
56 NiceMock<MockEventDispatcher> dispatcher_;
57 scoped_refptr<MockDevice> device_;
58 TrafficMonitor monitor_;
59};
60
61TEST_F(TrafficMonitorTest, StartAndStop) {
62 monitor_.Stop(); // Stop without start
63 ExpectStopped();
64
65 EXPECT_CALL(*device_, GetReceiveByteCount()).WillOnce(Return(100));
66 EXPECT_CALL(*device_, GetTransmitByteCount()).WillOnce(Return(200));
67 monitor_.Start();
68 EXPECT_EQ(100, monitor_.last_receive_byte_count_);
69 EXPECT_EQ(200, monitor_.last_transmit_byte_count_);
70 EXPECT_EQ(0, monitor_.no_traffic_count_);
71 EXPECT_EQ(0, monitor_.no_incoming_traffic_count_);
72 EXPECT_FALSE(monitor_.no_incoming_traffic_callback_invoked_);
73
74 monitor_.Stop(); // Stop after start
75 ExpectStopped();
76
77 monitor_.Stop(); // Stop again without start
78 ExpectStopped();
79}
80
81TEST_F(TrafficMonitorTest, SampleTraffic) {
82 const struct {
83 uint64 receive_byte_count;
84 uint64 transmit_byte_count;
85 int expected_no_traffic_count;
86 int expected_no_incoming_traffic_count;
87 int expected_callback_invocation_count;
88 bool expected_no_incoming_traffic_callback_invoked;
89 } kTestVector[] = {
90 { 1, 1, 0, 0, 0, false }, // Initial condition
91 { 1, 2, 0, 1, 0, false }, // No incoming traffic
92 { 2, 3, 0, 0, 0, false }, // Reset detection due to incoming traffic
93 { 2, 4, 0, 1, 0, false }, // No incoming traffic
94 { 2, 4, 1, 1, 0, false }, // No traffic
95 { 2, 5, 0, 2, 1, true }, // Invoke "no incoming traffic" callback
96 { 2, 6, 0, 3, 1, true }, // Do not invoke callback again
97 { 3, 7, 0, 0, 1, false }, // Reset detection due to incoming traffic
98 { 3, 8, 0, 1, 1, false }, // No incoming traffic
99 { 3, 9, 0, 2, 2, true }, // Invoke "no incoming traffic" callback
100 { 3, 9, 1, 2, 2, true }, // No traffic
101 { 3, 9, 2, 2, 2, true },
102 { 3, 9, 3, 2, 2, true },
103 { 3, 9, 4, 2, 2, true },
104 { 3, 9, 5, 2, 2, true },
105 { 3, 9, 6, 2, 2, true },
106 { 3, 9, 7, 2, 2, true },
107 { 3, 9, 8, 2, 2, true },
108 { 3, 9, 1, 0, 2, false }, // Reset detection due to no traffic
109 { 3, 9, 2, 0, 2, false },
110 { 3, 9, 3, 0, 2, false },
111 { 3, 9, 4, 0, 2, false },
112 { 3, 9, 5, 0, 2, false },
113 { 3, 9, 6, 0, 2, false },
114 { 3, 9, 7, 0, 2, false },
115 { 3, 9, 8, 0, 2, false },
116 { 4, 9, 0, 0, 2, false }, // Reset detection due to incoming traffic
117 { 4, 9, 1, 0, 2, false },
118 { 4, 9, 2, 0, 2, false },
119 { 4, 9, 3, 0, 2, false },
120 { 4, 9, 4, 0, 2, false },
121 { 4, 9, 5, 0, 2, false },
122 { 4, 9, 6, 0, 2, false },
123 { 4, 9, 7, 0, 2, false },
124 { 4, 9, 8, 0, 2, false },
125 { 4, 10, 0, 1, 2, false }, // Only outgoing traffic
126 };
127
128 CallbackChecker callback_checker;
129 monitor_.set_no_incoming_traffic_callback(
130 base::Bind(&CallbackChecker::InvokeCallback,
131 base::Unretained(&callback_checker)));
132
133 ExpectStopped();
134 EXPECT_FALSE(monitor_.no_incoming_traffic_callback_invoked_);
135
136 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kTestVector); ++i) {
137 EXPECT_CALL(*device_, GetReceiveByteCount())
138 .WillOnce(Return(kTestVector[i].receive_byte_count));
139 EXPECT_CALL(*device_, GetTransmitByteCount())
140 .WillOnce(Return(kTestVector[i].transmit_byte_count));
141
142 if (i == 0)
143 monitor_.Start();
144 else
145 monitor_.SampleTraffic();
146
147 EXPECT_EQ(kTestVector[i].receive_byte_count,
148 monitor_.last_receive_byte_count_);
149 EXPECT_EQ(kTestVector[i].transmit_byte_count,
150 monitor_.last_transmit_byte_count_);
151 EXPECT_EQ(kTestVector[i].expected_no_traffic_count,
152 monitor_.no_traffic_count_);
153 EXPECT_EQ(kTestVector[i].expected_no_incoming_traffic_count,
154 monitor_.no_incoming_traffic_count_);
155 EXPECT_EQ(kTestVector[i].expected_callback_invocation_count,
156 callback_checker.invocation_count());
157 EXPECT_EQ(kTestVector[i].expected_no_incoming_traffic_callback_invoked,
158 monitor_.no_incoming_traffic_callback_invoked_);
159 }
160}
161
162} // namespace shill