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);
+ }
}