nGrinder 설치 nGrinder 설치 가이드 참고 nGrinder Controller 실행 java -jar ngrinder-controller-3.5.5-p1.war localhast:8080 접속 id : admin pw : admin nGrinder Agent 설치 nGrinder Agent 실행 ./ngrinder-agent/run_agent.sh 스크립트 작성 import HTTPClient.HTTPResponse import HTTPClient.NVPair import groovy.json.JsonSlurper import net.grinder.plugin.http.HTTPRequest import net.grinder.script.GTest import net.grinder.scriptengine.groovy.junit.GrinderRunner import net.grinder.scriptengine.groovy.junit.annotation.BeforeProcess import net.grinder.scriptengine.groovy.junit.annotation.BeforeThread import org.junit.Before import org.junit.Test import org.junit.runner.RunWith import static net.grinder.script.Grinder.grinder import static org.hamcrest.Matchers.is import static org.junit.Assert.assertThat // import static net.grinder.util.GrinderUtils.* // You can use this if you're using nGrinder after 3.2.3 /** * A simple example using the HTTP plugin that shows the retrieval of a single page via HTTP. * * This script is automatically generated by ngrinder. * * @author admin */ @RunWith(GrinderRunner) class TestRunner { public static GTest test1 public static GTest test2 public static GTest test3 public static GTest test4 public static GTest test5 public static GTest test6 public static HTTPRequest request public static NVPair[] headers; public static String body = "{\n \"password\" : \"1234\"\n}" public static String token public static boolean active @BeforeProcess public static void beforeProcess() { test1 = new GTest(1, "POST api/hosts/{hostId}/enter") test2 = new GTest(1, "GET /api/spaces") test3 = new GTest(1, "GET /api/spaces/{spaceId}/jobs") test4 = new GTest(1, "GET /api/jobs/jobId/active") test5 = new GTest(1, "POST api/jobs/{jobId}/runningTasks/new") test6 = new GTest(1, "POST api/tasks/{taskId}/flip") request = new HTTPRequest() } @BeforeThread public void beforeThread() { test1.record(this, "test1") test2.record(this, "test2") test3.record(this, "test3") test4.record(this, "test4") test5.record(this, "test5") test6.record(this, "test6") grinder.statistics.delayReports = true } @Before public void before() { } @Test public void test1() { headers = [new NVPair("Content-Type", "application/json")] request.setHeaders(headers) HTTPResponse response = request.POST("https://dev.gongcheck.shop/api/hosts/asYuUFp1o2_TTvV_uP35VQ/enter", body.getBytes()) def jsonSlurper = new JsonSlurper() def object = jsonSlurper.parseText(response.getText()) assert object instanceof Map token = object.token println token if (response.statusCode == 301 || response.statusCode == 302) { grinder.logger.warn("Warning. The response may not be correct. The response code was {}.", response.statusCode) } else { assertThat(response.statusCode, is(200)) } grinder.logger.info('test1 완료') } @Test public void test2() { headers = [new NVPair("Authorization", "Bearer " + token)] request.setHeaders(headers) HTTPResponse response = request.GET("https://dev.gongcheck.shop/api/spaces") println response.getText() if (response.statusCode == 301 || response.statusCode == 302) { grinder.logger.warn("Warning. The response may not be correct. The response code was {}.", response.statusCode) } else { assertThat(response.statusCode, is(200)) } grinder.logger.info('test2 완료') } @Test public void test3() { headers = [new NVPair("Authorization", "Bearer " + token)] request.setHeaders(headers) HTTPResponse response = request.GET("https://dev.gongcheck.shop/api/spaces/47/jobs") println response.getText() if (response.statusCode == 301 || response.statusCode == 302) { grinder.logger.warn("Warning. The response may not be correct. The response code was {}.", response.statusCode) } else { assertThat(response.statusCode, is(200)) } grinder.logger.info('test3 완료') } @Test public void test4() { headers = [new NVPair("Authorization", "Bearer " + token)] request.setHeaders(headers) HTTPResponse response = request.GET("https://dev.gongcheck.shop/api/jobs/169/active") def jsonSlurper = new JsonSlurper() def object = jsonSlurper.parseText(response.getText()) assert object instanceof Map active = object.active if (response.statusCode == 301 || response.statusCode == 302) { grinder.logger.warn("Warning. The response may not be correct. The response code was {}.", response.statusCode) } else { assertThat(response.statusCode, is(200)) } grinder.logger.info('test4 완료') } @Test public void test5() { headers = [new NVPair("Authorization", "Bearer " + token)] request.setHeaders(headers) HTTPResponse response if (active) { response = request.GET("https://dev.gongcheck.shop/api/jobs/169/runningTasks/connect") assertThat(response.statusCode, is(200)) } else { response = request.POST("https://dev.gongcheck.shop/api/jobs/169/runningTasks/new") assertThat(response.statusCode, is(201)) } println response.getText() if (response.statusCode == 301 || response.statusCode == 302) { grinder.logger.warn("Warning. The response may not be correct. The response code was {}.", response.statusCode) } grinder.logger.info('test5 완료') } @Test public void test6() { headers = [new NVPair("Authorization", "Bearer " + token)] request.setHeaders(headers) HTTPResponse response = request.POST("https://dev.gongcheck.shop/api/tasks/1431/flip") println response.getText() if (response.statusCode == 301 || response.statusCode == 302) { grinder.logger.warn("Warning. The response may not be correct. The response code was {}.", response.statusCode) } else { assertThat(response.statusCode, is(200)) } grinder.logger.info('test7 완료') } } 성능 테스트 생성 Agent Vuser per agent Vuser Duration References https://github.com/naver/ngrinder https://velog.io/@max9106/nGrinderPinpoint-test1