[Test] Add ability to stop test pipeline if there was an exception in handler
This commit is contained in:
@@ -61,7 +61,8 @@ class TestRunner(private val testConfiguration: TestConfiguration) {
|
|||||||
var failedException: Throwable? = null
|
var failedException: Throwable? = null
|
||||||
try {
|
try {
|
||||||
for (module in modules) {
|
for (module in modules) {
|
||||||
processModule(services, module, dependencyProvider, moduleStructure)
|
val shouldProcessNextModules = processModule(services, module, dependencyProvider, moduleStructure)
|
||||||
|
if (!shouldProcessNextModules) break
|
||||||
}
|
}
|
||||||
} catch (e: Throwable) {
|
} catch (e: Throwable) {
|
||||||
failedException = e
|
failedException = e
|
||||||
@@ -101,41 +102,47 @@ class TestRunner(private val testConfiguration: TestConfiguration) {
|
|||||||
}
|
}
|
||||||
.map { if (it is ExceptionFromTestError) it.cause else it }
|
.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(
|
private fun processModule(
|
||||||
services: TestServices,
|
services: TestServices,
|
||||||
module: TestModule,
|
module: TestModule,
|
||||||
dependencyProvider: DependencyProviderImpl,
|
dependencyProvider: DependencyProviderImpl,
|
||||||
moduleStructure: TestModuleStructure
|
moduleStructure: TestModuleStructure
|
||||||
) {
|
): Boolean {
|
||||||
val sourcesArtifact = ResultingArtifact.Source()
|
val sourcesArtifact = ResultingArtifact.Source()
|
||||||
|
|
||||||
val frontendKind = module.frontendKind
|
val frontendKind = module.frontendKind
|
||||||
if (!frontendKind.shouldRunAnalysis) return
|
if (!frontendKind.shouldRunAnalysis) return true
|
||||||
|
|
||||||
val frontendArtifacts: ResultingArtifact.FrontendOutput<*> = testConfiguration.getFacade(SourcesKind, frontendKind)
|
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<AnalysisHandler<*>> = testConfiguration.getHandlers(frontendKind)
|
val frontendHandlers: List<AnalysisHandler<*>> = testConfiguration.getHandlers(frontendKind)
|
||||||
for (frontendHandler in frontendHandlers) {
|
for (frontendHandler in frontendHandlers) {
|
||||||
withAssertionCatching {
|
val thereWasAnException = withAssertionCatching {
|
||||||
if (frontendHandler.shouldRun(failedAssertions.isNotEmpty())) {
|
if (frontendHandler.shouldRun(failedAssertions.isNotEmpty())) {
|
||||||
frontendHandler.hackyProcess(module, frontendArtifacts)
|
frontendHandler.hackyProcess(module, frontendArtifacts)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (thereWasAnException && frontendHandler.failureDisablesNextSteps) return false
|
||||||
}
|
}
|
||||||
|
|
||||||
val backendKind = services.backendKindExtractor.backendKind(module.targetBackend)
|
val backendKind = services.backendKindExtractor.backendKind(module.targetBackend)
|
||||||
if (!backendKind.shouldRunAnalysis) return
|
if (!backendKind.shouldRunAnalysis) return true
|
||||||
|
|
||||||
val backendInputInfo = testConfiguration.getFacade(frontendKind, backendKind)
|
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<AnalysisHandler<*>> = testConfiguration.getHandlers(backendKind)
|
val backendHandlers: List<AnalysisHandler<*>> = testConfiguration.getHandlers(backendKind)
|
||||||
for (backendHandler in backendHandlers) {
|
for (backendHandler in backendHandlers) {
|
||||||
withAssertionCatching {
|
val thereWasAnException = withAssertionCatching {
|
||||||
if (backendHandler.shouldRun(failedAssertions.isNotEmpty())) {
|
if (backendHandler.shouldRun(failedAssertions.isNotEmpty())) {
|
||||||
backendHandler.hackyProcess(module, backendInputInfo)
|
backendHandler.hackyProcess(module, backendInputInfo)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (thereWasAnException && backendHandler.failureDisablesNextSteps) return false
|
||||||
}
|
}
|
||||||
|
|
||||||
for (artifactKind in moduleStructure.getTargetArtifactKinds(module)) {
|
for (artifactKind in moduleStructure.getTargetArtifactKinds(module)) {
|
||||||
@@ -143,28 +150,36 @@ class TestRunner(private val testConfiguration: TestConfiguration) {
|
|||||||
val binaryArtifact = testConfiguration.getFacade(backendKind, artifactKind)
|
val binaryArtifact = testConfiguration.getFacade(backendKind, artifactKind)
|
||||||
.hackyTransform(module, backendInputInfo)?.also {
|
.hackyTransform(module, backendInputInfo)?.also {
|
||||||
dependencyProvider.registerArtifact(module, it)
|
dependencyProvider.registerArtifact(module, it)
|
||||||
} ?: return
|
} ?: return true
|
||||||
|
|
||||||
val binaryHandlers: List<AnalysisHandler<*>> = testConfiguration.getHandlers(artifactKind)
|
val binaryHandlers: List<AnalysisHandler<*>> = testConfiguration.getHandlers(artifactKind)
|
||||||
for (binaryHandler in binaryHandlers) {
|
for (binaryHandler in binaryHandlers) {
|
||||||
withAssertionCatching {
|
val thereWasAnException = withAssertionCatching {
|
||||||
if (binaryHandler.shouldRun(failedAssertions.isNotEmpty())) {
|
if (binaryHandler.shouldRun(failedAssertions.isNotEmpty())) {
|
||||||
binaryHandler.hackyProcess(module, binaryArtifact)
|
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()
|
block()
|
||||||
|
false
|
||||||
} catch (e: Throwable) {
|
} catch (e: Throwable) {
|
||||||
if (insertExceptionInStart) {
|
if (insertExceptionInStart) {
|
||||||
failedAssertions.add(0, e)
|
failedAssertions.add(0, e)
|
||||||
} else {
|
} else {
|
||||||
failedAssertions += e
|
failedAssertions += e
|
||||||
}
|
}
|
||||||
|
true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+7
-3
@@ -13,6 +13,7 @@ import org.jetbrains.kotlin.test.services.assertions
|
|||||||
|
|
||||||
abstract class AnalysisHandler<A : ResultingArtifact<A>>(
|
abstract class AnalysisHandler<A : ResultingArtifact<A>>(
|
||||||
val testServices: TestServices,
|
val testServices: TestServices,
|
||||||
|
val failureDisablesNextSteps: Boolean,
|
||||||
val doNotRunIfThereWerePreviousFailures: Boolean
|
val doNotRunIfThereWerePreviousFailures: Boolean
|
||||||
) {
|
) {
|
||||||
protected val assertions: Assertions
|
protected val assertions: Assertions
|
||||||
@@ -34,17 +35,20 @@ abstract class AnalysisHandler<A : ResultingArtifact<A>>(
|
|||||||
abstract class FrontendOutputHandler<R : ResultingArtifact.FrontendOutput<R>>(
|
abstract class FrontendOutputHandler<R : ResultingArtifact.FrontendOutput<R>>(
|
||||||
testServices: TestServices,
|
testServices: TestServices,
|
||||||
override val artifactKind: FrontendKind<R>,
|
override val artifactKind: FrontendKind<R>,
|
||||||
|
failureDisablesNextSteps: Boolean,
|
||||||
doNotRunIfThereWerePreviousFailures: Boolean
|
doNotRunIfThereWerePreviousFailures: Boolean
|
||||||
) : AnalysisHandler<R>(testServices, doNotRunIfThereWerePreviousFailures)
|
) : AnalysisHandler<R>(testServices, failureDisablesNextSteps, doNotRunIfThereWerePreviousFailures)
|
||||||
|
|
||||||
abstract class BackendInputHandler<I : ResultingArtifact.BackendInput<I>>(
|
abstract class BackendInputHandler<I : ResultingArtifact.BackendInput<I>>(
|
||||||
testServices: TestServices,
|
testServices: TestServices,
|
||||||
override val artifactKind: BackendKind<I>,
|
override val artifactKind: BackendKind<I>,
|
||||||
|
failureDisablesNextSteps: Boolean,
|
||||||
doNotRunIfThereWerePreviousFailures: Boolean
|
doNotRunIfThereWerePreviousFailures: Boolean
|
||||||
) : AnalysisHandler<I>(testServices, doNotRunIfThereWerePreviousFailures)
|
) : AnalysisHandler<I>(testServices, failureDisablesNextSteps, doNotRunIfThereWerePreviousFailures)
|
||||||
|
|
||||||
abstract class BinaryArtifactHandler<A : ResultingArtifact.Binary<A>>(
|
abstract class BinaryArtifactHandler<A : ResultingArtifact.Binary<A>>(
|
||||||
testServices: TestServices,
|
testServices: TestServices,
|
||||||
override val artifactKind: BinaryKind<A>,
|
override val artifactKind: BinaryKind<A>,
|
||||||
|
failureDisablesNextSteps: Boolean,
|
||||||
doNotRunIfThereWerePreviousFailures: Boolean
|
doNotRunIfThereWerePreviousFailures: Boolean
|
||||||
) : AnalysisHandler<A>(testServices, doNotRunIfThereWerePreviousFailures)
|
) : AnalysisHandler<A>(testServices, failureDisablesNextSteps, doNotRunIfThereWerePreviousFailures)
|
||||||
|
|||||||
+2
-1
@@ -12,5 +12,6 @@ import org.jetbrains.kotlin.test.services.TestServices
|
|||||||
|
|
||||||
abstract class AbstractIrHandler(
|
abstract class AbstractIrHandler(
|
||||||
testServices: TestServices,
|
testServices: TestServices,
|
||||||
|
failureDisablesNextSteps: Boolean = false,
|
||||||
doNotRunIfThereWerePreviousFailures: Boolean = false
|
doNotRunIfThereWerePreviousFailures: Boolean = false
|
||||||
) : BackendInputHandler<IrBackendInput>(testServices, BackendKinds.IrBackend, doNotRunIfThereWerePreviousFailures)
|
) : BackendInputHandler<IrBackendInput>(testServices, BackendKinds.IrBackend, failureDisablesNextSteps, doNotRunIfThereWerePreviousFailures)
|
||||||
|
|||||||
+6
@@ -12,27 +12,33 @@ import org.jetbrains.kotlin.test.services.TestServices
|
|||||||
|
|
||||||
abstract class JvmBinaryArtifactHandler(
|
abstract class JvmBinaryArtifactHandler(
|
||||||
testServices: TestServices,
|
testServices: TestServices,
|
||||||
|
failureDisablesNextSteps: Boolean = false,
|
||||||
doNotRunIfThereWerePreviousFailures: Boolean = false
|
doNotRunIfThereWerePreviousFailures: Boolean = false
|
||||||
) : BinaryArtifactHandler<BinaryArtifacts.Jvm>(
|
) : BinaryArtifactHandler<BinaryArtifacts.Jvm>(
|
||||||
testServices,
|
testServices,
|
||||||
ArtifactKinds.Jvm,
|
ArtifactKinds.Jvm,
|
||||||
|
failureDisablesNextSteps,
|
||||||
doNotRunIfThereWerePreviousFailures
|
doNotRunIfThereWerePreviousFailures
|
||||||
)
|
)
|
||||||
|
|
||||||
abstract class JsBinaryArtifactHandler(
|
abstract class JsBinaryArtifactHandler(
|
||||||
testServices: TestServices,
|
testServices: TestServices,
|
||||||
|
failureDisablesNextSteps: Boolean = false,
|
||||||
doNotRunIfThereWerePreviousFailures: Boolean = false
|
doNotRunIfThereWerePreviousFailures: Boolean = false
|
||||||
) : BinaryArtifactHandler<BinaryArtifacts.Js>(
|
) : BinaryArtifactHandler<BinaryArtifacts.Js>(
|
||||||
testServices,
|
testServices,
|
||||||
ArtifactKinds.Js,
|
ArtifactKinds.Js,
|
||||||
|
failureDisablesNextSteps,
|
||||||
doNotRunIfThereWerePreviousFailures
|
doNotRunIfThereWerePreviousFailures
|
||||||
)
|
)
|
||||||
|
|
||||||
abstract class NativeBinaryArtifactHandler(
|
abstract class NativeBinaryArtifactHandler(
|
||||||
testServices: TestServices,
|
testServices: TestServices,
|
||||||
|
failureDisablesNextSteps: Boolean = false,
|
||||||
doNotRunIfThereWerePreviousFailures: Boolean = false
|
doNotRunIfThereWerePreviousFailures: Boolean = false
|
||||||
) : BinaryArtifactHandler<BinaryArtifacts.Native>(
|
) : BinaryArtifactHandler<BinaryArtifacts.Native>(
|
||||||
testServices,
|
testServices,
|
||||||
ArtifactKinds.Native,
|
ArtifactKinds.Native,
|
||||||
|
failureDisablesNextSteps,
|
||||||
doNotRunIfThereWerePreviousFailures
|
doNotRunIfThereWerePreviousFailures
|
||||||
)
|
)
|
||||||
|
|||||||
+4
-1
@@ -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.model.TestModule
|
||||||
import org.jetbrains.kotlin.test.services.TestServices
|
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<DirectivesContainer>
|
override val directivesContainers: List<DirectivesContainer>
|
||||||
get() = listOf(CodegenTestDirectives)
|
get() = listOf(CodegenTestDirectives)
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -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.model.TestModule
|
||||||
import org.jetbrains.kotlin.test.services.TestServices
|
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<DirectivesContainer>
|
override val directivesContainers: List<DirectivesContainer>
|
||||||
get() = listOf(CodegenTestDirectives)
|
get() = listOf(CodegenTestDirectives)
|
||||||
|
|
||||||
|
|||||||
+2
@@ -12,10 +12,12 @@ import org.jetbrains.kotlin.test.services.TestServices
|
|||||||
|
|
||||||
abstract class ClassicFrontendAnalysisHandler(
|
abstract class ClassicFrontendAnalysisHandler(
|
||||||
testServices: TestServices,
|
testServices: TestServices,
|
||||||
|
failureDisablesNextSteps: Boolean = false,
|
||||||
doNotRunIfThereWerePreviousFailures: Boolean = false
|
doNotRunIfThereWerePreviousFailures: Boolean = false
|
||||||
) : FrontendOutputHandler<ClassicFrontendOutputArtifact>(
|
) : FrontendOutputHandler<ClassicFrontendOutputArtifact>(
|
||||||
testServices,
|
testServices,
|
||||||
FrontendKinds.ClassicFrontend,
|
FrontendKinds.ClassicFrontend,
|
||||||
|
failureDisablesNextSteps,
|
||||||
doNotRunIfThereWerePreviousFailures
|
doNotRunIfThereWerePreviousFailures
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
+7
-1
@@ -13,8 +13,14 @@ import java.io.File
|
|||||||
|
|
||||||
abstract class FirAnalysisHandler(
|
abstract class FirAnalysisHandler(
|
||||||
testServices: TestServices,
|
testServices: TestServices,
|
||||||
|
failureDisablesNextSteps: Boolean = false,
|
||||||
doNotRunIfThereWerePreviousFailures: Boolean = false
|
doNotRunIfThereWerePreviousFailures: Boolean = false
|
||||||
) : FrontendOutputHandler<FirOutputArtifact>(testServices, FrontendKinds.FIR, doNotRunIfThereWerePreviousFailures) {
|
) : FrontendOutputHandler<FirOutputArtifact>(
|
||||||
|
testServices,
|
||||||
|
FrontendKinds.FIR,
|
||||||
|
failureDisablesNextSteps,
|
||||||
|
doNotRunIfThereWerePreviousFailures
|
||||||
|
) {
|
||||||
protected val File.nameWithoutFirExtension: String
|
protected val File.nameWithoutFirExtension: String
|
||||||
get() = nameWithoutExtension.removeSuffix(".fir")
|
get() = nameWithoutExtension.removeSuffix(".fir")
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user