From 373c0522441326889adde5e7d14b62e1c6f477a7 Mon Sep 17 00:00:00 2001 From: arcuri82 Date: Tue, 19 Mar 2024 22:37:23 +0100 Subject: [PATCH 01/10] working on new integration tests for REST --- core-it/pom.xml | 7 +++++++ .../core/problem/rest/IntegrationTestRestBase.kt | 9 +++++++++ .../core/problem/rest/RestIndividualSelectorUtilsTest.kt | 6 ++++++ 3 files changed, 22 insertions(+) create mode 100644 core-it/src/test/kotlin/org/evomaster/core/problem/rest/IntegrationTestRestBase.kt create mode 100644 core-it/src/test/kotlin/org/evomaster/core/problem/rest/RestIndividualSelectorUtilsTest.kt diff --git a/core-it/pom.xml b/core-it/pom.xml index 14c4fe2da7..9ea28d2128 100644 --- a/core-it/pom.xml +++ b/core-it/pom.xml @@ -86,6 +86,13 @@ spring-boot-starter-web + + org.evomaster + evomaster-e2e-tests-utils + test-jar + ${project.version} + + diff --git a/core-it/src/test/kotlin/org/evomaster/core/problem/rest/IntegrationTestRestBase.kt b/core-it/src/test/kotlin/org/evomaster/core/problem/rest/IntegrationTestRestBase.kt new file mode 100644 index 0000000000..b61af6b5e3 --- /dev/null +++ b/core-it/src/test/kotlin/org/evomaster/core/problem/rest/IntegrationTestRestBase.kt @@ -0,0 +1,9 @@ +package org.evomaster.core.problem.rest + +import org.evomaster.e2etests.utils.RestTestBase + +abstract class IntegrationTestRestBase : RestTestBase() { + + + +} \ No newline at end of file diff --git a/core-it/src/test/kotlin/org/evomaster/core/problem/rest/RestIndividualSelectorUtilsTest.kt b/core-it/src/test/kotlin/org/evomaster/core/problem/rest/RestIndividualSelectorUtilsTest.kt new file mode 100644 index 0000000000..aa5cf01c72 --- /dev/null +++ b/core-it/src/test/kotlin/org/evomaster/core/problem/rest/RestIndividualSelectorUtilsTest.kt @@ -0,0 +1,6 @@ +package org.evomaster.core.problem.rest + +class RestIndividualSelectorUtilsTest : IntegrationTestRestBase(){ + + //TODO +} \ No newline at end of file From 5dc218548c70d9d5f662b5ac63e86cb86964ad58 Mon Sep 17 00:00:00 2001 From: arcuri82 Date: Fri, 22 Mar 2024 13:38:17 +0100 Subject: [PATCH 02/10] deprecating old parser --- .../org/evomaster/core/problem/rest/seeding/AbstractParser.kt | 1 + .../kotlin/org/evomaster/core/problem/rest/seeding/Parser.kt | 2 ++ .../core/problem/rest/seeding/postman/PostmanParser.kt | 1 + 3 files changed, 4 insertions(+) diff --git a/core/src/main/kotlin/org/evomaster/core/problem/rest/seeding/AbstractParser.kt b/core/src/main/kotlin/org/evomaster/core/problem/rest/seeding/AbstractParser.kt index 27594560fb..c758342c46 100644 --- a/core/src/main/kotlin/org/evomaster/core/problem/rest/seeding/AbstractParser.kt +++ b/core/src/main/kotlin/org/evomaster/core/problem/rest/seeding/AbstractParser.kt @@ -28,6 +28,7 @@ import java.util.regex.Pattern * the set of default actions (i.e., actions representing single calls to each API * operation) and the Swagger specification. */ +@Deprecated("Code here will be replaced with intermediate representation. See new 'seeding' package") abstract class AbstractParser( protected val defaultRestCallActions: List, protected val swagger: OpenAPI diff --git a/core/src/main/kotlin/org/evomaster/core/problem/rest/seeding/Parser.kt b/core/src/main/kotlin/org/evomaster/core/problem/rest/seeding/Parser.kt index 90934b759f..8bc09ecba7 100644 --- a/core/src/main/kotlin/org/evomaster/core/problem/rest/seeding/Parser.kt +++ b/core/src/main/kotlin/org/evomaster/core/problem/rest/seeding/Parser.kt @@ -2,6 +2,8 @@ package org.evomaster.core.problem.rest.seeding import org.evomaster.core.problem.rest.RestCallAction + +@Deprecated("Code here will be replaced with intermediate representation. See new 'seeding' package") interface Parser { /** diff --git a/core/src/main/kotlin/org/evomaster/core/problem/rest/seeding/postman/PostmanParser.kt b/core/src/main/kotlin/org/evomaster/core/problem/rest/seeding/postman/PostmanParser.kt index 1069f5d4db..8c1591f74c 100644 --- a/core/src/main/kotlin/org/evomaster/core/problem/rest/seeding/postman/PostmanParser.kt +++ b/core/src/main/kotlin/org/evomaster/core/problem/rest/seeding/postman/PostmanParser.kt @@ -17,6 +17,7 @@ import java.lang.IllegalStateException import java.net.URLDecoder import java.nio.charset.StandardCharsets +@Deprecated("Code here will be replaced with intermediate representation. See new 'seeding' package") class PostmanParser( defaultRestCallActions: List, swagger: OpenAPI From 47f5677b1a428fffc20063e7cc6a3365389b6119 Mon Sep 17 00:00:00 2001 From: arcuri82 Date: Mon, 25 Mar 2024 22:47:01 +0100 Subject: [PATCH 03/10] starting basic parser --- .../evomaster/core/problem/api/param/Param.kt | 2 +- .../org/evomaster/core/search/gene/Gene.kt | 11 ++++ .../core/search/gene/string/StringGene.kt | 18 +++++- .../evomaster/core/seeding/PirToIndividual.kt | 17 +++++ .../evomaster/core/seeding/pir/PirTestCase.kt | 4 ++ .../evomaster/core/seeding/rest/PirToRest.kt | 62 +++++++++++++++++++ 6 files changed, 112 insertions(+), 2 deletions(-) create mode 100644 core/src/main/kotlin/org/evomaster/core/seeding/PirToIndividual.kt create mode 100644 core/src/main/kotlin/org/evomaster/core/seeding/pir/PirTestCase.kt create mode 100644 core/src/main/kotlin/org/evomaster/core/seeding/rest/PirToRest.kt diff --git a/core/src/main/kotlin/org/evomaster/core/problem/api/param/Param.kt b/core/src/main/kotlin/org/evomaster/core/problem/api/param/Param.kt index 84e5e48e7a..296837c82e 100644 --- a/core/src/main/kotlin/org/evomaster/core/problem/api/param/Param.kt +++ b/core/src/main/kotlin/org/evomaster/core/problem/api/param/Param.kt @@ -9,7 +9,7 @@ abstract class Param( val genes : MutableList ) : StructuralElement(genes){ - //TODO need refactoring + //TODO need refactoring. eg shared abstract class for cases in which only 1 gene for sure @Deprecated("Assumes there is only 1 gene") val gene : Gene = genes[0] diff --git a/core/src/main/kotlin/org/evomaster/core/search/gene/Gene.kt b/core/src/main/kotlin/org/evomaster/core/search/gene/Gene.kt index 39c7ea27dd..319fc1640f 100644 --- a/core/src/main/kotlin/org/evomaster/core/search/gene/Gene.kt +++ b/core/src/main/kotlin/org/evomaster/core/search/gene/Gene.kt @@ -767,6 +767,17 @@ abstract class Gene( open fun possiblySame(gene : Gene) : Boolean = gene.name == name && gene::class == this::class + /** + * Given a string value, apply it to the current state of this gene (and possibly recursively to its children). + * If it fails for any reason, return false, without modifying its state. + */ + open fun setFromStringValue(value: String) : Boolean{ + //TODO in future this should be abstract, to force each gene to handle it. + //few implementations can be based on AbstractParser class for Postman + throw IllegalStateException("setFromStringValue() is not implemented for gene ${this::class.simpleName}") + } + + //========================= handing binding genes =================================== //TODO make sure all public methods keep the gene in a valid state. diff --git a/core/src/main/kotlin/org/evomaster/core/search/gene/string/StringGene.kt b/core/src/main/kotlin/org/evomaster/core/search/gene/string/StringGene.kt index aa692b5c9f..a297c9e982 100644 --- a/core/src/main/kotlin/org/evomaster/core/search/gene/string/StringGene.kt +++ b/core/src/main/kotlin/org/evomaster/core/search/gene/string/StringGene.kt @@ -69,7 +69,7 @@ class StringGene( init { if (minLength>maxLength) { - throw IllegalArgumentException("Cannot create string gene ${this.name} with mininum length ${this.minLength} and maximum length ${this.maxLength}") + throw IllegalArgumentException("Cannot create string gene ${this.name} with minimum length ${this.minLength} and maximum length ${this.maxLength}") } } @@ -983,4 +983,20 @@ class StringGene( return otherelements.none { it is Gene && it.flatView().any { g-> g is StringGene && g.getPossiblyTaintedValue().equals(getPossiblyTaintedValue(), ignoreCase = true) } } } + + override fun setFromStringValue(value: String): Boolean { + + val previousSpecialization = selectedSpecialization + val previousValue = value + + this.value = value + selectedSpecialization = -1 + if(!isLocallyValid() || !checkForGloballyValid()){ + this.value = previousValue + this.selectedSpecialization = previousSpecialization + return false + } + + return true + } } diff --git a/core/src/main/kotlin/org/evomaster/core/seeding/PirToIndividual.kt b/core/src/main/kotlin/org/evomaster/core/seeding/PirToIndividual.kt new file mode 100644 index 0000000000..89864d56eb --- /dev/null +++ b/core/src/main/kotlin/org/evomaster/core/seeding/PirToIndividual.kt @@ -0,0 +1,17 @@ +package org.evomaster.core.seeding + +/** + * From Pojo Internal Representation (PIR), possibly derived from a textual representation (eg in JSON) of a test case, + * do create an individual, based on actual schema of the SUT. + * Note: we can assume that schema might change, and so the "old" test cases might not fully match the constraint + * in the current schema. Also, text might be manually modified by users. + * In other words, we can assume errors in parsing... in such cases, we should NOT crash EM, but rather issue warning + * messages. + * + * TODO should consider if this should be made a "service" + * + * TODO this will be the core of new "seeding" mechanism, eg seed from previous runs or manual edits from users, + * but for now we just need something basic to enable integration tests + */ +abstract class PirToIndividual { +} \ No newline at end of file diff --git a/core/src/main/kotlin/org/evomaster/core/seeding/pir/PirTestCase.kt b/core/src/main/kotlin/org/evomaster/core/seeding/pir/PirTestCase.kt new file mode 100644 index 0000000000..9371cf7c9b --- /dev/null +++ b/core/src/main/kotlin/org/evomaster/core/seeding/pir/PirTestCase.kt @@ -0,0 +1,4 @@ +package org.evomaster.core.seeding.pir + +class PirTestCase { +} \ No newline at end of file diff --git a/core/src/main/kotlin/org/evomaster/core/seeding/rest/PirToRest.kt b/core/src/main/kotlin/org/evomaster/core/seeding/rest/PirToRest.kt new file mode 100644 index 0000000000..5b1d938deb --- /dev/null +++ b/core/src/main/kotlin/org/evomaster/core/seeding/rest/PirToRest.kt @@ -0,0 +1,62 @@ +package org.evomaster.core.seeding.rest + +import org.evomaster.core.problem.rest.HttpVerb +import org.evomaster.core.problem.rest.RestCallAction +import org.evomaster.core.problem.rest.param.PathParam +import org.evomaster.core.search.service.Randomness +import org.evomaster.core.seeding.PirToIndividual +import org.slf4j.Logger +import org.slf4j.LoggerFactory + +class PirToRest( + private val schema : List, + private val randomness: Randomness +) : PirToIndividual(){ + + companion object{ + private val log: Logger = LoggerFactory.getLogger(PirToRest::class.java) + } + + fun fromVerbPath(verb: String, path: String) : RestCallAction?{ + + val v = try{HttpVerb.valueOf(verb)} + catch (e: IllegalArgumentException){ + log.warn("Unrecognized http verb: $verb") + return null + } + + val candidates = schema.filter { it.verb == v } + .filter { it.path.matches(path) } + + if(candidates.isEmpty()){ + log.warn("No match for endpoint path: $path") + return null + } + + if(candidates.size > 1){ + log.warn("Ambiguity issue, as ${candidates.size} endpoints are a match for: $path") + } + + val x = candidates[0].copy() as RestCallAction + x.doInitialize(randomness) + + x.parameters.forEach { p -> + when(p){ + is PathParam -> { + val toSeed = x.path.getKeyValues(path)?.get(p.name)!! + val isSet = p.gene.setFromStringValue(toSeed) + if(isSet){ + log.warn("Failed to update path parameter ${p.name} with value: $toSeed") + return null + } + } + else -> { + //TODO other cases + } + } + } + + return x + } + +} \ No newline at end of file From 0c6978707dd57b0c3608c621684e34afd81dec6c Mon Sep 17 00:00:00 2001 From: arcuri82 Date: Tue, 26 Mar 2024 09:04:18 +0100 Subject: [PATCH 04/10] refactored into services --- .../rest/service/BlackBoxRestModule.kt | 5 +++ .../rest/service/ResourceRestModule.kt | 4 +++ .../core/problem/rest/service/RestModule.kt | 3 ++ .../seeding/{ => service}/PirToIndividual.kt | 10 +++++- .../seeding/{ => service}/rest/PirToRest.kt | 33 +++++++++++++++---- 5 files changed, 47 insertions(+), 8 deletions(-) rename core/src/main/kotlin/org/evomaster/core/seeding/{ => service}/PirToIndividual.kt (75%) rename core/src/main/kotlin/org/evomaster/core/seeding/{ => service}/rest/PirToRest.kt (65%) diff --git a/core/src/main/kotlin/org/evomaster/core/problem/rest/service/BlackBoxRestModule.kt b/core/src/main/kotlin/org/evomaster/core/problem/rest/service/BlackBoxRestModule.kt index 7986c3d743..28463dfd57 100644 --- a/core/src/main/kotlin/org/evomaster/core/problem/rest/service/BlackBoxRestModule.kt +++ b/core/src/main/kotlin/org/evomaster/core/problem/rest/service/BlackBoxRestModule.kt @@ -12,6 +12,7 @@ import org.evomaster.core.search.service.Archive import org.evomaster.core.search.service.FitnessFunction import org.evomaster.core.search.service.Minimizer import org.evomaster.core.search.service.Sampler +import org.evomaster.core.seeding.service.rest.PirToRest class BlackBoxRestModule( val usingRemoteController: Boolean @@ -69,5 +70,9 @@ class BlackBoxRestModule( bind(SecurityRest::class.java) .asEagerSingleton() + + bind(PirToRest::class.java) + .asEagerSingleton() + } } \ No newline at end of file diff --git a/core/src/main/kotlin/org/evomaster/core/problem/rest/service/ResourceRestModule.kt b/core/src/main/kotlin/org/evomaster/core/problem/rest/service/ResourceRestModule.kt index 8ebd8d70bf..cd68a22c1d 100755 --- a/core/src/main/kotlin/org/evomaster/core/problem/rest/service/ResourceRestModule.kt +++ b/core/src/main/kotlin/org/evomaster/core/problem/rest/service/ResourceRestModule.kt @@ -17,6 +17,7 @@ import org.evomaster.core.search.service.Sampler import org.evomaster.core.search.service.mutator.Mutator import org.evomaster.core.search.service.mutator.StandardMutator import org.evomaster.core.search.service.mutator.StructureMutator +import org.evomaster.core.seeding.service.rest.PirToRest class ResourceRestModule(private val bindRemote : Boolean = true) : AbstractModule(){ @@ -112,5 +113,8 @@ class ResourceRestModule(private val bindRemote : Boolean = true) : AbstractModu bind(SecurityRest::class.java) .asEagerSingleton() + bind(PirToRest::class.java) + .asEagerSingleton() + } } \ No newline at end of file diff --git a/core/src/main/kotlin/org/evomaster/core/problem/rest/service/RestModule.kt b/core/src/main/kotlin/org/evomaster/core/problem/rest/service/RestModule.kt index 9277f7c1c4..8ed74f46fd 100644 --- a/core/src/main/kotlin/org/evomaster/core/problem/rest/service/RestModule.kt +++ b/core/src/main/kotlin/org/evomaster/core/problem/rest/service/RestModule.kt @@ -14,6 +14,7 @@ import org.evomaster.core.search.service.mutator.StandardMutator import org.evomaster.core.search.service.* import org.evomaster.core.search.service.mutator.Mutator import org.evomaster.core.search.service.mutator.StructureMutator +import org.evomaster.core.seeding.service.rest.PirToRest class RestModule(private val bindRemote : Boolean = true) : AbstractModule(){ @@ -88,5 +89,7 @@ class RestModule(private val bindRemote : Boolean = true) : AbstractModule(){ bind(SecurityRest::class.java) .asEagerSingleton() + bind(PirToRest::class.java) + .asEagerSingleton() } } \ No newline at end of file diff --git a/core/src/main/kotlin/org/evomaster/core/seeding/PirToIndividual.kt b/core/src/main/kotlin/org/evomaster/core/seeding/service/PirToIndividual.kt similarity index 75% rename from core/src/main/kotlin/org/evomaster/core/seeding/PirToIndividual.kt rename to core/src/main/kotlin/org/evomaster/core/seeding/service/PirToIndividual.kt index 89864d56eb..de6ff46eca 100644 --- a/core/src/main/kotlin/org/evomaster/core/seeding/PirToIndividual.kt +++ b/core/src/main/kotlin/org/evomaster/core/seeding/service/PirToIndividual.kt @@ -1,4 +1,8 @@ -package org.evomaster.core.seeding +package org.evomaster.core.seeding.service + +import com.google.inject.Inject +import org.evomaster.core.problem.rest.service.AbstractRestSampler +import org.evomaster.core.search.service.Randomness /** * From Pojo Internal Representation (PIR), possibly derived from a textual representation (eg in JSON) of a test case, @@ -14,4 +18,8 @@ package org.evomaster.core.seeding * but for now we just need something basic to enable integration tests */ abstract class PirToIndividual { + + @Inject + protected lateinit var randomness: Randomness + } \ No newline at end of file diff --git a/core/src/main/kotlin/org/evomaster/core/seeding/rest/PirToRest.kt b/core/src/main/kotlin/org/evomaster/core/seeding/service/rest/PirToRest.kt similarity index 65% rename from core/src/main/kotlin/org/evomaster/core/seeding/rest/PirToRest.kt rename to core/src/main/kotlin/org/evomaster/core/seeding/service/rest/PirToRest.kt index 5b1d938deb..70438bda9e 100644 --- a/core/src/main/kotlin/org/evomaster/core/seeding/rest/PirToRest.kt +++ b/core/src/main/kotlin/org/evomaster/core/seeding/service/rest/PirToRest.kt @@ -1,22 +1,41 @@ -package org.evomaster.core.seeding.rest +package org.evomaster.core.seeding.service.rest +import com.google.inject.Inject +import org.evomaster.core.problem.enterprise.auth.AuthSettings import org.evomaster.core.problem.rest.HttpVerb import org.evomaster.core.problem.rest.RestCallAction import org.evomaster.core.problem.rest.param.PathParam +import org.evomaster.core.problem.rest.service.AbstractRestSampler import org.evomaster.core.search.service.Randomness -import org.evomaster.core.seeding.PirToIndividual +import org.evomaster.core.seeding.service.PirToIndividual import org.slf4j.Logger import org.slf4j.LoggerFactory -class PirToRest( - private val schema : List, - private val randomness: Randomness -) : PirToIndividual(){ +class PirToRest: PirToIndividual(){ companion object{ private val log: Logger = LoggerFactory.getLogger(PirToRest::class.java) } + @Inject + private lateinit var sampler: AbstractRestSampler + + + //TODO move up, once doing refactoring + private lateinit var authSettings: AuthSettings + + + /** + * All actions that can be defined from the OpenAPI schema + */ + private lateinit var actionDefinitions : List + + init { + actionDefinitions = sampler.getActionDefinitions() as List + authSettings = sampler.authentications + } + + fun fromVerbPath(verb: String, path: String) : RestCallAction?{ val v = try{HttpVerb.valueOf(verb)} @@ -25,7 +44,7 @@ class PirToRest( return null } - val candidates = schema.filter { it.verb == v } + val candidates = actionDefinitions.filter { it.verb == v } .filter { it.path.matches(path) } if(candidates.isEmpty()){ From ee6b9ce48879e845f5769cdb93f5881c1a06be5f Mon Sep 17 00:00:00 2001 From: arcuri82 Date: Tue, 26 Mar 2024 09:59:53 +0100 Subject: [PATCH 05/10] working on first IT --- .../pathstatus/PathStatusApplication.kt | 39 +++++++++++ .../examples/it/spring/SpringController.kt | 67 +++++++++++++++++++ .../spring/pathstatus/PathStatusController.kt | 5 ++ .../problem/rest/IntegrationTestRestBase.kt | 10 +++ .../rest/RestIndividualSelectorUtilsTest.kt | 6 -- ...stIndividualSelectorUtilsPathStatusTest.kt | 29 ++++++++ .../rest/RestIndividualSelectorUtils.kt | 12 ++-- .../core/problem/rest/service/SecurityRest.kt | 13 +--- 8 files changed, 158 insertions(+), 23 deletions(-) create mode 100644 core-it/src/main/kotlin/bar/examples/it/spring/pathstatus/PathStatusApplication.kt create mode 100644 core-it/src/test/kotlin/bar/examples/it/spring/SpringController.kt create mode 100644 core-it/src/test/kotlin/bar/examples/it/spring/pathstatus/PathStatusController.kt delete mode 100644 core-it/src/test/kotlin/org/evomaster/core/problem/rest/RestIndividualSelectorUtilsTest.kt create mode 100644 core-it/src/test/kotlin/org/evomaster/core/problem/rest/selectorutils/RestIndividualSelectorUtilsPathStatusTest.kt diff --git a/core-it/src/main/kotlin/bar/examples/it/spring/pathstatus/PathStatusApplication.kt b/core-it/src/main/kotlin/bar/examples/it/spring/pathstatus/PathStatusApplication.kt new file mode 100644 index 0000000000..3345303ecc --- /dev/null +++ b/core-it/src/main/kotlin/bar/examples/it/spring/pathstatus/PathStatusApplication.kt @@ -0,0 +1,39 @@ +package bar.examples.it.spring.pathstatus + +import org.springframework.boot.SpringApplication +import org.springframework.boot.autoconfigure.SpringBootApplication +import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration +import org.springframework.http.ResponseEntity +import org.springframework.web.bind.annotation.GetMapping +import org.springframework.web.bind.annotation.PathVariable +import org.springframework.web.bind.annotation.RequestMapping +import org.springframework.web.bind.annotation.RestController + +@SpringBootApplication(exclude = [SecurityAutoConfiguration::class]) +@RequestMapping(path = ["/api/pathstatus"]) +@RestController +open class PathStatusApplication { + + + companion object { + @JvmStatic + fun main(args: Array) { + SpringApplication.run(PathStatusApplication::class.java, *args) + } + } + + @GetMapping("/byStatus/{status}") + open fun getByStatus(@PathVariable status: Int) : ResponseEntity { + + return ResponseEntity.status(status).body("byStatus") + } + + @GetMapping("/others/{x}") + open fun getOthers(@PathVariable status: Int) : ResponseEntity { + + return ResponseEntity.status(200).body("$status") + } + + + +} \ No newline at end of file diff --git a/core-it/src/test/kotlin/bar/examples/it/spring/SpringController.kt b/core-it/src/test/kotlin/bar/examples/it/spring/SpringController.kt new file mode 100644 index 0000000000..4e39710cd6 --- /dev/null +++ b/core-it/src/test/kotlin/bar/examples/it/spring/SpringController.kt @@ -0,0 +1,67 @@ +package bar.examples.it.spring + +import org.evomaster.client.java.controller.EmbeddedSutController +import org.evomaster.client.java.controller.api.dto.auth.AuthenticationDto +import org.evomaster.client.java.controller.api.dto.SutInfoDto +import org.evomaster.client.java.sql.DbSpecification +import org.evomaster.client.java.controller.problem.ProblemInfo +import org.evomaster.client.java.controller.problem.RestProblem +import org.springframework.boot.SpringApplication +import org.springframework.context.ConfigurableApplicationContext + + +abstract class SpringController(protected val applicationClass: Class<*>) : EmbeddedSutController() { + + init { + super.setControllerPort(0) + } + + + protected var ctx: ConfigurableApplicationContext? = null + + override fun startSut(): String { + ctx = SpringApplication.run(applicationClass, "--server.port=0") + return "http://localhost:$sutPort" + } + + protected val sutPort: Int + get() = (ctx!!.environment + .propertySources["server.ports"].source as Map<*, *>)["local.server.port"] as Int + + override fun isSutRunning(): Boolean { + return ctx != null && ctx!!.isRunning + } + + override fun stopSut() { + ctx?.stop() + ctx?.close() + } + + override fun getPackagePrefixesToCover(): String { + return "bar.foo." + } + + override fun resetStateOfSUT() { //nothing to do + } + + override fun getProblemInfo(): ProblemInfo { + return RestProblem( + "http://localhost:$sutPort/v3/api-docs", + null + ) + } + + override fun getInfoForAuthentication(): List { + return listOf() + } + + override fun getDbSpecifications(): MutableList? { + return null + } + + + override fun getPreferredOutputFormat(): SutInfoDto.OutputFormat { + return SutInfoDto.OutputFormat.KOTLIN_JUNIT_5 + } + +} \ No newline at end of file diff --git a/core-it/src/test/kotlin/bar/examples/it/spring/pathstatus/PathStatusController.kt b/core-it/src/test/kotlin/bar/examples/it/spring/pathstatus/PathStatusController.kt new file mode 100644 index 0000000000..0ccd1dc97a --- /dev/null +++ b/core-it/src/test/kotlin/bar/examples/it/spring/pathstatus/PathStatusController.kt @@ -0,0 +1,5 @@ +package bar.examples.it.spring.pathstatus + +import bar.examples.it.spring.SpringController + +class PathStatusController : SpringController(PathStatusApplication::class.java) \ No newline at end of file diff --git a/core-it/src/test/kotlin/org/evomaster/core/problem/rest/IntegrationTestRestBase.kt b/core-it/src/test/kotlin/org/evomaster/core/problem/rest/IntegrationTestRestBase.kt index b61af6b5e3..076c2c3d6b 100644 --- a/core-it/src/test/kotlin/org/evomaster/core/problem/rest/IntegrationTestRestBase.kt +++ b/core-it/src/test/kotlin/org/evomaster/core/problem/rest/IntegrationTestRestBase.kt @@ -1,9 +1,19 @@ package org.evomaster.core.problem.rest +import com.google.inject.Injector +import org.evomaster.core.seeding.service.rest.PirToRest import org.evomaster.e2etests.utils.RestTestBase +import org.junit.jupiter.api.BeforeEach abstract class IntegrationTestRestBase : RestTestBase() { + protected lateinit var injector: Injector + @BeforeEach + fun initInjector(){ + injector = init(listOf()) + } + + fun getPirToRest() = injector.getInstance(PirToRest::class.java) } \ No newline at end of file diff --git a/core-it/src/test/kotlin/org/evomaster/core/problem/rest/RestIndividualSelectorUtilsTest.kt b/core-it/src/test/kotlin/org/evomaster/core/problem/rest/RestIndividualSelectorUtilsTest.kt deleted file mode 100644 index aa5cf01c72..0000000000 --- a/core-it/src/test/kotlin/org/evomaster/core/problem/rest/RestIndividualSelectorUtilsTest.kt +++ /dev/null @@ -1,6 +0,0 @@ -package org.evomaster.core.problem.rest - -class RestIndividualSelectorUtilsTest : IntegrationTestRestBase(){ - - //TODO -} \ No newline at end of file diff --git a/core-it/src/test/kotlin/org/evomaster/core/problem/rest/selectorutils/RestIndividualSelectorUtilsPathStatusTest.kt b/core-it/src/test/kotlin/org/evomaster/core/problem/rest/selectorutils/RestIndividualSelectorUtilsPathStatusTest.kt new file mode 100644 index 0000000000..3fd13e2b81 --- /dev/null +++ b/core-it/src/test/kotlin/org/evomaster/core/problem/rest/selectorutils/RestIndividualSelectorUtilsPathStatusTest.kt @@ -0,0 +1,29 @@ +package org.evomaster.core.problem.rest.selectorutils + +import bar.examples.it.spring.pathstatus.PathStatusController +import org.evomaster.core.problem.rest.IntegrationTestRestBase +import org.evomaster.core.problem.rest.RestPath +import org.junit.jupiter.api.BeforeAll +import org.junit.jupiter.api.Test + +class RestIndividualSelectorUtilsPathStatusTest : IntegrationTestRestBase(){ + + companion object { + @BeforeAll + @JvmStatic + fun init() { + initClass(PathStatusController()) + } + } + + + @Test + fun testPathStatus(){ + + val pirTest = getPirToRest() + + val byStatus = RestPath("/api/") + } + + //TODO +} \ No newline at end of file diff --git a/core/src/main/kotlin/org/evomaster/core/problem/rest/RestIndividualSelectorUtils.kt b/core/src/main/kotlin/org/evomaster/core/problem/rest/RestIndividualSelectorUtils.kt index 796ca92c66..431be6559a 100644 --- a/core/src/main/kotlin/org/evomaster/core/problem/rest/RestIndividualSelectorUtils.kt +++ b/core/src/main/kotlin/org/evomaster/core/problem/rest/RestIndividualSelectorUtils.kt @@ -52,7 +52,7 @@ object RestIndividualSelectorUtils { return null } - fun findIndividuals( + fun old_findIndividuals( individuals: List>, verb: HttpVerb, statusGroup: String @@ -88,9 +88,11 @@ object RestIndividualSelectorUtils { /* Find individuals containing a certain action and STATUS */ - fun getIndividualsWithActionAndStatus(individualsInSolution: List>, - verb: HttpVerb, statusCode: Int) - :List> { + fun getIndividualsWithActionAndStatus( + individualsInSolution: List>, + verb: HttpVerb, + statusCode: Int + ):List> { val individualsList = mutableListOf>() @@ -143,7 +145,7 @@ object RestIndividualSelectorUtils { return foundRestAction } - fun getIndividualsWithActionAndStatus( + fun findIndividuals( individuals: List>, verb: HttpVerb, path: RestPath, diff --git a/core/src/main/kotlin/org/evomaster/core/problem/rest/service/SecurityRest.kt b/core/src/main/kotlin/org/evomaster/core/problem/rest/service/SecurityRest.kt index f01196853f..975057e816 100644 --- a/core/src/main/kotlin/org/evomaster/core/problem/rest/service/SecurityRest.kt +++ b/core/src/main/kotlin/org/evomaster/core/problem/rest/service/SecurityRest.kt @@ -3,27 +3,16 @@ package org.evomaster.core.problem.rest.service import com.google.inject.Inject import javax.annotation.PostConstruct -import org.apache.http.HttpStatus - -import org.evomaster.client.java.controller.api.dto.SutInfoDto -import org.evomaster.client.java.controller.api.dto.auth.AuthenticationDto - import org.evomaster.core.logging.LoggingUtil import org.evomaster.core.problem.enterprise.SampleType import org.evomaster.core.problem.enterprise.auth.AuthSettings import org.evomaster.core.problem.httpws.auth.HttpWsAuthenticationInfo import org.evomaster.core.problem.rest.* -import org.evomaster.core.problem.rest.param.PathParam -import org.evomaster.core.remote.service.RemoteController -import org.evomaster.core.remote.service.RemoteControllerImplementation import org.evomaster.core.search.* -import org.evomaster.core.search.action.ActionResult -import org.evomaster.core.search.gene.string.StringGene import org.evomaster.core.search.service.Archive import org.evomaster.core.search.service.FitnessFunction import org.evomaster.core.search.service.Randomness -import org.evomaster.core.search.service.Sampler //FIXME this needs to be cleaned-up @@ -167,7 +156,7 @@ class SecurityRest { // from archive, search if there is any test with a DELETE returning a 403 val existing403 : List> = - RestIndividualSelectorUtils.getIndividualsWithActionAndStatus(individualsInSolution, HttpVerb.DELETE, delete.path, 403) + RestIndividualSelectorUtils.findIndividuals(individualsInSolution, HttpVerb.DELETE, delete.path, 403) var individualToChooseForTest : RestIndividual From 8624b1a080e862b9a06132e44e55d53d1721bacb Mon Sep 17 00:00:00 2001 From: arcuri82 Date: Tue, 26 Mar 2024 10:54:23 +0100 Subject: [PATCH 06/10] draft for first IT --- .../problem/rest/IntegrationTestRestBase.kt | 18 +++++++++++++ ...stIndividualSelectorUtilsPathStatusTest.kt | 25 +++++++++++++++++-- .../rest/service/AbstractRestFitness.kt | 4 +-- .../rest/service/ResourceRestModule.kt | 2 +- .../core/problem/rest/service/RestFitness.kt | 2 +- .../rest/service/RestResourceFitness.kt | 2 +- .../RestIndividualDisabledHMTest.kt | 2 +- .../individual/RestIndividualResourceTest.kt | 2 +- .../rest/individual/RestIndividualTestBase.kt | 2 +- .../RestResourceIndividualDisabledHMTest.kt | 2 +- 10 files changed, 50 insertions(+), 11 deletions(-) diff --git a/core-it/src/test/kotlin/org/evomaster/core/problem/rest/IntegrationTestRestBase.kt b/core-it/src/test/kotlin/org/evomaster/core/problem/rest/IntegrationTestRestBase.kt index 076c2c3d6b..b76020b88b 100644 --- a/core-it/src/test/kotlin/org/evomaster/core/problem/rest/IntegrationTestRestBase.kt +++ b/core-it/src/test/kotlin/org/evomaster/core/problem/rest/IntegrationTestRestBase.kt @@ -1,6 +1,10 @@ package org.evomaster.core.problem.rest import com.google.inject.Injector +import org.evomaster.core.problem.enterprise.SampleType +import org.evomaster.core.problem.rest.service.AbstractRestFitness +import org.evomaster.core.search.EvaluatedIndividual +import org.evomaster.core.search.service.SearchGlobalState import org.evomaster.core.seeding.service.rest.PirToRest import org.evomaster.e2etests.utils.RestTestBase import org.junit.jupiter.api.BeforeEach @@ -16,4 +20,18 @@ abstract class IntegrationTestRestBase : RestTestBase() { } fun getPirToRest() = injector.getInstance(PirToRest::class.java) + + + fun createIndividual(actions: List): EvaluatedIndividual { + + val searchGlobalState = injector.getInstance(SearchGlobalState::class.java) + + val ind = RestIndividual(actions.toMutableList(), SampleType.SEEDED) + ind.doGlobalInitialize(searchGlobalState) + + val ff = injector.getInstance(AbstractRestFitness::class.java) + val ei = ff.calculateCoverage(ind)!! + + return ei + } } \ No newline at end of file diff --git a/core-it/src/test/kotlin/org/evomaster/core/problem/rest/selectorutils/RestIndividualSelectorUtilsPathStatusTest.kt b/core-it/src/test/kotlin/org/evomaster/core/problem/rest/selectorutils/RestIndividualSelectorUtilsPathStatusTest.kt index 3fd13e2b81..6c34662a22 100644 --- a/core-it/src/test/kotlin/org/evomaster/core/problem/rest/selectorutils/RestIndividualSelectorUtilsPathStatusTest.kt +++ b/core-it/src/test/kotlin/org/evomaster/core/problem/rest/selectorutils/RestIndividualSelectorUtilsPathStatusTest.kt @@ -1,8 +1,11 @@ package org.evomaster.core.problem.rest.selectorutils import bar.examples.it.spring.pathstatus.PathStatusController +import org.evomaster.core.problem.rest.HttpVerb import org.evomaster.core.problem.rest.IntegrationTestRestBase +import org.evomaster.core.problem.rest.RestIndividualSelectorUtils import org.evomaster.core.problem.rest.RestPath +import org.junit.jupiter.api.Assertions.assertEquals import org.junit.jupiter.api.BeforeAll import org.junit.jupiter.api.Test @@ -22,8 +25,26 @@ class RestIndividualSelectorUtilsPathStatusTest : IntegrationTestRestBase(){ val pirTest = getPirToRest() - val byStatus = RestPath("/api/") + val byStatus = RestPath("/api/pathstatus/byStatus/{status}") + val others = RestPath("/api/pathstatus/others/{x}") + + val s200 = pirTest.fromVerbPath("get", "/api/pathstatus/byStatus/200")!! + val s400 = pirTest.fromVerbPath("get", "/api/pathstatus/byStatus/400")!! + val o200 = pirTest.fromVerbPath("get", "/api/pathstatus/others/200")!! + val o500 = pirTest.fromVerbPath("get", "/api/pathstatus/others/500")!! + + val x0 = createIndividual(listOf(s200)) + val x1 = createIndividual(listOf(s400)) + val x2 = createIndividual(listOf(o200)) + val x3 = createIndividual(listOf(o500)) + + val individuals = listOf(x0,x1,x2,x3) + + val r0 = RestIndividualSelectorUtils.findIndividuals(individuals, HttpVerb.GET, byStatus, 200) + assertEquals(1, r0.size) + + val r1 = RestIndividualSelectorUtils.findIndividuals(individuals, HttpVerb.GET, byStatus, 500) + assertEquals(0, r1.size) } - //TODO } \ No newline at end of file diff --git a/core/src/main/kotlin/org/evomaster/core/problem/rest/service/AbstractRestFitness.kt b/core/src/main/kotlin/org/evomaster/core/problem/rest/service/AbstractRestFitness.kt index 6df3f365a6..e6add341ff 100755 --- a/core/src/main/kotlin/org/evomaster/core/problem/rest/service/AbstractRestFitness.kt +++ b/core/src/main/kotlin/org/evomaster/core/problem/rest/service/AbstractRestFitness.kt @@ -49,7 +49,7 @@ import javax.ws.rs.core.NewCookie import javax.ws.rs.core.Response -abstract class AbstractRestFitness : HttpWsFitness() where T : Individual { +abstract class AbstractRestFitness : HttpWsFitness() { // TODO: This will moved under ApiWsFitness once RPC and GraphQL support is completed @Inject @@ -760,7 +760,7 @@ abstract class AbstractRestFitness : HttpWsFitness() where T : Individual return null } - val dto = updateFitnessAfterEvaluation(targets, allCovered, individual as T, fv) + val dto = updateFitnessAfterEvaluation(targets, allCovered, individual, fv) ?: return null handleExtra(dto, fv) diff --git a/core/src/main/kotlin/org/evomaster/core/problem/rest/service/ResourceRestModule.kt b/core/src/main/kotlin/org/evomaster/core/problem/rest/service/ResourceRestModule.kt index cd68a22c1d..3b3852554d 100755 --- a/core/src/main/kotlin/org/evomaster/core/problem/rest/service/ResourceRestModule.kt +++ b/core/src/main/kotlin/org/evomaster/core/problem/rest/service/ResourceRestModule.kt @@ -60,7 +60,7 @@ class ResourceRestModule(private val bindRemote : Boolean = true) : AbstractModu .to(RestResourceFitness::class.java) .asEagerSingleton() - bind(object : TypeLiteral>() {}) + bind(object : TypeLiteral() {}) .to(RestResourceFitness::class.java) .asEagerSingleton() diff --git a/core/src/main/kotlin/org/evomaster/core/problem/rest/service/RestFitness.kt b/core/src/main/kotlin/org/evomaster/core/problem/rest/service/RestFitness.kt index 7e6e33a476..2a082c8dce 100644 --- a/core/src/main/kotlin/org/evomaster/core/problem/rest/service/RestFitness.kt +++ b/core/src/main/kotlin/org/evomaster/core/problem/rest/service/RestFitness.kt @@ -12,7 +12,7 @@ import org.evomaster.core.search.FitnessValue import org.slf4j.Logger import org.slf4j.LoggerFactory -open class RestFitness : AbstractRestFitness() { +open class RestFitness : AbstractRestFitness() { companion object { private val log: Logger = LoggerFactory.getLogger(RestFitness::class.java) diff --git a/core/src/main/kotlin/org/evomaster/core/problem/rest/service/RestResourceFitness.kt b/core/src/main/kotlin/org/evomaster/core/problem/rest/service/RestResourceFitness.kt index 125d8f5516..b94c34b39d 100755 --- a/core/src/main/kotlin/org/evomaster/core/problem/rest/service/RestResourceFitness.kt +++ b/core/src/main/kotlin/org/evomaster/core/problem/rest/service/RestResourceFitness.kt @@ -23,7 +23,7 @@ import javax.ws.rs.core.NewCookie /** * take care of calculating/collecting fitness of [RestIndividual] */ -class RestResourceFitness : AbstractRestFitness() { +class RestResourceFitness : AbstractRestFitness() { @Inject diff --git a/core/src/test/kotlin/org/evomaster/core/problem/rest/individual/RestIndividualDisabledHMTest.kt b/core/src/test/kotlin/org/evomaster/core/problem/rest/individual/RestIndividualDisabledHMTest.kt index d95816f3c1..7eb7152dfa 100644 --- a/core/src/test/kotlin/org/evomaster/core/problem/rest/individual/RestIndividualDisabledHMTest.kt +++ b/core/src/test/kotlin/org/evomaster/core/problem/rest/individual/RestIndividualDisabledHMTest.kt @@ -40,7 +40,7 @@ class RestIndividualDisabledHMTest : RestIndividualTestBase(){ override fun getMutator(): StandardMutator = mutator - override fun getFitnessFunction(): AbstractRestFitness = ff + override fun getFitnessFunction(): AbstractRestFitness = ff } \ No newline at end of file diff --git a/core/src/test/kotlin/org/evomaster/core/problem/rest/individual/RestIndividualResourceTest.kt b/core/src/test/kotlin/org/evomaster/core/problem/rest/individual/RestIndividualResourceTest.kt index afc3b93f0f..540b1e0510 100644 --- a/core/src/test/kotlin/org/evomaster/core/problem/rest/individual/RestIndividualResourceTest.kt +++ b/core/src/test/kotlin/org/evomaster/core/problem/rest/individual/RestIndividualResourceTest.kt @@ -25,7 +25,7 @@ class RestIndividualResourceTest : RestIndividualTestBase() { override fun getProblemModule() = ResourceRestModule(false) override fun getMutator(): StandardMutator = mutator - override fun getFitnessFunction(): AbstractRestFitness = ff + override fun getFitnessFunction(): AbstractRestFitness = ff override fun getSampler(): AbstractRestSampler = sampler diff --git a/core/src/test/kotlin/org/evomaster/core/problem/rest/individual/RestIndividualTestBase.kt b/core/src/test/kotlin/org/evomaster/core/problem/rest/individual/RestIndividualTestBase.kt index 4827c74e2b..a14ac059d1 100644 --- a/core/src/test/kotlin/org/evomaster/core/problem/rest/individual/RestIndividualTestBase.kt +++ b/core/src/test/kotlin/org/evomaster/core/problem/rest/individual/RestIndividualTestBase.kt @@ -175,7 +175,7 @@ abstract class RestIndividualTestBase { abstract fun getSampler() : AbstractRestSampler abstract fun getMutator() : StandardMutator - abstract fun getFitnessFunction() : AbstractRestFitness + abstract fun getFitnessFunction() : AbstractRestFitness @ParameterizedTest @MethodSource("getBudgetAndNumOfResourceForSampler") diff --git a/core/src/test/kotlin/org/evomaster/core/problem/rest/individual/RestResourceIndividualDisabledHMTest.kt b/core/src/test/kotlin/org/evomaster/core/problem/rest/individual/RestResourceIndividualDisabledHMTest.kt index cc5bbad676..11ee5993f7 100644 --- a/core/src/test/kotlin/org/evomaster/core/problem/rest/individual/RestResourceIndividualDisabledHMTest.kt +++ b/core/src/test/kotlin/org/evomaster/core/problem/rest/individual/RestResourceIndividualDisabledHMTest.kt @@ -80,7 +80,7 @@ class RestResourceIndividualDisabledHMTest : RestIndividualTestBase(){ override fun getMutator(): StandardMutator = mutator - override fun getFitnessFunction(): AbstractRestFitness = ff + override fun getFitnessFunction(): AbstractRestFitness = ff private fun sampleDbAction(table : Table) : List{ val actions = sqlInsertBuilder!!.createSqlInsertionAction(table.name) From c8be7d67d3142ab5ae072d7a7403f3c5e1285738 Mon Sep 17 00:00:00 2001 From: arcuri82 Date: Tue, 26 Mar 2024 10:58:10 +0100 Subject: [PATCH 07/10] fixed injection --- .../org/evomaster/core/seeding/service/rest/PirToRest.kt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/core/src/main/kotlin/org/evomaster/core/seeding/service/rest/PirToRest.kt b/core/src/main/kotlin/org/evomaster/core/seeding/service/rest/PirToRest.kt index 70438bda9e..56b10385e4 100644 --- a/core/src/main/kotlin/org/evomaster/core/seeding/service/rest/PirToRest.kt +++ b/core/src/main/kotlin/org/evomaster/core/seeding/service/rest/PirToRest.kt @@ -10,6 +10,7 @@ import org.evomaster.core.search.service.Randomness import org.evomaster.core.seeding.service.PirToIndividual import org.slf4j.Logger import org.slf4j.LoggerFactory +import javax.annotation.PostConstruct class PirToRest: PirToIndividual(){ @@ -30,7 +31,8 @@ class PirToRest: PirToIndividual(){ */ private lateinit var actionDefinitions : List - init { + @PostConstruct + fun initialize() { actionDefinitions = sampler.getActionDefinitions() as List authSettings = sampler.authentications } From 0a10438833a1bf015ca6753d14dff3d208c76cf9 Mon Sep 17 00:00:00 2001 From: arcuri82 Date: Tue, 26 Mar 2024 14:28:20 +0100 Subject: [PATCH 08/10] fixing scaffolding --- core-it/pom.xml | 16 ++++++++++++++++ .../spring/pathstatus/PathStatusApplication.kt | 4 ++-- .../core/problem/rest/IntegrationTestRestBase.kt | 6 +++++- .../core/search/gene/numeric/IntegerGene.kt | 9 +++++++++ .../gene/optional/CustomMutationRateGene.kt | 4 ++++ .../core/seeding/service/rest/PirToRest.kt | 4 ++-- 6 files changed, 38 insertions(+), 5 deletions(-) diff --git a/core-it/pom.xml b/core-it/pom.xml index 9ea28d2128..7ff4625e64 100644 --- a/core-it/pom.xml +++ b/core-it/pom.xml @@ -85,6 +85,22 @@ org.springframework.boot spring-boot-starter-web + + org.springdoc + springdoc-openapi-ui + + + + + + + org.springdoc + springdoc-openapi-kotlin + + + io.swagger.core.v3 + swagger-annotations + org.evomaster diff --git a/core-it/src/main/kotlin/bar/examples/it/spring/pathstatus/PathStatusApplication.kt b/core-it/src/main/kotlin/bar/examples/it/spring/pathstatus/PathStatusApplication.kt index 3345303ecc..cf487e2d73 100644 --- a/core-it/src/main/kotlin/bar/examples/it/spring/pathstatus/PathStatusApplication.kt +++ b/core-it/src/main/kotlin/bar/examples/it/spring/pathstatus/PathStatusApplication.kt @@ -29,9 +29,9 @@ open class PathStatusApplication { } @GetMapping("/others/{x}") - open fun getOthers(@PathVariable status: Int) : ResponseEntity { + open fun getOthers(@PathVariable x: Int) : ResponseEntity { - return ResponseEntity.status(200).body("$status") + return ResponseEntity.status(200).body("$x") } diff --git a/core-it/src/test/kotlin/org/evomaster/core/problem/rest/IntegrationTestRestBase.kt b/core-it/src/test/kotlin/org/evomaster/core/problem/rest/IntegrationTestRestBase.kt index b76020b88b..11ea0b6d58 100644 --- a/core-it/src/test/kotlin/org/evomaster/core/problem/rest/IntegrationTestRestBase.kt +++ b/core-it/src/test/kotlin/org/evomaster/core/problem/rest/IntegrationTestRestBase.kt @@ -16,7 +16,11 @@ abstract class IntegrationTestRestBase : RestTestBase() { @BeforeEach fun initInjector(){ - injector = init(listOf()) + val args = listOf( + "--sutControllerPort", "" + controllerPort, + "--createConfigPathIfMissing", "false" + ) + injector = init(args) } fun getPirToRest() = injector.getInstance(PirToRest::class.java) diff --git a/core/src/main/kotlin/org/evomaster/core/search/gene/numeric/IntegerGene.kt b/core/src/main/kotlin/org/evomaster/core/search/gene/numeric/IntegerGene.kt index 48b4f149fb..64e79b2af0 100644 --- a/core/src/main/kotlin/org/evomaster/core/search/gene/numeric/IntegerGene.kt +++ b/core/src/main/kotlin/org/evomaster/core/search/gene/numeric/IntegerGene.kt @@ -52,6 +52,15 @@ class IntegerGene( private val log: Logger = LoggerFactory.getLogger(IntegerGene::class.java) } + override fun setFromStringValue(value: String) : Boolean{ + try{ + this.value = value.toInt() + return true + }catch (e: NumberFormatException){ + return false + } + } + override fun copyContent(): Gene { return IntegerGene( name, diff --git a/core/src/main/kotlin/org/evomaster/core/search/gene/optional/CustomMutationRateGene.kt b/core/src/main/kotlin/org/evomaster/core/search/gene/optional/CustomMutationRateGene.kt index 867292e06b..d166aedadb 100644 --- a/core/src/main/kotlin/org/evomaster/core/search/gene/optional/CustomMutationRateGene.kt +++ b/core/src/main/kotlin/org/evomaster/core/search/gene/optional/CustomMutationRateGene.kt @@ -52,6 +52,10 @@ class CustomMutationRateGene( } + override fun setFromStringValue(value: String) : Boolean{ + return gene.setFromStringValue(value) + } + override fun getWrappedGene(klass: Class) : T? where T : Gene{ if(this.javaClass == klass){ return this as T diff --git a/core/src/main/kotlin/org/evomaster/core/seeding/service/rest/PirToRest.kt b/core/src/main/kotlin/org/evomaster/core/seeding/service/rest/PirToRest.kt index 56b10385e4..f50168e092 100644 --- a/core/src/main/kotlin/org/evomaster/core/seeding/service/rest/PirToRest.kt +++ b/core/src/main/kotlin/org/evomaster/core/seeding/service/rest/PirToRest.kt @@ -40,7 +40,7 @@ class PirToRest: PirToIndividual(){ fun fromVerbPath(verb: String, path: String) : RestCallAction?{ - val v = try{HttpVerb.valueOf(verb)} + val v = try{HttpVerb.valueOf(verb.uppercase())} catch (e: IllegalArgumentException){ log.warn("Unrecognized http verb: $verb") return null @@ -66,7 +66,7 @@ class PirToRest: PirToIndividual(){ is PathParam -> { val toSeed = x.path.getKeyValues(path)?.get(p.name)!! val isSet = p.gene.setFromStringValue(toSeed) - if(isSet){ + if(!isSet){ log.warn("Failed to update path parameter ${p.name} with value: $toSeed") return null } From 56878206b4dc3558c69fe6ccc9567c994fbf0760 Mon Sep 17 00:00:00 2001 From: Man Zhang Date: Tue, 26 Mar 2024 23:05:18 +0800 Subject: [PATCH 09/10] modify createIndividual --- .../core/problem/rest/IntegrationTestRestBase.kt | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/core-it/src/test/kotlin/org/evomaster/core/problem/rest/IntegrationTestRestBase.kt b/core-it/src/test/kotlin/org/evomaster/core/problem/rest/IntegrationTestRestBase.kt index 11ea0b6d58..3f1f2feff9 100644 --- a/core-it/src/test/kotlin/org/evomaster/core/problem/rest/IntegrationTestRestBase.kt +++ b/core-it/src/test/kotlin/org/evomaster/core/problem/rest/IntegrationTestRestBase.kt @@ -3,6 +3,7 @@ package org.evomaster.core.problem.rest import com.google.inject.Injector import org.evomaster.core.problem.enterprise.SampleType import org.evomaster.core.problem.rest.service.AbstractRestFitness +import org.evomaster.core.problem.rest.service.AbstractRestSampler import org.evomaster.core.search.EvaluatedIndividual import org.evomaster.core.search.service.SearchGlobalState import org.evomaster.core.seeding.service.rest.PirToRest @@ -28,10 +29,18 @@ abstract class IntegrationTestRestBase : RestTestBase() { fun createIndividual(actions: List): EvaluatedIndividual { - val searchGlobalState = injector.getInstance(SearchGlobalState::class.java) +// val searchGlobalState = injector.getInstance(SearchGlobalState::class.java) - val ind = RestIndividual(actions.toMutableList(), SampleType.SEEDED) - ind.doGlobalInitialize(searchGlobalState) +// val ind = RestIndividual(actions.toMutableList(), SampleType.SEEDED) +// ind.doGlobalInitialize(searchGlobalState) + + val sampler = injector.getInstance(AbstractRestSampler::class.java) + /* + the method `createIndividual` can be overridden + in this case, the sampler is an instance of ResourceSampler, + then check its implementation in ResourceSampler.createIndividual(...) + */ + val ind = sampler.createIndividual(SampleType.SEEDED, actions.toMutableList()) val ff = injector.getInstance(AbstractRestFitness::class.java) val ei = ff.calculateCoverage(ind)!! From 9755c3919961ab77369faa0ca8a72602a2af2867 Mon Sep 17 00:00:00 2001 From: arcuri82 Date: Wed, 27 Mar 2024 13:00:16 +0100 Subject: [PATCH 10/10] clarifications --- .../kotlin/org/evomaster/core/problem/rest/RestIndividual.kt | 3 +++ .../evomaster/core/problem/rest/service/AbstractRestSampler.kt | 3 +++ 2 files changed, 6 insertions(+) diff --git a/core/src/main/kotlin/org/evomaster/core/problem/rest/RestIndividual.kt b/core/src/main/kotlin/org/evomaster/core/problem/rest/RestIndividual.kt index c784678a88..d35fa3a4cc 100644 --- a/core/src/main/kotlin/org/evomaster/core/problem/rest/RestIndividual.kt +++ b/core/src/main/kotlin/org/evomaster/core/problem/rest/RestIndividual.kt @@ -28,6 +28,9 @@ import kotlin.math.max * * @property trackOperator indicates which operator create this individual. * @property index indicates when the individual is created, ie, using num of evaluated individual. + * + * + * FIXME: why having to use AbstractRestSampler.createIndividual() instead of having such code here in constructor??? */ class RestIndividual( sampleType: SampleType, diff --git a/core/src/main/kotlin/org/evomaster/core/problem/rest/service/AbstractRestSampler.kt b/core/src/main/kotlin/org/evomaster/core/problem/rest/service/AbstractRestSampler.kt index 87fef95987..66b6194c6b 100644 --- a/core/src/main/kotlin/org/evomaster/core/problem/rest/service/AbstractRestSampler.kt +++ b/core/src/main/kotlin/org/evomaster/core/problem/rest/service/AbstractRestSampler.kt @@ -307,6 +307,9 @@ abstract class AbstractRestSampler : HttpWsSampler() { /** * @return a created individual with specified actions, i.e., [restCalls]. * All actions must have been already initialized + * + * + * FIXME: why this function instead of dealing with this directly in the constructor of RestIndividual??? */ open fun createIndividual(sampleType: SampleType, restCalls: MutableList): RestIndividual { if(restCalls.any { !it.isInitialized() }){