Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,6 @@
import eu.luminis.jmeter.wssampler.SingleWriteWebSocketSampler;
import eu.luminis.jmeter.wssampler.SingleWriteWebSocketSamplerGui;
import java.lang.reflect.Method;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Arrays;
import java.util.List;
import org.apache.jmeter.testelement.TestElement;
Expand All @@ -25,6 +23,7 @@
import us.abstracta.jmeter.javadsl.codegeneration.params.EnumParam;
import us.abstracta.jmeter.javadsl.codegeneration.params.StringParam;
import us.abstracta.jmeter.javadsl.core.samplers.BaseSampler;
import us.abstracta.jmeter.javadsl.http.JmeterUrl;

/**
* Provides factory methods to create WebSocket samplers for performance
Expand Down Expand Up @@ -119,8 +118,8 @@ public static DslDisconnectSampler websocketDisconnect() {
* @return the write sampler for further configuration or usage
* @since 2.2
*/
public static DslWriteSampler websocketWrite(String requestData) {
return new DslWriteSampler(requestData);
public static DslWriteSampler websocketWrite(String requestData, String dataType) {
return new DslWriteSampler(requestData, dataType);
}

/**
Expand All @@ -133,11 +132,12 @@ public static DslWriteSampler websocketWrite(String requestData) {
* Requires an active WebSocket connection established via
* {@link #websocketConnect(String)}.
*
* @param type the data type to read from the server. Must be 'text' or 'binary'
* @return the read sampler for further configuration or usage
* @since 2.2
*/
public static DslReadSampler websocketRead() {
return new DslReadSampler();
public static DslReadSampler websocketRead(String type) {
return new DslReadSampler(type);
}

public static class DslConnectSampler extends BaseSampler<DslConnectSampler> {
Expand All @@ -150,43 +150,40 @@ public static class DslConnectSampler extends BaseSampler<DslConnectSampler> {

private DslConnectSampler(String url) {
super("WebSocket Open Connection", OpenWebSocketSamplerGui.class);
try {
URI uri = new URI(url);
parseUrl(url);
}

private static boolean containsJmeterExpression(String value) {
return value != null && value.contains("${");
}

String scheme = uri.getScheme();
if (scheme == null || (!"ws".equals(scheme) && !"wss".equals(scheme))) {
private void parseUrl(String url) {
JmeterUrl parsed = JmeterUrl.valueOf(url);
String scheme = parsed.protocol();
if (scheme != null && !containsJmeterExpression(scheme)) {
if (!"ws".equals(scheme) && !"wss".equals(scheme)) {
throw new IllegalArgumentException(
"Invalid WebSocket URL. Must start with 'ws://' or 'wss://'");
}

this.tls = "wss".equals(scheme);
this.server = uri.getHost();
if (this.server == null) {
throw new IllegalArgumentException("Invalid WebSocket URL. Host is required");
}

int port = uri.getPort();
if (port == -1) {
this.port = this.tls ? "443" : "80";
} else {
this.port = String.valueOf(port);
}

String path = uri.getPath();
if (path == null || path.isEmpty()) {
this.path = "/";
tls = "wss".equals(scheme);
}
server = parsed.host();
if ((server == null || server.isEmpty()) && scheme != null
&& !containsJmeterExpression(scheme)) {
throw new IllegalArgumentException("Invalid WebSocket URL. Host is required");
}
String parsedPort = parsed.port();
if (parsedPort == null || parsedPort.isEmpty()) {
if (scheme != null && !containsJmeterExpression(scheme)) {
port = tls ? "443" : "80";
} else {
this.path = path;
}

String query = uri.getQuery();
if (query != null && !query.isEmpty()) {
this.path = this.path + "?" + query;
port = "";
}

} catch (URISyntaxException e) {
throw new IllegalArgumentException("Invalid WebSocket URL: " + url, e);
} else {
port = parsedPort;
}
String parsedPath = parsed.path();
path = (parsedPath == null || parsedPath.isEmpty()) ? "/" : parsedPath;
}

@Override
Expand All @@ -199,9 +196,15 @@ protected TestElement buildTestElement() {
ret.setReadTimeout(responseTimeoutMillis);
}
ret.setTLS(tls);
ret.setServer(server);
ret.setPort(port);
ret.setPath(path);
if (server != null) {
ret.setServer(server);
}
if (port != null) {
ret.setPort(port);
}
if (path != null) {
ret.setPath(path);
}
return ret;
}

Expand Down Expand Up @@ -424,16 +427,21 @@ protected MethodCall buildMethodCall(CloseWebSocketSampler testElement,

public static class DslWriteSampler extends BaseSampler<DslWriteSampler> {
private String requestData;
private String dataType;

private DslWriteSampler(String requestData) {
private DslWriteSampler(String requestData, String dataType) {
super("WebSocket Single Write", SingleWriteWebSocketSamplerGui.class);
this.requestData = requestData;
this.dataType = dataType;
if (dataType != null && !"text".equals(dataType) && !"binary".equals(dataType)) {
throw new IllegalArgumentException("Invalid data type. Must be 'text' or 'binary'");
}
}

@Override
protected TestElement buildTestElement() {
SingleWriteWebSocketSampler write = new SingleWriteWebSocketSampler();
write.setType(DataPayloadType.Text);
write.setType("text".equals(dataType) ? DataPayloadType.Text : DataPayloadType.Binary);
write.setRequestData(requestData);
write.setCreateNewConnection(false);
return write;
Expand All @@ -460,9 +468,14 @@ protected MethodCall buildMethodCall(SingleWriteWebSocketSampler testElement,
public static class DslReadSampler extends BaseSampler<DslReadSampler> {
private String responseTimeoutMillis;
private boolean waitForResponse = true;
private String type;

private DslReadSampler() {
private DslReadSampler(String type) {
super("WebSocket Single Read", SingleReadWebSocketSamplerGui.class);
this.type = type;
if (type != null && !"text".equals(type) && !"binary".equals(type)) {
throw new IllegalArgumentException("Invalid data type. Must be 'text' or 'binary'");
}
}

@Override
Expand All @@ -471,7 +484,7 @@ protected TestElement buildTestElement() {
if (responseTimeoutMillis != null) {
read.setReadTimeout(responseTimeoutMillis);
}
read.setDataType(DataType.Text);
read.setDataType("text".equals(type) ? DataType.Text : DataType.Binary);
read.setOptional(!waitForResponse);
read.setCreateNewConnection(false);
return read;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
import java.util.concurrent.TimeUnit;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static us.abstracta.jmeter.javadsl.JmeterDsl.responseAssertion;
import static us.abstracta.jmeter.javadsl.JmeterDsl.testPlan;
import static us.abstracta.jmeter.javadsl.JmeterDsl.threadGroup;
import static us.abstracta.jmeter.javadsl.JmeterDsl.*;
import static us.abstracta.jmeter.javadsl.websocket.WebsocketJMeterDsl.*;

import org.junit.jupiter.api.Test;
import us.abstracta.jmeter.javadsl.core.TestPlanStats;
import us.abstracta.jmeter.javadsl.core.samplers.DslSampler;

public class DslWebsocketSamplerTest {

Expand All @@ -19,9 +18,10 @@ public void shouldConnectAndEchoMessageWhenWebSocketTestPlanWithEchoServer() thr
String wsUri = echoServer.getUri();
TestPlanStats stats = testPlan(
threadGroup(1, 1,
websocketConnect(wsUri),
websocketWrite("Hello WebSocket Test!"),
websocketRead()
vars().set("stream_key", "1234567890"),
websocketConnect(wsUri + "/test?stream_key=${stream_key}"),
websocketWrite("Hello WebSocket Test!", "text"),
websocketRead("text")
.children(
responseAssertion()
.containsSubstrings("Hello WebSocket Test!")),
Expand Down Expand Up @@ -61,7 +61,7 @@ public void shouldErrorSamplerWhenConnectWithVeryShortTimeout() throws Exception
public void shouldErrorSamplerWhenWriteOperationWhenNoPreviousConnection() throws Exception {
TestPlanStats stats = testPlan(
threadGroup(1, 1,
websocketWrite("Test message")))
websocketWrite("Test message", "text")))
.run();
assertThat(stats.overall().errorsCount()).isEqualTo(1);
}
Expand All @@ -70,7 +70,7 @@ public void shouldErrorSamplerWhenWriteOperationWhenNoPreviousConnection() throw
public void shouldErrorSamplerWhenReadOperationWhenNoPreviousConnection() throws Exception {
TestPlanStats stats = testPlan(
threadGroup(1, 1,
websocketRead()))
websocketRead("text")))
.run();
assertThat(stats.overall().errorsCount()).isEqualTo(1);
}
Expand Down