Hi
I’m trying to create a performance test cases using WebSocket but the server crashes and close my connection. What am I doing wrong?
Test case:
package tests.directSearch;
import io.gatling.app.SimulationClass;
import io.gatling.javaapi.core.ScenarioBuilder;
import io.gatling.javaapi.core.Simulation;
import io.gatling.javaapi.http.HttpProtocolBuilder;
import java.time.Duration;
import static io.gatling.javaapi.core.CoreDsl.;
import static io.gatling.javaapi.http.HttpDsl.;
public class WsSampleJava extends Simulation {
HttpProtocolBuilder httpProtocol = http
.baseUrl("http://[MY_URL]")
.header("Content-Type", "JSON")
.header("Connection", "keep-alive")
.wsBaseUrl("wss://[MY_URL]")
.wsReconnect();
ScenarioBuilder scn = scenario("WebSocket")
.exec(
http("Log in")
.post("[MY_ENDPOINT]")
.body(StringBody("{[USER_CREDENTIALS]}"))
.asJson()
.check(regex("\"access_token\":\"(.*?)\"").findAll().saveAs("access_token"))
.check(status().is(200)))
.exec(
ws("WebSocket Connect")
.connect("/[ENDPOINT]/websockets?Authorization=Bearer${access_token}")
.onConnected(
exec(
ws("Send message")
.sendText(StringBody("{[SOME_JSON]}"))
).pause(10)
)
)
.exec(
ws("WebSocket Connect").close()
);
{
setUp(
scn.injectOpen(
atOnceUsers(1)
)
).protocols(httpProtocol);
}
}
Logs:
12:00:47.135 [DEBUG] i.g.h.a.w.f.WsConnectingState$ - Connecting to wss://[MY_URL]?Authorization=Bearer%[access_token]
12:00:47.259 [DEBUG] i.g.h.a.w.f.WsConnectingState - Connected, no checks, performing onConnected action before performing next action
12:00:47.265 [DEBUG] i.g.h.a.w.f.WsIdleState - Send text frame Send message {[SOME_JSON]}
12:00:47.375 [DEBUG] i.g.h.a.w.f.WsFsm - Couldn’t cancel timeout because it wasn’t set
12:00:47.382 [DEBUG] i.g.h.a.w.f.WsIdleState - WebSocket crashed by the server while in WsIdleState state
io.gatling.http.client.impl.HttpAppHandler$1: Premature close
It means your server is closing the TCP socket, most likely because your CONNECT request is wrong.
.connect(“/[ENDPOINT]/websockets?Authorization=Bearer${access_token}”)
Connecting to wss://[MY_URL]?Authorization=Bearer%[access_token]
Are you sure this is correct? Authorization
is typically a HTTP header, not a query parameter.
Are you sure you don’t want instead:
.connect("/[ENDPOINT]/websockets")
.header("Authorization", "Bearer #{access_token}")
Hi @slandelle
I just tried it as you suggested but the result is the same.
My friend did the same thing using wss://[MY_URL]?Authorization=Bearer%20{access_token}
in JMeter. What helped him was “%20” before access token; in my Gatling script it doesn’t help.
Is there any setting that turns on/off the response comming from server, using wss?
%20` is the encoded whitespace.
.connect(“/[ENDPOINT]/websockets?Authorization=Bearer${access_token}”)
You’re lacking a whitespace between Bearer
and ${access_token}
.
Yes, I know that it’s whitespace, but as I wrote it didn’t help me. I didn’t change anything. That’s why I’m asking for help here.
Then, please clean up the data you provide. It feels like you’re mixing data from different tentatives and it’s impossible to follow.
For example, you’re saying that
.connect(“/[ENDPOINT]/websockets?Authorization=Bearer${access_token}”)
produces the log:
12:00:47.135 [DEBUG] i.g.h.a.w.f.WsConnectingState$ - Connecting to wss://[MY_URL]?Authorization=Bearer%[access_token]
which doesn’t make much sense. Where does this extra %
come from? Not from Gatling itself.
You probably should enable TRACE logging so you can compare payloads between your Gatling test and JMeter.
All the time I have TRACE enabled if we are speaking about this one.
logger name=“io.gatling.http.action.ws.fsm” level=“TRACE”
However I’m not sure if the messages that I see are comming from the server or Gatling shows me them only on my (client) side?
[DEBUG] i.g.h.a.w.f.WsConnectingState$ - Connecting to wss://[ENDPOINT]/websockets?Authorization=Bearer%[TOKEN]&Client-Application=EPL
[DEBUG] i.g.h.a.w.f.WsConnectingState - Connected, no checks, performing onConnected action before performing next action
[DEBUG] i.g.h.a.w.f.WsIdleState - Send text frame Send {[JSON]}
wss://[ENDPOINT]/websockets?Authorization=Bearer%[TOKEN]&Client-Application=EPL
So again, this is wrong. You should have something like Bearer%20[TOKEN]
, not Bearer%[TOKEN]
.
I suspect this %
comes from the value you’re injecting with ${access_token}
and that you’re missing the whitespace between Bearer
and the value.
If you think the issue in not on your side but with Gatling (which I don’t think), please provide a reproducer as instructed.
Also, I’ve just check that Gatling would encode a whitespace in the query as a +
, not as %20
. So this %
really doesn’t come from Gatling encoding a whitespace. A fun thing would be that you have a non printable character in your code that gets percent encoded. You should try to remove this line and type it again from scratch (not copy paste that would re-introduce the character).
So again - if instead of Bearer[TOKEN] I use:
- Bearer+[TOKEN]
- Bearer [TOKEN]
- Bearer #{[TOKEN]}
- Bearer ${[TOKEN]}, but “$” is obsolete
08:37:53.031 [DEBUG] i.g.h.a.w.f.WsConnectingState$ - Connecting to wss://[ENDPOINT]/websockets?Authorization=Bearer+35900932BB33085C2D6BB2F8481ADC57E161F5C53E77F074264C68754C76449&Client-Application=EPL
08:37:53.179 [DEBUG] i.g.h.a.w.f.WsConnectingState - Connected, no checks, performing onConnected action before performing next action
08:37:53.187 [DEBUG] i.g.h.a.w.f.WsIdleState - Send text frame Send {[JSON]}
The result is totally the same. I receive the message mentioned above. My question now is - these messages are correct - it should look like this? I didn’t use wss before so I don’t now what should I expect - as far as heard, it should be some JSON, but I don’t see any.
The result is totally the same.
wss://[ENDPOINT]/websockets?Authorization=Bearer+35900932BB33085C2D6BB2F8481ADC57E161F5C53E77F074264C68754C76449&Client-Application=EPL
No. Now your query looks correct (even though I’m very surprised to see Authorization as a query parameter and not an HTTP header).
There’s no way to help you if you don’t provide a way to reproduce your issue, as already requested above.
I’m happy that it looks correct.
Which informations do you need to reproduce this issue? I put here the code and error messages. I’m not sure if I can put anything more - can I?
In this message, there’s a link to a pinned post in this category.
In this other message, there’s a link to a StackOverFlow page that explains what a proper reproducer is.
Probably you didn’t understand my question.
What do you need MORE than code of the test case and all messages that I can see in Gatling?
There will be no screenshots because it’s API testing. I can’t also put here the testing application.
Do you understand my question now?
Probably you didn’t understand the requirement.
From https://stackoverflow.com/help/minimal-reproducible-example:
- …Minimal – Use as little code as possible that still produces the same problem
- …Complete – Provide all parts someone else needs to reproduce your problem in the question itself
- …Reproducible – Test the code you’re about to provide to make sure it reproduces the problem
How could one possibly run the piece of Gatling test you provided without you also providing a target application that exhibits the described behavior?
- if your target application is public, please share it
- if your target application is private and you can’t share any details (which your endpoint anonymization suggests), you have to build a sample application you can share and that exhibits the same behavior.
- if you’re not willing to build a sample application, you can consider going with a consulting contract to help you bebugging
Do you understand the requirement now?