blob: f5b8562136917b983f3df266cd1ba5508153d451 [file] [log] [blame]
Roman Elizarov507f5d42017-04-19 19:15:34 +03001/*
2 * Copyright 2016-2017 JetBrains s.r.o.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package kotlinx.coroutines.experimental
18
Roman Elizarovc0d71dc2017-12-21 22:12:43 +030019import kotlin.test.*
Roman Elizarov507f5d42017-04-19 19:15:34 +030020import java.util.concurrent.ExecutorService
21import java.util.concurrent.Executors
22import java.util.concurrent.ThreadFactory
Roman Elizarovca9d5be2017-04-20 19:23:18 +030023import java.util.concurrent.atomic.AtomicInteger
Roman Elizarov507f5d42017-04-19 19:15:34 +030024import kotlin.coroutines.experimental.CoroutineContext
25
26class WithTimeoutOrNullThreadDispatchTest : TestBase() {
27 var executor: ExecutorService? = null
28
Roman Elizarovc0d71dc2017-12-21 22:12:43 +030029 @AfterTest
Roman Elizarov507f5d42017-04-19 19:15:34 +030030 fun tearDown() {
31 executor?.shutdown()
32 }
33
34 @Test
35 fun testCancellationDispatchScheduled() {
36 checkCancellationDispatch {
37 executor = Executors.newScheduledThreadPool(1, it)
38 executor!!.asCoroutineDispatcher()
39 }
40 }
41
42 @Test
43 fun testCancellationDispatchNonScheduled() {
44 checkCancellationDispatch {
45 executor = Executors.newSingleThreadExecutor(it)
46 executor!!.asCoroutineDispatcher()
47 }
48 }
49
50 @Test
51 fun testCancellationDispatchCustomNoDelay() {
Roman Elizarovca9d5be2017-04-20 19:23:18 +030052 // it also checks that there is at most once scheduled request in flight (no spurious concurrency)
53 var error: String? = null
Roman Elizarov507f5d42017-04-19 19:15:34 +030054 checkCancellationDispatch {
55 executor = Executors.newSingleThreadExecutor(it)
Roman Elizarovca9d5be2017-04-20 19:23:18 +030056 val scheduled = AtomicInteger(0)
Roman Elizarov507f5d42017-04-19 19:15:34 +030057 object : CoroutineDispatcher() {
58 override fun dispatch(context: CoroutineContext, block: Runnable) {
Roman Elizarovca9d5be2017-04-20 19:23:18 +030059 if (scheduled.incrementAndGet() > 1) error = "Two requests are scheduled concurrently"
60 executor!!.execute {
61 scheduled.decrementAndGet()
62 block.run()
63 }
Roman Elizarov507f5d42017-04-19 19:15:34 +030064 }
65 }
66 }
Roman Elizarovca9d5be2017-04-20 19:23:18 +030067 error?.let { error(it) }
Roman Elizarov507f5d42017-04-19 19:15:34 +030068 }
69
70 private fun checkCancellationDispatch(factory: (ThreadFactory) -> CoroutineDispatcher) = runBlocking {
71 expect(1)
72 var thread: Thread? = null
73 val dispatcher = factory(ThreadFactory { Thread(it).also { thread = it } })
Roman Elizarovf9e13f52017-12-21 12:23:15 +030074 withContext(dispatcher) {
Roman Elizarov507f5d42017-04-19 19:15:34 +030075 expect(2)
Roman Elizarovc0d71dc2017-12-21 22:12:43 +030076 assertEquals(thread, Thread.currentThread())
Roman Elizarovca9d5be2017-04-20 19:23:18 +030077 val result = withTimeoutOrNull(100) {
78 try {
79 expect(3)
80 delay(1000)
81 expectUnreached()
82 } catch (e: CancellationException) {
83 expect(4)
Roman Elizarovc0d71dc2017-12-21 22:12:43 +030084 assertEquals(thread, Thread.currentThread())
Roman Elizarovca9d5be2017-04-20 19:23:18 +030085 throw e // rethrow
Roman Elizarov507f5d42017-04-19 19:15:34 +030086 }
Roman Elizarovca9d5be2017-04-20 19:23:18 +030087 }
Roman Elizarovc0d71dc2017-12-21 22:12:43 +030088 assertEquals(thread, Thread.currentThread())
89 assertEquals(null, result)
Roman Elizarovca9d5be2017-04-20 19:23:18 +030090 expect(5)
Roman Elizarov507f5d42017-04-19 19:15:34 +030091 }
Roman Elizarovca9d5be2017-04-20 19:23:18 +030092 finish(6)
Roman Elizarov507f5d42017-04-19 19:15:34 +030093 }
94}