Add support for creating multiple ifaces with RA responders
The RA responder is needed in order to properly provision interfaces in the ethernet tests. This CL wraps the tap interface creation and destruction inside a small helper class. Test: atest CtsNetTestCases:EthernetManagerTest Change-Id: Id92a233873f2f8a738ca563f507a2ead4478aebc
This commit is contained in:
parent
03d18df93d
commit
dcfe1937d9
1 changed files with 50 additions and 14 deletions
|
|
@ -17,7 +17,9 @@ package android.net.cts
|
|||
|
||||
import android.Manifest.permission.MANAGE_TEST_NETWORKS
|
||||
import android.Manifest.permission.NETWORK_SETTINGS
|
||||
import android.net.InetAddresses
|
||||
import android.net.IpConfiguration
|
||||
import android.net.MacAddress
|
||||
import android.net.TestNetworkInterface
|
||||
import android.net.TestNetworkManager
|
||||
import android.platform.test.annotations.AppModeFull
|
||||
|
|
@ -32,6 +34,7 @@ import org.junit.After
|
|||
import org.junit.Before
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import android.content.Context
|
||||
import org.junit.runner.RunWith
|
||||
import kotlin.test.assertNull
|
||||
import kotlin.test.fail
|
||||
|
|
@ -46,10 +49,15 @@ import com.android.networkstack.apishim.common.EthernetManagerShim.STATE_LINK_UP
|
|||
import com.android.networkstack.apishim.common.EthernetManagerShim.ROLE_CLIENT
|
||||
import com.android.networkstack.apishim.common.EthernetManagerShim.ROLE_NONE
|
||||
import com.android.networkstack.apishim.EthernetManagerShimImpl
|
||||
import com.android.testutils.RouterAdvertisementResponder
|
||||
import com.android.testutils.TapPacketReader
|
||||
import com.android.testutils.waitForIdle
|
||||
import java.net.Inet6Address
|
||||
import java.util.concurrent.Executor
|
||||
import kotlin.test.assertFalse
|
||||
import kotlin.test.assertEquals
|
||||
import kotlin.test.assertTrue
|
||||
import java.net.NetworkInterface
|
||||
|
||||
private const val TIMEOUT_MS = 1000L
|
||||
private const val NO_CALLBACK_TIMEOUT_MS = 200L
|
||||
|
|
@ -66,9 +74,40 @@ class EthernetManagerTest {
|
|||
private val context by lazy { InstrumentationRegistry.getInstrumentation().context }
|
||||
private val em by lazy { EthernetManagerShimImpl.newInstance(context) }
|
||||
|
||||
private val createdIfaces = ArrayList<TestNetworkInterface>()
|
||||
private val createdIfaces = ArrayList<EthernetTestInterface>()
|
||||
private val addedListeners = ArrayList<InterfaceStateListener>()
|
||||
|
||||
private class EthernetTestInterface(
|
||||
context: Context,
|
||||
private val handler: Handler
|
||||
) {
|
||||
private val tapInterface: TestNetworkInterface
|
||||
private val packetReader: TapPacketReader
|
||||
private val raResponder: RouterAdvertisementResponder
|
||||
val interfaceName get() = tapInterface.interfaceName
|
||||
|
||||
init {
|
||||
tapInterface = runAsShell(MANAGE_TEST_NETWORKS) {
|
||||
val tnm = context.getSystemService(TestNetworkManager::class.java)
|
||||
tnm.createTapInterface(false /* bringUp */)
|
||||
}
|
||||
val mtu = NetworkInterface.getByName(tapInterface.interfaceName).getMTU()
|
||||
packetReader = TapPacketReader(handler, tapInterface.fileDescriptor.fileDescriptor, mtu)
|
||||
raResponder = RouterAdvertisementResponder(packetReader)
|
||||
raResponder.addRouterEntry(MacAddress.fromString("01:23:45:67:89:ab"),
|
||||
InetAddresses.parseNumericAddress("fe80::abcd") as Inet6Address)
|
||||
|
||||
packetReader.startAsyncForTest()
|
||||
raResponder.start()
|
||||
}
|
||||
|
||||
fun destroy() {
|
||||
raResponder.stop()
|
||||
handler.post({ packetReader.stop() })
|
||||
handler.waitForIdle(TIMEOUT_MS)
|
||||
}
|
||||
}
|
||||
|
||||
private open class EthernetStateListener private constructor(
|
||||
private val history: ArrayTrackRecord<CallbackEntry>
|
||||
) : InterfaceStateListener,
|
||||
|
|
@ -101,7 +140,7 @@ class EthernetManagerTest {
|
|||
return event as T
|
||||
}
|
||||
|
||||
fun expectCallback(iface: TestNetworkInterface, state: Int, role: Int) {
|
||||
fun expectCallback(iface: EthernetTestInterface, state: Int, role: Int) {
|
||||
expectCallback(InterfaceStateChanged(iface.interfaceName, state, role,
|
||||
if (state != STATE_ABSENT) DEFAULT_IP_CONFIGURATION else null))
|
||||
}
|
||||
|
|
@ -125,7 +164,7 @@ class EthernetManagerTest {
|
|||
fun tearDown() {
|
||||
setIncludeTestInterfaces(false)
|
||||
for (iface in createdIfaces) {
|
||||
if (iface.fileDescriptor.fileDescriptor.valid()) iface.fileDescriptor.close()
|
||||
iface.destroy()
|
||||
}
|
||||
for (listener in addedListeners) {
|
||||
em.removeInterfaceStateListener(listener)
|
||||
|
|
@ -137,11 +176,8 @@ class EthernetManagerTest {
|
|||
addedListeners.add(listener)
|
||||
}
|
||||
|
||||
private fun createInterface(): TestNetworkInterface {
|
||||
return runAsShell(MANAGE_TEST_NETWORKS) {
|
||||
val tnm = context.getSystemService(TestNetworkManager::class.java)
|
||||
tnm.createTapInterface(false /* bringUp */).also { createdIfaces.add(it) }
|
||||
}
|
||||
private fun createInterface(): EthernetTestInterface {
|
||||
return EthernetTestInterface(context, Handler(Looper.getMainLooper()))
|
||||
}
|
||||
|
||||
private fun setIncludeTestInterfaces(value: Boolean) {
|
||||
|
|
@ -150,8 +186,8 @@ class EthernetManagerTest {
|
|||
}
|
||||
}
|
||||
|
||||
private fun removeInterface(iface: TestNetworkInterface) {
|
||||
iface.fileDescriptor.close()
|
||||
private fun removeInterface(iface: EthernetTestInterface) {
|
||||
iface.destroy()
|
||||
createdIfaces.remove(iface)
|
||||
}
|
||||
|
||||
|
|
@ -193,15 +229,15 @@ class EthernetManagerTest {
|
|||
val iface2 = createInterface()
|
||||
var ifaces = em.getInterfaceList()
|
||||
assertTrue(ifaces.size > 0)
|
||||
assertTrue(ifaces.contains(iface1.getInterfaceName()))
|
||||
assertTrue(ifaces.contains(iface2.getInterfaceName()))
|
||||
assertTrue(ifaces.contains(iface1.interfaceName))
|
||||
assertTrue(ifaces.contains(iface2.interfaceName))
|
||||
|
||||
// Remove one existing test interface and check the return list doesn't contain the
|
||||
// removed interface name.
|
||||
removeInterface(iface1)
|
||||
ifaces = em.getInterfaceList()
|
||||
assertFalse(ifaces.contains(iface1.getInterfaceName()))
|
||||
assertTrue(ifaces.contains(iface2.getInterfaceName()))
|
||||
assertFalse(ifaces.contains(iface1.interfaceName))
|
||||
assertTrue(ifaces.contains(iface2.interfaceName))
|
||||
|
||||
removeInterface(iface2)
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue