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/08/21 12:15:34 UTC

svn commit: r806483 - in /sling/trunk/installer/osgi: installer/src/main/java/org/apache/sling/osgi/installer/ installer/src/main/java/org/apache/sling/osgi/installer/impl/ it/src/test/java/org/apache/sling/osgi/installer/it/

Author: bdelacretaz
Date: Fri Aug 21 10:15:34 2009
New Revision: 806483

URL: http://svn.apache.org/viewvc?rev=806483&view=rev
Log:
SLING-1078 - Worker thread waits when it has nothing to do

Added:
    sling/trunk/installer/osgi/it/src/test/java/org/apache/sling/osgi/installer/it/WorkerThreadIdleTest.java   (with props)
Modified:
    sling/trunk/installer/osgi/installer/src/main/java/org/apache/sling/osgi/installer/OsgiInstaller.java
    sling/trunk/installer/osgi/installer/src/main/java/org/apache/sling/osgi/installer/impl/OsgiInstallerImpl.java
    sling/trunk/installer/osgi/installer/src/main/java/org/apache/sling/osgi/installer/impl/OsgiInstallerThread.java
    sling/trunk/installer/osgi/it/src/test/java/org/apache/sling/osgi/installer/it/BundleInstallUpgradeDowngradeTest.java
    sling/trunk/installer/osgi/it/src/test/java/org/apache/sling/osgi/installer/it/BundleStartRetriesTest.java
    sling/trunk/installer/osgi/it/src/test/java/org/apache/sling/osgi/installer/it/BundleStatePreservedTest.java
    sling/trunk/installer/osgi/it/src/test/java/org/apache/sling/osgi/installer/it/OsgiInstallerTestBase.java
    sling/trunk/installer/osgi/it/src/test/java/org/apache/sling/osgi/installer/it/RegisterResourcesTest.java

Modified: sling/trunk/installer/osgi/installer/src/main/java/org/apache/sling/osgi/installer/OsgiInstaller.java
URL: http://svn.apache.org/viewvc/sling/trunk/installer/osgi/installer/src/main/java/org/apache/sling/osgi/installer/OsgiInstaller.java?rev=806483&r1=806482&r2=806483&view=diff
==============================================================================
--- sling/trunk/installer/osgi/installer/src/main/java/org/apache/sling/osgi/installer/OsgiInstaller.java (original)
+++ sling/trunk/installer/osgi/installer/src/main/java/org/apache/sling/osgi/installer/OsgiInstaller.java Fri Aug 21 10:15:34 2009
@@ -71,6 +71,12 @@
      *  of resources having the same OSGi entity ID */
     int REGISTERED_GROUPS_COUNTER = 3;
     
+    /** Counter index: is worker thread idle? (not really a counter: 1 means true) */
+    int WORKER_THREAD_IS_IDLE_COUNTER = 4;
+    
+    /** Counter index: how many times did worker thread become idle */
+    int WORKER_THREAD_BECOMES_IDLE_COUNTER = 5;
+    
 	/** Size of the counters array */
-	int COUNTERS_SIZE = 4;
+	int COUNTERS_SIZE = 6;
 }
\ No newline at end of file

Modified: sling/trunk/installer/osgi/installer/src/main/java/org/apache/sling/osgi/installer/impl/OsgiInstallerImpl.java
URL: http://svn.apache.org/viewvc/sling/trunk/installer/osgi/installer/src/main/java/org/apache/sling/osgi/installer/impl/OsgiInstallerImpl.java?rev=806483&r1=806482&r2=806483&view=diff
==============================================================================
--- sling/trunk/installer/osgi/installer/src/main/java/org/apache/sling/osgi/installer/impl/OsgiInstallerImpl.java (original)
+++ sling/trunk/installer/osgi/installer/src/main/java/org/apache/sling/osgi/installer/impl/OsgiInstallerImpl.java Fri Aug 21 10:15:34 2009
@@ -19,9 +19,7 @@
 package org.apache.sling.osgi.installer.impl;
 
 import java.io.IOException;
-import java.util.ArrayList;
 import java.util.Collection;
-import java.util.List;
 
 import org.apache.sling.osgi.installer.InstallableResource;
 import org.apache.sling.osgi.installer.OsgiInstaller;
@@ -55,6 +53,7 @@
     }
 
     public void deactivate() {
+        installerThread.deactivate();
         if(getLogService() != null) {
             getLogService().log(LogService.LOG_WARNING,
                     OsgiInstaller.class.getName()

Modified: sling/trunk/installer/osgi/installer/src/main/java/org/apache/sling/osgi/installer/impl/OsgiInstallerThread.java
URL: http://svn.apache.org/viewvc/sling/trunk/installer/osgi/installer/src/main/java/org/apache/sling/osgi/installer/impl/OsgiInstallerThread.java?rev=806483&r1=806482&r2=806483&view=diff
==============================================================================
--- sling/trunk/installer/osgi/installer/src/main/java/org/apache/sling/osgi/installer/impl/OsgiInstallerThread.java (original)
+++ sling/trunk/installer/osgi/installer/src/main/java/org/apache/sling/osgi/installer/impl/OsgiInstallerThread.java Fri Aug 21 10:15:34 2009
@@ -31,6 +31,10 @@
 import org.apache.sling.osgi.installer.InstallableResource;
 import org.apache.sling.osgi.installer.OsgiInstaller;
 import org.osgi.framework.BundleContext;
+import org.osgi.framework.BundleEvent;
+import org.osgi.framework.BundleListener;
+import org.osgi.framework.FrameworkEvent;
+import org.osgi.framework.FrameworkListener;
 import org.osgi.service.log.LogService;
 
 /** Worker thread where all OSGi tasks are executed.
@@ -41,13 +45,14 @@
  *  that are updated or removed during a cycle, and merged with
  *  the main list at the end of the cycle.
  */
-class OsgiInstallerThread extends Thread {
+class OsgiInstallerThread extends Thread implements FrameworkListener, BundleListener {
     
     private final OsgiInstallerContext ctx;
     private final List<RegisteredResource> newResources = new LinkedList<RegisteredResource>();
     private final SortedSet<OsgiInstallerTask> tasks = new TreeSet<OsgiInstallerTask>();
     private final SortedSet<OsgiInstallerTask> tasksForNextCycle = new TreeSet<OsgiInstallerTask>();
     private final List<SortedSet<RegisteredResource>> newResourcesSets = new ArrayList<SortedSet<RegisteredResource>>();
+    private boolean active = true;
     
     /** Group our RegisteredResource by OSGi entity */ 
     private Map<String, SortedSet<RegisteredResource>>registeredResources = 
@@ -70,16 +75,50 @@
         this.ctx = ctx;
     }
 
+    void deactivate() {
+        ctx.getBundleContext().removeBundleListener(this);
+        ctx.getBundleContext().removeFrameworkListener(this);
+        active = false;
+        synchronized (newResources) {
+            newResources.notify();
+        }
+    }
+    
     @Override
     public void run() {
-        while(true) {
-            // TODO do nothing if nothing to process!
+        ctx.getBundleContext().addFrameworkListener(this);
+        ctx.getBundleContext().addBundleListener(this);
+        
+        while(active) {
             try {
             	mergeNewResources();
             	computeTasks();
+            	
+            	if(tasks.isEmpty()) {
+            	    // No tasks to execute - wait until new resources are
+            	    // registered
+            	    cleanupInstallableResources();
+            	    if(ctx.getLogService() != null) {
+            	        ctx.getLogService().log(LogService.LOG_DEBUG, "No tasks to process, going idle");
+            	    }
+                    ctx.setCounter(OsgiInstaller.WORKER_THREAD_IS_IDLE_COUNTER, 1);
+                    ctx.incrementCounter(OsgiInstaller.WORKER_THREAD_BECOMES_IDLE_COUNTER);
+            	    synchronized (newResources) {
+                        newResources.wait();
+                    }
+                    if(ctx.getLogService() != null) {
+                        ctx.getLogService().log(LogService.LOG_DEBUG, "Notified of new resources, back to work");
+                    }
+                    ctx.setCounter(OsgiInstaller.WORKER_THREAD_IS_IDLE_COUNTER, 0);
+            	    continue;
+            	}
+            	
                 executeTasks();
+                
+                // Some integration tests depend on this delay, make sure to
+                // rerun/adapt them if changing this value
                 Thread.sleep(250);
-                cycleDone();
+                cleanupInstallableResources();
             } catch(Exception e) {
                 if(ctx.getLogService() != null) {
                     ctx.getLogService().log(LogService.LOG_WARNING, e.toString(), e);
@@ -90,6 +129,9 @@
                 }
             }
         }
+        if(ctx.getLogService() != null) {
+            ctx.getLogService().log(LogService.LOG_INFO, "Deactivated, exiting");
+        }
     }
     
     void addTaskToCurrentCycle(OsgiInstallerTask t) {
@@ -105,6 +147,7 @@
     void addNewResource(RegisteredResource r) {
         synchronized (newResources) {
             newResources.add(r);
+            newResources.notify();
         }
     }
     
@@ -127,6 +170,7 @@
         if(!toAdd.isEmpty()) {
             synchronized (newResources) {
                 newResourcesSets.add(toAdd);
+                newResources.notify();
             }
         }
     }
@@ -233,7 +277,7 @@
         }
     }
     
-    private void cycleDone() {
+    private void cleanupInstallableResources() {
         // Cleanup resources that are not marked installable,
         // they have been processed by now
         int resourceCount = 0;
@@ -275,4 +319,18 @@
             ctx.getLogService().log(LogService.LOG_DEBUG, str);
        }
     }
+
+    /** Need to wake up on framework and bundle events, as we might have tasks waiting to retry */
+    public void frameworkEvent(FrameworkEvent arg0) {
+        synchronized (newResources) {
+            newResources.notify();
+        }
+    }
+
+    /** Need to wake up on framework and bundle events, as we might have tasks waiting to retry */
+    public void bundleChanged(BundleEvent arg0) {
+        synchronized (newResources) {
+            newResources.notify();
+        }
+    }
 }
\ No newline at end of file

Modified: sling/trunk/installer/osgi/it/src/test/java/org/apache/sling/osgi/installer/it/BundleInstallUpgradeDowngradeTest.java
URL: http://svn.apache.org/viewvc/sling/trunk/installer/osgi/it/src/test/java/org/apache/sling/osgi/installer/it/BundleInstallUpgradeDowngradeTest.java?rev=806483&r1=806482&r2=806483&view=diff
==============================================================================
--- sling/trunk/installer/osgi/it/src/test/java/org/apache/sling/osgi/installer/it/BundleInstallUpgradeDowngradeTest.java (original)
+++ sling/trunk/installer/osgi/it/src/test/java/org/apache/sling/osgi/installer/it/BundleInstallUpgradeDowngradeTest.java Fri Aug 21 10:15:34 2009
@@ -60,8 +60,7 @@
     	    resetCounters();
     	    installer.addResource(getInstallableResource(
     	            getTestBundle(BUNDLE_BASE_NAME + "-testbundle-1.1.jar")));
-    	    // wait for two tasks: install and start
-    	    waitForInstallerAction(OsgiInstaller.OSGI_TASKS_COUNTER, 2);
+            waitForInstallerAction(OsgiInstaller.WORKER_THREAD_BECOMES_IDLE_COUNTER, 1);
     	    final Bundle b = assertBundle("After installing", symbolicName, "1.1", Bundle.ACTIVE);
     	    bundleId = b.getBundleId();
     	}
@@ -73,8 +72,7 @@
     	    resetCounters();
             installer.addResource(getInstallableResource(
                     getTestBundle(BUNDLE_BASE_NAME + "-testbundle-1.2.jar")));
-            // wait for two tasks: update (includes stop) and start
-            waitForInstallerAction(OsgiInstaller.OSGI_TASKS_COUNTER, 2);
+            waitForInstallerAction(OsgiInstaller.WORKER_THREAD_BECOMES_IDLE_COUNTER, 1);
         	final Bundle b = assertBundle("After updating to 1.2", symbolicName, "1.2", Bundle.ACTIVE);
         	assertEquals("Bundle ID must not change after update", bundleId, b.getBundleId());
     	}
