Skip to content

Commit

Permalink
KTOR-5332 Fixes iOS unit test deadlock occurring with DarwinClientEng…
Browse files Browse the repository at this point in the history
…ine (#3291)
  • Loading branch information
adamsousa committed Dec 14, 2022
1 parent cfa15db commit 28308e7
Show file tree
Hide file tree
Showing 6 changed files with 28 additions and 22 deletions.
Expand Up @@ -16,7 +16,7 @@ import platform.Foundation.*
internal class DarwinLegacyClientEngine(
override val config: DarwinLegacyClientEngineConfig
) : HttpClientEngineBase("ktor-darwin-legacy") {
private val requestQueue = NSOperationQueue()
private val requestQueue: NSOperationQueue? = NSOperationQueue.currentQueue()

override val dispatcher = Dispatchers.Unconfined

Expand Down
Expand Up @@ -13,7 +13,7 @@ import kotlin.coroutines.*
@OptIn(UnsafeNumber::class)
internal class DarwinLegacySession(
private val config: DarwinLegacyClientEngineConfig,
private val requestQueue: NSOperationQueue
private val requestQueue: NSOperationQueue?
) : Closeable {
private val closed = atomic(false)

Expand Down Expand Up @@ -47,7 +47,7 @@ internal class DarwinLegacySession(
@OptIn(UnsafeNumber::class)
internal fun createSession(
config: DarwinLegacyClientEngineConfig,
requestQueue: NSOperationQueue
requestQueue: NSOperationQueue?
): Pair<NSURLSession, KtorLegacyNSURLSessionDelegate> {
val configuration = NSURLSessionConfiguration.defaultSessionConfiguration().apply {
setupProxy(config)
Expand Down
Expand Up @@ -8,6 +8,7 @@ import io.ktor.http.*
import kotlinx.coroutines.*
import platform.Foundation.*
import platform.Foundation.NSHTTPCookieStorage.Companion.sharedHTTPCookieStorage
import kotlin.coroutines.CoroutineContext
import kotlin.test.*

/*
Expand All @@ -16,8 +17,10 @@ import kotlin.test.*

class DarwinLegacyEngineTest {

val testCoroutineContext: CoroutineContext = Dispatchers.Default

@Test
fun testRequestInRunBlocking() = runBlocking {
fun testRequestInRunBlocking() = runBlocking(testCoroutineContext) {
val client = HttpClient(DarwinLegacy)

try {
Expand All @@ -31,7 +34,7 @@ class DarwinLegacyEngineTest {
}

@Test
fun testQueryWithCyrillic() = runBlocking {
fun testQueryWithCyrillic() = runBlocking(testCoroutineContext) {
val client = HttpClient(DarwinLegacy)

try {
Expand All @@ -45,7 +48,7 @@ class DarwinLegacyEngineTest {
}

@Test
fun testQueryWithMultipleParams() = runBlocking {
fun testQueryWithMultipleParams() = runBlocking(testCoroutineContext) {
val client = HttpClient(DarwinLegacy)

try {
Expand All @@ -72,7 +75,7 @@ class DarwinLegacyEngineTest {
}

@Test
fun testCookieIsNotPersistedByDefault() = runBlocking {
fun testCookieIsNotPersistedByDefault() = runBlocking(testCoroutineContext) {
val client = HttpClient(DarwinLegacy)
try {
client.get("$TEST_SERVER/cookies")
Expand All @@ -86,7 +89,7 @@ class DarwinLegacyEngineTest {
}

@Test
fun testCookiePersistedWithSessionStore() = runBlocking {
fun testCookiePersistedWithSessionStore() = runBlocking(testCoroutineContext) {
val client = HttpClient(DarwinLegacy) {
engine {
configureSession {
Expand All @@ -107,7 +110,7 @@ class DarwinLegacyEngineTest {
}

@Test
fun testOverrideDefaultSession(): Unit = runBlocking {
fun testOverrideDefaultSession(): Unit = runBlocking(testCoroutineContext) {
val client = HttpClient(DarwinLegacy) {
val delegate = KtorLegacyNSURLSessionDelegate()
val session = NSURLSession.sessionWithConfiguration(
Expand All @@ -129,7 +132,7 @@ class DarwinLegacyEngineTest {
}

@Test
fun testConfigureRequest(): Unit = runBlocking {
fun testConfigureRequest(): Unit = runBlocking(testCoroutineContext) {
val client = HttpClient(DarwinLegacy) {
engine {
configureRequest {
Expand Down
Expand Up @@ -18,7 +18,7 @@ import kotlin.coroutines.*

@OptIn(InternalAPI::class)
internal class DarwinClientEngine(override val config: DarwinClientEngineConfig) : HttpClientEngineBase("ktor-darwin") {
private val requestQueue = NSOperationQueue()
private val requestQueue: NSOperationQueue? = NSOperationQueue.currentQueue()

override val dispatcher = Dispatchers.Unconfined

Expand Down
Expand Up @@ -13,7 +13,7 @@ import kotlin.coroutines.*
@OptIn(UnsafeNumber::class)
internal class DarwinSession(
private val config: DarwinClientEngineConfig,
requestQueue: NSOperationQueue
requestQueue: NSOperationQueue?
) : Closeable {
private val closed = atomic(false)

Expand Down Expand Up @@ -54,7 +54,7 @@ internal class DarwinSession(
@OptIn(UnsafeNumber::class)
internal fun createSession(
config: DarwinClientEngineConfig,
requestQueue: NSOperationQueue
requestQueue: NSOperationQueue?
): Pair<NSURLSession, KtorNSURLSessionDelegate> {
val configuration = NSURLSessionConfiguration.defaultSessionConfiguration().apply {
setupProxy(config)
Expand Down
21 changes: 12 additions & 9 deletions ktor-client/ktor-client-darwin/darwin/test/DarwinEngineTest.kt
Expand Up @@ -11,6 +11,7 @@ import kotlinx.cinterop.*
import kotlinx.coroutines.*
import platform.Foundation.*
import platform.Foundation.NSHTTPCookieStorage.Companion.sharedHTTPCookieStorage
import kotlin.coroutines.CoroutineContext
import kotlin.test.*

/*
Expand All @@ -19,8 +20,10 @@ import kotlin.test.*

class DarwinEngineTest {

val testCoroutineContext: CoroutineContext = Dispatchers.Default

@Test
fun testRequestInRunBlocking() = runBlocking {
fun testRequestInRunBlocking() = runBlocking(testCoroutineContext) {
val client = HttpClient(Darwin)

try {
Expand All @@ -34,7 +37,7 @@ class DarwinEngineTest {
}

@Test
fun testQueryWithCyrillic() = runBlocking {
fun testQueryWithCyrillic() = runBlocking(testCoroutineContext) {
val client = HttpClient(Darwin)

try {
Expand All @@ -48,7 +51,7 @@ class DarwinEngineTest {
}

@Test
fun testQueryWithMultipleParams() = runBlocking {
fun testQueryWithMultipleParams() = runBlocking(testCoroutineContext) {
val client = HttpClient(Darwin)

try {
Expand All @@ -75,7 +78,7 @@ class DarwinEngineTest {
}

@Test
fun testCookieIsNotPersistedByDefault() = runBlocking {
fun testCookieIsNotPersistedByDefault() = runBlocking(testCoroutineContext) {
val client = HttpClient(Darwin)
try {
client.get("$TEST_SERVER/cookies")
Expand All @@ -89,7 +92,7 @@ class DarwinEngineTest {
}

@Test
fun testCookiePersistedWithSessionStore() = runBlocking {
fun testCookiePersistedWithSessionStore() = runBlocking(testCoroutineContext) {
val client = HttpClient(Darwin) {
engine {
configureSession {
Expand All @@ -110,7 +113,7 @@ class DarwinEngineTest {
}

@Test
fun testOverrideDefaultSession(): Unit = runBlocking {
fun testOverrideDefaultSession(): Unit = runBlocking(testCoroutineContext) {
val client = HttpClient(Darwin) {
val delegate = KtorNSURLSessionDelegate()
val session = NSURLSession.sessionWithConfiguration(
Expand All @@ -132,7 +135,7 @@ class DarwinEngineTest {
}

@Test
fun testOverrideDefaultSessionWithWebSockets(): Unit = runBlocking {
fun testOverrideDefaultSessionWithWebSockets(): Unit = runBlocking(testCoroutineContext) {
val client = HttpClient(Darwin) {
val delegate = KtorNSURLSessionDelegate()
val session = NSURLSession.sessionWithConfiguration(
Expand All @@ -158,7 +161,7 @@ class DarwinEngineTest {
}

@Test
fun testConfigureRequest(): Unit = runBlocking {
fun testConfigureRequest(): Unit = runBlocking(testCoroutineContext) {
val client = HttpClient(Darwin) {
engine {
configureRequest {
Expand All @@ -174,7 +177,7 @@ class DarwinEngineTest {

@OptIn(UnsafeNumber::class)
@Test
fun testConfigureWebsocketRequest(): Unit = runBlocking {
fun testConfigureWebsocketRequest(): Unit = runBlocking(testCoroutineContext) {
var customChallengeCalled = false
val client = HttpClient(Darwin) {
engine {
Expand Down

0 comments on commit 28308e7

Please sign in to comment.