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

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

There is a newer version: 1.9.0
Show newest version
/*
 * Copyright 2016-2019 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 kotlinx.coroutines.channels.*
import org.junit.*
import kotlin.coroutines.*
import org.junit.rules.TestName
import org.junit.Rule

class StackTraceRecoveryResumeModeTest : TestBase() {

    @get:Rule
    val testName = TestName()

    @Test
    fun testUnconfined() = runTest {
        testResumeModeFastPath(Dispatchers.Unconfined)
    }

    @Test
    fun testNestedUnconfined() = runTest {
        withContext(Dispatchers.Unconfined) {
            testResumeModeFastPath(Dispatchers.Unconfined)
        }
    }

    @Test
    fun testNestedUnconfinedChangedContext() = runTest {
        withContext(Dispatchers.Unconfined) {
            testResumeModeFastPath(CoroutineName("Test"))
        }
    }

    @Test
    fun testEventLoopDispatcher() = runTest {
        testResumeModeFastPath(wrapperDispatcher())
    }

    @Test
    fun testNestedEventLoopDispatcher() = runTest {
        val dispatcher = wrapperDispatcher()
        withContext(dispatcher) {
            testResumeModeFastPath(dispatcher)
        }
    }

    @Test
    fun testNestedEventLoopChangedContext() = runTest {
        withContext(wrapperDispatcher()) {
            testResumeModeFastPath(CoroutineName("Test"))
        }
    }

    private suspend fun testResumeModeFastPath(context: CoroutineContext) {
        try {
            val channel = Channel()
            channel.close(RecoverableTestException())
            doFastPath(context, channel)
        } catch (e: Throwable) {
            verifyStackTrace("resume-mode/${testName.methodName}", e)
        }
    }

    private suspend fun doFastPath(context: CoroutineContext, channel: Channel) {
        yield()
        withContext(context, channel)
    }

    private suspend fun withContext(context: CoroutineContext, channel: Channel) {
        withContext(context) {
            channel.receive()
            yield()
        }
    }

    @Test
    fun testUnconfinedSuspending() = runTest {
        testResumeModeSuspending(Dispatchers.Unconfined)
    }

    @Test
    fun testNestedUnconfinedSuspending() = runTest {
        withContext(Dispatchers.Unconfined) {
            testResumeModeSuspending(Dispatchers.Unconfined)
        }
    }

    @Test
    fun testNestedUnconfinedChangedContextSuspending() = runTest {
        withContext(Dispatchers.Unconfined) {
            testResumeModeSuspending(CoroutineName("Test"))
        }
    }

    @Test
    fun testEventLoopDispatcherSuspending() = runTest {
        testResumeModeSuspending(wrapperDispatcher())
    }

    @Test
    fun testNestedEventLoopDispatcherSuspending() = runTest {
        val dispatcher = wrapperDispatcher()
        withContext(dispatcher) {
            testResumeModeSuspending(dispatcher)
        }
    }

    @Test
    fun testNestedEventLoopChangedContextSuspending() = runTest {
        withContext(wrapperDispatcher()) {
            testResumeModeSuspending(CoroutineName("Test"))
        }
    }

    private suspend fun testResumeModeSuspending(context: CoroutineContext) {
        try {
            val channel = Channel()
            val latch = Channel()
            GlobalScope.launch(coroutineContext) {
                latch.receive()
                expect(3)
                channel.close(RecoverableTestException())
            }
            doSuspendingPath(context, channel, latch)
        } catch (e: Throwable) {
            finish(4)
            verifyStackTrace("resume-mode/${testName.methodName}", e)
        }
    }

    private suspend fun doSuspendingPath(context: CoroutineContext, channel: Channel, latch: Channel) {
        yield()
        withContext(context, channel, latch)
    }

    private suspend fun withContext(context: CoroutineContext, channel: Channel, latch: Channel) {
        withContext(context) {
            expect(1)
            latch.send(1)
            expect(2)
            channel.receive()
            yield()
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy