Merge "Check that wifi, cell validates before tests" into main

This commit is contained in:
Treehugger Robot
2023-09-19 10:20:38 +00:00
committed by Gerrit Code Review
2 changed files with 54 additions and 34 deletions

View File

@@ -18,17 +18,10 @@ package com.android.testutils.connectivitypreparer
import android.content.pm.PackageManager.FEATURE_TELEPHONY import android.content.pm.PackageManager.FEATURE_TELEPHONY
import android.content.pm.PackageManager.FEATURE_WIFI import android.content.pm.PackageManager.FEATURE_WIFI
import android.net.ConnectivityManager
import android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET
import android.net.NetworkCapabilities.TRANSPORT_CELLULAR
import android.net.NetworkRequest
import android.telephony.TelephonyManager import android.telephony.TelephonyManager
import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.platform.app.InstrumentationRegistry import androidx.test.platform.app.InstrumentationRegistry
import com.android.testutils.ConnectUtil import com.android.testutils.ConnectUtil
import com.android.testutils.RecorderCallback
import com.android.testutils.TestableNetworkCallback
import com.android.testutils.tryTest
import kotlin.test.assertTrue import kotlin.test.assertTrue
import kotlin.test.fail import kotlin.test.fail
import org.junit.Test import org.junit.Test
@@ -36,8 +29,9 @@ import org.junit.runner.RunWith
@RunWith(AndroidJUnit4::class) @RunWith(AndroidJUnit4::class)
class ConnectivityCheckTest { class ConnectivityCheckTest {
val context by lazy { InstrumentationRegistry.getInstrumentation().context } private val context by lazy { InstrumentationRegistry.getInstrumentation().context }
val pm by lazy { context.packageManager } private val pm by lazy { context.packageManager }
private val connectUtil by lazy { ConnectUtil(context) }
@Test @Test
fun testCheckConnectivity() { fun testCheckConnectivity() {
@@ -47,7 +41,7 @@ class ConnectivityCheckTest {
private fun checkWifiSetup() { private fun checkWifiSetup() {
if (!pm.hasSystemFeature(FEATURE_WIFI)) return if (!pm.hasSystemFeature(FEATURE_WIFI)) return
ConnectUtil(context).ensureWifiConnected() connectUtil.ensureWifiValidated()
} }
private fun checkTelephonySetup() { private fun checkTelephonySetup() {
@@ -69,20 +63,6 @@ class ConnectivityCheckTest {
assertTrue(tm.isDataConnectivityPossible, assertTrue(tm.isDataConnectivityPossible,
"The device is not setup with a SIM card that supports data connectivity. " + "The device is not setup with a SIM card that supports data connectivity. " +
commonError) commonError)
val cb = TestableNetworkCallback() connectUtil.ensureCellularValidated()
val cm = context.getSystemService(ConnectivityManager::class.java)
?: fail("Could not get ConnectivityManager")
cm.requestNetwork(
NetworkRequest.Builder()
.addTransportType(TRANSPORT_CELLULAR)
.addCapability(NET_CAPABILITY_INTERNET).build(), cb)
tryTest {
cb.poll { it is RecorderCallback.CallbackEntry.Available }
?: fail("The device does not have mobile data available. Check that it is " +
"setup with a SIM card that has a working data plan, and that the " +
"APN configuration is valid.")
} cleanup {
cm.unregisterNetworkCallback(cb)
}
} }
} }

View File

@@ -23,6 +23,9 @@ import android.content.Intent
import android.content.IntentFilter import android.content.IntentFilter
import android.net.ConnectivityManager import android.net.ConnectivityManager
import android.net.Network import android.net.Network
import android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET
import android.net.NetworkCapabilities.NET_CAPABILITY_VALIDATED
import android.net.NetworkCapabilities.TRANSPORT_CELLULAR
import android.net.NetworkCapabilities.TRANSPORT_WIFI import android.net.NetworkCapabilities.TRANSPORT_WIFI
import android.net.NetworkRequest import android.net.NetworkRequest
import android.net.wifi.ScanResult import android.net.wifi.ScanResult
@@ -33,6 +36,7 @@ import android.os.SystemClock
import android.util.Log import android.util.Log
import androidx.test.platform.app.InstrumentationRegistry.getInstrumentation import androidx.test.platform.app.InstrumentationRegistry.getInstrumentation
import com.android.testutils.RecorderCallback.CallbackEntry import com.android.testutils.RecorderCallback.CallbackEntry
import com.android.testutils.RecorderCallback.CallbackEntry.CapabilitiesChanged
import java.util.concurrent.CompletableFuture import java.util.concurrent.CompletableFuture
import java.util.concurrent.TimeUnit import java.util.concurrent.TimeUnit
import kotlin.test.assertNotNull import kotlin.test.assertNotNull
@@ -56,13 +60,35 @@ class ConnectUtil(private val context: Context) {
private val wifiManager = context.getSystemService(WifiManager::class.java) private val wifiManager = context.getSystemService(WifiManager::class.java)
?: fail("Could not find WifiManager") ?: fail("Could not find WifiManager")
fun ensureWifiConnected(): Network { fun ensureWifiConnected(): Network = ensureWifiConnected(requireValidated = false)
val callback = TestableNetworkCallback() fun ensureWifiValidated(): Network = ensureWifiConnected(requireValidated = true)
fun ensureCellularValidated(): Network {
val cb = TestableNetworkCallback()
cm.requestNetwork(
NetworkRequest.Builder()
.addTransportType(TRANSPORT_CELLULAR)
.addCapability(NET_CAPABILITY_INTERNET).build(), cb)
return tryTest {
val errorMsg = "The device does not have mobile data available. Check that it is " +
"setup with a SIM card that has a working data plan, that the APN " +
"configuration is valid, and that the device can access the internet through " +
"mobile data."
cb.eventuallyExpect<CapabilitiesChanged>(errorMsg) {
it.caps.hasCapability(NET_CAPABILITY_VALIDATED)
}.network
} cleanup {
cm.unregisterNetworkCallback(cb)
}
}
private fun ensureWifiConnected(requireValidated: Boolean): Network {
val callback = TestableNetworkCallback(timeoutMs = WIFI_CONNECT_TIMEOUT_MS)
cm.registerNetworkCallback(NetworkRequest.Builder() cm.registerNetworkCallback(NetworkRequest.Builder()
.addTransportType(TRANSPORT_WIFI) .addTransportType(TRANSPORT_WIFI)
.build(), callback) .build(), callback)
try { return tryTest {
val connInfo = wifiManager.connectionInfo val connInfo = wifiManager.connectionInfo
Log.d(TAG, "connInfo=" + connInfo) Log.d(TAG, "connInfo=" + connInfo)
if (connInfo == null || connInfo.networkId == -1) { if (connInfo == null || connInfo.networkId == -1) {
@@ -73,12 +99,19 @@ class ConnectUtil(private val context: Context) {
val config = getOrCreateWifiConfiguration() val config = getOrCreateWifiConfiguration()
connectToWifiConfig(config) connectToWifiConfig(config)
} }
val cb = callback.poll(WIFI_CONNECT_TIMEOUT_MS) { it is CallbackEntry.Available } val errorMsg = if (requireValidated) {
assertNotNull(cb, "Could not connect to a wifi access point within " + "The wifi access point did not have access to the internet after " +
"$WIFI_CONNECT_TIMEOUT_MS ms. Check that the test device has a wifi network " + "$WIFI_CONNECT_TIMEOUT_MS ms. Check that it has a working connection."
"configured, and that the test access point is functioning properly.") } else {
return cb.network "Could not connect to a wifi access point within $WIFI_CONNECT_TIMEOUT_MS ms. " +
} finally { "Check that the test device has a wifi network configured, and that the " +
"test access point is functioning properly."
}
val cb = callback.eventuallyExpect<CapabilitiesChanged>(errorMsg) {
(!requireValidated || it.caps.hasCapability(NET_CAPABILITY_VALIDATED))
}
cb.network
} cleanup {
cm.unregisterNetworkCallback(callback) cm.unregisterNetworkCallback(callback)
} }
} }
@@ -201,3 +234,10 @@ class ConnectUtil(private val context: Context) {
} }
} }
} }
private inline fun <reified T : CallbackEntry> TestableNetworkCallback.eventuallyExpect(
errorMsg: String,
crossinline predicate: (T) -> Boolean = { true }
): T = history.poll(defaultTimeoutMs, mark) { it is T && predicate(it) }.also {
assertNotNull(it, errorMsg)
} as T