Skip to content
Merged
Show file tree
Hide file tree
Changes from 14 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
@@ -1,6 +1,5 @@
package org.evomaster.core.output.dto

import org.evomaster.core.output.Lines
import org.evomaster.core.output.OutputFormat
import java.nio.file.Path

Expand All @@ -12,12 +11,14 @@ import java.nio.file.Path
interface DtoOutput {

/**
* Writes a DTO class in the corresponding [org.evomaster.core.output.OutputFormat].
*
* @param outputFormat under which the java class must be written
* @param testSuitePath under which the java class must be written
* @param testSuitePackage under which the java class must be written
* @param outputFormat forwarded to the [Lines] helper class and for setting the .java extension in the generated file
* @param dtoClass to be written to filesystem
*/
fun writeClass(testSuitePath: Path, testSuitePackage: String, outputFormat: OutputFormat, dtoClass: DtoClass)
fun writeClass(outputFormat: OutputFormat, testSuitePath: Path, testSuitePackage: String, dtoClass: DtoClass)

/**
* @param dtoName that will be instantiated for payload
Expand Down
23 changes: 6 additions & 17 deletions core/src/main/kotlin/org/evomaster/core/output/dto/DtoWriter.kt
Original file line number Diff line number Diff line change
Expand Up @@ -49,24 +49,13 @@ class DtoWriter(

fun write(testSuitePath: Path, testSuitePackage: String, solution: Solution<*>) {
calculateDtos(solution)
val dtoOutput = when {
outputFormat.isJava() -> JavaDtoOutput()
outputFormat.isKotlin() -> KotlinDtoOutput()
else -> throw IllegalStateException("$outputFormat output format does not support DTOs as request payloads.")
}
dtoCollector.forEach {
when {
outputFormat.isJava() -> JavaDtoOutput().writeClass(
testSuitePath,
testSuitePackage,
outputFormat,
it.value
)

outputFormat.isKotlin() -> KotlinDtoOutput().writeClass(
testSuitePath,
testSuitePackage,
outputFormat,
it.value
)

else -> throw IllegalStateException("$outputFormat output format does not support DTOs as request payloads.")
}
dtoOutput.writeClass(outputFormat, testSuitePath, testSuitePackage, it.value)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import java.nio.file.Path

class JavaDtoOutput: JvmDtoOutput() {

override fun writeClass(testSuitePath: Path, testSuitePackage: String, outputFormat: OutputFormat, dtoClass: DtoClass) {
override fun writeClass(outputFormat: OutputFormat, testSuitePath: Path, testSuitePackage: String, dtoClass: DtoClass) {
val dtoFilename = TestSuiteFileName(appendDtoPackage(dtoClass.name))
val lines = Lines(outputFormat)
setPackage(lines, testSuitePackage)
Expand Down Expand Up @@ -81,4 +81,5 @@ class JavaDtoOutput: JvmDtoOutput() {
lines.addEmpty()
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import java.nio.file.Path

class KotlinDtoOutput: JvmDtoOutput() {

override fun writeClass(testSuitePath: Path, testSuitePackage: String, outputFormat: OutputFormat, dtoClass: DtoClass) {
override fun writeClass(outputFormat: OutputFormat, testSuitePath: Path, testSuitePackage: String, dtoClass: DtoClass) {
val dtoFilename = TestSuiteFileName(appendDtoPackage(dtoClass.name))
val lines = Lines(outputFormat)
setPackage(lines, testSuitePackage)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import org.evomaster.core.output.auth.CookieWriter
import org.evomaster.core.output.auth.TokenWriter
import org.evomaster.core.output.dto.DtoCall
import org.evomaster.core.output.dto.GeneToDto
import org.evomaster.core.output.formatter.OutputFormatter
import org.evomaster.core.problem.enterprise.EnterpriseActionGroup
import org.evomaster.core.problem.externalservice.httpws.HttpExternalServiceAction
import org.evomaster.core.problem.httpws.HttpWsAction
Expand Down Expand Up @@ -123,8 +124,7 @@ abstract class HttpWsTestCaseWriter : ApiTestCaseWriter() {

private fun writeDto(call: HttpWsAction, lines: Lines): String {
val bodyParam = call.parameters.find { p -> p is BodyParam } as BodyParam?
if (bodyParam != null && bodyParam.isJson()) {

if (bodyParam != null && bodyParam.isJson() && payloadIsValidJson(bodyParam)) {
val primaryGene = bodyParam.primaryGene()
val choiceGene = primaryGene.getWrappedGene(ChoiceGene::class.java)
val actionName = call.getName()
Expand All @@ -147,6 +147,15 @@ abstract class HttpWsTestCaseWriter : ApiTestCaseWriter() {
return ""
}

/*
* Control characters break JSON and transform it into an invalid payload. If there's any invalid character
* then we'll avoid using DTOs and have the payload in the test case be represented by the raw JSON string.
*/
private fun payloadIsValidJson(bodyParam: BodyParam): Boolean {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this function, or parts of it (if taking as input a string and not a BodyParam), should go to org.evomaster.core.output.JsonUtils . also, we need unit tests for it, to make sure it works (eg, you can re-use the exact same JSON payload that was failing the E2E test)

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

actually, looks like there is also a TestWriterUtils in the same package having functions for JSON, including a call to OutputFormatter.JSON_FORMATTER.isValid(json) where the same type of check is done. maybe better to call that directly

val json = bodyParam.getValueAsPrintableString(mode = GeneUtils.EscapeMode.JSON, targetFormat = format)
return OutputFormatter.JSON_FORMATTER.isValid(json)
}

private fun generateDtoCall(gene: Gene, actionName: String, lines: Lines): DtoCall {
val geneToDto = GeneToDto(format)

Expand Down