blob: f3c22a51e2679ad8d0d35e7a03398c54d2e4ac9f [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 Benichi87d306b2017-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 Klinea923dba2015-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 Xu2fa7d9e2017-08-22 16:35:52 +010027import android.net.LinkProperties.CompareResult;
Erik Kline04612b02015-05-21 16:15:02 +090028import android.net.LinkProperties.ProvisioningChange;
Robert Greenwalt5a901292011-04-28 14:28:50 -070029import android.net.RouteInfo;
Hugo Benichi87d306b2017-10-12 09:54:49 +090030import android.support.test.filters.SmallTest;
31import android.support.test.runner.AndroidJUnit4;
Elliott Hughes8732b352014-04-28 11:11:32 -070032import android.system.OsConstants;
Rubin Xuffd77d82017-09-05 18:40:49 +010033import android.util.ArraySet;
34
John Wang3e567d52011-04-04 12:35:42 -070035import java.net.InetAddress;
Rubin Xu2fa7d9e2017-08-22 16:35:52 +010036import java.util.ArrayList;
Rubin Xuffd77d82017-09-05 18:40:49 +010037import java.util.Arrays;
38import java.util.Collection;
39import java.util.Collections;
Rubin Xu2fa7d9e2017-08-22 16:35:52 +010040import java.util.List;
Rubin Xuffd77d82017-09-05 18:40:49 +010041import java.util.Set;
John Wang3e567d52011-04-04 12:35:42 -070042
Hugo Benichi87d306b2017-10-12 09:54:49 +090043import org.junit.Test;
44import org.junit.runner.RunWith;
Erik Klinea923dba2015-06-26 19:21:34 +090045
Hugo Benichi87d306b2017-10-12 09:54:49 +090046@RunWith(AndroidJUnit4.class)
47@SmallTest
48public class LinkPropertiesTest {
Lorenzo Colittia2dc69a2013-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 Kline8b023072014-10-24 21:50:20 +090054 private static InetAddress DNS6 = NetworkUtils.numericToInetAddress("2001:4860:4860::8888");
Lorenzo Colittia2dc69a2013-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 Kline04612b02015-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.yun4aa73922013-09-02 05:24:09 +090060 private static int MTU = 1500;
John Wang3e567d52011-04-04 12:35:42 -070061
Lorenzo Colittia2dc69a2013-08-08 10:56:22 +090062 private static LinkAddress LINKADDRV4 = new LinkAddress(ADDRV4, 32);
63 private static LinkAddress LINKADDRV6 = new LinkAddress(ADDRV6, 128);
Lorenzo Colittifc854692014-06-23 22:33:43 +090064 private static LinkAddress LINKADDRV6LINKLOCAL = new LinkAddress("fe80::1/64");
Lorenzo Colittia2dc69a2013-08-08 10:56:22 +090065
Lorenzo Colitti28bb16c2015-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 Colitti89218e52013-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
dalyk7643abc2018-01-17 14:20:55 -050082 assertTrue(source.isIdenticalPrivateDns(target));
83 assertTrue(target.isIdenticalPrivateDns(source));
84
Lorenzo Colitti89218e52013-04-01 10:47:43 +090085 assertTrue(source.isIdenticalRoutes(target));
86 assertTrue(target.isIdenticalRoutes(source));
87
88 assertTrue(source.isIdenticalHttpProxy(target));
89 assertTrue(target.isIdenticalHttpProxy(source));
90
91 assertTrue(source.isIdenticalStackedLinks(target));
92 assertTrue(target.isIdenticalStackedLinks(source));
93
sy.yun4aa73922013-09-02 05:24:09 +090094 assertTrue(source.isIdenticalMtu(target));
95 assertTrue(target.isIdenticalMtu(source));
96
dalyk7643abc2018-01-17 14:20:55 -050097 assertTrue(source.isIdenticalTcpBufferSizes(target));
98 assertTrue(target.isIdenticalTcpBufferSizes(source));
99
Lorenzo Colitti89218e52013-04-01 10:47:43 +0900100 // Check result of equals().
101 assertTrue(source.equals(target));
102 assertTrue(target.equals(source));
103
104 // Check hashCode.
105 assertEquals(source.hashCode(), target.hashCode());
106 }
107
Hugo Benichi87d306b2017-10-12 09:54:49 +0900108 @Test
John Wang3e567d52011-04-04 12:35:42 -0700109 public void testEqualsNull() {
110 LinkProperties source = new LinkProperties();
111 LinkProperties target = new LinkProperties();
112
113 assertFalse(source == target);
Lorenzo Colitti89218e52013-04-01 10:47:43 +0900114 assertLinkPropertiesEqual(source, target);
John Wang3e567d52011-04-04 12:35:42 -0700115 }
116
Hugo Benichi87d306b2017-10-12 09:54:49 +0900117 @Test
118 public void testEqualsSameOrder() throws Exception {
119 LinkProperties source = new LinkProperties();
120 source.setInterfaceName(NAME);
121 // set 2 link addresses
122 source.addLinkAddress(LINKADDRV4);
123 source.addLinkAddress(LINKADDRV6);
124 // set 2 dnses
125 source.addDnsServer(DNS1);
126 source.addDnsServer(DNS2);
127 // set 2 gateways
128 source.addRoute(new RouteInfo(GATEWAY1));
129 source.addRoute(new RouteInfo(GATEWAY2));
130 source.setMtu(MTU);
John Wang3e567d52011-04-04 12:35:42 -0700131
Hugo Benichi87d306b2017-10-12 09:54:49 +0900132 LinkProperties target = new LinkProperties();
John Wang3e567d52011-04-04 12:35:42 -0700133
Hugo Benichi87d306b2017-10-12 09:54:49 +0900134 // All fields are same
135 target.setInterfaceName(NAME);
136 target.addLinkAddress(LINKADDRV4);
137 target.addLinkAddress(LINKADDRV6);
138 target.addDnsServer(DNS1);
139 target.addDnsServer(DNS2);
140 target.addRoute(new RouteInfo(GATEWAY1));
141 target.addRoute(new RouteInfo(GATEWAY2));
142 target.setMtu(MTU);
John Wang3e567d52011-04-04 12:35:42 -0700143
Hugo Benichi87d306b2017-10-12 09:54:49 +0900144 assertLinkPropertiesEqual(source, target);
John Wang3e567d52011-04-04 12:35:42 -0700145
Hugo Benichi87d306b2017-10-12 09:54:49 +0900146 target.clear();
147 // change Interface Name
148 target.setInterfaceName("qmi1");
149 target.addLinkAddress(LINKADDRV4);
150 target.addLinkAddress(LINKADDRV6);
151 target.addDnsServer(DNS1);
152 target.addDnsServer(DNS2);
153 target.addRoute(new RouteInfo(GATEWAY1));
154 target.addRoute(new RouteInfo(GATEWAY2));
155 target.setMtu(MTU);
156 assertFalse(source.equals(target));
John Wang3e567d52011-04-04 12:35:42 -0700157
Hugo Benichi87d306b2017-10-12 09:54:49 +0900158 target.clear();
159 target.setInterfaceName(NAME);
160 // change link addresses
161 target.addLinkAddress(new LinkAddress(
162 NetworkUtils.numericToInetAddress("75.208.6.2"), 32));
163 target.addLinkAddress(LINKADDRV6);
164 target.addDnsServer(DNS1);
165 target.addDnsServer(DNS2);
166 target.addRoute(new RouteInfo(GATEWAY1));
167 target.addRoute(new RouteInfo(GATEWAY2));
168 target.setMtu(MTU);
169 assertFalse(source.equals(target));
John Wang3e567d52011-04-04 12:35:42 -0700170
Hugo Benichi87d306b2017-10-12 09:54:49 +0900171 target.clear();
172 target.setInterfaceName(NAME);
173 target.addLinkAddress(LINKADDRV4);
174 target.addLinkAddress(LINKADDRV6);
175 // change dnses
176 target.addDnsServer(NetworkUtils.numericToInetAddress("75.208.7.2"));
177 target.addDnsServer(DNS2);
178 target.addRoute(new RouteInfo(GATEWAY1));
179 target.addRoute(new RouteInfo(GATEWAY2));
180 target.setMtu(MTU);
181 assertFalse(source.equals(target));
John Wang3e567d52011-04-04 12:35:42 -0700182
Hugo Benichi87d306b2017-10-12 09:54:49 +0900183 target.clear();
184 target.setInterfaceName(NAME);
185 target.addLinkAddress(LINKADDRV4);
186 target.addLinkAddress(LINKADDRV6);
187 target.addDnsServer(DNS1);
188 target.addDnsServer(DNS2);
189 // change gateway
190 target.addRoute(new RouteInfo(NetworkUtils.numericToInetAddress("75.208.8.2")));
191 target.addRoute(new RouteInfo(GATEWAY2));
192 target.setMtu(MTU);
193 assertFalse(source.equals(target));
sy.yun4aa73922013-09-02 05:24:09 +0900194
Hugo Benichi87d306b2017-10-12 09:54:49 +0900195 target.clear();
196 target.setInterfaceName(NAME);
197 target.addLinkAddress(LINKADDRV4);
198 target.addLinkAddress(LINKADDRV6);
199 target.addDnsServer(DNS1);
200 target.addDnsServer(DNS2);
201 target.addRoute(new RouteInfo(GATEWAY1));
202 target.addRoute(new RouteInfo(GATEWAY2));
203 // change mtu
204 target.setMtu(1440);
205 assertFalse(source.equals(target));
John Wang3e567d52011-04-04 12:35:42 -0700206 }
207
Hugo Benichi87d306b2017-10-12 09:54:49 +0900208 @Test
209 public void testEqualsDifferentOrder() throws Exception {
210 LinkProperties source = new LinkProperties();
211 source.setInterfaceName(NAME);
212 // set 2 link addresses
213 source.addLinkAddress(LINKADDRV4);
214 source.addLinkAddress(LINKADDRV6);
215 // set 2 dnses
216 source.addDnsServer(DNS1);
217 source.addDnsServer(DNS2);
218 // set 2 gateways
219 source.addRoute(new RouteInfo(GATEWAY1));
220 source.addRoute(new RouteInfo(GATEWAY2));
221 source.setMtu(MTU);
John Wang3e567d52011-04-04 12:35:42 -0700222
Hugo Benichi87d306b2017-10-12 09:54:49 +0900223 LinkProperties target = new LinkProperties();
224 // Exchange order
225 target.setInterfaceName(NAME);
226 target.addLinkAddress(LINKADDRV6);
227 target.addLinkAddress(LINKADDRV4);
228 target.addDnsServer(DNS2);
229 target.addDnsServer(DNS1);
230 target.addRoute(new RouteInfo(GATEWAY2));
231 target.addRoute(new RouteInfo(GATEWAY1));
232 target.setMtu(MTU);
John Wang3e567d52011-04-04 12:35:42 -0700233
Hugo Benichi87d306b2017-10-12 09:54:49 +0900234 assertLinkPropertiesEqual(source, target);
John Wang3e567d52011-04-04 12:35:42 -0700235 }
236
Hugo Benichi87d306b2017-10-12 09:54:49 +0900237 @Test
238 public void testEqualsDuplicated() throws Exception {
239 LinkProperties source = new LinkProperties();
240 // set 3 link addresses, eg, [A, A, B]
241 source.addLinkAddress(LINKADDRV4);
242 source.addLinkAddress(LINKADDRV4);
243 source.addLinkAddress(LINKADDRV6);
John Wang3e567d52011-04-04 12:35:42 -0700244
Hugo Benichi87d306b2017-10-12 09:54:49 +0900245 LinkProperties target = new LinkProperties();
246 // set 3 link addresses, eg, [A, B, B]
247 target.addLinkAddress(LINKADDRV4);
248 target.addLinkAddress(LINKADDRV6);
249 target.addLinkAddress(LINKADDRV6);
John Wang3e567d52011-04-04 12:35:42 -0700250
Hugo Benichi87d306b2017-10-12 09:54:49 +0900251 assertLinkPropertiesEqual(source, target);
John Wang3e567d52011-04-04 12:35:42 -0700252 }
253
Lorenzo Colitti8ec0b8a2013-03-08 19:11:40 -0800254 private void assertAllRoutesHaveInterface(String iface, LinkProperties lp) {
255 for (RouteInfo r : lp.getRoutes()) {
256 assertEquals(iface, r.getInterface());
257 }
258 }
259
Hugo Benichi87d306b2017-10-12 09:54:49 +0900260 @Test
Lorenzo Colitti8ec0b8a2013-03-08 19:11:40 -0800261 public void testRouteInterfaces() {
262 LinkAddress prefix = new LinkAddress(
263 NetworkUtils.numericToInetAddress("2001:db8::"), 32);
Lorenzo Colittia2dc69a2013-08-08 10:56:22 +0900264 InetAddress address = ADDRV6;
Lorenzo Colitti8ec0b8a2013-03-08 19:11:40 -0800265
266 // Add a route with no interface to a LinkProperties with no interface. No errors.
267 LinkProperties lp = new LinkProperties();
268 RouteInfo r = new RouteInfo(prefix, address, null);
Lorenzo Colitti3897f1a2014-06-23 21:16:34 +0900269 assertTrue(lp.addRoute(r));
Lorenzo Colitti8ec0b8a2013-03-08 19:11:40 -0800270 assertEquals(1, lp.getRoutes().size());
271 assertAllRoutesHaveInterface(null, lp);
272
Lorenzo Colitti3897f1a2014-06-23 21:16:34 +0900273 // Adding the same route twice has no effect.
274 assertFalse(lp.addRoute(r));
275 assertEquals(1, lp.getRoutes().size());
276
277 // Add a route with an interface. Expect an exception.
Lorenzo Colitti8ec0b8a2013-03-08 19:11:40 -0800278 r = new RouteInfo(prefix, address, "wlan0");
279 try {
280 lp.addRoute(r);
281 fail("Adding wlan0 route to LP with no interface, expect exception");
282 } catch (IllegalArgumentException expected) {}
283
284 // Change the interface name. All the routes should change their interface name too.
285 lp.setInterfaceName("rmnet0");
286 assertAllRoutesHaveInterface("rmnet0", lp);
287
288 // Now add a route with the wrong interface. This causes an exception too.
289 try {
290 lp.addRoute(r);
291 fail("Adding wlan0 route to rmnet0 LP, expect exception");
292 } catch (IllegalArgumentException expected) {}
293
294 // If the interface name matches, the route is added.
Lorenzo Colitti3897f1a2014-06-23 21:16:34 +0900295 r = new RouteInfo(prefix, null, "wlan0");
Lorenzo Colitti8ec0b8a2013-03-08 19:11:40 -0800296 lp.setInterfaceName("wlan0");
297 lp.addRoute(r);
298 assertEquals(2, lp.getRoutes().size());
299 assertAllRoutesHaveInterface("wlan0", lp);
300
301 // Routes with null interfaces are converted to wlan0.
Lorenzo Colittia2dc69a2013-08-08 10:56:22 +0900302 r = RouteInfo.makeHostRoute(ADDRV6, null);
Lorenzo Colitti8ec0b8a2013-03-08 19:11:40 -0800303 lp.addRoute(r);
304 assertEquals(3, lp.getRoutes().size());
305 assertAllRoutesHaveInterface("wlan0", lp);
306
307 // Check comparisons work.
308 LinkProperties lp2 = new LinkProperties(lp);
309 assertAllRoutesHaveInterface("wlan0", lp);
Lorenzo Colittie1b47422013-07-31 23:23:21 +0900310 assertEquals(0, lp.compareAllRoutes(lp2).added.size());
311 assertEquals(0, lp.compareAllRoutes(lp2).removed.size());
Lorenzo Colitti8ec0b8a2013-03-08 19:11:40 -0800312
313 lp2.setInterfaceName("p2p0");
314 assertAllRoutesHaveInterface("p2p0", lp2);
Lorenzo Colittie1b47422013-07-31 23:23:21 +0900315 assertEquals(3, lp.compareAllRoutes(lp2).added.size());
316 assertEquals(3, lp.compareAllRoutes(lp2).removed.size());
Lorenzo Colitti3989de82013-03-16 02:42:30 +0900317 }
Lorenzo Colittic0803122013-03-07 10:59:25 -0800318
Hugo Benichi87d306b2017-10-12 09:54:49 +0900319 @Test
Lorenzo Colittic0803122013-03-07 10:59:25 -0800320 public void testStackedInterfaces() {
321 LinkProperties rmnet0 = new LinkProperties();
322 rmnet0.setInterfaceName("rmnet0");
Lorenzo Colittia2dc69a2013-08-08 10:56:22 +0900323 rmnet0.addLinkAddress(LINKADDRV6);
Lorenzo Colittic0803122013-03-07 10:59:25 -0800324
325 LinkProperties clat4 = new LinkProperties();
326 clat4.setInterfaceName("clat4");
Lorenzo Colittia2dc69a2013-08-08 10:56:22 +0900327 clat4.addLinkAddress(LINKADDRV4);
Lorenzo Colittic0803122013-03-07 10:59:25 -0800328
329 assertEquals(0, rmnet0.getStackedLinks().size());
Lorenzo Colittie1b47422013-07-31 23:23:21 +0900330 assertEquals(1, rmnet0.getAddresses().size());
331 assertEquals(1, rmnet0.getLinkAddresses().size());
332 assertEquals(1, rmnet0.getAllAddresses().size());
333 assertEquals(1, rmnet0.getAllLinkAddresses().size());
334
Lorenzo Colittic0803122013-03-07 10:59:25 -0800335 rmnet0.addStackedLink(clat4);
336 assertEquals(1, rmnet0.getStackedLinks().size());
Lorenzo Colittie1b47422013-07-31 23:23:21 +0900337 assertEquals(1, rmnet0.getAddresses().size());
338 assertEquals(1, rmnet0.getLinkAddresses().size());
339 assertEquals(2, rmnet0.getAllAddresses().size());
340 assertEquals(2, rmnet0.getAllLinkAddresses().size());
341
Lorenzo Colittic0803122013-03-07 10:59:25 -0800342 rmnet0.addStackedLink(clat4);
343 assertEquals(1, rmnet0.getStackedLinks().size());
Lorenzo Colittie1b47422013-07-31 23:23:21 +0900344 assertEquals(1, rmnet0.getAddresses().size());
345 assertEquals(1, rmnet0.getLinkAddresses().size());
346 assertEquals(2, rmnet0.getAllAddresses().size());
347 assertEquals(2, rmnet0.getAllLinkAddresses().size());
348
Lorenzo Colittic0803122013-03-07 10:59:25 -0800349 assertEquals(0, clat4.getStackedLinks().size());
350
351 // Modify an item in the returned collection to see what happens.
352 for (LinkProperties link : rmnet0.getStackedLinks()) {
353 if (link.getInterfaceName().equals("clat4")) {
354 link.setInterfaceName("newname");
355 }
356 }
357 for (LinkProperties link : rmnet0.getStackedLinks()) {
358 assertFalse("newname".equals(link.getInterfaceName()));
359 }
Lorenzo Colitti09de4182013-08-08 11:00:12 +0900360
Lorenzo Colitti38258432014-10-20 11:08:03 +0900361 assertTrue(rmnet0.removeStackedLink("clat4"));
Lorenzo Colitti09de4182013-08-08 11:00:12 +0900362 assertEquals(0, rmnet0.getStackedLinks().size());
363 assertEquals(1, rmnet0.getAddresses().size());
364 assertEquals(1, rmnet0.getLinkAddresses().size());
365 assertEquals(1, rmnet0.getAllAddresses().size());
366 assertEquals(1, rmnet0.getAllLinkAddresses().size());
367
Lorenzo Colitti38258432014-10-20 11:08:03 +0900368 assertFalse(rmnet0.removeStackedLink("clat4"));
Lorenzo Colitti09de4182013-08-08 11:00:12 +0900369 }
370
Lorenzo Colitti61b65822013-11-15 18:43:52 +0900371 private LinkAddress getFirstLinkAddress(LinkProperties lp) {
372 return lp.getLinkAddresses().iterator().next();
373 }
374
Hugo Benichi87d306b2017-10-12 09:54:49 +0900375 @Test
Lorenzo Colitti09de4182013-08-08 11:00:12 +0900376 public void testAddressMethods() {
377 LinkProperties lp = new LinkProperties();
378
379 // No addresses.
380 assertFalse(lp.hasIPv4Address());
Lorenzo Colittifc854692014-06-23 22:33:43 +0900381 assertFalse(lp.hasGlobalIPv6Address());
Lorenzo Colitti09de4182013-08-08 11:00:12 +0900382
383 // Addresses on stacked links don't count.
384 LinkProperties stacked = new LinkProperties();
385 stacked.setInterfaceName("stacked");
386 lp.addStackedLink(stacked);
387 stacked.addLinkAddress(LINKADDRV4);
388 stacked.addLinkAddress(LINKADDRV6);
389 assertTrue(stacked.hasIPv4Address());
Lorenzo Colittifc854692014-06-23 22:33:43 +0900390 assertTrue(stacked.hasGlobalIPv6Address());
Lorenzo Colitti09de4182013-08-08 11:00:12 +0900391 assertFalse(lp.hasIPv4Address());
Lorenzo Colittifc854692014-06-23 22:33:43 +0900392 assertFalse(lp.hasGlobalIPv6Address());
Lorenzo Colitti38258432014-10-20 11:08:03 +0900393 lp.removeStackedLink("stacked");
Lorenzo Colitti09de4182013-08-08 11:00:12 +0900394 assertFalse(lp.hasIPv4Address());
Lorenzo Colittifc854692014-06-23 22:33:43 +0900395 assertFalse(lp.hasGlobalIPv6Address());
Lorenzo Colitti09de4182013-08-08 11:00:12 +0900396
397 // Addresses on the base link.
398 // Check the return values of hasIPvXAddress and ensure the add/remove methods return true
399 // iff something changes.
Lorenzo Colitti61b65822013-11-15 18:43:52 +0900400 assertEquals(0, lp.getLinkAddresses().size());
Lorenzo Colitti09de4182013-08-08 11:00:12 +0900401 assertTrue(lp.addLinkAddress(LINKADDRV6));
Lorenzo Colitti61b65822013-11-15 18:43:52 +0900402 assertEquals(1, lp.getLinkAddresses().size());
Lorenzo Colitti09de4182013-08-08 11:00:12 +0900403 assertFalse(lp.hasIPv4Address());
Lorenzo Colittifc854692014-06-23 22:33:43 +0900404 assertTrue(lp.hasGlobalIPv6Address());
Lorenzo Colitti09de4182013-08-08 11:00:12 +0900405
406 assertTrue(lp.removeLinkAddress(LINKADDRV6));
Lorenzo Colitti61b65822013-11-15 18:43:52 +0900407 assertEquals(0, lp.getLinkAddresses().size());
Lorenzo Colitti09de4182013-08-08 11:00:12 +0900408
Lorenzo Colittifc854692014-06-23 22:33:43 +0900409 assertTrue(lp.addLinkAddress(LINKADDRV6LINKLOCAL));
410 assertEquals(1, lp.getLinkAddresses().size());
411 assertFalse(lp.hasGlobalIPv6Address());
412
413 assertTrue(lp.addLinkAddress(LINKADDRV4));
Lorenzo Colitti61b65822013-11-15 18:43:52 +0900414 assertEquals(2, lp.getLinkAddresses().size());
Lorenzo Colitti09de4182013-08-08 11:00:12 +0900415 assertTrue(lp.hasIPv4Address());
Lorenzo Colittifc854692014-06-23 22:33:43 +0900416 assertFalse(lp.hasGlobalIPv6Address());
417
418 assertTrue(lp.addLinkAddress(LINKADDRV6));
419 assertEquals(3, lp.getLinkAddresses().size());
420 assertTrue(lp.hasIPv4Address());
421 assertTrue(lp.hasGlobalIPv6Address());
422
423 assertTrue(lp.removeLinkAddress(LINKADDRV6LINKLOCAL));
424 assertEquals(2, lp.getLinkAddresses().size());
425 assertTrue(lp.hasIPv4Address());
426 assertTrue(lp.hasGlobalIPv6Address());
Lorenzo Colitti09de4182013-08-08 11:00:12 +0900427
428 // Adding an address twice has no effect.
429 // Removing an address that's not present has no effect.
430 assertFalse(lp.addLinkAddress(LINKADDRV4));
Lorenzo Colitti61b65822013-11-15 18:43:52 +0900431 assertEquals(2, lp.getLinkAddresses().size());
Lorenzo Colitti09de4182013-08-08 11:00:12 +0900432 assertTrue(lp.hasIPv4Address());
433 assertTrue(lp.removeLinkAddress(LINKADDRV4));
Lorenzo Colitti61b65822013-11-15 18:43:52 +0900434 assertEquals(1, lp.getLinkAddresses().size());
Lorenzo Colitti09de4182013-08-08 11:00:12 +0900435 assertFalse(lp.hasIPv4Address());
436 assertFalse(lp.removeLinkAddress(LINKADDRV4));
Lorenzo Colitti61b65822013-11-15 18:43:52 +0900437 assertEquals(1, lp.getLinkAddresses().size());
438
439 // Adding an address that's already present but with different properties causes the
440 // existing address to be updated and returns true.
441 // Start with only LINKADDRV6.
442 assertEquals(1, lp.getLinkAddresses().size());
443 assertEquals(LINKADDRV6, getFirstLinkAddress(lp));
444
445 // Create a LinkAddress object for the same address, but with different flags.
446 LinkAddress deprecated = new LinkAddress(ADDRV6, 128,
447 OsConstants.IFA_F_DEPRECATED, OsConstants.RT_SCOPE_UNIVERSE);
448 assertTrue(deprecated.isSameAddressAs(LINKADDRV6));
449 assertFalse(deprecated.equals(LINKADDRV6));
450
451 // Check that adding it updates the existing address instead of adding a new one.
452 assertTrue(lp.addLinkAddress(deprecated));
453 assertEquals(1, lp.getLinkAddresses().size());
454 assertEquals(deprecated, getFirstLinkAddress(lp));
455 assertFalse(LINKADDRV6.equals(getFirstLinkAddress(lp)));
456
457 // Removing LINKADDRV6 removes deprecated, because removing addresses ignores properties.
458 assertTrue(lp.removeLinkAddress(LINKADDRV6));
459 assertEquals(0, lp.getLinkAddresses().size());
Lorenzo Colitti8ec0b8a2013-03-08 19:11:40 -0800460 }
Lorenzo Colitti174782b2013-08-23 20:54:49 +0900461
Hugo Benichi87d306b2017-10-12 09:54:49 +0900462 @Test
Lorenzo Colitti174782b2013-08-23 20:54:49 +0900463 public void testSetLinkAddresses() {
464 LinkProperties lp = new LinkProperties();
465 lp.addLinkAddress(LINKADDRV4);
466 lp.addLinkAddress(LINKADDRV6);
467
468 LinkProperties lp2 = new LinkProperties();
469 lp2.addLinkAddress(LINKADDRV6);
470
471 assertFalse(lp.equals(lp2));
472
473 lp2.setLinkAddresses(lp.getLinkAddresses());
474 assertTrue(lp.equals(lp));
475 }
Erik Kline8b023072014-10-24 21:50:20 +0900476
Hugo Benichi87d306b2017-10-12 09:54:49 +0900477 @Test
Erik Kline8b023072014-10-24 21:50:20 +0900478 public void testIsProvisioned() {
479 LinkProperties lp4 = new LinkProperties();
480 assertFalse("v4only:empty", lp4.isProvisioned());
481 lp4.addLinkAddress(LINKADDRV4);
482 assertFalse("v4only:addr-only", lp4.isProvisioned());
483 lp4.addDnsServer(DNS1);
484 assertFalse("v4only:addr+dns", lp4.isProvisioned());
485 lp4.addRoute(new RouteInfo(GATEWAY1));
486 assertTrue("v4only:addr+dns+route", lp4.isProvisioned());
Erik Kline04612b02015-05-21 16:15:02 +0900487 assertTrue("v4only:addr+dns+route", lp4.isIPv4Provisioned());
488 assertFalse("v4only:addr+dns+route", lp4.isIPv6Provisioned());
Erik Kline8b023072014-10-24 21:50:20 +0900489
490 LinkProperties lp6 = new LinkProperties();
491 assertFalse("v6only:empty", lp6.isProvisioned());
492 lp6.addLinkAddress(LINKADDRV6LINKLOCAL);
493 assertFalse("v6only:fe80-only", lp6.isProvisioned());
494 lp6.addDnsServer(DNS6);
495 assertFalse("v6only:fe80+dns", lp6.isProvisioned());
Erik Kline04612b02015-05-21 16:15:02 +0900496 lp6.addRoute(new RouteInfo(GATEWAY61));
Erik Kline8b023072014-10-24 21:50:20 +0900497 assertFalse("v6only:fe80+dns+route", lp6.isProvisioned());
498 lp6.addLinkAddress(LINKADDRV6);
Erik Kline04612b02015-05-21 16:15:02 +0900499 assertTrue("v6only:fe80+global+dns+route", lp6.isIPv6Provisioned());
Erik Kline8b023072014-10-24 21:50:20 +0900500 assertTrue("v6only:fe80+global+dns+route", lp6.isProvisioned());
501 lp6.removeLinkAddress(LINKADDRV6LINKLOCAL);
Erik Kline04612b02015-05-21 16:15:02 +0900502 assertFalse("v6only:global+dns+route", lp6.isIPv4Provisioned());
503 assertTrue("v6only:global+dns+route", lp6.isIPv6Provisioned());
Erik Kline8b023072014-10-24 21:50:20 +0900504 assertTrue("v6only:global+dns+route", lp6.isProvisioned());
505
506 LinkProperties lp46 = new LinkProperties();
507 lp46.addLinkAddress(LINKADDRV4);
508 lp46.addLinkAddress(LINKADDRV6);
509 lp46.addDnsServer(DNS1);
510 lp46.addDnsServer(DNS6);
511 assertFalse("dualstack:missing-routes", lp46.isProvisioned());
512 lp46.addRoute(new RouteInfo(GATEWAY1));
Erik Kline04612b02015-05-21 16:15:02 +0900513 assertTrue("dualstack:v4-provisioned", lp46.isIPv4Provisioned());
514 assertFalse("dualstack:v4-provisioned", lp46.isIPv6Provisioned());
Erik Kline8b023072014-10-24 21:50:20 +0900515 assertTrue("dualstack:v4-provisioned", lp46.isProvisioned());
Erik Kline04612b02015-05-21 16:15:02 +0900516 lp46.addRoute(new RouteInfo(GATEWAY61));
517 assertTrue("dualstack:both-provisioned", lp46.isIPv4Provisioned());
518 assertTrue("dualstack:both-provisioned", lp46.isIPv6Provisioned());
Erik Kline8b023072014-10-24 21:50:20 +0900519 assertTrue("dualstack:both-provisioned", lp46.isProvisioned());
520
521 // A link with an IPv6 address and default route, but IPv4 DNS server.
522 LinkProperties mixed = new LinkProperties();
523 mixed.addLinkAddress(LINKADDRV6);
524 mixed.addDnsServer(DNS1);
Erik Kline04612b02015-05-21 16:15:02 +0900525 mixed.addRoute(new RouteInfo(GATEWAY61));
526 assertFalse("mixed:addr6+route6+dns4", mixed.isIPv4Provisioned());
527 assertFalse("mixed:addr6+route6+dns4", mixed.isIPv6Provisioned());
Erik Kline8b023072014-10-24 21:50:20 +0900528 assertFalse("mixed:addr6+route6+dns4", mixed.isProvisioned());
529 }
Erik Kline04612b02015-05-21 16:15:02 +0900530
Hugo Benichi87d306b2017-10-12 09:54:49 +0900531 @Test
Erik Kline04612b02015-05-21 16:15:02 +0900532 public void testCompareProvisioning() {
533 LinkProperties v4lp = new LinkProperties();
534 v4lp.addLinkAddress(LINKADDRV4);
535 v4lp.addRoute(new RouteInfo(GATEWAY1));
536 v4lp.addDnsServer(DNS1);
537 assertTrue(v4lp.isProvisioned());
538
539 LinkProperties v4r = new LinkProperties(v4lp);
540 v4r.removeDnsServer(DNS1);
541 assertFalse(v4r.isProvisioned());
542
543 assertEquals(ProvisioningChange.STILL_NOT_PROVISIONED,
544 LinkProperties.compareProvisioning(v4r, v4r));
545 assertEquals(ProvisioningChange.LOST_PROVISIONING,
546 LinkProperties.compareProvisioning(v4lp, v4r));
547 assertEquals(ProvisioningChange.GAINED_PROVISIONING,
548 LinkProperties.compareProvisioning(v4r, v4lp));
549 assertEquals(ProvisioningChange.STILL_PROVISIONED,
550 LinkProperties.compareProvisioning(v4lp, v4lp));
551
552 // Check that losing IPv4 provisioning on a dualstack network is
553 // seen as a total loss of provisioning.
554 LinkProperties v6lp = new LinkProperties();
555 v6lp.addLinkAddress(LINKADDRV6);
556 v6lp.addRoute(new RouteInfo(GATEWAY61));
557 v6lp.addDnsServer(DNS6);
558 assertFalse(v6lp.isIPv4Provisioned());
559 assertTrue(v6lp.isIPv6Provisioned());
560 assertTrue(v6lp.isProvisioned());
561
562 LinkProperties v46lp = new LinkProperties(v6lp);
563 v46lp.addLinkAddress(LINKADDRV4);
564 v46lp.addRoute(new RouteInfo(GATEWAY1));
565 v46lp.addDnsServer(DNS1);
566 assertTrue(v46lp.isIPv4Provisioned());
567 assertTrue(v46lp.isIPv6Provisioned());
568 assertTrue(v46lp.isProvisioned());
569
570 assertEquals(ProvisioningChange.STILL_PROVISIONED,
Erik Klineaa8f8f32015-08-14 12:16:55 +0900571 LinkProperties.compareProvisioning(v4lp, v46lp));
572 assertEquals(ProvisioningChange.STILL_PROVISIONED,
Erik Kline04612b02015-05-21 16:15:02 +0900573 LinkProperties.compareProvisioning(v6lp, v46lp));
574 assertEquals(ProvisioningChange.LOST_PROVISIONING,
575 LinkProperties.compareProvisioning(v46lp, v6lp));
Erik Klineaa8f8f32015-08-14 12:16:55 +0900576 assertEquals(ProvisioningChange.LOST_PROVISIONING,
577 LinkProperties.compareProvisioning(v46lp, v4lp));
Erik Kline04612b02015-05-21 16:15:02 +0900578
579 // Check that losing and gaining a secondary router does not change
580 // the provisioning status.
581 LinkProperties v6lp2 = new LinkProperties(v6lp);
582 v6lp2.addRoute(new RouteInfo(GATEWAY62));
583 assertTrue(v6lp2.isProvisioned());
584
585 assertEquals(ProvisioningChange.STILL_PROVISIONED,
586 LinkProperties.compareProvisioning(v6lp2, v6lp));
587 assertEquals(ProvisioningChange.STILL_PROVISIONED,
588 LinkProperties.compareProvisioning(v6lp, v6lp2));
589 }
Erik Klinea923dba2015-06-26 19:21:34 +0900590
Hugo Benichi87d306b2017-10-12 09:54:49 +0900591 @Test
Erik Klinea923dba2015-06-26 19:21:34 +0900592 public void testIsReachable() {
593 final LinkProperties v4lp = new LinkProperties();
594 assertFalse(v4lp.isReachable(DNS1));
595 assertFalse(v4lp.isReachable(DNS2));
596
597 // Add an on-link route, making the on-link DNS server reachable,
598 // but there is still no IPv4 address.
599 assertTrue(v4lp.addRoute(new RouteInfo(
600 new IpPrefix(NetworkUtils.numericToInetAddress("75.208.0.0"), 16))));
601 assertFalse(v4lp.isReachable(DNS1));
602 assertFalse(v4lp.isReachable(DNS2));
603
604 // Adding an IPv4 address (right now, any IPv4 address) means we use
605 // the routes to compute likely reachability.
606 assertTrue(v4lp.addLinkAddress(new LinkAddress(ADDRV4, 16)));
607 assertTrue(v4lp.isReachable(DNS1));
608 assertFalse(v4lp.isReachable(DNS2));
609
610 // Adding a default route makes the off-link DNS server reachable.
611 assertTrue(v4lp.addRoute(new RouteInfo(GATEWAY1)));
612 assertTrue(v4lp.isReachable(DNS1));
613 assertTrue(v4lp.isReachable(DNS2));
614
615 final LinkProperties v6lp = new LinkProperties();
616 final InetAddress kLinkLocalDns = NetworkUtils.numericToInetAddress("fe80::6:1");
617 final InetAddress kLinkLocalDnsWithScope = NetworkUtils.numericToInetAddress("fe80::6:2%43");
618 final InetAddress kOnLinkDns = NetworkUtils.numericToInetAddress("2001:db8:85a3::53");
619 assertFalse(v6lp.isReachable(kLinkLocalDns));
620 assertFalse(v6lp.isReachable(kLinkLocalDnsWithScope));
621 assertFalse(v6lp.isReachable(kOnLinkDns));
622 assertFalse(v6lp.isReachable(DNS6));
623
624 // Add a link-local route, making the link-local DNS servers reachable. Because
625 // we assume the presence of an IPv6 link-local address, link-local DNS servers
626 // are considered reachable, but only those with a non-zero scope identifier.
627 assertTrue(v6lp.addRoute(new RouteInfo(
628 new IpPrefix(NetworkUtils.numericToInetAddress("fe80::"), 64))));
629 assertFalse(v6lp.isReachable(kLinkLocalDns));
630 assertTrue(v6lp.isReachable(kLinkLocalDnsWithScope));
631 assertFalse(v6lp.isReachable(kOnLinkDns));
632 assertFalse(v6lp.isReachable(DNS6));
633
634 // Add a link-local address--nothing changes.
635 assertTrue(v6lp.addLinkAddress(LINKADDRV6LINKLOCAL));
636 assertFalse(v6lp.isReachable(kLinkLocalDns));
637 assertTrue(v6lp.isReachable(kLinkLocalDnsWithScope));
638 assertFalse(v6lp.isReachable(kOnLinkDns));
639 assertFalse(v6lp.isReachable(DNS6));
640
641 // Add a global route on link, but no global address yet. DNS servers reachable
642 // via a route that doesn't require a gateway: give them the benefit of the
643 // doubt and hope the link-local source address suffices for communication.
644 assertTrue(v6lp.addRoute(new RouteInfo(
645 new IpPrefix(NetworkUtils.numericToInetAddress("2001:db8:85a3::"), 64))));
646 assertFalse(v6lp.isReachable(kLinkLocalDns));
647 assertTrue(v6lp.isReachable(kLinkLocalDnsWithScope));
648 assertTrue(v6lp.isReachable(kOnLinkDns));
649 assertFalse(v6lp.isReachable(DNS6));
650
651 // Add a global address; the on-link global address DNS server is (still)
652 // presumed reachable.
653 assertTrue(v6lp.addLinkAddress(new LinkAddress(ADDRV6, 64)));
654 assertFalse(v6lp.isReachable(kLinkLocalDns));
655 assertTrue(v6lp.isReachable(kLinkLocalDnsWithScope));
656 assertTrue(v6lp.isReachable(kOnLinkDns));
657 assertFalse(v6lp.isReachable(DNS6));
658
659 // Adding a default route makes the off-link DNS server reachable.
660 assertTrue(v6lp.addRoute(new RouteInfo(GATEWAY62)));
661 assertFalse(v6lp.isReachable(kLinkLocalDns));
662 assertTrue(v6lp.isReachable(kLinkLocalDnsWithScope));
663 assertTrue(v6lp.isReachable(kOnLinkDns));
664 assertTrue(v6lp.isReachable(DNS6));
Lorenzo Colitti28bb16c2015-07-30 23:41:43 +0900665
666 // Check isReachable on stacked links. This requires that the source IP address be assigned
667 // on the interface returned by the route lookup.
668 LinkProperties stacked = new LinkProperties();
669
670 // Can't add a stacked link without an interface name.
671 stacked.setInterfaceName("v4-test0");
672 v6lp.addStackedLink(stacked);
673
674 InetAddress stackedAddress = Address("192.0.0.4");
675 LinkAddress stackedLinkAddress = new LinkAddress(stackedAddress, 32);
676 assertFalse(v6lp.isReachable(stackedAddress));
677 stacked.addLinkAddress(stackedLinkAddress);
678 assertFalse(v6lp.isReachable(stackedAddress));
679 stacked.addRoute(new RouteInfo(stackedLinkAddress));
680 assertTrue(stacked.isReachable(stackedAddress));
681 assertTrue(v6lp.isReachable(stackedAddress));
682
683 assertFalse(v6lp.isReachable(DNS1));
684 stacked.addRoute(new RouteInfo((IpPrefix) null, stackedAddress));
685 assertTrue(v6lp.isReachable(DNS1));
Erik Klinea923dba2015-06-26 19:21:34 +0900686 }
Rubin Xuffd77d82017-09-05 18:40:49 +0100687
Hugo Benichi87d306b2017-10-12 09:54:49 +0900688 @Test
Rubin Xuffd77d82017-09-05 18:40:49 +0100689 public void testLinkPropertiesEnsureDirectlyConnectedRoutes() {
690 // IPv4 case: no route added initially
691 LinkProperties rmnet0 = new LinkProperties();
692 rmnet0.setInterfaceName("rmnet0");
693 rmnet0.addLinkAddress(new LinkAddress("10.0.0.2/8"));
694 RouteInfo directRoute0 = new RouteInfo(new IpPrefix("10.0.0.0/8"), null,
695 rmnet0.getInterfaceName());
696
697 // Since no routes is added explicitly, getAllRoutes() should return empty.
698 assertTrue(rmnet0.getAllRoutes().isEmpty());
699 rmnet0.ensureDirectlyConnectedRoutes();
700 // ensureDirectlyConnectedRoutes() should have added the missing local route.
701 assertEqualRoutes(Collections.singletonList(directRoute0), rmnet0.getAllRoutes());
702
703 // IPv4 case: both direct and default routes added initially
704 LinkProperties rmnet1 = new LinkProperties();
705 rmnet1.setInterfaceName("rmnet1");
706 rmnet1.addLinkAddress(new LinkAddress("10.0.0.3/8"));
707 RouteInfo defaultRoute1 = new RouteInfo((IpPrefix) null,
708 NetworkUtils.numericToInetAddress("10.0.0.1"), rmnet1.getInterfaceName());
709 RouteInfo directRoute1 = new RouteInfo(new IpPrefix("10.0.0.0/8"), null,
710 rmnet1.getInterfaceName());
711 rmnet1.addRoute(defaultRoute1);
712 rmnet1.addRoute(directRoute1);
713
714 // Check added routes
715 assertEqualRoutes(Arrays.asList(defaultRoute1, directRoute1), rmnet1.getAllRoutes());
716 // ensureDirectlyConnectedRoutes() shouldn't change the routes since direct connected
717 // route is already part of the configuration.
718 rmnet1.ensureDirectlyConnectedRoutes();
719 assertEqualRoutes(Arrays.asList(defaultRoute1, directRoute1), rmnet1.getAllRoutes());
720
721 // IPv6 case: only default routes added initially
722 LinkProperties rmnet2 = new LinkProperties();
723 rmnet2.setInterfaceName("rmnet2");
724 rmnet2.addLinkAddress(new LinkAddress("fe80::cafe/64"));
725 rmnet2.addLinkAddress(new LinkAddress("2001:db8::2/64"));
726 RouteInfo defaultRoute2 = new RouteInfo((IpPrefix) null,
727 NetworkUtils.numericToInetAddress("2001:db8::1"), rmnet2.getInterfaceName());
728 RouteInfo directRoute2 = new RouteInfo(new IpPrefix("2001:db8::/64"), null,
729 rmnet2.getInterfaceName());
730 RouteInfo linkLocalRoute2 = new RouteInfo(new IpPrefix("fe80::/64"), null,
731 rmnet2.getInterfaceName());
732 rmnet2.addRoute(defaultRoute2);
733
734 assertEqualRoutes(Arrays.asList(defaultRoute2), rmnet2.getAllRoutes());
735 rmnet2.ensureDirectlyConnectedRoutes();
736 assertEqualRoutes(Arrays.asList(defaultRoute2, directRoute2, linkLocalRoute2),
737 rmnet2.getAllRoutes());
738
739 // Corner case: no interface name
740 LinkProperties rmnet3 = new LinkProperties();
741 rmnet3.addLinkAddress(new LinkAddress("192.168.0.2/24"));
742 RouteInfo directRoute3 = new RouteInfo(new IpPrefix("192.168.0.0/24"), null,
743 rmnet3.getInterfaceName());
744
745 assertTrue(rmnet3.getAllRoutes().isEmpty());
746 rmnet3.ensureDirectlyConnectedRoutes();
747 assertEqualRoutes(Collections.singletonList(directRoute3), rmnet3.getAllRoutes());
748
749 }
750
Hugo Benichi87d306b2017-10-12 09:54:49 +0900751 @Test
Rubin Xu2fa7d9e2017-08-22 16:35:52 +0100752 public void testCompareResult() {
753 // Either adding or removing items
Hugo Benichi87d306b2017-10-12 09:54:49 +0900754 compareResult(Arrays.asList(1, 2, 3, 4), Arrays.asList(1),
Rubin Xu2fa7d9e2017-08-22 16:35:52 +0100755 Arrays.asList(2, 3, 4), new ArrayList<>());
Hugo Benichi87d306b2017-10-12 09:54:49 +0900756 compareResult(Arrays.asList(1, 2), Arrays.asList(3, 2, 1, 4),
Rubin Xu2fa7d9e2017-08-22 16:35:52 +0100757 new ArrayList<>(), Arrays.asList(3, 4));
758
759
760 // adding and removing items at the same time
Hugo Benichi87d306b2017-10-12 09:54:49 +0900761 compareResult(Arrays.asList(1, 2, 3, 4), Arrays.asList(2, 3, 4, 5),
Rubin Xu2fa7d9e2017-08-22 16:35:52 +0100762 Arrays.asList(1), Arrays.asList(5));
Hugo Benichi87d306b2017-10-12 09:54:49 +0900763 compareResult(Arrays.asList(1, 2, 3), Arrays.asList(4, 5, 6),
Rubin Xu2fa7d9e2017-08-22 16:35:52 +0100764 Arrays.asList(1, 2, 3), Arrays.asList(4, 5, 6));
765
766 // null cases
Hugo Benichi87d306b2017-10-12 09:54:49 +0900767 compareResult(Arrays.asList(1, 2, 3), null, Arrays.asList(1, 2, 3), new ArrayList<>());
768 compareResult(null, Arrays.asList(3, 2, 1), new ArrayList<>(), Arrays.asList(1, 2, 3));
769 compareResult(null, null, new ArrayList<>(), new ArrayList<>());
Rubin Xu2fa7d9e2017-08-22 16:35:52 +0100770 }
771
Rubin Xuffd77d82017-09-05 18:40:49 +0100772 private void assertEqualRoutes(Collection<RouteInfo> expected, Collection<RouteInfo> actual) {
773 Set<RouteInfo> expectedSet = new ArraySet<>(expected);
774 Set<RouteInfo> actualSet = new ArraySet<>(actual);
775 // Duplicated entries in actual routes are considered failures
776 assertEquals(actual.size(), actualSet.size());
777
778 assertEquals(expectedSet, actualSet);
779 }
Rubin Xu2fa7d9e2017-08-22 16:35:52 +0100780
Hugo Benichi87d306b2017-10-12 09:54:49 +0900781 private <T> void compareResult(List<T> oldItems, List<T> newItems, List<T> expectRemoved,
Rubin Xu83012442017-09-15 11:51:39 +0100782 List<T> expectAdded) {
783 CompareResult<T> result = new CompareResult<>(oldItems, newItems);
Rubin Xu2fa7d9e2017-08-22 16:35:52 +0100784 assertEquals(new ArraySet<>(expectAdded), new ArraySet<>(result.added));
785 assertEquals(new ArraySet<>(expectRemoved), (new ArraySet<>(result.removed)));
786 }
John Wang3e567d52011-04-04 12:35:42 -0700787}