diff --git a/thread/tests/integration/src/android/net/thread/BorderRoutingTest.java b/thread/tests/integration/src/android/net/thread/BorderRoutingTest.java index ddbef4709e..aeeed65306 100644 --- a/thread/tests/integration/src/android/net/thread/BorderRoutingTest.java +++ b/thread/tests/integration/src/android/net/thread/BorderRoutingTest.java @@ -58,6 +58,7 @@ import android.net.thread.utils.FullThreadDevice; import android.net.thread.utils.InfraNetworkDevice; import android.net.thread.utils.IntegrationTestUtils; import android.net.thread.utils.OtDaemonController; +import android.net.thread.utils.TestTunNetworkUtils; import android.net.thread.utils.ThreadFeatureCheckerRule; import android.net.thread.utils.ThreadFeatureCheckerRule.RequiresIpv6MulticastRouting; import android.net.thread.utils.ThreadFeatureCheckerRule.RequiresSimulationThreadDevice; @@ -160,6 +161,7 @@ public class BorderRoutingTest { @After public void tearDown() throws Exception { mController.setTestNetworkAsUpstreamAndWait(null); + TestTunNetworkUtils.tearDownAllInfraNetworks(); mHandlerThread.quitSafely(); mHandlerThread.join(); @@ -226,19 +228,13 @@ public class BorderRoutingTest { FullThreadDevice ftd = mFtds.get(0); joinNetworkAndWaitForOmr(ftd, DEFAULT_DATASET); Inet6Address ftdOmr = ftd.getOmrAddress(); - // Create a new infra network and let Thread prefer it - TestNetworkTracker oldInfraNetworkTracker = mInfraNetworkTracker; - try { - setUpInfraNetwork(); - mInfraNetworkReader = newPacketReader(mInfraNetworkTracker.getTestIface(), mHandler); - startInfraDeviceAndWaitForOnLinkAddr(); + setUpInfraNetwork(); + mInfraNetworkReader = newPacketReader(mInfraNetworkTracker.getTestIface(), mHandler); + startInfraDeviceAndWaitForOnLinkAddr(); - mInfraDevice.sendEchoRequest(ftd.getOmrAddress()); + mInfraDevice.sendEchoRequest(ftd.getOmrAddress()); - assertNotNull(pollForIcmpPacketOnInfraNetwork(ICMPV6_ECHO_REPLY_TYPE, ftdOmr)); - } finally { - runAsShell(MANAGE_TEST_NETWORKS, () -> oldInfraNetworkTracker.teardown()); - } + assertNotNull(pollForIcmpPacketOnInfraNetwork(ICMPV6_ECHO_REPLY_TYPE, ftdOmr)); } @Test @@ -615,8 +611,6 @@ public class BorderRoutingTest { subscribeMulticastAddressAndWait(ftd, GROUP_ADDR_SCOPE_5); Inet6Address ftdOmr = ftd.getOmrAddress(); - // Destroy infra link and re-create - tearDownInfraNetwork(); setUpInfraNetwork(); mInfraNetworkReader = newPacketReader(mInfraNetworkTracker.getTestIface(), mHandler); startInfraDeviceAndWaitForOnLinkAddr(); @@ -642,8 +636,6 @@ public class BorderRoutingTest { joinNetworkAndWaitForOmr(ftd, DEFAULT_DATASET); Inet6Address ftdOmr = ftd.getOmrAddress(); - // Destroy infra link and re-create - tearDownInfraNetwork(); setUpInfraNetwork(); mInfraNetworkReader = newPacketReader(mInfraNetworkTracker.getTestIface(), mHandler); startInfraDeviceAndWaitForOnLinkAddr(); @@ -683,7 +675,7 @@ public class BorderRoutingTest { @Test public void nat64_withAilNat64Prefix_threadDevicePingIpv4InfraDevice_outboundPacketIsForwarded() throws Exception { - tearDownInfraNetwork(); + TestTunNetworkUtils.tearDownInfraNetwork(mInfraNetworkTracker); LinkProperties lp = new LinkProperties(); // NAT64 feature requires the infra network to have an IPv4 default route. lp.addRoute( @@ -701,7 +693,7 @@ public class BorderRoutingTest { RouteInfo.RTN_UNICAST, 1500 /* mtu */)); lp.setNat64Prefix(AIL_NAT64_PREFIX); - mInfraNetworkTracker = IntegrationTestUtils.setUpInfraNetwork(mContext, mController, lp); + mInfraNetworkTracker = TestTunNetworkUtils.setUpInfraNetwork(mContext, mController, lp); mInfraNetworkReader = newPacketReader(mInfraNetworkTracker.getTestIface(), mHandler); FullThreadDevice ftd = mFtds.get(0); joinNetworkAndWaitForOmr(ftd, DEFAULT_DATASET); @@ -717,16 +709,12 @@ public class BorderRoutingTest { } private void setUpInfraNetwork() throws Exception { - mInfraNetworkTracker = IntegrationTestUtils.setUpInfraNetwork(mContext, mController); - } - - private void tearDownInfraNetwork() { - IntegrationTestUtils.tearDownInfraNetwork(mInfraNetworkTracker); + mInfraNetworkTracker = TestTunNetworkUtils.setUpInfraNetwork(mContext, mController); } private void startInfraDeviceAndWaitForOnLinkAddr() { mInfraDevice = - IntegrationTestUtils.startInfraDeviceAndWaitForOnLinkAddr(mInfraNetworkReader); + TestTunNetworkUtils.startInfraDeviceAndWaitForOnLinkAddr(mInfraNetworkReader); } private void assertInfraLinkMemberOfGroup(Inet6Address address) throws Exception { diff --git a/thread/tests/integration/src/android/net/thread/InternetAccessTest.kt b/thread/tests/integration/src/android/net/thread/InternetAccessTest.kt index 162f58e361..cb006114de 100644 --- a/thread/tests/integration/src/android/net/thread/InternetAccessTest.kt +++ b/thread/tests/integration/src/android/net/thread/InternetAccessTest.kt @@ -28,12 +28,10 @@ import android.net.thread.utils.IntegrationTestUtils.enableThreadAndJoinNetwork import android.net.thread.utils.IntegrationTestUtils.joinNetworkAndWaitForOmr import android.net.thread.utils.IntegrationTestUtils.leaveNetworkAndDisableThread import android.net.thread.utils.IntegrationTestUtils.newPacketReader -import android.net.thread.utils.IntegrationTestUtils.setUpInfraNetwork -import android.net.thread.utils.IntegrationTestUtils.startInfraDeviceAndWaitForOnLinkAddr -import android.net.thread.utils.IntegrationTestUtils.tearDownInfraNetwork import android.net.thread.utils.IntegrationTestUtils.waitFor import android.net.thread.utils.OtDaemonController import android.net.thread.utils.TestDnsServer +import android.net.thread.utils.TestTunNetworkUtils import android.net.thread.utils.TestUdpEchoServer import android.net.thread.utils.ThreadFeatureCheckerRule import android.net.thread.utils.ThreadFeatureCheckerRule.RequiresSimulationThreadDevice @@ -128,11 +126,11 @@ class InternetAccessTest { handler = Handler(handlerThread.looper) ftds = ArrayList() - infraNetworkTracker = setUpInfraNetwork(context, controller) + infraNetworkTracker = TestTunNetworkUtils.setUpInfraNetwork(context, controller) // Create an infra network device. infraNetworkReader = newPacketReader(infraNetworkTracker.testIface, handler) - infraDevice = startInfraDeviceAndWaitForOnLinkAddr(infraNetworkReader) + infraDevice = TestTunNetworkUtils.startInfraDeviceAndWaitForOnLinkAddr(infraNetworkReader) // Create a DNS server dnsServer = TestDnsServer(infraNetworkReader, DNS_SERVER_ADDR, ANSWER_RECORDS) @@ -150,7 +148,7 @@ class InternetAccessTest { @Throws(Exception::class) fun tearDown() { controller.setTestNetworkAsUpstreamAndWait(null) - tearDownInfraNetwork(infraNetworkTracker) + TestTunNetworkUtils.tearDownAllInfraNetworks() dnsServer.stop() udpEchoServer.stop() diff --git a/thread/tests/integration/src/android/net/thread/utils/IntegrationTestUtils.kt b/thread/tests/integration/src/android/net/thread/utils/IntegrationTestUtils.kt index c3859c17c5..07d03906d5 100644 --- a/thread/tests/integration/src/android/net/thread/utils/IntegrationTestUtils.kt +++ b/thread/tests/integration/src/android/net/thread/utils/IntegrationTestUtils.kt @@ -649,57 +649,6 @@ object IntegrationTestUtils { ) } - private fun defaultLinkProperties(): LinkProperties { - val lp = LinkProperties() - // TODO: use a fake DNS server - lp.setDnsServers(listOf(parseNumericAddress("8.8.8.8"))) - // NAT64 feature requires the infra network to have an IPv4 default route. - lp.addRoute( - RouteInfo( - IpPrefix("0.0.0.0/0") /* destination */, - null /* gateway */, - null /* iface */, - RouteInfo.RTN_UNICAST, 1500 /* mtu */ - ) - ) - return lp - } - - @JvmStatic - @JvmOverloads - fun startInfraDeviceAndWaitForOnLinkAddr( - pollPacketReader: PollPacketReader, - macAddress: MacAddress = MacAddress.fromString("1:2:3:4:5:6") - ): InfraNetworkDevice { - val infraDevice = InfraNetworkDevice(macAddress, pollPacketReader) - infraDevice.runSlaac(Duration.ofSeconds(60)) - requireNotNull(infraDevice.ipv6Addr) - return infraDevice - } - - @JvmStatic - @JvmOverloads - @Throws(java.lang.Exception::class) - fun setUpInfraNetwork( - context: Context, - controller: ThreadNetworkControllerWrapper, - lp: LinkProperties = defaultLinkProperties() - ): TestNetworkTracker { - val infraNetworkTracker: TestNetworkTracker = - runAsShell( - MANAGE_TEST_NETWORKS, - supplier = { initTestNetwork(context, lp, setupTimeoutMs = 5000) }) - val infraNetworkName: String = infraNetworkTracker.testIface.getInterfaceName() - controller.setTestNetworkAsUpstreamAndWait(infraNetworkName) - - return infraNetworkTracker - } - - @JvmStatic - fun tearDownInfraNetwork(testNetworkTracker: TestNetworkTracker) { - runAsShell(MANAGE_TEST_NETWORKS) { testNetworkTracker.teardown() } - } - /** * Stop the ot-daemon by shell command. */ diff --git a/thread/tests/integration/src/android/net/thread/utils/TestTunNetworkUtils.kt b/thread/tests/integration/src/android/net/thread/utils/TestTunNetworkUtils.kt new file mode 100644 index 0000000000..166798098e --- /dev/null +++ b/thread/tests/integration/src/android/net/thread/utils/TestTunNetworkUtils.kt @@ -0,0 +1,93 @@ +/* + * Copyright (C) 2024 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.thread.utils + +import android.Manifest.permission.MANAGE_TEST_NETWORKS +import android.content.Context +import android.net.InetAddresses.parseNumericAddress +import android.net.IpPrefix +import android.net.LinkProperties +import android.net.MacAddress +import android.net.RouteInfo +import com.android.testutils.PollPacketReader +import com.android.testutils.TestNetworkTracker +import com.android.testutils.initTestNetwork +import com.android.testutils.runAsShell +import java.time.Duration + +object TestTunNetworkUtils { + private val networkTrackers = mutableListOf() + + @JvmStatic + @JvmOverloads + fun setUpInfraNetwork( + context: Context, + controller: ThreadNetworkControllerWrapper, + lp: LinkProperties = defaultLinkProperties(), + ): TestNetworkTracker { + val infraNetworkTracker: TestNetworkTracker = + runAsShell( + MANAGE_TEST_NETWORKS, + supplier = { initTestNetwork(context, lp, setupTimeoutMs = 5000) }, + ) + val infraNetworkName: String = infraNetworkTracker.testIface.getInterfaceName() + controller.setTestNetworkAsUpstreamAndWait(infraNetworkName) + networkTrackers.add(infraNetworkTracker) + + return infraNetworkTracker + } + + @JvmStatic + fun tearDownInfraNetwork(testNetworkTracker: TestNetworkTracker) { + runAsShell(MANAGE_TEST_NETWORKS) { testNetworkTracker.teardown() } + } + + @JvmStatic + fun tearDownAllInfraNetworks() { + networkTrackers.forEach { tearDownInfraNetwork(it) } + networkTrackers.clear() + } + + @JvmStatic + @JvmOverloads + fun startInfraDeviceAndWaitForOnLinkAddr( + pollPacketReader: PollPacketReader, + macAddress: MacAddress = MacAddress.fromString("1:2:3:4:5:6"), + ): InfraNetworkDevice { + val infraDevice = InfraNetworkDevice(macAddress, pollPacketReader) + infraDevice.runSlaac(Duration.ofSeconds(60)) + requireNotNull(infraDevice.ipv6Addr) + return infraDevice + } + + private fun defaultLinkProperties(): LinkProperties { + val lp = LinkProperties() + // TODO: use a fake DNS server + lp.setDnsServers(listOf(parseNumericAddress("8.8.8.8"))) + // NAT64 feature requires the infra network to have an IPv4 default route. + lp.addRoute( + RouteInfo( + IpPrefix("0.0.0.0/0") /* destination */, + null /* gateway */, + null /* iface */, + RouteInfo.RTN_UNICAST, + 1500, /* mtu */ + ) + ) + return lp + } +}