You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by kw...@apache.org on 2017/02/23 15:58:46 UTC

svn commit: r1784163 - in /sling/trunk/testing/junit/teleporter/src: main/java/org/apache/sling/testing/teleporter/client/ test/java/org/apache/sling/testing/teleporter/client/

Author: kwin
Date: Thu Feb 23 15:58:46 2017
New Revision: 1784163

URL: http://svn.apache.org/viewvc?rev=1784163&view=rev
Log:
SLING-5668 allow to configure bundle headers via the DefaultPropertyBasedCustomizer

Modified:
    sling/trunk/testing/junit/teleporter/src/main/java/org/apache/sling/testing/teleporter/client/ClientSideTeleporter.java
    sling/trunk/testing/junit/teleporter/src/main/java/org/apache/sling/testing/teleporter/client/DefaultPropertyBasedCustomizer.java
    sling/trunk/testing/junit/teleporter/src/main/java/org/apache/sling/testing/teleporter/client/TeleporterHttpClient.java
    sling/trunk/testing/junit/teleporter/src/test/java/org/apache/sling/testing/teleporter/client/DefaultPropertyBasedCustomizerTest.java

Modified: sling/trunk/testing/junit/teleporter/src/main/java/org/apache/sling/testing/teleporter/client/ClientSideTeleporter.java
URL: http://svn.apache.org/viewvc/sling/trunk/testing/junit/teleporter/src/main/java/org/apache/sling/testing/teleporter/client/ClientSideTeleporter.java?rev=1784163&r1=1784162&r2=1784163&view=diff
==============================================================================
--- sling/trunk/testing/junit/teleporter/src/main/java/org/apache/sling/testing/teleporter/client/ClientSideTeleporter.java (original)
+++ sling/trunk/testing/junit/teleporter/src/main/java/org/apache/sling/testing/teleporter/client/ClientSideTeleporter.java Thu Feb 23 15:58:46 2017
@@ -86,6 +86,7 @@ public class ClientSideTeleporter extend
             .add(c);
 
         for(Map.Entry<String, String> header : additionalBundleHeaders.entrySet()) {
+            log.info("Add bundle header '{}' with value '{}'", header.getKey(), header.getValue());
             b.set(header.getKey(), header.getValue());
         }
         
@@ -193,10 +194,14 @@ public class ClientSideTeleporter extend
     }
     
     /** Set additional bundle headers on the generated test bundle */
+    public void addAdditionalBundleHeader(String name, String value) {
+        additionalBundleHeaders.put(name, value);
+    }
+    
     public Map<String, String> getAdditionalBundleHeaders() {
         return additionalBundleHeaders;
     }
