1
0
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:
Yuri Schimke
2020-01-02 07:04:58 +00:00
committed by GitHub
parent bb819709ec
commit 3e61ce3cf0
4 changed files with 68 additions and 23 deletions

View File

@@ -8,7 +8,7 @@ A gradle module for running Android instrumentation tests on a device or emulato
2. Turn on logs with logcat 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] 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 01-01 12:53:32.811 10999 11089 D OkHttp : [49 ms] responseBodyStart

View File

@@ -32,6 +32,7 @@ android {
dependencies { dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:${versions.kotlin}" implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:${versions.kotlin}"
implementation "org.jetbrains.kotlin:kotlin-reflect:${versions.kotlin}" implementation "org.jetbrains.kotlin:kotlin-reflect:${versions.kotlin}"
implementation 'com.google.android.gms:play-services-safetynet:17.0.0'
implementation project(':okhttp') implementation project(':okhttp')
testImplementation 'junit:junit:4.12' testImplementation 'junit:junit:4.12'
androidTestImplementation(project(':okhttp-testing-support')) { androidTestImplementation(project(':okhttp-testing-support')) {

View File

@@ -16,15 +16,18 @@
package okhttp.android.test package okhttp.android.test
import android.os.Build import android.os.Build
import android.support.test.InstrumentationRegistry
import android.support.test.runner.AndroidJUnit4 import android.support.test.runner.AndroidJUnit4
import com.squareup.moshi.Moshi import com.squareup.moshi.Moshi
import com.squareup.moshi.kotlin.reflect.KotlinJsonAdapterFactory import com.squareup.moshi.kotlin.reflect.KotlinJsonAdapterFactory
import com.google.android.gms.security.ProviderInstaller
import okhttp3.Call import okhttp3.Call
import okhttp3.CertificatePinner import okhttp3.CertificatePinner
import okhttp3.Connection import okhttp3.Connection
import okhttp3.EventListener import okhttp3.EventListener
import okhttp3.HttpUrl.Companion.toHttpUrl import okhttp3.HttpUrl.Companion.toHttpUrl
import okhttp3.OkHttpClient import okhttp3.OkHttpClient
import okhttp3.OkHttpClientTestRule
import okhttp3.Protocol import okhttp3.Protocol
import okhttp3.RecordingEventListener import okhttp3.RecordingEventListener
import okhttp3.Request import okhttp3.Request
@@ -35,6 +38,7 @@ import okhttp3.internal.platform.Platform
import okhttp3.logging.LoggingEventListener import okhttp3.logging.LoggingEventListener
import okhttp3.mockwebserver.MockResponse import okhttp3.mockwebserver.MockResponse
import okhttp3.mockwebserver.MockWebServer import okhttp3.mockwebserver.MockWebServer
import okhttp3.testing.PlatformRule
import okhttp3.tls.internal.TlsUtil.localhost import okhttp3.tls.internal.TlsUtil.localhost
import okio.ByteString.Companion.toByteString import okio.ByteString.Companion.toByteString
import org.conscrypt.Conscrypt import org.conscrypt.Conscrypt
@@ -56,6 +60,7 @@ import java.security.cert.X509Certificate
import java.security.Security import java.security.Security
import javax.net.ssl.SSLPeerUnverifiedException import javax.net.ssl.SSLPeerUnverifiedException
import javax.net.ssl.SSLSocket import javax.net.ssl.SSLSocket
import java.util.logging.Logger
import okhttp3.internal.platform.AndroidPlatform import okhttp3.internal.platform.AndroidPlatform
import okhttp3.internal.platform.Android10Platform import okhttp3.internal.platform.Android10Platform
@@ -64,7 +69,17 @@ import okhttp3.internal.platform.Android10Platform
*/ */
@RunWith(AndroidJUnit4::class) @RunWith(AndroidJUnit4::class)
class OkHttpTest { 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() private val moshi = Moshi.Builder()
.add(KotlinJsonAdapterFactory()) .add(KotlinJsonAdapterFactory())
@@ -75,16 +90,6 @@ class OkHttpTest {
val server = MockWebServer() val server = MockWebServer()
private val handshakeCertificates = localhost() private val handshakeCertificates = localhost()
@Before
fun createClient() {
client = OkHttpClient.Builder().build()
}
@After
fun cleanup() {
client.dispatcher.executorService.shutdownNow()
}
@Test @Test
fun testPlatform() { fun testPlatform() {
if (Build.VERSION.SDK_INT >= 29) { if (Build.VERSION.SDK_INT >= 29) {
@@ -118,17 +123,17 @@ class OkHttpTest {
var socketClass: String? = null 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) { override fun connectionAcquired(call: Call, connection: Connection) {
socketClass = connection.socket().javaClass.name socketClass = connection.socket().javaClass.name
} }
}).build() })).build()
val response = client.newCall(request).execute() val response = client.newCall(request).execute()
response.use { response.use {
assertEquals(Protocol.HTTP_2, response.protocol) assertEquals(Protocol.HTTP_2, response.protocol)
assertEquals(TlsVersion.TLS_1_3, response.handshake?.tlsVersion)
assertEquals(200, response.code) assertEquals(200, response.code)
// see https://github.com/google/conscrypt/blob/b9463b2f74df42d85c73715a5f19e005dfb7b802/android/src/main/java/org/conscrypt/Platform.java#L613 // see https://github.com/google/conscrypt/blob/b9463b2f74df42d85c73715a5f19e005dfb7b802/android/src/main/java/org/conscrypt/Platform.java#L613
if (Build.VERSION.SDK_INT >= 24) { if (Build.VERSION.SDK_INT >= 24) {
@@ -136,12 +141,44 @@ class OkHttpTest {
} else { } else {
assertEquals("org.conscrypt.ConscryptFileDescriptorSocket", socketClass) assertEquals("org.conscrypt.ConscryptFileDescriptorSocket", socketClass)
} }
assertEquals(TlsVersion.TLS_1_3, response.handshake?.tlsVersion)
} }
} finally { } finally {
Security.removeProvider("Conscrypt") 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 @Test
fun testRequestUsesAndroidConscrypt() { fun testRequestUsesAndroidConscrypt() {
assumeNetwork() assumeNetwork()
@@ -150,15 +187,15 @@ class OkHttpTest {
var socketClass: String? = null var socketClass: String? = null
val client2 = client.newBuilder() client = client.newBuilder()
.eventListener(object : EventListener() { .eventListenerFactory(clientTestRule.wrap(object : EventListener() {
override fun connectionAcquired(call: Call, connection: Connection) { override fun connectionAcquired(call: Call, connection: Connection) {
socketClass = connection.socket().javaClass.name socketClass = connection.socket().javaClass.name
} }
}) }))
.build() .build()
val response = client2.newCall(request).execute() val response = client.newCall(request).execute()
response.use { response.use {
assertEquals(Protocol.HTTP_2, response.protocol) assertEquals(Protocol.HTTP_2, response.protocol)
@@ -300,7 +337,7 @@ class OkHttpTest {
enableTls() enableTls()
client = client.newBuilder().eventListener(eventListener).build() client = client.newBuilder().eventListenerFactory(clientTestRule.wrap(eventListener)).build()
server.enqueue(MockResponse().setBody("abc1")) server.enqueue(MockResponse().setBody("abc1"))
server.enqueue(MockResponse().setBody("abc2")) server.enqueue(MockResponse().setBody("abc2"))
@@ -335,13 +372,13 @@ class OkHttpTest {
enableTls() enableTls()
client = client.newBuilder().eventListener(object : EventListener() { client = client.newBuilder().eventListenerFactory(clientTestRule.wrap(object : EventListener() {
override fun connectionAcquired(call: Call, connection: Connection) { override fun connectionAcquired(call: Call, connection: Connection) {
val sslSocket = connection.socket() as SSLSocket val sslSocket = connection.socket() as SSLSocket
sessionIds.add(sslSocket.session.id.toByteString().hex()) sessionIds.add(sslSocket.session.id.toByteString().hex())
} }
}).build() })).build()
server.enqueue(MockResponse().setBody("abc1")) server.enqueue(MockResponse().setBody("abc1"))
server.enqueue(MockResponse().setBody("abc2")) server.enqueue(MockResponse().setBody("abc2"))
@@ -368,7 +405,7 @@ class OkHttpTest {
assumeNetwork() assumeNetwork()
client = client.newBuilder() client = client.newBuilder()
.eventListenerFactory(LoggingEventListener.Factory()) .eventListenerFactory(clientTestRule.wrap(LoggingEventListener.Factory()))
.build() .build()
val dohDns = buildCloudflareIp(client) val dohDns = buildCloudflareIp(client)

View File

@@ -23,6 +23,7 @@ import org.junit.runner.Description
import org.junit.runners.model.Statement import org.junit.runners.model.Statement
import java.net.InetAddress import java.net.InetAddress
import java.util.concurrent.TimeUnit 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 * 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 val clientEventsList = mutableListOf<String>()
private var testClient: OkHttpClient? = null private var testClient: OkHttpClient? = null
private var uncaughtException: Throwable? = null private var uncaughtException: Throwable? = null
var logger: Logger? = null
fun wrap(eventListener: EventListener) = object : EventListener.Factory { fun wrap(eventListener: EventListener) = object : EventListener.Factory {
override fun create(call: Call) = ClientRuleEventListener(eventListener) { addEvent(it) } 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. * Returns an OkHttpClient for tests to use as a starting point.
* *
@@ -68,6 +74,7 @@ class OkHttpClientTestRule : TestRule {
} }
@Synchronized private fun addEvent(event: String) { @Synchronized private fun addEvent(event: String) {
logger?.info(event)
clientEventsList.add(event) clientEventsList.add(event)
} }