四, 拉取远程服务器上的测试报告
在远程服务器上执行自动化测试用例的时候
,存在一个问题:测试报告!而不管用什么自动化测试框架,都有相应的报告生成机制,如TestNG,HTMLTestRunner都能自己产生报告的,我们要做的只是把远程机上产生的报告拉取到本地,以供我们平台展示。
当然我们要先在本地创建存放测试报告的路径,检测出最新产生的测试报告文件夹,并需要进行相应的授权,示例代码如下:
public String copyreport(String
ip, String reportpath, String dstpath) throwsIOException, JSchException {
if (!FileHelper.isFileExists(dstpath)) {
FileHelper.createDir(dstpath);
log.info("报告文件夹创建完成!");
} else
{
log.info("报告文件夹已存在!");
}
String cmd
= "cd " + reportpath + ";" + "ls -t";
String result
= null;
try {
result = execAndResult(cmd,5);
} catch
(Exception e) {
e.printStackTrace();
}
// 获取最新的报告
log.info("文件名:" + result);
String[] files = result.split("\n");
// 判断新的报告是否产生
Pattern pattern
=
Pattern.compile("[0-9]*");
String filename
= null;
for (String tmp : files) {
Matcher isNum
= pattern.matcher(tmp);
if (isNum.matches()) {
log.info("测试报告生成成功,测试报告文件夹是:" + tmp);
filename = tmp;
break;
}
}
CommandRun commandRun = new CommandRun("kinit -k -t
/etc/krb5.keytab", true);
log.info("添加互信" + commandRun.startThread());
reportpath = reportpath + "/" + filename;
CommandRuncpfile = newCommandRun("scp -r" + " work@" + ip+ ":" + reportpath + " " + dstpath, true);
log.info("拷贝文件:" + cpfile.startThread());
returnfilename;
}
代码解析:
(1)
函数copyreport()通过传递Ip地址,报告在本地的路径,远程路径来获取报告的。
(2)
先通过初始化session,在远程机上进入报告路径,执行ls–t获取最新的报告文件夹。
(3)
通过CommandRun(本地封装的执行cmd的类)通过kerberos授权,并根据需求拼出scp命令,将我们获取到的测试报告文件夹拉取到本地。
五,实时获取日志输出
在开发测试平台的时候,一般需要实时显示出我们对服务器的操作结果,如部署环境的时候日志显示。而解决这个问题的办法是,借助于生产者消者模式,具体方法如下:
(1)创建生产者消费者类LogBuffer,具体实现代码如下:
import com.bj58.ershou.common.helper.LoggerHelper;
public class LogBuffer
{
private
staticLoggerHelper loggerHelper = new LoggerHelper(LogBuffer.class);
private
StringBuffer contents = new StringBuffer();
private
StringBuilder lastinfo = new StringBuilder();
private
boolean
finish = false;
private
long lastUpdateTime =
System.currentTimeMillis();
public String get()
{
if (contents.length() != 0) {
synchronized
(contents) {
String value = contents.toString();
loggerHelper.info("Get buffer:"+value);
if (!value.equals("")) {
lastinfo.setLength(0);
lastinfo.append(value);
}
contents.setLength(0);
return value;
}
} else
{
return "";
}
}
public String getStringUnClear(){
return lastinfo.toString().trim();
}
public
voidput(String value) {
synchronized
(contents) {
loggerHelper.info("Put buffer:"+value);
contents.append(value);
lastUpdateTime =
System.currentTimeMillis();
}
}
public
voidclear() {
synchronized
(contents) {
if (contents.length()>1){
contents.delete(0,contents.length()-1);
}
}
}
public
voiddelete() {
synchronized
(contents) {
contents = null;
}
}
public
booleanisFinish() {
return finish;
}
public
voidsetFinish(boolean finish) {
this.finish = finish;
}
public
longgetLastUpdateTime() {
return lastUpdateTime;
}
public
voidsetLastUpdateTime(long lastUpdateTime) {
this.lastUpdateTime = lastUpdateTime;
}
}
(2)优化执行命令的函数,将命令执行的结果写入到Buffer中,代码如下:
/**
* 执行命令并根据条件进行判断
*
@param cmd 要执行的命令
*
@param jumplog:要检测的日志标志
*
@param timeout:超时时间
*
@param write:写入缓存
*
@return
*
@throws
Exception
*/
public
boolean
exec( String cmd,String
jumplog,longtimeout,LogBuffer write)
throws Exception{
long prifix =
System.currentTimeMillis();
ChannelExec channelExec = null;
InputStream in = null;
InputStream errStream = null;
try {
channelExec = (ChannelExec)session.openChannel( "exec" );
channelExec.setCommand( cmd );
channelExec.setInputStream( null );
channelExec.setErrStream( null );
channelExec.setPty(false);
in = channelExec.getInputStream();
errStream = channelExec.getErrStream();
channelExec.connect();
int res = -1;
byte[] tmp = new byte[ 1024 ];
long starttime =
System.currentTimeMillis();
while ( true ) {
while ( in.available() > 0 ) {
int i = in.read( tmp, 0, 1024 );
loggerHelper.info("Command read i:"+Integer.toString(i));
if ( i < 0 ) break;
String tmp2 = new String( tmp, 0, i );
if (jumplog!=null) {
if (tmp2.indexOf(jumplog) > -1)
{
write.put(tmp2);
return
true;
}
}
write.put(tmp2);
starttime = System.currentTimeMillis();
}
while ( errStream.available() > 0 )
{
int i = errStream.read( tmp, 0, 1024
);
if ( i < 0 ) break;
String tmp2 = new String( tmp, 0, i );
write.put(tmp2);
}
if (System.currentTimeMillis() -
starttime >= timeout * 1000) {
break;
}
if ( channelExec.isClosed()) {
if (in.available() > 0)
continue;
res = channelExec.getExitStatus();
break;
}
}
} catch
(Exception e) {
e.printStackTrace();
} finally
{
if (channelExec !=null) {
channelExec.disconnect();
}
if (in !=null) {
in.close();
}
if (errStream!=null) {
errStream.close();
}
}
Thread.sleep(1000);
return
false;
}
(3)编写执行查看日志命令和获取实时日志的函数,注意:此时写入和读取的buffer必须是同一个,否则内容会出错。具体代码如下:
public classLogRelatedOperationController
extendsMvcController{
private
Map logBufferMap = new HashMap();//标识每个操作不同的buffer
private
staticLoggerHelper loggerHelper = new LoggerHelper(LogRelatedOperationController.class);
@GET
@POST
@Path("/getjumplog")
public ActionResult GetJumpLogs()
throws Exception
{
//执行获取日志命令
JschUtils jsutil = null;
HttpServletRequest request = beat.getRequest();
String serverip = ParamUtils.getString(request,
"serverip");
String jumptype = ParamUtils.getString(request,
"jumptype");
LogBuffer lgbuffer = new LogBuffer();
Map m = Collections.synchronizedMap(logBufferMap);
m.put(serverip, lgbuffer);
JSONObject resultjson = new JSONObject();
try {
jsutil=new JschUtils(serverip,22);
} catch
(Exception e) {
e.printStackTrace();
loggerHelper.info("权限认证失败");
resultjson.put("respCode", -1);
resultjson.put("errMsg", "权限认证失败!");
return JsonActionResult.parse(resultjson);
}
try
{
String cmd="tail -f
/opt/web/jwdf_m_sale/logs/catalina.out";
boolean
cmdres=jsutil.exec(cmd,jumptype,65,lgbuffer);
resultjson.put("respCode", 0);
if (cmdres) {
resultjson.put("respData", 1);
return JsonActionResult.parse(resultjson);
} else
{
resultjson.put("respData", 0);
return JsonActionResult.parse(resultjson);
}
} catch
(Exception e) {
e.printStackTrace();
resultjson.put("respCode", -1);
resultjson.put("errMsg", "执行脚本异常!");
return JsonActionResult.parse(resultjson);
}
}
@GET
@Path("/getrllog")
public ActionResult GetRealTimeLogs()
throws Exception
{
//获取实时日志
HttpServletRequest request = beat.getRequest();
String serverip = ParamUtils.getString(request,
"serverip");
JSONObject resultjson = new JSONObject();
LogBuffer lgbuffer = logBufferMap.get(serverip);
if (lgbuffer == null) {
resultjson.put("respCode", -1);
resultjson.put("respData", "");
return JsonActionResult.parse(resultjson);
}
String lgcont=lgbuffer.get();
if (lgcont!=null)
{
resultjson.put("respCode", 0);
resultjson.put("respData", lgcont);
}
else
{
resultjson.put("respCode", -1);
resultjson.put("errMsg", "获取日志失败!");
}
return JsonActionResult.parse(resultjson);
}
}
六 总结
通过上面的文字,我们介绍了jsch连接其他服务器的方法,同是介绍了相应的操作应该如何编码。希望以后遇到相应的情况的时候做参考,当然也有不足之处,以后随时更新。
加载中,请稍候......