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

Multiple responses for the same request are not thread-safe #1834

Open
dzianis-kryvapusk opened this issue Jan 24, 2024 · 0 comments
Open

Multiple responses for the same request are not thread-safe #1834

dzianis-kryvapusk opened this issue Jan 24, 2024 · 0 comments

Comments

@dzianis-kryvapusk
Copy link

Describe the issue
I noticed that MockServerClient responds with only the first mocked response even if it has multiple of them when an app calls mocked API concurrently many times.

What you are trying to do
An app calls third-party API many times in a non-blocking manner. It means that MockServerClient gets many requests at the same time. This third-party API should respond with a different response every time. I mock them but receive only the first mocked response. When I added a delay between calls, everything began to work as expected.

MockServer version
org.mock-server:mockserver-spring-test-listener:5.15.0

To Reproduce
I prepared a project with a test (test_getJokes_successful) which you can run and see the issue. You will find that the response from the server contains only the first mocked response repeated many times. That's why assertEquals(expected, response) will fail. To fix it, you need to uncomment lines in the method com.example.jokemicroservice.jokeprovider.ThirdPartyJokeProvider#getJokesAsync.
You can run this test directly from your IDE.
Expectations are built by the following code:

for (int i = 1; i <= 5; i++) {
            JokeDto joke = buildJoke(i);
            expected.add(joke);
            mockServer.when(request()
                                    .withMethod(HttpMethod.GET.name())
                                    .withPath(jokeApiProperties.getPath()),
                            once())
                    .respond(response()
                                     .withStatusCode(HttpStatusCode.OK_200.code())
                                     .withContentType(org.mockserver.model.MediaType.APPLICATION_JSON)
                                     .withBody(objectMapper.writeValueAsString(joke)));
        }

Expected behaviour
The server should respond with a mocked response only once even on concurrent calls.

MockServer Log
In the attached file you can find many logs like

matched expectation:

  {
    "httpRequest" : {
      "method" : "GET",
      "path" : "/random_joke"
    },
    "httpResponse" : {
      "statusCode" : 200,
      "headers" : {
        "content-type" : [ "application/json" ]
      },
      "body" : "{\"id\":1,\"type\":null,\"setup\":\"test setup 1\",\"punchline\":\"test punchline 1\"}"
    },
    "id" : "b5a90ca1-5dce-4c9e-9b6a-95d11bf92a13",
    "priority" : 0,
    "timeToLive" : {
      "unlimited" : true
    },
    "times" : {
      "remainingTimes" : 1
    }
  }

which lead to the negative remainingTimes

2024-01-24T12:29:37.462+04:00  INFO 10420 --- [erver-EventLog0] org.mockserver.log.MockServerEventLog    : 1080 removed expectation:

  {
    "httpRequest" : {
      "method" : "GET",
      "path" : "/random_joke"
    },
    "httpResponse" : {
      "statusCode" : 200,
      "headers" : {
        "content-type" : [ "application/json" ]
      },
      "body" : "{\"id\":1,\"type\":null,\"setup\":\"test setup 1\",\"punchline\":\"test punchline 1\"}"
    },
    "id" : "b5a90ca1-5dce-4c9e-9b6a-95d11bf92a13",
    "priority" : 0,
    "timeToLive" : {
      "unlimited" : true
    },
    "times" : {
      "remainingTimes" : -2
    }
  }

 with id:

  b5a90ca1-5dce-4c9e-9b6a-95d11bf92a13

mock-server.log

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

No branches or pull requests

1 participant