incubator-sling-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From bdelacre...@apache.org
Subject svn commit: r1074158 - in /sling/trunk/testing: ./ junit/remote/ junit/remote/src/main/java/org/apache/sling/junit/remote/testrunner/ samples/test-tools/ samples/test-tools/src/test/java/org/apache/sling/testing/samples/testtools/ samples/test-tools/sr...
Date Thu, 24 Feb 2011 14:14:27 GMT
Author: bdelacretaz
Date: Thu Feb 24 14:14:26 2011
New Revision: 1074158

URL: http://svn.apache.org/viewvc?rev=1074158&view=rev
Log:
SLING-1981 - fork the stanbol helper classes here to avoid depending on SNAPSHOTS - the http stuff might move to httpclient anyway

Added:
    sling/trunk/testing/tools/   (with props)
    sling/trunk/testing/tools/pom.xml   (with props)
    sling/trunk/testing/tools/src/
    sling/trunk/testing/tools/src/main/
    sling/trunk/testing/tools/src/main/java/
    sling/trunk/testing/tools/src/main/java/org/
    sling/trunk/testing/tools/src/main/java/org/apache/
    sling/trunk/testing/tools/src/main/java/org/apache/sling/
    sling/trunk/testing/tools/src/main/java/org/apache/sling/testing/
    sling/trunk/testing/tools/src/main/java/org/apache/sling/testing/tools/
    sling/trunk/testing/tools/src/main/java/org/apache/sling/testing/tools/http/
    sling/trunk/testing/tools/src/main/java/org/apache/sling/testing/tools/http/Request.java   (with props)
    sling/trunk/testing/tools/src/main/java/org/apache/sling/testing/tools/http/RequestBuilder.java   (with props)
    sling/trunk/testing/tools/src/main/java/org/apache/sling/testing/tools/http/RequestDocumentor.java   (with props)
    sling/trunk/testing/tools/src/main/java/org/apache/sling/testing/tools/http/RequestExecutor.java   (with props)
    sling/trunk/testing/tools/src/main/java/org/apache/sling/testing/tools/jarexec/
    sling/trunk/testing/tools/src/main/java/org/apache/sling/testing/tools/jarexec/JarExecutor.java   (with props)
    sling/trunk/testing/tools/src/main/java/org/apache/sling/testing/tools/retry/
    sling/trunk/testing/tools/src/main/java/org/apache/sling/testing/tools/retry/RetryLoop.java   (with props)
Modified:
    sling/trunk/testing/junit/remote/pom.xml
    sling/trunk/testing/junit/remote/src/main/java/org/apache/sling/junit/remote/testrunner/SlingRemoteTestRunner.java
    sling/trunk/testing/pom.xml
    sling/trunk/testing/samples/test-tools/pom.xml
    sling/trunk/testing/samples/test-tools/src/test/java/org/apache/sling/testing/samples/testtools/SlingTestBase.java
    sling/trunk/testing/samples/test-tools/src/test/java/org/apache/sling/testing/samples/testtools/serverside/FailingTestsTest.java
    sling/trunk/testing/samples/test-tools/src/test/java/org/apache/sling/testing/samples/testtools/serverside/JSONResponseTest.java
    sling/trunk/testing/samples/test-tools/src/test/java/org/apache/sling/testing/samples/testtools/serverside/ServerSideTestsBase.java

Modified: sling/trunk/testing/junit/remote/pom.xml
URL: http://svn.apache.org/viewvc/sling/trunk/testing/junit/remote/pom.xml?rev=1074158&r1=1074157&r2=1074158&view=diff
==============================================================================
--- sling/trunk/testing/junit/remote/pom.xml (original)
+++ sling/trunk/testing/junit/remote/pom.xml Thu Feb 24 14:14:26 2011
@@ -57,9 +57,9 @@
             <version>1.5.11</version>
         </dependency>
         <dependency>
-            <groupId>org.apache.stanbol</groupId>
-            <artifactId>org.apache.stanbol.commons.testing.http</artifactId>
-            <version>0.9-SNAPSHOT</version>
+            <groupId>org.apache.sling</groupId>
+            <artifactId>org.apache.sling.testing.tools</artifactId>
+            <version>0.1.1-SNAPSHOT</version>
         </dependency>
         <dependency>
             <groupId>org.apache.sling</groupId>

Modified: sling/trunk/testing/junit/remote/src/main/java/org/apache/sling/junit/remote/testrunner/SlingRemoteTestRunner.java
URL: http://svn.apache.org/viewvc/sling/trunk/testing/junit/remote/src/main/java/org/apache/sling/junit/remote/testrunner/SlingRemoteTestRunner.java?rev=1074158&r1=1074157&r2=1074158&view=diff
==============================================================================
--- sling/trunk/testing/junit/remote/src/main/java/org/apache/sling/junit/remote/testrunner/SlingRemoteTestRunner.java (original)
+++ sling/trunk/testing/junit/remote/src/main/java/org/apache/sling/junit/remote/testrunner/SlingRemoteTestRunner.java Thu Feb 24 14:14:26 2011
@@ -25,9 +25,9 @@ import org.apache.http.impl.client.Defau
 import org.apache.sling.commons.json.JSONArray;
 import org.apache.sling.commons.json.JSONObject;
 import org.apache.sling.commons.json.JSONTokener;
-import org.apache.stanbol.commons.testing.http.Request;
-import org.apache.stanbol.commons.testing.http.RequestBuilder;
-import org.apache.stanbol.commons.testing.http.RequestExecutor;
+import org.apache.sling.testing.tools.http.Request;
+import org.apache.sling.testing.tools.http.RequestBuilder;
+import org.apache.sling.testing.tools.http.RequestExecutor;
 import org.junit.internal.AssumptionViolatedException;
 import org.junit.internal.runners.model.EachTestNotifier;
 import org.junit.runner.Description;

