Skip to content

Commit 6ebc170

Browse files
committed
feat: add multi protocol support with server configurations
1 parent aa433d9 commit 6ebc170

28 files changed

Lines changed: 522 additions & 85 deletions

js-simulation/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
},
1919
"scripts": {
2020
"clean": "rimraf target",
21-
"format": "prettier --write '**/*.ts'",
21+
"format": "prettier --write '**/*.js'",
2222
"setup": "gatling install",
2323
"build": "gatling build",
2424
"start": "gatling run --simulation test-simulation",
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
syntax = "proto3";
2+
3+
package calculator;
4+
5+
option java_package = "io.gatling.grpc.demo.calculator";
6+
option java_multiple_files = true;
7+
8+
message SumRequest {
9+
int32 first_number = 1;
10+
int32 second_number = 2;
11+
}
12+
13+
message SumResponse {
14+
int32 sum_result = 1;
15+
}
16+
17+
message PrimeNumberDecompositionRequest {
18+
int64 number = 1;
19+
}
20+
21+
message PrimeNumberDecompositionResponse {
22+
int64 prime_factor = 1;
23+
}
24+
25+
message ComputeAverageRequest {
26+
int32 number = 1;
27+
}
28+
29+
message ComputeAverageResponse {
30+
double average = 1;
31+
}
32+
33+
message FindMaximumRequest {
34+
int32 number = 1;
35+
}
36+
37+
message FindMaximumResponse {
38+
int32 maximum = 1;
39+
}
40+
41+
message SquareRootRequest {
42+
int32 number = 1;
43+
}
44+
45+
message SquareRootResponse {
46+
double number_root = 1;
47+
}
48+
49+
service CalculatorService {
50+
rpc Sum(SumRequest) returns (SumResponse) {};
51+
rpc PrimeNumberDecomposition(PrimeNumberDecompositionRequest) returns (stream PrimeNumberDecompositionResponse) {};
52+
rpc ComputeAverage(stream ComputeAverageRequest) returns (ComputeAverageResponse) {};
53+
rpc FindMaximum(stream FindMaximumRequest) returns (stream FindMaximumResponse) {};
54+
// this RPC will throw an exception if the sent number is negative
55+
rpc SquareRoot(SquareRootRequest) returns (SquareRootResponse) {};
56+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
syntax = "proto3";
2+
3+
import "greeting_messages.proto";
4+
5+
package greeting;
6+
7+
service GreetingService {
8+
rpc Greet(GreetRequest) returns (GreetResponse) {};
9+
rpc GreetWithDeadline(GreetRequest) returns (GreetResponse) {};
10+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
syntax = "proto3";
2+
3+
package greeting;
4+
5+
message Greeting {
6+
string first_name = 1;
7+
string last_name = 2;
8+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
syntax = "proto3";
2+
3+
import "greeting/greeting_content.proto";
4+
5+
package greeting;
6+
7+
message GreetRequest {
8+
Greeting greeting = 1;
9+
}
10+
11+
message GreetResponse {
12+
string result = 1;
13+
}

js-simulation/src/grpc.gatling.js

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,23 +2,34 @@ import { atOnceUsers, scenario, simulation } from "@gatling.io/core";
22
import { grpc, response, statusCode } from "@gatling.io/grpc";
33

44
export default simulation((setUp) => {
5-
const grpcProtocol = grpc
5+
const greetingServerConfiguration = grpc
6+
.serverConfiguration("greeting")
67
.forAddress("localhost", 50051)
78
.overrideAuthority("gatling-grpc-demo-test-server");
89

10+
const calculatorServerConfiguration = grpc.serverConfiguration("calculator").forAddress("localhost", 50052);
11+
12+
const grpcProtocol = grpc.serverConfigurations(greetingServerConfiguration, calculatorServerConfiguration);
13+
914
const scn = scenario("Greeting Unary").exec(
1015
grpc("Greet")
1116
.unary("greeting.GreetingService/Greet")
17+
.serverConfiguration("greeting")
1218
.send({
1319
greeting: {
1420
first_name: "John",
1521
last_name: "Doe"
1622
}
1723
})
18-
.check(
19-
statusCode().is("OK"),
20-
response((response) => response.result).isEL("Hello John Doe")
21-
)
24+
.check(statusCode().is("OK"), response((response) => response.result).isEL("Hello John Doe")),
25+
grpc("Sum")
26+
.unary("calculator.CalculatorService/Sum")
27+
.serverConfiguration("calculator")
28+
.send({
29+
first_number: 1,
30+
second_number: 2
31+
})
32+
.check(statusCode().is("OK"), response((response) => response.sum_result).is(3))
2233
);
2334

2435
setUp(scn.injectOpen(atOnceUsers(5))).protocols(grpcProtocol);

js-simulation/src/mqtt.gatling.js

Lines changed: 6 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,24 @@
1-
import {
2-
StringBody,
3-
atOnceUsers,
4-
jmesPath,
5-
scenario,
6-
simulation
7-
} from "@gatling.io/core";
1+
import { StringBody, atOnceUsers, jmesPath, scenario, simulation } from "@gatling.io/core";
82
import { mqtt } from "@gatling.io/mqtt";
93
import * as uuid from "uuid";
104

115
export default simulation((setUp) => {
126
// Example using HiveMQ's free public MQTT broker: https://www.hivemq.com/mqtt/public-mqtt-broker/
13-
const baseMqttProtocol =
14-
mqtt.broker("broker.hivemq.com", 8883)
15-
.useTls(true)
16-
.correlateBy(jmesPath("id"));
7+
const baseMqttProtocol = mqtt.broker("broker.hivemq.com", 8883).useTls(true).correlateBy(jmesPath("id"));
178

189
const topic = "gatling-mqtt-demo/" + uuid.v4();
1910

2011
const scn = scenario("Publisher")
21-
.exec(session => session.set("id", uuid.v4()))
12+
.exec((session) => session.set("id", uuid.v4()))
2213
.exec(
2314
mqtt("Connecting").connect(),
24-
mqtt("Subscribing")
25-
.subscribe(topic),
15+
mqtt("Subscribing").subscribe(topic),
2616
mqtt("Publishing")
2717
.publish(topic)
28-
.message(StringBody("{\"id\":\"#{id}\",\"message\":\"Hello from #{id}\"}"))
18+
.message(StringBody('{"id":"#{id}","message":"Hello from #{id}"}'))
2919
.await({ amount: 1, unit: "seconds" })
3020
.check(jmesPath("message").isEL("Hello from #{id}"))
3121
);
3222

33-
setUp(scn.injectOpen(atOnceUsers(5)))
34-
.protocols(baseMqttProtocol);
23+
setUp(scn.injectOpen(atOnceUsers(5))).protocols(baseMqttProtocol);
3524
});

js-simulation/src/sse.gatling.js

Lines changed: 26 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,32 @@
1-
import {atOnceUsers, jmesPath, pause, simulation, scenario, substring} from "@gatling.io/core";
1+
import { atOnceUsers, jmesPath, pause, simulation, scenario, substring } from "@gatling.io/core";
22
import { http, sse } from "@gatling.io/http";
33

44
export default simulation((setUp) => {
5-
const httpProtocol = http
6-
.baseUrl("https://sse.dev")
7-
.sseUnmatchedInboundMessageBufferSize(10);
5+
const httpProtocol = http.baseUrl("https://sse.dev").sseUnmatchedInboundMessageBufferSize(10);
86

9-
const scn = scenario("Scenario")
10-
.exec(
11-
sse("test")
12-
.get("/test")
13-
.queryParam("interval", "1")
14-
.queryParam("jsonobj", "{\"message\":\"salutations maximales\"}")
15-
.await(5)//{ amount: 5, unit: "seconds" })
16-
.on(
17-
sse.checkMessage("data")
18-
.matching(substring("data"))
19-
.check(jmesPath("data").is("{\"message\":\"salutations maximales\"}"))
20-
),
21-
sse("setCheck")
22-
.setCheck()
23-
.await(1)
24-
.on(
25-
sse.checkMessage("data 2").check(jmesPath("data").is("{\"message\":\"salutations maximales\"}"))
26-
),
27-
pause(5),//{ amount: 5, unit: "seconds"}),
28-
sse.processUnmatchedMessages((messages, session) => {
29-
console.log("unmatched messages", messages);
30-
return session;
31-
}),
32-
sse("close").close()
33-
);
7+
const scn = scenario("Scenario").exec(
8+
sse("test")
9+
.get("/test")
10+
.queryParam("interval", "1")
11+
.queryParam("jsonobj", '{"message":"salutations maximales"}')
12+
.await(5) //{ amount: 5, unit: "seconds" })
13+
.on(
14+
sse
15+
.checkMessage("data")
16+
.matching(substring("data"))
17+
.check(jmesPath("data").is('{"message":"salutations maximales"}'))
18+
),
19+
sse("setCheck")
20+
.setCheck()
21+
.await(1)
22+
.on(sse.checkMessage("data 2").check(jmesPath("data").is('{"message":"salutations maximales"}'))),
23+
pause(5), //{ amount: 5, unit: "seconds"}),
24+
sse.processUnmatchedMessages((messages, session) => {
25+
console.log("unmatched messages", messages);
26+
return session;
27+
}),
28+
sse("close").close()
29+
);
3430

35-
setUp(scn.injectOpen(atOnceUsers(1)))
36-
.protocols(httpProtocol);
31+
setUp(scn.injectOpen(atOnceUsers(1))).protocols(httpProtocol);
3732
});

js-simulation/src/ws.gatling.js

Lines changed: 7 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,10 @@ import { simulation, scenario, atOnceUsers, bodyString, pause } from "@gatling.i
22
import { http, ws, isWsInboundMessageText } from "@gatling.io/http";
33

44
export default simulation((setUp) => {
5-
const httpProtocol = http
6-
.wsBaseUrl("wss://echo.websocket.org")
7-
.wsUnmatchedInboundMessageBufferSize(10);
5+
const httpProtocol = http.wsBaseUrl("wss://echo.websocket.org").wsUnmatchedInboundMessageBufferSize(10);
86

97
const scn = scenario("Scenario")
10-
.exec(session => session.set("message", "Hello WebSocket server!"))
8+
.exec((session) => session.set("message", "Hello WebSocket server!"))
119
.exec(
1210
ws("Connect WS")
1311
.connect("/")
@@ -17,24 +15,21 @@ export default simulation((setUp) => {
1715
.sendText("Hello WebSocket server! (1)")
1816
.await(5)
1917
.on(ws.checkTextMessage("Check response 1").check(bodyString().saveAs("response1"))),
20-
ws("Message 2")
21-
.sendText("#{message} (2)"),
22-
ws("Message 3")
23-
.sendText(session => `${session.get("message")} (3)`),
18+
ws("Message 2").sendText("#{message} (2)"),
19+
ws("Message 3").sendText((session) => `${session.get("message")} (3)`),
2420
pause(5),
2521
ws.processUnmatchedMessages((messages, session) => {
26-
const unmatchedMessages = messages.map(m => isWsInboundMessageText(m) ? m.message() : "<binary message>");
22+
const unmatchedMessages = messages.map((m) => (isWsInboundMessageText(m) ? m.message() : "<binary message>"));
2723
return session.set("unmatchedMessages", unmatchedMessages);
2824
}),
2925
ws("Close WS").close()
3026
)
31-
.exec(session => {
27+
.exec((session) => {
3228
console.log(`Connect response: ${session.get("response0")}`);
3329
console.log(`Response 1: ${session.get("response1")}`);
3430
console.log(`Unmatched responses: ${session.get("unmatchedMessages")}`);
3531
return session;
3632
});
3733

38-
setUp(scn.injectOpen(atOnceUsers(1)))
39-
.protocols(httpProtocol);
34+
setUp(scn.injectOpen(atOnceUsers(1))).protocols(httpProtocol);
4035
});

js/grpc/src/bidiStream.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ export interface GrpcBidirectionalStreamingServiceBuilder
4444
messageResponseTimePolicy(
4545
messageResponseTimePolicy: MessageResponseTimePolicy
4646
): GrpcBidirectionalStreamingServiceBuilder;
47+
serverConfiguration(serverConfigurationName: string): GrpcBidirectionalStreamingServiceBuilder;
4748
streamName(streamName: string): GrpcBidirectionalStreamingServiceBuilder;
4849

4950
// Terminal methods / specific actions
@@ -94,6 +95,7 @@ export const wrapGrpcBidirectionalStreamingServiceBuilder =
9495
),
9596
messageResponseTimePolicy: (messageResponseTimePolicy) =>
9697
wrap(_underlying.messageResponseTimePolicy(toJvmMessageResponseTimePolicy(messageResponseTimePolicy))),
98+
serverConfiguration: (serverConfigurationName) => wrap(_underlying.serverConfiguration(serverConfigurationName)),
9799
streamName: (streamName) => wrap(_underlying.streamName(streamName)),
98100
// Terminal methods / specific actions
99101
start: () => wrapActionBuilder(_underlying.start()),

0 commit comments

Comments
 (0)