diff --git a/.gitignore b/.gitignore
index 49f3cbee..ad913b3b 100644
--- a/.gitignore
+++ b/.gitignore
@@ -14,4 +14,4 @@
/WindowsMonitor/Monitor/x64
/WindowsMonitor/Native/Debug
/WindowsMonitor/Native/Release
-/WindowsMonitor/Native/x64
\ No newline at end of file
+/WindowsMonitor/Native/x64
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
+
+
+
+
+
+
+ -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
+
+
\ 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
+
+
+
+ -1
+ 0
+ -1
+
+
+
+
+ 0
+ Sleep
+
+
+ time
+ 15
+
+
+ TIMERBEHAVIOR
+
+
+
+ -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
+
+
+
+ 4
+ 2
+ -1
+
+
+
+
+ 0
+ Sleep
+
+
+ time
+ 133
+
+
+ TIMERBEHAVIOR
+
+
+
+ -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
+
+
+
+ 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
+
+
+
+ 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
+
+
+
+ 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
+
+
+
+ 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
+
+
+
+ -1
+ 4
+ 2
+
+
+
+
+ 0
+ Sleep
+
+
+ time
+ 1
+
+
+ TIMERBEHAVIOR
+
+
+
+ -1
+ 5
+ -1
+
+
+
+
+ 0
+ Sleep
+
+
+ time
+ 72
+
+
+ TIMERBEHAVIOR
+
+
+
+ -1
+ 6
+ -1
+
+
+
+
+ 0
+ Sleep
+
+
+ time
+ 24
+
+
+ TIMERBEHAVIOR
+
+
+
+ -1
+ 7
+ -1
+
+
+
+
+ 0
+ Sleep
+
+
+ time
+ 1
+
+
+ TIMERBEHAVIOR
+
+
+
+ -1
+ 8
+ -1
+
+
+
+
+ 0
+ Sleep
+
+
+ time
+ 211
+
+
+ TIMERBEHAVIOR
+
+
+
+ -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
+
+
+
+ -1
+ 10
+ -1
+
+
+
+
+ 0
+ Sleep
+
+
+ time
+ 3
+
+
+ TIMERBEHAVIOR
+
+
+
+ -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
+
+
+
+ -1
+ 12
+ -1
+
+
+
+
+ 0
+ Sleep
+
+
+ time
+ 82
+
+
+ TIMERBEHAVIOR
+
+
+
+ -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
+
+
+
+ -1
+ 14
+ -1
+
+
+
+
+ 0
+ Sleep
+
+
+ time
+ 2
+
+
+ TIMERBEHAVIOR
+
+
+
+ -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
+
+
+
+ -1
+ 16
+ -1
+
+
+
+
+ 0
+ Sleep
+
+
+ time
+ 10
+
+
+ TIMERBEHAVIOR
+
+
+
+ -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
+
+
+
+ -1
+ 18
+ -1
+
+
+
+
+ 0
+ Sleep
+
+
+ time
+ 8
+
+
+ TIMERBEHAVIOR
+
+
+
+ -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
+
+
+
+ -1
+ 20
+ -1
+
+
+
+
+ 0
+ Sleep
+
+
+ time
+ 52
+
+
+ TIMERBEHAVIOR
+
+
+
+ -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
+
+
+
+ -1
+ 22
+ -1
+
+
+
+
+ 0
+ Sleep
+
+
+ time
+ 16442
+
+
+ TIMERBEHAVIOR
+
+
+
+ -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
+
+
+
+ -1
+ 24
+ -1
+
+
+
+
+
+
+
+
+ 0
+ Sleep
+
+
+ time
+ 9
+
+
+ TIMERBEHAVIOR
+
+
+
+ 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
+
+
+
+ -1
+ 26
+ -1
+
+
+
+
+ 0
+ Sleep
+
+
+ time
+ 25
+
+
+ TIMERBEHAVIOR
+
+
+
+ -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
+
+
+
+ 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
+
+
+
+ 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
+
+
+
+ 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
+
+
+
+ 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
+
+
+
+ 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
+
+
+
+ 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
+
+
+
+ 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
+
+
+
+ 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
+
+
+
+ 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
+
+
+
+ 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
+
+
+
+ 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
+
+
+
+ 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
+
+
+
+ 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
+
+
+
+ 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
+
+
+
+ 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
+
+
+
+ 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
+
+
+
+ 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
+
+
+
+ -1
+ 28
+ 0
+
+
+
+
+ 0
+ Sleep
+
+
+ time
+ 10
+
+
+ TIMERBEHAVIOR
+
+
+
+ -1
+ 29
+ -1
+
+
+
+
+ 0
+ Sleep
+
+
+ time
+ 25
+
+
+ TIMERBEHAVIOR
+
+
+
+ -1
+ 30
+ -1
+
+
+
+
+ 0
+ Sleep
+
+
+ time
+ 1
+
+
+ TIMERBEHAVIOR
+
+
+
+ -1
+ 31
+ -1
+
+
+
+
+ 0
+ Sleep
+
+
+ time
+ 4
+
+
+ TIMERBEHAVIOR
+
+
+
+ -1
+ 32
+ -1
+
+
+
+
+ 0
+ Sleep
+
+
+ time
+ 4
+
+
+ TIMERBEHAVIOR
+
+
+
+ -1
+ 33
+ -1
+
+
+
+
+ 0
+ Sleep
+
+
+ time
+ 0
+
+
+ TIMERBEHAVIOR
+
+
+
+ -1
+ 34
+ -1
+
+
+
+
+ 0
+ Sleep
+
+
+ time
+ 1
+
+
+ TIMERBEHAVIOR
+
+
+
+ -1
+ 35
+ -1
+
+
+
+
+ 0
+ Sleep
+
+
+ time
+ 6
+
+
+ TIMERBEHAVIOR
+
+
+
+ -1
+ 36
+ -1
+
+
+
+
+ 0
+ Sleep
+
+
+ time
+ 27
+
+
+ TIMERBEHAVIOR
+
+
+
+ -1
+ 37
+ -1
+
+
+
+
+ 0
+ Sleep
+
+
+ time
+ 9
+
+
+ TIMERBEHAVIOR
+
+
+
+ -1
+ 38
+ -1
+
+
+
+
+ 0
+ Sleep
+
+
+ time
+ 1
+
+
+ TIMERBEHAVIOR
+
+
+
+ -1
+ 39
+ -1
+
+
+
+
+ 0
+ Sleep
+
+
+ time
+ 0
+
+
+ TIMERBEHAVIOR
+
+
+
+ -1
+ 40
+ -1
+
+
+
+
+ 0
+ Sleep
+
+
+ time
+ 1
+
+
+ TIMERBEHAVIOR
+
+
+
+ -1
+ 41
+ -1
+
+
+
+
+ 0
+ Sleep
+
+
+ time
+ 36
+
+
+ TIMERBEHAVIOR
+
+
+
+ -1
+ 42
+ -1
+
+
+
+
+ 0
+ Sleep
+
+
+ time
+ 5
+
+
+ TIMERBEHAVIOR
+
+
+
+ -1
+ 43
+ -1
+
+
+
+
+ 0
+ Sleep
+
+
+ time
+ 1
+
+
+ TIMERBEHAVIOR
+
+
+
+ -1
+ 44
+ -1
+
+
+
+
+ 0
+ Sleep
+
+
+ time
+ 75
+
+
+ TIMERBEHAVIOR
+
+
+
+ -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
+
+
+
+ -1
+ 46
+ -1
+
+
+
+
+ 0
+ Sleep
+
+
+ time
+ 30
+
+
+ TIMERBEHAVIOR
+
+
+
+ -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
+
+
+
+ -1
+ 48
+ -1
+
+
+
+
+ 0
+ Sleep
+
+
+ time
+ 27
+
+
+ TIMERBEHAVIOR
+
+
+
+ -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
+
+
+
+ -1
+ 50
+ -1
+
+
+
+
+ 0
+ Sleep
+
+
+ time
+ 1
+
+
+ TIMERBEHAVIOR
+
+
+
+ -1
+ 51
+ -1
+
+
+
+
+ 0
+ Sleep
+
+
+ time
+ 24
+
+
+ TIMERBEHAVIOR
+
+
+
+ -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
+
+
+
+ -1
+ 53
+ -1
+
+
+
+
+ 0
+ Sleep
+
+
+ time
+ 145
+
+
+ TIMERBEHAVIOR
+
+
+
+ -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
+
+
+
+ -1
+ 55
+ -1
+
+
+
+
+ 0
+ Sleep
+
+
+ time
+ 1
+
+
+ TIMERBEHAVIOR
+
+
+
+ -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
+
+
+
+ -1
+ 57
+ -1
+
+
+
+
+ 0
+ Sleep
+
+
+ time
+ 8
+
+
+ TIMERBEHAVIOR
+
+
+
+ -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
+
+
+
+ -1
+ 59
+ -1
+
+
+
+
+ 0
+ Sleep
+
+
+ time
+ 7
+
+
+ TIMERBEHAVIOR
+
+
+
+ -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
+
+
+
+ -1
+ 61
+ -1
+
+
+
+
+ 0
+ Sleep
+
+
+ time
+ 163
+
+
+ TIMERBEHAVIOR
+
+
+
+ -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
+
+
+
+ -1
+ 63
+ -1
+
+
+
+
+ 0
+ Sleep
+
+
+ time
+ 1
+
+
+ TIMERBEHAVIOR
+
+
+
+ -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
+
+
+
+ -1
+ 65
+ -1
+
+
+
+
+ 0
+ Sleep
+
+
+ time
+ 27
+
+
+ TIMERBEHAVIOR
+
+
+
+ -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
+
+
+
+ -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
+
+
+
+
+
+
+ 2
+ 0
+ -1
+
+
+
+
+ 0
+ Sleep
+
+
+ time
+ 2500
+
+
+
+
+
+ -1
+ 1
+ -1
+
+
+
+
+ 3
+ Get
+
+
+ url
+ http://133.133.12.3:8080/Bench4QTestCase/images/3.jpg
+
+
+
+ parameters
+
+
+
+
+
+
+ 4
+ Get
+
+
+ url
+ http://133.133.12.3:8080/Bench4QTestCase/script/agentTable.js
+
+
+
+ parameters
+
+
+
+
+
+
+ 5
+ Get
+
+
+ url
+ http://133.133.12.3:8080/Bench4QTestCase/script/base.js
+
+
+
+ parameters
+
+
+
+
+
+
+ 6
+ Get
+
+
+ url
+ http://133.133.12.3:8080/Bench4QTestCase/images/1.jpg
+
+
+
+ parameters
+
+
+
+
+
+
+ 7
+ Get
+
+
+ url
+ http://133.133.12.3:8080/Bench4QTestCase/images/2.jpg
+
+
+
+ parameters
+
+
+
+
+
+
+ -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
+
+
+
+ 2
+ 0
+ -1
+
+
+
+
+ 0
+ Sleep
+
+
+ time
+ 230
+
+
+ TIMERBEHAVIOR
+
+
+
+ -1
+ 1
+ -1
+
+
+
+
+ 1
+ Get
+
+
+ url
+ http://133.133.12.3:8080/Bench4QTestCase/script/agentTable.js
+
+
+
+ parameters
+
+
+
+ USERBEHAVIOR
+
+
+
+ 2
+ Get
+
+
+ url
+ http://133.133.12.3:8080/Bench4QTestCase/images/3.jpg
+
+
+
+ parameters
+
+
+
+ USERBEHAVIOR
+
+
+
+ 3
+ Get
+
+
+ url
+ http://133.133.12.3:8080/Bench4QTestCase/script/base.js
+
+
+
+ parameters
+
+
+
+ USERBEHAVIOR
+
+
+
+ 4
+ Get
+
+
+ url
+ http://133.133.12.3:8080/Bench4QTestCase/images/1.jpg
+
+
+
+ parameters
+
+
+
+ USERBEHAVIOR
+
+
+
+ 5
+ Get
+
+
+ url
+ http://133.133.12.3:8080/Bench4QTestCase/images/2.jpg
+
+
+
+ parameters
+
+
+
+ USERBEHAVIOR
+
+
+
+ -1
+ 2
+ 0
+
+
+
+
+ 0
+ Sleep
+
+
+ time
+ 96
+
+
+ TIMERBEHAVIOR
+
+
+
+ -1
+ 3
+ -1
+
+
+
+
+ 0
+ Sleep
+
+
+ time
+ 3
+
+
+ TIMERBEHAVIOR
+
+
+
+ -1
+ 4
+ -1
+
+
+
+
+ 0
+ Sleep
+
+
+ time
+ 10
+
+
+ TIMERBEHAVIOR
+
+
+
+ -1
+ 5
+ -1
+
+
+
+
+ 0
+ Sleep
+
+
+ time
+ 6
+
+
+ TIMERBEHAVIOR
+
+
+
+ -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
+
+
+
+ 2
+ 0
+ -1
+
+
+
+
+ 0
+ Sleep
+
+
+ time
+ 230
+
+
+ TIMERBEHAVIOR
+
+
+
+ -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
+
+
+
+
+
+ /
+
+
+
\ 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