• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2016-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license.
3  */
4 
5 package kotlinx.coroutines.tasks
6 
7 import com.google.android.gms.tasks.*
8 import kotlinx.coroutines.*
9 import org.junit.*
10 import org.junit.Test
11 import java.util.concurrent.locks.*
12 import kotlin.concurrent.*
13 import kotlin.test.*
14 
15 class TaskTest : TestBase() {
16     @Before
setupnull17     fun setup() {
18         ignoreLostThreads("ForkJoinPool.commonPool-worker-")
19     }
20 
21     @Test
<lambda>null22     fun testCompletedDeferredAsTask() = runTest {
23         expect(1)
24         val deferred = async(start = CoroutineStart.UNDISPATCHED) {
25             expect(2) // Completed immediately
26             "OK"
27         }
28         expect(3)
29         val task = deferred.asTask()
30         assertEquals("OK", task.await())
31         finish(4)
32     }
33 
34     @Test
<lambda>null35     fun testDeferredAsTask() = runTest {
36         expect(1)
37         val deferred = async {
38             expect(3) // Completed later
39             "OK"
40         }
41         expect(2)
42         val task = deferred.asTask()
43         assertEquals("OK", task.await())
44         finish(4)
45     }
46 
47     @Test
testCancelledAsTasknull48     fun testCancelledAsTask() {
49         val deferred = GlobalScope.async {
50             delay(100)
51         }.apply { cancel() }
52 
53         val task = deferred.asTask()
54         try {
55             runTest { task.await() }
56         } catch (e: Exception) {
57             assertTrue(e is CancellationException)
58             assertTrue(task.isCanceled)
59         }
60     }
61 
62     @Test
testThrowingAsTasknull63     fun testThrowingAsTask() {
64         val deferred = GlobalScope.async {
65             throw TestException("Fail")
66         }
67 
68         val task = deferred.asTask()
69         runTest(expected = { it is TestException }) {
70             task.await()
71         }
72     }
73 
74     @Test
<lambda>null75     fun testStateAsTask() = runTest {
76         val lock = ReentrantLock().apply { lock() }
77 
78         val deferred: Deferred<Int> = Tasks.call {
79             lock.withLock { 42 }
80         }.asDeferred()
81 
82         assertFalse(deferred.isCompleted)
83         lock.unlock()
84 
85         assertEquals(42, deferred.await())
86         assertTrue(deferred.isCompleted)
87     }
88 
89     @Test
<lambda>null90     fun testTaskAsDeferred() = runTest {
91         val deferred = Tasks.forResult(42).asDeferred()
92         assertEquals(42, deferred.await())
93     }
94 
95     @Test
<lambda>null96     fun testNullResultTaskAsDeferred() = runTest {
97         assertNull(Tasks.forResult(null).asDeferred().await())
98     }
99 
100     @Test
<lambda>null101     fun testCancelledTaskAsDeferred() = runTest {
102         val deferred = Tasks.forCanceled<Int>().asDeferred()
103 
104         assertTrue(deferred.isCancelled)
105         try {
106             deferred.await()
107             fail("deferred.await() should be cancelled")
108         } catch (e: Exception) {
109             assertTrue(e is CancellationException)
110         }
111     }
112 
113     @Test
testFailedTaskAsDeferrednull114     fun testFailedTaskAsDeferred() = runTest {
115         val deferred = Tasks.forException<Int>(TestException("something went wrong")).asDeferred()
116 
117         assertTrue(deferred.isCancelled && deferred.isCompleted)
118         val completionException = deferred.getCompletionExceptionOrNull()!!
119         assertTrue(completionException is TestException)
120         assertEquals("something went wrong", completionException.message)
121 
122         try {
123             deferred.await()
124             fail("deferred.await() should throw an exception")
125         } catch (e: Exception) {
126             assertTrue(e is TestException)
127             assertEquals("something went wrong", e.message)
128         }
129     }
130 
131     @Test
<lambda>null132     fun testFailingTaskAsDeferred() = runTest {
133         val lock = ReentrantLock().apply { lock() }
134 
135         val deferred: Deferred<Int> = Tasks.call {
136             lock.withLock { throw TestException("something went wrong") }
137         }.asDeferred()
138 
139         assertFalse(deferred.isCompleted)
140         lock.unlock()
141 
142         try {
143             deferred.await()
144             fail("deferred.await() should throw an exception")
145         } catch (e: Exception) {
146             assertTrue(e is TestException)
147             assertEquals("something went wrong", e.message)
148             assertSame(e.cause, deferred.getCompletionExceptionOrNull()) // debug mode stack augmentation
149         }
150     }
151 
152     class TestException(message: String) : Exception(message)
153 }
154