add Bench4Q-Recorder

This commit is contained in:
coderfengyun 2014-03-21 09:59:49 +08:00
parent d94b7ff301
commit 31919d0755
63 changed files with 14138 additions and 0 deletions

View File

@ -0,0 +1,8 @@
<html>
<head>
<title>frame1</title>
</head>
<body>
<img alt="No this picture" src="images/4.jpg">
</body>
</html>

View File

@ -0,0 +1,16 @@
<html>
<head>
<title>Bench4Q Test Case</title>
<link href="style/bootstrap-cerulean.css" />
<link href="style/bootstrap-classic.css" />
<link href="style/bootstrap-cerulean.css" />
</head>
<body>
<iframe src=""></iframe>
<img src="images/1.jpg" alt="No this one" />
<img src="images/2.jpg" alt="No this one" />
<img src="images/3.jpg" alt="No this one" />
<script src="script/agentTable.js" type="text/javascript"></script>
<script src="script/base.js" type="text/javascript"></script>
</body>
</html>

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

View File

@ -0,0 +1,94 @@
var table= $('#agents');
$('.datatable').dataTable({
"sDom": "<'row-fluid'<'span6'l><'span6'f>>t<'row-fluid'<'span12 center'p>>",
"sPaginationType": "bootstrap",
"oLanguage": {
"sLengthMenu": "_MENU_ records per page"
}
} );
$('.btn-setting').click(function(e){
e.preventDefault();
$("#agentParam").modal('show');
});
$(document).ready(function() {
loadAgents(table);
});
function cancel(){
$("#agentParam").modal('hide');
}
function loadAgents() {
table.dataTable().fnClearTable();
$.post("loadAgents", {}, function(data) {
if (data!=null) {
for (var i = 0; i<data.list.length; i++)
addAgentTableRow(table, data.list[i]);
}
},"json");
$('.btn-info').click(function() {
deleteAgent(this);
});
}
function addAgentTableRow(table, data) {
var status = "NA";
switch (data.currentStatus) {
case 1:
status = "Idle";
break;
case 2:
status = "Running";
break;
case 3:
status = "BackUp";
break;
case 4:
status = "BreakDown";
break;
default:
status = "NA";
break;
}
table.dataTable().fnAddData(
[ data.hostName, data.id, data.port, status, data.maxLoad,
data.remainLoad, deleteButton ]);
}
function getAgentId(obj) {
var row = obj.parentNode.parentNode;
var tbody = row.parentNode;
var id = $(tbody).children("tr").eq(row.rowIndex - 1).children("td").eq(1)
.text();
return id;
}
function deletetablerow(obj) {
id=getAgentId(obj);
table=obj.pratent.parent;
$.post("removeAgentFromPool", {
id : id,
}, function(data) {
if (data)
$(table).dataTable().fnDeleteRow(row.rowIndex - 1);
else{}
});
}
function addAgentToDB() {
$.post("addAgentToPool", {
hostName : $("#hostName").val(),
port : $("#port").val(),
maxLoad : $("#maxLoad").val(),
remainLoad : $("#remainLoad").val()
}, function(data) {
if (data) {
loadAgents();
}
});
}

View File