Modified: sling/trunk/testing/pom.xml
URL: http://svn.apache.org/viewvc/sling/trunk/testing/pom.xml?rev=1074158&r1=1074157&r2=1074158&view=diff
==============================================================================
--- sling/trunk/testing/pom.xml (original)
+++ sling/trunk/testing/pom.xml Thu Feb 24 14:14:26 2011
@@ -40,6 +40,7 @@
     </scm>
 
     <modules>
+        <module>tools</module>
         <module>junit/core</module>
         <module>junit/scriptable</module>
         <module>junit/remote</module>

Modified: sling/trunk/testing/samples/test-tools/pom.xml
URL: http://svn.apache.org/viewvc/sling/trunk/testing/samples/test-tools/pom.xml?rev=1074158&r1=1074157&r2=1074158&view=diff
==============================================================================
--- sling/trunk/testing/samples/test-tools/pom.xml (original)
+++ sling/trunk/testing/samples/test-tools/pom.xml Thu Feb 24 14:14:26 2011
@@ -191,14 +191,9 @@
             <version>0.1.1-SNAPSHOT</version>
         </dependency>
         <dependency>
-            <groupId>org.apache.stanbol</groupId>
-            <artifactId>org.apache.stanbol.commons.testing.jarexec</artifactId>
-            <version>0.9-SNAPSHOT</version>
-        </dependency>
-        <dependency>
-            <groupId>org.apache.stanbol</groupId>
-            <artifactId>org.apache.stanbol.commons.testing.http</artifactId>
-            <version>0.9-SNAPSHOT</version>
+            <groupId>org.apache.sling</groupId>
+            <artifactId>org.apache.sling.testing.tools</artifactId>
+            <version>0.1.1-SNAPSHOT</version>
         </dependency>
         <dependency>
             <groupId>org.apache.sling</groupId>

Modified: sling/trunk/testing/samples/test-tools/src/test/java/org/apache/sling/testing/samples/testtools/SlingTestBase.java
URL: http://svn.apache.org/viewvc/sling/trunk/testing/samples/test-tools/src/test/java/org/apache/sling/testing/samples/testtools/SlingTestBase.java?rev=1074158&r1=1074157&r2=1074158&view=diff
==============================================================================
--- sling/trunk/testing/samples/test-tools/src/test/java/org/apache/sling/testing/samples/testtools/SlingTestBase.java (original)
+++ sling/trunk/testing/samples/test-tools/src/test/java/org/apache/sling/testing/samples/testtools/SlingTestBase.java Thu Feb 24 14:14:26 2011
@@ -27,9 +27,9 @@ import org.apache.http.entity.mime.Multi
 import org.apache.http.entity.mime.content.FileBody;
 import org.apache.http.entity.mime.content.StringBody;
 import org.apache.http.impl.client.DefaultHttpClient;
-import org.apache.stanbol.commons.testing.http.RequestBuilder;
-import org.apache.stanbol.commons.testing.http.RequestExecutor;
-import org.apache.stanbol.commons.testing.jarexec.JarExecutor;
+import org.apache.sling.testing.tools.http.RequestBuilder;
+import org.apache.sling.testing.tools.http.RequestExecutor;
+import org.apache.sling.testing.tools.jarexec.JarExecutor;
 import org.junit.Before;
 import org.junit.BeforeClass;
 import org.slf4j.Logger;

Modified: sling/trunk/testing/samples/test-tools/src/test/java/org/apache/sling/testing/samples/testtools/serverside/FailingTestsTest.java
URL: http://svn.apache.org/viewvc/sling/trunk/testing/samples/test-tools/src/test/java/org/apache/sling/testing/samples/testtools/serverside/FailingTestsTest.java?rev=1074158&r1=1074157&r2=1074158&view=diff
==============================================================================
--- sling/trunk/testing/samples/test-tools/src/test/java/org/apache/sling/testing/samples/testtools/serverside/FailingTestsTest.java (original)
+++ sling/trunk/testing/samples/test-tools/src/test/java/org/apache/sling/testing/samples/testtools/serverside/FailingTestsTest.java Thu Feb 24 14:14:26 2011
@@ -22,7 +22,7 @@ import org.apache.sling.commons.json.JSO
 import org.apache.sling.commons.json.JSONException;
 import org.apache.sling.commons.json.JSONObject;
 import org.apache.sling.commons.json.JSONTokener;
