加载中…
个人资料
  • 博客等级:
  • 博客积分:
  • 博客访问:
  • 关注人气:
  • 获赠金笔:0支
  • 赠出金笔:0支
  • 荣誉徽章:
正文 字体大小:

Jsch远程操作服务器(下)

(2017-12-13 16:07:36)
标签:

jsch

远程操作服务器

分类: 软件测试技术

四, 拉取远程服务器上的测试报告

在远程服务器上执行自动化测试用例的时候 ,存在一个问题:测试报告!而不管用什么自动化测试框架,都有相应的报告生成机制,如TestNGHTMLTestRunner都能自己产生报告的,我们要做的只是把远程机上产生的报告拉取到本地,以供我们平台展示。

当然我们要先在本地创建存放测试报告的路径,检测出最新产生的测试报告文件夹,并需要进行相应的授权,示例代码如下:

 

       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连接其他服务器的方法,同是介绍了相应的操作应该如何编码。希望以后遇到相应的情况的时候做参考,当然也有不足之处,以后随时更新。

0

阅读 收藏 喜欢 打印举报/Report
  

新浪BLOG意见反馈留言板 欢迎批评指正

新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 产品答疑

新浪公司 版权所有