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";
        


Reply via email to