Java tutorial
/* * 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; static interface StringCondition { boolean eval(String input); } 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 assertContentWithTimeout(String message, String contentUrl, String expectedContentType, StringCondition condition, int timeoutSeconds) throws IOException { final long start = System.currentTimeMillis(); final long timeout = start + timeoutSeconds * 1000L; while (System.currentTimeMillis() < timeout) { final String content = getContent(contentUrl, expectedContentType); if (condition.eval(content)) { return; } sleep(200); } final long delta = System.currentTimeMillis() - start; fail(message + ": StringCondition did not return true" + " 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()); } } } }