blob: 2b911ffb65706142075ee4e61c110f5021e6cb6d [file] [log] [blame]
Roman Elizarovc0d71dc2017-12-21 22:12:43 +03001
Roman Elizarova7db8ec2017-12-21 22:45:12 +03002/*
Roman Elizarov1f74a2d2018-06-29 19:19:45 +03003 * Copyright 2016-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license.
Roman Elizarova7db8ec2017-12-21 22:45:12 +03004 */
5
Roman Elizarovc0d71dc2017-12-21 22:12:43 +03006@file:Suppress("NAMED_ARGUMENTS_NOT_ALLOWED") // KT-21913
7
8package kotlinx.coroutines.experimental
9
Roman Elizarov9fe5f462018-02-21 19:05:52 +030010import kotlin.coroutines.experimental.*
Roman Elizarovc0d71dc2017-12-21 22:12:43 +030011import kotlin.test.*
12
Roman Elizarovaa461cf2018-04-11 13:20:29 +030013class WithTimeoutTest : TestBase() {
Roman Elizarovc0d71dc2017-12-21 22:12:43 +030014 /**
15 * Tests a case of no timeout and no suspension inside.
16 */
17 @Test
18 fun testBasicNoSuspend() = runTest {
19 expect(1)
20 val result = withTimeout(10_000) {
21 expect(2)
22 "OK"
23 }
24 assertEquals("OK", result)
25 finish(3)
26 }
27
28 /**
29 * Tests a case of no timeout and one suspension inside.
30 */
31 @Test
32 fun testBasicSuspend() = runTest {
33 expect(1)
34 val result = withTimeout(10_000) {
35 expect(2)
36 yield()
37 expect(3)
38 "OK"
39 }
40 assertEquals("OK", result)
41 finish(4)
42 }
43
44 /**
45 * Tests proper dispatching of `withTimeout` blocks
46 */
47 @Test
48 fun testDispatch() = runTest {
49 expect(1)
50 launch(coroutineContext) {
51 expect(4)
52 yield() // back to main
53 expect(7)
54 }
55 expect(2)
56 // test that it does not yield to the above job when started
57 val result = withTimeout(1000) {
58 expect(3)
59 yield() // yield only now
60 expect(5)
61 "OK"
62 }
63 assertEquals("OK", result)
64 expect(6)
65 yield() // back to launch
66 finish(8)
67 }
68
69
70 /**
71 * Tests that a 100% CPU-consuming loop will react on timeout if it has yields.
72 */
73 @Test
74 fun testYieldBlockingWithTimeout() = runTest(
75 expected = { it is CancellationException }
76 ) {
77 withTimeout(100) {
78 while (true) {
79 yield()
80 }
81 }
82 }
83
84 /**
85 * Tests that [withTimeout] waits for children coroutines to complete.
86 */
87 @Test
88 fun testWithTimeoutChildWait() = runTest {
89 expect(1)
90 withTimeout(100) {
91 expect(2)
92 // launch child with timeout
93 launch(coroutineContext) {
94 expect(4)
95 }
96 expect(3)
97 // now will wait for child before returning
98 }
99 finish(5)
100 }
Konrad KamiƄskiea4cd452018-02-01 17:18:14 +0100101
102 @Test
103 fun testBadClass() = runTest {
104 val bad = BadClass()
105 val result = withTimeout(100) {
106 bad
107 }
108 assertSame(bad, result)
109 }
110
111 class BadClass {
112 override fun equals(other: Any?): Boolean = error("Should not be called")
113 override fun hashCode(): Int = error("Should not be called")
114 override fun toString(): String = error("Should not be called")
115 }
Roman Elizarovaa461cf2018-04-11 13:20:29 +0300116
117 @Test
118 fun testExceptionOnTimeout() = runTest {
119 expect(1)
120 try {
121 withTimeout(100) {
122 expect(2)
123 delay(1000)
124 expectUnreached()
125 "OK"
126 }
127 } catch (e: CancellationException) {
128 assertEquals("Timed out waiting for 100 MILLISECONDS", e.message)
129 finish(3)
130 }
131 }
132
133 @Test
134 fun testSuppressExceptionWithResult() = runTest(
135 expected = { it is CancellationException }
136 ) {
137 expect(1)
Vsevolod Tolstopyatov87f2faa2018-04-30 22:53:02 +0300138 withTimeout(100) {
Roman Elizarovaa461cf2018-04-11 13:20:29 +0300139 expect(2)
140 try {
141 delay(1000)
142 } catch (e: CancellationException) {
143 finish(3)
144 }
145 "OK"
146 }
147 expectUnreached()
148 }
149
150 @Test
151 fun testSuppressExceptionWithAnotherException() = runTest(
152 expected = { it is TestException }
153 ) {
154 expect(1)
155 withTimeout(100) {
156 expect(2)
157 try {
158 delay(1000)
159 } catch (e: CancellationException) {
160 finish(3)
161 throw TestException()
162 }
163 expectUnreached()
164 "OK"
165 }
166 expectUnreached()
167 }
168
169 private class TestException : Exception()
Vsevolod Tolstopyatov4cb5d192018-04-11 17:42:16 +0300170
171 @Test
172 fun testNegativeTimeout() = runTest {
173 expect(1)
174 try {
175 withTimeout(-1) {
176 expectUnreached()
177 "OK"
178 }
179 } catch (e: CancellationException) {
180 assertEquals("Timed out immediately", e.message)
181 finish(2)
182 }
183 }
Roman Elizarovc0d71dc2017-12-21 22:12:43 +0300184}
185