Skip to content

Try another approach to mark hanging generated tests #371 #554

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ import org.utbot.framework.plugin.api.util.objectClassId
import org.utbot.framework.plugin.api.util.shortArrayClassId
import org.utbot.framework.plugin.api.util.voidClassId
import java.io.File
import org.utbot.framework.plugin.api.util.longClassId
import org.utbot.framework.plugin.api.util.voidWrapperClassId

data class TestClassFile(val packageName: String, val imports: List<Import>, val testClass: String)

Expand Down Expand Up @@ -410,6 +412,19 @@ object Junit5 : TestFramework("JUnit5") {
simpleName = "TimeUnit"
)

val durationClassId = BuiltinClassId(
name = "Duration",
canonicalName = "java.time.Duration",
simpleName = "Duration"
)

val ofMillis = builtinStaticMethodId(
classId = durationClassId,
name = "ofMillis",
returnType = durationClassId,
arguments = arrayOf(longClassId)
)

override val testAnnotationId = BuiltinClassId(
name = "$JUNIT5_PACKAGE.Test",
canonicalName = "$JUNIT5_PACKAGE.Test",
Expand Down Expand Up @@ -447,6 +462,16 @@ object Junit5 : TestFramework("JUnit5") {
)
)

val assertTimeoutPreemptively = builtinStaticMethodId(
classId = assertionsClass,
name = "assertTimeoutPreemptively",
returnType = voidWrapperClassId,
arguments = arrayOf(
durationClassId,
executableClassId
)
)

val displayNameClassId = BuiltinClassId(
name = "$JUNIT5_PACKAGE.DisplayName",
canonicalName = "$JUNIT5_PACKAGE.DisplayName",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -361,11 +361,17 @@ internal class CgMethodConstructor(val context: CgContext) : CgContextOwner by c
return
}

when (exception) {
is TimeoutException -> {
methodType = TIMEOUT
writeWarningAboutTimeoutExceeding()
if (shouldTestPassWithTimeoutException(execution, exception)) {
writeWarningAboutTimeoutExceeding()
testFrameworkManager.expectTimeout(hangingTestsTimeout.timeoutMs) {
methodInvocationBlock()
}
methodType = TIMEOUT

return
}

when (exception) {
is ConcreteExecutionFailureException -> {
methodType = CRASH
writeWarningAboutCrash()
Expand All @@ -388,6 +394,10 @@ internal class CgMethodConstructor(val context: CgContext) : CgContextOwner by c
return exceptionRequiresAssert || exceptionIsExplicit
}

private fun shouldTestPassWithTimeoutException(execution: UtExecution, exception: Throwable): Boolean {
return execution.result is UtTimeoutException || exception is TimeoutException
}

private fun writeWarningAboutTimeoutExceeding() {
+CgMultilineComment(
listOf(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,8 @@ internal abstract class TestFrameworkManager(val context: CgContext)
// TestNg allows both approaches, we use similar to JUnit5
abstract fun expectException(exception: ClassId, block: () -> Unit)

open fun expectTimeout(timeoutMs: Long, block: () -> Unit) {}

open fun setTestExecutionTimeout(timeoutMs: Long) {
val timeout = CgNamedAnnotationArgument(
name = timeoutArgumentName,
Expand Down Expand Up @@ -327,6 +329,14 @@ internal class Junit5Manager(context: CgContext) : TestFrameworkManager(context)
+assertions[assertThrows](exception.toExceptionClass(), lambda)
}

override fun expectTimeout(timeoutMs : Long, block: () -> Unit) {
require(testFramework is Junit5) { "According to settings, JUnit5 was expected, but got: $testFramework" }
val lambda = statementConstructor.lambda(testFramework.executableClassId) { block() }
importIfNeeded(testFramework.durationClassId)
val duration = CgMethodCall(null, testFramework.ofMillis, listOf(timeoutMs.resolve()))
+assertions[testFramework.assertTimeoutPreemptively](duration, lambda)
}

override fun addDisplayName(name: String) {
require(testFramework is Junit5) { "According to settings, JUnit5 was expected, but got: $testFramework" }
collectedTestMethodAnnotations += statementConstructor.annotation(testFramework.displayNameClassId, name)
Expand Down