-import org.apache.stanbol.commons.testing.http.Request;
+import org.apache.sling.testing.tools.http.Request;
 import org.junit.Test;
 
 /** Verify that failures are correctly reported, using

Modified: sling/trunk/testing/samples/test-tools/src/test/java/org/apache/sling/testing/samples/testtools/serverside/JSONResponseTest.java
URL: http://svn.apache.org/viewvc/sling/trunk/testing/samples/test-tools/src/test/java/org/apache/sling/testing/samples/testtools/serverside/JSONResponseTest.java?rev=1074158&r1=1074157&r2=1074158&view=diff
==============================================================================
--- sling/trunk/testing/samples/test-tools/src/test/java/org/apache/sling/testing/samples/testtools/serverside/JSONResponseTest.java (original)
+++ sling/trunk/testing/samples/test-tools/src/test/java/org/apache/sling/testing/samples/testtools/serverside/JSONResponseTest.java Thu Feb 24 14:14:26 2011
@@ -25,8 +25,8 @@ import org.apache.sling.commons.json.JSO
 import org.apache.sling.commons.json.JSONException;
 import org.apache.sling.commons.json.JSONObject;
 import org.apache.sling.commons.json.JSONTokener;
-import org.apache.stanbol.commons.testing.http.Request;
-import org.apache.stanbol.commons.testing.http.RetryLoop;
+import org.apache.sling.testing.tools.http.Request;
+import org.apache.sling.testing.tools.retry.RetryLoop;
 import org.junit.Test;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;

Modified: sling/trunk/testing/samples/test-tools/src/test/java/org/apache/sling/testing/samples/testtools/serverside/ServerSideTestsBase.java
URL: http://svn.apache.org/viewvc/sling/trunk/testing/samples/test-tools/src/test/java/org/apache/sling/testing/samples/testtools/serverside/ServerSideTestsBase.java?rev=1074158&r1=1074157&r2=1074158&view=diff
==============================================================================
--- sling/trunk/testing/samples/test-tools/src/test/java/org/apache/sling/testing/samples/testtools/serverside/ServerSideTestsBase.java (original)
+++ sling/trunk/testing/samples/test-tools/src/test/java/org/apache/sling/testing/samples/testtools/serverside/ServerSideTestsBase.java Thu Feb 24 14:14:26 2011
@@ -17,7 +17,7 @@
 package org.apache.sling.testing.samples.testtools.serverside;
 
 import org.apache.sling.testing.samples.testtools.SlingTestBase;
-import org.apache.stanbol.commons.testing.http.RetryLoop;
+import org.apache.sling.testing.tools.retry.RetryLoop;
 import org.junit.Before;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;

Propchange: sling/trunk/testing/tools/
------------------------------------------------------------------------------
--- svn:ignore (added)
+++ svn:ignore Thu Feb 24 14:14:26 2011
@@ -0,0 +1,14 @@
+target
+bin
+*.iml
+*.ipr
+*.iws
+.settings
+.project
+.classpath
+.externalToolBuilders
+maven-eclipse.xml
+
+
+
+

Added: sling/trunk/testing/tools/pom.xml
URL: http://svn.apache.org/viewvc/sling/trunk/testing/tools/pom.xml?rev=1074158&view=auto
==============================================================================
--- sling/trunk/testing/tools/pom.xml (added)
+++ sling/trunk/testing/tools/pom.xml Thu Feb 24 14:14:26 2011
@@ -0,0 +1,77 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+    Licensed to the Apache Software Foundation (ASF) under one
+    or more contributor license agreements.  See the NOTICE file
+    distributed with this work for additional information
+    regarding copyright ownership.  The ASF licenses this file
+    to you under the Apache License, Version 2.0 (the
+    "License"); you may not use this file except in compliance
+    with the License.  You may obtain a copy of the License at
+    
+    http://www.apache.org/licenses/LICENSE-2.0
+    
+    Unless required by applicable law or agreed to in writing,
+    software distributed under the License is distributed on an
+    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+    KIND, either express or implied.  See the License for the
+    specific language governing permissions and limitations
+    under the License.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>org.apache.sling</groupId>
+        <artifactId>sling</artifactId>
+        <version>10</version>
+    </parent>
+
+    <artifactId>org.apache.sling.testing.tools</artifactId>
+    <version>0.1.1-SNAPSHOT</version>
+    <packaging>jar</packaging>
+
+    <name>Apache Sling Test Tools</name>
+    <description>
+        Sling testing utilities.
+    </description>
+    
+    <scm>
+        <connection>scm:svn:http://svn.apache.org/repos/asf/sling/trunk/testing/tools</connection>
+        <developerConnection> scm:svn:https://svn.apache.org/repos/asf/sling/trunk/testing/tools</developerConnection>
+        <url>http://svn.apache.org/viewvc/sling/trunk/testing/tools</url>
+    </scm>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.commons</groupId>
+            <artifactId>commons-exec</artifactId>
+            <version>1.1</version>
+        </dependency>
+        <dependency>
+            <groupId>commons-io</groupId>
+            <artifactId>commons-io</artifactId>
+            <version>2.0.1</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.httpcomponents</groupId>
+            <artifactId>httpcore</artifactId>
+            <version>4.0.1</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.httpcomponents</groupId>
+            <artifactId>httpclient</artifactId>
+            <version>4.0.1</version>
+        </dependency>
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-api</artifactId>
+            <version>1.5.11</version>
+        </dependency>
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+            <version>4.8.2</version>
+            <scope>compile</scope>
+        </dependency>
+    </dependencies>
+</project>
\ No newline at end of file

Propchange: sling/trunk/testing/tools/pom.xml
------------------------------------------------------------------------------
    svn:eol-style = native

Added: sling/trunk/testing/tools/src/main/java/org/apache/sling/testing/tools/http/Request.java
URL: http://svn.apache.org/viewvc/sling/trunk/testing/tools/src/main/java/org/apache/sling/testing/tools/http/Request.java?rev=1074158&view=auto
==============================================================================
--- sling/trunk/testing/tools/src/main/java/org/apache/sling/testing/tools/http/Request.java (added)
+++ sling/trunk/testing/tools/src/main/java/org/apache/sling/testing/tools/http/Request.java Thu Feb 24 14:14:26 2011
@@ -0,0 +1,89 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with this
+ * work for additional information regarding copyright ownership. The ASF
+ * licenses this file to You under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package org.apache.sling.testing.tools.http;
+
+import java.io.UnsupportedEncodingException;
+
+import org.apache.http.HttpEntity;
+import org.apache.http.client.methods.HttpEntityEnclosingRequestBase;
+import org.apache.http.client.methods.HttpUriRequest;
+import org.apache.http.entity.StringEntity;
+
+/** Request class with convenience with... methods to 
+ *  add headers, parameters etc.
+ */
+public class Request {
+    private final HttpUriRequest request;
+    private String username;
+    private String password;
+    private boolean redirects = true;
+    
+    Request(HttpUriRequest r) {
+        request = r;
+    }
+    
+    public HttpUriRequest getRequest() {
+        return request;
+    }
+    
+    public Request withHeader(String name, String value) {
+        request.addHeader(name, value);
+        return this;
+    }
+    
+    public Request withCredentials(String username, String password) {
+        this.username = username;
+        this.password = password;
+        return this;
+    }
+
+    public Request withRedirects(boolean followRedirectsAutomatically) {
+        redirects = followRedirectsAutomatically;
+        return this;
+    }
+    
+    private HttpEntityEnclosingRequestBase getHttpEntityEnclosingRequestBase() {
+        if(request instanceof HttpEntityEnclosingRequestBase) {
+            return (HttpEntityEnclosingRequestBase)request;
+        } else {
+            throw new IllegalStateException(
+                    "Request is not an HttpEntityEnclosingRequestBase: "  
+                + request.getClass().getName());
+        }
+    }
+
+    public Request withContent(String content) throws UnsupportedEncodingException {
+        return withEntity(new StringEntity(content, "UTF-8"));
+    }
+    
+    public Request withEntity(HttpEntity e) throws UnsupportedEncodingException {
+        getHttpEntityEnclosingRequestBase().setEntity(e);
+        return this;
+    }
+    
+    public String getUsername() {
+        return username;
+    }
+    
+    public String getPassword() {
+        return password;
+    }
+    
+    public boolean getRedirects() {
+        return redirects;
+    }
+}

Propchange: sling/trunk/testing/tools/src/main/java/org/apache/sling/testing/tools/http/Request.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: sling/trunk/testing/tools/src/main/java/org/apache/sling/testing/tools/http/Request.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision Rev URL

Added: sling/trunk/testing/tools/src/main/java/org/apache/sling/testing/tools/http/RequestBuilder.java
URL: http://svn.apache.org/viewvc/sling/trunk/testing/tools/src/main/java/org/apache/sling/testing/tools/http/RequestBuilder.java?rev=1074158&view=auto
==============================================================================
--- sling/trunk/testing/tools/src/main/java/org/apache/sling/testing/tools/http/RequestBuilder.java (added)
+++ sling/trunk/testing/tools/src/main/java/org/apache/sling/testing/tools/http/RequestBuilder.java Thu Feb 24 14:14:26 2011
@@ -0,0 +1,90 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with this
+ * work for additional information regarding copyright ownership. The ASF
+ * licenses this file to You under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package org.apache.sling.testing.tools.http;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.http.NameValuePair;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.client.methods.HttpRequestBase;
+import org.apache.http.client.utils.URLEncodedUtils;
+import org.apache.http.message.BasicNameValuePair;
+
+/** Convenience builder for Request objects */
+public class RequestBuilder {
+    private final String baseUrl;
+    
+    public RequestBuilder(String baseUrl) {
+        this.baseUrl = baseUrl;
+    }
+    
+    /** Build a GET request to specified path with optional query
+     *  parameters. See {@link #buildUrl(String, String...)} for
+     *  queryParameters semantics.
+     */
+    public Request buildGetRequest(String path, String...queryParameters) {
+        return new Request(new HttpGet(buildUrl(path, queryParameters)));
+    }
+    
+    /** Build a POST request to specified path with optional query
+     *  parameters. See {@link #buildUrl(String, String...)} for
+     *  queryParameters semantics.
+     */
+    public Request buildPostRequest(String path) {
+        return new Request(new HttpPost(buildUrl(path)));
+    }
+    
+    /** Wrap supplied HTTP request */
+    public Request buildOtherRequest(HttpRequestBase r) {
+        return new Request(r);
+    }
+    
+    /** Build an URL from our base path, supplied path and optional
+     *  query parameters.
+     *  @param queryParameters an even number of Strings, each pair
+     *  of values represents the key and value of a query parameter.
+     *  Keys and values are encoded by this method.
+     */
+    public String buildUrl(String path, String...queryParameters) {
+        final StringBuilder sb = new StringBuilder();
+        
+        if(queryParameters == null || queryParameters.length == 0) {
+            sb.append(baseUrl);
+            sb.append(path);
+            
+        } else if(queryParameters.length % 2 != 0) {
+            throw new IllegalArgumentException(
+                    "Invalid number of queryParameters arguments ("
+                    + queryParameters.length
+                    + "), must be even"
+                    );
+        } else {
+            final List<NameValuePair> p = new ArrayList<NameValuePair>();
+            for(int i=0 ; i < queryParameters.length; i+=2) {
+                p.add(new BasicNameValuePair(queryParameters[i], queryParameters[i+1]));
+            }
+            sb.append(baseUrl);
+            sb.append(path);
+            sb.append("?");
+            sb.append(URLEncodedUtils.format(p, "UTF-8"));
+        }
+        
+        return sb.toString();
+    }
+}

Propchange: sling/trunk/testing/tools/src/main/java/org/apache/sling/testing/tools/http/RequestBuilder.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: sling/trunk/testing/tools/src/main/java/org/apache/sling/testing/tools/http/RequestBuilder.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision Rev URL

