Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
aruvic opened this issue May 22, 2024 · 3 comments

Comments

@aruvic
Copy link

aruvic commented May 22, 2024

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);
    }
@arcuri82
Copy link
Collaborator

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
Copy link
Collaborator

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

@aruvic
Copy link
Author

aruvic commented May 22, 2024

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"
                        }
                     }
                  }
               }
            }
         }
      }
  
```}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants