Author: bdelacretaz
Date: Tue Dec  3 15:51:18 2013
New Revision: 1547444

URL: http://svn.apache.org/r1547444
Log:
SLING-1794 - improve synchronization and split between deferred install and 
remove tests, trying to avoid semi-random failures (haven't found the root 
cause yet)

Modified:
    
sling/trunk/installer/it/src/test/java/org/apache/sling/installer/it/ConfigInstallTest.java
    
sling/trunk/installer/it/src/test/java/org/apache/sling/installer/it/OsgiInstallerTestBase.java

Modified: 
sling/trunk/installer/it/src/test/java/org/apache/sling/installer/it/ConfigInstallTest.java
URL: 
http://svn.apache.org/viewvc/sling/trunk/installer/it/src/test/java/org/apache/sling/installer/it/ConfigInstallTest.java?rev=1547444&r1=1547443&r2=1547444&view=diff
==============================================================================
--- 
sling/trunk/installer/it/src/test/java/org/apache/sling/installer/it/ConfigInstallTest.java
 (original)
+++ 
sling/trunk/installer/it/src/test/java/org/apache/sling/installer/it/ConfigInstallTest.java
 Tue Dec  3 15:51:18 2013
@@ -20,12 +20,16 @@ import static org.junit.Assert.assertEqu
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertNull;
 
+import java.util.ArrayList;
 import java.util.Dictionary;
 import java.util.Hashtable;
 import java.util.LinkedList;
 import java.util.List;
+import java.util.concurrent.atomic.AtomicInteger;
 
 import org.apache.sling.installer.api.InstallableResource;
+import org.apache.sling.installer.api.event.InstallationEvent;
+import org.apache.sling.installer.api.event.InstallationListener;
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
@@ -45,7 +49,9 @@ public class ConfigInstallTest extends O
 
     private final static long TIMEOUT = 5000L;
     private List<ConfigurationEvent> events = new 
