blob: 52da79a18c6e5e32eaf8b906a1a48e1832b166f0 [file] [log] [blame]
John Wang3e567d52011-04-04 12:35:42 -07001/*
2 * Copyright (C) 2010 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package android.net;
18
Hugo Benichi39989e72017-10-12 09:54:49 +090019import static org.junit.Assert.assertEquals;
20import static org.junit.Assert.assertFalse;
21import static org.junit.Assert.assertTrue;
22import static org.junit.Assert.fail;
23
Erik Kline1c8fab52015-06-26 19:21:34 +090024import android.net.IpPrefix;
25import android.net.LinkAddress;
John Wang3e567d52011-04-04 12:35:42 -070026import android.net.LinkProperties;
Rubin Xu8cb82d22017-08-22 16:35:52 +010027import android.net.LinkProperties.CompareResult;
Erik Kline0e801362015-05-21 16:15:02 +090028import android.net.LinkProperties.ProvisioningChange;
Robert Greenwalt5a901292011-04-28 14:28:50 -070029import android.net.RouteInfo;
Hugo Benichi39989e72017-10-12 09:54:49 +090030import android.support.test.filters.SmallTest;
31import android.support.test.runner.AndroidJUnit4;
Elliott Hughes7ab81622014-04-28 11:11:32 -070032import android.system.OsConstants;
Rubin Xu57b437a2017-09-05 18:40:49 +010033import android.util.ArraySet;
34
John Wang3e567d52011-04-04 12:35:42 -070035import java.net.InetAddress;
Rubin Xu8cb82d22017-08-22 16:35:52 +010036import java.util.ArrayList;
Rubin Xu57b437a2017-09-05 18:40:49 +010037import java.util.Arrays;
38import java.util.Collection;
39import java.util.Collections;
Rubin Xu8cb82d22017-08-22 16:35:52 +010040import java.util.List;
Rubin Xu57b437a2017-09-05 18:40:49 +010041import java.util.Set;
John Wang3e567d52011-04-04 12:35:42 -070042
Hugo Benichi39989e72017-10-12 09:54:49 +090043import org.junit.Test;
44import org.junit.runner.RunWith;
Erik Kline1c8fab52015-06-26 19:21:34 +090045
Hugo Benichi39989e72017-10-12 09:54:49 +090046@RunWith(AndroidJUnit4.class)
47@SmallTest
48public class LinkPropertiesTest {
Lorenzo Colitti34b969b2013-08-08 10:56:22 +090049 private static InetAddress ADDRV4 = NetworkUtils.numericToInetAddress("75.208.6.1");
50 private static InetAddress ADDRV6 = NetworkUtils.numericToInetAddress(
51 "2001:0db8:85a3:0000:0000:8a2e:0370:7334");
52 private static InetAddress DNS1 = NetworkUtils.numericToInetAddress("75.208.7.1");
53 private static InetAddress DNS2 = NetworkUtils.numericToInetAddress("69.78.7.1");
Erik Klineba317782014-10-24 21:50:20 +090054 private static InetAddress DNS6 = NetworkUtils.numericToInetAddress("2001:4860:4860::8888");
Lorenzo Colitti34b969b2013-08-08 10:56:22 +090055 private static InetAddress GATEWAY1 = NetworkUtils.numericToInetAddress("75.208.8.1");
56 private static InetAddress GATEWAY2 = NetworkUtils.numericToInetAddress("69.78.8.1");
Erik Kline0e801362015-05-21 16:15:02 +090057 private static InetAddress GATEWAY61 = NetworkUtils.numericToInetAddress("fe80::6:0000:613");
58 private static InetAddress GATEWAY62 = NetworkUtils.numericToInetAddress("fe80::6:2222");
John Wang3e567d52011-04-04 12:35:42 -070059 private static String NAME = "qmi0";
sy.yun30043282013-09-02 05:24:09 +090060 private static int MTU = 1500;
John Wang3e567d52011-04-04 12:35:42 -070061
Lorenzo Colitti34b969b2013-08-08 10:56:22 +090062 private static LinkAddress LINKADDRV4 = new LinkAddress(ADDRV4, 32);
63 private static LinkAddress LINKADDRV6 = new LinkAddress(ADDRV6, 128);
Lorenzo Colittibf1b0002014-06-23 22:33:43 +090064 private static LinkAddress LINKADDRV6LINKLOCAL = new LinkAddress("fe80::1/64");
Lorenzo Colitti34b969b2013-08-08 10:56:22 +090065
Lorenzo Colitti319789d2015-07-30 23:41:43 +090066 // TODO: replace all calls to NetworkUtils.numericToInetAddress with calls to this method.
67 private InetAddress Address(String addrString) {
68 return NetworkUtils.numericToInetAddress(addrString);
69 }
70
Lorenzo Colittic3787fa2013-04-01 10:47:43 +090071 public void assertLinkPropertiesEqual(LinkProperties source, LinkProperties target) {
72 // Check implementation of equals(), element by element.
73 assertTrue(source.isIdenticalInterfaceName(target));
74 assertTrue(target.isIdenticalInterfaceName(source));
75
76 assertTrue(source.isIdenticalAddresses(target));
77 assertTrue(target.isIdenticalAddresses(source));
78
79 assertTrue(source.isIdenticalDnses(target));
80 assertTrue(target.isIdenticalDnses(source));
81
82 assertTrue(source.isIdenticalRoutes(target));
83 assertTrue(target.isIdenticalRoutes(source));
84
85 assertTrue(source.isIdenticalHttpProxy(target));
86 assertTrue(target.isIdenticalHttpProxy(source));
87
88 assertTrue(source.isIdenticalStackedLinks(target));
89 assertTrue(target.isIdenticalStackedLinks(source));
90
sy.yun30043282013-09-02 05:24:09 +090091 assertTrue(source.isIdenticalMtu(target));
92 assertTrue(target.isIdenticalMtu(source));
93
Lorenzo Colittic3787fa2013-04-01 10:47:43 +090094 // Check result of equals().
95 assertTrue(source.equals(target));
96 assertTrue(target.equals(source));
97
98 // Check hashCode.
99 assertEquals(source.hashCode(), target.hashCode());
100 }
101
Hugo Benichi39989e72017-10-12 09:54:49 +0900102 @Test
John Wang3e567d52011-04-04 12:35:42 -0700103 public void testEqualsNull() {
104 LinkProperties source = new LinkProperties();
105 LinkProperties target = new LinkProperties();
106
107 assertFalse(source == target);
Lorenzo Colittic3787fa2013-04-01 10:47:43 +0900108 assertLinkPropertiesEqual(source, target);
John Wang3e567d52011-04-04 12:35:42 -0700109 }
110
Hugo Benichi39989e72017-10-12 09:54:49 +0900111 @Test
112 public void testEqualsSameOrder() throws Exception {
113 LinkProperties source = new LinkProperties();
114 source.setInterfaceName(NAME);
115 // set 2 link addresses
116 source.addLinkAddress(LINKADDRV4);
117 source.addLinkAddress(LINKADDRV6);
118 // set 2 dnses
119 source.addDnsServer(DNS1);
120 source.addDnsServer(DNS2);
121 // set 2 gateways
122 source.addRoute(new RouteInfo(GATEWAY1));
123 source.addRoute(new RouteInfo(GATEWAY2));
124 source.setMtu(MTU);
John Wang3e567d52011-04-04 12:35:42 -0700125
Hugo Benichi39989e72017-10-12 09:54:49 +0900126 LinkProperties target = new LinkProperties();
John Wang3e567d52011-04-04 12:35:42 -0700127
Hugo Benichi39989e72017-10-12 09:54:49 +0900128 // All fields are same
129 target.setInterfaceName(NAME);
130 target.addLinkAddress(LINKADDRV4);
131 target.addLinkAddress(LINKADDRV6);
132 target.addDnsServer(DNS1);
133 target.addDnsServer(DNS2);
134 target.addRoute(new RouteInfo(GATEWAY1));
135 target.addRoute(new RouteInfo(GATEWAY2));
136 target.setMtu(MTU);
John Wang3e567d52011-04-04 12:35:42 -0700137
Hugo Benichi39989e72017-10-12 09:54:49 +0900138 assertLinkPropertiesEqual(source, target);
John Wang3e567d52011-04-04 12:35:42 -0700139
Hugo Benichi39989e72017-10-12 09:54:49 +0900140 target.clear();
141 // change Interface Name
142 target.setInterfaceName("qmi1");
143 target.addLinkAddress(LINKADDRV4);
144 target.addLinkAddress(LINKADDRV6);
145 target.addDnsServer(DNS1);
146 target.addDnsServer(DNS2);
147 target.addRoute(new RouteInfo(GATEWAY1));
148 target.addRoute(new RouteInfo(GATEWAY2));
149 target.setMtu(MTU);
150 assertFalse(source.equals(target));
John Wang3e567d52011-04-04 12:35:42 -0700151
Hugo Benichi39989e72017-10-12 09:54:49 +0900152 target.clear();
153 target.setInterfaceName(NAME);
154 // change link addresses
155 target.addLinkAddress(new LinkAddress(
156 NetworkUtils.numericToInetAddress("75.208.6.2"), 32));
157 target.addLinkAddress(LINKADDRV6);
158 target.addDnsServer(DNS1);
159 target.addDnsServer(DNS2);
160 target.addRoute(new RouteInfo(GATEWAY1));
161 target.addRoute(new RouteInfo(GATEWAY2));
162 target.setMtu(MTU);
163 assertFalse(source.equals(target));
John Wang3e567d52011-04-04 12:35:42 -0700164
Hugo Benichi39989e72017-10-12 09:54:49 +0900165 target.clear();
166 target.setInterfaceName(NAME);
167 target.addLinkAddress(LINKADDRV4);
168 target.addLinkAddress(LINKADDRV6);
169 // change dnses
170 target.addDnsServer(NetworkUtils.numericToInetAddress("75.208.7.2"));
171 target.addDnsServer(DNS2);
172 target.addRoute(new RouteInfo(GATEWAY1));
173 target.addRoute(new RouteInfo(GATEWAY2));
174 target.setMtu(MTU);
175 assertFalse(source.equals(target));
John Wang3e567d52011-04-04 12:35:42 -0700176
Hugo Benichi39989e72017-10-12 09:54:49 +0900177 target.clear();
178 target.setInterfaceName(NAME);
179 target.addLinkAddress(LINKADDRV4);
180 target.addLinkAddress(LINKADDRV6);
181 target.addDnsServer(DNS1);
182 target.addDnsServer(DNS2);
183 // change gateway
184 target.addRoute(new RouteInfo(NetworkUtils.numericToInetAddress("75.208.8.2")));
185 target.addRoute(new RouteInfo(GATEWAY2));
186 target.setMtu(MTU);
187 assertFalse(source.equals(target));
sy.yun30043282013-09-02 05:24:09 +0900188
Hugo Benichi39989e72017-10-12 09:54:49 +0900189 target.clear();
190 target.setInterfaceName(NAME);
191 target.addLinkAddress(LINKADDRV4);
192 target.addLinkAddress(LINKADDRV6);
193 target.addDnsServer(DNS1);
194 target.addDnsServer(DNS2);
195 target.addRoute(new RouteInfo(GATEWAY1));
196 target.addRoute(new RouteInfo(GATEWAY2));
197 // change mtu
198 target.setMtu(1440);
199 assertFalse(source.equals(target));
John Wang3e567d52011-04-04 12:35:42 -0700200 }
201
Hugo Benichi39989e72017-10-12 09:54:49 +0900202 @Test
203 public void testEqualsDifferentOrder() throws Exception {
204 LinkProperties source = new LinkProperties();
205 source.setInterfaceName(NAME);
206 // set 2 link addresses
207 source.addLinkAddress(LINKADDRV4);
208 source.addLinkAddress(LINKADDRV6);
209 // set 2 dnses
210 source.addDnsServer(DNS1);
211 source.addDnsServer(DNS2);
212 // set 2 gateways
213 source.addRoute(new RouteInfo(GATEWAY1));
214 source.addRoute(new RouteInfo(GATEWAY2));
215 source.setMtu(MTU);
John Wang3e567d52011-04-04 12:35:42 -0700216
Hugo Benichi39989e72017-10-12 09:54:49 +0900217 LinkProperties target = new LinkProperties();
218 // Exchange order
219 target.setInterfaceName(NAME);
220 target.addLinkAddress(LINKADDRV6);
221 target.addLinkAddress(LINKADDRV4);
222 target.addDnsServer(DNS2);
223 target.addDnsServer(DNS1);
224 target.addRoute(new RouteInfo(GATEWAY2));
225 target.addRoute(new RouteInfo(GATEWAY1));
226 target.setMtu(MTU);
John Wang3e567d52011-04-04 12:35:42 -0700227
Hugo Benichi39989e72017-10-12 09:54:49 +0900228 assertLinkPropertiesEqual(source, target);
John Wang3e567d52011-04-04 12:35:42 -0700229 }
230
Hugo Benichi39989e72017-10-12 09:54:49 +0900231 @Test
232 public void testEqualsDuplicated() throws Exception {
233 LinkProperties source = new LinkProperties();
234 // set 3 link addresses, eg, [A, A, B]
235 source.addLinkAddress(LINKADDRV4);
236 source.addLinkAddress(LINKADDRV4);
237 source.addLinkAddress(LINKADDRV6);
John Wang3e567d52011-04-04 12:35:42 -0700238
Hugo Benichi39989e72017-10-12 09:54:49 +0900239 LinkProperties target = new LinkProperties();
240 // set 3 link addresses, eg, [A, B, B]
241 target.addLinkAddress(LINKADDRV4);
242 target.addLinkAddress(LINKADDRV6);
243 target.addLinkAddress(LINKADDRV6);
John Wang3e567d52011-04-04 12:35:42 -0700244
Hugo Benichi39989e72017-10-12 09:54:49 +0900245 assertLinkPropertiesEqual(source, target);
John Wang3e567d52011-04-04 12:35:42 -0700246 }
247
Lorenzo Colittiaaacefb2013-03-08 19:11:40 -0800248 private void assertAllRoutesHaveInterface(String iface, LinkProperties lp) {
249 for (RouteInfo r : lp.getRoutes()) {
250 assertEquals(iface, r.getInterface());
251 }
252 }
253
Hugo Benichi39989e72017-10-12 09:54:49 +0900254 @Test
Lorenzo Colittiaaacefb2013-03-08 19:11:40 -0800255 public void testRouteInterfaces() {
256 LinkAddress prefix = new LinkAddress(
257 NetworkUtils.numericToInetAddress("2001:db8::"), 32);
Lorenzo Colitti34b969b2013-08-08 10:56:22 +0900258 InetAddress address = ADDRV6;
Lorenzo Colittiaaacefb2013-03-08 19:11:40 -0800259
260 // Add a route with no interface to a LinkProperties with no interface. No errors.
261 LinkProperties lp = new LinkProperties();
262 RouteInfo r = new RouteInfo(prefix, address, null);
Lorenzo Colittifa6b2632014-06-23 21:16:34 +0900263 assertTrue(lp.addRoute(r));
Lorenzo Colittiaaacefb2013-03-08 19:11:40 -0800264 assertEquals(1, lp.getRoutes().size());
265 assertAllRoutesHaveInterface(null, lp);
266
Lorenzo Colittifa6b2632014-06-23 21:16:34 +0900267 // Adding the same route twice has no effect.
268 assertFalse(lp.addRoute(r));
269 assertEquals(1, lp.getRoutes().size());
270
271 // Add a route with an interface. Expect an exception.
Lorenzo Colittiaaacefb2013-03-08 19:11:40 -0800272 r = new RouteInfo(prefix, address, "wlan0");
273 try {
274 lp.addRoute(r);
275 fail("Adding wlan0 route to LP with no interface, expect exception");
276 } catch (IllegalArgumentException expected) {}
277
278 // Change the interface name. All the routes should change their interface name too.
279 lp.setInterfaceName("rmnet0");
280 assertAllRoutesHaveInterface("rmnet0", lp);
281
282 // Now add a route with the wrong interface. This causes an exception too.
283 try {
284 lp.addRoute(r);
285 fail("Adding wlan0 route to rmnet0 LP, expect exception");
286 } catch (IllegalArgumentException expected) {}
287
288 // If the interface name matches, the route is added.
Lorenzo Colittifa6b2632014-06-23 21:16:34 +0900289 r = new RouteInfo(prefix, null, "wlan0");
Lorenzo Colittiaaacefb2013-03-08 19:11:40 -0800290 lp.setInterfaceName("wlan0");
291 lp.addRoute(r);
292 assertEquals(2, lp.getRoutes().size());
293 assertAllRoutesHaveInterface("wlan0", lp);
294
295 // Routes with null interfaces are converted to wlan0.
Lorenzo Colitti34b969b2013-08-08 10:56:22 +0900296 r = RouteInfo.makeHostRoute(ADDRV6, null);
Lorenzo Colittiaaacefb2013-03-08 19:11:40 -0800297 lp.addRoute(r);
298 assertEquals(3, lp.getRoutes().size());
299 assertAllRoutesHaveInterface("wlan0", lp);
300
301 // Check comparisons work.
302 LinkProperties lp2 = new LinkProperties(lp);
303 assertAllRoutesHaveInterface("wlan0", lp);
Lorenzo Colitti43553b62013-07-31 23:23:21 +0900304 assertEquals(0, lp.compareAllRoutes(lp2).added.size());
305 assertEquals(0, lp.compareAllRoutes(lp2).removed.size());
Lorenzo Colittiaaacefb2013-03-08 19:11:40 -0800306
307 lp2.setInterfaceName("p2p0");
308 assertAllRoutesHaveInterface("p2p0", lp2);
Lorenzo Colitti43553b62013-07-31 23:23:21 +0900309 assertEquals(3, lp.compareAllRoutes(lp2).added.size());
310 assertEquals(3, lp.compareAllRoutes(lp2).removed.size());
Lorenzo Colitti50e2b432013-03-16 02:42:30 +0900311 }
Lorenzo Colitti66e01c92013-03-07 10:59:25 -0800312
Hugo Benichi39989e72017-10-12 09:54:49 +0900313 @Test
Lorenzo Colitti66e01c92013-03-07 10:59:25 -0800314 public void testStackedInterfaces() {
315 LinkProperties rmnet0 = new LinkProperties();
316 rmnet0.setInterfaceName("rmnet0");
Lorenzo Colitti34b969b2013-08-08 10:56:22 +0900317 rmnet0.addLinkAddress(LINKADDRV6);
Lorenzo Colitti66e01c92013-03-07 10:59:25 -0800318
319 LinkProperties clat4 = new LinkProperties();
320 clat4.setInterfaceName("clat4");
Lorenzo Colitti34b969b2013-08-08 10:56:22 +0900321 clat4.addLinkAddress(LINKADDRV4);
Lorenzo Colitti66e01c92013-03-07 10:59:25 -0800322
323 assertEquals(0, rmnet0.getStackedLinks().size());
Lorenzo Colitti43553b62013-07-31 23:23:21 +0900324 assertEquals(1, rmnet0.getAddresses().size());
325 assertEquals(1, rmnet0.getLinkAddresses().size());
326 assertEquals(1, rmnet0.getAllAddresses().size());
327 assertEquals(1, rmnet0.getAllLinkAddresses().size());
328
Lorenzo Colitti66e01c92013-03-07 10:59:25 -0800329 rmnet0.addStackedLink(clat4);
330 assertEquals(1, rmnet0.getStackedLinks().size());
Lorenzo Colitti43553b62013-07-31 23:23:21 +0900331 assertEquals(1, rmnet0.getAddresses().size());
332 assertEquals(1, rmnet0.getLinkAddresses().size());
333 assertEquals(2, rmnet0.getAllAddresses().size());
334 assertEquals(2, rmnet0.getAllLinkAddresses().size());
335
Lorenzo Colitti66e01c92013-03-07 10:59:25 -0800336 rmnet0.addStackedLink(clat4);
337 assertEquals(1, rmnet0.getStackedLinks().size());
Lorenzo Colitti43553b62013-07-31 23:23:21 +0900338 assertEquals(1, rmnet0.getAddresses().size());
339 assertEquals(1, rmnet0.getLinkAddresses().size());
340 assertEquals(2, rmnet0.getAllAddresses().size());
341 assertEquals(2, rmnet0.getAllLinkAddresses().size());
342
Lorenzo Colitti66e01c92013-03-07 10:59:25 -0800343 assertEquals(0, clat4.getStackedLinks().size());
344
345 // Modify an item in the returned collection to see what happens.
346 for (LinkProperties link : rmnet0.getStackedLinks()) {
347 if (link.getInterfaceName().equals("clat4")) {
348 link.setInterfaceName("newname");
349 }
350 }
351 for (LinkProperties link : rmnet0.getStackedLinks()) {
352 assertFalse("newname".equals(link.getInterfaceName()));
353 }
Lorenzo Colitti662b96c2013-08-08 11:00:12 +0900354
Lorenzo Colittib8588572014-10-20 11:08:03 +0900355 assertTrue(rmnet0.removeStackedLink("clat4"));
Lorenzo Colitti662b96c2013-08-08 11:00:12 +0900356 assertEquals(0, rmnet0.getStackedLinks().size());
357 assertEquals(1, rmnet0.getAddresses().size());
358 assertEquals(1, rmnet0.getLinkAddresses().size());
359 assertEquals(1, rmnet0.getAllAddresses().size());
360 assertEquals(1, rmnet0.getAllLinkAddresses().size());
361
Lorenzo Colittib8588572014-10-20 11:08:03 +0900362 assertFalse(rmnet0.removeStackedLink("clat4"));
Lorenzo Colitti662b96c2013-08-08 11:00:12 +0900363 }
364
Lorenzo Colitti4ea70b72013-11-15 18:43:52 +0900365 private LinkAddress getFirstLinkAddress(LinkProperties lp) {
366 return lp.getLinkAddresses().iterator().next();
367 }
368
Hugo Benichi39989e72017-10-12 09:54:49 +0900369 @Test
Lorenzo Colitti662b96c2013-08-08 11:00:12 +0900370 public void testAddressMethods() {
371 LinkProperties lp = new LinkProperties();
372
373 // No addresses.
374 assertFalse(lp.hasIPv4Address());
Lorenzo Colittibf1b0002014-06-23 22:33:43 +0900375 assertFalse(lp.hasGlobalIPv6Address());
Lorenzo Colitti662b96c2013-08-08 11:00:12 +0900376
377 // Addresses on stacked links don't count.
378 LinkProperties stacked = new LinkProperties();
379 stacked.setInterfaceName("stacked");
380 lp.addStackedLink(stacked);
381 stacked.addLinkAddress(LINKADDRV4);
382 stacked.addLinkAddress(LINKADDRV6);
383 assertTrue(stacked.hasIPv4Address());
Lorenzo Colittibf1b0002014-06-23 22:33:43 +0900384 assertTrue(stacked.hasGlobalIPv6Address());
Lorenzo Colitti662b96c2013-08-08 11:00:12 +0900385 assertFalse(lp.hasIPv4Address());
Lorenzo Colittibf1b0002014-06-23 22:33:43 +0900386 assertFalse(lp.hasGlobalIPv6Address());
Lorenzo Colittib8588572014-10-20 11:08:03 +0900387 lp.removeStackedLink("stacked");
Lorenzo Colitti662b96c2013-08-08 11:00:12 +0900388 assertFalse(lp.hasIPv4Address());
Lorenzo Colittibf1b0002014-06-23 22:33:43 +0900389 assertFalse(lp.hasGlobalIPv6Address());
Lorenzo Colitti662b96c2013-08-08 11:00:12 +0900390
391 // Addresses on the base link.
392 // Check the return values of hasIPvXAddress and ensure the add/remove methods return true
393 // iff something changes.
Lorenzo Colitti4ea70b72013-11-15 18:43:52 +0900394 assertEquals(0, lp.getLinkAddresses().size());
Lorenzo Colitti662b96c2013-08-08 11:00:12 +0900395 assertTrue(lp.addLinkAddress(LINKADDRV6));
Lorenzo Colitti4ea70b72013-11-15 18:43:52 +0900396 assertEquals(1, lp.getLinkAddresses().size());
Lorenzo Colitti662b96c2013-08-08 11:00:12 +0900397 assertFalse(lp.hasIPv4Address());
Lorenzo Colittibf1b0002014-06-23 22:33:43 +0900398 assertTrue(lp.hasGlobalIPv6Address());
Lorenzo Colitti662b96c2013-08-08 11:00:12 +0900399
400 assertTrue(lp.removeLinkAddress(LINKADDRV6));
Lorenzo Colitti4ea70b72013-11-15 18:43:52 +0900401 assertEquals(0, lp.getLinkAddresses().size());
Lorenzo Colitti662b96c2013-08-08 11:00:12 +0900402
Lorenzo Colittibf1b0002014-06-23 22:33:43 +0900403 assertTrue(lp.addLinkAddress(LINKADDRV6LINKLOCAL));
404 assertEquals(1, lp.getLinkAddresses().size());
405 assertFalse(lp.hasGlobalIPv6Address());
406
407 assertTrue(lp.addLinkAddress(LINKADDRV4));
Lorenzo Colitti4ea70b72013-11-15 18:43:52 +0900408 assertEquals(2, lp.getLinkAddresses().size());
Lorenzo Colitti662b96c2013-08-08 11:00:12 +0900409 assertTrue(lp.hasIPv4Address());
Lorenzo Colittibf1b0002014-06-23 22:33:43 +0900410 assertFalse(lp.hasGlobalIPv6Address());
411
412 assertTrue(lp.addLinkAddress(LINKADDRV6));
413 assertEquals(3, lp.getLinkAddresses().size());
414 assertTrue(lp.hasIPv4Address());
415 assertTrue(lp.hasGlobalIPv6Address());
416
417 assertTrue(lp.removeLinkAddress(LINKADDRV6LINKLOCAL));
418 assertEquals(2, lp.getLinkAddresses().size());
419 assertTrue(lp.hasIPv4Address());
420 assertTrue(lp.hasGlobalIPv6Address());
Lorenzo Colitti662b96c2013-08-08 11:00:12 +0900421
422 // Adding an address twice has no effect.
423 // Removing an address that's not present has no effect.
424 assertFalse(lp.addLinkAddress(LINKADDRV4));
Lorenzo Colitti4ea70b72013-11-15 18:43:52 +0900425 assertEquals(2, lp.getLinkAddresses().size());
Lorenzo Colitti662b96c2013-08-08 11:00:12 +0900426 assertTrue(lp.hasIPv4Address());
427 assertTrue(lp.removeLinkAddress(LINKADDRV4));
Lorenzo Colitti4ea70b72013-11-15 18:43:52 +0900428 assertEquals(1, lp.getLinkAddresses().size());
Lorenzo Colitti662b96c2013-08-08 11:00:12 +0900429 assertFalse(lp.hasIPv4Address());
430 assertFalse(lp.removeLinkAddress(LINKADDRV4));
Lorenzo Colitti4ea70b72013-11-15 18:43:52 +0900431 assertEquals(1, lp.getLinkAddresses().size());
432
433 // Adding an address that's already present but with different properties causes the
434 // existing address to be updated and returns true.
435 // Start with only LINKADDRV6.
436 assertEquals(1, lp.getLinkAddresses().size());
437 assertEquals(LINKADDRV6, getFirstLinkAddress(lp));
438
439 // Create a LinkAddress object for the same address, but with different flags.
440 LinkAddress deprecated = new LinkAddress(ADDRV6, 128,
441 OsConstants.IFA_F_DEPRECATED, OsConstants.RT_SCOPE_UNIVERSE);
442 assertTrue(deprecated.isSameAddressAs(LINKADDRV6));
443 assertFalse(deprecated.equals(LINKADDRV6));
444
445 // Check that adding it updates the existing address instead of adding a new one.
446 assertTrue(lp.addLinkAddress(deprecated));
447 assertEquals(1, lp.getLinkAddresses().size());
448 assertEquals(deprecated, getFirstLinkAddress(lp));
449 assertFalse(LINKADDRV6.equals(getFirstLinkAddress(lp)));
450
451 // Removing LINKADDRV6 removes deprecated, because removing addresses ignores properties.
452 assertTrue(lp.removeLinkAddress(LINKADDRV6));
453 assertEquals(0, lp.getLinkAddresses().size());
Lorenzo Colittiaaacefb2013-03-08 19:11:40 -0800454 }
Lorenzo Colitti5f468e22013-08-23 20:54:49 +0900455
Hugo Benichi39989e72017-10-12 09:54:49 +0900456 @Test
Lorenzo Colitti5f468e22013-08-23 20:54:49 +0900457 public void testSetLinkAddresses() {
458 LinkProperties lp = new LinkProperties();
459 lp.addLinkAddress(LINKADDRV4);
460 lp.addLinkAddress(LINKADDRV6);
461
462 LinkProperties lp2 = new LinkProperties();
463 lp2.addLinkAddress(LINKADDRV6);
464
465 assertFalse(lp.equals(lp2));
466
467 lp2.setLinkAddresses(lp.getLinkAddresses());
468 assertTrue(lp.equals(lp));
469 }
Erik Klineba317782014-10-24 21:50:20 +0900470
Hugo Benichi39989e72017-10-12 09:54:49 +0900471 @Test
Erik Klineba317782014-10-24 21:50:20 +0900472 public void testIsProvisioned() {
473 LinkProperties lp4 = new LinkProperties();
474 assertFalse("v4only:empty", lp4.isProvisioned());
475 lp4.addLinkAddress(LINKADDRV4);
476 assertFalse("v4only:addr-only", lp4.isProvisioned());
477 lp4.addDnsServer(DNS1);
478 assertFalse("v4only:addr+dns", lp4.isProvisioned());
479 lp4.addRoute(new RouteInfo(GATEWAY1));
480 assertTrue("v4only:addr+dns+route", lp4.isProvisioned());
Erik Kline0e801362015-05-21 16:15:02 +0900481 assertTrue("v4only:addr+dns+route", lp4.isIPv4Provisioned());
482 assertFalse("v4only:addr+dns+route", lp4.isIPv6Provisioned());
Erik Klineba317782014-10-24 21:50:20 +0900483
484 LinkProperties lp6 = new LinkProperties();
485 assertFalse("v6only:empty", lp6.isProvisioned());
486 lp6.addLinkAddress(LINKADDRV6LINKLOCAL);
487 assertFalse("v6only:fe80-only", lp6.isProvisioned());
488 lp6.addDnsServer(DNS6);
489 assertFalse("v6only:fe80+dns", lp6.isProvisioned());
Erik Kline0e801362015-05-21 16:15:02 +0900490 lp6.addRoute(new RouteInfo(GATEWAY61));
Erik Klineba317782014-10-24 21:50:20 +0900491 assertFalse("v6only:fe80+dns+route", lp6.isProvisioned());
492 lp6.addLinkAddress(LINKADDRV6);
Erik Kline0e801362015-05-21 16:15:02 +0900493 assertTrue("v6only:fe80+global+dns+route", lp6.isIPv6Provisioned());
Erik Klineba317782014-10-24 21:50:20 +0900494 assertTrue("v6only:fe80+global+dns+route", lp6.isProvisioned());
495 lp6.removeLinkAddress(LINKADDRV6LINKLOCAL);
Erik Kline0e801362015-05-21 16:15:02 +0900496 assertFalse("v6only:global+dns+route", lp6.isIPv4Provisioned());
497 assertTrue("v6only:global+dns+route", lp6.isIPv6Provisioned());
Erik Klineba317782014-10-24 21:50:20 +0900498 assertTrue("v6only:global+dns+route", lp6.isProvisioned());
499
500 LinkProperties lp46 = new LinkProperties();
501 lp46.addLinkAddress(LINKADDRV4);
502 lp46.addLinkAddress(LINKADDRV6);
503 lp46.addDnsServer(DNS1);
504 lp46.addDnsServer(DNS6);
505 assertFalse("dualstack:missing-routes", lp46.isProvisioned());
506 lp46.addRoute(new RouteInfo(GATEWAY1));
Erik Kline0e801362015-05-21 16:15:02 +0900507 assertTrue("dualstack:v4-provisioned", lp46.isIPv4Provisioned());
508 assertFalse("dualstack:v4-provisioned", lp46.isIPv6Provisioned());
Erik Klineba317782014-10-24 21:50:20 +0900509 assertTrue("dualstack:v4-provisioned", lp46.isProvisioned());
Erik Kline0e801362015-05-21 16:15:02 +0900510 lp46.addRoute(new RouteInfo(GATEWAY61));
511 assertTrue("dualstack:both-provisioned", lp46.isIPv4Provisioned());
512 assertTrue("dualstack:both-provisioned", lp46.isIPv6Provisioned());
Erik Klineba317782014-10-24 21:50:20 +0900513 assertTrue("dualstack:both-provisioned", lp46.isProvisioned());
514
515 // A link with an IPv6 address and default route, but IPv4 DNS server.
516 LinkProperties mixed = new LinkProperties();
517 mixed.addLinkAddress(LINKADDRV6);
518 mixed.addDnsServer(DNS1);
Erik Kline0e801362015-05-21 16:15:02 +0900519 mixed.addRoute(new RouteInfo(GATEWAY61));
520 assertFalse("mixed:addr6+route6+dns4", mixed.isIPv4Provisioned());
521 assertFalse("mixed:addr6+route6+dns4", mixed.isIPv6Provisioned());
Erik Klineba317782014-10-24 21:50:20 +0900522 assertFalse("mixed:addr6+route6+dns4", mixed.isProvisioned());
523 }
Erik Kline0e801362015-05-21 16:15:02 +0900524
Hugo Benichi39989e72017-10-12 09:54:49 +0900525 @Test
Erik Kline0e801362015-05-21 16:15:02 +0900526 public void testCompareProvisioning() {
527 LinkProperties v4lp = new LinkProperties();
528 v4lp.addLinkAddress(LINKADDRV4);
529 v4lp.addRoute(new RouteInfo(GATEWAY1));
530 v4lp.addDnsServer(DNS1);
531 assertTrue(v4lp.isProvisioned());
532
533 LinkProperties v4r = new LinkProperties(v4lp);
534 v4r.removeDnsServer(DNS1);
535 assertFalse(v4r.isProvisioned());
536
537 assertEquals(ProvisioningChange.STILL_NOT_PROVISIONED,
538 LinkProperties.compareProvisioning(v4r, v4r));
539 assertEquals(ProvisioningChange.LOST_PROVISIONING,
540 LinkProperties.compareProvisioning(v4lp, v4r));
541 assertEquals(ProvisioningChange.GAINED_PROVISIONING,
542 LinkProperties.compareProvisioning(v4r, v4lp));
543 assertEquals(ProvisioningChange.STILL_PROVISIONED,
544 LinkProperties.compareProvisioning(v4lp, v4lp));
545
546 // Check that losing IPv4 provisioning on a dualstack network is
547 // seen as a total loss of provisioning.
548 LinkProperties v6lp = new LinkProperties();
549 v6lp.addLinkAddress(LINKADDRV6);
550 v6lp.addRoute(new RouteInfo(GATEWAY61));
551 v6lp.addDnsServer(DNS6);
552 assertFalse(v6lp.isIPv4Provisioned());
553 assertTrue(v6lp.isIPv6Provisioned());
554 assertTrue(v6lp.isProvisioned());
555
556 LinkProperties v46lp = new LinkProperties(v6lp);
557 v46lp.addLinkAddress(LINKADDRV4);
558 v46lp.addRoute(new RouteInfo(GATEWAY1));
559 v46lp.addDnsServer(DNS1);
560 assertTrue(v46lp.isIPv4Provisioned());
561 assertTrue(v46lp.isIPv6Provisioned());
562 assertTrue(v46lp.isProvisioned());
563
564 assertEquals(ProvisioningChange.STILL_PROVISIONED,
Erik Klinebb2024b2015-08-14 12:16:55 +0900565 LinkProperties.compareProvisioning(v4lp, v46lp));
566 assertEquals(ProvisioningChange.STILL_PROVISIONED,
Erik Kline0e801362015-05-21 16:15:02 +0900567 LinkProperties.compareProvisioning(v6lp, v46lp));
568 assertEquals(ProvisioningChange.LOST_PROVISIONING,
569 LinkProperties.compareProvisioning(v46lp, v6lp));
Erik Klinebb2024b2015-08-14 12:16:55 +0900570 assertEquals(ProvisioningChange.LOST_PROVISIONING,
571 LinkProperties.compareProvisioning(v46lp, v4lp));
Erik Kline0e801362015-05-21 16:15:02 +0900572
573 // Check that losing and gaining a secondary router does not change
574 // the provisioning status.
575 LinkProperties v6lp2 = new LinkProperties(v6lp);
576 v6lp2.addRoute(new RouteInfo(GATEWAY62));
577 assertTrue(v6lp2.isProvisioned());
578
579 assertEquals(ProvisioningChange.STILL_PROVISIONED,
580 LinkProperties.compareProvisioning(v6lp2, v6lp));
581 assertEquals(ProvisioningChange.STILL_PROVISIONED,
582 LinkProperties.compareProvisioning(v6lp, v6lp2));
583 }
Erik Kline1c8fab52015-06-26 19:21:34 +0900584
Hugo Benichi39989e72017-10-12 09:54:49 +0900585 @Test
Erik Kline1c8fab52015-06-26 19:21:34 +0900586 public void testIsReachable() {
587 final LinkProperties v4lp = new LinkProperties();
588 assertFalse(v4lp.isReachable(DNS1));
589 assertFalse(v4lp.isReachable(DNS2));
590
591 // Add an on-link route, making the on-link DNS server reachable,
592 // but there is still no IPv4 address.
593 assertTrue(v4lp.addRoute(new RouteInfo(
594 new IpPrefix(NetworkUtils.numericToInetAddress("75.208.0.0"), 16))));
595 assertFalse(v4lp.isReachable(DNS1));
596 assertFalse(v4lp.isReachable(DNS2));
597
598 // Adding an IPv4 address (right now, any IPv4 address) means we use
599 // the routes to compute likely reachability.
600 assertTrue(v4lp.addLinkAddress(new LinkAddress(ADDRV4, 16)));
601 assertTrue(v4lp.isReachable(DNS1));
602 assertFalse(v4lp.isReachable(DNS2));
603
604 // Adding a default route makes the off-link DNS server reachable.
605 assertTrue(v4lp.addRoute(new RouteInfo(GATEWAY1)));
606 assertTrue(v4lp.isReachable(DNS1));
607 assertTrue(v4lp.isReachable(DNS2));
608
609 final LinkProperties v6lp = new LinkProperties();
610 final InetAddress kLinkLocalDns = NetworkUtils.numericToInetAddress("fe80::6:1");
611 final InetAddress kLinkLocalDnsWithScope = NetworkUtils.numericToInetAddress("fe80::6:2%43");
612 final InetAddress kOnLinkDns = NetworkUtils.numericToInetAddress("2001:db8:85a3::53");
613 assertFalse(v6lp.isReachable(kLinkLocalDns));
614 assertFalse(v6lp.isReachable(kLinkLocalDnsWithScope));
615 assertFalse(v6lp.isReachable(kOnLinkDns));
616 assertFalse(v6lp.isReachable(DNS6));
617
618 // Add a link-local route, making the link-local DNS servers reachable. Because
619 // we assume the presence of an IPv6 link-local address, link-local DNS servers
620 // are considered reachable, but only those with a non-zero scope identifier.
621 assertTrue(v6lp.addRoute(new RouteInfo(
622 new IpPrefix(NetworkUtils.numericToInetAddress("fe80::"), 64))));
623 assertFalse(v6lp.isReachable(kLinkLocalDns));
624 assertTrue(v6lp.isReachable(kLinkLocalDnsWithScope));
625 assertFalse(v6lp.isReachable(kOnLinkDns));
626 assertFalse(v6lp.isReachable(DNS6));
627
628 // Add a link-local address--nothing changes.
629 assertTrue(v6lp.addLinkAddress(LINKADDRV6LINKLOCAL));
630 assertFalse(v6lp.isReachable(kLinkLocalDns));
631 assertTrue(v6lp.isReachable(kLinkLocalDnsWithScope));
632 assertFalse(v6lp.isReachable(kOnLinkDns));
633 assertFalse(v6lp.isReachable(DNS6));
634
635 // Add a global route on link, but no global address yet. DNS servers reachable
636 // via a route that doesn't require a gateway: give them the benefit of the
637 // doubt and hope the link-local source address suffices for communication.
638 assertTrue(v6lp.addRoute(new RouteInfo(
639 new IpPrefix(NetworkUtils.numericToInetAddress("2001:db8:85a3::"), 64))));
640 assertFalse(v6lp.isReachable(kLinkLocalDns));
641 assertTrue(v6lp.isReachable(kLinkLocalDnsWithScope));
642 assertTrue(v6lp.isReachable(kOnLinkDns));
643 assertFalse(v6lp.isReachable(DNS6));
644
645 // Add a global address; the on-link global address DNS server is (still)
646 // presumed reachable.
647 assertTrue(v6lp.addLinkAddress(new LinkAddress(ADDRV6, 64)));
648 assertFalse(v6lp.isReachable(kLinkLocalDns));
649 assertTrue(v6lp.isReachable(kLinkLocalDnsWithScope));
650 assertTrue(v6lp.isReachable(kOnLinkDns));
651 assertFalse(v6lp.isReachable(DNS6));
652
653 // Adding a default route makes the off-link DNS server reachable.
654 assertTrue(v6lp.addRoute(new RouteInfo(GATEWAY62)));
655 assertFalse(v6lp.isReachable(kLinkLocalDns));
656 assertTrue(v6lp.isReachable(kLinkLocalDnsWithScope));
657 assertTrue(v6lp.isReachable(kOnLinkDns));
658 assertTrue(v6lp.isReachable(DNS6));
Lorenzo Colitti319789d2015-07-30 23:41:43 +0900659
660 // Check isReachable on stacked links. This requires that the source IP address be assigned
661 // on the interface returned by the route lookup.
662 LinkProperties stacked = new LinkProperties();
663
664 // Can't add a stacked link without an interface name.
665 stacked.setInterfaceName("v4-test0");
666 v6lp.addStackedLink(stacked);
667
668 InetAddress stackedAddress = Address("192.0.0.4");
669 LinkAddress stackedLinkAddress = new LinkAddress(stackedAddress, 32);
670 assertFalse(v6lp.isReachable(stackedAddress));
671 stacked.addLinkAddress(stackedLinkAddress);
672 assertFalse(v6lp.isReachable(stackedAddress));
673 stacked.addRoute(new RouteInfo(stackedLinkAddress));
674 assertTrue(stacked.isReachable(stackedAddress));
675 assertTrue(v6lp.isReachable(stackedAddress));
676
677 assertFalse(v6lp.isReachable(DNS1));
678 stacked.addRoute(new RouteInfo((IpPrefix) null, stackedAddress));
679 assertTrue(v6lp.isReachable(DNS1));
Erik Kline1c8fab52015-06-26 19:21:34 +0900680 }
Rubin Xu57b437a2017-09-05 18:40:49 +0100681
Hugo Benichi39989e72017-10-12 09:54:49 +0900682 @Test
Rubin Xu57b437a2017-09-05 18:40:49 +0100683 public void testLinkPropertiesEnsureDirectlyConnectedRoutes() {
684 // IPv4 case: no route added initially
685 LinkProperties rmnet0 = new LinkProperties();
686 rmnet0.setInterfaceName("rmnet0");
687 rmnet0.addLinkAddress(new LinkAddress("10.0.0.2/8"));
688 RouteInfo directRoute0 = new RouteInfo(new IpPrefix("10.0.0.0/8"), null,
689 rmnet0.getInterfaceName());
690
691 // Since no routes is added explicitly, getAllRoutes() should return empty.
692 assertTrue(rmnet0.getAllRoutes().isEmpty());
693 rmnet0.ensureDirectlyConnectedRoutes();
694 // ensureDirectlyConnectedRoutes() should have added the missing local route.
695 assertEqualRoutes(Collections.singletonList(directRoute0), rmnet0.getAllRoutes());
696
697 // IPv4 case: both direct and default routes added initially
698 LinkProperties rmnet1 = new LinkProperties();
699 rmnet1.setInterfaceName("rmnet1");
700 rmnet1.addLinkAddress(new LinkAddress("10.0.0.3/8"));
701 RouteInfo defaultRoute1 = new RouteInfo((IpPrefix) null,
702 NetworkUtils.numericToInetAddress("10.0.0.1"), rmnet1.getInterfaceName());
703 RouteInfo directRoute1 = new RouteInfo(new IpPrefix("10.0.0.0/8"), null,
704 rmnet1.getInterfaceName());
705 rmnet1.addRoute(defaultRoute1);
706 rmnet1.addRoute(directRoute1);
707
708 // Check added routes
709 assertEqualRoutes(Arrays.asList(defaultRoute1, directRoute1), rmnet1.getAllRoutes());
710 // ensureDirectlyConnectedRoutes() shouldn't change the routes since direct connected
711 // route is already part of the configuration.
712 rmnet1.ensureDirectlyConnectedRoutes();
713 assertEqualRoutes(Arrays.asList(defaultRoute1, directRoute1), rmnet1.getAllRoutes());
714
715 // IPv6 case: only default routes added initially
716 LinkProperties rmnet2 = new LinkProperties();
717 rmnet2.setInterfaceName("rmnet2");
718 rmnet2.addLinkAddress(new LinkAddress("fe80::cafe/64"));
719 rmnet2.addLinkAddress(new LinkAddress("2001:db8::2/64"));
720 RouteInfo defaultRoute2 = new RouteInfo((IpPrefix) null,
721 NetworkUtils.numericToInetAddress("2001:db8::1"), rmnet2.getInterfaceName());
722 RouteInfo directRoute2 = new RouteInfo(new IpPrefix("2001:db8::/64"), null,
723 rmnet2.getInterfaceName());
724 RouteInfo linkLocalRoute2 = new RouteInfo(new IpPrefix("fe80::/64"), null,
725 rmnet2.getInterfaceName());
726 rmnet2.addRoute(defaultRoute2);
727
728 assertEqualRoutes(Arrays.asList(defaultRoute2), rmnet2.getAllRoutes());
729 rmnet2.ensureDirectlyConnectedRoutes();
730 assertEqualRoutes(Arrays.asList(defaultRoute2, directRoute2, linkLocalRoute2),
731 rmnet2.getAllRoutes());
732
733 // Corner case: no interface name
734 LinkProperties rmnet3 = new LinkProperties();
735 rmnet3.addLinkAddress(new LinkAddress("192.168.0.2/24"));
736 RouteInfo directRoute3 = new RouteInfo(new IpPrefix("192.168.0.0/24"), null,
737 rmnet3.getInterfaceName());
738
739 assertTrue(rmnet3.getAllRoutes().isEmpty());
740 rmnet3.ensureDirectlyConnectedRoutes();
741 assertEqualRoutes(Collections.singletonList(directRoute3), rmnet3.getAllRoutes());
742
743 }
744
Hugo Benichi39989e72017-10-12 09:54:49 +0900745 @Test
Rubin Xu8cb82d22017-08-22 16:35:52 +0100746 public void testCompareResult() {
747 // Either adding or removing items
Hugo Benichi39989e72017-10-12 09:54:49 +0900748 compareResult(Arrays.asList(1, 2, 3, 4), Arrays.asList(1),
Rubin Xu8cb82d22017-08-22 16:35:52 +0100749 Arrays.asList(2, 3, 4), new ArrayList<>());
Hugo Benichi39989e72017-10-12 09:54:49 +0900750 compareResult(Arrays.asList(1, 2), Arrays.asList(3, 2, 1, 4),
Rubin Xu8cb82d22017-08-22 16:35:52 +0100751 new ArrayList<>(), Arrays.asList(3, 4));
752
753
754 // adding and removing items at the same time
Hugo Benichi39989e72017-10-12 09:54:49 +0900755 compareResult(Arrays.asList(1, 2, 3, 4), Arrays.asList(2, 3, 4, 5),
Rubin Xu8cb82d22017-08-22 16:35:52 +0100756 Arrays.asList(1), Arrays.asList(5));
Hugo Benichi39989e72017-10-12 09:54:49 +0900757 compareResult(Arrays.asList(1, 2, 3), Arrays.asList(4, 5, 6),
Rubin Xu8cb82d22017-08-22 16:35:52 +0100758 Arrays.asList(1, 2, 3), Arrays.asList(4, 5, 6));
759
760 // null cases
Hugo Benichi39989e72017-10-12 09:54:49 +0900761 compareResult(Arrays.asList(1, 2, 3), null, Arrays.asList(1, 2, 3), new ArrayList<>());
762 compareResult(null, Arrays.asList(3, 2, 1), new ArrayList<>(), Arrays.asList(1, 2, 3));
763 compareResult(null, null, new ArrayList<>(), new ArrayList<>());
Rubin Xu8cb82d22017-08-22 16:35:52 +0100764 }
765
Rubin Xu57b437a2017-09-05 18:40:49 +0100766 private void assertEqualRoutes(Collection<RouteInfo> expected, Collection<RouteInfo> actual) {
767 Set<RouteInfo> expectedSet = new ArraySet<>(expected);
768 Set<RouteInfo> actualSet = new ArraySet<>(actual);
769 // Duplicated entries in actual routes are considered failures
770 assertEquals(actual.size(), actualSet.size());
771
772 assertEquals(expectedSet, actualSet);
773 }
Rubin Xu8cb82d22017-08-22 16:35:52 +0100774
Hugo Benichi39989e72017-10-12 09:54:49 +0900775 private <T> void compareResult(List<T> oldItems, List<T> newItems, List<T> expectRemoved,
Rubin Xu0a3da932017-09-15 11:51:39 +0100776 List<T> expectAdded) {
777 CompareResult<T> result = new CompareResult<>(oldItems, newItems);
Rubin Xu8cb82d22017-08-22 16:35:52 +0100778 assertEquals(new ArraySet<>(expectAdded), new ArraySet<>(result.added));
779 assertEquals(new ArraySet<>(expectRemoved), (new ArraySet<>(result.removed)));
780 }
John Wang3e567d52011-04-04 12:35:42 -0700781}