Merge "[TestOnly]Remove RemoteResponder from TetheringTester"
diff --git a/Tethering/tests/integration/src/android/net/EthernetTetheringTest.java b/Tethering/tests/integration/src/android/net/EthernetTetheringTest.java
index 237a645..21eb899 100644
--- a/Tethering/tests/integration/src/android/net/EthernetTetheringTest.java
+++ b/Tethering/tests/integration/src/android/net/EthernetTetheringTest.java
@@ -26,7 +26,6 @@
import static android.net.TetheringManager.CONNECTIVITY_SCOPE_GLOBAL;
import static android.net.TetheringManager.CONNECTIVITY_SCOPE_LOCAL;
import static android.net.TetheringManager.TETHERING_ETHERNET;
-import static android.net.TetheringTester.RemoteResponder;
import static android.net.TetheringTester.isIcmpv6Type;
import static android.system.OsConstants.IPPROTO_IP;
import static android.system.OsConstants.IPPROTO_IPV6;
@@ -816,10 +815,10 @@
mDownstreamReader = makePacketReader(mDownstreamIface);
mUpstreamReader = makePacketReader(mUpstreamTracker.getTestIface());
- runPing6Test(new TetheringTester(mDownstreamReader), new RemoteResponder(mUpstreamReader));
+ runPing6Test(new TetheringTester(mDownstreamReader, mUpstreamReader));
}
- private void runPing6Test(TetheringTester tester, RemoteResponder remote) throws Exception {
+ private void runPing6Test(TetheringTester tester) throws Exception {
// Currently tethering don't have API to tell when ipv6 tethering is available. Thus, let
// TetheringTester test ipv6 tethering connectivity before testing ipv6.
// TODO: move to a common place to avoid that every IPv6 test needs to call this function.
@@ -830,24 +829,18 @@
Inet6Address remoteIp6Addr = (Inet6Address) parseNumericAddress("2400:222:222::222");
ByteBuffer request = Ipv6Utils.buildEchoRequestPacket(tethered.macAddr,
tethered.routerMacAddr, tethered.ipv6Addr, remoteIp6Addr);
- tester.sendPacket(request);
-
- final byte[] echoRequest = remote.getNextMatchedPacket((p) -> {
+ tester.verifyUpload(request, p -> {
Log.d(TAG, "Packet in upstream: " + dumpHexString(p));
return isIcmpv6Type(p, false /* hasEth */, ICMPV6_ECHO_REQUEST_TYPE);
});
- assertNotNull("No icmpv6 echo request in upstream", echoRequest);
ByteBuffer reply = Ipv6Utils.buildEchoReplyPacket(remoteIp6Addr, tethered.ipv6Addr);
- remote.sendPacket(reply);
-
- final byte[] echoReply = tester.getNextMatchedPacket((p) -> {
+ tester.verifyDownload(reply, p -> {
Log.d(TAG, "Packet in downstream: " + dumpHexString(p));
return isIcmpv6Type(p, true /* hasEth */, ICMPV6_ECHO_REPLY_TYPE);
});
- assertNotNull("No icmpv6 echo reply in downstream", echoReply);
}
// Test network topology:
@@ -964,7 +957,7 @@
// TODO: remove this verification once upstream connected notification race is fixed.
// See #runUdp4Test.
private boolean isIpv4TetherConnectivityVerified(TetheringTester tester,
- RemoteResponder remote, TetheredDevice tethered) throws Exception {
+ TetheredDevice tethered) throws Exception {
final ByteBuffer probePacket = buildUdpPacket(tethered.macAddr,
tethered.routerMacAddr, tethered.ipv4Addr /* srcIp */,
REMOTE_IP4_ADDR /* dstIp */, LOCAL_PORT /* srcPort */, REMOTE_PORT /* dstPort */,
@@ -972,8 +965,7 @@
// Send a UDP packet from client and check the packet can be found on upstream interface.
for (int i = 0; i < TETHER_REACHABILITY_ATTEMPTS; i++) {
- tester.sendPacket(probePacket);
- byte[] expectedPacket = remote.getNextMatchedPacket(p -> {
+ byte[] expectedPacket = tester.testUpload(probePacket, p -> {
Log.d(TAG, "Packet in upstream: " + dumpHexString(p));
return isExpectedUdpPacket(p, false /* hasEther */, true /* isIpv4 */,
TEST_REACHABILITY_PAYLOAD);
@@ -983,8 +975,7 @@
return false;
}
- private void runUdp4Test(TetheringTester tester, RemoteResponder remote, boolean usingBpf)
- throws Exception {
+ private void runUdp4Test(TetheringTester tester, boolean usingBpf) throws Exception {
final TetheredDevice tethered = tester.createTetheredDevice(MacAddress.fromString(
"1:2:3:4:5:6"), false /* hasIpv6 */);
@@ -994,14 +985,14 @@
// For short term plan, consider using IPv6 RA to get MAC address because the prefix comes
// from upstream. That can guarantee that the routing is ready. Long term plan is that
// refactors upstream connected notification from async to sync.
- assertTrue(isIpv4TetherConnectivityVerified(tester, remote, tethered));
+ assertTrue(isIpv4TetherConnectivityVerified(tester, tethered));
// Send a UDP packet in original direction.
final ByteBuffer originalPacket = buildUdpPacket(tethered.macAddr,
tethered.routerMacAddr, tethered.ipv4Addr /* srcIp */,
REMOTE_IP4_ADDR /* dstIp */, LOCAL_PORT /* srcPort */, REMOTE_PORT /* dstPort */,
PAYLOAD /* payload */);
- tester.verifyUpload(remote, originalPacket, p -> {
+ tester.verifyUpload(originalPacket, p -> {
Log.d(TAG, "Packet in upstream: " + dumpHexString(p));
return isExpectedUdpPacket(p, false /* hasEther */, true /* isIpv4 */, PAYLOAD);
});
@@ -1011,7 +1002,7 @@
final ByteBuffer replyPacket = buildUdpPacket(REMOTE_IP4_ADDR /* srcIp */,
publicIp4Addr /* dstIp */, REMOTE_PORT /* srcPort */, LOCAL_PORT /* dstPort */,
PAYLOAD2 /* payload */);
- remote.verifyDownload(tester, replyPacket, p -> {
+ tester.verifyDownload(replyPacket, p -> {
Log.d(TAG, "Packet in downstream: " + dumpHexString(p));
return isExpectedUdpPacket(p, true /* hasEther */, true /* isIpv4 */, PAYLOAD2);
});
@@ -1030,7 +1021,7 @@
tethered.routerMacAddr, tethered.ipv4Addr /* srcIp */,
REMOTE_IP4_ADDR /* dstIp */, LOCAL_PORT /* srcPort */,
REMOTE_PORT /* dstPort */, PAYLOAD3 /* payload */);
- tester.verifyUpload(remote, originalPacket2, p -> {
+ tester.verifyUpload(originalPacket2, p -> {
Log.d(TAG, "Packet in upstream: " + dumpHexString(p));
return isExpectedUdpPacket(p, false /* hasEther */, true /* isIpv4 */, PAYLOAD3);
});
@@ -1066,7 +1057,7 @@
// Send packets on original direction.
for (int i = 0; i < TX_UDP_PACKET_COUNT; i++) {
- tester.verifyUpload(remote, originalPacket, p -> {
+ tester.verifyUpload(originalPacket, p -> {
Log.d(TAG, "Packet in upstream: " + dumpHexString(p));
return isExpectedUdpPacket(p, false /* hasEther */, true /* isIpv4 */, PAYLOAD);
});
@@ -1074,7 +1065,7 @@
// Send packets on reply direction.
for (int i = 0; i < RX_UDP_PACKET_COUNT; i++) {
- remote.verifyDownload(tester, replyPacket, p -> {
+ tester.verifyDownload(replyPacket, p -> {
Log.d(TAG, "Packet in downstream: " + dumpHexString(p));
return isExpectedUdpPacket(p, true /* hasEther */, true /* isIpv4 */, PAYLOAD2);
});
@@ -1130,8 +1121,7 @@
@IgnoreAfter(Build.VERSION_CODES.R)
public void testTetherUdpV4UpToR() throws Exception {
initializeTethering(toList(TEST_IP4_ADDR), toList(TEST_IP4_DNS));
- runUdp4Test(new TetheringTester(mDownstreamReader), new RemoteResponder(mUpstreamReader),
- false /* usingBpf */);
+ runUdp4Test(new TetheringTester(mDownstreamReader, mUpstreamReader), false /* usingBpf */);
}
private static boolean isUdpOffloadSupportedByKernel(final String kernelVersion) {
@@ -1172,8 +1162,7 @@
Log.i(TAG, "testTetherUdpV4AfterR will skip BPF offload test for kernel "
+ kernelVersion);
}
- runUdp4Test(new TetheringTester(mDownstreamReader), new RemoteResponder(mUpstreamReader),
- usingBpf);
+ runUdp4Test(new TetheringTester(mDownstreamReader, mUpstreamReader), usingBpf);
}
@Nullable
@@ -1233,8 +1222,8 @@
}
@Nullable
- private Inet6Address getClatIpv6Address(TetheringTester tester,
- RemoteResponder remote, TetheredDevice tethered) throws Exception {
+ private Inet6Address getClatIpv6Address(TetheringTester tester, TetheredDevice tethered)
+ throws Exception {
final ByteBuffer probePacket = buildUdpPacket(tethered.macAddr,
tethered.routerMacAddr, tethered.ipv4Addr /* srcIp */,
REMOTE_IP4_ADDR /* dstIp */, LOCAL_PORT /* srcPort */, REMOTE_PORT /* dstPort */,
@@ -1245,8 +1234,7 @@
// packet.
byte[] expectedPacket = null;
for (int i = 0; i < TETHER_REACHABILITY_ATTEMPTS; i++) {
- tester.sendPacket(probePacket);
- expectedPacket = remote.getNextMatchedPacket(p -> {
+ expectedPacket = tester.verifyUpload(probePacket, p -> {
Log.d(TAG, "Packet in upstream: " + dumpHexString(p));
return isExpectedUdpPacket(p, false /* hasEther */, false /* isIpv4 */,
TEST_REACHABILITY_PAYLOAD);
@@ -1275,8 +1263,7 @@
// sending out an IPv4 packet and extracting the source address from CLAT translated IPv6
// packet.
//
- private void runClatUdpTest(TetheringTester tester, RemoteResponder remote)
- throws Exception {
+ private void runClatUdpTest(TetheringTester tester) throws Exception {
// Currently tethering don't have API to tell when ipv6 tethering is available. Thus, let
// TetheringTester test ipv6 tethering connectivity before testing ipv6.
// TODO: move to a common place to avoid that every IPv6 test needs to call this function.
@@ -1286,7 +1273,7 @@
"1:2:3:4:5:6"), true /* hasIpv6 */);
// Get CLAT IPv6 address.
- final Inet6Address clatAddr6 = getClatIpv6Address(tester, remote, tethered);
+ final Inet6Address clatAddr6 = getClatIpv6Address(tester, tethered);
assertNotNull(clatAddr6);
// Send an IPv4 UDP packet in original direction.
@@ -1295,7 +1282,7 @@
tethered.routerMacAddr, tethered.ipv4Addr /* srcIp */,
REMOTE_IP4_ADDR /* dstIp */, LOCAL_PORT /* srcPort */, REMOTE_PORT /* dstPort */,
PAYLOAD /* payload */);
- tester.verifyUpload(remote, originalPacket, p -> {
+ tester.verifyUpload(originalPacket, p -> {
Log.d(TAG, "Packet in upstream: " + dumpHexString(p));
return isExpectedUdpPacket(p, false /* hasEther */, false /* isIpv4 */, PAYLOAD);
});
@@ -1305,7 +1292,7 @@
final ByteBuffer replyPacket = buildUdpPacket(REMOTE_NAT64_ADDR /* srcIp */,
clatAddr6 /* dstIp */, REMOTE_PORT /* srcPort */, LOCAL_PORT /* dstPort */,
PAYLOAD2 /* payload */);
- remote.verifyDownload(tester, replyPacket, p -> {
+ tester.verifyDownload(replyPacket, p -> {
Log.d(TAG, "Packet in downstream: " + dumpHexString(p));
return isExpectedUdpPacket(p, true /* hasEther */, true /* isIpv4 */, PAYLOAD2);
});
@@ -1318,8 +1305,7 @@
public void testTetherClatUdp() throws Exception {
// CLAT only starts on IPv6 only network.
initializeTethering(toList(TEST_IP6_ADDR), toList(TEST_IP6_DNS));
- runClatUdpTest(new TetheringTester(mDownstreamReader),
- new RemoteResponder(mUpstreamReader));
+ runClatUdpTest(new TetheringTester(mDownstreamReader, mUpstreamReader));
}
private <T> List<T> toList(T... array) {
diff --git a/Tethering/tests/integration/src/android/net/TetheringTester.java b/Tethering/tests/integration/src/android/net/TetheringTester.java
index 458680a..9df636b 100644
--- a/Tethering/tests/integration/src/android/net/TetheringTester.java
+++ b/Tethering/tests/integration/src/android/net/TetheringTester.java
@@ -42,6 +42,7 @@
import android.util.ArrayMap;
import android.util.Log;
+import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.android.net.module.util.Ipv6Utils;
@@ -88,11 +89,17 @@
private final ArrayMap<MacAddress, TetheredDevice> mTetheredDevices;
private final TapPacketReader mDownstreamReader;
+ private final TapPacketReader mUpstreamReader;
public TetheringTester(TapPacketReader downstream) {
+ this(downstream, null);
+ }
+
+ public TetheringTester(TapPacketReader downstream, TapPacketReader upstream) {
if (downstream == null) fail("Downstream reader could not be NULL");
mDownstreamReader = downstream;
+ mUpstreamReader = upstream;
mTetheredDevices = new ArrayMap<>();
}
@@ -170,7 +177,7 @@
}
private DhcpPacket getNextDhcpPacket() throws Exception {
- final byte[] packet = getNextMatchedPacket((p) -> {
+ final byte[] packet = getDownloadPacket((p) -> {
// Test whether this is DHCP packet.
try {
DhcpPacket.decodeFullPacket(p, p.length, DhcpPacket.ENCAP_L2);
@@ -213,7 +220,7 @@
tethered.ipv4Addr.getAddress() /* sender IP */,
(short) ARP_REPLY);
try {
- sendPacket(arpReply);
+ sendUploadPacket(arpReply);
} catch (Exception e) {
fail("Failed to reply ARP for " + tethered.ipv4Addr);
}
@@ -227,9 +234,9 @@
tetherMac.toByteArray() /* srcMac */, routerIp.getAddress() /* target IP */,
new byte[ETHER_ADDR_LEN] /* target HW address */,
tetherIp.getAddress() /* sender IP */, (short) ARP_REQUEST);
- sendPacket(arpProbe);
+ sendUploadPacket(arpProbe);
- final byte[] packet = getNextMatchedPacket((p) -> {
+ final byte[] packet = getDownloadPacket((p) -> {
final ArpPacket arpPacket = parseArpPacket(p);
if (arpPacket == null || arpPacket.opCode != ARP_REPLY) return false;
return arpPacket.targetIp.equals(tetherIp);
@@ -252,7 +259,7 @@
// connectivity is ready. We don't extract the router mac address from RA because
// we get the router mac address from IPv4 ARP packet. See #getRouterMacAddressFromArp.
for (int i = 0; i < READ_RA_ATTEMPTS; i++) {
- final byte[] raPacket = getNextMatchedPacket((p) -> {
+ final byte[] raPacket = getDownloadPacket((p) -> {
return isIcmpv6Type(p, true /* hasEth */, ICMPV6_ROUTER_ADVERTISEMENT);
});
if (raPacket != null) return;
@@ -290,13 +297,10 @@
private Inet6Address runSlaac(MacAddress srcMac, MacAddress dstMac) throws Exception {
sendRsPacket(srcMac, dstMac);
- final byte[] raPacket = getNextMatchedPacket((p) -> {
+ final byte[] raPacket = verifyPacketNotNull("Receive RA fail", getDownloadPacket(p -> {
return isIcmpv6Type(p, true /* hasEth */, ICMPV6_ROUTER_ADVERTISEMENT);
- });
+ }));
- if (raPacket == null) {
- fail("Could not get ra for prefix options");
- }
final List<PrefixInformationOption> options = getRaPrefixOptions(raPacket);
for (PrefixInformationOption pio : options) {
@@ -322,7 +326,7 @@
ByteBuffer rs = Ipv6Utils.buildRsPacket(srcMac, dstMac, (Inet6Address) LINK_LOCAL,
IPV6_ADDR_ALL_NODES_MULTICAST, slla);
- sendPacket(rs);
+ sendUploadPacket(rs);
}
private void maybeReplyNa(byte[] packet) {
@@ -347,7 +351,7 @@
ByteBuffer ns = Ipv6Utils.buildNaPacket(tethered.macAddr, tethered.routerMacAddr,
nsHdr.target, ipv6Hdr.srcIp, flags, nsHdr.target, tlla);
try {
- sendPacket(ns);
+ sendUploadPacket(ns);
} catch (Exception e) {
fail("Failed to reply NA for " + tethered.ipv6Addr);
}
@@ -380,11 +384,17 @@
return false;
}
- public void sendPacket(ByteBuffer packet) throws Exception {
+ private void sendUploadPacket(ByteBuffer packet) throws Exception {
mDownstreamReader.sendResponse(packet);
}
- public byte[] getNextMatchedPacket(Predicate<byte[]> filter) {
+ private void sendDownloadPacket(ByteBuffer packet) throws Exception {
+ assertNotNull("Can't deal with upstream interface in local only mode", mUpstreamReader);
+
+ mUpstreamReader.sendResponse(packet);
+ }
+
+ private byte[] getDownloadPacket(Predicate<byte[]> filter) {
byte[] packet;
while ((packet = mDownstreamReader.poll(PACKET_READ_TIMEOUT_MS)) != null) {
if (filter.test(packet)) return packet;
@@ -396,30 +406,34 @@
return null;
}
- public void verifyUpload(final RemoteResponder dst, final ByteBuffer packet,
- final Predicate<byte[]> filter) throws Exception {
- sendPacket(packet);
- assertNotNull("Upload fail", dst.getNextMatchedPacket(filter));
+ private byte[] getUploadPacket(Predicate<byte[]> filter) {
+ assertNotNull("Can't deal with upstream interface in local only mode", mUpstreamReader);
+
+ return mUpstreamReader.poll(PACKET_READ_TIMEOUT_MS, filter);
}
- public static class RemoteResponder {
- final TapPacketReader mUpstreamReader;
- public RemoteResponder(TapPacketReader reader) {
- mUpstreamReader = reader;
- }
+ private @NonNull byte[] verifyPacketNotNull(String message, @Nullable byte[] packet) {
+ assertNotNull(message, packet);
- public void sendPacket(ByteBuffer packet) throws Exception {
- mUpstreamReader.sendResponse(packet);
- }
+ return packet;
+ }
- public byte[] getNextMatchedPacket(Predicate<byte[]> filter) throws Exception {
- return mUpstreamReader.poll(PACKET_READ_TIMEOUT_MS, filter);
- }
+ public byte[] testUpload(final ByteBuffer packet, final Predicate<byte[]> filter)
+ throws Exception {
+ sendUploadPacket(packet);
- public void verifyDownload(final TetheringTester dst, final ByteBuffer packet,
- final Predicate<byte[]> filter) throws Exception {
- sendPacket(packet);
- assertNotNull("Download fail", dst.getNextMatchedPacket(filter));
- }
+ return getUploadPacket(filter);
+ }
+
+ public byte[] verifyUpload(final ByteBuffer packet, final Predicate<byte[]> filter)
+ throws Exception {
+ return verifyPacketNotNull("Upload fail", testUpload(packet, filter));
+ }
+
+ public byte[] verifyDownload(final ByteBuffer packet, final Predicate<byte[]> filter)
+ throws Exception {
+ sendDownloadPacket(packet);
+
+ return verifyPacketNotNull("Download fail", getDownloadPacket(filter));
}
}