Merge changes Id92a2338,I38671aa2,Ic2df53f1 am: bebd8b0b54

Original change: https://android-review.googlesource.com/c/platform/packages/modules/Connectivity/+/2060055

Change-Id: I8b29f45bd828aa7e6a2548bce62e82b913815a3f
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
Patrick Rohr
2022-04-12 12:57:55 +00:00
committed by Automerger Merge Worker

View File

@@ -17,7 +17,9 @@ package android.net.cts
import android.Manifest.permission.MANAGE_TEST_NETWORKS import android.Manifest.permission.MANAGE_TEST_NETWORKS
import android.Manifest.permission.NETWORK_SETTINGS import android.Manifest.permission.NETWORK_SETTINGS
import android.net.InetAddresses
import android.net.IpConfiguration import android.net.IpConfiguration
import android.net.MacAddress
import android.net.TestNetworkInterface import android.net.TestNetworkInterface
import android.net.TestNetworkManager import android.net.TestNetworkManager
import android.platform.test.annotations.AppModeFull import android.platform.test.annotations.AppModeFull
@@ -32,6 +34,7 @@ import org.junit.After
import org.junit.Before import org.junit.Before
import org.junit.Rule import org.junit.Rule
import org.junit.Test import org.junit.Test
import android.content.Context
import org.junit.runner.RunWith import org.junit.runner.RunWith
import kotlin.test.assertNull import kotlin.test.assertNull
import kotlin.test.fail 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_CLIENT
import com.android.networkstack.apishim.common.EthernetManagerShim.ROLE_NONE import com.android.networkstack.apishim.common.EthernetManagerShim.ROLE_NONE
import com.android.networkstack.apishim.EthernetManagerShimImpl 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 java.util.concurrent.Executor
import kotlin.test.assertFalse import kotlin.test.assertFalse
import kotlin.test.assertEquals import kotlin.test.assertEquals
import kotlin.test.assertTrue import kotlin.test.assertTrue
import java.net.NetworkInterface
private const val TIMEOUT_MS = 1000L private const val TIMEOUT_MS = 1000L
private const val NO_CALLBACK_TIMEOUT_MS = 200L private const val NO_CALLBACK_TIMEOUT_MS = 200L
@@ -66,9 +74,40 @@ class EthernetManagerTest {
private val context by lazy { InstrumentationRegistry.getInstrumentation().context } private val context by lazy { InstrumentationRegistry.getInstrumentation().context }
private val em by lazy { EthernetManagerShimImpl.newInstance(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 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 open class EthernetStateListener private constructor(
private val history: ArrayTrackRecord<CallbackEntry> private val history: ArrayTrackRecord<CallbackEntry>
) : InterfaceStateListener, ) : InterfaceStateListener,
@@ -101,7 +140,7 @@ class EthernetManagerTest {
return event as T 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, expectCallback(InterfaceStateChanged(iface.interfaceName, state, role,
if (state != STATE_ABSENT) DEFAULT_IP_CONFIGURATION else null)) if (state != STATE_ABSENT) DEFAULT_IP_CONFIGURATION else null))
} }
@@ -116,23 +155,55 @@ class EthernetManagerTest {
} }
} }
@Before
fun setUp() {
setIncludeTestInterfaces(true)
}
@After
fun tearDown() {
setIncludeTestInterfaces(false)
for (iface in createdIfaces) {
iface.destroy()
}
for (listener in addedListeners) {
em.removeInterfaceStateListener(listener)
}
}
private fun addInterfaceStateListener(executor: Executor, listener: InterfaceStateListener) {
em.addInterfaceStateListener(executor, listener)
addedListeners.add(listener)
}
private fun createInterface(): EthernetTestInterface {
return EthernetTestInterface(context, Handler(Looper.getMainLooper()))
}
private fun setIncludeTestInterfaces(value: Boolean) {
runAsShell(NETWORK_SETTINGS) {
em.setIncludeTestInterfaces(value)
}
}
private fun removeInterface(iface: EthernetTestInterface) {
iface.destroy()
createdIfaces.remove(iface)
}
@Test @Test
public fun testCallbacks() { public fun testCallbacks() {
val executor = HandlerExecutor(Handler(Looper.getMainLooper())) val executor = HandlerExecutor(Handler(Looper.getMainLooper()))
// If an interface exists when the callback is registered, it is reported on registration. // If an interface exists when the callback is registered, it is reported on registration.
val iface = runAsShell(MANAGE_TEST_NETWORKS) { val iface = createInterface()
createInterface()
}
val listener = EthernetStateListener() val listener = EthernetStateListener()
addInterfaceStateListener(executor, listener) addInterfaceStateListener(executor, listener)
listener.expectCallback(iface, STATE_LINK_UP, ROLE_CLIENT) listener.expectCallback(iface, STATE_LINK_UP, ROLE_CLIENT)
// If an interface appears, existing callbacks see it. // If an interface appears, existing callbacks see it.
// TODO: fix the up/up/down/up callbacks and only send down/up. // TODO: fix the up/up/down/up callbacks and only send down/up.
val iface2 = runAsShell(MANAGE_TEST_NETWORKS) { val iface2 = createInterface()
createInterface()
}
listener.expectCallback(iface2, STATE_LINK_UP, ROLE_CLIENT) listener.expectCallback(iface2, STATE_LINK_UP, ROLE_CLIENT)
listener.expectCallback(iface2, STATE_LINK_UP, ROLE_CLIENT) listener.expectCallback(iface2, STATE_LINK_UP, ROLE_CLIENT)
listener.expectCallback(iface2, STATE_LINK_DOWN, ROLE_CLIENT) listener.expectCallback(iface2, STATE_LINK_DOWN, ROLE_CLIENT)
@@ -149,66 +220,25 @@ class EthernetManagerTest {
listener.assertNoCallback() listener.assertNoCallback()
} }
@Before @Test
fun setUp() { public fun testGetInterfaceList() {
runAsShell(MANAGE_TEST_NETWORKS, NETWORK_SETTINGS) { setIncludeTestInterfaces(true)
em.setIncludeTestInterfaces(true)
}
}
@After
fun tearDown() {
runAsShell(MANAGE_TEST_NETWORKS, NETWORK_SETTINGS) {
em.setIncludeTestInterfaces(false)
for (iface in createdIfaces) {
if (iface.fileDescriptor.fileDescriptor.valid()) iface.fileDescriptor.close()
}
for (listener in addedListeners) {
em.removeInterfaceStateListener(listener)
}
}
}
private fun addInterfaceStateListener(executor: Executor, listener: InterfaceStateListener) {
em.addInterfaceStateListener(executor, listener)
addedListeners.add(listener)
}
private fun createInterface(): TestNetworkInterface {
val tnm = context.getSystemService(TestNetworkManager::class.java)
return tnm.createTapInterface(false /* bringUp */).also { createdIfaces.add(it) }
}
private fun removeInterface(iface: TestNetworkInterface) {
iface.fileDescriptor.close()
createdIfaces.remove(iface)
}
private fun doTestGetInterfaceList() {
em.setIncludeTestInterfaces(true)
// Create two test interfaces and check the return list contains the interface names. // Create two test interfaces and check the return list contains the interface names.
val iface1 = createInterface() val iface1 = createInterface()
val iface2 = createInterface() val iface2 = createInterface()
var ifaces = em.getInterfaceList() var ifaces = em.getInterfaceList()
assertTrue(ifaces.size > 0) assertTrue(ifaces.size > 0)
assertTrue(ifaces.contains(iface1.getInterfaceName())) assertTrue(ifaces.contains(iface1.interfaceName))
assertTrue(ifaces.contains(iface2.getInterfaceName())) assertTrue(ifaces.contains(iface2.interfaceName))
// Remove one existing test interface and check the return list doesn't contain the // Remove one existing test interface and check the return list doesn't contain the
// removed interface name. // removed interface name.
removeInterface(iface1) removeInterface(iface1)
ifaces = em.getInterfaceList() ifaces = em.getInterfaceList()
assertFalse(ifaces.contains(iface1.getInterfaceName())) assertFalse(ifaces.contains(iface1.interfaceName))
assertTrue(ifaces.contains(iface2.getInterfaceName())) assertTrue(ifaces.contains(iface2.interfaceName))
removeInterface(iface2) removeInterface(iface2)
} }
@Test
public fun testGetInterfaceList() {
runAsShell(MANAGE_TEST_NETWORKS, NETWORK_SETTINGS) {
doTestGetInterfaceList()
}
}
} }