blob: 7aeede24ec4c81e9e7fe57fb5fb0a4884b974a5a [file] [log] [blame]
Roman Elizarovc0d71dc2017-12-21 22:12:43 +03001
Roman Elizarova7db8ec2017-12-21 22:45:12 +03002/*
3 * Copyright 2016-2017 JetBrains s.r.o.
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
Roman Elizarovc0d71dc2017-12-21 22:12:43 +030018@file:Suppress("NAMED_ARGUMENTS_NOT_ALLOWED") // KT-21913
19
20package kotlinx.coroutines.experimental
21
Roman Elizarov9fe5f462018-02-21 19:05:52 +030022import kotlin.coroutines.experimental.*
Roman Elizarovc0d71dc2017-12-21 22:12:43 +030023import kotlin.test.*
24
Roman Elizarovaa461cf2018-04-11 13:20:29 +030025class WithTimeoutTest : TestBase() {
Roman Elizarovc0d71dc2017-12-21 22:12:43 +030026 /**
27 * Tests a case of no timeout and no suspension inside.
28 */
29 @Test
30 fun testBasicNoSuspend() = runTest {
31 expect(1)
32 val result = withTimeout(10_000) {
33 expect(2)
34 "OK"
35 }
36 assertEquals("OK", result)
37 finish(3)
38 }
39
40 /**
41 * Tests a case of no timeout and one suspension inside.
42 */
43 @Test
44 fun testBasicSuspend() = runTest {
45 expect(1)
46 val result = withTimeout(10_000) {
47 expect(2)
48 yield()
49 expect(3)
50 "OK"
51 }
52 assertEquals("OK", result)
53 finish(4)
54 }
55
56 /**
57 * Tests proper dispatching of `withTimeout` blocks
58 */
59 @Test
60 fun testDispatch() = runTest {
61 expect(1)
62 launch(coroutineContext) {
63 expect(4)
64 yield() // back to main
65 expect(7)
66 }
67 expect(2)
68 // test that it does not yield to the above job when started
69 val result = withTimeout(1000) {
70 expect(3)
71 yield() // yield only now
72 expect(5)
73 "OK"
74 }
75 assertEquals("OK", result)
76 expect(6)
77 yield() // back to launch
78 finish(8)
79 }
80
81
82 /**
83 * Tests that a 100% CPU-consuming loop will react on timeout if it has yields.
84 */
85 @Test
86 fun testYieldBlockingWithTimeout() = runTest(
87 expected = { it is CancellationException }
88 ) {
89 withTimeout(100) {
90 while (true) {
91 yield()
92 }
93 }
94 }
95
96 /**
97 * Tests that [withTimeout] waits for children coroutines to complete.
98 */
99 @Test
100 fun testWithTimeoutChildWait() = runTest {
101 expect(1)
102 withTimeout(100) {
103 expect(2)
104 // launch child with timeout
105 launch(coroutineContext) {
106 expect(4)
107 }
108 expect(3)
109 // now will wait for child before returning
110 }
111 finish(5)
112 }
Konrad KamiƄskiea4cd452018-02-01 17:18:14 +0100113
114 @Test
115 fun testBadClass() = runTest {
116 val bad = BadClass()
117 val result = withTimeout(100) {
118 bad
119 }
120 assertSame(bad, result)
121 }
122
123 class BadClass {
124 override fun equals(other: Any?): Boolean = error("Should not be called")
125 override fun hashCode(): Int = error("Should not be called")
126 override fun toString(): String = error("Should not be called")
127 }
Roman Elizarovaa461cf2018-04-11 13:20:29 +0300128
129 @Test
130 fun testExceptionOnTimeout() = runTest {
131 expect(1)
132 try {
133 withTimeout(100) {
134 expect(2)
135 delay(1000)
136 expectUnreached()
137 "OK"
138 }
139 } catch (e: CancellationException) {
140 assertEquals("Timed out waiting for 100 MILLISECONDS", e.message)
141 finish(3)
142 }
143 }
144
145 @Test
146 fun testSuppressExceptionWithResult() = runTest(
147 expected = { it is CancellationException }
148 ) {
149 expect(1)
Vsevolod Tolstopyatov87f2faa2018-04-30 22:53:02 +0300150 withTimeout(100) {
Roman Elizarovaa461cf2018-04-11 13:20:29 +0300151 expect(2)
152 try {
153 delay(1000)
154 } catch (e: CancellationException) {
155 finish(3)
156 }
157 "OK"
158 }
159 expectUnreached()
160 }
161
162 @Test
163 fun testSuppressExceptionWithAnotherException() = runTest(
164 expected = { it is TestException }
165 ) {
166 expect(1)
167 withTimeout(100) {
168 expect(2)
169 try {
170 delay(1000)
171 } catch (e: CancellationException) {
172 finish(3)
173 throw TestException()
174 }
175 expectUnreached()
176 "OK"
177 }
178 expectUnreached()
179 }
180
181 private class TestException : Exception()
Vsevolod Tolstopyatov4cb5d192018-04-11 17:42:16 +0300182
183 @Test
184 fun testNegativeTimeout() = runTest {
185 expect(1)
186 try {
187 withTimeout(-1) {
188 expectUnreached()
189 "OK"
190 }
191 } catch (e: CancellationException) {
192 assertEquals("Timed out immediately", e.message)
193 finish(2)
194 }
195 }
Roman Elizarovc0d71dc2017-12-21 22:12:43 +0300196}
197