Added: sling/trunk/testing/tools/src/main/java/org/apache/sling/testing/tools/http/RequestDocumentor.java
URL: http://svn.apache.org/viewvc/sling/trunk/testing/tools/src/main/java/org/apache/sling/testing/tools/http/RequestDocumentor.java?rev=1074158&view=auto
==============================================================================
--- sling/trunk/testing/tools/src/main/java/org/apache/sling/testing/tools/http/RequestDocumentor.java (added)
+++ sling/trunk/testing/tools/src/main/java/org/apache/sling/testing/tools/http/RequestDocumentor.java Thu Feb 24 14:14:26 2011
@@ -0,0 +1,133 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with this
+ * work for additional information regarding copyright ownership. The ASF
+ * licenses this file to You under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package org.apache.sling.testing.tools.http;
+
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.PrintWriter;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.http.Header;
+import org.apache.http.client.methods.HttpEntityEnclosingRequestBase;
+
+
+/** Generate RESTful API documentation based on actual requests
+ *  executed during integration tests, enhanced with user-supplied
+ *  bits of documentation. 
+ */
+public class RequestDocumentor {
+    public static final String OUTPUT_BASE = "./target/" + RequestDocumentor.class.getSimpleName();
+    private final String name;
+    
+    public RequestDocumentor(String name) {
+        this.name = name;
+    }
+    
+    public String toString() {
+        return getClass().getSimpleName() + " (" + name + ")";
+    }
+    
+    void generateDocumentation(RequestExecutor executor, String [] metadata) throws IOException {
+        final File f = getOutputFile();
+        final File dir = f.getParentFile();
+        dir.mkdirs();
+        if(!dir.isDirectory()) {
+            throw new IOException("Failed to create output folder " + dir.getAbsolutePath());
+        }
+        final PrintWriter pw = new PrintWriter(new FileWriter(f, true));
+        try {
+            System.out.println("Appending documentation of " + executor + " to " + f.getAbsolutePath());
+            documentRequest(pw, executor, metadata);
+        } finally {
+            pw.flush();
+            pw.close();
+        }
+    }
+    
+    protected File getOutputFile() {
+        return new File(OUTPUT_BASE + "/" + name + ".txt");
+    }
+    
+    protected void documentRequest(PrintWriter pw, RequestExecutor executor, String [] metadataArray) throws IOException {
+        // Convert metadata to more convenient Map 
+        final Map<String, String> m = new HashMap<String, String>();
+        if(metadataArray.length % 2 != 0) {
+            throw new IllegalArgumentException("Metadata array must be of even size, got " + metadataArray.length);
+        }
+        for(int i=0 ; i < metadataArray.length; i += 2) {
+            m.put(metadataArray[i], metadataArray[i+1]);
+        }
+        
+        // TODO use velocity or other templates? Just a rough prototype for now
+        // Also need to filter overly long input/output, binary etc.
+        pw.println();
+        pw.println("====================================================================================");
+        pw.print("=== ");
+        pw.print(m.get("title"));
+        pw.println(" ===");
+        pw.println(m.get("description"));
+
+        pw.print("\n=== ");
+        pw.print("REQUEST");
+        pw.println(" ===");
+        
+        pw.print("Method: ");
+        pw.println(executor.getRequest().getMethod());
+        pw.print("URI: ");
+        pw.println(executor.getRequest().getURI());
+        
+        final Header [] allHeaders = executor.getRequest().getAllHeaders();
+        if(allHeaders != null && allHeaders.length > 0) {
+            pw.println("Headers:");
+            for(Header h : allHeaders) {
+                pw.print(h.getName());
+                pw.print(":");
+                pw.println(h.getValue());
+            }
+        }
+        
+        if(executor.getRequest() instanceof HttpEntityEnclosingRequestBase) {
+            final HttpEntityEnclosingRequestBase heb = (HttpEntityEnclosingRequestBase)executor.getRequest();
+            if(heb.getEntity() != null) {
+                pw.print("Content-Type:");
+                pw.println(heb.getEntity().getContentType().getValue());
+                pw.println("Content:");
+                final InputStream is = heb.getEntity().getContent();
+                final byte[] buffer = new byte[16384];
+                int count = 0;
+                while( (count = is.read(buffer, 0, buffer.length)) > 0) {
+                    // TODO encoding??
+                    pw.write(new String(buffer, 0, count));
+                }
+                pw.println();
+            }
+        }
+        
+        pw.print("\n=== ");
+        pw.print("RESPONSE");
+        pw.println(" ===");
+        pw.print("Content-Type:");
+        pw.println(executor.getResponse().getEntity().getContentType().getValue());
+        pw.println("Content:");
+        pw.println(executor.getContent());
+        
+        pw.println("====================================================================================");
+    }
+}

Propchange: sling/trunk/testing/tools/src/main/java/org/apache/sling/testing/tools/http/RequestDocumentor.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: sling/trunk/testing/tools/src/main/java/org/apache/sling/testing/tools/http/RequestDocumentor.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision Rev URL

Added: sling/trunk/testing/tools/src/main/java/org/apache/sling/testing/tools/http/RequestExecutor.java
URL: http://svn.apache.org/viewvc/sling/trunk/testing/tools/src/main/java/org/apache/sling/testing/tools/http/RequestExecutor.java?rev=1074158&view=auto
==============================================================================
--- sling/trunk/testing/tools/src/main/java/org/apache/sling/testing/tools/http/RequestExecutor.java (added)
+++ sling/trunk/testing/tools/src/main/java/org/apache/sling/testing/tools/http/RequestExecutor.java Thu Feb 24 14:14:26 2011
@@ -0,0 +1,222 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with this
+ * work for additional information regarding copyright ownership. The ASF
+ * licenses this file to You under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package org.apache.sling.testing.tools.http;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.fail;
+
+import java.io.IOException;
+import java.io.StringReader;
+import java.util.regex.Pattern;
+
+import org.apache.commons.io.LineIterator;
+import org.apache.http.HttpEntity;
+import org.apache.http.HttpException;
+import org.apache.http.HttpHost;
+import org.apache.http.HttpRequest;
+import org.apache.http.HttpRequestInterceptor;
+import org.apache.http.HttpResponse;
+import org.apache.http.ParseException;
+import org.apache.http.auth.AuthScope;
+import org.apache.http.auth.AuthState;
+import org.apache.http.auth.Credentials;
+import org.apache.http.auth.UsernamePasswordCredentials;
+import org.apache.http.client.ClientProtocolException;
+import org.apache.http.client.CredentialsProvider;
+import org.apache.http.client.methods.HttpUriRequest;
+import org.apache.http.client.params.ClientPNames;
+import org.apache.http.client.protocol.ClientContext;
+import org.apache.http.impl.auth.BasicScheme;
+import org.apache.http.impl.client.DefaultHttpClient;
+import org.apache.http.protocol.ExecutionContext;
+import org.apache.http.protocol.HttpContext;
+import org.apache.http.util.EntityUtils;
+
+/** Executes a Request and provides convenience methods
+ *  to validate the results.
+ */
+public class RequestExecutor {
+    private final DefaultHttpClient httpClient;
+    private HttpUriRequest request; 
+    private HttpResponse response;
+    private HttpEntity entity;
+    private String content;
+    
+    /**
+     * HttpRequestInterceptor for preemptive authentication, based on httpclient
+     * 4.0 example
+     */
+    private static class PreemptiveAuthInterceptor implements
+            HttpRequestInterceptor {
+
+        public void process(HttpRequest request, HttpContext context)
+                throws HttpException, IOException {
+
+            AuthState authState = 
+                (AuthState) context.getAttribute(ClientContext.TARGET_AUTH_STATE);
+            CredentialsProvider credsProvider = 
+                (CredentialsProvider) context.getAttribute(ClientContext.CREDS_PROVIDER);
+            HttpHost targetHost = 
+                (HttpHost) context.getAttribute(ExecutionContext.HTTP_TARGET_HOST);
+
+            // If not auth scheme has been initialized yet
+            if (authState.getAuthScheme() == null) {
+                AuthScope authScope = 
+                    new AuthScope(targetHost.getHostName(), targetHost.getPort());
+
+                // Obtain credentials matching the target host
+                Credentials creds = credsProvider.getCredentials(authScope);
+
+                // If found, generate BasicScheme preemptively
+                if(creds != null) {
+                    authState.setAuthScheme(new BasicScheme());
+                    authState.setCredentials(creds);
+                }
+            }
+        }
+    }
+    
+    public RequestExecutor(DefaultHttpClient client) {
+        httpClient = client;
+    }
+    
+    public String toString() {
+        if(request == null) {
+            return "Request";
+        }
+        return request.getMethod() + " request to " + request.getURI();
+    }
+    
+    public RequestExecutor execute(Request r) throws ClientProtocolException, IOException {
+        clear();
+        request = r.getRequest();
+        
+        // Optionally setup for basic authentication
+        if(r.getUsername() != null) {
+            httpClient.getCredentialsProvider().setCredentials(
+                    AuthScope.ANY,
+                    new UsernamePasswordCredentials(r.getUsername(), r.getPassword()));
+
+            // And add request interceptor to have preemptive authentication
+            httpClient.addRequestInterceptor(new PreemptiveAuthInterceptor(), 0);
+        } else {
+            httpClient.getCredentialsProvider().setCredentials(AuthScope.ANY, null);
+            httpClient.removeRequestInterceptorByClass(PreemptiveAuthInterceptor.class);
+        }
+        
+        // Setup redirects
+        httpClient.getParams().setBooleanParameter(ClientPNames.HANDLE_REDIRECTS, r.getRedirects());
+        
+        // Execute request
+        response = httpClient.execute(request);
+        entity = response.getEntity();
+        if(entity != null) {
+            // We fully read the content every time, not super efficient but
+            // how can we read it on demand while avoiding a (boring) cleanup() 
+            // method on this class?
+            content = EntityUtils.toString(entity);
+            entity.consumeContent();
+        }
+        return this;
+    }
+    
+    protected void clear() {
+        request = null;
+        entity = null;
+        response = null;
+        content = null;
+    }
+
+    /** Verify that response matches supplied status */
+    public RequestExecutor assertStatus(int expected) {
+        assertNotNull(this.toString(), response);
+        assertEquals(this + ": expecting status " + expected, expected, response.getStatusLine().getStatusCode());
+        return this;
+    }
+    
+    /** Verify that response matches supplied content type */
+    public RequestExecutor assertContentType(String expected) {
+        assertNotNull(this.toString(), response);
+        if(entity == null) {
+            fail(this + ": no entity in response, cannot check content type");
+        }
+        
+        // Remove whatever follows semicolon in content-type
+        String contentType = entity.getContentType().getValue();
+        if(contentType != null) {
+            contentType = contentType.split(";")[0].trim();
+        }
+        
+        // And check for match
+        assertEquals(this + ": expecting content type " + expected, expected, contentType);
+        return this;
+    }
+
+    /** For each supplied regexp, fail unless content contains at 
+     *  least one line that matches.
+     *  Regexps are automatically prefixed/suffixed with .* so as
+     *  to have match partial lines.
+     */
+    public RequestExecutor assertContentRegexp(String... regexp) {
+        assertNotNull(this.toString(), response);
+        nextPattern:
+        for(String expr : regexp) {
+            final Pattern p = Pattern.compile(".*" + expr + ".*");
+            final LineIterator it = new LineIterator(new StringReader(content));
+            while(it.hasNext()) {
+                final String line = it.nextLine(); 
+                if(p.matcher(line).matches()) {
+                    continue nextPattern;
+                }
+            }
+            fail(this + ": no match for regexp '" + expr + "', content=\n" + content);
+        }
+        return this;
+    }
+
+    /** For each supplied string, fail unless content contains it */
+    public RequestExecutor assertContentContains(String... expected) throws ParseException, IOException {
+        assertNotNull(this.toString(), response);
+        for(String exp : expected) {
+            if(!content.contains(exp)) {
+                fail(this + ": content does not contain '" + exp + "', content=\n" + content);
+            }
+        }
+        return this;
+    }
+    
+    public void generateDocumentation(RequestDocumentor documentor, String...metadata) throws IOException {
+        documentor.generateDocumentation(this, metadata);
+    }
+
+    HttpUriRequest getRequest() {
+        return request;
+    }
+
+    HttpResponse getResponse() {
+        return response;
+    }
+
+    HttpEntity getEntity() {
+        return entity;
+    }
+
+    public String getContent() {
+        return content;
+    }
+}