-
+    
     public void setEnableLogging(boolean enableLogging) {
         this.enableLogging = enableLogging;
         this.initLogger();

Modified: sling/trunk/testing/junit/teleporter/src/main/java/org/apache/sling/testing/teleporter/client/DefaultPropertyBasedCustomizer.java
URL: http://svn.apache.org/viewvc/sling/trunk/testing/junit/teleporter/src/main/java/org/apache/sling/testing/teleporter/client/DefaultPropertyBasedCustomizer.java?rev=1784163&r1=1784162&r2=1784163&view=diff
==============================================================================
--- sling/trunk/testing/junit/teleporter/src/main/java/org/apache/sling/testing/teleporter/client/DefaultPropertyBasedCustomizer.java (original)
+++ sling/trunk/testing/junit/teleporter/src/main/java/org/apache/sling/testing/teleporter/client/DefaultPropertyBasedCustomizer.java Thu Feb 23 15:58:46 2017
@@ -26,39 +26,47 @@ import org.apache.sling.junit.rules.Tele
 import org.apache.sling.junit.rules.TeleporterRule.Customizer;
 
 /**
- * This is the default {@link Customizer} which is used in case {@code TeleporterRule.forClass(Class)} was called.
- * It relies on system properties to configure the important aspects of teleporting.
- * <br>
- * It assumes that there is already a running Sling server at the given baseUrl.
- * To provision such a server the <a href="https://sling.apache.org/documentation/development/slingstart.html#slingstart-maven-plugin">slingstart-maven-plugin</a>
- * could be used for example.
- * <br>
+ * This is the default {@link Customizer} which is used in case {@code TeleporterRule.forClass(Class)} was called. It relies on system
+ * properties to configure the important aspects of teleporting. <br>
+ * It assumes that there is already a running Sling server at the given baseUrl. To provision such a server the
+ * <a href="https://sling.apache.org/documentation/development/slingstart.html#slingstart-maven-plugin">slingstart-maven-plugin</a> could be
+ * used for example. <br>
  * The following system properties must be set for this Customizer to work
- *  <ul>
- *      <li>{@code ClientSideTeleporter.baseUrl}, the server url on which Sling is already running</li>
+ * <ul>
+ * <li>{@code ClientSideTeleporter.baseUrl}, the server url on which Sling is already running</li>
  * </ul>
  * 
  * The following system properties may be set to further tweak the behavior:
  * <ul>
- *      <li>{@code ClientSideTeleporter.includeDependencyPrefixes}, comma-separated list of package prefixes for classes referenced from the IT. 
- *      Only the classes having one of the given package prefix are included in the bundle being deployed to the given Sling instance together with the IT class itself. 
- *      They are only included though in case they are referenced! If this is not set, no referenced classes will be included.</li>
- *      <li>{@code ClientSideTeleporter.excludeDependencyPrefixes}, comma-separated list of package prefixes for classes referenced from the IT. 
- *      Classes having one of the given package prefix will not be included in the bundle being deployed to the given Sling instance together with the IT class itself. 
- *      This takes precedence over the {@code ClientSideTeleporter.includeDependencyPrefixes}.</li>
- *      <li>{@code ClientSideTeleporter.embedClasses}, comma-separated list of fully qualified class names which should be embedded in the test bundle.
- *      Use this only for classes which are not detected automatically by the Maven Dependency Analyzer but still should be embedded in the test bundle</li>
- *      <li>{@code ClientSideTeleporter.embedClassesDirectories}, comma-separated list directories containing classfiles which should be embedded in the test bundle.
- *      Use this only for classes which are not detected automatically by the Maven Dependency Analyzer but still should be embedded in the test bundle</li>
- *      <li>{@code ClientSideTeleporter.testReadyTimeoutSeconds}, how long to wait for our test to be ready on the server-side in seconds, after installing the test bundle. By default {@code 12}.</li>
- *      <li>{@code ClientSideTeleporter.serverUsername}, the username with which to send requests to the Sling server. By default {@code admin}.</li>
- *      <li>{@code ClientSideTeleporter.serverPassword}, the password with which to send requests to the Sling server. By default {@code admin}.</li>
- *      <li>{@code ClientSideTeleporter.enableLogging}, set to true to log the tasks being performed by the teleporter. Useful for debugging.</li>
- *      <li>{@code ClientSideTeleporter.preventToUninstallBundle}, set to true to not automatically uninstall the test bundle after test execution. Useful for debugging.</li>
- *      <li>{@code ClientSideTeleporter.testBundleDirectory}, if set the test bundles are being persisted (before being installed) within the given directory name. 
- *      If the directory does not exist, it will be automatically created. Useful for debugging.</li>
+ * <li>{@code ClientSideTeleporter.includeDependencyPrefixes}, comma-separated list of package prefixes for classes referenced from the IT.
+ * Only the classes having one of the given package prefix are included in the bundle being deployed to the given Sling instance together
+ * with the IT class itself. They are only included though in case they are referenced! If this is not set, no referenced classes will be
+ * included.</li>
+ * <li>{@code ClientSideTeleporter.excludeDependencyPrefixes}, comma-separated list of package prefixes for classes referenced from the IT.
+ * Classes having one of the given package prefix will not be included in the bundle being deployed to the given Sling instance together
+ * with the IT class itself. This takes precedence over the {@code ClientSideTeleporter.includeDependencyPrefixes}.</li>
+ * <li>{@code ClientSideTeleporter.embedClasses}, comma-separated list of fully qualified class names which should be embedded in the test
+ * bundle. Use this only for classes which are not detected automatically by the Maven Dependency Analyzer but still should be embedded in
+ * the test bundle</li>
+ * <li>{@code ClientSideTeleporter.embedClassesDirectories}, comma-separated list directories containing class files which should be
+ * embedded in the test bundle. Use this only for classes which are not detected automatically by the Maven Dependency Analyzer but still
+ * should be embedded in the test bundle</li>
+ * <li>{@code ClientSideTeleporter.additionalBundleHeaders}, comma-separated list of entries in the format {@code <name>:<value>} which
+ * should be added to the test bundle as additional headers</li>
+ * <li>{@code ClientSideTeleporter.testReadyTimeoutSeconds}, how long to wait for our test to be ready on the server-side in seconds, after
+ * installing the test bundle. By default {@code 12}.</li>
+ * <li>{@code ClientSideTeleporter.serverUsername}, the username with which to send requests to the Sling server. By default
+ * {@code admin}.</li>
+ * <li>{@code ClientSideTeleporter.serverPassword}, the password with which to send requests to the Sling server. By default
+ * {@code admin}.</li>
+ * <li>{@code ClientSideTeleporter.enableLogging}, set to true to log the tasks being performed by the teleporter. Useful for
+ * debugging.</li>
+ * <li>{@code ClientSideTeleporter.preventToUninstallBundle}, set to true to not automatically uninstall the test bundle after test
+ * execution. Useful for debugging.</li>
+ * <li>{@code ClientSideTeleporter.testBundleDirectory}, if set the test bundles are being persisted (before being installed) within the
+ * given directory name. If the directory does not exist, it will be automatically created. Useful for debugging.</li>
  * </ul>
- */
+*/
 public class DefaultPropertyBasedCustomizer implements Customizer {
     static final String PROPERTY_BASE_URL = "ClientSideTeleporter.baseUrl";
     static final String PROPERTY_INCLUDE_DEPENDENCY_PREFIXES = "ClientSideTeleporter.includeDependencyPrefixes";
@@ -71,9 +79,11 @@ public class DefaultPropertyBasedCustomi
     static final String PROPERTY_TESTBUNDLE_DIRECTORY = "ClientSideTeleporter.testBundleDirectory";
     static final String PROPERTY_ENABLE_LOGGING = "ClientSideTeleporter.enableLogging";
     static final String PROPERTY_PREVENT_TO_UNINSTALL_BUNDLE = "ClientSideTeleporter.preventToUninstallBundle";
-    
+    static final String PROPERTY_ADDITIONAL_BUNDLE_HEADERS = "ClientSideTeleporter.additionalBundleHeaders";
+
     static final String LIST_SEPARATOR = ",";
-    
+    static final String NAME_VALUE_SEPARATOR = ":";
+
     private final int testReadyTimeout;
     private final String serverUsername;
     private final String serverPassword;
@@ -85,6 +95,7 @@ public class DefaultPropertyBasedCustomi
     private final String testBundleDirectory;
     private final boolean enableLogging;
     private final boolean preventToUninstallBundle;
+    private final String additionalBundleHeaders;
 
     public DefaultPropertyBasedCustomizer() {
         testReadyTimeout = Integer.getInteger(PROPERTY_TESTREADY_TIMEOUT_SECONDS, 12);
@@ -95,6 +106,7 @@ public class DefaultPropertyBasedCustomi
         embedClasses = System.getProperty(PROPERTY_EMBED_CLASSES);
         embedClassesDirectories = System.getProperty(PROPERTY_EMBED_CLASSES_DIRECTORIES);
         baseUrl = System.getProperty(PROPERTY_BASE_URL);
+        additionalBundleHeaders = System.getProperty(PROPERTY_ADDITIONAL_BUNDLE_HEADERS);
         testBundleDirectory = System.getProperty(PROPERTY_TESTBUNDLE_DIRECTORY);
         enableLogging = Boolean.getBoolean(PROPERTY_ENABLE_LOGGING);
         preventToUninstallBundle = Boolean.getBoolean(PROPERTY_PREVENT_TO_UNINSTALL_BUNDLE);
@@ -151,5 +163,18 @@ public class DefaultPropertyBasedCustomi
                 }
             }
         }
