• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 
2 @file:Suppress("NAMED_ARGUMENTS_NOT_ALLOWED") // KT-21913
3 
4 package kotlinx.coroutines
5 
6 import kotlinx.coroutines.testing.*
7 import kotlinx.coroutines.channels.*
8 import kotlin.test.*
9 
10 class WithTimeoutOrNullTest : TestBase() {
11     /**
12      * Tests a case of no timeout and no suspension inside.
13      */
14     @Test
<lambda>null15     fun testBasicNoSuspend() = runTest {
16         expect(1)
17         val result = withTimeoutOrNull(10_000) {
18             expect(2)
19             "OK"
20         }
21         assertEquals("OK", result)
22         finish(3)
23     }
24 
25     /**
26      * Tests a case of no timeout and one suspension inside.
27      */
28     @Test
<lambda>null29     fun testBasicSuspend() = runTest {
30         expect(1)
31         val result = withTimeoutOrNull(10_000) {
32             expect(2)
33             yield()
34             expect(3)
35             "OK"
36         }
37         assertEquals("OK", result)
38         finish(4)
39     }
40 
41     /**
42      * Tests property dispatching of `withTimeoutOrNull` blocks
43      */
44     @Test
<lambda>null45     fun testDispatch() = runTest {
46         expect(1)
47         launch {
48             expect(4)
49             yield() // back to main
50             expect(7)
51         }
52         expect(2)
53         // test that it does not yield to the above job when started
54         val result = withTimeoutOrNull(1000) {
55             expect(3)
56             yield() // yield only now
57             expect(5)
58             "OK"
59         }
60         assertEquals("OK", result)
61         expect(6)
62         yield() // back to launch
63         finish(8)
64     }
65 
66     /**
67      * Tests that a 100% CPU-consuming loop will react on timeout if it has yields.
68      */
69     @Test
<lambda>null70     fun testYieldBlockingWithTimeout() = runTest {
71         expect(1)
72         val result = withTimeoutOrNull(100) {
73             while (true) {
74                 yield()
75             }
76         }
77         assertNull(result)
78         finish(2)
79     }
80 
81     @Test
testSmallTimeoutnull82     fun testSmallTimeout() = runTest {
83         val channel = Channel<Int>(1)
84         val value = withTimeoutOrNull(1) {
85             channel.receive()
86         }
87         assertNull(value)
88     }
89 
90     @Test
<lambda>null91     fun testThrowException() = runTest(expected = {it is AssertionError}) {
<lambda>null92         withTimeoutOrNull<Unit>(Long.MAX_VALUE) {
93             throw AssertionError()
94         }
95     }
96 
97     @Test
testInnerTimeoutnull98     fun testInnerTimeout() = runTest(
99         expected = { it is CancellationException }
<lambda>null100     ) {
101         withTimeoutOrNull(1000) {
102             withTimeout(10) {
103                 while (true) {
104                     yield()
105                 }
106             }
107             @Suppress("UNREACHABLE_CODE")
108             expectUnreached() // will timeout
109         }
110         expectUnreached() // will timeout
111     }
112 
113     @Test
testNestedTimeoutnull114     fun testNestedTimeout() = runTest(expected = { it is TimeoutCancellationException }) {
<lambda>null115         withTimeoutOrNull(Long.MAX_VALUE) {
116             // Exception from this withTimeout is not suppressed by withTimeoutOrNull
117             withTimeout(10) {
118                 delay(Long.MAX_VALUE)
119                 1
120             }
121         }
122 
123         expectUnreached()
124     }
125 
126     @Test
<lambda>null127     fun testOuterTimeout() = runTest {
128         if (isJavaAndWindows) return@runTest
129         var counter = 0
130         val result = withTimeoutOrNull(320) {
131             while (true) {
132                 val inner = withTimeoutOrNull(150) {
133                     while (true) {
134                         yield()
135                     }
136                 }
137                 assertNull(inner)
138                 counter++
139             }
140         }
141         assertNull(result)
142         check(counter in 1..2) {"Executed: $counter times"}
143     }
144 
145     @Test
<lambda>null146     fun testBadClass() = runTest {
147         val bad = BadClass()
148         val result = withTimeoutOrNull(100) {
149             bad
150         }
151         assertSame(bad, result)
152     }
153 
154     @Test
<lambda>null155     fun testNullOnTimeout() = runTest {
156         expect(1)
157         val result = withTimeoutOrNull(100) {
158             expect(2)
159             delay(1000)
160             expectUnreached()
161             "OK"
162         }
163         assertNull(result)
164         finish(3)
165     }
166 
167     @Test
<lambda>null168     fun testSuppressExceptionWithResult() = runTest {
169         expect(1)
170         val result = withTimeoutOrNull(100) {
171             expect(2)
172             try {
173                 delay(1000)
174             } catch (e: CancellationException) {
175                 expect(3)
176             }
177             "OK"
178         }
179         assertNull(result)
180         finish(4)
181     }
182 
183     @Test
<lambda>null184     fun testSuppressExceptionWithAnotherException() = runTest {
185         expect(1)
186         try {
187             withTimeoutOrNull(100) {
188                 expect(2)
189                 try {
190                     delay(1000)
191                 } catch (e: CancellationException) {
192                     expect(3)
193                     throw TestException()
194                 }
195                 expectUnreached()
196                 "OK"
197             }
198             expectUnreached()
199         } catch (e: TestException) {
200             // catches TestException
201             finish(4)
202 
203         }
204     }
205 
206     @Test
<lambda>null207     fun testNegativeTimeout() = runTest {
208         expect(1)
209         var result = withTimeoutOrNull(-1) {
210             expectUnreached()
211         }
212         assertNull(result)
213         result = withTimeoutOrNull(0) {
214             expectUnreached()
215         }
216         assertNull(result)
217         finish(2)
218     }
219 
220     @Test
<lambda>null221     fun testExceptionFromWithinTimeout() = runTest {
222         expect(1)
223         try {
224             expect(2)
225             withTimeoutOrNull(1000) {
226                 expect(3)
227                 throw TestException()
228             }
229             expectUnreached()
230         } catch (e: TestException) {
231             finish(4)
232         }
233     }
234 }
235