blob: bac4b8cb314ce7c7e79b056e1d5be8df6760d4b5 [file] [log] [blame]
// Copyright (c) 2011 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/device_info.h"
#include <glib.h>
#include <sys/socket.h>
#include <linux/if.h>
#include <linux/netlink.h> // Needs typedefs from sys/socket.h.
#include <linux/rtnetlink.h>
#include <base/callback_old.h>
#include <base/logging.h>
#include <base/memory/ref_counted.h>
#include <base/message_loop.h>
#include <base/stl_util-inl.h>
#include <gtest/gtest.h>
#include <gmock/gmock.h>
#include "shill/manager.h"
#include "shill/mock_control.h"
#include "shill/mock_glib.h"
#include "shill/mock_manager.h"
#include "shill/mock_sockets.h"
#include "shill/rtnl_handler.h"
#include "shill/rtnl_message.h"
using std::map;
using std::string;
using testing::_;
using testing::Return;
using testing::Test;
namespace shill {
class TestEventDispatcher : public EventDispatcher {
public:
virtual IOInputHandler *CreateInputHandler(
int fd,
Callback1<InputData*>::Type *callback) {
return NULL;
}
};
class DeviceInfoTest : public Test {
public:
DeviceInfoTest()
: manager_(&control_interface_, &dispatcher_, &glib_),
device_info_(&control_interface_, &dispatcher_, &manager_) {
}
protected:
static const int kTestDeviceIndex;
static const char kTestDeviceName[];
static const char kTestAddress[];
RTNLMessage *BuildMessage(RTNLMessage::MessageType type,
RTNLMessage::MessageMode mode);
void SendMessageToDeviceInfo(const RTNLMessage &message);
MockGLib glib_;
MockControl control_interface_;
MockManager manager_;
DeviceInfo device_info_;
TestEventDispatcher dispatcher_;
};
const int DeviceInfoTest::kTestDeviceIndex = 123456;
const char DeviceInfoTest::kTestDeviceName[] = "test-device";
const char DeviceInfoTest::kTestAddress[] = {
0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff };
RTNLMessage *DeviceInfoTest::BuildMessage(RTNLMessage::MessageType type,
RTNLMessage::MessageMode mode) {
RTNLMessage *message = new RTNLMessage(type, mode, 0, 0, 0, kTestDeviceIndex,
IPAddress::kAddressFamilyIPv4);
message->SetAttribute(static_cast<uint16>(IFLA_IFNAME),
ByteString(kTestDeviceName, true));
ByteString test_address(kTestAddress, sizeof(kTestAddress));
message->SetAttribute(IFLA_ADDRESS, test_address);
return message;
}
void DeviceInfoTest::SendMessageToDeviceInfo(const RTNLMessage &message) {
device_info_.LinkMsgHandler(message);
}
TEST_F(DeviceInfoTest, DeviceEnumeration) {
// Start our own private device_info
device_info_.Start();
scoped_ptr<RTNLMessage> message(BuildMessage(RTNLMessage::kMessageTypeLink,
RTNLMessage::kMessageModeAdd));
message->set_link_status(RTNLMessage::LinkStatus(0, IFF_LOWER_UP, 0));
EXPECT_FALSE(device_info_.GetDevice(kTestDeviceIndex).get());
SendMessageToDeviceInfo(*message);
EXPECT_TRUE(device_info_.GetDevice(kTestDeviceIndex).get());
unsigned int flags = 0;
EXPECT_TRUE(device_info_.GetFlags(kTestDeviceIndex, &flags));
EXPECT_EQ(IFF_LOWER_UP, flags);
ByteString address;
EXPECT_TRUE(device_info_.GetAddress(kTestDeviceIndex, &address));
EXPECT_FALSE(address.IsEmpty());
EXPECT_TRUE(address.Equals(ByteString(kTestAddress, sizeof(kTestAddress))));
message.reset(BuildMessage(RTNLMessage::kMessageTypeLink,
RTNLMessage::kMessageModeAdd));
message->set_link_status(RTNLMessage::LinkStatus(0, IFF_UP | IFF_RUNNING, 0));
SendMessageToDeviceInfo(*message);
EXPECT_TRUE(device_info_.GetFlags(kTestDeviceIndex, &flags));
EXPECT_EQ(IFF_UP | IFF_RUNNING, flags);
message.reset(BuildMessage(RTNLMessage::kMessageTypeLink,
RTNLMessage::kMessageModeDelete));
SendMessageToDeviceInfo(*message);
EXPECT_FALSE(device_info_.GetDevice(kTestDeviceIndex).get());
EXPECT_FALSE(device_info_.GetFlags(kTestDeviceIndex, NULL));
device_info_.Stop();
}
TEST_F(DeviceInfoTest, DeviceBlackList) {
device_info_.AddDeviceToBlackList(kTestDeviceName);
device_info_.Start();
scoped_ptr<RTNLMessage> message(BuildMessage(RTNLMessage::kMessageTypeLink,
RTNLMessage::kMessageModeAdd));
SendMessageToDeviceInfo(*message);
DeviceRefPtr device = device_info_.GetDevice(kTestDeviceIndex);
ASSERT_TRUE(device.get());
EXPECT_TRUE(device->TechnologyIs(Device::kBlacklisted));
device_info_.Stop();
}
} // namespace shill