Skip to content
Open
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
15 changes: 15 additions & 0 deletions core/src/main/kotlin/org/evomaster/core/EMConfig.kt
Original file line number Diff line number Diff line change
Expand Up @@ -806,6 +806,15 @@ class EMConfig {
throw ConfigProblemException("When using the seedTestCases option, you must specify the file path of the test cases with the seedTestCasesPath option")
}

if (problemType == ProblemType.ASYNCAPI && createTests) {
throw ConfigProblemException("Test generation for AsyncAPI services is not available yet." +
" For the time being, run with '--createTests false' to only search for faults.")
}

if (problemType == ProblemType.ASYNCAPI && seedTestCases) {
throw ConfigProblemException("Seeding test cases is not supported for AsyncAPI services yet")
}

if (problemType == ProblemType.RPC
&& createTests
&& (enablePureRPCTestGeneration || enableRPCAssertionWithInstance)
Expand Down Expand Up @@ -2836,6 +2845,12 @@ class EMConfig {
@Cfg("Whether to enable extra targets for responses, e.g., regarding nullable response, having extra targets for whether it is null")
var enableRPCExtraResponseTargets = true

@Experimental
@Cfg("When testing an AsyncAPI service, how long to wait for the reply to a published message before" +
" treating it as unanswered, in milliseconds.")
@Min(1.0)
var asyncApiReplyTimeoutMs = 5000

@Cfg("Whether to enable customized responses indicating business logic")
var enableRPCCustomizedResponseTargets = true

Expand Down
17 changes: 15 additions & 2 deletions core/src/main/kotlin/org/evomaster/core/Main.kt
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import org.evomaster.core.output.TestSuiteSplitter
import org.evomaster.core.output.clustering.SplitResult
import org.evomaster.core.output.service.TestSuiteWriter
import org.evomaster.core.problem.asyncapi.data.AsyncApiIndividual
import org.evomaster.core.problem.asyncapi.service.AsyncApiModule
import org.evomaster.core.problem.enterprise.service.WFCReportWriter
import org.evomaster.core.problem.externalservice.httpws.service.HarvestActualHttpWsResponseHandler
import org.evomaster.core.problem.externalservice.httpws.service.HttpWsExternalServiceHandler
Expand Down Expand Up @@ -571,6 +572,18 @@ class Main {
config.problemType = EMConfig.ProblemType.WEBFRONTEND
} else if (info.asyncApiProblem != null) {
config.problemType = EMConfig.ProblemType.ASYNCAPI
if (config.createTests) {
/*
There is no test writer for AsyncAPI yet, and the constraints checked
below refuse the combination. As the problem type was inferred rather
than asked for, turning test generation off is better than failing.
*/
LoggingUtil.uniqueUserWarn(
"The driver describes an AsyncAPI service, for which test generation is not" +
" available yet. Continuing with 'createTests' off."
)
config.createTests = false
}
} else {
throw IllegalStateException("Can connect to the EM Driver, but cannot infer the 'problemType'")
}
Expand Down Expand Up @@ -627,8 +640,8 @@ class Main {
}

EMConfig.ProblemType.ASYNCAPI -> {
//the sampler, fitness and module for it are being added one at a time
throw IllegalStateException("AsyncAPI is not wired into the search yet")
//one module for both modes: the driver is needed either way, see EMConfig.usesDriver
AsyncApiModule()
}

//this should never happen, unless we add new type and forget to add it here
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
package org.evomaster.core.problem.asyncapi.data

import org.evomaster.core.problem.enterprise.EnterpriseActionResult
import org.evomaster.core.search.action.Action

/**
* What happened when one message was published: the outcome, and the reply when there was one.
*/
class AsyncApiCallResult : EnterpriseActionResult {

companion object {
const val OUTCOME = "OUTCOME"
const val REPLY_PAYLOAD = "REPLY_PAYLOAD"
const val REPLY_MESSAGE = "REPLY_MESSAGE"
const val CORRELATION_MATCHED = "CORRELATION_MATCHED"
const val WAITED_MS = "WAITED_MS"
}

constructor(sourceLocalId: String, stopping: Boolean = false) : super(sourceLocalId, stopping)

private constructor(other: AsyncApiCallResult) : super(other)

override fun copy(): AsyncApiCallResult {
return AsyncApiCallResult(this)
}

override fun matchedType(action: Action): Boolean {
return action is AsyncApiAction
}

fun setOutcome(outcome: AsyncApiOutcome) {
addResultValue(OUTCOME, outcome.name)
}

fun getOutcome(): AsyncApiOutcome? = getResultValue(OUTCOME)?.let { AsyncApiOutcome.valueOf(it) }

fun setReplyPayload(payload: String) {
addResultValue(REPLY_PAYLOAD, payload)
}

fun getReplyPayload(): String? = getResultValue(REPLY_PAYLOAD)

/**
* Which of the messages the contract declares for the reply this one was recognised as.
*/
fun setReplyMessage(messageId: String) {
addResultValue(REPLY_MESSAGE, messageId)
}

fun getReplyMessage(): String? = getResultValue(REPLY_MESSAGE)

fun setCorrelationMatched(matched: Boolean) {
addResultValue(CORRELATION_MATCHED, matched.toString())
}

fun getCorrelationMatched(): Boolean? = getResultValue(CORRELATION_MATCHED)?.toBoolean()

fun setWaitedMs(ms: Long) {
addResultValue(WAITED_MS, ms.toString())
}

fun getWaitedMs(): Long? = getResultValue(WAITED_MS)?.toLong()
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package org.evomaster.core.problem.asyncapi.data

/**
* What came of publishing one message, as the driver reported it.
*/
enum class AsyncApiOutcome {

/**
* Published, and no reply was expected.
*/
PUBLISHED,

/**
* Published, and a reply arrived that answers it.
*/
REPLIED,

/**
* Published, a reply was expected, and none arrived within the time waited.
*/
NO_REPLY,

/**
* The driver could not put the message on the wire at all.
*/
PUBLISH_FAILED
}
Loading
Loading