Merge changes I9bccc558,Ifd855571
* changes:
Test: separate common variables to EthernetTetheringTestBase
Test: decouple the tests which access class member variables directly
diff --git a/Tethering/tests/integration/src/android/net/EthernetTetheringTest.java b/Tethering/tests/integration/src/android/net/EthernetTetheringTest.java
index c2c9fc4..da69a8d 100644
--- a/Tethering/tests/integration/src/android/net/EthernetTetheringTest.java
+++ b/Tethering/tests/integration/src/android/net/EthernetTetheringTest.java
@@ -67,16 +67,13 @@
import static org.junit.Assume.assumeFalse;
import static org.junit.Assume.assumeTrue;
-import android.app.UiAutomation;
import android.content.Context;
-import android.content.pm.PackageManager;
import android.net.EthernetManager.TetheredInterfaceCallback;
import android.net.EthernetManager.TetheredInterfaceRequest;
import android.net.TetheringManager.StartTetheringCallback;
import android.net.TetheringManager.TetheringEventCallback;
import android.net.TetheringManager.TetheringRequest;
import android.net.TetheringTester.TetheredDevice;
-import android.net.cts.util.CtsNetUtils;
import android.os.Build;
import android.os.Handler;
import android.os.HandlerThread;
@@ -88,7 +85,6 @@
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
-import androidx.test.InstrumentationRegistry;
import androidx.test.filters.MediumTest;
import androidx.test.runner.AndroidJUnit4;
@@ -143,17 +139,12 @@
@RunWith(AndroidJUnit4.class)
@MediumTest
-public class EthernetTetheringTest {
+public class EthernetTetheringTest extends EthernetTetheringTestBase {
@Rule
public final DevSdkIgnoreRule mIgnoreRule = new DevSdkIgnoreRule();
private static final String TAG = EthernetTetheringTest.class.getSimpleName();
- private static final int TIMEOUT_MS = 5000;
- // Used to check if any tethering interface is available. Choose 200ms to be request timeout
- // because the average interface requested time on cuttlefish@acloud is around 10ms.
- // See TetheredInterfaceRequester.getInterface, isInterfaceForTetheringAvailable.
- private static final int AVAILABLE_TETHER_IFACE_REQUEST_TIMEOUT_MS = 200;
- private static final int TETHER_REACHABILITY_ATTEMPTS = 20;
+
private static final int DUMP_POLLING_MAX_RETRY = 100;
private static final int DUMP_POLLING_INTERVAL_MS = 50;
// Kernel treats a confirmed UDP connection which active after two seconds as stream mode.
@@ -168,35 +159,14 @@
// Per TX UDP packet size: ethhdr (14) + iphdr (20) + udphdr (8) + payload (2) = 44 bytes.
private static final int TX_UDP_PACKET_SIZE = 44;
private static final int TX_UDP_PACKET_COUNT = 123;
- private static final long WAIT_RA_TIMEOUT_MS = 2000;
-
- private static final MacAddress TEST_MAC = MacAddress.fromString("1:2:3:4:5:6");
- private static final LinkAddress TEST_IP4_ADDR = new LinkAddress("10.0.0.1/24");
- private static final LinkAddress TEST_IP6_ADDR = new LinkAddress("2001:db8:1::101/64");
- private static final InetAddress TEST_IP4_DNS = parseNumericAddress("8.8.8.8");
- private static final InetAddress TEST_IP6_DNS = parseNumericAddress("2001:db8:1::888");
- private static final IpPrefix TEST_NAT64PREFIX = new IpPrefix("64:ff9b::/96");
- private static final Inet6Address REMOTE_NAT64_ADDR =
- (Inet6Address) parseNumericAddress("64:ff9b::808:808");
- private static final Inet6Address REMOTE_IP6_ADDR =
- (Inet6Address) parseNumericAddress("2002:db8:1::515:ca");
- private static final ByteBuffer TEST_REACHABILITY_PAYLOAD =
- ByteBuffer.wrap(new byte[] { (byte) 0x55, (byte) 0xaa });
- private static final ByteBuffer EMPTY_PAYLOAD = ByteBuffer.wrap(new byte[0]);
private static final short DNS_PORT = 53;
- private static final short WINDOW = (short) 0x2000;
- private static final short URGENT_POINTER = 0;
private static final String DUMPSYS_TETHERING_RAWMAP_ARG = "bpfRawMap";
private static final String DUMPSYS_RAWMAP_ARG_STATS = "--stats";
private static final String DUMPSYS_RAWMAP_ARG_UPSTREAM4 = "--upstream4";
private static final String LINE_DELIMITER = "\\n";
- // version=6, traffic class=0x0, flowlabel=0x0;
- private static final int VERSION_TRAFFICCLASS_FLOWLABEL = 0x60000000;
- private static final short HOP_LIMIT = 0x40;
-
private static final short ICMPECHO_CODE = 0x0;
private static final short ICMPECHO_ID = 0x0;
private static final short ICMPECHO_SEQ = 0x0;
@@ -261,27 +231,9 @@
(byte) 0x01, (byte) 0x02, (byte) 0x03, (byte) 0x04 /* Address: 1.2.3.4 */
};
- private final Context mContext = InstrumentationRegistry.getContext();
- private final EthernetManager mEm = mContext.getSystemService(EthernetManager.class);
- private final TetheringManager mTm = mContext.getSystemService(TetheringManager.class);
- private final PackageManager mPackageManager = mContext.getPackageManager();
- private final CtsNetUtils mCtsNetUtils = new CtsNetUtils(mContext);
-
- private TestNetworkInterface mDownstreamIface;
- private HandlerThread mHandlerThread;
- private Handler mHandler;
- private TapPacketReader mDownstreamReader;
- private TapPacketReader mUpstreamReader;
-
private TetheredInterfaceRequester mTetheredInterfaceRequester;
private MyTetheringEventCallback mTetheringEventCallback;
- private UiAutomation mUiAutomation =
- InstrumentationRegistry.getInstrumentation().getUiAutomation();
- private boolean mRunTests;
-
- private TestNetworkTracker mUpstreamTracker;
-
@Before
public void setUp() throws Exception {
mHandlerThread = new HandlerThread(getClass().getSimpleName());
@@ -295,6 +247,30 @@
mTetheredInterfaceRequester = new TetheredInterfaceRequester(mHandler, mEm);
}
+ private void maybeStopTapPacketReader(final TapPacketReader tapPacketReader)
+ throws Exception {
+ if (tapPacketReader != null) {
+ TapPacketReader reader = tapPacketReader;
+ mHandler.post(() -> reader.stop());
+ }
+ }
+
+ private void maybeCloseTestInterface(final TestNetworkInterface testInterface)
+ throws Exception {
+ if (testInterface != null) {
+ testInterface.getFileDescriptor().close();
+ Log.d(TAG, "Deleted test interface " + testInterface.getInterfaceName());
+ }
+ }
+
+ private void maybeUnregisterTetheringEventCallback(final MyTetheringEventCallback callback)
+ throws Exception {
+ if (callback != null) {
+ callback.awaitInterfaceUntethered();
+ callback.unregister();
+ }
+ }
+
private void cleanUp() throws Exception {
setPreferTestNetworks(false);
@@ -310,24 +286,19 @@
mUpstreamReader = null;
}
- if (mDownstreamReader != null) {
- TapPacketReader reader = mDownstreamReader;
- mHandler.post(() -> reader.stop());
- mDownstreamReader = null;
- }
-
+ maybeStopTapPacketReader(mDownstreamReader);
+ mDownstreamReader = null;
// To avoid flaky which caused by the next test started but the previous interface is not
// untracked from EthernetTracker yet. Just delete the test interface without explicitly
// calling TetheringManager#stopTethering could let EthernetTracker untrack the test
// interface from server mode before tethering stopped. Thus, awaitInterfaceUntethered
// could not only make sure tethering is stopped but also guarantee the test interface is
// untracked from EthernetTracker.
- maybeDeleteTestInterface();
- if (mTetheringEventCallback != null) {
- mTetheringEventCallback.awaitInterfaceUntethered();
- mTetheringEventCallback.unregister();
- mTetheringEventCallback = null;
- }
+ maybeCloseTestInterface(mDownstreamIface);
+ mDownstreamIface = null;
+ maybeUnregisterTetheringEventCallback(mTetheringEventCallback);
+ mTetheringEventCallback = null;
+
runAsShell(NETWORK_SETTINGS, () -> mTetheredInterfaceRequester.release());
setIncludeTestInterfaces(false);
}
@@ -383,26 +354,50 @@
});
}
+ private String getTetheredInterface() throws Exception {
+ return mTetheredInterfaceRequester.getInterface();
+ }
+
+ private CompletableFuture<String> requestTetheredInterface() throws Exception {
+ return mTetheredInterfaceRequester.requestInterface();
+ }
+
@Test
public void testVirtualEthernetAlreadyExists() throws Exception {
// This test requires manipulating packets. Skip if there is a physical Ethernet connected.
assumeFalse(isInterfaceForTetheringAvailable());
- mDownstreamIface = createTestInterface();
- // This must be done now because as soon as setIncludeTestInterfaces(true) is called, the
- // interface will be placed in client mode, which will delete the link-local address.
- // At that point NetworkInterface.getByName() will cease to work on the interface, because
- // starting in R NetworkInterface can no longer see interfaces without IP addresses.
- int mtu = getMTU(mDownstreamIface);
+ TestNetworkInterface downstreamIface = null;
+ MyTetheringEventCallback tetheringEventCallback = null;
+ TapPacketReader downstreamReader = null;
- Log.d(TAG, "Including test interfaces");
- setIncludeTestInterfaces(true);
+ try {
+ downstreamIface = createTestInterface();
+ // This must be done now because as soon as setIncludeTestInterfaces(true) is called,
+ // the interface will be placed in client mode, which will delete the link-local
+ // address. At that point NetworkInterface.getByName() will cease to work on the
+ // interface, because starting in R NetworkInterface can no longer see interfaces
+ // without IP addresses.
+ int mtu = getMTU(downstreamIface);
- final String iface = mTetheredInterfaceRequester.getInterface();
- assertEquals("TetheredInterfaceCallback for unexpected interface",
- mDownstreamIface.getInterfaceName(), iface);
+ Log.d(TAG, "Including test interfaces");
+ setIncludeTestInterfaces(true);
- checkVirtualEthernet(mDownstreamIface, mtu);
+ final String iface = getTetheredInterface();
+ assertEquals("TetheredInterfaceCallback for unexpected interface",
+ downstreamIface.getInterfaceName(), iface);
+
+ // Check virtual ethernet.
+ FileDescriptor fd = downstreamIface.getFileDescriptor().getFileDescriptor();
+ downstreamReader = makePacketReader(fd, mtu);
+ tetheringEventCallback = enableEthernetTethering(downstreamIface.getInterfaceName(),
+ null /* any upstream */);
+ checkTetheredClientCallbacks(downstreamReader, tetheringEventCallback);
+ } finally {
+ maybeStopTapPacketReader(downstreamReader);
+ maybeCloseTestInterface(downstreamIface);
+ maybeUnregisterTetheringEventCallback(tetheringEventCallback);
+ }
}
@Test
@@ -410,17 +405,32 @@
// This test requires manipulating packets. Skip if there is a physical Ethernet connected.
assumeFalse(isInterfaceForTetheringAvailable());
- CompletableFuture<String> futureIface = mTetheredInterfaceRequester.requestInterface();
+ CompletableFuture<String> futureIface = requestTetheredInterface();
setIncludeTestInterfaces(true);
- mDownstreamIface = createTestInterface();
+ TestNetworkInterface downstreamIface = null;
+ MyTetheringEventCallback tetheringEventCallback = null;
+ TapPacketReader downstreamReader = null;
- final String iface = futureIface.get(TIMEOUT_MS, TimeUnit.MILLISECONDS);
- assertEquals("TetheredInterfaceCallback for unexpected interface",
- mDownstreamIface.getInterfaceName(), iface);
+ try {
+ downstreamIface = createTestInterface();
- checkVirtualEthernet(mDownstreamIface, getMTU(mDownstreamIface));
+ final String iface = futureIface.get(TIMEOUT_MS, TimeUnit.MILLISECONDS);
+ assertEquals("TetheredInterfaceCallback for unexpected interface",
+ downstreamIface.getInterfaceName(), iface);
+
+ // Check virtual ethernet.
+ FileDescriptor fd = downstreamIface.getFileDescriptor().getFileDescriptor();
+ downstreamReader = makePacketReader(fd, getMTU(downstreamIface));
+ tetheringEventCallback = enableEthernetTethering(downstreamIface.getInterfaceName(),
+ null /* any upstream */);
+ checkTetheredClientCallbacks(downstreamReader, tetheringEventCallback);
+ } finally {
+ maybeStopTapPacketReader(downstreamReader);
+ maybeCloseTestInterface(downstreamIface);
+ maybeUnregisterTetheringEventCallback(tetheringEventCallback);
+ }
}
@Test
@@ -429,42 +439,51 @@
setIncludeTestInterfaces(true);
- mDownstreamIface = createTestInterface();
-
- final String iface = mTetheredInterfaceRequester.getInterface();
- assertEquals("TetheredInterfaceCallback for unexpected interface",
- mDownstreamIface.getInterfaceName(), iface);
-
- assertInvalidStaticIpv4Request(iface, null, null);
- assertInvalidStaticIpv4Request(iface, "2001:db8::1/64", "2001:db8:2::/64");
- assertInvalidStaticIpv4Request(iface, "192.0.2.2/28", "2001:db8:2::/28");
- assertInvalidStaticIpv4Request(iface, "2001:db8:2::/28", "192.0.2.2/28");
- assertInvalidStaticIpv4Request(iface, "192.0.2.2/28", null);
- assertInvalidStaticIpv4Request(iface, null, "192.0.2.2/28");
- assertInvalidStaticIpv4Request(iface, "192.0.2.3/27", "192.0.2.2/28");
-
- final String localAddr = "192.0.2.3/28";
- final String clientAddr = "192.0.2.2/28";
- mTetheringEventCallback = enableEthernetTethering(iface,
- requestWithStaticIpv4(localAddr, clientAddr), null /* any upstream */);
-
- mTetheringEventCallback.awaitInterfaceTethered();
- assertInterfaceHasIpAddress(iface, localAddr);
-
- byte[] client1 = MacAddress.fromString("1:2:3:4:5:6").toByteArray();
- byte[] client2 = MacAddress.fromString("a:b:c:d:e:f").toByteArray();
-
- FileDescriptor fd = mDownstreamIface.getFileDescriptor().getFileDescriptor();
- mDownstreamReader = makePacketReader(fd, getMTU(mDownstreamIface));
- TetheringTester tester = new TetheringTester(mDownstreamReader);
- DhcpResults dhcpResults = tester.runDhcp(client1);
- assertEquals(new LinkAddress(clientAddr), dhcpResults.ipAddress);
+ TestNetworkInterface downstreamIface = null;
+ MyTetheringEventCallback tetheringEventCallback = null;
+ TapPacketReader downstreamReader = null;
try {
- tester.runDhcp(client2);
- fail("Only one client should get an IP address");
- } catch (TimeoutException expected) { }
+ downstreamIface = createTestInterface();
+ final String iface = getTetheredInterface();
+ assertEquals("TetheredInterfaceCallback for unexpected interface",
+ downstreamIface.getInterfaceName(), iface);
+
+ assertInvalidStaticIpv4Request(iface, null, null);
+ assertInvalidStaticIpv4Request(iface, "2001:db8::1/64", "2001:db8:2::/64");
+ assertInvalidStaticIpv4Request(iface, "192.0.2.2/28", "2001:db8:2::/28");
+ assertInvalidStaticIpv4Request(iface, "2001:db8:2::/28", "192.0.2.2/28");
+ assertInvalidStaticIpv4Request(iface, "192.0.2.2/28", null);
+ assertInvalidStaticIpv4Request(iface, null, "192.0.2.2/28");
+ assertInvalidStaticIpv4Request(iface, "192.0.2.3/27", "192.0.2.2/28");
+
+ final String localAddr = "192.0.2.3/28";
+ final String clientAddr = "192.0.2.2/28";
+ tetheringEventCallback = enableEthernetTethering(iface,
+ requestWithStaticIpv4(localAddr, clientAddr), null /* any upstream */);
+
+ tetheringEventCallback.awaitInterfaceTethered();
+ assertInterfaceHasIpAddress(iface, localAddr);
+
+ byte[] client1 = MacAddress.fromString("1:2:3:4:5:6").toByteArray();
+ byte[] client2 = MacAddress.fromString("a:b:c:d:e:f").toByteArray();
+
+ FileDescriptor fd = downstreamIface.getFileDescriptor().getFileDescriptor();
+ downstreamReader = makePacketReader(fd, getMTU(downstreamIface));
+ TetheringTester tester = new TetheringTester(downstreamReader);
+ DhcpResults dhcpResults = tester.runDhcp(client1);
+ assertEquals(new LinkAddress(clientAddr), dhcpResults.ipAddress);
+
+ try {
+ tester.runDhcp(client2);
+ fail("Only one client should get an IP address");
+ } catch (TimeoutException expected) { }
+ } finally {
+ maybeStopTapPacketReader(downstreamReader);
+ maybeCloseTestInterface(downstreamIface);
+ maybeUnregisterTetheringEventCallback(tetheringEventCallback);
+ }
}
private static void waitForRouterAdvertisement(TapPacketReader reader, String iface,
@@ -510,26 +529,36 @@
setIncludeTestInterfaces(true);
- mDownstreamIface = createTestInterface();
+ TestNetworkInterface downstreamIface = null;
+ MyTetheringEventCallback tetheringEventCallback = null;
+ TapPacketReader downstreamReader = null;
- final String iface = mTetheredInterfaceRequester.getInterface();
- assertEquals("TetheredInterfaceCallback for unexpected interface",
- mDownstreamIface.getInterfaceName(), iface);
+ try {
+ downstreamIface = createTestInterface();
- final TetheringRequest request = new TetheringRequest.Builder(TETHERING_ETHERNET)
- .setConnectivityScope(CONNECTIVITY_SCOPE_LOCAL).build();
- mTetheringEventCallback = enableEthernetTethering(iface, request,
- null /* any upstream */);
- mTetheringEventCallback.awaitInterfaceLocalOnly();
+ final String iface = getTetheredInterface();
+ assertEquals("TetheredInterfaceCallback for unexpected interface",
+ downstreamIface.getInterfaceName(), iface);
- // makePacketReader only works after tethering is started, because until then the interface
- // does not have an IP address, and unprivileged apps cannot see interfaces without IP
- // addresses. This shouldn't be flaky because the TAP interface will buffer all packets even
- // before the reader is started.
- mDownstreamReader = makePacketReader(mDownstreamIface);
+ final TetheringRequest request = new TetheringRequest.Builder(TETHERING_ETHERNET)
+ .setConnectivityScope(CONNECTIVITY_SCOPE_LOCAL).build();
+ tetheringEventCallback = enableEthernetTethering(iface, request,
+ null /* any upstream */);
+ tetheringEventCallback.awaitInterfaceLocalOnly();
- waitForRouterAdvertisement(mDownstreamReader, iface, WAIT_RA_TIMEOUT_MS);
- expectLocalOnlyAddresses(iface);
+ // makePacketReader only works after tethering is started, because until then the
+ // interface does not have an IP address, and unprivileged apps cannot see interfaces
+ // without IP addresses. This shouldn't be flaky because the TAP interface will buffer
+ // all packets even before the reader is started.
+ downstreamReader = makePacketReader(downstreamIface);
+
+ waitForRouterAdvertisement(downstreamReader, iface, WAIT_RA_TIMEOUT_MS);
+ expectLocalOnlyAddresses(iface);
+ } finally {
+ maybeStopTapPacketReader(downstreamReader);
+ maybeCloseTestInterface(downstreamIface);
+ maybeUnregisterTetheringEventCallback(tetheringEventCallback);
+ }
}
private boolean isAdbOverNetwork() {
@@ -546,12 +575,16 @@
// from client mode to server mode. See b/160389275.
assumeFalse(isAdbOverNetwork());
- // Get an interface to use.
- final String iface = mTetheredInterfaceRequester.getInterface();
+ MyTetheringEventCallback tetheringEventCallback = null;
+ try {
+ // Get an interface to use.
+ final String iface = getTetheredInterface();
- // Enable Ethernet tethering and check that it starts.
- mTetheringEventCallback = enableEthernetTethering(iface, null /* any upstream */);
-
+ // Enable Ethernet tethering and check that it starts.
+ tetheringEventCallback = enableEthernetTethering(iface, null /* any upstream */);
+ } finally {
+ maybeUnregisterTetheringEventCallback(tetheringEventCallback);
+ }
// There is nothing more we can do on a physical interface without connecting an actual
// client, which is not possible in this test.
}
@@ -810,15 +843,8 @@
return reader;
}
- private void checkVirtualEthernet(TestNetworkInterface iface, int mtu) throws Exception {
- FileDescriptor fd = iface.getFileDescriptor().getFileDescriptor();
- mDownstreamReader = makePacketReader(fd, mtu);
- mTetheringEventCallback = enableEthernetTethering(iface.getInterfaceName(),
- null /* any upstream */);
- checkTetheredClientCallbacks(mDownstreamReader);
- }
-
- private void checkTetheredClientCallbacks(TapPacketReader packetReader) throws Exception {
+ private void checkTetheredClientCallbacks(final TapPacketReader packetReader,
+ final MyTetheringEventCallback tetheringEventCallback) throws Exception {
// Create a fake client.
byte[] clientMacAddr = new byte[6];
new Random().nextBytes(clientMacAddr);
@@ -826,7 +852,7 @@
TetheringTester tester = new TetheringTester(packetReader);
DhcpResults dhcpResults = tester.runDhcp(clientMacAddr);
- final Collection<TetheredClient> clients = mTetheringEventCallback.awaitClientConnected();
+ final Collection<TetheredClient> clients = tetheringEventCallback.awaitClientConnected();
assertEquals(1, clients.size());
final TetheredClient client = clients.iterator().next();
@@ -945,14 +971,6 @@
return iface;
}
- private void maybeDeleteTestInterface() throws Exception {
- if (mDownstreamIface != null) {
- mDownstreamIface.getFileDescriptor().close();
- Log.d(TAG, "Deleted test interface " + mDownstreamIface.getInterfaceName());
- mDownstreamIface = null;
- }
- }
-
private TestNetworkTracker createTestUpstream(final List<LinkAddress> addresses,
final List<InetAddress> dnses) throws Exception {
setPreferTestNetworks(true);
@@ -1002,22 +1020,6 @@
// remote ip public ip private ip
// 8.8.8.8:443 <Upstream ip>:9876 <TetheredDevice ip>:9876
//
- private static final Inet4Address REMOTE_IP4_ADDR =
- (Inet4Address) parseNumericAddress("8.8.8.8");
- // Used by public port and private port. Assume port 9876 has not been used yet before the
- // testing that public port and private port are the same in the testing. Note that NAT port
- // forwarding could be different between private port and public port.
- // TODO: move to the start of test class.
- private static final short LOCAL_PORT = 9876;
- private static final short REMOTE_PORT = 433;
- private static final byte TYPE_OF_SERVICE = 0;
- private static final short ID = 27149;
- private static final short FLAGS_AND_FRAGMENT_OFFSET = (short) 0x4000; // flags=DF, offset=0
- private static final byte TIME_TO_LIVE = (byte) 0x40;
- private static final ByteBuffer RX_PAYLOAD =
- ByteBuffer.wrap(new byte[] { (byte) 0x12, (byte) 0x34 });
- private static final ByteBuffer TX_PAYLOAD =
- ByteBuffer.wrap(new byte[] { (byte) 0x56, (byte) 0x78 });
private short getEthType(@NonNull final InetAddress srcIp, @NonNull final InetAddress dstIp) {
return isAddressIpv4(srcIp, dstIp) ? (short) ETHER_TYPE_IPV4 : (short) ETHER_TYPE_IPV6;
diff --git a/Tethering/tests/integration/src/android/net/EthernetTetheringTestBase.java b/Tethering/tests/integration/src/android/net/EthernetTetheringTestBase.java
new file mode 100644
index 0000000..d58a60c
--- /dev/null
+++ b/Tethering/tests/integration/src/android/net/EthernetTetheringTestBase.java
@@ -0,0 +1,115 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net;
+
+import static android.net.InetAddresses.parseNumericAddress;
+
+import android.app.UiAutomation;
+import android.content.Context;
+import android.content.pm.PackageManager;
+import android.net.cts.util.CtsNetUtils;
+import android.os.Handler;
+import android.os.HandlerThread;
+
+import androidx.test.platform.app.InstrumentationRegistry;
+
+import com.android.testutils.TapPacketReader;
+import com.android.testutils.TestNetworkTracker;
+
+import java.net.Inet4Address;
+import java.net.Inet6Address;
+import java.net.InetAddress;
+import java.nio.ByteBuffer;
+
+/**
+ * TODO: Common variables or methods shared between CtsEthernetTetheringTest and
+ * MtsEthernetTetheringTest.
+ */
+public abstract class EthernetTetheringTestBase {
+ private static final String TAG = EthernetTetheringTestBase.class.getSimpleName();
+
+ protected static final int TIMEOUT_MS = 5000;
+ // Used to check if any tethering interface is available. Choose 200ms to be request timeout
+ // because the average interface requested time on cuttlefish@acloud is around 10ms.
+ // See TetheredInterfaceRequester.getInterface, isInterfaceForTetheringAvailable.
+ protected static final int AVAILABLE_TETHER_IFACE_REQUEST_TIMEOUT_MS = 200;
+ protected static final int TETHER_REACHABILITY_ATTEMPTS = 20;
+ protected static final long WAIT_RA_TIMEOUT_MS = 2000;
+
+ // Address and NAT prefix definition.
+ protected static final MacAddress TEST_MAC = MacAddress.fromString("1:2:3:4:5:6");
+ protected static final LinkAddress TEST_IP4_ADDR = new LinkAddress("10.0.0.1/24");
+ protected static final LinkAddress TEST_IP6_ADDR = new LinkAddress("2001:db8:1::101/64");
+ protected static final InetAddress TEST_IP4_DNS = parseNumericAddress("8.8.8.8");
+ protected static final InetAddress TEST_IP6_DNS = parseNumericAddress("2001:db8:1::888");
+
+ protected static final Inet4Address REMOTE_IP4_ADDR =
+ (Inet4Address) parseNumericAddress("8.8.8.8");
+ protected static final Inet6Address REMOTE_IP6_ADDR =
+ (Inet6Address) parseNumericAddress("2002:db8:1::515:ca");
+ protected static final Inet6Address REMOTE_NAT64_ADDR =
+ (Inet6Address) parseNumericAddress("64:ff9b::808:808");
+ protected static final IpPrefix TEST_NAT64PREFIX = new IpPrefix("64:ff9b::/96");
+
+ // IPv4 header definition.
+ protected static final short ID = 27149;
+ protected static final short FLAGS_AND_FRAGMENT_OFFSET = (short) 0x4000; // flags=DF, offset=0
+ protected static final byte TIME_TO_LIVE = (byte) 0x40;
+ protected static final byte TYPE_OF_SERVICE = 0;
+
+ // IPv6 header definition.
+ protected static final short HOP_LIMIT = 0x40;
+ // version=6, traffic class=0x0, flowlabel=0x0;
+ protected static final int VERSION_TRAFFICCLASS_FLOWLABEL = 0x60000000;
+
+ // UDP and TCP header definition.
+ // LOCAL_PORT is used by public port and private port. Assume port 9876 has not been used yet
+ // before the testing that public port and private port are the same in the testing. Note that
+ // NAT port forwarding could be different between private port and public port.
+ protected static final short LOCAL_PORT = 9876;
+ protected static final short REMOTE_PORT = 433;
+ protected static final short WINDOW = (short) 0x2000;
+ protected static final short URGENT_POINTER = 0;
+
+ // Payload definition.
+ protected static final ByteBuffer EMPTY_PAYLOAD = ByteBuffer.wrap(new byte[0]);
+ protected static final ByteBuffer TEST_REACHABILITY_PAYLOAD =
+ ByteBuffer.wrap(new byte[] { (byte) 0x55, (byte) 0xaa });
+ protected static final ByteBuffer RX_PAYLOAD =
+ ByteBuffer.wrap(new byte[] { (byte) 0x12, (byte) 0x34 });
+ protected static final ByteBuffer TX_PAYLOAD =
+ ByteBuffer.wrap(new byte[] { (byte) 0x56, (byte) 0x78 });
+
+ protected final Context mContext = InstrumentationRegistry.getInstrumentation().getContext();
+ protected final EthernetManager mEm = mContext.getSystemService(EthernetManager.class);
+ protected final TetheringManager mTm = mContext.getSystemService(TetheringManager.class);
+ protected final PackageManager mPackageManager = mContext.getPackageManager();
+ protected final CtsNetUtils mCtsNetUtils = new CtsNetUtils(mContext);
+ protected final UiAutomation mUiAutomation =
+ InstrumentationRegistry.getInstrumentation().getUiAutomation();
+
+ // Late initialization in setUp()
+ protected boolean mRunTests;
+ protected HandlerThread mHandlerThread;
+ protected Handler mHandler;
+
+ // Late initialization in initTetheringTester().
+ protected TapPacketReader mUpstreamReader;
+ protected TestNetworkTracker mUpstreamTracker;
+ protected TestNetworkInterface mDownstreamIface;
+ protected TapPacketReader mDownstreamReader;
+}