안녕하세요! 이제 처음 ngrinder를 통해 테스트를 해보려고 스크립트를 짜서 돌렸보았어요.
성능이 낮은 PC에서 돌려서 test configuration 에서 process : 1 thread : 1 이렇게만 돌렸어요 eclipse 에서 실행했을때 @Repeat(500) 을 주고 돌려도 에러하나없이 잘 됐는데 ngrinder에서 Run Count 100을 주고 실행하면 에러율이 높게 나옵니다. (Run Count 10 으로 두고 하면 성공하는데 컴이 너무 후져서 그런걸까요..?) 먼저 ngrinder에서 Test 후 Stop by Error 와 함께 나온 메시지 입니다. ------------------------------------------------------------------------- Console is being prepared. Console is started on port 12006 1 agents are starting. 1 agents are ready. All necessary files are being distributed. The total size of distributed files is over 976.6KBB. - Safe file distribution mode is enabled by force. - resource1.txt - testAirapp.groovy - TestBuyBookingItem.groovy - TestBuyItem.groovy - TestCancelBookingBuyItem.groovy - TestDepositLog.groovy - TestDepositSend.groovy - testEtcProcedure.groovy - TestInterestItem.groovy - TestMobileSync.groovy - TestPurchaseItem.groovy - TestRunner.groovy - TestSalesCancel.groovy - TestSearchItem.groovy - TestTotal.groovy - lib\commons-beanutils-1.8.0.jar - lib\commons-codec-1.6.jar - lib\commons-collections-3.2.1.jar - lib\commons-lang-2.6.jar - lib\commons-logging-1.1.1.jar - lib\ezmorph-1.0.6.jar - lib\groovy-backports-compat23-2.3.11.jar - lib\http-builder-0.7.jar - lib\httpclient-4.2.1.jar - lib\httpcore-4.2.1.jar - lib\json-lib-2.3-jdk15.jar - lib\jtds-1.3.1.jar - lib\mysql-connector-java-8.0.13.jar - lib\nekohtml-1.9.16.jar - lib\sqljdbc4.jar - lib\xercesImpl-2.9.1.jar - lib\xml-apis-1.3.04.jar - lib\xml-resolver-1.2.jar All necessary files are distributed. The test is ready to start. The test is started. [WARNING] The test is finished but contains too much errors(over 30% of total runs). ------------------------------------------------------------------------ eclipse에서 groovy 로 작성한 테스트 소스입니다. ------------------------------------------------------------------------ @Repeat(500) @RunWith(GrinderRunner) class TestPurchaseItem { class VBot { public int planetId = 0; public int userDbId = 0; public int accountDbId = 0; public def accountNickname = ""; public def userName = ""; public VBot(int n) { this.planetId = 1; this.userDbId = n; this.accountDbId = n; this.accountNickname = "서버1테스트" + n.toString(); this.userName = "서버1유저"+ n.toString(); } public int getRandomNumberInRange( int min, int max) { if (min >= max) { throw new IllegalArgumentException("max must be greater than min"); } Random r = new Random(); return r.nextInt((max - min) + 1) + min; } } public static GTest test1 public static GTest test2 public static HTTPRequest request public static NVPair[] headers = [] public static NVPair[] params = [] public static Cookie[] cookies = [] public static String sessionKey def curNumber = 0; def requestURI = "http://192.168.56.1:8032/"; @BeforeProcess public static void beforeProcess() { HTTPPluginControl.getConnectionDefaults().timeout = 6000 test1 = new GTest(1, "Test1") test2 = new GTest(2, "Test2") request = new HTTPRequest() // Set header datas List<NVPair> headerList = new ArrayList<NVPair>() headerList.add(new NVPair("Content-Type", "application/x-www-form-urlencoded")) headers = headerList.toArray() grinder.logger.info("before process."); } @BeforeThread public void beforeThread() { test1.record(this, "test1") test2.record(this, "test2") grinder.statistics.delayReports=true; curNumber = getCurNumber(); //test1.record(this, "test1") //test2.record(this, "test2") VBot vuser = new VBot(1010 + curNumber); def http = new HTTPBuilder(requestURI + "auth/init") try { http.request(POST,JSON) { req -> response.success = { resp, json -> JSONObject obj = new JSONObject(json); sessionKey = obj.get("sessionKey").toString(); // grinder.logger.info("[init] sessionKey ${sessionKey}") def errorCode = json.errorCode; // grinder.logger.info("[init] errorCode = ${errorCode}") } response.failure = { resp -> grinder.logger.info("Request failed with status ${resp.status}"); } } } catch( Exception ex) { grinder.logger.info("error ${ex}"); } http = new HTTPBuilder(requestURI + "auth/weblogin") try { http.request(POST,JSON) { req -> body = [sessionKey: sessionKey, accountDbId: vuser.accountDbId, userDbId: vuser.userDbId, planetId: vuser.planetId, pushToken: 'test-token', language: 'KOR'] response.success = { resp, json -> def errorCode = json.errorCode; // grinder.logger.info("[weblogin] errorCode = ${errorCode}") } response.failure = { resp -> grinder.logger.info("Request failed with status ${resp.status}"); } } } catch( Exception ex) { grinder.logger.info("error ${ex}"); } grinder.logger.info("before thread."); } @Before public void before() { request.setHeaders(headers) cookies.each { CookieModule.addCookie(it, HTTPPluginControl.getThreadHTTPClientContext()) } // grinder.logger.info("before thread. init headers and cookies"); } public int getCurNumber() { int totalProcessCount = 0; int totalThreadCount = 0; int agentNumber = 0; int processNumber = 0; int threadNumber = 0; //eclipse에서 실행 에러 방지. try { totalProcessCount = grinder.getProperties().getInt("grinder.processes", 1); totalThreadCount = grinder.getProperties().getInt("grinder.threads", 1); agentNumber = grinder.agentNumber processNumber = grinder.processNumber threadNumber = grinder.threadNumber } catch(Exception ex) { //grinder.logger.info("error {}",ex); } return (agentNumber * totalProcessCount * totalThreadCount) + (processNumber * totalThreadCount) + threadNumber; } @Test public void test1(){ def http = new HTTPBuilder(requestURI + "market/purchaseLog") try { http.request(POST,JSON) { req -> body = [sessionKey: sessionKey, pageNumber: '1', rowsPerPage: '10', sortType: 'desc', sortColumn: 'purchasedAt'] response.success = { resp, json -> def errorCode = json.errorCode; // println("[purchaseLog] errorCode = ${errorCode} resultJson = ${json}") } response.failure = { resp -> println("Request failed with status ${resp.status} ${resp.statusLine.reasonPhrase}"); assertThat(200, is(300)); } } } catch( Exception ex) { grinder.logger.info("error ${ex}"); assertThat(200, is(300)); } } @Test public void test2() { def http = new HTTPBuilder(requestURI + "market/purchaseLog_web") try { http.request(POST,JSON) { req -> body = [sessionKey: sessionKey, pageNumber: '1', rowsPerPage: '10', sortType: 'desc', sortColumn: 'purchasedAt'] response.success = { resp, json -> def errorCode = json.errorCode; // println("[purchaseLog_web] errorCode = ${errorCode} resultJson = ${json}") } response.failure = { resp -> println("Request failed with status ${resp.status} ${resp.statusLine.reasonPhrase}"); assertThat(200, is(300)); } } } catch( Exception ex) { grinder.logger.info("error ${ex}"); assertThat(200, is(300)); } } public int getRandomNumberInRange( int min, int max) { if (min >= max) { throw new IllegalArgumentException("max must be greater than min"); } Random r = new Random(); return r.nextInt((max - min) + 1) + min; } } ------------------------------------------------------------------------ 제가 뭘 잘못한건가요? 프로세스, 스레드 각각 1개라 결국 Vusers 수는 1명 뿐인데 eclipse에서 실행시켜보는것도 vusers 수가 1명인거랑 다름 없지 않나요? 어째서 eclipse에서는 성공하는데 ngrinder에서는 100건도 성공하지 못하는 것일까요? 단순히 서버 성능 문제일까요?? ㅠㅠ 감사합니다 .. |
Administrator
|
에러 메시지를 봐야할 것 같은데요?
|
앗~~ 별다른 에러메시지는 없었어요~
패킷캡쳐를 해봐두 아예 패킷이 서버까지 전송이 안되더라구요! 그래서 제가 나름 해결한게 뭐냐면 먼저 virtualBox에서 테스트를 안하고 로컬(Window 10)에 서버를 설치해서 테스트했어요~ 어차피 동시접속률이 높은지 안높은지 테스트를 하는게 아니어서 꼭 윈도우 서버일 필요는 없었거든요! 그런데 500 에러가 자꾸 나길래 stackify 라는 툴로 http 패킷을 캡쳐했어요 서버 자체에 에러가 나더라구여ㅜㅜ 스레드 안전한 함수를 썼어야 했는데, 그게 아니어서 문서에 로그를 남기다가 데드락상태에 빠져서 아무것도 못하고 계속 500에러를 남기는거였어요 그걸 고치고 난 후에 정상적으로 테스트할 수 있어서~ 해결되었습니당~! 관심 감사합니다~! |
Free forum by Nabble | Edit this page |