+        if (StringUtils.isNotBlank(additionalBundleHeaders)) {
+            for (String additionalBundleHeader : additionalBundleHeaders.split(LIST_SEPARATOR)) {
+                if (StringUtils.isNotBlank(additionalBundleHeader)) {
+                    // split up by name and value
+                    int pos = additionalBundleHeader.indexOf(NAME_VALUE_SEPARATOR);
+                    if (pos < 1 || pos >= additionalBundleHeader.length() -1) {
+                        fail("Each entry given to property '" + PROPERTY_ADDITIONAL_BUNDLE_HEADERS + 
+                             "' must have exactly the format <name>:<value>, but one entry is '" + additionalBundleHeader + "'.");
+                    }
+                    cst.addAdditionalBundleHeader(additionalBundleHeader.substring(0, pos), additionalBundleHeader.substring(pos+1));
+                }
+            }
+        }
     }
 }

Modified: sling/trunk/testing/junit/teleporter/src/main/java/org/apache/sling/testing/teleporter/client/TeleporterHttpClient.java
URL: http://svn.apache.org/viewvc/sling/trunk/testing/junit/teleporter/src/main/java/org/apache/sling/testing/teleporter/client/TeleporterHttpClient.java?rev=1784163&r1=1784162&r2=1784163&view=diff
==============================================================================
--- sling/trunk/testing/junit/teleporter/src/main/java/org/apache/sling/testing/teleporter/client/TeleporterHttpClient.java (original)
+++ sling/trunk/testing/junit/teleporter/src/main/java/org/apache/sling/testing/teleporter/client/TeleporterHttpClient.java Thu Feb 23 15:58:46 2017
@@ -138,50 +138,60 @@ class TeleporterHttpClient {
         }
     }
     
