이 가이드는 nGrinder 3.3 이후 버전의 설치 방법을 다루고 있습니다. nGrinder 3.2 대 버전에 대한 설치 가이드를 보고 싶으시면, nGrinder 3.2 : 설치방법 을 참고하시기 바랍니다.
3.3 버전은 곧 출시됩니다~!!

사전 준비 사항

  • nGrinder 는 웹 어플리케이션인 컨트롤러와 자바 어플리케이션인 에이전트, 모니터로 구성되어 있습니다. 만약 컨컨트롤러와 에이전트가 뭔지 알고 싶으시다면, 아키텍처를 참고하세요.
    nGrinder 컨트롤러와 에이전트를 설치하려면 설치할 서버에 오라클 JDK 1.6 이후 버전 또는 오픈JDK 1.7 이후 버전이 설치할 서버에 사전 설치되어 있어야 합니다.
  • PATH 환경 변수를 먼저 확인하셔서 Java 의 바이너리 위치가 PATH에 들어와 있는지 확인해 주세요.
  • nGrinder 는 컨트롤러와 에이전트간의 통신을 위해 많은 포트를 사용합니다. 만약 방화벽에 의해 일부 포트가 막혀 있다면, 네트워크 관리자에게 문의하여 아래 포트들을 열어달라고 요청하셔야 합니다. 설정을 통해 사용할 포트를 수정할 수도 있습니다.
    • 에이전트:모든 포트 ==> 컨트롤러 : 16001
    • 에이전트:모든 포트 ==> 컨트롤러 : 12000 ~ 12000 + 동시 테스트 허용할 테스트 개수
    • 컨트롤러:모든 포트 ==> 모니터:13243
    • 컨트롤러 ==> 일반 유저 : 웹 서버 설정 방식에 따르나, 디폴트는 8080 입니다.

다운로드

nGrinder 3.3 의 설치 파일은 다음 링크에서 다운로드 할 수 있습니다.

다운된 war 파일은 반드시 스페이스가 포함되지 않은 폴더에 설치하셔야 합니다. 예를 들어 C:\Program Files\tomcat\webapps 같은 폴더는 Program Files 라는 패스에 스페이가 들어가게 되므로 문제가 됩니다.

컨트롤러 설치하기

nGrinder 3.3 은 Jenkins와 유사하게 자체적으로 실행 가능한 웹 아카이브 파일(WAR)로 배포됩니다. 따라서 WAR 파일을 직접 자바로 실행할 수도 있고, 아니면 톰캣같은 웹 어플리케이션 서버에 올려서 실행할 수도 있습니다. 초보자인 경우에는 직접 실행하기를 권장 드리고, 전문가이시면 톰캣에 설치하기를 권장 드립니다.

직접 실행하기

  1. PATH와 JAVA_HOME 환경 변수가 잘 정의되어 있는지 확인합니다. 특히 PATH 환경 변수를 잘못 설정함에 발생하는 문제가 상당히 많습니다. 따라서 자바의 실행 패스가 PATH의 제일 앞 단에 있는지 확인 합니다. 예를 들어 윈도우 서버 버전에서는 디폴트로 1.4 버전의 자바가 이미 PATH 안에 설정되어 있는 경우가 있습니다. 따라서 PATH 맨 뒤에 신규 자바를 넣을 경우, 신규 버전의 자바가 아닌  1.4 버전대의 자바가 실행되고는 합니다. 따라서 윈도우에서 반드시 PATH가 C:\Program Files\Java\Your_Java_Version\bin;BlarBlar... 과 같이 맨 앞에 설정되도록 합니다.
  2. 다운받은 nGrinder 컨트롤러를 다음과 같이 실행합니다.
    java -jar ngrinder-controller-X.X.war
  3. 그러면 다음과 같은 에러 메시지를 보시게 될 겁니다.
    nGrinder needs quite big perm-gen memory.
    Please run nGrinder with the following command.
    java -XX:MaxPermSize=200m -jar  ngrinder-controller-3.3.war

    nGrinder 는 꽤 많은 PermGen 메모리를 필요로 합니다. 왜냐하면, 편리하게 한 개의 패키지로 구성하다 보니, 꽤나 많은 라이브러리(SVNKit, Maven, Jetty Web Server, Groovy, Jython등)를 한 통으로 포함하게 되었고, 이에 따라 메모리 요구량이 많아 졌기 때문입니다.
  4. 디폴트로 nGrinder 은 웹서버 포트로 8080을 사용합니다. 만약 다른 포트를 사용하고자 한다면, 실행 시에 --port 옵션을 주어 포트를 재설정 하면 됩니다. 다음은 최종 실행 커멘드 입니다.
    java -XX:MaxPermSize=200m -jar  ngrinder-controller-3.3.war --port 80
  5. 위와 같이 WAR 파일을 실행하면, WAR 파일은 ${user.home}/.ngrinder/webapp 폴더로 압축이 풀리게 됩니다. ${user.home}/.ngrinder 폴더에는 실행 파일 내에도 DB 나 설정 파일 같은 각종 파일들도 같이 생성됩니다.
  6. 화면에 웹 서버를 띄우면서 로그를 출력하게 됩니다. 만약 다음과 같은 화면을 보게 된다면, nGrinder 컨트롤러가 실행 준비 된 겁니다.
    INFO 14. 1. 20 오후 4:39:liquibase: ChangeSet ngrinder_datachange_logfile/db.changelog_schema_22.xml::22::ngrinder.3.3 r
    an successfully in 4ms
    INFO 14. 1. 20 오후 4:39:liquibase: ChangeSet ngrinder_datachange_logfile/db.changelog_schema_23.xml::23::ngrinder.3.3 r
    an successfully in 7ms
    INFO 14. 1. 20 오후 4:39:liquibase: ChangeSet ngrinder_datachange_logfile/db.changelog_schema_24.xml::24::ngrinder.3.3 r
    an successfully in 2ms
    INFO 14. 1. 20 오후 4:39:liquibase: ChangeSet ngrinder_datachange_logfile/db.changelog_schema_25.xml::25::ngrinder.3.3 r
    an successfully in 7ms
    INFO 14. 1. 20 오후 4:39:liquibase: ChangeSet ngrinder_datachange_logfile/db.changelog_schema_26.xml::26::ngrinder.3.3 r
    an successfully in 8ms
    2014-01-20 16:39:30.633:INFO:/:Initializing Spring FrameworkServlet 'appServlet'
    2014-01-20 16:39:31.141:INFO::Started SocketConnector@@0.0.0.0:80
  7. 브라우저를 열고 http://localhost 로 접근해 보세요.

