Wade Guthrie | 0d43853 | 2012-05-18 14:18:50 -0700 | [diff] [blame] | 1 | // 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 Guthrie | f48a195 | 2013-03-04 17:33:47 -0800 | [diff] [blame] | 6 | // NetlinkMessageFactory's ability to create specific message types and it |
| 7 | // tests the various NetlinkMessage types' ability to parse those |
Wade Guthrie | 0d43853 | 2012-05-18 14:18:50 -0700 | [diff] [blame] | 8 | // messages. |
| 9 | |
Wade Guthrie | bb9fca2 | 2013-04-10 17:21:42 -0700 | [diff] [blame] | 10 | // This file tests the public interface to NetlinkManager. |
Wade Guthrie | bb9fca2 | 2013-04-10 17:21:42 -0700 | [diff] [blame] | 11 | #include "shill/netlink_manager.h" |
Wade Guthrie | 0d43853 | 2012-05-18 14:18:50 -0700 | [diff] [blame] | 12 | |
Wade Guthrie | ee29300 | 2013-06-05 14:49:16 -0700 | [diff] [blame] | 13 | #include <map> |
Wade Guthrie | fa2100e | 2013-05-15 10:11:22 -0700 | [diff] [blame] | 14 | #include <string> |
| 15 | |
Wade Guthrie | ee29300 | 2013-06-05 14:49:16 -0700 | [diff] [blame] | 16 | #include <base/stringprintf.h> |
Wade Guthrie | 0d43853 | 2012-05-18 14:18:50 -0700 | [diff] [blame] | 17 | #include <gmock/gmock.h> |
| 18 | #include <gtest/gtest.h> |
Wade Guthrie | 0d43853 | 2012-05-18 14:18:50 -0700 | [diff] [blame] | 19 | |
Wade Guthrie | ee29300 | 2013-06-05 14:49:16 -0700 | [diff] [blame] | 20 | #include "shill/mock_event_dispatcher.h" |
| 21 | #include "shill/mock_log.h" |
Wade Guthrie | cc53f23 | 2013-03-05 13:22:23 -0800 | [diff] [blame] | 22 | #include "shill/mock_netlink_socket.h" |
Wade Guthrie | fa2100e | 2013-05-15 10:11:22 -0700 | [diff] [blame] | 23 | #include "shill/mock_sockets.h" |
| 24 | #include "shill/mock_time.h" |
| 25 | #include "shill/netlink_attribute.h" |
repo sync | dc085c8 | 2012-12-28 08:54:41 -0800 | [diff] [blame] | 26 | #include "shill/nl80211_message.h" |
Wade Guthrie | bbe59f7 | 2013-05-21 08:45:39 -0700 | [diff] [blame] | 27 | #include "shill/scope_logger.h" |
Wade Guthrie | 0d43853 | 2012-05-18 14:18:50 -0700 | [diff] [blame] | 28 | |
| 29 | using base::Bind; |
Wade Guthrie | ee29300 | 2013-06-05 14:49:16 -0700 | [diff] [blame] | 30 | using base::StringPrintf; |
Wade Guthrie | 0d43853 | 2012-05-18 14:18:50 -0700 | [diff] [blame] | 31 | using base::Unretained; |
Wade Guthrie | ee29300 | 2013-06-05 14:49:16 -0700 | [diff] [blame] | 32 | using std::map; |
Wade Guthrie | fa2100e | 2013-05-15 10:11:22 -0700 | [diff] [blame] | 33 | using std::string; |
Wade Guthrie | 0d43853 | 2012-05-18 14:18:50 -0700 | [diff] [blame] | 34 | using testing::_; |
Wade Guthrie | ee29300 | 2013-06-05 14:49:16 -0700 | [diff] [blame] | 35 | using testing::AnyNumber; |
| 36 | using testing::EndsWith; |
Wade Guthrie | 5d3d6de | 2012-11-02 11:08:34 -0700 | [diff] [blame] | 37 | using testing::Invoke; |
Wade Guthrie | 0d43853 | 2012-05-18 14:18:50 -0700 | [diff] [blame] | 38 | using testing::Return; |
| 39 | using testing::Test; |
| 40 | |
| 41 | namespace shill { |
| 42 | |
| 43 | namespace { |
| 44 | |
Wade Guthrie | bb9fca2 | 2013-04-10 17:21:42 -0700 | [diff] [blame] | 45 | // These data blocks have been collected by shill using NetlinkManager while, |
Wade Guthrie | 0d43853 | 2012-05-18 14:18:50 -0700 | [diff] [blame] | 46 | // 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 Guthrie | bdcdaa7 | 2013-03-04 12:47:12 -0800 | [diff] [blame] | 53 | const uint16_t kNl80211FamilyId = 0x13; |
Wade Guthrie | 0d43853 | 2012-05-18 14:18:50 -0700 | [diff] [blame] | 54 | |
Wade Guthrie | ee29300 | 2013-06-05 14:49:16 -0700 | [diff] [blame] | 55 | // Family and group Ids. |
| 56 | const char kFamilyStoogesString[] = "stooges"; // Not saved as a legal family. |
| 57 | const char kGroupMoeString[] = "moe"; // Not saved as a legal group. |
| 58 | const char kFamilyMarxString[] = "marx"; |
| 59 | const uint16_t kFamilyMarxNumber = 20; |
| 60 | const char kGroupGrouchoString[] = "groucho"; |
| 61 | const uint32_t kGroupGrouchoNumber = 21; |
| 62 | const char kGroupHarpoString[] = "harpo"; |
| 63 | const uint32_t kGroupHarpoNumber = 22; |
| 64 | const char kGroupChicoString[] = "chico"; |
| 65 | const uint32_t kGroupChicoNumber = 23; |
| 66 | const char kGroupZeppoString[] = "zeppo"; |
| 67 | const uint32_t kGroupZeppoNumber = 24; |
| 68 | const char kGroupGummoString[] = "gummo"; |
| 69 | const uint32_t kGroupGummoNumber = 25; |
| 70 | |
Wade Guthrie | 0d43853 | 2012-05-18 14:18:50 -0700 | [diff] [blame] | 71 | // wlan0 (phy #0): disconnected (by AP) reason: 2: Previous authentication no |
| 72 | // longer valid |
| 73 | |
Wade Guthrie | 0d43853 | 2012-05-18 14:18:50 -0700 | [diff] [blame] | 74 | const 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 sync | dc085c8 | 2012-12-28 08:54:41 -0800 | [diff] [blame] | 83 | const char kGetFamilyCommandString[] = "CTRL_CMD_GETFAMILY"; |
| 84 | |
Wade Guthrie | b1ec860 | 2012-10-18 17:26:14 -0700 | [diff] [blame] | 85 | } // namespace |
repo sync | dc085c8 | 2012-12-28 08:54:41 -0800 | [diff] [blame] | 86 | |
Wade Guthrie | bb9fca2 | 2013-04-10 17:21:42 -0700 | [diff] [blame] | 87 | class NetlinkManagerTest : public Test { |
Wade Guthrie | 0d43853 | 2012-05-18 14:18:50 -0700 | [diff] [blame] | 88 | public: |
Wade Guthrie | fa2100e | 2013-05-15 10:11:22 -0700 | [diff] [blame] | 89 | NetlinkManagerTest() |
| 90 | : netlink_manager_(NetlinkManager::GetInstance()), |
| 91 | sockets_(new MockSockets), |
| 92 | saved_sequence_number_(0) { |
Wade Guthrie | ee29300 | 2013-06-05 14:49:16 -0700 | [diff] [blame] | 93 | 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 Guthrie | bb9fca2 | 2013-04-10 17:21:42 -0700 | [diff] [blame] | 103 | netlink_manager_->message_factory_.AddFactoryMethod( |
Wade Guthrie | 12f113a | 2013-03-12 17:15:46 -0700 | [diff] [blame] | 104 | kNl80211FamilyId, Bind(&Nl80211Message::CreateMessage)); |
Wade Guthrie | 318445d | 2013-05-16 14:05:28 -0700 | [diff] [blame] | 105 | Nl80211Message::SetMessageType(kNl80211FamilyId); |
Wade Guthrie | fa2100e | 2013-05-15 10:11:22 -0700 | [diff] [blame] | 106 | // 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 Guthrie | bee87c2 | 2013-03-06 11:00:46 -0800 | [diff] [blame] | 112 | } |
Wade Guthrie | c6c8196 | 2013-03-06 15:47:13 -0800 | [diff] [blame] | 113 | |
Wade Guthrie | bb9fca2 | 2013-04-10 17:21:42 -0700 | [diff] [blame] | 114 | ~NetlinkManagerTest() { |
| 115 | // NetlinkManager is a singleton, the sock_ field *MUST* be cleared |
| 116 | // before "NetlinkManagerTest::socket_" gets invalidated, otherwise |
Han Shen | 4afba20 | 2012-12-17 08:48:35 -0800 | [diff] [blame] | 117 | // later tests will refer to a corrupted memory. |
Wade Guthrie | bb9fca2 | 2013-04-10 17:21:42 -0700 | [diff] [blame] | 118 | netlink_manager_->sock_ = NULL; |
Han Shen | 4afba20 | 2012-12-17 08:48:35 -0800 | [diff] [blame] | 119 | } |
Wade Guthrie | c6c8196 | 2013-03-06 15:47:13 -0800 | [diff] [blame] | 120 | |
Wade Guthrie | fa2100e | 2013-05-15 10:11:22 -0700 | [diff] [blame] | 121 | // |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 Guthrie | 84db7ce | 2013-06-12 11:40:49 -0700 | [diff] [blame] | 162 | // send/receive pair. One is bad because the default for |
Wade Guthrie | fa2100e | 2013-05-15 10:11:22 -0700 | [diff] [blame] | 163 | // |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 Guthrie | 0d43853 | 2012-05-18 14:18:50 -0700 | [diff] [blame] | 172 | } |
| 173 | |
Wade Guthrie | c6c8196 | 2013-03-06 15:47:13 -0800 | [diff] [blame] | 174 | protected: |
Wade Guthrie | 7347bf2 | 2013-04-30 11:21:51 -0700 | [diff] [blame] | 175 | class MockHandlerNetlink { |
Wade Guthrie | c6c8196 | 2013-03-06 15:47:13 -0800 | [diff] [blame] | 176 | public: |
Wade Guthrie | 7347bf2 | 2013-04-30 11:21:51 -0700 | [diff] [blame] | 177 | MockHandlerNetlink() : |
| 178 | on_netlink_message_(base::Bind(&MockHandlerNetlink::OnNetlinkMessage, |
Wade Guthrie | c6c8196 | 2013-03-06 15:47:13 -0800 | [diff] [blame] | 179 | base::Unretained(this))) {} |
| 180 | MOCK_METHOD1(OnNetlinkMessage, void(const NetlinkMessage &msg)); |
Wade Guthrie | bb9fca2 | 2013-04-10 17:21:42 -0700 | [diff] [blame] | 181 | const NetlinkManager::NetlinkMessageHandler &on_netlink_message() const { |
Wade Guthrie | c6c8196 | 2013-03-06 15:47:13 -0800 | [diff] [blame] | 182 | return on_netlink_message_; |
| 183 | } |
| 184 | private: |
Wade Guthrie | bb9fca2 | 2013-04-10 17:21:42 -0700 | [diff] [blame] | 185 | NetlinkManager::NetlinkMessageHandler on_netlink_message_; |
Wade Guthrie | 7347bf2 | 2013-04-30 11:21:51 -0700 | [diff] [blame] | 186 | DISALLOW_COPY_AND_ASSIGN(MockHandlerNetlink); |
| 187 | }; |
| 188 | |
| 189 | class MockHandlerNetlinkAuxilliary { |
| 190 | public: |
| 191 | MockHandlerNetlinkAuxilliary() : |
| 192 | on_netlink_message_( |
Wade Guthrie | 84db7ce | 2013-06-12 11:40:49 -0700 | [diff] [blame] | 193 | base::Bind(&MockHandlerNetlinkAuxilliary::OnErrorHandler, |
Wade Guthrie | 7347bf2 | 2013-04-30 11:21:51 -0700 | [diff] [blame] | 194 | base::Unretained(this))) {} |
Wade Guthrie | 84db7ce | 2013-06-12 11:40:49 -0700 | [diff] [blame] | 195 | MOCK_METHOD2(OnErrorHandler, |
| 196 | void(NetlinkManager::AuxilliaryMessageType type, |
| 197 | const NetlinkMessage *msg)); |
Wade Guthrie | 7347bf2 | 2013-04-30 11:21:51 -0700 | [diff] [blame] | 198 | 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 Guthrie | c6c8196 | 2013-03-06 15:47:13 -0800 | [diff] [blame] | 218 | DISALLOW_COPY_AND_ASSIGN(MockHandler80211); |
| 219 | }; |
| 220 | |
Wade Guthrie | fa2100e | 2013-05-15 10:11:22 -0700 | [diff] [blame] | 221 | void Reset() { |
| 222 | netlink_manager_->Reset(false); |
| 223 | } |
| 224 | |
Wade Guthrie | bb9fca2 | 2013-04-10 17:21:42 -0700 | [diff] [blame] | 225 | NetlinkManager *netlink_manager_; |
Wade Guthrie | fa2100e | 2013-05-15 10:11:22 -0700 | [diff] [blame] | 226 | MockNetlinkSocket netlink_socket_; |
| 227 | MockSockets *sockets_; // Owned by |netlink_socket_|. |
| 228 | ByteString saved_message_; |
| 229 | uint32_t saved_sequence_number_; |
Wade Guthrie | 0d43853 | 2012-05-18 14:18:50 -0700 | [diff] [blame] | 230 | }; |
| 231 | |
Wade Guthrie | fa2100e | 2013-05-15 10:11:22 -0700 | [diff] [blame] | 232 | namespace { |
| 233 | |
| 234 | class 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 Guthrie | ee29300 | 2013-06-05 14:49:16 -0700 | [diff] [blame] | 273 | TEST_F(NetlinkManagerTest, Start) { |
| 274 | MockEventDispatcher dispatcher; |
| 275 | |
| 276 | EXPECT_CALL(dispatcher, CreateInputHandler(_, _, _)); |
| 277 | netlink_manager_->Start(&dispatcher); |
| 278 | } |
| 279 | |
| 280 | TEST_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 Guthrie | bee87c2 | 2013-03-06 11:00:46 -0800 | [diff] [blame] | 305 | |
Wade Guthrie | fa2100e | 2013-05-15 10:11:22 -0700 | [diff] [blame] | 306 | TEST_F(NetlinkManagerTest, GetFamily) { |
| 307 | const uint16_t kSampleMessageType = 42; |
| 308 | const string kSampleMessageName("SampleMessageName"); |
| 309 | const uint32_t kRandomSequenceNumber = 3; |
Wade Guthrie | 5d3d6de | 2012-11-02 11:08:34 -0700 | [diff] [blame] | 310 | |
Wade Guthrie | fa2100e | 2013-05-15 10:11:22 -0700 | [diff] [blame] | 311 | 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 | |
| 336 | TEST_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 | |
| 369 | TEST_F(NetlinkManagerTest, GetFamilyTimeout) { |
| 370 | Reset(); |
| 371 | MockTime time; |
Wade Guthrie | 84db7ce | 2013-06-12 11:40:49 -0700 | [diff] [blame] | 372 | Time *old_time = netlink_manager_->time_; |
Wade Guthrie | fa2100e | 2013-05-15 10:11:22 -0700 | [diff] [blame] | 373 | 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 Guthrie | 84db7ce | 2013-06-12 11:40:49 -0700 | [diff] [blame] | 394 | netlink_manager_->time_ = old_time; |
Wade Guthrie | fa2100e | 2013-05-15 10:11:22 -0700 | [diff] [blame] | 395 | } |
| 396 | |
Wade Guthrie | bbe59f7 | 2013-05-21 08:45:39 -0700 | [diff] [blame] | 397 | TEST_F(NetlinkManagerTest, BroadcastHandler) { |
Wade Guthrie | 84db7ce | 2013-06-12 11:40:49 -0700 | [diff] [blame] | 398 | Reset(); |
Wade Guthrie | 5d3d6de | 2012-11-02 11:08:34 -0700 | [diff] [blame] | 399 | nlmsghdr *message = const_cast<nlmsghdr *>( |
| 400 | reinterpret_cast<const nlmsghdr *>(kNL80211_CMD_DISCONNECT)); |
| 401 | |
Wade Guthrie | 7347bf2 | 2013-04-30 11:21:51 -0700 | [diff] [blame] | 402 | MockHandlerNetlink handler1; |
| 403 | MockHandlerNetlink handler2; |
Wade Guthrie | 5d3d6de | 2012-11-02 11:08:34 -0700 | [diff] [blame] | 404 | |
Wade Guthrie | 71cb0a7 | 2013-02-27 10:27:18 -0800 | [diff] [blame] | 405 | // Simple, 1 handler, case. |
Wade Guthrie | c6c8196 | 2013-03-06 15:47:13 -0800 | [diff] [blame] | 406 | EXPECT_CALL(handler1, OnNetlinkMessage(_)).Times(1); |
Wade Guthrie | 12f113a | 2013-03-12 17:15:46 -0700 | [diff] [blame] | 407 | EXPECT_FALSE( |
Wade Guthrie | bb9fca2 | 2013-04-10 17:21:42 -0700 | [diff] [blame] | 408 | netlink_manager_->FindBroadcastHandler(handler1.on_netlink_message())); |
| 409 | netlink_manager_->AddBroadcastHandler(handler1.on_netlink_message()); |
Wade Guthrie | 12f113a | 2013-03-12 17:15:46 -0700 | [diff] [blame] | 410 | EXPECT_TRUE( |
Wade Guthrie | bb9fca2 | 2013-04-10 17:21:42 -0700 | [diff] [blame] | 411 | netlink_manager_->FindBroadcastHandler(handler1.on_netlink_message())); |
| 412 | netlink_manager_->OnNlMessageReceived(message); |
Wade Guthrie | 5d3d6de | 2012-11-02 11:08:34 -0700 | [diff] [blame] | 413 | |
Wade Guthrie | 71cb0a7 | 2013-02-27 10:27:18 -0800 | [diff] [blame] | 414 | // Add a second handler. |
Wade Guthrie | c6c8196 | 2013-03-06 15:47:13 -0800 | [diff] [blame] | 415 | EXPECT_CALL(handler1, OnNetlinkMessage(_)).Times(1); |
| 416 | EXPECT_CALL(handler2, OnNetlinkMessage(_)).Times(1); |
Wade Guthrie | bb9fca2 | 2013-04-10 17:21:42 -0700 | [diff] [blame] | 417 | netlink_manager_->AddBroadcastHandler(handler2.on_netlink_message()); |
| 418 | netlink_manager_->OnNlMessageReceived(message); |
Wade Guthrie | 5d3d6de | 2012-11-02 11:08:34 -0700 | [diff] [blame] | 419 | |
Wade Guthrie | 71cb0a7 | 2013-02-27 10:27:18 -0800 | [diff] [blame] | 420 | // Verify that a handler can't be added twice. |
Wade Guthrie | c6c8196 | 2013-03-06 15:47:13 -0800 | [diff] [blame] | 421 | EXPECT_CALL(handler1, OnNetlinkMessage(_)).Times(1); |
| 422 | EXPECT_CALL(handler2, OnNetlinkMessage(_)).Times(1); |
Wade Guthrie | bb9fca2 | 2013-04-10 17:21:42 -0700 | [diff] [blame] | 423 | netlink_manager_->AddBroadcastHandler(handler1.on_netlink_message()); |
| 424 | netlink_manager_->OnNlMessageReceived(message); |
Wade Guthrie | 5d3d6de | 2012-11-02 11:08:34 -0700 | [diff] [blame] | 425 | |
Wade Guthrie | 71cb0a7 | 2013-02-27 10:27:18 -0800 | [diff] [blame] | 426 | // Check that we can remove a handler. |
Wade Guthrie | c6c8196 | 2013-03-06 15:47:13 -0800 | [diff] [blame] | 427 | EXPECT_CALL(handler1, OnNetlinkMessage(_)).Times(0); |
| 428 | EXPECT_CALL(handler2, OnNetlinkMessage(_)).Times(1); |
Wade Guthrie | bb9fca2 | 2013-04-10 17:21:42 -0700 | [diff] [blame] | 429 | EXPECT_TRUE(netlink_manager_->RemoveBroadcastHandler( |
Wade Guthrie | c6c8196 | 2013-03-06 15:47:13 -0800 | [diff] [blame] | 430 | handler1.on_netlink_message())); |
Wade Guthrie | bb9fca2 | 2013-04-10 17:21:42 -0700 | [diff] [blame] | 431 | netlink_manager_->OnNlMessageReceived(message); |
Wade Guthrie | 5d3d6de | 2012-11-02 11:08:34 -0700 | [diff] [blame] | 432 | |
Wade Guthrie | 71cb0a7 | 2013-02-27 10:27:18 -0800 | [diff] [blame] | 433 | // Check that re-adding the handler goes smoothly. |
Wade Guthrie | c6c8196 | 2013-03-06 15:47:13 -0800 | [diff] [blame] | 434 | EXPECT_CALL(handler1, OnNetlinkMessage(_)).Times(1); |
| 435 | EXPECT_CALL(handler2, OnNetlinkMessage(_)).Times(1); |
Wade Guthrie | bb9fca2 | 2013-04-10 17:21:42 -0700 | [diff] [blame] | 436 | netlink_manager_->AddBroadcastHandler(handler1.on_netlink_message()); |
| 437 | netlink_manager_->OnNlMessageReceived(message); |
Wade Guthrie | 5d3d6de | 2012-11-02 11:08:34 -0700 | [diff] [blame] | 438 | |
Wade Guthrie | 71cb0a7 | 2013-02-27 10:27:18 -0800 | [diff] [blame] | 439 | // Check that ClearBroadcastHandlers works. |
Wade Guthrie | bb9fca2 | 2013-04-10 17:21:42 -0700 | [diff] [blame] | 440 | netlink_manager_->ClearBroadcastHandlers(); |
Wade Guthrie | c6c8196 | 2013-03-06 15:47:13 -0800 | [diff] [blame] | 441 | EXPECT_CALL(handler1, OnNetlinkMessage(_)).Times(0); |
| 442 | EXPECT_CALL(handler2, OnNetlinkMessage(_)).Times(0); |
Wade Guthrie | bb9fca2 | 2013-04-10 17:21:42 -0700 | [diff] [blame] | 443 | netlink_manager_->OnNlMessageReceived(message); |
Wade Guthrie | 5d3d6de | 2012-11-02 11:08:34 -0700 | [diff] [blame] | 444 | } |
| 445 | |
Wade Guthrie | bbe59f7 | 2013-05-21 08:45:39 -0700 | [diff] [blame] | 446 | TEST_F(NetlinkManagerTest, MessageHandler) { |
Wade Guthrie | fa2100e | 2013-05-15 10:11:22 -0700 | [diff] [blame] | 447 | Reset(); |
Wade Guthrie | 7347bf2 | 2013-04-30 11:21:51 -0700 | [diff] [blame] | 448 | MockHandlerNetlink handler_broadcast; |
Wade Guthrie | bb9fca2 | 2013-04-10 17:21:42 -0700 | [diff] [blame] | 449 | EXPECT_TRUE(netlink_manager_->AddBroadcastHandler( |
Wade Guthrie | c6c8196 | 2013-03-06 15:47:13 -0800 | [diff] [blame] | 450 | handler_broadcast.on_netlink_message())); |
Wade Guthrie | 5d3d6de | 2012-11-02 11:08:34 -0700 | [diff] [blame] | 451 | |
repo sync | dc085c8 | 2012-12-28 08:54:41 -0800 | [diff] [blame] | 452 | Nl80211Message sent_message_1(CTRL_CMD_GETFAMILY, kGetFamilyCommandString); |
Wade Guthrie | 71cb0a7 | 2013-02-27 10:27:18 -0800 | [diff] [blame] | 453 | MockHandler80211 handler_sent_1; |
Wade Guthrie | 5d3d6de | 2012-11-02 11:08:34 -0700 | [diff] [blame] | 454 | |
repo sync | dc085c8 | 2012-12-28 08:54:41 -0800 | [diff] [blame] | 455 | Nl80211Message sent_message_2(CTRL_CMD_GETFAMILY, kGetFamilyCommandString); |
Wade Guthrie | 71cb0a7 | 2013-02-27 10:27:18 -0800 | [diff] [blame] | 456 | MockHandler80211 handler_sent_2; |
Wade Guthrie | 5d3d6de | 2012-11-02 11:08:34 -0700 | [diff] [blame] | 457 | |
| 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 Guthrie | 5d3d6de | 2012-11-02 11:08:34 -0700 | [diff] [blame] | 465 | |
| 466 | // Now, we can start the actual test... |
| 467 | |
Wade Guthrie | 71cb0a7 | 2013-02-27 10:27:18 -0800 | [diff] [blame] | 468 | // Verify that generic handler gets called for a message when no |
| 469 | // message-specific handler has been installed. |
Wade Guthrie | c6c8196 | 2013-03-06 15:47:13 -0800 | [diff] [blame] | 470 | EXPECT_CALL(handler_broadcast, OnNetlinkMessage(_)).Times(1); |
Wade Guthrie | bb9fca2 | 2013-04-10 17:21:42 -0700 | [diff] [blame] | 471 | netlink_manager_->OnNlMessageReceived(received_message); |
Wade Guthrie | 5d3d6de | 2012-11-02 11:08:34 -0700 | [diff] [blame] | 472 | |
Wade Guthrie | 71cb0a7 | 2013-02-27 10:27:18 -0800 | [diff] [blame] | 473 | // Send the message and give our handler. Verify that we get called back. |
Wade Guthrie | 7347bf2 | 2013-04-30 11:21:51 -0700 | [diff] [blame] | 474 | 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 Wiley | 393b93f | 2012-11-08 17:30:58 -0800 | [diff] [blame] | 479 | // Make it appear that this message is in response to our sent message. |
Wade Guthrie | fa2100e | 2013-05-15 10:11:22 -0700 | [diff] [blame] | 480 | received_message->nlmsg_seq = netlink_socket_.GetLastSequenceNumber(); |
Wade Guthrie | c6c8196 | 2013-03-06 15:47:13 -0800 | [diff] [blame] | 481 | EXPECT_CALL(handler_sent_1, OnNetlinkMessage(_)).Times(1); |
Wade Guthrie | bb9fca2 | 2013-04-10 17:21:42 -0700 | [diff] [blame] | 482 | netlink_manager_->OnNlMessageReceived(received_message); |
Wade Guthrie | 5d3d6de | 2012-11-02 11:08:34 -0700 | [diff] [blame] | 483 | |
Wade Guthrie | 71cb0a7 | 2013-02-27 10:27:18 -0800 | [diff] [blame] | 484 | // Verify that broadcast handler is called for the message after the |
| 485 | // message-specific handler is called once. |
Wade Guthrie | c6c8196 | 2013-03-06 15:47:13 -0800 | [diff] [blame] | 486 | EXPECT_CALL(handler_broadcast, OnNetlinkMessage(_)).Times(1); |
Wade Guthrie | bb9fca2 | 2013-04-10 17:21:42 -0700 | [diff] [blame] | 487 | netlink_manager_->OnNlMessageReceived(received_message); |
Wade Guthrie | 5d3d6de | 2012-11-02 11:08:34 -0700 | [diff] [blame] | 488 | |
Wade Guthrie | 71cb0a7 | 2013-02-27 10:27:18 -0800 | [diff] [blame] | 489 | // Install and then uninstall message-specific handler; verify broadcast |
| 490 | // handler is called on message receipt. |
Wade Guthrie | 7347bf2 | 2013-04-30 11:21:51 -0700 | [diff] [blame] | 491 | EXPECT_TRUE(netlink_manager_->SendNl80211Message( |
| 492 | &sent_message_1, handler_sent_1.on_netlink_message(), |
| 493 | null_error_handler)); |
Wade Guthrie | fa2100e | 2013-05-15 10:11:22 -0700 | [diff] [blame] | 494 | received_message->nlmsg_seq = netlink_socket_.GetLastSequenceNumber(); |
Wade Guthrie | bb9fca2 | 2013-04-10 17:21:42 -0700 | [diff] [blame] | 495 | EXPECT_TRUE(netlink_manager_->RemoveMessageHandler(sent_message_1)); |
Wade Guthrie | c6c8196 | 2013-03-06 15:47:13 -0800 | [diff] [blame] | 496 | EXPECT_CALL(handler_broadcast, OnNetlinkMessage(_)).Times(1); |
Wade Guthrie | bb9fca2 | 2013-04-10 17:21:42 -0700 | [diff] [blame] | 497 | netlink_manager_->OnNlMessageReceived(received_message); |
Wade Guthrie | 5d3d6de | 2012-11-02 11:08:34 -0700 | [diff] [blame] | 498 | |
Wade Guthrie | 71cb0a7 | 2013-02-27 10:27:18 -0800 | [diff] [blame] | 499 | // Install handler for different message; verify that broadcast handler is |
Wade Guthrie | 5d3d6de | 2012-11-02 11:08:34 -0700 | [diff] [blame] | 500 | // called for _this_ message. |
Wade Guthrie | 7347bf2 | 2013-04-30 11:21:51 -0700 | [diff] [blame] | 501 | EXPECT_TRUE(netlink_manager_->SendNl80211Message( |
| 502 | &sent_message_2, handler_sent_2.on_netlink_message(), |
| 503 | null_error_handler)); |
Wade Guthrie | c6c8196 | 2013-03-06 15:47:13 -0800 | [diff] [blame] | 504 | EXPECT_CALL(handler_broadcast, OnNetlinkMessage(_)).Times(1); |
Wade Guthrie | bb9fca2 | 2013-04-10 17:21:42 -0700 | [diff] [blame] | 505 | netlink_manager_->OnNlMessageReceived(received_message); |
Wade Guthrie | 5d3d6de | 2012-11-02 11:08:34 -0700 | [diff] [blame] | 506 | |
Wade Guthrie | 71cb0a7 | 2013-02-27 10:27:18 -0800 | [diff] [blame] | 507 | // Change the ID for the message to that of the second handler; verify that |
| 508 | // the appropriate handler is called for _that_ message. |
Wade Guthrie | fa2100e | 2013-05-15 10:11:22 -0700 | [diff] [blame] | 509 | received_message->nlmsg_seq = netlink_socket_.GetLastSequenceNumber(); |
Wade Guthrie | c6c8196 | 2013-03-06 15:47:13 -0800 | [diff] [blame] | 510 | EXPECT_CALL(handler_sent_2, OnNetlinkMessage(_)).Times(1); |
Wade Guthrie | bb9fca2 | 2013-04-10 17:21:42 -0700 | [diff] [blame] | 511 | netlink_manager_->OnNlMessageReceived(received_message); |
Wade Guthrie | 5d3d6de | 2012-11-02 11:08:34 -0700 | [diff] [blame] | 512 | } |
| 513 | |
Wade Guthrie | bbe59f7 | 2013-05-21 08:45:39 -0700 | [diff] [blame] | 514 | TEST_F(NetlinkManagerTest, MultipartMessageHandler) { |
| 515 | Reset(); |
| 516 | |
| 517 | // Install a broadcast handler. |
Wade Guthrie | 7347bf2 | 2013-04-30 11:21:51 -0700 | [diff] [blame] | 518 | MockHandlerNetlink broadcast_handler; |
Wade Guthrie | bbe59f7 | 2013-05-21 08:45:39 -0700 | [diff] [blame] | 519 | 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 Guthrie | 7347bf2 | 2013-04-30 11:21:51 -0700 | [diff] [blame] | 525 | MockHandlerNetlinkAuxilliary auxilliary_handler; |
Wade Guthrie | bbe59f7 | 2013-05-21 08:45:39 -0700 | [diff] [blame] | 526 | EXPECT_CALL(netlink_socket_, SendMessage(_)).WillOnce(Return(true)); |
Wade Guthrie | 7347bf2 | 2013-04-30 11:21:51 -0700 | [diff] [blame] | 527 | 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 Guthrie | bbe59f7 | 2013-05-21 08:45:39 -0700 | [diff] [blame] | 531 | |
| 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 Guthrie | 84db7ce | 2013-06-12 11:40:49 -0700 | [diff] [blame] | 556 | EXPECT_CALL(auxilliary_handler, OnErrorHandler(_, _)); |
Wade Guthrie | bbe59f7 | 2013-05-21 08:45:39 -0700 | [diff] [blame] | 557 | 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 Guthrie | 84db7ce | 2013-06-12 11:40:49 -0700 | [diff] [blame] | 563 | EXPECT_CALL(auxilliary_handler, OnErrorHandler(_, _)).Times(0); |
Wade Guthrie | bbe59f7 | 2013-05-21 08:45:39 -0700 | [diff] [blame] | 564 | EXPECT_CALL(broadcast_handler, OnNetlinkMessage(_)).Times(1); |
| 565 | netlink_manager_->OnNlMessageReceived(received_message); |
| 566 | } |
| 567 | |
Wade Guthrie | 84db7ce | 2013-06-12 11:40:49 -0700 | [diff] [blame] | 568 | TEST_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 Guthrie | 0d43853 | 2012-05-18 14:18:50 -0700 | [diff] [blame] | 645 | } // namespace shill |