-    void verifyCorrectBundleState(String bundleSymbolicName, int webConsoleReadyTimeoutSeconds) throws IOException {
+    void verifyCorrectBundleState(String bundleSymbolicName, int timeoutInSeconds) throws IOException {
         final String url = baseUrl + "/system/console/bundles/" + bundleSymbolicName + ".json";
         
-        String jsonBody = waitForStatus(url, 200, webConsoleReadyTimeoutSeconds * 1000);
-        // deserialize json (https://issues.apache.org/jira/browse/SLING-6536)
-        try {
-            JsonReader jsonReader = Json.createReader(new StringReader(jsonBody));
-            // extract state
-            JsonArray jsonArray = jsonReader.readObject().getJsonArray("data");
-            if (jsonArray == null) {
-                throw new JsonException("Could not find 'data' array");
-            }
-            JsonObject bundleObject = jsonArray.getJsonObject(0);
-            String state = bundleObject.getString("state");
-            if ("Active".equals(state)) {
-                return;
-            }
-            // otherwise evaluate the import section
-            JsonArray propsArray = bundleObject.getJsonArray("props");
-            if (propsArray == null) {
-                throw new JsonException("Could not find 'props' object");
-            }
-            // iterate through all of them until key="Imported Packages" is found
-            for (JsonValue propValue : propsArray) {
-                if (propValue.getValueType().equals(ValueType.OBJECT)) {
-                    JsonObject propObject = (JsonObject)propValue;
-                    if ("Imported Packages".equals(propObject.getString("key"))) {
-                        JsonArray importedPackagesArray = propObject.getJsonArray("value");
-                        String reason = "Unknown";
-                        for (JsonValue importedPackageValue : importedPackagesArray) {
-                            if (importedPackageValue.getValueType().equals(ValueType.STRING)) {
-                                String importedPackage = ((JsonString)importedPackageValue).getString();
-                                if (importedPackage.startsWith("ERROR:")) {
-                                    reason = importedPackage;
+        final long end = System.currentTimeMillis() + timeoutInSeconds * 1000;
+        final ExponentialBackoffDelay d = new ExponentialBackoffDelay(50,  250);
+        while(System.currentTimeMillis() < end) {
+            
+            String jsonBody = waitForStatus(url, 200, timeoutInSeconds * 1000);
+            // deserialize json (https://issues.apache.org/jira/browse/SLING-6536)
+            try {
+                JsonReader jsonReader = Json.createReader(new StringReader(jsonBody));
+                // extract state
+                JsonArray jsonArray = jsonReader.readObject().getJsonArray("data");
+                if (jsonArray == null) {
+                    throw new JsonException("Could not find 'data' array");
+                }
+                JsonObject bundleObject = jsonArray.getJsonObject(0);
+                String state = bundleObject.getString("state");
+                if ("Active".equals(state)) {
+                    return;
+                }
+                // otherwise evaluate the import section
+                JsonArray propsArray = bundleObject.getJsonArray("props");
+                if (propsArray == null) {
+                    throw new JsonException("Could not find 'props' object");
+                }
+                // iterate through all of them until key="Imported Packages" is found
+                for (JsonValue propValue : propsArray) {
+                    if (propValue.getValueType().equals(ValueType.OBJECT)) {
+                        JsonObject propObject = (JsonObject)propValue;
+                        if ("Imported Packages".equals(propObject.getString("key"))) {
+                            JsonArray importedPackagesArray = propObject.getJsonArray("value");
+                            String reason = null;
+                            for (JsonValue importedPackageValue : importedPackagesArray) {
+                                if (importedPackageValue.getValueType().equals(ValueType.STRING)) {
+                                    String importedPackage = ((JsonString)importedPackageValue).getString();
+                                    if (importedPackage.startsWith("ERROR:")) {
+                                        reason = importedPackage;
+                                    }
                                 }
                             }
+                            // only if ERROR is found there is no more need to wait for the bundle to become active, otherwise it might just be started in the background
+                            if (reason != null) {
+                                throw new IllegalStateException("The test bundle '" + bundleSymbolicName + "' is in state '" + state +"'. This is due to unresolved import-packages: " + reason);
+                            }
                         }
-                        throw new IllegalStateException("The test bundle is in state '" + state +"'. Most probably this is due to unresolved import-packages: " + reason);
                     }
                 }
+            } catch (JsonException|IndexOutOfBoundsException e) {
+                throw new IllegalArgumentException("Test bundle '" + bundleSymbolicName +"' not correctly installed. Could not parse JSON response though to expose further information: " + jsonBody, e);
             }
-        } catch (JsonException|IndexOutOfBoundsException e) {
-            throw new IllegalArgumentException("Test bundle '" + bundleSymbolicName +"' not correctly installed. Could not parse JSON response though to expose further information: " + jsonBody, e);
+            d.waitNextDelay();
         }
+        throw new IOException("Bundle '" + bundleSymbolicName + "' was not started after " + timeoutInSeconds + " seconds. The check at " + url + " was not successfull");
     }
 
     void uninstallBundle(String bundleSymbolicName, int webConsoleReadyTimeoutSeconds) throws MalformedURLException, IOException {

Modified: sling/trunk/testing/junit/teleporter/src/test/java/org/apache/sling/testing/teleporter/client/DefaultPropertyBasedCustomizerTest.java
URL: http://svn.apache.org/viewvc/sling/trunk/testing/junit/teleporter/src/test/java/org/apache/sling/testing/teleporter/client/DefaultPropertyBasedCustomizerTest.java?rev=1784163&r1=1784162&r2=1784163&view=diff
==============================================================================
--- sling/trunk/testing/junit/teleporter/src/test/java/org/apache/sling/testing/teleporter/client/DefaultPropertyBasedCustomizerTest.java (original)
+++ sling/trunk/testing/junit/teleporter/src/test/java/org/apache/sling/testing/teleporter/client/DefaultPropertyBasedCustomizerTest.java Thu Feb 23 15:58:46 2017
@@ -68,6 +68,7 @@ public class DefaultPropertyBasedCustomi
         System.setProperty(DefaultPropertyBasedCustomizer.PROPERTY_TESTREADY_TIMEOUT_SECONDS, "50");
         System.setProperty(DefaultPropertyBasedCustomizer.PROPERTY_SERVER_USERNAME, "adminuser");
         System.setProperty(DefaultPropertyBasedCustomizer.PROPERTY_SERVER_PASSWORD, "adminpassword");
+        System.setProperty(DefaultPropertyBasedCustomizer.PROPERTY_ADDITIONAL_BUNDLE_HEADERS, "name1:value1,name2:value2:something");
         customizer = new DefaultPropertyBasedCustomizer();
         customizer.customize(clientSideTeleporter, null);
         Mockito.verify(clientSideTeleporter).setBaseUrl("base-url");
@@ -79,6 +80,8 @@ public class DefaultPropertyBasedCustomi
         Mockito.verify(clientSideTeleporter).embedClass(ClientSideTeleporter.class);
         Mockito.verify(clientSideTeleporter).setTestReadyTimeoutSeconds(50);
         Mockito.verify(clientSideTeleporter).setServerCredentials("adminuser", "adminpassword");
+        Mockito.verify(clientSideTeleporter).addAdditionalBundleHeader("name1", "value1");
+        Mockito.verify(clientSideTeleporter).addAdditionalBundleHeader("name2", "value2:something");
     }
 
     @Test(expected=AssertionError.class)
@@ -88,4 +91,28 @@ public class DefaultPropertyBasedCustomi
         customizer = new DefaultPropertyBasedCustomizer();
         customizer.customize(clientSideTeleporter, null);
     }
+    
+    @Test(expected=AssertionError.class)
+    public void testAdditionalHeaderWithInvalidValue1() {
+        System.setProperty(DefaultPropertyBasedCustomizer.PROPERTY_BASE_URL, "base-url");
+        System.setProperty(DefaultPropertyBasedCustomizer.PROPERTY_ADDITIONAL_BUNDLE_HEADERS, "entrywithoutcolon");
+        customizer = new DefaultPropertyBasedCustomizer();
+        customizer.customize(clientSideTeleporter, null);
+    }
+
+    @Test(expected=AssertionError.class)
+    public void testAdditionalHeaderWithInvalidValue2() {
+        System.setProperty(DefaultPropertyBasedCustomizer.PROPERTY_BASE_URL, "base-url");
+        System.setProperty(DefaultPropertyBasedCustomizer.PROPERTY_ADDITIONAL_BUNDLE_HEADERS, ":value");
+        customizer = new DefaultPropertyBasedCustomizer();
+        customizer.customize(clientSideTeleporter, null);
+    }
+
+    @Test(expected=AssertionError.class)
+    public void testAdditionalHeaderWithInvalidValue3() {
+        System.setProperty(DefaultPropertyBasedCustomizer.PROPERTY_BASE_URL, "base-url");
+        System.setProperty(DefaultPropertyBasedCustomizer.PROPERTY_ADDITIONAL_BUNDLE_HEADERS, "key:");
+        customizer = new DefaultPropertyBasedCustomizer();
+        customizer.customize(clientSideTeleporter, null);
+    }
 }