You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by bd...@apache.org on 2009/09/10 16:38:56 UTC
svn commit: r813460 - in /sling/trunk/installer/osgi/it: pom.xml
src/test/java/org/apache/sling/osgi/installer/it/BundleInstallStressTest.java
src/test/java/org/apache/sling/osgi/installer/it/OsgiInstallerTestBase.java
Author: bdelacretaz
Date: Thu Sep 10 14:38:56 2009
New Revision: 813460
URL: http://svn.apache.org/viewvc?rev=813460&view=rev
Log:
SLING-1078 - BundleInstallStressTest added
Added:
sling/trunk/installer/osgi/it/src/test/java/org/apache/sling/osgi/installer/it/BundleInstallStressTest.java (with props)
Modified:
sling/trunk/installer/osgi/it/pom.xml
sling/trunk/installer/osgi/it/src/test/java/org/apache/sling/osgi/installer/it/OsgiInstallerTestBase.java
Modified: sling/trunk/installer/osgi/it/pom.xml
URL: http://svn.apache.org/viewvc/sling/trunk/installer/osgi/it/pom.xml?rev=813460&r1=813459&r2=813460&view=diff
==============================================================================
--- sling/trunk/installer/osgi/it/pom.xml (original)
+++ sling/trunk/installer/osgi/it/pom.xml Thu Sep 10 14:38:56 2009
@@ -37,6 +37,13 @@
<pax.exam.log.level>INFO</pax.exam.log.level>
<!-- This can be set to activate remote debugging of the Pax Exam tests -->
<pax.exam.debug.port></pax.exam.debug.port>
+
+ <!-- BundleInstallStressTest parameters -->
+ <BundleInstallStressTest.default.bundles.folder>${project.build.directory}/bundle-install-stress-test-bundles</BundleInstallStressTest.default.bundles.folder>
+ <osgi.installer.BundleInstallStressTest.bundles.folder>${BundleInstallStressTest.default.bundles.folder}</osgi.installer.BundleInstallStressTest.bundles.folder>
+ <osgi.installer.BundleInstallStressTest.cycle.count>10</osgi.installer.BundleInstallStressTest.cycle.count>
+ <osgi.installer.BundleInstallStressTest.expect.timeout.seconds>30</osgi.installer.BundleInstallStressTest.expect.timeout.seconds>
+
</properties>
<scm>
@@ -89,6 +96,18 @@
<name>osgi.installer.base.dir</name>
<value>${project.build.directory}</value>
</property>
+ <property>
+ <name>osgi.installer.BundleInstallStressTest.bundles.folder</name>
+ <value>${osgi.installer.BundleInstallStressTest.bundles.folder}</value>
+ </property>
+ <property>
+ <name>osgi.installer.BundleInstallStressTest.cycle.count</name>
+ <value>${osgi.installer.BundleInstallStressTest.cycle.count}</value>
+ </property>
+ <property>
+ <name>osgi.installer.BundleInstallStressTest.expect.timeout.seconds</name>
+ <value>${osgi.installer.BundleInstallStressTest.expect.timeout.seconds}</value>
+ </property>
</systemProperties>
</configuration>
</plugin>
@@ -273,6 +292,31 @@
</execution>
</executions>
</plugin>
+ <plugin>
+ <artifactId>maven-antrun-plugin</artifactId>
+ <executions>
+ <execution>
+ <phase>test-compile</phase>
+ <configuration>
+ <tasks>
+ <!-- Copy a set of distinct valid bundles for the BundleInstallStressTest -->
+ <mkdir dir="${BundleInstallStressTest.default.bundles.folder}"/>
+ <copy todir="${BundleInstallStressTest.default.bundles.folder}">
+ <fileset dir="${project.build.directory}">
+ <include name="*testbundle-1.2.jar"/>
+ <include name="*testB-1.0.jar"/>
+ <include name="*testA-1.0.jar"/>
+ <include name="*needsB.jar"/>
+ </fileset>
+ </copy>
+ </tasks>
+ </configuration>
+ <goals>
+ <goal>run</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
</plugins>
</build>
Added: sling/trunk/installer/osgi/it/src/test/java/org/apache/sling/osgi/installer/it/BundleInstallStressTest.java
URL: http://svn.apache.org/viewvc/sling/trunk/installer/osgi/it/src/test/java/org/apache/sling/osgi/installer/it/BundleInstallStressTest.java?rev=813460&view=auto
==============================================================================
--- sling/trunk/installer/osgi/it/src/test/java/org/apache/sling/osgi/installer/it/BundleInstallStressTest.java (added)
+++ sling/trunk/installer/osgi/it/src/test/java/org/apache/sling/osgi/installer/it/BundleInstallStressTest.java Thu Sep 10 14:38:56 2009
@@ -0,0 +1,206 @@
+/*
+ * 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.osgi.installer.it;
+
+import static org.junit.Assert.fail;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Random;
+
+import org.apache.sling.osgi.installer.InstallableResource;
+import org.apache.sling.osgi.installer.OsgiInstaller;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.ops4j.pax.exam.Option;
+import org.ops4j.pax.exam.junit.JUnit4TestRunner;
+import org.osgi.framework.Bundle;
+import org.osgi.service.log.LogService;
+
+/** Repeatedly install/remove/reinstall semi-random sets
+ * of bundles, to stress-test the installer and framework.
+ */
+@RunWith(JUnit4TestRunner.class)
+public class BundleInstallStressTest extends OsgiInstallerTestBase {
+
+ public static final String PROP_BUNDLES_FOLDER = "osgi.installer.BundleInstallStressTest.bundles.folder";
+ public static final String PROP_CYCLE_COUNT = "osgi.installer.BundleInstallStressTest.cycle.count";
+ public static final String PROP_EXPECT_TIMEOUT_SECONDS = "osgi.installer.BundleInstallStressTest.expect.timeout.seconds";
+ public static final int MIN_TEST_BUNDLES = 4;
+
+ /** Folder where test bundles are found */
+ private File bundlesFolder;
+
+ /** How many cycles to run */
+ private int cycleCount;
+
+ /** List of available test bundles */
+ private List<File> testBundles;
+
+ /** Always use the same random sequence */
+ private Random random;
+
+ /** Timeout for expectBundles() */
+ private long expectBundlesTimeoutMsec;
+
+ @org.ops4j.pax.exam.junit.Configuration
+ public static Option[] configuration() {
+ return defaultConfiguration();
+ }
+
+ @Before
+ public void setUp() {
+ setupInstaller();
+
+ final String bf = System.getProperty(PROP_BUNDLES_FOLDER);
+ if(bf == null) {
+ fail("Missing system property: " + PROP_BUNDLES_FOLDER);
+ }
+ bundlesFolder = new File(bf);
+ if(!bundlesFolder.isDirectory()) {
+ fail("Bundles folder '" + bundlesFolder.getAbsolutePath() + "' not found");
+ }
+
+ final String cc = System.getProperty(PROP_CYCLE_COUNT);
+ if(cc == null) {
+ fail("Missing system property:" + PROP_CYCLE_COUNT);
+ }
+ cycleCount = Integer.parseInt(cc);
+
+ final String et = System.getProperty(PROP_EXPECT_TIMEOUT_SECONDS);
+ if(et == null) {
+ fail("Missing system property:" + PROP_EXPECT_TIMEOUT_SECONDS);
+ }
+ expectBundlesTimeoutMsec = Integer.parseInt(et) * 1000L;
+
+ log(LogService.LOG_INFO, getClass().getSimpleName()
+ + ": cycle count=" + cycleCount
+ + ", expect timeout (msec)=" + expectBundlesTimeoutMsec
+ + ", test bundles folder=" + bundlesFolder.getAbsolutePath());
+
+ testBundles = new LinkedList<File>();
+ final String [] files = bundlesFolder.list();
+ for(String filename : files) {
+ if(filename.endsWith(".jar")) {
+ testBundles.add(new File(bundlesFolder, filename));
+ }
+ }
+
+ if(testBundles.size() < MIN_TEST_BUNDLES) {
+ fail("Found only " + testBundles.size()
+ + " bundles in test folder, expected at least " + MIN_TEST_BUNDLES
+ + " (test folder=" + bundlesFolder.getAbsolutePath() + ")"
+ );
+ }
+
+ random = new Random(42 + cycleCount);
+ }
+
+ @After
+ public void tearDown() {
+ super.tearDown();
+ }
+
+ @Test
+ public void testSemiRandomInstall() throws Exception {
+ if(cycleCount < 1) {
+ fail("Cycle count (" + cycleCount + ") should be >= 1");
+ }
+
+ final int initialBundleCount = bundleContext.getBundles().length;
+ log(LogService.LOG_INFO,"Initial bundle count=" + initialBundleCount);
+
+ // Start by installing all bundles
+ log(LogService.LOG_INFO,"Registering all test bundles, " + testBundles.size() + " resources");
+ install(testBundles);
+ waitForInstallerAction(OsgiInstaller.WORKER_THREAD_BECOMES_IDLE_COUNTER, 1);
+ expectBundleCount("After installing all test bundles", initialBundleCount + testBundles.size());
+
+ for(int i=0; i < cycleCount; i++) {
+ final long start = System.currentTimeMillis();
+ log(LogService.LOG_DEBUG, "Test cycle " + i + ", semi-randomly selecting a subset of our test bundles");
+ final List<File> toInstall = selectRandomBundles();
+ log(LogService.LOG_INFO,"Re-registering " + toInstall.size() + " randomly selected resources (other test bundles should be uninstalled)");
+ install(toInstall);
+ waitForInstallerAction(OsgiInstaller.WORKER_THREAD_BECOMES_IDLE_COUNTER, 1);
+ // TODO this sleep shouldn't be needed, probably hides a bug in OsgiInstallerImpl
+ sleep(2500L);
+ expectBundleCount("At cycle " + i, initialBundleCount + toInstall.size());
+ log(LogService.LOG_INFO,"Test cycle " + i + " successful, "
+ + toInstall.size() + " bundles, "
+ + (System.currentTimeMillis() - start) + " msec");
+ }
+ }
+
+ private void install(List<File> bundles) throws IOException {
+ final List<InstallableResource> toInstall = new LinkedList<InstallableResource>();
+ for(File f : bundles) {
+ toInstall.add(getInstallableResource(f, f.getAbsolutePath() + f.lastModified()));
+ }
+ installer.registerResources(toInstall, URL_SCHEME);
+ }
+
+ private void expectBundleCount(String info, final int nBundles) throws Exception {
+ log(LogService.LOG_INFO,"Expecting " + nBundles + " bundles to be installed");
+ final Condition c = new Condition() {
+ int actualCount = 0;
+ public boolean isTrue() throws Exception {
+ actualCount = bundleContext.getBundles().length;
+ return actualCount == nBundles;
+ }
+
+ @Override
+ String additionalInfo() {
+ return "Expected " + nBundles + " installed bundles, got " + actualCount;
+ }
+
+ @Override
+ void onFailure() {
+ log(LogService.LOG_INFO, "Failure: " + additionalInfo());
+ for(Bundle b : bundleContext.getBundles()) {
+ log(LogService.LOG_INFO, "Installed bundle: " + b.getSymbolicName());
+ }
+ }
+
+ @Override
+ long getMsecBetweenEvaluations() {
+ return 1000L;
+ }
+ };
+ waitForCondition(info, expectBundlesTimeoutMsec, c);
+ }
+
+ private List<File> selectRandomBundles() {
+ final List<File> result = new LinkedList<File>();
+ for(File f : testBundles) {
+ if(random.nextBoolean()) {
+ log(LogService.LOG_DEBUG, "Test bundle selected: " + f.getName());
+ result.add(f);
+ }
+ }
+
+ if(result.size() == 0) {
+ result.add(testBundles.get(0));
+ }
+
+ return result;
+ }
+}
Propchange: sling/trunk/installer/osgi/it/src/test/java/org/apache/sling/osgi/installer/it/BundleInstallStressTest.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: sling/trunk/installer/osgi/it/src/test/java/org/apache/sling/osgi/installer/it/BundleInstallStressTest.java
------------------------------------------------------------------------------
svn:keywords = Author Date Id Revision Rev URL
Modified: sling/trunk/installer/osgi/it/src/test/java/org/apache/sling/osgi/installer/it/OsgiInstallerTestBase.java
URL: http://svn.apache.org/viewvc/sling/trunk/installer/osgi/it/src/test/java/org/apache/sling/osgi/installer/it/OsgiInstallerTestBase.java?rev=813460&r1=813459&r2=813460&view=diff
==============================================================================
--- sling/trunk/installer/osgi/it/src/test/java/org/apache/sling/osgi/installer/it/OsgiInstallerTestBase.java (original)
+++ sling/trunk/installer/osgi/it/src/test/java/org/apache/sling/osgi/installer/it/OsgiInstallerTestBase.java Thu Sep 10 14:38:56 2009
@@ -46,6 +46,7 @@
import org.osgi.framework.ServiceReference;
import org.osgi.service.cm.Configuration;
import org.osgi.service.cm.ConfigurationAdmin;
+import org.osgi.service.log.LogService;
import org.osgi.service.packageadmin.PackageAdmin;
import org.osgi.util.tracker.ServiceTracker;
@@ -65,8 +66,11 @@
public static final String URL_SCHEME = "OsgiInstallerTest";
- static interface Condition {
- boolean isTrue() throws Exception;
+ static abstract class Condition {
+ abstract boolean isTrue() throws Exception;
+ String additionalInfo() { return null; }
+ void onFailure() { }
+ long getMsecBetweenEvaluations() { return 100L; }
}
@SuppressWarnings("unchecked")
@@ -163,8 +167,14 @@
if(c.isTrue()) {
return;
}
- Thread.sleep(100L);
+ Thread.sleep(c.getMsecBetweenEvaluations());
} while(System.currentTimeMillis() < end);
+
+ if(c.additionalInfo() != null) {
+ info += " " + c.additionalInfo();
+ }
+
+ c.onFailure();
fail("WaitForCondition failed: " + info);
}
@@ -357,6 +367,11 @@
assertEquals("Expected value matches for counter " + index, value, installer.getCounters()[index]);
}
+ protected void log(int level, String msg) {
+ final LogService log = getService(LogService.class);
+ log.log(LogService.LOG_INFO, msg);
+ }
+
public static Option[] defaultConfiguration() {
String vmOpt = "-Dosgi.installer.testing";