diff --git a/.gitignore b/.gitignore index 97413ccd..e41edda5 100644 --- a/.gitignore +++ b/.gitignore @@ -1,10 +1,8 @@ -.project -.classpath -/.settings -/target -/Scripts -/report -/logs -/hs_err_pid45152.log -/hs_err_pid76832.log -/hs_err_pid86000.log +.classpath +.project +.settings/ +Scripts/ +*.log +logs/ +report/ +target/ \ No newline at end of file diff --git a/Bench4Q-Agent/ScenarioParameters/param1.txt b/Bench4Q-Agent/ScenarioParameters/param1.txt new file mode 100644 index 00000000..748dc5f7 --- /dev/null +++ b/Bench4Q-Agent/ScenarioParameters/param1.txt @@ -0,0 +1 @@ +row1;10;11~row2;20;21~row3,30,31~ \ No newline at end of file diff --git a/Bench4Q-Agent/Scripts/345376a7-d01c-4faa-af89-4a3e1a182048.xml b/Bench4Q-Agent/Scripts/345376a7-d01c-4faa-af89-4a3e1a182048.xml new file mode 100644 index 00000000..53e13dfa --- /dev/null +++ b/Bench4Q-Agent/Scripts/345376a7-d01c-4faa-af89-4a3e1a182048.xml @@ -0,0 +1,41 @@ + + + + + + + 1 + Get + + + url + http://www.baidu.com + + + + parameters + + + + http + + + -1 + 0 + -1 + + + 0 + + + http + Http + + + + timer + ConstantTimer + + + + \ No newline at end of file diff --git a/Bench4Q-Agent/Scripts/behaviorModel.xml b/Bench4Q-Agent/Scripts/behaviorModel.xml new file mode 100644 index 00000000..136480d0 --- /dev/null +++ b/Bench4Q-Agent/Scripts/behaviorModel.xml @@ -0,0 +1,17 @@ + + 0 + Get + + + url + http://133.133.12.3:8080/Bench4QTestCase/testcase.html + + + + parameters + + + + USERBEHAVIOR + http + \ No newline at end of file diff --git a/Bench4Q-Agent/Scripts/forGoodRecord.xml b/Bench4Q-Agent/Scripts/forGoodRecord.xml new file mode 100644 index 00000000..aeb6083b --- /dev/null +++ b/Bench4Q-Agent/Scripts/forGoodRecord.xml @@ -0,0 +1,2076 @@ + + + + + + + + + 0 + Get + + + url + http://133.133.12.2:8080/bench4q-web/homepage.jsp + + + + queryParams + + + + headers + header=Accept|value= + text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8|; + + + + USERBEHAVIOR + http + + + -1 + 0 + -1 + + + + + 0 + Sleep + + + time + 15 + + + TIMERBEHAVIOR + timer + + + -1 + 1 + -1 + + + + + 1 + Get + + + url + http://133.133.12.2:8080/bench4q-web/index.jsp + + + queryParams + + + + headers + header=Accept|value= + text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8|; + + + + USERBEHAVIOR + http + + + 4 + 2 + -1 + + + + + 0 + Sleep + + + time + 133 + + + TIMERBEHAVIOR + timer + + + -1 + 3 + -1 + + + + + 2 + Get + + + url + http://133.133.12.2:8080/bench4q-web/css/bootstrap-cerulean.css + + + + queryParams + + + + headers + header=Accept|value= + text/css,*/*;q=0.1|;header=Referer|value=http://133.133.12.2:8080/bench4q-web/index.jsp|; + + + + USERBEHAVIOR + http + + + 3 + Get + + + url + http://133.133.12.2:8080/bench4q-web/script/login.js + + + + queryParams + + + + headers + header=Accept|value= + */*|;header=Referer|value=http://133.133.12.2:8080/bench4q-web/index.jsp|; + + + + USERBEHAVIOR + http + + + 4 + Get + + + url + http://133.133.12.2:8080/bench4q-web/js/jquery-1.7.2.min.js + + + + queryParams + + + + headers + header=Accept|value= + */*|;header=Referer|value=http://133.133.12.2:8080/bench4q-web/index.jsp|; + + + + USERBEHAVIOR + http + + + 5 + Get + + + url + http://133.133.12.2:8080/bench4q-web/js/jquery.i18n.properties-1.0.9.js + + + + queryParams + + + + headers + header=Accept|value= + */*|;header=Referer|value=http://133.133.12.2:8080/bench4q-web/index.jsp|; + + + + USERBEHAVIOR + http + + + 6 + Get + + + url + http://133.133.12.2:8080/bench4q-web/css/charisma-app.css + + + + queryParams + + + + headers + header=Accept|value= + text/css,*/*;q=0.1|;header=Referer|value=http://133.133.12.2:8080/bench4q-web/index.jsp|; + + + + USERBEHAVIOR + http + + + -1 + 4 + 2 + + + + + 0 + Sleep + + + time + 1 + + + TIMERBEHAVIOR + timer + + + -1 + 5 + -1 + + + + + 0 + Sleep + + + time + 72 + + + TIMERBEHAVIOR + timer + + + -1 + 6 + -1 + + + + + 0 + Sleep + + + time + 24 + + + TIMERBEHAVIOR + timer + + + -1 + 7 + -1 + + + + + 0 + Sleep + + + time + 1 + + + TIMERBEHAVIOR + timer + + + -1 + 8 + -1 + + + + + 0 + Sleep + + + time + 211 + + + TIMERBEHAVIOR + timer + + + -1 + 9 + -1 + + + + + 7 + Get + + + url + http://fonts.googleapis.com/css + + + queryParams + family=Karla|Ubuntu + + + headers + header=Accept|value= + text/css,*/*;q=0.1|;header=Referer|value=http://133.133.12.2:8080/bench4q-web/index.jsp|; + + + + USERBEHAVIOR + http + + + -1 + 10 + -1 + + + + + 0 + Sleep + + + time + 3 + + + TIMERBEHAVIOR + timer + + + -1 + 11 + -1 + + + + + 8 + Get + + + url + http://fonts.googleapis.com/css + + + queryParams + family=Shojumaru + + + headers + header=Accept|value= + text/css,*/*;q=0.1|;header=Referer|value=http://133.133.12.2:8080/bench4q-web/index.jsp|; + + + + USERBEHAVIOR + http + + + -1 + 12 + -1 + + + + + 0 + Sleep + + + time + 82 + + + TIMERBEHAVIOR + timer + + + -1 + 13 + -1 + + + + + 9 + Get + + + url + http://133.133.12.2:8080/bench4q-web/img/glyphicons-halflings.png + + + + queryParams + + + + headers + header=Accept|value= + image/webp,*/*;q=0.8|;header=Referer|value=http://133.133.12.2:8080/bench4q-web/index.jsp|; + + + + USERBEHAVIOR + http + + + -1 + 14 + -1 + + + + + 0 + Sleep + + + time + 2 + + + TIMERBEHAVIOR + timer + + + -1 + 15 + -1 + + + + + 10 + Get + + + url + http://133.133.12.2:8080/bench4q-web/i18n/i18n.properties + + + + queryParams + _=1389777175541 + + + headers + header=Content-Type|value=text/plain;charset=UTF-8|;header=Accept|value= + text/plain, */*; + q=0.01|;header=Referer|value=http://133.133.12.2:8080/bench4q-web/index.jsp|; + + + + USERBEHAVIOR + http + + + -1 + 16 + -1 + + + + + 0 + Sleep + + + time + 10 + + + TIMERBEHAVIOR + timer + + + -1 + 17 + -1 + + + + + 11 + Get + + + url + http://133.133.12.2:8080/bench4q-web/i18n/i18n_zh.properties + + + + queryParams + _=1389777175572 + + + headers + header=Content-Type|value=text/plain;charset=UTF-8|;header=Accept|value= + text/plain, */*; + q=0.01|;header=Referer|value=http://133.133.12.2:8080/bench4q-web/index.jsp|; + + + + USERBEHAVIOR + http + + + -1 + 18 + -1 + + + + + 0 + Sleep + + + time + 8 + + + TIMERBEHAVIOR + timer + + + -1 + 19 + -1 + + + + + 12 + Get + + + url + http://133.133.12.2:8080/bench4q-web/i18n/i18n_zh-CN.properties + + + + queryParams + _=1389777175587 + + + headers + header=Content-Type|value=text/plain;charset=UTF-8|;header=Accept|value= + text/plain, */*; + q=0.01|;header=Referer|value=http://133.133.12.2:8080/bench4q-web/index.jsp|; + + + + USERBEHAVIOR + http + + + -1 + 20 + -1 + + + + + 0 + Sleep + + + time + 52 + + + TIMERBEHAVIOR + timer + + + -1 + 21 + -1 + + + + + 13 + Get + + + url + http://themes.googleusercontent.com/static/fonts/karla/v3/azR40LUJrT4HaWK28zHmVA.woff + + + + queryParams + + + + headers + header=Accept|value= + */*|;header=Referer|value=http://133.133.12.2:8080/bench4q-web/index.jsp|; + + + + USERBEHAVIOR + http + + + -1 + 22 + -1 + + + + + 0 + Sleep + + + time + 16442 + + + TIMERBEHAVIOR + timer + + + -1 + 23 + -1 + + + + + 14 + Get + + + url + http://themes.googleusercontent.com/static/fonts/ubuntu/v5/_xyN3apAT_yRRDeqB3sPRg.woff + + + + queryParams + + + + headers + header=Accept|value= + */*|;header=Referer|value=http://133.133.12.2:8080/bench4q-web/index.jsp|; + + + + USERBEHAVIOR + http + + + -1 + 24 + -1 + + + + + + + + + 0 + Sleep + + + time + 9 + + + TIMERBEHAVIOR + timer + + + 3 + 25 + -1 + + + + + 15 + Get + + + url + http://133.133.12.2:8080/bench4q-web/homepage.jsp + + + + queryParams + + + + headers + header=Accept|value= + text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8|;header=Referer|value=http://133.133.12.2:8080/bench4q-web/index.jsp|; + + + + USERBEHAVIOR + http + + + -1 + 26 + -1 + + + + + 0 + Sleep + + + time + 25 + + + TIMERBEHAVIOR + timer + + + -1 + 27 + -1 + + + + + 16 + Get + + + url + http://133.133.12.2:8080/bench4q-web/css/bootstrap-responsive.css + + + + queryParams + + + + headers + header=Accept|value= + text/css,*/*;q=0.1|;header=Referer|value=http://133.133.12.2:8080/bench4q-web/homepage.jsp|; + + + + USERBEHAVIOR + http + + + 17 + Get + + + url + http://133.133.12.2:8080/bench4q-web/css/noty_theme_default.css + + + + queryParams + + + + headers + header=Accept|value= + text/css,*/*;q=0.1|;header=Referer|value=http://133.133.12.2:8080/bench4q-web/homepage.jsp|; + + + + USERBEHAVIOR + http + + + 18 + Get + + + url + http://133.133.12.2:8080/bench4q-web/js/jquery-1.8.2.min.js + + + + queryParams + + + + headers + header=Accept|value= + */*|;header=Referer|value=http://133.133.12.2:8080/bench4q-web/homepage.jsp|; + + + + USERBEHAVIOR + http + + + 19 + Get + + + url + http://133.133.12.2:8080/bench4q-web/bench4q-css/bench4q.css + + + + queryParams + + + + headers + header=Accept|value= + text/css,*/*;q=0.1|;header=Referer|value=http://133.133.12.2:8080/bench4q-web/homepage.jsp|; + + + + USERBEHAVIOR + http + + + 20 + Get + + + url + http://133.133.12.2:8080/bench4q-web/css/jquery-ui-1.8.21.custom.css + + + + queryParams + + + + headers + header=Accept|value= + text/css,*/*;q=0.1|;header=Referer|value=http://133.133.12.2:8080/bench4q-web/homepage.jsp|; + + + + USERBEHAVIOR + http + + + 21 + Get + + + url + http://133.133.12.2:8080/bench4q-web/css/opa-icons.css + + + + queryParams + + + + headers + header=Accept|value= + text/css,*/*;q=0.1|;header=Referer|value=http://133.133.12.2:8080/bench4q-web/homepage.jsp|; + + + + USERBEHAVIOR + http + + + 22 + Get + + + url + http://133.133.12.2:8080/bench4q-web/css/colorbox.css + + + + queryParams + + + + headers + header=Accept|value= + text/css,*/*;q=0.1|;header=Referer|value=http://133.133.12.2:8080/bench4q-web/homepage.jsp|; + + + + USERBEHAVIOR + http + + + 23 + Get + + + url + http://133.133.12.2:8080/bench4q-web/js/jquery.cookie.js + + + + queryParams + + + + headers + header=Accept|value= + */*|;header=Referer|value=http://133.133.12.2:8080/bench4q-web/homepage.jsp|; + + + + USERBEHAVIOR + http + + + 24 + Get + + + url + http://133.133.12.2:8080/bench4q-web/js/jquery.dataTables.min.js + + + + queryParams + + + + headers + header=Accept|value= + */*|;header=Referer|value=http://133.133.12.2:8080/bench4q-web/homepage.jsp|; + + + + USERBEHAVIOR + http + + + 25 + Get + + + url + http://133.133.12.2:8080/bench4q-web/js/theme.js + + + queryParams + + + + headers + header=Accept|value= + */*|;header=Referer|value=http://133.133.12.2:8080/bench4q-web/homepage.jsp|; + + + + USERBEHAVIOR + http + + + 26 + Get + + + url + http://133.133.12.2:8080/bench4q-web/script/base.js + + + + queryParams + + + + headers + header=Accept|value= + */*|;header=Referer|value=http://133.133.12.2:8080/bench4q-web/homepage.jsp|; + + + + USERBEHAVIOR + http + + + 27 + Get + + + url + http://133.133.12.2:8080/bench4q-web/script/bench4q.table.js + + + + queryParams + + + + headers + header=Accept|value= + */*|;header=Referer|value=http://133.133.12.2:8080/bench4q-web/homepage.jsp|; + + + + USERBEHAVIOR + http + + + 28 + Get + + + url + http://133.133.12.2:8080/bench4q-web/script/loadTestPlans.js + + + + queryParams + + + + headers + header=Accept|value= + */*|;header=Referer|value=http://133.133.12.2:8080/bench4q-web/homepage.jsp|; + + + + USERBEHAVIOR + http + + + 29 + Get + + + url + http://133.133.12.2:8080/bench4q-web/script/scriptTable.js + + + + queryParams + + + + headers + header=Accept|value= + */*|;header=Referer|value=http://133.133.12.2:8080/bench4q-web/homepage.jsp|; + + + + USERBEHAVIOR + http + + + 30 + Get + + + url + http://133.133.12.2:8080/bench4q-web/js/jquery-ui-1.8.21.custom.min.js + + + + queryParams + + + + headers + header=Accept|value= + */*|;header=Referer|value=http://133.133.12.2:8080/bench4q-web/homepage.jsp|; + + + + USERBEHAVIOR + http + + + 31 + Get + + + url + http://133.133.12.2:8080/bench4q-web/img/bench4q.png + + + + queryParams + + + + headers + header=Accept|value= + image/webp,*/*;q=0.8|;header=Referer|value=http://133.133.12.2:8080/bench4q-web/homepage.jsp|; + + + + USERBEHAVIOR + http + + + 32 + Get + + + url + http://133.133.12.2:8080/bench4q-web/js/bootstrap-dropdown.js + + + + queryParams + + + + headers + header=Accept|value= + */*|;header=Referer|value=http://133.133.12.2:8080/bench4q-web/homepage.jsp|; + + + + USERBEHAVIOR + http + + + 36 + Get + + + url + http://133.133.12.2:8080/bench4q-web/script/home.js + + + + queryParams + + + + headers + header=Accept|value= + */*|;header=Referer|value=http://133.133.12.2:8080/bench4q-web/homepage.jsp|; + + + + USERBEHAVIOR + http + + + -1 + 28 + 0 + + + + + 0 + Sleep + + + time + 10 + + + TIMERBEHAVIOR + timer + + + -1 + 29 + -1 + + + + + 0 + Sleep + + + time + 25 + + + TIMERBEHAVIOR + timer + + + -1 + 30 + -1 + + + + + 0 + Sleep + + + time + 1 + + + TIMERBEHAVIOR + timer + + + -1 + 31 + -1 + + + + + 0 + Sleep + + + time + 4 + + + TIMERBEHAVIOR + timer + + + -1 + 32 + -1 + + + + + 0 + Sleep + + + time + 4 + + + TIMERBEHAVIOR + timer + + + -1 + 33 + -1 + + + + + 0 + Sleep + + + time + 0 + + + TIMERBEHAVIOR + timer + + + -1 + 34 + -1 + + + + + 0 + Sleep + + + time + 1 + + + TIMERBEHAVIOR + timer + + + -1 + 35 + -1 + + + + + 0 + Sleep + + + time + 6 + + + TIMERBEHAVIOR + timer + + + -1 + 36 + -1 + + + + + 0 + Sleep + + + time + 27 + + + TIMERBEHAVIOR + timer + + + -1 + 37 + -1 + + + + + 0 + Sleep + + + time + 9 + + + TIMERBEHAVIOR + timer + + + -1 + 38 + -1 + + + + + 0 + Sleep + + + time + 1 + + + TIMERBEHAVIOR + timer + + + -1 + 39 + -1 + + + + + 0 + Sleep + + + time + 0 + + + TIMERBEHAVIOR + timer + + + -1 + 40 + -1 + + + + + 0 + Sleep + + + time + 1 + + + TIMERBEHAVIOR + timer + + + -1 + 41 + -1 + + + + + 0 + Sleep + + + time + 36 + + + TIMERBEHAVIOR + timer + + + -1 + 42 + -1 + + + + + 0 + Sleep + + + time + 5 + + + TIMERBEHAVIOR + timer + + + -1 + 43 + -1 + + + + + 0 + Sleep + + + time + 1 + + + TIMERBEHAVIOR + timer + + + -1 + 44 + -1 + + + + + 0 + Sleep + + + time + 75 + + + TIMERBEHAVIOR + timer + + + -1 + 45 + -1 + + + + + 33 + Get + + + url + http://133.133.12.2:8080/bench4q-web/img/opa-icons-blue32.png + + + + queryParams + + + + headers + header=Accept|value= + image/webp,*/*;q=0.8|;header=Referer|value=http://133.133.12.2:8080/bench4q-web/homepage.jsp|; + + + + USERBEHAVIOR + http + + + -1 + 46 + -1 + + + + + 0 + Sleep + + + time + 30 + + + TIMERBEHAVIOR + timer + + + -1 + 47 + -1 + + + + + 34 + Get + + + url + http://133.133.12.2:8080/bench4q-web/img/opa-icons-color32.png + + + + queryParams + + + + headers + header=Accept|value= + image/webp,*/*;q=0.8|;header=Referer|value=http://133.133.12.2:8080/bench4q-web/homepage.jsp|; + + + + USERBEHAVIOR + http + + + -1 + 48 + -1 + + + + + 0 + Sleep + + + time + 27 + + + TIMERBEHAVIOR + timer + + + -1 + 49 + -1 + + + + + 35 + Get + + + url + http://133.133.12.2:8080/bench4q-web/img/opa-icons-red32.png + + + + queryParams + + + + headers + header=Accept|value= + image/webp,*/*;q=0.8|;header=Referer|value=http://133.133.12.2:8080/bench4q-web/homepage.jsp|; + + + + USERBEHAVIOR + http + + + -1 + 50 + -1 + + + + + 0 + Sleep + + + time + 1 + + + TIMERBEHAVIOR + timer + + + -1 + 51 + -1 + + + + + 0 + Sleep + + + time + 24 + + + TIMERBEHAVIOR + timer + + + -1 + 52 + -1 + + + + + 37 + Get + + + url + http://themes.googleusercontent.com/static/fonts/shojumaru/v2/pYVcIM206l3F7GUKEvtB3T8E0i7KZn-EPnyo3HZu7kw.woff + + + + queryParams + + + + headers + header=Accept|value= + */*|;header=Referer|value=http://133.133.12.2:8080/bench4q-web/index.jsp|; + + + + USERBEHAVIOR + http + + + -1 + 53 + -1 + + + + + 0 + Sleep + + + time + 145 + + + TIMERBEHAVIOR + timer + + + -1 + 54 + -1 + + + + + 38 + Get + + + url + http://133.133.12.2:8080/bench4q-web/img/opa-icons-green32.png + + + + queryParams + + + + headers + header=Accept|value= + image/webp,*/*;q=0.8|;header=Referer|value=http://133.133.12.2:8080/bench4q-web/homepage.jsp|; + + + + USERBEHAVIOR + http + + + -1 + 55 + -1 + + + + + 0 + Sleep + + + time + 1 + + + TIMERBEHAVIOR + timer + + + -1 + 56 + -1 + + + + + 39 + Get + + + url + http://133.133.12.2:8080/bench4q-web/i18n/i18n.properties + + + + queryParams + _=1389777196041 + + + headers + header=Content-Type|value=text/plain;charset=UTF-8|;header=Accept|value= + text/plain, */*; + q=0.01|;header=Referer|value=http://133.133.12.2:8080/bench4q-web/homepage.jsp|; + + + + USERBEHAVIOR + http + + + -1 + 57 + -1 + + + + + 0 + Sleep + + + time + 8 + + + TIMERBEHAVIOR + timer + + + -1 + 58 + -1 + + + + + 40 + Get + + + url + http://133.133.12.2:8080/bench4q-web/i18n/i18n_zh.properties + + + + queryParams + _=1389777196134 + + + headers + header=Content-Type|value=text/plain;charset=UTF-8|;header=Accept|value= + text/plain, */*; + q=0.01|;header=Referer|value=http://133.133.12.2:8080/bench4q-web/homepage.jsp|; + + + + USERBEHAVIOR + http + + + -1 + 59 + -1 + + + + + 0 + Sleep + + + time + 7 + + + TIMERBEHAVIOR + timer + + + -1 + 60 + -1 + + + + + 41 + Get + + + url + http://133.133.12.2:8080/bench4q-web/i18n/i18n_zh-CN.properties + + + + queryParams + _=1389777196150 + + + headers + header=Content-Type|value=text/plain;charset=UTF-8|;header=Accept|value= + text/plain, */*; + q=0.01|;header=Referer|value=http://133.133.12.2:8080/bench4q-web/homepage.jsp|; + + + + USERBEHAVIOR + http + + + -1 + 61 + -1 + + + + + 0 + Sleep + + + time + 163 + + + TIMERBEHAVIOR + timer + + + -1 + 62 + -1 + + + + + 42 + Post + + + url + http://133.133.12.2:8080/bench4q-web/loadTestPlans + + + + queryParams + + + + headers + header=Accept|value= application/json, text/javascript, + */*; + q=0.01|;header=Referer|value=http://133.133.12.2:8080/bench4q-web/homepage.jsp|; + + + + bodyparameters + + + + USERBEHAVIOR + http + + + -1 + 63 + -1 + + + + + 0 + Sleep + + + time + 1 + + + TIMERBEHAVIOR + timer + + + -1 + 64 + -1 + + + + + 43 + Post + + + url + http://133.133.12.2:8080/bench4q-web/loadScript + + + queryParams + + + + headers + header=Accept|value= application/json, text/javascript, + */*; + q=0.01|;header=Referer|value=http://133.133.12.2:8080/bench4q-web/homepage.jsp|; + + + + bodyparameters + + + + USERBEHAVIOR + http + + + -1 + 65 + -1 + + + + + 0 + Sleep + + + time + 27 + + + TIMERBEHAVIOR + timer + + + -1 + 66 + -1 + + + + + 44 + Get + + + url + http://133.133.12.2:8080/bench4q-web/img/glyphicons-halflings-white.png + + + + queryParams + + + + headers + header=Accept|value= + image/webp,*/*;q=0.8|;header=Referer|value=http://133.133.12.2:8080/bench4q-web/homepage.jsp|; + + + + USERBEHAVIOR + http + + + -1 + 67 + -1 + + + + + 0 + + + http + Http + + + + timer + ConstantTimer + + + + \ No newline at end of file diff --git a/Bench4Q-Agent/Scripts/goodForBatch.xml b/Bench4Q-Agent/Scripts/goodForBatch.xml new file mode 100644 index 00000000..8be2d6e7 --- /dev/null +++ b/Bench4Q-Agent/Scripts/goodForBatch.xml @@ -0,0 +1,146 @@ + + + + + + + 1 + Get + + + url + http://133.133.12.3:8080/Bench4QTestCase/testcase.html + + + + parameters + + + + http + + + 2 + 0 + -1 + + + + + 0 + Sleep + + + time + 2500 + + + timer + + + -1 + 1 + -1 + + + + + 3 + Get + + + url + http://133.133.12.3:8080/Bench4QTestCase/images/3.jpg + + + + parameters + + + + http + + + 4 + Get + + + url + http://133.133.12.3:8080/Bench4QTestCase/script/agentTable.js + + + + parameters + + + + http + + + 5 + Get + + + url + http://133.133.12.3:8080/Bench4QTestCase/script/base.js + + + + parameters + + + + http + + + 6 + Get + + + url + http://133.133.12.3:8080/Bench4QTestCase/images/1.jpg + + + + parameters + + + + http + + + 7 + Get + + + url + http://133.133.12.3:8080/Bench4QTestCase/images/2.jpg + + + + parameters + + + + http + + + -1 + 2 + 0 + + + 0 + + + http + Http + + + + timer + ConstantTimer + + + + \ No newline at end of file diff --git a/Bench4Q-Agent/Scripts/goodForPage.xml b/Bench4Q-Agent/Scripts/goodForPage.xml new file mode 100644 index 00000000..12cb22e0 --- /dev/null +++ b/Bench4Q-Agent/Scripts/goodForPage.xml @@ -0,0 +1,234 @@ + + + + + + + + + 0 + Get + + + url + + http://133.133.12.3:8080/Bench4QTestCase/testcase.html + + + + parameters + + + + USERBEHAVIOR + http + + + 2 + 0 + -1 + + + + + 0 + Sleep + + + time + 230 + + + TIMERBEHAVIOR + timer + + + -1 + 1 + -1 + + + + + 1 + Get + + + url + http://133.133.12.3:8080/Bench4QTestCase/script/agentTable.js + + + + parameters + + + + USERBEHAVIOR + http + + + 2 + Get + + + url + http://133.133.12.3:8080/Bench4QTestCase/images/3.jpg + + + + parameters + + + + USERBEHAVIOR + http + + + 3 + Get + + + url + http://133.133.12.3:8080/Bench4QTestCase/script/base.js + + + + parameters + + + + USERBEHAVIOR + http + + + 4 + Get + + + url + http://133.133.12.3:8080/Bench4QTestCase/images/1.jpg + + + + parameters + + + + USERBEHAVIOR + http + + + 5 + Get + + + url + http://133.133.12.3:8080/Bench4QTestCase/images/2.jpg + + + + parameters + + + + USERBEHAVIOR + http + + + -1 + 2 + 0 + + + + + 0 + Sleep + + + time + 96 + + + TIMERBEHAVIOR + timer + + + -1 + 3 + -1 + + + + + 0 + Sleep + + + time + 3 + + + TIMERBEHAVIOR + timer + + + -1 + 4 + -1 + + + + + 0 + Sleep + + + time + 10 + + + TIMERBEHAVIOR + timer + + + -1 + 5 + -1 + + + + + 0 + Sleep + + + time + 6 + + + TIMERBEHAVIOR + timer + + + -1 + 6 + -1 + + + + + 0 + + + http + Http + + + + timer + ConstantTimer + + + + \ No newline at end of file diff --git a/Bench4Q-Agent/Scripts/testJD.xml b/Bench4Q-Agent/Scripts/testJD.xml new file mode 100644 index 00000000..f8c2d673 --- /dev/null +++ b/Bench4Q-Agent/Scripts/testJD.xml @@ -0,0 +1,66 @@ + + + + + + + + + 0 + Get + + + url + + http://www.baidu.com + + + + parameters + + + + USERBEHAVIOR + http + + + 2 + 0 + -1 + + + + + 0 + Sleep + + + time + 230 + + + TIMERBEHAVIOR + timer + + + -1 + 1 + -1 + + + + + 0 + + + http + Http + + + + timer + ConstantTimer + + + + \ No newline at end of file diff --git a/Bench4Q-Agent/StorageTest/testInput.txt b/Bench4Q-Agent/StorageTest/testInput.txt new file mode 100644 index 00000000..785f1382 --- /dev/null +++ b/Bench4Q-Agent/StorageTest/testInput.txt @@ -0,0 +1 @@ +1Get1064text/html2013-12-16T10:01:02.620+08:00httpHttp6true2013-12-16T10:01:02.614+08:00200true \ No newline at end of file diff --git a/Bench4Q-Agent/StorageTest/test_123.txt b/Bench4Q-Agent/StorageTest/test_123.txt new file mode 100644 index 00000000..30d74d25 --- /dev/null +++ b/Bench4Q-Agent/StorageTest/test_123.txt @@ -0,0 +1 @@ +test \ No newline at end of file diff --git a/Bench4Q-Agent/configure/agent-config.properties b/Bench4Q-Agent/configure/agent-config.properties new file mode 100644 index 00000000..3c09e025 --- /dev/null +++ b/Bench4Q-Agent/configure/agent-config.properties @@ -0,0 +1,3 @@ +isToSaveDetailResult=false +servePort=6565 +userDefinedParamFolder=userDefinedParams \ No newline at end of file diff --git a/Bench4Q-Agent/descriptor.xml b/Bench4Q-Agent/descriptor.xml new file mode 100644 index 00000000..ca85606d --- /dev/null +++ b/Bench4Q-Agent/descriptor.xml @@ -0,0 +1,25 @@ + + + publish + + tar.gz + + false + + + lib + false + false + runtime + + + + + target/bench4q-agent.jar + / + + + \ No newline at end of file diff --git a/Bench4Q-Agent/pom.xml b/Bench4Q-Agent/pom.xml new file mode 100644 index 00000000..b08d984e --- /dev/null +++ b/Bench4Q-Agent/pom.xml @@ -0,0 +1,124 @@ + + 4.0.0 + org.bench4q + bench4q-agent + jar + 0.0.1-SNAPSHOT + Bench4Q Agent + Bench4Q Agent + + TCSE, ISCAS + + + + junit + junit + 4.11 + test + + + org.eclipse.jetty + jetty-server + 9.1.0.RC2 + + + org.eclipse.jetty + jetty-servlet + 9.1.0.RC2 + + + org.springframework + spring-webmvc + 3.2.4.RELEASE + + + org.codehaus.jackson + jackson-core-lgpl + 1.9.13 + + + org.codehaus.jackson + jackson-mapper-asl + 1.9.13 + + + org.apache.hadoop + hadoop-core + 1.1.2 + + + log4j + log4j + 1.2.17 + + + org.bench4q + bench4q-share + 0.0.1-SNAPSHOT + + + org.springframework + spring-core + 3.2.5.RELEASE + + + org.springframework + spring-test + 3.2.5.RELEASE + + + + commons-fileupload + commons-fileupload + 1.2 + + + + commons-io + commons-io + 2.4 + + + + + + maven-jar-plugin + + + + org.bench4q.agent.Main + true + lib/ + + + + + + maven-assembly-plugin + + + make-zip + package + + single + + + + descriptor.xml + + + + + + + org.apache.maven.plugins + maven-surefire-plugin + + true + + + + bench4q-agent + + \ No newline at end of file diff --git a/Bench4Q-Agent/src/main/java/org/bench4q/agent/AgentServer.java b/Bench4Q-Agent/src/main/java/org/bench4q/agent/AgentServer.java new file mode 100644 index 00000000..66a95382 --- /dev/null +++ b/Bench4Q-Agent/src/main/java/org/bench4q/agent/AgentServer.java @@ -0,0 +1,64 @@ +package org.bench4q.agent; + +import org.eclipse.jetty.server.Server; +import org.eclipse.jetty.servlet.ServletContextHandler; +import org.eclipse.jetty.servlet.ServletHolder; +import org.springframework.web.servlet.DispatcherServlet; + +public class AgentServer { + private Server server; + private int port; + + private Server getServer() { + return server; + } + + private void setServer(Server server) { + this.server = server; + } + + private int getPort() { + return port; + } + + private void setPort(int port) { + this.port = port; + } + + public AgentServer(int port) { + this.setPort(port); + } + + public boolean start() { + try { + this.setServer(new Server(this.getPort())); + ServletContextHandler servletContextHandler = new ServletContextHandler(); + ServletHolder servletHolder = servletContextHandler.addServlet( + DispatcherServlet.class, "/"); + servletHolder + .setInitParameter("contextConfigLocation", + "classpath*:/org/bench4q/agent/config/application-context.xml"); + servletHolder.setInitOrder(1); + this.getServer().setHandler(servletContextHandler); + this.getServer().start(); + return true; + } catch (Exception e) { + e.printStackTrace(); + return false; + } + } + + public boolean stop() { + try { + if (this.getServer() != null) { + this.getServer().stop(); + } + return true; + } catch (Exception e) { + e.printStackTrace(); + return false; + } finally { + this.setServer(null); + } + } +} diff --git a/Bench4Q-Agent/src/main/java/org/bench4q/agent/Main.java b/Bench4Q-Agent/src/main/java/org/bench4q/agent/Main.java new file mode 100644 index 00000000..45c45d7b --- /dev/null +++ b/Bench4Q-Agent/src/main/java/org/bench4q/agent/Main.java @@ -0,0 +1,86 @@ +package org.bench4q.agent; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.util.Properties; + +import org.apache.log4j.Logger; + +public class Main { + private static final String CONFIG_FILE_NAME = "agent-config.properties"; + private static String DIR_PATH = "configure" + + System.getProperty("file.separator"); + private static Logger logger = Logger.getLogger(Main.class); + private static int PORT_TO_SERVE; + public static boolean IS_TO_SAVE_DETAIL; + public static String USER_DEFINED_PARAMS_FOLDER; + + static { + init(); + } + + public static void main(String[] args) { + AgentServer agentServer = new AgentServer(PORT_TO_SERVE); + agentServer.start(); + } + + public static void init() { + guardConfigureExists(); + initProperties(); + } + + private static void guardConfigureExists() { + File dirFile = new File(DIR_PATH); + if (!dirFile.exists()) { + dirFile.mkdirs(); + } + File configFile = new File(DIR_PATH + CONFIG_FILE_NAME); + if (!configFile.exists()) { + createDefaultConfig(configFile); + } + } + + private static void createDefaultConfig(File configFile) { + try { + if (configFile.createNewFile()) { + FileOutputStream outputStream = new FileOutputStream(configFile); + String content = "isToSaveDetailResult=false" + "\n" + + "servePort=6565" + "\n" + + "userDefinedParamFolder=userDefinedParams"; + outputStream.write(content.getBytes()); + outputStream.flush(); + outputStream.close(); + } + } catch (Exception e) { + } + } + + private static void initProperties() { + try { + FileInputStream inputStream = new FileInputStream(new File(DIR_PATH + + CONFIG_FILE_NAME)); + Properties properties = new Properties(); + properties.load(inputStream); + PORT_TO_SERVE = Integer.parseInt((String) properties + .get("servePort")); + IS_TO_SAVE_DETAIL = Boolean.parseBoolean((String) properties + .get("isToSaveDetailResult")); + USER_DEFINED_PARAMS_FOLDER = properties + .getProperty("userDefinedParamFolder"); + guardUserDefinedFolderExists(); + } catch (IOException e) { + logger.error("There is an error when getPortToServe!"); + } + } + + private static void guardUserDefinedFolderExists() { + File dirFile = new File(USER_DEFINED_PARAMS_FOLDER + + System.getProperty("file.separator")); + if (!dirFile.exists()) { + dirFile.mkdirs(); + } + } + +} diff --git a/Bench4Q-Agent/src/main/java/org/bench4q/agent/api/HomeController.java b/Bench4Q-Agent/src/main/java/org/bench4q/agent/api/HomeController.java new file mode 100644 index 00000000..22d6d739 --- /dev/null +++ b/Bench4Q-Agent/src/main/java/org/bench4q/agent/api/HomeController.java @@ -0,0 +1,49 @@ +package org.bench4q.agent.api; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; + +import org.bench4q.agent.scenario.ScenarioContext; +import org.bench4q.agent.scenario.ScenarioEngine; +import org.bench4q.share.models.agent.ServerStatusModel; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.ResponseBody; + +@Controller +@RequestMapping("/") +public class HomeController { + private ScenarioEngine scenarioEngine; + + private ScenarioEngine getScenarioEngine() { + return scenarioEngine; + } + + @Autowired + private void setScenarioEngine(ScenarioEngine scenarioEngine) { + this.scenarioEngine = scenarioEngine; + } + + @RequestMapping(method = { RequestMethod.GET, RequestMethod.POST }) + @ResponseBody + public ServerStatusModel index() { + ServerStatusModel serverStatusModel = new ServerStatusModel(); + serverStatusModel.setFinishedTests(new ArrayList()); + serverStatusModel.setRunningTests(new ArrayList()); + Map contexts = new HashMap( + getScenarioEngine().getRunningTests()); + for (UUID key : contexts.keySet()) { + ScenarioContext value = contexts.get(key); + if (value.isFinished()) { + serverStatusModel.getFinishedTests().add(key); + } else { + serverStatusModel.getRunningTests().add(key); + } + } + return serverStatusModel; + } +} diff --git a/Bench4Q-Agent/src/main/java/org/bench4q/agent/api/PluginController.java b/Bench4Q-Agent/src/main/java/org/bench4q/agent/api/PluginController.java new file mode 100644 index 00000000..f903984b --- /dev/null +++ b/Bench4Q-Agent/src/main/java/org/bench4q/agent/api/PluginController.java @@ -0,0 +1,81 @@ +package org.bench4q.agent.api; + +import java.util.ArrayList; +import java.util.List; + +import org.bench4q.agent.plugin.BehaviorInfo; +import org.bench4q.agent.plugin.ParameterInfo; +import org.bench4q.agent.plugin.PluginInfo; +import org.bench4q.agent.plugin.PluginManager; +import org.bench4q.share.models.agent.BehaviorInfoModel; +import org.bench4q.share.models.agent.ParameterInfoModel; +import org.bench4q.share.models.agent.PluginInfoListModel; +import org.bench4q.share.models.agent.PluginInfoModel; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.ResponseBody; + +@Controller +@RequestMapping("/plugin") +public class PluginController { + private PluginManager pluginManager; + + public PluginManager getPluginManager() { + return pluginManager; + } + + @Autowired + public void setPluginManager(PluginManager pluginManager) { + this.pluginManager = pluginManager; + } + + @RequestMapping(method = RequestMethod.GET) + @ResponseBody + public PluginInfoListModel list() { + List pluginInfos = this.getPluginManager().getPluginInfo(); + PluginInfoListModel pluginInfoListModel = new PluginInfoListModel(); + pluginInfoListModel.setPlugins(new ArrayList()); + for (PluginInfo pluginInfo : pluginInfos) { + PluginInfoModel pluginInfoModel = buildPluginInfoModel(pluginInfo); + pluginInfoListModel.getPlugins().add(pluginInfoModel); + } + return pluginInfoListModel; + } + + private PluginInfoModel buildPluginInfoModel(PluginInfo pluginInfo) { + PluginInfoModel pluginInfoModel = new PluginInfoModel(); + pluginInfoModel.setName(pluginInfo.getName()); + pluginInfoModel.setParameters(new ArrayList()); + for (ParameterInfo param : pluginInfo.getParameters()) { + ParameterInfoModel model = buildParameterInfoModel(param); + pluginInfoModel.getParameters().add(model); + } + pluginInfoModel.setBehaviors(new ArrayList()); + for (BehaviorInfo behaviorInfo : pluginInfo.getBehaviors()) { + BehaviorInfoModel behaviorInfoModel = buildBehaviorInfoModel(behaviorInfo); + pluginInfoModel.getBehaviors().add(behaviorInfoModel); + } + return pluginInfoModel; + } + + private BehaviorInfoModel buildBehaviorInfoModel(BehaviorInfo behaviorInfo) { + BehaviorInfoModel behaviorInfoModel = new BehaviorInfoModel(); + behaviorInfoModel.setName(behaviorInfo.getName()); + behaviorInfoModel.setParameters(new ArrayList()); + for (ParameterInfo param : behaviorInfo.getParameters()) { + ParameterInfoModel model = buildParameterInfoModel(param); + behaviorInfoModel.getParameters().add(model); + } + return behaviorInfoModel; + } + + private ParameterInfoModel buildParameterInfoModel(ParameterInfo param) { + ParameterInfoModel model = new ParameterInfoModel(); + model.setName(param.getName()); + model.setType(param.getType()); + return model; + } + +} diff --git a/Bench4Q-Agent/src/main/java/org/bench4q/agent/api/TestController.java b/Bench4Q-Agent/src/main/java/org/bench4q/agent/api/TestController.java new file mode 100644 index 00000000..736b1032 --- /dev/null +++ b/Bench4Q-Agent/src/main/java/org/bench4q/agent/api/TestController.java @@ -0,0 +1,290 @@ +package org.bench4q.agent.api; + +import java.net.UnknownHostException; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; +import java.util.Map; +import java.util.UUID; + +import org.apache.log4j.Logger; +import org.bench4q.agent.datacollector.impl.BehaviorStatusCodeResult; +import org.bench4q.agent.parameterization.ParameterFileCollector; +import org.bench4q.agent.scenario.Scenario; +import org.bench4q.agent.scenario.ScenarioContext; +import org.bench4q.agent.scenario.ScenarioEngine; +import org.bench4q.agent.scenario.behavior.Behavior; +import org.bench4q.share.helper.MarshalHelper; +import org.bench4q.share.models.agent.BehaviorBriefModel; +import org.bench4q.share.models.agent.BehaviorStatusCodeResultModel; +import org.bench4q.share.models.agent.CleanTestResultModel; +import org.bench4q.share.models.agent.RunScenarioModel; +import org.bench4q.share.models.agent.RunScenarioResultModel; +import org.bench4q.share.models.agent.StopTestModel; +import org.bench4q.share.models.agent.TestBriefStatusModel; +import org.bench4q.share.models.agent.statistics.AgentBriefStatusModel; +import org.bench4q.share.models.agent.statistics.AgentBehaviorsBriefModel; +import org.bench4q.share.models.agent.statistics.AgentPageBriefModel; +import org.bench4q.share.models.agent.statistics.AgentPagesBriefModel; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.multipart.MultipartFile; + +@Controller +@RequestMapping("/test") +public class TestController { + private ScenarioEngine scenarioEngine; + private ParameterFileCollector paramFileCollector; + private Logger logger = Logger.getLogger(TestController.class); + + private Logger getLogger() { + return logger; + } + + private ScenarioEngine getScenarioEngine() { + return scenarioEngine; + } + + @Autowired + private void setScenarioEngine(ScenarioEngine scenarioEngine) { + this.scenarioEngine = scenarioEngine; + } + + private ParameterFileCollector getParamFileCollector() { + return paramFileCollector; + } + + @Autowired + private void setParamFileCollector(ParameterFileCollector paramFileCollector) { + this.paramFileCollector = paramFileCollector; + } + + @RequestMapping(value = "/submitScenarioWithParams", method = RequestMethod.POST) + @ResponseBody + public String submitParams( + @RequestParam("files[]") List files, + @RequestParam("scenarioModel") String scenarioModel) { + try { + UUID runId = UUID.randomUUID(); + this.getParamFileCollector().collectParamFiles(files, runId); + System.out.println(scenarioModel); + RunScenarioModel runScenarioModel = (RunScenarioModel) MarshalHelper + .unmarshal(RunScenarioModel.class, scenarioModel); + + this.getScenarioEngine().submitScenario(runId, + Scenario.scenarioBuilder(runScenarioModel), + runScenarioModel.getPoolSize()); + return MarshalHelper.tryMarshal(buildWith(runId)); + } catch (Exception e) { + logger.error("/submitScenarioWithParams", e); + return null; + } + } + + private RunScenarioResultModel buildWith(UUID runId) { + RunScenarioResultModel result = new RunScenarioResultModel(); + result.setRunId(runId); + return result; + } + + @RequestMapping(value = "/runWithParams/{runId}", method = RequestMethod.POST) + @ResponseBody + public RunScenarioResultModel runWithParams(@PathVariable UUID runId) { + return this.getScenarioEngine().runWith(runId) ? buildWith(runId) + : null; + } + + @RequestMapping(value = "/runWithoutParams", method = RequestMethod.POST) + @ResponseBody + public RunScenarioResultModel run( + @RequestBody RunScenarioModel runScenarioModel) + throws UnknownHostException { + Scenario scenario = Scenario.scenarioBuilder(runScenarioModel); + UUID runId = UUID.randomUUID(); + System.out.println(runScenarioModel.getPoolSize()); + this.getLogger().info(MarshalHelper.tryMarshal(runScenarioModel)); + if (runScenarioModel.getPoolSize() <= 0) { + logger.info("This RunScenarioModel's pool size is L.E zero, so throw out"); + return null; + } + this.getScenarioEngine().submitScenario(runId, scenario, + runScenarioModel.getPoolSize()); + + this.getScenarioEngine().runWith(runId); + RunScenarioResultModel runScenarioResultModel = new RunScenarioResultModel(); + runScenarioResultModel.setRunId(runId); + return runScenarioResultModel; + } + + @RequestMapping(value = "/briefAll/{runId}", method = RequestMethod.GET) + @ResponseBody + public TestBriefStatusModel briefAll(@PathVariable UUID runId) { + TestBriefStatusModel result = new TestBriefStatusModel(); + result.setScenarioBriefModel(this.brief(runId)); + result.setPagesBriefModel(this.pagesBrief(runId)); + result.setBehaviorsBriefModel(this.behaviorsBrief(runId)); + return result; + } + + @RequestMapping(value = "/brief/{runId}/{behaviorId}", method = RequestMethod.GET) + @ResponseBody + public BehaviorBriefModel behaviorBrief(@PathVariable UUID runId, + @PathVariable int behaviorId) { + ScenarioContext scenarioContext = this.getScenarioEngine() + .getRunningTests().get(runId); + if (scenarioContext == null) { + return null; + } + Map map = scenarioContext + .getDataStatistics().getBehaviorBriefStatistics(behaviorId); + return buildBehaviorBrief(runId, behaviorId, "", map); + } + + private BehaviorBriefModel buildBehaviorBrief(UUID runId, int behaviorId, + String behaviorUrl, Map map) { + List detailStatusCodeResultModels = new ArrayList(); + for (int statusCode : map.keySet()) { + BehaviorStatusCodeResultModel behaviorStatusCodeResultModel = new BehaviorStatusCodeResultModel(); + BehaviorStatusCodeResult detailStatusCodeResult = map + .get(statusCode); + behaviorStatusCodeResultModel.setStatusCode(statusCode); + behaviorStatusCodeResultModel + .setCount(detailStatusCodeResult.count); + behaviorStatusCodeResultModel + .setContentLength(detailStatusCodeResult.contentLength); + behaviorStatusCodeResultModel + .setMinResponseTime(detailStatusCodeResult.minResponseTime); + behaviorStatusCodeResultModel + .setMaxResponseTime(detailStatusCodeResult.maxResponseTime); + behaviorStatusCodeResultModel + .setContentType(detailStatusCodeResult.contentType); + behaviorStatusCodeResultModel + .setTotalResponseTimeThisTime(detailStatusCodeResult.totalResponseTimeThisTime); + detailStatusCodeResultModels.add(behaviorStatusCodeResultModel); + } + BehaviorBriefModel behaviorBriefModel = new BehaviorBriefModel(); + behaviorBriefModel.setBehaviorId(behaviorId); + behaviorBriefModel + .setDetailStatusCodeResultModels(detailStatusCodeResultModels); + behaviorBriefModel.setBehaviorUrl(behaviorUrl); + return behaviorBriefModel; + } + + @RequestMapping(value = "/pagesBrief/{runId}") + @ResponseBody + public AgentPagesBriefModel pagesBrief(@PathVariable UUID runId) { + ScenarioContext context = this.getScenarioEngine().getRunningTests() + .get(runId); + AgentPagesBriefModel result = new AgentPagesBriefModel(); + List pageBrieves = new ArrayList(); + + if (context == null || context.isFinished()) { + return null; + } + for (int i = 0; i < context.getScenario().getPages().length; i++) { + pageBrieves.add((AgentPageBriefModel) context.getDataStatistics() + .getPageBriefStatistics(i)); + } + result.setPageBriefModels(pageBrieves); + return result; + } + + @RequestMapping(value = "/pageBrief/{runId}/{pageId}") + @ResponseBody + public AgentPageBriefModel pageBrief(@PathVariable UUID runId, + @PathVariable int pageId) { + ScenarioContext context = this.getScenarioEngine().getRunningTests() + .get(runId); + if (context == null || context.isFinished()) { + return null; + } + return (AgentPageBriefModel) context.getDataStatistics() + .getPageBriefStatistics(pageId); + } + + @RequestMapping(value = "/behaviorsBrief/{runId}") + @ResponseBody + public AgentBehaviorsBriefModel behaviorsBrief(@PathVariable UUID runId) { + AgentBehaviorsBriefModel ret = new AgentBehaviorsBriefModel(); + List behaviorBriefModels = new ArrayList(); + ScenarioContext scenarioContext = this.getScenarioEngine() + .getRunningTests().get(runId); + if (scenarioContext == null || scenarioContext.isFinished()) { + return null; + } + for (Behavior behavior : scenarioContext.getScenario() + .getAllBehaviorsInScenario()) { + int behaviorId = behavior.getId(); + Map map = behavior + .getBehaviorBriefResult(scenarioContext.getDataStatistics()); + if (map == null) { + continue; + } + behaviorBriefModels.add(buildBehaviorBrief(runId, behaviorId, + behavior.getUrl(), map)); + } + ret.setBehaviorBriefModels(behaviorBriefModels); + return ret; + } + + @RequestMapping(value = "/brief/{runId}", method = RequestMethod.GET) + @ResponseBody + public AgentBriefStatusModel brief(@PathVariable UUID runId) { + ScenarioContext scenarioContext = this.getScenarioEngine() + .getRunningTests().get(runId); + if (scenarioContext == null) { + return null; + } + AgentBriefStatusModel agentStatusModel = (AgentBriefStatusModel) scenarioContext + .getDataStatistics().getScenarioBriefStatistics(); + agentStatusModel.setvUserCount(scenarioContext.getExecutor() + .getActiveCount()); + return agentStatusModel; + } + + @RequestMapping(value = "/stop/{runId}", method = { RequestMethod.GET, + RequestMethod.POST }) + @ResponseBody + public StopTestModel stop(@PathVariable UUID runId) { + System.out.println("stop method"); + ScenarioContext scenarioContext = this.getScenarioEngine() + .getRunningTests().get(runId); + if (scenarioContext == null) { + return null; + } + scenarioContext.setEndDate(new Date(System.currentTimeMillis())); + System.out.println("when before stop, classId:" + + scenarioContext.getExecutor().toString()); + scenarioContext.getExecutor().shutdown(); + scenarioContext.getExecutor().shutdownNow(); + System.out.println("when after stop, classId:" + + scenarioContext.getExecutor().toString()); + scenarioContext.setFinished(true); + StopTestModel stopTestModel = new StopTestModel(); + stopTestModel.setSuccess(true); + clean(runId); + return stopTestModel; + } + + @RequestMapping(value = "/clean/{runId}", method = RequestMethod.GET) + @ResponseBody + public CleanTestResultModel clean(@PathVariable UUID runId) { + ScenarioContext scenarioContext = this.getScenarioEngine() + .getRunningTests().get(runId); + if (scenarioContext == null) { + return null; + } + scenarioContext.getExecutor().shutdownNow(); + this.getScenarioEngine().getRunningTests().remove(runId); + System.gc(); + CleanTestResultModel cleanTestResultModel = new CleanTestResultModel(); + cleanTestResultModel.setSuccess(true); + return cleanTestResultModel; + } +} diff --git a/Bench4Q-Agent/src/main/java/org/bench4q/agent/datacollector/DataCollector.java b/Bench4Q-Agent/src/main/java/org/bench4q/agent/datacollector/DataCollector.java new file mode 100644 index 00000000..94c13c9f --- /dev/null +++ b/Bench4Q-Agent/src/main/java/org/bench4q/agent/datacollector/DataCollector.java @@ -0,0 +1,20 @@ +package org.bench4q.agent.datacollector; + +import java.util.Map; + +import org.bench4q.agent.datacollector.impl.BehaviorStatusCodeResult; +import org.bench4q.agent.scenario.BehaviorResult; +import org.bench4q.agent.scenario.PageResult; + +public interface DataCollector { + public void add(BehaviorResult behaviorResult); + + public void add(PageResult pageResult); + + public Object getScenarioBriefStatistics(); + + public Map getBehaviorBriefStatistics( + int behaviorId); + + public Object getPageBriefStatistics(int pageId); +} diff --git a/Bench4Q-Agent/src/main/java/org/bench4q/agent/datacollector/impl/AbstractDataCollector.java b/Bench4Q-Agent/src/main/java/org/bench4q/agent/datacollector/impl/AbstractDataCollector.java new file mode 100644 index 00000000..e14a0b75 --- /dev/null +++ b/Bench4Q-Agent/src/main/java/org/bench4q/agent/datacollector/impl/AbstractDataCollector.java @@ -0,0 +1,82 @@ +package org.bench4q.agent.datacollector.impl; + +import java.util.Map; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; + +import org.bench4q.agent.Main; +import org.bench4q.agent.datacollector.DataCollector; +import org.bench4q.agent.helper.ApplicationContextHelper; +import org.bench4q.agent.scenario.BehaviorResult; +import org.bench4q.agent.storage.StorageHelper; +import org.bench4q.share.models.agent.BehaviorResultModel; + +public abstract class AbstractDataCollector implements DataCollector { + protected StorageHelper storageHelper; + + protected StorageHelper getStorageHelper() { + return storageHelper; + } + + public void setStorageHelper(StorageHelper storageHelper) { + this.storageHelper = storageHelper; + } + + public AbstractDataCollector() { + mustDoWhenIniti(); + } + + // Each sub class should call this in their constructor + protected void mustDoWhenIniti() { + this.setStorageHelper(ApplicationContextHelper.getContext().getBean( + StorageHelper.class)); + } + + public void add(final BehaviorResult behaviorResult) { + if (!Main.IS_TO_SAVE_DETAIL) { + return; + } + if (behaviorResult == null) { + return; + } + Runnable runnable = new Runnable() { + public void run() { + storageHelper.getLocalStorage().writeFile( + buildBehaviorResultModel(behaviorResult) + .getModelString(), + calculateSavePath(behaviorResult)); + } + }; + ExecutorService executorService = Executors + .newSingleThreadScheduledExecutor(); + executorService.execute(runnable); + executorService.shutdown(); + } + + private BehaviorResultModel buildBehaviorResultModel( + BehaviorResult behaviorResult) { + BehaviorResultModel resultModel = new BehaviorResultModel(); + resultModel.setBehaviorId(behaviorResult.getBehaviorId()); + resultModel.setBehaviorName(behaviorResult.getBehaviorName()); + resultModel.setContentLength(behaviorResult.getContentLength()); + resultModel.setContentType(behaviorResult.getContentType()); + resultModel.setEndDate(behaviorResult.getEndDate()); + resultModel.setPluginId(behaviorResult.getPluginId()); + resultModel.setPluginName(behaviorResult.getPluginName()); + resultModel.setResponseTime(behaviorResult.getResponseTime()); + resultModel.setShouldBeCountResponseTime(behaviorResult + .isShouldBeCountResponseTime()); + resultModel.setStartDate(behaviorResult.getStartDate()); + resultModel.setStatusCode(behaviorResult.getStatusCode()); + resultModel.setSuccess(behaviorResult.isSuccess()); + return resultModel; + } + + protected abstract String calculateSavePath(BehaviorResult behaviorResult); + + public abstract Object getScenarioBriefStatistics(); + + public abstract Map getBehaviorBriefStatistics( + int id); + +} diff --git a/Bench4Q-Agent/src/main/java/org/bench4q/agent/datacollector/impl/BehaviorResultCollector.java b/Bench4Q-Agent/src/main/java/org/bench4q/agent/datacollector/impl/BehaviorResultCollector.java new file mode 100644 index 00000000..09cd8dab --- /dev/null +++ b/Bench4Q-Agent/src/main/java/org/bench4q/agent/datacollector/impl/BehaviorResultCollector.java @@ -0,0 +1,5 @@ +package org.bench4q.agent.datacollector.impl; + +public class BehaviorResultCollector { + +} diff --git a/Bench4Q-Agent/src/main/java/org/bench4q/agent/datacollector/impl/BehaviorStatusCodeResult.java b/Bench4Q-Agent/src/main/java/org/bench4q/agent/datacollector/impl/BehaviorStatusCodeResult.java new file mode 100644 index 00000000..5fe233de --- /dev/null +++ b/Bench4Q-Agent/src/main/java/org/bench4q/agent/datacollector/impl/BehaviorStatusCodeResult.java @@ -0,0 +1,52 @@ +package org.bench4q.agent.datacollector.impl; + +import java.lang.reflect.Field; + +public class BehaviorStatusCodeResult { + public long count; + public long contentLength; + public long minResponseTime; + public long maxResponseTime; + public long totalResponseTimeThisTime; + public String contentType; + + public BehaviorStatusCodeResult(String contentType) { + this.totalResponseTimeThisTime = 0; + this.contentType = contentType; + this.count = 0; + this.contentLength = 0; + this.minResponseTime = Long.MAX_VALUE; + this.maxResponseTime = Long.MIN_VALUE; + } + + public static boolean isSuccess(int statusCode) { + return statusCode == 200; + } + + public boolean equals(Object expectedObj) { + Field[] fields = this.getClass().getDeclaredFields(); + boolean equal = true; + try { + for (Field field : fields) { + field.setAccessible(true); + if (field.getName().equals("contentType")) { + field.get(expectedObj).equals(field.get(this)); + continue; + } + if (field.getLong(this) != field.getLong(expectedObj)) { + System.out.println(field.getName() + + " is diferent, this is " + field.getLong(this) + + ", and the expected is " + + field.getLong(expectedObj)); + equal = false; + } + + } + } catch (Exception e) { + e.printStackTrace(); + equal = false; + + } + return equal; + } +} \ No newline at end of file diff --git a/Bench4Q-Agent/src/main/java/org/bench4q/agent/datacollector/impl/PageResultCollector.java b/Bench4Q-Agent/src/main/java/org/bench4q/agent/datacollector/impl/PageResultCollector.java new file mode 100644 index 00000000..f046c746 --- /dev/null +++ b/Bench4Q-Agent/src/main/java/org/bench4q/agent/datacollector/impl/PageResultCollector.java @@ -0,0 +1,110 @@ +package org.bench4q.agent.datacollector.impl; + +import java.util.Date; +import java.util.HashMap; +import java.util.Map; + +import org.bench4q.agent.scenario.BehaviorResult; +import org.bench4q.agent.scenario.PageResult; +import org.bench4q.share.models.agent.statistics.AgentPageBriefModel; + +public class PageResultCollector extends AbstractDataCollector { + Map pageBriefMap; + + private Map getPageBriefMap() { + return pageBriefMap; + } + + private void setPageBriefMap(Map pageBriefMap) { + this.pageBriefMap = pageBriefMap; + } + + public PageResultCollector() { + this.setPageBriefMap(new HashMap()); + } + + public void add(PageResult pageResult) { + if (pageResult == null || pageResult.getPageId() < 0) { + return; + } + PageBrief pageBrief = guardTheValueOfThePageIdExists(pageResult + .getPageId()); + pageBrief.countThisTime++; + pageBrief.countFromBegin++; + pageBrief.totalResponseTimeThisTime += pageResult.getExecuteRange(); + pageBrief.latesTimeResponseTime = pageResult.getExecuteRange(); + if (pageResult.getExecuteRange() > pageBrief.maxResponseTimeFromBegin) { + pageBrief.maxResponseTimeFromBegin = pageResult.getExecuteRange(); + } + if (pageResult.getExecuteRange() < pageBrief.minResponseTimeFromBegin) { + pageBrief.minResponseTimeFromBegin = pageResult.getExecuteRange(); + } + } + + private synchronized PageBrief guardTheValueOfThePageIdExists(int pageId) { + if (!this.getPageBriefMap().containsKey(pageId)) { + this.getPageBriefMap().put(pageId, new PageBrief()); + } + return this.getPageBriefMap().get(pageId); + } + + public Object getPageBriefStatistics(int pageId) { + PageBrief pageBrief = guardTheValueOfThePageIdExists(pageId); + AgentPageBriefModel result = new AgentPageBriefModel(); + result.setCountFromBegin(pageBrief.countFromBegin); + result.setCountThisTime(pageBrief.countThisTime); + result.setMaxResponseTimeFromBegin(pageBrief.maxResponseTimeFromBegin); + result.setMinResponseTimeFromBegin(pageBrief.minResponseTimeFromBegin); + result.setTotalResponseTimeThisTime(pageBrief.totalResponseTimeThisTime); + result.setPageId(pageId); + long nowTime = new Date().getTime(); + result.setTimeFrame(nowTime - pageBrief.lastSampleTime); + result.setLatestResponseTime(pageBrief.latesTimeResponseTime); + pageBrief.resetTemperatyField(); + return result; + } + + @Override + public void add(BehaviorResult behaviorResult) { + } + + @Override + protected String calculateSavePath(BehaviorResult behaviorResult) { + return null; + } + + @Override + public Object getScenarioBriefStatistics() { + return null; + } + + @Override + public Map getBehaviorBriefStatistics( + int id) { + return null; + } + + public class PageBrief { + public long lastSampleTime; + public long countThisTime; + public long totalResponseTimeThisTime; + public long maxResponseTimeFromBegin; + public long minResponseTimeFromBegin; + public long countFromBegin; + public long latesTimeResponseTime; + + public PageBrief() { + resetTemperatyField(); + this.maxResponseTimeFromBegin = Long.MIN_VALUE; + this.minResponseTimeFromBegin = Long.MAX_VALUE; + this.countFromBegin = 0; + this.latesTimeResponseTime = 0; + } + + public void resetTemperatyField() { + this.lastSampleTime = new Date().getTime(); + this.countThisTime = 0; + this.totalResponseTimeThisTime = 0; + } + } +} diff --git a/Bench4Q-Agent/src/main/java/org/bench4q/agent/datacollector/impl/ScenarioResultCollector.java b/Bench4Q-Agent/src/main/java/org/bench4q/agent/datacollector/impl/ScenarioResultCollector.java new file mode 100644 index 00000000..557282d1 --- /dev/null +++ b/Bench4Q-Agent/src/main/java/org/bench4q/agent/datacollector/impl/ScenarioResultCollector.java @@ -0,0 +1,278 @@ +package org.bench4q.agent.datacollector.impl; + +import java.text.SimpleDateFormat; +import java.util.Collections; +import java.util.Date; +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; + +import org.bench4q.agent.scenario.BehaviorResult; +import org.bench4q.agent.scenario.PageResult; +import org.bench4q.share.models.agent.statistics.AgentBriefStatusModel; + +/** + * This class collect the behavior result and statistic it. + * + * @author coderfengyun + * + */ +public class ScenarioResultCollector extends AbstractDataCollector { + private long timeOfPreviousCall; + private long failCountOfThisCall; + private long successCountOfThisCall; + private long totalResponseTimeOfThisCall; + private long maxResponseTimeOfThisCall; + private long minResponseTimeOfThisCall; + private long totalSqureResponseTimeOfThisCall; + private long cumulativeSucessfulCount; + private long cumulativeFailCount; + private static long TIME_UNIT = 1000; + private UUID testID; + private PageResultCollector pageResultCollector; + // The first integer is the behavior's id, and the second integer is + // the StatusCode of this behaviorResult. + private Map> detailMap; + + private void setTimeOfPreviousCall(long timeOfPreviousCall) { + this.timeOfPreviousCall = timeOfPreviousCall; + } + + private void setFailCountOfThisCall(long failCountOfThisCall) { + this.failCountOfThisCall = failCountOfThisCall; + } + + private long getSuccessCountOfThisCall() { + return successCountOfThisCall; + } + + private void setSuccessCountOfThisCall(long successCountOfThisCall) { + this.successCountOfThisCall = successCountOfThisCall; + } + + private void setTotalResponseTimeOfThisCall(long totalResponseTimeOfThisCall) { + this.totalResponseTimeOfThisCall = totalResponseTimeOfThisCall; + } + + private long getMaxResponseTimeOfThisCall() { + return maxResponseTimeOfThisCall; + } + + private void setMaxResponseTimeOfThisCall(long maxResponseTimeOfThisCall) { + this.maxResponseTimeOfThisCall = maxResponseTimeOfThisCall; + } + + private long getMinResponseTimeOfThisCall() { + return minResponseTimeOfThisCall; + } + + private void setMinResponseTimeOfThisCall(long minResponseTimeOfThisCall) { + this.minResponseTimeOfThisCall = minResponseTimeOfThisCall; + } + + private void setTotalSqureResponseTimeOfThisCall( + long totalSqureResponseTimeOfThisCall) { + this.totalSqureResponseTimeOfThisCall = totalSqureResponseTimeOfThisCall; + } + + private void setCumulativeSucessfulCount(long cumulativeSucessfulCount) { + this.cumulativeSucessfulCount = cumulativeSucessfulCount; + } + + private void setCumulativeFailCount(long cumulativeFailCount) { + this.cumulativeFailCount = cumulativeFailCount; + } + + private String getTestID() { + return testID == null ? "default" : testID.toString(); + } + + private void setTestID(UUID testID) { + this.testID = testID; + } + + private void setDetailMap( + Map> detailMap) { + this.detailMap = detailMap; + } + + private PageResultCollector getPageResultCollector() { + return pageResultCollector; + } + + private void setPageResultCollector(PageResultCollector pageResultCollector) { + this.pageResultCollector = pageResultCollector; + } + + public ScenarioResultCollector(UUID testId) { + this.setTestID(testId); + this.setPageResultCollector(new PageResultCollector()); + init(); + } + + private void init() { + reset(); + this.setCumulativeFailCount(0); + this.setCumulativeSucessfulCount(0); + this.setDetailMap(new HashMap>()); + } + + private void reset() { + this.setTimeOfPreviousCall(System.currentTimeMillis()); + this.setFailCountOfThisCall(0); + this.setMaxResponseTimeOfThisCall(Long.MIN_VALUE); + this.setMinResponseTimeOfThisCall(Long.MAX_VALUE); + this.setSuccessCountOfThisCall(0); + this.setTotalResponseTimeOfThisCall(0); + this.setTotalSqureResponseTimeOfThisCall(0); + } + + // /////////////////////////////// + // DataStatistics Interface start + // /////////////////////////////// + + public AgentBriefStatusModel getScenarioBriefStatistics() { + AgentBriefStatusModel result = new AgentBriefStatusModel(); + result.setTimeFrame(System.currentTimeMillis() + - this.timeOfPreviousCall); + if (this.getSuccessCountOfThisCall() == 0) { + result.setMaxResponseTime(0); + result.setMinResponseTime(0); + } else { + result.setMinResponseTime(this.minResponseTimeOfThisCall); + result.setMaxResponseTime(this.maxResponseTimeOfThisCall); + } + this.cumulativeSucessfulCount += this.successCountOfThisCall; + result.setSuccessCountFromBegin(this.cumulativeSucessfulCount); + this.cumulativeFailCount += this.failCountOfThisCall; + result.setFailCountFromBegin(this.cumulativeFailCount); + if (result.getTimeFrame() == 0) { + result.setSuccessThroughputThisTime(0); + result.setFailThroughputThisTime(0); + } else { + result.setSuccessThroughputThisTime(this.successCountOfThisCall + * TIME_UNIT / result.getTimeFrame()); + result.setFailThroughputThisTime(this.failCountOfThisCall + * TIME_UNIT / result.getTimeFrame()); + } + result.setTotalResponseTimeThisTime(this.totalResponseTimeOfThisCall); + result.setSuccessCountThisTime(this.successCountOfThisCall); + result.setFailCountThisTime(this.failCountOfThisCall); + result.setTotalSqureResponseTimeThisTime(this.totalSqureResponseTimeOfThisCall); + reset(); + return result; + } + + // /////////////////////////////// + // DataStatistics Interface end + // /////////////////////////////// + /** + * For the failed one, only the fail count statistics will be added, Others + * of this failed one will be ignored. + * + * @param behaviorResult + */ + + private void statisticScenarioBriefResult(BehaviorResult behaviorResult) { + if (behaviorResult.isSuccess()) { + this.successCountOfThisCall++; + this.totalResponseTimeOfThisCall += behaviorResult + .getResponseTime(); + this.totalSqureResponseTimeOfThisCall += ((long) behaviorResult + .getResponseTime()) * behaviorResult.getResponseTime(); + if (behaviorResult.getResponseTime() > this + .getMaxResponseTimeOfThisCall()) { + this.setMaxResponseTimeOfThisCall(behaviorResult + .getResponseTime()); + } + if (behaviorResult.getResponseTime() < this + .getMinResponseTimeOfThisCall()) { + this.setMinResponseTimeOfThisCall(behaviorResult + .getResponseTime()); + } + } else { + this.failCountOfThisCall++; + } + } + + private void statisticBehaviorBriefResult(BehaviorResult behaviorResult) { + insertWhenNotExist(behaviorResult); + Map detailStatusMap = this.detailMap + .get(behaviorResult.getBehaviorId()); + // TODO: there's a problem about concurrency + guardStatusMapExists(behaviorResult, detailStatusMap); + BehaviorStatusCodeResult statusCodeResult = detailStatusMap + .get(behaviorResult.getStatusCode()); + statusCodeResult.count++; + if (!behaviorResult.isSuccess()) { + statusCodeResult.maxResponseTime = 0; + statusCodeResult.minResponseTime = 0; + statusCodeResult.contentLength = 0; + statusCodeResult.totalResponseTimeThisTime = 0; + return; + } + statusCodeResult.contentLength += behaviorResult.getContentLength(); + statusCodeResult.totalResponseTimeThisTime += behaviorResult + .getResponseTime(); + if (behaviorResult.getResponseTime() > statusCodeResult.maxResponseTime) { + statusCodeResult.maxResponseTime = behaviorResult.getResponseTime(); + } + if (behaviorResult.getResponseTime() < statusCodeResult.minResponseTime) { + statusCodeResult.minResponseTime = behaviorResult.getResponseTime(); + } + } + + private synchronized void guardStatusMapExists( + BehaviorResult behaviorResult, + Map detailStatusMap) { + if (!detailStatusMap.containsKey(behaviorResult.getStatusCode())) { + detailStatusMap.put( + new Integer(behaviorResult.getStatusCode()), + new BehaviorStatusCodeResult(behaviorResult + .getContentType())); + } + } + + private synchronized void insertWhenNotExist(BehaviorResult behaviorResult) { + if (!this.detailMap.containsKey(behaviorResult.getBehaviorId())) { + this.detailMap.put(new Integer(behaviorResult.getBehaviorId()), + new HashMap()); + } + } + + @Override + protected String calculateSavePath(BehaviorResult behaviorResult) { + Date now = new Date(); + + return "DetailResults" + System.getProperty("file.separator") + + new SimpleDateFormat("yyyyMMdd").format(now) + + System.getProperty("file.separator") + this.getTestID() + "_" + + behaviorResult.getBehaviorId() + "_" + + new SimpleDateFormat("hhmm") + ".txt"; + } + + public void add(PageResult pageResult) { + this.getPageResultCollector().add(pageResult); + } + + @Override + public void add(BehaviorResult behaviorResult) { + super.add(behaviorResult); + statisticScenarioBriefResult(behaviorResult); + statisticBehaviorBriefResult(behaviorResult); + } + + @Override + public Map getBehaviorBriefStatistics( + int behaviorId) { + if (!this.detailMap.containsKey(behaviorId)) { + return null; + } + return Collections.unmodifiableMap(this.detailMap.get(behaviorId)); + } + + public Object getPageBriefStatistics(int pageId) { + return this.getPageResultCollector().getPageBriefStatistics(pageId); + } + +} diff --git a/Bench4Q-Agent/src/main/java/org/bench4q/agent/helper/ApplicationContextHelper.java b/Bench4Q-Agent/src/main/java/org/bench4q/agent/helper/ApplicationContextHelper.java new file mode 100644 index 00000000..4ace1b14 --- /dev/null +++ b/Bench4Q-Agent/src/main/java/org/bench4q/agent/helper/ApplicationContextHelper.java @@ -0,0 +1,26 @@ +package org.bench4q.agent.helper; + +import org.springframework.beans.BeansException; +import org.springframework.context.ApplicationContext; +import org.springframework.context.ApplicationContextAware; +import org.springframework.stereotype.Component; + +@Component +public class ApplicationContextHelper implements ApplicationContextAware { + + private static ApplicationContext context; + + public static ApplicationContext getContext() { + return context; + } + + private void setContext(ApplicationContext context) { + ApplicationContextHelper.context = context; + } + + public void setApplicationContext(ApplicationContext applicationContext) + throws BeansException { + this.setContext(applicationContext); + } + +} diff --git a/Bench4Q-Agent/src/main/java/org/bench4q/agent/parameterization/ParameterFileCollector.java b/Bench4Q-Agent/src/main/java/org/bench4q/agent/parameterization/ParameterFileCollector.java new file mode 100644 index 00000000..54bdb87a --- /dev/null +++ b/Bench4Q-Agent/src/main/java/org/bench4q/agent/parameterization/ParameterFileCollector.java @@ -0,0 +1,33 @@ +package org.bench4q.agent.parameterization; + +import java.io.File; +import java.io.IOException; +import java.util.List; +import java.util.UUID; + +import org.springframework.stereotype.Component; +import org.springframework.web.multipart.MultipartFile; + +@Component +public class ParameterFileCollector { + private static final String FILE_SEPARATOR = System + .getProperty("file.separator"); + + public void collectParamFiles(List files, UUID runId) + throws IOException { + for (MultipartFile file : files) { + file.transferTo(new File(guardDirExists(runId) + + file.getOriginalFilename())); + } + } + + private String guardDirExists(UUID runId) { + String dirPath = "ScenarioParameters" + FILE_SEPARATOR + + runId.toString() + FILE_SEPARATOR; + File dirFile = new File(dirPath); + if (!dirFile.exists()) { + dirFile.mkdirs(); + } + return dirPath; + } +} diff --git a/Bench4Q-Agent/src/main/java/org/bench4q/agent/parameterization/SessionObject.java b/Bench4Q-Agent/src/main/java/org/bench4q/agent/parameterization/SessionObject.java new file mode 100644 index 00000000..a96586f4 --- /dev/null +++ b/Bench4Q-Agent/src/main/java/org/bench4q/agent/parameterization/SessionObject.java @@ -0,0 +1,14 @@ +package org.bench4q.agent.parameterization; + +import java.util.Map; + +public interface SessionObject { + + public String getParam(String name); + + public void saveRuntimeParam(String name, String value); + + public void doCleanUp(); + + public void saveRuntimeParams(Map runTimeParams); +} diff --git a/Bench4Q-Agent/src/main/java/org/bench4q/agent/parameterization/impl/InstanceControler.java b/Bench4Q-Agent/src/main/java/org/bench4q/agent/parameterization/impl/InstanceControler.java new file mode 100644 index 00000000..e14e9164 --- /dev/null +++ b/Bench4Q-Agent/src/main/java/org/bench4q/agent/parameterization/impl/InstanceControler.java @@ -0,0 +1,183 @@ +package org.bench4q.agent.parameterization.impl; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; +import java.util.UUID; +import java.util.concurrent.locks.ReentrantReadWriteLock; + +import org.bench4q.agent.parameterization.SessionObject; + +public class InstanceControler implements SessionObject { + private String userDefineParameterFolderPath = "/home/yxsh/git/Bench4Q-Agent/parameterClass/"; + private UUID instandid = java.util.UUID.randomUUID(); + private Set usedClassName = new HashSet(); + private Map objMap = new HashMap(); + private Map runtimeParaMap = new HashMap(); + private Map cacheObjMap = new HashMap(); + private ReentrantReadWriteLock mapRWLock = new ReentrantReadWriteLock(); + + String instanceLevelGetParameter(String name, String className, + String functionName, Object[] args) { + + boolean hasThisClass = false; + mapRWLock.readLock().lock(); + hasThisClass = objMap.containsKey(className); + mapRWLock.readLock().unlock(); + if (false == hasThisClass) { + createObj(className); + } + Object instance = getObj(className); + Object result = null; + try { + Class[] argTypeArr = new Class[args.length + 2]; + argTypeArr[0] = instandid.getClass(); + argTypeArr[1] = this.cacheObjMap.getClass(); + Object[] totalArgs = new Object[args.length + 2]; + totalArgs[0] = instandid; + totalArgs[1] = this.cacheObjMap; + for (int i = 2; i < args.length + 2; i++) { + argTypeArr[i] = args[i - 2].getClass(); + totalArgs[i] = args[i - 2]; + } + Method m = instance.getClass().getMethod(functionName, argTypeArr); + result = m.invoke(instance, totalArgs); + } catch (Exception ex) { + System.out.println(ex.getMessage() + ex.getStackTrace()); + System.out.println(((InvocationTargetException) ex) + .getTargetException().getMessage()); + return null; + } + runtimeParaMap.put(name, (String) result); + return (String) result; + + } + + String getParameterByContext(String name) { + if (false == this.runtimeParaMap.containsKey(name)) { + return null; + } + return runtimeParaMap.get(name); + } + + private boolean createObj(String className) { + try { + MyFileClassLoader cl = new MyFileClassLoader(); + cl.setClassPath(userDefineParameterFolderPath); + Class cls = cl.loadClass(className); + Object instance = cls.newInstance(); + mapRWLock.writeLock().lock(); + objMap.put(className, instance); + + } catch (Exception ex) { + return false; + } + mapRWLock.writeLock().unlock(); + return true; + } + + private Object getObj(String className) { + Object result = null; + mapRWLock.readLock().lock(); + objMap.get(className); + mapRWLock.readLock().unlock(); + return result; + } + + String getParameter(String name, String className, String functionName, + Object[] args) { + + ParametersFactory pf = ParametersFactory.getInstance(); + boolean hasThisClass = pf.containObj(className); + if (false == hasThisClass) { + pf.createObj(className); + } + + Object instance = pf.getObj(className); + Object result = null; + try { + Class[] argTypeArr = new Class[args.length + 2]; + argTypeArr[0] = instandid.getClass(); + argTypeArr[1] = this.cacheObjMap.getClass(); + Object[] totalArgs = new Object[args.length + 2]; + totalArgs[0] = instandid; + totalArgs[1] = this.cacheObjMap; + for (int i = 2; i < args.length + 2; i++) { + argTypeArr[i] = args[i - 2].getClass(); + totalArgs[i] = args[i - 2]; + } + + Method m = instance.getClass().getMethod(functionName, argTypeArr); + + result = m.invoke(instance, totalArgs); + + } catch (Exception ex) { + System.out.println(ex.getMessage() + ex.getStackTrace()); + System.out.println(((InvocationTargetException) ex) + .getTargetException().getMessage()); + return null; + } + + usedClassName.add(className); + runtimeParaMap.put(name, (String) result); + return (String) result; + } + + /** + * Implement SessionObject begin + */ + + public String getParam(String name) { + if (!(name.startsWith(""))) + return name; + return ParameterizationParser.parse(name, this); + } + + public void saveRuntimeParam(String name, String value) { + runtimeParaMap.put(name, value); + } + + public void saveRuntimeParams(Map runTimeParams) { + runtimeParaMap.putAll(runTimeParams); + } + + public void doCleanUp() { + this.releaseAll(); + } + + /** + * Implement SessionObject end + */ + + private void releaseAll() { + for (String xx : usedClassName) { + release(xx); + } + } + + private void release(String className) { + ParametersFactory pf = ParametersFactory.getInstance(); + boolean hasThisClass = pf.containObj(className); + if (false == hasThisClass) { + pf.createObj(className); + } + + Object instance = pf.getObj(className); + + try { + + Method m = instance.getClass().getMethod("unreg", + instandid.getClass()); + + m.invoke(instance, instandid); + + } catch (Exception ex) { + System.out.println("realse failed"); + } + + } + +} diff --git a/Bench4Q-Agent/src/main/java/org/bench4q/agent/parameterization/impl/MyFileClassLoader.java b/Bench4Q-Agent/src/main/java/org/bench4q/agent/parameterization/impl/MyFileClassLoader.java new file mode 100644 index 00000000..44448d68 --- /dev/null +++ b/Bench4Q-Agent/src/main/java/org/bench4q/agent/parameterization/impl/MyFileClassLoader.java @@ -0,0 +1,98 @@ +package org.bench4q.agent.parameterization.impl; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; + +public class MyFileClassLoader extends ClassLoader { + + private String classPath; + + public static void main(String[] args) throws ClassNotFoundException, + InstantiationException, IllegalAccessException, + IllegalArgumentException, InvocationTargetException { + MyFileClassLoader fileClsLoader = new MyFileClassLoader(); + fileClsLoader + .setClassPath("E:\\j2ee_proj\\skythink\\WebContent\\WEB-INF\\classes\\"); + Class cls = fileClsLoader + .loadClass("com.cmw.entity.sys.AccordionEntity"); + Object obj = cls.newInstance(); + Method[] mthds = cls.getMethods(); + for (Method mthd : mthds) { + String methodName = mthd.getName(); + System.out.println("mthd.name=" + methodName); + } + System.out.println("obj.class=" + obj.getClass().getName()); + System.out.println("obj.class=" + cls.getClassLoader().toString()); + System.out.println("obj.class=" + + cls.getClassLoader().getParent().toString()); + } + + /** + * ��������ַ��ָ����Ŀ¼�����࣬����������� + */ + @Override + protected Class findClass(String name) throws ClassNotFoundException { + byte[] classData = null; + try { + classData = loadClassData(name); + } catch (IOException e) { + e.printStackTrace(); + } + return super.defineClass(name, classData, 0, classData.length); + } + + /** + * ��������ַ������ byte ����� + * + * @param name + * �����ַ� ���磺 com.cmw.entity.SysEntity + * @return �������ļ� byte ����� + * @throws IOException + */ + private byte[] loadClassData(String name) throws IOException { + File file = getFile(name); + @SuppressWarnings("resource") + FileInputStream fis = new FileInputStream(file); + byte[] arrData = new byte[(int) file.length()]; + fis.read(arrData); + return arrData; + } + + /** + * ��������ַ���һ�� File ���� + * + * @param name + * �����ַ� + * @return File ���� + * @throws FileNotFoundException + */ + private File getFile(String name) throws FileNotFoundException { + File dir = new File(classPath); + if (!dir.exists()) + throw new FileNotFoundException(classPath + " Ŀ¼�����ڣ�"); + String _classPath = classPath.replaceAll("[\\\\]", "/"); + int offset = _classPath.lastIndexOf("/"); + name = name.replaceAll("[.]", "/"); + if (offset != -1 && offset < _classPath.length() - 1) { + _classPath += "/"; + } + _classPath += name + ".class"; + dir = new File(_classPath); + if (!dir.exists()) + throw new FileNotFoundException(dir + " �����ڣ�"); + return dir; + } + + public String getClassPath() { + return classPath; + } + + public void setClassPath(String classPath) { + this.classPath = classPath; + } + +} diff --git a/Bench4Q-Agent/src/main/java/org/bench4q/agent/parameterization/impl/Para_File.java b/Bench4Q-Agent/src/main/java/org/bench4q/agent/parameterization/impl/Para_File.java new file mode 100644 index 00000000..aaca0b6d --- /dev/null +++ b/Bench4Q-Agent/src/main/java/org/bench4q/agent/parameterization/impl/Para_File.java @@ -0,0 +1,18 @@ +package org.bench4q.agent.parameterization.impl; + +import java.io.BufferedReader; +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; + +public class Para_File { + + @SuppressWarnings("unused") + private Map readBuffer = new HashMap(); + + public void getFromFile(UUID id, String fileName, String column, + String firstData, String byNumber) { + + } + +} diff --git a/Bench4Q-Agent/src/main/java/org/bench4q/agent/parameterization/impl/Para_GetEletronicCombine.java b/Bench4Q-Agent/src/main/java/org/bench4q/agent/parameterization/impl/Para_GetEletronicCombine.java new file mode 100644 index 00000000..16295ae5 --- /dev/null +++ b/Bench4Q-Agent/src/main/java/org/bench4q/agent/parameterization/impl/Para_GetEletronicCombine.java @@ -0,0 +1,32 @@ +package org.bench4q.agent.parameterization.impl; + +import java.util.Date; +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; +import java.util.concurrent.locks.ReentrantReadWriteLock; + +public class Para_GetEletronicCombine { + + public class eletronicParas + { + String beginUser; + String endUser; + String beginTime; + String endTime; + } + public Map useInstanceMap = new HashMap(); + @SuppressWarnings("deprecation") + Date currentTimeLoop = new Date("2014-01-01"); + long currentUser = 10001; + ReentrantReadWriteLock timeRWLock = new ReentrantReadWriteLock(); + + public Para_GetEletronicCombine() { + + } + + public String getBeginUser(UUID id) { + return null; + } + +} diff --git a/Bench4Q-Agent/src/main/java/org/bench4q/agent/parameterization/impl/Para_IteratorNumber.java b/Bench4Q-Agent/src/main/java/org/bench4q/agent/parameterization/impl/Para_IteratorNumber.java new file mode 100644 index 00000000..e4d42743 --- /dev/null +++ b/Bench4Q-Agent/src/main/java/org/bench4q/agent/parameterization/impl/Para_IteratorNumber.java @@ -0,0 +1,29 @@ +package org.bench4q.agent.parameterization.impl; + +import java.util.Map; +import java.util.UUID; + +public class Para_IteratorNumber { + public Long iteratorNum = new Long(0); + + /** + * For all methods, they will has these two params + * + * @param id + * @param a + * @return + */ + public String getIteratorNumber(UUID id, Map a) { + long result = 0; + synchronized (iteratorNum) { + iteratorNum++; + result = iteratorNum; + } + String ret = String.valueOf(result); + return ret; + } + + public void unreg(UUID id) { + + } +} diff --git a/Bench4Q-Agent/src/main/java/org/bench4q/agent/parameterization/impl/Para_RandomNumber.java b/Bench4Q-Agent/src/main/java/org/bench4q/agent/parameterization/impl/Para_RandomNumber.java new file mode 100644 index 00000000..f0b6f360 --- /dev/null +++ b/Bench4Q-Agent/src/main/java/org/bench4q/agent/parameterization/impl/Para_RandomNumber.java @@ -0,0 +1,28 @@ +package org.bench4q.agent.parameterization.impl; + +import java.util.Random; +import java.util.UUID; + +public class Para_RandomNumber { + + public String getRandomIntegerNumber(UUID id,String begin, String end, String stringformat) + { + + Random r = new Random(); + int beginNum = Integer.parseInt(begin); + int endNum = Integer.parseInt(end); + + int result = r.nextInt(endNum-beginNum) +beginNum; + return String.format(stringformat,result); + } + + public String getRandomDouble(UUID id , String begin, String end , String stringformat) + { + Random r = new Random(); + double beginNum = Integer.parseInt(begin); + double endNum = Integer.parseInt(end); + + double result = r.nextDouble()*(endNum-beginNum) +beginNum; + return String.format(stringformat, result); + } +} diff --git a/Bench4Q-Agent/src/main/java/org/bench4q/agent/parameterization/impl/Para_Table.java b/Bench4Q-Agent/src/main/java/org/bench4q/agent/parameterization/impl/Para_Table.java new file mode 100644 index 00000000..201003a5 --- /dev/null +++ b/Bench4Q-Agent/src/main/java/org/bench4q/agent/parameterization/impl/Para_Table.java @@ -0,0 +1,271 @@ +package org.bench4q.agent.parameterization.impl; + +import java.io.BufferedReader; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStreamReader; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Random; +import java.util.UUID; +import java.util.concurrent.ArrayBlockingQueue; +import java.util.concurrent.ConcurrentHashMap; + +public class Para_Table { + public final int cacheCap = 5000;// 1 sequence 2 random + public final int cacheSize = 1000;// 1 sequence 2 random + public final int readCharSize = 10000; + public ConcurrentHashMap readerMap = new ConcurrentHashMap(); + + public abstract class Reader { + public final Table t; + + public Reader(Table table) { + this.t = table; + } + + public abstract TableRow nextRow(); + + } + + public class RandomReader extends Reader { + public ArrayBlockingQueue queue; + + public RandomReader(ArrayBlockingQueue queue, Table t) { + super(t); + this.queue = queue; + } + + @Override + public TableRow nextRow() { + TableRow result = null; + do { + if (queue.size() == 0) { + synchronized (queue) { + if (queue.size() == 0) { + List rows = t.readRows(); + int n = rows.size(); + Random r = new Random(); + for (int i = 0; i < n; i++) { + int next = r.nextInt(n); + TableRow tempRow = rows.get(i); + rows.set(i, rows.get(next)); + rows.set(next, tempRow); + } + queue.addAll(rows); + } + } + } + result = queue.poll(); + } while (result == null); + return result; + } + + } + + public class SequenceReader extends Reader { + public ArrayBlockingQueue queue; + + public SequenceReader(ArrayBlockingQueue queue, Table t) { + super(t); + this.queue = queue; + } + + @Override + public TableRow nextRow() { + TableRow result = null; + do { + if (queue.size() == 0) { + synchronized (queue) { + if (queue.size() == 0) { + List rows = t.readRows(); + queue.addAll(rows); + } + } + } + result = queue.poll(); + } while (result == null); + return result; + } + + } + + public abstract class Table { + String sourceValue; + int firstRow; + + public Table(String sourceValue, int firstRow) { + this.sourceValue = sourceValue; + } + + public abstract List readRows(); + + public List rows = new ArrayList(); + + public int getTime = 0; + + public boolean add(TableRow r) { + return rows.add(r); + } + } + + public class FileTable extends Table { + private BufferedReader bfr; + char splitChar; + char lineChar; + + public FileTable(String sourceValue, int firstRow, char splitChar, + char lineChar) { + super(sourceValue, firstRow); + this.splitChar = splitChar; + this.lineChar = lineChar; + try { + createBFR(); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + + private void createBFR() throws IOException { + FileInputStream fis = new FileInputStream(sourceValue); + InputStreamReader ir = new InputStreamReader(fis); + bfr = new BufferedReader(ir); + for (int i = 0; i < firstRow;) { + char readChar = (char) bfr.read(); + if (readChar == lineChar) + i++; + } + + } + + @Override + public List readRows() { + StringBuilder target = new StringBuilder(); + List result = new ArrayList(); + TableRow tempTableRow = new TableRow(); + try { + for (int i = 0; i < cacheSize;) { + int tt = bfr.read(); + char readBuff = (char) tt; + if (tt == -1) { + createBFR(); + break; + } else if (readBuff == this.splitChar) { + String cellString = target.toString(); + tempTableRow.AddCell(cellString); + target = new StringBuilder(); + continue; + } else if (readBuff == this.lineChar) { + tempTableRow.AddCell(target.toString()); + result.add(tempTableRow); + tempTableRow = new TableRow(); + target = new StringBuilder(); + i++; + continue; + } + target.append(readBuff); + } + } catch (IOException ioex) { + return result; + } + if (target.length() > 0) { + tempTableRow.AddCell(target.toString()); + result.add(tempTableRow); + target = new StringBuilder(); + } + return result; + } + + } + + public class StringTable extends Table { + + char splitChar; + char lineChar; + + public StringTable(String sourceValue, int firstRow, char splitChar, + char lineChar) { + super(sourceValue, firstRow); + this.splitChar = splitChar; + this.lineChar = lineChar; + } + + @Override + public List readRows() { + String readStr = this.sourceValue; + String[] tokens = readStr.split(String.valueOf(lineChar)); + List result = new ArrayList(); + for (String line : tokens) { + TableRow tempRow = new TableRow(); + String[] columns = line.split(String.valueOf(splitChar)); + for (String column : columns) { + tempRow.AddCell(column); + } + result.add(tempRow); + } + return result; + } + + } + + public class TableRow { + public List cells = new ArrayList(); + + public void AddCell(String s) { + cells.add(s); + } + } + + // org.bench4q.agent.parameterization.impl.Para_Table.getTableColumnValue(java.util.UUID, + // java.util.HashMap, java.lang.String, java.lang.String, java.lang.String, + // java.lang.String, java.lang.String, java.lang.String, java.lang.String) + + public String getTableColumnValue(UUID id, + HashMap objCache, String source, + String sourceValue, String firstRow, String nextRow, + String splitChar, String lineChar, String column) { + int fRow = Integer.parseInt(firstRow); + char sChar = splitChar.charAt(0); + char lChar = lineChar.charAt(0); + int col = Integer.parseInt(column); + TableRow resultRow = null; + Table table = null; + Reader reader = null; + if (objCache.containsKey(sourceValue) == true) { + resultRow = (TableRow) objCache.get(sourceValue); + return resultRow.cells.get(col); + } + + if (this.readerMap.containsKey(sourceValue)) { + reader = readerMap.get(sourceValue); + + } else { + if (source.equals("file")) { + table = new FileTable(sourceValue, fRow, sChar, lChar); + } else if (source.equals("input")) { + table = new StringTable(sourceValue, fRow, sChar, lChar); + } + + if (nextRow.equals("random")) { + ArrayBlockingQueue queue = new ArrayBlockingQueue( + cacheCap); + reader = new RandomReader(queue, table); + } else if (nextRow.equals("sequence")) { + + ArrayBlockingQueue queue = new ArrayBlockingQueue( + cacheCap); + reader = new SequenceReader(queue, table); + } + readerMap.put(sourceValue, reader); + } + resultRow = reader.nextRow(); + objCache.put(sourceValue, resultRow); + return resultRow.cells.get(col); + } + + public void unreg(UUID id) { + + } +} diff --git a/Bench4Q-Agent/src/main/java/org/bench4q/agent/parameterization/impl/Para_Table.xml b/Bench4Q-Agent/src/main/java/org/bench4q/agent/parameterization/impl/Para_Table.xml new file mode 100644 index 00000000..15f7c4a6 --- /dev/null +++ b/Bench4Q-Agent/src/main/java/org/bench4q/agent/parameterization/impl/Para_Table.xml @@ -0,0 +1,19 @@ + + + + file + input + + + + + + + sequence + random + + + + + + diff --git a/Bench4Q-Agent/src/main/java/org/bench4q/agent/parameterization/impl/Para_UniqueNumber.java b/Bench4Q-Agent/src/main/java/org/bench4q/agent/parameterization/impl/Para_UniqueNumber.java new file mode 100644 index 00000000..24bcb320 --- /dev/null +++ b/Bench4Q-Agent/src/main/java/org/bench4q/agent/parameterization/impl/Para_UniqueNumber.java @@ -0,0 +1,12 @@ +package org.bench4q.agent.parameterization.impl; + +import java.util.UUID; + +public class Para_UniqueNumber { + int currentNumber = 0; + + synchronized String getNumber(UUID id) + { + return String.valueOf(currentNumber++); + } +} diff --git a/Bench4Q-Agent/src/main/java/org/bench4q/agent/parameterization/impl/Para_UserNameAndPassword.java b/Bench4Q-Agent/src/main/java/org/bench4q/agent/parameterization/impl/Para_UserNameAndPassword.java new file mode 100644 index 00000000..736c83ec --- /dev/null +++ b/Bench4Q-Agent/src/main/java/org/bench4q/agent/parameterization/impl/Para_UserNameAndPassword.java @@ -0,0 +1,121 @@ +package org.bench4q.agent.parameterization.impl; + +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; +import java.util.concurrent.locks.ReentrantReadWriteLock; + +public class Para_UserNameAndPassword { + String[] Password = new String[] { "a", "b", "c", "d", "e" }; + String[] userName = new String[] { "http://www.baidu.com/", + "http://www.163.com/", "http://baike.baidu.com/", + "http://zhidao.baidu.com/", "http://www.sina.com.cn/" }; + UUID[] useUUID = new UUID[5]; + + Map posMap = new HashMap(); + ReentrantReadWriteLock mapRWLock = new ReentrantReadWriteLock(); + ReentrantReadWriteLock idposLock = new ReentrantReadWriteLock(); + + public String getUserName(UUID id) { + mapRWLock.readLock().lock(); + if (posMap.containsKey(id)) { + mapRWLock.readLock().unlock(); + return userName[posMap.get(id)]; + } + mapRWLock.readLock().unlock(); + + int vaildPos = -1; + int tryNum = 0; + while (vaildPos < 0 && tryNum < 100) { + tryNum++; + idposLock.readLock().lock(); + for (int i = 0; i < 5; i++) { + + if (useUUID[i] == null) { + vaildPos = i; + break; + } + } + idposLock.readLock().unlock(); + if (vaildPos < 0) { + try { + Thread.sleep(1000); + } catch (Exception ex) { + + } + } + } + + idposLock.writeLock().lock(); + useUUID[vaildPos] = id; + idposLock.writeLock().unlock(); + mapRWLock.writeLock().lock(); + posMap.put(id, vaildPos); + mapRWLock.writeLock().unlock(); + return userName[vaildPos]; + } + + public String getPassword(UUID id) { + mapRWLock.readLock().lock(); + if (posMap.containsKey(id)) { + mapRWLock.readLock().unlock(); + return Password[posMap.get(id)]; + } + mapRWLock.readLock().unlock(); + + int vaildPos = -1; + int tryNum = 0; + while (vaildPos < 0 && tryNum < 100) { + tryNum++; + idposLock.readLock().lock(); + for (int i = 0; i < 5; i++) { + + if (useUUID[i] == null) { + vaildPos = i; + break; + } + } + idposLock.readLock().unlock(); + if (vaildPos < 0) { + try { + Thread.sleep(1000); + } catch (Exception ex) { + + } + } + } + + idposLock.writeLock().lock(); + useUUID[vaildPos] = id; + idposLock.writeLock().unlock(); + mapRWLock.writeLock().lock(); + posMap.put(id, vaildPos); + mapRWLock.writeLock().unlock(); + return Password[vaildPos]; + } + + public void unreg(UUID id) { + try { + // System.out.println("1"); + mapRWLock.writeLock().lock(); + // System.out.println("2"); + int pos = posMap.get(id); + // System.out.println("3"); + posMap.remove(id); + // System.out.println("4"); + mapRWLock.writeLock().unlock(); + // System.out.println("5"); + idposLock.writeLock().lock(); + // System.out.println("6"); + useUUID[pos] = null; + idposLock.writeLock().unlock(); + } catch (Exception ex) { + System.out.println(ex.getClass().getName()); + System.out.println(ex.getMessage()); + System.out.println(ex.getStackTrace()); + mapRWLock.writeLock().unlock(); + idposLock.writeLock().unlock(); + } + } + +} diff --git a/Bench4Q-Agent/src/main/java/org/bench4q/agent/parameterization/impl/ParameterThreadOption.java b/Bench4Q-Agent/src/main/java/org/bench4q/agent/parameterization/impl/ParameterThreadOption.java new file mode 100644 index 00000000..e4b79149 --- /dev/null +++ b/Bench4Q-Agent/src/main/java/org/bench4q/agent/parameterization/impl/ParameterThreadOption.java @@ -0,0 +1,29 @@ +package org.bench4q.agent.parameterization.impl; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class ParameterThreadOption { + public final ParameterThreadOption instance = new ParameterThreadOption(); + Map> optionMap = new HashMap>(); + private List all = Arrays.asList("crossThread", "inThread"); + // private List justIn = Arrays.asList("inThread"); + private List justCross = Arrays.asList("crossThread"); + + private ParameterThreadOption() { + + optionMap.put("Para_File", all); + optionMap.put("Para_IteratorNumber", justCross); + optionMap.put("Para_RandomNumber", all); + optionMap.put("Para_UniqueNumber", all); + optionMap.put("Para_UserNameAndPassword", justCross); + } + + public List getThreadOption(String classname) { + if (this.optionMap.containsKey(classname) == false) + return all; + return optionMap.get(classname); + } +} diff --git a/Bench4Q-Agent/src/main/java/org/bench4q/agent/parameterization/impl/ParameterizationParser.java b/Bench4Q-Agent/src/main/java/org/bench4q/agent/parameterization/impl/ParameterizationParser.java new file mode 100644 index 00000000..ff6f6684 --- /dev/null +++ b/Bench4Q-Agent/src/main/java/org/bench4q/agent/parameterization/impl/ParameterizationParser.java @@ -0,0 +1,53 @@ +package org.bench4q.agent.parameterization.impl; + +import java.io.StringReader; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; + +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.xml.sax.InputSource; + +public class ParameterizationParser { + + public static String parse(String text, InstanceControler insCon) { + // Pattern pattern = Pattern.compile(""); + String result = ""; + try { + DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + DocumentBuilder db = dbf.newDocumentBuilder(); + Document document = db + .parse(new InputSource(new StringReader(text))); + Element root = document.getDocumentElement(); + String className = root.getAttribute("class"); + String methodName = root.getAttribute("method"); + String argString = root.getAttribute("args"); + String type = root.getAttribute("type"); + String[] args = argString.split(","); + if (argString.trim().equals("")) + args = new String[0]; + + String name = root.getAttribute("name"); + result = insCon.getParameterByContext(name); + if (result != null) + return result; + if (type.equals("crossThread")) { + result = insCon.getParameter(name, getCurrentPackageFullName() + + "." + className, methodName, args); + } else if (type.equals("inThread")) { + result = insCon.instanceLevelGetParameter(name, className, + methodName, args); + } + + } catch (Exception ex) { + return text; + } + return result; + } + + private static String getCurrentPackageFullName() { + return ParameterizationParser.class.getName().substring(0, + ParameterizationParser.class.getName().lastIndexOf('.')); + } +} diff --git a/Bench4Q-Agent/src/main/java/org/bench4q/agent/parameterization/impl/ParametersFactory.java b/Bench4Q-Agent/src/main/java/org/bench4q/agent/parameterization/impl/ParametersFactory.java new file mode 100644 index 00000000..13795e4e --- /dev/null +++ b/Bench4Q-Agent/src/main/java/org/bench4q/agent/parameterization/impl/ParametersFactory.java @@ -0,0 +1,57 @@ +package org.bench4q.agent.parameterization.impl; + +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.locks.ReentrantReadWriteLock; + +public class ParametersFactory { + private ParametersFactory() { + + }; + + static private final ParametersFactory instance = new ParametersFactory(); + static String lockObj = ""; + + static public ParametersFactory getInstance() { + return instance; + } + + private Map objMap = new HashMap(); + + public boolean containObj(String className) { + boolean ret = false; + mapRWLock.readLock().lock(); + ret = objMap.containsKey(className); + mapRWLock.readLock().unlock(); + return ret; + } + + public Object getObj(String className) { + Object result = null; + mapRWLock.readLock().lock(); + result = objMap.get(className); + mapRWLock.readLock().unlock(); + return result; + } + + private String rootFilePath = "/home/yxsh/git/Bench4Q-Agent/parameterClass/"; + + ReentrantReadWriteLock mapRWLock = new ReentrantReadWriteLock(); + + public boolean createObj(String className) { + try { + MyFileClassLoader cl = new MyFileClassLoader(); + cl.setClassPath(rootFilePath); + Class cls = cl.loadClass(className); + Object instance = cls.newInstance(); + mapRWLock.writeLock().lock(); + objMap.put(className, instance); + + } catch (Exception ex) { + System.out.println(ex.getMessage()); + } + mapRWLock.writeLock().unlock(); + return true; + } + +} diff --git a/Bench4Q-Agent/src/main/java/org/bench4q/agent/plugin/Behavior.java b/Bench4Q-Agent/src/main/java/org/bench4q/agent/plugin/Behavior.java new file mode 100644 index 00000000..ad20e417 --- /dev/null +++ b/Bench4Q-Agent/src/main/java/org/bench4q/agent/plugin/Behavior.java @@ -0,0 +1,12 @@ +package org.bench4q.agent.plugin; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.RUNTIME) +public @interface Behavior { + String value(); +} \ No newline at end of file diff --git a/Bench4Q-Agent/src/main/java/org/bench4q/agent/plugin/BehaviorInfo.java b/Bench4Q-Agent/src/main/java/org/bench4q/agent/plugin/BehaviorInfo.java new file mode 100644 index 00000000..d09d4b88 --- /dev/null +++ b/Bench4Q-Agent/src/main/java/org/bench4q/agent/plugin/BehaviorInfo.java @@ -0,0 +1,23 @@ +package org.bench4q.agent.plugin; + +public class BehaviorInfo { + private String name; + private ParameterInfo[] parameters; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public ParameterInfo[] getParameters() { + return parameters; + } + + public void setParameters(ParameterInfo[] parameters) { + this.parameters = parameters; + } + +} diff --git a/Bench4Q-Agent/src/main/java/org/bench4q/agent/plugin/ClassHelper.java b/Bench4Q-Agent/src/main/java/org/bench4q/agent/plugin/ClassHelper.java new file mode 100644 index 00000000..950bab2f --- /dev/null +++ b/Bench4Q-Agent/src/main/java/org/bench4q/agent/plugin/ClassHelper.java @@ -0,0 +1,124 @@ +package org.bench4q.agent.plugin; + +import java.io.File; +import java.io.IOException; +import java.net.URL; +import java.net.URLClassLoader; +import java.util.ArrayList; +import java.util.Enumeration; +import java.util.List; +import java.util.jar.JarEntry; +import java.util.jar.JarFile; + +import org.springframework.stereotype.Component; + +@Component +public class ClassHelper { + + public List getClassNames(String packageName, + boolean searchInChildPackage) { + try { + List classNames = new ArrayList(); + URLClassLoader classLoader = (URLClassLoader) Thread + .currentThread().getContextClassLoader(); + URL[] urls = classLoader.getURLs(); + for (URL url : urls) { + if (url.getProtocol().equals("file")) { + File file = new File(url.getFile()); + String root = file.getPath().replace("\\", "/"); + if (file.isDirectory()) { + classNames.addAll(this.getClassNamesFromDirectory(root, + packageName, searchInChildPackage, file, true)); + } else if (file.getName().endsWith(".jar")) { + classNames.addAll(this.getClassNameFromJar(packageName, + searchInChildPackage, file)); + } + } + } + return classNames; + } catch (Exception e) { + e.printStackTrace(); + return null; + } + } + + private List getClassNamesFromDirectory(String root, + String packageName, boolean searchInChildPackage, File directory, + boolean continueSearch) { + List classNames = new ArrayList(); + File[] files = directory.listFiles(); + for (File file : files) { + String filePath = file.getPath().replace("\\", "/"); + if (file.isDirectory()) { + if (searchInChildPackage || continueSearch) { + boolean needToContinue = continueSearch; + if (filePath.endsWith(packageName.replace(".", "/"))) { + needToContinue = needToContinue & false; + } + classNames.addAll(this.getClassNamesFromDirectory(root, + packageName, searchInChildPackage, file, + needToContinue)); + } + } else { + if (filePath.endsWith(".class")) { + String classFileName = filePath.replace(root + "/", ""); + if (classFileName.startsWith(packageName.replace(".", "/"))) { + String className = classFileName.substring(0, + classFileName.length() - ".class".length()) + .replace("/", "."); + classNames.add(className); + } + } + } + } + return classNames; + } + + private List getClassNameFromJar(String packageName, + boolean searchInChildPackage, File file) { + List classNames = new ArrayList(); + JarFile jarFile = null; + try { + jarFile = new JarFile(file); + Enumeration jarEntries = jarFile.entries(); + while (jarEntries.hasMoreElements()) { + JarEntry jarEntry = jarEntries.nextElement(); + String entryName = jarEntry.getName(); + if (entryName.endsWith(".class")) { + String packagePath = packageName.replace(".", "/"); + if (searchInChildPackage) { + if (entryName.startsWith(packagePath)) { + entryName = entryName.replace("/", ".").substring( + 0, entryName.lastIndexOf(".")); + classNames.add(entryName); + } + } else { + int index = entryName.lastIndexOf("/"); + String entryPath; + if (index != -1) { + entryPath = entryName.substring(0, index); + } else { + entryPath = entryName; + } + if (entryPath.equals(packagePath)) { + entryName = entryName.replace("/", ".").substring( + 0, entryName.lastIndexOf(".")); + classNames.add(entryName); + } + } + } + } + } catch (IOException e) { + e.printStackTrace(); + } finally { + if (jarFile != null) { + try { + jarFile.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + return classNames; + } +} diff --git a/Bench4Q-Agent/src/main/java/org/bench4q/agent/plugin/Parameter.java b/Bench4Q-Agent/src/main/java/org/bench4q/agent/plugin/Parameter.java new file mode 100644 index 00000000..a9e0a171 --- /dev/null +++ b/Bench4Q-Agent/src/main/java/org/bench4q/agent/plugin/Parameter.java @@ -0,0 +1,12 @@ +package org.bench4q.agent.plugin; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target(ElementType.PARAMETER) +@Retention(RetentionPolicy.RUNTIME) +public @interface Parameter { + String value(); +} diff --git a/Bench4Q-Agent/src/main/java/org/bench4q/agent/plugin/ParameterInfo.java b/Bench4Q-Agent/src/main/java/org/bench4q/agent/plugin/ParameterInfo.java new file mode 100644 index 00000000..4db0e540 --- /dev/null +++ b/Bench4Q-Agent/src/main/java/org/bench4q/agent/plugin/ParameterInfo.java @@ -0,0 +1,23 @@ +package org.bench4q.agent.plugin; + +public class ParameterInfo { + private String name; + private String type; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + +} diff --git a/Bench4Q-Agent/src/main/java/org/bench4q/agent/plugin/Plugin.java b/Bench4Q-Agent/src/main/java/org/bench4q/agent/plugin/Plugin.java new file mode 100644 index 00000000..4647553c --- /dev/null +++ b/Bench4Q-Agent/src/main/java/org/bench4q/agent/plugin/Plugin.java @@ -0,0 +1,12 @@ +package org.bench4q.agent.plugin; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target(ElementType.TYPE) +@Retention(RetentionPolicy.RUNTIME) +public @interface Plugin { + String value(); +} diff --git a/Bench4Q-Agent/src/main/java/org/bench4q/agent/plugin/PluginInfo.java b/Bench4Q-Agent/src/main/java/org/bench4q/agent/plugin/PluginInfo.java new file mode 100644 index 00000000..aadc176a --- /dev/null +++ b/Bench4Q-Agent/src/main/java/org/bench4q/agent/plugin/PluginInfo.java @@ -0,0 +1,32 @@ +package org.bench4q.agent.plugin; + +public class PluginInfo { + private String name; + private ParameterInfo[] parameters; + private BehaviorInfo[] behaviors; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public ParameterInfo[] getParameters() { + return parameters; + } + + public void setParameters(ParameterInfo[] parameters) { + this.parameters = parameters; + } + + public BehaviorInfo[] getBehaviors() { + return behaviors; + } + + public void setBehaviors(BehaviorInfo[] behaviors) { + this.behaviors = behaviors; + } + +} diff --git a/Bench4Q-Agent/src/main/java/org/bench4q/agent/plugin/PluginManager.java b/Bench4Q-Agent/src/main/java/org/bench4q/agent/plugin/PluginManager.java new file mode 100644 index 00000000..735d3a37 --- /dev/null +++ b/Bench4Q-Agent/src/main/java/org/bench4q/agent/plugin/PluginManager.java @@ -0,0 +1,269 @@ +package org.bench4q.agent.plugin; + +import java.lang.annotation.Annotation; +import java.lang.reflect.Constructor; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.apache.log4j.Logger; +import org.bench4q.agent.share.DealWithLog; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +@Component +public class PluginManager { + private ClassHelper classHelper; + private TypeConverter typeConverter; + private Map> plugins; + private Logger logger = Logger.getLogger(PluginManager.class); + + @Autowired + public PluginManager(ClassHelper classHelper, TypeConverter typeConverter) { + this.setClassHelper(classHelper); + this.setTypeConverter(typeConverter); + this.setPlugins(this.loadPlugins("org.bench4q.agent.plugin")); + } + + private ClassHelper getClassHelper() { + return classHelper; + } + + private void setClassHelper(ClassHelper classHelper) { + this.classHelper = classHelper; + } + + private TypeConverter getTypeConverter() { + return typeConverter; + } + + private void setTypeConverter(TypeConverter typeConverter) { + this.typeConverter = typeConverter; + } + + public Map> getPlugins() { + return plugins; + } + + private void setPlugins(Map> plugins) { + this.plugins = plugins; + } + + public Map> loadPlugins(String packageName) { + try { + List classNames = this.getClassHelper().getClassNames( + packageName, true); + Map> ret = new HashMap>(); + for (String className : classNames) { + Class plugin = Class.forName(className); + if (plugin.isAnnotationPresent(Plugin.class)) { + ret.put(plugin.getAnnotation(Plugin.class).value(), plugin); + } + } + return ret; + } catch (Exception e) { + e.printStackTrace(); + return null; + } + } + + public List getPluginInfo() { + try { + Map> plugins = this.getPlugins(); + List ret = new ArrayList(); + for (Class plugin : plugins.values()) { + PluginInfo pluginInfo = new PluginInfo(); + pluginInfo + .setName((plugin.getAnnotation(Plugin.class)).value()); + pluginInfo.setParameters(this.getParameters(plugin + .getConstructors()[0])); + Method[] behaviors = this.getBehaviors(plugin); + pluginInfo.setBehaviors(new BehaviorInfo[behaviors.length]); + int i = 0; + for (i = 0; i < behaviors.length; i++) { + Method behaviorMethod = behaviors[i]; + BehaviorInfo behaviorInfo = buildBehaviorInfo(behaviorMethod); + pluginInfo.getBehaviors()[i] = behaviorInfo; + } + ret.add(pluginInfo); + } + return ret; + } catch (Exception e) { + e.printStackTrace(); + return null; + } + } + + private BehaviorInfo buildBehaviorInfo(Method behaviorMethod) + throws ClassNotFoundException { + BehaviorInfo behaviorInfo = new BehaviorInfo(); + behaviorInfo.setName((behaviorMethod.getAnnotation(Behavior.class)) + .value()); + behaviorInfo.setParameters(this.getParameters(behaviorMethod)); + return behaviorInfo; + } + + private ParameterInfo[] getParameters(Method behavior) { + try { + int parameterCount = behavior.getParameterTypes().length; + Annotation[][] parameterAnnotations = behavior + .getParameterAnnotations(); + ParameterInfo[] parameterNames = new ParameterInfo[parameterCount]; + int i; + for (i = 0; i < parameterCount; i++) { + Annotation[] annotations = parameterAnnotations[i]; + Parameter parameter = (Parameter) annotations[0]; + Class type = behavior.getParameterTypes()[i]; + ParameterInfo parameterInfo = buildParameterInfo( + parameter.value(), type.getName()); + parameterNames[i] = parameterInfo; + } + return parameterNames; + } catch (Exception e) { + logger.error(DealWithLog.getExceptionStackTrace(e)); + return null; + } + } + + private ParameterInfo[] getParameters(Constructor behavior) { + try { + int parameterCount = behavior.getParameterTypes().length; + Annotation[][] parameterAnnotations = behavior + .getParameterAnnotations(); + ParameterInfo[] parameterNames = new ParameterInfo[parameterCount]; + int i; + for (i = 0; i < parameterCount; i++) { + Annotation[] annotations = parameterAnnotations[i]; + Parameter parameter = (Parameter) annotations[0]; + Class type = behavior.getParameterTypes()[i]; + ParameterInfo parameterInfo = buildParameterInfo( + parameter.value(), type.getName()); + parameterNames[i] = parameterInfo; + } + return parameterNames; + } catch (Exception e) { + e.printStackTrace(); + return null; + } + } + + private ParameterInfo buildParameterInfo(String name, String type) { + ParameterInfo parameterInfo = new ParameterInfo(); + parameterInfo.setName(name); + parameterInfo.setType(type); + return parameterInfo; + } + + private Method[] getBehaviors(Class plugin) { + try { + Method[] methods = plugin.getMethods(); + List ret = new ArrayList(); + int i = 0; + for (i = 0; i < methods.length; i++) { + if (methods[i].isAnnotationPresent(Behavior.class)) { + ret.add(methods[i]); + } + } + return ret.toArray(new Method[0]); + } catch (Exception e) { + e.printStackTrace(); + return null; + } + } + + public Object initializePlugin(Class plugin, + Map parameters) { + try { + Constructor[] ctConstructors = plugin.getConstructors(); + if (ctConstructors.length != 1) { + return null; + } + Constructor constructor = ctConstructors[0]; + Object[] params = prepareParameters(constructor, parameters); + return plugin.getConstructors()[0].newInstance(params); + } catch (Exception e) { + e.printStackTrace(); + return null; + } + } + + private Object[] prepareParameters(Constructor behavior, + Map parameters) { + try { + ParameterInfo[] parameterInfo = this.getParameters(behavior); + Object values[] = new Object[parameterInfo.length]; + int i = 0; + for (i = 0; i < parameterInfo.length; i++) { + Object value = parameters.get(parameterInfo[i].getName()); + if (value == null) { + values[i] = null; + } else { + values[i] = this.getTypeConverter().convert(value, + parameterInfo[i].getType()); + } + } + return values; + } catch (Exception e) { + e.printStackTrace(); + return null; + } + } + + private Object[] prepareParameters(Method behavior, + Map parameters) { + try { + ParameterInfo[] parameterInfo = this.getParameters(behavior); + Object values[] = new Object[parameterInfo.length]; + int i = 0; + for (i = 0; i < parameterInfo.length; i++) { + Object value = parameters.get(parameterInfo[i].getName()); + if (value == null) { + values[i] = null; + } else { + values[i] = this.getTypeConverter().convert(value, + parameterInfo[i].getType()); + } + } + return values; + } catch (Exception e) { + e.printStackTrace(); + return null; + } + } + + public Object doBehavior(Object plugin, String behaviorName, + Map parameters) { + try { + Method method = findMethod(plugin, behaviorName); + if (method == null) { + return null; + } + Object[] params = prepareParameters(method, parameters); + return method.invoke(plugin, params); + } catch (Exception e) { + + return null; + } + } + + private Method findMethod(Object plugin, String behaviorName) { + try { + Method[] methods = plugin.getClass().getMethods(); + int i = 0; + for (i = 0; i < methods.length; i++) { + if (methods[i].isAnnotationPresent(Behavior.class)) { + if (((Behavior) methods[i].getAnnotation(Behavior.class)) + .value().equals(behaviorName)) { + return methods[i]; + } + } + } + return null; + } catch (Exception e) { + e.printStackTrace(); + return null; + } + } +} diff --git a/Bench4Q-Agent/src/main/java/org/bench4q/agent/plugin/TypeConverter.java b/Bench4Q-Agent/src/main/java/org/bench4q/agent/plugin/TypeConverter.java new file mode 100644 index 00000000..8b6b29b0 --- /dev/null +++ b/Bench4Q-Agent/src/main/java/org/bench4q/agent/plugin/TypeConverter.java @@ -0,0 +1,44 @@ +package org.bench4q.agent.plugin; + +import org.springframework.stereotype.Component; + +@Component +public class TypeConverter { + public Object convert(Object source, String targetClassName) { + if (targetClassName.equals("boolean")) { + return Boolean.parseBoolean(source.toString()); + } + if (targetClassName.equals("char")) { + return source.toString().toCharArray()[0]; + } + if (targetClassName.equals("byte")) { + return Byte.parseByte(source.toString()); + } + if (targetClassName.equals("short")) { + return Short.parseShort(source.toString()); + } + if (targetClassName.equals("int")) { + return Integer.parseInt(source.toString()); + } + if (targetClassName.equals("long")) { + return Long.parseLong(source.toString()); + } + if (targetClassName.equals("float")) { + return Float.parseFloat(source.toString()); + } + if (targetClassName.equals("double")) { + return Double.parseDouble(source.toString()); + } + + try { + Class targetClass = Class.forName(targetClassName); + if (targetClass.isAssignableFrom(String.class)) { + return source.toString(); + } + return targetClass.cast(source); + } catch (Exception e) { + e.printStackTrace(); + return null; + } + } +} diff --git a/Bench4Q-Agent/src/main/java/org/bench4q/agent/plugin/basic/CommandLinePlugin.java b/Bench4Q-Agent/src/main/java/org/bench4q/agent/plugin/basic/CommandLinePlugin.java new file mode 100644 index 00000000..97072a39 --- /dev/null +++ b/Bench4Q-Agent/src/main/java/org/bench4q/agent/plugin/basic/CommandLinePlugin.java @@ -0,0 +1,89 @@ +package org.bench4q.agent.plugin.basic; + +import java.io.BufferedReader; +import java.io.InputStreamReader; + +import org.bench4q.agent.plugin.Behavior; +import org.bench4q.agent.plugin.Parameter; +import org.bench4q.agent.plugin.Plugin; +import org.bench4q.agent.plugin.result.CommandLineReturn; + +@Plugin("CommandLine") +public class CommandLinePlugin { + private String standardOutput; + private String standardError; + + public String getStandardOutput() { + return standardOutput; + } + + private void setStandardOutput(String standardOutput) { + this.standardOutput = standardOutput; + } + + public String getStandardError() { + return standardError; + } + + private void setStandardError(String standardError) { + this.standardError = standardError; + } + + public CommandLinePlugin() { + + } + + @Behavior("Command") + public CommandLineReturn command(@Parameter("command") String command) { + try { + final Process process = Runtime.getRuntime().exec(command); + new Thread() { + public void run() { + try { + BufferedReader reader = new BufferedReader( + new InputStreamReader(process.getInputStream())); + String streamline = ""; + try { + setStandardOutput(""); + while ((streamline = reader.readLine()) != null) { + setStandardOutput(getStandardOutput() + + streamline + + System.getProperty("line.separator")); + } + } finally { + reader.close(); + } + } catch (Exception e) { + e.printStackTrace(); + } + } + }.start(); + new Thread() { + public void run() { + try { + BufferedReader reader = new BufferedReader( + new InputStreamReader(process.getErrorStream())); + String streamline = ""; + try { + setStandardError(""); + while ((streamline = reader.readLine()) != null) { + setStandardError(getStandardError() + + streamline + + System.getProperty("line.separator")); + } + } finally { + reader.close(); + } + } catch (Exception e) { + e.printStackTrace(); + } + } + }.start(); + process.waitFor(); + return new CommandLineReturn(true); + } catch (Exception e) { + e.printStackTrace(); + return new CommandLineReturn(false); + } + } +} diff --git a/Bench4Q-Agent/src/main/java/org/bench4q/agent/plugin/basic/ConstantTimerPlugin.java b/Bench4Q-Agent/src/main/java/org/bench4q/agent/plugin/basic/ConstantTimerPlugin.java new file mode 100644 index 00000000..589d0b40 --- /dev/null +++ b/Bench4Q-Agent/src/main/java/org/bench4q/agent/plugin/basic/ConstantTimerPlugin.java @@ -0,0 +1,27 @@ +package org.bench4q.agent.plugin.basic; + +import org.apache.log4j.Logger; +import org.bench4q.agent.plugin.Behavior; +import org.bench4q.agent.plugin.Parameter; +import org.bench4q.agent.plugin.Plugin; +import org.bench4q.agent.plugin.result.TimerReturn; + +@Plugin("ConstantTimer") +public class ConstantTimerPlugin { + private Logger logger = Logger.getLogger(ConstantTimerPlugin.class); + + public ConstantTimerPlugin() { + + } + + @Behavior("Sleep") + public TimerReturn sleep(@Parameter("time") int time) { + try { + Thread.sleep(time); + return new TimerReturn(true); + } catch (Exception e) { + logger.info("sleep interrupted!"); + return new TimerReturn(false); + } + } +} diff --git a/Bench4Q-Agent/src/main/java/org/bench4q/agent/plugin/basic/LogPlugin.java b/Bench4Q-Agent/src/main/java/org/bench4q/agent/plugin/basic/LogPlugin.java new file mode 100644 index 00000000..473ef163 --- /dev/null +++ b/Bench4Q-Agent/src/main/java/org/bench4q/agent/plugin/basic/LogPlugin.java @@ -0,0 +1,19 @@ +package org.bench4q.agent.plugin.basic; + +import org.bench4q.agent.plugin.Behavior; +import org.bench4q.agent.plugin.Parameter; +import org.bench4q.agent.plugin.Plugin; +import org.bench4q.agent.plugin.result.LogReturn; + +@Plugin("Log") +public class LogPlugin { + public LogPlugin() { + + } + + @Behavior("Log") + public LogReturn log(@Parameter("message") String message) { + System.out.println(message); + return new LogReturn(true); + } +} diff --git a/Bench4Q-Agent/src/main/java/org/bench4q/agent/plugin/basic/http/HttpPlugin.java b/Bench4Q-Agent/src/main/java/org/bench4q/agent/plugin/basic/http/HttpPlugin.java new file mode 100644 index 00000000..3d41a5d9 --- /dev/null +++ b/Bench4Q-Agent/src/main/java/org/bench4q/agent/plugin/basic/http/HttpPlugin.java @@ -0,0 +1,339 @@ +/* + * Author Coderfengyun + * + * And th parmas has some special split. + * Like, QueryParams and bodyParams should be split by ';' + * And Headers should be split by '|;' + */ +package org.bench4q.agent.plugin.basic.http; + +import java.io.IOException; +import java.io.UnsupportedEncodingException; +import java.util.HashSet; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import org.apache.commons.httpclient.Cookie; +import org.apache.commons.httpclient.Header; +import org.apache.commons.httpclient.HttpClient; +import org.apache.commons.httpclient.HttpException; +import org.apache.commons.httpclient.HttpMethod; +import org.apache.commons.httpclient.NameValuePair; +import org.apache.commons.httpclient.methods.DeleteMethod; +import org.apache.commons.httpclient.methods.GetMethod; +import org.apache.commons.httpclient.methods.PostMethod; +import org.apache.commons.httpclient.methods.PutMethod; +import org.apache.commons.httpclient.methods.StringRequestEntity; +import org.bench4q.agent.plugin.Behavior; +import org.bench4q.agent.plugin.Parameter; +import org.bench4q.agent.plugin.Plugin; +import org.bench4q.agent.plugin.result.HttpReturn; +import org.bench4q.agent.scenario.util.ParameterParser; +import org.bench4q.agent.scenario.util.Table; + +@Plugin("Http") +public class HttpPlugin { + private HttpClient httpClient; + + public HttpClient getHttpClient() { + return httpClient; + } + + private void setHttpClient(HttpClient httpClient) { + this.httpClient = httpClient; + } + + public HttpPlugin() { + this.setHttpClient(new HttpClient()); + } + + void setHeaders(HttpMethod method, String headers) { + if (headers != null) { + List nvPairs = parseHeaders(headers); + for (NameValuePair nv : nvPairs) { + method.addRequestHeader(nv.getName(), nv.getValue()); + } + // New add + String cookieValue = ""; + for (Cookie cookie : this.getHttpClient().getState().getCookies()) { + if (!cookieValue.isEmpty()) { + cookieValue += ";"; + } + cookieValue += cookie.getName() + "=" + cookie.getValue(); + } + if (!cookieValue.isEmpty()) { + method.addRequestHeader("Cookie", cookieValue); + } + } + } + + List parseHeaders(String value) { + List nvPairs = new LinkedList(); + Table headerTable = ParameterParser.buildTable(value, + new LinkedList() { + private static final long serialVersionUID = 3498984411571605459L; + { + add("header"); + add("value"); + } + }); + for (List entry : headerTable.getRealContent()) { + if (entry.size() != headerTable.getColumnCount()) { + continue; + } + nvPairs.add(new NameValuePair(entry.get(0).trim(), entry.get(1) + .trim())); + } + return nvPairs; + } + + private static NameValuePair[] setInputParameters( + List inputParameters) { + Set res = new HashSet(); + Iterator paramIter = inputParameters.iterator(); + + while (paramIter.hasNext()) { + String token = paramIter.next(); + int index = token.indexOf('='); + res.add(new NameValuePair(token.substring(0, index), token + .substring(index + 1))); + } + return res.toArray(new NameValuePair[res.size()]); + } + + private static String completeUri(String uri) { + String scheme = uri.substring(0, 5); + if (!scheme.equals("http:") && !scheme.equals("https")) + uri = "http://" + uri; + return uri; + } + + /** + * + * @param url + * @param queryParams + * (NField) QueryParams should be split by ';' + * @param headers + * (Table)has two columns, such as header and value + * + * @param respVarsToSaveInSession + * (Table) has four columns, such as varName, + * varRegularExpression, leftBoundry, and rightBoundry + * @return + */ + @Behavior("Get") + public HttpReturn get(@Parameter("url") String url, + @Parameter("queryParams") String queryParams, + @Parameter("headers") String headers, + @Parameter("respVarsToSaveInSession") String respVarsToSaveInSession) { + + GetMethod method = new GetMethod(completeUri(url)); + if (isValid(queryParams)) { + method.setQueryString(queryParams); + } + setHeaders(method, headers); + method.getParams().makeLenient(); + method.setFollowRedirects(false); + return excuteMethod(method, respVarsToSaveInSession); + } + + private HttpReturn excuteMethod(HttpMethod method, + String respVarsToSaveInSession) { + int responseCode = -1; + long contentLength = 0; + String contentType = ""; + Map respVars = new LinkedHashMap(); + + try { + responseCode = this.getHttpClient().executeMethod(method); + method.getStatusLine().toString(); + Header[] responseHeaders = method.getResponseHeaders(); + if (method.getResponseHeader("Content-Length") != null) { + contentLength = Long.parseLong(method.getResponseHeader( + "Content-Length").getValue()); + } + if (method.getResponseHeader("Content-Type") != null) { + contentType = method.getResponseHeader("Content-Type") + .getValue(); + } + if (isValid(respVarsToSaveInSession)) { + respVars = doExtractResponseVariables(respVarsToSaveInSession, + method.getResponseBodyAsString()); + } + return new HttpReturn(responseCode > 0, responseCode, + contentLength, contentType, responseHeaders, respVars); + } catch (HttpException e) { + e.printStackTrace(); + return new HttpReturn(false, 400, contentLength, contentType); + } catch (IOException e) { + e.printStackTrace(); + return new HttpReturn(false, 400, contentLength, contentType); + } finally { + method.releaseConnection(); + } + } + + private Map doExtractResponseVariables( + String respVarsToSaveInSession, String responseBodyAsString) { + Map keyValues = new LinkedHashMap(); + List> varExtractExpressionList = ParameterParser + .buildTable(respVarsToSaveInSession, new LinkedList() { + private static final long serialVersionUID = -923211006660227362L; + { + add("varName"); + add("varRegularExpression"); + add("leftBoundry"); + add("rightBoundry"); + } + }).getRealContent(); + for (List row : varExtractExpressionList) { + keyValues.putAll(doExtractParamByRow(row, responseBodyAsString)); + } + return keyValues; + } + + private Map doExtractParamByRow(List row, + String responseBody) { + Map result = new LinkedHashMap(); + if (row.size() <= 3) { + return result; + } + String varName = row.get(0); + String varExpression = row.get(1); + String varLeftBoundry = row.get(2); + String varRightBoundry = row.get(3); + + if (!isValid(varExpression)) { + result.put( + varName, + extractExactlyValueWith(varLeftBoundry, varRightBoundry, + responseBody)); + return result; + } + + Matcher matcher = Pattern.compile(varExpression).matcher(responseBody); + if (!matcher.find()) { + result.put( + varName, + extractExactlyValueWith(varLeftBoundry, varRightBoundry, + responseBody)); + return result; + } + result.put( + varName, + extractExactlyValueWith(varLeftBoundry, varRightBoundry, + matcher.group())); + return result; + } + + private String extractExactlyValueWith(String varLeftBoundry, + String varRightBoundry, String matchedVariable) { + int indexOfLB = matchedVariable.indexOf(varLeftBoundry); + int indexOfRB = matchedVariable.indexOf(varRightBoundry); + return matchedVariable.substring(indexOfLB + varLeftBoundry.length(), + indexOfRB); + } + + /** + * + * @param url + * @param queryParams + * @param headers + * @param bodyContent + * , when the Content-Length in header G.T. zero, then use this + * @param bodyParams + * , else use this + * @return + */ + @Behavior("Post") + public HttpReturn post(@Parameter("url") String url, + @Parameter("queryParams") String queryParams, + @Parameter("headers") String headers, + @Parameter("bodyContent") String bodyContent, + @Parameter("bodyparameters") String bodyParams, + @Parameter("respVarsToSaveInSession") String respVarToSaveInSession) { + PostMethod method = new PostMethod(completeUri(url)); + setHeaders(method, headers); + if (isValid(queryParams)) { + method.setQueryString(setInputParameters(ParameterParser + .buildNField(queryParams))); + } + if (isValid(bodyParams)) { + method.setRequestBody(setInputParameters(ParameterParser + .buildNField(bodyParams))); + } + String contentType = getMethodContentType(method); + if (isValid(bodyContent) && isValid(contentType)) { + try { + method.setRequestEntity(new StringRequestEntity(bodyContent, + contentType, null)); + } catch (Exception ex) { + ex.printStackTrace(); + } + } + method.getParams().makeLenient(); + method.setFollowRedirects(false); + return excuteMethod(method, respVarToSaveInSession); + } + + private String getMethodContentType(HttpMethod method) { + Header contentTypeHeader = method.getRequestHeader("Content-Type"); + String contentType = null; + if (contentTypeHeader != null + && !contentTypeHeader.toExternalForm().isEmpty()) { + contentType = contentTypeHeader.toExternalForm(); + } + return contentType; + } + + private boolean isValid(String content) { + return content != null && content.length() != 0; + } + + @Behavior("Put") + public HttpReturn put(@Parameter("url") String url, + @Parameter("queryParams") String queryParams, + @Parameter("headers") String headers, + @Parameter("bodyContent") String bodyContent, + @Parameter("bodyparameters") String bodyParams, + @Parameter("respVarsToSaveInSession") String respVarToSaveInSession) { + PutMethod method = new PutMethod(completeUri(url)); + setHeaders(method, headers); + if (isValid(queryParams)) { + method.setQueryString(setInputParameters(ParameterParser + .buildNField(queryParams))); + } + String contentType = getMethodContentType(method); + if (isValid(bodyContent) && isValid(contentType)) { + try { + method.setRequestEntity(new StringRequestEntity(bodyContent, + contentType, null)); + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + } + } + method.getParams().makeLenient(); + return excuteMethod(method, respVarToSaveInSession); + } + + @Behavior("Delete") + public HttpReturn delete(@Parameter("url") String url, + @Parameter("queryParams") String queryParams, + @Parameter("headers") String headers, + @Parameter("respVarsToSaveInSession") String respVarToSaveInSession) { + DeleteMethod method = new DeleteMethod(completeUri(url)); + setHeaders(method, headers); + if (isValid(queryParams)) { + method.setQueryString(setInputParameters(ParameterParser + .buildNField(queryParams))); + } + method.getParams().makeLenient(); + return excuteMethod(method, respVarToSaveInSession); + } +} diff --git a/Bench4Q-Agent/src/main/java/org/bench4q/agent/plugin/basic/http/ParameterConstant.java b/Bench4Q-Agent/src/main/java/org/bench4q/agent/plugin/basic/http/ParameterConstant.java new file mode 100644 index 00000000..691565f5 --- /dev/null +++ b/Bench4Q-Agent/src/main/java/org/bench4q/agent/plugin/basic/http/ParameterConstant.java @@ -0,0 +1,5 @@ +package org.bench4q.agent.plugin.basic.http; + +public class ParameterConstant { + public static final String escape = "\\"; +} diff --git a/Bench4Q-Agent/src/main/java/org/bench4q/agent/plugin/result/CommandLineReturn.java b/Bench4Q-Agent/src/main/java/org/bench4q/agent/plugin/result/CommandLineReturn.java new file mode 100644 index 00000000..15679f69 --- /dev/null +++ b/Bench4Q-Agent/src/main/java/org/bench4q/agent/plugin/result/CommandLineReturn.java @@ -0,0 +1,7 @@ +package org.bench4q.agent.plugin.result; + +public class CommandLineReturn extends PluginReturn { + public CommandLineReturn(boolean success) { + this.setSuccess(success); + } +} diff --git a/Bench4Q-Agent/src/main/java/org/bench4q/agent/plugin/result/HttpReturn.java b/Bench4Q-Agent/src/main/java/org/bench4q/agent/plugin/result/HttpReturn.java new file mode 100644 index 00000000..bee2dcce --- /dev/null +++ b/Bench4Q-Agent/src/main/java/org/bench4q/agent/plugin/result/HttpReturn.java @@ -0,0 +1,66 @@ +package org.bench4q.agent.plugin.result; + +import java.util.Map; + +import org.apache.commons.httpclient.Header; + +/*** + * the contentLength's unit is Byte + * + * @author coderfengyun + * + */ +public class HttpReturn extends PluginReturn { + private int statusCode; + private long contentLength; + private String contentType; + private Header[] headers; + + public int getStatusCode() { + return statusCode; + } + + private void setStatusCode(int statusCode) { + this.statusCode = statusCode; + } + + public long getContentLength() { + return contentLength; + } + + private void setContentLength(long contentLength) { + this.contentLength = contentLength; + } + + public String getContentType() { + return contentType; + } + + private void setContentType(String contentType) { + this.contentType = contentType; + } + + public Header[] getHeaders() { + return headers; + } + + private void setHeaders(Header[] headers) { + this.headers = headers; + } + + public HttpReturn(boolean success, int statusCode, long contentLength, + String contentType) { + this.setSuccess(success); + this.setStatusCode(statusCode); + this.setContentLength(contentLength); + this.setContentType(contentType); + } + + public HttpReturn(boolean success, int responseCode, long contentLength2, + String contentType2, Header[] responseHeaders, + Map runTimeParams) { + this(success, responseCode, contentLength2, contentType2); + this.setHeaders(responseHeaders); + this.getRunTimeParams().putAll(runTimeParams); + } +} diff --git a/Bench4Q-Agent/src/main/java/org/bench4q/agent/plugin/result/LogReturn.java b/Bench4Q-Agent/src/main/java/org/bench4q/agent/plugin/result/LogReturn.java new file mode 100644 index 00000000..d26ff1eb --- /dev/null +++ b/Bench4Q-Agent/src/main/java/org/bench4q/agent/plugin/result/LogReturn.java @@ -0,0 +1,7 @@ +package org.bench4q.agent.plugin.result; + +public class LogReturn extends PluginReturn { + public LogReturn(boolean success) { + this.setSuccess(success); + } +} diff --git a/Bench4Q-Agent/src/main/java/org/bench4q/agent/plugin/result/PluginReturn.java b/Bench4Q-Agent/src/main/java/org/bench4q/agent/plugin/result/PluginReturn.java new file mode 100644 index 00000000..b931dcb0 --- /dev/null +++ b/Bench4Q-Agent/src/main/java/org/bench4q/agent/plugin/result/PluginReturn.java @@ -0,0 +1,29 @@ +package org.bench4q.agent.plugin.result; + +import java.util.LinkedHashMap; +import java.util.Map; + +public abstract class PluginReturn { + private boolean success; + private Map runTimeParams; + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public Map getRunTimeParams() { + return runTimeParams; + } + + public void setRunTimeParams(Map runTimeParams) { + this.runTimeParams = runTimeParams; + } + + public PluginReturn() { + this.setRunTimeParams(new LinkedHashMap()); + } +} diff --git a/Bench4Q-Agent/src/main/java/org/bench4q/agent/plugin/result/TimerReturn.java b/Bench4Q-Agent/src/main/java/org/bench4q/agent/plugin/result/TimerReturn.java new file mode 100644 index 00000000..9f3ecad0 --- /dev/null +++ b/Bench4Q-Agent/src/main/java/org/bench4q/agent/plugin/result/TimerReturn.java @@ -0,0 +1,12 @@ +package org.bench4q.agent.plugin.result; + +/** + * + * @author coderfengyun + * + */ +public class TimerReturn extends PluginReturn { + public TimerReturn(boolean success) { + this.setSuccess(success); + } +} diff --git a/Bench4Q-Agent/src/main/java/org/bench4q/agent/scenario/Batch.java b/Bench4Q-Agent/src/main/java/org/bench4q/agent/scenario/Batch.java new file mode 100644 index 00000000..f05a3a2f --- /dev/null +++ b/Bench4Q-Agent/src/main/java/org/bench4q/agent/scenario/Batch.java @@ -0,0 +1,43 @@ +package org.bench4q.agent.scenario; + +import org.bench4q.agent.scenario.behavior.Behavior; + +public class Batch { + private int id; + private int parentId; + private int childId; + private Behavior[] behaviors; + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public int getParentId() { + return parentId; + } + + public void setParentId(int parentId) { + this.parentId = parentId; + } + + public int getChildId() { + return childId; + } + + public void setChildId(int childId) { + this.childId = childId; + } + + public Behavior[] getBehaviors() { + return behaviors; + } + + public void setBehaviors(Behavior[] behaviors) { + this.behaviors = behaviors; + } + +} diff --git a/Bench4Q-Agent/src/main/java/org/bench4q/agent/scenario/BehaviorResult.java b/Bench4Q-Agent/src/main/java/org/bench4q/agent/scenario/BehaviorResult.java new file mode 100644 index 00000000..3311f076 --- /dev/null +++ b/Bench4Q-Agent/src/main/java/org/bench4q/agent/scenario/BehaviorResult.java @@ -0,0 +1,125 @@ +package org.bench4q.agent.scenario; + +import java.util.Date; + +public class BehaviorResult { + private String pluginId; + private String pluginName; + private String behaviorName; + private Date startDate; + private Date endDate; + private long responseTime; + private boolean success; + + private int behaviorId; + private String behaviorUrl; + private long contentLength; + private int statusCode; + private String contentType; + private boolean shouldBeCountResponseTime; + + public String getPluginId() { + return pluginId; + } + + public void setPluginId(String pluginId) { + this.pluginId = pluginId; + } + + public String getPluginName() { + return pluginName; + } + + public void setPluginName(String pluginName) { + this.pluginName = pluginName; + } + + public String getBehaviorName() { + return behaviorName; + } + + public void setBehaviorName(String behaviorName) { + this.behaviorName = behaviorName; + } + + public Date getStartDate() { + return startDate; + } + + public void setStartDate(Date startDate) { + this.startDate = startDate; + } + + public Date getEndDate() { + return endDate; + } + + public void setEndDate(Date endDate) { + this.endDate = endDate; + } + + public long getResponseTime() { + return responseTime; + } + + public void setResponseTime(long responseTime) { + this.responseTime = responseTime; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public int getBehaviorId() { + return behaviorId; + } + + public void setBehaviorId(int behaviorId) { + this.behaviorId = behaviorId; + } + + public String getBehaviorUrl() { + return behaviorUrl; + } + + public void setBehaviorUrl(String behaviorUrl) { + this.behaviorUrl = behaviorUrl; + } + + public long getContentLength() { + return contentLength; + } + + public void setContentLength(long contentLength) { + this.contentLength = contentLength; + } + + public int getStatusCode() { + return statusCode; + } + + public void setStatusCode(int statusCode) { + this.statusCode = statusCode; + } + + public String getContentType() { + return contentType; + } + + public void setContentType(String contentType) { + this.contentType = contentType; + } + + public boolean isShouldBeCountResponseTime() { + return shouldBeCountResponseTime; + } + + public void setShouldBeCountResponseTime(boolean shouldBeCountResponseTime) { + this.shouldBeCountResponseTime = shouldBeCountResponseTime; + } + +} diff --git a/Bench4Q-Agent/src/main/java/org/bench4q/agent/scenario/Page.java b/Bench4Q-Agent/src/main/java/org/bench4q/agent/scenario/Page.java new file mode 100644 index 00000000..f03f9e77 --- /dev/null +++ b/Bench4Q-Agent/src/main/java/org/bench4q/agent/scenario/Page.java @@ -0,0 +1,22 @@ +package org.bench4q.agent.scenario; + +import org.bench4q.agent.datacollector.DataCollector; +import org.bench4q.agent.datacollector.impl.PageResultCollector; + +public class Page { + private Batch[] batches; + final private DataCollector dataCollector = new PageResultCollector(); + + public Batch[] getBatches() { + return batches; + } + + public void setBatches(Batch[] batches) { + this.batches = batches; + } + + public DataCollector getDataCollector() { + return dataCollector; + } + +} diff --git a/Bench4Q-Agent/src/main/java/org/bench4q/agent/scenario/PageResult.java b/Bench4Q-Agent/src/main/java/org/bench4q/agent/scenario/PageResult.java new file mode 100644 index 00000000..fcadd468 --- /dev/null +++ b/Bench4Q-Agent/src/main/java/org/bench4q/agent/scenario/PageResult.java @@ -0,0 +1,77 @@ +package org.bench4q.agent.scenario; + +import java.util.ArrayList; +import java.util.List; + +public class PageResult { + private int pageId; + private long pageStartTime; + private long pageEndTime; + private long executeRange; + + public int getPageId() { + return pageId; + } + + private void setPageId(int pageId) { + this.pageId = pageId; + } + + public long getPageStartTime() { + return pageStartTime; + } + + private void setPageStartTime(long pageStartTime) { + this.pageStartTime = pageStartTime; + } + + public long getPageEndTime() { + return pageEndTime; + } + + private void setPageEndTime(long pageEndTime) { + this.pageEndTime = pageEndTime; + } + + public long getExecuteRange() { + return executeRange; + } + + private void setExecuteRange(long executeRange) { + this.executeRange = executeRange; + } + + private PageResult() { + init(); + } + + private void init() { + this.setPageStartTime(Long.MAX_VALUE); + this.setPageEndTime(Long.MIN_VALUE); + this.setExecuteRange(0); + } + + public static PageResult buildPageResult(int pageId, + List behaviorResults) { + PageResult result = new PageResult(); + result.setPageId(pageId); + if (behaviorResults == null) { + behaviorResults = new ArrayList(); + } + for (BehaviorResult behaviorResult : behaviorResults) { + if (behaviorResult.getStartDate().getTime() < result + .getPageStartTime()) { + result.setPageStartTime(behaviorResult.getStartDate().getTime()); + } + if (behaviorResult.getEndDate().getTime() > result.getPageEndTime()) { + result.setPageEndTime(behaviorResult.getEndDate().getTime()); + } + // Page excuteRange rely on the behaviors' execute way, if it's + // executed in batch, i should take the longest behavior in batch + // to calculate this One. + } + result.setExecuteRange(result.getPageEndTime() + - result.getPageStartTime()); + return result; + } +} diff --git a/Bench4Q-Agent/src/main/java/org/bench4q/agent/scenario/Parameter.java b/Bench4Q-Agent/src/main/java/org/bench4q/agent/scenario/Parameter.java new file mode 100644 index 00000000..10785505 --- /dev/null +++ b/Bench4Q-Agent/src/main/java/org/bench4q/agent/scenario/Parameter.java @@ -0,0 +1,23 @@ +package org.bench4q.agent.scenario; + +public class Parameter { + private String key; + private String value; + + public String getKey() { + return key; + } + + public void setKey(String key) { + this.key = key; + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + +} diff --git a/Bench4Q-Agent/src/main/java/org/bench4q/agent/scenario/Scenario.java b/Bench4Q-Agent/src/main/java/org/bench4q/agent/scenario/Scenario.java new file mode 100644 index 00000000..04983540 --- /dev/null +++ b/Bench4Q-Agent/src/main/java/org/bench4q/agent/scenario/Scenario.java @@ -0,0 +1,176 @@ +package org.bench4q.agent.scenario; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import org.bench4q.agent.scenario.behavior.Behavior; +import org.bench4q.agent.scenario.behavior.BehaviorFactory; +import org.bench4q.share.helper.MarshalHelper; +import org.bench4q.share.models.agent.ParameterModel; +import org.bench4q.share.models.agent.RunScenarioModel; +import org.bench4q.share.models.agent.scriptrecord.BatchModel; +import org.bench4q.share.models.agent.scriptrecord.BehaviorModel; +import org.bench4q.share.models.agent.scriptrecord.PageModel; +import org.bench4q.share.models.agent.scriptrecord.UsePluginModel; + +public class Scenario { + private UsePlugin[] usePlugins; + private Page[] pages; + private List behaviors; + + public UsePlugin[] getUsePlugins() { + return usePlugins; + } + + public void setUsePlugins(UsePlugin[] usePlugins) { + this.usePlugins = usePlugins; + } + + public Page[] getPages() { + return pages; + } + + public void setPages(Page[] pages) { + this.pages = pages; + } + + private List getBehaviors() { + return behaviors; + } + + private void setBehaviors(List behaviors) { + this.behaviors = behaviors; + } + + public Scenario() { + this.setBehaviors(new ArrayList()); + } + + public List getAllBehaviorsInScenario() { + if (this.getBehaviors().size() > 0) { + return Collections.unmodifiableList(this.getBehaviors()); + } + List behaviors = new ArrayList(); + for (Page page : this.getPages()) { + for (Batch batch : page.getBatches()) { + for (Behavior behavior : batch.getBehaviors()) { + behaviors.add(behavior); + } + } + } + return Collections.unmodifiableList(behaviors); + } + + public static Scenario scenarioBuilder(String scenarioContent) { + return extractScenario((RunScenarioModel) MarshalHelper.tryUnmarshal( + RunScenarioModel.class, scenarioContent)); + } + + public static Scenario scenarioBuilder(RunScenarioModel scenarioModel) { + if (scenarioModel == null) { + throw new NullPointerException(); + } + Scenario scenario = extractScenario(scenarioModel); + return scenario; + } + + private static Scenario extractScenario(RunScenarioModel runScenarioModel) { + Scenario scenario = new Scenario(); + scenario.setUsePlugins(new UsePlugin[runScenarioModel.getUsePlugins() + .size()]); + scenario.setPages(new Page[runScenarioModel.getPages().size()]); + extractUsePlugins(runScenarioModel, scenario); + extractPages(runScenarioModel, scenario); + return scenario; + } + + private static void extractPages(RunScenarioModel runScenarioModel, + Scenario scenario) { + List pageModels = runScenarioModel.getPages(); + for (int i = 0; i < pageModels.size(); i++) { + PageModel pageModel = pageModels.get(i); + scenario.getPages()[i] = extractPage(pageModel); + } + } + + private static Page extractPage(PageModel pageModel) { + Page page = new Page(); + page.setBatches(new Batch[pageModel.getBatches().size()]); + List batches = pageModel.getBatches(); + for (int i = 0; i < pageModel.getBatches().size(); i++) { + BatchModel batch = batches.get(i); + page.getBatches()[i] = extractBatch(batch); + } + return page; + } + + private static Batch extractBatch(BatchModel batchModel) { + Batch batch = new Batch(); + batch.setBehaviors(new Behavior[batchModel.getBehaviors().size()]); + batch.setId(batchModel.getId()); + batch.setParentId(batchModel.getParentId()); + batch.setChildId(batchModel.getChildId()); + if (batchModel.getBehaviors() == null) { + return batch; + } + batch.setBehaviors(new Behavior[batchModel.getBehaviors().size()]); + for (int i = 0; i < batchModel.getBehaviors().size(); ++i) { + batch.getBehaviors()[i] = extractBehavior(batchModel.getBehaviors() + .get(i)); + } + return batch; + } + + private static void extractUsePlugins(RunScenarioModel runScenarioModel, + Scenario scenario) { + int i; + List usePluginModels = runScenarioModel.getUsePlugins(); + for (i = 0; i < runScenarioModel.getUsePlugins().size(); i++) { + UsePluginModel usePluginModel = usePluginModels.get(i); + UsePlugin usePlugin = extractUsePlugin(usePluginModel); + scenario.getUsePlugins()[i] = usePlugin; + } + } + + private static Behavior extractBehavior(BehaviorModel behaviorModel) { + Behavior behavior = BehaviorFactory.getBuisinessObject(behaviorModel); + behavior.setName(behaviorModel.getName()); + behavior.setUse(behaviorModel.getUse()); + behavior.setId(behaviorModel.getId()); + behavior.setParameters(new Parameter[behaviorModel.getParameters() + .size()]); + + int k = 0; + for (k = 0; k < behaviorModel.getParameters().size(); k++) { + ParameterModel parameterModel = behaviorModel.getParameters() + .get(k); + Parameter parameter = extractParameter(parameterModel); + behavior.getParameters()[k] = parameter; + } + return behavior; + } + + private static UsePlugin extractUsePlugin(UsePluginModel usePluginModel) { + UsePlugin usePlugin = new UsePlugin(); + usePlugin.setId(usePluginModel.getId()); + usePlugin.setName(usePluginModel.getName()); + usePlugin.setParameters(new Parameter[usePluginModel.getParameters() + .size()]); + int k = 0; + for (k = 0; k < usePluginModel.getParameters().size(); k++) { + ParameterModel parameterModel = usePluginModel.getParameters().get( + k); + Parameter parameter = extractParameter(parameterModel); + usePlugin.getParameters()[k] = parameter; + } + return usePlugin; + } + + private static Parameter extractParameter(ParameterModel parameterModel) { + Parameter parameter = new Parameter(); + parameter.setKey(parameterModel.getKey()); + parameter.setValue(parameterModel.getValue()); + return parameter; + } +} diff --git a/Bench4Q-Agent/src/main/java/org/bench4q/agent/scenario/ScenarioContext.java b/Bench4Q-Agent/src/main/java/org/bench4q/agent/scenario/ScenarioContext.java new file mode 100644 index 00000000..f3454810 --- /dev/null +++ b/Bench4Q-Agent/src/main/java/org/bench4q/agent/scenario/ScenarioContext.java @@ -0,0 +1,84 @@ +package org.bench4q.agent.scenario; + +import java.util.Date; +import java.util.UUID; +import java.util.concurrent.SynchronousQueue; +import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.ThreadPoolExecutor.DiscardPolicy; + +import org.bench4q.agent.datacollector.DataCollector; +import org.bench4q.agent.datacollector.impl.ScenarioResultCollector; + +public class ScenarioContext { + private static final long keepAliveTime = 10; + private Date startDate; + private Date endDate; + private ThreadPoolExecutor executor; + private Scenario scenario; + private boolean finished; + private DataCollector dataStatistics; + + public Date getStartDate() { + return startDate; + } + + public void setStartDate(Date saveStartDate) { + this.startDate = saveStartDate; + } + + public Date getEndDate() { + return endDate; + } + + public void setEndDate(Date endDate) { + this.endDate = endDate; + } + + public ThreadPoolExecutor getExecutor() { + return executor; + } + + public void setExecutorService(ThreadPoolExecutor executor) { + this.executor = executor; + } + + public Scenario getScenario() { + return scenario; + } + + public void setScenario(Scenario scenario) { + this.scenario = scenario; + } + + public boolean isFinished() { + return finished; + } + + public void setFinished(boolean finished) { + this.finished = finished; + } + + public DataCollector getDataStatistics() { + return dataStatistics; + } + + private void setDataStatistics(DataCollector dataStatistics) { + this.dataStatistics = dataStatistics; + } + + public static ScenarioContext buildScenarioContext(UUID testId, + final Scenario scenario, int poolSize) { + ScenarioContext scenarioContext = new ScenarioContext(); + final SynchronousQueue workQueue = new SynchronousQueue(); + ThreadPoolExecutor executor = new ThreadPoolExecutor(poolSize, + poolSize, keepAliveTime, TimeUnit.MINUTES, workQueue, + new DiscardPolicy()); + scenarioContext.setScenario(scenario); + scenarioContext.setStartDate(new Date(System.currentTimeMillis())); + scenarioContext.setExecutorService(executor); + scenarioContext.setDataStatistics(new ScenarioResultCollector(testId)); + return scenarioContext; + } + +} diff --git a/Bench4Q-Agent/src/main/java/org/bench4q/agent/scenario/ScenarioEngine.java b/Bench4Q-Agent/src/main/java/org/bench4q/agent/scenario/ScenarioEngine.java new file mode 100644 index 00000000..141b1e23 --- /dev/null +++ b/Bench4Q-Agent/src/main/java/org/bench4q/agent/scenario/ScenarioEngine.java @@ -0,0 +1,92 @@ +package org.bench4q.agent.scenario; + +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import org.apache.log4j.Logger; +import org.bench4q.agent.parameterization.impl.InstanceControler; +import org.bench4q.agent.storage.StorageHelper; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +@Component +public class ScenarioEngine { + private Map runningTests; + private StorageHelper storageHelper; + private Logger logger; + + @SuppressWarnings("unused") + private Logger getLogger() { + return logger; + } + + private void setLogger(Logger logger) { + this.logger = logger; + } + + public ScenarioEngine() { + this.setRunningTests(new HashMap()); + this.setLogger(Logger.getLogger(ScenarioEngine.class)); + } + + public StorageHelper getStorageHelper() { + return storageHelper; + } + + @Autowired + public void setStorageHelper(StorageHelper storageHelper) { + this.storageHelper = storageHelper; + } + + public Map getRunningTests() { + return runningTests; + } + + private void setRunningTests(Map runningTests) { + this.runningTests = runningTests; + } + + public void submitScenario(UUID runId, final Scenario scenario, int poolSize) { + try { + final ScenarioContext scenarioContext = ScenarioContext + .buildScenarioContext(runId, scenario, poolSize); + this.getRunningTests().put(runId, scenarioContext); + + System.out.println(poolSize); + + } catch (Exception e) { + e.printStackTrace(); + } + } + + public boolean runWith(UUID runId) { + if (!this.getRunningTests().containsKey(runId)) { + return false; + } + final ScenarioContext context = this.getRunningTests().get(runId); + return runWith(context); + } + + private boolean runWith(final ScenarioContext scenarioContext) { + if (scenarioContext == null) { + logger.error("The context required is null"); + return false; + } + ExecutorService taskMaker = Executors.newSingleThreadExecutor(); + + taskMaker.execute(new Runnable() { + public void run() { + while (!scenarioContext.isFinished()) { + scenarioContext.getExecutor() + .execute( + new Worker(scenarioContext, + new InstanceControler())); + } + } + }); + return true; + } + +} diff --git a/Bench4Q-Agent/src/main/java/org/bench4q/agent/scenario/SessionContext.java b/Bench4Q-Agent/src/main/java/org/bench4q/agent/scenario/SessionContext.java new file mode 100644 index 00000000..ac9813bf --- /dev/null +++ b/Bench4Q-Agent/src/main/java/org/bench4q/agent/scenario/SessionContext.java @@ -0,0 +1,28 @@ +package org.bench4q.agent.scenario; + +import java.util.HashMap; +import java.util.Map; + +public class SessionContext { + Map variables; + + private Map getVariables() { + return variables; + } + + private void setVariables(Map variables) { + this.variables = variables; + } + + public SessionContext() { + this.setVariables(new HashMap()); + } + + public void addAVariable(String entryName, String entryValue) { + this.getVariables().put(entryName, entryValue); + } + + public String getVariable(String entryName) { + return this.getVariable(entryName); + } +} diff --git a/Bench4Q-Agent/src/main/java/org/bench4q/agent/scenario/TestResult.java b/Bench4Q-Agent/src/main/java/org/bench4q/agent/scenario/TestResult.java new file mode 100644 index 00000000..6457ca30 --- /dev/null +++ b/Bench4Q-Agent/src/main/java/org/bench4q/agent/scenario/TestResult.java @@ -0,0 +1,111 @@ +package org.bench4q.agent.scenario; + +import java.io.Serializable; +import java.util.Date; +import java.util.List; +import java.util.UUID; + +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlElementWrapper; +import javax.xml.bind.annotation.XmlRootElement; + +@XmlRootElement(name = "testResult") +public class TestResult implements Serializable { + private static final long serialVersionUID = -370091935554266546L; + private UUID runId; + private int poolSize; + private int totalCount; + private Date startDate; + private long elapsedTime; + private int successCount; + private int failCount; + private int finishedCount; + private double averageResponseTime; + private List results; + + @XmlElement + public UUID getRunId() { + return runId; + } + + public void setRunId(UUID runId) { + this.runId = runId; + } + + @XmlElement + public int getPoolSize() { + return poolSize; + } + + public void setPoolSize(int poolSize) { + this.poolSize = poolSize; + } + + @XmlElement + public int getTotalCount() { + return totalCount; + } + + public void setTotalCount(int totalCount) { + this.totalCount = totalCount; + } + + @XmlElement + public Date getStartDate() { + return startDate; + } + + public void setStartDate(Date startDate) { + this.startDate = startDate; + } + + public long getElapsedTime() { + return elapsedTime; + } + + public void setElapsedTime(long elapsedTime) { + this.elapsedTime = elapsedTime; + } + + public int getSuccessCount() { + return successCount; + } + + public void setSuccessCount(int successCount) { + this.successCount = successCount; + } + + public int getFailCount() { + return failCount; + } + + public void setFailCount(int failCount) { + this.failCount = failCount; + } + + public int getFinishedCount() { + return finishedCount; + } + + public void setFinishedCount(int finishedCount) { + this.finishedCount = finishedCount; + } + + public double getAverageResponseTime() { + return averageResponseTime; + } + + public void setAverageResponseTime(double averageResponseTime) { + this.averageResponseTime = averageResponseTime; + } + + @XmlElementWrapper(name = "results") + @XmlElement(name = "result") + public List getResults() { + return results; + } + + public void setResults(List results) { + this.results = results; + } +} diff --git a/Bench4Q-Agent/src/main/java/org/bench4q/agent/scenario/TestResultItem.java b/Bench4Q-Agent/src/main/java/org/bench4q/agent/scenario/TestResultItem.java new file mode 100644 index 00000000..39481fa8 --- /dev/null +++ b/Bench4Q-Agent/src/main/java/org/bench4q/agent/scenario/TestResultItem.java @@ -0,0 +1,93 @@ +package org.bench4q.agent.scenario; + +import java.io.Serializable; +import java.util.Date; +import java.util.UUID; + +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; + +@XmlRootElement(name = "testResultItem") +public class TestResultItem implements Serializable { + private static final long serialVersionUID = 3307951299814477213L; + private UUID id; + private String pluginId; + private String pluginName; + private String behaviorName; + private Date startDate; + private Date endDate; + private long responseTime; + private boolean success; + + @XmlElement + public UUID getId() { + return id; + } + + public void setId(UUID id) { + this.id = id; + } + + @XmlElement + public String getPluginId() { + return pluginId; + } + + public void setPluginId(String pluginId) { + this.pluginId = pluginId; + } + + @XmlElement + public String getPluginName() { + return pluginName; + } + + public void setPluginName(String pluginName) { + this.pluginName = pluginName; + } + + @XmlElement + public String getBehaviorName() { + return behaviorName; + } + + public void setBehaviorName(String behaviorName) { + this.behaviorName = behaviorName; + } + + @XmlElement + public Date getStartDate() { + return startDate; + } + + public void setStartDate(Date startDate) { + this.startDate = startDate; + } + + @XmlElement + public Date getEndDate() { + return endDate; + } + + public void setEndDate(Date endDate) { + this.endDate = endDate; + } + + @XmlElement + public long getResponseTime() { + return responseTime; + } + + public void setResponseTime(long responseTime) { + this.responseTime = responseTime; + } + + @XmlElement + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } +} diff --git a/Bench4Q-Agent/src/main/java/org/bench4q/agent/scenario/UsePlugin.java b/Bench4Q-Agent/src/main/java/org/bench4q/agent/scenario/UsePlugin.java new file mode 100644 index 00000000..3e7379dd --- /dev/null +++ b/Bench4Q-Agent/src/main/java/org/bench4q/agent/scenario/UsePlugin.java @@ -0,0 +1,32 @@ +package org.bench4q.agent.scenario; + +public class UsePlugin { + private String id; + private String name; + private Parameter[] parameters; + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public Parameter[] getParameters() { + return parameters; + } + + public void setParameters(Parameter[] parameters) { + this.parameters = parameters; + } + +} diff --git a/Bench4Q-Agent/src/main/java/org/bench4q/agent/scenario/Worker.java b/Bench4Q-Agent/src/main/java/org/bench4q/agent/scenario/Worker.java new file mode 100644 index 00000000..587bcc04 --- /dev/null +++ b/Bench4Q-Agent/src/main/java/org/bench4q/agent/scenario/Worker.java @@ -0,0 +1,168 @@ +package org.bench4q.agent.scenario; + +import java.util.ArrayList; +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.bench4q.agent.datacollector.DataCollector; +import org.bench4q.agent.helper.ApplicationContextHelper; +import org.bench4q.agent.parameterization.SessionObject; +import org.bench4q.agent.plugin.Plugin; +import org.bench4q.agent.plugin.PluginManager; +import org.bench4q.agent.plugin.result.HttpReturn; +import org.bench4q.agent.plugin.result.PluginReturn; +import org.bench4q.agent.scenario.behavior.Behavior; + +public class Worker implements Runnable { + private ScenarioContext scenarioContext; + private SessionObject sessionObject; + + private PluginManager pluginManager; + + private ScenarioContext getScenarioContext() { + return scenarioContext; + } + + private void setScenarioContext(ScenarioContext scenarioContext) { + this.scenarioContext = scenarioContext; + } + + private SessionObject getSessionObject() { + return sessionObject; + } + + private void setSessionObject(SessionObject sessionObject) { + this.sessionObject = sessionObject; + } + + private PluginManager getPluginManager() { + return pluginManager; + } + + private void setPluginManager(PluginManager pluginManager) { + this.pluginManager = pluginManager; + } + + public Worker(ScenarioContext scenarioContext, SessionObject sessionObject) { + this.setScenarioContext(scenarioContext); + this.setPluginManager(ApplicationContextHelper.getContext().getBean( + PluginManager.class)); + this.setSessionObject(sessionObject); + } + + public void run() { + doRunScenario(getScenarioContext()); + doCleanUp(); + } + + private void doCleanUp() { + this.sessionObject.doCleanUp(); + } + + public void doRunScenario(ScenarioContext context) { + Map plugins = new HashMap(); + preparePlugins(context.getScenario(), plugins); + for (int i = 0; i < context.getScenario().getPages().length; i++) { + Page page = context.getScenario().getPages()[i]; + context.getDataStatistics().add( + PageResult.buildPageResult( + i, + doRunBatchesInPage(plugins, page, + context.getDataStatistics()))); + } + + } + + private List doRunBatchesInPage( + Map plugins, Page page, DataCollector dataCollector) { + List results = new ArrayList(); + for (Batch batch : page.getBatches()) { + results.addAll(doRunBatch(plugins, batch, dataCollector)); + } + return results; + } + + private List doRunBatch(Map plugins, + Batch batch, DataCollector dataCollector) { + List results = new ArrayList(); + for (Behavior behavior : batch.getBehaviors()) { + // each execution should call this + behavior.distillParams(this.getSessionObject()); + Object plugin = plugins.get(behavior.getUse()); + Map behaviorParameters = prepareBehaviorParameters(behavior); + Date startDate = new Date(System.currentTimeMillis()); + PluginReturn pluginReturn = (PluginReturn) this.getPluginManager() + .doBehavior(plugin, behavior.getName(), behaviorParameters); + extractRunTimeParams(pluginReturn); + Date endDate = new Date(System.currentTimeMillis()); + if (!behavior.shouldBeCountResponseTime()) { + continue; + } + BehaviorResult behaviorResult = buildBehaviorResult(behavior, + plugin, startDate, pluginReturn, endDate); + pluginReturn = null; + dataCollector.add(behaviorResult); + results.add(behaviorResult); + } + return results; + } + + private void extractRunTimeParams(PluginReturn pluginReturn) { + this.getSessionObject().saveRuntimeParams( + pluginReturn.getRunTimeParams()); + } + + private BehaviorResult buildBehaviorResult(Behavior behavior, + Object plugin, Date startDate, PluginReturn pluginReturn, + Date endDate) { + BehaviorResult result = new BehaviorResult(); + result.setStartDate(startDate); + result.setEndDate(endDate); + result.setSuccess(pluginReturn.isSuccess()); + result.setResponseTime(endDate.getTime() - startDate.getTime()); + result.setBehaviorName(behavior.getName()); + result.setPluginId(behavior.getUse()); + result.setPluginName(plugin.getClass().getAnnotation(Plugin.class) + .value()); + result.setShouldBeCountResponseTime(behavior + .shouldBeCountResponseTime()); + if (pluginReturn instanceof HttpReturn) { + HttpReturn httpReturn = (HttpReturn) pluginReturn; + result.setBehaviorId(behavior.getId()); + for (Parameter parameter : behavior.getParameters()) { + if (parameter.getKey().equals("url")) { + result.setBehaviorUrl(parameter.getValue()); + } + } + result.setContentLength(httpReturn.getContentLength()); + result.setContentType(httpReturn.getContentType()); + result.setStatusCode(httpReturn.getStatusCode()); + } + return result; + } + + private Map prepareBehaviorParameters(Behavior behavior) { + Map behaviorParameters = new HashMap(); + for (Parameter parameter : behavior.getParameters()) { + behaviorParameters.put(parameter.getKey(), parameter.getValue()); + } + return behaviorParameters; + } + + private void preparePlugins(Scenario scenario, Map plugins) { + for (UsePlugin usePlugin : scenario.getUsePlugins()) { + String pluginId = usePlugin.getId(); + Class pluginClass = this.getPluginManager().getPlugins() + .get(usePlugin.getName()); + Map initParameters = new HashMap(); + for (Parameter parameter : usePlugin.getParameters()) { + initParameters.put(parameter.getKey(), parameter.getValue()); + } + Object plugin = this.getPluginManager().initializePlugin( + pluginClass, initParameters); + plugins.put(pluginId, plugin); + } + } +} diff --git a/Bench4Q-Agent/src/main/java/org/bench4q/agent/scenario/behavior/Behavior.java b/Bench4Q-Agent/src/main/java/org/bench4q/agent/scenario/behavior/Behavior.java new file mode 100644 index 00000000..80142d7a --- /dev/null +++ b/Bench4Q-Agent/src/main/java/org/bench4q/agent/scenario/behavior/Behavior.java @@ -0,0 +1,71 @@ +package org.bench4q.agent.scenario.behavior; + +import java.util.Map; + +import org.bench4q.agent.datacollector.DataCollector; +import org.bench4q.agent.datacollector.impl.BehaviorStatusCodeResult; +import org.bench4q.agent.parameterization.SessionObject; +import org.bench4q.agent.scenario.Parameter; + +public abstract class Behavior { + private int id; + private String use; + private String name; + private Parameter[] parameters; + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public String getUse() { + return use; + } + + public void setUse(String use) { + this.use = use; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public Parameter[] getParameters() { + return parameters; + } + + public void setParameters(Parameter[] parameters) { + this.parameters = parameters; + } + + public abstract boolean shouldBeCountResponseTime(); + + public abstract Map getBehaviorBriefResult( + DataCollector dataStatistics); + + public String getUrl() { + for (Parameter parameter : this.getParameters()) { + if (parameter.getKey().equals("url")) { + return parameter.getValue(); + } + } + return ""; + } + + public void distillParams(SessionObject session) { + for (Parameter parameter : this.getParameters()) { + String s = parameter.getValue(); + System.out.println("before Change :" + s); + String re = session.getParam(s); + System.out.println("after Change : " + re); + parameter.setValue(re); + } + } +} diff --git a/Bench4Q-Agent/src/main/java/org/bench4q/agent/scenario/behavior/BehaviorFactory.java b/Bench4Q-Agent/src/main/java/org/bench4q/agent/scenario/behavior/BehaviorFactory.java new file mode 100644 index 00000000..e5761868 --- /dev/null +++ b/Bench4Q-Agent/src/main/java/org/bench4q/agent/scenario/behavior/BehaviorFactory.java @@ -0,0 +1,14 @@ +package org.bench4q.agent.scenario.behavior; + +import org.bench4q.share.models.agent.scriptrecord.BehaviorModel; + +public class BehaviorFactory { + public static Behavior getBuisinessObject(BehaviorModel modelInput) { + if (modelInput.getType().equalsIgnoreCase("TIMERBEHAVIOR")) { + return new TimerBehavior(); + } else if (modelInput.getType().equalsIgnoreCase("USERBEHAVIOR")) { + return new UserBehavior(); + } + return null; + } +} diff --git a/Bench4Q-Agent/src/main/java/org/bench4q/agent/scenario/behavior/TimerBehavior.java b/Bench4Q-Agent/src/main/java/org/bench4q/agent/scenario/behavior/TimerBehavior.java new file mode 100644 index 00000000..c99d80aa --- /dev/null +++ b/Bench4Q-Agent/src/main/java/org/bench4q/agent/scenario/behavior/TimerBehavior.java @@ -0,0 +1,21 @@ +package org.bench4q.agent.scenario.behavior; + +import java.util.Map; + +import org.bench4q.agent.datacollector.DataCollector; +import org.bench4q.agent.datacollector.impl.BehaviorStatusCodeResult; + +public class TimerBehavior extends Behavior { + + @Override + public boolean shouldBeCountResponseTime() { + return false; + } + + @Override + public Map getBehaviorBriefResult( + DataCollector dataStatistics) { + return null; + } + +} diff --git a/Bench4Q-Agent/src/main/java/org/bench4q/agent/scenario/behavior/UserBehavior.java b/Bench4Q-Agent/src/main/java/org/bench4q/agent/scenario/behavior/UserBehavior.java new file mode 100644 index 00000000..6fe473d5 --- /dev/null +++ b/Bench4Q-Agent/src/main/java/org/bench4q/agent/scenario/behavior/UserBehavior.java @@ -0,0 +1,20 @@ +package org.bench4q.agent.scenario.behavior; + +import java.util.Map; + +import org.bench4q.agent.datacollector.DataCollector; +import org.bench4q.agent.datacollector.impl.BehaviorStatusCodeResult; + +public class UserBehavior extends Behavior { + @Override + public boolean shouldBeCountResponseTime() { + return true; + } + + @Override + public Map getBehaviorBriefResult( + DataCollector dataStatistics) { + return dataStatistics.getBehaviorBriefStatistics(this.getId()); + } + +} diff --git a/Bench4Q-Agent/src/main/java/org/bench4q/agent/scenario/util/ParameterParser.java b/Bench4Q-Agent/src/main/java/org/bench4q/agent/scenario/util/ParameterParser.java new file mode 100644 index 00000000..e8c81bf2 --- /dev/null +++ b/Bench4Q-Agent/src/main/java/org/bench4q/agent/scenario/util/ParameterParser.java @@ -0,0 +1,122 @@ +package org.bench4q.agent.scenario.util; + +import java.util.ArrayList; +import java.util.List; +import java.util.StringTokenizer; + +import org.bench4q.agent.plugin.basic.http.ParameterConstant; + +/** + * + * @author coderfengyun + * + */ +public abstract class ParameterParser { + private static final String RadioGroup_SEPARATOR = ";"; + private static final String NFIELD_SEPARATOR = RadioGroup_SEPARATOR; + + static public List buildNField(String value) { + StringTokenizer st = new StringTokenizer(value, NFIELD_SEPARATOR, false); + List result = new ArrayList(); + while (st.hasMoreTokens()) { + String token = st.nextToken(); + result.add(token.trim()); + } + return result; + } + + static public String buildRadioGroup(String value) { + List realTokens = getRealTokens(RadioGroup_SEPARATOR, value, + false); + if (realTokens.size() == 0) { + return ""; + } else { + return unescape(realTokens.get(0)); + } + } + + static public List buildCheckBox(String value) { + return buildNField(value); + } + + static public String buildCombo(String value) { + return buildRadioGroup(value); + } + + static public Table buildTable(String value, List columnLables) { + return Table.buildTable(value, columnLables); + } + + /** + * Get the number of escape character in the end of the string + * + * @param value + * The string to be analyzed + * @return 0 if no escape character was found, else the number + */ + private static int getNumberOfEscapeCharacter(String value) { + int result = 0; + if (value.length() > 0) { + int last = value.lastIndexOf(ParameterConstant.escape); + if (last == value.length() - 1) { + result = 1 + getNumberOfEscapeCharacter(value + .substring(0, last)); + } + } + return result; + } + + /** + * Split the string value with the separator, and check if there is no + * escape character before the separator + * + * @param separator + * The separator + * @param value + * The string value to be split + * @return The vector containing each token + */ + static List getRealTokens(String separator, String value, + boolean toUnescapeSeparator) { + List result = new ArrayList(); + for (String entry : value.split(separator)) { + if (getNumberOfEscapeCharacter(entry) % 2 != 0) { + if (toUnescapeSeparator) { + entry = entry.substring(0, entry.length() - 1) + + unescape(separator); + } else { + entry = entry.substring(0, entry.length() - 1) + separator; + } + } + result.add(entry); + } + return result; + } + + /** + * Replaces every escape sequences by the corresponding original character + * + * @param value + * the string where some characters are escaped by '\' character + * @return the unescaped string + */ + static String unescape(String value) { + StringBuilder result = new StringBuilder(); + char c; + boolean escape = false; // escape sequence + for (int i = 0; i < value.length(); ++i) { + c = value.charAt(i); + if (escape) { + result.append(c); + escape = false; + } else { + if (c == ParameterConstant.escape.charAt(0)) { + escape = true; + } else { + result.append(c); + } + } + } + return result.toString(); + } +} diff --git a/Bench4Q-Agent/src/main/java/org/bench4q/agent/scenario/util/Table.java b/Bench4Q-Agent/src/main/java/org/bench4q/agent/scenario/util/Table.java new file mode 100644 index 00000000..866287b3 --- /dev/null +++ b/Bench4Q-Agent/src/main/java/org/bench4q/agent/scenario/util/Table.java @@ -0,0 +1,115 @@ +package org.bench4q.agent.scenario.util; + +import java.util.ArrayList; +import java.util.LinkedList; +import java.util.List; + +import org.bench4q.agent.plugin.basic.http.ParameterConstant; + +public class Table { + public static final String ROW_SEPARATOR = "|;"; + public static final String COLUMN_SEPARATOR = "|"; + public static final String ROW_SEPARATOR_TAIL = ";"; + + public static final String ESCAPE_ROW_SEPARATOR = ParameterConstant.escape + + ROW_SEPARATOR; + public static final String ESCAPE_COLUMN_SEPARATOR = ParameterConstant.escape + + COLUMN_SEPARATOR; + private List> realContent; + private List columnLables; + + public List> getRealContent() { + return realContent; + } + + private void setRealContent(List> realContent) { + this.realContent = realContent; + } + + private List getColumnLables() { + return columnLables; + } + + private void setColumnLables(List columnLables) { + this.columnLables = columnLables; + } + + private Table() { + this.setColumnLables(new LinkedList()); + } + + static Table buildTable(String value, List columnLablesInSequence) { + Table result = new Table(); + result.setRealContent(buildTableContent(value)); + result.setColumnLables(columnLablesInSequence); + return result; + } + + /** + * This method analyzes the value to be set in the table, and remove all + * escape characters + * + * @param value + * The value containing the serialization of all values of the + * table + * @return The vector containing all the entries, each entries is in a + * vector, which contains the string values + */ + private static List> buildTableContent(String value) { + List tempEntries = ParameterParser.getRealTokens( + Table.ESCAPE_ROW_SEPARATOR, value, false); + List> allValues = new ArrayList>(); + for (int i = 0; i < tempEntries.size(); i++) { + String tempEntry = tempEntries.get(i); + List values = ParameterParser.getRealTokens( + Table.ESCAPE_COLUMN_SEPARATOR, tempEntry, true); + arrangeTableWithRowSeparatorTail(values); + allValues.add(values); + } + // now analyze all values, and get the '=' separator + return extractValueFromWellFormedTable(allValues); + } + + private static List> extractValueFromWellFormedTable( + List> allValues) { + List> result = new LinkedList>(); + for (int i = 0; i < allValues.size(); i++) { + List resultValues = new ArrayList(); + List tempValues = allValues.get(i); + for (int j = 0; j < tempValues.size(); j++) { + String v = tempValues.get(j); + List temp = ParameterParser + .getRealTokens("=", v, false); + String res; + if (temp.size() <= 1) { + continue; + } + res = temp.get(1); + resultValues.add(res); + } + result.add(resultValues); + } + return result; + } + + /** + * This method check if the table_separator after escape is split by the + * table_entry_separator + * + * @param values + */ + private static void arrangeTableWithRowSeparatorTail(List values) { + for (int i = 0; i < values.size(); i++) { + + String currentToken = values.get(i); + if (currentToken.equals(Table.ROW_SEPARATOR_TAIL) && i > 0) { + values.set(i - 1, values.get(i - 1) + Table.ROW_SEPARATOR_TAIL); + } + } + + } + + public int getColumnCount() { + return this.getColumnLables().size(); + } +} diff --git a/Bench4Q-Agent/src/main/java/org/bench4q/agent/share/DealWithLog.java b/Bench4Q-Agent/src/main/java/org/bench4q/agent/share/DealWithLog.java new file mode 100644 index 00000000..3c18c981 --- /dev/null +++ b/Bench4Q-Agent/src/main/java/org/bench4q/agent/share/DealWithLog.java @@ -0,0 +1,13 @@ +package org.bench4q.agent.share; + +import java.io.ByteArrayOutputStream; +import java.io.PrintStream; + +public class DealWithLog { + public static ByteArrayOutputStream getExceptionStackTrace(Exception e) { + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + PrintStream printStream = new PrintStream(outputStream); + e.printStackTrace(printStream); + return outputStream; + } +} diff --git a/Bench4Q-Agent/src/main/java/org/bench4q/agent/storage/Buffer.java b/Bench4Q-Agent/src/main/java/org/bench4q/agent/storage/Buffer.java new file mode 100644 index 00000000..a40de8bd --- /dev/null +++ b/Bench4Q-Agent/src/main/java/org/bench4q/agent/storage/Buffer.java @@ -0,0 +1,57 @@ +package org.bench4q.agent.storage; + +public class Buffer { + private byte[] content; + private int currentPos; + private int totalSize; + + public byte[] getContent() { + return content; + } + + public void setContent(byte[] content) { + this.content = content; + } + + public int getCurrentPos() { + return currentPos; + } + + public void setCurrentPos(int currentPos) { + this.currentPos = currentPos; + } + + public int getTotalSize() { + return totalSize; + } + + public void setTotalSize(int totalSize) { + this.totalSize = totalSize; + } + + public static Buffer createBuffer(int totalSize) { + Buffer buffer = new Buffer(); + buffer.setContent(new byte[totalSize]); + buffer.setCurrentPos(0); + buffer.setTotalSize(totalSize); + return buffer; + } + + public int getRemainSize() { + return this.totalSize - this.currentPos; + } + + public void reset() { + this.setCurrentPos(0); + } + + public void setFull() { + this.setCurrentPos(this.getTotalSize()); + } + + void writeToCurrentBuffer(int size, byte[] cache) { + System.arraycopy(cache, 0, this.getContent(), this.getCurrentPos(), + size); + this.setCurrentPos(this.getCurrentPos() + size); + } +} diff --git a/Bench4Q-Agent/src/main/java/org/bench4q/agent/storage/DoubleBufferStorage.java b/Bench4Q-Agent/src/main/java/org/bench4q/agent/storage/DoubleBufferStorage.java new file mode 100644 index 00000000..f92f050e --- /dev/null +++ b/Bench4Q-Agent/src/main/java/org/bench4q/agent/storage/DoubleBufferStorage.java @@ -0,0 +1,157 @@ +package org.bench4q.agent.storage; + +import java.io.ByteArrayInputStream; +import java.io.File; +import java.io.FilenameFilter; +import java.nio.charset.Charset; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; + +import org.bench4q.share.models.agent.CleanTestResultModel; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +@Component +public class DoubleBufferStorage { + private static final int THRESHOLD = 1024; + private static Charset charset = Charset.forName("utf-8"); + private static int BUFFER_SIZE = 48 * 1024; + private List bufferList; + private int currentBufferIndex; + private LocalStorage localStorage; + public CleanTestResultModel forTest = new CleanTestResultModel(); + + private int getCurrentBufferIndex() { + return currentBufferIndex; + } + + private void setCurrentBufferIndex(int currentBuffer) { + this.currentBufferIndex = currentBuffer; + } + + private List getBufferList() { + return bufferList; + } + + private void setBufferList(List bufferList) { + this.bufferList = bufferList; + } + + private LocalStorage getLocalStorage() { + return localStorage; + } + + @Autowired + private void setLocalStorage(LocalStorage localStorage) { + this.localStorage = localStorage; + } + + public DoubleBufferStorage() { + this.setBufferList(new ArrayList()); + this.getBufferList().add(Buffer.createBuffer(BUFFER_SIZE)); + this.getBufferList().add(Buffer.createBuffer(BUFFER_SIZE)); + this.setCurrentBufferIndex(0); + } + + public String readFiles(String pathPrefix) { + int pos = pathPrefix.lastIndexOf(System.getProperty("file.separator")); + String dirPath = pathPrefix.substring(0, pos); + final String prefix = pathPrefix.substring(pos + 1); + String result = new String(); + + File dirFile = new File(dirPath); + if (!dirFile.exists()) { + return ""; + } + File[] files = dirFile.listFiles(new FilenameFilter() { + public boolean accept(File dir, String name) { + return name.contains(prefix); + } + }); + for (File file : files) { + if (!file.exists()) { + continue; + } + result += this.getLocalStorage().readFile(file.getAbsolutePath()); + } + return result; + } + + public boolean writeFile(String content, String path) { + ByteArrayInputStream inputStream = new ByteArrayInputStream( + content.getBytes(charset)); + int size = -1; + byte[] cache = new byte[THRESHOLD]; + while ((size = inputStream.read(cache, 0, THRESHOLD)) != -1) { + if (isCurrentBufferFull(size)) { + doSave(calculateSavePath(path)); + changeToTheMaxRemainBuffer(); + } + this.getCurrentBuffer().writeToCurrentBuffer(size, cache); + } + return true; + } + + private boolean isCurrentBufferFull(int size) { + return getCurrentBuffer().getRemainSize() <= THRESHOLD + size; + } + + public String calculateSavePath(String path, int index) { + return path.substring(0, path.lastIndexOf(".")) + "_" + index + ".xml"; + } + + private String calculateSavePath(String path) { + return calculateSavePath(path, this.getCurrentBufferIndex()); + } + + private void doSave(final String path) { + final Buffer bufferUnderSave = this.getCurrentBuffer(); + final String writeContent = this.getMeaningfulContent(); + Runnable runnable = new Runnable() { + public void run() { + getLocalStorage().writeFile(writeContent, path); + bufferUnderSave.reset(); + forTest.setSuccess(true); + } + }; + ExecutorService service = Executors.newFixedThreadPool(1); + service.execute(runnable); + service.shutdown(); + + } + + private String getMeaningfulContent() { + byte[] meaningfulContent = new byte[getCurrentBuffer().getCurrentPos()]; + System.arraycopy(getCurrentBuffer().getContent(), 0, meaningfulContent, + 0, getCurrentBuffer().getCurrentPos()); + return new String(meaningfulContent); + } + + private void changeToTheMaxRemainBuffer() { + int maxRemainSize = 2 * THRESHOLD; + int maxRemainSizeBufferIndex = -1; + for (int i = 0; i < this.getBufferList().size(); ++i) { + System.out.println(i + " remain : " + + this.getBufferList().get(i).getRemainSize()); + if (this.getBufferList().get(i).getRemainSize() > maxRemainSize) { + maxRemainSize = this.getBufferList().get(i).getRemainSize(); + maxRemainSizeBufferIndex = i; + } + } + if (maxRemainSizeBufferIndex == -1) { + this.getBufferList().add(Buffer.createBuffer(BUFFER_SIZE)); + maxRemainSizeBufferIndex = this.getBufferList().size() - 1; + } + this.setCurrentBufferIndex(maxRemainSizeBufferIndex); + } + + private Buffer getCurrentBuffer() { + return this.getBufferList().get(this.getCurrentBufferIndex()); + } + + public void flush() { + + } +} diff --git a/Bench4Q-Agent/src/main/java/org/bench4q/agent/storage/HdfsStorage.java b/Bench4Q-Agent/src/main/java/org/bench4q/agent/storage/HdfsStorage.java new file mode 100644 index 00000000..9d9e0694 --- /dev/null +++ b/Bench4Q-Agent/src/main/java/org/bench4q/agent/storage/HdfsStorage.java @@ -0,0 +1,140 @@ +package org.bench4q.agent.storage; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; + +import org.apache.hadoop.conf.Configuration; +import org.apache.hadoop.fs.FSDataInputStream; +import org.apache.hadoop.fs.FSDataOutputStream; +import org.apache.hadoop.fs.FileStatus; +import org.apache.hadoop.fs.FileSystem; +import org.apache.hadoop.fs.Path; +import org.apache.hadoop.io.IOUtils; +import org.springframework.stereotype.Component; + +@Component +public class HdfsStorage implements Storage { + private FileSystem getFileSystem() throws IOException { + Configuration conf = new Configuration(); + conf.set("mapred.jop.tracker", "hdfs://133.133.12.21:9001"); + conf.set("fs.default.name", "hdfs://133.133.12.21:9000"); + return FileSystem.get(conf); + } + + public boolean uploadFile(String localPath, String remotePath) { + try { + FileSystem fs = this.getFileSystem(); + fs.copyFromLocalFile(new Path(localPath), new Path(remotePath)); + return true; + } catch (Exception e) { + e.printStackTrace(); + return false; + } + } + + public boolean writeFile(String content, String remotePath) { + try { + InputStream in = new ByteArrayInputStream(content.getBytes()); + FileSystem fs = this.getFileSystem(); + OutputStream out = fs.create(new Path(remotePath)); + IOUtils.copyBytes(in, out, 4096, true); + return true; + } catch (Exception e) { + e.printStackTrace(); + return false; + } + } + + public boolean downloadFile(String localPath, String remotePath) { + try { + FileSystem fs = this.getFileSystem(); + fs.copyToLocalFile(new Path(remotePath), new Path(localPath)); + return true; + } catch (Exception e) { + e.printStackTrace(); + return false; + } + } + + public String readFile(String remotePath) { + try { + FileSystem fs = this.getFileSystem(); + FSDataInputStream hdfsInStream = fs.open(new Path(remotePath)); + OutputStream out = new ByteArrayOutputStream(); + byte[] ioBuffer = new byte[1024]; + int readLen = hdfsInStream.read(ioBuffer); + while (-1 != readLen) { + out.write(ioBuffer, 0, readLen); + readLen = hdfsInStream.read(ioBuffer); + } + out.close(); + String ret = out.toString(); + hdfsInStream.close(); + return ret; + } catch (Exception e) { + e.printStackTrace(); + return null; + } + } + + public boolean appendFile(String content, String remotePath) { + try { + FileSystem fs = this.getFileSystem(); + FSDataOutputStream out = fs.append(new Path(remotePath)); + int readLen = content.getBytes().length; + while (-1 != readLen) { + out.write(content.getBytes(), 0, readLen); + } + out.close(); + return true; + } catch (Exception e) { + e.printStackTrace(); + return false; + } + } + + public boolean deleteFile(String remotePath) { + try { + FileSystem fs = this.getFileSystem(); + return fs.delete(new Path(remotePath), false); + } catch (Exception e) { + e.printStackTrace(); + return false; + } + } + + public boolean deleteDirectory(String remotePath) { + try { + FileSystem fs = this.getFileSystem(); + return fs.delete(new Path(remotePath), true); + } catch (Exception e) { + e.printStackTrace(); + return false; + } + } + + public boolean renameFile(String fromPath, String toPath) { + try { + FileSystem fs = this.getFileSystem(); + return fs.rename(new Path(fromPath), new Path(toPath)); + } catch (Exception e) { + e.printStackTrace(); + return false; + } + } + + public FileStatus[] listFile(String remotePath) { + try { + FileSystem fs = this.getFileSystem(); + FileStatus[] fileList = fs.listStatus(new Path(remotePath)); + return fileList; + } catch (Exception e) { + e.printStackTrace(); + return null; + } + } + +} diff --git a/Bench4Q-Agent/src/main/java/org/bench4q/agent/storage/LocalStorage.java b/Bench4Q-Agent/src/main/java/org/bench4q/agent/storage/LocalStorage.java new file mode 100644 index 00000000..6eb1b2da --- /dev/null +++ b/Bench4Q-Agent/src/main/java/org/bench4q/agent/storage/LocalStorage.java @@ -0,0 +1,50 @@ +package org.bench4q.agent.storage; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.InputStreamReader; +import java.io.OutputStreamWriter; + +import org.springframework.stereotype.Component; + +@Component +public class LocalStorage implements Storage { + + public String readFile(String path) { + try { + InputStreamReader inputStreamReader = new InputStreamReader( + new FileInputStream(new File(path)), "UTF-8"); + StringBuffer ret = new StringBuffer(); + int toRead; + while ((toRead = inputStreamReader.read()) != -1) { + ret.append((char) toRead); + } + inputStreamReader.close(); + return ret.toString(); + } catch (Exception e) { + e.printStackTrace(); + return null; + } + } + + public boolean writeFile(String content, String path) { + try { + String dirPath = path.substring(0, + path.lastIndexOf(System.getProperty("file.separator"))); + File file = new File(dirPath); + if (!file.exists()) { + file.mkdirs(); + } + OutputStreamWriter outputStreamWriter = new OutputStreamWriter( + new FileOutputStream(new File(path), true), "UTF-8"); + outputStreamWriter.write(content); + outputStreamWriter.flush(); + outputStreamWriter.close(); + return true; + } catch (Exception e) { + e.printStackTrace(); + return false; + } + } +} diff --git a/Bench4Q-Agent/src/main/java/org/bench4q/agent/storage/MooseStorage.java b/Bench4Q-Agent/src/main/java/org/bench4q/agent/storage/MooseStorage.java new file mode 100644 index 00000000..ec8eabfb --- /dev/null +++ b/Bench4Q-Agent/src/main/java/org/bench4q/agent/storage/MooseStorage.java @@ -0,0 +1,17 @@ +package org.bench4q.agent.storage; + +import org.springframework.stereotype.Component; + +@Component +public class MooseStorage implements Storage { + + public String readFile(String path) { + + return null; + } + + public boolean writeFile(String content, String path) { + return false; + } + +} diff --git a/Bench4Q-Agent/src/main/java/org/bench4q/agent/storage/Storage.java b/Bench4Q-Agent/src/main/java/org/bench4q/agent/storage/Storage.java new file mode 100644 index 00000000..6dbbe36d --- /dev/null +++ b/Bench4Q-Agent/src/main/java/org/bench4q/agent/storage/Storage.java @@ -0,0 +1,7 @@ +package org.bench4q.agent.storage; + +public interface Storage { + public String readFile(String path); + + public boolean writeFile(String content, String path); +} diff --git a/Bench4Q-Agent/src/main/java/org/bench4q/agent/storage/StorageHelper.java b/Bench4Q-Agent/src/main/java/org/bench4q/agent/storage/StorageHelper.java new file mode 100644 index 00000000..7a49f28c --- /dev/null +++ b/Bench4Q-Agent/src/main/java/org/bench4q/agent/storage/StorageHelper.java @@ -0,0 +1,39 @@ +package org.bench4q.agent.storage; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +@Component +public class StorageHelper { + private HdfsStorage hdfsStorage; + private LocalStorage localStorage; + private MooseStorage mooseStorage; + + public HdfsStorage getHdfsStorage() { + return hdfsStorage; + } + + @Autowired + public void setHdfsStorage(HdfsStorage hdfsStorage) { + this.hdfsStorage = hdfsStorage; + } + + public LocalStorage getLocalStorage() { + return localStorage; + } + + @Autowired + public void setLocalStorage(LocalStorage localStorage) { + this.localStorage = localStorage; + } + + public MooseStorage getMooseStorage() { + return mooseStorage; + } + + @Autowired + public void setMooseStorage(MooseStorage mooseStorage) { + this.mooseStorage = mooseStorage; + } + +} diff --git a/Bench4Q-Agent/src/main/resources/log4j.properties b/Bench4Q-Agent/src/main/resources/log4j.properties new file mode 100644 index 00000000..0fa2c1c5 --- /dev/null +++ b/Bench4Q-Agent/src/main/resources/log4j.properties @@ -0,0 +1,31 @@ +log4j.rootLogger = INFO,WARN,ERROR,FALTAL,D + +log4j.appender.WARN = org.apache.log4j.DailyRollingFileAppender +log4j.appender.WARN.File = logs/log.log +log4j.appender.WARN.Append = true +log4j.appender.WARN.Threshold = WARN +log4j.appender.WARN.layout = org.apache.log4j.PatternLayout +log4j.appender.WARN.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss} [ %t:%r ] - [ %p ] %m%n + +log4j.appender.ERROR = org.apache.log4j.DailyRollingFileAppender +log4j.appender.ERROR.File = logs/log.log +log4j.appender.ERROR.Append = true +log4j.appender.ERROR.Threshold = ERROR +log4j.appender.ERROR.layout = org.apache.log4j.PatternLayout +log4j.appender.ERROR.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss} [ %t:%r ] - [ %p ] %m%n + +log4j.appender.FALTAL = org.apache.log4j.DailyRollingFileAppender +log4j.appender.FALTAL.File = logs/log.log +log4j.appender.FALTAL.Append = true +log4j.appender.FALTAL.Threshold = ERROR +log4j.appender.FALTAL.layout = org.apache.log4j.PatternLayout +log4j.appender.FALTAL.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss} [ %t:%r ] - [ %p ] %m%n + + +log4j.appender.D = org.apache.log4j.DailyRollingFileAppender +log4j.appender.D.File = logs/log.log +log4j.appender.D.Append = true +log4j.appender.D.Threshold = INFO +log4j.appender.D.layout = org.apache.log4j.PatternLayout +log4j.appender.D.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss} [ %t:%r ] - [ %p ] %m%n + diff --git a/Bench4Q-Agent/src/main/resources/org/bench4q/agent/config/application-context.xml b/Bench4Q-Agent/src/main/resources/org/bench4q/agent/config/application-context.xml new file mode 100644 index 00000000..48c14bb0 --- /dev/null +++ b/Bench4Q-Agent/src/main/resources/org/bench4q/agent/config/application-context.xml @@ -0,0 +1,18 @@ + + + + + + + + + + + + diff --git a/Bench4Q-Agent/src/test/java/org/bench4q/agent/test/ExtractScenarioTest.java b/Bench4Q-Agent/src/test/java/org/bench4q/agent/test/ExtractScenarioTest.java new file mode 100644 index 00000000..8912eea5 --- /dev/null +++ b/Bench4Q-Agent/src/test/java/org/bench4q/agent/test/ExtractScenarioTest.java @@ -0,0 +1,27 @@ +package org.bench4q.agent.test; + +import static org.junit.Assert.*; + +import java.io.File; +import java.io.IOException; + +import javax.xml.bind.JAXBException; + +import org.apache.commons.io.FileUtils; +import org.bench4q.agent.scenario.Scenario; +import org.bench4q.share.helper.MarshalHelper; +import org.bench4q.share.models.agent.RunScenarioModel; +import org.junit.Test; + +public class ExtractScenarioTest { + + @Test + public void test() throws JAXBException, IOException { + RunScenarioModel runScenarioModel = (RunScenarioModel) MarshalHelper + .unmarshal(RunScenarioModel.class, FileUtils + .readFileToString(new File("Scripts/goodForPage.xml"))); + Scenario scenario = Scenario.scenarioBuilder(runScenarioModel); + + assertTrue(scenario.getPages().length > 0); + } +} diff --git a/Bench4Q-Agent/src/test/java/org/bench4q/agent/test/HomeControllerTest.java b/Bench4Q-Agent/src/test/java/org/bench4q/agent/test/HomeControllerTest.java new file mode 100644 index 00000000..6902b437 --- /dev/null +++ b/Bench4Q-Agent/src/test/java/org/bench4q/agent/test/HomeControllerTest.java @@ -0,0 +1,5 @@ +package org.bench4q.agent.test; + +public class HomeControllerTest { + +} diff --git a/Bench4Q-Agent/src/test/java/org/bench4q/agent/test/MainTest.java b/Bench4Q-Agent/src/test/java/org/bench4q/agent/test/MainTest.java new file mode 100644 index 00000000..70602654 --- /dev/null +++ b/Bench4Q-Agent/src/test/java/org/bench4q/agent/test/MainTest.java @@ -0,0 +1,37 @@ +package org.bench4q.agent.test; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.util.Properties; + +import org.bench4q.agent.Main; +import org.junit.Test; + +import static org.junit.Assert.*; + +public class MainTest { + public MainTest() { + Main.init(); + } + + @Test + public void initTest() { + Main.init(); + assertTrue(new File("configure").exists()); + } + + @Test + public void getPropertiesTest() throws IOException { + FileInputStream inputStream = new FileInputStream(new File("configure" + + System.getProperty("file.separator") + + "agent-config.properties")); + Properties properties = new Properties(); + properties.load(inputStream); + assertEquals(6565, + Integer.parseInt((String) properties.get("servePort"))); + assertEquals(false, Boolean.parseBoolean((String) properties + .get("isToSaveDetailResult"))); + } + +} diff --git a/Bench4Q-Agent/src/test/java/org/bench4q/agent/test/PluginControllerTest.java b/Bench4Q-Agent/src/test/java/org/bench4q/agent/test/PluginControllerTest.java new file mode 100644 index 00000000..ca35983c --- /dev/null +++ b/Bench4Q-Agent/src/test/java/org/bench4q/agent/test/PluginControllerTest.java @@ -0,0 +1,5 @@ +package org.bench4q.agent.test; + +public class PluginControllerTest { + +} diff --git a/Bench4Q-Agent/src/test/java/org/bench4q/agent/test/TestWithScriptFile.java b/Bench4Q-Agent/src/test/java/org/bench4q/agent/test/TestWithScriptFile.java new file mode 100644 index 00000000..d9a83b3a --- /dev/null +++ b/Bench4Q-Agent/src/test/java/org/bench4q/agent/test/TestWithScriptFile.java @@ -0,0 +1,243 @@ +package org.bench4q.agent.test; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.LinkedList; +import java.util.List; +import java.util.UUID; + +import static org.junit.Assert.*; + +import javax.xml.bind.JAXBContext; +import javax.xml.bind.JAXBException; +import javax.xml.bind.Unmarshaller; + +import org.apache.commons.io.FileUtils; +import org.bench4q.agent.parameterization.ParameterFileCollector; +import org.bench4q.share.communication.HttpRequester; +import org.bench4q.share.communication.HttpRequester.HttpResponse; +import org.bench4q.share.helper.MarshalHelper; +import org.bench4q.share.helper.TestHelper; +import org.bench4q.share.models.agent.BehaviorBriefModel; +import org.bench4q.share.models.agent.RunScenarioModel; +import org.bench4q.share.models.agent.RunScenarioResultModel; +import org.bench4q.share.models.agent.statistics.AgentBriefStatusModel; +import org.bench4q.share.models.agent.statistics.AgentBehaviorsBriefModel; +import org.bench4q.share.models.agent.statistics.AgentPageBriefModel; +import org.junit.Test; + +public class TestWithScriptFile { + private HttpRequester httpRequester; + private String url = "http://localhost:6565/test"; + private String filePath; + private UUID testId; + private static int load = 10; + + private String getFilePath() { + return filePath; + } + + private void setFilePath(String filePath) { + this.filePath = filePath; + } + + private HttpRequester getHttpRequester() { + return httpRequester; + } + + private void setHttpRequester(HttpRequester httpRequester) { + this.httpRequester = httpRequester; + } + + private UUID getTestId() { + return testId; + } + + private void setTestId(UUID testId) { + this.testId = testId; + } + + public TestWithScriptFile() { + this.setFilePath("Scripts" + System.getProperty("file.separator") + + "forGoodRecord.xml"); + this.setHttpRequester(new HttpRequester()); + } + + private void startTest() throws JAXBException { + try { + RunScenarioModel runScenarioModel = getScenarioModel(); + if (runScenarioModel == null) { + System.out.println("can't execute an invalid script"); + return; + } + assertTrue(runScenarioModel.getPages().size() > 0); + assertTrue(runScenarioModel.getPages().get(0).getBatches().get(0) + .getBehaviors().size() > 0); + + HttpResponse httpResponse = this.getHttpRequester().sendPostXml( + this.url + "/runWithoutParams", + marshalRunScenarioModel(runScenarioModel), null); + RunScenarioResultModel resultModel = (RunScenarioResultModel) MarshalHelper + .unmarshal(RunScenarioResultModel.class, + httpResponse.getContent()); + this.setTestId(resultModel.getRunId()); + } catch (IOException e) { + System.out.println("IO exception!"); + } + } + + private RunScenarioModel getScenarioModel() throws IOException { + String scriptContent; + File file = new File(this.getFilePath()); + if (!file.exists()) { + System.out.println("this script not exists!"); + return null; + } + scriptContent = FileUtils.readFileToString(file); + RunScenarioModel runScenarioModel = extractRunScenarioModel(scriptContent); + runScenarioModel.setPoolSize(load); + return runScenarioModel; + } + + private RunScenarioModel extractRunScenarioModel(String scriptContent) { + try { + Unmarshaller unmarshaller = JAXBContext.newInstance( + RunScenarioModel.class).createUnmarshaller(); + return (RunScenarioModel) unmarshaller + .unmarshal(new ByteArrayInputStream(scriptContent + .getBytes())); + } catch (JAXBException e) { + System.out.println("model unmarshal has an exception!"); + e.printStackTrace(); + return null; + } + + } + + private String marshalRunScenarioModel(RunScenarioModel model) + throws JAXBException { + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + JAXBContext.newInstance(RunScenarioModel.class).createMarshaller() + .marshal(model, outputStream); + return outputStream.toString(); + } + + private void stopTest() throws IOException { + System.out.println("Enter stopTest!"); + this.getHttpRequester().sendGet( + this.url + "/stop/" + this.getTestId().toString(), null, null); + } + + private void scenarioBrief() throws IOException, JAXBException { + System.out.println("Enter brief!"); + HttpResponse httpResponse = this.getHttpRequester().sendGet( + this.url + "/brief/" + this.getTestId().toString(), null, null); + System.out.println(httpResponse.getContent()); + AgentBriefStatusModel briefModel = (AgentBriefStatusModel) MarshalHelper + .unmarshal(AgentBriefStatusModel.class, + httpResponse.getContent()); + assertTrue(briefModel.getTimeFrame() > 0); + } + + private void behaviorsBrief() throws IOException, JAXBException { + System.out.println("Enter behaviorsBrief!"); + HttpResponse httpResponse = this.getHttpRequester().sendGet( + this.url + "/behaviorsBrief/" + this.getTestId().toString(), + null, null); + System.out.println(httpResponse.getContent()); + AgentBehaviorsBriefModel behaviorsBriefModel = (AgentBehaviorsBriefModel) MarshalHelper + .unmarshal(AgentBehaviorsBriefModel.class, + httpResponse.getContent()); + assertTrue(behaviorsBriefModel.getBehaviorBriefModels().size() > 0); + } + + private void behaviorBrief() throws IOException, JAXBException { + System.out.println("Enter behaviorBrief!"); + HttpResponse httpResponse = this.getHttpRequester().sendGet( + this.url + "/brief/" + this.getTestId().toString() + "/0", + null, null); + BehaviorBriefModel behaviorBriefModel = (BehaviorBriefModel) MarshalHelper + .unmarshal(BehaviorBriefModel.class, httpResponse.getContent()); + assertTrue(behaviorBriefModel.getDetailStatusCodeResultModels().size() > 0); + } + + @Test + public void integrateTest() throws JAXBException, InterruptedException, + IOException { + try { + this.startTest(); + Thread.sleep(5000); + this.scenarioBrief(); + Thread.sleep(5000); + this.behaviorsBrief(); + Thread.sleep(5000); + this.behaviorBrief(); + Thread.sleep(5000); + this.pageBrief(0); + } catch (Exception e) { + e.printStackTrace(); + } finally { + this.stopTest(); + } + + } + + @Test + public void testSubmitParamsAndRun() throws Exception { + List files = new ArrayList(); + files.add(new File("Scripts" + System.getProperty("file.separator") + + "forGoodRecord.xml")); + files.add(new File("Scripts" + System.getProperty("file.separator") + + "testJD.xml")); + HttpResponse httpResponse = this.getHttpRequester().postFiles( + url + "/submitScenarioWithParams", "files[]", files, + "scenarioModel", new LinkedList() { + private static final long serialVersionUID = 1L; + { + add(MarshalHelper.tryMarshal(getScenarioModel())); + } + }); + assertNotNull(httpResponse); + assertNotNull(httpResponse.getContent()); + assertEquals(200, httpResponse.getCode()); + RunScenarioResultModel resultModel = (RunScenarioResultModel) MarshalHelper + .tryUnmarshal(RunScenarioResultModel.class, + httpResponse.getContent()); + String dirPath = (String) TestHelper.invokePrivate( + new ParameterFileCollector(), "guardDirExists", + new Class[] { UUID.class }, + new Object[] { resultModel.getRunId() }); + File file = new File(dirPath); + assertTrue(file.exists()); + assertEquals(2, file.listFiles().length); + System.out.println(httpResponse.getContent()); + + httpResponse = this.getHttpRequester().sendPost( + this.url + "/runWithParams/" + + resultModel.getRunId().toString(), null, null); + assertNotNull(httpResponse); + System.out.println(httpResponse.getContent()); + } + + private void pageBrief(int i) throws IOException, JAXBException { + try { + HttpResponse httpResponse = this.getHttpRequester().sendGet( + url + "/pageBrief/" + this.getTestId() + "/" + i, null, + null); + if (httpResponse == null || httpResponse.getContent().isEmpty()) { + fail(); + } + System.out.println(httpResponse); + AgentPageBriefModel pageBriefModel = (AgentPageBriefModel) MarshalHelper + .unmarshal(AgentPageBriefModel.class, + httpResponse.getContent()); + assertTrue(pageBriefModel.getCountFromBegin() > 0); + } catch (Exception e) { + this.stopTest(); + } + + } +} diff --git a/Bench4Q-Agent/src/test/java/org/bench4q/agent/test/datastatistics/DetailStatisticsTest.java b/Bench4Q-Agent/src/test/java/org/bench4q/agent/test/datastatistics/DetailStatisticsTest.java new file mode 100644 index 00000000..1df3257a --- /dev/null +++ b/Bench4Q-Agent/src/test/java/org/bench4q/agent/test/datastatistics/DetailStatisticsTest.java @@ -0,0 +1,139 @@ +package org.bench4q.agent.test.datastatistics; + +import static org.junit.Assert.*; + +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; + +import org.bench4q.agent.datacollector.DataCollector; +import org.bench4q.agent.datacollector.impl.ScenarioResultCollector; +import org.bench4q.agent.datacollector.impl.BehaviorStatusCodeResult; +import org.bench4q.agent.scenario.BehaviorResult; +import org.bench4q.agent.storage.StorageHelper; +import org.junit.Test; +import org.springframework.context.ApplicationContext; +import org.springframework.context.support.ClassPathXmlApplicationContext; + +public class DetailStatisticsTest { + private DataCollector detailStatistics; + + private DataCollector getDetailStatistics() { + return detailStatistics; + } + + private void setDetailStatistics(DataCollector detailStatistics) { + this.detailStatistics = detailStatistics; + } + + public DetailStatisticsTest() { + init(); + } + + private void init() { + @SuppressWarnings("resource") + ApplicationContext context = new ClassPathXmlApplicationContext( + "classpath*:/org/bench4q/agent/config/application-context.xml"); + ScenarioResultCollector agentResultDataCollector = new ScenarioResultCollector( + UUID.randomUUID()); + agentResultDataCollector.setStorageHelper((StorageHelper) context + .getBean(StorageHelper.class)); + this.setDetailStatistics(agentResultDataCollector); + } + + @Test + public void addZeroTest() { + for (BehaviorResult behaviorResult : ScenarioStatisticsTest + .makeBehaviorList(0)) { + this.getDetailStatistics().add(behaviorResult); + } + + Object object = this.detailStatistics.getBehaviorBriefStatistics(0); + assertEquals(null, object); + } + + @Test + public void addOneDetailTest() { + for (BehaviorResult behaviorResult : ScenarioStatisticsTest + .makeBehaviorList(1)) { + this.getDetailStatistics().add(behaviorResult); + } + Map map = this.detailStatistics + .getBehaviorBriefStatistics(1); + + BehaviorStatusCodeResult actualResult = map.get(200); + assertTrue(actualResult.equals(makeExpectedResultForOne())); + } + + private BehaviorStatusCodeResult makeExpectedResultForOne() { + BehaviorStatusCodeResult ret = new BehaviorStatusCodeResult(""); + ret.contentLength = 20; + ret.count = 1; + ret.maxResponseTime = 200; + ret.minResponseTime = 200; + ret.totalResponseTimeThisTime = 200; + return ret; + } + + @Test + public void addTwoDetailTest() { + for (BehaviorResult behaviorResult : ScenarioStatisticsTest + .makeBehaviorList(2)) { + this.getDetailStatistics().add(behaviorResult); + } + Map map = this.detailStatistics + .getBehaviorBriefStatistics(1); + assertTrue(mapEquals(map, makeExpectedMapForTwo())); + } + + private Map makeExpectedMapForTwo() { + Map ret = new HashMap(); + ret.put(new Integer(200), buildCodeResult(20, 1, 200, 200, 200)); + ret.put(new Integer(400), buildCodeResult(0, 1, 0, 0, 0)); + return ret; + } + + private BehaviorStatusCodeResult buildCodeResult(long contentLength, + long count, long maxResponseTime, long minResponseTime, + long totalResponseTimeThisTime) { + BehaviorStatusCodeResult ret = new BehaviorStatusCodeResult(""); + ret.contentLength = contentLength; + ret.count = count; + ret.maxResponseTime = maxResponseTime; + ret.minResponseTime = minResponseTime; + ret.totalResponseTimeThisTime = totalResponseTimeThisTime; + return ret; + } + + private boolean mapEquals(Map mapActual, + Map mapExpected) { + boolean equal = true; + if (mapActual.size() != mapExpected.size()) { + return false; + } + for (int i : mapActual.keySet()) { + if (!mapActual.get(i).equals(mapExpected.get(i))) { + equal = false; + } + } + return equal; + } + + @Test + public void addThreeTest() { + for (BehaviorResult behaviorResult : ScenarioStatisticsTest + .makeBehaviorList(3)) { + this.getDetailStatistics().add(behaviorResult); + } + Map mapActual = this + .getDetailStatistics().getBehaviorBriefStatistics(1); + assertTrue(mapEquals(mapActual, makeExpectedMapForThree())); + } + + private Map makeExpectedMapForThree() { + Map retMap = new HashMap(); + retMap.put(200, buildCodeResult(40, 2, 220, 200, 420)); + retMap.put(400, buildCodeResult(0, 1, 0, 0, 0)); + return retMap; + } +} diff --git a/Bench4Q-Agent/src/test/java/org/bench4q/agent/test/datastatistics/PageResultStatisticsTest.java b/Bench4Q-Agent/src/test/java/org/bench4q/agent/test/datastatistics/PageResultStatisticsTest.java new file mode 100644 index 00000000..a6b4dad8 --- /dev/null +++ b/Bench4Q-Agent/src/test/java/org/bench4q/agent/test/datastatistics/PageResultStatisticsTest.java @@ -0,0 +1,133 @@ +package org.bench4q.agent.test.datastatistics; + +import org.bench4q.agent.datacollector.DataCollector; +import org.bench4q.agent.datacollector.impl.PageResultCollector; +import org.bench4q.agent.scenario.PageResult; +import org.bench4q.share.models.agent.statistics.AgentPageBriefModel; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.context.support.ClassPathXmlApplicationContext; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +import static org.junit.Assert.*; + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration(locations = { "classpath:test-storage-context.xml", + "classpath*:/org/bench4q/agent/config/application-context.xml" }) +public class PageResultStatisticsTest { + private DataCollector dataCollector; + + private DataCollector getDataCollector() { + return dataCollector; + } + + private void setDataCollector(DataCollector dataCollector) { + this.dataCollector = dataCollector; + } + + @SuppressWarnings("resource") + public PageResultStatisticsTest() { + new ClassPathXmlApplicationContext( + "classpath*:/org/bench4q/agent/config/application-context.xml"); + this.setDataCollector(new PageResultCollector()); + } + + @Test + public void pageResultTest() { + PageResult pageResult = PageResult.buildPageResult(2, + ScenarioStatisticsTest.makeBehaviorList(1)); + assertEquals(2, pageResult.getPageId()); + assertEquals(200, pageResult.getExecuteRange()); + assertTrue(pageResult.getPageStartTime() > 0); + } + + @Test + public void pageResultWithTwoBehaviorTest() { + PageResult pageResult = PageResult.buildPageResult(2, + ScenarioStatisticsTest.makeBehaviorList(2)); + assertEquals(2, pageResult.getPageId()); + assertEquals(220, pageResult.getExecuteRange()); + assertEquals(200, pageResult.getPageStartTime()); + assertEquals(420, pageResult.getPageEndTime()); + } + + @Test + public void testNull() { + this.getDataCollector().add((PageResult) null); + assertNotNull(dataCollector.getPageBriefStatistics(0)); + } + + @Test + public void testOnePaegWithOneBehaviorResult() { + this.getDataCollector().add( + PageResult.buildPageResult(2, + ScenarioStatisticsTest.makeBehaviorList(1))); + AgentPageBriefModel pageBriefModel = (AgentPageBriefModel) this + .getDataCollector().getPageBriefStatistics(2); + assertEquals(2, pageBriefModel.getPageId()); + assertEquals(1, pageBriefModel.getCountFromBegin()); + assertEquals(1, pageBriefModel.getCountThisTime()); + assertEquals(200, pageBriefModel.getMaxResponseTimeFromBegin()); + assertEquals(200, pageBriefModel.getMinResponseTimeFromBegin()); + assertTrue(pageBriefModel.getTimeFrame() >= 0); + assertEquals(200, pageBriefModel.getTotalResponseTimeThisTime()); + assertEquals(200, pageBriefModel.getLatestResponseTime()); + } + + @Test + public void testOnePageWithTwoBehaviorResult() { + this.getDataCollector().add( + PageResult.buildPageResult(2, + ScenarioStatisticsTest.makeBehaviorList(2))); + AgentPageBriefModel pageBriefModel = (AgentPageBriefModel) this + .getDataCollector().getPageBriefStatistics(2); + System.out.println(pageBriefModel.getCountFromBegin()); + assertEquals(2, pageBriefModel.getPageId()); + assertEquals(1, pageBriefModel.getCountFromBegin()); + assertEquals(1, pageBriefModel.getCountThisTime()); + assertEquals(220, pageBriefModel.getMaxResponseTimeFromBegin()); + assertEquals(220, pageBriefModel.getMinResponseTimeFromBegin()); + assertTrue(pageBriefModel.getTimeFrame() >= 0); + assertEquals(220, pageBriefModel.getTotalResponseTimeThisTime()); + assertEquals(220, pageBriefModel.getLatestResponseTime()); + } + + @Test + public void testTwoPageWithStatisticsAtLast() { + this.getDataCollector().add( + PageResult.buildPageResult(2, + ScenarioStatisticsTest.makeBehaviorList(1))); + this.getDataCollector().add( + PageResult.buildPageResult(2, + ScenarioStatisticsTest.makeBehaviorList(2))); + AgentPageBriefModel pageBriefModel = (AgentPageBriefModel) this + .getDataCollector().getPageBriefStatistics(2); + assertEquals(2, pageBriefModel.getPageId()); + assertEquals(2, pageBriefModel.getCountFromBegin()); + assertEquals(2, pageBriefModel.getCountThisTime()); + assertEquals(220, pageBriefModel.getMaxResponseTimeFromBegin()); + assertEquals(200, pageBriefModel.getMinResponseTimeFromBegin()); + assertEquals(420, pageBriefModel.getTotalResponseTimeThisTime()); + assertTrue(pageBriefModel.getTimeFrame() >= 0); + assertEquals(220, pageBriefModel.getLatestResponseTime()); + } + + @Test + public void testTwoPageWithStatisticsIndividually() { + testOnePaegWithOneBehaviorResult(); + this.getDataCollector().add( + PageResult.buildPageResult(2, + ScenarioStatisticsTest.makeBehaviorList(2))); + AgentPageBriefModel model = (AgentPageBriefModel) this.getDataCollector() + .getPageBriefStatistics(2); + assertEquals(2, model.getPageId()); + assertEquals(2, model.getCountFromBegin()); + assertEquals(1, model.getCountThisTime()); + assertEquals(220, model.getMaxResponseTimeFromBegin()); + assertEquals(200, model.getMinResponseTimeFromBegin()); + assertEquals(220, model.getTotalResponseTimeThisTime()); + assertTrue(model.getTimeFrame() >= -0); + assertEquals(220, model.getLatestResponseTime()); + } +} diff --git a/Bench4Q-Agent/src/test/java/org/bench4q/agent/test/datastatistics/ScenarioStatisticsTest.java b/Bench4Q-Agent/src/test/java/org/bench4q/agent/test/datastatistics/ScenarioStatisticsTest.java new file mode 100644 index 00000000..e8680020 --- /dev/null +++ b/Bench4Q-Agent/src/test/java/org/bench4q/agent/test/datastatistics/ScenarioStatisticsTest.java @@ -0,0 +1,173 @@ +package org.bench4q.agent.test.datastatistics; + +import static org.junit.Assert.*; + +import java.util.ArrayList; +import java.util.Date; +import java.util.List; +import java.util.UUID; + +import org.bench4q.agent.datacollector.DataCollector; +import org.bench4q.agent.datacollector.impl.ScenarioResultCollector; +import org.bench4q.agent.scenario.BehaviorResult; +import org.bench4q.agent.scenario.PageResult; +import org.bench4q.agent.storage.StorageHelper; +import org.bench4q.share.models.agent.statistics.AgentBriefStatusModel; +import org.junit.Test; +import org.springframework.context.ApplicationContext; +import org.springframework.context.support.ClassPathXmlApplicationContext; + +public class ScenarioStatisticsTest { + private DataCollector dataStatistics; + + protected DataCollector getDataStatistics() { + return dataStatistics; + } + + private void setDataStatistics(DataCollector dataStatistics) { + this.dataStatistics = dataStatistics; + } + + public ScenarioStatisticsTest() { + init(); + } + + public void init() { + @SuppressWarnings("resource") + ApplicationContext context = new ClassPathXmlApplicationContext( + "classpath*:/org/bench4q/agent/config/application-context.xml"); + ScenarioResultCollector agentResultDataCollector = new ScenarioResultCollector( + UUID.randomUUID()); + agentResultDataCollector.setStorageHelper((StorageHelper) context + .getBean(StorageHelper.class)); + this.setDataStatistics(agentResultDataCollector); + } + + @Test + public void addZeroBriefTest() { + for (BehaviorResult behaviorResult : makeBehaviorList(0)) { + this.getDataStatistics().add(behaviorResult); + } + AgentBriefStatusModel model = (AgentBriefStatusModel) this + .getDataStatistics().getScenarioBriefStatistics(); + AgentBriefStatusModel modelExpect = makeAllZeroModel(); + modelExpect.setTimeFrame(model.getTimeFrame()); + assertTrue(model.equals(modelExpect)); + } + + @Test + public void addOneBriefTest() throws InterruptedException { + for (BehaviorResult behaviorResult : makeBehaviorList(1)) { + this.getDataStatistics().add(behaviorResult); + } + + Thread.sleep(100); + AgentBriefStatusModel model = (AgentBriefStatusModel) this + .getDataStatistics().getScenarioBriefStatistics(); + AgentBriefStatusModel modelExpect = new AgentBriefStatusModel(); + modelExpect.setTimeFrame(model.getTimeFrame()); + makeUpStatusModelForOneBehavior(modelExpect); + assertTrue(model.equals(modelExpect)); + } + + @Test + public void addTwoBriefTest() throws InterruptedException { + for (BehaviorResult behaviorResult : makeBehaviorList(2)) { + this.getDataStatistics().add(behaviorResult); + } + Thread.sleep(100); + AgentBriefStatusModel model = (AgentBriefStatusModel) this + .getDataStatistics().getScenarioBriefStatistics(); + AgentBriefStatusModel modelExpect = makeUpStatusModelForTwoBehavior(model + .getTimeFrame()); + assertTrue(model.equals(modelExpect)); + } + + public static AgentBriefStatusModel makeUpStatusModelForTwoBehavior( + long timeFrame) { + AgentBriefStatusModel model = new AgentBriefStatusModel(); + model.setTimeFrame(timeFrame); + model.setSuccessThroughputThisTime(1 * 1000 / timeFrame); + model.setFailCountFromBegin(1); + model.setFailThroughputThisTime(1 * 1000 / timeFrame); + model.setMaxResponseTime(200); + model.setMinResponseTime(200); + model.setSuccessCountFromBegin(1); + model.setSuccessCountThisTime(1); + model.setFailCountThisTime(1); + model.setTotalResponseTimeThisTime(200); + model.setTotalSqureResponseTimeThisTime(40000); + return model; + } + + public static void makeUpStatusModelForOneBehavior( + AgentBriefStatusModel model) { + model.setSuccessThroughputThisTime(1 * 1000 / model.getTimeFrame()); + model.setFailCountFromBegin(0); + model.setFailThroughputThisTime(0); + model.setMaxResponseTime(200); + model.setMinResponseTime(200); + model.setSuccessCountFromBegin(1); + model.setSuccessCountThisTime(1); + model.setFailCountThisTime(0); + model.setTotalResponseTimeThisTime(200); + model.setTotalSqureResponseTimeThisTime(40000); + } + + public static AgentBriefStatusModel makeAllZeroModel() { + AgentBriefStatusModel model = new AgentBriefStatusModel(); + model.setSuccessThroughputThisTime(0); + model.setFailCountFromBegin(0); + model.setFailThroughputThisTime(0); + model.setMaxResponseTime(0); + model.setMinResponseTime(0); + model.setTimeFrame(0); + model.setSuccessCountFromBegin(0); + model.setTotalResponseTimeThisTime(0); + model.setSuccessCountThisTime(0); + model.setFailCountThisTime(0); + model.setTotalSqureResponseTimeThisTime(0); + return model; + } + + public static PageResult makePageResultWithBehaviorResult(int count) { + List behaviorResults = makeBehaviorList(count); + return PageResult.buildPageResult(2, behaviorResults); + } + + public static List makeBehaviorList(int count) { + List behaviorResults = new ArrayList(); + for (int i = 0; i < count; i++) { + int statusCode = i % 2 == 0 ? 200 : 400; + behaviorResults.add(buildBehaviorResult(200 + 10 * i, i % 2 == 0, + statusCode, 1, 200 + 10 * i)); + } + return behaviorResults; + } + + public static BehaviorResult buildBehaviorResult(long responseTime, + boolean success, int statusCode, int behaviorId, long startDateTime) { + Date date = new Date(startDateTime); + BehaviorResult result = new BehaviorResult(); + result.setBehaviorName(""); + result.setEndDate(new Date(date.getTime() + responseTime)); + result.setPluginId("Get"); + result.setPluginName("get"); + result.setResponseTime(responseTime); + result.setStartDate(date); + result.setSuccess(success); + result.setShouldBeCountResponseTime(true); + + result.setBehaviorId(behaviorId); + if (result.isSuccess()) { + result.setContentLength(20); + result.setContentType("image"); + } else { + result.setContentLength(0); + result.setContentType(""); + } + result.setStatusCode(statusCode); + return result; + } + +} diff --git a/Bench4Q-Agent/src/test/java/org/bench4q/agent/test/model/ModelTest.java b/Bench4Q-Agent/src/test/java/org/bench4q/agent/test/model/ModelTest.java new file mode 100644 index 00000000..b11ce4b3 --- /dev/null +++ b/Bench4Q-Agent/src/test/java/org/bench4q/agent/test/model/ModelTest.java @@ -0,0 +1,30 @@ +package org.bench4q.agent.test.model; + +import java.io.File; +import java.io.IOException; + +import javax.xml.bind.JAXBContext; +import javax.xml.bind.JAXBException; +import javax.xml.bind.annotation.XmlRootElement; + +import org.bench4q.share.models.agent.scriptrecord.BehaviorModel; +import org.junit.Test; + +import static org.junit.Assert.*; + +@XmlRootElement(name = "modelTest") +public class ModelTest { + + @Test + public void unmarshalVerify() throws IOException, JAXBException { + Object object = JAXBContext + .newInstance(BehaviorModel.class) + .createUnmarshaller() + .unmarshal( + new File("Scripts" + + System.getProperty("file.separator") + + "behaviorModel.xml")); + assertTrue(object instanceof BehaviorModel); + } + +} diff --git a/Bench4Q-Agent/src/test/java/org/bench4q/agent/test/model/UserBehaviorModelTest.java b/Bench4Q-Agent/src/test/java/org/bench4q/agent/test/model/UserBehaviorModelTest.java new file mode 100644 index 00000000..c74138d7 --- /dev/null +++ b/Bench4Q-Agent/src/test/java/org/bench4q/agent/test/model/UserBehaviorModelTest.java @@ -0,0 +1,26 @@ +package org.bench4q.agent.test.model; + +import static org.junit.Assert.*; + +import java.io.File; + +import javax.xml.bind.JAXBContext; +import javax.xml.bind.JAXBException; +import javax.xml.bind.Unmarshaller; + +import org.bench4q.share.models.agent.scriptrecord.BehaviorModel; +import org.junit.Test; + +public class UserBehaviorModelTest { + + @Test + public void testUnmarshal() throws JAXBException { + Unmarshaller unmarshaller = JAXBContext.newInstance( + BehaviorModel.class).createUnmarshaller(); + Object object = unmarshaller.unmarshal(new File("Scripts" + + System.getProperty("file.separator") + "behaviorModel.xml")); + BehaviorModel userBehaviorModel = (BehaviorModel) object; + System.out.println(userBehaviorModel.getUse()); + assertTrue(object instanceof BehaviorModel); + } +} diff --git a/Bench4Q-Agent/src/test/java/org/bench4q/agent/test/parameterization/TEST_HelloThread.java b/Bench4Q-Agent/src/test/java/org/bench4q/agent/test/parameterization/TEST_HelloThread.java new file mode 100644 index 00000000..b93f6413 --- /dev/null +++ b/Bench4Q-Agent/src/test/java/org/bench4q/agent/test/parameterization/TEST_HelloThread.java @@ -0,0 +1,64 @@ +package org.bench4q.agent.test.parameterization; + +import org.bench4q.agent.parameterization.impl.InstanceControler; +import org.bench4q.share.helper.TestHelper; + +public class TEST_HelloThread extends Thread { + InstanceControler ic; + + public TEST_HelloThread() { + ic = new InstanceControler(); + } + + public void run() { + java.util.Random r = new java.util.Random(); + int t = r.nextInt(10000); + System.out.print(Thread.currentThread().getId()); + System.out.println(":" + t); + try { + Thread.sleep(t); + } catch (InterruptedException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + System.out.print(Thread.currentThread().getId()); + System.out.print("\t"); + + String userName = ic + .getParam(""); + String passwordName = ic + .getParam(""); + System.out.print(userName); + System.out.print("\t"); + System.out.println(passwordName); + try { + Thread.sleep(r.nextInt(10000)); + } catch (InterruptedException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + // ic.releaseAll(); + try { + TestHelper.invokePrivate(ic, "releaseAll", null, null); + } catch (Exception e) { + e.printStackTrace(); + } + + } + + public static void main(String[] args) { + while (true) { + TEST_HelloThread h1 = new TEST_HelloThread(); + + h1.start(); + try { + Thread.sleep(1000); + } catch (InterruptedException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + } + + // private String name; +} diff --git a/Bench4Q-Agent/src/test/java/org/bench4q/agent/test/parameterization/TEST_UserName.java b/Bench4Q-Agent/src/test/java/org/bench4q/agent/test/parameterization/TEST_UserName.java new file mode 100644 index 00000000..89e4f2f2 --- /dev/null +++ b/Bench4Q-Agent/src/test/java/org/bench4q/agent/test/parameterization/TEST_UserName.java @@ -0,0 +1,37 @@ +package org.bench4q.agent.test.parameterization; + +import static org.junit.Assert.*; + +import java.util.HashMap; + +import org.bench4q.agent.parameterization.impl.InstanceControler; +import org.bench4q.agent.parameterization.impl.Para_Table; +import org.bench4q.share.helper.TestHelper; +import org.junit.Test; + +public class TEST_UserName { + + @Test + public void testGetParam() throws Exception { + Para_Table table = new Para_Table(); + String ret = table.getTableColumnValue(java.util.UUID.randomUUID(), + new HashMap(), "file", + "ScenarioParameters\\param1.txt", "0", "sequence", ";", "~", + "2"); + System.out.println(ret); + + InstanceControler ic = new InstanceControler(); + String passwordName = ic + .getParam(""); + System.out.println(passwordName); + assertNotNull(passwordName); + InstanceControler instanceControler = new InstanceControler(); + String password2 = instanceControler + .getParam(""); + System.out.println(password2); + assertNotNull(password2); + assertEquals(Integer.parseInt(passwordName) + 10, + Integer.parseInt(password2)); + TestHelper.invokePrivate(ic, "releaseAll", null, null); + } +} diff --git a/Bench4Q-Agent/src/test/java/org/bench4q/agent/test/parameterization/Test_ParameterizationParser.java b/Bench4Q-Agent/src/test/java/org/bench4q/agent/test/parameterization/Test_ParameterizationParser.java new file mode 100644 index 00000000..a802129b --- /dev/null +++ b/Bench4Q-Agent/src/test/java/org/bench4q/agent/test/parameterization/Test_ParameterizationParser.java @@ -0,0 +1,26 @@ +package org.bench4q.agent.test.parameterization; + +import static org.junit.Assert.assertEquals; + +import org.bench4q.agent.parameterization.impl.InstanceControler; +import org.bench4q.agent.parameterization.impl.ParameterizationParser; +import org.bench4q.share.helper.TestHelper; +import org.junit.Test; + +public class Test_ParameterizationParser { + @Test + public void testGetClassName() throws Exception { + String result = (String) TestHelper.invokePrivate( + new ParameterizationParser(), "getCurrentPackageFullName", + null, null); + assertEquals("org.bench4q.agent.parameterization.impl", result); + } + + @Test + public void testParse() { + String result = ParameterizationParser.parse( + "", new InstanceControler()); + System.out.println(result); + } +} diff --git a/Bench4Q-Agent/src/test/java/org/bench4q/agent/test/plugin/Test_HttpPlugin.java b/Bench4Q-Agent/src/test/java/org/bench4q/agent/test/plugin/Test_HttpPlugin.java new file mode 100644 index 00000000..930951c4 --- /dev/null +++ b/Bench4Q-Agent/src/test/java/org/bench4q/agent/test/plugin/Test_HttpPlugin.java @@ -0,0 +1,134 @@ +package org.bench4q.agent.test.plugin; + +import java.util.Map; + +import org.apache.commons.httpclient.Cookie; +import org.apache.commons.httpclient.cookie.MalformedCookieException; +import org.bench4q.agent.plugin.basic.http.HttpPlugin; +import org.bench4q.agent.plugin.result.HttpReturn; +import org.bench4q.agent.plugin.result.PluginReturn; +import org.bench4q.share.helper.TestHelper; +import org.junit.Test; + +import static org.junit.Assert.*; + +public class Test_HttpPlugin { + private static final int UnAuthorized = 401; + private HttpPlugin httpPlugin; + + private HttpPlugin getHttpPlugin() { + return httpPlugin; + } + + private void setHttpPlugin(HttpPlugin httpPlugin) { + this.httpPlugin = httpPlugin; + } + + public Test_HttpPlugin() { + this.setHttpPlugin(new HttpPlugin()); + } + + @Test + public void testGet() { + PluginReturn return1 = this.getHttpPlugin().get( + "http://www.baidu.com/s", "wd=ok", "", ""); + assertTrue(return1.isSuccess()); + } + + @Test + public void testPost() { + PluginReturn result = this.getHttpPlugin().post( + "http://133.133.12.2:8080/bench4q-web/login", + "userName=admin;password=admin", null, null, null, null); + assertTrue(result.isSuccess()); + } + + @Test + public void testGetWithActualBehavior() { + PluginReturn result = this + .getHttpPlugin() + .get("http://133.133.12.2:8080/bench4q-web/index.jsp", + "", + "header=Accept|value=text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8|", + null); + assertTrue(result.isSuccess()); + } + + @Test + public void testSessionAndCookie() throws MalformedCookieException, + IllegalArgumentException { + String loginPageUrl = "http://124.16.137.203:7080/cloudshare_web/login"; + HttpReturn indexReturn = this + .getHttpPlugin() + .get(loginPageUrl, + "", + "header=Accept|value=text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8|;", + null); + assertEquals(UnAuthorized, indexReturn.getStatusCode()); + assertNotNull(indexReturn.getHeaders()); + logTheCookie("first"); + + HttpReturn loginReturn = this + .getHttpPlugin() + .post(loginPageUrl, + null, + "header=Content-Type|value=application/x-www-form-urlencoded|;header=Content-Length|value=63|;header=Accept|value=text/html,application/xhtml+xml,application/xml|;", + "username=chentienan12%40otcaix.iscas.ac.cn&password=jingcai2008", + null, null); + assertEquals(302, loginReturn.getStatusCode()); + assertNotNull(loginReturn.getHeaders()); + logTheCookie("second"); + + HttpReturn homeReturn = this + .getHttpPlugin() + .get("http://124.16.137.203:7080/cloudshare_web/home", + null, + "header=Accept|value=text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8|;", + null); + assertEquals(200, homeReturn.getStatusCode()); + logTheCookie("third"); + + HttpReturn ticketReturn = this + .getHttpPlugin() + .post("http://124.16.137.203:7080/cloudshare_web/v2/file/ajax/uploadFiles/-1", + null, + "header=Accept|value=*/*|;" + + "header=Content-Length|value=0|;" + + "header=X-Requested-With|value=XMLHttpRequest|;", + "", + null, + "varName=ticket|varExpression=\"ticket\":\\s*?\"\\w+\",|leftBoundry=\"ticket\"\": \"|rightBoundry=\",|;"); + assertEquals(200, ticketReturn.getStatusCode()); + assertNotNull(ticketReturn.getRunTimeParams()); + assertEquals(1, ticketReturn.getRunTimeParams().size()); + System.out.println(ticketReturn.getRunTimeParams().get("ticket")); + } + + private void logTheCookie(String times) { + for (Cookie cookie : this.getHttpPlugin().getHttpClient().getState() + .getCookies()) { + System.out.println("Cookie from httpState for " + times + " : " + + cookie.getName() + " : " + cookie.getValue()); + } + } + + @Test + public void testDoExtractResponseVariables() throws Exception { + String respVarsToSave = "varName=ticket|varExpression=\"ticket\":\\s*?\"\\w+\",|leftBoundry=\"ticket\"\": \"|rightBoundry=\",|;"; + String responseBodyAsString = "{" + "\n" + + "\"ticket\": \"e55de793fc934001b156e97f94ff3eb6\"," + "\n" + + "\"parentId\": 3273," + "\n" + "\"expiresIn\": 300000" + "\n" + + "}"; + @SuppressWarnings("unchecked") + Map nameValueMap = (Map) TestHelper + .invokePrivate(this.getHttpPlugin(), + "doExtractResponseVariables", new Class[] { + String.class, String.class }, new Object[] { + respVarsToSave, responseBodyAsString }); + assertEquals(1, nameValueMap.size()); + assertTrue(nameValueMap.containsKey("ticket")); + System.out.println(nameValueMap.get("ticket")); + assertEquals("e55de793fc934001b156e97f94ff3eb6", + nameValueMap.get("ticket")); + } +} diff --git a/Bench4Q-Agent/src/test/java/org/bench4q/agent/test/scenario/Test_ScenarioContext.java b/Bench4Q-Agent/src/test/java/org/bench4q/agent/test/scenario/Test_ScenarioContext.java new file mode 100644 index 00000000..c2f4f838 --- /dev/null +++ b/Bench4Q-Agent/src/test/java/org/bench4q/agent/test/scenario/Test_ScenarioContext.java @@ -0,0 +1,27 @@ +package org.bench4q.agent.test.scenario; + +import static org.junit.Assert.*; + +import java.util.UUID; +import java.util.concurrent.TimeUnit; + +import org.bench4q.agent.scenario.Scenario; +import org.bench4q.agent.scenario.ScenarioContext; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration(locations = { "classpath*:/org/bench4q/agent/config/application-context.xml" }) +public class Test_ScenarioContext { + + @Test + public void test() { + ScenarioContext context = ScenarioContext.buildScenarioContext( + UUID.randomUUID(), new Scenario(), 20); + assertEquals(10, + context.getExecutor().getKeepAliveTime(TimeUnit.MINUTES)); + assertEquals(20, context.getExecutor().getMaximumPoolSize()); + } +} diff --git a/Bench4Q-Agent/src/test/java/org/bench4q/agent/test/scenario/utils/Test_ParameterParser.java b/Bench4Q-Agent/src/test/java/org/bench4q/agent/test/scenario/utils/Test_ParameterParser.java new file mode 100644 index 00000000..a7bb2c72 --- /dev/null +++ b/Bench4Q-Agent/src/test/java/org/bench4q/agent/test/scenario/utils/Test_ParameterParser.java @@ -0,0 +1,202 @@ +package org.bench4q.agent.test.scenario.utils; + +import static org.junit.Assert.*; + +import java.util.ArrayList; +import java.util.LinkedList; +import java.util.List; + +import org.apache.commons.httpclient.NameValuePair; +import org.bench4q.agent.plugin.basic.http.HttpPlugin; +import org.bench4q.agent.scenario.util.ParameterParser; +import org.bench4q.agent.scenario.util.Table; +import org.bench4q.share.helper.TestHelper; +import org.junit.Test; + +public class Test_ParameterParser { + private String testcase = " _nacc=yeah ;_nvid=525d29a534e918cbf04ea7159706a93d;_nvtm=0;_nvsf=0;_nvfi=1;_nlag=zh-cn;_nlmf=1389570024;_nres=1440x900;_nscd=32-bit;_nstm=0;"; + private String testHeaders = "header=Content-Type|value=application/x-www-form-urlencoded|;header=Content-Length|value=63|;header=Accept|value=text/html,application/xhtml+xml,application/xml|;"; + private String testheaderWithUpperCase = "HEADER=Content-Type|Value=application/x-www-form-urlencoded|;header=Content-Length|value=63|;header=Accept|value=text/html,application/xhtml+xml,application/xml|;"; + private static final String TESTCASE1_CONTAIN_SEPARATOR = "header=accept|value=asdfasdf\\|;|;"; + private static final String testcase2 = "header=accept|value=fafsd|;varName=abc|varValue=234|;"; + + private String testcaseWithEscapes = "varName=ticket|varExpression=\"ticket\":\\s*?\"\\w+\",|;"; + private List expectedNFField = new ArrayList() { + private static final long serialVersionUID = 1L; + { + add("_nacc=yeah"); + add("_nvid=525d29a534e918cbf04ea7159706a93d"); + add("_nvtm=0"); + add("_nvsf=0"); + add("_nvfi=1"); + add("_nlag=zh-cn"); + add("_nlmf=1389570024"); + add("_nres=1440x900"); + add("_nscd=32-bit"); + add("_nstm=0"); + } + }; + + @Test + public void testGetNumberOfEscapeCharacter() throws Exception { + assertEquals(3, "\\\\\\".length()); + assertEquals(2, TestHelper.invokePrivate(null, + "getNumberOfEscapeCharacter", new Class[] { String.class }, + new Object[] { "\\\\" })); + } + + @Test + public void testGetRealTokenForContainSeparator() throws Exception { + List entryList = invokeGetRealTokens( + Table.ESCAPE_ROW_SEPARATOR, TESTCASE1_CONTAIN_SEPARATOR, true); + assertEquals(1, entryList.size()); + assertEquals("header=accept|value=asdfasdf|;", entryList.get(0)); + } + + @Test + public void testGetRealTokenForContainManyEscapse() throws Exception { + List rowList = invokeGetRealTokens(Table.ESCAPE_ROW_SEPARATOR, + testcaseWithEscapes, false); + assertEquals(1, rowList.size()); + assertEquals("varName=ticket|varExpression=\"ticket\":\\s*?\"\\w+\",", + rowList.get(0)); + + final List columnList = invokeGetRealTokens( + Table.ESCAPE_COLUMN_SEPARATOR, rowList.get(0), false); + assertEquals(2, columnList.size()); + assertEquals("varName=ticket", columnList.get(0)); + assertEquals("varExpression=\"ticket\":\\s*?\"\\w+\",", + columnList.get(1)); + @SuppressWarnings("unchecked") + List> result = (List>) TestHelper + .invokePrivate(null, "extractValueFromWellFormedTable", + new Class[] { List.class }, + new Object[] { new LinkedList>() { + private static final long serialVersionUID = 1L; + { + add(columnList); + } + } }); + // Table.extractValueFromWellFormedTable(new LinkedList>() + // { + // private static final long serialVersionUID = 1L; + // { + // add(columnList); + // } + // }); + assertEquals(1, result.size()); + assertEquals(2, result.get(0).size()); + assertEquals("ticket", result.get(0).get(0)); + assertEquals("\"ticket\":\\s*?\"\\w+\",", result.get(0).get(1)); + } + + @SuppressWarnings("unchecked") + private List invokeGetRealTokens(String separator, String value, + boolean toUnescapeSeparator) throws Exception { + return (List) TestHelper.invokePrivate(null, "getRealTokens", + new Class[] { String.class, String.class, boolean.class }, + new Object[] { separator, value, true }); + } + + @Test + public void testGetRealTokensForMultiSeparator() throws Exception { + List entryList = invokeGetRealTokens( + Table.ESCAPE_ROW_SEPARATOR, testcase2, false); + assertEquals(2, entryList.size()); + assertEquals("header=accept|value=fafsd", entryList.get(0)); + assertEquals("varName=abc|varValue=234", entryList.get(1)); + } + + @Test + public void testGetTableForSeparator() { + List> resultEntries = buildHeaderTable( + TESTCASE1_CONTAIN_SEPARATOR).getRealContent(); + assertEquals(1, resultEntries.size()); + assertEquals(2, resultEntries.get(0).size()); + assertEquals("accept", resultEntries.get(0).get(0)); + assertEquals("asdfasdf|;", resultEntries.get(0).get(1)); + } + + @Test + public void testGetTableForMultipleHeader() { + List> resultEntries = buildHeaderTable(testcase2) + .getRealContent(); + assertEquals(2, resultEntries.size()); + assertEquals("fafsd", resultEntries.get(0).get(1)); + assertEquals("accept", resultEntries.get(0).get(0)); + assertEquals("234", resultEntries.get(1).get(1)); + assertEquals("abc", resultEntries.get(1).get(0)); + } + + private Table buildHeaderTable(String value) { + return ParameterParser.buildTable(value, new LinkedList() { + private static final long serialVersionUID = -6734367739974282326L; + { + add("header"); + add("value"); + } + }); + } + + @Test + public void testGetTableWithManyEscapse() { + List> resultTable = buildHeaderTable(testcaseWithEscapes) + .getRealContent(); + assertEquals(1, resultTable.size()); + assertEquals(2, resultTable.get(0).size()); + assertEquals("ticket", resultTable.get(0).get(0)); + assertEquals("\"ticket\":\\s*?\"\\w+\",", resultTable.get(0).get(1)); + } + + @Test + public void testParseParam() { + List result = ParameterParser.buildNField(testcase); + assertEquals(10, result.size()); + for (int i = 0; i < result.size(); i++) { + assertEquals(result.get(i), expectedNFField.get(i)); + System.out.println(result.get(i)); + } + } + + @Test + public void testGetHeadersWithRightCase() throws Exception { + @SuppressWarnings("unchecked") + List nvPairs = (List) TestHelper + .invokePrivate(new HttpPlugin(), "parseHeaders", + new Class[] { String.class }, + new Object[] { testHeaders }); + + assertEquals(3, nvPairs.size()); + assertEquals("Content-Type", nvPairs.get(0).getName()); + assertEquals("application/x-www-form-urlencoded", nvPairs.get(0) + .getValue()); + assertEquals("Content-Length", nvPairs.get(1).getName()); + assertEquals("63", nvPairs.get(1).getValue()); + assertEquals("Accept", nvPairs.get(2).getName()); + assertEquals("text/html,application/xhtml+xml,application/xml", nvPairs + .get(2).getValue()); + } + + @Test + public void testGetHeadersWithUpperCase() throws Exception { + @SuppressWarnings("unchecked") + List nvPairs = (List) TestHelper + .invokePrivate(new HttpPlugin(), "parseHeaders", + new Class[] { String.class }, + new Object[] { testheaderWithUpperCase }); + assertEquals(3, nvPairs.size()); + assertEquals("Content-Type", nvPairs.get(0).getName()); + assertEquals("application/x-www-form-urlencoded", nvPairs.get(0) + .getValue()); + assertEquals("Content-Length", nvPairs.get(1).getName()); + assertEquals("63", nvPairs.get(1).getValue()); + assertEquals("Accept", nvPairs.get(2).getName()); + assertEquals("text/html,application/xhtml+xml,application/xml", nvPairs + .get(2).getValue()); + } + + @Test + public void testParseResponseVariables() { + + } +} diff --git a/Bench4Q-Agent/src/test/java/org/bench4q/agent/test/scenario/utils/Test_RegularExpression.java b/Bench4Q-Agent/src/test/java/org/bench4q/agent/test/scenario/utils/Test_RegularExpression.java new file mode 100644 index 00000000..0597fc4d --- /dev/null +++ b/Bench4Q-Agent/src/test/java/org/bench4q/agent/test/scenario/utils/Test_RegularExpression.java @@ -0,0 +1,31 @@ +package org.bench4q.agent.test.scenario.utils; + +import static org.junit.Assert.*; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import org.junit.Test; + +public class Test_RegularExpression { + String regex1 = "(?i)((^[aeiou])|(\\s+[aeiou]))\\w+?[aeiou]\\b"; + String regex2 = "(?i)\\w+?[aeiou]"; + String regex3 = "(?i)(\\s+[aeiou])\\w+?[aeiou]\b"; + String regex4 = "(?i)(^[aeiou])\\w+?[aeiou]\b"; + String target1 = "Arline ate eight apples and one orange while anita hadn't any"; + String target2 = "Arline ate"; + + @Test + public void test() { + + Pattern pattern = Pattern.compile(regex2); + + Matcher matcher = pattern.matcher(target1); + System.out.println(matcher.matches()); + matcher.reset(); + while (matcher.find()) { + System.out.println(matcher.group()); + } + fail(); + } +} diff --git a/Bench4Q-Agent/src/test/java/org/bench4q/agent/test/storage/TestDoubleBufferStorage.java b/Bench4Q-Agent/src/test/java/org/bench4q/agent/test/storage/TestDoubleBufferStorage.java new file mode 100644 index 00000000..3559adc2 --- /dev/null +++ b/Bench4Q-Agent/src/test/java/org/bench4q/agent/test/storage/TestDoubleBufferStorage.java @@ -0,0 +1,204 @@ +package org.bench4q.agent.test.storage; + +import static org.junit.Assert.*; + +import java.io.File; +import java.io.IOException; +import java.util.List; + +import org.bench4q.agent.storage.Buffer; +import org.bench4q.agent.storage.DoubleBufferStorage; +import org.bench4q.share.helper.TestHelper; +import org.junit.After; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.test.annotation.DirtiesContext; +import org.springframework.test.annotation.DirtiesContext.ClassMode; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration(locations = { "classpath*:/org/bench4q/agent/config/application-context.xml" }) +public class TestDoubleBufferStorage { + private DoubleBufferStorage doubleBufferStorage; + private static String SAVE_DIR = "StorageTest" + + System.getProperty("file.separator"); + private static final String INPUT_FILE_PATH = SAVE_DIR + "testInput.txt"; + private static String SAVE_PATH = SAVE_DIR + "test.txt"; + + private DoubleBufferStorage getDoubleBufferStorage() { + return doubleBufferStorage; + } + + @Autowired + private void setDoubleBufferStorage(DoubleBufferStorage doubleBufferStorage) { + this.doubleBufferStorage = doubleBufferStorage; + } + + public TestDoubleBufferStorage() throws IOException { + File dir = new File(SAVE_DIR); + if (!dir.exists()) { + dir.mkdirs(); + } + File outPutFile = new File(SAVE_PATH); + if (!outPutFile.exists()) { + outPutFile.createNewFile(); + } + File inputFile = new File(INPUT_FILE_PATH); + if (!inputFile.exists()) { + inputFile.createNewFile(); + } + } + + @After + public void cleanUp() { + File file = new File(SAVE_DIR + "test.txt"); + if (file.exists()) { + file.delete(); + } + for (int i = 0; i < 4; ++i) { + String realSavePathString = this.getDoubleBufferStorage() + .calculateSavePath(SAVE_PATH, i); + File output = new File(realSavePathString); + if (output.exists()) { + output.delete(); + } + } + } + + @SuppressWarnings("unchecked") + @Test + public void testWriteWithLittleContent() throws Exception { + this.getDoubleBufferStorage().writeFile("test", SAVE_PATH); + assertEquals( + 48 * 1024 - 4, + ((Buffer) invokePrivateMethod(this.getDoubleBufferStorage() + .getClass(), this.getDoubleBufferStorage(), + "getCurrentBuffer", null, null)).getRemainSize()); + List buffers = ((List) invokePrivateMethod(this + .getDoubleBufferStorage().getClass(), + this.getDoubleBufferStorage(), "getBufferList", null, null)); + for (int i = 0; i < buffers.size() + && i != (Integer) invokePrivateMethod(this + .getDoubleBufferStorage().getClass(), + this.getDoubleBufferStorage(), "getCurrentBufferIndex", + null, null); i++) { + assertEquals(48 * 1024, buffers.get(i).getRemainSize()); + } + } + + @Test + @DirtiesContext(classMode = ClassMode.AFTER_EACH_TEST_METHOD) + public void testWriteWithJustLargerThanOneBufferContent() throws Exception { + String realSavePathString = this.getDoubleBufferStorage() + .calculateSavePath( + SAVE_PATH, + (Integer) invokePrivateMethod(this + .getDoubleBufferStorage().getClass(), this + .getDoubleBufferStorage(), + "getCurrentBufferIndex", null, null)); + doWriteFile(95); + while (!this.getDoubleBufferStorage().forTest.isSuccess()) { + Thread.sleep(1000); + } + String readContent = this.getDoubleBufferStorage().readFiles( + realSavePathString); + assertTrue(readContent.length() <= 48 * 1024); + assertTrue(readContent.length() >= 46 * 1024); + assertTrue(readContent.indexOf("encoding") > 0); + Buffer currentBuffer = (Buffer) invokePrivateMethod(this + .getDoubleBufferStorage().getClass(), + this.getDoubleBufferStorage(), "getCurrentBuffer", null, null); + System.out.println(currentBuffer.getCurrentPos()); + System.out + .println((Integer) invokePrivateMethod(this + .getDoubleBufferStorage().getClass(), this + .getDoubleBufferStorage(), "getCurrentBufferIndex", + null, null)); + assertTrue(currentBuffer.getCurrentPos() == 1563); + } + + private void doWriteFile(int size) { + String saveContent = this.getDoubleBufferStorage().readFiles( + INPUT_FILE_PATH); + for (int i = 0; i < size; i++) { + this.getDoubleBufferStorage().writeFile(saveContent, SAVE_PATH); + } + } + + @Test + @DirtiesContext(classMode = ClassMode.AFTER_EACH_TEST_METHOD) + public void testWriteWithJustLargerThanTwoBufferContent() + throws InterruptedException { + doWriteFile(92 * 2 + 2); + while (!this.getDoubleBufferStorage().forTest.isSuccess()) { + Thread.sleep(1000); + } + assertEquals(47932 * 2, getResultLength()); + } + + @Test + @DirtiesContext(classMode = ClassMode.AFTER_EACH_TEST_METHOD) + public void testWriteContentLargerThanThree() throws InterruptedException { + doWriteFile(92 * 3 + 2); + while (!this.getDoubleBufferStorage().forTest.isSuccess()) { + Thread.sleep(1000); + } + int resultLength = getResultLength(); + assertEquals(47932 * 3, resultLength); + } + + private int getResultLength() { + int resultLength = 0; + for (int i = 0; i < 4; i++) { + String path = this.getDoubleBufferStorage().calculateSavePath( + SAVE_PATH, i); + if (!new File(path).exists()) { + continue; + } + String readContentString = this.getDoubleBufferStorage().readFiles( + path); + resultLength += readContentString.length(); + } + return resultLength; + } + + @Test + public void testChangeBuffer() throws Exception { + @SuppressWarnings("unchecked") + List buffers = (List) invokePrivateMethod(this + .getDoubleBufferStorage().getClass(), + this.getDoubleBufferStorage(), "getBufferList", null, null); + buffers.get(0).setCurrentPos(48 * 1024 - 1220); + buffers.get(1).setCurrentPos(0); + invokePrivateMethod(getDoubleBufferStorage().getClass(), + this.getDoubleBufferStorage(), "setCurrentBufferIndex", + new Class[] { int.class }, new Object[] { 0 }); + invokePrivateMethod(this.getDoubleBufferStorage().getClass(), + this.getDoubleBufferStorage(), "changeToTheMaxRemainBuffer", + null, null); + + assertEquals(1220, buffers.get(0).getRemainSize()); + assertEquals(48 * 1024, buffers.get(1).getRemainSize()); + assertEquals( + 1, + invokePrivateMethod(this.getDoubleBufferStorage().getClass(), + this.getDoubleBufferStorage(), "getCurrentBufferIndex", + null, null)); + } + + private static Object invokePrivateMethod(Class containerClass, + Object targetObject, String methodName, Class[] paramClasses, + Object[] params) throws Exception { + return TestHelper.invokePrivate(targetObject, methodName, paramClasses, + params); + } + + @Test + public void testReadFiles() { + String content = this.getDoubleBufferStorage().readFiles( + INPUT_FILE_PATH); + assertEquals(content.length(), 521); + } +} diff --git a/Bench4Q-Agent/src/test/resources/test-storage-context.xml b/Bench4Q-Agent/src/test/resources/test-storage-context.xml new file mode 100644 index 00000000..dcef0042 --- /dev/null +++ b/Bench4Q-Agent/src/test/resources/test-storage-context.xml @@ -0,0 +1,11 @@ + + + + + diff --git a/LICENSE b/LICENSE new file mode 100644 index 00000000..70566f2d --- /dev/null +++ b/LICENSE @@ -0,0 +1,674 @@ +GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + {one line to give the program's name and a brief idea of what it does.} + Copyright (C) {year} {name of author} + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + {project} Copyright (C) {year} {fullname} + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. \ No newline at end of file diff --git a/README.md b/README.md index dd813340..83c5f3ad 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,8 @@ -Bench4Q-Master -============== +======= +======= +Bench4Q +======= -Master Node of Bench4Q -When you get the Bench4Q-Master's source code, you should get the Bench4Q-Share project, and run"mvn install" -on the share project. \ No newline at end of file + +A QoS-Oriented E-Commerce Benchmark