blob: 4f9b994aa9d0a8b84ac389376f9c3f08e99a45cc [file] [log] [blame]
Wade Guthrie0d438532012-05-18 14:18:50 -07001// Copyright (c) 2012 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// This file provides tests for individual messages. It tests
Wade Guthrief48a1952013-03-04 17:33:47 -08006// NetlinkMessageFactory's ability to create specific message types and it
7// tests the various NetlinkMessage types' ability to parse those
Wade Guthrie0d438532012-05-18 14:18:50 -07008// messages.
9
Wade Guthriebb9fca22013-04-10 17:21:42 -070010// This file tests the public interface to NetlinkManager.
Wade Guthriebb9fca22013-04-10 17:21:42 -070011#include "shill/netlink_manager.h"
Wade Guthrie0d438532012-05-18 14:18:50 -070012
13#include <gmock/gmock.h>
14#include <gtest/gtest.h>
Wade Guthrie0d438532012-05-18 14:18:50 -070015
Wade Guthriecc53f232013-03-05 13:22:23 -080016#include "shill/mock_netlink_socket.h"
repo syncdc085c82012-12-28 08:54:41 -080017#include "shill/nl80211_message.h"
Wade Guthrie0d438532012-05-18 14:18:50 -070018
19using base::Bind;
20using base::Unretained;
Wade Guthrie0d438532012-05-18 14:18:50 -070021using testing::_;
Wade Guthrie5d3d6de2012-11-02 11:08:34 -070022using testing::Invoke;
Wade Guthrie0d438532012-05-18 14:18:50 -070023using testing::Return;
24using testing::Test;
25
26namespace shill {
27
28namespace {
29
Wade Guthriebb9fca22013-04-10 17:21:42 -070030// These data blocks have been collected by shill using NetlinkManager while,
Wade Guthrie0d438532012-05-18 14:18:50 -070031// simultaneously (and manually) comparing shill output with that of the 'iw'
32// code from which it was derived. The test strings represent the raw packet
33// data coming from the kernel. The comments above each of these strings is
34// the markup that "iw" outputs for ech of these packets.
35
36// These constants are consistent throughout the packets, below.
37
Wade Guthriebdcdaa72013-03-04 12:47:12 -080038const uint16_t kNl80211FamilyId = 0x13;
Wade Guthrie0d438532012-05-18 14:18:50 -070039
40// wlan0 (phy #0): disconnected (by AP) reason: 2: Previous authentication no
41// longer valid
42
Wade Guthrie0d438532012-05-18 14:18:50 -070043const unsigned char kNL80211_CMD_DISCONNECT[] = {
44 0x30, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00,
45 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
46 0x30, 0x01, 0x00, 0x00, 0x08, 0x00, 0x01, 0x00,
47 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x03, 0x00,
48 0x04, 0x00, 0x00, 0x00, 0x06, 0x00, 0x36, 0x00,
49 0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x47, 0x00,
50};
51
repo syncdc085c82012-12-28 08:54:41 -080052const char kGetFamilyCommandString[] = "CTRL_CMD_GETFAMILY";
53
Wade Guthrieb1ec8602012-10-18 17:26:14 -070054} // namespace
repo syncdc085c82012-12-28 08:54:41 -080055
Wade Guthriecc53f232013-03-05 13:22:23 -080056bool MockNetlinkSocket::SendMessage(const ByteString &out_string) {
repo syncdc085c82012-12-28 08:54:41 -080057 return true;
58}
59
Wade Guthriebb9fca22013-04-10 17:21:42 -070060class NetlinkManagerTest : public Test {
Wade Guthrie0d438532012-05-18 14:18:50 -070061 public:
Wade Guthriebb9fca22013-04-10 17:21:42 -070062 NetlinkManagerTest() : netlink_manager_(NetlinkManager::GetInstance()) {
63 netlink_manager_->message_types_[Nl80211Message::kMessageTypeString]
64 .family_id = kNl80211FamilyId;
65 netlink_manager_->message_factory_.AddFactoryMethod(
Wade Guthrie12f113a2013-03-12 17:15:46 -070066 kNl80211FamilyId, Bind(&Nl80211Message::CreateMessage));
Wade Guthriebee87c22013-03-06 11:00:46 -080067 Nl80211Message::SetMessageType(
Wade Guthriebb9fca22013-04-10 17:21:42 -070068 netlink_manager_->GetMessageType(Nl80211Message::kMessageTypeString));
Wade Guthriebee87c22013-03-06 11:00:46 -080069 }
Wade Guthriec6c81962013-03-06 15:47:13 -080070
Wade Guthriebb9fca22013-04-10 17:21:42 -070071 ~NetlinkManagerTest() {
72 // NetlinkManager is a singleton, the sock_ field *MUST* be cleared
73 // before "NetlinkManagerTest::socket_" gets invalidated, otherwise
Han Shen4afba202012-12-17 08:48:35 -080074 // later tests will refer to a corrupted memory.
Wade Guthriebb9fca22013-04-10 17:21:42 -070075 netlink_manager_->sock_ = NULL;
Han Shen4afba202012-12-17 08:48:35 -080076 }
Wade Guthriec6c81962013-03-06 15:47:13 -080077
Wade Guthriebb9fca22013-04-10 17:21:42 -070078 void SetupNetlinkManagerObject() {
79 EXPECT_NE(reinterpret_cast<NetlinkManager *>(NULL), netlink_manager_);
80 netlink_manager_->sock_ = &socket_;
81 EXPECT_TRUE(netlink_manager_->Init());
Wade Guthrie0d438532012-05-18 14:18:50 -070082 }
83
Wade Guthriec6c81962013-03-06 15:47:13 -080084 protected:
85 class MockHandler80211 {
86 public:
87 MockHandler80211() :
88 on_netlink_message_(base::Bind(&MockHandler80211::OnNetlinkMessage,
89 base::Unretained(this))) {}
90 MOCK_METHOD1(OnNetlinkMessage, void(const NetlinkMessage &msg));
Wade Guthriebb9fca22013-04-10 17:21:42 -070091 const NetlinkManager::NetlinkMessageHandler &on_netlink_message() const {
Wade Guthriec6c81962013-03-06 15:47:13 -080092 return on_netlink_message_;
93 }
94 private:
Wade Guthriebb9fca22013-04-10 17:21:42 -070095 NetlinkManager::NetlinkMessageHandler on_netlink_message_;
Wade Guthriec6c81962013-03-06 15:47:13 -080096 DISALLOW_COPY_AND_ASSIGN(MockHandler80211);
97 };
98
Wade Guthriebb9fca22013-04-10 17:21:42 -070099 NetlinkManager *netlink_manager_;
Wade Guthriecc53f232013-03-05 13:22:23 -0800100 MockNetlinkSocket socket_;
Wade Guthrie0d438532012-05-18 14:18:50 -0700101};
102
Wade Guthriebee87c22013-03-06 11:00:46 -0800103// TODO(wdg): Add a test for multi-part messages. crbug.com/224652
104// TODO(wdg): Add a test for GetFaimily. crbug.com/224649
105// TODO(wdg): Add a test for OnNewFamilyMessage. crbug.com/222486
Wade Guthrie12f113a2013-03-12 17:15:46 -0700106// TODO(wdg): Add a test for GetMessageType
Wade Guthriebee87c22013-03-06 11:00:46 -0800107// TODO(wdg): Add a test for SubscribeToEvents (verify that it handles bad input
108// appropriately, and that it calls NetlinkSocket::SubscribeToEvents if input
109// is good.)
110
Wade Guthriebb9fca22013-04-10 17:21:42 -0700111TEST_F(NetlinkManagerTest, BroadcastHandlerTest) {
112 SetupNetlinkManagerObject();
Wade Guthrie5d3d6de2012-11-02 11:08:34 -0700113
114 nlmsghdr *message = const_cast<nlmsghdr *>(
115 reinterpret_cast<const nlmsghdr *>(kNL80211_CMD_DISCONNECT));
116
Wade Guthrie71cb0a72013-02-27 10:27:18 -0800117 MockHandler80211 handler1;
118 MockHandler80211 handler2;
Wade Guthrie5d3d6de2012-11-02 11:08:34 -0700119
Wade Guthrie71cb0a72013-02-27 10:27:18 -0800120 // Simple, 1 handler, case.
Wade Guthriec6c81962013-03-06 15:47:13 -0800121 EXPECT_CALL(handler1, OnNetlinkMessage(_)).Times(1);
Wade Guthrie12f113a2013-03-12 17:15:46 -0700122 EXPECT_FALSE(
Wade Guthriebb9fca22013-04-10 17:21:42 -0700123 netlink_manager_->FindBroadcastHandler(handler1.on_netlink_message()));
124 netlink_manager_->AddBroadcastHandler(handler1.on_netlink_message());
Wade Guthrie12f113a2013-03-12 17:15:46 -0700125 EXPECT_TRUE(
Wade Guthriebb9fca22013-04-10 17:21:42 -0700126 netlink_manager_->FindBroadcastHandler(handler1.on_netlink_message()));
127 netlink_manager_->OnNlMessageReceived(message);
Wade Guthrie5d3d6de2012-11-02 11:08:34 -0700128
Wade Guthrie71cb0a72013-02-27 10:27:18 -0800129 // Add a second handler.
Wade Guthriec6c81962013-03-06 15:47:13 -0800130 EXPECT_CALL(handler1, OnNetlinkMessage(_)).Times(1);
131 EXPECT_CALL(handler2, OnNetlinkMessage(_)).Times(1);
Wade Guthriebb9fca22013-04-10 17:21:42 -0700132 netlink_manager_->AddBroadcastHandler(handler2.on_netlink_message());
133 netlink_manager_->OnNlMessageReceived(message);
Wade Guthrie5d3d6de2012-11-02 11:08:34 -0700134
Wade Guthrie71cb0a72013-02-27 10:27:18 -0800135 // Verify that a handler can't be added twice.
Wade Guthriec6c81962013-03-06 15:47:13 -0800136 EXPECT_CALL(handler1, OnNetlinkMessage(_)).Times(1);
137 EXPECT_CALL(handler2, OnNetlinkMessage(_)).Times(1);
Wade Guthriebb9fca22013-04-10 17:21:42 -0700138 netlink_manager_->AddBroadcastHandler(handler1.on_netlink_message());
139 netlink_manager_->OnNlMessageReceived(message);
Wade Guthrie5d3d6de2012-11-02 11:08:34 -0700140
Wade Guthrie71cb0a72013-02-27 10:27:18 -0800141 // Check that we can remove a handler.
Wade Guthriec6c81962013-03-06 15:47:13 -0800142 EXPECT_CALL(handler1, OnNetlinkMessage(_)).Times(0);
143 EXPECT_CALL(handler2, OnNetlinkMessage(_)).Times(1);
Wade Guthriebb9fca22013-04-10 17:21:42 -0700144 EXPECT_TRUE(netlink_manager_->RemoveBroadcastHandler(
Wade Guthriec6c81962013-03-06 15:47:13 -0800145 handler1.on_netlink_message()));
Wade Guthriebb9fca22013-04-10 17:21:42 -0700146 netlink_manager_->OnNlMessageReceived(message);
Wade Guthrie5d3d6de2012-11-02 11:08:34 -0700147
Wade Guthrie71cb0a72013-02-27 10:27:18 -0800148 // Check that re-adding the handler goes smoothly.
Wade Guthriec6c81962013-03-06 15:47:13 -0800149 EXPECT_CALL(handler1, OnNetlinkMessage(_)).Times(1);
150 EXPECT_CALL(handler2, OnNetlinkMessage(_)).Times(1);
Wade Guthriebb9fca22013-04-10 17:21:42 -0700151 netlink_manager_->AddBroadcastHandler(handler1.on_netlink_message());
152 netlink_manager_->OnNlMessageReceived(message);
Wade Guthrie5d3d6de2012-11-02 11:08:34 -0700153
Wade Guthrie71cb0a72013-02-27 10:27:18 -0800154 // Check that ClearBroadcastHandlers works.
Wade Guthriebb9fca22013-04-10 17:21:42 -0700155 netlink_manager_->ClearBroadcastHandlers();
Wade Guthriec6c81962013-03-06 15:47:13 -0800156 EXPECT_CALL(handler1, OnNetlinkMessage(_)).Times(0);
157 EXPECT_CALL(handler2, OnNetlinkMessage(_)).Times(0);
Wade Guthriebb9fca22013-04-10 17:21:42 -0700158 netlink_manager_->OnNlMessageReceived(message);
Wade Guthrie5d3d6de2012-11-02 11:08:34 -0700159}
160
Wade Guthriebb9fca22013-04-10 17:21:42 -0700161TEST_F(NetlinkManagerTest, MessageHandlerTest) {
Wade Guthrie5d3d6de2012-11-02 11:08:34 -0700162 // Setup.
Wade Guthriebb9fca22013-04-10 17:21:42 -0700163 SetupNetlinkManagerObject();
Wade Guthrie5d3d6de2012-11-02 11:08:34 -0700164
Wade Guthrie71cb0a72013-02-27 10:27:18 -0800165 MockHandler80211 handler_broadcast;
Wade Guthriebb9fca22013-04-10 17:21:42 -0700166 EXPECT_TRUE(netlink_manager_->AddBroadcastHandler(
Wade Guthriec6c81962013-03-06 15:47:13 -0800167 handler_broadcast.on_netlink_message()));
Wade Guthrie5d3d6de2012-11-02 11:08:34 -0700168
repo syncdc085c82012-12-28 08:54:41 -0800169 Nl80211Message sent_message_1(CTRL_CMD_GETFAMILY, kGetFamilyCommandString);
Wade Guthrie71cb0a72013-02-27 10:27:18 -0800170 MockHandler80211 handler_sent_1;
Wade Guthrie5d3d6de2012-11-02 11:08:34 -0700171
repo syncdc085c82012-12-28 08:54:41 -0800172 Nl80211Message sent_message_2(CTRL_CMD_GETFAMILY, kGetFamilyCommandString);
Wade Guthrie71cb0a72013-02-27 10:27:18 -0800173 MockHandler80211 handler_sent_2;
Wade Guthrie5d3d6de2012-11-02 11:08:34 -0700174
175 // Set up the received message as a response to sent_message_1.
176 scoped_array<unsigned char> message_memory(
177 new unsigned char[sizeof(kNL80211_CMD_DISCONNECT)]);
178 memcpy(message_memory.get(), kNL80211_CMD_DISCONNECT,
179 sizeof(kNL80211_CMD_DISCONNECT));
180 nlmsghdr *received_message =
181 reinterpret_cast<nlmsghdr *>(message_memory.get());
Wade Guthrie5d3d6de2012-11-02 11:08:34 -0700182
183 // Now, we can start the actual test...
184
Wade Guthrie71cb0a72013-02-27 10:27:18 -0800185 // Verify that generic handler gets called for a message when no
186 // message-specific handler has been installed.
Wade Guthriec6c81962013-03-06 15:47:13 -0800187 EXPECT_CALL(handler_broadcast, OnNetlinkMessage(_)).Times(1);
Wade Guthriebb9fca22013-04-10 17:21:42 -0700188 netlink_manager_->OnNlMessageReceived(received_message);
Wade Guthrie5d3d6de2012-11-02 11:08:34 -0700189
Wade Guthrie71cb0a72013-02-27 10:27:18 -0800190 // Send the message and give our handler. Verify that we get called back.
Wade Guthrie92d06362013-04-25 15:41:30 -0700191 EXPECT_TRUE(netlink_manager_->SendMessage(
192 &sent_message_1, handler_sent_1.on_netlink_message()));
Christopher Wiley393b93f2012-11-08 17:30:58 -0800193 // Make it appear that this message is in response to our sent message.
194 received_message->nlmsg_seq = socket_.GetLastSequenceNumber();
Wade Guthriec6c81962013-03-06 15:47:13 -0800195 EXPECT_CALL(handler_sent_1, OnNetlinkMessage(_)).Times(1);
Wade Guthriebb9fca22013-04-10 17:21:42 -0700196 netlink_manager_->OnNlMessageReceived(received_message);
Wade Guthrie5d3d6de2012-11-02 11:08:34 -0700197
Wade Guthrie71cb0a72013-02-27 10:27:18 -0800198 // Verify that broadcast handler is called for the message after the
199 // message-specific handler is called once.
Wade Guthriec6c81962013-03-06 15:47:13 -0800200 EXPECT_CALL(handler_broadcast, OnNetlinkMessage(_)).Times(1);
Wade Guthriebb9fca22013-04-10 17:21:42 -0700201 netlink_manager_->OnNlMessageReceived(received_message);
Wade Guthrie5d3d6de2012-11-02 11:08:34 -0700202
Wade Guthrie71cb0a72013-02-27 10:27:18 -0800203 // Install and then uninstall message-specific handler; verify broadcast
204 // handler is called on message receipt.
Wade Guthrie92d06362013-04-25 15:41:30 -0700205 EXPECT_TRUE(netlink_manager_->SendMessage(
206 &sent_message_1, handler_sent_1.on_netlink_message()));
Christopher Wiley393b93f2012-11-08 17:30:58 -0800207 received_message->nlmsg_seq = socket_.GetLastSequenceNumber();
Wade Guthriebb9fca22013-04-10 17:21:42 -0700208 EXPECT_TRUE(netlink_manager_->RemoveMessageHandler(sent_message_1));
Wade Guthriec6c81962013-03-06 15:47:13 -0800209 EXPECT_CALL(handler_broadcast, OnNetlinkMessage(_)).Times(1);
Wade Guthriebb9fca22013-04-10 17:21:42 -0700210 netlink_manager_->OnNlMessageReceived(received_message);
Wade Guthrie5d3d6de2012-11-02 11:08:34 -0700211
Wade Guthrie71cb0a72013-02-27 10:27:18 -0800212 // Install handler for different message; verify that broadcast handler is
Wade Guthrie5d3d6de2012-11-02 11:08:34 -0700213 // called for _this_ message.
Wade Guthrie92d06362013-04-25 15:41:30 -0700214 EXPECT_TRUE(netlink_manager_->SendMessage(
215 &sent_message_2, handler_sent_2.on_netlink_message()));
Wade Guthriec6c81962013-03-06 15:47:13 -0800216 EXPECT_CALL(handler_broadcast, OnNetlinkMessage(_)).Times(1);
Wade Guthriebb9fca22013-04-10 17:21:42 -0700217 netlink_manager_->OnNlMessageReceived(received_message);
Wade Guthrie5d3d6de2012-11-02 11:08:34 -0700218
Wade Guthrie71cb0a72013-02-27 10:27:18 -0800219 // Change the ID for the message to that of the second handler; verify that
220 // the appropriate handler is called for _that_ message.
Christopher Wiley393b93f2012-11-08 17:30:58 -0800221 received_message->nlmsg_seq = socket_.GetLastSequenceNumber();
Wade Guthriec6c81962013-03-06 15:47:13 -0800222 EXPECT_CALL(handler_sent_2, OnNetlinkMessage(_)).Times(1);
Wade Guthriebb9fca22013-04-10 17:21:42 -0700223 netlink_manager_->OnNlMessageReceived(received_message);
Wade Guthrie5d3d6de2012-11-02 11:08:34 -0700224}
225
Wade Guthrie0d438532012-05-18 14:18:50 -0700226} // namespace shill