LinkedList<ConfigurationEvent>();
-    private ServiceRegistration serviceRegistration;
+    private List<ServiceRegistration<?>> serviceRegistrations = new 
ArrayList<ServiceRegistration<?>>();
+    private int installationEvents = 0;
+    private static final AtomicInteger counter = new AtomicInteger();
 
     @org.ops4j.pax.exam.Configuration
     public Option[] config() {
@@ -54,21 +60,34 @@ public class ConfigInstallTest extends O
     
     @Before
     public void setUp() {
+        installationEvents = 0;
         setupInstaller();
         events.clear();
-        serviceRegistration = 
bundleContext.registerService(ConfigurationListener.class.getName(), this, 
null);
+        serviceRegistrations.clear();
+        
serviceRegistrations.add(bundleContext.registerService(ConfigurationListener.class.getName(),
 this, null));
+        
+        final InstallationListener il = new InstallationListener() {
+            public void onEvent(InstallationEvent event) {
+                installationEvents++;
+            }
+        };
+        
serviceRegistrations.add(bundleContext.registerService(InstallationListener.class.getName(),
 il, null));
     }
 
     @Override
     @After
     public void tearDown() {
         super.tearDown();
-        if(serviceRegistration != null) {
-               serviceRegistration.unregister();
-               serviceRegistration = null;
+        for(ServiceRegistration<?> reg : serviceRegistrations) {
+               reg.unregister();
         }
+        serviceRegistrations.clear();
     }
-
+    
+    private String uniqueID() {
+        return counter.incrementAndGet() + "_" + System.currentTimeMillis();
+    }
+    
     /**
      * @see 
org.osgi.service.cm.ConfigurationListener#configurationEvent(org.osgi.service.cm.ConfigurationEvent)
      */
@@ -82,7 +101,7 @@ public class ConfigInstallTest extends O
     public void testInstallAndRemoveConfig() throws Exception {
         final Dictionary<String, Object> cfgData = new Hashtable<String, 
Object>();
         cfgData.put("foo", "bar");
-        final String cfgPid = getClass().getSimpleName() + "." + 
System.currentTimeMillis();
+        final String cfgPid = getClass().getSimpleName() + "." + uniqueID();
         assertNull("Config " + cfgPid + " must not be found before test", 
findConfiguration(cfgPid));
 
         // install config
@@ -115,7 +134,7 @@ public class ConfigInstallTest extends O
        waitForConfigAdmin(true);
 
        // check that configuration is not available
-        final String cfgPid = getClass().getSimpleName() + ".deferred." + 
System.currentTimeMillis();
+        final String cfgPid = getClass().getSimpleName() + ".deferred." + 
uniqueID();
         assertNull("Config " + cfgPid + " must not be found before test", 
findConfiguration(cfgPid));
        // create new configuration object
        final Dictionary<String, Object> cfgData = new Hashtable<String, 
Object>();
@@ -124,23 +143,52 @@ public class ConfigInstallTest extends O
        // Configuration installs must be deferred if ConfigAdmin service is 
stopped
         configAdmin.stop();
        waitForConfigAdmin(false);
+       
        // add new configuration
         final InstallableResource[] rsrc = getInstallableResource(cfgPid, 
cfgData);
+        installationEvents = 0;
         installer.updateResources(URL_SCHEME, rsrc, null);
-        // let's wait a little bit and restart configuration admin
-        sleep(1000L);
+        waitForInstallationEvents(2);
         configAdmin.start();
        waitForConfigAdmin(true);
         waitForConfiguration("Config must be installed once ConfigurationAdmin 
restarts",
                 cfgPid, TIMEOUT, true);
 
+        // Remove config and check
+        installer.updateResources(URL_SCHEME, null, new String[] 
{rsrc[0].getId()});
+        waitForConfiguration("Config must be removed once ConfigurationAdmin 
restarts",
+                cfgPid, TIMEOUT, false);
+    }
+
+    @Test
+    public void testDeferredConfigRemove() throws Exception {
+        // get config admin bundle and wait for service
+        final Bundle configAdmin = this.getConfigAdminBundle();
+        assertNotNull("ConfigAdmin bundle must be found", configAdmin);
+        waitForConfigAdmin(true);
+
+        // check that configuration is not available
+        final String cfgPid = getClass().getSimpleName() + ".deferred." + 
uniqueID();
+        assertNull("Config " + cfgPid + " must not be found before test", 
findConfiguration(cfgPid));
+        
+        // create and install new configuration object, verify
+        final Dictionary<String, Object> cfgData = new Hashtable<String, 
Object>();
+        cfgData.put("foo", "bar");
+        final InstallableResource[] rsrc = getInstallableResource(cfgPid, 
cfgData);
+        installationEvents = 0;
+        installer.updateResources(URL_SCHEME, rsrc, null);
+        waitForInstallationEvents(2);
+        waitForConfiguration("Config must be installed before stopping 
ConfigurationAdmin",
+                cfgPid, TIMEOUT, true);
+
         // Configuration uninstalls must be deferred if ConfigAdmin service is 
stopped
         configAdmin.stop();
         waitForConfigAdmin(false);
+        
         // remove configuration
+        installationEvents = 0;
         installer.updateResources(URL_SCHEME, null, new String[] 
{rsrc[0].getId()});
-        // let's wait a little bit and restart configuration admin
-        sleep(1000L);
+        waitForInstallationEvents(2);
         configAdmin.start();
         waitForConfigAdmin(true);
         waitForConfiguration("Config must be removed once ConfigurationAdmin 
restarts",
@@ -151,7 +199,7 @@ public class ConfigInstallTest extends O
     public void testReinstallSameConfig() throws Exception {
        final Dictionary<String, Object> cfgData = new Hashtable<String, 
Object>();
        cfgData.put("foo", "bar");
-       final String cfgPid = getClass().getSimpleName() + ".reinstall." + 
System.currentTimeMillis();
+       final String cfgPid = getClass().getSimpleName() + ".reinstall." + 
uniqueID();
        assertNull("Config " + cfgPid + " must not be found before test", 
findConfiguration(cfgPid));
 
        // Install config directly
@@ -217,4 +265,14 @@ public class ConfigInstallTest extends O
             return sb.toString();
         }
     }
+    
+    private void waitForInstallationEvents(final int howMany) throws Exception 
{
+        final Condition c = new Condition() {
+            @Override
+            boolean isTrue() throws Exception {
+                return installationEvents >= howMany;
+            }
+        };
+        waitForCondition("Wait for " + howMany + " installation events", 
TIMEOUT, c);
+    }
 }

Modified: 
sling/trunk/installer/it/src/test/java/org/apache/sling/installer/it/OsgiInstallerTestBase.java
URL: 
http://svn.apache.org/viewvc/sling/trunk/installer/it/src/test/java/org/apache/sling/installer/it/OsgiInstallerTestBase.java?rev=1547444&r1=1547443&r2=1547444&view=diff
==============================================================================
--- 
sling/trunk/installer/it/src/test/java/org/apache/sling/installer/it/OsgiInstallerTestBase.java
 (original)
+++ 
sling/trunk/installer/it/src/test/java/org/apache/sling/installer/it/OsgiInstallerTestBase.java
 Tue Dec  3 15:51:18 2013
@@ -40,6 +40,7 @@ import javax.inject.Inject;
 
 import org.apache.sling.installer.api.InstallableResource;
 import org.apache.sling.installer.api.OsgiInstaller;
+import org.junit.Before;
 import org.ops4j.pax.exam.Option;
 import org.osgi.framework.Bundle;
 import org.osgi.framework.BundleContext;
@@ -60,9 +61,9 @@ import org.osgi.service.packageadmin.Pac
 import org.osgi.util.tracker.ServiceTracker;
 
 /** Base class for OsgiInstaller testing */
-class OsgiInstallerTestBase implements FrameworkListener {
-       private final static String POM_VERSION = 
System.getProperty("osgi.installer.pom.version");
-    private final static String CONFIG_VERSION = 
System.getProperty("installer.configuration.version");
+public class OsgiInstallerTestBase implements FrameworkListener {
+       private final static String POM_VERSION = 
System.getProperty("osgi.installer.pom.version", "POM_VERSION_NOT_SET");
+    private final static String CONFIG_VERSION = 
System.getProperty("installer.configuration.version", 
"INSTALLER_VERSION_NOT_SET");
 
        public final static String JAR_EXT = ".jar";
        private int packageRefreshEventsCount;
@@ -102,6 +103,12 @@ class OsgiInstallerTestBase implements F
         installer = getService(OsgiInstaller.class);
     }
 
+    @Before
+    public void setup() {
+        configAdminTracker = new ServiceTracker(bundleContext, 
ConfigurationAdmin.class.getName(), null);
+        configAdminTracker.open();
+    }
+
     /** Tear down everything. */
     public void tearDown() {
         synchronized (this) {
@@ -203,7 +210,7 @@ class OsgiInstallerTestBase implements F
                if(c.isTrue()) {
                        return;
                }
-               Thread.sleep(c.getMsecBetweenEvaluations());
+               sleep(c.getMsecBetweenEvaluations());
         } while(System.currentTimeMillis() < end);
 
         if(c.additionalInfo() != null) {
@@ -221,7 +228,7 @@ class OsgiInstallerTestBase implements F
                if(value.equals(c.getProperties().get(key))) {
                        return;
                }
-               Thread.sleep(100L);
+               sleep(100L);
         } while(System.currentTimeMillis() < end);
         fail("Did not get " + key + "=" + value + " for config " + pid);
     }
@@ -329,12 +336,6 @@ class OsgiInstallerTestBase implements F
 
     protected ConfigurationAdmin waitForConfigAdmin(final boolean 
shouldBePresent) {
        ConfigurationAdmin result = null;
-        synchronized (this) {
-            if (configAdminTracker == null) {
-                configAdminTracker = new ServiceTracker(bundleContext, 
ConfigurationAdmin.class.getName(), null);
-                configAdminTracker.open();
-            }
-        }
 
         final int timeout = 5;
        final long waitUntil = System.currentTimeMillis() + (timeout * 1000L);
@@ -385,7 +386,7 @@ class OsgiInstallerTestBase implements F
        }
 
        // optional debugging
-       final String paxDebugLevel = System.getProperty("pax.exam.log.level");
+       final String paxDebugLevel = System.getProperty("pax.exam.log.level", 
"INFO");
        final String paxDebugPort = System.getProperty("pax.exam.debug.port");
        if(paxDebugPort != null && paxDebugPort.length() > 0) {
                vmOpt += " 
-Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=" + paxDebugPort;
@@ -534,9 +535,7 @@ class OsgiInstallerTestBase implements F
                         }
                     }
                 }
-                try {
-                    Thread.sleep(100);
-                } catch (InterruptedException ignore) {}
+                sleep(100);
             }
             logInstalledBundles();
             final StringBuilder sb = new StringBuilder();


Reply via email to