Home | History | Annotate | Download | only in net
      1 /*
      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 
     17 package android.net;
     18 
     19 import android.net.IpPrefix;
     20 import android.net.LinkAddress;
     21 import android.net.LinkProperties;
     22 import android.net.LinkProperties.ProvisioningChange;
     23 import android.net.RouteInfo;
     24 import android.system.OsConstants;
     25 import android.test.suitebuilder.annotation.SmallTest;
     26 import junit.framework.TestCase;
     27 
     28 import java.net.InetAddress;
     29 import java.util.ArrayList;
     30 
     31 
     32 public class LinkPropertiesTest extends TestCase {
     33     private static InetAddress ADDRV4 = NetworkUtils.numericToInetAddress("75.208.6.1");
     34     private static InetAddress ADDRV6 = NetworkUtils.numericToInetAddress(
     35             "2001:0db8:85a3:0000:0000:8a2e:0370:7334");
     36     private static InetAddress DNS1 = NetworkUtils.numericToInetAddress("75.208.7.1");
     37     private static InetAddress DNS2 = NetworkUtils.numericToInetAddress("69.78.7.1");
     38     private static InetAddress DNS6 = NetworkUtils.numericToInetAddress("2001:4860:4860::8888");
     39     private static InetAddress GATEWAY1 = NetworkUtils.numericToInetAddress("75.208.8.1");
     40     private static InetAddress GATEWAY2 = NetworkUtils.numericToInetAddress("69.78.8.1");
     41     private static InetAddress GATEWAY61 = NetworkUtils.numericToInetAddress("fe80::6:0000:613");
     42     private static InetAddress GATEWAY62 = NetworkUtils.numericToInetAddress("fe80::6:2222");
     43     private static String NAME = "qmi0";
     44     private static int MTU = 1500;
     45 
     46     private static LinkAddress LINKADDRV4 = new LinkAddress(ADDRV4, 32);
     47     private static LinkAddress LINKADDRV6 = new LinkAddress(ADDRV6, 128);
     48     private static LinkAddress LINKADDRV6LINKLOCAL = new LinkAddress("fe80::1/64");
     49 
     50     public void assertLinkPropertiesEqual(LinkProperties source, LinkProperties target) {
     51         // Check implementation of equals(), element by element.
     52         assertTrue(source.isIdenticalInterfaceName(target));
     53         assertTrue(target.isIdenticalInterfaceName(source));
     54 
     55         assertTrue(source.isIdenticalAddresses(target));
     56         assertTrue(target.isIdenticalAddresses(source));
     57 
     58         assertTrue(source.isIdenticalDnses(target));
     59         assertTrue(target.isIdenticalDnses(source));
     60 
     61         assertTrue(source.isIdenticalRoutes(target));
     62         assertTrue(target.isIdenticalRoutes(source));
     63 
     64         assertTrue(source.isIdenticalHttpProxy(target));
     65         assertTrue(target.isIdenticalHttpProxy(source));
     66 
     67         assertTrue(source.isIdenticalStackedLinks(target));
     68         assertTrue(target.isIdenticalStackedLinks(source));
     69 
     70         assertTrue(source.isIdenticalMtu(target));
     71         assertTrue(target.isIdenticalMtu(source));
     72 
     73         // Check result of equals().
     74         assertTrue(source.equals(target));
     75         assertTrue(target.equals(source));
     76 
     77         // Check hashCode.
     78         assertEquals(source.hashCode(), target.hashCode());
     79     }
     80 
     81     @SmallTest
     82     public void testEqualsNull() {
     83         LinkProperties source = new LinkProperties();
     84         LinkProperties target = new LinkProperties();
     85 
     86         assertFalse(source == target);
     87         assertLinkPropertiesEqual(source, target);
     88     }
     89 
     90     @SmallTest
     91     public void testEqualsSameOrder() {
     92         try {
     93             LinkProperties source = new LinkProperties();
     94             source.setInterfaceName(NAME);
     95             // set 2 link addresses
     96             source.addLinkAddress(LINKADDRV4);
     97             source.addLinkAddress(LINKADDRV6);
     98             // set 2 dnses
     99             source.addDnsServer(DNS1);
    100             source.addDnsServer(DNS2);
    101             // set 2 gateways
    102             source.addRoute(new RouteInfo(GATEWAY1));
    103             source.addRoute(new RouteInfo(GATEWAY2));
    104             source.setMtu(MTU);
    105 
    106             LinkProperties target = new LinkProperties();
    107 
    108             // All fields are same
    109             target.setInterfaceName(NAME);
    110             target.addLinkAddress(LINKADDRV4);
    111             target.addLinkAddress(LINKADDRV6);
    112             target.addDnsServer(DNS1);
    113             target.addDnsServer(DNS2);
    114             target.addRoute(new RouteInfo(GATEWAY1));
    115             target.addRoute(new RouteInfo(GATEWAY2));
    116             target.setMtu(MTU);
    117 
    118             assertLinkPropertiesEqual(source, target);
    119 
    120             target.clear();
    121             // change Interface Name
    122             target.setInterfaceName("qmi1");
    123             target.addLinkAddress(LINKADDRV4);
    124             target.addLinkAddress(LINKADDRV6);
    125             target.addDnsServer(DNS1);
    126             target.addDnsServer(DNS2);
    127             target.addRoute(new RouteInfo(GATEWAY1));
    128             target.addRoute(new RouteInfo(GATEWAY2));
    129             target.setMtu(MTU);
    130             assertFalse(source.equals(target));
    131 
    132             target.clear();
    133             target.setInterfaceName(NAME);
    134             // change link addresses
    135             target.addLinkAddress(new LinkAddress(
    136                     NetworkUtils.numericToInetAddress("75.208.6.2"), 32));
    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);
    143             assertFalse(source.equals(target));
    144 
    145             target.clear();
    146             target.setInterfaceName(NAME);
    147             target.addLinkAddress(LINKADDRV4);
    148             target.addLinkAddress(LINKADDRV6);
    149             // change dnses
    150             target.addDnsServer(NetworkUtils.numericToInetAddress("75.208.7.2"));
    151             target.addDnsServer(DNS2);
    152             target.addRoute(new RouteInfo(GATEWAY1));
    153             target.addRoute(new RouteInfo(GATEWAY2));
    154             target.setMtu(MTU);
    155             assertFalse(source.equals(target));
    156 
    157             target.clear();
    158             target.setInterfaceName(NAME);
    159             target.addLinkAddress(LINKADDRV4);
    160             target.addLinkAddress(LINKADDRV6);
    161             target.addDnsServer(DNS1);
    162             target.addDnsServer(DNS2);
    163             // change gateway
    164             target.addRoute(new RouteInfo(NetworkUtils.numericToInetAddress("75.208.8.2")));
    165             target.addRoute(new RouteInfo(GATEWAY2));
    166             target.setMtu(MTU);
    167             assertFalse(source.equals(target));
    168 
    169             target.clear();
    170             target.setInterfaceName(NAME);
    171             target.addLinkAddress(LINKADDRV4);
    172             target.addLinkAddress(LINKADDRV6);
    173             target.addDnsServer(DNS1);
    174             target.addDnsServer(DNS2);
    175             target.addRoute(new RouteInfo(GATEWAY1));
    176             target.addRoute(new RouteInfo(GATEWAY2));
    177             // change mtu
    178             target.setMtu(1440);
    179             assertFalse(source.equals(target));
    180 
    181         } catch (Exception e) {
    182             throw new RuntimeException(e.toString());
    183             //fail();
    184         }
    185     }
    186 
    187     @SmallTest
    188     public void testEqualsDifferentOrder() {
    189         try {
    190             LinkProperties source = new LinkProperties();
    191             source.setInterfaceName(NAME);
    192             // set 2 link addresses
    193             source.addLinkAddress(LINKADDRV4);
    194             source.addLinkAddress(LINKADDRV6);
    195             // set 2 dnses
    196             source.addDnsServer(DNS1);
    197             source.addDnsServer(DNS2);
    198             // set 2 gateways
    199             source.addRoute(new RouteInfo(GATEWAY1));
    200             source.addRoute(new RouteInfo(GATEWAY2));
    201             source.setMtu(MTU);
    202 
    203             LinkProperties target = new LinkProperties();
    204             // Exchange order
    205             target.setInterfaceName(NAME);
    206             target.addLinkAddress(LINKADDRV6);
    207             target.addLinkAddress(LINKADDRV4);
    208             target.addDnsServer(DNS2);
    209             target.addDnsServer(DNS1);
    210             target.addRoute(new RouteInfo(GATEWAY2));
    211             target.addRoute(new RouteInfo(GATEWAY1));
    212             target.setMtu(MTU);
    213 
    214             assertLinkPropertiesEqual(source, target);
    215         } catch (Exception e) {
    216             fail();
    217         }
    218     }
    219 
    220     @SmallTest
    221     public void testEqualsDuplicated() {
    222         try {
    223             LinkProperties source = new LinkProperties();
    224             // set 3 link addresses, eg, [A, A, B]
    225             source.addLinkAddress(LINKADDRV4);
    226             source.addLinkAddress(LINKADDRV4);
    227             source.addLinkAddress(LINKADDRV6);
    228 
    229             LinkProperties target = new LinkProperties();
    230             // set 3 link addresses, eg, [A, B, B]
    231             target.addLinkAddress(LINKADDRV4);
    232             target.addLinkAddress(LINKADDRV6);
    233             target.addLinkAddress(LINKADDRV6);
    234 
    235             assertLinkPropertiesEqual(source, target);
    236         } catch (Exception e) {
    237             fail();
    238         }
    239     }
    240 
    241     private void assertAllRoutesHaveInterface(String iface, LinkProperties lp) {
    242         for (RouteInfo r : lp.getRoutes()) {
    243             assertEquals(iface, r.getInterface());
    244         }
    245     }
    246 
    247     @SmallTest
    248     public void testRouteInterfaces() {
    249         LinkAddress prefix = new LinkAddress(
    250             NetworkUtils.numericToInetAddress("2001:db8::"), 32);
    251         InetAddress address = ADDRV6;
    252 
    253         // Add a route with no interface to a LinkProperties with no interface. No errors.
    254         LinkProperties lp = new LinkProperties();
    255         RouteInfo r = new RouteInfo(prefix, address, null);
    256         assertTrue(lp.addRoute(r));
    257         assertEquals(1, lp.getRoutes().size());
    258         assertAllRoutesHaveInterface(null, lp);
    259 
    260         // Adding the same route twice has no effect.
    261         assertFalse(lp.addRoute(r));
    262         assertEquals(1, lp.getRoutes().size());
    263 
    264         // Add a route with an interface. Expect an exception.
    265         r = new RouteInfo(prefix, address, "wlan0");
    266         try {
    267           lp.addRoute(r);
    268           fail("Adding wlan0 route to LP with no interface, expect exception");
    269         } catch (IllegalArgumentException expected) {}
    270 
    271         // Change the interface name. All the routes should change their interface name too.
    272         lp.setInterfaceName("rmnet0");
    273         assertAllRoutesHaveInterface("rmnet0", lp);
    274 
    275         // Now add a route with the wrong interface. This causes an exception too.
    276         try {
    277           lp.addRoute(r);
    278           fail("Adding wlan0 route to rmnet0 LP, expect exception");
    279         } catch (IllegalArgumentException expected) {}
    280 
    281         // If the interface name matches, the route is added.
    282         r = new RouteInfo(prefix, null, "wlan0");
    283         lp.setInterfaceName("wlan0");
    284         lp.addRoute(r);
    285         assertEquals(2, lp.getRoutes().size());
    286         assertAllRoutesHaveInterface("wlan0", lp);
    287 
    288         // Routes with null interfaces are converted to wlan0.
    289         r = RouteInfo.makeHostRoute(ADDRV6, null);
    290         lp.addRoute(r);
    291         assertEquals(3, lp.getRoutes().size());
    292         assertAllRoutesHaveInterface("wlan0", lp);
    293 
    294         // Check comparisons work.
    295         LinkProperties lp2 = new LinkProperties(lp);
    296         assertAllRoutesHaveInterface("wlan0", lp);
    297         assertEquals(0, lp.compareAllRoutes(lp2).added.size());
    298         assertEquals(0, lp.compareAllRoutes(lp2).removed.size());
    299 
    300         lp2.setInterfaceName("p2p0");
    301         assertAllRoutesHaveInterface("p2p0", lp2);
    302         assertEquals(3, lp.compareAllRoutes(lp2).added.size());
    303         assertEquals(3, lp.compareAllRoutes(lp2).removed.size());
    304     }
    305 
    306     @SmallTest
    307     public void testStackedInterfaces() {
    308         LinkProperties rmnet0 = new LinkProperties();
    309         rmnet0.setInterfaceName("rmnet0");
    310         rmnet0.addLinkAddress(LINKADDRV6);
    311 
    312         LinkProperties clat4 = new LinkProperties();
    313         clat4.setInterfaceName("clat4");
    314         clat4.addLinkAddress(LINKADDRV4);
    315 
    316         assertEquals(0, rmnet0.getStackedLinks().size());
    317         assertEquals(1, rmnet0.getAddresses().size());
    318         assertEquals(1, rmnet0.getLinkAddresses().size());
    319         assertEquals(1, rmnet0.getAllAddresses().size());
    320         assertEquals(1, rmnet0.getAllLinkAddresses().size());
    321 
    322         rmnet0.addStackedLink(clat4);
    323         assertEquals(1, rmnet0.getStackedLinks().size());
    324         assertEquals(1, rmnet0.getAddresses().size());
    325         assertEquals(1, rmnet0.getLinkAddresses().size());
    326         assertEquals(2, rmnet0.getAllAddresses().size());
    327         assertEquals(2, rmnet0.getAllLinkAddresses().size());
    328 
    329         rmnet0.addStackedLink(clat4);
    330         assertEquals(1, rmnet0.getStackedLinks().size());
    331         assertEquals(1, rmnet0.getAddresses().size());
    332         assertEquals(1, rmnet0.getLinkAddresses().size());
    333         assertEquals(2, rmnet0.getAllAddresses().size());
    334         assertEquals(2, rmnet0.getAllLinkAddresses().size());
    335 
    336         assertEquals(0, clat4.getStackedLinks().size());
    337 
    338         // Modify an item in the returned collection to see what happens.
    339         for (LinkProperties link : rmnet0.getStackedLinks()) {
    340             if (link.getInterfaceName().equals("clat4")) {
    341                link.setInterfaceName("newname");
    342             }
    343         }
    344         for (LinkProperties link : rmnet0.getStackedLinks()) {
    345             assertFalse("newname".equals(link.getInterfaceName()));
    346         }
    347 
    348         assertTrue(rmnet0.removeStackedLink("clat4"));
    349         assertEquals(0, rmnet0.getStackedLinks().size());
    350         assertEquals(1, rmnet0.getAddresses().size());
    351         assertEquals(1, rmnet0.getLinkAddresses().size());
    352         assertEquals(1, rmnet0.getAllAddresses().size());
    353         assertEquals(1, rmnet0.getAllLinkAddresses().size());
    354 
    355         assertFalse(rmnet0.removeStackedLink("clat4"));
    356     }
    357 
    358     private LinkAddress getFirstLinkAddress(LinkProperties lp) {
    359         return lp.getLinkAddresses().iterator().next();
    360     }
    361 
    362     @SmallTest
    363     public void testAddressMethods() {
    364         LinkProperties lp = new LinkProperties();
    365 
    366         // No addresses.
    367         assertFalse(lp.hasIPv4Address());
    368         assertFalse(lp.hasGlobalIPv6Address());
    369 
    370         // Addresses on stacked links don't count.
    371         LinkProperties stacked = new LinkProperties();
    372         stacked.setInterfaceName("stacked");
    373         lp.addStackedLink(stacked);
    374         stacked.addLinkAddress(LINKADDRV4);
    375         stacked.addLinkAddress(LINKADDRV6);
    376         assertTrue(stacked.hasIPv4Address());
    377         assertTrue(stacked.hasGlobalIPv6Address());
    378         assertFalse(lp.hasIPv4Address());
    379         assertFalse(lp.hasGlobalIPv6Address());
    380         lp.removeStackedLink("stacked");
    381         assertFalse(lp.hasIPv4Address());
    382         assertFalse(lp.hasGlobalIPv6Address());
    383 
    384         // Addresses on the base link.
    385         // Check the return values of hasIPvXAddress and ensure the add/remove methods return true
    386         // iff something changes.
    387         assertEquals(0, lp.getLinkAddresses().size());
    388         assertTrue(lp.addLinkAddress(LINKADDRV6));
    389         assertEquals(1, lp.getLinkAddresses().size());
    390         assertFalse(lp.hasIPv4Address());
    391         assertTrue(lp.hasGlobalIPv6Address());
    392 
    393         assertTrue(lp.removeLinkAddress(LINKADDRV6));
    394         assertEquals(0, lp.getLinkAddresses().size());
    395 
    396         assertTrue(lp.addLinkAddress(LINKADDRV6LINKLOCAL));
    397         assertEquals(1, lp.getLinkAddresses().size());
    398         assertFalse(lp.hasGlobalIPv6Address());
    399 
    400         assertTrue(lp.addLinkAddress(LINKADDRV4));
    401         assertEquals(2, lp.getLinkAddresses().size());
    402         assertTrue(lp.hasIPv4Address());
    403         assertFalse(lp.hasGlobalIPv6Address());
    404 
    405         assertTrue(lp.addLinkAddress(LINKADDRV6));
    406         assertEquals(3, lp.getLinkAddresses().size());
    407         assertTrue(lp.hasIPv4Address());
    408         assertTrue(lp.hasGlobalIPv6Address());
    409 
    410         assertTrue(lp.removeLinkAddress(LINKADDRV6LINKLOCAL));
    411         assertEquals(2, lp.getLinkAddresses().size());
    412         assertTrue(lp.hasIPv4Address());
    413         assertTrue(lp.hasGlobalIPv6Address());
    414 
    415         // Adding an address twice has no effect.
    416         // Removing an address that's not present has no effect.
    417         assertFalse(lp.addLinkAddress(LINKADDRV4));
    418         assertEquals(2, lp.getLinkAddresses().size());
    419         assertTrue(lp.hasIPv4Address());
    420         assertTrue(lp.removeLinkAddress(LINKADDRV4));
    421         assertEquals(1, lp.getLinkAddresses().size());
    422         assertFalse(lp.hasIPv4Address());
    423         assertFalse(lp.removeLinkAddress(LINKADDRV4));
    424         assertEquals(1, lp.getLinkAddresses().size());
    425 
    426         // Adding an address that's already present but with different properties causes the
    427         // existing address to be updated and returns true.
    428         // Start with only LINKADDRV6.
    429         assertEquals(1, lp.getLinkAddresses().size());
    430         assertEquals(LINKADDRV6, getFirstLinkAddress(lp));
    431 
    432         // Create a LinkAddress object for the same address, but with different flags.
    433         LinkAddress deprecated = new LinkAddress(ADDRV6, 128,
    434                 OsConstants.IFA_F_DEPRECATED, OsConstants.RT_SCOPE_UNIVERSE);
    435         assertTrue(deprecated.isSameAddressAs(LINKADDRV6));
    436         assertFalse(deprecated.equals(LINKADDRV6));
    437 
    438         // Check that adding it updates the existing address instead of adding a new one.
    439         assertTrue(lp.addLinkAddress(deprecated));
    440         assertEquals(1, lp.getLinkAddresses().size());
    441         assertEquals(deprecated, getFirstLinkAddress(lp));
    442         assertFalse(LINKADDRV6.equals(getFirstLinkAddress(lp)));
    443 
    444         // Removing LINKADDRV6 removes deprecated, because removing addresses ignores properties.
    445         assertTrue(lp.removeLinkAddress(LINKADDRV6));
    446         assertEquals(0, lp.getLinkAddresses().size());
    447     }
    448 
    449     @SmallTest
    450     public void testSetLinkAddresses() {
    451         LinkProperties lp = new LinkProperties();
    452         lp.addLinkAddress(LINKADDRV4);
    453         lp.addLinkAddress(LINKADDRV6);
    454 
    455         LinkProperties lp2 = new LinkProperties();
    456         lp2.addLinkAddress(LINKADDRV6);
    457 
    458         assertFalse(lp.equals(lp2));
    459 
    460         lp2.setLinkAddresses(lp.getLinkAddresses());
    461         assertTrue(lp.equals(lp));
    462     }
    463 
    464     @SmallTest
    465     public void testIsProvisioned() {
    466         LinkProperties lp4 = new LinkProperties();
    467         assertFalse("v4only:empty", lp4.isProvisioned());
    468         lp4.addLinkAddress(LINKADDRV4);
    469         assertFalse("v4only:addr-only", lp4.isProvisioned());
    470         lp4.addDnsServer(DNS1);
    471         assertFalse("v4only:addr+dns", lp4.isProvisioned());
    472         lp4.addRoute(new RouteInfo(GATEWAY1));
    473         assertTrue("v4only:addr+dns+route", lp4.isProvisioned());
    474         assertTrue("v4only:addr+dns+route", lp4.isIPv4Provisioned());
    475         assertFalse("v4only:addr+dns+route", lp4.isIPv6Provisioned());
    476 
    477         LinkProperties lp6 = new LinkProperties();
    478         assertFalse("v6only:empty", lp6.isProvisioned());
    479         lp6.addLinkAddress(LINKADDRV6LINKLOCAL);
    480         assertFalse("v6only:fe80-only", lp6.isProvisioned());
    481         lp6.addDnsServer(DNS6);
    482         assertFalse("v6only:fe80+dns", lp6.isProvisioned());
    483         lp6.addRoute(new RouteInfo(GATEWAY61));
    484         assertFalse("v6only:fe80+dns+route", lp6.isProvisioned());
    485         lp6.addLinkAddress(LINKADDRV6);
    486         assertTrue("v6only:fe80+global+dns+route", lp6.isIPv6Provisioned());
    487         assertTrue("v6only:fe80+global+dns+route", lp6.isProvisioned());
    488         lp6.removeLinkAddress(LINKADDRV6LINKLOCAL);
    489         assertFalse("v6only:global+dns+route", lp6.isIPv4Provisioned());
    490         assertTrue("v6only:global+dns+route", lp6.isIPv6Provisioned());
    491         assertTrue("v6only:global+dns+route", lp6.isProvisioned());
    492 
    493         LinkProperties lp46 = new LinkProperties();
    494         lp46.addLinkAddress(LINKADDRV4);
    495         lp46.addLinkAddress(LINKADDRV6);
    496         lp46.addDnsServer(DNS1);
    497         lp46.addDnsServer(DNS6);
    498         assertFalse("dualstack:missing-routes", lp46.isProvisioned());
    499         lp46.addRoute(new RouteInfo(GATEWAY1));
    500         assertTrue("dualstack:v4-provisioned", lp46.isIPv4Provisioned());
    501         assertFalse("dualstack:v4-provisioned", lp46.isIPv6Provisioned());
    502         assertTrue("dualstack:v4-provisioned", lp46.isProvisioned());
    503         lp46.addRoute(new RouteInfo(GATEWAY61));
    504         assertTrue("dualstack:both-provisioned", lp46.isIPv4Provisioned());
    505         assertTrue("dualstack:both-provisioned", lp46.isIPv6Provisioned());
    506         assertTrue("dualstack:both-provisioned", lp46.isProvisioned());
    507 
    508         // A link with an IPv6 address and default route, but IPv4 DNS server.
    509         LinkProperties mixed = new LinkProperties();
    510         mixed.addLinkAddress(LINKADDRV6);
    511         mixed.addDnsServer(DNS1);
    512         mixed.addRoute(new RouteInfo(GATEWAY61));
    513         assertFalse("mixed:addr6+route6+dns4", mixed.isIPv4Provisioned());
    514         assertFalse("mixed:addr6+route6+dns4", mixed.isIPv6Provisioned());
    515         assertFalse("mixed:addr6+route6+dns4", mixed.isProvisioned());
    516     }
    517 
    518     @SmallTest
    519     public void testCompareProvisioning() {
    520         LinkProperties v4lp = new LinkProperties();
    521         v4lp.addLinkAddress(LINKADDRV4);
    522         v4lp.addRoute(new RouteInfo(GATEWAY1));
    523         v4lp.addDnsServer(DNS1);
    524         assertTrue(v4lp.isProvisioned());
    525 
    526         LinkProperties v4r = new LinkProperties(v4lp);
    527         v4r.removeDnsServer(DNS1);
    528         assertFalse(v4r.isProvisioned());
    529 
    530         assertEquals(ProvisioningChange.STILL_NOT_PROVISIONED,
    531                 LinkProperties.compareProvisioning(v4r, v4r));
    532         assertEquals(ProvisioningChange.LOST_PROVISIONING,
    533                 LinkProperties.compareProvisioning(v4lp, v4r));
    534         assertEquals(ProvisioningChange.GAINED_PROVISIONING,
    535                 LinkProperties.compareProvisioning(v4r, v4lp));
    536         assertEquals(ProvisioningChange.STILL_PROVISIONED,
    537                 LinkProperties.compareProvisioning(v4lp, v4lp));
    538 
    539         // Check that losing IPv4 provisioning on a dualstack network is
    540         // seen as a total loss of provisioning.
    541         LinkProperties v6lp = new LinkProperties();
    542         v6lp.addLinkAddress(LINKADDRV6);
    543         v6lp.addRoute(new RouteInfo(GATEWAY61));
    544         v6lp.addDnsServer(DNS6);
    545         assertFalse(v6lp.isIPv4Provisioned());
    546         assertTrue(v6lp.isIPv6Provisioned());
    547         assertTrue(v6lp.isProvisioned());
    548 
    549         LinkProperties v46lp = new LinkProperties(v6lp);
    550         v46lp.addLinkAddress(LINKADDRV4);
    551         v46lp.addRoute(new RouteInfo(GATEWAY1));
    552         v46lp.addDnsServer(DNS1);
    553         assertTrue(v46lp.isIPv4Provisioned());
    554         assertTrue(v46lp.isIPv6Provisioned());
    555         assertTrue(v46lp.isProvisioned());
    556 
    557         assertEquals(ProvisioningChange.STILL_PROVISIONED,
    558                 LinkProperties.compareProvisioning(v6lp, v46lp));
    559         assertEquals(ProvisioningChange.LOST_PROVISIONING,
    560                 LinkProperties.compareProvisioning(v46lp, v6lp));
    561 
    562         // Check that losing and gaining a secondary router does not change
    563         // the provisioning status.
    564         LinkProperties v6lp2 = new LinkProperties(v6lp);
    565         v6lp2.addRoute(new RouteInfo(GATEWAY62));
    566         assertTrue(v6lp2.isProvisioned());
    567 
    568         assertEquals(ProvisioningChange.STILL_PROVISIONED,
    569                 LinkProperties.compareProvisioning(v6lp2, v6lp));
    570         assertEquals(ProvisioningChange.STILL_PROVISIONED,
    571                 LinkProperties.compareProvisioning(v6lp, v6lp2));
    572     }
    573 
    574     @SmallTest
    575     public void testIsReachable() {
    576         final LinkProperties v4lp = new LinkProperties();
    577         assertFalse(v4lp.isReachable(DNS1));
    578         assertFalse(v4lp.isReachable(DNS2));
    579 
    580         // Add an on-link route, making the on-link DNS server reachable,
    581         // but there is still no IPv4 address.
    582         assertTrue(v4lp.addRoute(new RouteInfo(
    583                 new IpPrefix(NetworkUtils.numericToInetAddress("75.208.0.0"), 16))));
    584         assertFalse(v4lp.isReachable(DNS1));
    585         assertFalse(v4lp.isReachable(DNS2));
    586 
    587         // Adding an IPv4 address (right now, any IPv4 address) means we use
    588         // the routes to compute likely reachability.
    589         assertTrue(v4lp.addLinkAddress(new LinkAddress(ADDRV4, 16)));
    590         assertTrue(v4lp.isReachable(DNS1));
    591         assertFalse(v4lp.isReachable(DNS2));
    592 
    593         // Adding a default route makes the off-link DNS server reachable.
    594         assertTrue(v4lp.addRoute(new RouteInfo(GATEWAY1)));
    595         assertTrue(v4lp.isReachable(DNS1));
    596         assertTrue(v4lp.isReachable(DNS2));
    597 
    598         final LinkProperties v6lp = new LinkProperties();
    599         final InetAddress kLinkLocalDns = NetworkUtils.numericToInetAddress("fe80::6:1");
    600         final InetAddress kLinkLocalDnsWithScope = NetworkUtils.numericToInetAddress("fe80::6:2%43");
    601         final InetAddress kOnLinkDns = NetworkUtils.numericToInetAddress("2001:db8:85a3::53");
    602         assertFalse(v6lp.isReachable(kLinkLocalDns));
    603         assertFalse(v6lp.isReachable(kLinkLocalDnsWithScope));
    604         assertFalse(v6lp.isReachable(kOnLinkDns));
    605         assertFalse(v6lp.isReachable(DNS6));
    606 
    607         // Add a link-local route, making the link-local DNS servers reachable. Because
    608         // we assume the presence of an IPv6 link-local address, link-local DNS servers
    609         // are considered reachable, but only those with a non-zero scope identifier.
    610         assertTrue(v6lp.addRoute(new RouteInfo(
    611                 new IpPrefix(NetworkUtils.numericToInetAddress("fe80::"), 64))));
    612         assertFalse(v6lp.isReachable(kLinkLocalDns));
    613         assertTrue(v6lp.isReachable(kLinkLocalDnsWithScope));
    614         assertFalse(v6lp.isReachable(kOnLinkDns));
    615         assertFalse(v6lp.isReachable(DNS6));
    616 
    617         // Add a link-local address--nothing changes.
    618         assertTrue(v6lp.addLinkAddress(LINKADDRV6LINKLOCAL));
    619         assertFalse(v6lp.isReachable(kLinkLocalDns));
    620         assertTrue(v6lp.isReachable(kLinkLocalDnsWithScope));
    621         assertFalse(v6lp.isReachable(kOnLinkDns));
    622         assertFalse(v6lp.isReachable(DNS6));
    623 
    624         // Add a global route on link, but no global address yet. DNS servers reachable
    625         // via a route that doesn't require a gateway: give them the benefit of the
    626         // doubt and hope the link-local source address suffices for communication.
    627         assertTrue(v6lp.addRoute(new RouteInfo(
    628                 new IpPrefix(NetworkUtils.numericToInetAddress("2001:db8:85a3::"), 64))));
    629         assertFalse(v6lp.isReachable(kLinkLocalDns));
    630         assertTrue(v6lp.isReachable(kLinkLocalDnsWithScope));
    631         assertTrue(v6lp.isReachable(kOnLinkDns));
    632         assertFalse(v6lp.isReachable(DNS6));
    633 
    634         // Add a global address; the on-link global address DNS server is (still)
    635         // presumed reachable.
    636         assertTrue(v6lp.addLinkAddress(new LinkAddress(ADDRV6, 64)));
    637         assertFalse(v6lp.isReachable(kLinkLocalDns));
    638         assertTrue(v6lp.isReachable(kLinkLocalDnsWithScope));
    639         assertTrue(v6lp.isReachable(kOnLinkDns));
    640         assertFalse(v6lp.isReachable(DNS6));
    641 
    642         // Adding a default route makes the off-link DNS server reachable.
    643         assertTrue(v6lp.addRoute(new RouteInfo(GATEWAY62)));
    644         assertFalse(v6lp.isReachable(kLinkLocalDns));
    645         assertTrue(v6lp.isReachable(kLinkLocalDnsWithScope));
    646         assertTrue(v6lp.isReachable(kOnLinkDns));
    647         assertTrue(v6lp.isReachable(DNS6));
    648     }
    649 }
    650