blob: 6fde41805661186c2b8e10cbaba3e48e03377f71 [file] [log] [blame]
/*
* 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.launchpad.webapp.integrationtest.jcrinstall;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.HashSet;
import java.util.Properties;
import java.util.Set;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.sling.commons.testing.integration.HttpTestBase;
import org.apache.sling.launchpad.webapp.integrationtest.jcrinstall.util.BundleCloner;
import org.osgi.framework.Bundle;
/** Base class for jcrinstall test cases */
public class JcrinstallTestBase extends HttpTestBase {
public static final String JCRINSTALL_STATUS_PATH = "/system/sling/jcrinstall";
public static final String DEFAULT_INSTALL_PATH = "/libs/integration-testing/install";
public static final String DEFAULT_BUNDLE_NAME_PATTERN = "observer";
private static long bundleCounter = System.currentTimeMillis();
private static Set<String> installedClones;
public static final String SCALE_FACTOR_PROP = "sling.test.scale.factor";
public static final String DEFAULT_TIMEOUT_PROP = "sling.test.bundles.wait.seconds";
protected int scaleFactor;
protected int defaultBundlesTimeout;
private class ShutdownThread extends Thread {
@Override
public void run() {
try {
System.out.println("Deleting " + installedClones.size() + " cloned bundles...");
for(String path : installedClones) {
testClient.delete(WEBDAV_BASE_URL + path);
}
} catch(Exception e) {
System.out.println("Exception in ShutdownThread:" + e);
}
}
};
@Override
protected void setUp() throws Exception {
super.setUp();
scaleFactor = requireIntProperty(SCALE_FACTOR_PROP);
defaultBundlesTimeout = requireIntProperty(DEFAULT_TIMEOUT_PROP);
enableJcrinstallService(true);
}
@Override
protected void tearDown() throws Exception {
// TODO Auto-generated method stub
super.tearDown();
enableJcrinstallService(true);
}
protected int requireIntProperty(String systemPropertyKey) throws Exception {
final String s = System.getProperty(systemPropertyKey);
if(s == null) {
throw new Exception("Missing system property '" + systemPropertyKey + "'");
}
return Integer.valueOf(s);
}
/** Fail test if active bundles count is not expectedCount, after
* at most timeoutSeconds */
protected void assertActiveBundleCount(String message, int expectedCount, int timeoutSeconds) throws IOException {
final long start = System.currentTimeMillis();
final long timeout = start + timeoutSeconds * 1000L;
int count = 0;
int lastCount = -1;
while(System.currentTimeMillis() < timeout) {
count = getActiveBundlesCount();
if(count != lastCount) {
// continue until the count is stable for at least one second
lastCount = count;
sleep(1000);
continue;
} else if(count == expectedCount) {
return;
}
sleep(500);
}
final long delta = System.currentTimeMillis() - start;
fail(message + ": expected " + expectedCount + " active bundles, found " + count
+ " after waiting " + delta / 1000.0 + " seconds");
}
protected void sleep(long millis) {
try {
Thread.sleep(millis);
} catch(InterruptedException ignore) {
}
}
protected int getActiveBundlesCount() throws IOException {
final String key = "bundles.in.state." + Bundle.ACTIVE;
final Properties props = getJcrInstallProperties();
int result = 0;
if(props.containsKey(key)) {
result = Integer.valueOf(props.getProperty(key));
}
return result;
}
protected boolean getJcrinstallServiceEnabled() throws IOException {
final Properties props = getJcrInstallProperties();
return "true".equals(props.get("jcrinstall.enabled"));
}
protected void enableJcrinstallService(boolean enable) throws IOException {
if(enable != getJcrinstallServiceEnabled()) {
final PostMethod post = new PostMethod(HTTP_BASE_URL + JCRINSTALL_STATUS_PATH);
post.setFollowRedirects(false);
post.addParameter("enabled", String.valueOf(enable));
final int status = httpClient.executeMethod(post);
assertEquals("Expected status 200 in enableJcrinstallService", 200, status);
assertEquals("Expected jcrinstall.enabled to be " + enable, enable, getJcrinstallServiceEnabled());
}
}
/** Return the Properties found at /system/sling/jcrinstall */
protected Properties getJcrInstallProperties() throws IOException {
final String content = getContent(HTTP_BASE_URL + JCRINSTALL_STATUS_PATH, CONTENT_TYPE_PLAIN);
final Properties result = new Properties();
result.load(new ByteArrayInputStream(content.getBytes("UTF-8")));
return result;
}
/** Remove a cloned bundle that had been installed before */
protected void removeClonedBundle(String path) throws IOException {
testClient.delete(WEBDAV_BASE_URL + path);
installedClones.remove(path);
}
/** Generate a clone of one of our test bundles, with unique bundle name and
* symbolic name, and install it via WebDAV.
* @param bundleNamePattern The first test bundle that contains this pattern
* is used as a source. If null, uses DEFAULT_BUNDLE_NAME_PATTERN
* @param installPath if null, use DEFAULT_INSTALL_PATH
* @return the path of the installed bundle
*/
protected String installClonedBundle(String bundleNamePattern, String installPath) throws Exception {
if(bundleNamePattern == null) {
bundleNamePattern = DEFAULT_BUNDLE_NAME_PATTERN;
}
if(installPath == null) {
installPath = DEFAULT_INSTALL_PATH;
}
// find test bundle to clone
final File testBundlesDir = new File(System.getProperty("sling.testbundles.path"));
if(!testBundlesDir.isDirectory()) {
throw new IOException(testBundlesDir.getAbsolutePath() + " is not a directory");
}
File bundleSrc = null;
for(String bundle : testBundlesDir.list()) {
if(bundle.contains(bundleNamePattern)) {
bundleSrc = new File(testBundlesDir, bundle);
break;
}
}
// clone bundle
final File outputDir = new File(testBundlesDir, "cloned-bundles");
outputDir.mkdirs();
final String bundleId = bundleNamePattern + "_clone_" + bundleCounter++;
final File clone = new File(outputDir, bundleId + ".jar");
new BundleCloner().cloneBundle(bundleSrc, clone, bundleId, bundleId);
// install clone by copying to repository - jcrinstall should then pick it up
FileInputStream fis = new FileInputStream(clone);
final String path = installPath + "/" + clone.getName();
final String url = WEBDAV_BASE_URL + path;
try {
testClient.mkdirs(WEBDAV_BASE_URL, installPath);
testClient.upload(url, fis);
setupBundlesCleanup();
installedClones.add(path);
} finally {
if(fis != null) {
fis.close();
}
}
return path;
}
/** If not done yet, register a shutdown hook to delete cloned bundles that
* we installed.
*/
private void setupBundlesCleanup() {
synchronized (JcrinstallTestBase.class) {
if(installedClones == null) {
installedClones = new HashSet<String>();
Runtime.getRuntime().addShutdownHook(new ShutdownThread());
}
}
}
}