You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by ro...@apache.org on 2017/11/07 10:17:21 UTC

[sling-org-apache-sling-testing-clients] annotated tag org.apache.sling.testing.clients-1.1.0 created (now 1154fdf)

This is an automated email from the ASF dual-hosted git repository.

rombert pushed a change to annotated tag org.apache.sling.testing.clients-1.1.0
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-testing-clients.git.


      at 1154fdf  (tag)
 tagging 0bc914243a02816ca07bb714b0181d4eaa20c02f (commit)
      by Karl Pauls
      on Fri Jun 2 21:22:00 2017 +0000

- Log -----------------------------------------------------------------
org.apache.sling.testing.clients-1.1.0
-----------------------------------------------------------------------

This annotated tag includes the following new commits:

     new 098e995  SLING-5703 - new http/clients module, extracted and enhanced from testing/tools. Contributed by Andrei Dulvac, thanks!
     new 6f3b69e  SLING-5725 - Remove o.a.s.testing.tools dependency in o.a.s.testing.clients and merge OSGi console clients - contribued by Andrei Dulvac, thanks!
     new 4f93441  trivial - reduced wait time in test
     new 9525b72  SLING-5727 Remove o.a.s.testing.tools dependency in o.a.s.testing.serversetup and adapt http code
     new 58ae43e  SLING-5727 Remove o.a.s.testing.tools dependency in o.a.s.testing.serversetup and adapt http code  * Added TimeoutsProvider
     new 3b0a1ba  SLING-5793 Add client that can leverage hapi client in testing http clients
     new 465aaa9  @trivial Added missing package version
     new 3e93b69  @trivial Added http status code to ClientException
     new 2336236  Rollback release of org.apache.sling.hapi.client
     new 429e5f4  Fix compilation errors
     new c5a1b9b  @releng updated dependency in org.apache.sling.testing.clients to hapi client 1.0.0
     new 8b6bbb4  @releng changed package versions in org.apache.sling.testing.clients
     new 5bfb5cf  @releng changed package versions in org.apache.sling.testing.clients
     new 134249e  [maven-release-plugin] prepare release org.apache.sling.testing.clients-1.0.0
     new c2e4bf3  [maven-release-plugin] prepare for next development iteration
     new ac1c276  Fix broken build - this module relies on an hapi snapshot from contrib, that's not good but at least the build should pass now (I have deployed hapi snapshots)
     new b7333ca  SLING-6405 - Make testing.clients.interceptors.TestDescriptionInterceptor in line with TestLogServlet from junit core
     new 2eefa29  SLING-6431 and some cosmetic changes
     new 5ffc89e  [maven-release-plugin] prepare release org.apache.sling.testing.clients-1.0.1
     new 599b6e0  [maven-release-plugin] prepare for next development iteration
     new cab958b  use Sling Parent 30
     new 7d6589d  use OSGi annotations and remove unused Maven SCR Plugin
     new 0883798  SLING-6853 Improve polling capabilities in o.a.s.testing.clients thanks @volteanu for the contribution!
     new a06ceb1  SLING-6853 Fixed incomplete patch.
     new e3911b9  SLING-6905: Remove commons.json from testing http clients by using already used jackson library. Patch provided by Valentin Olteanu. This closes #235.
     new be1e939  [maven-release-plugin] prepare release org.apache.sling.testing.clients-1.1.0
     new 0bc9142  [maven-release-plugin] copy for tag org.apache.sling.testing.clients-1.1.0

The 27 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


-- 
To stop receiving notification emails like this one, please contact
['"commits@sling.apache.org" <co...@sling.apache.org>'].

[sling-org-apache-sling-testing-clients] 02/08: use Sling Parent 30

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to annotated tag org.apache.sling.testing.clients-1.1.0
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-testing-clients.git

commit cab958bd4350305cce8fd410aff180bdb95bb5dd
Author: Oliver Lietz <ol...@apache.org>
AuthorDate: Mon Mar 6 10:31:22 2017 +0000

    use Sling Parent 30
    
    git-svn-id: https://svn.apache.org/repos/asf/sling/trunk/testing/http/clients@1785622 13f79535-47bb-0310-9956-ffa450edef68
---
 pom.xml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/pom.xml b/pom.xml
index 17392ee..af7f357 100644
--- a/pom.xml
+++ b/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.apache.sling</groupId>
         <artifactId>sling</artifactId>
-        <version>28</version>
+        <version>30</version>
         <relativePath />
     </parent>
 

-- 
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.

[sling-org-apache-sling-testing-clients] 01/08: [maven-release-plugin] prepare for next development iteration

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to annotated tag org.apache.sling.testing.clients-1.1.0
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-testing-clients.git

commit 599b6e02e2173a7ae602a871dd555a8ca48d7767
Author: Andrei Dulvac <du...@apache.org>
AuthorDate: Fri Jan 6 10:01:21 2017 +0000

    [maven-release-plugin] prepare for next development iteration
    
    git-svn-id: https://svn.apache.org/repos/asf/sling/trunk/testing/http/clients@1777560 13f79535-47bb-0310-9956-ffa450edef68
---
 pom.xml | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/pom.xml b/pom.xml
index 72731ed..17392ee 100644
--- a/pom.xml
+++ b/pom.xml
@@ -28,7 +28,7 @@
     </parent>
 
     <artifactId>org.apache.sling.testing.clients</artifactId>
-    <version>1.0.1</version>
+    <version>1.0.2-SNAPSHOT</version>
     <packaging>bundle</packaging>
 
     <name>Apache Sling Testing Clients</name>
@@ -36,9 +36,9 @@
         Sling testing http clients and utils
     </description>
     <scm>
-        <connection>scm:svn:http://svn.apache.org/repos/asf/sling/tags/org.apache.sling.testing.clients-1.0.1</connection>
-        <developerConnection> scm:svn:https://svn.apache.org/repos/asf/sling/tags/org.apache.sling.testing.clients-1.0.1</developerConnection>
-        <url>http://svn.apache.org/viewvc/sling/tags/org.apache.sling.testing.clients-1.0.1</url>
+        <connection>scm:svn:http://svn.apache.org/repos/asf/sling/trunk/testing/http/clients</connection>
+        <developerConnection> scm:svn:https://svn.apache.org/repos/asf/sling/trunk/testing/http/clients</developerConnection>
+        <url>http://svn.apache.org/viewvc/sling/trunk/testing/http/clients</url>
     </scm>
     
     <build>

-- 
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.

[sling-org-apache-sling-testing-clients] 07/08: [maven-release-plugin] prepare release org.apache.sling.testing.clients-1.1.0

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to annotated tag org.apache.sling.testing.clients-1.1.0
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-testing-clients.git

commit be1e939e3e7d13e9bda93b8a8e2e7c1f87660bcc
Author: Karl Pauls <pa...@apache.org>
AuthorDate: Fri Jun 2 21:21:45 2017 +0000

    [maven-release-plugin] prepare release org.apache.sling.testing.clients-1.1.0
    
    git-svn-id: https://svn.apache.org/repos/asf/sling/trunk/testing/http/clients@1797449 13f79535-47bb-0310-9956-ffa450edef68
---
 pom.xml | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/pom.xml b/pom.xml
index 1b42b85..85aff6b 100644
--- a/pom.xml
+++ b/pom.xml
@@ -28,7 +28,7 @@
     </parent>
 
     <artifactId>org.apache.sling.testing.clients</artifactId>
-    <version>1.1.0-SNAPSHOT</version>
+    <version>1.1.0</version>
     <packaging>bundle</packaging>
 
     <name>Apache Sling Testing Clients</name>
@@ -36,9 +36,9 @@
         Sling testing http clients and utils
     </description>
     <scm>
-        <connection>scm:svn:http://svn.apache.org/repos/asf/sling/trunk/testing/http/clients</connection>
-        <developerConnection> scm:svn:https://svn.apache.org/repos/asf/sling/trunk/testing/http/clients</developerConnection>
-        <url>http://svn.apache.org/viewvc/sling/trunk/testing/http/clients</url>
+        <connection>scm:svn:http://svn.apache.org/repos/asf/sling/tags/org.apache.sling.testing.clients-1.1.0</connection>
+        <developerConnection> scm:svn:https://svn.apache.org/repos/asf/sling/tags/org.apache.sling.testing.clients-1.1.0</developerConnection>
+        <url>http://svn.apache.org/viewvc/sling/tags/org.apache.sling.testing.clients-1.1.0</url>
     </scm>
     
     <build>

-- 
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.

[sling-org-apache-sling-testing-clients] 04/08: SLING-6853 Improve polling capabilities in o.a.s.testing.clients thanks @volteanu for the contribution!

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to annotated tag org.apache.sling.testing.clients-1.1.0
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-testing-clients.git

commit 0883798bbf4fe5a4a7f479f51feffb91534883d3
Author: Andrei Dulvac <du...@apache.org>
AuthorDate: Tue May 16 12:34:17 2017 +0000

    SLING-6853 Improve polling capabilities in o.a.s.testing.clients
    thanks @volteanu for the contribution!
    
    
    git-svn-id: https://svn.apache.org/repos/asf/sling/trunk/testing/http/clients@1795303 13f79535-47bb-0310-9956-ffa450edef68
---
 pom.xml                                            |   9 +-
 .../apache/sling/testing/clients/SlingClient.java  |  88 ++++++--
 .../sling/testing/clients/html/package-info.java   |   2 +-
 .../testing/clients/osgi/BundlesInstaller.java     | 146 ++++++-------
 .../testing/clients/osgi/OsgiConsoleClient.java    | 241 ++++++++++++++++-----
 .../testing/clients/osgi/OsgiInstanceConfig.java   |  28 ++-
 .../sling/testing/clients/osgi/package-info.java   |   2 +-
 .../apache/sling/testing/clients/package-info.java |   2 +-
 .../testing/clients/util/TimeoutsProvider.java     |   4 +
 .../clients/util/config/InstanceConfig.java        |   4 +-
 .../util/config/impl/InstanceConfigCacheImpl.java  |   4 +-
 .../clients/util/poller/AbstractPoller.java        |   5 +
 .../testing/clients/util/poller/PathPoller.java    |   1 +
 .../sling/testing/clients/util/poller/Poller.java  |   4 +
 .../testing/clients/util/poller/package-info.java  |   2 +-
 15 files changed, 369 insertions(+), 173 deletions(-)

diff --git a/pom.xml b/pom.xml
index ff471a4..be389da 100644
--- a/pom.xml
+++ b/pom.xml
@@ -28,7 +28,7 @@
     </parent>
 
     <artifactId>org.apache.sling.testing.clients</artifactId>
-    <version>1.0.2-SNAPSHOT</version>
+    <version>1.1.0-SNAPSHOT</version>
     <packaging>bundle</packaging>
 
     <name>Apache Sling Testing Clients</name>
@@ -149,5 +149,12 @@
             <artifactId>org.apache.sling.hapi.client</artifactId>
             <version>1.0.0</version>
         </dependency>
+        <dependency>
+            <groupId>org.apache.httpcomponents</groupId>
+            <artifactId>httpclient</artifactId>
+            <version>4.5.3</version>
+            <classifier>tests</classifier>
+            <scope>test</scope>
+        </dependency>
     </dependencies>
 </project>
