All Downloads are FREE. Search and download functionalities are using the official Maven repository.

jvmTest.exceptions.JobNestedExceptionsTest.kt Maven / Gradle / Ivy

There is a newer version: 1.9.0
Show newest version
/*
 * 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)
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy