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

jvmTest.exceptions.JobBasicCancellationTest.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.*

/*
 * Basic checks that check that cancellation more or less works,
 * parent is not cancelled on child cancellation and launch {}, Job(), async {} and
 * CompletableDeferred behave properly
 */

@Suppress("DEPRECATION") // cancel(cause)
class JobBasicCancellationTest : TestBase() {

    @Test
    fun testJobCancelChild() = runTest {
        val parent = launch {
            expect(1)
            val child = launch {
                expect(2)
            }

            yield()
            expect(3)
            child.cancel()
            child.join()
            expect(4)
        }

        parent.join()
        finish(5)
    }

    @Test
    fun testJobCancelChildAtomic() = runTest {
        val parent = launch {
            expect(1)
            val child = launch(start = CoroutineStart.ATOMIC) {
                expect(3)
            }

            expect(2)
            child.cancel()
            child.join()
            yield()
            expect(4)
        }

        parent.join()
        assertTrue(parent.isCompleted)
        assertFalse(parent.isCancelled)
        finish(5)
    }

    @Test
    fun testAsyncCancelChild() = runTest {
        val parent = async {
            expect(1)
            val child = async {
                expect(2)
            }

            yield()
            expect(3)
            child.cancel()
            child.await()
            expect(4)
        }

        parent.await()
        finish(5)
    }

    @Test
    fun testAsyncCancelChildAtomic() = runTest {
        val parent = async {
            expect(1)
            val child = async(start = CoroutineStart.ATOMIC) {
                expect(3)
            }

            expect(2)
            child.cancel()
            child.join()
            expect(4)
        }

        parent.await()
        finish(5)
    }

    @Test
    fun testNestedAsyncFailure() = runTest {
        val deferred = async(NonCancellable) {
            val nested = async(NonCancellable) {
                expect(3)
                throw IOException()
            }

            expect(2)
            yield()
            expect(4)
            nested.await()
        }

        expect(1)
        try {
            deferred.await()
        } catch (e: IOException) {
            finish(5)
        }
    }

    @Test
    fun testCancelJobImpl() = runTest {
        val parent = launch {
            expect(1)
            val child = Job(coroutineContext[Job])
            expect(2)
            child.cancel() // cancel without cause -- should not cancel us (parent)
            child.join()
            expect(3)
        }
        parent.join()
        finish(4)
    }

    @Test
    fun cancelCompletableDeferred() = runTest {
        val parent = launch {
            expect(1)
            val child = CompletableDeferred(coroutineContext[Job])
            expect(2)
            child.cancel() // cancel without cause -- should not cancel us (parent)
            child.join()
            expect(3)
        }

        parent.join()
        finish(4)
    }

    @Test
    fun testConsecutiveCancellation() {
        val deferred = CompletableDeferred()
        assertTrue(deferred.completeExceptionally(IndexOutOfBoundsException()))
        assertFalse(deferred.completeExceptionally(AssertionError())) // second is too late
        val cause = deferred.getCancellationException().cause!!
        assertTrue(cause is IndexOutOfBoundsException)
        assertNull(cause.cause)
        assertTrue(cause.suppressed.isEmpty())
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy