【问题标题】:How can I get Ant to load and check a URL resource in a 'waitfor' task?如何让 Ant 在“等待”任务中加载和检查 URL 资源?
【发布时间】:2010-11-12 04:21:55
【问题描述】:

我正在开发一个用于运行测试的 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 -->

【问题讨论】:

    标签: web-applications ant


    【解决方案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;
           }
        }
    }
    

    【讨论】:

    • 我正在使用 ant 1.8.2 并出现错误:使用类加载器 AntClassLoader[] 找不到 typedef 类 HttpContains
    【解决方案2】:

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

    要使用它,您需要将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 目标获取 URL 并查找匹配项,如果找到,则设置属性 theurl.matchesscriptcondition 执行嵌入在waitfor 中的目标,直到成功或超时。

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-01-09
      • 1970-01-01
      • 2023-04-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-07-10
      • 1970-01-01
      相关资源
      最近更新 更多