@@ -87,8 +85,8 @@
             installer.addResource(getInstallableResource(
                     getTestBundle(BUNDLE_BASE_NAME + "-testbundle-1.0.jar")));
             
-            // wait for two cycles to make sure no updates happen
-            waitForInstallerAction(OsgiInstaller.INSTALLER_CYCLES_COUNTER, 2);
+            // make sure no updates happen
+            waitForInstallerAction(OsgiInstaller.WORKER_THREAD_BECOMES_IDLE_COUNTER, 1);
             final Bundle b = assertBundle("After ignored downgrade", symbolicName, "1.2", Bundle.ACTIVE);
             assertEquals("Bundle ID must not change after ignored downgrade", bundleId, b.getBundleId());
         }
@@ -104,18 +102,20 @@
             resetCounters();
             installer.removeResource(getInstallableResource(
                     getTestBundle(BUNDLE_BASE_NAME + "-testbundle-1.0.jar")));
+            waitForInstallerAction(OsgiInstaller.WORKER_THREAD_BECOMES_IDLE_COUNTER, 1);
+            
+            resetCounters();
             installer.removeResource(getInstallableResource(
                     getTestBundle(BUNDLE_BASE_NAME + "-testbundle-1.1.jar")));
+            waitForInstallerAction(OsgiInstaller.WORKER_THREAD_BECOMES_IDLE_COUNTER, 1);
+            
+            resetCounters();
             installer.removeResource(getInstallableResource(
                     getTestBundle(BUNDLE_BASE_NAME + "-testbundle-1.2.jar")));