Propchange: sling/trunk/testing/tools/src/main/java/org/apache/sling/testing/tools/http/RequestExecutor.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: sling/trunk/testing/tools/src/main/java/org/apache/sling/testing/tools/http/RequestExecutor.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision Rev URL

Added: sling/trunk/testing/tools/src/main/java/org/apache/sling/testing/tools/jarexec/JarExecutor.java
URL: http://svn.apache.org/viewvc/sling/trunk/testing/tools/src/main/java/org/apache/sling/testing/tools/jarexec/JarExecutor.java?rev=1074158&view=auto
==============================================================================
--- sling/trunk/testing/tools/src/main/java/org/apache/sling/testing/tools/jarexec/JarExecutor.java (added)
+++ sling/trunk/testing/tools/src/main/java/org/apache/sling/testing/tools/jarexec/JarExecutor.java Thu Feb 24 14:14:26 2011
@@ -0,0 +1,156 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with this
+ * work for additional information regarding copyright ownership. The ASF
+ * licenses this file to You under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package org.apache.sling.testing.tools.jarexec;
+
+import java.io.File;
+import java.util.Arrays;
+import java.util.Properties;
+import java.util.regex.Pattern;
+
+import org.apache.commons.exec.CommandLine;
+import org.apache.commons.exec.DefaultExecutor;
+import org.apache.commons.exec.ExecuteException;
+import org.apache.commons.exec.ExecuteResultHandler;
+import org.apache.commons.exec.Executor;
+import org.apache.commons.exec.PumpStreamHandler;
+import org.apache.commons.exec.ShutdownHookProcessDestroyer;
+import org.apache.commons.exec.util.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/** Start a runnable jar by forking a JVM process,
+ *  and terminate the process when this VM exits.
+ */
+public class JarExecutor {
+    private static JarExecutor instance;
+    private final File jarToExecute;
+    private final String javaExecutable;
+    private final int serverPort;
+    
+    private final Logger log = LoggerFactory.getLogger(getClass());
+
+    public static final int DEFAULT_PORT = 8765;
+    public static final String DEFAULT_JAR_FOLDER = "target/dependency";
+    public static final String DEFAULT_JAR_NAME_REGEXP = "org.apache.sling.*jar$";
+    public static final String PROP_PREFIX = "jar.executor.";
+    public static final String PROP_SERVER_PORT = PROP_PREFIX + "server.port";
+    public static final String PROP_JAR_FOLDER = PROP_PREFIX + "jar.folder";
+    public static final String PROP_JAR_NAME_REGEXP = PROP_PREFIX + "jar.name.regexp";
+    
+    @SuppressWarnings("serial")
+    public static class ExecutorException extends Exception {
+        ExecutorException(String reason) {
+            super(reason);
+        }
+        ExecutorException(String reason, Throwable cause) {
+            super(reason, cause);
+        }
+    }
+    
+    public int getServerPort() {
+        return serverPort;
+    }
+
+    public static JarExecutor getInstance(Properties config) throws ExecutorException {
+        if(instance == null) {
+            synchronized (JarExecutor.class) {
+                if(instance == null) {
+                    instance = new JarExecutor(config);
+                }
+            }
+        }
+        return instance;
+    }
+    
+    /** Build a JarExecutor, locate the jar to run, etc */
+    private JarExecutor(Properties config) throws ExecutorException {
+        final boolean isWindows = System.getProperty("os.name").toLowerCase().contains("windows");
+
+        String portStr = config.getProperty(PROP_SERVER_PORT);
+        serverPort = portStr == null ? DEFAULT_PORT : Integer.valueOf(portStr);
+
+        javaExecutable = isWindows ? "java.exe" : "java";
+        
+        String jarFolderPath = config.getProperty(PROP_JAR_FOLDER);
+        jarFolderPath = jarFolderPath == null ? DEFAULT_JAR_FOLDER : jarFolderPath;
+        final File jarFolder = new File(jarFolderPath);
+        
+        String jarNameRegexp = config.getProperty(PROP_JAR_NAME_REGEXP);
+        jarNameRegexp = jarNameRegexp == null ? DEFAULT_JAR_NAME_REGEXP : jarNameRegexp;
+        final Pattern jarPattern = Pattern.compile(jarNameRegexp);
+
+        // Find executable jar
+        final String [] candidates = jarFolder.list();
+        if(candidates == null) {
+            throw new ExecutorException(
+                    "No files found in jar folder specified by " 
+                    + PROP_JAR_FOLDER + " property: " + jarFolder.getAbsolutePath());
+        }
+        File f = null;
+        if(candidates != null) {
+            for(String filename : candidates) {
+                if(jarPattern.matcher(filename).matches()) {
+                    f = new File(jarFolder, filename);
+                    break;
+                }
+            }
+        }
+
+        if(f == null) {
+            throw new ExecutorException("Executable jar matching '" + jarPattern
+                    + "' not found in " + jarFolder.getAbsolutePath()
+                    + ", candidates are " + Arrays.asList(candidates));
+        }
+        jarToExecute = f;
+    }
+
+    /** Start the jar if not done yet, and setup runtime hook
+     *  to stop it.
+     */
+    public void start() throws Exception {
+        final ExecuteResultHandler h = new ExecuteResultHandler() {
+            @Override
+            public void onProcessFailed(ExecuteException ex) {
+                log.error("Process execution failed:" + ex, ex);
+            }
+
+            @Override
+            public void onProcessComplete(int result) {
+                log.info("Process execution complete, exit code=" + result);
+            }
+        };
+
+        final String vmOptions = System.getProperty("jar.executor.vm.options");
+        final Executor e = new DefaultExecutor();
+        final CommandLine cl = new CommandLine(javaExecutable);
+        if (vmOptions != null && vmOptions.length() > 0) {
+            // TODO: this will fail if one of the vm options as a quoted value with a space in it, but this is
+            // not the case for common usage patterns
+            for (String option : StringUtils.split(vmOptions, " ")) {
+                cl.addArgument(option);
+            }
+        }
+        cl.addArgument("-jar");
+        cl.addArgument(jarToExecute.getAbsolutePath());
+        cl.addArgument("-p");
+        cl.addArgument(String.valueOf(serverPort));
+        log.info("Executing " + cl);
+        e.setStreamHandler(new PumpStreamHandler());
+        e.setProcessDestroyer(new ShutdownHookProcessDestroyer());
+        e.execute(cl, h);
+    }
+}
\ No newline at end of file

