diff options
-rw-r--r-- | tests/unit/src/android/net/ip/IpClientTest.java | 191 |
1 files changed, 154 insertions, 37 deletions
diff --git a/tests/unit/src/android/net/ip/IpClientTest.java b/tests/unit/src/android/net/ip/IpClientTest.java index 1d6ce6e..b3e652e 100644 --- a/tests/unit/src/android/net/ip/IpClientTest.java +++ b/tests/unit/src/android/net/ip/IpClientTest.java @@ -16,6 +16,8 @@ package android.net.ip; +import static android.system.OsConstants.RT_SCOPE_UNIVERSE; + import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; @@ -31,12 +33,15 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verifyNoMoreInteractions; import static org.mockito.Mockito.when; +import static java.util.Collections.emptySet; + import android.app.AlarmManager; import android.content.ContentResolver; import android.content.Context; import android.content.res.Resources; import android.net.ConnectivityManager; import android.net.INetd; +import android.net.InetAddresses; import android.net.IpPrefix; import android.net.LinkAddress; import android.net.LinkProperties; @@ -51,11 +56,11 @@ import android.net.util.InterfaceParams; import androidx.test.filters.SmallTest; import androidx.test.runner.AndroidJUnit4; -import com.android.internal.R; import com.android.server.NetworkObserver; import com.android.server.NetworkObserverRegistry; import com.android.server.NetworkStackService; import com.android.server.connectivity.ipmemorystore.IpMemoryStoreService; +import com.android.testutils.HandlerUtilsKt; import org.junit.Before; import org.junit.Test; @@ -64,6 +69,8 @@ import org.mockito.ArgumentCaptor; import org.mockito.Mock; import org.mockito.MockitoAnnotations; +import java.net.Inet4Address; +import java.net.Inet6Address; import java.net.InetAddress; import java.util.Arrays; import java.util.HashSet; @@ -77,8 +84,6 @@ import java.util.Set; @RunWith(AndroidJUnit4.class) @SmallTest public class IpClientTest { - private static final int DEFAULT_AVOIDBADWIFI_CONFIG_VALUE = 1; - private static final String VALID = "VALID"; private static final String INVALID = "INVALID"; private static final String TEST_IFNAME = "test_wlan0"; @@ -89,6 +94,19 @@ public class IpClientTest { private static final String TEST_L2KEY = "some l2key"; private static final String TEST_GROUPHINT = "some grouphint"; + private static final String TEST_GLOBAL_ADDRESS = "1234:4321::548d:2db2:4fcf:ef75/64"; + private static final String[] TEST_LOCAL_ADDRESSES = { + "fe80::a4be:f92:e1f7:22d1/64", + "fe80::f04a:8f6:6a32:d756/64", + "fd2c:4e57:8e3c:0:548d:2db2:4fcf:ef75/64" + }; + private static final String TEST_IPV4_LINKADDRESS = "192.168.42.24/24"; + private static final String[] TEST_PREFIXES = { "fe80::/64", "fd2c:4e57:8e3c::/64" }; + private static final String[] TEST_DNSES = { "fd2c:4e57:8e3c::42" }; + private static final String TEST_IPV6_GATEWAY = "fd2c:4e57:8e3c::43"; + private static final String TEST_IPV4_GATEWAY = "192.168.42.11"; + private static final long TEST_DNS_LIFETIME = 3600; + @Mock private Context mContext; @Mock private ConnectivityManager mCm; @Mock private NetworkObserverRegistry mObserverRegistry; @@ -114,8 +132,7 @@ public class IpClientTest { when(mContext.getSystemService(eq(ConnectivityManager.class))).thenReturn(mCm); when(mContext.getResources()).thenReturn(mResources); when(mDependencies.getNetd(any())).thenReturn(mNetd); - when(mResources.getInteger(R.integer.config_networkAvoidBadWifi)) - .thenReturn(DEFAULT_AVOIDBADWIFI_CONFIG_VALUE); + when(mCm.shouldAvoidBadWifi()).thenReturn(true); when(mContext.getContentResolver()).thenReturn(mContentResolver); when(mNetworkStackServiceManager.getIpMemoryStoreService()) .thenReturn(mIpMemoryStoreService); @@ -209,10 +226,20 @@ public class IpClientTest { ipc.shutdown(); } - @Test - public void testDefaultProvisioningConfiguration() throws Exception { - final String iface = TEST_IFNAME; - final IpClient ipc = makeIpClient(iface); + private LinkProperties makeIPv6ProvisionedLinkProperties() { + // Add local addresses, and a global address with global scope + final Set<LinkAddress> addresses = links(TEST_LOCAL_ADDRESSES); + addresses.add(new LinkAddress(TEST_GLOBAL_ADDRESS, 0, RT_SCOPE_UNIVERSE)); + + // Add a route on the interface for each prefix, and a global route + final Set<RouteInfo> routes = routes(TEST_PREFIXES); + routes.add(defaultIPV6Route(TEST_IPV6_GATEWAY)); + + return linkproperties(addresses, routes, ips(TEST_DNSES)); + } + + private IpClient doProvisioningWithDefaultConfiguration() throws Exception { + final IpClient ipc = makeIpClient(TEST_IFNAME); ProvisioningConfiguration config = new ProvisioningConfiguration.Builder() .withoutIPv4() @@ -224,34 +251,115 @@ public class IpClientTest { ipc.startProvisioning(config); verify(mCb, times(1)).setNeighborDiscoveryOffload(true); verify(mCb, timeout(TEST_TIMEOUT_MS).times(1)).setFallbackMulticastFilter(false); + + final LinkProperties lp = makeIPv6ProvisionedLinkProperties(); + lp.getRoutes().forEach(mObserver::onRouteUpdated); + lp.getLinkAddresses().forEach(la -> mObserver.onInterfaceAddressUpdated(la, TEST_IFNAME)); + mObserver.onInterfaceDnsServerInfo(TEST_IFNAME, TEST_DNS_LIFETIME, + lp.getDnsServers().stream().map(InetAddress::getHostAddress) + .toArray(String[]::new)); + + HandlerUtilsKt.waitForIdle(ipc.getHandler(), TEST_TIMEOUT_MS); verify(mCb, never()).onProvisioningFailure(any()); verify(mIpMemoryStore, never()).storeNetworkAttributes(any(), any(), any()); - ipc.shutdown(); - verify(mNetd, timeout(TEST_TIMEOUT_MS).times(1)).interfaceSetEnableIPv6(iface, false); - verify(mNetd, timeout(TEST_TIMEOUT_MS).times(1)).interfaceClearAddrs(iface); - verify(mCb, timeout(TEST_TIMEOUT_MS).times(1)) - .onLinkPropertiesChange(makeEmptyLinkProperties(iface)); + verify(mCb).onProvisioningSuccess(lp); + return ipc; + } + + private void addIPv4Provisioning(LinkProperties lp) { + final LinkAddress la = new LinkAddress(TEST_IPV4_LINKADDRESS); + final RouteInfo defaultRoute = new RouteInfo(new IpPrefix(Inet4Address.ANY, 0), + InetAddresses.parseNumericAddress(TEST_IPV4_GATEWAY), TEST_IFNAME); + mObserver.onInterfaceAddressUpdated(la, TEST_IFNAME); + mObserver.onRouteUpdated(defaultRoute); + + lp.addLinkAddress(la); + lp.addRoute(defaultRoute); + } + + /** + * Simulate loss of IPv6 provisioning (default route lost). + * + * @return The expected new LinkProperties. + */ + private void doIPv6ProvisioningLoss(LinkProperties lp) { + final RouteInfo defaultRoute = defaultIPV6Route(TEST_IPV6_GATEWAY); + mObserver.onRouteRemoved(defaultRoute); + + lp.removeRoute(defaultRoute); + } + + private void doDefaultIPv6ProvisioningConfigurationAndProvisioningLossTest(boolean avoidBadWifi) + throws Exception { + when(mCm.shouldAvoidBadWifi()).thenReturn(avoidBadWifi); + final IpClient ipc = doProvisioningWithDefaultConfiguration(); + final LinkProperties lp = makeIPv6ProvisionedLinkProperties(); + + reset(mCb); + doIPv6ProvisioningLoss(lp); + HandlerUtilsKt.waitForIdle(ipc.getHandler(), TEST_TIMEOUT_MS); + verify(mCb).onProvisioningFailure(lp); + verify(mCb).onLinkPropertiesChange(makeEmptyLinkProperties(TEST_IFNAME)); + + verifyShutdown(ipc); + } + + @Test + public void testDefaultIPv6ProvisioningConfiguration_AvoidBadWifi() throws Exception { + doDefaultIPv6ProvisioningConfigurationAndProvisioningLossTest(true /* avoidBadWifi */); + } + + @Test + public void testDefaultIPv6ProvisioningConfiguration_StayOnBadWifi() throws Exception { + // Even when avoidBadWifi=false, if IPv6 only, loss of all provisioning causes + // onProvisioningFailure to be called. + doDefaultIPv6ProvisioningConfigurationAndProvisioningLossTest(false /* avoidBadWifi */); + } + + private void doDefaultDualStackProvisioningConfigurationTest( + boolean avoidBadWifi) throws Exception { + when(mCm.shouldAvoidBadWifi()).thenReturn(avoidBadWifi); + final IpClient ipc = doProvisioningWithDefaultConfiguration(); + final LinkProperties lp = makeIPv6ProvisionedLinkProperties(); + addIPv4Provisioning(lp); + HandlerUtilsKt.waitForIdle(ipc.getHandler(), TEST_TIMEOUT_MS); + + reset(mCb); + doIPv6ProvisioningLoss(lp); + HandlerUtilsKt.waitForIdle(ipc.getHandler(), TEST_TIMEOUT_MS); + if (avoidBadWifi) { // Provisioning failure is expected only when avoidBadWifi is true + verify(mCb).onProvisioningFailure(lp); + verify(mCb).onLinkPropertiesChange(makeEmptyLinkProperties(TEST_IFNAME)); + } else { + verify(mCb, never()).onProvisioningFailure(any()); + verify(mCb).onLinkPropertiesChange(lp); + } + + verifyShutdown(ipc); } @Test + public void testDefaultDualStackProvisioningConfiguration_AvoidBadWifi() throws Exception { + doDefaultDualStackProvisioningConfigurationTest(true /* avoidBadWifi */); + } + + @Test + public void testDefaultDualStackProvisioningConfiguration_StayOnBadWifi() throws Exception { + doDefaultDualStackProvisioningConfigurationTest(false /* avoidBadWifi */); + } + public void testProvisioningWithInitialConfiguration() throws Exception { final String iface = TEST_IFNAME; final IpClient ipc = makeIpClient(iface); final String l2Key = TEST_L2KEY; final String groupHint = TEST_GROUPHINT; - String[] addresses = { - "fe80::a4be:f92:e1f7:22d1/64", - "fe80::f04a:8f6:6a32:d756/64", - "fd2c:4e57:8e3c:0:548d:2db2:4fcf:ef75/64" - }; - String[] prefixes = { "fe80::/64", "fd2c:4e57:8e3c::/64" }; - ProvisioningConfiguration config = new ProvisioningConfiguration.Builder() .withoutIPv4() .withoutIpReachabilityMonitor() - .withInitialConfiguration(conf(links(addresses), prefixes(prefixes), ips())) + .withInitialConfiguration( + conf(links(TEST_LOCAL_ADDRESSES), prefixes(TEST_PREFIXES), ips())) .build(); ipc.startProvisioning(config); @@ -260,35 +368,38 @@ public class IpClientTest { verify(mCb, never()).onProvisioningFailure(any()); ipc.setL2KeyAndGroupHint(l2Key, groupHint); - for (String addr : addresses) { + for (String addr : TEST_LOCAL_ADDRESSES) { String[] parts = addr.split("/"); verify(mNetd, timeout(TEST_TIMEOUT_MS).times(1)) .interfaceAddAddress(iface, parts[0], Integer.parseInt(parts[1])); } - final int lastAddr = addresses.length - 1; + final int lastAddr = TEST_LOCAL_ADDRESSES.length - 1; // Add N - 1 addresses for (int i = 0; i < lastAddr; i++) { - mObserver.onInterfaceAddressUpdated(new LinkAddress(addresses[i]), iface); + mObserver.onInterfaceAddressUpdated(new LinkAddress(TEST_LOCAL_ADDRESSES[i]), iface); verify(mCb, timeout(TEST_TIMEOUT_MS)).onLinkPropertiesChange(any()); reset(mCb); } // Add Nth address - mObserver.onInterfaceAddressUpdated(new LinkAddress(addresses[lastAddr]), iface); - LinkProperties want = linkproperties(links(addresses), routes(prefixes)); + mObserver.onInterfaceAddressUpdated(new LinkAddress(TEST_LOCAL_ADDRESSES[lastAddr]), iface); + LinkProperties want = linkproperties(links(TEST_LOCAL_ADDRESSES), + routes(TEST_PREFIXES), emptySet() /* dnses */); want.setInterfaceName(iface); verify(mCb, timeout(TEST_TIMEOUT_MS).times(1)).onProvisioningSuccess(want); verifyNetworkAttributesStored(l2Key, new NetworkAttributes.Builder() .setGroupHint(groupHint) .build()); + } + private void verifyShutdown(IpClient ipc) throws Exception { ipc.shutdown(); - verify(mNetd, timeout(TEST_TIMEOUT_MS).times(1)).interfaceSetEnableIPv6(iface, false); - verify(mNetd, timeout(TEST_TIMEOUT_MS).times(1)).interfaceClearAddrs(iface); + verify(mNetd, timeout(TEST_TIMEOUT_MS).times(1)).interfaceSetEnableIPv6(TEST_IFNAME, false); + verify(mNetd, timeout(TEST_TIMEOUT_MS).times(1)).interfaceClearAddrs(TEST_IFNAME); verify(mCb, timeout(TEST_TIMEOUT_MS).times(1)) - .onLinkPropertiesChange(makeEmptyLinkProperties(iface)); + .onLinkPropertiesChange(makeEmptyLinkProperties(TEST_IFNAME)); verifyNoMoreInteractions(mIpMemoryStore); } @@ -360,7 +471,7 @@ public class IpClientTest { Set<RouteInfo> lpRoutes, Set<InetAddress> lpDns, InitialConfiguration config) { IsProvisionedTestCase testcase = new IsProvisionedTestCase(); testcase.isProvisioned = isProvisioned; - testcase.lp = new LinkProperties(); + testcase.lp = makeEmptyLinkProperties(TEST_IFNAME); testcase.lp.setLinkAddresses(lpAddrs); for (RouteInfo route : lpRoutes) { testcase.lp.addRoute(route); @@ -456,12 +567,12 @@ public class IpClientTest { return testcase; } - static LinkProperties linkproperties(Set<LinkAddress> addresses, Set<RouteInfo> routes) { - LinkProperties lp = new LinkProperties(); + static LinkProperties linkproperties(Set<LinkAddress> addresses, + Set<RouteInfo> routes, Set<InetAddress> dnses) { + LinkProperties lp = makeEmptyLinkProperties(TEST_IFNAME); lp.setLinkAddresses(addresses); - for (RouteInfo route : routes) { - lp.addRoute(route); - } + routes.forEach(lp::addRoute); + dnses.forEach(lp::addDnsServer); return lp; } @@ -479,7 +590,13 @@ public class IpClientTest { } static Set<RouteInfo> routes(String... routes) { - return mapIntoSet(routes, (r) -> new RouteInfo(new IpPrefix(r))); + return mapIntoSet(routes, (r) -> new RouteInfo(new IpPrefix(r), null /* gateway */, + TEST_IFNAME)); + } + + static RouteInfo defaultIPV6Route(String gateway) { + return new RouteInfo(new IpPrefix(Inet6Address.ANY, 0), + InetAddresses.parseNumericAddress(gateway), TEST_IFNAME); } static Set<IpPrefix> prefixes(String... prefixes) { |