From 345ee9fe7492a86fcda23cdb3ec6611beedfd106 Mon Sep 17 00:00:00 2001 From: arcuri82 Date: Mon, 8 Jun 2026 14:46:00 +0200 Subject: [PATCH 1/7] created (failing) E2E example --- .../openapi/v3/logincreateuser/AuthDto.kt | 6 ++ .../v3/logincreateuser/CreateUserDto.kt | 7 ++ .../LoginCreateUsersApplication.kt | 17 +++++ .../logincreateuser/LoginCreateUsersRest.kt | 67 +++++++++++++++++++ .../openapi/v3/logincreateuser/LoginDto.kt | 6 ++ .../openapi/v3/logincreateuser/TokenDto.kt | 5 ++ .../resources/config/logincreateusers.yaml | 13 ++++ .../LoginCreateUsersController.kt | 20 ++++++ .../LoginCreateUsersEMTest.kt | 41 ++++++++++++ 9 files changed, 182 insertions(+) create mode 100644 core-tests/e2e-tests/spring/spring-rest-openapi-v3/src/main/kotlin/com/foo/rest/examples/spring/openapi/v3/logincreateuser/AuthDto.kt create mode 100644 core-tests/e2e-tests/spring/spring-rest-openapi-v3/src/main/kotlin/com/foo/rest/examples/spring/openapi/v3/logincreateuser/CreateUserDto.kt create mode 100644 core-tests/e2e-tests/spring/spring-rest-openapi-v3/src/main/kotlin/com/foo/rest/examples/spring/openapi/v3/logincreateuser/LoginCreateUsersApplication.kt create mode 100644 core-tests/e2e-tests/spring/spring-rest-openapi-v3/src/main/kotlin/com/foo/rest/examples/spring/openapi/v3/logincreateuser/LoginCreateUsersRest.kt create mode 100644 core-tests/e2e-tests/spring/spring-rest-openapi-v3/src/main/kotlin/com/foo/rest/examples/spring/openapi/v3/logincreateuser/LoginDto.kt create mode 100644 core-tests/e2e-tests/spring/spring-rest-openapi-v3/src/main/kotlin/com/foo/rest/examples/spring/openapi/v3/logincreateuser/TokenDto.kt create mode 100644 core-tests/e2e-tests/spring/spring-rest-openapi-v3/src/main/resources/config/logincreateusers.yaml create mode 100644 core-tests/e2e-tests/spring/spring-rest-openapi-v3/src/test/kotlin/com/foo/rest/examples/spring/openapi/v3/logincreateusers/LoginCreateUsersController.kt create mode 100644 core-tests/e2e-tests/spring/spring-rest-openapi-v3/src/test/kotlin/org/evomaster/e2etests/spring/openapi/v3/logincreateusers/LoginCreateUsersEMTest.kt diff --git a/core-tests/e2e-tests/spring/spring-rest-openapi-v3/src/main/kotlin/com/foo/rest/examples/spring/openapi/v3/logincreateuser/AuthDto.kt b/core-tests/e2e-tests/spring/spring-rest-openapi-v3/src/main/kotlin/com/foo/rest/examples/spring/openapi/v3/logincreateuser/AuthDto.kt new file mode 100644 index 0000000000..d56c3f07a5 --- /dev/null +++ b/core-tests/e2e-tests/spring/spring-rest-openapi-v3/src/main/kotlin/com/foo/rest/examples/spring/openapi/v3/logincreateuser/AuthDto.kt @@ -0,0 +1,6 @@ +package com.foo.rest.examples.spring.openapi.v3.logincreateuser + +class AuthDto( + var email : String? = null, + var token: TokenDto? = null +) diff --git a/core-tests/e2e-tests/spring/spring-rest-openapi-v3/src/main/kotlin/com/foo/rest/examples/spring/openapi/v3/logincreateuser/CreateUserDto.kt b/core-tests/e2e-tests/spring/spring-rest-openapi-v3/src/main/kotlin/com/foo/rest/examples/spring/openapi/v3/logincreateuser/CreateUserDto.kt new file mode 100644 index 0000000000..b596e9e0b1 --- /dev/null +++ b/core-tests/e2e-tests/spring/spring-rest-openapi-v3/src/main/kotlin/com/foo/rest/examples/spring/openapi/v3/logincreateuser/CreateUserDto.kt @@ -0,0 +1,7 @@ +package com.foo.rest.examples.spring.openapi.v3.logincreateuser + +class CreateUserDto( + var email: String? = null, + var password: String? = null, + var username: String? = null +) diff --git a/core-tests/e2e-tests/spring/spring-rest-openapi-v3/src/main/kotlin/com/foo/rest/examples/spring/openapi/v3/logincreateuser/LoginCreateUsersApplication.kt b/core-tests/e2e-tests/spring/spring-rest-openapi-v3/src/main/kotlin/com/foo/rest/examples/spring/openapi/v3/logincreateuser/LoginCreateUsersApplication.kt new file mode 100644 index 0000000000..acc0f14c92 --- /dev/null +++ b/core-tests/e2e-tests/spring/spring-rest-openapi-v3/src/main/kotlin/com/foo/rest/examples/spring/openapi/v3/logincreateuser/LoginCreateUsersApplication.kt @@ -0,0 +1,17 @@ +package com.foo.rest.examples.spring.openapi.v3.logincreateuser + +import org.springframework.boot.SpringApplication +import org.springframework.boot.autoconfigure.SpringBootApplication +import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration + + +@SpringBootApplication(exclude = [SecurityAutoConfiguration::class]) +open class LoginCreateUsersApplication { + + companion object { + @JvmStatic + fun main(args: Array) { + SpringApplication.run(LoginCreateUsersApplication::class.java, *args) + } + } +} \ No newline at end of file diff --git a/core-tests/e2e-tests/spring/spring-rest-openapi-v3/src/main/kotlin/com/foo/rest/examples/spring/openapi/v3/logincreateuser/LoginCreateUsersRest.kt b/core-tests/e2e-tests/spring/spring-rest-openapi-v3/src/main/kotlin/com/foo/rest/examples/spring/openapi/v3/logincreateuser/LoginCreateUsersRest.kt new file mode 100644 index 0000000000..c241ebd3f0 --- /dev/null +++ b/core-tests/e2e-tests/spring/spring-rest-openapi-v3/src/main/kotlin/com/foo/rest/examples/spring/openapi/v3/logincreateuser/LoginCreateUsersRest.kt @@ -0,0 +1,67 @@ +package com.foo.rest.examples.spring.openapi.v3.logincreateuser + +import com.foo.rest.examples.spring.openapi.v3.wiremock.harvestresponse.UserDto +import org.springframework.http.MediaType +import org.springframework.http.ResponseEntity +import org.springframework.web.bind.annotation.* + +@RestController +@RequestMapping(path = ["/api/logincreateusers"]) +class LoginCreateUsersRest { + + private val SECRET = "a complex secret - " + + private val users = mutableMapOf() + + private val tokens = mutableMapOf() + + + @PostMapping("/users") + fun createUser(@RequestBody user: CreateUserDto): ResponseEntity { + + if(user.email == null || user.username == null || user.password == null) { + return ResponseEntity.status(400).build() + } + + if(!user.email!!.contains("@") || !user.email!!.contains(".")) { + return ResponseEntity.status(400).build() + } + + if(users.containsKey(user.email)){ + return ResponseEntity.status(403).build() + } + + users[user.email!!] = user + return ResponseEntity.status(201).build() + } + + + @PostMapping(path = ["/users/login"], consumes = [MediaType.APPLICATION_JSON_VALUE]) + fun login(@RequestBody login : LoginDto) : ResponseEntity{ + + val user = users[login.email!!] + ?: return ResponseEntity.status(404).build() + + if(login.password != user.password){ + return ResponseEntity.status(400).build() + } + + val secret = "$SECRET${System.currentTimeMillis()}" + + tokens[secret] = user.email!! + + return ResponseEntity.ok(AuthDto(user.email, TokenDto(secret))) + } + + @GetMapping(path = ["/check"]) + fun check(@RequestHeader("Authorization") authorization: String?) : ResponseEntity{ + + val secret = authorization!!.substring("Bearer ".length) + + if(tokens.containsKey(secret)){ + return ResponseEntity.ok("OK") + } + + return ResponseEntity.status(401).build() + } +} diff --git a/core-tests/e2e-tests/spring/spring-rest-openapi-v3/src/main/kotlin/com/foo/rest/examples/spring/openapi/v3/logincreateuser/LoginDto.kt b/core-tests/e2e-tests/spring/spring-rest-openapi-v3/src/main/kotlin/com/foo/rest/examples/spring/openapi/v3/logincreateuser/LoginDto.kt new file mode 100644 index 0000000000..cd5181550a --- /dev/null +++ b/core-tests/e2e-tests/spring/spring-rest-openapi-v3/src/main/kotlin/com/foo/rest/examples/spring/openapi/v3/logincreateuser/LoginDto.kt @@ -0,0 +1,6 @@ +package com.foo.rest.examples.spring.openapi.v3.logincreateuser + +class LoginDto( + var email: String? = null, + var password: String? = null +) \ No newline at end of file diff --git a/core-tests/e2e-tests/spring/spring-rest-openapi-v3/src/main/kotlin/com/foo/rest/examples/spring/openapi/v3/logincreateuser/TokenDto.kt b/core-tests/e2e-tests/spring/spring-rest-openapi-v3/src/main/kotlin/com/foo/rest/examples/spring/openapi/v3/logincreateuser/TokenDto.kt new file mode 100644 index 0000000000..c29ee6c04c --- /dev/null +++ b/core-tests/e2e-tests/spring/spring-rest-openapi-v3/src/main/kotlin/com/foo/rest/examples/spring/openapi/v3/logincreateuser/TokenDto.kt @@ -0,0 +1,5 @@ +package com.foo.rest.examples.spring.openapi.v3.logincreateuser + +class TokenDto( + var authToken : String? = null +) \ No newline at end of file diff --git a/core-tests/e2e-tests/spring/spring-rest-openapi-v3/src/main/resources/config/logincreateusers.yaml b/core-tests/e2e-tests/spring/spring-rest-openapi-v3/src/main/resources/config/logincreateusers.yaml new file mode 100644 index 0000000000..25daf47028 --- /dev/null +++ b/core-tests/e2e-tests/spring/spring-rest-openapi-v3/src/main/resources/config/logincreateusers.yaml @@ -0,0 +1,13 @@ +auth: + - name: "CreatedUser" + loginEndpointAuth: + endpoint: "/api/logintokenheader/login" + verb: "POST" + contentType: "application/json" + payloadRaw: '{"email": "{email}", "password": "123456", "username": "{username}"}' + token: + extractFrom: "body" + extractSelector: "/token/authToken" + sendIn: "header" + sendName: "Authorization" + sendTemplate: "Bearer {token}" diff --git a/core-tests/e2e-tests/spring/spring-rest-openapi-v3/src/test/kotlin/com/foo/rest/examples/spring/openapi/v3/logincreateusers/LoginCreateUsersController.kt b/core-tests/e2e-tests/spring/spring-rest-openapi-v3/src/test/kotlin/com/foo/rest/examples/spring/openapi/v3/logincreateusers/LoginCreateUsersController.kt new file mode 100644 index 0000000000..97873866e3 --- /dev/null +++ b/core-tests/e2e-tests/spring/spring-rest-openapi-v3/src/test/kotlin/com/foo/rest/examples/spring/openapi/v3/logincreateusers/LoginCreateUsersController.kt @@ -0,0 +1,20 @@ +package com.foo.rest.examples.spring.openapi.v3.logincreateusers + +import com.foo.rest.examples.spring.openapi.v3.SpringController +import com.foo.rest.examples.spring.openapi.v3.logincreateuser.LoginCreateUsersApplication +import com.foo.rest.examples.spring.openapi.v3.logintoken.LoginTokenApplication +import org.evomaster.client.java.controller.AuthUtils +import org.evomaster.client.java.controller.api.dto.auth.AuthenticationDto +import org.evomaster.client.java.controller.problem.ProblemInfo +import org.evomaster.client.java.controller.problem.RestProblem + +class LoginCreateUsersController : SpringController(LoginCreateUsersApplication::class.java) { + + + override fun getProblemInfo(): ProblemInfo { + return RestProblem( + "http://localhost:$sutPort/v3/api-docs", + null + ) + } +} \ No newline at end of file diff --git a/core-tests/e2e-tests/spring/spring-rest-openapi-v3/src/test/kotlin/org/evomaster/e2etests/spring/openapi/v3/logincreateusers/LoginCreateUsersEMTest.kt b/core-tests/e2e-tests/spring/spring-rest-openapi-v3/src/test/kotlin/org/evomaster/e2etests/spring/openapi/v3/logincreateusers/LoginCreateUsersEMTest.kt new file mode 100644 index 0000000000..ffb6a380a0 --- /dev/null +++ b/core-tests/e2e-tests/spring/spring-rest-openapi-v3/src/test/kotlin/org/evomaster/e2etests/spring/openapi/v3/logincreateusers/LoginCreateUsersEMTest.kt @@ -0,0 +1,41 @@ +package org.evomaster.e2etests.spring.openapi.v3.logincreateusers + +import com.foo.rest.examples.spring.openapi.v3.logincreateusers.LoginCreateUsersController +import com.foo.rest.examples.spring.openapi.v3.logintoken.LoginTokenController +import org.evomaster.core.problem.rest.data.HttpVerb +import org.evomaster.e2etests.spring.openapi.v3.SpringTestBase +import org.junit.jupiter.api.Assertions +import org.junit.jupiter.api.BeforeAll +import org.junit.jupiter.api.Test + +class LoginCreateUsersEMTest : SpringTestBase(){ + + companion object { + @BeforeAll + @JvmStatic + fun init() { + initClass(LoginCreateUsersController()) + } + } + + + @Test + fun testRunBlackBoxEM() { + runTestHandlingFlakyAndCompilation( + "LoginCreateUsersEMBlackBox", + 50 + ) { args: MutableList -> + + setOption(args, "blackBox", "true") + setOption(args, "base", baseUrlOfSut) + setOption(args, "schema", "$baseUrlOfSut/v3/api-docs") + setOption(args, "configPath", "src/main/resources/config/logincreateusers.yaml") + + val solution = initAndRun(args) + + Assertions.assertTrue(solution.individuals.size >= 1) + assertHasAtLeastOne(solution, HttpVerb.GET, 200, "/api/logincreateusers/check", "OK") + } + } + +} \ No newline at end of file From 27f3759f35f1049735f905f2fe3a2ecf1bfc7622 Mon Sep 17 00:00:00 2001 From: arcuri82 Date: Mon, 8 Jun 2026 15:18:31 +0200 Subject: [PATCH 2/7] auth configuration --- .../openapi/v3/logincreateuser/CreateUserDto.kt | 1 + .../v3/logincreateuser/LoginCreateUsersRest.kt | 4 ++++ .../main/resources/config/logincreateusers.yaml | 14 +++++++++++++- 3 files changed, 18 insertions(+), 1 deletion(-) diff --git a/core-tests/e2e-tests/spring/spring-rest-openapi-v3/src/main/kotlin/com/foo/rest/examples/spring/openapi/v3/logincreateuser/CreateUserDto.kt b/core-tests/e2e-tests/spring/spring-rest-openapi-v3/src/main/kotlin/com/foo/rest/examples/spring/openapi/v3/logincreateuser/CreateUserDto.kt index b596e9e0b1..37a791c4f8 100644 --- a/core-tests/e2e-tests/spring/spring-rest-openapi-v3/src/main/kotlin/com/foo/rest/examples/spring/openapi/v3/logincreateuser/CreateUserDto.kt +++ b/core-tests/e2e-tests/spring/spring-rest-openapi-v3/src/main/kotlin/com/foo/rest/examples/spring/openapi/v3/logincreateuser/CreateUserDto.kt @@ -3,5 +3,6 @@ package com.foo.rest.examples.spring.openapi.v3.logincreateuser class CreateUserDto( var email: String? = null, var password: String? = null, + var repeatPassword: String? = null, var username: String? = null ) diff --git a/core-tests/e2e-tests/spring/spring-rest-openapi-v3/src/main/kotlin/com/foo/rest/examples/spring/openapi/v3/logincreateuser/LoginCreateUsersRest.kt b/core-tests/e2e-tests/spring/spring-rest-openapi-v3/src/main/kotlin/com/foo/rest/examples/spring/openapi/v3/logincreateuser/LoginCreateUsersRest.kt index c241ebd3f0..3028a8094e 100644 --- a/core-tests/e2e-tests/spring/spring-rest-openapi-v3/src/main/kotlin/com/foo/rest/examples/spring/openapi/v3/logincreateuser/LoginCreateUsersRest.kt +++ b/core-tests/e2e-tests/spring/spring-rest-openapi-v3/src/main/kotlin/com/foo/rest/examples/spring/openapi/v3/logincreateuser/LoginCreateUsersRest.kt @@ -27,6 +27,10 @@ class LoginCreateUsersRest { return ResponseEntity.status(400).build() } + if(user.password != user.repeatPassword) { + return ResponseEntity.status(400).build() + } + if(users.containsKey(user.email)){ return ResponseEntity.status(403).build() } diff --git a/core-tests/e2e-tests/spring/spring-rest-openapi-v3/src/main/resources/config/logincreateusers.yaml b/core-tests/e2e-tests/spring/spring-rest-openapi-v3/src/main/resources/config/logincreateusers.yaml index 25daf47028..b15298fd1f 100644 --- a/core-tests/e2e-tests/spring/spring-rest-openapi-v3/src/main/resources/config/logincreateusers.yaml +++ b/core-tests/e2e-tests/spring/spring-rest-openapi-v3/src/main/resources/config/logincreateusers.yaml @@ -1,10 +1,22 @@ auth: - name: "CreatedUser" + createUser: + endpoint: "/api/logintokenheader/users" + verb: "POST" + payloadRaw: '{"email": "{email}", "password": "123456", "repeatPassword": "123456", "username": "{username}"}' + generators: + - placeHolder: "{email}" + min: 6 + max: 30 + pattern: "[A-Za-z0-9]{2,}@[A-Za-z0-9]+\.[A-Za-z]{2,}" + - placeHolder: "{username}" + min: 2 + max: 30 loginEndpointAuth: endpoint: "/api/logintokenheader/login" verb: "POST" contentType: "application/json" - payloadRaw: '{"email": "{email}", "password": "123456", "username": "{username}"}' + payloadRaw: '{"email": "{email}", "password": "123456"}' token: extractFrom: "body" extractSelector: "/token/authToken" From 04b9846987c9766a999fcf7af114b719f98dc4c2 Mon Sep 17 00:00:00 2001 From: arcuri82 Date: Mon, 8 Jun 2026 22:10:43 +0200 Subject: [PATCH 3/7] rewrote (faileing) E2E for BB --- .../examples/bb/authcreateusers}/AuthDto.kt | 2 +- .../BBAuthCreateUsersApplication.kt} | 6 +-- .../authcreateusers/BBAuthCreateUsersRest.kt} | 9 ++-- .../bb/authcreateusers}/CreateUserDto.kt | 2 +- .../examples/bb/authcreateusers}/LoginDto.kt | 2 +- .../examples/bb/authcreateusers/TokenDto.kt | 5 ++ .../AuthCreateUsersController.kt | 8 ++++ .../BBAuthCreateUsersEMTest.kt | 48 +++++++++++++++++++ .../resources/config/authcreateusers.yaml} | 0 .../openapi/v3/logincreateuser/TokenDto.kt | 5 -- .../LoginCreateUsersController.kt | 20 -------- .../LoginCreateUsersEMTest.kt | 41 ---------------- 12 files changed, 72 insertions(+), 76 deletions(-) rename core-tests/e2e-tests/spring/{spring-rest-openapi-v3/src/main/kotlin/com/foo/rest/examples/spring/openapi/v3/logincreateuser => spring-rest-bb/src/main/kotlin/com/foo/rest/examples/bb/authcreateusers}/AuthDto.kt (58%) rename core-tests/e2e-tests/spring/{spring-rest-openapi-v3/src/main/kotlin/com/foo/rest/examples/spring/openapi/v3/logincreateuser/LoginCreateUsersApplication.kt => spring-rest-bb/src/main/kotlin/com/foo/rest/examples/bb/authcreateusers/BBAuthCreateUsersApplication.kt} (66%) rename core-tests/e2e-tests/spring/{spring-rest-openapi-v3/src/main/kotlin/com/foo/rest/examples/spring/openapi/v3/logincreateuser/LoginCreateUsersRest.kt => spring-rest-bb/src/main/kotlin/com/foo/rest/examples/bb/authcreateusers/BBAuthCreateUsersRest.kt} (89%) rename core-tests/e2e-tests/spring/{spring-rest-openapi-v3/src/main/kotlin/com/foo/rest/examples/spring/openapi/v3/logincreateuser => spring-rest-bb/src/main/kotlin/com/foo/rest/examples/bb/authcreateusers}/CreateUserDto.kt (71%) rename core-tests/e2e-tests/spring/{spring-rest-openapi-v3/src/main/kotlin/com/foo/rest/examples/spring/openapi/v3/logincreateuser => spring-rest-bb/src/main/kotlin/com/foo/rest/examples/bb/authcreateusers}/LoginDto.kt (58%) create mode 100644 core-tests/e2e-tests/spring/spring-rest-bb/src/main/kotlin/com/foo/rest/examples/bb/authcreateusers/TokenDto.kt create mode 100644 core-tests/e2e-tests/spring/spring-rest-bb/src/test/kotlin/com/foo/rest/examples/bb/authcreateusers/AuthCreateUsersController.kt create mode 100644 core-tests/e2e-tests/spring/spring-rest-bb/src/test/kotlin/org/evomaster/e2etests/spring/rest/bb/authcreateusers/BBAuthCreateUsersEMTest.kt rename core-tests/e2e-tests/spring/{spring-rest-openapi-v3/src/main/resources/config/logincreateusers.yaml => spring-rest-bb/src/test/resources/config/authcreateusers.yaml} (100%) delete mode 100644 core-tests/e2e-tests/spring/spring-rest-openapi-v3/src/main/kotlin/com/foo/rest/examples/spring/openapi/v3/logincreateuser/TokenDto.kt delete mode 100644 core-tests/e2e-tests/spring/spring-rest-openapi-v3/src/test/kotlin/com/foo/rest/examples/spring/openapi/v3/logincreateusers/LoginCreateUsersController.kt delete mode 100644 core-tests/e2e-tests/spring/spring-rest-openapi-v3/src/test/kotlin/org/evomaster/e2etests/spring/openapi/v3/logincreateusers/LoginCreateUsersEMTest.kt diff --git a/core-tests/e2e-tests/spring/spring-rest-openapi-v3/src/main/kotlin/com/foo/rest/examples/spring/openapi/v3/logincreateuser/AuthDto.kt b/core-tests/e2e-tests/spring/spring-rest-bb/src/main/kotlin/com/foo/rest/examples/bb/authcreateusers/AuthDto.kt similarity index 58% rename from core-tests/e2e-tests/spring/spring-rest-openapi-v3/src/main/kotlin/com/foo/rest/examples/spring/openapi/v3/logincreateuser/AuthDto.kt rename to core-tests/e2e-tests/spring/spring-rest-bb/src/main/kotlin/com/foo/rest/examples/bb/authcreateusers/AuthDto.kt index d56c3f07a5..28a38a4716 100644 --- a/core-tests/e2e-tests/spring/spring-rest-openapi-v3/src/main/kotlin/com/foo/rest/examples/spring/openapi/v3/logincreateuser/AuthDto.kt +++ b/core-tests/e2e-tests/spring/spring-rest-bb/src/main/kotlin/com/foo/rest/examples/bb/authcreateusers/AuthDto.kt @@ -1,4 +1,4 @@ -package com.foo.rest.examples.spring.openapi.v3.logincreateuser +package com.foo.rest.examples.bb.authcreateusers class AuthDto( var email : String? = null, diff --git a/core-tests/e2e-tests/spring/spring-rest-openapi-v3/src/main/kotlin/com/foo/rest/examples/spring/openapi/v3/logincreateuser/LoginCreateUsersApplication.kt b/core-tests/e2e-tests/spring/spring-rest-bb/src/main/kotlin/com/foo/rest/examples/bb/authcreateusers/BBAuthCreateUsersApplication.kt similarity index 66% rename from core-tests/e2e-tests/spring/spring-rest-openapi-v3/src/main/kotlin/com/foo/rest/examples/spring/openapi/v3/logincreateuser/LoginCreateUsersApplication.kt rename to core-tests/e2e-tests/spring/spring-rest-bb/src/main/kotlin/com/foo/rest/examples/bb/authcreateusers/BBAuthCreateUsersApplication.kt index acc0f14c92..cb8b03b02a 100644 --- a/core-tests/e2e-tests/spring/spring-rest-openapi-v3/src/main/kotlin/com/foo/rest/examples/spring/openapi/v3/logincreateuser/LoginCreateUsersApplication.kt +++ b/core-tests/e2e-tests/spring/spring-rest-bb/src/main/kotlin/com/foo/rest/examples/bb/authcreateusers/BBAuthCreateUsersApplication.kt @@ -1,4 +1,4 @@ -package com.foo.rest.examples.spring.openapi.v3.logincreateuser +package com.foo.rest.examples.bb.authcreateusers import org.springframework.boot.SpringApplication import org.springframework.boot.autoconfigure.SpringBootApplication @@ -6,12 +6,12 @@ import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfi @SpringBootApplication(exclude = [SecurityAutoConfiguration::class]) -open class LoginCreateUsersApplication { +open class BBAuthCreateUsersApplication { companion object { @JvmStatic fun main(args: Array) { - SpringApplication.run(LoginCreateUsersApplication::class.java, *args) + SpringApplication.run(BBAuthCreateUsersApplication::class.java, *args) } } } \ No newline at end of file diff --git a/core-tests/e2e-tests/spring/spring-rest-openapi-v3/src/main/kotlin/com/foo/rest/examples/spring/openapi/v3/logincreateuser/LoginCreateUsersRest.kt b/core-tests/e2e-tests/spring/spring-rest-bb/src/main/kotlin/com/foo/rest/examples/bb/authcreateusers/BBAuthCreateUsersRest.kt similarity index 89% rename from core-tests/e2e-tests/spring/spring-rest-openapi-v3/src/main/kotlin/com/foo/rest/examples/spring/openapi/v3/logincreateuser/LoginCreateUsersRest.kt rename to core-tests/e2e-tests/spring/spring-rest-bb/src/main/kotlin/com/foo/rest/examples/bb/authcreateusers/BBAuthCreateUsersRest.kt index 3028a8094e..04081f8891 100644 --- a/core-tests/e2e-tests/spring/spring-rest-openapi-v3/src/main/kotlin/com/foo/rest/examples/spring/openapi/v3/logincreateuser/LoginCreateUsersRest.kt +++ b/core-tests/e2e-tests/spring/spring-rest-bb/src/main/kotlin/com/foo/rest/examples/bb/authcreateusers/BBAuthCreateUsersRest.kt @@ -1,13 +1,13 @@ -package com.foo.rest.examples.spring.openapi.v3.logincreateuser +package com.foo.rest.examples.bb.authcreateusers -import com.foo.rest.examples.spring.openapi.v3.wiremock.harvestresponse.UserDto +import org.evomaster.e2etests.utils.CoveredTargets import org.springframework.http.MediaType import org.springframework.http.ResponseEntity import org.springframework.web.bind.annotation.* @RestController -@RequestMapping(path = ["/api/logincreateusers"]) -class LoginCreateUsersRest { +@RequestMapping(path = ["/api/authcreateusers"]) +class BBAuthCreateUsersRest { private val SECRET = "a complex secret - " @@ -63,6 +63,7 @@ class LoginCreateUsersRest { val secret = authorization!!.substring("Bearer ".length) if(tokens.containsKey(secret)){ + CoveredTargets.cover("CHECK") return ResponseEntity.ok("OK") } diff --git a/core-tests/e2e-tests/spring/spring-rest-openapi-v3/src/main/kotlin/com/foo/rest/examples/spring/openapi/v3/logincreateuser/CreateUserDto.kt b/core-tests/e2e-tests/spring/spring-rest-bb/src/main/kotlin/com/foo/rest/examples/bb/authcreateusers/CreateUserDto.kt similarity index 71% rename from core-tests/e2e-tests/spring/spring-rest-openapi-v3/src/main/kotlin/com/foo/rest/examples/spring/openapi/v3/logincreateuser/CreateUserDto.kt rename to core-tests/e2e-tests/spring/spring-rest-bb/src/main/kotlin/com/foo/rest/examples/bb/authcreateusers/CreateUserDto.kt index 37a791c4f8..1e768bf878 100644 --- a/core-tests/e2e-tests/spring/spring-rest-openapi-v3/src/main/kotlin/com/foo/rest/examples/spring/openapi/v3/logincreateuser/CreateUserDto.kt +++ b/core-tests/e2e-tests/spring/spring-rest-bb/src/main/kotlin/com/foo/rest/examples/bb/authcreateusers/CreateUserDto.kt @@ -1,4 +1,4 @@ -package com.foo.rest.examples.spring.openapi.v3.logincreateuser +package com.foo.rest.examples.bb.authcreateusers class CreateUserDto( var email: String? = null, diff --git a/core-tests/e2e-tests/spring/spring-rest-openapi-v3/src/main/kotlin/com/foo/rest/examples/spring/openapi/v3/logincreateuser/LoginDto.kt b/core-tests/e2e-tests/spring/spring-rest-bb/src/main/kotlin/com/foo/rest/examples/bb/authcreateusers/LoginDto.kt similarity index 58% rename from core-tests/e2e-tests/spring/spring-rest-openapi-v3/src/main/kotlin/com/foo/rest/examples/spring/openapi/v3/logincreateuser/LoginDto.kt rename to core-tests/e2e-tests/spring/spring-rest-bb/src/main/kotlin/com/foo/rest/examples/bb/authcreateusers/LoginDto.kt index cd5181550a..dbdedac31a 100644 --- a/core-tests/e2e-tests/spring/spring-rest-openapi-v3/src/main/kotlin/com/foo/rest/examples/spring/openapi/v3/logincreateuser/LoginDto.kt +++ b/core-tests/e2e-tests/spring/spring-rest-bb/src/main/kotlin/com/foo/rest/examples/bb/authcreateusers/LoginDto.kt @@ -1,4 +1,4 @@ -package com.foo.rest.examples.spring.openapi.v3.logincreateuser +package com.foo.rest.examples.bb.authcreateusers class LoginDto( var email: String? = null, diff --git a/core-tests/e2e-tests/spring/spring-rest-bb/src/main/kotlin/com/foo/rest/examples/bb/authcreateusers/TokenDto.kt b/core-tests/e2e-tests/spring/spring-rest-bb/src/main/kotlin/com/foo/rest/examples/bb/authcreateusers/TokenDto.kt new file mode 100644 index 0000000000..74c134ccad --- /dev/null +++ b/core-tests/e2e-tests/spring/spring-rest-bb/src/main/kotlin/com/foo/rest/examples/bb/authcreateusers/TokenDto.kt @@ -0,0 +1,5 @@ +package com.foo.rest.examples.bb.authcreateusers + +class TokenDto( + var authToken : String? = null +) \ No newline at end of file diff --git a/core-tests/e2e-tests/spring/spring-rest-bb/src/test/kotlin/com/foo/rest/examples/bb/authcreateusers/AuthCreateUsersController.kt b/core-tests/e2e-tests/spring/spring-rest-bb/src/test/kotlin/com/foo/rest/examples/bb/authcreateusers/AuthCreateUsersController.kt new file mode 100644 index 0000000000..cb3d52b451 --- /dev/null +++ b/core-tests/e2e-tests/spring/spring-rest-bb/src/test/kotlin/com/foo/rest/examples/bb/authcreateusers/AuthCreateUsersController.kt @@ -0,0 +1,8 @@ +package com.foo.rest.examples.bb.authcreateusers + +import com.foo.rest.examples.bb.SpringController +import com.foo.rest.examples.bb.authcookie.CookieLoginApplication +import org.evomaster.client.java.controller.problem.ProblemInfo +import org.evomaster.client.java.controller.problem.RestProblem + +class AuthCreateUsersController : SpringController(BBAuthCreateUsersApplication::class.java) \ No newline at end of file diff --git a/core-tests/e2e-tests/spring/spring-rest-bb/src/test/kotlin/org/evomaster/e2etests/spring/rest/bb/authcreateusers/BBAuthCreateUsersEMTest.kt b/core-tests/e2e-tests/spring/spring-rest-bb/src/test/kotlin/org/evomaster/e2etests/spring/rest/bb/authcreateusers/BBAuthCreateUsersEMTest.kt new file mode 100644 index 0000000000..f7b4aeba37 --- /dev/null +++ b/core-tests/e2e-tests/spring/spring-rest-bb/src/test/kotlin/org/evomaster/e2etests/spring/rest/bb/authcreateusers/BBAuthCreateUsersEMTest.kt @@ -0,0 +1,48 @@ +package org.evomaster.e2etests.spring.rest.bb.authcreateusers + +import com.foo.rest.examples.bb.authcookie.CookieLoginController +import com.foo.rest.examples.bb.authcreateusers.AuthCreateUsersController +import org.evomaster.core.output.OutputFormat +import org.evomaster.core.problem.rest.data.HttpVerb +import org.evomaster.e2etests.spring.rest.bb.SpringTestBase +import org.evomaster.e2etests.utils.EnterpriseTestBase +import org.junit.jupiter.api.Assertions.assertTrue +import org.junit.jupiter.api.BeforeAll +import org.junit.jupiter.params.ParameterizedTest +import org.junit.jupiter.params.provider.EnumSource + +class BBAuthCreateUsersEMTest : SpringTestBase() { + + companion object { + init { + shouldApplyInstrumentation = false + } + + @BeforeAll + @JvmStatic + fun init() { + initClass(AuthCreateUsersController()) + } + } + + @ParameterizedTest + @EnumSource + fun testBlackBoxOutput(outputFormat: OutputFormat) { + + executeAndEvaluateBBTest( + outputFormat, + "authcreateusers", + 50, + 3, + "CHECK" + ){ args: MutableList -> + + setOption(args, "configPath", "src/main/resources/config/authcreateusers.yaml") + + val solution = initAndRun(args) + + assertTrue(solution.individuals.size >= 1) + assertHasAtLeastOne(solution, HttpVerb.GET, 200, "/api/authcreateusers/check", "OK") + } + } +} \ No newline at end of file diff --git a/core-tests/e2e-tests/spring/spring-rest-openapi-v3/src/main/resources/config/logincreateusers.yaml b/core-tests/e2e-tests/spring/spring-rest-bb/src/test/resources/config/authcreateusers.yaml similarity index 100% rename from core-tests/e2e-tests/spring/spring-rest-openapi-v3/src/main/resources/config/logincreateusers.yaml rename to core-tests/e2e-tests/spring/spring-rest-bb/src/test/resources/config/authcreateusers.yaml diff --git a/core-tests/e2e-tests/spring/spring-rest-openapi-v3/src/main/kotlin/com/foo/rest/examples/spring/openapi/v3/logincreateuser/TokenDto.kt b/core-tests/e2e-tests/spring/spring-rest-openapi-v3/src/main/kotlin/com/foo/rest/examples/spring/openapi/v3/logincreateuser/TokenDto.kt deleted file mode 100644 index c29ee6c04c..0000000000 --- a/core-tests/e2e-tests/spring/spring-rest-openapi-v3/src/main/kotlin/com/foo/rest/examples/spring/openapi/v3/logincreateuser/TokenDto.kt +++ /dev/null @@ -1,5 +0,0 @@ -package com.foo.rest.examples.spring.openapi.v3.logincreateuser - -class TokenDto( - var authToken : String? = null -) \ No newline at end of file diff --git a/core-tests/e2e-tests/spring/spring-rest-openapi-v3/src/test/kotlin/com/foo/rest/examples/spring/openapi/v3/logincreateusers/LoginCreateUsersController.kt b/core-tests/e2e-tests/spring/spring-rest-openapi-v3/src/test/kotlin/com/foo/rest/examples/spring/openapi/v3/logincreateusers/LoginCreateUsersController.kt deleted file mode 100644 index 97873866e3..0000000000 --- a/core-tests/e2e-tests/spring/spring-rest-openapi-v3/src/test/kotlin/com/foo/rest/examples/spring/openapi/v3/logincreateusers/LoginCreateUsersController.kt +++ /dev/null @@ -1,20 +0,0 @@ -package com.foo.rest.examples.spring.openapi.v3.logincreateusers - -import com.foo.rest.examples.spring.openapi.v3.SpringController -import com.foo.rest.examples.spring.openapi.v3.logincreateuser.LoginCreateUsersApplication -import com.foo.rest.examples.spring.openapi.v3.logintoken.LoginTokenApplication -import org.evomaster.client.java.controller.AuthUtils -import org.evomaster.client.java.controller.api.dto.auth.AuthenticationDto -import org.evomaster.client.java.controller.problem.ProblemInfo -import org.evomaster.client.java.controller.problem.RestProblem - -class LoginCreateUsersController : SpringController(LoginCreateUsersApplication::class.java) { - - - override fun getProblemInfo(): ProblemInfo { - return RestProblem( - "http://localhost:$sutPort/v3/api-docs", - null - ) - } -} \ No newline at end of file diff --git a/core-tests/e2e-tests/spring/spring-rest-openapi-v3/src/test/kotlin/org/evomaster/e2etests/spring/openapi/v3/logincreateusers/LoginCreateUsersEMTest.kt b/core-tests/e2e-tests/spring/spring-rest-openapi-v3/src/test/kotlin/org/evomaster/e2etests/spring/openapi/v3/logincreateusers/LoginCreateUsersEMTest.kt deleted file mode 100644 index ffb6a380a0..0000000000 --- a/core-tests/e2e-tests/spring/spring-rest-openapi-v3/src/test/kotlin/org/evomaster/e2etests/spring/openapi/v3/logincreateusers/LoginCreateUsersEMTest.kt +++ /dev/null @@ -1,41 +0,0 @@ -package org.evomaster.e2etests.spring.openapi.v3.logincreateusers - -import com.foo.rest.examples.spring.openapi.v3.logincreateusers.LoginCreateUsersController -import com.foo.rest.examples.spring.openapi.v3.logintoken.LoginTokenController -import org.evomaster.core.problem.rest.data.HttpVerb -import org.evomaster.e2etests.spring.openapi.v3.SpringTestBase -import org.junit.jupiter.api.Assertions -import org.junit.jupiter.api.BeforeAll -import org.junit.jupiter.api.Test - -class LoginCreateUsersEMTest : SpringTestBase(){ - - companion object { - @BeforeAll - @JvmStatic - fun init() { - initClass(LoginCreateUsersController()) - } - } - - - @Test - fun testRunBlackBoxEM() { - runTestHandlingFlakyAndCompilation( - "LoginCreateUsersEMBlackBox", - 50 - ) { args: MutableList -> - - setOption(args, "blackBox", "true") - setOption(args, "base", baseUrlOfSut) - setOption(args, "schema", "$baseUrlOfSut/v3/api-docs") - setOption(args, "configPath", "src/main/resources/config/logincreateusers.yaml") - - val solution = initAndRun(args) - - Assertions.assertTrue(solution.individuals.size >= 1) - assertHasAtLeastOne(solution, HttpVerb.GET, 200, "/api/logincreateusers/check", "OK") - } - } - -} \ No newline at end of file From de54dc52673105613bfeaf0077e239742a5c8c9f Mon Sep 17 00:00:00 2001 From: arcuri82 Date: Tue, 9 Jun 2026 15:15:59 +0200 Subject: [PATCH 4/7] parsing CreateUsers info --- .../resources/config/authcreateusers.yaml | 19 +++-- .../core/problem/httpws/auth/CreateUsers.kt | 57 ++++++++++++++ .../core/problem/httpws/auth/Generator.kt | 76 +++++++++++++++++++ .../httpws/auth/HttpWsAuthenticationInfo.kt | 18 ++++- pom.xml | 2 +- 5 files changed, 159 insertions(+), 13 deletions(-) create mode 100644 core/src/main/kotlin/org/evomaster/core/problem/httpws/auth/CreateUsers.kt create mode 100644 core/src/main/kotlin/org/evomaster/core/problem/httpws/auth/Generator.kt diff --git a/core-tests/e2e-tests/spring/spring-rest-bb/src/test/resources/config/authcreateusers.yaml b/core-tests/e2e-tests/spring/spring-rest-bb/src/test/resources/config/authcreateusers.yaml index b15298fd1f..9c39458edf 100644 --- a/core-tests/e2e-tests/spring/spring-rest-bb/src/test/resources/config/authcreateusers.yaml +++ b/core-tests/e2e-tests/spring/spring-rest-bb/src/test/resources/config/authcreateusers.yaml @@ -1,22 +1,21 @@ auth: - name: "CreatedUser" - createUser: + createUsers: endpoint: "/api/logintokenheader/users" + contentType: "application/json" verb: "POST" - payloadRaw: '{"email": "{email}", "password": "123456", "repeatPassword": "123456", "username": "{username}"}' + payloadRaw: '{"email": "{$username}@example.com", "password": "123456", "repeatPassword": "123456", "username": "{$username}"}' generators: - - placeHolder: "{email}" - min: 6 - max: 30 - pattern: "[A-Za-z0-9]{2,}@[A-Za-z0-9]+\.[A-Za-z]{2,}" - - placeHolder: "{username}" - min: 2 - max: 30 + - placeHolder: "{$username}" + minLength: 8 + maxLength: 30 + prefix: "user_" + postfix: "" loginEndpointAuth: endpoint: "/api/logintokenheader/login" verb: "POST" contentType: "application/json" - payloadRaw: '{"email": "{email}", "password": "123456"}' + payloadRaw: '{"email": "{$username}@example.com", "password": "123456"}' token: extractFrom: "body" extractSelector: "/token/authToken" diff --git a/core/src/main/kotlin/org/evomaster/core/problem/httpws/auth/CreateUsers.kt b/core/src/main/kotlin/org/evomaster/core/problem/httpws/auth/CreateUsers.kt new file mode 100644 index 0000000000..cdad899bfa --- /dev/null +++ b/core/src/main/kotlin/org/evomaster/core/problem/httpws/auth/CreateUsers.kt @@ -0,0 +1,57 @@ +package org.evomaster.core.problem.httpws.auth + +import com.webfuzzing.commons.auth.CreateUsers +import org.evomaster.core.problem.rest.data.ContentType +import org.evomaster.core.problem.rest.data.HttpVerb +import java.net.MalformedURLException +import java.net.URL + +class CreateUsers( + + val endpoint: String?, + + val externalEndpointURL: String?, + + val payload: String, + + val verb: HttpVerb, + + val contentType: ContentType, + + val generators: List +){ + init { + if (endpoint == null && externalEndpointURL == null) { + throw IllegalArgumentException("Either 'endpoint' or 'externalEndpointURL' should be specified") + } + if (endpoint != null && externalEndpointURL != null) { + throw IllegalArgumentException("Cannot have both 'endpoint' and 'externalEndpointURL' specified. It is ambiguous.") + } + if (endpoint != null && !endpoint.startsWith("/")) { + throw IllegalArgumentException( + "Create endpoint definition must start with a /. It is not a full URL." + + " For example: '/users'" + ) + } + if (externalEndpointURL != null) { + try { + URL(externalEndpointURL) + } catch (e: MalformedURLException) { + throw IllegalArgumentException("'externalEndpointURL' is not a valid URL: ${e.message}") + } + } + } + + companion object { + fun fromDto(dto: CreateUsers) : org.evomaster.core.problem.httpws.auth.CreateUsers{ + return CreateUsers( + endpoint = dto.endpoint, + externalEndpointURL = dto.externalEndpointURL, + payload = dto.payloadRaw, + verb = HttpVerb.valueOf(dto.verb.toString()), + contentType = dto.contentType.let { ContentType.from(it)}, + generators = dto.generators.map {Generator.fromDto(it)} + ) + } + } +} \ No newline at end of file diff --git a/core/src/main/kotlin/org/evomaster/core/problem/httpws/auth/Generator.kt b/core/src/main/kotlin/org/evomaster/core/problem/httpws/auth/Generator.kt new file mode 100644 index 0000000000..e4386bd2b7 --- /dev/null +++ b/core/src/main/kotlin/org/evomaster/core/problem/httpws/auth/Generator.kt @@ -0,0 +1,76 @@ +package org.evomaster.core.problem.httpws.auth + +import com.webfuzzing.commons.auth.Generator + +class Generator( + + /** + * Placeholder tag used to represent a value generated with this generator. \ + * String interpolation will be applied to the raw payloads to replace any found instance of \ + * this placeholder with the generated value. + */ + val placeHolder: String, + + /** + * Minimum length of the generated string + */ + val minLength: Int?, + + /** + * Maximum length of the generated string + */ + val maxLength: Int?, + + /** + * Fixed prefix shared by all generated strings + */ + val prefix: String?, + + /** + * Fixed postfix shared by all generated strings + */ + val postfix: String? +){ + + init{ + if(placeHolder.isEmpty()){ + throw IllegalArgumentException("Placeholder can not be empty") + } + if(minLength != null && minLength < 0){ + throw IllegalArgumentException("Minimum length must be greater than or equal to 0, but was $minLength") + } + if(maxLength != null && maxLength < 0){ + throw IllegalArgumentException("Maximum length must be greater than or equal to 0, but was $maxLength") + } + + if(maxLength != null) { + var length = 0 + if (prefix != null) { + length += prefix.length + } + if (postfix != null) { + length += postfix.length + } + if (length >= maxLength) { + throw IllegalArgumentException("If specified, maximum length must be greater than prefix+postfix") + } + } + } + + + companion object { + + fun fromDto(dto: Generator) : org.evomaster.core.problem.httpws.auth.Generator{ + + return Generator( + placeHolder = dto.placeHolder, + minLength = dto.minLength, + maxLength = dto.maxLength, + prefix = dto.prefix, + postfix = dto.postfix + ) + } + + } + +} \ No newline at end of file diff --git a/core/src/main/kotlin/org/evomaster/core/problem/httpws/auth/HttpWsAuthenticationInfo.kt b/core/src/main/kotlin/org/evomaster/core/problem/httpws/auth/HttpWsAuthenticationInfo.kt index 94f621e526..8e3d332c2d 100644 --- a/core/src/main/kotlin/org/evomaster/core/problem/httpws/auth/HttpWsAuthenticationInfo.kt +++ b/core/src/main/kotlin/org/evomaster/core/problem/httpws/auth/HttpWsAuthenticationInfo.kt @@ -24,7 +24,11 @@ open class HttpWsAuthenticationInfo( * for auth in following requests. */ val endpointCallLogin: EndpointCallLogin?, - val requireMockHandling: Boolean + val requireMockHandling: Boolean, + /** + * Represent information on to create new users on-the-fly + */ + val createUsers: CreateUsers? ): AuthenticationInfo(name) { init { @@ -71,7 +75,17 @@ open class HttpWsAuthenticationInfo( val requireMockHandling = dto.requireMockHandling != null && dto.requireMockHandling - return HttpWsAuthenticationInfo(dto.name.trim(), headers, endpointCallLogin, requireMockHandling) + val createUsers = if (dto.createUsers != null){ + try { + CreateUsers.fromDto(dto.createUsers) + }catch (e: Exception){ + throw IllegalArgumentException("Issue when parsing auth info for '${dto.name}': ${e.message}") + } + } else { + null + } + + return HttpWsAuthenticationInfo(dto.name.trim(), headers, endpointCallLogin, requireMockHandling, createUsers) } } diff --git a/pom.xml b/pom.xml index 190cc0f09c..edb4ff0f5a 100644 --- a/pom.xml +++ b/pom.xml @@ -217,7 +217,7 @@ 17 2.2.20 true - 0.5.1 + 0.5.2-SNAPSHOT 5.14.2 1.14.2 3.1.5 From 9e827795f92aa064d7c3c3aecda1be503e2a37b6 Mon Sep 17 00:00:00 2001 From: arcuri82 Date: Tue, 9 Jun 2026 21:57:59 +0200 Subject: [PATCH 5/7] preparing calls to create users --- .../org/evomaster/test/utils/EMTestUtils.java | 15 +++ .../core/problem/httpws/auth/AuthUtils.kt | 121 ++++++++++++++---- .../core/problem/httpws/auth/CreateUsers.kt | 12 +- .../problem/httpws/auth/EndpointCallLogin.kt | 13 +- .../httpws/auth/HttpWsAuthenticationInfo.kt | 2 +- .../httpws/auth/PlaceHolderResolver.kt | 9 ++ 6 files changed, 136 insertions(+), 36 deletions(-) create mode 100644 core/src/main/kotlin/org/evomaster/core/problem/httpws/auth/PlaceHolderResolver.kt diff --git a/client-java/test-utils-java/src/main/java/org/evomaster/test/utils/EMTestUtils.java b/client-java/test-utils-java/src/main/java/org/evomaster/test/utils/EMTestUtils.java index e106cbecce..5141740f52 100644 --- a/client-java/test-utils-java/src/main/java/org/evomaster/test/utils/EMTestUtils.java +++ b/client-java/test-utils-java/src/main/java/org/evomaster/test/utils/EMTestUtils.java @@ -22,6 +22,21 @@ is used in the EvoMaster Core (eg, when making HTTP calls) and */ public class EMTestUtils { + /** + * + * @param minLength Optional minimum length of the generated string + * @param maxLength Optional maximum length of the generated string + * @param prefix Optional fixed prefix shared by all generated strings + * @param postfix Optional fixed postfix shared by all generated strings + * @return + */ + public static String createString(Integer minLength, Integer maxLength, String prefix, String postfix){ + + TODO + return null; + } + + /** * * @param locationHeader a URI-reference, coming from a "location" header. See RFC 7231. diff --git a/core/src/main/kotlin/org/evomaster/core/problem/httpws/auth/AuthUtils.kt b/core/src/main/kotlin/org/evomaster/core/problem/httpws/auth/AuthUtils.kt index cb8afa5e8d..9c0e52390a 100644 --- a/core/src/main/kotlin/org/evomaster/core/problem/httpws/auth/AuthUtils.kt +++ b/core/src/main/kotlin/org/evomaster/core/problem/httpws/auth/AuthUtils.kt @@ -1,6 +1,8 @@ package org.evomaster.core.problem.httpws.auth import com.fasterxml.jackson.databind.ObjectMapper +import org.checkerframework.checker.units.qual.g +import org.evomaster.core.Lazy import org.evomaster.core.logging.LoggingUtil import org.evomaster.core.output.auth.CookieWriter import org.evomaster.core.output.auth.TokenWriter @@ -11,6 +13,7 @@ import org.evomaster.core.problem.rest.data.ContentType import org.evomaster.core.problem.rest.data.HttpVerb import org.evomaster.core.problem.rest.data.RestCallAction import org.evomaster.core.search.Individual +import org.evomaster.test.utils.EMTestUtils import org.slf4j.Logger import org.slf4j.LoggerFactory import javax.ws.rs.client.Client @@ -25,7 +28,7 @@ object AuthUtils { private val log: Logger = LoggerFactory.getLogger(AuthUtils::class.java) - fun getTokens(client: Client, baseUrl: String, ind: Individual): Map{ + fun getTokens(client: Client, baseUrl: String, ind: Individual): Map { val tokensLogin = TokenWriter.getTokenLoginAuth(ind) return getTokens(client, baseUrl, tokensLogin) } @@ -34,14 +37,14 @@ object AuthUtils { * If any action needs auth based on tokens via JSON, do a "login" before * running the actions, and store the tokens */ - fun getTokens(client: Client, baseUrl: String, tokensLogin: List): Map{ + fun getTokens(client: Client, baseUrl: String, tokensLogin: List): Map { //from userId to Token val map = mutableMapOf() - for(tl in tokensLogin){ + for (tl in tokensLogin) { - if(tl.expectsCookie()){ + if (tl.expectsCookie()) { throw IllegalArgumentException("Token based login does not expect cookies") } val data = tl.token ?: throw IllegalArgumentException("Token based login requires token definition") @@ -49,9 +52,9 @@ object AuthUtils { val response = makeCall(client, tl, baseUrl) ?: continue - var token = when(data.extractFrom){ + var token = when (data.extractFrom) { TokenHandling.ExtractFrom.BODY -> { - if(! response.hasEntity()){ + if (!response.hasEntity()) { log.warn("Login request failed, with no body response from which to extract the auth token") continue } @@ -62,16 +65,17 @@ object AuthUtils { val jackson = ObjectMapper() val tree = jackson.readTree(body) val token = tree.at(tl.token!!.extractSelector).asText() - if(token == null || token.isEmpty()){ + if (token == null || token.isEmpty()) { log.warn("Failed login. Cannot extract token '${data.extractSelector}' from response: $body") continue } token } + TokenHandling.ExtractFrom.HEADER -> { val header = response.getHeaderString(data.extractSelector) response.close() - if(header == null || header.isEmpty()){ + if (header == null || header.isEmpty()) { log.warn("Failed login. No token to extract from header '${data.extractSelector}'") continue } @@ -79,8 +83,8 @@ object AuthUtils { } } - if(data.sendTemplate.isNotEmpty()){ - token = data.sendTemplate.replace("{token}", token) + if (data.sendTemplate.isNotEmpty()) { + token = data.sendTemplate.replace("{token}", token) } map[tl.name] = token @@ -102,13 +106,17 @@ object AuthUtils { * * @return a map from username to auth cookie for those users */ - fun getCookies(client: Client, baseUrl: String, cookieLogins: List): Map> { + fun getCookies( + client: Client, + baseUrl: String, + cookieLogins: List + ): Map> { val map: MutableMap> = mutableMapOf() for (cl in cookieLogins) { - if(!cl.expectsCookie()){ + if (!cl.expectsCookie()) { throw IllegalArgumentException("Cookie based login expects cookies") } @@ -128,33 +136,102 @@ object AuthUtils { return map } + TODO call it + + /** + * Make calls to create new users. + * Each user will be chosen with info based on the declared generators. + */ + fun createUsers( + client: Client, + baseUrl: String, + createUsersList: List + ): List { + + val results = mutableListOf() + + for(c in createUsersList) { + var payload = c.payload + val placeHolders = mutableMapOf() + + for(g in c.generators) { + val generated = EMTestUtils.createString(g.minLength, g.maxLength, g.prefix, g.postfix) + placeHolders[g.placeHolder] = generated + payload = payload.replace(g.placeHolder, generated) + } + + val response = makeCall(client, baseUrl, c.verb, c.contentType, payload, listOf(), c.endpoint, c.externalEndpointURL) + ?: continue + response.close() + + results.add(PlaceHolderResolver(c.name, placeHolders)) + } + + return results + } - private fun makeCall(client: Client, x: EndpointCallLogin, baseUrl: String) : Response?{ + fun constructUrl(baseUrl: String, endpoint: String?, externalEndpointURL: String?): String { + + if (externalEndpointURL != null) { + return externalEndpointURL + } + + val s = baseUrl.trim() + + if (!s.startsWith("http://", true) && !s.startsWith("https://")) { + throw IllegalArgumentException("baseUrl should use HTTP(S): $baseUrl") + } + + if(endpoint == null || !endpoint.startsWith("/")) { + throw IllegalArgumentException("Invalid endpoint when externalEndpointURL is null -> $endpoint") + } + + return if (s.endsWith("/")) { + s.substring(0, s.length - 1) + endpoint + } else { + s + endpoint + } + } + + + private fun makeCall(client: Client, x: EndpointCallLogin, baseUrl: String): Response?{ + return makeCall(client, baseUrl, x.verb, x.contentType, x.payload, x.headers, x.endpoint, x.externalEndpointURL) + } - val mediaType = when (x.contentType) { + private fun makeCall( + client: Client, + baseUrl: String, + verb: HttpVerb, + contentType: ContentType?, + payload: String?, + headers: List, + endpoint: String?, + externalEndpointURL: String? + ) : Response?{ + + val mediaType = when (contentType) { ContentType.X_WWW_FORM_URLENCODED -> MediaType.APPLICATION_FORM_URLENCODED_TYPE ContentType.JSON -> MediaType.APPLICATION_JSON_TYPE null -> null } val bodyEntity = if(mediaType != null) { - Entity.entity(x.payload, mediaType) + Entity.entity(payload, mediaType) } else { null } - val builder = client.target(x.getUrl(baseUrl)).request() + val builder = client.target(constructUrl(baseUrl,endpoint,externalEndpointURL)).request() - x.headers.forEach { builder.header(it.name, it.value) } + headers.forEach { builder.header(it.name, it.value) } if(mediaType!=null){ builder.header("Content-Type", mediaType) } - //TODO duplicated code, should put in a utility val invocation = if(bodyEntity != null) { - when (x.verb) { + when (verb) { HttpVerb.GET -> builder.buildGet() HttpVerb.DELETE -> builder.build("DELETE", bodyEntity) HttpVerb.POST -> builder.buildPost(bodyEntity) @@ -165,7 +242,7 @@ object AuthUtils { HttpVerb.TRACE -> builder.build("TRACE") } } else { - builder.build(x.verb.toString()) + builder.build(verb.toString()) } val response = try { @@ -188,12 +265,12 @@ object AuthUtils { if (response.statusInfo.family == Response.Status.Family.REDIRECTION) { val location = response.getHeaderString("location") if (location != null && (location.contains("error", true) || location.contains("login", true))) { - log.warn("Login request failed with ${response.status} redirection toward $location") + log.warn("Auth request failed with ${response.status} redirection toward $location") response.close() return null } } else { - log.warn("Login request failed with status ${response.status}") + log.warn("Auth request failed with status ${response.status}") response.close() return null } diff --git a/core/src/main/kotlin/org/evomaster/core/problem/httpws/auth/CreateUsers.kt b/core/src/main/kotlin/org/evomaster/core/problem/httpws/auth/CreateUsers.kt index cdad899bfa..7e7780569c 100644 --- a/core/src/main/kotlin/org/evomaster/core/problem/httpws/auth/CreateUsers.kt +++ b/core/src/main/kotlin/org/evomaster/core/problem/httpws/auth/CreateUsers.kt @@ -8,6 +8,8 @@ import java.net.URL class CreateUsers( + val name: String, + val endpoint: String?, val externalEndpointURL: String?, @@ -40,11 +42,19 @@ class CreateUsers( throw IllegalArgumentException("'externalEndpointURL' is not a valid URL: ${e.message}") } } + + for (generator in generators) { + val placeholder = generator.placeHolder + if(!payload.contains(placeholder)) { + throw IllegalArgumentException("Payload does not contain the placeholder '$placeholder': $payload") + } + } } companion object { - fun fromDto(dto: CreateUsers) : org.evomaster.core.problem.httpws.auth.CreateUsers{ + fun fromDto(name: String, dto: CreateUsers) : org.evomaster.core.problem.httpws.auth.CreateUsers{ return CreateUsers( + name = name, endpoint = dto.endpoint, externalEndpointURL = dto.externalEndpointURL, payload = dto.payloadRaw, diff --git a/core/src/main/kotlin/org/evomaster/core/problem/httpws/auth/EndpointCallLogin.kt b/core/src/main/kotlin/org/evomaster/core/problem/httpws/auth/EndpointCallLogin.kt index bf0e705f5a..31803b1612 100644 --- a/core/src/main/kotlin/org/evomaster/core/problem/httpws/auth/EndpointCallLogin.kt +++ b/core/src/main/kotlin/org/evomaster/core/problem/httpws/auth/EndpointCallLogin.kt @@ -155,18 +155,7 @@ class EndpointCallLogin( fun expectsCookie() = token == null fun getUrl(baseUrl: String): String { - val s = baseUrl.trim() - if (externalEndpointURL != null) return externalEndpointURL - - if (!s.startsWith("http://", true) && !s.startsWith("https://")) { - throw IllegalArgumentException("baseUrl should use HTTP(S): $baseUrl") - } - Lazy.assert { endpoint != null && endpoint.startsWith("/") } - return if (s.endsWith("/")) { - s.substring(0, s.length - 1) + endpoint - } else { - s + endpoint - } + return AuthUtils.constructUrl(baseUrl, endpoint, externalEndpointURL) } diff --git a/core/src/main/kotlin/org/evomaster/core/problem/httpws/auth/HttpWsAuthenticationInfo.kt b/core/src/main/kotlin/org/evomaster/core/problem/httpws/auth/HttpWsAuthenticationInfo.kt index 8e3d332c2d..c91987f906 100644 --- a/core/src/main/kotlin/org/evomaster/core/problem/httpws/auth/HttpWsAuthenticationInfo.kt +++ b/core/src/main/kotlin/org/evomaster/core/problem/httpws/auth/HttpWsAuthenticationInfo.kt @@ -77,7 +77,7 @@ open class HttpWsAuthenticationInfo( val createUsers = if (dto.createUsers != null){ try { - CreateUsers.fromDto(dto.createUsers) + CreateUsers.fromDto(dto.name, dto.createUsers) }catch (e: Exception){ throw IllegalArgumentException("Issue when parsing auth info for '${dto.name}': ${e.message}") } diff --git a/core/src/main/kotlin/org/evomaster/core/problem/httpws/auth/PlaceHolderResolver.kt b/core/src/main/kotlin/org/evomaster/core/problem/httpws/auth/PlaceHolderResolver.kt new file mode 100644 index 0000000000..165a496148 --- /dev/null +++ b/core/src/main/kotlin/org/evomaster/core/problem/httpws/auth/PlaceHolderResolver.kt @@ -0,0 +1,9 @@ +package org.evomaster.core.problem.httpws.auth + +class PlaceHolderResolver( + val name: String, + /** + * Map from (key) placeholder to (value) newly created string that will replace it + */ + val placeHolders: Map +) \ No newline at end of file From f1aec82043ff8cea0db11ebd0c56533c497a8da1 Mon Sep 17 00:00:00 2001 From: arcuri82 Date: Sat, 13 Jun 2026 21:28:15 +0200 Subject: [PATCH 6/7] createusers handling in fitness function --- .../org/evomaster/test/utils/EMTestUtils.java | 62 ++++++++++++++++++- .../evomaster/test/utils/EMTestUtilsTest.java | 30 +++++++-- .../BBAuthCreateUsersEMTest.kt | 2 +- .../core/output/auth/CreateUsersWriter.kt | 13 ++++ .../problem/graphql/service/GraphQLFitness.kt | 5 +- .../core/problem/httpws/auth/AuthUtils.kt | 51 ++++++++++----- .../core/problem/httpws/auth/HttpWsNoAuth.kt | 2 +- .../core/problem/rest/schema/OpenApiAccess.kt | 8 ++- .../service/fitness/BlackBoxRestFitness.kt | 5 +- .../service/fitness/ResourceRestFitness.kt | 5 +- .../rest/service/fitness/RestFitness.kt | 5 +- 11 files changed, 156 insertions(+), 32 deletions(-) create mode 100644 core/src/main/kotlin/org/evomaster/core/output/auth/CreateUsersWriter.kt diff --git a/client-java/test-utils-java/src/main/java/org/evomaster/test/utils/EMTestUtils.java b/client-java/test-utils-java/src/main/java/org/evomaster/test/utils/EMTestUtils.java index 5141740f52..664032249f 100644 --- a/client-java/test-utils-java/src/main/java/org/evomaster/test/utils/EMTestUtils.java +++ b/client-java/test-utils-java/src/main/java/org/evomaster/test/utils/EMTestUtils.java @@ -22,6 +22,15 @@ is used in the EvoMaster Core (eg, when making HTTP calls) and */ public class EMTestUtils { + /** + * Loaded only once at class loading. + * Seed is still going to incremented with ++ at each use. + * The idea is to force each value unique during a session, even when generating hundreds of thousands of tests. + * However, when running again in generated test suite, a new starting seed might reduce chances of clashes, + * albeit cannot guarantee removal of them + */ + private static long seed = System.currentTimeMillis(); + /** * * @param minLength Optional minimum length of the generated string @@ -32,8 +41,57 @@ public class EMTestUtils { */ public static String createString(Integer minLength, Integer maxLength, String prefix, String postfix){ - TODO - return null; + if(minLength != null && minLength < 0){ + throw new IllegalArgumentException("Negative minimum length: " + minLength); + } + if(maxLength != null && maxLength < 0){ + throw new IllegalArgumentException("Negative maximum length: " + maxLength); + } + + int min = 0; + if(minLength != null){ + min = minLength; + } + int len = 0; + if(prefix != null){ + len += prefix.length(); + } + if(postfix != null){ + len += postfix.length(); + } + min = Math.max(min, len); + + //actual check on inputs + if(maxLength != null && maxLength < len){ + throw new IllegalArgumentException("Maximum length " + maxLength + " does not cover minimum prefix+postfix length: "+prefix+postfix); + } + + //recompute with default values if not specified + if(prefix == null){ + prefix = "u"; + } + if(postfix == null){ + postfix = ""; + } + len = prefix.length() + postfix.length(); + + int maxDigits = 6; // 999 999 values + if(maxDigits + len < min){ + maxDigits = min - len; + } + if(maxLength != null && maxDigits + len > maxLength ){ + maxDigits = maxLength - len; + } + + int mask = 1; + for(int i = 0; i < maxDigits; i++){ + mask = mask * 10; + } + + long value = seed % mask; + seed++; + + return prefix + value + postfix; } diff --git a/client-java/test-utils-java/src/test/java/org/evomaster/test/utils/EMTestUtilsTest.java b/client-java/test-utils-java/src/test/java/org/evomaster/test/utils/EMTestUtilsTest.java index dd3fe17261..4f3bb05c63 100644 --- a/client-java/test-utils-java/src/test/java/org/evomaster/test/utils/EMTestUtilsTest.java +++ b/client-java/test-utils-java/src/test/java/org/evomaster/test/utils/EMTestUtilsTest.java @@ -1,13 +1,35 @@ package org.evomaster.test.utils; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertTrue; - import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.*; + public class EMTestUtilsTest { + @Test + public void testCreateString(){ + + String prefix = "foo"; + String postfix = "bar"; + int min = 5; + int max = 10; + + String first = EMTestUtils.createString(min, max, prefix, postfix); + assertTrue(first.startsWith(prefix)); + assertTrue(first.endsWith(postfix)); + assertTrue(first.length() >= min); + assertTrue(first.length() <= max); + + String second = EMTestUtils.createString(min, max, prefix, postfix); + assertTrue(second.startsWith(prefix)); + assertTrue(second.endsWith(postfix)); + assertTrue(second.length() >= min); + assertTrue(second.length() <= max); + + assertNotEquals(first, second); + } + + @Test public void testEmptyPath(){ diff --git a/core-tests/e2e-tests/spring/spring-rest-bb/src/test/kotlin/org/evomaster/e2etests/spring/rest/bb/authcreateusers/BBAuthCreateUsersEMTest.kt b/core-tests/e2e-tests/spring/spring-rest-bb/src/test/kotlin/org/evomaster/e2etests/spring/rest/bb/authcreateusers/BBAuthCreateUsersEMTest.kt index f7b4aeba37..0e8dee74cd 100644 --- a/core-tests/e2e-tests/spring/spring-rest-bb/src/test/kotlin/org/evomaster/e2etests/spring/rest/bb/authcreateusers/BBAuthCreateUsersEMTest.kt +++ b/core-tests/e2e-tests/spring/spring-rest-bb/src/test/kotlin/org/evomaster/e2etests/spring/rest/bb/authcreateusers/BBAuthCreateUsersEMTest.kt @@ -37,7 +37,7 @@ class BBAuthCreateUsersEMTest : SpringTestBase() { "CHECK" ){ args: MutableList -> - setOption(args, "configPath", "src/main/resources/config/authcreateusers.yaml") + setOption(args, "configPath", "src/test/resources/config/authcreateusers.yaml") val solution = initAndRun(args) diff --git a/core/src/main/kotlin/org/evomaster/core/output/auth/CreateUsersWriter.kt b/core/src/main/kotlin/org/evomaster/core/output/auth/CreateUsersWriter.kt new file mode 100644 index 0000000000..41b9fb2211 --- /dev/null +++ b/core/src/main/kotlin/org/evomaster/core/output/auth/CreateUsersWriter.kt @@ -0,0 +1,13 @@ +package org.evomaster.core.output.auth + +import org.evomaster.core.problem.httpws.HttpWsAction +import org.evomaster.core.search.Individual + +object CreateUsersWriter { + + fun getCreateUsersAuth(ind: Individual) = ind.seeAllActions() + .filterIsInstance() + .filter { it.auth.createUsers != null } + .distinctBy { it.auth.name } + .map { it.auth.createUsers!! } +} \ No newline at end of file diff --git a/core/src/main/kotlin/org/evomaster/core/problem/graphql/service/GraphQLFitness.kt b/core/src/main/kotlin/org/evomaster/core/problem/graphql/service/GraphQLFitness.kt index e1d1876ed2..da881fc358 100644 --- a/core/src/main/kotlin/org/evomaster/core/problem/graphql/service/GraphQLFitness.kt +++ b/core/src/main/kotlin/org/evomaster/core/problem/graphql/service/GraphQLFitness.kt @@ -42,8 +42,9 @@ open class GraphQLFitness : HttpWsFitness() { goingToStartExecutingNewTest() - val cookies = AuthUtils.getCookies(client, getBaseUrl(), individual) - val tokens = AuthUtils.getTokens(client, getBaseUrl(), individual) + val placeholders = AuthUtils.createUsers(client, getBaseUrl(), individual) + val cookies = AuthUtils.getCookies(client, getBaseUrl(), individual, placeholders) + val tokens = AuthUtils.getTokens(client, getBaseUrl(), individual, placeholders) val actionResults: MutableList = mutableListOf() diff --git a/core/src/main/kotlin/org/evomaster/core/problem/httpws/auth/AuthUtils.kt b/core/src/main/kotlin/org/evomaster/core/problem/httpws/auth/AuthUtils.kt index 9c0e52390a..08e9e69dbf 100644 --- a/core/src/main/kotlin/org/evomaster/core/problem/httpws/auth/AuthUtils.kt +++ b/core/src/main/kotlin/org/evomaster/core/problem/httpws/auth/AuthUtils.kt @@ -5,6 +5,7 @@ import org.checkerframework.checker.units.qual.g import org.evomaster.core.Lazy import org.evomaster.core.logging.LoggingUtil import org.evomaster.core.output.auth.CookieWriter +import org.evomaster.core.output.auth.CreateUsersWriter import org.evomaster.core.output.auth.TokenWriter import org.evomaster.core.problem.enterprise.auth.NoAuth import org.evomaster.core.problem.graphql.GraphQLAction @@ -28,16 +29,16 @@ object AuthUtils { private val log: Logger = LoggerFactory.getLogger(AuthUtils::class.java) - fun getTokens(client: Client, baseUrl: String, ind: Individual): Map { + fun getTokens(client: Client, baseUrl: String, ind: Individual, placeholders: List): Map { val tokensLogin = TokenWriter.getTokenLoginAuth(ind) - return getTokens(client, baseUrl, tokensLogin) + return getTokens(client, baseUrl, tokensLogin, placeholders) } /** * If any action needs auth based on tokens via JSON, do a "login" before * running the actions, and store the tokens */ - fun getTokens(client: Client, baseUrl: String, tokensLogin: List): Map { + fun getTokens(client: Client, baseUrl: String, tokensLogin: List, placeholders: List): Map { //from userId to Token val map = mutableMapOf() @@ -49,7 +50,7 @@ object AuthUtils { } val data = tl.token ?: throw IllegalArgumentException("Token based login requires token definition") - val response = makeCall(client, tl, baseUrl) + val response = makeCall(client, tl, baseUrl, placeholders) ?: continue var token = when (data.extractFrom) { @@ -94,10 +95,9 @@ object AuthUtils { } - fun getCookies(client: Client, baseUrl: String, ind: Individual): Map> { - + fun getCookies(client: Client, baseUrl: String, ind: Individual, placeholders: List): Map> { val cookieLogins = CookieWriter.getCookieLoginAuth(ind) - return getCookies(client, baseUrl, cookieLogins) + return getCookies(client, baseUrl, cookieLogins, placeholders) } /** @@ -109,7 +109,8 @@ object AuthUtils { fun getCookies( client: Client, baseUrl: String, - cookieLogins: List + cookieLogins: List, + placeholders: List ): Map> { val map: MutableMap> = mutableMapOf() @@ -121,7 +122,7 @@ object AuthUtils { } - val response = makeCall(client, cl, baseUrl) + val response = makeCall(client, cl, baseUrl, placeholders) ?: continue response.close() @@ -136,7 +137,14 @@ object AuthUtils { return map } - TODO call it + + fun createUsers( + client: Client, + baseUrl: String, + individual: Individual + ) : List { + return createUsers(client, baseUrl, CreateUsersWriter.getCreateUsersAuth(individual)) + } /** * Make calls to create new users. @@ -161,7 +169,7 @@ object AuthUtils { payload = payload.replace(g.placeHolder, generated) } - val response = makeCall(client, baseUrl, c.verb, c.contentType, payload, listOf(), c.endpoint, c.externalEndpointURL) + val response = makeCall(client, baseUrl, c.name, c.verb, c.contentType, payload, listOf(), c.endpoint, c.externalEndpointURL) ?: continue response.close() @@ -195,13 +203,28 @@ object AuthUtils { } - private fun makeCall(client: Client, x: EndpointCallLogin, baseUrl: String): Response?{ - return makeCall(client, baseUrl, x.verb, x.contentType, x.payload, x.headers, x.endpoint, x.externalEndpointURL) + private fun makeCall(client: Client, x: EndpointCallLogin, baseUrl: String, placeholders: List): Response?{ + + val resolver = placeholders.firstOrNull { it.name == x.name } + val payload = if(resolver == null){ + x.payload + } else { + var modified = x.payload + if(modified != null) { + for (p in resolver.placeHolders.entries) { + modified = modified!!.replace(p.key, p.value) + } + } + modified + } + + return makeCall(client, baseUrl, x.name, x.verb, x.contentType, payload, x.headers, x.endpoint, x.externalEndpointURL) } private fun makeCall( client: Client, baseUrl: String, + name: String, verb: HttpVerb, contentType: ContentType?, payload: String?, @@ -248,7 +271,7 @@ object AuthUtils { val response = try { invocation.invoke() } catch (e: Exception) { - log.warn("Failed to login for ${x.name}: $e") + log.warn("Failed to login for ${name}: $e") return null } diff --git a/core/src/main/kotlin/org/evomaster/core/problem/httpws/auth/HttpWsNoAuth.kt b/core/src/main/kotlin/org/evomaster/core/problem/httpws/auth/HttpWsNoAuth.kt index fdb4df9322..6ec5f46aa1 100644 --- a/core/src/main/kotlin/org/evomaster/core/problem/httpws/auth/HttpWsNoAuth.kt +++ b/core/src/main/kotlin/org/evomaster/core/problem/httpws/auth/HttpWsNoAuth.kt @@ -3,4 +3,4 @@ package org.evomaster.core.problem.httpws.auth import org.evomaster.core.problem.enterprise.auth.NoAuth -class HttpWsNoAuth : HttpWsAuthenticationInfo("NoAuth", listOf(), null, false), NoAuth \ No newline at end of file +class HttpWsNoAuth : HttpWsAuthenticationInfo("NoAuth", listOf(), null, false, null), NoAuth \ No newline at end of file diff --git a/core/src/main/kotlin/org/evomaster/core/problem/rest/schema/OpenApiAccess.kt b/core/src/main/kotlin/org/evomaster/core/problem/rest/schema/OpenApiAccess.kt index 5432418a83..f44aecc0f6 100644 --- a/core/src/main/kotlin/org/evomaster/core/problem/rest/schema/OpenApiAccess.kt +++ b/core/src/main/kotlin/org/evomaster/core/problem/rest/schema/OpenApiAccess.kt @@ -212,16 +212,20 @@ object OpenApiAccess { */ val baseUrl = "${url.protocol}://${url.host}:${url.port}" + //TODO should handle CreateUsers here? + val cookies = if(ecl != null && ecl.expectsCookie()) AuthUtils.getCookies( client, baseUrl, - listOf(ecl) + listOf(ecl), + listOf() ) else mapOf() val tokens = if(ecl != null && !ecl.expectsCookie()) AuthUtils.getTokens( client, baseUrl, - listOf(ecl) + listOf(ecl), + listOf() ) else mapOf() diff --git a/core/src/main/kotlin/org/evomaster/core/problem/rest/service/fitness/BlackBoxRestFitness.kt b/core/src/main/kotlin/org/evomaster/core/problem/rest/service/fitness/BlackBoxRestFitness.kt index bc93bafb9a..5e4aeee0c5 100644 --- a/core/src/main/kotlin/org/evomaster/core/problem/rest/service/fitness/BlackBoxRestFitness.kt +++ b/core/src/main/kotlin/org/evomaster/core/problem/rest/service/fitness/BlackBoxRestFitness.kt @@ -49,8 +49,9 @@ class BlackBoxRestFitness : RestFitness() { rc.resetSUT() } - cookies.putAll(AuthUtils.getCookies(client, getBaseUrl(), individual)) - tokens.putAll(AuthUtils.getTokens(client, getBaseUrl(), individual)) + val placeholders = AuthUtils.createUsers(client, getBaseUrl(), individual) + cookies.putAll(AuthUtils.getCookies(client, getBaseUrl(), individual, placeholders)) + tokens.putAll(AuthUtils.getTokens(client, getBaseUrl(), individual, placeholders)) val fv = FitnessValue(individual.size().toDouble()) diff --git a/core/src/main/kotlin/org/evomaster/core/problem/rest/service/fitness/ResourceRestFitness.kt b/core/src/main/kotlin/org/evomaster/core/problem/rest/service/fitness/ResourceRestFitness.kt index d8e6abec88..f7887da108 100644 --- a/core/src/main/kotlin/org/evomaster/core/problem/rest/service/fitness/ResourceRestFitness.kt +++ b/core/src/main/kotlin/org/evomaster/core/problem/rest/service/fitness/ResourceRestFitness.kt @@ -60,8 +60,9 @@ class ResourceRestFitness : AbstractRestFitness() { which prevents the retrieval of token or cookie values. */ - val cookies = AuthUtils.getCookies(client, getBaseUrl(), individual) - val tokens = AuthUtils.getTokens(client, getBaseUrl(), individual) + val placeholders = AuthUtils.createUsers(client, getBaseUrl(), individual) + val cookies = AuthUtils.getCookies(client, getBaseUrl(), individual, placeholders) + val tokens = AuthUtils.getTokens(client, getBaseUrl(), individual, placeholders) /* there might some dbaction between rest actions. diff --git a/core/src/main/kotlin/org/evomaster/core/problem/rest/service/fitness/RestFitness.kt b/core/src/main/kotlin/org/evomaster/core/problem/rest/service/fitness/RestFitness.kt index bf4a9a4e11..83555c0ae9 100644 --- a/core/src/main/kotlin/org/evomaster/core/problem/rest/service/fitness/RestFitness.kt +++ b/core/src/main/kotlin/org/evomaster/core/problem/rest/service/fitness/RestFitness.kt @@ -31,8 +31,9 @@ open class RestFitness : AbstractRestFitness() { rc.resetSUT() goingToStartExecutingNewTest() - val cookies = AuthUtils.getCookies(client, getBaseUrl(), individual) - val tokens = AuthUtils.getTokens(client, getBaseUrl(), individual) + val placeholders = AuthUtils.createUsers(client, getBaseUrl(), individual) + val cookies = AuthUtils.getCookies(client, getBaseUrl(), individual, placeholders) + val tokens = AuthUtils.getTokens(client, getBaseUrl(), individual, placeholders) if (log.isTraceEnabled){ log.trace("do evaluate the individual, which contains {} dbactions and {} rest actions", From a64f474c4f79a8cf253e6d5122b9c4dfcedbac3e Mon Sep 17 00:00:00 2001 From: arcuri82 Date: Sat, 13 Jun 2026 21:36:53 +0200 Subject: [PATCH 7/7] fixed E2E, but still have to handle createusers in generated output --- .../src/test/resources/config/authcreateusers.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core-tests/e2e-tests/spring/spring-rest-bb/src/test/resources/config/authcreateusers.yaml b/core-tests/e2e-tests/spring/spring-rest-bb/src/test/resources/config/authcreateusers.yaml index 9c39458edf..9bc398a34c 100644 --- a/core-tests/e2e-tests/spring/spring-rest-bb/src/test/resources/config/authcreateusers.yaml +++ b/core-tests/e2e-tests/spring/spring-rest-bb/src/test/resources/config/authcreateusers.yaml @@ -1,7 +1,7 @@ auth: - name: "CreatedUser" createUsers: - endpoint: "/api/logintokenheader/users" + endpoint: "/api/authcreateusers/users" contentType: "application/json" verb: "POST" payloadRaw: '{"email": "{$username}@example.com", "password": "123456", "repeatPassword": "123456", "username": "{$username}"}' @@ -12,7 +12,7 @@ auth: prefix: "user_" postfix: "" loginEndpointAuth: - endpoint: "/api/logintokenheader/login" + endpoint: "/api/authcreateusers/users/login" verb: "POST" contentType: "application/json" payloadRaw: '{"email": "{$username}@example.com", "password": "123456"}'