blob: d5bf2e95eb7fb25364d971a37cf89eddbe54080e [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
Wade Guthrieee293002013-06-05 14:49:16 -070013#include <map>
Wade Guthriefa2100e2013-05-15 10:11:22 -070014#include <string>
15
Wade Guthrieee293002013-06-05 14:49:16 -070016#include <base/stringprintf.h>
Wade Guthrie0d438532012-05-18 14:18:50 -070017#include <gmock/gmock.h>
18#include <gtest/gtest.h>
Wade Guthrie0d438532012-05-18 14:18:50 -070019
Wade Guthrieee293002013-06-05 14:49:16 -070020#include "shill/mock_event_dispatcher.h"
21#include "shill/mock_log.h"
Wade Guthriecc53f232013-03-05 13:22:23 -080022#include "shill/mock_netlink_socket.h"
Wade Guthriefa2100e2013-05-15 10:11:22 -070023#include "shill/mock_sockets.h"
24#include "shill/mock_time.h"
25#include "shill/netlink_attribute.h"
repo syncdc085c82012-12-28 08:54:41 -080026#include "shill/nl80211_message.h"
Wade Guthriebbe59f72013-05-21 08:45:39 -070027#include "shill/scope_logger.h"
Wade Guthrie0d438532012-05-18 14:18:50 -070028
29using base::Bind;
Wade Guthrieee293002013-06-05 14:49:16 -070030using base::StringPrintf;
Wade Guthrie0d438532012-05-18 14:18:50 -070031using base::Unretained;
Wade Guthrieee293002013-06-05 14:49:16 -070032using std::map;
Wade Guthriefa2100e2013-05-15 10:11:22 -070033using std::string;
Wade Guthrie0d438532012-05-18 14:18:50 -070034using testing::_;
Wade Guthrieee293002013-06-05 14:49:16 -070035using testing::AnyNumber;
36using testing::EndsWith;
Wade Guthrie5d3d6de2012-11-02 11:08:34 -070037using testing::Invoke;
Wade Guthrie0d438532012-05-18 14:18:50 -070038using testing::Return;
39using testing::Test;
40
41namespace shill {
42
43namespace {
44
Wade Guthriebb9fca22013-04-10 17:21:42 -070045// These data blocks have been collected by shill using NetlinkManager while,
Wade Guthrie0d438532012-05-18 14:18:50 -070046// simultaneously (and manually) comparing shill output with that of the 'iw'
47// code from which it was derived. The test strings represent the raw packet
48// data coming from the kernel. The comments above each of these strings is
49// the markup that "iw" outputs for ech of these packets.
50
51// These constants are consistent throughout the packets, below.
52
Wade Guthriebdcdaa72013-03-04 12:47:12 -080053const uint16_t kNl80211FamilyId = 0x13;
Wade Guthrie0d438532012-05-18 14:18:50 -070054
Wade Guthrieee293002013-06-05 14:49:16 -070055// Family and group Ids.
56const char kFamilyStoogesString[] = "stooges"; // Not saved as a legal family.
57const char kGroupMoeString[] = "moe"; // Not saved as a legal group.
58const char kFamilyMarxString[] = "marx";
59const uint16_t kFamilyMarxNumber = 20;
60const char kGroupGrouchoString[] = "groucho";
61const uint32_t kGroupGrouchoNumber = 21;
62const char kGroupHarpoString[] = "harpo";
63const uint32_t kGroupHarpoNumber = 22;
64const char kGroupChicoString[] = "chico";
65const uint32_t kGroupChicoNumber = 23;
66const char kGroupZeppoString[] = "zeppo";
67const uint32_t kGroupZeppoNumber = 24;
68const char kGroupGummoString[] = "gummo";
69const uint32_t kGroupGummoNumber = 25;
70
Wade Guthrie0d438532012-05-18 14:18:50 -070071// wlan0 (phy #0): disconnected (by AP) reason: 2: Previous authentication no
72// longer valid
73
Wade Guthrie0d438532012-05-18 14:18:50 -070074const unsigned char kNL80211_CMD_DISCONNECT[] = {
75 0x30, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00,
76 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
77 0x30, 0x01, 0x00, 0x00, 0x08, 0x00, 0x01, 0x00,
78 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x03, 0x00,
79 0x04, 0x00, 0x00, 0x00, 0x06, 0x00, 0x36, 0x00,
80 0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x47, 0x00,
81};
82
repo syncdc085c82012-12-28 08:54:41 -080083const char kGetFamilyCommandString[] = "CTRL_CMD_GETFAMILY";
84
Wade Guthrieb1ec8602012-10-18 17:26:14 -070085} // namespace
repo syncdc085c82012-12-28 08:54:41 -080086
Wade Guthriebb9fca22013-04-10 17:21:42 -070087class NetlinkManagerTest : public Test {
Wade Guthrie0d438532012-05-18 14:18:50 -070088 public:
Wade Guthriefa2100e2013-05-15 10:11:22 -070089 NetlinkManagerTest()
90 : netlink_manager_(NetlinkManager::GetInstance()),
91 sockets_(new MockSockets),
92 saved_sequence_number_(0) {
Wade Guthrieee293002013-06-05 14:49:16 -070093 netlink_manager_->message_types_[Nl80211Message::kMessageTypeString].
94 family_id = kNl80211FamilyId;
95 netlink_manager_->message_types_[kFamilyMarxString].family_id =
96 kFamilyMarxNumber;
97 netlink_manager_->message_types_[kFamilyMarxString].groups =
98 map<string, uint32_t> {{kGroupGrouchoString, kGroupGrouchoNumber},
99 {kGroupHarpoString, kGroupHarpoNumber},
100 {kGroupChicoString, kGroupChicoNumber},
101 {kGroupZeppoString, kGroupZeppoNumber},
102 {kGroupGummoString, kGroupGummoNumber}};
Wade Guthriebb9fca22013-04-10 17:21:42 -0700103 netlink_manager_->message_factory_.AddFactoryMethod(
Wade Guthrie12f113a2013-03-12 17:15:46 -0700104 kNl80211FamilyId, Bind(&Nl80211Message::CreateMessage));
Wade Guthrie318445d2013-05-16 14:05:28 -0700105 Nl80211Message::SetMessageType(kNl80211FamilyId);
Wade Guthriefa2100e2013-05-15 10:11:22 -0700106 // Passes ownership.
107 netlink_socket_.sockets_.reset(sockets_);
108
109 EXPECT_NE(reinterpret_cast<NetlinkManager *>(NULL), netlink_manager_);
110 netlink_manager_->sock_ = &netlink_socket_;
111 EXPECT_TRUE(netlink_manager_->Init());
Wade Guthriebee87c22013-03-06 11:00:46 -0800112 }
Wade Guthriec6c81962013-03-06 15:47:13 -0800113
Wade Guthriebb9fca22013-04-10 17:21:42 -0700114 ~NetlinkManagerTest() {
115 // NetlinkManager is a singleton, the sock_ field *MUST* be cleared
116 // before "NetlinkManagerTest::socket_" gets invalidated, otherwise
Han Shen4afba202012-12-17 08:48:35 -0800117 // later tests will refer to a corrupted memory.
Wade Guthriebb9fca22013-04-10 17:21:42 -0700118 netlink_manager_->sock_ = NULL;
Han Shen4afba202012-12-17 08:48:35 -0800119 }
Wade Guthriec6c81962013-03-06 15:47:13 -0800120
Wade Guthriefa2100e2013-05-15 10:11:22 -0700121 // |SaveReply|, |SendMessage|, and |ReplyToSentMessage| work together to
122 // enable a test to get a response to a sent message. They must be called
123 // in the order, above, so that a) a reply message is available to b) have
124 // its sequence number replaced, and then c) sent back to the code.
125 void SaveReply(const ByteString &message) {
126 saved_message_ = message;
127 }
128
129 // Replaces the |saved_message_|'s sequence number with the sent value.
130 bool SendMessage(const ByteString &outgoing_message) {
131 if (outgoing_message.GetLength() < sizeof(nlmsghdr)) {
132 LOG(ERROR) << "Outgoing message is too short";
133 return false;
134 }
135 const nlmsghdr *outgoing_header =
136 reinterpret_cast<const nlmsghdr *>(outgoing_message.GetConstData());
137
138 if (saved_message_.GetLength() < sizeof(nlmsghdr)) {
139 LOG(ERROR) << "Saved message is too short; have you called |SaveReply|?";
140 return false;
141 }
142 nlmsghdr *reply_header =
143 reinterpret_cast<nlmsghdr *>(saved_message_.GetData());
144
145 reply_header->nlmsg_seq = outgoing_header->nlmsg_seq;
146 saved_sequence_number_ = reply_header->nlmsg_seq;
147 return true;
148 }
149
150 bool ReplyToSentMessage(ByteString *message) {
151 if (!message) {
152 return false;
153 }
154 *message = saved_message_;
155 return true;
156 }
157
158 bool ReplyWithRandomMessage(ByteString *message) {
159 GetFamilyMessage get_family_message;
160 // Any number that's not 0 or 1 is acceptable, here. Zero is bad because
161 // we want to make sure that this message is different than the main
Wade Guthrie84db7ce2013-06-12 11:40:49 -0700162 // send/receive pair. One is bad because the default for
Wade Guthriefa2100e2013-05-15 10:11:22 -0700163 // |saved_sequence_number_| is zero and the likely default value for the
164 // first sequence number generated from the code is 1.
165 const uint32_t kRandomOffset = 1003;
166 if (!message) {
167 return false;
168 }
169 *message = get_family_message.Encode(saved_sequence_number_ +
170 kRandomOffset);
171 return true;
Wade Guthrie0d438532012-05-18 14:18:50 -0700172 }
173
Wade Guthriec6c81962013-03-06 15:47:13 -0800174 protected:
Wade Guthrie7347bf22013-04-30 11:21:51 -0700175 class MockHandlerNetlink {
Wade Guthriec6c81962013-03-06 15:47:13 -0800176 public:
Wade Guthrie7347bf22013-04-30 11:21:51 -0700177 MockHandlerNetlink() :
178 on_netlink_message_(base::Bind(&MockHandlerNetlink::OnNetlinkMessage,
Wade Guthriec6c81962013-03-06 15:47:13 -0800179 base::Unretained(this))) {}
180 MOCK_METHOD1(OnNetlinkMessage, void(const NetlinkMessage &msg));
Wade Guthriebb9fca22013-04-10 17:21:42 -0700181 const NetlinkManager::NetlinkMessageHandler &on_netlink_message() const {
Wade Guthriec6c81962013-03-06 15:47:13 -0800182 return on_netlink_message_;
183 }
184 private:
Wade Guthriebb9fca22013-04-10 17:21:42 -0700185 NetlinkManager::NetlinkMessageHandler on_netlink_message_;
Wade Guthrie7347bf22013-04-30 11:21:51 -0700186 DISALLOW_COPY_AND_ASSIGN(MockHandlerNetlink);
187 };
188
189 class MockHandlerNetlinkAuxilliary {
190 public:
191 MockHandlerNetlinkAuxilliary() :
192 on_netlink_message_(
Wade Guthrie84db7ce2013-06-12 11:40:49 -0700193 base::Bind(&MockHandlerNetlinkAuxilliary::OnErrorHandler,
Wade Guthrie7347bf22013-04-30 11:21:51 -0700194 base::Unretained(this))) {}
Wade Guthrie84db7ce2013-06-12 11:40:49 -0700195 MOCK_METHOD2(OnErrorHandler,
196 void(NetlinkManager::AuxilliaryMessageType type,
197 const NetlinkMessage *msg));
Wade Guthrie7347bf22013-04-30 11:21:51 -0700198 const NetlinkManager::NetlinkAuxilliaryMessageHandler &on_netlink_message()
199 const {
200 return on_netlink_message_;
201 }
202 private:
203 NetlinkManager::NetlinkAuxilliaryMessageHandler on_netlink_message_;
204 DISALLOW_COPY_AND_ASSIGN(MockHandlerNetlinkAuxilliary);
205 };
206
207 class MockHandler80211 {
208 public:
209 MockHandler80211() :
210 on_netlink_message_(base::Bind(&MockHandler80211::OnNetlinkMessage,
211 base::Unretained(this))) {}
212 MOCK_METHOD1(OnNetlinkMessage, void(const Nl80211Message &msg));
213 const NetlinkManager::Nl80211MessageHandler &on_netlink_message() const {
214 return on_netlink_message_;
215 }
216 private:
217 NetlinkManager::Nl80211MessageHandler on_netlink_message_;
Wade Guthriec6c81962013-03-06 15:47:13 -0800218 DISALLOW_COPY_AND_ASSIGN(MockHandler80211);
219 };
220
Wade Guthriefa2100e2013-05-15 10:11:22 -0700221 void Reset() {
222 netlink_manager_->Reset(false);
223 }
224
Wade Guthriebb9fca22013-04-10 17:21:42 -0700225 NetlinkManager *netlink_manager_;
Wade Guthriefa2100e2013-05-15 10:11:22 -0700226 MockNetlinkSocket netlink_socket_;
227 MockSockets *sockets_; // Owned by |netlink_socket_|.
228 ByteString saved_message_;
229 uint32_t saved_sequence_number_;
Wade Guthrie0d438532012-05-18 14:18:50 -0700230};
231
Wade Guthriefa2100e2013-05-15 10:11:22 -0700232namespace {
233
234class TimeFunctor {
235 public:
236 TimeFunctor(time_t tv_sec, suseconds_t tv_usec) {
237 return_value_.tv_sec = tv_sec;
238 return_value_.tv_usec = tv_usec;
239 }
240
241 TimeFunctor() {
242 return_value_.tv_sec = 0;
243 return_value_.tv_usec = 0;
244 }
245
246 TimeFunctor(const TimeFunctor &other) {
247 return_value_.tv_sec = other.return_value_.tv_sec;
248 return_value_.tv_usec = other.return_value_.tv_usec;
249 }
250
251 TimeFunctor &operator=(const TimeFunctor &rhs) {
252 return_value_.tv_sec = rhs.return_value_.tv_sec;
253 return_value_.tv_usec = rhs.return_value_.tv_usec;
254 return *this;
255 }
256
257 // Replaces GetTimeMonotonic.
258 int operator()(struct timeval *answer) {
259 if (answer) {
260 *answer = return_value_;
261 }
262 return 0;
263 }
264
265 private:
266 struct timeval return_value_;
267
268 // No DISALLOW_COPY_AND_ASSIGN since testing::Invoke uses copy.
269};
270
271} // namespace
272
Wade Guthrieee293002013-06-05 14:49:16 -0700273TEST_F(NetlinkManagerTest, Start) {
274 MockEventDispatcher dispatcher;
275
276 EXPECT_CALL(dispatcher, CreateInputHandler(_, _, _));
277 netlink_manager_->Start(&dispatcher);
278}
279
280TEST_F(NetlinkManagerTest, SubscribeToEvents) {
281 ScopedMockLog log;
282 EXPECT_CALL(log, Log(_, _, _)).Times(AnyNumber());
283
284 // Family not registered.
285 EXPECT_CALL(log, Log(logging::LOG_ERROR, _,
286 EndsWith("doesn't exist")));
287 EXPECT_CALL(netlink_socket_, SubscribeToEvents(_)).Times(0);
288 EXPECT_FALSE(netlink_manager_->SubscribeToEvents(kFamilyStoogesString,
289 kGroupMoeString));
290
291 // Group not part of family
292 string in_family = StringPrintf("doesn't exist in family '%s'",
293 kFamilyMarxString);
294 EXPECT_CALL(log, Log(logging::LOG_ERROR, _, EndsWith(in_family)));
295 EXPECT_CALL(netlink_socket_, SubscribeToEvents(_)).Times(0);
296 EXPECT_FALSE(netlink_manager_->SubscribeToEvents(kFamilyMarxString,
297 kGroupMoeString));
298
299 // Family registered and group part of family.
300 EXPECT_CALL(netlink_socket_, SubscribeToEvents(kGroupHarpoNumber)).
301 WillOnce(Return(true));
302 EXPECT_TRUE(netlink_manager_->SubscribeToEvents(kFamilyMarxString,
303 kGroupHarpoString));
304}
Wade Guthriebee87c22013-03-06 11:00:46 -0800305
Wade Guthriefa2100e2013-05-15 10:11:22 -0700306TEST_F(NetlinkManagerTest, GetFamily) {
307 const uint16_t kSampleMessageType = 42;
308 const string kSampleMessageName("SampleMessageName");
309 const uint32_t kRandomSequenceNumber = 3;
Wade Guthrie5d3d6de2012-11-02 11:08:34 -0700310
Wade Guthriefa2100e2013-05-15 10:11:22 -0700311 NewFamilyMessage new_family_message;
312 new_family_message.attributes()->CreateAttribute(
313 CTRL_ATTR_FAMILY_ID,
314 base::Bind(&NetlinkAttribute::NewControlAttributeFromId));
315 new_family_message.attributes()->SetU16AttributeValue(
316 CTRL_ATTR_FAMILY_ID, kSampleMessageType);
317 new_family_message.attributes()->CreateAttribute(
318 CTRL_ATTR_FAMILY_NAME,
319 base::Bind(&NetlinkAttribute::NewControlAttributeFromId));
320 new_family_message.attributes()->SetStringAttributeValue(
321 CTRL_ATTR_FAMILY_NAME, kSampleMessageName);
322
323 // The sequence number is immaterial since it'll be overwritten.
324 SaveReply(new_family_message.Encode(kRandomSequenceNumber));
325 EXPECT_CALL(netlink_socket_, SendMessage(_)).
326 WillOnce(Invoke(this, &NetlinkManagerTest::SendMessage));
327 EXPECT_CALL(netlink_socket_, file_descriptor()).WillRepeatedly(Return(0));
328 EXPECT_CALL(*sockets_, Select(_, _, _, _, _)).WillOnce(Return(1));
329 EXPECT_CALL(netlink_socket_, RecvMessage(_)).
330 WillOnce(Invoke(this, &NetlinkManagerTest::ReplyToSentMessage));
331 NetlinkMessageFactory::FactoryMethod null_factory;
332 EXPECT_EQ(kSampleMessageType, netlink_manager_->GetFamily(kSampleMessageName,
333 null_factory));
334}
335
336TEST_F(NetlinkManagerTest, GetFamilyOneInterstitialMessage) {
337 Reset();
338
339 const uint16_t kSampleMessageType = 42;
340 const string kSampleMessageName("SampleMessageName");
341 const uint32_t kRandomSequenceNumber = 3;
342
343 NewFamilyMessage new_family_message;
344 new_family_message.attributes()->CreateAttribute(
345 CTRL_ATTR_FAMILY_ID,
346 base::Bind(&NetlinkAttribute::NewControlAttributeFromId));
347 new_family_message.attributes()->SetU16AttributeValue(
348 CTRL_ATTR_FAMILY_ID, kSampleMessageType);
349 new_family_message.attributes()->CreateAttribute(
350 CTRL_ATTR_FAMILY_NAME,
351 base::Bind(&NetlinkAttribute::NewControlAttributeFromId));
352 new_family_message.attributes()->SetStringAttributeValue(
353 CTRL_ATTR_FAMILY_NAME, kSampleMessageName);
354
355 // The sequence number is immaterial since it'll be overwritten.
356 SaveReply(new_family_message.Encode(kRandomSequenceNumber));
357 EXPECT_CALL(netlink_socket_, SendMessage(_)).
358 WillOnce(Invoke(this, &NetlinkManagerTest::SendMessage));
359 EXPECT_CALL(netlink_socket_, file_descriptor()).WillRepeatedly(Return(0));
360 EXPECT_CALL(*sockets_, Select(_, _, _, _, _)).WillRepeatedly(Return(1));
361 EXPECT_CALL(netlink_socket_, RecvMessage(_)).
362 WillOnce(Invoke(this, &NetlinkManagerTest::ReplyWithRandomMessage)).
363 WillOnce(Invoke(this, &NetlinkManagerTest::ReplyToSentMessage));
364 NetlinkMessageFactory::FactoryMethod null_factory;
365 EXPECT_EQ(kSampleMessageType, netlink_manager_->GetFamily(kSampleMessageName,
366 null_factory));
367}
368
369TEST_F(NetlinkManagerTest, GetFamilyTimeout) {
370 Reset();
371 MockTime time;
Wade Guthrie84db7ce2013-06-12 11:40:49 -0700372 Time *old_time = netlink_manager_->time_;
Wade Guthriefa2100e2013-05-15 10:11:22 -0700373 netlink_manager_->time_ = &time;
374
375 EXPECT_CALL(netlink_socket_, SendMessage(_)).WillOnce(Return(true));
376 time_t kStartSeconds = 1234; // Arbitrary.
377 suseconds_t kSmallUsec = 100;
378 EXPECT_CALL(time, GetTimeMonotonic(_)).
379 WillOnce(Invoke(TimeFunctor(kStartSeconds, 0))). // Initial time.
380 WillOnce(Invoke(TimeFunctor(kStartSeconds, kSmallUsec))).
381 WillOnce(Invoke(TimeFunctor(kStartSeconds, 2 * kSmallUsec))).
382 WillOnce(Invoke(TimeFunctor(
383 kStartSeconds + NetlinkManager::kMaximumNewFamilyWaitSeconds + 1,
384 NetlinkManager::kMaximumNewFamilyWaitMicroSeconds)));
385 EXPECT_CALL(netlink_socket_, file_descriptor()).WillRepeatedly(Return(0));
386 EXPECT_CALL(*sockets_, Select(_, _, _, _, _)).WillRepeatedly(Return(1));
387 EXPECT_CALL(netlink_socket_, RecvMessage(_)).
388 WillRepeatedly(Invoke(this, &NetlinkManagerTest::ReplyWithRandomMessage));
389 NetlinkMessageFactory::FactoryMethod null_factory;
390
391 const string kSampleMessageName("SampleMessageName");
392 EXPECT_EQ(NetlinkMessage::kIllegalMessageType,
393 netlink_manager_->GetFamily(kSampleMessageName, null_factory));
Wade Guthrie84db7ce2013-06-12 11:40:49 -0700394 netlink_manager_->time_ = old_time;
Wade Guthriefa2100e2013-05-15 10:11:22 -0700395}
396
Wade Guthriebbe59f72013-05-21 08:45:39 -0700397TEST_F(NetlinkManagerTest, BroadcastHandler) {
Wade Guthrie84db7ce2013-06-12 11:40:49 -0700398 Reset();
Wade Guthrie5d3d6de2012-11-02 11:08:34 -0700399 nlmsghdr *message = const_cast<nlmsghdr *>(
400 reinterpret_cast<const nlmsghdr *>(kNL80211_CMD_DISCONNECT));
401
Wade Guthrie7347bf22013-04-30 11:21:51 -0700402 MockHandlerNetlink handler1;
403 MockHandlerNetlink handler2;
Wade Guthrie5d3d6de2012-11-02 11:08:34 -0700404
Wade Guthrie71cb0a72013-02-27 10:27:18 -0800405 // Simple, 1 handler, case.
Wade Guthriec6c81962013-03-06 15:47:13 -0800406 EXPECT_CALL(handler1, OnNetlinkMessage(_)).Times(1);
Wade Guthrie12f113a2013-03-12 17:15:46 -0700407 EXPECT_FALSE(
Wade Guthriebb9fca22013-04-10 17:21:42 -0700408 netlink_manager_->FindBroadcastHandler(handler1.on_netlink_message()));
409 netlink_manager_->AddBroadcastHandler(handler1.on_netlink_message());
Wade Guthrie12f113a2013-03-12 17:15:46 -0700410 EXPECT_TRUE(
Wade Guthriebb9fca22013-04-10 17:21:42 -0700411 netlink_manager_->FindBroadcastHandler(handler1.on_netlink_message()));
412 netlink_manager_->OnNlMessageReceived(message);
Wade Guthrie5d3d6de2012-11-02 11:08:34 -0700413
Wade Guthrie71cb0a72013-02-27 10:27:18 -0800414 // Add a second handler.
Wade Guthriec6c81962013-03-06 15:47:13 -0800415 EXPECT_CALL(handler1, OnNetlinkMessage(_)).Times(1);
416 EXPECT_CALL(handler2, OnNetlinkMessage(_)).Times(1);
Wade Guthriebb9fca22013-04-10 17:21:42 -0700417 netlink_manager_->AddBroadcastHandler(handler2.on_netlink_message());
418 netlink_manager_->OnNlMessageReceived(message);
Wade Guthrie5d3d6de2012-11-02 11:08:34 -0700419
Wade Guthrie71cb0a72013-02-27 10:27:18 -0800420 // Verify that a handler can't be added twice.
Wade Guthriec6c81962013-03-06 15:47:13 -0800421 EXPECT_CALL(handler1, OnNetlinkMessage(_)).Times(1);
422 EXPECT_CALL(handler2, OnNetlinkMessage(_)).Times(1);
Wade Guthriebb9fca22013-04-10 17:21:42 -0700423 netlink_manager_->AddBroadcastHandler(handler1.on_netlink_message());
424 netlink_manager_->OnNlMessageReceived(message);
Wade Guthrie5d3d6de2012-11-02 11:08:34 -0700425
Wade Guthrie71cb0a72013-02-27 10:27:18 -0800426 // Check that we can remove a handler.
Wade Guthriec6c81962013-03-06 15:47:13 -0800427 EXPECT_CALL(handler1, OnNetlinkMessage(_)).Times(0);
428 EXPECT_CALL(handler2, OnNetlinkMessage(_)).Times(1);
Wade Guthriebb9fca22013-04-10 17:21:42 -0700429 EXPECT_TRUE(netlink_manager_->RemoveBroadcastHandler(
Wade Guthriec6c81962013-03-06 15:47:13 -0800430 handler1.on_netlink_message()));
Wade Guthriebb9fca22013-04-10 17:21:42 -0700431 netlink_manager_->OnNlMessageReceived(message);
Wade Guthrie5d3d6de2012-11-02 11:08:34 -0700432
Wade Guthrie71cb0a72013-02-27 10:27:18 -0800433 // Check that re-adding the handler goes smoothly.
Wade Guthriec6c81962013-03-06 15:47:13 -0800434 EXPECT_CALL(handler1, OnNetlinkMessage(_)).Times(1);
435 EXPECT_CALL(handler2, OnNetlinkMessage(_)).Times(1);
Wade Guthriebb9fca22013-04-10 17:21:42 -0700436 netlink_manager_->AddBroadcastHandler(handler1.on_netlink_message());
437 netlink_manager_->OnNlMessageReceived(message);
Wade Guthrie5d3d6de2012-11-02 11:08:34 -0700438
Wade Guthrie71cb0a72013-02-27 10:27:18 -0800439 // Check that ClearBroadcastHandlers works.
Wade Guthriebb9fca22013-04-10 17:21:42 -0700440 netlink_manager_->ClearBroadcastHandlers();
Wade Guthriec6c81962013-03-06 15:47:13 -0800441 EXPECT_CALL(handler1, OnNetlinkMessage(_)).Times(0);
442 EXPECT_CALL(handler2, OnNetlinkMessage(_)).Times(0);
Wade Guthriebb9fca22013-04-10 17:21:42 -0700443 netlink_manager_->OnNlMessageReceived(message);
Wade Guthrie5d3d6de2012-11-02 11:08:34 -0700444}
445
Wade Guthriebbe59f72013-05-21 08:45:39 -0700446TEST_F(NetlinkManagerTest, MessageHandler) {
Wade Guthriefa2100e2013-05-15 10:11:22 -0700447 Reset();
Wade Guthrie7347bf22013-04-30 11:21:51 -0700448 MockHandlerNetlink handler_broadcast;
Wade Guthriebb9fca22013-04-10 17:21:42 -0700449 EXPECT_TRUE(netlink_manager_->AddBroadcastHandler(
Wade Guthriec6c81962013-03-06 15:47:13 -0800450 handler_broadcast.on_netlink_message()));
Wade Guthrie5d3d6de2012-11-02 11:08:34 -0700451
repo syncdc085c82012-12-28 08:54:41 -0800452 Nl80211Message sent_message_1(CTRL_CMD_GETFAMILY, kGetFamilyCommandString);
Wade Guthrie71cb0a72013-02-27 10:27:18 -0800453 MockHandler80211 handler_sent_1;
Wade Guthrie5d3d6de2012-11-02 11:08:34 -0700454
repo syncdc085c82012-12-28 08:54:41 -0800455 Nl80211Message sent_message_2(CTRL_CMD_GETFAMILY, kGetFamilyCommandString);
Wade Guthrie71cb0a72013-02-27 10:27:18 -0800456 MockHandler80211 handler_sent_2;
Wade Guthrie5d3d6de2012-11-02 11:08:34 -0700457
458 // Set up the received message as a response to sent_message_1.
459 scoped_array<unsigned char> message_memory(
460 new unsigned char[sizeof(kNL80211_CMD_DISCONNECT)]);
461 memcpy(message_memory.get(), kNL80211_CMD_DISCONNECT,
462 sizeof(kNL80211_CMD_DISCONNECT));
463 nlmsghdr *received_message =
464 reinterpret_cast<nlmsghdr *>(message_memory.get());
Wade Guthrie5d3d6de2012-11-02 11:08:34 -0700465
466 // Now, we can start the actual test...
467
Wade Guthrie71cb0a72013-02-27 10:27:18 -0800468 // Verify that generic handler gets called for a message when no
469 // message-specific handler has been installed.
Wade Guthriec6c81962013-03-06 15:47:13 -0800470 EXPECT_CALL(handler_broadcast, OnNetlinkMessage(_)).Times(1);
Wade Guthriebb9fca22013-04-10 17:21:42 -0700471 netlink_manager_->OnNlMessageReceived(received_message);
Wade Guthrie5d3d6de2012-11-02 11:08:34 -0700472
Wade Guthrie71cb0a72013-02-27 10:27:18 -0800473 // Send the message and give our handler. Verify that we get called back.
Wade Guthrie7347bf22013-04-30 11:21:51 -0700474 NetlinkManager::NetlinkAuxilliaryMessageHandler null_error_handler;
475 EXPECT_CALL(netlink_socket_, SendMessage(_)).WillRepeatedly(Return(true));
476 EXPECT_TRUE(netlink_manager_->SendNl80211Message(
477 &sent_message_1, handler_sent_1.on_netlink_message(),
478 null_error_handler));
Christopher Wiley393b93f2012-11-08 17:30:58 -0800479 // Make it appear that this message is in response to our sent message.
Wade Guthriefa2100e2013-05-15 10:11:22 -0700480 received_message->nlmsg_seq = netlink_socket_.GetLastSequenceNumber();
Wade Guthriec6c81962013-03-06 15:47:13 -0800481 EXPECT_CALL(handler_sent_1, OnNetlinkMessage(_)).Times(1);
Wade Guthriebb9fca22013-04-10 17:21:42 -0700482 netlink_manager_->OnNlMessageReceived(received_message);
Wade Guthrie5d3d6de2012-11-02 11:08:34 -0700483
Wade Guthrie71cb0a72013-02-27 10:27:18 -0800484 // Verify that broadcast handler is called for the message after the
485 // message-specific handler is called once.
Wade Guthriec6c81962013-03-06 15:47:13 -0800486 EXPECT_CALL(handler_broadcast, OnNetlinkMessage(_)).Times(1);
Wade Guthriebb9fca22013-04-10 17:21:42 -0700487 netlink_manager_->OnNlMessageReceived(received_message);
Wade Guthrie5d3d6de2012-11-02 11:08:34 -0700488
Wade Guthrie71cb0a72013-02-27 10:27:18 -0800489 // Install and then uninstall message-specific handler; verify broadcast
490 // handler is called on message receipt.
Wade Guthrie7347bf22013-04-30 11:21:51 -0700491 EXPECT_TRUE(netlink_manager_->SendNl80211Message(
492 &sent_message_1, handler_sent_1.on_netlink_message(),
493 null_error_handler));
Wade Guthriefa2100e2013-05-15 10:11:22 -0700494 received_message->nlmsg_seq = netlink_socket_.GetLastSequenceNumber();
Wade Guthriebb9fca22013-04-10 17:21:42 -0700495 EXPECT_TRUE(netlink_manager_->RemoveMessageHandler(sent_message_1));
Wade Guthriec6c81962013-03-06 15:47:13 -0800496 EXPECT_CALL(handler_broadcast, OnNetlinkMessage(_)).Times(1);
Wade Guthriebb9fca22013-04-10 17:21:42 -0700497 netlink_manager_->OnNlMessageReceived(received_message);
Wade Guthrie5d3d6de2012-11-02 11:08:34 -0700498
Wade Guthrie71cb0a72013-02-27 10:27:18 -0800499 // Install handler for different message; verify that broadcast handler is
Wade Guthrie5d3d6de2012-11-02 11:08:34 -0700500 // called for _this_ message.
Wade Guthrie7347bf22013-04-30 11:21:51 -0700501 EXPECT_TRUE(netlink_manager_->SendNl80211Message(
502 &sent_message_2, handler_sent_2.on_netlink_message(),
503 null_error_handler));
Wade Guthriec6c81962013-03-06 15:47:13 -0800504 EXPECT_CALL(handler_broadcast, OnNetlinkMessage(_)).Times(1);
Wade Guthriebb9fca22013-04-10 17:21:42 -0700505 netlink_manager_->OnNlMessageReceived(received_message);
Wade Guthrie5d3d6de2012-11-02 11:08:34 -0700506
Wade Guthrie71cb0a72013-02-27 10:27:18 -0800507 // Change the ID for the message to that of the second handler; verify that
508 // the appropriate handler is called for _that_ message.
Wade Guthriefa2100e2013-05-15 10:11:22 -0700509 received_message->nlmsg_seq = netlink_socket_.GetLastSequenceNumber();
Wade Guthriec6c81962013-03-06 15:47:13 -0800510 EXPECT_CALL(handler_sent_2, OnNetlinkMessage(_)).Times(1);
Wade Guthriebb9fca22013-04-10 17:21:42 -0700511 netlink_manager_->OnNlMessageReceived(received_message);
Wade Guthrie5d3d6de2012-11-02 11:08:34 -0700512}
513
Wade Guthriebbe59f72013-05-21 08:45:39 -0700514TEST_F(NetlinkManagerTest, MultipartMessageHandler) {
515 Reset();
516
517 // Install a broadcast handler.
Wade Guthrie7347bf22013-04-30 11:21:51 -0700518 MockHandlerNetlink broadcast_handler;
Wade Guthriebbe59f72013-05-21 08:45:39 -0700519 EXPECT_TRUE(netlink_manager_->AddBroadcastHandler(
520 broadcast_handler.on_netlink_message()));
521
522 // Build a message and send it in order to install a response handler.
523 TriggerScanMessage trigger_scan_message;
524 MockHandler80211 response_handler;
Wade Guthrie7347bf22013-04-30 11:21:51 -0700525 MockHandlerNetlinkAuxilliary auxilliary_handler;
Wade Guthriebbe59f72013-05-21 08:45:39 -0700526 EXPECT_CALL(netlink_socket_, SendMessage(_)).WillOnce(Return(true));
Wade Guthrie7347bf22013-04-30 11:21:51 -0700527 NetlinkManager::NetlinkAuxilliaryMessageHandler null_error_handler;
528 EXPECT_TRUE(netlink_manager_->SendNl80211Message(
529 &trigger_scan_message, response_handler.on_netlink_message(),
530 auxilliary_handler.on_netlink_message()));
Wade Guthriebbe59f72013-05-21 08:45:39 -0700531
532 // Build a multi-part response (well, it's just one message but it'll be
533 // received multiple times).
534 const uint32_t kSequenceNumber = 32; // Arbitrary (replaced, later).
535 NewScanResultsMessage new_scan_results;
536 new_scan_results.AddFlag(NLM_F_MULTI);
537 ByteString new_scan_results_bytes(new_scan_results.Encode(kSequenceNumber));
538 nlmsghdr *received_message =
539 reinterpret_cast<nlmsghdr *>(new_scan_results_bytes.GetData());
540 received_message->nlmsg_seq = netlink_socket_.GetLastSequenceNumber();
541
542 // Verify that the message-specific handler is called.
543 EXPECT_CALL(response_handler, OnNetlinkMessage(_));
544 netlink_manager_->OnNlMessageReceived(received_message);
545
546 // Verify that the message-specific handler is still called.
547 EXPECT_CALL(response_handler, OnNetlinkMessage(_));
548 netlink_manager_->OnNlMessageReceived(received_message);
549
550 // Build a Done message with the sent-message sequence number.
551 DoneMessage done_message;
552 ByteString done_message_bytes(
553 done_message.Encode(netlink_socket_.GetLastSequenceNumber()));
554
555 // Verify that the message-specific handler is called for the done message.
Wade Guthrie84db7ce2013-06-12 11:40:49 -0700556 EXPECT_CALL(auxilliary_handler, OnErrorHandler(_, _));
Wade Guthriebbe59f72013-05-21 08:45:39 -0700557 netlink_manager_->OnNlMessageReceived(
558 reinterpret_cast<nlmsghdr *>(done_message_bytes.GetData()));
559
560 // Verify that broadcast handler is called now that the done message has
561 // been seen.
562 EXPECT_CALL(response_handler, OnNetlinkMessage(_)).Times(0);
Wade Guthrie84db7ce2013-06-12 11:40:49 -0700563 EXPECT_CALL(auxilliary_handler, OnErrorHandler(_, _)).Times(0);
Wade Guthriebbe59f72013-05-21 08:45:39 -0700564 EXPECT_CALL(broadcast_handler, OnNetlinkMessage(_)).Times(1);
565 netlink_manager_->OnNlMessageReceived(received_message);
566}
567
Wade Guthrie84db7ce2013-06-12 11:40:49 -0700568TEST_F(NetlinkManagerTest, TimeoutResponseHandlers) {
569 Reset();
570 MockHandlerNetlink broadcast_handler;
571 EXPECT_TRUE(netlink_manager_->AddBroadcastHandler(
572 broadcast_handler.on_netlink_message()));
573
574 // Set up the received message as a response to the get_wiphi_message
575 // we're going to send.
576 NewWiphyMessage new_wiphy_message;
577 const uint32_t kRandomSequenceNumber = 3;
578 ByteString new_wiphy_message_bytes =
579 new_wiphy_message.Encode(kRandomSequenceNumber);
580 nlmsghdr *received_message =
581 reinterpret_cast<nlmsghdr *>(new_wiphy_message_bytes.GetData());
582
583 // Setup a random received message to trigger wiping out old messages.
584 NewScanResultsMessage new_scan_results;
585 ByteString new_scan_results_bytes =
586 new_scan_results.Encode(kRandomSequenceNumber);
587
588 // Setup the timestamps of various messages
589 MockTime time;
590 Time *old_time = netlink_manager_->time_;
591 netlink_manager_->time_ = &time;
592
593 time_t kStartSeconds = 1234; // Arbitrary.
594 suseconds_t kSmallUsec = 100;
595 EXPECT_CALL(time, GetTimeMonotonic(_)).
596 WillOnce(Invoke(TimeFunctor(kStartSeconds, 0))). // Initial time.
597 WillOnce(Invoke(TimeFunctor(kStartSeconds, kSmallUsec))).
598
599 WillOnce(Invoke(TimeFunctor(kStartSeconds, 0))). // Initial time.
600 WillOnce(Invoke(TimeFunctor(
601 kStartSeconds + NetlinkManager::kResponseTimeoutSeconds + 1,
602 NetlinkManager::kResponseTimeoutMicroSeconds)));
603 EXPECT_CALL(netlink_socket_, SendMessage(_)).WillRepeatedly(Return(true));
604
605 GetWiphyMessage get_wiphi_message;
606 MockHandler80211 response_handler;
607 MockHandlerNetlinkAuxilliary auxilliary_handler;
608
609 GetRegMessage get_reg_message; // Just a message to trigger timeout.
610 NetlinkManager::Nl80211MessageHandler null_message_handler;
611 NetlinkManager::NetlinkAuxilliaryMessageHandler null_error_handler;
612
613 // Send two messages within the message handler timeout; verify that we
614 // get called back (i.e., that the first handler isn't discarded).
615 EXPECT_TRUE(netlink_manager_->SendNl80211Message(
616 &get_wiphi_message, response_handler.on_netlink_message(),
617 auxilliary_handler.on_netlink_message()));
618 received_message->nlmsg_seq = netlink_socket_.GetLastSequenceNumber();
619 EXPECT_TRUE(netlink_manager_->SendNl80211Message(
620 &get_reg_message, null_message_handler, null_error_handler));
621 EXPECT_CALL(response_handler, OnNetlinkMessage(_));
622 netlink_manager_->OnNlMessageReceived(received_message);
623
624 // Send two messages at an interval greater than the message handler timeout
625 // before the response to the first arrives. Verify that the error handler
626 // for the first message is called (with a timeout flag) and that the
627 // broadcast handler gets called, instead of the message's handler.
628 EXPECT_TRUE(netlink_manager_->SendNl80211Message(
629 &get_wiphi_message, response_handler.on_netlink_message(),
630 auxilliary_handler.on_netlink_message()));
631 received_message->nlmsg_seq = netlink_socket_.GetLastSequenceNumber();
632 EXPECT_CALL(auxilliary_handler,
633 OnErrorHandler(NetlinkManager::kTimeoutWaitingForResponse, NULL));
634 EXPECT_TRUE(netlink_manager_->SendNl80211Message(&get_reg_message,
635 null_message_handler,
636 null_error_handler));
637 EXPECT_CALL(response_handler, OnNetlinkMessage(_)).Times(0);
638 EXPECT_CALL(broadcast_handler, OnNetlinkMessage(_));
639 netlink_manager_->OnNlMessageReceived(received_message);
640
641 // Put the state of the singleton back where it was.
642 netlink_manager_->time_ = old_time;
643}
644
Wade Guthrie0d438532012-05-18 14:18:50 -0700645} // namespace shill