• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 
2 @file:Suppress("NAMED_ARGUMENTS_NOT_ALLOWED", "UNREACHABLE_CODE") // KT-21913
3 
4 package kotlinx.coroutines
5 
6 import kotlinx.coroutines.testing.*
7 import kotlin.test.*
8 
9 class WithTimeoutTest : TestBase() {
10     /**
11      * Tests a case of no timeout and no suspension inside.
12      */
13     @Test
<lambda>null14     fun testBasicNoSuspend() = runTest {
15         expect(1)
16         val result = withTimeout(10_000) {
17             expect(2)
18             "OK"
19         }
20         assertEquals("OK", result)
21         finish(3)
22     }
23 
24     /**
25      * Tests a case of no timeout and one suspension inside.
26      */
27     @Test
<lambda>null28     fun testBasicSuspend() = runTest {
29         expect(1)
30         val result = withTimeout(10_000) {
31             expect(2)
32             yield()
33             expect(3)
34             "OK"
35         }
36         assertEquals("OK", result)
37         finish(4)
38     }
39 
40     /**
41      * Tests proper dispatching of `withTimeout` blocks
42      */
43     @Test
<lambda>null44     fun testDispatch() = runTest {
45         expect(1)
46         launch {
47             expect(4)
48             yield() // back to main
49             expect(7)
50         }
51         expect(2)
52         // test that it does not yield to the above job when started
53         val result = withTimeout(1000) {
54             expect(3)
55             yield() // yield only now
56             expect(5)
57             "OK"
58         }
59         assertEquals("OK", result)
60         expect(6)
61         yield() // back to launch
62         finish(8)
63     }
64 
65 
66     /**
67      * Tests that a 100% CPU-consuming loop will react on timeout if it has yields.
68      */
69     @Test
testYieldBlockingWithTimeoutnull70     fun testYieldBlockingWithTimeout() = runTest(
71         expected = { it is CancellationException }
<lambda>null72     ) {
73         withTimeout(100) {
74             while (true) {
75                 yield()
76             }
77         }
78     }
79 
80     /**
81      * Tests that [withTimeout] waits for children coroutines to complete.
82      */
83     @Test
<lambda>null84     fun testWithTimeoutChildWait() = runTest {
85         expect(1)
86         withTimeout(100) {
87             expect(2)
88             // launch child with timeout
89             launch {
90                 expect(4)
91             }
92             expect(3)
93             // now will wait for child before returning
94         }
95         finish(5)
96     }
97 
98     @Test
<lambda>null99     fun testBadClass() = runTest {
100         val bad = BadClass()
101         val result = withTimeout(100) {
102             bad
103         }
104         assertSame(bad, result)
105     }
106 
107     @Test
<lambda>null108     fun testExceptionOnTimeout() = runTest {
109         expect(1)
110         try {
111             withTimeout(100) {
112                 expect(2)
113                 delay(1000)
114                 expectUnreached()
115                 "OK"
116             }
117         } catch (e: CancellationException) {
118             assertEquals("Timed out waiting for 100 ms", e.message)
119             finish(3)
120         }
121     }
122 
123     @Test
testSuppressExceptionWithResultnull124     fun testSuppressExceptionWithResult() = runTest(
125         expected = { it is CancellationException }
<lambda>null126     ) {
127         expect(1)
128         withTimeout(100) {
129             expect(2)
130             try {
131                 delay(1000)
132             } catch (e: CancellationException) {
133                 finish(3)
134             }
135             "OK"
136         }
137         expectUnreached()
138     }
139 
140     @Test
<lambda>null141     fun testSuppressExceptionWithAnotherException() = runTest{
142         expect(1)
143         try {
144             withTimeout(100) {
145                 expect(2)
146                 try {
147                     delay(1000)
148                 } catch (e: CancellationException) {
149                     expect(3)
150                     throw TestException()
151                 }
152                 expectUnreached()
153                 "OK"
154             }
155             expectUnreached()
156         } catch (e: TestException) {
157             finish(4)
158         }
159     }
160 
161     @Test
<lambda>null162     fun testNegativeTimeout() = runTest {
163         expect(1)
164         try {
165             withTimeout(-1) {
166                 expectUnreached()
167                 "OK"
168             }
169         } catch (e: TimeoutCancellationException) {
170             assertEquals("Timed out immediately", e.message)
171             finish(2)
172         }
173     }
174 
175     @Test
<lambda>null176     fun testExceptionFromWithinTimeout() = runTest {
177         expect(1)
178         try {
179             expect(2)
180             withTimeout(1000) {
181                 expect(3)
182                 throw TestException()
183             }
184             expectUnreached()
185         } catch (e: TestException) {
186             finish(4)
187         }
188     }
189 
190     @Test
<lambda>null191     fun testIncompleteWithTimeoutState() = runTest {
192         lateinit var timeoutJob: Job
193         val handle = withTimeout(Long.MAX_VALUE) {
194             timeoutJob = coroutineContext[Job]!!
195             timeoutJob.invokeOnCompletion { }
196         }
197 
198         handle.dispose()
199         timeoutJob.join()
200         assertTrue(timeoutJob.isCompleted)
201         assertFalse(timeoutJob.isActive)
202         assertFalse(timeoutJob.isCancelled)
203     }
204 }
205