톰캣에 설치하기

  1. 먼저 톰캣을 설치하세요.
  2. 먼저 다운로드 받는 WAR 파일을 톰캣의 webapps 폴더(${TOMCAT_HOME}/webapps)에 저장합니다. 만약 nGrinder 를 컨텍스트 경로(http://localhost/ngrinder-controller-3.3와 같이)가 없이 바로 http://localhost 와 같은 형태로 접근하고자 한다면 WAR 파일명을 ROOT.war로 변경하세요.
  3. 그 다음에 ${TOMCAT_HOME}/bin/catalina.sh(리눅스) / ${TOMCAT_HOME}/catalina.bat(윈도우) 파일을 열어서 제일 앞 부분에 다음과 같이 메모리 설정을 넣습니다.
    JAVA_OPTS="-Xms600m -Xmx1024m -XX:MaxPermSize=200m"    # for catalina.sh
    set JAVA_OPTS=-Xms600m -Xmx1024m -XX:MaxPermSize=200m   # for catalina.bat
  4. 그 다음에 ${TOMCAT_HOME}/startup.sh(리눅스) 또는 ${TOMCAT_HOME}/startup.bat 파일을 실행하세요.
  5. 브라우저를 열고 http://localhost:8080/ngrinder-controller-X.X 를 방문하시거나, WAR 파일을 ROOT.war 로 변경하였다면 http://localhost:8080 로 접근해 봅니다.

추가 정보

  • nGrinder 는 다수개의 컨트롤러를 묶어 한 개의 nGrinder 인스턴스 처럼 동작하게 하는 클러스터 모드라는 것을 제공합니다. 각 컨트롤러는 특정 지역(네트워크 구간)의 테스트를 담당합니다. 클러스터 모드로 컨트롤러가 묶기게 되면, 어느 컨트롤러의 인터페이스로 테스트를 진행하더라도 해당하는 지역을 담당하는 컨트롤러가 자동적으로 실행됩니다. 이에 대해서는 컨트롤러 클러스터링 가이드를 참고하시기 바랍니다.
  • 각 설치하는 조직의 요구에 따라 nGrinder를 다양하게 커스터마이징 할 수도 있습니다. 이에 대해서는 컨트롤러 설정 가이드를 참고하시기 바랍니다.

에이전트 설치하기

기존 nGrinder 버전에서는 nGrinder 에이전트 패키지를 sourceforge 에서 별도로 다운받아 설치하여야만 했습니다. 그러나 nGrinder 3.3 부터는  컨트롤러에서 에이전트 패키지를 직접 다운로드 하는 방법으로 바뀌었습니다. 컨트롤러에서 다운로드 되기 때문에, 여러 가지가 가능하게 되었는데, 그 중 으뜸은 에이전트 패키지에 해당 컨트롤러에 접속하는 방법이 미리 설정되어 제공되는 겁니다. 따라서 무설정 에이전트 설치가 가능해 졌습니다.

  1. 먼저 컨트롤러로 로그인 합니다. 디폴트 admin 유저의 패스워드는 admin 입니다.
    image
  2. 우상 측의 메뉴를 클릭하여 “에이전트 다운로드” 메뉴를 선택하세요.
    image

    admin 유저로 로그인하면, 전체 사용자가 공유할 수 있는 에이전트가 다운됩니다. 만약 admin 유저가 아닌 일반 유저로 로그인 하였을 경우에는 “전용 에이전트 다운로드”라는 메뉴가 보입니다. 이 메뉴로 에이전트를 다운로드 하면 현재 사용자만 사용할 수 있는 전용 에이전트 설정이 담긴 에이전트가 다운됩니다. 자세한 사항은 전용 에이전트 항목을 참조하세요.
    만약 리눅스 서버에서 wget 등으로 에이전트를 직접 다운로드 하고 싶다면, wget에 해당 메뉴의 링크를 넣으시면 됩니다. 링크는 현재 nGrinder를 어떻게 설정하였는 지에 따라 조금씩 바뀌니 항상 해당 메뉴의 링크를 복사해서 다운로드 하세요.
    예: wget http://ngrinder.com/agent/download
    다운로드된 에이전트 팩키지는 다운로드 URL 의 호스트명을 사용하여 접속하도록 설정되어 있습니다.(위의 경우에 에이전트는 ngrinder.com 으로 접속하도록 되어 있습니다.) 그런데 어떤 경우에는 다른 해당 컨트롤러의 다른 IP를 통해 접속하고자 하는 경우가 있을 겁니다. 이때는 다음과 같이 다운로드 하셔야 합니다.
    예: wget http://10.10.10.10/agent/download
    그러면 10.10.10.10 으로 접근하도록 미리 설정된 에이전트가 자동으로 다운됩니다.
  3. 그러면 에이전트가 담긴 tar 파일이 다운로드 됩니다. tar 파일은 윈도우에서는 7zip으로 압축 해제 가능하고, 리눅스에서는 tar xvf tar_file.tar 명령어로 해제 가능합니다.
  4. tar 파일을 압축 해제하고, 해제된 폴더로 이동하여 run_agent.sh(리눅스) 또는 run_agent.bat 파일을 실행합니다. 그러면 에이전트는 다음과 같은 절차를 통해 실행됩니다.
    1. ${user.home}/.ngrinder_agent 폴더와 해당 폴더 내에 agent.conf 파일이 있는지 확인합니다.
    2. 만약 해당 파일이 없다면 에이전트 설치 파일 내에 있는 __agent.conf(설정 파일입니다.) 파일을 ${user.home}/.ngrinder_agent 폴더로 복사합니다.
    3. 만약 해당 파일이 이미 있다면, 복사하지 않고 기존의 설정 파일을 사용하여 실행합니다.
  5. 만약 기존 설정 파일(${user.home}/.ngrinder_agent/agent.conf)을 최신 설정 파일(__agent.conf)로 덮어쓰기 하고 싶다면,  에이전트 실행 시 –o 옵션을 주면 됩니다.
    run_agent.sh -o # for linux / mac
    run_agent_bg.sh -o # If you want to run it in the background for linux / macor 
    
    run_agent.bat –o # for windows
  6. 에이전트를 정지하고 싶다면 다음 명령어를 실행하세요.
    stop_agent.sh # for linux / mac 
    
    stop_agent.bat # for windows
  7. nGrinder 3.3 부터는 에이전트가 컨트롤러에 연결시 자동으로 사용가능 하도록 승인 처리됩니다. 그러나 만약 어뷰징을 막기 위해, 반드시 어드민이 승인해야지만 해당 에이전트를 사용 가능하게 하고 싶다면, nGrinder 의 시스템 설정을 열어 다음 설정을 부여해 줘야 합니다.
    controller.enable_agent_auto_approval=false
  8. 에이전트를 승인하기 위해서는 에이전트 관리 페이지로 들어가서 우측의 “승인됨 버튼을 눌러 주세요.
    image
  9. 만약 현재 리눅스를 사용 중에 있다면, 에이전트가 많은 쓰레드를 실행할 수 있게 하기 위해 리눅스 설정을 조금 변경해 줘야 합니다. 먼저 ulimit –a 명령을 실행하여 현재 리눅스의 설정을 살펴봅니다.
    > ulimit -a                                                                                                                                         
    core file size          (blocks, -c) 0
    data seg size           (kbytes, -d) unlimited
    scheduling priority             (-e) 0
    file size               (blocks, -f) unlimited
    pending signals                 (-i) 30676
    max locked memory       (kbytes, -l) 64
    max memory size         (kbytes, -m) unlimited
    open files                      (-n) 16000
    pipe size            (512 bytes, -p) 8
    POSIX message queues     (bytes, -q) 819200
    real-time priority              (-r) 0
    stack size              (kbytes, -s) 10240
    cpu time               (seconds, -t) unlimited
    max user processes              (-u) 32768
    virtual memory          (kbytes, -v) unlimited
    file locks                      (-x) unlimited
  10. 위 설정사항 중에 특히 주의해서 봐야 할 설정은 max user processes 와 open files 입니다. 만약 두 값이 10000 이하라면, 루트 권한으로 /etc/security/limits.conf  를 열어 다음과 같이 편집해 줘야 합니다.
    your_account soft    nproc           32768
    your_account hard    nproc           32768
    root         soft    nproc           32768
    root         hard    nproc           32768
    your_account soft    nofile          16000
    your_account hard    nofile          16000
    root         soft    nofile          16000
    root         hard    nofile          16000
  11. 별다른 설정이 없다면 한 개의 머신 에는 단 한 개의 에이전트만이 설치 가능합니다. 그러나 간혼 한 개의 머신에 여러 에이전트를 설치하여야만 하는 경우도 있습니다. 만약 이런 요구사항이 있다면 에이전트 설정 가이드를 참고하시기 바랍니다.

모니터 설치하기

nGrinder 모니터는 테스트 타겟 서버에 설치하여, 성능 테스트 중 해당 서버의 시스템 상태(CPU 사용률, 메모리 사용률, 네트워크 사용율)을 측정할 때 사용하는 어플리케이션 입니다. 에이전트와 마찬가지로 컨트롤러에서 다운로드 가능합니다.

  1. 우상측의 메뉴를 클릭하여 모니터를 다운로드 합니다.
    image
  2. 다운된 모니터 패키지의 압축을 푼 다음에 다음 명령어를 실행합니다.
    run_monitor_bg.sh  # for linux / mac 
    run_monitor.bat # for windows
  3. 만약 모니터를 종료하고자 한다면 다음 명령어를 실행하세요.
    stop_monitor.sh   # for linux / mac
    stop_monitor.bat  # for windows

자 이제 설치가 끝나서 성능 테스트를 실행할 수 있습니다. 빨리 사용하기 를 참조하세요~

Posted by 윤준호

제가 보통 외부에 3시간 정도로 긴 시간동안 ngrinder 소개할일이 있을 때 사용하는 자료를 공개합니다.


http://www.slideshare.net/junhoyoon3994


사실 보통 세미나에서 발표할 때 사용하는 1시간은 ngrinder 가 뭐고 어떤건지 정도 알아보는 시간밖에 않되는데요..


3시간쯤 세미나를 진행하여야, 혼란 없이 ngrinder 를 사용하여 unlimited 한 테스트를 수행하실 수 있습니다.


자료는 향후에도 조끔 더 보강될 겁니다. 소켓 테스트 같은 것을 추가할 예정입니다.

Posted by 윤준호

3.2.3 버전부터 nGrinder 는 스크립트에 파라미터를 전달할 수 있습니다.

image

테스트 설정 화면에는 Paramer 라는 입력 필드가 있는데, 여기에 스크립트에 전달할 파라미터를 넣게 되면, 스크립트에서 System.getProperty(“param”)이라는 명령으로 테스트에서 전달한 파라미터를 받아올 수 있습니다. 파라미터는 1~30 사이즈의 알파벳, 숫자, 언더바와 쉼표로만 구성할 수 있으며, 중간에 스페이스를 넣을 수는 없습니다.

스크립트에서 System.getProperty(“param”) 이라고 입력하게 되면, 테스트 설정화면에서 지정한 파라미터를 스트링 형태로 얻어올 수 있습니다. 이를 boolean 이나 integer 타입으로 변환하여야 한다면 스크립트에 직접 수행하여야 합니다. 그러나 스크립트 검증(Script Validation)을 수행할 때는 해당 스크립트가 어떤 테스트와 바인딩 된 상황이 아니기 때문에 널 값이 리턴됩니다. 따라서 이 문제를 회피하기 위해서는 System.getProperty(“param”, “defaultValue”) 와 같이 default 로 리턴될 값을 항상 지정해 주어야 합니다.

만약 ngrinder groovy 를 사용 중이고, 3.2.3 버전 이상의 ngrinder-groovy maven dependency를 갖도록 pom.xml 을 설정해 두셨다면 좀 더 편리한 유틸리티 클래스를 사용할 수 있습니다.

net.grinder.util.GrinderUtils 클래스는 다음과 같은 스태틱 메소드를 가지고 있습니다.

  • getParam()
  • getParam(defaultValue)
  • getParamInt()
  • getParamLong()
  • getParamFloat()
  • getParamDouble()
  • getParamBoolean()

이 메소드들은 System.getProperty(“param”)을 수행한 뒤에 필요한 지정한 타입으로 컨버팅을 수행합니다. 따라서 만약 나는 항상 숫자를 파라미터로 지정할 요량이면, GrinderUtils.getParamInt() 라고 호출하시면 Integer 형의 파라미터를 리턴해 줍니다. 단 스크립트 검증 단계에서는 0이 리턴됩니다.


// 아래 코드는 파라미터가 주어지지 않거나 0으로 호출될 때는 
// http://naver.com/helloworld 를 호출하고
// 1이 주어질 때는 http://naver.com/helloworld1 을 호출합니다.
def hello = GrinderUtils.getParamInt()
if (hello == 0) {
    HTTPResponse result = request.GET("http://naver.com/helloworld")
} else if (hello == 1) {
    HTTPResponse result = request.GET("http://naver.com/helloworld1")
}

파이선의 경우 이 클래스가 존재하지 않기 때문에 어쩔 수 없이 System.getProperty(“param”, “defaultValue”) 파라미터를 가져와서 직접 컨버팅 해야 합니다.

그리고 파라미터를 여러 개 전달해 줘야 하는 경우에는 어떻게 할까요? 다행히도 파라미터 스트링 내에 , 를 포함할 수 있으로, 파라미터를 스트링으로 가져온 후에 , 를 기준으로 Split 해서 직접 컨버팅 해야 합니다. 좀 복잡할 수 있습니다만 그닥 어렵진 않으므로 한번 처리해 보시기 바랍니다.

Posted by 윤준호

아래는 nGrinder 3.2.3 부터 제공되는 REST API에 대한 설명을 담고 있습니다. nGrinder 3.3 부터에서 제공되는 추가 REST API를 확인하고자 한다면 REST API 를 참고하시기 바랍니다.

3.2.3 버전부터 nGrinder 컨트롤러는 3개의 간단한 Web API를 제공합니다. nGrinder 사용자는 curl 같은 커멘드 라인도구를 사용하여 테스트 실행을 자동화 할 수 있습니다.

이 API 들은 HTTP Basic Auth 로 보호되고 있습니다. 따라서 반드시 ID 와 PW를 HTTP Basic Auth 형태로 제공하여야만 합니다.

기존 테스트를 복제하여 실행

이 API를 호출하기 위해서는 반드시 이전에 성공적으로 실행되었던 테스트가 있어야 합니다. 사용자는 간단한 Web API 호출을 통해, 이 테스트를 복제하여 새로운 테스트를 만들고 바로 시작할 수 있습니다.

http://host_name/perftest/api/{test_id_to_be_cloned}/cloneAndStart

이 API를 수행하면 다음과 같이 신규로 만들어진 테스트의 정보가 출력됩니다.

{
     "testName": "Test for www.yahoo.com",
     "tagString": "",
     "description": "",
     "status": "READY",
     "ignoreSampleCount": 0,
     "targetHosts": "www.yahoo.com",
     "useRampUp": false,
     "threshold": "D",
     "scriptName": "www.yahoo.com/src/main/java/TestRunner.groovy",
     "duration": 60000,
     "runCount": 0,
     "agentCount": 2,
     "vuserPerAgent": 1,
     "processes": 1,
     "initProcesses": 0,
     "initSleepTime": 0,
     "processIncrement": 1,
     "processIncrementInterval": 1000,
     "threads": 1,
     "testErrorCause": "UNKNOWN",
     "progressMessage": "",
     "testComment": "",
     "scriptRevision": 70,
     "region": "NONE",
     "samplingInterval": 2,
     "param": "",
     "createdDate": "Oct 8, 2013 12:20:01 AM",
     "lastModifiedDate": "Oct 8, 2013 12:20:01 AM",
     "id": 380
}

이 API를 호출할 때 다음 2개의 파라미터를 제공하면 테스트 설정을 약간 바꿔 복제할 수 있습니다.

  • agentCount : 이 테스트를 실행시킬 때 사용할 에이전트 개수를 지정합니다. 1 부터 최대 에이전트 제한 설정치사지만 설정 가능합니다.
  • scriptRevision=사용할 스크립트의 리비전을 지정합니다. 최신버전을 지정하고 싶다면 이 값을 제공하지 않거나, -1을 사용하면 됩니다.

예를 들어 다음과 같은 호출이 가능합니다.

http://host_name/perftest/api/11/cloneAndStart?agentCount=2

ID 값이 11인 테스트를 에이전트 2개로 설정하여 복제하고 실행하라.

jq(http://stedolan.github.io/jq/) 같은 커멘드 라인 기반 JSON 파서를 사용하면, API를 호출할 때 나오는 JSON 메시지를 쉽게 파싱 할 수 있습니다. 예를 들어 신규로 만들어진 테스트의 ID를 확인하고 싶으면 다음과 같이 호출하면 됩니다.

curl –u admin:admin –s http://host_name/perftest/api/123/cloneAndStart | jq “.id” 

기존 성능 테스트 정보 보기

기존 성능 테스트의 정보를 파악하고 싶다면 다음의 API를 호출하면 됩니다.

 http://host_name/perftest/api/{test_id}

{
     "testName": "Test for www.yahoo.com", 
     "tagString": "", 
     "description": "",
     "status": "CANCELED", 
     "ignoreSampleCount": 0,
     "startTime": "Sep 30, 2013 6:49:30 PM",
     "finishTime": "Sep 30, 2013 6:50:02 PM",
     "targetHosts": "www.yahoo.com",
     "useRampUp": false,
     "threshold": "D",
     "scriptName": "www.yahoo.com/src/main/java/TestRunner.groovy",
     "duration": 60000,
     "runCount": 0,
     "agentCount": 1,
     "vuserPerAgent": 1,
     "processes": 1,
     "initProcesses": 0,
     "initSleepTime": 0,
     "processIncrement": 1,
     "processIncrementInterval": 1000,
     "threads": 1,
     "tests": 11,
     "errors": 0,
     "meanTestTime": 2094.82,
     "tps": 0.46,
     "peakTps": 1.0,
     "testErrorCause": "UNKNOWN",
     "progressMessage": "
Console is being prepared.
Console is started on port 11104
1 agents are starting.
1 agents are ready.
All necessary files are being distributed.
- resource1.txt
- TestRunner.groovy
- logback-worker.xml
All necessary files are distributed.
The test is ready to start.
The test is started.
",
     "testComment": "",
     "scriptRevision": 70,
     "region": "NONE",
     "samplingInterval": 2,
     "param": "",
     "createdDate": "Sep 30, 2013 6:49:25 PM",
     "lastModifiedDate": "Sep 30, 2013 6:49:25 PM",
     "id": 376
}
마찬가지로 jq같은 도구를 사용하면 위 JSON 스트링에서 쉽게 정보를 뽑을 수 있습니다. 만약 테스트 123번의 에이전트 개수를 알고 싶다고 하면 다음과 같이 명령을 수행할 수 있습니다.
curl –u admin:admin –s http://host_name/perftest/api/123 | jq “.agentCount”

최신 성능 테스트 리스트 보기

사용자가 최신 성능 테스트 리스트를 확인하고자 하면 다음과 같은 형식으로 호출 가능합니다.

http://host_name/perftest/api/last?size=the_array_size

위의 size 파라미터를 제공하지 않는다면 JSON Array에 1개의 PerfTest 가 담긴 리스트를 리턴합니다. 위 호출은 유저가 볼 수 있는 성능 테스트중 최근 3개의 성능 테스트를 리턴합니다. 리턴되는 메시지는 JSON 배열 이기 때문에 앞선 방법과 마찬가지로 jq 를 사용하면 쉽게 정보를 뽑을 수 있습니다. 아래는 총 10개의 최신 테스트를 가져오고 그 중 4번째 항목의 에이전트 개수를 가져오는 명령입니다.

curl –u admin:admin –s http://host_name/perftest/api/last?size=10 | jq “.[4].agentCount”


Posted by 윤준호

간혹 nGrinder 테스트할 수 있는 범위가 HTTP로 제한된다고 생각하시는 분이 있습니다. 그러나 nGrinder 는 프로토콜과는 상관 없습니다. 테스트 하고자 하는 트랜잭션을 함수로 구현하고, 이 함수를 record 하기만 하면, 어떠한 프로토콜이든 테스트 가능합니다. 소켓에 직접 쓰기 읽기를 하는 경우도 마찬가지 입니다. 다음은 소켓을 열고, 데이터를 쓴 뒤, 응답을 읽어오고 소켓을 닫는 행위를 Jython 스크립트로 구현한 예입니다.

from net.grinder.script import Test
from net.grinder.plugin.http import HTTPRequest
from net.grinder.script.Grinder import grinder
import struct
import socket

class TestRunner:
    # initlialize a thread 
    def __init__(self):
        grinder.statistics.delayReports=True

    # 소켓을 열고 데이터를 쓰고 결과를 읽는 과정을 테스트로 구현합니다.
    def connection_test(self) :
        try:
            clientsock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            clientsock.connect(('10.10.10.01',8080))
            l_onoff = 1
            l_linger = 0
            # 아래 코드를 넣지 않으면 소켓 포트가 금방 소진됩니다.  
            # 소켓 close 시에 즉각 소켓을 반환하도록 링거 옵션을 부여합니다.
            clientsock.setsockopt(socket.SOL_SOCKET, socket.SO_LINGER, struct.pack('ii', l_onoff, l_linger))
            clientsock.send('{"...":1,"...":3400,"parameter":[]}')
            msg = clientsock.recv(128)
            return msg
        finally:
            clientsock.close()

    # test method        
    def __call__(self):
        try :
            msg = self.connection_test();
            if len(msg) == 0:
                grinder.logger.error("msg length==0")
                grinder.statistics.forLastTest.success = 0
            else :
                grinder.statistics.forLastTest.success = 1
        except socket.error, e:
            grinder.logger.error(str(e))
            grinder.statistics.forLastTest.success = 0
        #grinder.sleep(200)

# 트랜잭션으로 정의한 구문을 레코딩 합니다.
Test(1, "NNI-LookupServer Test").record(TestRunner.connection_test)
Posted by 윤준호

nGrinder는 여러개의 쓰레드를 포함하는 프로세스를 여러 에이전트에서 실행하여 성능 테스트를 수행합니다. 간혹 성능 테스트 요구사항 중에 캐시 효과를 제거하기 위해, 각 쓰레드 마다 다른 일을 시키게 하고 싶다는 요구가 있습니다. 보통 이와 같은 요구사항은 grinder.threadNumber 라는 API를 통해 현재 쓰레드 번호를 가져와서 해결하는 경우가 있는데요. 이 threadNumber 라는 게 각각의 프로세스마다 0부터 새로 부여되는 거라서, 테스트 설정시 지정한 쓰레드 개수 이상을 처리할 수 없습니다. 이때는 grinder.processNumber 와 grinder.threadNumber를 조합하여 신규로 어떠한 구분자를 생성해 내어야 하는데요. 다음을 이를 처리하는 방법을 설명합니다.

Groovy

def curNumber;

@BeforeThread
public void beforeThread() {
  // 에이전트당 프로세스 개수를 가져옵니다.
  int totalProcessCount = grinder.getProperties().getInt("grinder.processes", 1);
  // 프로세스당 쓰레드 개수를 가져옵니다.
  int totalThreadCount = grinder.getProperties().getInt("grinder.threads", 1);

  // 현재 이 쓰레드가 동작하는 에이전트의 번호를 가져옵니다.(0부터 시작)
  int agentNumber = grinder.agentNumber

  // 현재 이 쓰레드가 동작하는 프로세스의 번호를 가져옵니다.(0부터 시작)
  int processNumber = grinder.processNumber

  // 현재 이 쓰레드의 번호를 가져옵니다.
  int threadNumber = grinder.threadNumber
  
  // 현재 쓰레드의 Unique ID를 계산합니다.
  curNumber = (agentNumber * totalProcessCount * totalThreadCount)
               + (processNumber * totalThreadCount) + threadNumber;
  ....
}

@Test
public doTest() {
   //curNumber를 가지고 여러 가지 장난을 칩니다.
}

Python

class TestRunner:
    # initlialize a thread 
    def __init__(self):
        # 에이전트당 프로세스 개수를 가져옵니다.
        totalProcessCount = grinder.getProperties().getInt("grinder.processes", 1)
        # 프로세스당 쓰레드 개수를 가져옵니다.
        totalThreadCount = grinder.getProperties().getInt("grinder.threads", 1)
        # 현재 이 쓰레드가 동작하는 에이전트의 번호를 가져옵니다. (0부터 시작)
        agentNumber = grinder.agentNumber
        # 현재 이 쓰레디가 동작하는 프로세스의 번호를 가져옵니다. (0부터 시작)
        processNumber = grinder.processNumber
        # 현재 이 쓰레드의 번호를 가져옵니다.
        threadNumber = grinder.threadNumber
        # 현재 쓰레드의 Unique ID를 계산합니다.
        self.curNumber = (agentNumber * totalProcessCount * totalThreadCount) + 
                         (processNumber * totalThreadCount) + threadNumber;
        ....
    # test method       
    def __call__(self):
        print ("curNumber :") +  str(self.curNumber)
        #curNumber를 가지고 여러 가지 활용을 합니다.

 

위와 같은 코드를 사용하면, 각 쓰레드는 curNumber 에 전체 성능 테스트상에서 유일한 값을 가지게 됩니다. 예를 들어 에이전트가 2개, 프로세스가 2개, 쓰레드가 10개면, curNumber 는 0 부터 39 까지의 값을 가지게 됩니다. 그 값을 가지고 doTest 메소드에서 적절히 분기 처리해주면, 각 쓰레드는 완벽히 다른 일을 처리하게 됩니다.

Posted by 윤준호

이 가이드는 nGridner 3.2.1 부터 적용됩니다. 여기서 설명 드리는 부분을 적용하시기 위해서는 nGrinder 3.2.1로 업그레이드 하시기 바랍니다. 그리고 기존 버전에서 만들었던 Groovy 메이븐 프로젝트가 있다면, 해당 프로젝트내의 pom.xml 을 편집하시어 ngrinder-groovy 버전을 3.2 에서 3.2.1 로 업그레이드 하셔야 합니다.

nGrinder 3.2.1 부터는 Groovy Script 상에서 @RunRate 라는 어노테이션을 사용할 수 있습니다. 여러 테스트를 한번에 실행하여야 할 경우 각 테스트 메소드의 실행 비율을 조정하기 위해, 테스트 메소드에 이 어노테이션을 붙여주게 됩니다. @RunRate 어노테이션은 0부터 100까지 퍼센트 단위의 상수를 파라미터로 받습니다. 예를 들어 @RunRate(10)은 전체 테스트 실행 횟수 중 10% 에서만 실행하라는 의미입니다.

@RunRate(10)
@Test
public void doTest() {
   ... // This part will be executed only 10% of total runs
}

그런데 조심하셔야 할 것은 여기서 이야기한 10%는 다른 테스트 메소드에 어떤 @RunRate 값이 붙더라도 아무런 상관이 없다는 겁니다. 예를 들어 여기서 10%는 다른 테스트들을 90%를 실행하고 나머지 10%를 실행하라는 의미가 아닙니다. 단지 nGrinder 에이전트 쓰레드가 여러번 전체 테스트 메소드들을 반복 실행할 때, 그 실행 중 10% 에서만 실행됩니다. 즉 다른 테스트 메소드하고는 아무런 관련이 없습니다. 위 케이스 에서 만약 테스트 메소드가 1개 였 다면, 사실상 @RunRate 를 붙여주지 않는 것과 효과가 동일합니다. 왜냐하면 만약 테스트 설정시 100번 실행하도록 설정하였다면 90번 에서는 아무 일도 않하고 튕기고, 10번에만 위 테스트가 돌 것이기 때문이죠.

따라서 @RunRate 는 테스트가 2개 이상 일 때만 의미가 있습니다.

@RunWith(GrinderRunner)
class TestRunner {
    ...
    @RunRate(50)
    @Test
    void doTest1() {
           ...
    }
 
    @RunRate(20)
    @Test
    void doTest2() {
           ...
    }
}
위 스크립트 100회 테스트를 실행하셨다면 doTest1은 100번 중 50% 인 50번을 doTest2 는 100번 중 20%인 20번만 동작하게 됩니다. 실제로 각 쓰레드에서는 좀 더 정확히 말하자면 다음과 같이 수행합니다.
  • RUN 0 : None (아무것도 실행 안 함)
  • RUN 1 : doTest1()
  • RUN 2 : None
  • RUN 3 : doTest1()
  • RUN 4 : None
  • RUN 5 : doTest1(), doTest2()
  • RUN 6 : None
  • RUN 7 : doTest1()
  • RUN 8 : None
  • RUN 9 : doTest1()
  • RUN 10 : doTest2()

Groovy 메이븐 프로젝트의 경우, IDE 에서 테스트를 실행할 수 있습니다. 그러나 아시다시피 디폴트 JUnit은 단 1회만 실행하죠. 따라서 정확히 @RunRate 에 준 상수 비율대로 동작하는지 확인하기 까다롭습니다. 다행히도 nGrinder GroovyRunner 는 @Repeat 라는 클래스 레벨 어노테이션을 인식합니다. 스크립트 클래스 앞에 이 어노테이션을 붙이면, IGroovyRunner는 이를 인식하여 전체 테스트를 지정한 횟수만큼 반복 수행합니다. 이때 @RunRate 가 적용됩니다.

@Repeat(200)
@RunWith(GrinderRunner)
class TestRunner {
    ...
    @RunRate(50)
    @Test
    void doTest1() {
           ...
    }
 
    @RunRate(20)
    @Test
    void doTest2() {
           ...
    }
}

위 코드를 IDE JUnit Runner 로 실행하면, 총 200회 반복하되 doTest1()은 200회중 50% 즉 100번만 수행되고, doTest2()는 20% 즉 40회만 수행됩니다. @Repeat 어노테이션은 IDE 에서 JUnit Runner 를 사용하여 스크립트를 수행할 때만 인식됩니다. 즉 스크립트를 에이전트로 배포하거나 컨트롤러에서 검증 할 때는 적용되지 않습니다. 당연하겠죠? 

Posted by 윤준호

nGrinder 레코더는 내부 컴포넌트의 기능 제약으로 인해 윈도우즈에서 사용할 때만 그 풀 기능을 제공합니다. 리눅스나 맥 유저의 경우 일부 기능을 사용할 수 없기 때문에 약간의 추가 설정을 통해 우회하여 사용하여야 합니다. 맥과 리눅스에서는 내장 브라우저에서 크래시가 자주 발생하고 자체 인증서에 따른 경고를 무시할 수 없기 때문에 HTTPS 메시지를 레코딩 되지 않습니다. 따라서 자체 브라우저 대신에 별도의 브라우저(파이어 폭스나 사파리)를 사용하여 nGrinder 레코더의 프록시에 접근하여야 합니다. 다음은 어떻게 프록시를 설정하는지 설명합니다.

image

레코더를 시작하면 위와 같은 화면을 볼 수 있는데요. 여기에 프록시가 10288 에 설정되었음을 알 수 있습니다.

image

내장 브라우저 대신 파이어폭스를 사용하여 HTTP/HTTPS 를 레코딩 하기 원한다면, 파이어폭스를 먼저 여시고 Preference ==> Advanced ==> Settings 를 차례로 선택하셔야 합니다.

image

여기서 10288을 HTTP와 HTTPS 프락시로 설정합니다.

image

그런 다음에 파이어폭스로 웹사이트를 방문 해보세요. 물론 nGrinder 레코더에서 Start Recording 버튼을 누르시는 것을 잊지 마셔야 합니다.

image

그런 다음 Stop Recoring 버튼을 눌러 레코딩을 종료하세요. 그러면 현재까지 주고 받은 HTTP / HTTPS 메시지가 스크립트로 생성된 것을 볼 수 있습니다.

image

레코딩이 끝난뒤 부라우저의 프록시 셋팅을 해제하는 것을 잊지 마세요. 만약 그대로 놔둔다면 향후에는 인터넷 서핑을 할 수 없을지 모릅니다.

HTTPS 사이트를 돌아다니다 보면 다음과 같은 화면을 볼 수 있습니다. 이는 nGrinder 프록시가 사용하는 자체 인증서 때문에 생기는 문제인데요. 이 에러 메시지를 무시하기 위해서는 제일 아래의 “I Understand the Risks” 버튼을 클릭하여 예외를 추가하면 됩니다.

image

Posted by 윤준호

nGrinder 레코더는 유저의 브라우저 액션으로부터 nGrinder 스크립트를 생성해내는 헬퍼 어플리케이션 입니다. 브라우저로부터 보내진 HTTP / HTTPS 메시지를 레코딩 하여 The Grinder 에 호환되는 스크립트를 생성해냅니다. nGrinder 레코더는 The Grinder 에서 제공하는 TCPProxy 를 기반으로 개발되어 있습니다. TCPProxy는 상당히 파워풀한 레코딩 기능을 제공하나, 커멘드 라인 기반 도구로 제공되고 있어, 사용하기 좀 까다롭습니다. 그리고 생성된 스크립트도 상당히 장황한 편입니다. 따라서 nGrinder 개발팀은 내장된 브라우저와 java webstart 기술을 사용하여 새로운 nGrinder 레코더를 개발하였습니다. 사용자는 단지 몇 번의 클릭만으로 스크립트를 만들어 낼 수 있습니다.

저희는 nGrinder 레코더를 만드는 데 아주 큰 에너지를 투입하고 있진 않습니다. 저희는 사람이 직접 작성한 스크립트가 항상 생성한 스크립트 보다 더 낫다고 믿고 있습니다. 그래서 레코더를 완벽하고 에러 없이 릴리즈하려고 궂이 노력하지 않습니다. 그냥 사용 가능한 수준이면 된다고 믿고 있습니다.

image

Posted by 윤준호

만약 이미 nGrinder 레코더를 설치 한뒤 nGrinder 레코더 빨리 사용하기 대로 따라 해보셨다면, 아마도 생성된 스크립트가 너무 길어서 당황하셨을 겁니다. 이는 요즘은 브라우저로 일반적인 한 개의 웹 페이지를 보기만 해도 실제로 엄청난 량의 HTTP/HTTPS 호출이 일어나기 때문입니다. 이를 스크립트로 표현하려니 길어질 수 밖에요. 그런데 생성된 대부분의 HTTP 스크립트는 성능 테스트로 돌리기에 적합하지 않습니다.

대부분의 대규모 사이트들은 이미지나 자바스크립트 같은 정적 리소스들을 배포하기 위해 CDN (Content Delivery Network)를 사용합니다. CDN는 각 지역별로 서버를 분산시켜 저장하기 때문에 현재 어디에서 호출이 이뤄졌냐 에 따라 해당 위치에서 가장 빠른 서버가 해당 정적 리소스들을 서비스 하도록 고안되어 있습니다. 그리고 CDN은 충분히 높은 부하 상황에서도 잘 견딜 수 있도록 고안되어 있습니다. 또한 얼마나 많은 호출을 하였느냐에 따라 비용을 청구하는 것이 일반적입니다. 그럴 경우, 정적 리소스 다운로드를 성능 테스트에 포함시킬 이유가 있을까요? 돈이 많이 청구될 수 있기도 하고, 또 만약 CDN이 성능 문제가 있다 하더라도 개발자가 어떻게 할 방법이 없을 겁니다.

즉 개발자는 자신의 통제하에 있는 서버만을 대상으로 성능 테스트를 돌리고 싶을 겁니다. 그래서 nGrinder 레코더는 필요 없는 리소스들을 성능 테스트 레코딩 대상에서 제외하기 위해 필터링 기능을 제공합니다.

호스트명 필터링

nGrinder 레코더의 프록시는 현재 브라우저를 통해 접근 중인 웹 서버의 도메인 이름을 인식합니다. 그리고 해당 도메인을 향상 호출을 얼마나 레코딩 했는지 좌측 패널에 보여줍니다. 만약 아직 레코딩을 시작 않았다면 도메인명(호스트명) 좌측 R 컬럼에 0이 출력됩니다.

레코딩을 시작하게 되면 R 컬럼에 현재까지 레코딩한 메시지 개수가 표시됩니다. 좌측 패널에 실시간으로 추가되는 도메인명을 잘 살펴보시고, 불필요한 도메인으로 향하는 호출을 레코딩 대상에서 제외시킬 수 있습니다.

불필요한 도메인들을 제외시키는 가장 쉬운 방법은 먼저 아래쪽의 Unselect All 버튼을 눌러 모든 도메인을 필터링시킨 후 관심 있는 도메인만 다시 체크 하는 겁니다.

리소스 타입별 필터링

이미지 / css / 자바 스크립트 같은 정적 리소스의 경우 아주 간단히 필터링할 수 있습니다. 호스트명(도메인명) 기준 필터링 패널 아래쪽에 보시면 Recorded Type 이라는 체크박스 패널이 있습니다.

여기서 레코딩 할 필요가 없는 리소스 타입이 있다면 해당 체크를 풀어버립니다. 위 그림 우측과 같이 모든 리소스의 체크를 풀어버리면, URL 에 해당 리소스의 파일 확장자를 내포하고 있거나(예: .png) 아니면 리턴되는 응답의 Content Type 필드가 해당 리소스에 해당될 경우(예: 자바스크립트 : text/javascript) 해당 응답을 레코딩 하지 않습니다.

현재 레코딩을 진행하고 있는 중이라면, 현재 선택한 필터링 설정은 지금부터 진행되는 호출에만 적용됩니다.즉 기존 레코딩 분이 메모리에서 삭제되진 않습니다. 그러나 최종 스크립트 생성시에 한번 더 필터링 하게 되어 지정한 리소스 타입분만이 스크립트에 포함되게 됩니다.

레코딩 초기화

Reset 메뉴 아래의 “Clear all recording” 하위 메뉴를 선택하면 현재까지 레코딩 내역을 삭제할 수 있습니다.

그 외에도 여러 선택 가능한 하위 메뉴가 있는데, 각각의 기능은 다음과 같습니다.

하위 메뉴명 행위
Clear all recording 현재 레코딩된 메시지를 모두 삭제. 그러나 필터링 셋팅은 변경하지 않음.
Clear all filters 모든 필터를 삭제. 그러나 이미 레코딩된 메시지는 삭제하지 않음.
Clear connection count 모든 호출 횟수를 0으로 재셋팅
Reset browser cache 모든 브라우저 캐시를 삭제
Reset cookies 모든 브라우저 쿠키를 삭제

 

스크립트 생성

사용자가 “Stop Recording” 버튼을 클릭하면, nGrinder 레코더는 현재까지 레코딩된 HTTP/HTTPS 메시지들을 The Grinder 의 스크립트로 변환하여 출력합니다. nGrinder 레코더가 생성한 스크립트는 Grinder 가 제공하는 TCPProxy 의 생성 스크립트와는 약간 다른 형태를 띄고 있습니다.

여기서 “Stop Recording” 버튼을 클릭하는 것이 “Reset Recording”과는 다르다는 것을 기억해 주세요. “Stop Recording”이후에 “Start Recording”을 다시 클릭하면, nGrinder 레코더는 현재까지 레코딩한 내역 뒤에 추가하여 레코딩합니다. 스크립트 레코딩 시에는 다음과 같이 스크립트 생성에 관련한 몇 가지 옵션을 사용할 수 있습니다. 이에 대해 알아보도록 하죠.

Add sleep time

Add sleep time 을 체크하시게 되면, 각 호출간의 실제 레코딩 시간 간격만큼 sleep 시간이 부여됩니다. 예를 들어 레코딩 중 화장실에 다녀오셨다면 화장실에 다녀오신 만큼 sleep 이 추가 됩니다. 보통 다른 성능 테스트 도구에서는 이를 think time 이라 부릅니다. 그러나 think time은 스크립트 디버깅 측면에서는 쥐약입니다. 스크립트가 정확히 동작하는지 한번 실행해 보기 위해서는 화장실 다녀온 시간을 포함한 만큼 기다려야 결과를 볼 수 있기 때문입니다. 다행히도 위 sleep 메소드는 다음과 같이 구현되어 있습니다.

따라서 스크립트 디버깅 시에는 잠시 다음과 같이 커멘트 처리하면 스크립트 개발 속도가 빨라질 겁니다.

Follow Redirection

보통 웹을 개발하실 때 302 Redirection 을 리턴하기도 합니다. 브라우저가 http://url 을 접근했는데 서버가 http://url2 로 재접근하도록 명령을 내리는 거죠. nGrinder 는 디폴트 설정으로 HTTP Redirection을 따라가지 않도록 되어 있습니다. 즉 302 가 리턴되면, 302가 리턴 되었다고 확인하는 것이 끝이죠. 만약 nGrinder 레코더에서 이 명령을 따라 다른 URL로 재접근을 시도했으면, 302 리턴된 메시지를 레코딩 함과 동시에 재시도 행위도 추가로 레코딩 합니다. 만약 Follow Redirection 체크 박스를 선택하신 상태로 스크립트 생성을 하시게 된다면 다음과 같은 코드가 생성되면서 nGrinder HTTPRequest 객체는 Redirection을 따라가도록 설정됩니다.

Language

nGrinder 레코더 3.2 부터는 Groovy 스크립트로도 스크립트를 생성할 수 있습니다. 만약 Language 에 Groovy 를 선택하신뒤, 레코딩을 종료하시면 다음과 같은 스크립트가 생성됩니다.

@RunWith(GrinderRunner)
public class TestRunner {
    static def connectionDefaults = HTTPPluginControl.getConnectionDefaults()
    static def httpUtilities = HTTPPluginControl.getHTTPUtilities()
    static def logger = grinder.logger
    def result
    /** Requests */
    static def request_ad26_feeldmc_com = createRequest("http://ad26.feeldmc.com")
    static def request_lcs_naver_com = createRequest("http://lcs.naver.com")
    static def request_castbox_shopping_naver_com = createRequest("http://castbox.shopping.naver.com")
    static def request_www_naver_com = createRequest("http://www.naver.com")
    static def request_nv1_ad_naver_com = createRequest("http://nv1.ad.naver.com")
    static def request_nv2_ad_naver_com = createRequest("http://nv2.ad.naver.com")
    static def request_nv_ad_naver_com = createRequest("http://nv.ad.naver.com")
    static def request_ad02_coas2_co_kr = createRequest("http://ad02.coas2.co.kr")
    
    /** Tokens */
    def token_sl
    ...
    def token_p

    /** Common Headers */
    static NVPair[] headers0 = [
        new NVPair("Accept", "application/x-ms-application, image/jpeg, application/xaml+xml, image/gif, image/pjpeg, application/x-ms-xbap, application/msword, application/vnd.ms-powerpoint, application/vnd.ms-excel, */*"),
        new NVPair("Referer", "http://www.naver.com/"),
        new NVPair("Accept-Language", "ko,Korean;q=0.7,en-US;q=0.3"),
        new NVPair("User-Agent", "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64;; APCPMS=E839.353E.B2A0-win7^N20120502090046254556C65BBCE3E22DEE3F_4641^1^2^20490432^1594442250^30301500^200566000; Trident/6.0; TCO_20130530155944)")
    ]
    
    ...

    def pageTest1 = new GTest(1, "Test1")
        
    @BeforeProcess
    static void beforeProcess() {
        CookieModule.setCookiePolicyHandler(new MyCookiePolicyHandler())
        connectionDefaults.timeout = 600
        connectionDefaults.followRedirects = true
    }
    
    
    @BeforeThread
    void beforeThread() {
        grinder.statistics.delayReports=true
        // Instrument the pages
        pageTest1.record(this, new MethodNameFilter("page1"))
    }

    @Test
    void test() {
        page1()
    }

    def page1() {
        /***********************************************************************************************
         * http://lcs.naver.com/m
         ***********************************************************************************************/
        sleep(273)
        ....
        token_ls = "WRV6QHCKDHBU4"  
        result = request_lcs_naver_com.GET(
            "/m?u=$token_u&e=$token_e&i=$token_i&os=$token_os&ln=$token_ln&sr=$token_sr&bw=$token_bw&bh=$token_bh&c=$token_c&j=$token_j&jv=$token_jv&k=$token_k&fv=$token_fv&sl=$token_sl&ct=$token_ct&cta=$token_cta&p=$token_p&ls=$token_ls",
            null,    
            [
                new NVPair("Accept", "*/*"),
                new NVPair("Referer", "http://www.naver.com/"),
                new NVPair("Accept-Language", "ko,Korean;q=0.7,en-US;q=0.3"),
                new NVPair("User-Agent", "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64;; APCPMS=E839.353E.B2A0-win7^N20120502090046254556C65BBCE3E22DEE3F_4641^1^2^20490432^1594442250^30301500^200566000; Trident/6.0; TCO_20130530155944)")
            ] as NVPair[]
        ) 
        assertThat("http://lcs.naver.com should returns 200", result.statusCode, is(200))
        ...
      }
      ....
}

생성된 Groovy 스크립트를 Groovy 메이븐 프로젝트에 탑재하여 실행하게 되면, 생성된 스크립트를 디버깅 할 수 있습니다. 이에 대해서는 Groovy 메이븐 프로젝트 를 참고하시기 바랍니다.

Posted by 윤준호