Skip to content

Commit 9fc7bba

Browse files
authored
FIX: Thread-safe response callback (#141)
1 parent 0324d63 commit 9fc7bba

File tree

3 files changed

+51
-1
lines changed

3 files changed

+51
-1
lines changed

mockfaster/src/main/java/com/decathlon/tzatziki/utils/MockFaster.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -341,7 +341,7 @@ private static class UpdatableExpectationResponseCallback implements Expectation
341341
private ExpectationResponseCallback callback;
342342

343343
@Override
344-
public HttpResponse handle(HttpRequest httpRequest) throws Exception {
344+
public synchronized HttpResponse handle(HttpRequest httpRequest) throws Exception {
345345
return callback.handle(httpRequest);
346346
}
347347

tzatziki-http/src/test/java/com/decathlon/tzatziki/steps/LocalSteps.java

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,29 @@
11
package com.decathlon.tzatziki.steps;
22

3+
import com.decathlon.tzatziki.utils.Asserts;
34
import com.decathlon.tzatziki.utils.Comparison;
45
import com.decathlon.tzatziki.utils.Guard;
56
import com.decathlon.tzatziki.utils.Interaction;
67
import io.cucumber.java.Before;
78
import io.cucumber.java.en.Given;
9+
import io.cucumber.java.en.Then;
810
import lombok.RequiredArgsConstructor;
911

12+
import java.util.List;
13+
import java.util.concurrent.CompletableFuture;
14+
import java.util.concurrent.ExecutorService;
15+
import java.util.concurrent.Executors;
1016
import java.util.stream.IntStream;
1117

18+
import static com.decathlon.tzatziki.utils.MockFaster.target;
19+
import static com.decathlon.tzatziki.utils.Patterns.QUOTED_CONTENT;
20+
import static com.decathlon.tzatziki.utils.Unchecked.unchecked;
21+
import static io.restassured.RestAssured.given;
22+
1223
@RequiredArgsConstructor
1324
public class LocalSteps {
1425
private final HttpSteps httpSteps;
26+
private final ObjectSteps objects;
1527

1628
static {
1729
Interaction.printResponses = true;
@@ -32,4 +44,18 @@ public void mockIdEndpointAsSeveralMocks(int startId, int endId) {
3244
payload: Hello %d
3345
""".formatted(idx)));
3446
}
47+
48+
@Then("getting (?:on )?" + QUOTED_CONTENT + " four times in parallel returns:$")
49+
public void sendInParallel(String path, String content) {
50+
ExecutorService executor = Executors.newFixedThreadPool(4);
51+
52+
List<CompletableFuture<Interaction.Response>> responsesAsync = List.of(
53+
CompletableFuture.supplyAsync(() -> Interaction.Response.fromResponse(Interaction.Request.builder().build().send(given(), target(path), objects)), executor),
54+
CompletableFuture.supplyAsync(() -> Interaction.Response.fromResponse(Interaction.Request.builder().build().send(given(), target(path), objects)), executor),
55+
CompletableFuture.supplyAsync(() -> Interaction.Response.fromResponse(Interaction.Request.builder().build().send(given(), target(path), objects)), executor),
56+
CompletableFuture.supplyAsync(() -> Interaction.Response.fromResponse(Interaction.Request.builder().build().send(given(), target(path), objects)), executor)
57+
);
58+
59+
Asserts.contains(responsesAsync.stream().map(future -> unchecked(() -> future.get())).map(response -> response.body.payload).toList(), objects.resolve(content));
60+
}
3561
}

tzatziki-http/src/test/resources/com/decathlon/tzatziki/steps/http.feature

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1194,6 +1194,30 @@ Feature: to interact with an http service and setup mocks
11941194
Then getting on "http://backend/time" returns a status 404
11951195
Then getting on "http://backend/time" returns a status 404
11961196

1197+
Scenario: Concurrency consumption is handled properly
1198+
Given that "http://backend/time" is mocked as:
1199+
"""
1200+
response:
1201+
- consumptions: 1
1202+
body:
1203+
payload: morning
1204+
- consumptions: 1
1205+
body:
1206+
payload: noon
1207+
- consumptions: 1
1208+
body:
1209+
payload: afternoon
1210+
- body:
1211+
payload: evening
1212+
"""
1213+
Then getting on "http://backend/time" four times in parallel returns:
1214+
"""
1215+
- morning
1216+
- noon
1217+
- afternoon
1218+
- evening
1219+
"""
1220+
11971221
Scenario: We can use variables from request regex into response also when using an intermediary object
11981222
Given that response is:
11991223
"""

0 commit comments

Comments
 (0)