blob: a22b0bbe25013d1202b93ff437caf1e3aeba208a [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
Vsevolod Tolstopyatov988eb262018-08-21 19:45:29 +030010import kotlinx.coroutines.experimental.channels.*
Roman Elizarovc0d71dc2017-12-21 22:12:43 +030011import kotlin.test.*
12
Roman Elizarovaa461cf2018-04-11 13:20:29 +030013class WithTimeoutOrNullTest : 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 = withTimeoutOrNull(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 = withTimeoutOrNull(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 property dispatching of `withTimeoutOrNull` blocks
46 */
47 @Test
48 fun testDispatch() = runTest {
49 expect(1)
Roman Elizarov6e3ffb12018-09-14 13:46:58 +030050 launch {
Roman Elizarovc0d71dc2017-12-21 22:12:43 +030051 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 = withTimeoutOrNull(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 * Tests that a 100% CPU-consuming loop will react on timeout if it has yields.
71 */
72 @Test
73 fun testYieldBlockingWithTimeout() = runTest {
74 expect(1)
75 val result = withTimeoutOrNull(100) {
76 while (true) {
77 yield()
78 }
79 }
80 assertEquals(null, result)
81 finish(2)
82 }
83
84 @Test
Vsevolod Tolstopyatov988eb262018-08-21 19:45:29 +030085 fun testSmallTimeout() = runTest {
86 val channel = Channel<Int>(1)
87 val value = withTimeoutOrNull(1) {
88 channel.receive()
89 }
Vsevolod Tolstopyatov988eb262018-08-21 19:45:29 +030090 assertNull(value)
91 }
92
93 @Test
94 fun testThrowException() = runTest(expected = {it is AssertionError}) {
95 withTimeoutOrNull(Long.MAX_VALUE) {
96 throw AssertionError()
97 }
98 }
99
100 @Test
Roman Elizarov44d28cd2018-09-17 15:03:47 +0300101 fun testInnerTimeout() = runTest(
Roman Elizarovc0d71dc2017-12-21 22:12:43 +0300102 expected = { it is CancellationException }
103 ) {
Roman Elizarov44d28cd2018-09-17 15:03:47 +0300104 withTimeoutOrNull(1000) {
105 withTimeout(10) {
Roman Elizarovc0d71dc2017-12-21 22:12:43 +0300106 while (true) {
107 yield()
108 }
109 }
110 expectUnreached() // will timeout
111 }
112 expectUnreached() // will timeout
113 }
114
115 @Test
Vsevolod Tolstopyatov988eb262018-08-21 19:45:29 +0300116 fun testNestedTimeout() = runTest(expected = { it is TimeoutCancellationException }) {
117 withTimeoutOrNull(Long.MAX_VALUE) {
118 // Exception from this withTimeout is not suppressed by withTimeoutOrNull
119 withTimeout(10) {
120 delay(Long.MAX_VALUE)
121 1
122 }
123 }
124
125 expectUnreached()
126 }
127
128 @Test
Roman Elizarov44d28cd2018-09-17 15:03:47 +0300129 fun testOuterTimeout() = runTest {
Roman Elizarovc0d71dc2017-12-21 22:12:43 +0300130 var counter = 0
131 val result = withTimeoutOrNull(250) {
132 while (true) {
133 val inner = withTimeoutOrNull(100) {
134 while (true) {
135 yield()
136 }
137 }
138 assertEquals(null, inner)
139 counter++
140 }
141 }
142 assertEquals(null, result)
Vsevolod Tolstopyatove0cf38f2018-08-15 14:24:57 +0300143 check(counter in 1..2) {"Executed: $counter times"}
Roman Elizarovc0d71dc2017-12-21 22:12:43 +0300144 }
Roman Elizarova0cc1152018-02-02 10:45:27 +0100145
146 @Test
147 fun testBadClass() = runTest {
148 val bad = BadClass()
149 val result = withTimeoutOrNull(100) {
150 bad
151 }
152 assertSame(bad, result)
153 }
154
155 class BadClass {
156 override fun equals(other: Any?): Boolean = error("Should not be called")
157 override fun hashCode(): Int = error("Should not be called")
158 override fun toString(): String = error("Should not be called")
159 }
Roman Elizarovaa461cf2018-04-11 13:20:29 +0300160
161 @Test
162 fun testNullOnTimeout() = runTest {
163 expect(1)
164 val result = withTimeoutOrNull(100) {
165 expect(2)
166 delay(1000)
167 expectUnreached()
168 "OK"
169 }
170 assertEquals(null, result)
171 finish(3)
172 }
173
174 @Test
175 fun testSuppressExceptionWithResult() = runTest {
176 expect(1)
177 val result = withTimeoutOrNull(100) {
178 expect(2)
179 try {
180 delay(1000)
181 } catch (e: CancellationException) {
182 expect(3)
183 }
184 "OK"
185 }
186 assertEquals(null, result)
187 finish(4)
188 }
189
190 @Test
Vsevolod Tolstopyatov06f57aa2018-07-24 19:51:21 +0300191 fun testSuppressExceptionWithAnotherException() = runTest {
Roman Elizarovaa461cf2018-04-11 13:20:29 +0300192 expect(1)
Roman Elizarov541a9b62018-09-25 23:23:34 +0300193 try {
194 withTimeoutOrNull(100) {
195 expect(2)
196 try {
197 delay(1000)
198 } catch (e: CancellationException) {
199 expect(3)
200 throw TestException()
201 }
202 expectUnreached()
203 "OK"
Roman Elizarovaa461cf2018-04-11 13:20:29 +0300204 }
205 expectUnreached()
Roman Elizarov541a9b62018-09-25 23:23:34 +0300206 } catch (e: TestException) {
207 // catches TestException
208 finish(4)
Vsevolod Tolstopyatov06f57aa2018-07-24 19:51:21 +0300209
Roman Elizarov541a9b62018-09-25 23:23:34 +0300210 }
Roman Elizarovaa461cf2018-04-11 13:20:29 +0300211 }
212
213 private class TestException : Exception()
Vsevolod Tolstopyatov4cb5d192018-04-11 17:42:16 +0300214
215 @Test
216 fun testNegativeTimeout() = runTest {
217 expect(1)
218 var result = withTimeoutOrNull(-1) {
219 expectUnreached()
220 }
221 assertNull(result)
222 result = withTimeoutOrNull(0) {
223 expectUnreached()
224 }
225 assertNull(result)
226 finish(2)
227 }
Roman Elizarovc0d71dc2017-12-21 22:12:43 +0300228}