• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 package kotlinx.coroutines
2 
3 import kotlinx.coroutines.testing.*
4 import kotlin.test.*
5 
6 class AwaitTest : TestBase() {
7 
8     @Test
<lambda>null9     fun testAwaitAll() = runTest {
10         expect(1)
11         val d = async {
12             expect(3)
13             "OK"
14         }
15 
16         val d2 = async {
17             yield()
18             expect(4)
19             1L
20         }
21 
22         expect(2)
23         require(d2.isActive && !d2.isCompleted)
24 
25         assertEquals(listOf("OK", 1L), awaitAll(d, d2))
26         expect(5)
27 
28         require(d.isCompleted && d2.isCompleted)
29         require(!d.isCancelled && !d2.isCancelled)
30         finish(6)
31     }
32 
33     @Test
<lambda>null34     fun testAwaitAllLazy() = runTest {
35         expect(1)
36         val d = async(start = CoroutineStart.LAZY) {
37             expect(2)
38             1
39         }
40         val d2 = async(start = CoroutineStart.LAZY) {
41             expect(3)
42             2
43         }
44         assertEquals(listOf(1, 2), awaitAll(d, d2))
45         finish(4)
46     }
47 
48     @Test
<lambda>null49     fun testAwaitAllTyped() = runTest {
50         val d1 = async { 1L }
51         val d2 = async { "" }
52         val d3 = async { }
53 
54         assertEquals(listOf(1L, ""), listOf(d1, d2).awaitAll())
55         assertEquals(listOf(1L, Unit), listOf(d1, d3).awaitAll())
56         assertEquals(listOf("", Unit), listOf(d2, d3).awaitAll())
57     }
58 
59     @Test
<lambda>null60     fun testAwaitAllExceptionally() = runTest {
61         expect(1)
62         val d = async {
63             expect(3)
64             "OK"
65         }
66 
67         val d2 = async(NonCancellable) {
68             yield()
69             throw TestException()
70         }
71 
72         val d3 = async {
73             expect(4)
74             delay(Long.MAX_VALUE)
75             1
76         }
77 
78         expect(2)
79         try {
80             awaitAll(d, d2, d3)
81         } catch (e: TestException) {
82             expect(5)
83         }
84 
85         yield()
86         require(d.isCompleted && d2.isCancelled && d3.isActive)
87         d3.cancel()
88         finish(6)
89     }
90 
91     @Test
<lambda>null92     fun testAwaitAllMultipleExceptions() = runTest {
93         val d = async(NonCancellable) {
94             expect(2)
95             throw TestException()
96         }
97 
98         val d2 = async(NonCancellable) {
99             yield()
100             throw TestException()
101         }
102 
103         val d3 = async {
104             yield()
105         }
106 
107         expect(1)
108         try {
109             awaitAll(d, d2, d3)
110         } catch (e: TestException) {
111             expect(3)
112         }
113 
114         finish(4)
115     }
116 
117     @Test
<lambda>null118     fun testAwaitAllCancellation() = runTest {
119         val outer = async {
120 
121             expect(1)
122             val inner = async {
123                 expect(4)
124                 delay(Long.MAX_VALUE)
125             }
126 
127             expect(2)
128             awaitAll(inner)
129             expectUnreached()
130         }
131 
132         yield()
133         expect(3)
134         yield()
135         require(outer.isActive)
136         outer.cancel()
137         require(outer.isCancelled)
138         finish(5)
139     }
140 
141     @Test
<lambda>null142     fun testAwaitAllPartiallyCompleted() = runTest {
143         val d1 = async { expect(1); 1 }
144         d1.await()
145         val d2 = async { expect(3); 2 }
146         expect(2)
147         assertEquals(listOf(1, 2), awaitAll(d1, d2))
148         require(d1.isCompleted && d2.isCompleted)
149         finish(4)
150     }
151 
152     @Test
<lambda>null153     fun testAwaitAllPartiallyCompletedExceptionally() = runTest {
154         val d1 = async(NonCancellable) {
155             expect(1)
156             throw TestException()
157         }
158 
159         yield()
160 
161         // This job is called after exception propagation
162         val d2 = async { expect(4) }
163 
164         expect(2)
165         try {
166             awaitAll(d1, d2)
167             expectUnreached()
168         } catch (e: TestException) {
169             expect(3)
170         }
171 
172         require(d2.isActive)
173         d2.await()
174         require(d1.isCompleted && d2.isCompleted)
175         finish(5)
176     }
177 
178     @Test
<lambda>null179     fun testAwaitAllFullyCompleted() = runTest {
180         val d1 = CompletableDeferred(Unit)
181         val d2 = CompletableDeferred(Unit)
182         val job = async { expect(3) }
183         expect(1)
184         awaitAll(d1, d2)
185         expect(2)
186         job.await()
187         finish(4)
188     }
189 
190     @Test
<lambda>null191     fun testAwaitOnSet() = runTest {
192         val d1 = CompletableDeferred(Unit)
193         val d2 = CompletableDeferred(Unit)
194         val job = async { expect(2) }
195         expect(1)
196         listOf(d1, d2, job).awaitAll()
197         finish(3)
198     }
199 
200     @Test
<lambda>null201     fun testAwaitAllFullyCompletedExceptionally() = runTest {
202         val d1 = CompletableDeferred<Unit>(parent = null)
203             .apply { completeExceptionally(TestException()) }
204         val d2 = CompletableDeferred<Unit>(parent = null)
205             .apply { completeExceptionally(TestException()) }
206         val job = async { expect(3) }
207         expect(1)
208         try {
209             awaitAll(d1, d2)
210         } catch (e: TestException) {
211             expect(2)
212         }
213 
214         job.await()
215         finish(4)
216     }
217 
218     @Test
<lambda>null219     fun testAwaitAllSameJobMultipleTimes() = runTest {
220         val d = async { "OK" }
221         // Duplicates are allowed though kdoc doesn't guarantee that
222         assertEquals(listOf("OK", "OK", "OK"), awaitAll(d, d, d))
223     }
224 
225     @Test
<lambda>null226     fun testAwaitAllSameThrowingJobMultipleTimes() = runTest {
227         val d1 =
228             async(NonCancellable) { throw TestException() }
229         val d2 = async { } // do nothing
230 
231         try {
232             expect(1)
233             // Duplicates are allowed though kdoc doesn't guarantee that
234             awaitAll(d1, d2, d1, d2)
235             expectUnreached()
236         } catch (e: TestException) {
237             finish(2)
238         }
239     }
240 
241     @Test
<lambda>null242     fun testAwaitAllEmpty() = runTest {
243         expect(1)
244         assertEquals(emptyList(), awaitAll<Unit>())
245         assertEquals(emptyList(), emptyList<Deferred<Unit>>().awaitAll())
246         finish(2)
247     }
248 
249     // joinAll
250 
251     @Test
<lambda>null252     fun testJoinAll() = runTest {
253         val d1 = launch { expect(2) }
254         val d2 = async {
255             expect(3)
256             "OK"
257         }
258         val d3 = launch { expect(4) }
259 
260         expect(1)
261         joinAll(d1, d2, d3)
262         finish(5)
263     }
264 
265     @Test
<lambda>null266     fun testJoinAllLazy() = runTest {
267         expect(1)
268         val d = async(start = CoroutineStart.LAZY) {
269             expect(2)
270         }
271         val d2 = launch(start = CoroutineStart.LAZY) {
272             expect(3)
273         }
274         joinAll(d, d2)
275         finish(4)
276     }
277 
278     @Test
<lambda>null279     fun testJoinAllExceptionally() = runTest {
280         val d1 = launch {
281             expect(2)
282         }
283         val d2 = async(NonCancellable) {
284             expect(3)
285             throw TestException()
286         }
287         val d3 = async {
288             expect(4)
289         }
290 
291         expect(1)
292         joinAll(d1, d2, d3)
293         finish(5)
294     }
295 
296     @Test
<lambda>null297     fun testJoinAllCancellation() = runTest {
298         val outer = launch {
299             expect(2)
300             val inner = launch {
301                 expect(3)
302                 delay(Long.MAX_VALUE)
303             }
304 
305             joinAll(inner)
306             expectUnreached()
307         }
308 
309         expect(1)
310         yield()
311         require(outer.isActive)
312         yield()
313         outer.cancel()
314         outer.join()
315         finish(4)
316     }
317 
318     @Test
<lambda>null319     fun testJoinAllAlreadyCompleted() = runTest {
320         val job = launch {
321             expect(1)
322         }
323 
324         job.join()
325         expect(2)
326 
327         joinAll(job)
328         finish(3)
329     }
330 
331     @Test
<lambda>null332     fun testJoinAllEmpty() = runTest {
333         expect(1)
334         joinAll()
335         listOf<Job>().joinAll()
336         finish(2)
337     }
338 
339     @Test
<lambda>null340     fun testJoinAllSameJob() = runTest {
341         val job = launch { }
342         joinAll(job, job, job)
343     }
344 
345     @Test
<lambda>null346     fun testJoinAllSameJobExceptionally() = runTest {
347         val job =
348             async(NonCancellable) { throw TestException() }
349         joinAll(job, job, job)
350     }
351 
352     @Test
testAwaitAllDelegatesnull353     fun testAwaitAllDelegates() = runTest {
354         expect(1)
355         val deferred = CompletableDeferred<String>()
356         @OptIn(InternalForInheritanceCoroutinesApi::class)
357         val delegate = object : Deferred<String> by deferred {}
358         launch {
359             expect(3)
360             deferred.complete("OK")
361         }
362         expect(2)
363         awaitAll(delegate)
364         finish(4)
365     }
366 
367     @Test
testCancelAwaitAllDelegatenull368     fun testCancelAwaitAllDelegate() = runTest {
369         expect(1)
370         val deferred = CompletableDeferred<String>()
371         @OptIn(InternalForInheritanceCoroutinesApi::class)
372         val delegate = object : Deferred<String> by deferred {}
373         launch {
374             expect(3)
375             deferred.cancel()
376         }
377         expect(2)
378         assertFailsWith<CancellationException> { awaitAll(delegate) }
379         finish(4)
380     }
381 }
382