diff --git a/src/main/java/org/apache/sling/testing/clients/SlingClient.java b/src/main/java/org/apache/sling/testing/clients/SlingClient.java
index ede00b5..bee5b40 100644
--- a/src/main/java/org/apache/sling/testing/clients/SlingClient.java
+++ b/src/main/java/org/apache/sling/testing/clients/SlingClient.java
@@ -30,19 +30,20 @@ import org.apache.http.entity.ContentType;
 import org.apache.http.entity.mime.MultipartEntityBuilder;
 import org.apache.http.impl.client.CloseableHttpClient;
 import org.apache.http.impl.client.HttpClientBuilder;
-
 import org.apache.sling.testing.clients.interceptors.DelayRequestInterceptor;
 import org.apache.sling.testing.clients.interceptors.TestDescriptionInterceptor;
 import org.apache.sling.testing.clients.util.FormEntityBuilder;
 import org.apache.sling.testing.clients.util.HttpUtils;
 import org.apache.sling.testing.clients.util.JsonUtils;
 import org.apache.sling.testing.clients.util.poller.AbstractPoller;
+import org.apache.sling.testing.clients.util.poller.Polling;
 import org.codehaus.jackson.JsonNode;
 
 import java.io.File;
 import java.net.URI;
 import java.util.ArrayList;
 import java.util.List;
+import java.util.concurrent.TimeoutException;
 
 import static org.apache.http.HttpStatus.SC_CREATED;
 import static org.apache.http.HttpStatus.SC_OK;
