-
Notifications
You must be signed in to change notification settings - Fork 24
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit d17682a
Showing
33 changed files
with
1,513 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
# Eclipse | ||
.classpath | ||
.project | ||
.settings/ | ||
|
||
# Intellij | ||
.idea/ | ||
*.iml | ||
*.iws | ||
|
||
# Mac | ||
.DS_Store | ||
|
||
# Maven | ||
log/ | ||
target/ | ||
|
||
dependency-reduced-pom.xml | ||
docs/example/apache-jmeter-5.2 | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
# Jmeter Grpc Plugin | ||
|
||
A Jmeter plugin supports load test grpc service. | ||
|
||
|
||
## Prerequisites | ||
|
||
* Apache Jmeter (version >= 5.2) | ||
* Apache Maven (version >= 3.6.0) | ||
|
||
## Installation | ||
|
||
```sh | ||
$ mvn clean install | ||
$ cp target/jmeter-grpc-client-sampler.jar path/to/jmeter/lib/ext | ||
``` | ||
|
||
## Usage | ||
|
||
> *Note*: Please read [example](./docs/example/README.md) first if you want to skip the step by step below | ||
* Build and copy the protobuf jar to folder `jmeter/lib/ext` | ||
|
||
* Create test plan : | ||
* `TestPlan > Add > Thread (Users) > Thread Group` | ||
* `Thread Group > Add > Sampler > GRPC Client Sampler` | ||
* Config host, port, package, service... (see [more](docs/description.md)) | ||
* Save your test plan with name <your_test_script>.jmx | ||
|
||
* Example: [hello.jmx](./docs/example/hello.jmx) | ||
<div align="center"> | ||
<img src="docs/images/create-grpc-sampler.png" width="95%"/> | ||
</div> | ||
|
||
### Run | ||
|
||
```sh | ||
# view all command in jmeter | ||
$ jmeter/bin/jmeter.sh -h | ||
|
||
# running load test | ||
$ jmeter/bin/jmeter.sh -n -t <your_test_script>.jmx -l <result_file>.csv | ||
|
||
# generate report | ||
$ jmeter/bin/jmeter.sh -g <result_file>.csv -o <report> | ||
``` | ||
|
||
### Report | ||
|
||
<div align="center"> | ||
<img src="docs/images/report-results.png" width="90%"/> | ||
</div> | ||
|
||
|
||
## Acknowledgements | ||
|
||
Thanks to @A1Darkwing (Thanh Tran), @anhldbk (Anh Le), @VoxT (Thieu Vo) who dedicated to help me review and refactor the source code of project. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
Name | Description | Example | ||
--- | --- | --- | ||
hostname | service host | 127.0.0.1 | ||
port | service port | 50051 | ||
useSsl | use ssl or not | false | ||
packageN | package name is defined in .proto | io.grpc.examples.helloworld | ||
service | the service is defined in .proto | Greeter | ||
method | rpc method to load test | sayHello | ||
request | request class name | io.grpc.examples.helloworld.HelloRequest | ||
timeout | timeout for each call in milisecond | 3000 | ||
metaData | gRPC interceptor | {"Authorization" : "Bearer TOKEN", "Username": "A"} | ||
requestBuilderCode | the request message | | ||
|
||
`Note:` The requestBuilderCode must follows template below: | ||
|
||
```java | ||
import com.google.protobuf.Message; | ||
import org.apache.jmeter.threads.JMeterContext; | ||
import org.apache.jmeter.threads.JMeterVariables; | ||
import vn.zalopay.jmeter.grpc.utils.MessageBuilder; | ||
// TODO: import the message request | ||
|
||
public class RequestFactory implements MessageBuilder { | ||
public Message buildMessage(JMeterContext ctx) { | ||
// TODO: construct the message and return it | ||
// TIPS: you can get Jmeter variable from ctx.getVariables() | ||
// and Jmeter properties from ctx.getProperties() | ||
} | ||
} | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
# Example | ||
|
||
## Overview | ||
|
||
This example contains utility commands, help you run test gRPC with Jmeter easily. | ||
|
||
## Prerequisites | ||
|
||
* Golang (version >= 1.12.4) | ||
* Maven (version >= 3.6.0) | ||
|
||
## Usage | ||
|
||
|
||
|
||
```sh | ||
# grant role execute shell script | ||
$ sudo chmod +x scripts/* | ||
|
||
# download apache-jmeter-x.x.zip | ||
$ scripts/download.sh | ||
|
||
# install grpc jmeter plugin | ||
$ scripts/install.sh | ||
|
||
# run your jmeter test script | ||
$ go run main.go -p <protofile> -t <jmxfile> -l <csv contain metrics> -o <folder name contain report> | ||
``` | ||
|
||
### Example | ||
|
||
* Run server : | ||
|
||
```sh | ||
# run greeter server | ||
$ scripts/runserver.sh | ||
``` | ||
|
||
* Run test : | ||
|
||
```sh | ||
# run example | ||
$ go run main.go -p ./hello.proto -t ./hello.jmx -l ./hello.csv -o ./hello_report | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
# Eclipse | ||
.classpath | ||
.project | ||
.settings/ | ||
|
||
# Intellij | ||
.idea/ | ||
*.iml | ||
*.iws | ||
|
||
# Mac | ||
.DS_Store | ||
|
||
# Maven | ||
log/ | ||
target/ | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> | ||
|
||
<modelVersion>4.0.0</modelVersion> | ||
|
||
<artifactId>grpc-lib</artifactId> | ||
<groupId>vn.zalopay</groupId> | ||
<version>0.0.1</version> | ||
|
||
<properties> | ||
<grpc.version>1.23.0</grpc.version> | ||
<os-maven-plugin.version>1.4.1.Final</os-maven-plugin.version> | ||
</properties> | ||
|
||
<dependencies> | ||
<dependency> | ||
<groupId>io.grpc</groupId> | ||
<artifactId>grpc-netty</artifactId> | ||
<version>${grpc.version}</version> | ||
</dependency> | ||
<dependency> | ||
<groupId>io.grpc</groupId> | ||
<artifactId>grpc-netty-shaded</artifactId> | ||
<version>${grpc.version}</version> | ||
</dependency> | ||
|
||
<dependency> | ||
<groupId>io.grpc</groupId> | ||
<artifactId>grpc-protobuf</artifactId> | ||
<version>${grpc.version}</version> | ||
</dependency> | ||
<dependency> | ||
<groupId>io.grpc</groupId> | ||
<artifactId>grpc-stub</artifactId> | ||
<version>${grpc.version}</version> | ||
</dependency> | ||
|
||
</dependencies> | ||
|
||
<build> | ||
<extensions> | ||
<extension> | ||
<groupId>kr.motd.maven</groupId> | ||
<artifactId>os-maven-plugin</artifactId> | ||
<version>${os-maven-plugin.version}</version> | ||
</extension> | ||
</extensions> | ||
|
||
|
||
<plugins> | ||
<plugin> | ||
<groupId>org.xolstice.maven.plugins</groupId> | ||
<artifactId>protobuf-maven-plugin</artifactId> | ||
<version>0.5.0</version> | ||
<configuration> | ||
<protocArtifact>com.google.protobuf:protoc:3.3.0:exe:${os.detected.classifier}</protocArtifact> | ||
<pluginId>grpc-java</pluginId> | ||
<pluginArtifact>io.grpc:protoc-gen-grpc-java:1.4.0:exe:${os.detected.classifier} | ||
</pluginArtifact> | ||
</configuration> | ||
<executions> | ||
<execution> | ||
<goals> | ||
<goal>compile</goal> | ||
<goal>compile-custom</goal> | ||
</goals> | ||
</execution> | ||
</executions> | ||
</plugin> | ||
</plugins> | ||
</build> | ||
|
||
</project> |
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<jmeterTestPlan version="1.2" properties="5.0" jmeter="5.2"> | ||
<hashTree> | ||
<TestPlan guiclass="TestPlanGui" testclass="TestPlan" testname="Test Plan" enabled="true"> | ||
<stringProp name="TestPlan.comments"></stringProp> | ||
<boolProp name="TestPlan.functional_mode">false</boolProp> | ||
<boolProp name="TestPlan.tearDown_on_shutdown">true</boolProp> | ||
<boolProp name="TestPlan.serialize_threadgroups">false</boolProp> | ||
<elementProp name="TestPlan.user_defined_variables" elementType="Arguments" guiclass="ArgumentsPanel" testclass="Arguments" testname="User Defined Variables" enabled="true"> | ||
<collectionProp name="Arguments.arguments"/> | ||
</elementProp> | ||
<stringProp name="TestPlan.user_define_classpath"></stringProp> | ||
</TestPlan> | ||
<hashTree> | ||
<ThreadGroup guiclass="ThreadGroupGui" testclass="ThreadGroup" testname="Thread Group" enabled="true"> | ||
<stringProp name="ThreadGroup.on_sample_error">continue</stringProp> | ||
<elementProp name="ThreadGroup.main_controller" elementType="LoopController" guiclass="LoopControlPanel" testclass="LoopController" testname="Loop Controller" enabled="true"> | ||
<boolProp name="LoopController.continue_forever">false</boolProp> | ||
<intProp name="LoopController.loops">-1</intProp> | ||
</elementProp> | ||
<stringProp name="ThreadGroup.num_threads">16</stringProp> | ||
<stringProp name="ThreadGroup.ramp_time">1</stringProp> | ||
<boolProp name="ThreadGroup.scheduler">true</boolProp> | ||
<stringProp name="ThreadGroup.duration">5</stringProp> | ||
<stringProp name="ThreadGroup.delay"></stringProp> | ||
<boolProp name="ThreadGroup.same_user_on_next_iteration">true</boolProp> | ||
</ThreadGroup> | ||
<hashTree> | ||
<RandomVariableConfig guiclass="TestBeanGUI" testclass="RandomVariableConfig" testname="randomNumber" enabled="true"> | ||
<stringProp name="maximumValue">9999</stringProp> | ||
<stringProp name="minimumValue">1000</stringProp> | ||
<stringProp name="outputFormat"></stringProp> | ||
<boolProp name="perThread">false</boolProp> | ||
<stringProp name="randomSeed"></stringProp> | ||
<stringProp name="variableName">randomNumber</stringProp> | ||
</RandomVariableConfig> | ||
<hashTree/> | ||
<vn.zalopay.jmeter.grpc.client.GrpcClientSampler guiclass="TestBeanGUI" testclass="vn.zalopay.jmeter.grpc.client.GrpcClientSampler" testname="Hello World" enabled="true"> | ||
<stringProp name="hostname">localhost</stringProp> | ||
<longProp name="timeout">30</longProp> | ||
<stringProp name="metaData">{"Authorization": "Bearer TOKEN"}</stringProp> | ||
<stringProp name="method">sayHello</stringProp> | ||
<stringProp name="packageN">io.grpc.examples.helloworld</stringProp> | ||
<intProp name="port">50051</intProp> | ||
<stringProp name="request">io.grpc.examples.helloworld.HelloRequest</stringProp> | ||
<stringProp name="requestBuilderCode">import vn.zalopay.jmeter.grpc.utils.MessageBuilder; | ||
import io.grpc.examples.helloworld.HelloRequest; | ||
import com.google.protobuf.Message; | ||
import org.apache.jmeter.threads.JMeterContext; | ||
import org.apache.jmeter.threads.JMeterVariables; | ||
|
||
public class RequestFactory implements MessageBuilder { | ||
public Message buildMessage(JMeterContext jmctx) { | ||
|
||
JMeterVariables vars = jmctx.getVariables(); | ||
HelloRequest request = HelloRequest.newBuilder() | ||
.setName("Name" + vars.get("randomNumber")) | ||
.setSleepOn(23).build(); | ||
|
||
return request; | ||
} | ||
} | ||
</stringProp> | ||
<stringProp name="service">Greeter</stringProp> | ||
<boolProp name="useSsl">false</boolProp> | ||
</vn.zalopay.jmeter.grpc.client.GrpcClientSampler> | ||
<hashTree/> | ||
</hashTree> | ||
</hashTree> | ||
</hashTree> | ||
</jmeterTestPlan> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
// Copyright 2015 The gRPC Authors | ||
// | ||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
// | ||
// http://www.apache.org/licenses/LICENSE-2.0 | ||
// | ||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, | ||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
syntax = "proto3"; | ||
|
||
option java_multiple_files = true; | ||
option java_package = "io.grpc.examples.helloworld"; | ||
option java_outer_classname = "HelloWorldProto"; | ||
option objc_class_prefix = "HLW"; | ||
|
||
package helloworld; | ||
|
||
// The greeting service definition. | ||
service Greeter { | ||
// Sends a greeting | ||
rpc SayHello (HelloRequest) returns (HelloReply) {} | ||
} | ||
|
||
// The request message containing the user's name. | ||
message HelloRequest { | ||
string name = 1; | ||
int32 sleepOn = 2; | ||
} | ||
|
||
// The response message containing the greetings | ||
message HelloReply { | ||
string message = 1; | ||
} |
Oops, something went wrong.