blob: 9c3cdadd5fbc691c1380a0f3ef82f0db7c59f7c3 [file] [log] [blame]
Roman Elizarov769d7dc2018-04-26 12:13:40 +03001/*
Roman Elizarov1f74a2d2018-06-29 19:19:45 +03002 * Copyright 2016-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license.
Roman Elizarov769d7dc2018-04-26 12:13:40 +03003 */
4
Vsevolod Tolstopyatov4f0d48b2018-04-11 13:51:33 +03005package kotlinx.coroutines.experimental
6
7import kotlin.coroutines.experimental.coroutineContext
Roman Elizarov189e9952018-04-26 11:06:37 +03008import kotlin.test.*
Vsevolod Tolstopyatov4f0d48b2018-04-11 13:51:33 +03009
10class AwaitTest : TestBase() {
11
12 @Test
13 fun testAwaitAll() = runTest {
14 expect(1)
15 val d = async(coroutineContext) {
16 expect(3)
17 "OK"
18 }
19
20 val d2 = async(coroutineContext) {
21 yield()
22 expect(4)
23 1L
24 }
25
26 expect(2)
27 require(d2.isActive && !d2.isCompleted)
28
Roman Elizarov189e9952018-04-26 11:06:37 +030029 assertEquals(listOf("OK", 1L), awaitAll(d, d2))
Vsevolod Tolstopyatov4f0d48b2018-04-11 13:51:33 +030030 expect(5)
31
32 require(d.isCompleted && d2.isCompleted)
33 require(!d.isCancelled && !d2.isCancelled)
34 finish(6)
35 }
36
37 @Test
Vsevolod Tolstopyatovf0ef14e2018-04-11 19:44:08 +030038 fun testAwaitAllLazy() = runTest {
39 expect(1)
Roman Elizarov769d7dc2018-04-26 12:13:40 +030040 val d = async(
41 coroutineContext,
42 start = CoroutineStart.LAZY
43 ) { expect(2); 1 }
44 val d2 = async(
45 coroutineContext,
46 start = CoroutineStart.LAZY
47 ) { expect(3); 2 }
Roman Elizarov189e9952018-04-26 11:06:37 +030048 assertEquals(listOf(1, 2), awaitAll(d, d2))
Vsevolod Tolstopyatovf0ef14e2018-04-11 19:44:08 +030049 finish(4)
50 }
51
52 @Test
Vsevolod Tolstopyatov4f0d48b2018-04-11 13:51:33 +030053 fun testAwaitAllTyped() = runTest {
54 val d1 = async(coroutineContext) { 1L }
55 val d2 = async(coroutineContext) { "" }
Roman Elizarov769d7dc2018-04-26 12:13:40 +030056 val d3 = async(coroutineContext) { }
Vsevolod Tolstopyatov4f0d48b2018-04-11 13:51:33 +030057
Roman Elizarov189e9952018-04-26 11:06:37 +030058 assertEquals(listOf(1L, ""), listOf(d1, d2).awaitAll())
59 assertEquals(listOf(1L, Unit), listOf(d1, d3).awaitAll())
60 assertEquals(listOf("", Unit), listOf(d2, d3).awaitAll())
Vsevolod Tolstopyatov4f0d48b2018-04-11 13:51:33 +030061 }
62
Vsevolod Tolstopyatovcd006432018-04-26 16:03:40 +030063 @Test
64 fun testAwaitAllExceptionally() = runTest {
65 expect(1)
66 val d = async(coroutineContext) {
67 expect(3)
68 "OK"
69 }
70
71 val d2 = async(coroutineContext) {
72 yield()
73 throw TestException()
74 }
75
76 val d3 = async(coroutineContext) {
77 expect(4)
78 delay(Long.MAX_VALUE)
79 1
80 }
81
82 expect(2)
83 try {
84 awaitAll(d, d2, d3)
85 } catch (e: TestException) {
86 expect(5)
87 }
88
89 yield()
90 require(d.isCompleted && d2.isCompletedExceptionally && d3.isActive)
91 d3.cancel()
92 finish(6)
93 }
Vsevolod Tolstopyatov4f0d48b2018-04-11 13:51:33 +030094
95 @Test
96 fun testAwaitAllMultipleExceptions() = runTest {
97 val d = async(coroutineContext) {
98 expect(2)
99 throw TestException()
100 }
101
102 val d2 = async(coroutineContext) {
103 yield()
104 throw TestException()
105 }
106
107 val d3 = async(coroutineContext) {
108 yield()
109 }
110
111 expect(1)
112 try {
113 awaitAll(d, d2, d3)
114 } catch (e: TestException) {
115 expect(3)
116 }
117
118 finish(4)
119 }
120
Vsevolod Tolstopyatovcd006432018-04-26 16:03:40 +0300121 @Test
122 fun testAwaitAllCancellation() = runTest {
123 val outer = async(coroutineContext) {
124
125 expect(1)
126 val inner = async(coroutineContext) {
127 expect(4)
128 delay(Long.MAX_VALUE)
129 }
130
131 expect(2)
132 awaitAll(inner)
133 expectUnreached()
134 }
135
136 yield()
137 expect(3)
138 yield()
139 require(outer.isActive)
140 outer.cancel()
141 require(outer.isCancelled)
142 finish(5)
143 }
Vsevolod Tolstopyatov4f0d48b2018-04-11 13:51:33 +0300144
145 @Test
146 fun testAwaitAllPartiallyCompleted() = runTest {
Roman Elizarov189e9952018-04-26 11:06:37 +0300147 val d1 = async(coroutineContext) { expect(1); 1 }
Vsevolod Tolstopyatov4f0d48b2018-04-11 13:51:33 +0300148 d1.await()
Roman Elizarov189e9952018-04-26 11:06:37 +0300149 val d2 = async(coroutineContext) { expect(3); 2 }
Vsevolod Tolstopyatov4f0d48b2018-04-11 13:51:33 +0300150 expect(2)
Roman Elizarov189e9952018-04-26 11:06:37 +0300151 assertEquals(listOf(1, 2), awaitAll(d1, d2))
Vsevolod Tolstopyatov4f0d48b2018-04-11 13:51:33 +0300152 require(d1.isCompleted && d2.isCompleted)
153 finish(4)
154 }
155
156 @Test
157 fun testAwaitAllPartiallyCompletedExceptionally() = runTest {
158 val d1 = async(coroutineContext) {
159 expect(1)
160 throw TestException()
161 }
162
163 yield()
164
165 // This job is called after exception propagation
166 val d2 = async(coroutineContext) { expect(4) }
167
168 expect(2)
169 try {
170 awaitAll(d1, d2)
171 expectUnreached()
172 } catch (e: TestException) {
173 expect(3)
174 }
175
176 require(d2.isActive)
177 d2.await()
178 require(d1.isCompleted && d2.isCompleted)
179 finish(5)
180 }
181
182 @Test
183 fun testAwaitAllFullyCompleted() = runTest {
184 val d1 = CompletableDeferred(Unit)
185 val d2 = CompletableDeferred(Unit)
186 val job = async(coroutineContext) { expect(3) }
187 expect(1)
188 awaitAll(d1, d2)
189 expect(2)
190 job.await()
191 finish(4)
192 }
193
194 @Test
195 fun testAwaitOnSet() = runTest {
196 val d1 = CompletableDeferred(Unit)
197 val d2 = CompletableDeferred(Unit)
198 val job = async(coroutineContext) { expect(2) }
199 expect(1)
200 listOf(d1, d2, job).awaitAll()
201 finish(3)
202 }
203
204 @Test
205 fun testAwaitAllFullyCompletedExceptionally() = runTest {
Roman Elizarov769d7dc2018-04-26 12:13:40 +0300206 val d1 = CompletableDeferred<Unit>(parent = null)
207 .apply { completeExceptionally(TestException()) }
208 val d2 = CompletableDeferred<Unit>(parent = null)
209 .apply { completeExceptionally(TestException()) }
Vsevolod Tolstopyatov4f0d48b2018-04-11 13:51:33 +0300210 val job = async(coroutineContext) { expect(3) }
211 expect(1)
212 try {
213 awaitAll(d1, d2)
214 } catch (e: TestException) {
215 expect(2)
216 }
217
218 job.await()
219 finish(4)
220 }
221
222 @Test
223 fun testAwaitAllSameJobMultipleTimes() = runTest {
Roman Elizarov189e9952018-04-26 11:06:37 +0300224 val d = async(coroutineContext) { "OK" }
Vsevolod Tolstopyatov4f0d48b2018-04-11 13:51:33 +0300225 // Duplicates are allowed though kdoc doesn't guarantee that
Roman Elizarov189e9952018-04-26 11:06:37 +0300226 assertEquals(listOf("OK", "OK", "OK"), awaitAll(d, d, d))
Vsevolod Tolstopyatov4f0d48b2018-04-11 13:51:33 +0300227 }
228
229 @Test
230 fun testAwaitAllSameThrowingJobMultipleTimes() = runTest {
Roman Elizarov769d7dc2018-04-26 12:13:40 +0300231 val d1 =
232 async(coroutineContext) { throw TestException() }
Vsevolod Tolstopyatov4f0d48b2018-04-11 13:51:33 +0300233 val d2 = async(coroutineContext) { } // do nothing
234
235 try {
236 expect(1)
237 // Duplicates are allowed though kdoc doesn't guarantee that
238 awaitAll(d1, d2, d1, d2)
239 expectUnreached()
240 } catch (e: TestException) {
241 finish(2)
242 }
243 }
244
245 @Test
246 fun testAwaitAllEmpty() = runTest {
247 expect(1)
Roman Elizarov189e9952018-04-26 11:06:37 +0300248 assertEquals(emptyList(), awaitAll<Unit>())
249 assertEquals(emptyList(), emptyList<Deferred<Unit>>().awaitAll())
Vsevolod Tolstopyatov4f0d48b2018-04-11 13:51:33 +0300250 finish(2)
251 }
252
253 // joinAll
254
255 @Test
256 fun testJoinAll() = runTest {
257 val d1 = launch(coroutineContext) { expect(2) }
258 val d2 = async(coroutineContext) {
259 expect(3)
260 "OK"
261 }
262 val d3 = launch(coroutineContext) { expect(4) }
263
264 expect(1)
265 joinAll(d1, d2, d3)
266 finish(5)
267 }
268
269 @Test
Vsevolod Tolstopyatovf0ef14e2018-04-11 19:44:08 +0300270 fun testJoinAllLazy() = runTest {
271 expect(1)
Roman Elizarov769d7dc2018-04-26 12:13:40 +0300272 val d = async(
273 coroutineContext,
274 start = CoroutineStart.LAZY
275 ) { expect(2) }
276 val d2 = launch(
277 coroutineContext,
278 start = CoroutineStart.LAZY
279 ) { expect(3) }
Vsevolod Tolstopyatovf0ef14e2018-04-11 19:44:08 +0300280 joinAll(d, d2)
281 finish(4)
282 }
283
284 @Test
Vsevolod Tolstopyatov4f0d48b2018-04-11 13:51:33 +0300285 fun testJoinAllExceptionally() = runTest {
286 val d1 = launch(coroutineContext) {
287 expect(2)
288 }
289 val d2 = async(coroutineContext) {
290 expect(3)
291 throw TestException()
292 }
293 val d3 = async(coroutineContext) {
294 expect(4)
295 }
296
297 expect(1)
298 joinAll(d1, d2, d3)
299 finish(5)
300 }
301
Vsevolod Tolstopyatovcd006432018-04-26 16:03:40 +0300302 @Test
303 fun testJoinAllCancellation() = runTest {
304 val outer = launch(coroutineContext) {
305 expect(2)
306 val inner = launch(coroutineContext) {
307 expect(3)
308 delay(Long.MAX_VALUE)
309 }
310
311 joinAll(inner)
312 expectUnreached()
313 }
314
315 expect(1)
316 yield()
317 require(outer.isActive)
318 yield()
319 outer.cancel()
320 outer.join()
321 finish(4)
322 }
Vsevolod Tolstopyatov4f0d48b2018-04-11 13:51:33 +0300323
324 @Test
325 fun testJoinAllAlreadyCompleted() = runTest {
326 val job = launch(coroutineContext) {
327 expect(1)
328 }
329
330 job.join()
331 expect(2)
332
333 joinAll(job)
334 finish(3)
335 }
336
337 @Test
338 fun testJoinAllEmpty() = runTest {
339 expect(1)
340 joinAll()
341 listOf<Job>().joinAll()
342 finish(2)
343 }
344
345 @Test
346 fun testJoinAllSameJob() = runTest {
347 val job = launch(coroutineContext) { }
348 joinAll(job, job, job)
349 }
350
351 @Test
352 fun testJoinAllSameJobExceptionally() = runTest {
Roman Elizarov769d7dc2018-04-26 12:13:40 +0300353 val job =
354 async(coroutineContext) { throw TestException() }
Vsevolod Tolstopyatov4f0d48b2018-04-11 13:51:33 +0300355 joinAll(job, job, job)
356 }
357
358 private class TestException : Exception()
359}