From f1ca406585d6a3319e0f8a403ab4fd537cdb3ba8 Mon Sep 17 00:00:00 2001 From: Daniel Lopera Date: Sun, 13 Sep 2026 20:03:41 -0300 Subject: [PATCH 1/2] Test e2e: ArazzoEMTest --- .../v3/arazzo/ArazzoPetCouponsApplication.kt | 16 + .../openapi/v3/arazzo/ArazzoPetCouponsRest.kt | 42 ++ .../openapi/v3/arazzo/PetCouponsDtos.kt | 16 + .../resources/static/pet-coupons-arazzo.yaml | 160 ++++++ .../resources/static/pet-coupons-openapi.yaml | 532 ++++++++++++++++++ .../v3/arazzo/ArazzoPetCouponsController.kt | 15 + .../spring/openapi/v3/arazzo/ArazzoEMTest.kt | 80 +++ 7 files changed, 861 insertions(+) create mode 100644 core-tests/e2e-tests/spring/spring-rest-openapi-v3/src/main/kotlin/com/foo/rest/examples/spring/openapi/v3/arazzo/ArazzoPetCouponsApplication.kt create mode 100644 core-tests/e2e-tests/spring/spring-rest-openapi-v3/src/main/kotlin/com/foo/rest/examples/spring/openapi/v3/arazzo/ArazzoPetCouponsRest.kt create mode 100644 core-tests/e2e-tests/spring/spring-rest-openapi-v3/src/main/kotlin/com/foo/rest/examples/spring/openapi/v3/arazzo/PetCouponsDtos.kt create mode 100644 core-tests/e2e-tests/spring/spring-rest-openapi-v3/src/main/resources/static/pet-coupons-arazzo.yaml create mode 100644 core-tests/e2e-tests/spring/spring-rest-openapi-v3/src/main/resources/static/pet-coupons-openapi.yaml create mode 100644 core-tests/e2e-tests/spring/spring-rest-openapi-v3/src/test/kotlin/com/foo/rest/examples/spring/openapi/v3/arazzo/ArazzoPetCouponsController.kt create mode 100644 core-tests/e2e-tests/spring/spring-rest-openapi-v3/src/test/kotlin/org/evomaster/e2etests/spring/openapi/v3/arazzo/ArazzoEMTest.kt diff --git a/core-tests/e2e-tests/spring/spring-rest-openapi-v3/src/main/kotlin/com/foo/rest/examples/spring/openapi/v3/arazzo/ArazzoPetCouponsApplication.kt b/core-tests/e2e-tests/spring/spring-rest-openapi-v3/src/main/kotlin/com/foo/rest/examples/spring/openapi/v3/arazzo/ArazzoPetCouponsApplication.kt new file mode 100644 index 0000000000..4eb2ae1857 --- /dev/null +++ b/core-tests/e2e-tests/spring/spring-rest-openapi-v3/src/main/kotlin/com/foo/rest/examples/spring/openapi/v3/arazzo/ArazzoPetCouponsApplication.kt @@ -0,0 +1,16 @@ +package com.foo.rest.examples.spring.openapi.v3.arazzo + +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 ArazzoPetCouponsApplication { + + companion object { + @JvmStatic + fun main(args: Array) { + SpringApplication.run(ArazzoPetCouponsApplication::class.java, *args) + } + } +} diff --git a/core-tests/e2e-tests/spring/spring-rest-openapi-v3/src/main/kotlin/com/foo/rest/examples/spring/openapi/v3/arazzo/ArazzoPetCouponsRest.kt b/core-tests/e2e-tests/spring/spring-rest-openapi-v3/src/main/kotlin/com/foo/rest/examples/spring/openapi/v3/arazzo/ArazzoPetCouponsRest.kt new file mode 100644 index 0000000000..8f5d8e9c54 --- /dev/null +++ b/core-tests/e2e-tests/spring/spring-rest-openapi-v3/src/main/kotlin/com/foo/rest/examples/spring/openapi/v3/arazzo/ArazzoPetCouponsRest.kt @@ -0,0 +1,42 @@ +package com.foo.rest.examples.spring.openapi.v3.arazzo + +import org.springframework.http.MediaType +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.PostMapping +import org.springframework.web.bind.annotation.RequestBody +import org.springframework.web.bind.annotation.RequestParam +import org.springframework.web.bind.annotation.RestController +import java.util.concurrent.atomic.AtomicLong + +@RestController +open class ArazzoPetCouponsRest { + + private fun samplePet(): PetDto = PetDto( + id = 1, + name = "doggie", + photoUrls = listOf("http://example.com/photo"), + price = 9.99, + ) + + @GetMapping("/pet/findByTags") + open fun findPetsByTags( + @RequestParam(required = false) tags: List?, + ): ResponseEntity> = ResponseEntity.ok(listOf(samplePet())) + + @GetMapping("/pet/findByStatus") + open fun findPetsByStatus( + @RequestParam(required = false) status: String?, + @RequestParam page: Int, + @RequestParam(required = false, defaultValue = "10") pageSize: Int?, + ): ResponseEntity> = ResponseEntity.ok(listOf(samplePet())) + + @GetMapping("/pet/{petId}/coupons") + open fun getPetCoupons(@PathVariable petId: Long): ResponseEntity = + ResponseEntity.ok(CouponDto(couponCode = "SUMMERSALE")) + + @PostMapping(path = ["/store/order"], consumes = [MediaType.APPLICATION_JSON_VALUE]) + open fun placeOrder(@RequestBody order: OrderDto): ResponseEntity = + ResponseEntity.ok(order.copy(id = 1)) +} diff --git a/core-tests/e2e-tests/spring/spring-rest-openapi-v3/src/main/kotlin/com/foo/rest/examples/spring/openapi/v3/arazzo/PetCouponsDtos.kt b/core-tests/e2e-tests/spring/spring-rest-openapi-v3/src/main/kotlin/com/foo/rest/examples/spring/openapi/v3/arazzo/PetCouponsDtos.kt new file mode 100644 index 0000000000..173bbc883e --- /dev/null +++ b/core-tests/e2e-tests/spring/spring-rest-openapi-v3/src/main/kotlin/com/foo/rest/examples/spring/openapi/v3/arazzo/PetCouponsDtos.kt @@ -0,0 +1,16 @@ +package com.foo.rest.examples.spring.openapi.v3.arazzo + +data class PetDto( + val id: Long? = null, + val name: String, + val photoUrls: List, + val price: Double, +) + +data class CouponDto( + val couponCode: String, +) + +data class OrderDto( + val id: Long? = null, +) diff --git a/core-tests/e2e-tests/spring/spring-rest-openapi-v3/src/main/resources/static/pet-coupons-arazzo.yaml b/core-tests/e2e-tests/spring/spring-rest-openapi-v3/src/main/resources/static/pet-coupons-arazzo.yaml new file mode 100644 index 0000000000..1092239d19 --- /dev/null +++ b/core-tests/e2e-tests/spring/spring-rest-openapi-v3/src/main/resources/static/pet-coupons-arazzo.yaml @@ -0,0 +1,160 @@ +arazzo: 1.0.0 +info: + title: Petstore - Apply Coupons + version: 1.0.0 + description: >- + Illustrates a workflow whereby a client a) finds a pet in the petstore, + b) finds coupons for that pet, and finally + c) orders the pet while applying the coupons from step b. +sourceDescriptions: + - name: pet-coupons + url: pet-coupons-openapi.yaml + type: openapi +workflows: + - workflowId: apply-coupon + summary: Apply a coupon to a pet order. + description: >- + This is how you can find a pet, find an applicable coupon, and apply that coupon in your order. + The workflow concludes by outputting the ID of the placed order. + inputs: + $ref: "#/components/inputs/apply_coupon_input" + steps: + - stepId: find-pet + description: Find a pet based on the provided tags. + operationId: findPetsByTags + parameters: + - name: pet_tags + in: query + value: $inputs.my_pet_tags + successCriteria: + - condition: $statusCode == 200 + outputs: + my_pet_id: $response.body#/0/id + # there is some implied selection here - findPetsByTags responds with a list of pets, + # but the client only wants to choose one, and that's what will be provided to the next step. + # not totally sure how to indicate that. + - stepId: find-coupons + description: Find a coupon available for the selected pet. + operationId: getPetCoupons + parameters: + - name: pet_id + in: path + value: $steps.find-pet.outputs.my_pet_id + successCriteria: + - condition: $statusCode == 200 + outputs: + my_coupon_code: $response.body#/couponCode + - stepId: place-order + description: Place an order for the pet, applying the coupon. + workflowId: place-order + parameters: + - name: pet_id + value: $steps.find-pet.outputs.my_pet_id + - name: coupon_code + value: $steps.find-coupons.outputs.my_coupon_code + successCriteria: + - condition: $statusCode == 200 + outputs: + my_order_id: $outputs.workflow_order_id + outputs: + apply_coupon_pet_order_id: $steps.place-order.outputs.my_order_id + - workflowId: buy-available-pet + summary: Buy an available pet if one is available. + description: + This workflow demonstrates a workflow very similar to `apply-coupon`, by intention. + It's meant to indicate how to reuse a step (`place-order`) as well as a parameter (`page`, `pageSize`). + inputs: + $ref: "#/components/inputs/buy_available_pet_input" + steps: + - stepId: find-pet + description: Find a pet that is available for purchase. + operationId: findPetsByStatus + parameters: + - name: status + in: query + value: "available" + - reference: $components.parameters.page + value: 1 + - reference: $components.parameters.pageSize + value: 10 + successCriteria: + - condition: $statusCode == 200 + outputs: + my_pet_id: $response.body#/0/id + - stepId: place-order + description: Place an order for the pet. + workflowId: place-order + parameters: + - name: pet_id + value: $steps.find-pet.outputs.my_pet_id + successCriteria: + - condition: $statusCode == 200 + outputs: + my_order_id: $outputs.workflow_order_id + outputs: + buy_pet_order_id: $steps.place-order.outputs.my_order_id + - workflowId: place-order + summary: Place an order for a pet. + description: + This workflow places an order for a pet. It may be reused by other workflows as the "final step" in a purchase. + inputs: + type: object + properties: + pet_id: + type: integer + format: int64 + description: The ID of the pet to place in the order. + quantity: + type: integer + format: int32 + description: The number of pets to place in the order. + coupon_code: + type: string + description: The coupon code to apply to the order. + steps: + - stepId: place-order + description: Place an order for the pet. + operationId: placeOrder + requestBody: + contentType: application/json + payload: + petId: $inputs.pet_id + quantity: $inputs.quantity + couponCode: $inputs.coupon_code + status: placed + complete: false + successCriteria: + - condition: $statusCode == 200 + outputs: + step_order_id: $response.body#/id + outputs: + workflow_order_id: $steps.place-order.outputs.step_order_id +components: + inputs: + apply_coupon_input: + type: object + properties: + my_pet_tags: + type: array + items: + type: string + description: Desired tags to use when searching for a pet, in CSV format (e.g. "puppy, dalmatian") + store_id: + $ref: "#/components/inputs/store_id" + buy_available_pet_input: + type: object + properties: + store_id: + $ref: "#/components/inputs/store_id" + store_id: + type: string + description: Indicates the domain name of the store where the customer is browsing or buying pets, e.g. "pets.example.com" or "pets.example.co.uk". + parameters: + page: + name: page + in: query + value: 1 + pageSize: + name: pageSize + in: query + value: 100 \ No newline at end of file diff --git a/core-tests/e2e-tests/spring/spring-rest-openapi-v3/src/main/resources/static/pet-coupons-openapi.yaml b/core-tests/e2e-tests/spring/spring-rest-openapi-v3/src/main/resources/static/pet-coupons-openapi.yaml new file mode 100644 index 0000000000..6ad78adf73 --- /dev/null +++ b/core-tests/e2e-tests/spring/spring-rest-openapi-v3/src/main/resources/static/pet-coupons-openapi.yaml @@ -0,0 +1,532 @@ +openapi: 3.0.3 +info: + title: Swagger Petstore - OpenAPI 3.0 + description: Modifies the standard Petstore example to illustrate a workflow in which coupons are discovered and then used in an order. + license: + name: Apache 2.0 + url: http://www.apache.org/licenses/LICENSE-2.0.html + version: 1.0.0 +tags: + - name: pet + description: Everything about your Pets + externalDocs: + description: Find out more + url: http://swagger.io + - name: store + description: Access to Petstore orders + externalDocs: + description: Find out more about our store + url: http://swagger.io +paths: + /pet: + put: + tags: + - pet + summary: Update an existing pet + description: Update an existing pet by Id + operationId: updatePet + requestBody: + description: Update an existent pet in the store + content: + application/json: + schema: + $ref: '#/components/schemas/Pet' + application/xml: + schema: + $ref: '#/components/schemas/Pet' + application/x-www-form-urlencoded: + schema: + $ref: '#/components/schemas/Pet' + required: true + responses: + '200': + description: Successful operation + content: + application/json: + schema: + $ref: '#/components/schemas/Pet' + application/xml: + schema: + $ref: '#/components/schemas/Pet' + '400': + description: Invalid ID supplied + '404': + description: Pet not found + '405': + description: Validation exception + security: + - petstore_auth: + - write:pets + - read:pets + post: + tags: + - pet + summary: Add a new pet to the store + description: Add a new pet to the store + operationId: addPet + requestBody: + description: Create a new pet in the store + content: + application/json: + schema: + $ref: '#/components/schemas/Pet' + application/xml: + schema: + $ref: '#/components/schemas/Pet' + application/x-www-form-urlencoded: + schema: + $ref: '#/components/schemas/Pet' + required: true + responses: + '200': + description: Successful operation + content: + application/json: + schema: + $ref: '#/components/schemas/Pet' + application/xml: + schema: + $ref: '#/components/schemas/Pet' + '405': + description: Invalid input + security: + - petstore_auth: + - write:pets + - read:pets + /pet/findByStatus: + get: + tags: + - pet + summary: Finds Pets by status + description: Multiple status values can be provided with comma separated strings + operationId: findPetsByStatus + parameters: + - name: status + in: query + description: Status values that need to be considered for filter + required: false + explode: true + schema: + type: string + default: available + enum: + - available + - pending + - sold + - name: page + in: query + description: Which page of results to display. First page is 1. + required: true + schema: + type: integer + format: int32 + - name: pageSize + in: query + description: Number of results to display per page. + required: false + schema: + type: integer + format: int32 + default: 10 + responses: + '200': + description: successful operation + content: + application/json: + schema: + type: array + items: + $ref: '#/components/schemas/Pet' + application/xml: + schema: + type: array + items: + $ref: '#/components/schemas/Pet' + '400': + description: Invalid status value + security: + - petstore_auth: + - write:pets + - read:pets + /pet/findByTags: + get: + tags: + - pet + summary: Finds Pets by tags + description: Multiple tags can be provided with comma separated strings. Use tag1, tag2, tag3 for testing. + operationId: findPetsByTags + parameters: + - name: tags + in: query + description: Tags to filter by + required: false + explode: true + schema: + type: array + items: + type: string + responses: + '200': + description: successful operation + content: + application/json: + schema: + type: array + items: + $ref: '#/components/schemas/Pet' + application/xml: + schema: + type: array + items: + $ref: '#/components/schemas/Pet' + '400': + description: Invalid tag value + security: + - petstore_auth: + - write:pets + - read:pets + /pet/{petId}: + get: + tags: + - pet + summary: Find pet by ID + description: Returns a single pet + operationId: getPetById + parameters: + - name: petId + in: path + description: ID of pet to return + required: true + schema: + type: integer + format: int64 + responses: + '200': + description: successful operation + content: + application/json: + schema: + $ref: '#/components/schemas/Pet' + application/xml: + schema: + $ref: '#/components/schemas/Pet' + '400': + description: Invalid ID supplied + '404': + description: Pet not found + security: + - api_key: [] + - petstore_auth: + - write:pets + - read:pets + post: + tags: + - pet + summary: Updates a pet in the store with form data + description: '' + operationId: updatePetWithForm + parameters: + - name: petId + in: path + description: ID of pet that needs to be updated + required: true + schema: + type: integer + format: int64 + - name: name + in: query + description: Name of pet that needs to be updated + schema: + type: string + - name: status + in: query + description: Status of pet that needs to be updated + schema: + type: string + responses: + '405': + description: Invalid input + security: + - petstore_auth: + - write:pets + - read:pets + delete: + tags: + - pet + summary: Deletes a pet + description: delete a pet + operationId: deletePet + parameters: + - name: api_key + in: header + description: '' + required: false + schema: + type: string + - name: petId + in: path + description: Pet id to delete + required: true + schema: + type: integer + format: int64 + responses: + '400': + description: Invalid pet value + security: + - petstore_auth: + - write:pets + - read:pets + /pet/{petId}/coupons: + get: + tags: + - pet + summary: Find a coupon available for a pet + description: Returns a coupon available for the pet, if applicable + operationId: getPetCoupons + parameters: + - name: petId + in: path + description: ID of pet with available coupons + required: true + schema: + type: integer + format: int64 + responses: + '200': + description: successful operation + content: + application/json: + schema: + $ref: '#/components/schemas/Coupon' + application/xml: + schema: + $ref: '#/components/schemas/Coupon' + '400': + description: Invalid ID supplied + '404': + description: Pet not found or coupon not available + security: + - api_key: [] + - petstore_auth: + - read:pets + /store/order: + post: + tags: + - store + summary: Place an order for a pet + description: Place a new order in the store + operationId: placeOrder + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/Order' + application/xml: + schema: + $ref: '#/components/schemas/Order' + application/x-www-form-urlencoded: + schema: + $ref: '#/components/schemas/Order' + responses: + '200': + description: successful operation + content: + application/json: + schema: + $ref: '#/components/schemas/Order' + '400': + description: Invalid input + /store/order/{orderId}: + get: + tags: + - store + summary: Find purchase order by ID + description: For valid response try integer IDs with value <= 5 or > 10. Other values will generate exceptions. + operationId: getOrderById + parameters: + - name: orderId + in: path + description: ID of order that needs to be fetched + required: true + schema: + type: integer + format: int64 + responses: + '200': + description: successful operation + content: + application/json: + schema: + $ref: '#/components/schemas/Order' + application/xml: + schema: + $ref: '#/components/schemas/Order' + '400': + description: Invalid ID supplied + '404': + description: Order not found + delete: + tags: + - store + summary: Delete purchase order by ID + description: For valid response try integer IDs with value < 1000. Anything above 1000 or nonintegers will generate API errors + operationId: deleteOrder + parameters: + - name: orderId + in: path + description: ID of the order that needs to be deleted + required: true + schema: + type: integer + format: int64 + responses: + '400': + description: Invalid ID supplied + '404': + description: Order not found +components: + schemas: + Order: + type: object + properties: + id: + type: integer + format: int64 + example: 10 + petId: + type: integer + format: int64 + example: 198772 + quantity: + type: integer + format: int32 + example: 7 + status: + type: string + description: Order Status + example: approved + enum: + - placed + - approved + - delivered + complete: + type: boolean + couponCode: + type: string + example: "SUMMERSALE" + xml: + name: order + Category: + type: object + properties: + id: + type: integer + format: int64 + example: 1 + name: + type: string + example: Dogs + xml: + name: category + Tag: + type: object + properties: + id: + type: integer + format: int64 + name: + type: string + xml: + name: tag + Pet: + required: + - name + - price + - photoUrls + type: object + properties: + id: + type: integer + format: int64 + example: 10 + name: + type: string + example: doggie + category: + $ref: '#/components/schemas/Category' + photoUrls: + type: array + xml: + wrapped: true + items: + type: string + xml: + name: photoUrl + price: + type: number + tags: + type: array + xml: + wrapped: true + items: + $ref: '#/components/schemas/Tag' + status: + type: string + description: pet status in the store + enum: + - available + - pending + - sold + xml: + name: pet + ApiResponse: + type: object + properties: + code: + type: integer + format: int32 + type: + type: string + message: + type: string + xml: + name: '##default' + Coupon: + type: object + properties: + id: + type: integer + format: int64 + example: 10 + description: + type: string + example: "Summer Sale - 10% off!" + couponCode: + type: string + example: "SUMMERSALE" + xml: + name: coupon + requestBodies: + Pet: + description: Pet object that needs to be added to the store + content: + application/json: + schema: + $ref: '#/components/schemas/Pet' + application/xml: + schema: + $ref: '#/components/schemas/Pet' + securitySchemes: + petstore_auth: + type: oauth2 + flows: + implicit: + authorizationUrl: https://petstore3.swagger.io/oauth/authorize + scopes: + write:pets: modify pets in your account + read:pets: read your pets + api_key: + type: apiKey + name: api_key + in: header \ 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/arazzo/ArazzoPetCouponsController.kt b/core-tests/e2e-tests/spring/spring-rest-openapi-v3/src/test/kotlin/com/foo/rest/examples/spring/openapi/v3/arazzo/ArazzoPetCouponsController.kt new file mode 100644 index 0000000000..5fd85b3988 --- /dev/null +++ b/core-tests/e2e-tests/spring/spring-rest-openapi-v3/src/test/kotlin/com/foo/rest/examples/spring/openapi/v3/arazzo/ArazzoPetCouponsController.kt @@ -0,0 +1,15 @@ +package com.foo.rest.examples.spring.openapi.v3.arazzo + +import com.foo.rest.examples.spring.openapi.v3.SpringController +import org.evomaster.client.java.controller.problem.ProblemInfo +import org.evomaster.client.java.controller.problem.RestProblem + +class ArazzoPetCouponsController : SpringController(ArazzoPetCouponsApplication::class.java) { + + override fun getProblemInfo(): ProblemInfo { + return RestProblem( + "http://localhost:$sutPort/pet-coupons-openapi.yaml", + null, + ) + } +} diff --git a/core-tests/e2e-tests/spring/spring-rest-openapi-v3/src/test/kotlin/org/evomaster/e2etests/spring/openapi/v3/arazzo/ArazzoEMTest.kt b/core-tests/e2e-tests/spring/spring-rest-openapi-v3/src/test/kotlin/org/evomaster/e2etests/spring/openapi/v3/arazzo/ArazzoEMTest.kt new file mode 100644 index 0000000000..bb6b5ce242 --- /dev/null +++ b/core-tests/e2e-tests/spring/spring-rest-openapi-v3/src/test/kotlin/org/evomaster/e2etests/spring/openapi/v3/arazzo/ArazzoEMTest.kt @@ -0,0 +1,80 @@ +package org.evomaster.e2etests.spring.openapi.v3.arazzo + +import com.foo.rest.examples.spring.openapi.v3.arazzo.ArazzoPetCouponsController +import org.evomaster.core.problem.rest.data.HttpVerb +import org.evomaster.core.problem.rest.data.RestCallAction +import org.evomaster.core.problem.rest.service.ArazzoWorkflowsService +import org.evomaster.core.problem.rest.service.sampler.RestSampler +import org.evomaster.e2etests.spring.openapi.v3.SpringTestBase +import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.api.Assertions.assertTrue +import org.junit.jupiter.api.BeforeAll +import org.junit.jupiter.api.Test + +class ArazzoEMTest : SpringTestBase() { + + companion object { + private const val ARAZZO_LOCATION = "src/main/resources/static/pet-coupons-arazzo.yaml" + + @BeforeAll + @JvmStatic + fun init() { + initClass(ArazzoPetCouponsController()) + } + } + + @Test + fun testRunEMWithArazzoWorkflowSampling() { + runTestHandlingFlakyAndCompilation( + "ArazzoEM", + "org.foo.ArazzoEM", + 50, + ) { args -> + setOption(args, "enableArazzoWorkflowSampling", "true") + setOption(args, "arazzoLocation", ARAZZO_LOCATION) + setOption(args, "probOfArazzoSampling", "1.0") + + val solution = initAndRun(args) + + assertTrue(solution.individuals.size >= 1) + } + } + + @Test + fun testArazzoWorkflowsMatchPetCouponsSpec() { + runTestHandlingFlaky( + "ArazzoWorkflowShape", + "org.foo.ArazzoWorkflowShape", + 1, + false, + ) { args -> + setOption(args, "enableArazzoWorkflowSampling", "true") + setOption(args, "arazzoLocation", ARAZZO_LOCATION) + setOption(args, "probOfArazzoSampling", "1.0") + + val injector = init(args) + val arazzoService = injector.getInstance(ArazzoWorkflowsService::class.java) + val sampler = injector.getInstance(RestSampler::class.java) + + assertTrue(arazzoService.arazzoWorkflows.isNotEmpty()) + assertTrue(sampler.numberOfDistinctActions() > 0) + + val workflow = arazzoService.arazzoWorkflowsById["apply-coupon"]!! + val ind = arazzoService.buildIndividualFromWorkflow(workflow) + val actions = ind.seeAllActions().filterIsInstance() + + assertEquals( + listOf("findPetsByTags", "getPetCoupons", "placeOrder"), + actions.map { it.operationId }, + ) + assertEquals( + listOf(HttpVerb.GET, HttpVerb.GET, HttpVerb.POST), + actions.map { it.verb }, + ) + assertEquals( + listOf("/pet/findByTags", "/pet/{petId}/coupons", "/store/order"), + actions.map { it.path.toString() }, + ) + } + } +} From 139a82871e135fab948304fcc79472204453d91e Mon Sep 17 00:00:00 2001 From: Daniel Lopera Date: Tue, 15 Sep 2026 21:36:51 -0300 Subject: [PATCH 2/2] Change test Arazzo:testRunEMWithArazzoWorkflowSampling --- .../spring/openapi/v3/arazzo/ArazzoEMTest.kt | 48 ++++--------------- 1 file changed, 8 insertions(+), 40 deletions(-) diff --git a/core-tests/e2e-tests/spring/spring-rest-openapi-v3/src/test/kotlin/org/evomaster/e2etests/spring/openapi/v3/arazzo/ArazzoEMTest.kt b/core-tests/e2e-tests/spring/spring-rest-openapi-v3/src/test/kotlin/org/evomaster/e2etests/spring/openapi/v3/arazzo/ArazzoEMTest.kt index bb6b5ce242..b010ba5306 100644 --- a/core-tests/e2e-tests/spring/spring-rest-openapi-v3/src/test/kotlin/org/evomaster/e2etests/spring/openapi/v3/arazzo/ArazzoEMTest.kt +++ b/core-tests/e2e-tests/spring/spring-rest-openapi-v3/src/test/kotlin/org/evomaster/e2etests/spring/openapi/v3/arazzo/ArazzoEMTest.kt @@ -2,11 +2,7 @@ package org.evomaster.e2etests.spring.openapi.v3.arazzo import com.foo.rest.examples.spring.openapi.v3.arazzo.ArazzoPetCouponsController import org.evomaster.core.problem.rest.data.HttpVerb -import org.evomaster.core.problem.rest.data.RestCallAction -import org.evomaster.core.problem.rest.service.ArazzoWorkflowsService -import org.evomaster.core.problem.rest.service.sampler.RestSampler import org.evomaster.e2etests.spring.openapi.v3.SpringTestBase -import org.junit.jupiter.api.Assertions.assertEquals import org.junit.jupiter.api.Assertions.assertTrue import org.junit.jupiter.api.BeforeAll import org.junit.jupiter.api.Test @@ -33,48 +29,20 @@ class ArazzoEMTest : SpringTestBase() { setOption(args, "enableArazzoWorkflowSampling", "true") setOption(args, "arazzoLocation", ARAZZO_LOCATION) setOption(args, "probOfArazzoSampling", "1.0") + // SmartSampling is disabled to ensure that the created individuals were generated by Arazzo. + setOption(args, "probOfSmartSampling", "0.0") val solution = initAndRun(args) assertTrue(solution.individuals.size >= 1) - } - } - - @Test - fun testArazzoWorkflowsMatchPetCouponsSpec() { - runTestHandlingFlaky( - "ArazzoWorkflowShape", - "org.foo.ArazzoWorkflowShape", - 1, - false, - ) { args -> - setOption(args, "enableArazzoWorkflowSampling", "true") - setOption(args, "arazzoLocation", ARAZZO_LOCATION) - setOption(args, "probOfArazzoSampling", "1.0") - - val injector = init(args) - val arazzoService = injector.getInstance(ArazzoWorkflowsService::class.java) - val sampler = injector.getInstance(RestSampler::class.java) - - assertTrue(arazzoService.arazzoWorkflows.isNotEmpty()) - assertTrue(sampler.numberOfDistinctActions() > 0) - val workflow = arazzoService.arazzoWorkflowsById["apply-coupon"]!! - val ind = arazzoService.buildIndividualFromWorkflow(workflow) - val actions = ind.seeAllActions().filterIsInstance() + // apply-coupon: findPetsByTags -> getPetCoupons -> placeOrder + assertHasAtLeastOne(solution, HttpVerb.GET, 200, "/pet/findByTags", null) + assertHasAtLeastOne(solution, HttpVerb.GET, 200, "/pet/{petId}/coupons", null) + assertHasAtLeastOne(solution, HttpVerb.POST, 200, "/store/order", null) - assertEquals( - listOf("findPetsByTags", "getPetCoupons", "placeOrder"), - actions.map { it.operationId }, - ) - assertEquals( - listOf(HttpVerb.GET, HttpVerb.GET, HttpVerb.POST), - actions.map { it.verb }, - ) - assertEquals( - listOf("/pet/findByTags", "/pet/{petId}/coupons", "/store/order"), - actions.map { it.path.toString() }, - ) + // buy-available-pet: findPetsByStatus -> placeOrder + assertHasAtLeastOne(solution, HttpVerb.GET, 200, "/pet/findByStatus", null) } } }