override fun runInvocation()

in src/jvm/main/org/jetbrains/kotlinx/lincheck/runner/ExecutionScenarioRunner.kt [300:361]


    override fun runInvocation(): InvocationResult {
        var timeout = timeoutMs * 1_000_000
        try {
            // Create a new testing class instance.
            createTestInstance()
            // Set the event tracker.
            setEventTracker()
            // Execute the initial part.
            initialPartExecution?.let {
                beforePart(INIT)
                val initPartTask = threadMapOf<Runnable>(INIT_THREAD_ID to it)
                timeout -= executor.submitAndAwait(initPartTask, timeout)
            }
            onThreadSwitchesOrActorFinishes()
            val afterInitStateRepresentation = constructStateRepresentation()
            // Execute the parallel part.
            beforePart(PARALLEL)
            val parallelPartTasks = threadMapOf(*parallelPartExecutions
                .mapIndexed { i, execution -> i to execution }
                .toTypedArray()
            )
            timeout -= executor.submitAndAwait(parallelPartTasks, timeout)
            // Wait for all user threads to finish at the end of the parallel part
            timeout -= strategy.awaitUserThreads(timeout)
            val afterParallelStateRepresentation: String? = constructStateRepresentation()
            onThreadSwitchesOrActorFinishes()
            // Execute the post part.
            postPartExecution?.let {
                beforePart(POST)
                val postPartTask = threadMapOf<Runnable>(POST_THREAD_ID to it)
                timeout -= executor.submitAndAwait(postPartTask, timeout)
            }
            val afterPostStateRepresentation = constructStateRepresentation()
            // Execute validation functions
            validationPartExecution?.let { validationPart ->
                beforePart(VALIDATION)
                val validationTask = threadMapOf<Runnable>(VALIDATION_THREAD_ID to validationPart)
                executor.submitAndAwait(validationTask, timeout)
                val validationResult = validationPart.results.single()
                if (validationResult is ExceptionResult) {
                    return ValidationFailureInvocationResult(scenario, validationResult.throwable, collectExecutionResults())
                }
            }
            // Combine the results and convert them for the standard class loader (if they are of non-primitive types).
            // We do not want the transformed code to be reachable outside of the runner and strategy classes.
            return CompletedInvocationResult(collectExecutionResults(afterInitStateRepresentation, afterParallelStateRepresentation, afterPostStateRepresentation))
        } catch (_: TimeoutException) {
            return RunnerTimeoutInvocationResult()
        } catch (e: ExecutionException) {
            // In case when invocation raised an exception,
            // we need to wait for all user threads to finish before continuing.
            // In case if waiting for threads termination abrupt with the timeout,
            // we return `RunnerTimeoutInvocationResult`.
            // Otherwise, we return `UnexpectedExceptionInvocationResult` with the original exception.
            runCatching { strategy.awaitUserThreads(timeout) }.onFailure { exception ->
                if (exception is TimeoutException) return RunnerTimeoutInvocationResult()
            }
            return UnexpectedExceptionInvocationResult(e.cause!!, collectExecutionResults())
        } finally {
            resetState()
        }
    }