@ -0,0 +1,143 @@
/*var viewButton = "<a class='btn btn-success' href='#' ><i class='icon-zoom-in icon-white'></i>View</a>"+" ";
var editButton = "<a class='btn btn-success' href='#' ><i class='icon-edit icon-white'></i>Edit</a>"+" ";
var deleteButton = "<a class='btn btn-info' href='#'><i class='icon-trash icon-white'></i>Delete</a>";*/
$(document).ready(function(){
//highlight current / active link
$('ul.main-menu li a').each(function(){
if($($(this))[0].href==String(window.location))
$(this).parent().addClass('active');
});
//animating menus on hover
$('ul.main-menu li:not(.nav-header)').hover(function(){
$(this).animate({'margin-left':'+=5'},300);
},
function(){
$(this).animate({'margin-left':'-=5'},300);
});
docReady();
loadProperties();
});
function docReady(){
//makes elements soratble, elements that sort need to have id attribute to save the result
$('.sortable').sortable({
revert:true,
cancel:'.btn,.box-content,.nav-header',
update:function(event,ui){
//line below gives the ids of elements, you can make ajax call here to save it to the database
//console.log($(this).sortable('toArray'));
}
});
$('.btn-close').click(function(e){
e.preventDefault();
$(this).parent().parent().parent().fadeOut();
});
$('.btn-minimize').click(function(e){
e.preventDefault();
var $target = $(this).parent().parent().next('.box-content');
if($target.is(':visible')) $('i',$(this)).removeClass('icon-chevron-up').addClass('icon-chevron-down');
else $('i',$(this)).removeClass('icon-chevron-down').addClass('icon-chevron-up');
$target.slideToggle();
});
/*$('.btn-setting').click(function(e){
e.preventDefault();
$('#myModal').modal('show');
});*/
}
$.fn.dataTableExt.oApi.fnPagingInfo = function ( oSettings )
{
return {
"iStart": oSettings._iDisplayStart,
"iEnd": oSettings.fnDisplayEnd(),
"iLength": oSettings._iDisplayLength,
"iTotal": oSettings.fnRecordsTotal(),
"iFilteredTotal": oSettings.fnRecordsDisplay(),
"iPage": Math.ceil( oSettings._iDisplayStart / oSettings._iDisplayLength ),
"iTotalPages": Math.ceil( oSettings.fnRecordsDisplay() / oSettings._iDisplayLength )
};
};
$.extend( $.fn.dataTableExt.oPagination, {
"bootstrap": {
"fnInit": function( oSettings, nPaging, fnDraw ) {
var oLang = oSettings.oLanguage.oPaginate;
var fnClickHandler = function ( e ) {
e.preventDefault();
if ( oSettings.oApi._fnPageChange(oSettings, e.data.action) ) {
fnDraw( oSettings );
}
};
$(nPaging).addClass('pagination').append(
'<ul>'+
'<li class="prev disabled"><a href="#">&larr; '+oLang.sPrevious+'</a></li>'+
'<li class="next disabled"><a href="#">'+oLang.sNext+' &rarr; </a></li>'+
'</ul>'
);
var els = $('a', nPaging);
$(els[0]).bind( 'click.DT', { action: "previous" }, fnClickHandler );
$(els[1]).bind( 'click.DT', { action: "next" }, fnClickHandler );
},
"fnUpdate": function ( oSettings, fnDraw ) {
var iListLength = 5;
var oPaging = oSettings.oInstance.fnPagingInfo();
var an = oSettings.aanFeatures.p;
var i, j, sClass, iStart, iEnd, iHalf=Math.floor(iListLength/2);
if ( oPaging.iTotalPages < iListLength) {
iStart = 1;
iEnd = oPaging.iTotalPages;
}
else if ( oPaging.iPage <= iHalf ) {
iStart = 1;
iEnd = iListLength;
} else if ( oPaging.iPage >= (oPaging.iTotalPages-iHalf) ) {
iStart = oPaging.iTotalPages - iListLength + 1;
iEnd = oPaging.iTotalPages;
} else {
iStart = oPaging.iPage - iHalf + 1;
iEnd = iStart + iListLength - 1;
}
for ( i=0, iLen=an.length ; i<iLen ; i++ ) {
// remove the middle elements
$('li:gt(0)', an[i]).filter(':not(:last)').remove();
// add the new list items and their event handlers
for ( j=iStart ; j<=iEnd ; j++ ) {
sClass = (j==oPaging.iPage+1) ? 'class="active"' : '';
$('<li '+sClass+'><a href="#">'+j+'</a></li>')
.insertBefore( $('li:last', an[i])[0] )
.bind('click', function (e) {
e.preventDefault();
oSettings._iDisplayStart = (parseInt($('a', this).text(),10)-1) * oPaging.iLength;
fnDraw( oSettings );
} );
}
// add / remove disabled classes from the static elements
if ( oPaging.iPage === 0 ) {
$('li:first', an[i]).addClass('disabled');
} else {
$('li:first', an[i]).removeClass('disabled');
}
if ( oPaging.iPage === oPaging.iTotalPages-1 || oPaging.iTotalPages === 0 ) {
$('li:last', an[i]).addClass('disabled');
} else {
$('li:last', an[i]).removeClass('disabled');
}
}
}
}
});
function loadProperties(){
jQuery.i18n.properties({// 加载资浏览器语言对应的资源文件
name:'i18n', // 资源文件名称
path:'i18n/', // 资源文件路径
mode:'map', // 用 Map 的方式使用资源文件中的值
} );
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,17 @@
<html>
<head>
<title>Bench4Q Test Case</title>
<link href="style/bootstrap-cerulean.css" />
<link href="style/bootstrap-classic.css" />
<link href="style/bootstrap-cerulean.css" />
</head>
<body>
<img src="images/1.jpg" alt="No this one" />
<img src="images/2.jpg" alt="No this one" />
<img src="images/3.jpg" alt="No this one" />
<script src="script/agentTable.js" type="text/javascript"></script>
<script src="script/base.js" type="text/javascript"></script>
</body>
</html>

View File

@ -0,0 +1,17 @@
<html>
<head>
<title>Bench4Q Test Case</title>
<link href="style/bootstrap-cerulean.css" />
<link href="style/bootstrap-classic.css" />
<link href="style/bootstrap-cerulean.css" />
</head>
<body>
<img src="images/1.jpg" alt="No this one" />
<img src="images/2.jpg" alt="No this one" />
<img src="images/3.jpg" alt="No this one" />
<script src="script/agentTable.js" type="text/javascript"></script>
<script src="script/base.js" type="text/javascript"></script>
</body>
</html

View File

@ -0,0 +1,16 @@
HTTP/1.1 200 OK
Content-Type: text/html; charset=utf-8
Server: Microsoft-IIS/7.0
CachedXSLT: true
X-AspNet-Version: 2.0.50727
X-Powered-By: ASP.NET
Vary: Accept-Encoding
Cache-Control: private, max-age=31
Date: Tue, 10 Dec 2013 08:40:29 GMT
Content-Length: 26
Connection: keep-alive
Set-Cookie: agentscape-tag-devtype=desktop; Path=/
Set-Cookie: agentscape-proc=noop; Path=/
x-agentscape-info: c=1.0-r9869; v=3; fp=f844b0e65e9b5458; ts=1333395837
<html><body></body></html>

View File

@ -0,0 +1,16 @@
HTTP/1.1 200 OK
Content-Type: text/plain; charset=utf-8
Server: Microsoft-IIS/7.0
CachedXSLT: true
X-AspNet-Version: 2.0.50727
X-Powered-By: ASP.NET
Vary: Accept-Encoding
Cache-Control: private, max-age=31
Date: Tue, 10 Dec 2013 08:40:29 GMT
Content-Length: 6
Connection: keep-alive
Set-Cookie: agentscape-tag-devtype=desktop; Path=/
Set-Cookie: agentscape-proc=noop; Path=/
x-agentscape-info: c=1.0-r9869; v=3; fp=f844b0e65e9b5458; ts=1333395837
adnddm

View File

@ -0,0 +1,14 @@
HTTP/1.1 200 OK
Content-Type: text/html; charset=utf-8
Server: Microsoft-IIS/7.0
CachedXSLT: true
X-AspNet-Version: 2.0.50727
X-Powered-By: ASP.NET
Vary: Accept-Encoding
Cache-Control: private, max-age=31
Date: Tue, 10 Dec 2013 08:40:29 GMT
Content-Length: 0
Connection: keep-alive
Set-Cookie: agentscape-tag-devtype=desktop; Path=/
Set-Cookie: agentscape-proc=noop; Path=/
x-agentscape-info: c=1.0-r9869; v=3; fp=f844b0e65e9b5458; ts=1333395837

View File

@ -0,0 +1,15 @@
GET /phoenix.zhtml?c=188488&p=irol-homeprofile HTTP/1.1
Host: ir.baidu.com
Connection: keep-alive
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.63 Safari/537.36
Referer: http://www.baidu.com/
Accept-Encoding: gzip,deflate,sdch
IF-MODIFIED-SINCE: Mon, 22 Mar 2010 14:14:40 GMT; old-content-length=200
AUTHORIZATION: bearer
Accept-Language: zh-CN,zh;q=0.8
Content-Type: multipart
Content-Length: 100
Pragma: No-Cache
Cookie: BAIDUID=993724E1CAB01EE3D0C0AFAA99796E6A:FG=1; H_PS_PSSID=4381_1463_4212_4264_4451

View File

@ -0,0 +1,10 @@
GET / HTTP/1.1
Host: www.baidu.com
Connection: keep-alive
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
User-Agent: Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.63 Safari/537.36
DNT: 1
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en,zh-CN;q=0.8,zh;q=0.6
Cookie: BAIDUID=1D43A956BCED0A81B8340058134CD2F6:FG=1; BDUSS=EJMRWZ2eklMaERoQ344em5RZ2EyTVh0UjRDcWpiRmhnMjRlLTZnR3NZajBOS0JTQVFBQUFBJCQAAAAAAAAAAAEAAAA2JuwxZmVuZ3l1bjIwMTIzOQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPSneFL0p3hSN; Hm_lvt_9f14aaa038bbba8b12ec2a4a3e51d254=1384429678; H_PS_PSSID=3784_4199_1432_4421_4414_4211_4264_4450_4503; BDRCVFR[feWj1Vr5u3D]=I67x6TjHwwYf0

View File

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<agentBriefStatusModel>
<failCountFromBegin>0</failCountFromBegin>
<failCountThisTime>0</failCountThisTime>
<failThroughputThisTime>0</failThroughputThisTime>
<maxResponseTime>1203</maxResponseTime>
<minResponseTime>0</minResponseTime>
<successCountFromBegin>28205</successCountFromBegin>
<successCountThisTime>1774</successCountThisTime>
<successThroughputThisTime>559</successThroughputThisTime>
<timeFrame>3172</timeFrame>
<totalResponseTimeThisTime>22154</totalResponseTimeThisTime>
<totalSqureResponseTimeThisTime>5245392
</totalSqureResponseTimeThisTime>
<vUserCount>40</vUserCount>
</agentBriefStatusModel>

View File

@ -0,0 +1,26 @@
HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
Accept-Ranges: bytes
ETag: W/"532-1386125334307"
Last-Modified: Wed, 04 Dec 2013 02:48:54 GMT
Content-Type: text/html
Content-Length: 532
Date: Mon, 09 Dec 2013 07:03:15 GMT
<html>
<head>
<title>Bench4Q Test Case</title>
<link href="style/bootstrap-cerulean.css" />
<link href="style/bootstrap-classic.css" />
<link href="style/bootstrap-cerulean.css" />
</head>
<body>
<img src="images/1.jpg" alt="No this one" />
<img src="images/2.jpg" alt="No this one" />
<img src="images/3.jpg" alt="No this one" />
<script src="script/agentTable.js" type="text/javascript"></script>
<script src="script/base.js" type="text/javascript"></script>
</body>
</html>

25
Bench4Q-Recorder/pom.xml Normal file
View File

@ -0,0 +1,25 @@
<?xml version="1.0"?>
<project
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.bench4q</groupId>
<artifactId>integration</artifactId>
<version>1.0 Beta</version>
</parent>
<artifactId>bench4q-recorder</artifactId>
<name>bench4q-recorder</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<!-- parse the dom tree of response html -->
<dependency>
<groupId>org.jsoup</groupId>
<artifactId>jsoup</artifactId>
<version>1.7.3</version>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,91 @@
package org.bench4q.recorder;
import java.io.IOException;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.HashMap;
import java.util.Map;
import javax.swing.JTextArea;
import org.bench4q.recorder.httpcapture.HttpCapture;
import org.bench4q.recorder.httpcapture.Utils.UserException;
import org.springframework.stereotype.Component;
@Component
public class ScriptCapturer {
private String ipHttpCaptureServerAdress;
private static final String HTTPCATUREGENERATOR_STRING = "org.bench4q.master.scriptrecord.httpcapture.generator.Bench4qCodeGenerator";
private Map<Integer, HttpCapture> httpCaptureMap;
public String getIpHttpCaptureServerAdress() {
return ipHttpCaptureServerAdress;
}
public void setIpHttpCaptureServerAdress(String ipHttpCaptureServerAdress) {
this.ipHttpCaptureServerAdress = ipHttpCaptureServerAdress;
}
public Map<Integer, HttpCapture> getHttpCaptureMap() {
return httpCaptureMap;
}
public void setHttpCaptureMap(Map<Integer, HttpCapture> httpCaptureMap) {
this.httpCaptureMap = httpCaptureMap;
}
public ScriptCapturer() {
this.setIpHttpCaptureServerAdress(this.getLocalHostIp());
this.setHttpCaptureMap(new HashMap<Integer, HttpCapture>());
}
private String getLocalHostIp() {
InetAddress addr;
try {
addr = InetAddress.getLocalHost();
return addr.getHostAddress().toString();
} catch (UnknownHostException e) {
e.printStackTrace();
return null;
}
}
public void startRecord(int port, String fileDir, String fileName) {
try {
HttpCapture httpCapture = buildACapture(port, fileDir, fileName);
httpCapture.startProxyServer();
httpCapture.startRecording();
} catch (IOException e1) {
System.out.println("Error When start recording!");
e1.printStackTrace();
} catch (UserException e1) {
System.out.println("Error When start recording!");
e1.printStackTrace();
}
}
private HttpCapture buildACapture(int port, String filePath, String fileName) {
HttpCapture httpCapture = new HttpCapture(filePath, fileName, port,
HTTPCATUREGENERATOR_STRING, new JTextArea());
this.getHttpCaptureMap().put(new Integer(port), httpCapture);
return httpCapture;
}
public void stopCurrentRecord(int port) {
try {
HttpCapture httpCapture = this.getHttpCaptureMap().get(
new Integer(port));
if (httpCapture == null) {
return;
}
assert (httpCapture.isRecording());
httpCapture.stopRecording();
httpCapture.shutProxyServer();
this.getHttpCaptureMap().remove(new Integer(port));
} catch (Exception e1) {
System.out.println("Error When stop recording!");
e1.printStackTrace();
}
}
}

View File

@ -0,0 +1,147 @@
package org.bench4q.recorder.httpcapture;
import java.util.Vector;
public class Action {
private String url;
private String method;
private String expected_result;
private int delayTime;
private int expected_size;
private int timeout;
private Vector<HeaderValue> headers;
private Vector<Param> queryStringParams;
private Vector<Param> bodyParams;
private String multiPartData;
public Action() {
this.headers = new Vector<HeaderValue>();
this.queryStringParams = new Vector<Param>();
this.bodyParams = new Vector<Param>();
this.expected_result = "";
this.multiPartData = "";
}
public void setUrl(String url) {
this.url = url;
}
public String getUrl() {
return this.url;
}
public void setMethod(String method) {
this.method = method;
}
public String getMethod() {
return this.method;
}
public void setExpectedResult(String str) {
this.expected_result = str;
}
public String getExpectedResult() {
return this.expected_result;
}
public void setDelayTime(int seconds) {
this.delayTime = seconds;
}
public int getDelayTime() {
return this.delayTime;
}
public void setExpectedSize(int bytes) {
this.expected_size = bytes;
}
public int getExpectedSize() {
return this.expected_size;
}
public void setTimeout(int seconds) {
this.timeout = seconds;
}
public int getTimeout() {
return this.timeout;
}
public int getHeaderCount() {
return this.headers.size();
}
public HeaderValue[] getHeaders() {
HeaderValue[] list = new HeaderValue[this.headers.size()];
this.headers.copyInto(list);
return list;
}
public void addHeader(HeaderValue p) {
this.headers.addElement(p);
}
public void removeHeader(HeaderValue p) {
this.headers.removeElement(p);
}
public int getParamsCount() {
return getParams().length;
}
public int getQueryStringParamCount() {
return this.queryStringParams.size();
}
public int getBodyParamCount() {
return this.bodyParams.size();
}
public Param[] getQueryStringParams() {
Param[] list = new Param[this.queryStringParams.size()];
this.queryStringParams.copyInto(list);
return list;
}
public Param[] getBodyParams() {
Param[] list = new Param[this.bodyParams.size()];
this.bodyParams.copyInto(list);
return list;
}
public Param[] getParams() {
@SuppressWarnings("unchecked")
Vector<Param> v = (Vector<Param>) this.queryStringParams.clone();
v.addAll(this.bodyParams);
Param[] list = new Param[v.size()];
v.copyInto(list);
return list;
}
public void addQueryStringParam(Param p) {
this.queryStringParams.addElement(p);
}
public void addBodyParam(Param p) {
this.bodyParams.addElement(p);
}
public void removeQueryStringParam(Param p) {
this.queryStringParams.removeElement(p);
}
public void removeBodyParam(Param p) {
this.bodyParams.removeElement(p);
}
public void setMultiPartData(String multiPartData) {
this.multiPartData = multiPartData;
}
public String getMultiPartData() {
return this.multiPartData;
}
}

View File

@ -0,0 +1,218 @@
package org.bench4q.recorder.httpcapture;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.List;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import org.apache.log4j.Logger;
import org.bench4q.recorder.httpcapture.generator.ChildrenUrl;
import org.bench4q.share.helper.MarshalHelper;
import org.bench4q.share.helper.RunScenarioModelHelper;
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 Bench4qTestScriptAdapter implements IScriptAdapter {
private int pageCount;
private RunScenarioModel runScenarioModel;
private List<ChildrenUrl> childrenUrls = new ArrayList<ChildrenUrl>();
private static Logger logger = Logger
.getLogger(Bench4qTestScriptAdapter.class);
public RunScenarioModel getRunScenarioModel() {
return runScenarioModel;
}
private void setRunScenarioModel(RunScenarioModel runScenarioModel) {
this.runScenarioModel = runScenarioModel;
}
public List<ChildrenUrl> getChildrenUrls() {
return childrenUrls;
}
private void setChildrenUrls(List<ChildrenUrl> childrenUrls) {
this.childrenUrls = childrenUrls;
}
private int getPageCount() {
return pageCount;
}
private void setPageCount(int pageCount) {
this.pageCount = pageCount;
}
public Bench4qTestScriptAdapter(RunScenarioModel runScenarioModel) {
this.runScenarioModel = runScenarioModel;
this.setChildrenUrls(new ArrayList<ChildrenUrl>());
this.setPageCount(0);
initWithOnePage();
}
private void initWithOnePage() {
addPage();
}
public void appendUsePluginsToScenario(List<UsePluginModel> usePluginModels) {
this.runScenarioModel.setUsePlugins(usePluginModels);
}
public void addPage() {
this.setPageCount(this.getPageCount() + 1);
this.getRunScenarioModel().getPages().add(new PageModel());
assert (pageCountEqualWithPageSizeInScenario());
}
public void insertUserBehaviorsToScenario(BehaviorModel model) {
List<BatchModel> batches = this.getCurrentPage().getBatches();
int parentBatchId = -1;
assert (batches != null);
parentBatchId = getUrlParentBatch(model);
if (isIndependent(parentBatchId)) {
BatchModel batch = createBatchBehaviorWithProperBatchId();
batch.getBehaviors().add(model);
batches.add(batch);
return;
}
guardChildBatchExist(batches, parentBatchId);
batches.get(batches.get(parentBatchId).getChildId()).getBehaviors()
.add(model);
}
private void guardChildBatchExist(List<BatchModel> batches,
int parentBatchId) {
if (isChildBatchAbsent(batches, parentBatchId)) {
BatchModel batchBehavior = createBatchBehaviorWithProperBatchId();
batchBehavior.setParentId(parentBatchId);
batches.add(batchBehavior);
batches.get(parentBatchId).setChildId(batches.size() - 1);
}
}
private PageModel getCurrentPage() {
if (!pageCountEqualWithPageSizeInScenario()) {
logger.error("The page count is not equal with the size of scenario pages, and the page count is"
+ this.getPageCount()
+ " , and pageSize is "
+ this.getRunScenarioModel().getPages().size());
return new PageModel();
}
return this.getRunScenarioModel().getPages()
.get(this.getPageCount() - 1);
}
private boolean pageCountEqualWithPageSizeInScenario() {
return this.getPageCount() == this.getRunScenarioModel().getPages()
.size();
}
private BatchModel createBatchBehaviorWithProperBatchId() {
BatchModel batchBehavior = new BatchModel();
batchBehavior.setId(RunScenarioModelHelper.getBatches(
this.runScenarioModel).size());
batchBehavior.setParentId(-1);
batchBehavior.setChildId(-1);
List<BehaviorModel> behaviors = new ArrayList<BehaviorModel>();
batchBehavior.setBehaviors(behaviors);
return batchBehavior;
}
private boolean isChildBatchAbsent(List<BatchModel> batches,
int parentBatchId) {
if (parentBatchId >= batches.size()) {
return false;
}
return batches.get(parentBatchId).getChildId() < 0;
}
private boolean isIndependent(int parentBatchId) {
return parentBatchId < 0;
}
public boolean isInChildrenUrl(String url) {
for (ChildrenUrl childrenUrl : this.getChildrenUrls()) {
if (childrenUrl.getUrl().equals(url)) {
return true;
}
}
return false;
}
private int getUrlParentBatch(BehaviorModel model) {
int parentBatchId = -1;
for (ParameterModel parameter : model.getParameters()) {
if (!parameter.getKey().equals("url")) {
continue;
}
parentBatchId = getParentBatchIdWithChildUrl(parameter.getValue());
}
return parentBatchId;
}
private int getParentBatchIdWithChildUrl(String url) {
for (ChildrenUrl childrenUrl : this.getChildrenUrls()) {
if (childrenUrl.getUrl().equals(url)) {
return childrenUrl.getParentBatchId();
}
}
return -1;
}
public int getParentBatchIdWithParentUrl(String url) {
List<BatchModel> batchesInScenario = RunScenarioModelHelper
.getBatches(this.getRunScenarioModel());
for (int batchId = 0; batchId < batchesInScenario.size(); batchId++) {
BatchModel batch = batchesInScenario.get(batchId);
for (BehaviorModel behavior : batch.getBehaviors()) {
for (ParameterModel parameter : behavior.getParameters()) {
if (parameter.getKey().equals("url")
&& parameter.getValue().equals(url)) {
return batchId;
}
}
}
}
return -1;
}
public void resetChildrenUrls() {
this.getChildrenUrls().clear();
}
public String getText() {
StringWriter stringWriter = new StringWriter();
try {
Marshaller marshaller = JAXBContext.newInstance(
this.runScenarioModel.getClass()).createMarshaller();
marshaller.marshal(this.runScenarioModel, stringWriter);
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
} catch (JAXBException e) {
e.printStackTrace();
}
return stringWriter.toString();
}
public void setText(String text) {
if (text == null || text.isEmpty()) {
// this.setRunScenarioModel(new RunScenarioModelNew());
return;
}
try {
this.setRunScenarioModel((RunScenarioModel) MarshalHelper
.unmarshal(RunScenarioModel.class, text));
} catch (JAXBException e) {
logger.error(e, e);
this.setRunScenarioModel(new RunScenarioModel());
}
}
}

View File

@ -0,0 +1,271 @@
package org.bench4q.recorder.httpcapture;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.Properties;
import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.log4j.ConsoleAppender;
import org.apache.log4j.Layout;
import org.apache.log4j.Level;
import org.apache.log4j.Logger;
import org.apache.log4j.PatternLayout;
public class Config {
private static Config config = null;
private static final Log log = LogFactory.getLog(Config.class);
private static Properties props;
private String pythonPath;
private int port = 8090;
private boolean debug;
private boolean quiet;
private String exist;
private String replace;
private List<String> includeList;
private List<String> excludeList;
private List<Pattern> includePatterns = new ArrayList<Pattern>();
private List<Pattern> excludePatterns = new ArrayList<Pattern>();
private String scriptArg;
private ProxySettings proxySettings;
private static String defDriverPkgName = "com.bitmechanic.maxq";
private static String defValidatorPkgName = "com.bitmechanic.maxq";
static {
Layout layout = new PatternLayout("%d [%t] %-5p %c - %m%n");
Logger.getRootLogger().addAppender(
new ConsoleAppender(layout, "System.err"));
}
public static Config getConfig() {
if (config == null)
initConfig();
return config;
}
public static void initConfig() {
config = new Config();
String maxqDir = System.getProperty("maxq.dir");
String pathSep = System.getProperty("file.separator");
// "\\src\\main\\resources\\org\\bench4q\\master\\config\\httpCaptureConfig\\maxq.properties";
String propertiesFileName = System.getProperty("user.dir") + "src"
+ pathSep + "main" + pathSep + "resources" + pathSep + "org"
+ pathSep + "bench4q" + pathSep + "master" + pathSep + "config"
+ pathSep + "httpCaptureConfig" + pathSep + "maxq.properties";
InputStream propertiesStream = Config.class.getClassLoader()
.getResourceAsStream(propertiesFileName);
props = new Properties();
if (propertiesStream != null) {
try {
props.load(propertiesStream);
log.debug("Generator: "
+ props.getProperty("generator.classnames"));
} catch (IOException e) {
throw new ExceptionInInitializerError(e);
}
}
config.addPythonPath(maxqDir + pathSep + "jython");
String path = config.getProperty("python.path");
if (path != null) {
config.addPythonPath(path);
}
String portStr = props.getProperty("local.proxy.port");
if (portStr != null)
config.port = Integer.parseInt(portStr);
}
public void completeInit() throws Utils.UserException {
Level level = this.quiet ? Level.WARN : this.debug ? Level.ALL
: Level.INFO;
Logger.getRootLogger().setLevel(level);
System.setProperty("org.apache.commons.logging.simplelog.defaultlog",
"warn");
Properties ppref = new Properties();
if (getPythonPath() != null)
ppref.put("python.path", getPythonPath());
// PythonInterpreter.initialize(System.getProperties(), ppref,
// new String[0]);
String host = getProperty("remote.proxy.host");
Integer port = getPropertyInt("remote.proxy.port");
if ((host == null ? 1 : 0) != (port == null ? 1 : 0))
throw new Utils.UserException(
"Not using proxy server. You must set both remote.proxy.host and remote.proxy.port.");
if ((host != null) && (port != null)) {
this.proxySettings = new ProxySettings();
this.proxySettings.host = host;
this.proxySettings.port = port.intValue();
log.info("Proxying requests via " + this.proxySettings.host + ":"
+ Integer.toString(this.proxySettings.port));
}
}
public String getProperty(String prop) {
return (String) props.get(prop);
}
public String getProperty(String prop, String def) {
String val = getProperty(prop);
return (val == null) || (val.equals("")) ? def : val;
}
public void setProperty(String property, String value) {
props.setProperty(property, value);
}
public Integer getPropertyInt(String prop) throws Utils.UserException {
String s = getProperty(prop);
if (s == null)
return null;
try {
return new Integer(s);
} catch (NumberFormatException e) {
}
throw new Utils.UserException(prop + " property must be an integer");
}
public void addPythonPath(String path) {
if (this.pythonPath == null)
this.pythonPath = path;
else
this.pythonPath = (this.pythonPath
+ System.getProperty("path.separator") + path);
}
public String getPythonPath() {
return this.pythonPath;
}
public void setPort(int pt) {
this.port = pt;
}
public int getPort() {
return this.port;
}
public void setDebug(boolean d) {
this.debug = d;
}
public boolean isDebug() {
return this.debug;
}
public void setQuiet(boolean q) {
this.quiet = q;
}
public boolean isQuiet() {
return this.quiet;
}
public void setExist(String e) {
this.exist = e;
}
public String getExist() {
return this.exist;
}
public void setReplace(String e) {
this.replace = e;
}
public String getReplace() {
return this.replace;
}
public void setIncludePatterns(String[] pats) {
this.includeList = Arrays.asList(pats);
createPatterns(this.includeList, this.includePatterns);
}
public void setExcludePatterns(String[] pats) {
this.excludeList = Arrays.asList(pats);
createPatterns(this.excludeList, this.excludePatterns);
}
public List<Pattern> getIncludePatterns() {
return this.includePatterns;
}
public List<Pattern> getExcludePatterns() {
return this.excludePatterns;
}
public void setScriptArg(String arg) {
this.scriptArg = arg;
}
public String getScriptArg() {
return this.scriptArg;
}
public static String getDriverPkgName() {
return System.getProperty("maxq.driverpkgname", defDriverPkgName);
}
public static String getValidatorPkgName() {
return System.getProperty("maxq.validatorpkgname", defValidatorPkgName);
}
public static Log getTestLogger() {
return LogFactory.getLog("com.bitmechanic.maxq.testrun");
}
public ProxySettings getProxySettings() {
return this.proxySettings;
}
public void setProxySettings(ProxySettings proxySettings) {
this.proxySettings = proxySettings;
}
private void createPatterns(List<String> list,
List<Pattern> excludePatterns2) {
Iterator<String> iter = list.iterator();
excludePatterns2.clear();
while (iter.hasNext())
try {
Pattern p = Pattern.compile(iter.next().toString());
excludePatterns2.add(p);
} catch (PatternSyntaxException e) {
log.error(e);
}
}
public static class ProxySettings {
String host;
int port;
public String getHost() {
return this.host;
}
public void setHost(String host) {
this.host = host;
}
public int getPort() {
return this.port;
}
public void setPort(int port) {
this.port = port;
}
}
}

View File

@ -0,0 +1,73 @@
package org.bench4q.recorder.httpcapture;
public class HeaderValue {
public static final String GENERAL_CACHE_CONTROL = "Cache-Control";
public static final String GENERAL_CONNECTION = "Connection";
public static final String GENERAL_DATE = "Date";
public static final String GENERAL_PRAGMA = "Pragma";
public static final String GENERAL_TRAILER = "Trailer";
public static final String GENERAL_TRANSFER_ENC = "Transfer-Encoding";
public static final String GENERAL_UPGRADE = "Upgrade";
public static final String GENERAL_VIA = "Via";
public static final String GENERAL_WARNING = "Warning";
public static final String REQUEST_ACCEPT = "Accept";
public static final String REQUEST_ACCEPT_CHARSET = "Accept-Charset";
public static final String REQUEST_ACCEPT_ENCODING = "Accept-Encoding";
public static final String REQUEST_ACCEPT_LANGUAGE = "Accept-Language";
public static final String REQUEST_AUTHORIZATION = "Authorization";
public static final String REQUEST_EXPECT = "Expect";
public static final String REQUEST_FROM = "From";
public static final String REQUEST_HOST = "Host";
public static final String REQUEST_IF_MATCH = "If-Match";
public static final String REQUEST_IF_MODIFIED_SINCE = "If-Modified-Since";
public static final String REQUEST_IF_NONE_MATCH = "If-None-Match";
public static final String REQUEST_IF_RANGE = "If-Range";
public static final String REQUEST_IF_UNMODIFIED_SINCE = "If-Unmodified-Since";
public static final String REQUEST_MAX_FORWARDS = "Max-Forwards";
public static final String REQUEST_PROXY_AUTHORIZATION = "Proxy-Authorization";
public static final String REQUEST_RANGE = "Range";
public static final String REQUEST_REFERER = "Referer";
public static final String REQUEST_TE = "TE";
public static final String REQUEST_USER_AGENT = "User-Agent";
public static final String RESPONSE_AGE = "Age";
public static final String RESPONSE_ETAG = "ETag";
public static final String RESPONSE_LOCATION = "Location";
public static final String RESPONSE_PROXY_AUTHENTICATE = "Proxy-Authenticate";
public static final String RESPONSE_RETRY_AFTER = "Retry-After";
public static final String RESPONSE_SERVER = "Server";
public static final String RESPONSE_VARY = "Vary";
public static final String RESPONSE_WWW_AUTHENTICATE = "WWW-Authenticate";
public static final String ENTITY_ALLOW = "Allow";
public static final String ENTITY_CONTENT_ENCODING = "Content-Encoding";
public static final String ENTITY_CONTENT_LANGUAGE = "Content-Language";
public static final String ENTITY_CONTENT_LENGHT = "Content-Length";
public static final String ENTITY_CONTENT_LOCATION = "Content-Location";
public static final String ENTITY_CONTENT_MD5 = "Content-MD5";
public static final String ENTITY_CONTENT_RANGE = "Content-Range";
public static final String ENTITY_CONTENT_TYPE = "Content-Type";
public static final String ENTITY_EXPIRES = "Expires";
public static final String ENTITY_LAST_MODIFIED = "Last-Modified";
private String header;
private String value;
public HeaderValue(String header, String value) {
this.header = header;
this.value = value;
}
public String getHeader() {
return this.header;
}
public void setHeader(String header) {
this.header = header;
}
public String getValue() {
return this.value;
}
public void setValue(String value) {
this.value = value;
}
}

View File

@ -0,0 +1,128 @@
package org.bench4q.recorder.httpcapture;
import java.io.File;
import java.io.IOException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import javax.swing.JTextArea;
import org.apache.log4j.Logger;
import org.bench4q.share.models.agent.RunScenarioModel;
public class HttpCapture {
private int localport;
private Config config;
private Test currentTest;
private ProxyServer proxy;
private File resultFile;
private ExecutorService executorService;
private String scriptContent;
private static Logger logger = Logger.getLogger(HttpCapture.class);
public int getLocalport() {
return localport;
}
public void setLocalport(int localport) {
this.localport = localport;
}
public Config getConfig() {
return config;
}
public void setConfig(Config config) {
this.config = config;
}
public Test getCurrentTest() {
return currentTest;
}
public void setCurrentTest(Test currentTest) {
this.currentTest = currentTest;
}
public ProxyServer getProxy() {
return proxy;
}
public void setProxy(ProxyServer proxy) {
this.proxy = proxy;
}
public File getResultFile() {
return resultFile;
}
public void setResultFile(File resultFile) {
this.resultFile = resultFile;
}
public String getScriptContent() {
return scriptContent;
}
private void setScriptContent(String scriptContent) {
this.scriptContent = scriptContent;
}
public boolean isRecording() {
return this.getCurrentTest().isRecording();
}
public HttpCapture(String dirPath, String fileName, int localport,
String generator, JTextArea textArea) {
this.localport = localport;
System.out.println(dirPath + System.getProperty("file.separator")
+ fileName + ".xml");
File file = new File(dirPath);
if (!file.exists()) {
file.mkdirs();
}
this.resultFile = new File(dirPath
+ System.getProperty("file.separator") + fileName + ".xml");
this.config = Config.getConfig();
try {
this.config.completeInit();
this.proxy = new ProxyServer(this.localport);
} catch (Exception e) {
e.printStackTrace();
}
this.currentTest = new Test(this.proxy, new Bench4qTestScriptAdapter(
new RunScenarioModel()), generator);
}
public void startProxyServer() throws IOException, Utils.UserException {
logger.info("enter startProxyServer!");
this.executorService = Executors.newCachedThreadPool();
this.executorService.execute(this.proxy);
}
public void startRecording() throws IOException, Utils.UserException {
this.currentTest.startRecording();
this.resultFile.createNewFile();
this.currentTest.setTestFile(this.resultFile);
}
public void stopRecording() throws IOException, Utils.UserException {
this.currentTest.stopRecording();
this.currentTest.save();
}
public void shutProxyServer() throws IOException, Utils.UserException {
if (this.proxy.getServerSocket() != null) {
this.proxy.getServerSocket().close();
}
this.executorService.shutdownNow();
this.currentTest.close();
this.retrieveScriptContent();
}
private void retrieveScriptContent() {
this.setScriptContent(this.currentTest.getScriptContent());
}
}

View File

@ -0,0 +1,290 @@
package org.bench4q.recorder.httpcapture;
import org.apache.log4j.Logger;
import java.io.IOException;
import java.io.InputStream;
import java.util.StringTokenizer;
/**
* Parses and stores a http server request. Originally posted to comp.lang.java
* in 1996.
*
* @author Sherman Janes
*/
public class HttpRequestHeader {
private static final Logger log = Logger.getLogger(HttpRequestHeader.class);
/**
* Http Request method. Such as get or post.
*/
public String method = new String();
/**
* The requested url. The universal resource locator that hopefully uniquely
* describes the object or service the client is requesting.
*/
public String url = new String();
/**
* Version of http being used. Such as HTTP/1.0
*/
public String version = new String();
/**
* to support http 1.1
*/
public String host = new String();
/**
* The client's browser's name.
*/
public String userAgent = new String();
/**
* The requesting documents that contained the url link.
*/
public String referer = new String();
/**
* A internet address date of the remote copy.
*/
public String ifModifiedSince = new String();
/**
* A list of mime types the client can accept.
*/
public String accept = new String();
public String acceptLanguage = new String();
// public String acceptEncoding = new String();
/**
* The clients authorization. Don't belive it.
*/
public String authorization = new String();
/**
* The type of content following the request header. Normally there is no
* content and this is blank, however the post method usually does have a
* content and a content length.
*/
public String contentType = new String();
/**
* The length of the content following the header. Usually blank.
*/
public int contentLength = -1;
/**
* The content length of a remote copy of the requested object.
*/
public int oldContentLength = -1;
/**
* Anything in the header that was unrecognized by this class.
*/
public String unrecognized = new String();
/**
* Indicates that no cached versions of the requested object are to be sent.
* Usually used to tell proxy not to send a cached copy. This may also
* effect servers that are front end for data bases.
*/
public boolean pragmaNoCache = false;
final static String CR = "\r\n";
/**
* That from which we read.
*/
private InputStream input;
/**
* Parses a http header from a stream.
*
* @param in
* The stream to parse.
*/
public HttpRequestHeader(InputStream in) throws IOException {
input = in;
/*
* Read by lines
*/
StringTokenizer tz = new StringTokenizer(readLine());
/*
* HTTP COMMAND LINE < <METHOD==get> <URL> <HTTP_VERSION> >
*/
method = getToken(tz).toUpperCase();
url = getToken(tz);
version = getToken(tz);
while (true) {
String line = readLine();
log.trace(line);
tz = new StringTokenizer(line);
String Token = getToken(tz);
// look for termination of HTTP command
if (0 == Token.length())
break;
if (Token.equalsIgnoreCase("Host:")) {
// line = <Host: host description>
host = getRemainder(tz);
} else if (Token.equalsIgnoreCase("USER-AGENT:")) {
// line =<User-Agent: <Agent Description>>
userAgent = getRemainder(tz);
} else if (Token.equalsIgnoreCase("ACCEPT:")) {
// line=<Accept: <Type>/<Form>
// examp: Accept image/jpeg
accept += getRemainder(tz);
} else if (Token
.equalsIgnoreCase(HeaderValue.REQUEST_ACCEPT_LANGUAGE + ":")) {
acceptLanguage += getRemainder(tz);
} else if (Token.equalsIgnoreCase("REFERER:")) {
// line =<Referer: <URL>>
referer = getRemainder(tz);
} else if (Token.equalsIgnoreCase("PRAGMA:")) {
// Pragma: <no-cache>
Token = getToken(tz);
if (Token.equalsIgnoreCase("NO-CACHE"))
pragmaNoCache = true;
else
unrecognized += "Pragma:" + Token + " " + getRemainder(tz)
+ "\n";
} else if (Token.equalsIgnoreCase("AUTHORIZATION:")) {
// Authenticate: Basic UUENCODED
authorization = getRemainder(tz);
} else if (Token.equalsIgnoreCase("IF-MODIFIED-SINCE:")) {
// line =<If-Modified-Since: <http date>
// *** Conditional GET replaces HEAD method ***
String str = getRemainder(tz);
int index = str.indexOf(";");
if (index == -1) {
ifModifiedSince = str;
} else {
ifModifiedSince = str.substring(0, index);
index = str.indexOf("=");
if (index != -1) {
str = str.substring(index + 1);
oldContentLength = Integer.parseInt(str);
}
}
} else if (Token.equalsIgnoreCase("CONTENT-LENGTH:")) {
Token = getToken(tz);
contentLength = Integer.parseInt(Token);
} else if (Token.equalsIgnoreCase("CONTENT-TYPE:")) {
contentType = getRemainder(tz);
} else {
unrecognized += Token + " " + getRemainder(tz) + CR;
}
}
}
/**
* We would like to use BufferedReader.readLine(), but it may read past the
* header while filling its buffer. Anything it over-read would thus be
* missed from the body. (Reading the body cannot be via a Reader- derived
* class because we do not want to do any character set conversion at this
* stage. It might be binary data!)
*/
String readLine() throws IOException {
int c;
StringBuffer sb = new StringBuffer();
while ((c = input.read()) != '\n') {
if (c == -1)
throw new IOException("unterminated line in request header");
sb.append((char) c);
}
return sb.toString();
}
/*
* Rebuilds the header in a string
*
* @return The header in a string.
*/
public String toString(boolean sendUnknowen) {
String Request;
if (0 == method.length())
method = "GET";
Request = method + " " + url + " " + version + CR;
if (0 < host.length()) {
Request += "Host:" + host + CR;
}
if (0 < userAgent.length())
Request += "User-Agent:" + userAgent + CR;
if (0 < referer.length())
Request += "Referer:" + referer + CR;
if (pragmaNoCache)
Request += "Pragma: no-cache" + CR;
if (0 < ifModifiedSince.length())
Request += "If-Modified-Since: " + ifModifiedSince + CR;
// ACCEPT TYPES //
if (0 < accept.length())
Request += "Accept: " + accept + CR;
else
Request += "Accept: */" + "* \r\n";
if (0 < acceptLanguage.length()) {
Request += HeaderValue.REQUEST_ACCEPT_LANGUAGE + ": "
+ acceptLanguage + CR;
}
if (0 < contentType.length())
Request += "Content-Type: " + contentType + CR;
if (0 < contentLength)
Request += "Content-Length: " + contentLength + CR;
if (0 != authorization.length())
Request += "Authorization: " + authorization + CR;
if (sendUnknowen) {
if (0 != unrecognized.length())
Request += unrecognized;
}
Request += CR;
return Request;
}
/**
* (Re)builds the header in a string.
*
* @return The header in a string.
*/
public String toString() {
return toString(true);
}
/**
* Returns the next token in a string
*
* @param tk
* String that is partially tokenized.
* @return The remainder
*/
String getToken(StringTokenizer tk) {
String str = "";
if (tk.hasMoreTokens())
str = tk.nextToken();
return str;
}
/**
* Returns the remainder of a tokenized string
*
* @param tk
* String that is partially tokenized.
* @return The remainder
*/
String getRemainder(StringTokenizer tk) {
String str = "";
if (tk.hasMoreTokens())
str = tk.nextToken();
while (tk.hasMoreTokens()) {
str += " " + tk.nextToken();
}
return str;
}
}

View File

@ -0,0 +1,238 @@
package org.bench4q.recorder.httpcapture;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import javax.swing.JOptionPane;
import org.apache.commons.httpclient.HostConfiguration;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpMethod;
import org.apache.commons.httpclient.NameValuePair;
import org.apache.commons.httpclient.URIException;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.httpclient.methods.PostMethod;
public class HttpTestCase {
private Config config = Config.getConfig();
protected HttpMethod method = null;
protected HttpClient client = new HttpClient();
protected String data;
private boolean followRedirects = false;
private String charset;
public void setCharset(String cs) {
this.charset = cs;
}
public HttpTestCase(String name) {
Config.ProxySettings proxy = this.config.getProxySettings();
if (proxy != null) {
HostConfiguration hc = this.client.getHostConfiguration();
hc.setProxy(proxy.host, proxy.port);
}
}
public void Run() throws Throwable {
}
public HttpMethod getMethod() {
return this.method;
}
private void cleanupMethod() {
if (this.method != null) {
this.method.releaseConnection();
this.method = null;
}
}
public void get(String url) throws IOException {
get(url, null);
}
public void get(String url, Object[] args) throws IOException {
cleanupMethod();
this.method = new GetMethod(url);
if (args != null) {
this.method.setQueryString(paramsToNV(args));
}
this.method.setFollowRedirects(this.followRedirects);
this.client.executeMethod(this.method);
}
public void post(String url) throws IOException {
post(url, null);
}
public void post(String url, Object[] args) throws IOException {
cleanupMethod();
PostMethod post = new PostMethod(url);
if (this.charset != null) {
post.setRequestHeader("Content-Type",
"application/x-www-form-urlencoded; charset="
+ this.charset);
}
if (args != null) {
post.setRequestBody(paramsToNV(args));
}
this.method = post;
this.method.setFollowRedirects(this.followRedirects);
this.client.executeMethod(this.method);
}
public void postMultiPart(String url, String data, int contLen)
throws IOException {
postMultiPart(url, data, contLen, null);
}
public void postMultiPart(String url, String data, int contLen,
Object[] args) throws IOException {
cleanupMethod();
PostMethod multipartPostMethod = new PostMethod(url);
multipartPostMethod.addParameter("data", data);
if (args != null) {
multipartPostMethod.setQueryString(paramsToNV(args));
}
this.method = multipartPostMethod;
this.method.setFollowRedirects(this.followRedirects);
this.client.executeMethod(this.method);
}
public NameValuePair[] paramsToNV(Object[] params) {
NameValuePair[] res = new NameValuePair[params.length];
for (int i = 0; i < params.length; ++i) {
Object param = params[i];
// if (param instanceof PyTuple) {
// PyTuple pyParam = (PyTuple) param;
// res[i] = new NameValuePair(pyParam.__getitem__(0).toString(),
// pyParam.__getitem__(1).toString());
// } else
if (param instanceof NameValuePair) {
res[i] = ((NameValuePair) param);
}
}
return res;
}
public String urlDecode(String s) {
return staticUrlDecode(s);
}
public static String staticUrlDecode(String s) {
String sUrl = "";
ByteArrayOutputStream out = new ByteArrayOutputStream(s.length());
for (int count = 0; count < s.length(); ++count)
if (s.charAt(count) == '%') {
++count;
if (count < s.length()) {
int a = Character.digit(s.charAt(count++), 16);
a <<= 4;
int b = Character.digit(s.charAt(count), 16);
if ((a + b == 39) || (a + b == 132))
out.write(92);
out.write(a + b);
} else {
out.write(37);
}
} else if (s.charAt(count) == '+') {
out.write(32);
} else {
sUrl += s.charAt(count);
out.write(s.charAt(count));
}
System.out.println(sUrl);
return out.toString();
}
protected void responseOK() throws URIException {
}
protected boolean responseContainsURI(String uri) throws URIException {
return ((this.method != null) && (this.method.getURI().getPath()
.indexOf(uri) != -1));
}
protected boolean responseContains(String text) {
try {
if ((this.method == null)
|| (this.method.getResponseBody() == null))
return false;
this.data = this.method.getResponseBodyAsString();
} catch (IOException e) {
e.printStackTrace();
}
return (this.data.indexOf(text) != -1);
}
protected void printResponse() {
try {
System.err.println(new String(this.method.getResponseBody()));
} catch (IOException e) {
e.printStackTrace();
}
}
public String getResponse() throws IOException {
return this.method.getResponseBodyAsString();
}
public byte[] getResponseAsBytes() throws IOException {
return this.method.getResponseBody();
}
public int getResponseCode() {
return getMethod().getStatusCode();
}
// public PyDictionary getResponseHeader() {
// PyDictionary dict = new PyDictionary();
// Header[] headers = this.method.getResponseHeaders();
//
// for (int i = 0; i < headers.length; ++i)
// dict.__setitem__(new PyString(headers[i].getName()), new PyString(
// headers[i].getValue()));
// return dict;
// }
public String getScriptArg() {
return this.config.getScriptArg();
}
public boolean userConfirm(String msg) {
int rc = JOptionPane.showConfirmDialog(null, msg, "HttpCapture", 2);
return (rc == 0);
}
public String userInput(String msg) {
return JOptionPane.showInputDialog(null, msg, "HttpCapture", 3);
}
public String getStrutsToken() throws IOException {
String responseString = new String(
this.method.getResponseBodyAsString());
String strutsToken = null;
int tokenIDIndex = responseString.toLowerCase().indexOf(
"org.apache.struts.taglib.html.TOKEN".toLowerCase());
int nextValue = responseString.toLowerCase().indexOf(
"value=\"".toLowerCase(), tokenIDIndex);
strutsToken = responseString.substring(nextValue + "value=\"".length(),
nextValue + "value=\"".length() + 32);
return strutsToken;
}
}

View File

@ -0,0 +1,33 @@
package org.bench4q.recorder.httpcapture;
import java.util.List;
import org.bench4q.recorder.httpcapture.generator.ChildrenUrl;
import org.bench4q.share.models.agent.RunScenarioModel;
import org.bench4q.share.models.agent.scriptrecord.BehaviorModel;
import org.bench4q.share.models.agent.scriptrecord.UsePluginModel;
public interface IScriptAdapter {
public abstract RunScenarioModel getRunScenarioModel();
public abstract void addPage();
public abstract void appendUsePluginsToScenario(
List<UsePluginModel> usePluginModels);
public abstract void insertUserBehaviorsToScenario(BehaviorModel model);
public abstract String getText();
public abstract void setText(String paramString);
// TODO:move this function to more fit place
public abstract List<ChildrenUrl> getChildrenUrls();
public abstract int getParentBatchIdWithParentUrl(String url);
public abstract boolean isInChildrenUrl(String url);
public abstract void resetChildrenUrls();
}

View File

@ -0,0 +1,40 @@
package org.bench4q.recorder.httpcapture;
import java.util.ArrayList;
import java.util.List;
import java.util.StringTokenizer;
public class Param {
public String name;
public String value;
public static Param createParam(String name, String value) {
Param param = new Param();
param.name = name;
param.value = value;
return param;
}
public static class ParamParser {
public static List<Param> parse(String paramString) {
List<String> paramStrings = getNVField(paramString);
List<Param> params = new ArrayList<Param>();
for (String paramSource : paramStrings) {
int index = paramSource.indexOf("=");
params.add(createParam(paramSource.substring(0, index).trim(),
paramSource.substring(index + 1)));
}
return params;
}
static public List<String> getNVField(String value) {
StringTokenizer st = new StringTokenizer(value, ";", false);
List<String> result = new ArrayList<String>();
while (st.hasMoreTokens()) {
String token = st.nextToken();
result.add(token.trim());
}
return result;
}
}
}

View File

@ -0,0 +1,87 @@
package org.bench4q.recorder.httpcapture;
import java.io.IOException;
import java.net.ServerSocket;
import java.util.Enumeration;
import java.util.Vector;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
public class ProxyServer implements Runnable {
private Vector<Observer> listeners;
private ServerSocket srvSock;
private int count;
private static final Log log = LogFactory.getLog(ProxyServer.class);
public ProxyServer() throws IOException {
this(0);
}
public ProxyServer(int port) throws IOException {
this.srvSock = new ServerSocket(port);
this.listeners = new Vector<Observer>();
}
public void addObserver(Observer proxy) {
this.listeners.addElement(proxy);
}
public void removeObserver(Observer proxy) {
this.listeners.removeElement(proxy);
}
public void processRequest(HttpRequestHeader header, byte[] requestBody)
throws Exception {
for (Enumeration<Observer> e = this.listeners.elements(); e
.hasMoreElements();) {
Observer pl = (Observer) e.nextElement();
pl.processRequest(header, requestBody);
}
}
public void processResponse(HttpRequestHeader header, byte[] requestBody,
byte[] response) throws Exception {
for (Enumeration<Observer> e = this.listeners.elements(); e
.hasMoreElements();) {
Observer pl = (Observer) e.nextElement();
pl.processResponse(header, requestBody, response);
}
}
public void run() {
if (this.getServerSocket().isClosed()) {
return;
}
try {
while (true) {
RequestHandler handler = new RequestHandler(this, this
.getServerSocket().accept());
log.trace("New connection. Creating new RequestHandler thread.");
Thread t = new Thread(handler, "Bench4QRequestHandler #"
+ this.getLocalPort() + "#" + this.count);
t.start();
this.count += 1;
}
} catch (Exception e) {
return;
}
}
int getLocalPort() {
return this.srvSock.getLocalPort();
}
public ServerSocket getServerSocket() {
return this.srvSock;
}
public static abstract interface Observer {
public abstract void processRequest(
HttpRequestHeader paramHttpRequestHeader,
byte[] paramArrayOfByte) throws Exception;
public abstract void processResponse(
HttpRequestHeader paramHttpRequestHeader, byte[] requestBody,
byte[] paramArrayOfByte) throws Exception;
}
}

View File

@ -0,0 +1,212 @@
package org.bench4q.recorder.httpcapture;
import java.io.BufferedInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ConnectException;
import java.net.InetAddress;
import java.net.MalformedURLException;
import java.net.Socket;
import java.net.SocketException;
import java.net.URL;
import org.apache.log4j.Logger;
public class RequestHandler implements Runnable {
private static final Logger log = Logger.getLogger(RequestHandler.class);
private Config config = Config.getConfig();
private InputStream clientIn;
private InputStream serverIn;
private OutputStream clientOut;
private OutputStream serverOut;
private HttpRequestHeader header;
private ProxyServer proxyServer;
private Socket clientSocket;
private Socket serverSocket;
private ByteArrayOutputStream buffer;
private static Object mutex = new Object();
public RequestHandler(ProxyServer proxyServer, Socket s) {
assert (s != null);
this.clientSocket = s;
this.buffer = new ByteArrayOutputStream();
this.proxyServer = proxyServer;
}
private void initClientServerConnections(Socket s) throws Throwable {
this.clientIn = new BufferedInputStream(s.getInputStream());
this.clientOut = s.getOutputStream();
try {
this.header = new HttpRequestHeader(this.clientIn);
} catch (IOException e) {
log.error("truncated request from browser: " + this.header.url, e);
System.out.println(this.header.url);
throw new Utils.SilentException();
}
if (!this.header.url.startsWith("http"))
throw new Utils.UserException(
"Bench4Q only supports the HTTP protocol.");
URL url = new URL(this.header.url);
Config.ProxySettings proxy = this.config.getProxySettings();
int port;
String host;
if (proxy != null) {
host = proxy.host;
port = proxy.port;
} else {
host = url.getHost();
port = url.getPort();
}
if (port < 1)
port = 80;
try {
this.serverSocket = new Socket(InetAddress.getByName(host), port);
} catch (ConnectException e) {
String msg = "Cannot connect to ";
if (proxy != null)
msg = msg + "proxy server ";
msg = msg + host;
if (port != 80)
msg = msg + " on port " + Integer.toString(port);
throw new Utils.UserException(msg + ".");
}
try {
this.serverIn = this.serverSocket.getInputStream();
this.serverOut = this.serverSocket.getOutputStream();
} catch (Throwable e) {
this.serverSocket.close();
this.serverSocket = null;
throw e;
}
}
private String stripProxyInfoFromRequestHeader()
throws MalformedURLException {
String res = "";
String origUrl = this.header.url;
URL url = new URL(origUrl);
this.header.url = url.getFile();
res = this.header.toString();
this.header.url = origUrl;
return res;
}
public void run() {
try {
try {
int rs = this.clientSocket.getReceiveBufferSize();
int ss = this.clientSocket.getSendBufferSize();
int BUF_SIZE = rs < ss ? ss : rs;
byte[] buf = new byte[BUF_SIZE];
initClientServerConnections(this.clientSocket);
String headerStr;
if (this.config.getProxySettings() == null)
headerStr = stripProxyInfoFromRequestHeader();
else
headerStr = this.header.toString();
log.trace("read request header");
byte[] bytes = headerStr.getBytes();
this.serverOut.write(bytes, 0, bytes.length);
log.trace("wrote request header");
byte[] requestBody;
if (this.header.contentLength > 0) {
this.buffer.reset();
int len = 0;
int num = 0;
while (num < this.header.contentLength) {
try {
len = readRequestBody(buf);
} catch (SocketException e) {
log.info("truncated request from browser: "
+ e.getMessage());
throw new Utils.SilentException();
}
if (len == 0 || len == -1) {
System.out.println("Read " + num
+ "byte from requestBody");
break;
}
log.trace("read " + Integer.toString(len) + " bytes");
this.serverOut.write(buf, 0, len);
this.buffer.write(buf, 0, len);
log.trace("wrote " + Integer.toString(len) + " bytes");
num += len;
}
requestBody = this.buffer.toByteArray();
log.trace("transferred rest of request body");
} else {
requestBody = new byte[0];
log.trace("no request body");
}
this.clientSocket.shutdownInput();
this.serverSocket.shutdownOutput();
synchronized (mutex) {
this.proxyServer.processRequest(this.header, requestBody);
log.trace("processed request");
this.buffer.reset();
int len;
while ((len = this.serverIn.read(buf, 0, buf.length)) >= 0) {
log.trace("read " + Integer.toString(len));
try {
this.clientOut.write(buf, 0, len);
} catch (SocketException e) {
log.info("browser stopped listening: "
+ e.getMessage() + this.buffer.toString());
throw new Utils.SilentException();
}
this.buffer.write(buf, 0, len);
}
log.trace("transferred response len:" + len);
this.proxyServer.processResponse(this.header, requestBody,
this.buffer.toByteArray());
log.trace("processed response");
}
} catch (Exception e) {
log.error(e, e);
} finally {
if (this.serverSocket != null) {
this.serverSocket.close();
log.trace("closed server socket");
}
this.clientSocket.close();
log.trace("closed client socket");
}
if (this.serverSocket != null) {
this.serverSocket.close();
log.trace("closed server socket");
}
this.clientSocket.close();
log.trace("closed client socket");
} catch (Throwable localThrowable) {
log.error(localThrowable, localThrowable);
}
}
private int readRequestBody(byte[] buf) throws IOException {
int alreadyReadLength = 0;
int ch = -1;
while (alreadyReadLength < this.header.contentLength) {
if ((ch = this.clientIn.read()) != -1) {
buf[alreadyReadLength] = (byte) ch;
}
alreadyReadLength++;
}
return alreadyReadLength;
}
}

View File

@ -0,0 +1,112 @@
package org.bench4q.recorder.httpcapture;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import org.bench4q.recorder.httpcapture.generator.GeneratorFactory;
import org.bench4q.recorder.httpcapture.generator.IScriptGenerator;
public class Test {
private IScriptGenerator generator;
private IScriptAdapter scriptAdapter;
private boolean isRecording;
private File testFile;
ProxyServer proxyServer;
public Test(ProxyServer proxy, IScriptAdapter adapter, String generatorClass) {
this.proxyServer = proxy;
adapter.setText("");
this.generator = GeneratorFactory.newGenerator(generatorClass, adapter);
this.generator.doNew();
this.scriptAdapter = adapter;
}
public Test(ProxyServer proxy, IScriptAdapter adapter, File file)
throws IOException, Utils.UserException {
this.proxyServer = proxy;
this.testFile = file;
StringBuffer buffer = new StringBuffer();
BufferedReader r = new BufferedReader(new FileReader(this.testFile));
String line = r.readLine();
while (line != null) {
buffer.append(line);
buffer.append(IScriptGenerator.EOL);
line = r.readLine();
}
r.close();
String script = buffer.toString();
String generatorClass = null;
String[] classes = GeneratorFactory.getClasses();
for (int i = 0; i < classes.length; i++) {
if (script.indexOf(classes[i]) != -1) {
generatorClass = classes[i];
break;
}
}
if (generatorClass == null) {
throw new Utils.UserException(
"Your file does not appear to have been generated by MaxQ.\n\n(MaxQ expects to find the class name of the generator somewhere in the script.\nPerhaps you have mistakenly deleted it?)");
}
adapter.setText(script);
this.generator = GeneratorFactory.newGenerator(generatorClass, adapter);
this.generator.doLoad();
this.generator.parseTestName();
}
public File getTestFile() {
return this.testFile;
}
public void setTestFile(File file) {
this.testFile = file;
}
public boolean isRecording() {
return this.isRecording;
}
public void stopRecording() {
this.proxyServer.removeObserver(this.generator);
assert (this.isRecording);
this.generator.doStopRecording();
this.isRecording = false;
}
public void startRecording() {
assert (!this.isRecording);
this.proxyServer.addObserver(this.generator);
this.isRecording = true;
this.generator.doStartRecording();
}
public boolean save() throws IOException {
return this.generator.doSave(
stripFileName(this.testFile.getAbsolutePath()),
this.testFile.getName());
}
private String stripFileName(String absolutePath) {
int index = absolutePath.lastIndexOf(System
.getProperty("file.separator"));
if (index == -1) {
return absolutePath;
}
return absolutePath.substring(0, index);
}
public void close() {
if (this.isRecording)
this.proxyServer.removeObserver(this.generator);
this.generator.close();
}
public String getScriptContent() {
return this.scriptAdapter.getText();
}
}

View File

@ -0,0 +1,114 @@
package org.bench4q.recorder.httpcapture;
import java.io.File;
import java.io.FileWriter;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;
import java.util.StringTokenizer;
import org.apache.log4j.Logger;
public class Utils {
public static final String SPACE = " ";
private static final Logger log = Logger.getLogger(Utils.class);
public static File saveHTML(String htmlFileName, String str, String dir_str) {
if (str == null) {
log.error("Argument is null: EditorPane.saveHTML()");
return null;
}
File dir, htmlFile;
if (dir_str == null) {
dir = new File("Tempfiles");
} else {
dir = new File(dir_str);
}
dir.mkdir();
try {
htmlFile = new File(dir, htmlFileName);
if (htmlFile.exists()) {
htmlFile.delete();
log.warn("deleting duplicated file: " + htmlFileName);
}
htmlFile.createNewFile();
PrintWriter writer = new PrintWriter(new FileWriter(htmlFile));
writer.print(str);
writer.close();
} catch (Exception e) {
e.printStackTrace();
return null;
}
return htmlFile;
}
public static String[] splitString(String str, String delim) {
StringTokenizer st = new StringTokenizer(str, delim);
String[] res = new String[st.countTokens()];
int i = 0;
while (st.hasMoreTokens()) {
res[i] = st.nextToken();
i++;
}
return res;
}
public static String replace(String str, String search, String replace) {
int pos = str.indexOf(search);
if (pos == -1)
return str;
StringBuffer buff = new StringBuffer(str.length() + 32);
int start = 0;
while ((pos != -1) && (start < str.length())) {
buff.append(str.substring(start, pos));
buff.append(replace);
start = pos + search.length();
if (start < str.length())
pos = str.indexOf(search, start);
}
if (start < str.length())
buff.append(str.substring(start));
return buff.toString();
}
public static List<Param> getParams(String query) {
List<Param> paramList = new ArrayList<Param>();
if (query != null) {
query = query.trim();
log.debug(" parsing: " + query);
String[] items = splitString(query, "&");
for (int i = 0; i < items.length; i++) {
int pos = items[i].indexOf("=");
if (pos != -1) {
Param p = new Param();
paramList.add(p);
p.name = items[i].substring(0, pos);
if (pos < items[i].length() - 1)
p.value = items[i].substring(pos + 1);
else
p.value = "";
}
}
}
return paramList;
}
public static class SilentException extends Exception {
private static final long serialVersionUID = 3172942039967787899L;
public SilentException() {
super();
}
}
public static class UserException extends Exception {
private static final long serialVersionUID = -7337004995296463936L;
public UserException(String s) {
super();
}
}
}

View File

@ -0,0 +1,555 @@
package org.bench4q.recorder.httpcapture.generator;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Vector;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.bench4q.recorder.httpcapture.ProxyServer;
import org.bench4q.recorder.httpcapture.Action;
import org.bench4q.recorder.httpcapture.Config;
import org.bench4q.recorder.httpcapture.HeaderValue;
import org.bench4q.recorder.httpcapture.HttpRequestHeader;
import org.bench4q.recorder.httpcapture.HttpTestCase;
import org.bench4q.recorder.httpcapture.IScriptAdapter;
import org.bench4q.recorder.httpcapture.Param;
import org.bench4q.recorder.httpcapture.Utils;
import org.bench4q.recorder.httpcapture.Utils.UserException;
import org.bench4q.share.models.agent.RunScenarioModel;
import org.bench4q.share.models.agent.scriptrecord.BehaviorModel;
public abstract class AbstractCodeGenerator implements IScriptGenerator,
ProxyServer.Observer, Runnable {
private Config config = Config.getConfig();
private static final Log log;
private static String cpRspTo;
private static boolean cpRspToStdout;
private static boolean cpRspToFile;
private static final String[] MIME_DEFAULTS;
static HashMap<String, String> mimeTypes;
protected static final String END_STATEMENT;
protected static String jtidyConfigFile;
protected long assertNumber = 0L;
protected boolean headersExist = false;
private IScriptAdapter scriptAdapter;
private String testName;
private boolean ignoreNextResponse;
private Pattern[] namePatterns;
private LinkedList<BehaviorModel> outstandingInserts;
private Thread insertThread;
private String charset;
private long timeElapsedSinceLastestRequest;
private Date latestRequestDate;
private int requestCount;
private boolean firstHtmlResponse;
static final boolean $assertionsDisabled = !(AbstractCodeGenerator.class
.desiredAssertionStatus());
private static boolean isCpRspToStdout() {
return cpRspToStdout;
}
private static boolean isCpRspToFile() {
return cpRspToFile;
}
protected int getRequestCount() {
return requestCount;
}
private boolean isFirstHtmlResponse() {
return firstHtmlResponse;
}
private void setFirstHtmlResponse(boolean firstHtmlResponse) {
this.firstHtmlResponse = firstHtmlResponse;
}
public AbstractCodeGenerator(IScriptAdapter adapter, String[] nameRegExps) {
this.reset();
this.scriptAdapter = adapter;
this.namePatterns = new Pattern[nameRegExps.length];
for (int i = 0; i < nameRegExps.length; ++i)
this.namePatterns[i] = Pattern.compile(nameRegExps[i], 8);
this.testName = this.config.getProperty("test.default_testname",
"Bench4QTest");
this.insertThread = new Thread(this);
this.insertThread.start();
}
private void reset() {
this.latestRequestDate = new Date();
this.assertNumber = 0;
this.requestCount = 0;
this.latestRequestDate = new Date();
this.timeElapsedSinceLastestRequest = 0L;
this.setFirstHtmlResponse(true);
}
public IScriptAdapter getScriptAdapter() {
return this.scriptAdapter;
}
private void setTestName(String testName) {
this.testName = testName;
}
private void setTestPath(String testPath) {
}
public long getTimeElapsedSinceLastestRequest() {
return this.timeElapsedSinceLastestRequest;
}
public boolean isFirstRequest() {
return this.requestCount == 0;
}
public String parseTestName() {
return this.testName;
}
public boolean doSave(String path, String fileName) {
String name = fileName;
int dotPos = fileName.indexOf(".");
RunScenarioModel runScenarioModel = this.scriptAdapter
.getRunScenarioModel();
FileWriter fileWriter;
if (dotPos > -1)
name = fileName.substring(0, dotPos);
setTestName(name);
setTestPath(path);
if (runScenarioModel == null) {
}
try {
fileWriter = new FileWriter(new File(path
+ System.getProperty("file.separator") + fileName));
Marshaller marshaller = JAXBContext.newInstance(
runScenarioModel.getClass()).createMarshaller();
marshaller.marshal(runScenarioModel, fileWriter);
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
return true;
} catch (JAXBException e) {
e.printStackTrace();
return false;
} catch (IOException e) {
e.printStackTrace();
return false;
}
}
public void doLoad() {
setTestName(parseTestName());
}
public void close() {
this.insertThread.interrupt();
}
public void processRequest(HttpRequestHeader header, byte[] requestBody)
throws Exception {
// doParseRequest(header, requestBody);
}
private void doParseRequest(HttpRequestHeader header, byte[] requestBody)
throws UserException, UnsupportedEncodingException {
Param[] params;
int i;
String name;
String value;
Date d = new Date();
this.timeElapsedSinceLastestRequest = (d.getTime() - this.latestRequestDate
.getTime());
this.latestRequestDate = d;
if ((header.method.toLowerCase().equals("get"))
&& (urlIgnored(header.url))) {
log.debug("Ignoring GET request: \"" + header.url + "\"");
this.ignoreNextResponse = true;
return;
}
boolean isMultiPartRequest = header.contentType
.startsWith("multipart/form-data");
boolean isFormRequest = header.contentType
.startsWith("application/x-www-form-urlencoded");
Action action = new Action();
String newCharset = null;
newCharset = doForCharset(header.contentType);
doHeaders(createHeaders(header));
String url = header.url;
log.debug(" recording url: " + url);
String method = header.method.toLowerCase();
if (method.equals("get")) {
method = "Get";
} else if (method.equals("post")) {
method = "Post";
}
int pos = url.indexOf("?");
if ((pos != -1) && (url.length() > pos + 1)) {
setQueryStringParams(action, url.substring(pos + 1));
action.setUrl(url.substring(0, pos));
} else {
action.setUrl(url);
}
if (requestBody.length > 0) {
if (isMultiPartRequest) {
setMultiPartData(action, header, requestBody);
} else if (!isFormRequest) {
if (newCharset != null)
doSetData(new String(requestBody, newCharset));
else
doSetData(new String(requestBody));
} else if (newCharset != null) {
setBodyParams(action, new String(requestBody, newCharset));
} else {
setBodyParams(action, new String(requestBody));
}
}
if (action.getParamsCount() > 0) {
params = action.getParams();
for (i = 0; i < params.length; ++i) {
name = params[i].name;
value = params[i].value;
if ((name.indexOf("+") != -1) || (name.indexOf("%") != -1))
params[i].name = HttpTestCase.staticUrlDecode(name);
if ((value.indexOf("+") != -1) || (value.indexOf("%") != -1))
params[i].value = HttpTestCase.staticUrlDecode(value);
}
doParameterList(params);
}
if (action.getQueryStringParamCount() > 0) {
params = action.getQueryStringParams();
for (i = 0; i < params.length; ++i) {
name = params[i].name;
value = params[i].value;
if ((name.indexOf("+") != -1) || (name.indexOf("%") != -1))
params[i].name = HttpTestCase.staticUrlDecode(name);
if ((value.indexOf("+") != -1) || (value.indexOf("%") != -1))
params[i].value = HttpTestCase.staticUrlDecode(value);
}
doQueryStringParameterList(params);
}
if (action.getBodyParamCount() > 0) {
params = action.getBodyParams();
for (i = 0; i < params.length; ++i) {
name = params[i].name;
value = params[i].value;
if ((name.indexOf("+") != -1) || (name.indexOf("%") != -1))
params[i].name = HttpTestCase.staticUrlDecode(name);
if ((value.indexOf("+") != -1) || (value.indexOf("%") != -1))
params[i].value = HttpTestCase.staticUrlDecode(value);
}
doBodyParameterList(params);
}
String url_str = header.url;
if (requestBody.length > 0) {
url_str = url_str + '?' + new String(requestBody);
}
if (!(isMultiPartRequest)) {
doTestUrlMessage(HttpTestCase.staticUrlDecode(url_str).trim());
}
String data_str = "";
String cont_len_str = "";
if (isMultiPartRequest) {
method = method + "MultiPart";
data_str = ", data";
cont_len_str = ", " + header.contentLength;
doSetData(action.getMultiPartData());
}
doCallUrl(action, method, data_str, cont_len_str);
this.requestCount++;
}
private String doForCharset(String contentType) throws UserException {
Matcher charsetParser = Pattern.compile("charset=([a-z0-9_\\-]+)", 2)
.matcher(contentType);
String newCharset = "";
if (charsetParser.matches()) {
newCharset = charsetParser.group();
if (!(newCharset.equals(this.charset))) {
doSetCharset(newCharset);
} else if (this.charset != null) {
doSetCharset(this.charset);
}
}
return newCharset;
}
private HeaderValue[] createHeaders(HttpRequestHeader header) {
Vector<HeaderValue> v = new Vector<HeaderValue>();
if (header.contentType.length() > 0)
v.add(new HeaderValue("Content-Type", header.contentType));
if (header.accept.length() > 0)
v.add(new HeaderValue("Accept", header.accept));
if (header.referer.length() > 0)
v.add(new HeaderValue("Referer", header.referer));
if (header.pragmaNoCache)
v.add(new HeaderValue("Cache-Control", "no-cache"));
HeaderValue[] hv = new HeaderValue[v.size()];
return ((HeaderValue[]) (HeaderValue[]) v.toArray(hv));
}
public void processResponse(HttpRequestHeader header, byte[] requestBody,
byte[] response) throws Exception {
if (this.ignoreNextResponse) {
log.debug("Ignoring response");
this.ignoreNextResponse = false;
return;
}
ResponseParser responseParser = new ResponseParser(response);
ResponseHeader responseHeader = responseParser.getResponseHeader();
doAssertResponse(responseHeader.getRespCode());
if (responseHeader.isValidResponseHeader()) {
if (responseHeader.isGoodRequest()
&& responseHeader.isHtmlContentType()
&& hasHtmlTag(responseParser)) {
dealWithHtmlResponse(header, responseParser);
doParseRequest(header, requestBody);
System.out.println("enter doParseHtml");
doParseHtmlContent(responseParser.getResponseBody(), header.url);
setStruts(new String(response).toLowerCase().indexOf(
"org.apache.struts.taglib.html.token") > 0);
doEndTransaction();
return;
}
setStruts(new String(response).toLowerCase().indexOf(
"org.apache.struts.taglib.html.token") > 0);
doEndTransaction();
} else {
log.debug("Ignoring response because content type is not known: "
+ responseHeader.getRespCode());
}
doParseRequest(header, requestBody);
}
private boolean hasHtmlTag(ResponseParser responseParser) {
return responseParser.getResponseBody() == null ? false
: responseParser.getResponseBody().contains("<html");
}
private void dealWithHtmlResponse(HttpRequestHeader header,
ResponseParser responseParser) throws UserException {
if (!isFirstHtmlResponse()) {
this.getScriptAdapter().addPage();
}
this.getScriptAdapter().resetChildrenUrls();
this.setFirstHtmlResponse(false);
doTidyCode(HttpTestCase.staticUrlDecode(header.url));
copyResponseToSpecificOut(header.url);
}
private void copyResponseToSpecificOut(String requestUrl)
throws UserException {
if (isCpRspToStdout())
doResponseForStdOut(HttpTestCase.staticUrlDecode(requestUrl).trim());
else if (isCpRspToFile())
doResponseForFile();
}
public void run() {
this.outstandingInserts = new LinkedList<BehaviorModel>();
try {
while (!(Thread.interrupted())) {
synchronized (this.outstandingInserts) {
this.outstandingInserts.wait();
while (this.outstandingInserts.size() > 0) {
BehaviorModel behaviorModel = this.outstandingInserts
.removeFirst();
this.getScriptAdapter().insertUserBehaviorsToScenario(
behaviorModel);
}
}
}
} catch (InterruptedException e) {
log.trace("Thread dead");
}
}
public abstract void doAssertResponse(String paramString)
throws Utils.UserException;
public abstract void doCallUrl(Action action, String paramString2,
String paramString3, String paramString4)
throws Utils.UserException;
public abstract void doEndTransaction() throws Utils.UserException;
public abstract void setStruts(boolean paramBoolean);
public abstract void doSetCharset(String paramString)
throws Utils.UserException;
public abstract void doParameterList(Param[] paramArrayOfParam)
throws Utils.UserException;
public abstract void doQueryStringParameterList(Param[] paramArrayOfParam)
throws Utils.UserException;
public abstract void doBodyParameterList(Param[] paramArrayOfParam)
throws Utils.UserException;
public abstract void doResponseForFile() throws Utils.UserException;
public abstract void doResponseForStdOut(String paramString)
throws Utils.UserException;
public abstract void doSetData(String paramString)
throws Utils.UserException;
public abstract void doTestUrlMessage(String paramString)
throws Utils.UserException;
public abstract void doTidyCode(String paramString)
throws Utils.UserException;
public abstract void doParseHtmlContent(String responseBody, String rootUrl);
public abstract void doHeaders(HeaderValue[] paramArrayOfHeaderValue);
protected void insert(BehaviorModel behaviorModel)
throws Utils.UserException {
synchronized (this.outstandingInserts) {
this.outstandingInserts.add(behaviorModel);
this.outstandingInserts.notifyAll();
}
}
private void setMultiPartData(Action action, HttpRequestHeader header,
byte[] strarray) {
String str = new String(strarray);
int begin = header.contentType.indexOf("boundary=");
int end = header.contentType.indexOf("; ", begin);
if (end == -1)
end = header.contentType.length();
String boundary = header.contentType.substring(begin + 9, end);
String[] parts = str.split("--" + boundary);
if ((!($assertionsDisabled)) && (!(parts[0].equals(""))))
throw new AssertionError();
Pattern re = Pattern
.compile(
"\r\nContent-Disposition: form-data; name=\"([^\"]+)\"[^\r\n]*\r\n\r\n(.*)\r\n",
32);
for (int i = 1; i < parts.length - 1; ++i) {
Matcher m = re.matcher(parts[i]);
boolean ok = m.matches();
if ((!($assertionsDisabled)) && (!(ok)))
throw new AssertionError();
Param p = new Param();
p.name = m.group(1);
p.value = m.group(2);
action.addBodyParam(p);
}
if ((!($assertionsDisabled))
&& (!(parts[(parts.length - 1)].equals("--\r\n"))))
throw new AssertionError();
}
private void setQueryStringParams(Action action, String str) {
List<Param> params = Utils.getParams(str);
Iterator<Param> iter = params.iterator();
while (iter.hasNext())
action.addQueryStringParam((Param) iter.next());
}
private void setBodyParams(Action action, String str) {
List<Param> params = Utils.getParams(str);
Iterator<Param> iter = params.iterator();
while (iter.hasNext())
action.addBodyParam((Param) iter.next());
}
private boolean urlIgnored(String str) {
boolean ignore = false;
List<Pattern> incPats = this.config.getIncludePatterns();
List<Pattern> excPats = this.config.getExcludePatterns();
if ((!(ignore)) && (incPats.size() != 0)) {
log.debug("urlIgnored: checking for include matches");
ignore = this.checkMatch(incPats.iterator(), str, false, true);
}
if ((!(ignore)) && (excPats.size() != 0)) {
log.debug("urlIgnored: checking for exclude matches");
ignore = this.checkMatch(excPats.iterator(), str, true, ignore);
}
return ignore;
}
private boolean checkMatch(Iterator<Pattern> iter, String str, boolean res,
boolean def) {
while (iter.hasNext()) {
Matcher m = ((Pattern) iter.next()).matcher(str);
log.debug("checkMatch: for \"" + str + "\" with pattern: \""
+ m.pattern().pattern() + "\"");
if (m.find()) {
log.debug("checkMatch: Found match, returning: " + res);
return res;
}
}
log.debug("checkMatch: Didn't find match, returning: " + def);
return def;
}
static {
log = LogFactory.getLog(AbstractCodeGenerator.class);
cpRspTo = System.getProperty("http.cpRspTo");
cpRspToFile = false;
MIME_DEFAULTS = new String[] { "text/plain", "text/html",
"text/comma-separated-values" };
END_STATEMENT = ";" + EOL;
jtidyConfigFile = System.getProperty("jtidy.config");
if (cpRspTo != null)
if (cpRspTo.toLowerCase().compareTo("stdout") == 0)
cpRspToStdout = true;
else if (cpRspTo.toLowerCase().compareTo("file") == 0)
cpRspToFile = true;
mimeTypes = new HashMap<String, String>();
for (int i = 0; i < MIME_DEFAULTS.length; ++i)
mimeTypes.put(MIME_DEFAULTS[i], MIME_DEFAULTS[i]);
}
}

View File

@ -0,0 +1,367 @@
package org.bench4q.recorder.httpcapture.generator;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import org.apache.commons.io.FileUtils;
import org.apache.log4j.Logger;
import org.bench4q.recorder.httpcapture.Action;
import org.bench4q.recorder.httpcapture.Config;
import org.bench4q.recorder.httpcapture.HeaderValue;
import org.bench4q.recorder.httpcapture.IScriptAdapter;
import org.bench4q.recorder.httpcapture.Param;
import org.bench4q.recorder.httpcapture.Utils;
import org.bench4q.share.models.agent.ParameterModel;
import org.bench4q.share.models.agent.scriptrecord.BehaviorModel;
import org.bench4q.share.models.agent.scriptrecord.UsePluginModel;
public class Bench4qCodeGenerator extends AbstractCodeGenerator {
static final String TIMER_PROP = "generator.isac.timer";
static final String NULL_TIMER = "null";
static final String CONSTANT_TIMER = "ConstantTimer";
static final String RANDOM_TIMER = "Random";
static final String DEFAULT_TIMER = "ConstantTimer";
static final String RANDOM_TIMER_DIST_PROP = "generator.isac.timer.random.dist";
static final String RANDOM_TIMER_DIST_UNIFORM = "uniform";
static final String RANDOM_TIMER_DIST_GAUSSIAN = "gaussian";
static final String RANDOM_TIMER_DIST_POISSON = "poisson";
static final String RANDOM_TIMER_DIST_NEGEXPO = "negexpo";
static final String RANDOM_TIMER_DIST_DEFAULT = "uniform";
static final String RANDOM_TIMER_MIN_PROP = "generator.isac.timer.random.min";
static final String RANDOM_TIMER_DELTA_PROP = "generator.isac.timer.random.delta";
static final String RANDOM_TIMER_UNIT_PROP = "generator.isac.timer.random.unit";
static final String RANDOM_TIMER_DEVIATION_PROP = "generator.isac.timer.random.deviation";
static final String[][] escapes = { { "\\", "\\\\" }, { ";", "\\;" },
{ "&", "&amp;" }, { "\"", "&quot;" }, { "<", "&lt;" },
{ ">", "&gt;" } };
private String queryStringParameters = "";
private String bodyParameters = "";
private String body = "";
private String headers = "";
private String timer;
private String randomDist;
private int delta = 0;
private int deviation = 0;
private int unit = 1;
private static Logger logger = Logger.getLogger(Bench4qCodeGenerator.class);
private static String escapeXmlString(String str) {
for (int i = 0; i < escapes.length; ++i)
str = str.replace(escapes[i][0], escapes[i][1]);
return str;
}
private static String encodedParameterList(Param[] params) {
String result = "";
for (int i = 0; i < params.length; ++i) {
if (i > 0)
result = result + ";";
result = result + escapeXmlString(params[i].name) + "="
+ escapeXmlString(params[i].value);
}
return result;
}
public Bench4qCodeGenerator(IScriptAdapter adapter) {
super(adapter, new String[0]);
}
public static String getGeneratorDescription() {
return "Bench4Q Scenario";
}
public void doNew() {
List<UsePluginModel> usePlugins = new ArrayList<UsePluginModel>();
UsePluginModel usePlugin1 = new UsePluginModel();
UsePluginModel usePlugin2 = new UsePluginModel();
usePlugin1.setParameters(new ArrayList<ParameterModel>());
usePlugin1.setId("http");
usePlugin1.setName("Http");
usePlugin2.setId("timer");
usePlugin2.setParameters(new ArrayList<ParameterModel>());
Config conf = Config.getConfig();
this.timer = conf.getProperty("generator.isac.timer", "ConstantTimer");
if (this.timer.equals("ConstantTimer")) {
usePlugin2.setName("ConstantTimer");
} else if (this.timer.equals("Random")) {
usePlugin2.setName("Random");
this.randomDist = Config.getConfig().getProperty(
"generator.isac.timer.random.dist", "uniform");
try {
if (this.randomDist.equals("uniform")) {
this.delta = conf.getPropertyInt(
"generator.isac.timer.random.delta").intValue();
} else if (this.randomDist.equals("gaussian")) {
this.delta = conf.getPropertyInt(
"generator.isac.timer.random.delta").intValue();
this.deviation = conf.getPropertyInt(
"generator.isac.timer.random.deviation").intValue();
} else if (this.randomDist.equals("poisson")) {
this.unit = conf.getPropertyInt(
"generator.isac.timer.random.unit").intValue();
} else if (!(this.randomDist.equals("negexpo"))) {
} else {
this.delta = conf.getPropertyInt(
"generator.isac.timer.random.delta").intValue();
}
} catch (Utils.UserException ex) {
ex.printStackTrace(System.err);
System.err
.println("Warning: incorrect property settings for Isac random timer distribution "
+ this.randomDist);
}
}
usePlugins.add(usePlugin1);
usePlugins.add(usePlugin2);
appendUserPluginsToScenario(usePlugins);
}
public String[] getValidFileExtensions() {
return new String[] { ".xis" };
}
public void doParameterList(Param[] params) throws Utils.UserException {
}
public void doQueryStringParameterList(Param[] params)
throws Utils.UserException {
this.queryStringParameters = encodedParameterList(params);
}
public void doBodyParameterList(Param[] params) throws Utils.UserException {
this.bodyParameters = encodedParameterList(params);
}
public void doTestUrlMessage(String url) {
}
public void doSetData(String data) {
if (data == null) {
return;
}
body = data;
}
public void doCallUrl(Action action, String method, String data,
String contentLength) throws Utils.UserException {
if (!isFirstRequest())
doInsertDelay(getTimeElapsedSinceLastestRequest());
BehaviorModel userBehavior = createHttpBehavior(this.getRequestCount(),
action.getUrl(), method);
insertBehavior(userBehavior);
this.queryStringParameters = "";
this.bodyParameters = "";
}
public BehaviorModel createHttpBehavior(int behaviorId, String url,
String method) {
List<ParameterModel> params = new ArrayList<ParameterModel>();
params.add(ParameterModel.createParameter("url", url));
params.add(ParameterModel.createParameter("queryParams",
this.queryStringParameters));
params.add(ParameterModel.createParameter("headers", this.headers));
if (method.equalsIgnoreCase("post")) {
if (body.length() > 0) {
params.add(ParameterModel.createParameter("bodyContent",
this.body));
} else {
params.add(ParameterModel.createParameter("bodyparameters",
this.bodyParameters));
}
}
this.queryStringParameters = "";
this.bodyParameters = "";
this.headers = "";
this.body = "";
return BehaviorModel.UserBehaviorBuilder(behaviorId, method, "http",
params);
}
public void doAssertResponse(String respCode) {
// TODO:Here I can tell if there are some incorrect request when
// record the script
}
public void doTidyCode(String url) {
}
@Override
public void doParseHtmlContent(String responseBody, String rootUrl) {
int htmlStart = responseBody.indexOf("<html");
int htmlEnd = responseBody.indexOf("</html>");
if (htmlStart == -1 || htmlEnd == -1) {
return;
}
parseDocument(rootUrl, responseBody, htmlStart, htmlEnd);
}
private void parseDocument(String rootUrl, String responseContent,
int htmlStart, int htmlEnd) {
// TODO:reset the childrenUrls in scirptAdapter
String htmlContent = responseContent.substring(htmlStart, htmlEnd + 6);
saveToFile(htmlContent);
HtmlDocumentParser documentParser = new HtmlDocumentParser(htmlContent,
rootUrl);
List<ChildrenUrl> childrenUrls = documentParser
.buildParentChildrenRelationship(this.getScriptAdapter()
.getParentBatchIdWithParentUrl(rootUrl));
this.getScriptAdapter().getChildrenUrls().addAll(childrenUrls);
}
private void saveToFile(String htmlContent) {
// TODO: For Test
try {
File storeFile = new File("RecordScriptTestCase/baidu.html");
FileUtils.writeStringToFile(storeFile, htmlContent);
} catch (IOException e) {
e.printStackTrace();
}
}
public void doResponseForStdOut(String url) {
}
public void doResponseForFile() {
}
public void doEndTransaction() throws Utils.UserException {
}
public void doStartRecording() {
}
public void doStopRecording() {
}
public void doClose() {
}
public void setStruts(boolean struts) {
}
public void doHeaders(HeaderValue[] headers) {
StringBuilder headersSB = new StringBuilder();
for (int i = 0; i < headers.length; ++i) {
headersSB.append("header=");
headersSB.append(headers[i].getHeader());
headersSB.append("|value=");
headersSB.append(headers[i].getValue());
headersSB.append("|;");
}
this.headers = headersSB.toString();
}
private void appendUserPluginsToScenario(List<UsePluginModel> usePlugins) {
this.getScriptAdapter().appendUsePluginsToScenario(usePlugins);
}
private void insertBehavior(BehaviorModel behaviorModel)
throws Utils.UserException {
insert(behaviorModel);
}
private void doInsertDelay(long delay) throws Utils.UserException {
BehaviorModel timerBehavior = createTimerBehavior(delay);
try {
insertBehavior(timerBehavior);
} catch (Exception e) {
e.printStackTrace();
logger.error("exception occured when doInsertDelay" + e.toString());
}
}
private BehaviorModel createTimerBehavior(long delay) {
List<ParameterModel> parameterModels = new ArrayList<ParameterModel>();
ParameterModel parameterModel = new ParameterModel();
parameterModel.setKey("time");
parameterModel.setValue(String.valueOf(delay));
parameterModels.add(parameterModel);
return BehaviorModel.TimerBehaviorBuilder(0, "Sleep", "timer",
parameterModels);
}
@SuppressWarnings("unused")
private StringBuilder createTimer(long delay) {
StringBuilder timerStr = new StringBuilder();
if (this.timer.equals("Random")) {
int min = (int) (delay - this.delta);
if (min < 0)
min = 0;
if (this.randomDist.equals("uniform")) {
timerStr.append("\t\t\t<control use=\"replayTimer\" name=\"setUniform\">"
+ EOL);
timerStr.append("\t\t\t\t<params>" + EOL);
timerStr.append("\t\t\t\t\t<param name=\"min\" value=\"" + min
+ "\"/>" + EOL);
timerStr.append("\t\t\t\t\t<param name=\"max\" value=\""
+ (delay + this.delta) + "\"/>" + EOL);
timerStr.append("\t\t\t\t</params>" + EOL);
timerStr.append("\t\t\t</control>" + EOL);
} else if (this.randomDist.equals("gaussian")) {
timerStr.append("\t\t\t<control use=\"replayTimer\" name=\"setGaussian\">"
+ EOL);
timerStr.append("\t\t\t\t<params>" + EOL);
timerStr.append("\t\t\t\t\t<param name=\"min\" value=\"" + min
+ "\"/>" + EOL);
timerStr.append("\t\t\t\t\t<param name=\"max\" value=\""
+ (delay + this.delta) + "\"/>" + EOL);
timerStr.append("\t\t\t\t\t<param name=\"mean\" value=\""
+ delay + "\"/>" + EOL);
timerStr.append("\t\t\t\t\t<param name=\"deviation\" value=\""
+ this.deviation + "\"/>" + EOL);
timerStr.append("\t\t\t\t</params>" + EOL);
timerStr.append("\t\t\t</control>" + EOL);
} else if (this.randomDist.equals("poisson")) {
timerStr.append("\t\t\t<control use=\"replayTimer\" name=\"setPoisson\">"
+ EOL);
timerStr.append("\t\t\t\t<params>" + EOL);
timerStr.append("\t\t\t\t\t<param name=\"unit\" value=\""
+ this.unit + "\"/>" + EOL);
timerStr.append("\t\t\t\t\t<param name=\"parameter\" value=\""
+ delay + "\"/>" + EOL);
timerStr.append("\t\t\t\t</params>" + EOL);
timerStr.append("\t\t\t</control>" + EOL);
} else if (this.randomDist.equals("negexpo")) {
timerStr.append("\t\t\t<control use=\"replayTimer\" name=\"setNegativeExpo\">"
+ EOL);
timerStr.append("\t\t\t\t<params>" + EOL);
timerStr.append("\t\t\t\t\t<param name=\"min\" value=\"" + min
+ "\"/>" + EOL);
timerStr.append("\t\t\t\t\t<param name=\"mean\" value=\""
+ delay + "\"/>" + EOL);
timerStr.append("\t\t\t\t</params>" + EOL);
timerStr.append("\t\t\t</control>" + EOL);
}
timerStr.append("\t\t\t<timer use=\"replayTimer\" name=\"sleep\"/>"
+ EOL);
} else if (this.timer.equals("ConstantTimer")) {
timerStr.append("\t\t\t<timer use=\"replayTimer\" name=\"sleep\">"
+ EOL);
timerStr.append("\t\t\t\t<params>" + EOL);
timerStr.append("\t\t\t\t\t<param name=\"duration_arg\" value=\""
+ delay + "\"></param>" + EOL);
timerStr.append("\t\t\t\t</params>" + EOL);
timerStr.append("\t\t\t</timer>" + EOL);
}
return timerStr;
}
public void doSetCharset(String cs) throws Utils.UserException {
}
}

View File

@ -0,0 +1,29 @@
package org.bench4q.recorder.httpcapture.generator;
public class ChildrenUrl {
private String url;
private int parentBatchId;
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public int getParentBatchId() {
return parentBatchId;
}
public void setParentBatchId(int parentBatchId) {
this.parentBatchId = parentBatchId;
}
public static ChildrenUrl createChilldUrl(String url, int parentBatchId) {
ChildrenUrl ret = new ChildrenUrl();
ret.setParentBatchId(parentBatchId);
ret.setUrl(url);
return ret;
}
}

View File

@ -0,0 +1,44 @@
package org.bench4q.recorder.httpcapture.generator;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import org.apache.log4j.Logger;
public class ContentDecoder {
protected Logger logger = Logger.getLogger(ContentDecoder.class);
protected ContentDecoder() {
}
public static ContentDecoder createDecoder(String encodeType) {
if (encodeType == null) {
return new ContentDecoder();
}
if (encodeType.equalsIgnoreCase("gzip")) {
return new GzipDecoder();
} else {
return new ContentDecoder();
}
}
public byte[] decodeContent(InputStream inputStream) {
try {
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
byte[] buf = new byte[1024];
int len;
while ((len = inputStream.read(buf)) > 0) {
outputStream.write(buf, 0, len);
}
System.out.println(outputStream.toString());
System.out.println("ouputStream's size is" + outputStream.size());
return outputStream.toByteArray();
} catch (Exception e) {
logger.error(e, e);
return null;
}
}
}

View File

@ -0,0 +1,79 @@
package org.bench4q.recorder.httpcapture.generator;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import org.bench4q.recorder.httpcapture.Config;
import org.bench4q.recorder.httpcapture.IScriptAdapter;
import org.bench4q.recorder.httpcapture.Utils;
public class GeneratorFactory {
private static Config config = Config.getConfig();
public static final String GENERATOR_CLASSNAMES_PROPERTY = "generator.classnames";
public static final String JYTHON_CLASSNAME = "com.bitmechanic.maxq.generator.JythonCodeGenerator";
public static String[] getClasses() {
String names = config.getProperty("generator.classnames",
"com.bitmechanic.maxq.generator.JythonCodeGenerator");
return Utils.splitString(names, ":");
}
public static String getClassDescription(String className)
throws ClassNotFoundException, IllegalAccessException,
InvocationTargetException {
Method getGenDesc;
Class<?> gen = Class.forName(className);
try {
getGenDesc = gen.getMethod("getGeneratorDescription", gen);
} catch (NoSuchMethodException e) {
return className;
}
return (String) getGenDesc.invoke((Object) null, (Object) null);
}
public static IScriptGenerator newGenerator(String className,
IScriptAdapter adapter) {
Class<?> clazz = null;
try {
clazz = GeneratorFactory.class.getClassLoader()
.loadClass(className);
} catch (ClassNotFoundException e) {
throw new IllegalStateException(
"Invalid test script class specified . Class not found:"
+ className);
}
if (IScriptGenerator.class.isAssignableFrom(clazz)) {
try {
Class<?>[] generatorConstructorParameterClasses = { IScriptAdapter.class };
Object[] generatorConstructorParameters = { adapter };
Constructor<?> constructor = clazz
.getDeclaredConstructor(generatorConstructorParameterClasses);
return (IScriptGenerator) constructor
.newInstance(generatorConstructorParameters);
} catch (NoSuchMethodException e) {
throw new IllegalStateException(
"Invalid test script class specified. Must have a constructor that takes in properties: "
+ className);
} catch (InstantiationException e) {
throw new IllegalStateException(
"Invalid test script class specified. Could not construct: "
+ className);
} catch (InvocationTargetException e) {
e.printStackTrace();
throw new IllegalStateException(
"Invalid test script class specified. Exception thrown in constructor: "
+ className);
} catch (IllegalAccessException e) {
throw new IllegalStateException(
"Invalid test script class specified. IllegalAccessException: "
+ className);
}
}
throw new IllegalStateException(
"Invalid test script class specified. Does not implement IScriptGenerator: "
+ className);
}
}

View File

@ -0,0 +1,26 @@
package org.bench4q.recorder.httpcapture.generator;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.zip.GZIPInputStream;
public class GzipDecoder extends ContentDecoder {
public byte[] decodeContent(InputStream inputStream) {
try {
GZIPInputStream gzipInputStream = new GZIPInputStream(inputStream);
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
byte[] buf = new byte[1024];
int len;
while ((len = gzipInputStream.read(buf)) > 0) {
outputStream.write(buf, 0, len);
}
return outputStream.toByteArray();
} catch (IOException e) {
logger.error("decodeContent", e);
return null;
}
}
}

View File

@ -0,0 +1,54 @@
package org.bench4q.recorder.httpcapture.generator;
import java.util.ArrayList;
import java.util.List;
import org.apache.log4j.Logger;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
public class HtmlDocumentParser {
private Document document;
private static Logger logger = Logger.getLogger(HtmlDocumentParser.class);
private Document getDocument() {
return document;
}
private void setDocument(Document document) {
this.document = document;
}
public HtmlDocumentParser(String htmlContent, String baseUrl) {
this.setDocument(Jsoup.parse(htmlContent, baseUrl));
}
public void beginParse() {
}
public List<ChildrenUrl> buildParentChildrenRelationship(int parentBatchId) {
List<ChildrenUrl> result = new ArrayList<ChildrenUrl>();
if (parentBatchId == -1) {
return result;
}
Elements allChildrenLinks = new Elements();
allChildrenLinks.addAll(this.getDocument().select("[src]"));
allChildrenLinks.addAll(this.getDocument().select("link[href]"));
logger.info("Following url shuold in children urls: \n");
for (Element element : allChildrenLinks) {
String childAbsoluteUrl = element.absUrl("src");
if (childAbsoluteUrl.isEmpty()) {
childAbsoluteUrl = element.absUrl("href");
}
logger.info(childAbsoluteUrl);
result.add(ChildrenUrl.createChilldUrl(childAbsoluteUrl,
parentBatchId));
}
return result;
}
}

View File

@ -0,0 +1,23 @@
package org.bench4q.recorder.httpcapture.generator;
import org.bench4q.recorder.httpcapture.ProxyServer;
public interface IScriptGenerator extends ProxyServer.Observer {
public static final String EOL = System.getProperty("line.separator");
public abstract String[] getValidFileExtensions();
public abstract String parseTestName();
public abstract void doStartRecording();
public abstract void doStopRecording();
public abstract void doNew();
public abstract boolean doSave(String paramString1, String paramString2);
public abstract void doLoad();
public abstract void close();
}

View File

@ -0,0 +1,74 @@
package org.bench4q.recorder.httpcapture.generator;
import java.util.HashMap;
public class ResponseHeader {
public static HashMap<String, String> MIME_TYPE = new HashMap<String, String>() {
private static final long serialVersionUID = 1L;
{
put("text/plain", "text/plain");
put("text/html", "text/html");
put("text/comma-separated-values", "text/comma-separated-values");
}
};
private String respCode;
private String contentType;
private String charset;
private String contentEncoding;
private int contentLength;
public String getRespCode() {
return respCode;
}
public void setRespCode(String respCode) {
this.respCode = respCode;
}
public String getContentType() {
return contentType;
}
public void setContentType(String contentType) {
this.contentType = contentType;
}
public String getCharset() {
return charset;
}
public void setCharset(String charset) {
this.charset = charset;
}
public String getContentEncoding() {
return contentEncoding;
}
public void setContentEncoding(String contentEncoding) {
this.contentEncoding = contentEncoding;
}
public int getContentLength() {
return contentLength;
}
public void setContentLength(int contentLength) {
this.contentLength = contentLength;
}
boolean isValidResponseHeader() {
return (getContentType() != null)
&& (MIME_TYPE.containsKey(getContentType()))
&& (getRespCode() != null);
}
boolean isHtmlContentType() {
return getContentType().toLowerCase().contains("text/html");
}
boolean isGoodRequest() {
return this.getRespCode().startsWith("200");
}
}

View File

@ -0,0 +1,165 @@
package org.bench4q.recorder.httpcapture.generator;
import java.io.ByteArrayInputStream;
import java.nio.charset.Charset;
import java.util.StringTokenizer;
import org.apache.log4j.Logger;
public class ResponseParser {
private Logger logger = Logger.getLogger(ResponseParser.class);
private byte[] response;
private ResponseHeader responseHeader;
private String responseBody;
private byte[] getResponse() {
return response;
}
private void setResponse(byte[] response) {
this.response = response;
}
public ResponseHeader getResponseHeader() {
return responseHeader;
}
private void setResponseHeader(ResponseHeader responseHeader) {
this.responseHeader = responseHeader;
}
public String getResponseBody() {
return responseBody;
}
private void setResponseBody(String responseBody) {
this.responseBody = responseBody;
}
public ResponseParser(byte[] response) {
this.setResponse(response);
this.setResponseHeader(parseResponseHeader());
if (this.getResponseHeader().isValidResponseHeader()
&& this.getResponseHeader().isHtmlContentType()) {
this.parseResponseBody();
}
}
private ResponseHeader parseResponseHeader() {
ResponseHeader result = new ResponseHeader();
result.setCharset(parseCharset());
result.setContentEncoding(parseContentEncoding());
result.setContentLength(Integer.parseInt(parseContentLength()));
result.setContentType(parseContentType());
result.setRespCode(parseResponseCode());
return result;
}
private String preprocess(String respString) {
return respString.toLowerCase();
}
private String parseContentLength() {
String respStr = preprocess(new String(this.getResponse()));
int pos = respStr.indexOf("content-length:");
if (pos > -1) {
pos += 15;
int end = respStr.indexOf("\r\n", pos);
return respStr.substring(pos, end).trim();
}
return "-1";
}
private String parseContentEncoding() {
String respStr = preprocess(new String(this.getResponse()));
int pos = respStr.indexOf("content-encoding:");
if (pos > -1) {
pos += 18;
int end = respStr.indexOf("\r\n", pos);
return respStr.substring(pos, end);
}
return null;
}
private String parseCharset() {
String response = preprocess(new String(this.getResponse()));
String ret = null;
int pos = response.indexOf("content-type:");
if (pos > -1) {
pos += 14;
int end = response.indexOf("\r\n", pos);
int middle = response.indexOf(";", pos);
if (middle > -1 && middle < end) {
ret = response.substring(middle + 1, end);
}
}
if (ret != null) {
int begin = ret.indexOf("charset=");
ret = ret.substring(begin + 8);
}
return ret;
}
private String parseContentType() {
String response = preprocess(new String(this.getResponse()));
String contentType = null;
int pos = response.indexOf("content-type:");
if (pos > -1) {
pos += 14;
int end = response.indexOf("\r\n", pos);
int end2 = response.indexOf(";", pos);
if ((end2 > -1) && (end2 < end))
end = end2;
if (end > -1)
contentType = response.substring(pos, end).trim();
logger.debug(" Content-Type: " + contentType);
} else {
logger.debug(" No content-type header! First few lines:");
StringTokenizer st = new StringTokenizer(response, "\n");
int i = 0;
while ((st.hasMoreTokens()) && (i < 5)) {
logger.debug(st.nextToken());
++i;
}
}
return contentType;
}
private String parseResponseCode() {
String response = preprocess(new String(this.getResponse()));
String respCode = null;
int pos = response.indexOf(" ");
if (pos != -1) {
int end = response.indexOf(" ", pos + 1);
int end2 = response.indexOf("\n", pos + 1);
if ((end2 != -1) && (end2 < end))
end = end2;
if (end != -1)
respCode = response.substring(pos + 1, end).trim();
}
logger.debug("HTTP response code: " + respCode);
return respCode;
}
private void parseResponseBody() {
ContentDecoder contentDecoder = ContentDecoder.createDecoder(this
.getResponseHeader().getContentEncoding());
byte[] contentBodyAfterDecoded = contentDecoder
.decodeContent(new ByteArrayInputStream(this.getResponse(),
this.getResponse().length
- this.getResponseHeader().getContentLength(),
this.getResponseHeader().getContentLength()));
if (contentBodyAfterDecoded == null) {
return;
}
Charset charset = null;
try {
charset = Charset.forName(this.getResponseHeader().getCharset());
} catch (Exception e) {
charset = Charset.forName("utf-8");
logger.error(e, e);
}
this.setResponseBody(new String(contentBodyAfterDecoded, charset));
}
}

View File

@ -0,0 +1,40 @@
package org.bench4q.recorder;
import static org.junit.Assert.*;
import org.bench4q.recorder.httpcapture.generator.ContentDecoder;
import org.bench4q.recorder.httpcapture.generator.GzipDecoder;
import org.junit.Test;
public class ContentDecoderTest {
@Test
public void testWithNullEncoding() {
ContentDecoder contentDecoder = ContentDecoder.createDecoder(null);
assertTrue(contentDecoder instanceof ContentDecoder);
}
@Test
public void testWithLowerCaseEncoding() {
ContentDecoder contentDecoder = ContentDecoder.createDecoder("gzip");
assertTrue(contentDecoder instanceof GzipDecoder);
}
@Test
public void testWithUpperCaseEncoding() {
ContentDecoder contentDecoder = ContentDecoder.createDecoder("GZIP");
assertTrue(contentDecoder instanceof GzipDecoder);
}
@Test
public void testWithMixCaseEncoding() {
ContentDecoder contentDecoder = ContentDecoder.createDecoder("Gzip");
assertTrue(contentDecoder instanceof GzipDecoder);
}
@Test
public void testWithNotSupportedEncoding() {
ContentDecoder contentDecoder = ContentDecoder.createDecoder("deflate");
assertTrue(contentDecoder instanceof ContentDecoder);
}
}

View File

@ -0,0 +1,45 @@
package org.bench4q.recorder;
import static org.junit.Assert.*;
import java.util.ArrayList;
import java.util.List;
import org.bench4q.recorder.httpcapture.Bench4qTestScriptAdapter;
import org.bench4q.share.helper.RunScenarioModelHelper;
import org.bench4q.share.models.agent.ParameterModel;
import org.bench4q.share.models.agent.RunScenarioModel;
import org.junit.Test;
public class TestBench4qTestScriptAdapter {
private Bench4qTestScriptAdapter bench4qTestScriptAdapter;
private Bench4qTestScriptAdapter getBench4qTestScriptAdapter() {
return bench4qTestScriptAdapter;
}
private void setBench4qTestScriptAdapter(
Bench4qTestScriptAdapter bench4qTestScriptAdapter) {
this.bench4qTestScriptAdapter = bench4qTestScriptAdapter;
}
public TestBench4qTestScriptAdapter() {
this.setBench4qTestScriptAdapter(new Bench4qTestScriptAdapter(
new RunScenarioModel()));
}
@Test
public void testInsertUserBehaviorsToScenario() {
List<ParameterModel> params = new ArrayList<ParameterModel>();
params.add(RunScenarioModelHelper.createParameterModel("url",
"www.baidu.com"));
this.getBench4qTestScriptAdapter().insertUserBehaviorsToScenario(
RunScenarioModelHelper.createUserBehaviorModel(0, "http",
"get", params));
assertEquals(
1,
RunScenarioModelHelper.getBatches(
this.getBench4qTestScriptAdapter()
.getRunScenarioModel()).size());
}
}

View File

@ -0,0 +1,68 @@
package org.bench4q.recorder;
import static org.junit.Assert.*;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import org.apache.commons.io.FileUtils;
import org.bench4q.recorder.httpcapture.generator.ChildrenUrl;
import org.junit.Test;
public class TestDomGenerator extends TestRecordBase {
private URL url = this.getClass().getResource("testcase.html");
public TestDomGenerator() {
init();
}
@Test
public void testDomParser() throws IOException {
this.getCodeGenerator()
.getScriptAdapter()
.insertUserBehaviorsToScenario(
createUserBehaviorModel(parentUrl));
this.getCodeGenerator().doParseHtmlContent(
FileUtils.readFileToString(new File(url.getPath())), parentUrl);
assertTrue(this.getCodeGenerator().getScriptAdapter().getChildrenUrls()
.size() == 8);
for (ChildrenUrl childrenUrl : this.getCodeGenerator()
.getScriptAdapter().getChildrenUrls()) {
assertTrue(childrenUrl.getParentBatchId() == 0);
}
}
@Test
public void testDomParserWithinAdapter() throws IOException {
this.getAdpater().insertUserBehaviorsToScenario(
createUserBehaviorModel(independentUrl));
this.getAdpater().insertUserBehaviorsToScenario(
createUserBehaviorModel(parentUrl));
this.getCodeGenerator().doParseHtmlContent(
FileUtils.readFileToString(new File(this.url.getPath())),
parentUrl);
System.out.println(this.getCodeGenerator().getScriptAdapter()
.getChildrenUrls().size());
assertTrue(this.getCodeGenerator().getScriptAdapter().getChildrenUrls()
.size() == 8);
for (ChildrenUrl childrenUrl : this.getAdpater().getChildrenUrls()) {
assertTrue(childrenUrl.getParentBatchId() == 1);
}
}
@Test
public void testDomParserWithIncorrectParentUrl() throws IOException {
this.getAdpater().insertUserBehaviorsToScenario(
createUserBehaviorModel(parentUrl));
this.getAdpater().insertUserBehaviorsToScenario(
createUserBehaviorModel(independentUrl));
this.getCodeGenerator().doParseHtmlContent(
FileUtils.readFileToString(new File(this.url.getPath())),
parentUrl + "error");
assertTrue(this.getCodeGenerator().getScriptAdapter().getChildrenUrls()
.size() == 0);
}
}

View File

@ -0,0 +1,79 @@
package org.bench4q.recorder;
import static org.junit.Assert.*;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.URL;
import org.apache.commons.httpclient.HttpException;
import org.bench4q.recorder.httpcapture.HttpRequestHeader;
import org.junit.Test;
public class TestHttpRequestHeader {
private static final String PATHNAME = Test_Bench4QCodeGenerator.dealWithSerie
+ "Request.txt";
private HttpRequestHeader requestHeader;
private HttpRequestHeader getRequestHeader() {
return requestHeader;
}
private void setRequestHeader(HttpRequestHeader requestHeader) {
this.requestHeader = requestHeader;
}
public TestHttpRequestHeader() throws FileNotFoundException, IOException,
HttpException {
this.setRequestHeader(new HttpRequestHeader(new FileInputStream(
new File(PATHNAME))));
}
@Test
public void testHeaders() {
assertEquals("GET", this.getRequestHeader().method.toUpperCase());
assertEquals("HTTP://WWW.BAIDU.COM/",
this.getRequestHeader().referer.toUpperCase());
assertEquals(
"text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8",
this.getRequestHeader().accept.toLowerCase().trim());
assertEquals("/phoenix.zhtml?c=188488&p=irol-homeprofile",
this.getRequestHeader().url.toLowerCase().trim());
assertEquals("HTTP/1.1", this.getRequestHeader().version.toUpperCase()
.trim());
assertEquals(
"Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.63 Safari/537.36",
this.getRequestHeader().userAgent.trim());
assertEquals("bearer", this.getRequestHeader().authorization.trim());
assertEquals("multipart", this.getRequestHeader().contentType.trim());
assertEquals(100, this.getRequestHeader().contentLength);
assertEquals(true, this.getRequestHeader().pragmaNoCache);
assertEquals("zh-CN,zh;q=0.8", this.getRequestHeader().acceptLanguage);
// assertEquals("Mon, 22 Mar 2010 14:14:40 GMT; old-content-length=200",
// this.getRequestHeader().ifModifiedSince.trim());
}
@Test
public void testStripProxyInfoFromRequestHeader() throws Exception {
HttpRequestHeader header = new HttpRequestHeader(new FileInputStream(
new File(PATHNAME)));
String res = "";
String origUrl = "http://ir.baidu.com/phoenix.zhtml?c=188488&p=irol-homeprofile";
URL url = new URL(origUrl);
header.url = url.getFile();
res = header.toString();
header.url = origUrl;
System.out.println(res);
}
// @Test
// public void testToStringWithLib() throws IOException {
// assertEquals(FileUtils.readFileToString(new File(PATHNAME))
// .toLowerCase(), this.getRequestHeader().toStringWithLib()
// .toLowerCase());
// }
}

View File

@ -0,0 +1,199 @@
package org.bench4q.recorder;
import static org.junit.Assert.*;
import java.util.List;
import org.bench4q.recorder.httpcapture.Bench4qTestScriptAdapter;
import org.bench4q.recorder.httpcapture.IScriptAdapter;
import org.bench4q.recorder.httpcapture.generator.ChildrenUrl;
import org.bench4q.share.helper.RunScenarioModelHelper;
import org.bench4q.share.models.agent.RunScenarioModel;
import org.bench4q.share.models.agent.scriptrecord.BatchModel;
import org.junit.Test;
public class TestParentRequest extends TestRecordBase {
private IScriptAdapter adapater;
private static String parentUrl = "www.apache.com";
private static String childUrl = "www.yahoo.com";
private static String independentUrl = "www.baidu.com";
private static String independentUrl2 = "www.eclipse.org";
private static String childUrl2 = "www.tomcat.com";
private IScriptAdapter getAdapater() {
return adapater;
}
private void setAdapater(IScriptAdapter adapater) {
this.adapater = adapater;
}
public TestParentRequest() {
this.setAdapater(new Bench4qTestScriptAdapter(new RunScenarioModel()));
}
@Test
public void testAddOneBehaviorWihoutChildrenUrl() {
this.getAdapater().insertUserBehaviorsToScenario(
createUserBehaviorModel(parentUrl));
assertNotNull(this.getAdapater().getRunScenarioModel());
List<BatchModel> batches = RunScenarioModelHelper.getBatches(this
.getAdapater().getRunScenarioModel());
assertNotNull(batches);
assertNotNull(batches.get(0));
assertTrue(batches.get(0).getId() == 0);
}
@Test
public void testAddTwoBehaviorWithOutChildrenUrl() {
this.getAdapater().insertUserBehaviorsToScenario(
createUserBehaviorModel(parentUrl));
this.getAdapater().getChildrenUrls()
.add(createChildrenUrl(childUrl, 0));
this.getAdapater().insertUserBehaviorsToScenario(
createUserBehaviorModel(independentUrl));
this.getAdapater().insertUserBehaviorsToScenario(
createUserBehaviorModel(independentUrl2));
RunScenarioModel runScenarioModel = this.getAdapater()
.getRunScenarioModel();
assertNotNull(runScenarioModel);
List<BatchModel> batches = RunScenarioModelHelper
.getBatches(runScenarioModel);
assertNotNull(batches);
assertTrue(batches.size() == 3);
assertTrue(batches.get(1).getBehaviors().size() == 1);
assertTrue(batches.get(2).getBehaviors().size() == 1);
assertTrue(batches.get(1).getBehaviors().get(0).getParameters().get(0)
.getValue().equals(independentUrl));
assertTrue(batches.get(2).getBehaviors().get(0).getParameters().get(0)
.getValue().equals(independentUrl2));
}
// private UserBehaviorModel createUserBehavior(String url) {
// UserBehaviorModel model = new UserBehaviorModel();
// model.setId(1);
// model.setName("Get");
// model.setUse("http");
// List<ParameterModel> params = new ArrayList<ParameterModel>();
// ParameterModel param = new ParameterModel();
// param.setKey("url");
// param.setValue(url);
// params.add(param);
// model.setParameters(params);
// return model;
// }
@Test
public void testAddBehaviorWithInChildrenUrl() {
this.getAdapater().insertUserBehaviorsToScenario(
createUserBehaviorModel(parentUrl));
this.getAdapater().getChildrenUrls()
.add(createChildrenUrl(childUrl, 0));
this.getAdapater().insertUserBehaviorsToScenario(
createUserBehaviorModel(childUrl));
RunScenarioModel runScenarioModel = this.getAdapater()
.getRunScenarioModel();
assertNotNull(runScenarioModel);
List<BatchModel> batches = RunScenarioModelHelper
.getBatches(runScenarioModel);
assertNotNull(batches);
assertNotNull(batches.get(0));
assertNotNull(batches.get(1));
assertTrue(batches.get(1).getId() == 1);
assertEquals(batches.get(0).getChildId(), batches.get(1).getId());
assertEquals(batches.get(1).getParentId(), batches.get(0).getId());
}
private ChildrenUrl createChildrenUrl(String url, int parentBatchId) {
ChildrenUrl childrenUrl = new ChildrenUrl();
childrenUrl.setParentBatchId(parentBatchId);
childrenUrl.setUrl(url);
return childrenUrl;
}
@Test
public void testAddBehaviorsIncludeInAndOut() {
this.getAdapater().insertUserBehaviorsToScenario(
createUserBehaviorModel(parentUrl));
this.getAdapater().getChildrenUrls()
.add(createChildrenUrl(childUrl, 0));
this.getAdapater().insertUserBehaviorsToScenario(
createUserBehaviorModel(childUrl));
this.getAdapater().insertUserBehaviorsToScenario(
createUserBehaviorModel(independentUrl));
List<BatchModel> batches = RunScenarioModelHelper.getBatches(this
.getAdapater().getRunScenarioModel());
assertTrue(batches.get(1).getBehaviors().size() == 1);
assertTrue(batches.get(2).getBehaviors().size() == 1);
assertTrue(batches.get(1).getBehaviors().get(0).getParameters().get(0)
.getValue().equals(childUrl));
assertTrue(batches.get(2).getBehaviors().get(0).getParameters().get(0)
.getValue().equals(independentUrl));
assertEquals(batches.get(0).getChildId(), batches.get(1).getId());
assertEquals(batches.get(1).getParentId(), batches.get(0).getId());
}
@Test
public void addTwoBehaviorsInChildrenUrl() {
this.getAdapater().insertUserBehaviorsToScenario(
createUserBehaviorModel(parentUrl));
this.getAdapater().getChildrenUrls()
.add(createChildrenUrl(childUrl, 0));
this.getAdapater().getChildrenUrls()
.add(createChildrenUrl(childUrl2, 0));
this.getAdapater().insertUserBehaviorsToScenario(
createUserBehaviorModel(childUrl));
this.getAdapater().insertUserBehaviorsToScenario(
createUserBehaviorModel(childUrl2));
List<BatchModel> batches = RunScenarioModelHelper.getBatches(this
.getAdapater().getRunScenarioModel());
System.out.println(batches.size());
assertTrue(batches.size() == 2);
assertTrue(batches.get(0).getBehaviors().get(0).getParameters().get(0)
.getValue().equals(parentUrl));
assertTrue(batches.get(1).getBehaviors().get(0).getParameters().get(0)
.getValue().equals(childUrl));
assertTrue(batches.get(1).getBehaviors().get(1).getParameters().get(0)
.getValue().equals(childUrl2));
}
@Test
public void addTwoInTwoOut() {
this.getAdapater().insertUserBehaviorsToScenario(
createUserBehaviorModel(parentUrl));
this.getAdapater().getChildrenUrls()
.add(createChildrenUrl(childUrl, 0));
this.getAdapater().getChildrenUrls()
.add(createChildrenUrl(childUrl2, 0));
this.getAdapater().insertUserBehaviorsToScenario(
createUserBehaviorModel(childUrl));
this.getAdapater().insertUserBehaviorsToScenario(
createUserBehaviorModel(childUrl2));
this.getAdapater().insertUserBehaviorsToScenario(
createUserBehaviorModel(independentUrl));
this.getAdapater().insertUserBehaviorsToScenario(
createUserBehaviorModel(independentUrl2));
assertTrue(RunScenarioModelHelper.getBatches(
this.getAdapater().getRunScenarioModel()).size() == 4);
}
@Test
public void testGetParentUrl() {
this.getAdapater().insertUserBehaviorsToScenario(
createUserBehaviorModel(parentUrl));
this.getAdapater().insertUserBehaviorsToScenario(
createUserBehaviorModel(independentUrl));
this.getAdapater().insertUserBehaviorsToScenario(
createUserBehaviorModel(independentUrl2));
assertTrue(this.getAdapater().getParentBatchIdWithParentUrl(parentUrl) == 0);
assertTrue(this.getAdapater().getParentBatchIdWithParentUrl(
independentUrl) == 1);
assertTrue(this.getAdapater().getParentBatchIdWithParentUrl(
independentUrl2) == 2);
}
}

View File

@ -0,0 +1,49 @@
package org.bench4q.recorder;
import java.util.ArrayList;
import java.util.List;
import org.bench4q.recorder.httpcapture.Bench4qTestScriptAdapter;
import org.bench4q.recorder.httpcapture.IScriptAdapter;
import org.bench4q.recorder.httpcapture.generator.Bench4qCodeGenerator;
import org.bench4q.share.models.agent.ParameterModel;
import org.bench4q.share.models.agent.RunScenarioModel;
import org.bench4q.share.models.agent.scriptrecord.BehaviorModel;
public abstract class TestRecordBase {
private IScriptAdapter adapter;
private Bench4qCodeGenerator codeGenerator;
protected static String parentUrl = "http://localhost:8080/Bench4QTestCase/testcase.html";
protected static String independentUrl = "www.baidu.com";
protected static String childrenUrl1 = "http://localhost:8080/Bench4QTestCase/script/agenttable.js";
protected IScriptAdapter getAdpater() {
return adapter;
}
private void setAdpater(IScriptAdapter adapter) {
this.adapter = adapter;
}
protected Bench4qCodeGenerator getCodeGenerator() {
return codeGenerator;
}
private void setCodeGenerator(Bench4qCodeGenerator codeGenerator) {
this.codeGenerator = codeGenerator;
}
protected void init() {
this.setAdpater(new Bench4qTestScriptAdapter(new RunScenarioModel()));
this.setCodeGenerator(new Bench4qCodeGenerator(this.getAdpater()));
}
protected BehaviorModel createUserBehaviorModel(String url) {
List<ParameterModel> params = new ArrayList<ParameterModel>();
ParameterModel param = new ParameterModel();
param.setKey("url");
param.setValue(url);
params.add(param);
return BehaviorModel.UserBehaviorBuilder(1, "Get", "http", params);
}
}

View File

@ -0,0 +1,49 @@
package org.bench4q.recorder;
import java.io.File;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import org.apache.commons.io.FileUtils;
import org.bench4q.recorder.httpcapture.generator.ResponseHeader;
import org.bench4q.recorder.httpcapture.generator.ResponseParser;
import org.junit.Test;
import static org.junit.Assert.*;
public class TestResponseParser {
private ResponseParser responseParser;
private static String FILE_SEPARATOR = System.getProperty("file.separator");
private ResponseParser getResponseParser() {
return responseParser;
}
private void setResponseParser(ResponseParser responseParser) {
this.responseParser = responseParser;
}
public TestResponseParser() throws IOException {
byte[] response = FileUtils.readFileToByteArray(new File(
"RecordScriptTestCase" + FILE_SEPARATOR
+ "gzipBaiduResponse.txt"));
this.setResponseParser(new ResponseParser(response));
}
@Test
public void testParseResponseHeader() throws Exception {
ResponseHeader parseResponseHeader = this.getResponseParser()
.getResponseHeader();
assertEquals(parseResponseHeader.getContentLength(), 12852);
assertEquals(parseResponseHeader.getCharset(), "utf-8");
assertEquals(parseResponseHeader.getContentEncoding(), "gzip");
assertEquals(parseResponseHeader.getContentType(), "text/html");
assertEquals(parseResponseHeader.getRespCode(), "200");
}
@Test
public void testParseResponseBody() throws UnsupportedEncodingException {
String responseBody = this.getResponseParser().getResponseBody();
assertTrue(responseBody.indexOf("我的") > -1);
}
}

View File

@ -0,0 +1,195 @@
package org.bench4q.recorder;
import static org.junit.Assert.*;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.nio.charset.Charset;
import java.util.zip.GZIPInputStream;
import org.apache.commons.io.FileUtils;
import org.bench4q.recorder.httpcapture.Bench4qTestScriptAdapter;
import org.bench4q.recorder.httpcapture.HeaderValue;
import org.bench4q.recorder.httpcapture.HttpRequestHeader;
import org.bench4q.recorder.httpcapture.Param;
import org.bench4q.recorder.httpcapture.Utils.UserException;
import org.bench4q.recorder.httpcapture.generator.Bench4qCodeGenerator;
import org.bench4q.recorder.httpcapture.generator.ContentDecoder;
import org.bench4q.recorder.httpcapture.generator.IScriptGenerator;
import org.bench4q.recorder.httpcapture.generator.ResponseParser;
import org.bench4q.share.models.agent.RunScenarioModel;
import org.bench4q.share.models.agent.scriptrecord.BehaviorModel;
import org.junit.Test;
public class Test_Bench4QCodeGenerator extends TestRecordBase {
private Bench4qTestScriptAdapter scriptAdapter = new Bench4qTestScriptAdapter(
new RunScenarioModel());
private Bench4qCodeGenerator codeGenerator = new Bench4qCodeGenerator(
this.scriptAdapter);
public static String dealWithSerie = "RecordScriptTestCase/gzip/gzipBaiduIR";
@Test
public void testProcessResponseWithHtmlContentTypeWithNullResponseBody()
throws FileNotFoundException, IOException, Exception {
IScriptGenerator scriptGenerator = this.codeGenerator;
scriptGenerator.processResponse(
makeAHeader("www.makeup.com"),
new byte[0],
FileUtils.readFileToByteArray(new File(dealWithSerie
+ "NullResponseBody.html")));
assertEquals(0, this.scriptAdapter.getChildrenUrls().size());
}
@Test
public void testProcessResponseOnceWithHtmlResponseButHaveNoBody()
throws Exception, IOException, FileNotFoundException {
IScriptGenerator scriptGenerator = this.codeGenerator;
scriptGenerator.processResponse(
makeAHeader("www.makeup.com"),
new byte[0],
FileUtils.readFileToByteArray(new File(dealWithSerie
+ "BlankBody.html")));
assertEquals(0, this.scriptAdapter.getChildrenUrls().size());
}
@Test
public void testProcessResponseWithOneHtmlResponseHaveBody()
throws Exception {
HttpRequestHeader header = makeAHeader("ir.baidu.com");
IScriptGenerator scriptGenerator = this.codeGenerator;
scriptGenerator.processResponse(
header,
new byte[0],
FileUtils.readFileToByteArray(new File(dealWithSerie
+ "Response.txt")));
assertEquals(11, this.scriptAdapter.getChildrenUrls().size());
}
private HttpRequestHeader makeAHeader(String url) throws IOException,
FileNotFoundException {
HttpRequestHeader header = new HttpRequestHeader(new FileInputStream(
new File(dealWithSerie + "Request.txt")));
header.url = url;
return header;
}
@Test
public void testProcessResponseTwiceWithTwoHtmlResponseButTheSecondHaveNoBody()
throws Exception {
testProcessResponseWithOneHtmlResponseHaveBody();
testProcessResponseOnceWithHtmlResponseButHaveNoBody();
assertEquals(0, this.scriptAdapter.getChildrenUrls().size());
}
@Test
public void testProcessResponseTwiceWithTwoHtmlResponseOneHtmlSecondNot()
throws Exception {
testProcessResponseWithOneHtmlResponseHaveBody();
testProcessResponseWithNotHtmlResponse();
assertEquals(11, this.scriptAdapter.getChildrenUrls().size());
}
@Test
public void testProcessResponseWithTwoHtmlResponseFirstNoBodySecondHave()
throws FileNotFoundException, IOException, Exception {
testProcessResponseOnceWithHtmlResponseButHaveNoBody();
testProcessResponseWithOneHtmlResponseHaveBody();
}
private void testProcessResponseWithNotHtmlResponse() throws Exception,
IOException, FileNotFoundException {
IScriptGenerator scriptGenerator = this.codeGenerator;
scriptGenerator.processResponse(
makeAHeader("www.makeup2.com"),
new byte[0],
FileUtils.readFileToByteArray(new File(dealWithSerie
+ "NotHtmlResponse.html")));
}
@Test
public void testParseContentLength() throws IOException {
int contentLength = new ResponseParser(
FileUtils.readFileToByteArray(new File(dealWithSerie
+ "Response.txt"))).getResponseHeader()
.getContentLength();
assertTrue(contentLength == 5023);
}
@Test
public void testGetContentBody() throws IOException {
String contentFromFile = FileUtils.readFileToString(new File(
dealWithSerie + "ResponseBody.txt"), "ISO-8859-1");
byte[] contentBody1 = contentFromFile.getBytes("ISO-8859-1");
String responseString = new String(contentBody1,
Charset.forName("ISO-8859-1"));
System.out.println("testGetContentBody total length:"
+ responseString.getBytes("ISO-8859-1").length);
System.out.println("testGetContentBody :" + contentBody1.length);
GZIPInputStream inputStream = new GZIPInputStream(
new ByteArrayInputStream(contentBody1));
assertEquals(responseString.getBytes("ISO-8859-1").length,
contentBody1.length);
assertTrue(inputStream != null);
}
@Test
public void testUncompressGzipContent() throws IOException {
ContentDecoder contentDecoder = ContentDecoder.createDecoder("gzip");
FileInputStream inputStream = new FileInputStream(new File(
dealWithSerie + "ResponseBody.txt"));
String contentString = new String(
contentDecoder.decodeContent(inputStream),
Charset.forName("utf-8"));
System.out.println(contentString);
assertTrue(contentString.indexOf("<html") > -1);
}
@Test
public void testFileInputStreamAndFileUtils() throws IOException {
byte[] responseBodyBytes = FileUtils.readFileToString(
new File(dealWithSerie + "ResponseBody.txt"), "UTF-8")
.getBytes("UTF-8");
int length1 = responseBodyBytes.length;
String responseBodyString = new String(responseBodyBytes, "UTF-8");
int length2 = responseBodyString.getBytes("UTF-8").length;
assertEquals(length1, length2);
System.out.println(length1);
}
@Test
public void testCreateGetBehavior() throws UserException {
this.codeGenerator.doQueryStringParameterList(new Param[] { Param
.createParam("a", "b") });
this.codeGenerator.doHeaders(new HeaderValue[] { new HeaderValue(
"token", "Bearer") });
this.codeGenerator.doBodyParameterList(new Param[] { Param.createParam(
"a", "b") });
BehaviorModel behaviorModel = this.codeGenerator.createHttpBehavior(1,
"http://www.baidu.com", "Get");
assertEquals("a=b", behaviorModel.getParameters().get(1).getValue());
assertEquals("header=token|value=Bearer|;", behaviorModel
.getParameters().get(2).getValue());
assertEquals(3, behaviorModel.getParameters().size());
}
public void testCreatePostBehavior() throws UserException {
this.codeGenerator.doQueryStringParameterList(new Param[] { Param
.createParam("a", "b") });
this.codeGenerator.doHeaders(new HeaderValue[] { new HeaderValue(
"token", "Bearer") });
this.codeGenerator.doBodyParameterList(new Param[] { Param.createParam(
"a", "b") });
this.codeGenerator.doSetData("ava");
BehaviorModel behaviorModel = this.codeGenerator.createHttpBehavior(1,
"http://www.baidu.com", "Post");
assertEquals("a=b", behaviorModel.getParameters().get(1).getValue());
assertEquals("header=token|value=Bearer|;", behaviorModel
.getParameters().get(2).getValue());
assertEquals(5, behaviorModel.getParameters().size());
assertEquals("ava", behaviorModel.getParameters().get(3).getValue());
assertEquals("a=b", behaviorModel.getParameters().get(4).getValue());
}
}

View File

@ -0,0 +1,58 @@
package org.bench4q.recorder;
import static org.junit.Assert.*;
import java.util.ArrayList;
import java.util.List;
import org.bench4q.recorder.httpcapture.Param;
import org.junit.Test;
public class Test_ParamParser {
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 List<String> expectedNFField = new ArrayList<String>() {
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");
}
};
private List<Param> expectedParams = new ArrayList<Param>() {
private static final long serialVersionUID = 1L;
{
add(Param.createParam("_nacc", "yeah"));
add(Param.createParam("_nvid", "525d29a534e918cbf04ea7159706a93d"));
add(Param.createParam("_nvtm", "0"));
}
};
@Test
public void testParseParam() {
List<String> result = Param.ParamParser.getNVField(testcase);
assertEquals(10, result.size());
for (int i = 0; i < result.size(); i++) {
assertEquals(result.get(i), expectedNFField.get(i));
System.out.println(result.get(i));
}
}
@Test
public void testParse() {
List<Param> result = Param.ParamParser.parse(testcase);
assertEquals(10, result.size());
for (int i = 0; i < 3; i++) {
assertEquals(result.get(i).name, expectedParams.get(i).name);
assertEquals(result.get(i).value, expectedParams.get(i).value);
}
}
}

View File

@ -0,0 +1,17 @@
<html>
<head>
<title>Bench4Q Test Case</title>
<link href="style/bootstrap-cerulean.css" />
<link href="style/bootstrap-classic.css" />
<link href="style/bootstrap-cerulean.css" />
</head>
<body>
<img src="images/1.jpg" alt="No this one" />
<img src="images/2.jpg" alt="No this one" />
<img src="images/3.jpg" alt="No this one" />
<script src="script/agentTable.js" type="text/javascript"></script>
<script src="script/base.js" type="text/javascript"></script>
</body>
</html>