如何在“waitfor”任务中加载Ant并检查URL资源?

时间:2010-01-29 07:26:17

标签: web-applications ant

我正在研究运行测试的Ant目标,我需要在测试开始之前启动并运行应用服务器。我正在使用waitFor任务来ping一个URL,直到它得到响应。这是有效的,除了我不仅需要确保URL只是可访问,还要检查特定的状态字符串是否存在。第二个要求本身很简单,有gettelnet任务,后跟子字符串搜索。但是'waitfor'任务不接受除标准Ant条件之外的任何嵌套元素,或者它们可以包装的东西(返回布尔值的东西)。我尝试在运行带有resourceconatins条件的'waitfor'任务之前将URL作为资源加载,但是缓存响应,并且不从服务器刷新。

有没有办法强制在每个循环上加载URL?或者其他一些方法来实现这个目标?

这是我想用伪代码实现的目标:

<waitfor>
    <and>
        <!-- make sure the URL is accessible at all -->
        <http url="theurl.jsp"/>

        <!-- load the URL as a resource and make sure it contains a substring -->
        <!-- moving the "url" task before the waitfor works if all conditions are met the first time through, but does not refresh the URL if it has to loop over again. having it inside like this, fails because waitfor/and don't support nexted "url" tasks -->
        <url id="url.resource" url="url.jsp"/>
        <resourcecontains refid="url.resource" substring="status"/>
    </and>
    <!-- else, keep on trying until timeout -->
</waitfor>
<!-- continue on to the tests to be run -->

2 个答案:

答案 0 :(得分:1)

您可以使用scriptconditionwaitfor元素调用的目标来实现此目的。这是一个例子。

要使用它,您需要将theurlcontent.matches属性设置为相关资源,并将字符串分别设置为匹配。根据需要调整“maxwait”设置。

属性theurl.fail在超时时设置。

<target name="lr">
    <local name="local.data" />
    <loadresource property="local.data">
        <url url="${theurl}" />
    </loadresource>
    <condition property="theurl.matches">
       <matches pattern="${content.matches}" string="${local.data}"/>
    </condition>
</target>

<waitfor maxwait="10" maxwaitunit="second" timeoutproperty="theurl.fail">
    <scriptcondition language="javascript" value="false">
    <![CDATA[
        project.getTargets().get( "lr" ).execute( );
        if ( project.getProperty( "theurl.matches" ) )
            self.setValue( true );
    ]]>
    </scriptcondition>
</waitfor>

这利用了v1.8中新增的Ant local任务。如果找到属性lr,则theurl.matches目标会提取该网址并查找匹配项。 scriptcondition执行嵌入waitfor内的目标,直到成功或超时。

我针对US Naval Observatory Master Clock Time和各种短时间字符串对此进行了测试,似乎效果很好。

答案 1 :(得分:1)

用法:

   <typedef
      name="httpcontains"
      classname="HttpContains"
   />

  <waitfor maxwait="10" maxwaitunit="minute" checkevery="500">
    <httpcontains contains="Running" url="http://myurl"/>
  </waitfor>

以下代码允许:

import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.ProjectComponent;
import org.apache.tools.ant.taskdefs.condition.Condition;

/**
 * Condition to wait for a HTTP request to succeed. Its attribute(s) are:
 *   url - the URL of the request.
 *   errorsBeginAt - number at which errors begin at; default=400.
 * @since Ant 1.5
 */
public class HttpContains extends ProjectComponent implements Condition {
    private String spec = null;
    private String contains = null;
    /**
     * Set the url attribute
     *
     * @param url the url of the request
     */
    public void setUrl(String url) {
        spec = url;
    }

    public void setContains(String s){
       contains = s;
    }

    private int errorsBeginAt = 400;

    /**
     * Set the errorsBeginAt attribute
     *
     * @param errorsBeginAt number at which errors begin at, default is
     *                      400
     */
    public void setErrorsBeginAt(int errorsBeginAt) {
        this.errorsBeginAt = errorsBeginAt;
    }

    /**
     * @return true if the HTTP request succeeds
     * @exception BuildException if an error occurs
     */
    public boolean eval() throws BuildException {
        if (spec == null) {
            throw new BuildException("No url specified in http condition");
        }
        log("Checking for " + spec, Project.MSG_VERBOSE);
        try {
            URL url = new URL(spec);
            try {
                URLConnection conn = url.openConnection();
                if (conn instanceof HttpURLConnection) {
                    HttpURLConnection http = (HttpURLConnection) conn;
                    int code = http.getResponseCode();
                    log("Result code for " + spec + " was " + code,
                        Project.MSG_VERBOSE);
                    if (code > 0 && code < errorsBeginAt) 
                    {
                       if ( evalContents(url) )
                          return true;
                       else
                          return false;

                    } else {
                        return false;
                    }
                }
            } catch (java.io.IOException e) {
                return false;
            }
        } catch (MalformedURLException e) {
            throw new BuildException("Badly formed URL: " + spec, e);
        }
        return true;
    }

    public boolean evalContents(URL mUrl )
    {
       try
       {

          String contents;

          StringBuffer buffer = new StringBuffer();
          byte[] buf = new byte[1024];
          int amount = 0;
          InputStream input = mUrl.openStream();

          while ((amount = input.read(buf)) > 0) 
          {   
             buffer.append(new String(buf, 0, amount));
          }
          input.close();
          contents = buffer.toString();

          log("Result code for " + contents,
                Project.MSG_VERBOSE);

          if ( contents.indexOf(contains) > -1 )
          {

             log("Result code for " + contents.indexOf(contains),
                   Project.MSG_VERBOSE);
             return true;

          }






          return false;
       }
       catch ( Exception e )
       {
          e.printStackTrace();
          log("Result code for " + e.toString(),
                Project.MSG_VERBOSE);

          return false;
       }
    }
}