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