• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 
2 /*
3  * Copyright 2016-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license.
4  */
5 
6 @file:Suppress("NAMED_ARGUMENTS_NOT_ALLOWED") // KT-21913
7 
8 package kotlinx.coroutines
9 
10 import kotlinx.coroutines.channels.*
11 import kotlin.test.*
12 
13 class WithTimeoutOrNullTest : TestBase() {
14     /**
15      * Tests a case of no timeout and no suspension inside.
16      */
17     @Test
<lambda>null18     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
<lambda>null32     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
<lambda>null48     fun testDispatch() = runTest {
49         expect(1)
50         launch {
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 = 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
<lambda>null73     fun testYieldBlockingWithTimeout() = runTest {
74         expect(1)
75         val result = withTimeoutOrNull(100) {
76             while (true) {
77                 yield()
78             }
79         }
80         assertNull(result)
81         finish(2)
82     }
83 
84     @Test
testSmallTimeoutnull85     fun testSmallTimeout() = runTest {
86         val channel = Channel<Int>(1)
87         val value = withTimeoutOrNull(1) {
88             channel.receive()
89         }
90         assertNull(value)
91     }
92 
93     @Test
<lambda>null94     fun testThrowException() = runTest(expected = {it is AssertionError}) {
<lambda>null95         withTimeoutOrNull<Unit>(Long.MAX_VALUE) {
96             throw AssertionError()
97         }
98     }
99 
100     @Test
testInnerTimeoutnull101     fun testInnerTimeout() = runTest(
102         expected = { it is CancellationException }
<lambda>null103     ) {
104         withTimeoutOrNull(1000) {
105             withTimeout(10) {
106                 while (true) {
107                     yield()
108                 }
109             }
110             @Suppress("UNREACHABLE_CODE")
111             expectUnreached() // will timeout
112         }
113         expectUnreached() // will timeout
114     }
115 
116     @Test
testNestedTimeoutnull117     fun testNestedTimeout() = runTest(expected = { it is TimeoutCancellationException }) {
<lambda>null118         withTimeoutOrNull(Long.MAX_VALUE) {
119             // Exception from this withTimeout is not suppressed by withTimeoutOrNull
120             withTimeout(10) {
121                 delay(Long.MAX_VALUE)
122                 1
123             }
124         }
125 
126         expectUnreached()
127     }
128 
129     @Test
<lambda>null130     fun testOuterTimeout() = runTest {
131         if (isJavaAndWindows) return@runTest
132         var counter = 0
133         val result = withTimeoutOrNull(320) {
134             while (true) {
135                 val inner = withTimeoutOrNull(150) {
136                     while (true) {
137                         yield()
138                     }
139                 }
140                 assertNull(inner)
141                 counter++
142             }
143         }
144         assertNull(result)
145         check(counter in 1..2) {"Executed: $counter times"}
146     }
147 
148     @Test
<lambda>null149     fun testBadClass() = runTest {
150         val bad = BadClass()
151         val result = withTimeoutOrNull(100) {
152             bad
153         }
154         assertSame(bad, result)
155     }
156 
157     @Test
<lambda>null158     fun testNullOnTimeout() = runTest {
159         expect(1)
160         val result = withTimeoutOrNull(100) {
161             expect(2)
162             delay(1000)
163             expectUnreached()
164             "OK"
165         }
166         assertNull(result)
167         finish(3)
168     }
169 
170     @Test
<lambda>null171     fun testSuppressExceptionWithResult() = runTest {
172         expect(1)
173         val result = withTimeoutOrNull(100) {
174             expect(2)
175             try {
176                 delay(1000)
177             } catch (e: CancellationException) {
178                 expect(3)
179             }
180             "OK"
181         }
182         assertNull(result)
183         finish(4)
184     }
185 
186     @Test
<lambda>null187     fun testSuppressExceptionWithAnotherException() = runTest {
188         expect(1)
189         try {
190             withTimeoutOrNull(100) {
191                 expect(2)
192                 try {
193                     delay(1000)
194                 } catch (e: CancellationException) {
195                     expect(3)
196                     throw TestException()
197                 }
198                 expectUnreached()
199                 "OK"
200             }
201             expectUnreached()
202         } catch (e: TestException) {
203             // catches TestException
204             finish(4)
205 
206         }
207     }
208 
209     @Test
<lambda>null210     fun testNegativeTimeout() = runTest {
211         expect(1)
212         var result = withTimeoutOrNull(-1) {
213             expectUnreached()
214         }
215         assertNull(result)
216         result = withTimeoutOrNull(0) {
217             expectUnreached()
218         }
219         assertNull(result)
220         finish(2)
221     }
222 
223     @Test
<lambda>null224     fun testExceptionFromWithinTimeout() = runTest {
225         expect(1)
226         try {
227             expect(2)
228             withTimeoutOrNull(1000) {
229                 expect(3)
230                 throw TestException()
231             }
232             expectUnreached()
233         } catch (e: TestException) {
234             finish(4)
235         }
236     }
237 }
238