EvoMaster icon indicating copy to clipboard operation
EvoMaster copied to clipboard

Should this test be in EvoMaster_fault_representatives_Test.java and is resolveLocation() working as expected?

Open aruvic opened this issue 1 year ago • 3 comments

Hi,

Please, should this test be in EvoMaster_fault_representatives_Test.java and what is the purpose of this test using: org.evomaster.client.java.controller.api.resolveLocation()?

The test first inserts 4 records into the databasa and creates the 5th record via POST. This is normal and expected beheviour. After the POST situation in the DB is as depicted below: image

location_myentity contains "/api/myentity/5" and baseUrlOfSut contains "http://localhost:8080"

Using: resolveLocation("/api/myentity/5", "http://localhost:8080/api/myentity/-15942/jsonpath?jsonPath=status&EMextraParam123=42")

Following was actualy executed: REQUEST:

Request method:	GET
Request URI:	http://localhost:8080/api/myentity/5/jsonpath?jsonPath=status&EMextraParam123=42
Proxy:			<none>
Request params:	<none>
Query params:	<none>
Form params:	<none>
Path params:	<none>
Headers:		Accept=*/*
				x-EMextraHeader123=
Cookies:		<none>
Multiparts:		<none>
Body:			<none>

RESPONSE:

HTTP/1.1 200 
Content-Type: text/plain;charset=UTF-8
Content-Length: 12
Date: Wed, 22 May 2024 08:50:36 GMT
Keep-Alive: timeout=60
Connection: keep-alive

_EM_300_XYZ_

Was the intention of the test to use a negative ID -15942 and even in that case code returns 404 Not Found

TEST:

    @Test @Timeout(60)
    public void test_2() throws Exception {
        List<InsertionDto> insertions = sql().insertInto("MY_ENTITY", 30L)
                .d("CREATION_DATE", "\"2025-07-01 22:15:05\"")
                .d("DESCRIPTION", "\"2067-07-07 08:52:52\"")
                .d("NAME", "NULL")
                .d("ROLE", "\"OwpWZAjY\"")
                .d("STATUS", "NULL")
            .and().insertInto("MY_ENTITY", 31L)
                .d("CREATION_DATE", "\"2017-08-12 16:09:59\"")
                .d("DESCRIPTION", "\"_EM_471_XYZ_\"")
                .d("NAME", "\"AmlNJnVAb\"")
                .d("ROLE", "\"_EM_302_XYZ_\"")
                .d("STATUS", "NULL")
            .and().insertInto("MY_ENTITY", 32L)
                .d("CREATION_DATE", "\"1906-04-22 13:32:55\"")
                .d("DESCRIPTION", "\"FgQQoW\"")
                .d("NAME", "\"k\"")
                .d("ROLE", "\"_2LNsgS7pYGT9QL\"")
                .d("STATUS", "\"_EM_304_XYZ_\"")
            .and().insertInto("MY_ENTITY", 33L)
                .d("CREATION_DATE", "\"1956-06-14 12:21:38\"")
                .d("DESCRIPTION", "\"_EM_472_XYZ_\"")
                .d("NAME", "NULL")
                .d("ROLE", "\"\"")
                .d("STATUS", "\"_EM_305_XYZ_\"")
            .dtos();
        InsertionResultsDto insertionsresult = controller.execInsertionsIntoDatabase(insertions);
        ExpectationHandler expectationHandler = expectationHandler();
        
        String location_myentity = "";
        
        ValidatableResponse res_0 = given().accept("*/*")
                .header("x-EMextraHeader123", "42")
                .contentType("application/json")
                .body(" { " + 
                    " \"id\": 736, " + 
                    " \"name\": \"_EM_35_XYZ_\", " + 
                    " \"description\": \"yTV\", " + 
                    " \"status\": \"_EM_300_XYZ_\", " + 
                    " \"relatedParty\": { " + 
                    " \"role\": \"_EM_38_XYZ_\" " + 
                    " } " + 
                    " } ")
                .post(baseUrlOfSut + "/api/myentity")
                .then()
                .statusCode(201)
                .assertThat()
                .contentType("application/json")
                .body("'name'", containsString("_EM_35_XYZ_"))
                .body("'description'", containsString("yTV"))
                .body("'status'", containsString("_EM_300_XYZ_"))
                .body("'creationDate'", nullValue())
                .body("'relatedParty'.'role'", containsString("_EM_38_XYZ_"));
        location_myentity = "/api/myentity" + "/" + res_0.extract().body().path("id").toString();
        
        expectationHandler.expect(ems)
            .that(sco, Arrays.asList(200).contains(res_0.extract().statusCode()));
        
        ValidatableResponse res_1 = given().accept("*/*")
                .header("x-EMextraHeader123", "")
                .log().all()
                .get(resolveLocation(location_myentity, baseUrlOfSut + "/api/myentity/-15942/jsonpath?jsonPath=status&EMextraParam123=42"))
                .then()
                .log().all()
                .statusCode(200)
                .assertThat()
                .contentType("text/plain")
                .body(containsString("_EM_300_XYZ_"));
        
        expectationHandler.expect(ems);
    }

aruvic avatar May 22 '24 09:05 aruvic

hi, there 2 things at play here:

  1. the JavaDocs of resolveLocation is:
  /**
     *
     * @param locationHeader a URI-reference, coming from a "location" header. See RFC 7231.
     *                       Note: it can be a relative reference
     * @param expectedTemplate a full URI of the target resource, but with some path elements
     *                         that might (or might not) be unresolved. If {@code locationHeader} is not
     *                         empty, it will replace the beginning of this template.
     * @return a fully resolved URI for the target resource. If there are problems, just
     *          return the input locationHeader. If this latter is empty/null, then return the template
     */

is that not clear? if not, I can try to provide more info. The idea here is that it tries to re-use the resource created on the fly, by inferring its full URL.

  1. it seems there is bug in the schema/API. the endpoint declares to return only 200, but a 201 is rather obtained. However, we should do a better job at explaining what bugs are found in the generated tests, eg, with clarifying comments, something like: "//ERROR: the non-declared status code 201 was returned. Declared status codes are: 200.". Implementing this is on our TODO list

arcuri82 avatar May 22 '24 10:05 arcuri82

and yes, as this test reveals a fault, it should be under EvoMaster_fault_representatives_Test.

arcuri82 avatar May 22 '24 10:05 arcuri82

Hi,

Number 1 is clear and now I understand how resolveLocation works.

For the purpose of exploring EvoMaster a simple REST API was created and OAS3 was generated using springdoc-openapi-starter-webmvc-ui. Indeed OAS3 specifies 200 and code returns 201. Thanks a lot.

    "/api/myentity":{         
	"post":{
            "tags":[
               "my-entity-controller"
            ],
            "operationId":"createResource",
            "requestBody":{
               "content":{
                  "application/json":{
                     "schema":{
                        "$ref":"#/components/schemas/MyEntity"
                     }
                  }
               },
               "required":true
            },
            "responses":{
               "200":{
                  "description":"OK",
                  "content":{
                     "*/*":{
                        "schema":{
                           "type":"object"
                        }
                     }
                  }
               }
            }
         }
      }
  
```}

aruvic avatar May 22 '24 11:05 aruvic

closed. as now fault explanations are provided in the generated tests

arcuri82 avatar Oct 28 '24 13:10 arcuri82