2015-02-11 139 views
3

在构建服务器上运行phatomjs/java集成测试后,phantomjs进程仍然在后台运行,必须手动终止。如何在测试完成后杀死在后台运行的phantomjs进程

有没有办法在java代码中做到这一点?我已经在测试清理部分使用了driver.quit()。还有什么还包括在内?

+0

@WorryNerd你的phantomjs的版本是什么? – erhun 2015-02-11 22:48:59

+0

类似的问题要求为phyton http://stackoverflow.com/questions/25110624/how-to-properly-stop-phantomjs-execution有一个工作在这里为Linux系统手动过程pgrep phantomjs | xargs kill – erhun 2015-02-11 22:55:28

+0

感谢@erhun重定向到这个问题。那是我目前面临的问题,但我无法每次手动杀死这些进程。我在我的代码中使用了driver.quit(),但是一旦构建完成,这些进程仍留在服务器中。是否有任何线程谈到在teamcity中添加一个步骤来杀死进程? – WorryNerd 2015-02-12 17:42:35

回答

0

这是一个著名的问题,存在的,因为2012年12月 - UnreachableBrowserException

所以,我提出了一些解决方法 - 创建类,这与重载方法扩展PhantomJSDriver“执行”:

@Override 
protected Response execute(String driverCommand, Map<String, ?> parameters) { 
    int retryAttempt = 0; 

    while (true) { 
     try { 
      return super.execute(driverCommand, parameters); 
     } catch (WebDriverException e) { 
      retryAttempt++; 
      if (retryAttempt > retryCount) { 
       throw e; 
      } 
     } 
    } 
} 

这是有帮助的,但并不总是 - 有时phantomjs过程没有停止工作。所以,我发现了一种通过PID(进程ID)

@Override 
protected Response execute(String driverCommand, Map<String, ?> parameters) { 
    int retryAttempt = 0; 

    while (true) { 
     try { 
      return super.execute(driverCommand, parameters); 
     } catch (WebDriverException e) { 
      retryAttempt++; 
      if (retryAttempt > retryCount) { 
       if(driverCommand.equalsIgnoreCase("quit")) { 
        int port = GetDriverPort(); 
        try { 
         int processID = GetPIDByServerPort(port); 
         boolean processExist = processID != -1; 
         if(processExist) { 
          log.info("Killing phantomJS, of process id:" + processID + " that listen to port:" + port); 
          KillPhantomProcess(processID); 
         } 
         return null; 
        } catch (IOException | InterruptedException ignore) { 
         throw e; 
        } 
       } 

       throw e; 
      } 
     } 
    } 
} 

private int GetDriverPort(){ 
    return ((HttpCommandExecutor)(this).getCommandExecutor()).getAddressOfRemoteServer().getPort(); 
} 

private int GetPIDByServerPort(int port) throws InterruptedException, IOException { 
    int pid = -1; 
    ProcessBuilder p = new ProcessBuilder("cmd.exe", "/C", "netstat -no | findstr :" + String.valueOf(port)); 
    p.inheritIO().redirectOutput(ProcessBuilder.Redirect.PIPE); 

    Process netstat = p.start(); 
    netstat.waitFor(); 
    InputStream inputStream = netstat.getInputStream(); 

    int bytesRead; 
    byte[] bytes = new byte[1024]; 
    String result = ""; 
    while ((bytesRead = inputStream.read(bytes)) > -1) { 
     result = result + new String(bytes, 0, bytesRead); 
    } 

    String[] lines = result.split("\\n+"); 
    for (String line : lines) { 
     if(!(line.toUpperCase().contains("ESTABLISHED") && line.contains("127.0.0.1:" + port))) continue; 

     String[] str = line.trim().split("\\s+"); 
     if(str[1].contains(String.valueOf(port))) pid = Integer.parseInt(str[4]); 
    } 

    return pid; 
} 

private void KillPhantomProcess(int pid) throws IOException { 
    try { 
     Runtime.getRuntime().exec(TASKKILL_COMMAND + pid); 
    } catch (IOException e) { 
     log.error("Failed to kill phantomJs process. PID: " + pid, e); 
     throw e; 
    } 

    if(pid > 0) log.info("phantomJs process " + pid + " was interrupted"); 
} 

我希望这将有帮助

7

最简单的方法(不一定是正式的方式)要杀死他的进程来处理这个问题是要拍

ps -ef | grep phantomjs | awk '{print $2}' | xargs sudo kill -9 

在终端上运行会杀死所有后台以上脚本phantomjs你使用Java或Python或Ruby ... 是否已经开始他们一个快速的解决方法,直到:从bash脚本,终止所有phantomjs进程kill命令实际的错误得到解决了,imo。

+1

正是我在找什么 - 谢谢。 – 2016-11-30 10:48:57

+3

这个整个shell管道可以被'killall -s SIGKILL phantomjs'或甚至'killall phantomjs'替代(如果SIGTERM足够了) – 2017-05-24 19:30:13

相关问题