+            waitForInstallerAction(OsgiInstaller.WORKER_THREAD_BECOMES_IDLE_COUNTER, 1);
             
-            // wait for one task: uninstall
-            waitForInstallerAction(OsgiInstaller.OSGI_TASKS_COUNTER, 1);
             final Bundle b = findBundle(symbolicName);
-            assertNull("Bundle must be gone", b);
-            
-            // uninstall task generates package refresh and a number of bundle start tasks, consume these
-            waitForInstallerAction(OsgiInstaller.INSTALLER_CYCLES_COUNTER, 2);
+            assertNull("Testbundle must be gone", b);
     	}
     	
     	// No resources must be registered anymore
@@ -129,8 +129,7 @@
             resetCounters();
             installer.addResource(getInstallableResource(
                     getTestBundle(BUNDLE_BASE_NAME + "-testbundle-1.1.jar")));
-            // wait for two tasks: install and start
-            waitForInstallerAction(OsgiInstaller.OSGI_TASKS_COUNTER, 2);
+            waitForInstallerAction(OsgiInstaller.WORKER_THREAD_BECOMES_IDLE_COUNTER, 1);
             assertBundle("After reinstalling 1.1", symbolicName, "1.1", Bundle.ACTIVE);
         }
 

Modified: sling/trunk/installer/osgi/it/src/test/java/org/apache/sling/osgi/installer/it/BundleStartRetriesTest.java
URL: http://svn.apache.org/viewvc/sling/trunk/installer/osgi/it/src/test/java/org/apache/sling/osgi/installer/it/BundleStartRetriesTest.java?rev=806483&r1=806482&r2=806483&view=diff
==============================================================================
--- sling/trunk/installer/osgi/it/src/test/java/org/apache/sling/osgi/installer/it/BundleStartRetriesTest.java (original)
+++ sling/trunk/installer/osgi/it/src/test/java/org/apache/sling/osgi/installer/it/BundleStartRetriesTest.java Fri Aug 21 10:15:34 2009
@@ -48,16 +48,18 @@
         // (== 3 tasks since last counters reset)
         waitForInstallerAction(OsgiInstaller.OSGI_TASKS_COUNTER, 3);
         
-        // and no more retries must happen before receiving a bundle event 
-        waitForInstallerAction(OsgiInstaller.INSTALLER_CYCLES_COUNTER, 2);
+        // and no more retries must happen before receiving a bundle event
+        sleep(1000L);
         assertEquals("Exactly 3 OSGi tasks must have been executed after a few installer cycles",
                 nOps + 3, installer.getCounters()[OsgiInstaller.OSGI_TASKS_COUNTER]);
 
         // generate a bundle event -> must trigger just one retry
+        resetCounters();
         generateBundleEvent();
-        waitForInstallerAction(OsgiInstaller.INSTALLER_CYCLES_COUNTER, 3);
-        assertEquals("Exactly 4 OSGi tasks total must have been executed after bundle event received",
-                nOps + 4, installer.getCounters()[OsgiInstaller.OSGI_TASKS_COUNTER]);
+        waitForInstallerAction(OsgiInstaller.WORKER_THREAD_BECOMES_IDLE_COUNTER, 1);
+        sleep(1000L);
+        assertEquals("Exactly 5 OSGi tasks total must have been executed after bundle event received",
+                nOps + 5, installer.getCounters()[OsgiInstaller.OSGI_TASKS_COUNTER]);
     }
 
 }

