summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--tests/integration/src/android/net/ip/IpClientIntegrationTest.java91
1 files changed, 80 insertions, 11 deletions
diff --git a/tests/integration/src/android/net/ip/IpClientIntegrationTest.java b/tests/integration/src/android/net/ip/IpClientIntegrationTest.java
index a89f07d..79264a8 100644
--- a/tests/integration/src/android/net/ip/IpClientIntegrationTest.java
+++ b/tests/integration/src/android/net/ip/IpClientIntegrationTest.java
@@ -135,6 +135,7 @@ import com.android.networkstack.apishim.CaptivePortalDataShimImpl;
import com.android.networkstack.apishim.ConstantsShim;
import com.android.networkstack.apishim.ShimUtils;
import com.android.networkstack.arp.ArpPacket;
+import com.android.server.NetworkObserver;
import com.android.server.NetworkObserverRegistry;
import com.android.server.NetworkStackService.NetworkStackServiceManager;
import com.android.server.connectivity.ipmemorystore.IpMemoryStoreService;
@@ -168,6 +169,8 @@ import java.util.HashMap;
import java.util.List;
import java.util.Objects;
import java.util.Random;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
/**
* Tests for IpClient.
@@ -199,6 +202,7 @@ public class IpClientIntegrationTest {
@Spy private INetd mNetd;
private String mIfaceName;
+ private NetworkObserverRegistry mNetworkObserverRegistry;
private HandlerThread mPacketReaderThread;
private Handler mHandler;
private TapPacketReader mPacketReader;
@@ -441,10 +445,10 @@ public class IpClientIntegrationTest {
when(mContext.getSystemService(eq(Context.NETD_SERVICE))).thenReturn(netdIBinder);
assertNotNull(mNetd);
- final NetworkObserverRegistry reg = new NetworkObserverRegistry();
- reg.register(mNetd);
- mIpc = new IpClient(mContext, mIfaceName, mCb, reg, mNetworkStackServiceManager,
- mDependencies);
+ mNetworkObserverRegistry = new NetworkObserverRegistry();
+ mNetworkObserverRegistry.register(mNetd);
+ mIpc = new IpClient(mContext, mIfaceName, mCb, mNetworkObserverRegistry,
+ mNetworkStackServiceManager, mDependencies);
}
private void expectAlarmCancelled(InOrder inOrder, OnAlarmListener listener) {
@@ -1202,6 +1206,19 @@ public class IpClientIntegrationTest {
fail("No router solicitation received on interface within timeout");
}
+ private void sendBasicRouterAdvertisement(boolean waitForRs) throws Exception {
+ final String dnsServer = "2001:4860:4860::64";
+ final ByteBuffer pio = buildPioOption(3600, 1800, "2001:db8:1::/64");
+ ByteBuffer rdnss = buildRdnssOption(3600, dnsServer);
+ ByteBuffer ra = buildRaPacket(pio, rdnss);
+
+ if (waitForRs) {
+ waitForRouterSolicitation();
+ }
+
+ mPacketReader.sendResponse(ra);
+ }
+
// TODO: move this and the following method to a common location and use them in ApfTest.
private static ByteBuffer buildPioOption(int valid, int preferred, String prefixString)
throws Exception {
@@ -1485,6 +1502,41 @@ public class IpClientIntegrationTest {
expectNat64PrefixUpdate(inOrder, null);
}
+ private void addIpAddressAndWaitForIt(final String iface) throws Exception {
+ final CountDownLatch latch = new CountDownLatch(1);
+
+ final String addr1 = "192.0.2.99";
+ final String addr2 = "192.0.2.3";
+ final int prefixLength = 26;
+
+ // Add two IPv4 addresses to the specified interface, and proceed when the NetworkObserver
+ // has seen the second one. This ensures that every other NetworkObserver registered with
+ // mNetworkObserverRegistry - in particular, IpClient's - has seen the addition of the first
+ // address.
+ final LinkAddress trigger = new LinkAddress(addr2 + "/" + prefixLength);
+ NetworkObserver observer = new NetworkObserver() {
+ @Override
+ public void onInterfaceAddressUpdated(LinkAddress address, String ifName) {
+ if (ifName.equals(iface) && address.isSameAddressAs(trigger)) {
+ latch.countDown();
+ }
+ }
+ };
+
+ mNetworkObserverRegistry.registerObserverForNonblockingCallback(observer);
+ try {
+ mNetd.interfaceAddAddress(iface, addr1, prefixLength);
+ mNetd.interfaceAddAddress(iface, addr2, prefixLength);
+ assertTrue("Trigger IP address " + addr2 + " not seen after " + TEST_TIMEOUT_MS + "ms",
+ latch.await(TEST_TIMEOUT_MS, TimeUnit.MILLISECONDS));
+ } finally {
+ mNetworkObserverRegistry.unregisterObserver(observer);
+ }
+
+ // Wait for IpClient to process the addition of the address.
+ HandlerUtilsKt.waitForIdle(mIpc.getHandler(), TEST_TIMEOUT_MS);
+ }
+
@Test
public void testIpClientClearingIpAddressState() throws Exception {
final long currentTime = System.currentTimeMillis();
@@ -1503,14 +1555,31 @@ public class IpClientIntegrationTest {
// Pretend that something else (e.g., Tethering) used the interface and left an IP address
// configured on it. When IpClient starts, it must clear this address before proceeding.
- // TODO: test IPv6 instead, since the DHCP client will remove this address by replacing it
- // with the new address.
- mNetd.interfaceAddAddress(mIfaceName, "192.0.2.99", 26);
+ // The address must be noticed before startProvisioning is called, or IpClient will
+ // immediately declare provisioning success due to the presence of an IPv4 address.
+ // The address must be IPv4 because IpClient clears IPv6 addresses on startup.
+ //
+ // TODO: once IpClient gets IP addresses directly from netlink instead of from netd, it
+ // may be sufficient to call waitForIdle to see if IpClient has seen the address.
+ addIpAddressAndWaitForIt(mIfaceName);
- // start IpClient again and should enter Clearing State and wait for the message from kernel
- performDhcpHandshake(true /* isSuccessLease */, TEST_LEASE_DURATION_S,
- true /* isDhcpLeaseCacheEnabled */, false /* shouldReplyRapidCommitAck */,
- TEST_DEFAULT_MTU, false /* isDhcpIpConflictDetectEnabled */);
+ disableRouterSolicitationDelay();
+
+ ProvisioningConfiguration config = new ProvisioningConfiguration.Builder()
+ .withoutIpReachabilityMonitor()
+ .build();
+ mIpc.startProvisioning(config);
+
+ sendBasicRouterAdvertisement(true /*waitForRs*/);
+
+ // Check that the IPv4 addresses configured earlier are not in LinkProperties...
+ ArgumentCaptor<LinkProperties> captor = ArgumentCaptor.forClass(LinkProperties.class);
+ verify(mCb, timeout(TEST_TIMEOUT_MS)).onProvisioningSuccess(captor.capture());
+ assertFalse(captor.getValue().hasIpv4Address());
+
+ // ... or configured on the interface.
+ InterfaceConfigurationParcel cfg = mNetd.interfaceGetCfg(mIfaceName);
+ assertEquals("0.0.0.0", cfg.ipv4Addr);
}
@Test