Skip to content

Commit

Permalink
feat: 위치 기반 API Gatling 부하 테스트 (#220)
Browse files Browse the repository at this point in the history
* chore: docker-compose.yml 작성 (#195)

* test: Gatling 부하 테스트 구현 (#195)

* Update .env

* Delete .env
  • Loading branch information
choidongkuen authored Feb 16, 2024
1 parent 824c4a8 commit 76f9275
Show file tree
Hide file tree
Showing 6 changed files with 181 additions and 3 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -37,3 +37,6 @@ bin/

### Mac OS ###
.DS_Store

### .env ###
.env
56 changes: 56 additions & 0 deletions Docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
services:
db:
image: "mysql:8.3.0"
container_name: load_test_mysql
restart: always
environment:
MYSQL_ROOT_PASSWORD: root#1234
MYSQL_DATABASE: load_test_db
TZ: UTC

ports:
- "3000:3306"
deploy:
resources:
limits:
cpus: "0.5"
memory: "512MB"

redis:
image: "docker.io/bitnami/redis:7.2"
container_name: load_test_redis
restart: always
environment:
- ALLOW_EMPTY_PASSWORD=yes
- REDIS_AOF_ENABLED=yes
- REDIS_RDB_ENABLED=no
ports:
- "6299:6379"
deploy:
resources:
limits:
cpus: "0.5"
memory: "512MB"

teumteum-server:
build:
context: .
dockerfile: Dockerfile
restart: always
environment:
DB_URL: jdbc:mysql://db:3306/load_test_db
DB_USERNAME: root
DB_PASSWORD: root#1234
REDIS_HOST: redis
REDIS_PORT: 6379
JWT_SECERT_KEY: ${JWT_ACCESS_KEY}

depends_on:
- db
- redis
ports:
- "8080:8080"

networks:
teumteum_local:
driver: bridge
2 changes: 1 addition & 1 deletion src/gatling/java/protocol/Protocol.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ public class Protocol {

private static final String USER_AGENT = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.8; rv:16.0) Gecko/20100101 Firefox/16.0";

public static final HttpProtocolBuilder httpProtocol = HttpDsl.http.baseUrl("https://api.teum.org")
public static final HttpProtocolBuilder httpProtocol = HttpDsl.http.baseUrl("http://localhost:8080")
.header("Content-Type", "application/json")
.userAgentHeader(USER_AGENT);

Expand Down
3 changes: 1 addition & 2 deletions src/gatling/java/simulation/SimulationSample.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,7 @@ public class SimulationSample extends Simulation {
private final ScenarioBuilder scn = scenario(this.getClass().getSimpleName())
.exec(http("get user")
.get("/users/1")
.check(status().is(200))
);
.check(status().is(200)));

{
setUp(
Expand Down
66 changes: 66 additions & 0 deletions src/gatling/java/simulation/TeumTeumApiSimulation.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
package simulation;

import static io.gatling.javaapi.core.CoreDsl.StringBody;
import static io.gatling.javaapi.core.CoreDsl.constantUsersPerSec;
import static io.gatling.javaapi.core.CoreDsl.jsonPath;
import static io.gatling.javaapi.core.CoreDsl.rampUsersPerSec;
import static io.gatling.javaapi.core.CoreDsl.scenario;
import static io.gatling.javaapi.http.HttpDsl.http;
import static io.gatling.javaapi.http.HttpDsl.status;
import static protocol.Protocol.httpProtocol;

import io.gatling.javaapi.core.ScenarioBuilder;
import io.gatling.javaapi.core.Simulation;
import java.time.Duration;
import java.time.temporal.ChronoUnit;
import net.datafaker.Faker;

public class TeumTeumApiSimulation extends Simulation {

private static final Faker faker = new Faker();
private final ScenarioBuilder teumteumScn = scenario("TeumTeum 찬해지기 API 부하 테스트를 진행한다.")
.exec(session ->
session
.set("id", java.util.UUID.randomUUID().toString())
.set("name", faker.name().fullName()))

.exec(http("User 카드 등록 API 요청")
.post("/users")
.body(StringBody(
"{"
+ "\"id\": \"${id}\", "
+ "\"terms\": {\"service\": true, \"privatePolicy\": true}, "
+ "\"name\": \"${name}\", "
+ "\"birth\": \"20000402\", "
+ "\"characterId\": 2, "
+ "\"authenticated\": \"네이버\", "
+ "\"activityArea\": \"경기 시흥\", "
+ "\"mbti\": \"ENFP\", "
+ "\"status\": \"직장인\", "
+ "\"job\": {\"name\" : \"카카오 뱅크\", \"class\" : \"개발\", \"detailClass\" : \"BE 개발자\"}, "
+ "\"interests\": [\"네트워킹\", \"IT\", \"모여서 각자 일하기\"], "
+ "\"goal\": \"회사에서 좋은 사람들과 멋진 개발하기\""
+ "}"
))
.check(status().is(201))
.check(jsonPath("$.id").saveAs("userId"))
.check(jsonPath("$.accessToken").saveAs("accessToken"))
.check(jsonPath("$.refreshToken").saveAs("refreshToken")))

.exec(http("TeumTeum 친해지기 API 요청")
.post("/teum-teum/around")
.header("Authorization", "Bearer ${accessToken}")
.body(StringBody("{\"id\": ${userId}, \"latitude\": 37.5665, \"longitude\": 126.9780,"
+ " \"name\": \"test_name\", \"jobDetailClass\": \"test_job\", \"characterId\": 1}"))
.check(status().is(200))
);

{
setUp(
teumteumScn.injectOpen(
constantUsersPerSec(10).during(Duration.of(30, ChronoUnit.SECONDS)),
rampUsersPerSec(10).to(50).during(Duration.of(30, ChronoUnit.SECONDS))
).protocols(httpProtocol)
);
}
}
54 changes: 54 additions & 0 deletions src/gatling/java/simulation/UserApiSimulation.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package simulation;

import static io.gatling.javaapi.core.CoreDsl.StringBody;
import static io.gatling.javaapi.core.CoreDsl.atOnceUsers;
import static io.gatling.javaapi.core.CoreDsl.jsonPath;
import static io.gatling.javaapi.core.CoreDsl.scenario;
import static io.gatling.javaapi.http.HttpDsl.http;
import static io.gatling.javaapi.http.HttpDsl.status;
import static protocol.Protocol.httpProtocol;

import io.gatling.javaapi.core.ScenarioBuilder;
import io.gatling.javaapi.core.Simulation;

public class UserApiSimulation extends Simulation {

private final ScenarioBuilder UserScn = scenario("User API 부하 테스트를 진행한다.")
.exec(http("User 카드 등록 API 요청")
.post("/users")
.body(StringBody(
"{\"id\": \"test_id\", "
+ "\"terms\": {\"service\": true, \"privatePolicy\": true}, "
+ "\"name\": \"홍길동\", "
+ "\"birth\": \"1990-01-01\", "
+ "\"characterId\": 1, "
+ "\"authenticated\": \"SNS\", "
+ "\"activityArea\": \"서울\", "
+ "\"mbti\": \"INTJ\", "
+ "\"status\": \"ACTIVE\", "
+ "\"job\": {\"name\": \"개발자\", \"class\": \"IT\", \"detailClass\": \"백엔드\"}, "
+ "\"interests\": [\"코딩\", \"독서\", \"운동\"], "
+ "\"goal\": \"성장하기 위해 노력하는 개발자가 되기\"}"
))
.check(status().is(201))
.check(jsonPath("$.id").saveAs("userId"))
.check(jsonPath("$.accessToken").saveAs("accessToken"))
.check(jsonPath("$.refreshToken").saveAs("refreshToken"))

).exec(http("User 정보 조회 API 요청")
.get("/users/${userId}")
.header("Authorization", "Bearer ${accessToken}")
.check(status().is(200))

).exec(http("User 리뷰 조회 API 요청")
.get("/users/${userId}")
.header("Authorization", "Bearer ${accessToken}")
.check(status().is(200)));


{
setUp(
UserScn.injectOpen(
atOnceUsers(10)).protocols(httpProtocol));
}
}

0 comments on commit 76f9275

Please sign in to comment.