Hi,
I’m testing a websocket service, the scenario should be:
- Each client keeps the connection open and sends 1 message with a random unique sequence number every 10 seconds.
- Server returns the seq in response body.
- Client should only accept the message with the same seq.
I also want to print the seq for failed requests.
Here’s my code:
public class WebsocketTest extends Simulation {
private static final Logger log = LoggerFactory.getLogger(WebsocketTest.class);
// ...
HttpProtocolBuilder httpConf = http
.wsBaseUrl(baseUrl)
.wsAutoReplySocketIo4();
ScenarioBuilder scn = scenario("WebSocket")
.exec(ws("Connect WS").connect(path))
.exitHereIfFailed()
.repeat(loop).on(
pause(sendIntervalMin, sendIntervalMax)
.exec(session -> {
session.markAsSucceeded();
String nanoTime = String.valueOf(System.nanoTime());
return session.set("seq", System.currentTimeMillis() + nanoTime.substring(nanoTime.length() - 5));
})
.exec(ws("Send text")
.sendText(data)
.await(responseTimeout).on(
ws.checkTextMessage("Check response code")
.matching(
jsonPath(matchJsonPath).ofLong().isEL("#{seq}").saveAs("returnSeq")
)
.check(
jsonPath(checkJsonPath).ofInt().is(returnCode).saveAs("returnCode")
)
)
).doIf(Session::isFailed).then(
exec(session -> {
log.error("Failed request seq: {} ; Return seq: {} ; Return code: {} ; session: {}",
session.getString("seq"),
session.getString("returnSeq"),
session.getString("returnCode"),
session.userId()
);
return session.reset();
}
)
)
).exec(ws("Close WS").close());
public WebsocketTest() {
setUp(
scn.injectOpen(rampUsers(connections).during(rampUp))
).protocols(httpConf);
}
}
But the result is so confusing. In this pic, validation is passed, but an error msg is still logged.
So Session::isFailed
returns true?
And here looks like thread gatling-1-2 consumes gatling-1-3’s msg, then gatling-1-3 has to wait for nothing until timeout and fails the request.
Env:
- Gradle 7.5 w/ Gatling plugin 3.8.3.2
- JDK 11
- macOS 12.1