mirror of
https://github.com/square/okhttp.git
synced 2025-11-26 06:43:09 +03:00
Test Android with Play provider (#5679)
This commit is contained in:
@@ -8,7 +8,7 @@ A gradle module for running Android instrumentation tests on a device or emulato
|
||||
2. Turn on logs with logcat
|
||||
|
||||
```
|
||||
$ adb logcat '*:E' OkHttp:D Http2:D TestRunner:D TaskRunner:D
|
||||
$ adb logcat '*:E' OkHttp:D Http2:D TestRunner:D TaskRunner:D OkHttpTest:D GnssHAL_GnssInterface:F DeviceStateChecker:F memtrack:F
|
||||
...
|
||||
01-01 12:53:32.811 10999 11089 D OkHttp : [49 ms] responseHeadersEnd: Response{protocol=h2, code=200, message=, url=https://1.1.1.1/dns-query?dns=AAABAAABAAAAAAAAA3d3dwhmYWNlYm9vawNjb20AABwAAQ}
|
||||
01-01 12:53:32.811 10999 11089 D OkHttp : [49 ms] responseBodyStart
|
||||
|
||||
@@ -32,6 +32,7 @@ android {
|
||||
dependencies {
|
||||
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:${versions.kotlin}"
|
||||
implementation "org.jetbrains.kotlin:kotlin-reflect:${versions.kotlin}"
|
||||
implementation 'com.google.android.gms:play-services-safetynet:17.0.0'
|
||||
implementation project(':okhttp')
|
||||
testImplementation 'junit:junit:4.12'
|
||||
androidTestImplementation(project(':okhttp-testing-support')) {
|
||||
|
||||
@@ -16,15 +16,18 @@
|
||||
package okhttp.android.test
|
||||
|
||||
import android.os.Build
|
||||
import android.support.test.InstrumentationRegistry
|
||||
import android.support.test.runner.AndroidJUnit4
|
||||
import com.squareup.moshi.Moshi
|
||||
import com.squareup.moshi.kotlin.reflect.KotlinJsonAdapterFactory
|
||||
import com.google.android.gms.security.ProviderInstaller
|
||||
import okhttp3.Call
|
||||
import okhttp3.CertificatePinner
|
||||
import okhttp3.Connection
|
||||
import okhttp3.EventListener
|
||||
import okhttp3.HttpUrl.Companion.toHttpUrl
|
||||
import okhttp3.OkHttpClient
|
||||
import okhttp3.OkHttpClientTestRule
|
||||
import okhttp3.Protocol
|
||||
import okhttp3.RecordingEventListener
|
||||
import okhttp3.Request
|
||||
@@ -35,6 +38,7 @@ import okhttp3.internal.platform.Platform
|
||||
import okhttp3.logging.LoggingEventListener
|
||||
import okhttp3.mockwebserver.MockResponse
|
||||
import okhttp3.mockwebserver.MockWebServer
|
||||
import okhttp3.testing.PlatformRule
|
||||
import okhttp3.tls.internal.TlsUtil.localhost
|
||||
import okio.ByteString.Companion.toByteString
|
||||
import org.conscrypt.Conscrypt
|
||||
@@ -56,6 +60,7 @@ import java.security.cert.X509Certificate
|
||||
import java.security.Security
|
||||
import javax.net.ssl.SSLPeerUnverifiedException
|
||||
import javax.net.ssl.SSLSocket
|
||||
import java.util.logging.Logger
|
||||
import okhttp3.internal.platform.AndroidPlatform
|
||||
import okhttp3.internal.platform.Android10Platform
|
||||
|
||||
@@ -64,7 +69,17 @@ import okhttp3.internal.platform.Android10Platform
|
||||
*/
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
class OkHttpTest {
|
||||
private lateinit var client: OkHttpClient
|
||||
@Suppress("RedundantVisibilityModifier")
|
||||
@JvmField
|
||||
@Rule public val platform = PlatformRule()
|
||||
|
||||
@Suppress("RedundantVisibilityModifier")
|
||||
@JvmField
|
||||
@Rule public val clientTestRule = OkHttpClientTestRule().apply {
|
||||
logger = Logger.getLogger(OkHttpTest::class.java.name)
|
||||
}
|
||||
|
||||
private var client = clientTestRule.newClient()
|
||||
|
||||
private val moshi = Moshi.Builder()
|
||||
.add(KotlinJsonAdapterFactory())
|
||||
@@ -75,16 +90,6 @@ class OkHttpTest {
|
||||
val server = MockWebServer()
|
||||
private val handshakeCertificates = localhost()
|
||||
|
||||
@Before
|
||||
fun createClient() {
|
||||
client = OkHttpClient.Builder().build()
|
||||
}
|
||||
|
||||
@After
|
||||
fun cleanup() {
|
||||
client.dispatcher.executorService.shutdownNow()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testPlatform() {
|
||||
if (Build.VERSION.SDK_INT >= 29) {
|
||||
@@ -118,17 +123,17 @@ class OkHttpTest {
|
||||
|
||||
var socketClass: String? = null
|
||||
|
||||
client = OkHttpClient.Builder().eventListener(object : EventListener() {
|
||||
// Need fresh client to reset sslSocketFactoryOrNull
|
||||
client = OkHttpClient.Builder().eventListenerFactory(clientTestRule.wrap(object : EventListener() {
|
||||
override fun connectionAcquired(call: Call, connection: Connection) {
|
||||
socketClass = connection.socket().javaClass.name
|
||||
}
|
||||
}).build()
|
||||
})).build()
|
||||
|
||||
val response = client.newCall(request).execute()
|
||||
|
||||
response.use {
|
||||
assertEquals(Protocol.HTTP_2, response.protocol)
|
||||
assertEquals(TlsVersion.TLS_1_3, response.handshake?.tlsVersion)
|
||||
assertEquals(200, response.code)
|
||||
// see https://github.com/google/conscrypt/blob/b9463b2f74df42d85c73715a5f19e005dfb7b802/android/src/main/java/org/conscrypt/Platform.java#L613
|
||||
if (Build.VERSION.SDK_INT >= 24) {
|
||||
@@ -136,12 +141,44 @@ class OkHttpTest {
|
||||
} else {
|
||||
assertEquals("org.conscrypt.ConscryptFileDescriptorSocket", socketClass)
|
||||
}
|
||||
assertEquals(TlsVersion.TLS_1_3, response.handshake?.tlsVersion)
|
||||
}
|
||||
} finally {
|
||||
Security.removeProvider("Conscrypt")
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testRequestUsesPlayProvider() {
|
||||
assumeNetwork()
|
||||
|
||||
try {
|
||||
ProviderInstaller.installIfNeeded(InstrumentationRegistry.getTargetContext())
|
||||
|
||||
val request = Request.Builder().url("https://facebook.com/robots.txt").build()
|
||||
|
||||
var socketClass: String? = null
|
||||
|
||||
// Need fresh client to reset sslSocketFactoryOrNull
|
||||
client = OkHttpClient.Builder().eventListenerFactory(clientTestRule.wrap(object : EventListener() {
|
||||
override fun connectionAcquired(call: Call, connection: Connection) {
|
||||
socketClass = connection.socket().javaClass.name
|
||||
}
|
||||
})).build()
|
||||
|
||||
val response = client.newCall(request).execute()
|
||||
|
||||
response.use {
|
||||
assertEquals(Protocol.HTTP_2, response.protocol)
|
||||
assertEquals(200, response.code)
|
||||
assertEquals("com.google.android.gms.org.conscrypt.Java8FileDescriptorSocket", socketClass)
|
||||
assertEquals(TlsVersion.TLS_1_2, response.handshake?.tlsVersion)
|
||||
}
|
||||
} finally {
|
||||
Security.removeProvider("GmsCore_OpenSSL")
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testRequestUsesAndroidConscrypt() {
|
||||
assumeNetwork()
|
||||
@@ -150,15 +187,15 @@ class OkHttpTest {
|
||||
|
||||
var socketClass: String? = null
|
||||
|
||||
val client2 = client.newBuilder()
|
||||
.eventListener(object : EventListener() {
|
||||
client = client.newBuilder()
|
||||
.eventListenerFactory(clientTestRule.wrap(object : EventListener() {
|
||||
override fun connectionAcquired(call: Call, connection: Connection) {
|
||||
socketClass = connection.socket().javaClass.name
|
||||
}
|
||||
})
|
||||
}))
|
||||
.build()
|
||||
|
||||
val response = client2.newCall(request).execute()
|
||||
val response = client.newCall(request).execute()
|
||||
|
||||
response.use {
|
||||
assertEquals(Protocol.HTTP_2, response.protocol)
|
||||
@@ -300,7 +337,7 @@ class OkHttpTest {
|
||||
|
||||
enableTls()
|
||||
|
||||
client = client.newBuilder().eventListener(eventListener).build()
|
||||
client = client.newBuilder().eventListenerFactory(clientTestRule.wrap(eventListener)).build()
|
||||
|
||||
server.enqueue(MockResponse().setBody("abc1"))
|
||||
server.enqueue(MockResponse().setBody("abc2"))
|
||||
@@ -335,13 +372,13 @@ class OkHttpTest {
|
||||
|
||||
enableTls()
|
||||
|
||||
client = client.newBuilder().eventListener(object : EventListener() {
|
||||
client = client.newBuilder().eventListenerFactory(clientTestRule.wrap(object : EventListener() {
|
||||
override fun connectionAcquired(call: Call, connection: Connection) {
|
||||
val sslSocket = connection.socket() as SSLSocket
|
||||
|
||||
sessionIds.add(sslSocket.session.id.toByteString().hex())
|
||||
}
|
||||
}).build()
|
||||
})).build()
|
||||
|
||||
server.enqueue(MockResponse().setBody("abc1"))
|
||||
server.enqueue(MockResponse().setBody("abc2"))
|
||||
@@ -368,7 +405,7 @@ class OkHttpTest {
|
||||
assumeNetwork()
|
||||
|
||||
client = client.newBuilder()
|
||||
.eventListenerFactory(LoggingEventListener.Factory())
|
||||
.eventListenerFactory(clientTestRule.wrap(LoggingEventListener.Factory()))
|
||||
.build()
|
||||
|
||||
val dohDns = buildCloudflareIp(client)
|
||||
|
||||
@@ -23,6 +23,7 @@ import org.junit.runner.Description
|
||||
import org.junit.runners.model.Statement
|
||||
import java.net.InetAddress
|
||||
import java.util.concurrent.TimeUnit
|
||||
import java.util.logging.Logger
|
||||
|
||||
/**
|
||||
* Apply this rule to all tests. It adds additional checks for leaked resources and uncaught
|
||||
@@ -35,11 +36,16 @@ class OkHttpClientTestRule : TestRule {
|
||||
private val clientEventsList = mutableListOf<String>()
|
||||
private var testClient: OkHttpClient? = null
|
||||
private var uncaughtException: Throwable? = null
|
||||
var logger: Logger? = null
|
||||
|
||||
fun wrap(eventListener: EventListener) = object : EventListener.Factory {
|
||||
override fun create(call: Call) = ClientRuleEventListener(eventListener) { addEvent(it) }
|
||||
}
|
||||
|
||||
fun wrap(eventListenerFactory: EventListener.Factory) = object : EventListener.Factory {
|
||||
override fun create(call: Call) = ClientRuleEventListener(eventListenerFactory.create(call)) { addEvent(it) }
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an OkHttpClient for tests to use as a starting point.
|
||||
*
|
||||
@@ -68,6 +74,7 @@ class OkHttpClientTestRule : TestRule {
|
||||
}
|
||||
|
||||
@Synchronized private fun addEvent(event: String) {
|
||||
logger?.info(event)
|
||||
clientEventsList.add(event)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user