jvmTest.exceptions.JobNestedExceptionsTest.kt Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of kotlinx-coroutines-core
Show all versions of kotlinx-coroutines-core
Coroutines support libraries for Kotlin
/*
* Copyright 2016-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license.
*/
package kotlinx.coroutines.exceptions
import kotlinx.coroutines.*
import org.junit.Test
import java.io.*
import kotlin.test.*
class JobNestedExceptionsTest : TestBase() {
@Test
fun testExceptionUnwrapping() {
val exception = captureExceptionsRun {
val job = Job()
launch(job) {
expect(2)
launch {
launch {
launch {
throw IllegalStateException()
}
}
}
}
expect(1)
job.join()
finish(3)
}
checkException(exception)
checkCycles(exception)
}
@Test
fun testExceptionUnwrappingWithSuspensions() {
val exception = captureExceptionsRun {
val job = Job()
launch(job) {
expect(2)
launch {
launch {
launch {
launch {
throw IOException()
}
yield()
}
delay(Long.MAX_VALUE)
}
delay(Long.MAX_VALUE)
}
delay(Long.MAX_VALUE)
}
expect(1)
job.join()
finish(3)
}
assertTrue(exception is IOException)
}
@Test
fun testNestedAtomicThrow() {
val exception = captureExceptionsRun {
expect(1)
val job = launch(NonCancellable + CoroutineName("outer"), start = CoroutineStart.ATOMIC) {
expect(2)
launch(CoroutineName("nested"), start = CoroutineStart.ATOMIC) {
expect(4)
throw IOException()
}
expect(3)
throw ArithmeticException()
}
job.join()
finish(5)
}
assertTrue(exception is ArithmeticException, "Found $exception")
checkException(exception.suppressed[0])
}
@Test
fun testChildThrowsDuringCompletion() {
val exceptions = captureMultipleExceptionsRun {
expect(1)
val job = launch(NonCancellable + CoroutineName("outer"), start = CoroutineStart.ATOMIC) {
expect(2)
launch(CoroutineName("nested"), start = CoroutineStart.ATOMIC) {
expect(4)
launch(CoroutineName("nested2"), start = CoroutineStart.ATOMIC) {
// This child attaches to the parent and throws after parent completion
expect(6)
throw NullPointerException()
}
expect(5)
throw IOException()
}
expect(3)
throw ArithmeticException()
}
job.join()
finish(7)
}
assertEquals(1, exceptions.size, "Found $exceptions")
val exception = exceptions[0]
assertTrue(exception is ArithmeticException, "Exception is $exception")
val suppressed = exception.suppressed
val ioe = suppressed[0]
assertTrue(ioe is IOException)
checkException(ioe.suppressed[0])
checkCycles(exception)
}
}