blob: 3132720518d38750b38a171cccf5bfc4c7ab064c [file] [log] [blame]
// Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "shill/traffic_monitor.h"
#include <base/bind.h>
#include <gtest/gtest.h>
#include "shill/mock_device.h"
#include "shill/mock_event_dispatcher.h"
#include "shill/nice_mock_control.h"
using testing::NiceMock;
using testing::Return;
using testing::Test;
namespace shill {
class CallbackChecker {
public:
CallbackChecker() : invocation_count_(0) {}
~CallbackChecker() {}
void InvokeCallback() { ++invocation_count_; }
int invocation_count() const { return invocation_count_; }
private:
int invocation_count_;
DISALLOW_COPY_AND_ASSIGN(CallbackChecker);
};
class TrafficMonitorTest : public Test {
public:
TrafficMonitorTest()
: device_(new MockDevice(&control_,
&dispatcher_,
reinterpret_cast<Metrics *>(NULL),
reinterpret_cast<Manager *>(NULL),
"netdev0",
"00:11:22:33:44:55",
1)),
monitor_(device_, &dispatcher_) {
}
protected:
void ExpectStopped() {
EXPECT_EQ(0, monitor_.last_receive_byte_count_);
EXPECT_EQ(0, monitor_.last_transmit_byte_count_);
EXPECT_EQ(0, monitor_.no_traffic_count_);
EXPECT_EQ(0, monitor_.no_incoming_traffic_count_);
EXPECT_FALSE(monitor_.no_incoming_traffic_callback_invoked_);
}
NiceMockControl control_;
NiceMock<MockEventDispatcher> dispatcher_;
scoped_refptr<MockDevice> device_;
TrafficMonitor monitor_;
};
TEST_F(TrafficMonitorTest, StartAndStop) {
monitor_.Stop(); // Stop without start
ExpectStopped();
EXPECT_CALL(*device_, GetReceiveByteCount()).WillOnce(Return(100));
EXPECT_CALL(*device_, GetTransmitByteCount()).WillOnce(Return(200));
monitor_.Start();
EXPECT_EQ(100, monitor_.last_receive_byte_count_);
EXPECT_EQ(200, monitor_.last_transmit_byte_count_);
EXPECT_EQ(0, monitor_.no_traffic_count_);
EXPECT_EQ(0, monitor_.no_incoming_traffic_count_);
EXPECT_FALSE(monitor_.no_incoming_traffic_callback_invoked_);
monitor_.Stop(); // Stop after start
ExpectStopped();
monitor_.Stop(); // Stop again without start
ExpectStopped();
}
TEST_F(TrafficMonitorTest, SampleTraffic) {
const struct {
uint64 receive_byte_count;
uint64 transmit_byte_count;
int expected_no_traffic_count;
int expected_no_incoming_traffic_count;
int expected_callback_invocation_count;
bool expected_no_incoming_traffic_callback_invoked;
} kTestVector[] = {
{ 1, 1, 0, 0, 0, false }, // Initial condition
{ 1, 2, 0, 1, 0, false }, // No incoming traffic
{ 2, 3, 0, 0, 0, false }, // Reset detection due to incoming traffic
{ 2, 4, 0, 1, 0, false }, // No incoming traffic
{ 2, 4, 1, 1, 0, false }, // No traffic
{ 2, 5, 0, 2, 1, true }, // Invoke "no incoming traffic" callback
{ 2, 6, 0, 3, 1, true }, // Do not invoke callback again
{ 3, 7, 0, 0, 1, false }, // Reset detection due to incoming traffic
{ 3, 8, 0, 1, 1, false }, // No incoming traffic
{ 3, 9, 0, 2, 2, true }, // Invoke "no incoming traffic" callback
{ 3, 9, 1, 2, 2, true }, // No traffic
{ 3, 9, 2, 2, 2, true },
{ 3, 9, 3, 2, 2, true },
{ 3, 9, 4, 2, 2, true },
{ 3, 9, 5, 2, 2, true },
{ 3, 9, 6, 2, 2, true },
{ 3, 9, 7, 2, 2, true },
{ 3, 9, 8, 2, 2, true },
{ 3, 9, 1, 0, 2, false }, // Reset detection due to no traffic
{ 3, 9, 2, 0, 2, false },
{ 3, 9, 3, 0, 2, false },
{ 3, 9, 4, 0, 2, false },
{ 3, 9, 5, 0, 2, false },
{ 3, 9, 6, 0, 2, false },
{ 3, 9, 7, 0, 2, false },
{ 3, 9, 8, 0, 2, false },
{ 4, 9, 0, 0, 2, false }, // Reset detection due to incoming traffic
{ 4, 9, 1, 0, 2, false },
{ 4, 9, 2, 0, 2, false },
{ 4, 9, 3, 0, 2, false },
{ 4, 9, 4, 0, 2, false },
{ 4, 9, 5, 0, 2, false },
{ 4, 9, 6, 0, 2, false },
{ 4, 9, 7, 0, 2, false },
{ 4, 9, 8, 0, 2, false },
{ 4, 10, 0, 1, 2, false }, // Only outgoing traffic
};
CallbackChecker callback_checker;
monitor_.set_no_incoming_traffic_callback(
base::Bind(&CallbackChecker::InvokeCallback,
base::Unretained(&callback_checker)));
ExpectStopped();
EXPECT_FALSE(monitor_.no_incoming_traffic_callback_invoked_);
for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kTestVector); ++i) {
EXPECT_CALL(*device_, GetReceiveByteCount())
.WillOnce(Return(kTestVector[i].receive_byte_count));
EXPECT_CALL(*device_, GetTransmitByteCount())
.WillOnce(Return(kTestVector[i].transmit_byte_count));
if (i == 0)
monitor_.Start();
else
monitor_.SampleTraffic();
EXPECT_EQ(kTestVector[i].receive_byte_count,
monitor_.last_receive_byte_count_);
EXPECT_EQ(kTestVector[i].transmit_byte_count,
monitor_.last_transmit_byte_count_);
EXPECT_EQ(kTestVector[i].expected_no_traffic_count,
monitor_.no_traffic_count_);
EXPECT_EQ(kTestVector[i].expected_no_incoming_traffic_count,
monitor_.no_incoming_traffic_count_);
EXPECT_EQ(kTestVector[i].expected_callback_invocation_count,
callback_checker.invocation_count());
EXPECT_EQ(kTestVector[i].expected_no_incoming_traffic_callback_invoked,
monitor_.no_incoming_traffic_callback_invoked_);
}
}
} // namespace shill