cc: Added inline to Tile::IsReadyToDraw
[chromium-blink-merge.git] / net / base / address_tracker_linux_unittest.cc
bloba9feed491dca516a3f569795c675f2b66518c276
1 // Copyright (c) 2012 The Chromium 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.
5 #include "net/base/address_tracker_linux.h"
7 #include <linux/if.h>
9 #include <vector>
11 #include "base/bind.h"
12 #include "testing/gtest/include/gtest/gtest.h"
14 namespace net {
15 namespace internal {
17 typedef std::vector<char> Buffer;
19 void Noop() {}
21 class AddressTrackerLinuxTest : public testing::Test {
22 protected:
23 AddressTrackerLinuxTest() : tracker_(base::Bind(&Noop), base::Bind(&Noop)) {}
25 bool HandleAddressMessage(const Buffer& buf) {
26 bool address_changed = false;
27 bool link_changed = false;
28 tracker_.HandleMessage(&buf[0], buf.size(),
29 &address_changed, &link_changed);
30 EXPECT_FALSE(link_changed);
31 return address_changed;
34 bool HandleLinkMessage(const Buffer& buf) {
35 bool address_changed = false;
36 bool link_changed = false;
37 tracker_.HandleMessage(&buf[0], buf.size(),
38 &address_changed, &link_changed);
39 EXPECT_FALSE(address_changed);
40 return link_changed;
43 AddressTrackerLinux::AddressMap GetAddressMap() {
44 return tracker_.GetAddressMap();
47 const base::hash_set<int>* GetOnlineLinks() const {
48 return &tracker_.online_links_;
51 AddressTrackerLinux tracker_;
54 namespace {
56 class NetlinkMessage {
57 public:
58 explicit NetlinkMessage(uint16 type) : buffer_(NLMSG_HDRLEN) {
59 header()->nlmsg_type = type;
60 Align();
63 void AddPayload(const void* data, size_t length) {
64 CHECK_EQ(static_cast<size_t>(NLMSG_HDRLEN),
65 buffer_.size()) << "Payload must be added first";
66 Append(data, length);
67 Align();
70 void AddAttribute(uint16 type, const void* data, size_t length) {
71 struct nlattr attr;
72 attr.nla_len = NLA_HDRLEN + length;
73 attr.nla_type = type;
74 Append(&attr, sizeof(attr));
75 Align();
76 Append(data, length);
77 Align();
80 void AppendTo(Buffer* output) const {
81 CHECK_EQ(NLMSG_ALIGN(output->size()), output->size());
82 output->reserve(output->size() + NLMSG_LENGTH(buffer_.size()));
83 output->insert(output->end(), buffer_.begin(), buffer_.end());
86 private:
87 void Append(const void* data, size_t length) {
88 const char* chardata = reinterpret_cast<const char*>(data);
89 buffer_.insert(buffer_.end(), chardata, chardata + length);
92 void Align() {
93 header()->nlmsg_len = buffer_.size();
94 buffer_.insert(buffer_.end(), NLMSG_ALIGN(buffer_.size()) - buffer_.size(),
95 0);
96 CHECK(NLMSG_OK(header(), buffer_.size()));
99 struct nlmsghdr* header() {
100 return reinterpret_cast<struct nlmsghdr*>(&buffer_[0]);
103 Buffer buffer_;
106 void MakeAddrMessage(uint16 type,
107 uint8 flags,
108 uint8 family,
109 const IPAddressNumber& address,
110 const IPAddressNumber& local,
111 Buffer* output) {
112 NetlinkMessage nlmsg(type);
113 struct ifaddrmsg msg = {};
114 msg.ifa_family = family;
115 msg.ifa_flags = flags;
116 nlmsg.AddPayload(&msg, sizeof(msg));
117 if (address.size())
118 nlmsg.AddAttribute(IFA_ADDRESS, &address[0], address.size());
119 if (local.size())
120 nlmsg.AddAttribute(IFA_LOCAL, &local[0], local.size());
121 nlmsg.AppendTo(output);
124 void MakeLinkMessage(uint16 type, uint32 flags, uint32 index, Buffer* output) {
125 NetlinkMessage nlmsg(type);
126 struct ifinfomsg msg = {};
127 msg.ifi_index = index;
128 msg.ifi_flags = flags;
129 nlmsg.AddPayload(&msg, sizeof(msg));
130 output->clear();
131 nlmsg.AppendTo(output);
134 const unsigned char kAddress0[] = { 127, 0, 0, 1 };
135 const unsigned char kAddress1[] = { 10, 0, 0, 1 };
136 const unsigned char kAddress2[] = { 192, 168, 0, 1 };
137 const unsigned char kAddress3[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
138 0, 0, 0, 1 };
139 const unsigned char kAddress4[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255,
140 169, 254, 0, 1 };
142 TEST_F(AddressTrackerLinuxTest, NewAddress) {
143 const IPAddressNumber kEmpty;
144 const IPAddressNumber kAddr0(kAddress0, kAddress0 + arraysize(kAddress0));
145 const IPAddressNumber kAddr1(kAddress1, kAddress1 + arraysize(kAddress1));
146 const IPAddressNumber kAddr2(kAddress2, kAddress2 + arraysize(kAddress2));
147 const IPAddressNumber kAddr3(kAddress3, kAddress3 + arraysize(kAddress3));
149 Buffer buffer;
150 MakeAddrMessage(RTM_NEWADDR, IFA_F_TEMPORARY, AF_INET, kAddr0, kEmpty,
151 &buffer);
152 EXPECT_TRUE(HandleAddressMessage(buffer));
153 AddressTrackerLinux::AddressMap map = GetAddressMap();
154 EXPECT_EQ(1u, map.size());
155 EXPECT_EQ(1u, map.count(kAddr0));
156 EXPECT_EQ(IFA_F_TEMPORARY, map[kAddr0].ifa_flags);
158 buffer.clear();
159 MakeAddrMessage(RTM_NEWADDR, IFA_F_HOMEADDRESS, AF_INET, kAddr1, kAddr2,
160 &buffer);
161 EXPECT_TRUE(HandleAddressMessage(buffer));
162 map = GetAddressMap();
163 EXPECT_EQ(2u, map.size());
164 EXPECT_EQ(1u, map.count(kAddr0));
165 EXPECT_EQ(1u, map.count(kAddr2));
166 EXPECT_EQ(IFA_F_HOMEADDRESS, map[kAddr2].ifa_flags);
168 buffer.clear();
169 MakeAddrMessage(RTM_NEWADDR, 0, AF_INET6, kEmpty, kAddr3, &buffer);
170 EXPECT_TRUE(HandleAddressMessage(buffer));
171 map = GetAddressMap();
172 EXPECT_EQ(3u, map.size());
173 EXPECT_EQ(1u, map.count(kAddr3));
176 TEST_F(AddressTrackerLinuxTest, NewAddressChange) {
177 const IPAddressNumber kEmpty;
178 const IPAddressNumber kAddr0(kAddress0, kAddress0 + arraysize(kAddress0));
180 Buffer buffer;
181 MakeAddrMessage(RTM_NEWADDR, IFA_F_TEMPORARY, AF_INET, kAddr0, kEmpty,
182 &buffer);
183 EXPECT_TRUE(HandleAddressMessage(buffer));
184 AddressTrackerLinux::AddressMap map = GetAddressMap();
185 EXPECT_EQ(1u, map.size());
186 EXPECT_EQ(1u, map.count(kAddr0));
187 EXPECT_EQ(IFA_F_TEMPORARY, map[kAddr0].ifa_flags);
189 buffer.clear();
190 MakeAddrMessage(RTM_NEWADDR, IFA_F_HOMEADDRESS, AF_INET, kAddr0, kEmpty,
191 &buffer);
192 EXPECT_TRUE(HandleAddressMessage(buffer));
193 map = GetAddressMap();
194 EXPECT_EQ(1u, map.size());
195 EXPECT_EQ(1u, map.count(kAddr0));
196 EXPECT_EQ(IFA_F_HOMEADDRESS, map[kAddr0].ifa_flags);
198 // Both messages in one buffer.
199 buffer.clear();
200 MakeAddrMessage(RTM_NEWADDR, IFA_F_TEMPORARY, AF_INET, kAddr0, kEmpty,
201 &buffer);
202 MakeAddrMessage(RTM_NEWADDR, IFA_F_HOMEADDRESS, AF_INET, kAddr0, kEmpty,
203 &buffer);
204 EXPECT_TRUE(HandleAddressMessage(buffer));
205 map = GetAddressMap();
206 EXPECT_EQ(1u, map.size());
207 EXPECT_EQ(IFA_F_HOMEADDRESS, map[kAddr0].ifa_flags);
210 TEST_F(AddressTrackerLinuxTest, NewAddressDuplicate) {
211 const IPAddressNumber kAddr0(kAddress0, kAddress0 + arraysize(kAddress0));
213 Buffer buffer;
214 MakeAddrMessage(RTM_NEWADDR, IFA_F_TEMPORARY, AF_INET, kAddr0, kAddr0,
215 &buffer);
216 EXPECT_TRUE(HandleAddressMessage(buffer));
217 AddressTrackerLinux::AddressMap map = GetAddressMap();
218 EXPECT_EQ(1u, map.size());
219 EXPECT_EQ(1u, map.count(kAddr0));
220 EXPECT_EQ(IFA_F_TEMPORARY, map[kAddr0].ifa_flags);
222 EXPECT_FALSE(HandleAddressMessage(buffer));
223 map = GetAddressMap();
224 EXPECT_EQ(1u, map.size());
225 EXPECT_EQ(IFA_F_TEMPORARY, map[kAddr0].ifa_flags);
228 TEST_F(AddressTrackerLinuxTest, DeleteAddress) {
229 const IPAddressNumber kEmpty;
230 const IPAddressNumber kAddr0(kAddress0, kAddress0 + arraysize(kAddress0));
231 const IPAddressNumber kAddr1(kAddress1, kAddress1 + arraysize(kAddress1));
232 const IPAddressNumber kAddr2(kAddress2, kAddress2 + arraysize(kAddress2));
234 Buffer buffer;
235 MakeAddrMessage(RTM_NEWADDR, 0, AF_INET, kAddr0, kEmpty, &buffer);
236 MakeAddrMessage(RTM_NEWADDR, 0, AF_INET, kAddr1, kAddr2, &buffer);
237 EXPECT_TRUE(HandleAddressMessage(buffer));
238 AddressTrackerLinux::AddressMap map = GetAddressMap();
239 EXPECT_EQ(2u, map.size());
241 buffer.clear();
242 MakeAddrMessage(RTM_DELADDR, 0, AF_INET, kEmpty, kAddr0, &buffer);
243 EXPECT_TRUE(HandleAddressMessage(buffer));
244 map = GetAddressMap();
245 EXPECT_EQ(1u, map.size());
246 EXPECT_EQ(0u, map.count(kAddr0));
247 EXPECT_EQ(1u, map.count(kAddr2));
249 buffer.clear();
250 MakeAddrMessage(RTM_DELADDR, 0, AF_INET, kAddr2, kAddr1, &buffer);
251 // kAddr1 does not exist in the map.
252 EXPECT_FALSE(HandleAddressMessage(buffer));
253 map = GetAddressMap();
254 EXPECT_EQ(1u, map.size());
256 buffer.clear();
257 MakeAddrMessage(RTM_DELADDR, 0, AF_INET, kAddr2, kEmpty, &buffer);
258 EXPECT_TRUE(HandleAddressMessage(buffer));
259 map = GetAddressMap();
260 EXPECT_EQ(0u, map.size());
263 TEST_F(AddressTrackerLinuxTest, IgnoredMessage) {
264 const IPAddressNumber kEmpty;
265 const IPAddressNumber kAddr0(kAddress0, kAddress0 + arraysize(kAddress0));
266 const IPAddressNumber kAddr3(kAddress3, kAddress3 + arraysize(kAddress3));
268 Buffer buffer;
269 // Ignored family.
270 MakeAddrMessage(RTM_NEWADDR, 0, AF_UNSPEC, kAddr3, kAddr0, &buffer);
271 // No address.
272 MakeAddrMessage(RTM_NEWADDR, 0, AF_INET, kEmpty, kEmpty, &buffer);
273 // Ignored type.
274 MakeAddrMessage(RTM_DELROUTE, 0, AF_INET6, kAddr3, kEmpty, &buffer);
275 EXPECT_FALSE(HandleAddressMessage(buffer));
276 EXPECT_TRUE(GetAddressMap().empty());
278 // Valid message after ignored messages.
279 NetlinkMessage nlmsg(RTM_NEWADDR);
280 struct ifaddrmsg msg = {};
281 msg.ifa_family = AF_INET;
282 nlmsg.AddPayload(&msg, sizeof(msg));
283 // Ignored attribute.
284 struct ifa_cacheinfo cache_info = {};
285 nlmsg.AddAttribute(IFA_CACHEINFO, &cache_info, sizeof(cache_info));
286 nlmsg.AddAttribute(IFA_ADDRESS, &kAddr0[0], kAddr0.size());
287 nlmsg.AppendTo(&buffer);
289 EXPECT_TRUE(HandleAddressMessage(buffer));
290 EXPECT_EQ(1u, GetAddressMap().size());
293 TEST_F(AddressTrackerLinuxTest, AddInterface) {
294 Buffer buffer;
296 // Ignores loopback.
297 MakeLinkMessage(RTM_NEWLINK,
298 IFF_LOOPBACK | IFF_UP | IFF_LOWER_UP | IFF_RUNNING,
299 0, &buffer);
300 EXPECT_FALSE(HandleLinkMessage(buffer));
301 EXPECT_TRUE(GetOnlineLinks()->empty());
303 // Ignores not IFF_LOWER_UP.
304 MakeLinkMessage(RTM_NEWLINK, IFF_UP | IFF_RUNNING, 0, &buffer);
305 EXPECT_FALSE(HandleLinkMessage(buffer));
306 EXPECT_TRUE(GetOnlineLinks()->empty());
308 // Ignores deletion.
309 MakeLinkMessage(RTM_DELLINK, IFF_UP | IFF_LOWER_UP | IFF_RUNNING, 0, &buffer);
310 EXPECT_FALSE(HandleLinkMessage(buffer));
311 EXPECT_TRUE(GetOnlineLinks()->empty());
313 // Verify success.
314 MakeLinkMessage(RTM_NEWLINK, IFF_UP | IFF_LOWER_UP | IFF_RUNNING, 0, &buffer);
315 EXPECT_TRUE(HandleLinkMessage(buffer));
316 EXPECT_EQ(1u, GetOnlineLinks()->count(0));
317 EXPECT_EQ(1u, GetOnlineLinks()->size());
319 // Ignores redundant enables.
320 MakeLinkMessage(RTM_NEWLINK, IFF_UP | IFF_LOWER_UP | IFF_RUNNING, 0, &buffer);
321 EXPECT_FALSE(HandleLinkMessage(buffer));
322 EXPECT_EQ(1u, GetOnlineLinks()->count(0));
323 EXPECT_EQ(1u, GetOnlineLinks()->size());
325 // Verify adding another online device (e.g. VPN) is considered a change.
326 MakeLinkMessage(RTM_NEWLINK, IFF_UP | IFF_LOWER_UP | IFF_RUNNING, 1, &buffer);
327 EXPECT_TRUE(HandleLinkMessage(buffer));
328 EXPECT_EQ(1u, GetOnlineLinks()->count(0));
329 EXPECT_EQ(1u, GetOnlineLinks()->count(1));
330 EXPECT_EQ(2u, GetOnlineLinks()->size());
333 TEST_F(AddressTrackerLinuxTest, RemoveInterface) {
334 Buffer buffer;
336 // Should disappear when not IFF_LOWER_UP.
337 MakeLinkMessage(RTM_NEWLINK, IFF_UP | IFF_LOWER_UP | IFF_RUNNING, 0, &buffer);
338 EXPECT_TRUE(HandleLinkMessage(buffer));
339 EXPECT_FALSE(GetOnlineLinks()->empty());
340 MakeLinkMessage(RTM_NEWLINK, IFF_UP | IFF_RUNNING, 0, &buffer);
341 EXPECT_TRUE(HandleLinkMessage(buffer));
342 EXPECT_TRUE(GetOnlineLinks()->empty());
344 // Ignores redundant disables.
345 MakeLinkMessage(RTM_NEWLINK, IFF_UP | IFF_RUNNING, 0, &buffer);
346 EXPECT_FALSE(HandleLinkMessage(buffer));
347 EXPECT_TRUE(GetOnlineLinks()->empty());
349 // Ignores deleting down interfaces.
350 MakeLinkMessage(RTM_DELLINK, IFF_UP | IFF_RUNNING, 0, &buffer);
351 EXPECT_FALSE(HandleLinkMessage(buffer));
352 EXPECT_TRUE(GetOnlineLinks()->empty());
354 // Should disappear when deleted.
355 MakeLinkMessage(RTM_NEWLINK, IFF_UP | IFF_LOWER_UP | IFF_RUNNING, 0, &buffer);
356 EXPECT_TRUE(HandleLinkMessage(buffer));
357 EXPECT_FALSE(GetOnlineLinks()->empty());
358 MakeLinkMessage(RTM_DELLINK, IFF_UP | IFF_LOWER_UP | IFF_RUNNING, 0, &buffer);
359 EXPECT_TRUE(HandleLinkMessage(buffer));
360 EXPECT_TRUE(GetOnlineLinks()->empty());
363 } // namespace
365 } // namespace internal
366 } // namespace net