blob: c21d4f7298eb32922e61e074855d9010f58e718f [file] [log] [blame]
Roman Elizarov8552f0e2017-09-28 13:03:44 +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
19import org.hamcrest.MatcherAssert.assertThat
20import org.hamcrest.core.IsEqual
21import org.junit.Test
22import java.util.concurrent.Executor
23import java.util.concurrent.Executors
Vsevolod Tolstopyatov4cb5d192018-04-11 17:42:16 +030024import kotlin.coroutines.experimental.*
Roman Elizarov8552f0e2017-09-28 13:03:44 +030025
Vsevolod Tolstopyatovcd006432018-04-26 16:03:40 +030026class DelayJvmTest : TestBase() {
Roman Elizarov8552f0e2017-09-28 13:03:44 +030027 /**
28 * Test that delay works properly in contexts with custom [ContinuationInterceptor]
29 */
30 @Test
31 fun testDelayInArbitraryContext() = runBlocking {
32 var thread: Thread? = null
33 val pool = Executors.newFixedThreadPool(1) { runnable ->
34 Thread(runnable).also { thread = it }
35 }
36 val context = CustomInterceptor(pool)
37 val c = async(context) {
38 assertThat(Thread.currentThread(), IsEqual(thread))
39 delay(100)
40 assertThat(Thread.currentThread(), IsEqual(thread))
41 42
42 }
43 assertThat(c.await(), IsEqual(42))
44 pool.shutdown()
45 }
46
Roman Elizarov8552f0e2017-09-28 13:03:44 +030047 @Test
48 fun testDelayWithoutDispatcher() = runBlocking(CoroutineName("testNoDispatcher.main")) {
49 // launch w/o a specified dispatcher
50 val c = async(CoroutineName("testNoDispatcher.inner")) {
51 delay(100)
52 42
53 }
54 assertThat(c.await(), IsEqual(42))
55 }
56
Vsevolod Tolstopyatov4cb5d192018-04-11 17:42:16 +030057 @Test
58 fun testNegativeDelay() = runBlocking {
59 expect(1)
60 val job = async(coroutineContext) {
61 expect(3)
62 delay(0)
63 expect(4)
64 }
65
66 delay(-1)
67 expect(2)
68 job.await()
69 finish(5)
70 }
71
Roman Elizarov8552f0e2017-09-28 13:03:44 +030072 class CustomInterceptor(val pool: Executor) : AbstractCoroutineContextElement(ContinuationInterceptor), ContinuationInterceptor {
73 override fun <T> interceptContinuation(continuation: Continuation<T>): Continuation<T> =
74 Wrapper(pool, continuation)
75 }
76
77 class Wrapper<T>(val pool: Executor, val cont: Continuation<T>) : Continuation<T> {
78 override val context: CoroutineContext
79 get() = cont.context
80
81 override fun resume(value: T) {
82 pool.execute { cont.resume(value) }
83 }
84
85 override fun resumeWithException(exception: Throwable) {
86 pool.execute { cont.resumeWithException(exception) }
87 }
88 }
89
90}