@@ -212,12 +213,16 @@ public class SlingClient extends AbstractSlingClient {
     /**
      * <p>Checks whether a path exists or not by making a GET request to that path with the {@code json extension} </p>
      * <p>It polls the server and waits until the path exists </p>
+     *
+     * @deprecated use {@link #waitExists(String, long, long)} instead.
+     *
      * @param path path to be checked
      * @param waitMillis time to wait between retries
      * @param retryCount number of retries before throwing an exception
      * @throws ClientException if the path was not found
      * @throws InterruptedException to mark this operation as "waiting"
      */
+    @Deprecated
     public void waitUntilExists(final String path, final long waitMillis, int retryCount)
             throws ClientException, InterruptedException {
         AbstractPoller poller =  new AbstractPoller(waitMillis, retryCount) {
@@ -244,6 +249,34 @@ public class SlingClient extends AbstractSlingClient {
     }
 
     /**
+     * <p>Waits until a path exists by making successive GET requests to that path with the {@code json extension} </p>
+     * <p>Polls the server until the path exists or until timeout is reached </p>
+     * @param path path to be checked
+     * @param timeout max total time to wait, in milliseconds
+     * @param delay time to wait between checks, in milliseconds
+     * @throws TimeoutException if the path was not found before timeout
+     * @throws InterruptedException to mark this operation as "waiting", should be rethrown by callers
+     * @since 1.1.0
+     */
+    public void waitExists(final String path, final long timeout, final long delay)
+            throws TimeoutException, InterruptedException {
+
+        Polling p = new Polling() {
+            @Override
+            public Boolean call() throws Exception {
+                return exists(path);
+            }
+
+            @Override
+            protected String message() {
+                return "Path " + path + " does not exist after %1$d ms";
+            }
+        };
+
+        p.poll(timeout, delay);
+    }
+
+    /**
      * Sets String component property on a node.
      *
      * @param nodePath       path to the node to be edited
@@ -303,12 +336,14 @@ public class SlingClient extends AbstractSlingClient {
      * Returns the JSON content of a node already mapped to a {@link org.codehaus.jackson.JsonNode}.<br>
      * Waits max 10 seconds for the node to be created.
      *
+     * @deprecated use {@link #waitExists(String, long, long)} and {@link #doGetJson(String, int, int...)} instead
      * @param path  the path to the content node
      * @param depth the number of levels to go down the tree, -1 for infinity
      * @return a {@link org.codehaus.jackson.JsonNode} mapping to the requested content node.
      * @throws ClientException if something fails during request/response processing
      * @throws InterruptedException to mark this operation as "waiting"
      */
+    @Deprecated
     public JsonNode getJsonNode(String path, int depth) throws ClientException, InterruptedException {
         return getJsonNode(path, depth, 500, 20);
     }
@@ -316,6 +351,7 @@ public class SlingClient extends AbstractSlingClient {
     /**
      * Returns JSON format of a content node already mapped to a {@link org.codehaus.jackson.JsonNode}.
      *
+     * @deprecated use {@link #waitExists(String, long, long)} and {@link #doGetJson(String, int, int...)} instead
      * @param path                 the path to the content node
      * @param depth                the number of levels to go down the tree, -1 for infinity
      * @param waitMillis           how long it should wait between requests
@@ -326,6 +362,7 @@ public class SlingClient extends AbstractSlingClient {
      * @throws ClientException if something fails during request/response cycle
      * @throws InterruptedException to mark this operation as "waiting"
      */
+    @Deprecated
     public JsonNode getJsonNode(String path, int depth, final long waitMillis, final int retryNumber, int... expectedStatus)
             throws ClientException, InterruptedException {
 
@@ -347,6 +384,31 @@ public class SlingClient extends AbstractSlingClient {
     }
 
     /**
+     * Returns the {@link org.codehaus.jackson.JsonNode} object corresponding to a content node.
+     *
+     * @param path the path to the content node
+     * @param depth the number of levels to go down the tree, -1 for infinity
+     * @param expectedStatus list of allowed HTTP Status to be returned. If not set, 200 (OK) is assumed.
+     *
+     * @return a {@link org.codehaus.jackson.JsonNode} mapping to the requested content node.
+     * @throws ClientException if the path does not exist or something fails during request/response cycle
+     * @since 1.1.0
+     */
+    public JsonNode doGetJson(String path, int depth, int... expectedStatus) throws ClientException {
+
+        // check for infinity
+        if (depth == -1) {
+            path += ".infinity.json";
+        } else {
+            path += "." + depth + ".json";
+        }
+
+        // request the JSON for the node
+        SlingHttpResponse response = this.doGet(path, HttpUtils.getExpectedStatus(SC_OK, expectedStatus));
+        return JsonUtils.getJsonNodeFromString(response.getContent());
+    }
+
+    /**
      * Uploads a file to the repository. It creates a leaf node typed {@code nt:file}. The intermediary nodes are created with
      * type "sling:OrderedFolder" if parameter {@code createFolders} is true
      *
@@ -413,33 +475,31 @@ public class SlingClient extends AbstractSlingClient {
     }
 
     /**
-     * Get uuid from any repository path
+     * Get the UUID of a repository path
      *
-     * @param repPath path in repository
-     * @return uuid as String
+     * @param path path in repository
+     * @return uuid as String or null if path does not exist
      * @throws ClientException if something fails during request/response cycle
-     * @throws InterruptedException to mark this operation as "waiting"
      */
-    public String getUUID(String repPath) throws ClientException, InterruptedException {
-        // TODO review if this check is necessary. Maybe rewrite getJsonNode to wait only if requested
-        if (!exists(repPath)) {
+    public String getUUID(String path) throws ClientException {
+        if (!exists(path)) {
             return null;
         }
-        JsonNode jsonNode = getJsonNode(repPath, -1);
+        JsonNode jsonNode = doGetJson(path, -1);
         return getUUId(jsonNode);
     }
 
     /**
-     * Get uuid from any repository path
+     * Get the UUID from a node that was already parsed in a {@link JsonNode}
      *
-     * @param jsonNode {@link JsonNode} in repository
-     * @return uuid as String or null if jsonNode is null or if the uuid was not found
+     * @param jsonNode {@link JsonNode} object of the repository node
+     * @return UUID as String or null if jsonNode is null or if the UUID was not found
      * @throws ClientException if something fails during request/response cycle
      */
+    // TODO make this method static
     public String getUUId(JsonNode jsonNode) throws ClientException {
-        // TODO review if this check is necessary. Maybe rewrite getJsonNode to wait only if requested
         if (jsonNode == null) {
-            return null;  // node does not exist
+            return null;
         }
 
         JsonNode uuidNode = jsonNode.get("jcr:uuid");
diff --git a/src/main/java/org/apache/sling/testing/clients/html/package-info.java b/src/main/java/org/apache/sling/testing/clients/html/package-info.java
index 5f5a9f5..cd55c59 100644
--- a/src/main/java/org/apache/sling/testing/clients/html/package-info.java
+++ b/src/main/java/org/apache/sling/testing/clients/html/package-info.java
@@ -17,7 +17,7 @@
  * under the License.
  */
 
-@Version("2.1.0")
+@Version("2.2.0")
 package org.apache.sling.testing.clients.html;
 
 import org.osgi.annotation.versioning.Version;
diff --git a/src/main/java/org/apache/sling/testing/clients/osgi/BundlesInstaller.java b/src/main/java/org/apache/sling/testing/clients/osgi/BundlesInstaller.java
index 8a19aa6..fcfd6c5 100644
--- a/src/main/java/org/apache/sling/testing/clients/osgi/BundlesInstaller.java
+++ b/src/main/java/org/apache/sling/testing/clients/osgi/BundlesInstaller.java
@@ -17,13 +17,14 @@
 package org.apache.sling.testing.clients.osgi;
 
 import org.apache.sling.testing.clients.ClientException;
-import org.apache.sling.testing.clients.util.poller.AbstractPoller;
+import org.apache.sling.testing.clients.util.poller.Polling;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import java.io.File;
 import java.io.IOException;
 import java.util.List;
+import java.util.concurrent.TimeoutException;
 
 
 /**
@@ -40,31 +41,34 @@ public class BundlesInstaller {
 
     /**
      * Checks if a bundle is installed or not. Does not retry.
-     * @param bundleFile
-     * @return
-     * @throws ClientException
-     * @throws IOException
-     * @throws InterruptedException
+     * @param bundleFile bundle file
+     * @return true if the bundle is installed
+     * @throws ClientException if the state of the bundle could not be determined
      */
-    public boolean isInstalled(File bundleFile) throws InterruptedException, IOException {
-        final String bundleSymbolicName = OsgiConsoleClient.getBundleSymbolicName(bundleFile);
-        log.debug("Checking if installed: " + bundleSymbolicName);
-        boolean installed = osgiConsoleClient.checkBundleInstalled(bundleSymbolicName, 1000, 1);
-        // if this succeeds, then there's no need to install again
-        if (installed) {
+    public boolean isInstalled(File bundleFile) throws ClientException {
+        String bundleSymbolicName = "";
+        try {
+            bundleSymbolicName = OsgiConsoleClient.getBundleSymbolicName(bundleFile);
+            log.debug("Checking if installed: " + bundleSymbolicName);
+
+            osgiConsoleClient.getBundleState(bundleSymbolicName);
             log.debug("Already installed: " + bundleSymbolicName);
             return true;
-        } else {
+        } catch (ClientException e) {
             log.debug("Not yet installed: " + bundleSymbolicName);
             return false;
+        } catch (IOException e) {
+            log.debug("Failed to retrieve bundle symbolic name from file. ", e);
+            throw new ClientException("Failed to retrieve bundle symbolic name from file. ", e);
         }
     }
 
     /**
      * Check if the installed version matches the one of the bundle (file)
-     * @param bundleFile
-     * @return
-     * @throws Exception
+     * @param bundleFile bundle file
+     * @return true if the bundle is installed and has the same version
+     * @throws ClientException if the installed version cannot be retrieved
+     * @throws IOException if the file version cannot be read
      */
     public boolean isInstalledWithSameVersion(File bundleFile) throws ClientException, IOException {
         final String bundleSymbolicName = OsgiConsoleClient.getBundleSymbolicName(bundleFile);
@@ -81,11 +85,11 @@ public class BundlesInstaller {
 
     /**
      * Install a list of bundles supplied as Files
-     * @param toInstall
-     * @param startBundles
-     * @throws Exception
+     * @param toInstall list ob bundles to install
+     * @param startBundles whether to start the bundles
+     * @throws ClientException if an error occurs during installation
      */
-    public void installBundles(List<File> toInstall, boolean startBundles) throws ClientException, IOException, InterruptedException {
+    public void installBundles(List<File> toInstall, boolean startBundles) throws ClientException, IOException {
         for(File f : toInstall) {
             final String bundleSymbolicName = OsgiConsoleClient.getBundleSymbolicName(f);
             if (isInstalled(f)) {
@@ -112,12 +116,11 @@ public class BundlesInstaller {
 
     /**
      * Uninstall a list of bundles supplied as Files
-     * @param toUninstall
-     * @throws ClientException
-     * @throws IOException
-     * @throws InterruptedException
+     * @param toUninstall bundles to uninstall
+     * @throws ClientException if one of the requests failed
+     * @throws IOException if the files cannot be read from disk
      */
-    public void uninstallBundles(List<File> toUninstall) throws ClientException, IOException, InterruptedException {
+    public void uninstallBundles(List<File> toUninstall) throws ClientException, IOException {
         for(File f : toUninstall) {
             final String bundleSymbolicName = OsgiConsoleClient.getBundleSymbolicName(f);
             if (isInstalled(f)) {
@@ -137,11 +140,12 @@ public class BundlesInstaller {
 
     /**
      * Wait for all bundles specified in symbolicNames list to be installed in the OSGi web console.
+     * @deprecated use {@link #waitBundlesInstalled(List, long)}
      * @param symbolicNames the list of names for the bundles
      * @param timeoutSeconds how many seconds to wait
-     * @return
-     * @throws Exception
+     * @return true if all the bundles were installed
      */
+    @Deprecated
     public boolean waitForBundlesInstalled(List<String> symbolicNames, int timeoutSeconds) throws ClientException, InterruptedException {
         log.info("Checking that the following bundles are installed (timeout {} seconds): {}", timeoutSeconds, symbolicNames);
         for (String symbolicName : symbolicNames) {
@@ -152,66 +156,50 @@ public class BundlesInstaller {
     }
 
     /**
-     * Start all the bundles in a {{List}}
-     * @param symbolicNames the list of bundles to start
-     * @param timeoutSeconds number of seconds until it times out
-     * @throws ClientException
-     * @throws InterruptedException
+     * Wait for multiple bundles to be installed in the OSGi web console.
+     * @param symbolicNames the list bundles to be checked
+     * @param timeout max total time to wait for all bundles, in ms, before throwing {@code TimeoutException}
+     * @throws TimeoutException if the timeout was reached before all the bundles were installed
+     * @throws InterruptedException to mark this operation as "waiting", callers should rethrow it
      */
-    public void startAllBundles(final List<String> symbolicNames, int timeoutSeconds) throws ClientException, InterruptedException {
-        log.info("Starting bundles (timeout {} seconds): {}", timeoutSeconds, symbolicNames);
-        class StartAllBundlesPoller extends AbstractPoller {
-            private ClientException exception;
-            public StartAllBundlesPoller(List<String> symbolicNames, long waitInterval, long waitCount) {
-                super(waitInterval, waitCount);
-            }
+    public void waitBundlesInstalled(List<String> symbolicNames, long timeout)
+            throws InterruptedException, TimeoutException {
+        log.info("Checking that the following bundles are installed (timeout {} ms): {}", timeout, symbolicNames);
+        long start = System.currentTimeMillis();
+        for (String symbolicName : symbolicNames) {
+            osgiConsoleClient.waitBundleInstalled(symbolicName, timeout, 500);
 
-            @Override
-            public boolean call() {
-                for (String bundle : symbolicNames) {
-                    final String state;
-                    try {
-                        state = osgiConsoleClient.getBundleState(bundle);
-                        if (!state.equalsIgnoreCase(ACTIVE_STATE)) {
-                            osgiConsoleClient.startBundle(bundle);
-                        }
-                    } catch (ClientException e) {
-                        this.exception = e;
-                        return false;
-                    }
-                }
-                return true;
+            if (System.currentTimeMillis() > start + timeout) {
+                throw new TimeoutException("Waiting for bundles did not finish in " + timeout + " ms.");
             }
+        }
+    }
 
+    /**
+     * Start all the bundles in a {{List}}
+     * @param symbolicNames the list of bundles to start
+     * @param timeout total max time to wait for all the bundles, in ms
+     * @throws TimeoutException if the timeout is reached before all the bundles are started
+     * @throws InterruptedException to mark this operation as "waiting", callers should rethrow it
+     */
+    public void startAllBundles(final List<String> symbolicNames, int timeout) throws InterruptedException, TimeoutException {
+        log.info("Starting bundles (timeout {} seconds): {}", timeout, symbolicNames);
+
+        Polling p = new Polling() {
             @Override
-            public boolean condition() {
+            public Boolean call() throws Exception {
+                boolean allActive = true;
                 for (String bundle : symbolicNames) {
-                    final String state;
-                    try {
-                        state = osgiConsoleClient.getBundleState(bundle);
-                        if (!state.equalsIgnoreCase(ACTIVE_STATE)) {
-                            return false;
-                        }
-                    } catch (ClientException e) {
-                        this.exception = e;
-                        return false;
+                    String state = osgiConsoleClient.getBundleState(bundle);
+                    if (!state.equalsIgnoreCase(ACTIVE_STATE)) {
+                        osgiConsoleClient.startBundle(bundle);
+                        allActive = false;
                     }
                 }
-                return true;
+                return allActive;
             }
+        };
 
-            public ClientException getException() {
-                return exception;
-            }
-        }
-        StartAllBundlesPoller poller = new StartAllBundlesPoller(symbolicNames, 1000, timeoutSeconds);
-        if (!poller.callUntilCondition()) {
-            throw new ClientException("Some bundles did not start or timed out", poller.getException());
-        }
-
+        p.poll(timeout, 500);
     }
-
-
-
-
-}
\ No newline at end of file
+}
diff --git a/src/main/java/org/apache/sling/testing/clients/osgi/OsgiConsoleClient.java b/src/main/java/org/apache/sling/testing/clients/osgi/OsgiConsoleClient.java
index 08cd742..8dd8ca2 100644
--- a/src/main/java/org/apache/sling/testing/clients/osgi/OsgiConsoleClient.java
+++ b/src/main/java/org/apache/sling/testing/clients/osgi/OsgiConsoleClient.java
@@ -24,14 +24,14 @@ import org.apache.sling.commons.json.JSONArray;
 import org.apache.sling.commons.json.JSONException;
 import org.apache.sling.commons.json.JSONObject;
 import org.apache.sling.testing.clients.ClientException;
-import org.apache.sling.testing.clients.SlingHttpResponse;
-import org.apache.sling.testing.clients.util.JsonUtils;
-import org.apache.sling.testing.clients.util.poller.AbstractPoller;
 import org.apache.sling.testing.clients.SlingClient;
 import org.apache.sling.testing.clients.SlingClientConfig;
+import org.apache.sling.testing.clients.SlingHttpResponse;
 import org.apache.sling.testing.clients.util.FormEntityBuilder;
 import org.apache.sling.testing.clients.util.HttpUtils;
+import org.apache.sling.testing.clients.util.JsonUtils;
 import org.apache.sling.testing.clients.util.poller.PathPoller;
+import org.apache.sling.testing.clients.util.poller.Polling;
 import org.codehaus.jackson.JsonNode;
 import org.osgi.framework.Constants;
 import org.slf4j.Logger;
@@ -41,7 +41,12 @@ import java.io.File;
 import java.io.FileInputStream;
 import java.io.IOException;
 import java.net.URI;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.TimeoutException;
 import java.util.jar.JarInputStream;
 import java.util.jar.Manifest;
 
@@ -204,11 +209,12 @@ public class OsgiConsoleClient extends SlingClient {
         }
         return props;
     }
-
     /**
      * Returns a map of all properties set for the config referenced by the PID, where the map keys
      * are the property names. The method waits until the configuration has been set.
      *
+     * @deprecated use {@link #waitGetConfiguration(long, String, int...)}
+     *
      * @param waitCount The number of maximum wait intervals of 500ms.
      *                  Between each wait interval, the method polls the backend to see if the configuration ahs been set.
      * @param pid pid
@@ -217,11 +223,36 @@ public class OsgiConsoleClient extends SlingClient {
      * @throws ClientException if the response status does not match any of the expectedStatus
      * @throws InterruptedException to mark this operation as "waiting"
      */
+    @Deprecated
     public Map<String, Object> getConfigurationWithWait(long waitCount, String pid, int... expectedStatus)
             throws ClientException, InterruptedException {
-        ConfigurationPoller poller = new ConfigurationPoller(500L, waitCount, pid, expectedStatus);
-        if (!poller.callUntilCondition())
-            return getConfiguration(pid, expectedStatus);
+        ConfigurationPoller poller = new ConfigurationPoller(pid, expectedStatus);
+        try {
+            poller.poll(500L * waitCount, 500);
+        } catch (TimeoutException e) {
+            throw new ClientException("Cannot retrieve configuration.", e);
+        }
+        return poller.getConfig();
+    }
+
+    /**
+     * Returns a map of all properties set for the config referenced by the PID, where the map keys
+     * are the property names. The method waits until the configuration has been set.
+     *
+     * @param timeout Maximum time to wait for the configuration to be available, in ms.
+     * @param pid service pid
+     * @param expectedStatus expected response status
+     * @return the config properties
+     * @throws ClientException if the response status does not match any of the expectedStatus
+     * @throws InterruptedException to mark this operation as "waiting"
+     * @throws TimeoutException if the timeout was reached
+     */
+    public Map<String, Object> waitGetConfiguration(long timeout, String pid, int... expectedStatus)
+            throws ClientException, InterruptedException, TimeoutException {
+
+        ConfigurationPoller poller = new ConfigurationPoller(pid, expectedStatus);
+        poller.poll(timeout, 500);
+
         return poller.getConfig();
     }
 
@@ -277,6 +308,8 @@ public class OsgiConsoleClient extends SlingClient {
      * Sets properties of a config referenced by its PID. the properties to be edited are passed as
      * a map of property (name,value) pairs. The method waits until the configuration has been set.
      *
+     * @deprecated use {@link #waitEditConfiguration(long, String, String, Map, int...)}
+     *
      * @param waitCount The number of maximum wait intervals of 500ms.
      *                  Between each wait interval, the method polls the backend to see if the configuration ahs been set.
      * @param PID Persistent identity string
@@ -287,6 +320,7 @@ public class OsgiConsoleClient extends SlingClient {
      * @throws ClientException if the response status does not match any of the expectedStatus
      * @throws InterruptedException to mark this operation as "waiting"
      */
+    @Deprecated
     public String editConfigurationWithWait(int waitCount, String PID, String factoryPID, Map<String, Object> configProperties,
                                             int... expectedStatus) throws ClientException, InterruptedException {
         String pid = editConfiguration(PID, factoryPID, configProperties, expectedStatus);
@@ -295,6 +329,28 @@ public class OsgiConsoleClient extends SlingClient {
     }
 
     /**
+     * Sets properties of a config referenced by its PID. the properties to be edited are passed as
+     * a map of property (name,value) pairs. The method waits until the configuration has been set.
+     *
+     * @param timeout Max time to wait for the configuration to be set, in ms
+     * @param PID Persistent identity string
+     * @param factoryPID Factory persistent identity string or {@code null}
+     * @param configProperties map of properties
+     * @param expectedStatus expected response status
+     * @return the pid
+     * @throws ClientException if the response status does not match any of the expectedStatus
+     * @throws InterruptedException to mark this operation as "waiting"
+     * @throws TimeoutException if the timeout was reached
+     */
+    public String waitEditConfiguration(long timeout, String PID, String factoryPID, Map<String, Object> configProperties,
+                                        int... expectedStatus)
+            throws ClientException, InterruptedException, TimeoutException {
+        String pid = editConfiguration(PID, factoryPID, configProperties, expectedStatus);
+        waitGetConfiguration(timeout, pid);
+        return pid;
+    }
+
+    /**
      * Delete the config referenced by the PID
      *
      * @param pid pid
@@ -319,7 +375,7 @@ public class OsgiConsoleClient extends SlingClient {
 
     /**
      * Uninstall a bundle
-     * @param symbolicName
+     * @param symbolicName bundle symbolic name
      * @return the sling response
      * @throws ClientException
      */
@@ -344,11 +400,11 @@ public class OsgiConsoleClient extends SlingClient {
 
     /**
      * Install a bundle using the Felix webconsole HTTP interface, with a specific start level
-     * @param f
-     * @param startBundle
-     * @param startLevel
+     * @param f bundle file
+     * @param startBundle whether to start or just install the bundle
+     * @param startLevel start level
      * @return the sling response
-     * @throws ClientException
+     * @throws ClientException if the request failed
      */
     public SlingHttpResponse installBundle(File f, boolean startBundle, int startLevel) throws ClientException {
         // Setup request for Felix Webconsole bundle install
@@ -370,7 +426,24 @@ public class OsgiConsoleClient extends SlingClient {
     }
 
     /**
+     * Check that specified bundle is installed and retries every {{waitTime}} milliseconds, until the
+     * bundle is installed or the number of retries was reached
+     * @deprecated does not respect polling practices; use {@link #waitBundleInstalled(String, long, long)} instead
+     * @param symbolicName the name of the bundle
+     * @param waitTime How many milliseconds to wait between retries
+     * @param retries the number of retries
+     * @return true if the bundle was installed until the retries stop, false otherwise
+     * @throws InterruptedException
+     */
+    @Deprecated
+    public boolean checkBundleInstalled(String symbolicName, int waitTime, int retries) throws InterruptedException {
+        final String path = getBundlePath(symbolicName, ".json");
+        return new PathPoller(this, path, waitTime, retries).callAndWait();
+    }
+
+    /**
      * Install a bundle using the Felix webconsole HTTP interface and wait for it to be installed
+     * @deprecated {@link #waitInstallBundle(File, boolean, int, long, long)}
      * @param f the bundle file
      * @param startBundle whether to start the bundle or not
      * @param startLevel the start level of the bundle. negative values mean default start level
@@ -379,6 +452,7 @@ public class OsgiConsoleClient extends SlingClient {
      * @return true if the bundle was successfully installed, false otherwise
      * @throws ClientException
      */
+    @Deprecated
     public boolean installBundleWithRetry(File f, boolean startBundle, int startLevel, int waitTime, int retries)
             throws ClientException, InterruptedException {
         installBundle(f, startBundle, startLevel);
@@ -390,24 +464,51 @@ public class OsgiConsoleClient extends SlingClient {
     }
 
     /**
-     * Check that specified bundle is installed and retries every {{waitTime}} milliseconds, until the
-     * bundle is installed or the number of retries was reached
-     * @param symbolicName the name of the bundle
-     * @param waitTime How many milliseconds to wait between retries
-     * @param retries the number of retries
-     * @return true if the bundle was installed until the retries stop, false otherwise
+     * Install a bundle using the Felix webconsole HTTP interface and wait for it to be installed
+     * @param f the bundle file
+     * @param startBundle whether to start the bundle or not
+     * @param startLevel the start level of the bundle. negative values mean default start level
+     * @param timeout how much to wait for the bundle to be installed before throwing a {@code TimeoutException}
+     * @param delay time to wait between checks of the state
+     * @throws ClientException
+     * @throws TimeoutException if the bundle did not install before timeout was reached
      * @throws InterruptedException
      */
-    public boolean checkBundleInstalled(String symbolicName, int waitTime, int retries) throws InterruptedException {
-        final String path = getBundlePath(symbolicName, ".json");
-        return new PathPoller(this, path, waitTime, retries).callAndWait();
+    public void waitInstallBundle(File f, boolean startBundle, int startLevel, long timeout, long delay)
+            throws ClientException, InterruptedException, TimeoutException {
+
+        installBundle(f, startBundle, startLevel);
+        try {
+            waitBundleInstalled(getBundleSymbolicName(f), timeout, delay);
+        } catch (IOException e) {
+            throw new ClientException("Cannot get bundle symbolic name", e);
+        }
+    }
+
+    public void waitBundleInstalled(final String symbolicName, final long timeout, final long delay)
+            throws TimeoutException, InterruptedException {
+
+        final String path = getBundlePath(symbolicName);
+        Polling p = new Polling() {
+            @Override
+            public Boolean call() throws Exception {
+                return exists(path);
+            }
+
+            @Override
+            protected String message() {
+                return "Bundle " + symbolicName + " did not install in %1$ ms";
+            }
+        };
+
+        p.poll(timeout, delay);
     }
 
     /**
      * Get the id of the bundle
-     * @param symbolicName
-     * @return
-     * @throws Exception
+     * @param symbolicName bundle symbolic name
+     * @return the id
+     * @throws ClientException if the id cannot be retrieved
      */
     public long getBundleId(String symbolicName) throws ClientException {
         final JSONObject bundle = getBundleData(symbolicName);
@@ -420,8 +521,8 @@ public class OsgiConsoleClient extends SlingClient {
 
     /**
      * Get the version of the bundle
-     * @param symbolicName
-     * @return
+     * @param symbolicName bundle symbolic name
+     * @return bundle version
      * @throws ClientException
      */
     public String getBundleVersion(String symbolicName) throws ClientException {
@@ -435,9 +536,9 @@ public class OsgiConsoleClient extends SlingClient {
 
     /**
      * Get the state of the bundle
-     * @param symbolicName
-     * @return
-     * @throws Exception
+     * @param symbolicName bundle symbolic name
+     * @return the state of the bundle
+     * @throws ClientException if the state cannot be retrieved
      */
     public String getBundleState(String symbolicName) throws ClientException {
         final JSONObject bundle = getBundleData(symbolicName);
@@ -460,13 +561,16 @@ public class OsgiConsoleClient extends SlingClient {
         this.doPost(path, FormEntityBuilder.create().addParameter("action", "start").build(), SC_OK);
     }
 
+
     /**
      * Starts a bundle and waits for it to be started
+     * @deprecated use {@link #waitStartBundle(String, long, long)}
      * @param symbolicName the name of the bundle
      * @param waitTime How many milliseconds to wait between retries
      * @param retries the number of retries
      * @throws ClientException, InterruptedException
      */
+    @Deprecated
     public void startBundlewithWait(String symbolicName, int waitTime, int retries)
             throws ClientException, InterruptedException {
         // start a bundle
@@ -476,6 +580,20 @@ public class OsgiConsoleClient extends SlingClient {
     }
 
     /**
+     * Starts a bundle and waits for it to be started
+     * @param symbolicName the name of the bundle
+     * @param timeout max time to wait for the bundle to start, in ms
+     * @param delay time to wait between status checks, in ms
+     * @throws ClientException, InterruptedException, TimeoutException
+     */
+    public void waitStartBundle(String symbolicName, long timeout, long delay)
+            throws ClientException, InterruptedException, TimeoutException {
+        startBundle(symbolicName);
+        // FIXME this should wait for the started state
+        waitBundleInstalled(symbolicName, timeout, delay);
+    }
+
+    /**
      * Calls PackageAdmin.refreshPackages to force re-wiring of all the bundles.
      * @throws ClientException
      */
@@ -499,12 +617,25 @@ public class OsgiConsoleClient extends SlingClient {
         return URL_BUNDLES + "/" + symbolicName;
     }
 
+    /**
+     * Returns a data structure like:
+     *
+     * {
+     *   "status" : "Bundle information: 173 bundles in total - all 173 bundles active.",
+     *   "s" : [173,171,2,0,0],
+     *   "data": [{
+     *     "id":0,
+     *     "name":"System Bundle",
+     *     "fragment":false,
+     *     "stateRaw":32,
+     *     "state":"Active",
+     *     "version":"3.0.7",
+     *     "symbolicName":"org.apache.felix.framework",
+     *     "category":""
+     *   }]
+     * }
+     */
     private JSONObject getBundleData(String symbolicName) throws ClientException {
-        // This returns a data structure like
-        // {"status":"Bundle information: 173 bundles in total - all 173 bundles active.","s":[173,171,2,0,0],"data":
-        //  [
-        //      {"id":0,"name":"System Bundle","fragment":false,"stateRaw":32,"state":"Active","version":"3.0.7","symbolicName":"org.apache.felix.framework","category":""},
-        //  ]}
         final String path = getBundlePath(symbolicName, ".json");
         final String content = this.doGet(path, SC_OK).getContent();
 
@@ -536,9 +667,9 @@ public class OsgiConsoleClient extends SlingClient {
     //
 
     /**
-     * Get the symbolic name from a bundle file
-     * @param bundleFile
-     * @return
+     * Get the symbolic name from a bundle file by looking at the manifest
+     * @param bundleFile bundle file
+     * @return the name extracted from the manifest
      * @throws IOException
      */
     public static String getBundleSymbolicName(File bundleFile) throws IOException {
@@ -557,9 +688,9 @@ public class OsgiConsoleClient extends SlingClient {
     }
 
     /**
-     * Get the version form a bundle file
-     * @param bundleFile
-     * @return
+     * Get the version form a bundle file by looking at the manifest
+     * @param bundleFile bundle file
+     * @return the version
      * @throws IOException
      */
     public static String getBundleVersionFromFile(File bundleFile) throws IOException {
@@ -578,32 +709,24 @@ public class OsgiConsoleClient extends SlingClient {
     }
 
 
-    class ConfigurationPoller extends AbstractPoller {
+    class ConfigurationPoller extends Polling {
 
         private final String pid;
-        int[] expectedStatus;
-        public Map<String, Object> config;
+        private final int[] expectedStatus;
+        private Map<String, Object> config;
+
+        public ConfigurationPoller(String pid, int... expectedStatus) {
+            super();
 
-        public ConfigurationPoller(long waitInterval, long waitCount, String pid, int... expectedStatus) {
-            super(waitInterval, waitCount);
             this.pid = pid;
-            this.config = null;
             this.expectedStatus = expectedStatus;
+            this.config = null;
         }
 
         @Override
-        public boolean call() {
-            try {
-                config = getConfiguration(pid, expectedStatus);
-            } catch (ClientException e) {
-                LOG.warn("Couldn't get config " + pid, e);
-            }
-            return true;
-        }
-
-        @Override
-        public boolean condition() {
-            return null != config;
+        public Boolean call() throws Exception {
+            config = getConfiguration(pid, expectedStatus);
+            return config != null;
         }
 
         public Map<String, Object> getConfig() {
diff --git a/src/main/java/org/apache/sling/testing/clients/osgi/OsgiInstanceConfig.java b/src/main/java/org/apache/sling/testing/clients/osgi/OsgiInstanceConfig.java
index 41ea39c..9f9c4bd 100644
--- a/src/main/java/org/apache/sling/testing/clients/osgi/OsgiInstanceConfig.java
+++ b/src/main/java/org/apache/sling/testing/clients/osgi/OsgiInstanceConfig.java
@@ -24,23 +24,26 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import java.util.Map;
+import java.util.concurrent.TimeoutException;
 
 /**
  * <p>Allows saving and restoring the OSGiConfig to be used before and after altering OSGi configurations for tests</p>
  * <p>See {@link InstanceConfig}</p>
  */
 public class OsgiInstanceConfig implements InstanceConfig {
+    private static final Logger LOG = LoggerFactory.getLogger(OsgiInstanceConfig.class);
 
     /**
-     * Number of retries for retrieving the current osgi config for save() and restore()
+     * Time im ms to wait for retrieving the current osgi config for save() and restore()
      */
-    protected int waitCount = 20;
+    private static final long WAIT_TIMEOUT = 20000;  // in ms
 
-    private static final Logger LOG = LoggerFactory.getLogger(OsgiInstanceConfig.class);
     private final OsgiConsoleClient osgiClient;
     private final String configPID;
     private Map<String, Object> config;
 
+    @Deprecated
+    protected int waitCount = 20;
 
     /**
      *
@@ -50,7 +53,8 @@ public class OsgiInstanceConfig implements InstanceConfig {
      * @throws ClientException if the client cannot be initialized
      * @throws InstanceConfigException if the config cannot be saved
      */
-    public <T extends SlingClient> OsgiInstanceConfig(T client, String configPID) throws ClientException, InstanceConfigException {
+    public <T extends SlingClient> OsgiInstanceConfig(T client, String configPID)
+            throws ClientException, InstanceConfigException, InterruptedException {
         this.osgiClient = client.adaptTo(OsgiConsoleClient.class);
         this.configPID = configPID;
 
@@ -63,14 +67,14 @@ public class OsgiInstanceConfig implements InstanceConfig {
      *
      * @throws InstanceConfigException if the config cannot be saved
      */
-    public InstanceConfig save() throws InstanceConfigException {
+    public InstanceConfig save() throws InstanceConfigException, InterruptedException {
         try {
-            this.config = osgiClient.getConfigurationWithWait(waitCount, this.configPID);
+            this.config = osgiClient.waitGetConfiguration(WAIT_TIMEOUT, this.configPID);
             LOG.info("Saved OSGi config for {}. It is currently this: {}", this.configPID, this.config);
         } catch (ClientException e) {
             throw new InstanceConfigException("Error getting config", e);
-        } catch (InterruptedException e) {
-            throw new InstanceConfigException("Saving configuration was interrupted ", e);
+        } catch (TimeoutException e) {
+            throw new InstanceConfigException("Timeout of " + WAIT_TIMEOUT + " ms was reached while waiting for the configuration", e);
         }
         return this;
     }
@@ -80,14 +84,14 @@ public class OsgiInstanceConfig implements InstanceConfig {
      *
      * @throws InstanceConfigException if the config cannot be restored
      */
-    public InstanceConfig restore() throws InstanceConfigException {
+    public InstanceConfig restore() throws InstanceConfigException, InterruptedException {
         try {
-            osgiClient.editConfigurationWithWait(waitCount, this.configPID, null, config);
+            osgiClient.waitEditConfiguration(WAIT_TIMEOUT, this.configPID, null, config);
             LOG.info("restored OSGi config for {}. It is now this: {}", this.configPID, this.config);
         } catch (ClientException e) {
             throw new InstanceConfigException("Could not edit OSGi configuration", e);
-        } catch (InterruptedException e) {
-            throw new InstanceConfigException("Restoring configuration was interrupted", e);
+        } catch (TimeoutException e) {
+            throw new InstanceConfigException("Timeout of " + WAIT_TIMEOUT + " ms was reached while waiting for the configuration", e);
         }
         return this;
     }
diff --git a/src/main/java/org/apache/sling/testing/clients/osgi/package-info.java b/src/main/java/org/apache/sling/testing/clients/osgi/package-info.java
index 119cb90..83ff1ab 100644
--- a/src/main/java/org/apache/sling/testing/clients/osgi/package-info.java
+++ b/src/main/java/org/apache/sling/testing/clients/osgi/package-info.java
@@ -19,7 +19,7 @@
 /**
  * OSGI testing tools.
  */
-@Version("1.1.0")
+@Version("1.2.0")
 package org.apache.sling.testing.clients.osgi;
 
 import org.osgi.annotation.versioning.Version;
diff --git a/src/main/java/org/apache/sling/testing/clients/package-info.java b/src/main/java/org/apache/sling/testing/clients/package-info.java
index c7b45c6..991d7e5 100644
--- a/src/main/java/org/apache/sling/testing/clients/package-info.java
+++ b/src/main/java/org/apache/sling/testing/clients/package-info.java
@@ -17,7 +17,7 @@
  * under the License.
  */
 
-@Version("1.2.0")
+@Version("1.3.0")
 package org.apache.sling.testing.clients;
 
 import org.osgi.annotation.versioning.Version;
diff --git a/src/main/java/org/apache/sling/testing/clients/util/TimeoutsProvider.java b/src/main/java/org/apache/sling/testing/clients/util/TimeoutsProvider.java
index 4964300..fa6f99a 100644
--- a/src/main/java/org/apache/sling/testing/clients/util/TimeoutsProvider.java
+++ b/src/main/java/org/apache/sling/testing/clients/util/TimeoutsProvider.java
@@ -23,7 +23,11 @@ import org.slf4j.LoggerFactory;
  *  factor. Useful to cope with slower integration testing systems:
  *  use timeout constants in your code that work for usual development
  *  systems, and set a multiplier when running on a slower system.
+ *
+ *  @deprecated duplicate of {@link org.apache.sling.testing.timeouts.TimeoutsProvider}. This will be removed in the future, so switch to
+ *  the other one instead
  */
+@Deprecated
 public class TimeoutsProvider {
     private static final Logger log = LoggerFactory.getLogger(TimeoutsProvider.class);
     public static final String PROP_TIMEOUT_MULTIPLIER = "sling.testing.timeout.multiplier";
diff --git a/src/main/java/org/apache/sling/testing/clients/util/config/InstanceConfig.java b/src/main/java/org/apache/sling/testing/clients/util/config/InstanceConfig.java
index 8af55ac..b545a7b 100644
--- a/src/main/java/org/apache/sling/testing/clients/util/config/InstanceConfig.java
+++ b/src/main/java/org/apache/sling/testing/clients/util/config/InstanceConfig.java
@@ -28,7 +28,7 @@ public interface InstanceConfig {
      * @return this
      * @throws InstanceConfigException if saving the configuration fails
      */
-    public InstanceConfig save() throws InstanceConfigException;
+    public InstanceConfig save() throws InstanceConfigException, InterruptedException;
 
     /**
      * Restores the saved status of the configuration
@@ -36,5 +36,5 @@ public interface InstanceConfig {
      * @return this
      * @throws InstanceConfigException if restoring the configuration fails
      */
-    public InstanceConfig restore() throws InstanceConfigException;
+    public InstanceConfig restore() throws InstanceConfigException, InterruptedException;
 }
diff --git a/src/main/java/org/apache/sling/testing/clients/util/config/impl/InstanceConfigCacheImpl.java b/src/main/java/org/apache/sling/testing/clients/util/config/impl/InstanceConfigCacheImpl.java
index 4bae77f..7a82d4b 100644
--- a/src/main/java/org/apache/sling/testing/clients/util/config/impl/InstanceConfigCacheImpl.java
+++ b/src/main/java/org/apache/sling/testing/clients/util/config/impl/InstanceConfigCacheImpl.java
@@ -103,7 +103,7 @@ public class InstanceConfigCacheImpl implements InstanceConfigCache {
 
 
     @Override
-    public InstanceConfig save() throws InstanceConfigException {
+    public InstanceConfig save() throws InstanceConfigException, InterruptedException {
         for (InstanceConfig ic : configs) {
             ic.save();
         }
@@ -111,7 +111,7 @@ public class InstanceConfigCacheImpl implements InstanceConfigCache {
     }
 
     @Override
-    public InstanceConfig restore() throws InstanceConfigException {
+    public InstanceConfig restore() throws InstanceConfigException, InterruptedException {
         for (InstanceConfig ic : configs) {
             ic.restore();
         }
diff --git a/src/main/java/org/apache/sling/testing/clients/util/poller/AbstractPoller.java b/src/main/java/org/apache/sling/testing/clients/util/poller/AbstractPoller.java
index 57c34c3..87b42c6 100644
--- a/src/main/java/org/apache/sling/testing/clients/util/poller/AbstractPoller.java
+++ b/src/main/java/org/apache/sling/testing/clients/util/poller/AbstractPoller.java
@@ -16,6 +16,11 @@
  */
 package org.apache.sling.testing.clients.util.poller;
 
+/**
+ * @deprecated use {@link Polling} instead.
+ * @see Polling for a better way to implement polling
+ */
+@Deprecated
 public abstract class AbstractPoller  implements Poller {
 
     private final long waitInterval;
diff --git a/src/main/java/org/apache/sling/testing/clients/util/poller/PathPoller.java b/src/main/java/org/apache/sling/testing/clients/util/poller/PathPoller.java
index 61a1ee1..cdbbf93 100644
--- a/src/main/java/org/apache/sling/testing/clients/util/poller/PathPoller.java
+++ b/src/main/java/org/apache/sling/testing/clients/util/poller/PathPoller.java
@@ -26,6 +26,7 @@ import org.slf4j.LoggerFactory;
 /**
  * Allows polling for a resource
  */
+@Deprecated
 public class PathPoller extends AbstractPoller {
     private static final Logger LOG = LoggerFactory.getLogger(PathPoller.class);
     private final AbstractSlingClient client;
diff --git a/src/main/java/org/apache/sling/testing/clients/util/poller/Poller.java b/src/main/java/org/apache/sling/testing/clients/util/poller/Poller.java
index e772edb..7ac2500 100644
--- a/src/main/java/org/apache/sling/testing/clients/util/poller/Poller.java
+++ b/src/main/java/org/apache/sling/testing/clients/util/poller/Poller.java
@@ -19,7 +19,11 @@ package org.apache.sling.testing.clients.util.poller;
 /**
  * Abstract Poller interface.
  * Provides simple methods to implement custom pollers
+ *
+ * @deprecated use {@link Polling} instead.
+ * @see Polling for a better way to implement polling
  */
+@Deprecated
 public interface Poller {
     boolean call();
     boolean condition();
diff --git a/src/main/java/org/apache/sling/testing/clients/util/poller/package-info.java b/src/main/java/org/apache/sling/testing/clients/util/poller/package-info.java
index 4ff5bb0..4d723bb 100644
--- a/src/main/java/org/apache/sling/testing/clients/util/poller/package-info.java
+++ b/src/main/java/org/apache/sling/testing/clients/util/poller/package-info.java
@@ -17,7 +17,7 @@
  * under the License.
  */
 
-@Version("1.0.0")
+@Version("1.1.0")
 package org.apache.sling.testing.clients.util.poller;
 
 import org.osgi.annotation.versioning.Version;

-- 
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.

[sling-org-apache-sling-testing-clients] 05/08: SLING-6853 Fixed incomplete patch.

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to annotated tag org.apache.sling.testing.clients-1.1.0
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-testing-clients.git

commit a06ceb1265a678a3e7820441ff8152062c59cd53
Author: Andrei Dulvac <du...@apache.org>
AuthorDate: Tue May 16 15:03:12 2017 +0000

    SLING-6853 Fixed incomplete patch.
    
    
    git-svn-id: https://svn.apache.org/repos/asf/sling/trunk/testing/http/clients@1795326 13f79535-47bb-0310-9956-ffa450edef68
---
 .../sling/testing/clients/util/poller/Polling.java | 131 +++++++++++++++
 .../sling/testing/clients/HttpServerRule.java      |  84 ++++++++++
 .../testing/clients/SlingClientDoGetJsonTest.java  |  71 ++++++++
 .../testing/clients/SlingClientWaitExistsTest.java |  93 +++++++++++
 .../testing/clients/util/poller/PollingTest.java   | 179 +++++++++++++++++++++
 5 files changed, 558 insertions(+)

diff --git a/src/main/java/org/apache/sling/testing/clients/util/poller/Polling.java b/src/main/java/org/apache/sling/testing/clients/util/poller/Polling.java
new file mode 100644
index 0000000..faef6b2
--- /dev/null
+++ b/src/main/java/org/apache/sling/testing/clients/util/poller/Polling.java
@@ -0,0 +1,131 @@
+/*
+ * 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.clients.util.poller;
+
+import org.apache.sling.testing.timeouts.TimeoutsProvider;
+
+import java.util.concurrent.Callable;
+import java.util.concurrent.TimeoutException;
+
+/**
+ * Helper for repeating a call until it returns true, with timeout capabilities.
+ * Subclasses should override the {@link #call()} method.
+ * Can be used with lambda expressions, using the constructor {@link #Polling(Callable c)}.
+ *
+ * @since 1.1.0
+ */
+public class Polling implements Callable<Boolean> {
+
+    /**
+     * Optional object to be used by the default implementation of call()
+     */
+    protected final Callable<Boolean> c;
+
+    /**
+     * Holder for the last exception thrown by call(), to be used for logging
+     */
+    protected Exception lastException;
+
+    /**
+     * Default constructor to be used in subclasses that override the {@link #call()} method.
+     * Should not be used directly on {@code Polling} instances, but only on extended classes.
+     * If used directly to get a {@code Polling} instance, executing {@link #poll(long timeout, long delay)}
+     * will be equivalent to {@code Thread.sleep(timeout)}
+     */
+    public Polling() {
+        this.c = null;
+        this.lastException = null;
+    }
+
+    /**
+     * Creates a new instance that uses the {@code Callable} parameter for polling
+     *
+     * @param c object whose {@code call()} method will be polled
+     */
+    public Polling(Callable<Boolean> c) {
+        this.c = c;
+        this.lastException = null;
+    }
+
+    /**
+     * <p>Method to be called by {@link #poll(long timeout, long delay)}, potentially multiple times,
+     * until it returns true or timeout is reached.<br/>
+     * Subclasses can override it to change the check accordingly. The method should return true
+     * only when the call was successful.<br/>
+     * It can return false or throw any {@code Exception} to make the poller try again later.</p>
+     *
+     * <p>The default implementation delegates the call to the {@code Callable c} instance.</p>
+     *
+     * @return {@code true} to end polling
+     * @throws Exception if unable to compute a result
+     */
+    @Override
+    public Boolean call() throws Exception {
+        if (c != null) {
+            return c.call();
+        } else {
+            return false;
+        }
+    }
+
+    /**
+     * <p>Tries to execute {@link #call()} until it returns true or until {@code timeout} is reached.
+     * Between retries, it waits using {@code Thread.sleep(delay)}. It means the retry is not at a fixed pace,
+     * but depends on the execution time of the call itself.</p>
+     * <p>The method guarantees that the call() will be executed at least once. If the timeout is 0 or less, then
+     * call() will be executed exactly once.</p>
+     * <p>The timeout is adjusted using {@link TimeoutsProvider} so the final value can be changed using the
+     * system property: {@value org.apache.sling.testing.timeouts.TimeoutsProvider#PROP_TIMEOUT_MULTIPLIER}</p>
+     *
+     * @param timeout max total execution time, in milliseconds
+     * @param delay time to wait between calls, in milliseconds
+     *
+     * @throws TimeoutException if {@code timeout} was reached
+     * @throws InterruptedException if the thread was interrupted while sleeping; caller should throw it further
+     */
+    public void poll(long timeout, long delay) throws TimeoutException, InterruptedException {
+        long start = System.currentTimeMillis();
+        long effectiveTimeout = TimeoutsProvider.getInstance().getTimeout(timeout);
+
+        do {
+            try {
+                boolean success = call();
+                if (success) {
+                    return;
+                }
+                Thread.sleep(delay);
+            } catch (InterruptedException e) {
+                throw e;
+            } catch (Exception e) {
+                lastException = e;
+            }
+        } while (System.currentTimeMillis() < start + effectiveTimeout);
+
+        throw new TimeoutException(String.format(message(), effectiveTimeout, delay));
+    }
+
+    /**
+     * Returns the string to be used in the {@code TimeoutException}, if needed.
+     * The string is passed to {@code String.format(message(), timeout, delay)}, so it can be a format
+     * including {@code %1$} and {@code %2$}. The field {@code lastException} is also available for logging
+     *
+     * @return the format string
+     */
+    protected String message() {
+        return "Call failed to return true in %1$d ms. Last exception was: " + lastException;
+    }
+}
diff --git a/src/test/java/org/apache/sling/testing/clients/HttpServerRule.java b/src/test/java/org/apache/sling/testing/clients/HttpServerRule.java
new file mode 100644
index 0000000..926f79b
--- /dev/null
+++ b/src/test/java/org/apache/sling/testing/clients/HttpServerRule.java
@@ -0,0 +1,84 @@
+/*******************************************************************************
+ * 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
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * 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.clients;
+
+import java.io.IOException;
+import java.net.URI;
+import java.util.concurrent.TimeUnit;
+
+import org.apache.http.HttpHost;
+import org.apache.http.client.utils.URIUtils;
+import org.apache.http.config.SocketConfig;
+import org.apache.http.impl.bootstrap.HttpServer;
+import org.apache.http.impl.bootstrap.ServerBootstrap;
+import org.apache.http.localserver.SSLTestContexts;
+import org.junit.rules.ExternalResource;
+
+/** JUnit Rule that starts an HTTP server */
+public class HttpServerRule extends ExternalResource {
+    public static final String ORIGIN = "TEST/1.1";
+    private HttpServer server;
+    private HttpHost host;
+    private URI uri;
+
+    protected ServerBootstrap serverBootstrap;
+
+    public static enum ProtocolScheme {
+        http,
+        https;
+        private ProtocolScheme() {
+        }
+    }
+
+    protected final ProtocolScheme protocolScheme;
+
+    public HttpServerRule() {
+        this(ProtocolScheme.http);
+    }
+
+    public HttpServerRule(ProtocolScheme protocolScheme) {
+        this.protocolScheme = protocolScheme;
+    }
+
+    @Override
+    protected void after() {
+        server.shutdown(-1, TimeUnit.SECONDS);
+    }
+
+    @Override
+    protected void before() throws Throwable {
+        final SocketConfig socketConfig = SocketConfig.custom().setSoTimeout(5000).build();
+        serverBootstrap = ServerBootstrap.bootstrap().setSocketConfig(socketConfig).setServerInfo(ORIGIN);
+        if(ProtocolScheme.https.equals(protocolScheme)) {
+            serverBootstrap.setSslContext(SSLTestContexts.createServerSSLContext());
+        }
+        registerHandlers();
+        server = serverBootstrap.create();
+        server.start();
+        host = new HttpHost("127.0.0.1", server.getLocalPort(), protocolScheme.name());
+        uri = URIUtils.rewriteURI(new URI("/"), host);
+    }
+
+    protected void registerHandlers() throws IOException {
+    }
+
+    public URI getURI() {
+        return uri;
+    }
+}
\ No newline at end of file
diff --git a/src/test/java/org/apache/sling/testing/clients/SlingClientDoGetJsonTest.java b/src/test/java/org/apache/sling/testing/clients/SlingClientDoGetJsonTest.java
new file mode 100644
index 0000000..6eeba23
--- /dev/null
+++ b/src/test/java/org/apache/sling/testing/clients/SlingClientDoGetJsonTest.java
@@ -0,0 +1,71 @@
+/*
+ * 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.clients;
+
+import org.apache.http.HttpException;
+import org.apache.http.HttpRequest;
+import org.apache.http.HttpResponse;
+import org.apache.http.entity.StringEntity;
+import org.apache.http.protocol.HttpContext;
+import org.apache.http.protocol.HttpRequestHandler;
+import org.codehaus.jackson.JsonNode;
+import org.junit.ClassRule;
+import org.junit.Test;
+
+import java.io.IOException;
+
+import static org.junit.Assert.*;
+
+public class SlingClientDoGetJsonTest {
+    private static final String GET_JSON_PATH = "/test/json/resource";
+    private static final String JSON_RESPONSE = "{\"jcr:primaryType\":\"cq:Page\",\"jcr:createdBy\":\"admin-json\"}";
+    private static final String JSON_INF_RESPONSE = "{\"jcr:primaryType\":\"cq:Page\",\"jcr:createdBy\":\"admin-infinity\"}";
+
+    @ClassRule
+    public static HttpServerRule httpServer = new HttpServerRule() {
+        @Override
+        protected void registerHandlers() throws IOException {
+            serverBootstrap.registerHandler(GET_JSON_PATH + ".1.json", new HttpRequestHandler() {
+                @Override
+                public void handle(HttpRequest request, HttpResponse response, HttpContext context) throws HttpException, IOException {
+                    response.setEntity(new StringEntity(JSON_RESPONSE));
+                }
+            });
+
+            serverBootstrap.registerHandler(GET_JSON_PATH + ".infinity.json", new HttpRequestHandler() {
+                @Override
+                public void handle(HttpRequest request, HttpResponse response, HttpContext context) throws HttpException, IOException {
+                    response.setEntity(new StringEntity(JSON_INF_RESPONSE));
+                }
+            });
+        }
+    };
+
+    @Test
+    public void testDoGetJson() throws Exception {
+        SlingClient c = new SlingClient(httpServer.getURI(), "user", "pass");
+        JsonNode res = c.doGetJson(GET_JSON_PATH, 1, 200);
+        assertEquals("admin-json", res.get("jcr:createdBy").getTextValue());
+    }
+
+    @Test
+    public void testDoGetJsonInfinity() throws Exception {
+        SlingClient c = new SlingClient(httpServer.getURI(), "user", "pass");
+        JsonNode res = c.doGetJson(GET_JSON_PATH, -1, 200);
+        assertEquals("admin-infinity", res.get("jcr:createdBy").getTextValue());
+    }
+}
diff --git a/src/test/java/org/apache/sling/testing/clients/SlingClientWaitExistsTest.java b/src/test/java/org/apache/sling/testing/clients/SlingClientWaitExistsTest.java
new file mode 100644
index 0000000..31b67bf
--- /dev/null
+++ b/src/test/java/org/apache/sling/testing/clients/SlingClientWaitExistsTest.java
@@ -0,0 +1,93 @@
+/*
+ * 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.clients;
+
+import org.apache.http.HttpException;
+import org.apache.http.HttpRequest;
+import org.apache.http.HttpResponse;
+import org.apache.http.entity.StringEntity;
+import org.apache.http.protocol.HttpContext;
+import org.apache.http.protocol.HttpRequestHandler;
+import org.junit.Assert;
+import org.junit.ClassRule;
+import org.junit.Test;
+
+import java.io.IOException;
+import java.util.concurrent.TimeoutException;
+
+import static org.junit.Assert.*;
+
+public class SlingClientWaitExistsTest {
+    private static final String GET_WAIT_PATH = "/test/wait/resource";
+    private static final String OK_RESPONSE = "TEST_OK";
+    private static final String NOK_RESPONSE = "TEST_OK";
+
+    private static int waitCount = 4; // truly randomly chosen by typing with the eyes closed
+    private static int callCount = 0;
+
+    @ClassRule
+    public static HttpServerRule httpServer = new HttpServerRule() {
+        @Override
+        protected void registerHandlers() throws IOException {
+            serverBootstrap.registerHandler(GET_WAIT_PATH + ".json", new HttpRequestHandler() {
+                @Override
+                public void handle(HttpRequest request, HttpResponse response, HttpContext context) throws HttpException, IOException {
+                    callCount++;
+                    if (callCount == waitCount) {
+                        response.setEntity(new StringEntity(OK_RESPONSE));
+                    } else {
+                        response.setEntity(new StringEntity(NOK_RESPONSE));
+                        response.setStatusCode(404);
+                    }
+                }
+            });
+        }
+    };
+
+    @Test
+    public void testWaitExists() throws Exception {
+        callCount = 0;  // reset counter
+        waitCount = 3;  // less than timeout
+        SlingClient c = new SlingClient(httpServer.getURI(), "user", "pass");
+        c.waitExists(GET_WAIT_PATH, 500, 10);
+        assertEquals(waitCount, callCount);
+    }
+
+    @Test
+    public void testWaitExistsTimeout() throws Exception {
+        callCount = 0;  // reset counter
+        waitCount = 40;  // to be sure we reach timeout
+        SlingClient c = new SlingClient(httpServer.getURI(), "user", "pass");
+        try {
+            c.waitExists(GET_WAIT_PATH, 200, 10);
+        } catch (TimeoutException e ) {
+            assertTrue("call was executed only " + callCount + " times", callCount > 3);
+            return;
+        }
+
+        fail("waitExists did not timeout");
+    }
+
+    @Test
+    public void testWaitExistsOnce() throws Exception {
+        callCount = 0;  // reset counter
+        waitCount = 1;  // less than timeout
+        SlingClient c = new SlingClient(httpServer.getURI(), "user", "pass");
+        c.waitExists(GET_WAIT_PATH, -1, 10);
+        assertEquals(1, callCount);
+    }
+}
diff --git a/src/test/java/org/apache/sling/testing/clients/util/poller/PollingTest.java b/src/test/java/org/apache/sling/testing/clients/util/poller/PollingTest.java
new file mode 100644
index 0000000..15994ed
--- /dev/null
+++ b/src/test/java/org/apache/sling/testing/clients/util/poller/PollingTest.java
@@ -0,0 +1,179 @@
+/*
+ * 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.clients.util.poller;
+
+import org.apache.commons.lang3.mutable.MutableBoolean;
+import org.apache.commons.lang3.mutable.MutableInt;
+import org.junit.Test;
+
+import java.util.concurrent.Callable;
+import java.util.concurrent.TimeoutException;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+public class PollingTest {
+    @Test
+    public void testCallOnce() throws Exception {
+        final MutableInt callCount = new MutableInt(0);
+        Polling p = new Polling() {
+            @Override
+            public Boolean call() throws Exception {
+                callCount.increment();
+                return true;
+            }
+        };
+        p.poll(500, 10);
+
+        assertEquals(1, callCount.intValue());
+    }
+
+    @Test
+    public void testCallTwice() throws Exception {
+        final MutableInt callCount = new MutableInt(0);
+        final MutableBoolean called = new MutableBoolean(false);
+        Polling p = new Polling() {
+            @Override
+            public Boolean call() throws Exception {
+                callCount.increment();
+                boolean b = called.booleanValue();
+                called.setTrue();
+                return b;
+            }
+        };
+        p.poll(500, 10);
+
+        assertEquals(2, callCount.intValue());
+    }
+
+    @Test
+    public void testCallTimeout() throws Exception {
+        final MutableInt callCount = new MutableInt(0);
+        Polling p = new Polling() {
+            @Override
+            public Boolean call() throws Exception {
+                callCount.increment();
+                return false;
+            }
+        };
+
+        try {
+            p.poll(100, 10);
+        } catch (TimeoutException e ) {
+            assertTrue("Expected to execute call() at least 4 times, got instead only " + callCount.intValue() + " calls",
+                    callCount.intValue() > 5);
+            return;
+        }
+
+        fail("Did not reach timeout");
+    }
+
+    @Test
+    public void testNegativeTimeout() throws Exception {
+        final MutableInt callCount = new MutableInt(0);
+        Polling p = new Polling() {
+            @Override
+            public Boolean call() throws Exception {
+                callCount.increment();
+                return true;
+            }
+        };
+        p.poll(-1, 10);
+
+        assertEquals(1, callCount.intValue());
+    }
+
+    //
+    // Tests with Callable
+    //
+
+    @Test
+    public void testCallableOnce() throws Exception {
+        final MutableInt callCount = new MutableInt(0);
+        final MutableBoolean called = new MutableBoolean(false);
+        Polling p = new Polling(new Callable<Boolean>() {
+            @Override
+            public Boolean call() throws Exception {
+                callCount.increment();
+                return true;
+            }
+        });
+        p.poll(500, 10);
+
+        assertEquals(1, callCount.intValue());
+    }
+
+    @Test
+    public void testCallableTwice() throws Exception {
+        final MutableInt callCount = new MutableInt(0);
+        final MutableBoolean called = new MutableBoolean(false);
+        Polling p = new Polling(new Callable<Boolean>() {
+            @Override
+            public Boolean call() throws Exception {
+                callCount.increment();
+                boolean b = called.booleanValue();
+                called.setTrue();
+                return b;
+            }
+        });
+        p.poll(500, 10);
+
+        assertEquals(2, callCount.intValue());
+    }
+
+    @Test
+    public void testCallableTimeout() throws Exception {
+        final MutableInt callCount = new MutableInt(0);
+        Polling p = new Polling(new Callable<Boolean>() {
+            @Override
+            public Boolean call() throws Exception {
+                callCount.increment();
+                return false;
+            }
+        });
+
+        try {
+            p.poll(100, 10);
+        } catch (TimeoutException e ) {
+            assertTrue("Expected to execute call() at least 4 times, got instead only " + callCount.intValue() + " calls",
+                    callCount.intValue() > 5);
+            return;
+        }
+
+        fail("Did not reach timeout");
+    }
+
+
+    @Test
+    public void testCallPriority() throws Exception {
+        Polling p = new Polling(new Callable<Boolean>() {
+            @Override
+            public Boolean call() throws Exception {
+                return false;
+            }
+        }) {
+            @Override
+            public Boolean call() throws Exception {
+                return true;
+            }
+        };
+
+        // Should not reach timeout since overridden call() has priority over Callable param
+        p.poll(100, 10);
+    }
+}
\ No newline at end of file

-- 
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.

[sling-org-apache-sling-testing-clients] 03/08: use OSGi annotations and remove unused Maven SCR Plugin

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to annotated tag org.apache.sling.testing.clients-1.1.0
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-testing-clients.git

commit 7d6589d2c8d2608f5c1515baa1e263539b8e97d6
Author: Oliver Lietz <ol...@apache.org>
AuthorDate: Mon Mar 6 19:11:05 2017 +0000

    use OSGi annotations and remove unused Maven SCR Plugin
    
    git-svn-id: https://svn.apache.org/repos/asf/sling/trunk/testing/http/clients@1785736 13f79535-47bb-0310-9956-ffa450edef68
---
 pom.xml                                                               | 4 ----
 src/main/java/org/apache/sling/testing/clients/html/package-info.java | 3 +--
 .../java/org/apache/sling/testing/clients/instance/package-info.java  | 3 +--
 .../org/apache/sling/testing/clients/interceptors/package-info.java   | 3 +--
 src/main/java/org/apache/sling/testing/clients/osgi/package-info.java | 4 +++-
 src/main/java/org/apache/sling/testing/clients/package-info.java      | 3 +--
 .../apache/sling/testing/clients/util/config/impl/package-info.java   | 3 +--
 .../org/apache/sling/testing/clients/util/config/package-info.java    | 3 +--
 src/main/java/org/apache/sling/testing/clients/util/package-info.java | 3 +--
 .../org/apache/sling/testing/clients/util/poller/package-info.java    | 3 +--
 10 files changed, 11 insertions(+), 21 deletions(-)

diff --git a/pom.xml b/pom.xml
index af7f357..ff471a4 100644
--- a/pom.xml
+++ b/pom.xml
@@ -43,10 +43,6 @@
     
     <build>
         <plugins>
-           <plugin>
-                <groupId>org.apache.felix</groupId>
-                <artifactId>maven-scr-plugin</artifactId>
-            </plugin>
              <plugin>
                 <groupId>org.apache.felix</groupId>
                 <artifactId>maven-bundle-plugin</artifactId>
diff --git a/src/main/java/org/apache/sling/testing/clients/html/package-info.java b/src/main/java/org/apache/sling/testing/clients/html/package-info.java
index 97b22cb..5f5a9f5 100644
--- a/src/main/java/org/apache/sling/testing/clients/html/package-info.java
+++ b/src/main/java/org/apache/sling/testing/clients/html/package-info.java
@@ -20,5 +20,4 @@
 @Version("2.1.0")
 package org.apache.sling.testing.clients.html;
 
-import aQute.bnd.annotation.Version;
-
+import org.osgi.annotation.versioning.Version;
diff --git a/src/main/java/org/apache/sling/testing/clients/instance/package-info.java b/src/main/java/org/apache/sling/testing/clients/instance/package-info.java
index 43010e9..4d8063e 100644
--- a/src/main/java/org/apache/sling/testing/clients/instance/package-info.java
+++ b/src/main/java/org/apache/sling/testing/clients/instance/package-info.java
@@ -20,5 +20,4 @@
 @Version("1.1.0")
 package org.apache.sling.testing.clients.instance;
 
-import aQute.bnd.annotation.Version;
-
+import org.osgi.annotation.versioning.Version;
diff --git a/src/main/java/org/apache/sling/testing/clients/interceptors/package-info.java b/src/main/java/org/apache/sling/testing/clients/interceptors/package-info.java
index 49e7065..0f097b5 100644
--- a/src/main/java/org/apache/sling/testing/clients/interceptors/package-info.java
+++ b/src/main/java/org/apache/sling/testing/clients/interceptors/package-info.java
@@ -20,5 +20,4 @@
 @Version("1.0.1")
 package org.apache.sling.testing.clients.interceptors;
 
-import aQute.bnd.annotation.Version;
-
+import org.osgi.annotation.versioning.Version;
diff --git a/src/main/java/org/apache/sling/testing/clients/osgi/package-info.java b/src/main/java/org/apache/sling/testing/clients/osgi/package-info.java
index 3a2f85e..119cb90 100644
--- a/src/main/java/org/apache/sling/testing/clients/osgi/package-info.java
+++ b/src/main/java/org/apache/sling/testing/clients/osgi/package-info.java
@@ -19,5 +19,7 @@
 /**
  * OSGI testing tools.
  */
-@aQute.bnd.annotation.Version("1.1.0")
+@Version("1.1.0")
 package org.apache.sling.testing.clients.osgi;
+
+import org.osgi.annotation.versioning.Version;
diff --git a/src/main/java/org/apache/sling/testing/clients/package-info.java b/src/main/java/org/apache/sling/testing/clients/package-info.java
index d9cf961..c7b45c6 100644
--- a/src/main/java/org/apache/sling/testing/clients/package-info.java
+++ b/src/main/java/org/apache/sling/testing/clients/package-info.java
@@ -20,5 +20,4 @@
 @Version("1.2.0")
 package org.apache.sling.testing.clients;
 
-import aQute.bnd.annotation.Version;
-
+import org.osgi.annotation.versioning.Version;
diff --git a/src/main/java/org/apache/sling/testing/clients/util/config/impl/package-info.java b/src/main/java/org/apache/sling/testing/clients/util/config/impl/package-info.java
index d6bfe66..e085e7e 100644
--- a/src/main/java/org/apache/sling/testing/clients/util/config/impl/package-info.java
+++ b/src/main/java/org/apache/sling/testing/clients/util/config/impl/package-info.java
@@ -20,5 +20,4 @@
 @Version("1.0.0")
 package org.apache.sling.testing.clients.util.config.impl;
 
-import aQute.bnd.annotation.Version;
-
+import org.osgi.annotation.versioning.Version;
diff --git a/src/main/java/org/apache/sling/testing/clients/util/config/package-info.java b/src/main/java/org/apache/sling/testing/clients/util/config/package-info.java
index 59d0aaa..025052b 100644
--- a/src/main/java/org/apache/sling/testing/clients/util/config/package-info.java
+++ b/src/main/java/org/apache/sling/testing/clients/util/config/package-info.java
@@ -20,5 +20,4 @@
 @Version("1.0.0")
 package org.apache.sling.testing.clients.util.config;
 
-import aQute.bnd.annotation.Version;
-
+import org.osgi.annotation.versioning.Version;
diff --git a/src/main/java/org/apache/sling/testing/clients/util/package-info.java b/src/main/java/org/apache/sling/testing/clients/util/package-info.java
index 048ebae..7d4ac3b 100644
--- a/src/main/java/org/apache/sling/testing/clients/util/package-info.java
+++ b/src/main/java/org/apache/sling/testing/clients/util/package-info.java
@@ -20,5 +20,4 @@
 @Version("1.0.0")
 package org.apache.sling.testing.clients.util;
 
-import aQute.bnd.annotation.Version;
-
+import org.osgi.annotation.versioning.Version;
diff --git a/src/main/java/org/apache/sling/testing/clients/util/poller/package-info.java b/src/main/java/org/apache/sling/testing/clients/util/poller/package-info.java
index 6367401..4ff5bb0 100644
--- a/src/main/java/org/apache/sling/testing/clients/util/poller/package-info.java
+++ b/src/main/java/org/apache/sling/testing/clients/util/poller/package-info.java
@@ -20,5 +20,4 @@
 @Version("1.0.0")
 package org.apache.sling.testing.clients.util.poller;
 
-import aQute.bnd.annotation.Version;
-
+import org.osgi.annotation.versioning.Version;

-- 
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.

[sling-org-apache-sling-testing-clients] 06/08: SLING-6905: Remove commons.json from testing http clients by using already used jackson library. Patch provided by Valentin Olteanu. This closes #235.

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to annotated tag org.apache.sling.testing.clients-1.1.0
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-testing-clients.git

commit e3911b9bc0d0f0d4afdb7d8fcf30734375b565e5
Author: Karl Pauls <pa...@apache.org>
AuthorDate: Tue May 30 08:41:19 2017 +0000

    SLING-6905: Remove commons.json from testing http clients by using already used jackson library. Patch provided by Valentin Olteanu. This closes #235.
    
    git-svn-id: https://svn.apache.org/repos/asf/sling/trunk/testing/http/clients@1796802 13f79535-47bb-0310-9956-ffa450edef68
---
 pom.xml                                            |  5 --
 .../testing/clients/osgi/OsgiConsoleClient.java    | 72 +++++++++++-----------
 2 files changed, 35 insertions(+), 42 deletions(-)

diff --git a/pom.xml b/pom.xml
index be389da..1b42b85 100644
--- a/pom.xml
+++ b/pom.xml
@@ -131,11 +131,6 @@
             <artifactId>org.apache.sling.xss</artifactId>
             <version>1.0.4</version>
         </dependency>
-        <dependency>
-            <groupId>org.apache.sling</groupId>
-            <artifactId>org.apache.sling.commons.json</artifactId>
-            <version>2.0.16</version>
-        </dependency>
 
         <!-- For tests -->
         <dependency>
diff --git a/src/main/java/org/apache/sling/testing/clients/osgi/OsgiConsoleClient.java b/src/main/java/org/apache/sling/testing/clients/osgi/OsgiConsoleClient.java
index 8dd8ca2..1253d76 100644
--- a/src/main/java/org/apache/sling/testing/clients/osgi/OsgiConsoleClient.java
+++ b/src/main/java/org/apache/sling/testing/clients/osgi/OsgiConsoleClient.java
@@ -20,9 +20,6 @@ package org.apache.sling.testing.clients.osgi;
 import org.apache.http.Header;
 import org.apache.http.entity.mime.MultipartEntityBuilder;
 import org.apache.http.impl.client.CloseableHttpClient;
-import org.apache.sling.commons.json.JSONArray;
-import org.apache.sling.commons.json.JSONException;
-import org.apache.sling.commons.json.JSONObject;
 import org.apache.sling.testing.clients.ClientException;
 import org.apache.sling.testing.clients.SlingClient;
 import org.apache.sling.testing.clients.SlingClientConfig;
@@ -511,12 +508,14 @@ public class OsgiConsoleClient extends SlingClient {
      * @throws ClientException if the id cannot be retrieved
      */
     public long getBundleId(String symbolicName) throws ClientException {
-        final JSONObject bundle = getBundleData(symbolicName);
-        try {
-            return bundle.getLong(JSON_KEY_ID);
-        } catch (JSONException e) {
-            throw new ClientException("Cannot get id from json", e);
+        final JsonNode bundle = getBundleData(symbolicName);
+        final JsonNode idNode = bundle.get(JSON_KEY_ID);
+
+        if (idNode == null) {
+            throw new ClientException("Cannot get id from bundle json");
         }
+
+        return idNode.getLongValue();
     }
 
     /**
@@ -526,12 +525,14 @@ public class OsgiConsoleClient extends SlingClient {
      * @throws ClientException
      */
     public String getBundleVersion(String symbolicName) throws ClientException {
-        final JSONObject bundle = getBundleData(symbolicName);
-        try {
-            return bundle.getString(JSON_KEY_VERSION);
-        } catch (JSONException e) {
-            throw new ClientException("Cannot get version from json", e);
+        final JsonNode bundle = getBundleData(symbolicName);
+        final JsonNode versionNode = bundle.get(JSON_KEY_VERSION);
+
+        if (versionNode == null) {
+            throw new ClientException("Cannot get version from bundle json");
         }
+
+        return versionNode.getTextValue();
     }
 
     /**
@@ -541,12 +542,14 @@ public class OsgiConsoleClient extends SlingClient {
      * @throws ClientException if the state cannot be retrieved
      */
     public String getBundleState(String symbolicName) throws ClientException {
-        final JSONObject bundle = getBundleData(symbolicName);
-        try {
-            return bundle.getString(JSON_KEY_STATE);
-        } catch (JSONException e) {
-            throw new ClientException("Cannot get state from json", e);
+        final JsonNode bundle = getBundleData(symbolicName);
+        final JsonNode stateNode = bundle.get(JSON_KEY_STATE);
+
+        if (stateNode == null) {
+            throw new ClientException("Cannot get state from bundle json");
         }
+
+        return stateNode.getTextValue();
     }
 
     /**
@@ -635,31 +638,26 @@ public class OsgiConsoleClient extends SlingClient {
      *   }]
      * }
      */
-    private JSONObject getBundleData(String symbolicName) throws ClientException {
+    private JsonNode getBundleData(String symbolicName) throws ClientException {
         final String path = getBundlePath(symbolicName, ".json");
         final String content = this.doGet(path, SC_OK).getContent();
+        final JsonNode root = JsonUtils.getJsonNodeFromString(content);
 
-        try {
-            final JSONObject root = new JSONObject(content);
-
-            if (!root.has(JSON_KEY_DATA)) {
-                throw new ClientException(path + " does not provide '" + JSON_KEY_DATA + "' element, JSON content=" + content);
-            }
-
-            final JSONArray data = root.getJSONArray(JSON_KEY_DATA);
-            if (data.length() < 1) {
-                throw new ClientException(path + "." + JSON_KEY_DATA + " is empty, JSON content=" + content);
-            }
+        if (root.get(JSON_KEY_DATA) == null) {
+            throw new ClientException(path + " does not provide '" + JSON_KEY_DATA + "' element, JSON content=" + content);
+        }
 
-            final JSONObject bundle = data.getJSONObject(0);
-            if (!bundle.has(JSON_KEY_STATE)) {
-                throw new ClientException(path + ".data[0].state missing, JSON content=" + content);
-            }
+        Iterator<JsonNode> data = root.get(JSON_KEY_DATA).getElements();
+        if (!data.hasNext()) {
+            throw new ClientException(path + "." + JSON_KEY_DATA + " is empty, JSON content=" + content);
+        }
 
-            return bundle;
-        } catch (JSONException e) {
-            throw new ClientException("Cannot get json", e);
+        final JsonNode bundle = data.next();
+        if (bundle.get(JSON_KEY_STATE) == null) {
+            throw new ClientException(path + ".data[0].state missing, JSON content=" + content);
         }
+
+        return bundle;
     }
 
     //

-- 
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.

[sling-org-apache-sling-testing-clients] 08/08: [maven-release-plugin] copy for tag org.apache.sling.testing.clients-1.1.0

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to annotated tag org.apache.sling.testing.clients-1.1.0
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-testing-clients.git

commit 0bc914243a02816ca07bb714b0181d4eaa20c02f
Author: Karl Pauls <pa...@apache.org>
AuthorDate: Fri Jun 2 21:22:00 2017 +0000

    [maven-release-plugin] copy for tag org.apache.sling.testing.clients-1.1.0
    
    git-svn-id: https://svn.apache.org/repos/asf/sling/tags/org.apache.sling.testing.clients-1.1.0@1797450 13f79535-47bb-0310-9956-ffa450edef68

-- 
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.