Add basic IpReachabilityMonitor integration test. am: 60175d2d5e am: 368a7117ff
Original change: https://android-review.googlesource.com/c/platform/packages/modules/NetworkStack/+/1724690
Change-Id: I4dae1d01ba9c23b23deb7ddeb23b4299f8671727
diff --git a/src/android/net/ip/IpClient.java b/src/android/net/ip/IpClient.java
index 445f915..c0ae611 100644
--- a/src/android/net/ip/IpClient.java
+++ b/src/android/net/ip/IpClient.java
@@ -70,6 +70,7 @@
import android.net.util.SharedLog;
import android.os.Build;
import android.os.ConditionVariable;
+import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.os.RemoteException;
@@ -596,11 +597,33 @@
return new IpConnectivityLog();
}
+ /**
+ * Get a NetworkQuirkMetrics instance.
+ */
public NetworkQuirkMetrics getNetworkQuirkMetrics() {
return new NetworkQuirkMetrics();
}
/**
+ * Get a IpReachabilityMonitor instance.
+ */
+ public IpReachabilityMonitor getIpReachabilityMonitor(Context context,
+ InterfaceParams ifParams, Handler h, SharedLog log,
+ IpReachabilityMonitor.Callback callback, boolean usingMultinetworkPolicyTracker,
+ IpReachabilityMonitor.Dependencies deps, final INetd netd) {
+ return new IpReachabilityMonitor(context, ifParams, h, log, callback,
+ usingMultinetworkPolicyTracker, deps, netd);
+ }
+
+ /**
+ * Get a IpReachabilityMonitor dependencies instance.
+ */
+ public IpReachabilityMonitor.Dependencies getIpReachabilityMonitorDeps(Context context,
+ String name) {
+ return IpReachabilityMonitor.Dependencies.makeDefault(context, name);
+ }
+
+ /**
* Return whether a feature guarded by a feature flag is enabled.
* @see NetworkStackUtils#isFeatureEnabled(Context, String, String)
*/
@@ -1776,7 +1799,7 @@
private boolean startIpReachabilityMonitor() {
try {
- mIpReachabilityMonitor = new IpReachabilityMonitor(
+ mIpReachabilityMonitor = mDependencies.getIpReachabilityMonitor(
mContext,
mInterfaceParams,
getHandler(),
@@ -1788,6 +1811,7 @@
}
},
mConfiguration.mUsingMultinetworkPolicyTracker,
+ mDependencies.getIpReachabilityMonitorDeps(mContext, mInterfaceParams.name),
mNetd);
} catch (IllegalArgumentException iae) {
// Failed to start IpReachabilityMonitor. Log it and call
diff --git a/src/android/net/ip/IpReachabilityMonitor.java b/src/android/net/ip/IpReachabilityMonitor.java
index 3dbe662..face72c 100644
--- a/src/android/net/ip/IpReachabilityMonitor.java
+++ b/src/android/net/ip/IpReachabilityMonitor.java
@@ -199,9 +199,9 @@
public IpReachabilityMonitor(
Context context, InterfaceParams ifParams, Handler h, SharedLog log, Callback callback,
- boolean usingMultinetworkPolicyTracker, final INetd netd) {
- this(context, ifParams, h, log, callback, usingMultinetworkPolicyTracker,
- Dependencies.makeDefault(context, ifParams.name), new IpConnectivityLog(), netd);
+ boolean usingMultinetworkPolicyTracker, Dependencies dependencies, final INetd netd) {
+ this(context, ifParams, h, log, callback, usingMultinetworkPolicyTracker, dependencies,
+ new IpConnectivityLog(), netd);
}
@VisibleForTesting
diff --git a/tests/integration/src/android/net/ip/IpClientIntegrationTest.kt b/tests/integration/src/android/net/ip/IpClientIntegrationTest.kt
index eb0a799..b217ebb 100644
--- a/tests/integration/src/android/net/ip/IpClientIntegrationTest.kt
+++ b/tests/integration/src/android/net/ip/IpClientIntegrationTest.kt
@@ -18,6 +18,8 @@
import android.net.ipmemorystore.NetworkAttributes
import android.util.ArrayMap
+import java.net.Inet6Address
+import kotlin.test.assertEquals
import org.mockito.Mockito.any
import org.mockito.ArgumentCaptor
import org.mockito.Mockito.eq
@@ -56,4 +58,15 @@
override fun assertIpMemoryNeverStoreNetworkAttributes(l2Key: String, timeout: Long) {
verify(mIpMemoryStore, never()).storeNetworkAttributes(eq(l2Key), any(), any())
}
+
+ override fun assertNotifyNeighborLost(targetIp: Inet6Address) {
+ val target = ArgumentCaptor.forClass(Inet6Address::class.java)
+
+ verify(mCallback, timeout(TEST_TIMEOUT_MS)).notifyLost(target.capture(), any())
+ assertEquals(targetIp, target.getValue())
+ }
+
+ override fun assertNeverNotifyNeighborLost() {
+ verify(mCallback, never()).notifyLost(any(), any())
+ }
}
diff --git a/tests/integration/src/android/net/ip/IpClientIntegrationTestCommon.java b/tests/integration/src/android/net/ip/IpClientIntegrationTestCommon.java
index e40db77..630b05d 100644
--- a/tests/integration/src/android/net/ip/IpClientIntegrationTestCommon.java
+++ b/tests/integration/src/android/net/ip/IpClientIntegrationTestCommon.java
@@ -40,13 +40,17 @@
import static com.android.net.module.util.NetworkStackConstants.ETHER_BROADCAST;
import static com.android.net.module.util.NetworkStackConstants.ETHER_HEADER_LEN;
import static com.android.net.module.util.NetworkStackConstants.ETHER_TYPE_OFFSET;
+import static com.android.net.module.util.NetworkStackConstants.ICMPV6_ND_OPTION_SLLA;
import static com.android.net.module.util.NetworkStackConstants.ICMPV6_NEIGHBOR_ADVERTISEMENT;
+import static com.android.net.module.util.NetworkStackConstants.ICMPV6_NEIGHBOR_SOLICITATION;
import static com.android.net.module.util.NetworkStackConstants.ICMPV6_ROUTER_SOLICITATION;
import static com.android.net.module.util.NetworkStackConstants.IPV4_ADDR_ANY;
import static com.android.net.module.util.NetworkStackConstants.IPV6_ADDR_ALL_NODES_MULTICAST;
import static com.android.net.module.util.NetworkStackConstants.IPV6_ADDR_ALL_ROUTERS_MULTICAST;
import static com.android.net.module.util.NetworkStackConstants.IPV6_HEADER_LEN;
import static com.android.net.module.util.NetworkStackConstants.IPV6_PROTOCOL_OFFSET;
+import static com.android.net.module.util.NetworkStackConstants.NEIGHBOR_ADVERTISEMENT_FLAG_ROUTER;
+import static com.android.net.module.util.NetworkStackConstants.NEIGHBOR_ADVERTISEMENT_FLAG_SOLICITED;
import static com.android.net.module.util.NetworkStackConstants.PIO_FLAG_AUTONOMOUS;
import static com.android.net.module.util.NetworkStackConstants.PIO_FLAG_ON_LINK;
@@ -108,6 +112,7 @@
import android.net.dhcp.DhcpPacket;
import android.net.dhcp.DhcpPacket.ParseException;
import android.net.dhcp.DhcpRequestPacket;
+import android.net.ip.IpNeighborMonitor.NeighborEventConsumer;
import android.net.ipmemorystore.NetworkAttributes;
import android.net.ipmemorystore.OnNetworkAttributesRetrievedListener;
import android.net.ipmemorystore.Status;
@@ -119,6 +124,7 @@
import android.net.shared.ProvisioningConfiguration.ScanResultInfo;
import android.net.util.InterfaceParams;
import android.net.util.NetworkStackUtils;
+import android.net.util.SharedLog;
import android.os.Build;
import android.os.Handler;
import android.os.HandlerThread;
@@ -141,6 +147,7 @@
import com.android.internal.util.StateMachine;
import com.android.net.module.util.ArrayTrackRecord;
import com.android.net.module.util.Ipv6Utils;
+import com.android.net.module.util.structs.LlaOption;
import com.android.net.module.util.structs.PrefixInformationOption;
import com.android.net.module.util.structs.RdnssOption;
import com.android.networkstack.apishim.CaptivePortalDataShimImpl;
@@ -150,6 +157,7 @@
import com.android.networkstack.metrics.IpProvisioningMetrics;
import com.android.networkstack.metrics.NetworkQuirkMetrics;
import com.android.networkstack.packets.NeighborAdvertisement;
+import com.android.networkstack.packets.NeighborSolicitation;
import com.android.server.NetworkObserver;
import com.android.server.NetworkObserverRegistry;
import com.android.server.NetworkStackService.NetworkStackServiceManager;
@@ -263,6 +271,7 @@
@Mock private PowerManager.WakeLock mTimeoutWakeLock;
@Mock protected NetworkStackIpMemoryStore mIpMemoryStore;
@Mock private NetworkQuirkMetrics.Dependencies mNetworkQuirkMetricsDeps;
+ @Mock protected IpReachabilityMonitor.Callback mCallback;
@Spy private INetd mNetd;
private NetworkObserverRegistry mNetworkObserverRegistry;
@@ -272,7 +281,7 @@
/***** END signature required test members *****/
- private IIpClientCallbacks mCb;
+ protected IIpClientCallbacks mCb;
private IIpClient mIIpClient;
private String mIfaceName;
private HandlerThread mPacketReaderThread;
@@ -327,7 +336,10 @@
private static final String HOSTNAME = "testhostname";
private static final int TEST_DEFAULT_MTU = 1500;
private static final int TEST_MIN_MTU = 1280;
- private static final byte[] SERVER_MAC = new byte[] { 0x00, 0x1A, 0x11, 0x22, 0x33, 0x44 };
+ private static final MacAddress ROUTER_MAC = MacAddress.fromString("00:1A:11:22:33:44");
+ private static final byte[] ROUTER_MAC_BYTES = ROUTER_MAC.toByteArray();
+ private static final Inet6Address ROUTER_LINK_LOCAL =
+ (Inet6Address) InetAddresses.parseNumericAddress("fe80::1");
private static final String TEST_HOST_NAME = "AOSP on Crosshatch";
private static final String TEST_HOST_NAME_TRANSLITERATION = "AOSP-on-Crosshatch";
private static final String TEST_CAPTIVE_PORTAL_URL = "https://example.com/capportapi";
@@ -401,6 +413,15 @@
}
@Override
+ public IpReachabilityMonitor getIpReachabilityMonitor(Context context,
+ InterfaceParams ifParams, Handler h, SharedLog log,
+ IpReachabilityMonitor.Callback callback, boolean usingMultinetworkPolicyTracker,
+ IpReachabilityMonitor.Dependencies deps, final INetd netd) {
+ return new IpReachabilityMonitor(context, ifParams, h, log, mCallback,
+ usingMultinetworkPolicyTracker, deps, netd);
+ }
+
+ @Override
public boolean isFeatureEnabled(final Context context, final String name,
final boolean defaultEnabled) {
return IpClientIntegrationTestCommon.this.isFeatureEnabled(name, defaultEnabled);
@@ -440,6 +461,23 @@
}
@Override
+ public IpReachabilityMonitor.Dependencies getIpReachabilityMonitorDeps(Context context,
+ String name) {
+ return new IpReachabilityMonitor.Dependencies() {
+ public void acquireWakeLock(long durationMs) {
+ // It doesn't matter for the integration test app on whether the wake lock
+ // is acquired or not.
+ return;
+ }
+
+ public IpNeighborMonitor makeIpNeighborMonitor(Handler h, SharedLog log,
+ NeighborEventConsumer cb) {
+ return new IpNeighborMonitor(h, log, cb);
+ }
+ };
+ }
+
+ @Override
public int getDeviceConfigPropertyInt(String name, int defaultValue) {
Integer value = mIntConfigProperties.get(name);
if (value == null) {
@@ -472,6 +510,10 @@
protected abstract void assertIpMemoryNeverStoreNetworkAttributes(String l2Key, long timeout);
+ protected abstract void assertNotifyNeighborLost(Inet6Address targetIp);
+
+ protected abstract void assertNeverNotifyNeighborLost();
+
protected final boolean testSkipped() {
// TODO: split out a test suite for root tests, and fail hard instead of skipping the test
// if it is run on devices where TestNetworkStackServiceClient is not supported
@@ -712,6 +754,14 @@
}
}
+ private NeighborSolicitation parseNeighborSolicitationOrNull(final byte[] packet) {
+ try {
+ return NeighborSolicitation.parse(packet, packet.length);
+ } catch (NeighborSolicitation.ParseException e) {
+ return null;
+ }
+ }
+
private static ByteBuffer buildDhcpOfferPacket(final DhcpPacket packet,
final Inet4Address clientAddress, final Integer leaseTimeSec, final short mtu,
final String captivePortalUrl, final Integer ipv6OnlyWaitTime) {
@@ -761,7 +811,7 @@
private void sendArpReply(final byte[] clientMac) throws IOException {
final ByteBuffer packet = ArpPacket.buildArpPacket(clientMac /* dst */,
- SERVER_MAC /* src */, INADDR_ANY.getAddress() /* target IP */,
+ ROUTER_MAC_BYTES /* srcMac */, INADDR_ANY.getAddress() /* target IP */,
clientMac /* target HW address */, CLIENT_ADDR.getAddress() /* sender IP */,
(short) ARP_REPLY);
mPacketReader.sendResponse(packet);
@@ -769,7 +819,7 @@
private void sendArpProbe() throws IOException {
final ByteBuffer packet = ArpPacket.buildArpPacket(DhcpPacket.ETHER_BROADCAST /* dst */,
- SERVER_MAC /* src */, CLIENT_ADDR.getAddress() /* target IP */,
+ ROUTER_MAC_BYTES /* srcMac */, CLIENT_ADDR.getAddress() /* target IP */,
new byte[ETHER_ADDR_LEN] /* target HW address */,
INADDR_ANY.getAddress() /* sender IP */, (short) ARP_REQUEST);
mPacketReader.sendResponse(packet);
@@ -1458,20 +1508,23 @@
HandlerUtils.waitForIdle(mIpc.getHandler(), TEST_TIMEOUT_MS);
}
- private boolean isRouterSolicitation(final byte[] packetBytes) {
+ private boolean isIcmpv6PacketOfType(final byte[] packetBytes, int type) {
ByteBuffer packet = ByteBuffer.wrap(packetBytes);
return packet.getShort(ETHER_TYPE_OFFSET) == (short) ETH_P_IPV6
&& packet.get(ETHER_HEADER_LEN + IPV6_PROTOCOL_OFFSET) == (byte) IPPROTO_ICMPV6
- && packet.get(ETHER_HEADER_LEN + IPV6_HEADER_LEN)
- == (byte) ICMPV6_ROUTER_SOLICITATION;
+ && packet.get(ETHER_HEADER_LEN + IPV6_HEADER_LEN) == (byte) type;
+ }
+
+ private boolean isRouterSolicitation(final byte[] packetBytes) {
+ return isIcmpv6PacketOfType(packetBytes, ICMPV6_ROUTER_SOLICITATION);
}
private boolean isNeighborAdvertisement(final byte[] packetBytes) {
- ByteBuffer packet = ByteBuffer.wrap(packetBytes);
- return packet.getShort(ETHER_TYPE_OFFSET) == (short) ETH_P_IPV6
- && packet.get(ETHER_HEADER_LEN + IPV6_PROTOCOL_OFFSET) == (byte) IPPROTO_ICMPV6
- && packet.get(ETHER_HEADER_LEN + IPV6_HEADER_LEN)
- == (byte) ICMPV6_NEIGHBOR_ADVERTISEMENT;
+ return isIcmpv6PacketOfType(packetBytes, ICMPV6_NEIGHBOR_ADVERTISEMENT);
+ }
+
+ private boolean isNeighborSolicitation(final byte[] packetBytes) {
+ return isIcmpv6PacketOfType(packetBytes, ICMPV6_NEIGHBOR_SOLICITATION);
}
private NeighborAdvertisement getNextNeighborAdvertisement() throws ParseException {
@@ -1484,6 +1537,16 @@
return na;
}
+ private NeighborSolicitation getNextNeighborSolicitation() throws ParseException {
+ final byte[] packet = mPacketReader.popPacket(PACKET_TIMEOUT_MS,
+ this::isNeighborSolicitation);
+ if (packet == null) return null;
+
+ final NeighborSolicitation ns = parseNeighborSolicitationOrNull(packet);
+ assertNotNull("Invalid neighbour solicitation received", ns);
+ return ns;
+ }
+
private void waitForRouterSolicitation() throws ParseException {
assertNotNull("No router solicitation received on interface within timeout",
mPacketReader.popPacket(PACKET_TIMEOUT_MS, this::isRouterSolicitation));
@@ -1521,17 +1584,18 @@
return RdnssOption.build(lifetime, servers);
}
+ private static ByteBuffer buildSllaOption() throws Exception {
+ return LlaOption.build((byte) ICMPV6_ND_OPTION_SLLA, ROUTER_MAC);
+ }
+
private static ByteBuffer buildRaPacket(short lifetime, ByteBuffer... options)
throws Exception {
- final MacAddress dstMac = MacAddress.fromString("33:33:00:00:00:01");
- final MacAddress srcMac = MacAddress.fromString("01:02:03:04:05:06");
- final Inet6Address routerLinkLocal =
- (Inet6Address) InetAddresses.parseNumericAddress("fe80::1");
-
- return Ipv6Utils.buildRaPacket(srcMac, dstMac, routerLinkLocal,
- IPV6_ADDR_ALL_NODES_MULTICAST, (byte) 0 /* M=0, O=0 */, lifetime,
- 0 /* Reachable time, unspecified */, 100 /* Retrans time 100ms */,
- options);
+ final MacAddress dstMac =
+ NetworkStackUtils.ipv6MulticastToEthernetMulticast(IPV6_ADDR_ALL_ROUTERS_MULTICAST);
+ return Ipv6Utils.buildRaPacket(ROUTER_MAC /* srcMac */, dstMac,
+ ROUTER_LINK_LOCAL /* srcIp */, IPV6_ADDR_ALL_NODES_MULTICAST /* dstIp */,
+ (byte) 0 /* M=0, O=0 */, lifetime, 0 /* Reachable time, unspecified */,
+ 100 /* Retrans time 100ms */, options);
}
private static ByteBuffer buildRaPacket(ByteBuffer... options) throws Exception {
@@ -1575,7 +1639,8 @@
final String dnsServer = "2001:4860:4860::64";
final ByteBuffer pio = buildPioOption(3600, 1800, "2001:db8:1::/64");
final ByteBuffer rdnss = buildRdnssOption(3600, dnsServer);
- final ByteBuffer ra = buildRaPacket(pio, rdnss);
+ final ByteBuffer slla = buildSllaOption();
+ final ByteBuffer ra = buildRaPacket(pio, rdnss, slla);
return doIpv6OnlyProvisioning(inOrder, ra);
}
@@ -2383,7 +2448,8 @@
final String dnsServer = "2001:4860:4860::64";
final ByteBuffer pio = buildPioOption(3600, 1800, "2001:db8:1::/64");
final ByteBuffer rdnss = buildRdnssOption(3600, dnsServer);
- final ByteBuffer ra = buildRaPacket(pio, rdnss);
+ final ByteBuffer slla = buildSllaOption();
+ final ByteBuffer ra = buildRaPacket(pio, rdnss, slla);
doIpv6OnlyProvisioning(inOrder, ra);
@@ -2965,7 +3031,7 @@
@Test
public void testGratuitousArpAndNaAfterRoaming_disableExpFlag() throws Exception {
startGratuitousArpAndNaAfterRoamingTest(false /* isGratuitousArpNaRoamingEnabled */,
- true /* hasIpv6 */, true /* hasIpv6 */);
+ true /* hasIpv4 */, true /* hasIpv6 */);
performDualStackProvisioning();
forceLayer2Roaming();
@@ -3007,4 +3073,84 @@
assertEquals(0, naList.size());
assertEquals(1, arpList.size());
}
+
+ private void assertNeighborSolicitation(final NeighborSolicitation ns,
+ final Inet6Address target) {
+ assertEquals(ETH_P_IPV6, ns.ethHdr.etherType);
+ assertEquals(IPPROTO_ICMPV6, ns.ipv6Hdr.nextHeader);
+ assertEquals(0xff, ns.ipv6Hdr.hopLimit);
+ assertTrue(ns.ipv6Hdr.srcIp.isLinkLocalAddress());
+ assertEquals(ICMPV6_NEIGHBOR_SOLICITATION, ns.icmpv6Hdr.type);
+ assertEquals(0, ns.icmpv6Hdr.code);
+ assertEquals(0, ns.nsHdr.reserved);
+ assertEquals(target, ns.nsHdr.target);
+ assertEquals(ns.slla.linkLayerAddress, ns.ethHdr.srcMac);
+ }
+
+ private void assertUnicastNeighborSolicitation(final NeighborSolicitation ns,
+ final MacAddress dstMac, final Inet6Address dstIp, final Inet6Address target) {
+ assertEquals(dstMac, ns.ethHdr.dstMac);
+ assertEquals(dstIp, ns.ipv6Hdr.dstIp);
+ assertNeighborSolicitation(ns, target);
+ }
+
+ private void prepareIpReachabilityMonitorTest() throws Exception {
+ final ScanResultInfo info = makeScanResultInfo(TEST_DEFAULT_SSID, TEST_DEFAULT_BSSID);
+ ProvisioningConfiguration config = new ProvisioningConfiguration.Builder()
+ .withLayer2Information(new Layer2Information(TEST_L2KEY, TEST_CLUSTER,
+ MacAddress.fromString(TEST_DEFAULT_BSSID)))
+ .withScanResultInfo(info)
+ .withDisplayName(TEST_DEFAULT_SSID)
+ .withoutIPv4()
+ .build();
+ startIpClientProvisioning(config);
+ verify(mCb, timeout(TEST_TIMEOUT_MS)).setFallbackMulticastFilter(false);
+ doIpv6OnlyProvisioning();
+
+ // Simulate the roaming.
+ forceLayer2Roaming();
+ }
+
+ @Test
+ public void testIpReachabilityMonitor_probeFailed() throws Exception {
+ prepareIpReachabilityMonitorTest();
+
+ NeighborSolicitation packet;
+ final List<NeighborSolicitation> nsList = new ArrayList<NeighborSolicitation>();
+ while ((packet = getNextNeighborSolicitation()) != null) {
+ // Filter out the NSes used for duplicate address detetction, the target address
+ // is the global IPv6 address inside these NSes.
+ if (packet.nsHdr.target.isLinkLocalAddress()) {
+ nsList.add(packet);
+ }
+ }
+ assertEquals(IpReachabilityMonitor.MIN_NUD_SOLICIT_NUM, nsList.size());
+ for (NeighborSolicitation ns : nsList) {
+ assertUnicastNeighborSolicitation(ns, ROUTER_MAC /* dstMac */,
+ ROUTER_LINK_LOCAL /* dstIp */, ROUTER_LINK_LOCAL /* targetIp */);
+ }
+ assertNotifyNeighborLost(ROUTER_LINK_LOCAL /* targetIp */);
+ }
+
+ @Test
+ public void testIpReachabilityMonitor_probeReachable() throws Exception {
+ prepareIpReachabilityMonitorTest();
+
+ NeighborSolicitation ns;
+ while ((ns = getNextNeighborSolicitation()) != null) {
+ // Filter out the NSes used for duplicate address detetction, the target address
+ // is the global IPv6 address inside these NSes.
+ if (ns.nsHdr.target.isLinkLocalAddress()) break;
+ }
+ assertUnicastNeighborSolicitation(ns, ROUTER_MAC /* dstMac */,
+ ROUTER_LINK_LOCAL /* dstIp */, ROUTER_LINK_LOCAL /* targetIp */);
+
+ // Reply Neighbor Advertisement and check notifyLost callback won't be triggered.
+ int flag = NEIGHBOR_ADVERTISEMENT_FLAG_ROUTER | NEIGHBOR_ADVERTISEMENT_FLAG_SOLICITED;
+ final ByteBuffer na = NeighborAdvertisement.build(ROUTER_MAC /* srcMac */,
+ ns.ethHdr.srcMac /* dstMac */, ROUTER_LINK_LOCAL /* srcIp */,
+ ns.ipv6Hdr.srcIp /* dstIp */, flag, ROUTER_LINK_LOCAL /* target */);
+ mPacketReader.sendResponse(na);
+ assertNeverNotifyNeighborLost();
+ }
}
diff --git a/tests/integration/src/android/net/ip/IpClientRootTest.kt b/tests/integration/src/android/net/ip/IpClientRootTest.kt
index 68d8aab..8a99e4f 100644
--- a/tests/integration/src/android/net/ip/IpClientRootTest.kt
+++ b/tests/integration/src/android/net/ip/IpClientRootTest.kt
@@ -33,6 +33,7 @@
import androidx.test.platform.app.InstrumentationRegistry
import com.android.net.module.util.DeviceConfigUtils
import java.lang.System.currentTimeMillis
+import java.net.Inet6Address
import java.util.concurrent.CompletableFuture
import java.util.concurrent.CountDownLatch
import java.util.concurrent.TimeUnit
@@ -45,6 +46,8 @@
import org.junit.AfterClass
import org.junit.BeforeClass
import org.mockito.ArgumentCaptor
+import org.mockito.Mockito.anyString
+import org.mockito.Mockito.never
import org.mockito.Mockito.timeout
import org.mockito.Mockito.verify
@@ -260,4 +263,12 @@
mStore.retrieveNetworkAttributes(l2Key, listener)
assertNull(listener.getBlockingNetworkAttributes(timeout))
}
+
+ override fun assertNotifyNeighborLost(targetIp: Inet6Address) {
+ verify(mCb, timeout(TEST_TIMEOUT_MS)).onReachabilityLost(anyString())
+ }
+
+ override fun assertNeverNotifyNeighborLost() {
+ verify(mCb, never()).onReachabilityLost(anyString())
+ }
}
diff --git a/tests/unit/src/android/net/ip/IpClientTest.java b/tests/unit/src/android/net/ip/IpClientTest.java
index c9e486b..d86d0bb 100644
--- a/tests/unit/src/android/net/ip/IpClientTest.java
+++ b/tests/unit/src/android/net/ip/IpClientTest.java
@@ -115,6 +115,7 @@
private static final String TEST_CLUSTER = "some cluster";
private static final String TEST_SSID = "test_ssid";
private static final String TEST_BSSID = "00:11:22:33:44:55";
+ private static final String TEST_BSSID2 = "00:1A:11:22:33:44";
private static final String TEST_GLOBAL_ADDRESS = "1234:4321::548d:2db2:4fcf:ef75/64";
private static final String[] TEST_LOCAL_ADDRESSES = {
@@ -735,7 +736,18 @@
final IpClient ipc = makeIpClient(TEST_IFNAME);
final Layer2Information layer2Info = new Layer2Information(TEST_L2KEY, TEST_CLUSTER,
MacAddress.fromString(TEST_BSSID));
- final MacAddress bssid = ipc.getInitialBssid(layer2Info, null /* ScanReqsultInfo */,
+ final ScanResultInfo scanResultInfo = makeScanResultInfo(TEST_SSID, TEST_BSSID2);
+ final MacAddress bssid = ipc.getInitialBssid(layer2Info, scanResultInfo,
+ true /* isAtLeastS */);
+ assertEquals(bssid, MacAddress.fromString(TEST_BSSID));
+ }
+
+ @Test
+ public void testGetInitialBssidOnSOrAbove_NullScanReqsultInfo() throws Exception {
+ final IpClient ipc = makeIpClient(TEST_IFNAME);
+ final Layer2Information layer2Info = new Layer2Information(TEST_L2KEY, TEST_CLUSTER,
+ MacAddress.fromString(TEST_BSSID));
+ final MacAddress bssid = ipc.getInitialBssid(layer2Info, null /* ScanResultInfo */,
true /* isAtLeastS */);
assertEquals(bssid, MacAddress.fromString(TEST_BSSID));
}
@@ -764,7 +776,7 @@
public void testGetInitialBssidBeforeS() throws Exception {
final IpClient ipc = makeIpClient(TEST_IFNAME);
final Layer2Information layer2Info = new Layer2Information(TEST_L2KEY, TEST_CLUSTER,
- MacAddress.fromString(TEST_BSSID));
+ MacAddress.fromString(TEST_BSSID2));
final ScanResultInfo scanResultInfo = makeScanResultInfo(TEST_SSID, TEST_BSSID);
final MacAddress bssid = ipc.getInitialBssid(layer2Info, scanResultInfo,
false /* isAtLeastS */);