Modified: sling/trunk/installer/osgi/it/src/test/java/org/apache/sling/osgi/installer/it/BundleStatePreservedTest.java
URL: http://svn.apache.org/viewvc/sling/trunk/installer/osgi/it/src/test/java/org/apache/sling/osgi/installer/it/BundleStatePreservedTest.java?rev=806483&r1=806482&r2=806483&view=diff
==============================================================================
--- sling/trunk/installer/osgi/it/src/test/java/org/apache/sling/osgi/installer/it/BundleStatePreservedTest.java (original)
+++ sling/trunk/installer/osgi/it/src/test/java/org/apache/sling/osgi/installer/it/BundleStatePreservedTest.java Fri Aug 21 10:15:34 2009
@@ -70,23 +70,21 @@
     	
     	// Execute some OsgiController operations
         installer.addResource(getInstallableResource(getTestBundle(BUNDLE_BASE_NAME + "-testbundle-1.0.jar")));
-        waitForInstallerAction(OsgiInstaller.INSTALLER_CYCLES_COUNTER, 1);
         installer.addResource(getInstallableResource(getTestBundle(BUNDLE_BASE_NAME + "-testbundle-1.2.jar")));
-        waitForInstallerAction(OsgiInstaller.INSTALLER_CYCLES_COUNTER, 1);
+        resetCounters();
         installer.addResource(getInstallableResource(getTestBundle(BUNDLE_BASE_NAME + "-testbundle-1.1.jar")));
-        waitForInstallerAction(OsgiInstaller.INSTALLER_CYCLES_COUNTER, 1);
-        
+        waitForInstallerAction(OsgiInstaller.WORKER_THREAD_BECOMES_IDLE_COUNTER, 1);
         assertBundle("After installing testbundle", "osgi-installer-testbundle", "1.2", Bundle.ACTIVE);
     	
         // Verify number of registered resources and groups
-        waitForInstallerAction(OsgiInstaller.INSTALLER_CYCLES_COUNTER, 1);
         assertCounter(OsgiInstaller.REGISTERED_RESOURCES_COUNTER, 5);
         assertCounter(OsgiInstaller.REGISTERED_GROUPS_COUNTER, 3);
     	
         installer.removeResource(getInstallableResource(getTestBundle(BUNDLE_BASE_NAME + "-testbundle-1.0.jar")));
         installer.removeResource(getInstallableResource(getTestBundle(BUNDLE_BASE_NAME + "-testbundle-1.1.jar")));
+        resetCounters();
         installer.removeResource(getInstallableResource(getTestBundle(BUNDLE_BASE_NAME + "-testbundle-1.2.jar")));
-        waitForInstallerAction(OsgiInstaller.INSTALLER_CYCLES_COUNTER, 2);
+        waitForInstallerAction(OsgiInstaller.OSGI_TASKS_COUNTER, 1);
         assertNull("testbundle must be gone at end of test", findBundle("osgi-installer-testbundle"));
         
     	// Now check that bundles A and B have kept their states

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=806483&r1=806482&r2=806483&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 Fri Aug 21 10:15:34 2009
@@ -95,7 +95,7 @@
             b.start();
             final long timeout = System.currentTimeMillis() + 2000L;
             while(b.getState() != Bundle.ACTIVE && System.currentTimeMillis() < timeout) {
-                Thread.sleep(10L);
+                sleep(10L);
             }
         } finally {
             if(is != null) {
@@ -130,10 +130,7 @@
                 if(packageRefreshEventsCount >= targetEventCount) {
                     break;
                 }
-                try {
-                    Thread.sleep(250L);
-                } catch(InterruptedException ignore) {
-                }
+                sleep(250L);
             }
         } finally {
             bundleContext.removeFrameworkListener(this);
@@ -205,7 +202,7 @@
         return result;
     }
     
