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();