Propchange: sling/trunk/testing/tools/src/main/java/org/apache/sling/testing/tools/jarexec/JarExecutor.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: sling/trunk/testing/tools/src/main/java/org/apache/sling/testing/tools/jarexec/JarExecutor.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision Rev URL

Added: sling/trunk/testing/tools/src/main/java/org/apache/sling/testing/tools/retry/RetryLoop.java
URL: http://svn.apache.org/viewvc/sling/trunk/testing/tools/src/main/java/org/apache/sling/testing/tools/retry/RetryLoop.java?rev=1074158&view=auto
==============================================================================
--- sling/trunk/testing/tools/src/main/java/org/apache/sling/testing/tools/retry/RetryLoop.java (added)
+++ sling/trunk/testing/tools/src/main/java/org/apache/sling/testing/tools/retry/RetryLoop.java Thu Feb 24 14:14:26 2011
@@ -0,0 +1,80 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with this
+ * work for additional information regarding copyright ownership. The ASF
+ * licenses this file to You under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package org.apache.sling.testing.tools.retry;
+
+import static org.junit.Assert.fail;
+
+/** Convenience class for retrying tests
+ *  until timeout or success.
+ */
+public class RetryLoop {
+    
+    private final long timeout;
+    
+    /** Interface for conditions to check, isTrue will be called
+     *  repeatedly until success or timeout */
+    static public interface Condition {
+        /** Used in failure messages to describe what was expected */
+        String getDescription();
+        
+        /** If true we stop retrying. The RetryLoop retries on AssertionError, 
+         *  so if tests fail in this method they are not reported as 
+         *  failures but retried.
+         */
+        boolean isTrue() throws Exception;
+    }
+    
+    /** Retry Condition c until it returns true or timeout. See {@link Condition}
+     *  for isTrue semantics.
+     */
+    public RetryLoop(Condition c, int timeoutSeconds, int intervalBetweenTriesMsec) {
+        timeout = System.currentTimeMillis() + timeoutSeconds * 1000L;
+        while(System.currentTimeMillis() < timeout) {
+            try {
+                if(c.isTrue()) {
+                    return;
+                }
+            } catch(AssertionError ae) {
+                // Retry JUnit tests failing in the condition as well
+                reportException(ae);
+            } catch(Exception e) {
+                reportException(e);
+            }
+            
+            try {
+                Thread.sleep(intervalBetweenTriesMsec);
+            } catch(InterruptedException ignore) {
+            }
+        }
+    
+        onTimeout();
+        fail("RetryLoop failed, condition is false after " + timeoutSeconds + " seconds: " 
+                + c.getDescription());
+    }
+
+    /** Can be overridden to report Exceptions that happen in the retry loop */
+    protected void reportException(Throwable t) {
+    }
+    
+    /** Called if the loop times out without success, just before failing */
+    protected void onTimeout() {
+    }
+    
+    protected long getRemainingTimeSeconds() {
+        return Math.max(0L, (timeout - System.currentTimeMillis()) / 1000L);
+    }
+}
\ No newline at end of file

Propchange: sling/trunk/testing/tools/src/main/java/org/apache/sling/testing/tools/retry/RetryLoop.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: sling/trunk/testing/tools/src/main/java/org/apache/sling/testing/tools/retry/RetryLoop.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision Rev URL



Mime
View raw message