-    protected void waitForConfigAdmin(boolean shouldBePresent) throws InterruptedException {
+    protected void waitForConfigAdmin(boolean shouldBePresent) {
         if(configAdminTracker == null) {
             synchronized (this) {
                 configAdminTracker = new ServiceTracker(bundleContext, ConfigurationAdmin.class.getName(), null);
@@ -220,7 +217,7 @@
     		if(isPresent == shouldBePresent) {
     			return;
     		}
-    		Thread.sleep(100L);
+    		sleep(100L);
     	} while(System.currentTimeMillis() < waitUntil);
     	fail("ConfigurationAdmin service not available after waiting " + timeout + " seconds");
     }
@@ -239,23 +236,40 @@
     }
     
     protected void waitForInstallerAction(int counterType, long howMany) {
-        // if waiting for installer cycles, get initial value from
-        // that counter - we know we want to wait from now on, not from an 
-        // earlier resetCounters() call
-        long targetValue = counters[counterType] + howMany;
-        if(counterType == OsgiInstaller.INSTALLER_CYCLES_COUNTER) {
+        waitForInstallerAction(null, counterType, howMany);
+    }
+    
+    /** @param howMany negative values means absolute, instead of relative to current value */
+    protected void waitForInstallerAction(String info, int counterType, long howMany) {
+        if(info == null) {
+            info = "";
+        } else {
+            info += ": ";
+        }
+        
+        final boolean waitForCycles = counterType == OsgiInstaller.INSTALLER_CYCLES_COUNTER;
+        
+        long targetValue = howMany <  0 ? -howMany : counters[counterType] + howMany;
+        if(waitForCycles) {
+            // if waiting for installer cycles, get initial value from
+            // that counter - we know we want to wait from now on, not from an 
+            // earlier resetCounters() call
             targetValue = installer.getCounters()[counterType] + howMany;
         }
+        
         final long endTime = System.currentTimeMillis() + WAIT_FOR_ACTION_TIMEOUT_MSEC;
         long lastValue = 0;
         while(System.currentTimeMillis() < endTime) {
-            lastValue = installer.getCounters()[counterType]; 
+            lastValue = installer.getCounters()[counterType];
             if(lastValue >= targetValue) {
                 return;
+            } else if(waitForCycles && installer.getCounters()[OsgiInstaller.WORKER_THREAD_IS_IDLE_COUNTER] == 1) {
+                // Waiting for controller cycles, but worker thread became idle -> ok
+                return;
             }
             sleep(10);
         }
-        fail("waitForInstallerAction(" + counterType + "," + howMany 
+        fail(info + "waitForInstallerAction(" + counterType + "," + howMany 
                 + ") fails after " + WAIT_FOR_ACTION_TIMEOUT_MSEC + " msec"
                 + ", expected value " + targetValue + ", actual " + lastValue);
     }

Modified: sling/trunk/installer/osgi/it/src/test/java/org/apache/sling/osgi/installer/it/RegisterResourcesTest.java
URL: http://svn.apache.org/viewvc/sling/trunk/installer/osgi/it/src/test/java/org/apache/sling/osgi/installer/it/RegisterResourcesTest.java?rev=806483&r1=806482&r2=806483&view=diff
==============================================================================
--- sling/trunk/installer/osgi/it/src/test/java/org/apache/sling/osgi/installer/it/RegisterResourcesTest.java (original)
+++ sling/trunk/installer/osgi/it/src/test/java/org/apache/sling/osgi/installer/it/RegisterResourcesTest.java Fri Aug 21 10:15:34 2009
@@ -58,6 +58,7 @@
     
     @Test
     public void initialRegistrationTest() throws IOException {
+        resetCounters();
         final List<InstallableResource> r = new ArrayList<InstallableResource>();
         r.add(getInstallableResource(getTestBundle(BUNDLE_BASE_NAME + "-testB-1.0.jar")));
         r.add(getInstallableResource(getTestBundle(BUNDLE_BASE_NAME + "-needsB.jar")));
@@ -65,7 +66,9 @@
         r.add(getInstallableResource(getTestBundle(BUNDLE_BASE_NAME + "-testbundle-1.2.jar")));
         
         installer.registerResources(r, URL_SCHEME);
-        waitForInstallerAction(OsgiInstaller.INSTALLER_CYCLES_COUNTER, 2);
+        
+        // Wait for worker thread to wake up and become idle once
+        waitForInstallerAction(OsgiInstaller.WORKER_THREAD_BECOMES_IDLE_COUNTER, 1);
         
         final String info = "After initial registration";
         assertBundle(info, "osgi-installer-testB", "1.0", Bundle.ACTIVE);
@@ -76,6 +79,7 @@
     @Test
     public void removeAndReaddBundlesTest() throws IOException, BundleException {
         {
+            resetCounters();
             final List<InstallableResource> r = new ArrayList<InstallableResource>();
             r.add(getInstallableResource(getTestBundle(BUNDLE_BASE_NAME + "-testB-1.0.jar")));
             r.add(getInstallableResource(getTestBundle(BUNDLE_BASE_NAME + "-needsB.jar")));
@@ -83,7 +87,7 @@
             r.add(getInstallableResource(getTestBundle(BUNDLE_BASE_NAME + "-testbundle-1.1.jar")));
             
             installer.registerResources(r, URL_SCHEME);
-            waitForInstallerAction(OsgiInstaller.INSTALLER_CYCLES_COUNTER, 2);
+            waitForInstallerAction(OsgiInstaller.WORKER_THREAD_BECOMES_IDLE_COUNTER, 1);
             
             final String info = "After initial registration";
             assertBundle(info, "osgi-installer-testB", "1.0", Bundle.ACTIVE);
@@ -93,8 +97,9 @@
         
         {
             // Add test 1.2 in between, to make sure it disappears in next registerResources call
+            resetCounters();
             installer.addResource(getInstallableResource(getTestBundle(BUNDLE_BASE_NAME + "-testbundle-1.2.jar")));
-            waitForInstallerAction(OsgiInstaller.INSTALLER_CYCLES_COUNTER, 2);
+            waitForInstallerAction(OsgiInstaller.WORKER_THREAD_BECOMES_IDLE_COUNTER, 1);
             assertBundle("After adding testbundle V1.2", "osgi-installer-testbundle", "1.2", Bundle.ACTIVE);
         }
         

Added: sling/trunk/installer/osgi/it/src/test/java/org/apache/sling/osgi/installer/it/WorkerThreadIdleTest.java
URL: http://svn.apache.org/viewvc/sling/trunk/installer/osgi/it/src/test/java/org/apache/sling/osgi/installer/it/WorkerThreadIdleTest.java?rev=806483&view=auto
==============================================================================
--- sling/trunk/installer/osgi/it/src/test/java/org/apache/sling/osgi/installer/it/WorkerThreadIdleTest.java (added)
+++ sling/trunk/installer/osgi/it/src/test/java/org/apache/sling/osgi/installer/it/WorkerThreadIdleTest.java Fri Aug 21 10:15:34 2009
@@ -0,0 +1,64 @@
+/*
+ * 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.assertNull;
+
+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;
+
+@RunWith(JUnit4TestRunner.class)
+public class WorkerThreadIdleTest extends OsgiInstallerTestBase {
+    
+    @org.ops4j.pax.exam.junit.Configuration
+    public static Option[] configuration() {
+        return defaultConfiguration();
+    }
+    
+    @Before
+    public void setUp() {
+        setupInstaller();
+    }
+    
+    @After
+    public void tearDown() {
+        super.tearDown();
+    }
+    
+    @Test
+    public void testWorkerThreadBecomesIdle() throws Exception {
+        waitForInstallerAction("Worker thread should become idle soon after controller starts",
+                OsgiInstaller.WORKER_THREAD_IS_IDLE_COUNTER, -1);
+        
+        final String symbolicName = "osgi-installer-testbundle";
+        assertNull("Test bundle must be absent before installing", findBundle(symbolicName));
+        resetCounters();
+        installer.addResource(getInstallableResource(getTestBundle(BUNDLE_BASE_NAME + "-testbundle-1.1.jar")));
+        // wait for two tasks: install and start
+        waitForInstallerAction(OsgiInstaller.OSGI_TASKS_COUNTER, 2);
+        assertBundle("After installing", symbolicName, "1.1", Bundle.ACTIVE);
+        
+        waitForInstallerAction("Worker thread should become idle after installing bundle",
+                OsgiInstaller.WORKER_THREAD_IS_IDLE_COUNTER, -1);
+    }
+}
\ No newline at end of file

Propchange: sling/trunk/installer/osgi/it/src/test/java/org/apache/sling/osgi/installer/it/WorkerThreadIdleTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: sling/trunk/installer/osgi/it/src/test/java/org/apache/sling/osgi/installer/it/WorkerThreadIdleTest.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision Rev URL