diff --git a/compiler/test-infrastructure/tests/org/jetbrains/kotlin/test/TestRunner.kt b/compiler/test-infrastructure/tests/org/jetbrains/kotlin/test/TestRunner.kt index bd5a38164cf..724111abe66 100644 --- a/compiler/test-infrastructure/tests/org/jetbrains/kotlin/test/TestRunner.kt +++ b/compiler/test-infrastructure/tests/org/jetbrains/kotlin/test/TestRunner.kt @@ -61,7 +61,8 @@ class TestRunner(private val testConfiguration: TestConfiguration) { var failedException: Throwable? = null try { for (module in modules) { - processModule(services, module, dependencyProvider, moduleStructure) + val shouldProcessNextModules = processModule(services, module, dependencyProvider, moduleStructure) + if (!shouldProcessNextModules) break } } catch (e: Throwable) { failedException = e @@ -101,41 +102,47 @@ class TestRunner(private val testConfiguration: TestConfiguration) { } .map { if (it is ExceptionFromTestError) it.cause else it } + /* + * If there was failure from handler with `failureDisablesNextSteps=true` then `processModule` + * returns false which indicates that other modules should not be processed + */ private fun processModule( services: TestServices, module: TestModule, dependencyProvider: DependencyProviderImpl, moduleStructure: TestModuleStructure - ) { + ): Boolean { val sourcesArtifact = ResultingArtifact.Source() val frontendKind = module.frontendKind - if (!frontendKind.shouldRunAnalysis) return + if (!frontendKind.shouldRunAnalysis) return true val frontendArtifacts: ResultingArtifact.FrontendOutput<*> = testConfiguration.getFacade(SourcesKind, frontendKind) - .transform(module, sourcesArtifact)?.also { dependencyProvider.registerArtifact(module, it) } ?: return + .transform(module, sourcesArtifact)?.also { dependencyProvider.registerArtifact(module, it) } ?: return true val frontendHandlers: List> = testConfiguration.getHandlers(frontendKind) for (frontendHandler in frontendHandlers) { - withAssertionCatching { + val thereWasAnException = withAssertionCatching { if (frontendHandler.shouldRun(failedAssertions.isNotEmpty())) { frontendHandler.hackyProcess(module, frontendArtifacts) } } + if (thereWasAnException && frontendHandler.failureDisablesNextSteps) return false } val backendKind = services.backendKindExtractor.backendKind(module.targetBackend) - if (!backendKind.shouldRunAnalysis) return + if (!backendKind.shouldRunAnalysis) return true val backendInputInfo = testConfiguration.getFacade(frontendKind, backendKind) - .hackyTransform(module, frontendArtifacts)?.also { dependencyProvider.registerArtifact(module, it) } ?: return + .hackyTransform(module, frontendArtifacts)?.also { dependencyProvider.registerArtifact(module, it) } ?: return true val backendHandlers: List> = testConfiguration.getHandlers(backendKind) for (backendHandler in backendHandlers) { - withAssertionCatching { + val thereWasAnException = withAssertionCatching { if (backendHandler.shouldRun(failedAssertions.isNotEmpty())) { backendHandler.hackyProcess(module, backendInputInfo) } } + if (thereWasAnException && backendHandler.failureDisablesNextSteps) return false } for (artifactKind in moduleStructure.getTargetArtifactKinds(module)) { @@ -143,28 +150,36 @@ class TestRunner(private val testConfiguration: TestConfiguration) { val binaryArtifact = testConfiguration.getFacade(backendKind, artifactKind) .hackyTransform(module, backendInputInfo)?.also { dependencyProvider.registerArtifact(module, it) - } ?: return + } ?: return true val binaryHandlers: List> = testConfiguration.getHandlers(artifactKind) for (binaryHandler in binaryHandlers) { - withAssertionCatching { + val thereWasAnException = withAssertionCatching { if (binaryHandler.shouldRun(failedAssertions.isNotEmpty())) { binaryHandler.hackyProcess(module, binaryArtifact) } } + if (thereWasAnException && binaryHandler.failureDisablesNextSteps) return false } } + + return true } - private inline fun withAssertionCatching(insertExceptionInStart: Boolean = false, block: () -> Unit) { - try { + /* + * Returns true if there was an exception in block + */ + private inline fun withAssertionCatching(insertExceptionInStart: Boolean = false, block: () -> Unit): Boolean { + return try { block() + false } catch (e: Throwable) { if (insertExceptionInStart) { failedAssertions.add(0, e) } else { failedAssertions += e } + true } } diff --git a/compiler/test-infrastructure/tests/org/jetbrains/kotlin/test/model/AnalysisHandler.kt b/compiler/test-infrastructure/tests/org/jetbrains/kotlin/test/model/AnalysisHandler.kt index a9b7a4907da..992d9adc172 100644 --- a/compiler/test-infrastructure/tests/org/jetbrains/kotlin/test/model/AnalysisHandler.kt +++ b/compiler/test-infrastructure/tests/org/jetbrains/kotlin/test/model/AnalysisHandler.kt @@ -13,6 +13,7 @@ import org.jetbrains.kotlin.test.services.assertions abstract class AnalysisHandler>( val testServices: TestServices, + val failureDisablesNextSteps: Boolean, val doNotRunIfThereWerePreviousFailures: Boolean ) { protected val assertions: Assertions @@ -34,17 +35,20 @@ abstract class AnalysisHandler>( abstract class FrontendOutputHandler>( testServices: TestServices, override val artifactKind: FrontendKind, + failureDisablesNextSteps: Boolean, doNotRunIfThereWerePreviousFailures: Boolean -) : AnalysisHandler(testServices, doNotRunIfThereWerePreviousFailures) +) : AnalysisHandler(testServices, failureDisablesNextSteps, doNotRunIfThereWerePreviousFailures) abstract class BackendInputHandler>( testServices: TestServices, override val artifactKind: BackendKind, + failureDisablesNextSteps: Boolean, doNotRunIfThereWerePreviousFailures: Boolean -) : AnalysisHandler(testServices, doNotRunIfThereWerePreviousFailures) +) : AnalysisHandler(testServices, failureDisablesNextSteps, doNotRunIfThereWerePreviousFailures) abstract class BinaryArtifactHandler>( testServices: TestServices, override val artifactKind: BinaryKind, + failureDisablesNextSteps: Boolean, doNotRunIfThereWerePreviousFailures: Boolean -) : AnalysisHandler(testServices, doNotRunIfThereWerePreviousFailures) +) : AnalysisHandler(testServices, failureDisablesNextSteps, doNotRunIfThereWerePreviousFailures) diff --git a/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/backend/handlers/AbstractIrHandler.kt b/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/backend/handlers/AbstractIrHandler.kt index ddfb1a5606d..4526ed0d70f 100644 --- a/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/backend/handlers/AbstractIrHandler.kt +++ b/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/backend/handlers/AbstractIrHandler.kt @@ -12,5 +12,6 @@ import org.jetbrains.kotlin.test.services.TestServices abstract class AbstractIrHandler( testServices: TestServices, + failureDisablesNextSteps: Boolean = false, doNotRunIfThereWerePreviousFailures: Boolean = false -) : BackendInputHandler(testServices, BackendKinds.IrBackend, doNotRunIfThereWerePreviousFailures) +) : BackendInputHandler(testServices, BackendKinds.IrBackend, failureDisablesNextSteps, doNotRunIfThereWerePreviousFailures) diff --git a/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/backend/handlers/BinaryArtifactHandlers.kt b/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/backend/handlers/BinaryArtifactHandlers.kt index 2ae59632869..24a858d9f82 100644 --- a/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/backend/handlers/BinaryArtifactHandlers.kt +++ b/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/backend/handlers/BinaryArtifactHandlers.kt @@ -12,27 +12,33 @@ import org.jetbrains.kotlin.test.services.TestServices abstract class JvmBinaryArtifactHandler( testServices: TestServices, + failureDisablesNextSteps: Boolean = false, doNotRunIfThereWerePreviousFailures: Boolean = false ) : BinaryArtifactHandler( testServices, ArtifactKinds.Jvm, + failureDisablesNextSteps, doNotRunIfThereWerePreviousFailures ) abstract class JsBinaryArtifactHandler( testServices: TestServices, + failureDisablesNextSteps: Boolean = false, doNotRunIfThereWerePreviousFailures: Boolean = false ) : BinaryArtifactHandler( testServices, ArtifactKinds.Js, + failureDisablesNextSteps, doNotRunIfThereWerePreviousFailures ) abstract class NativeBinaryArtifactHandler( testServices: TestServices, + failureDisablesNextSteps: Boolean = false, doNotRunIfThereWerePreviousFailures: Boolean = false ) : BinaryArtifactHandler( testServices, ArtifactKinds.Native, + failureDisablesNextSteps, doNotRunIfThereWerePreviousFailures ) diff --git a/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/backend/handlers/NoCompilationErrorsHandler.kt b/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/backend/handlers/NoCompilationErrorsHandler.kt index 7fb53fdb433..07516602e42 100644 --- a/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/backend/handlers/NoCompilationErrorsHandler.kt +++ b/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/backend/handlers/NoCompilationErrorsHandler.kt @@ -14,7 +14,10 @@ import org.jetbrains.kotlin.test.frontend.classic.handlers.ClassicFrontendAnalys import org.jetbrains.kotlin.test.model.TestModule import org.jetbrains.kotlin.test.services.TestServices -class NoCompilationErrorsHandler(testServices: TestServices) : ClassicFrontendAnalysisHandler(testServices) { +class NoCompilationErrorsHandler(testServices: TestServices) : ClassicFrontendAnalysisHandler( + testServices, + failureDisablesNextSteps = true +) { override val directivesContainers: List get() = listOf(CodegenTestDirectives) diff --git a/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/backend/handlers/NoFirCompilationErrorsHandler.kt b/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/backend/handlers/NoFirCompilationErrorsHandler.kt index de08fdae0eb..a25be5c8fd7 100644 --- a/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/backend/handlers/NoFirCompilationErrorsHandler.kt +++ b/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/backend/handlers/NoFirCompilationErrorsHandler.kt @@ -21,7 +21,7 @@ import org.jetbrains.kotlin.test.frontend.fir.handlers.FirAnalysisHandler import org.jetbrains.kotlin.test.model.TestModule import org.jetbrains.kotlin.test.services.TestServices -class NoFirCompilationErrorsHandler(testServices: TestServices) : FirAnalysisHandler(testServices) { +class NoFirCompilationErrorsHandler(testServices: TestServices) : FirAnalysisHandler(testServices, failureDisablesNextSteps = true) { override val directivesContainers: List get() = listOf(CodegenTestDirectives) diff --git a/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/frontend/classic/handlers/ClassicFrontendAnalysisHandler.kt b/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/frontend/classic/handlers/ClassicFrontendAnalysisHandler.kt index 7be2d8574b2..90b031d8d45 100644 --- a/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/frontend/classic/handlers/ClassicFrontendAnalysisHandler.kt +++ b/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/frontend/classic/handlers/ClassicFrontendAnalysisHandler.kt @@ -12,10 +12,12 @@ import org.jetbrains.kotlin.test.services.TestServices abstract class ClassicFrontendAnalysisHandler( testServices: TestServices, + failureDisablesNextSteps: Boolean = false, doNotRunIfThereWerePreviousFailures: Boolean = false ) : FrontendOutputHandler( testServices, FrontendKinds.ClassicFrontend, + failureDisablesNextSteps, doNotRunIfThereWerePreviousFailures ) diff --git a/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/frontend/fir/handlers/FirAnalysisHandler.kt b/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/frontend/fir/handlers/FirAnalysisHandler.kt index f6026ff0ba8..3c7df6fd5c7 100644 --- a/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/frontend/fir/handlers/FirAnalysisHandler.kt +++ b/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/frontend/fir/handlers/FirAnalysisHandler.kt @@ -13,8 +13,14 @@ import java.io.File abstract class FirAnalysisHandler( testServices: TestServices, + failureDisablesNextSteps: Boolean = false, doNotRunIfThereWerePreviousFailures: Boolean = false -) : FrontendOutputHandler(testServices, FrontendKinds.FIR, doNotRunIfThereWerePreviousFailures) { +) : FrontendOutputHandler( + testServices, + FrontendKinds.FIR, + failureDisablesNextSteps, + doNotRunIfThereWerePreviousFailures +) { protected val File.nameWithoutFirExtension: String get() = nameWithoutExtension.removeSuffix(".fir") }