| /* |
| * 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.installer.it; |
| |
| import static org.junit.Assert.assertEquals; |
| import static org.junit.Assert.assertNotNull; |
| import static org.junit.Assert.fail; |
| import static org.ops4j.pax.exam.CoreOptions.frameworkProperty; |
| import static org.ops4j.pax.exam.CoreOptions.junitBundles; |
| import static org.ops4j.pax.exam.CoreOptions.mavenBundle; |
| import static org.ops4j.pax.exam.CoreOptions.options; |
| import static org.ops4j.pax.exam.CoreOptions.provision; |
| import static org.ops4j.pax.exam.CoreOptions.systemProperty; |
| import static org.ops4j.pax.exam.CoreOptions.when; |
| |
| import java.io.File; |
| import java.io.FileInputStream; |
| import java.io.IOException; |
| import java.io.InputStream; |
| import java.util.ArrayList; |
| import java.util.Dictionary; |
| import java.util.Enumeration; |
| import java.util.Hashtable; |
| import java.util.List; |
| |
| import javax.inject.Inject; |
| |
| import org.apache.sling.installer.api.InstallableResource; |
| import org.apache.sling.installer.api.OsgiInstaller; |
| import org.apache.sling.installer.api.ResourceChangeListener; |
| import org.apache.sling.installer.api.info.InfoProvider; |
| import org.apache.sling.installer.api.info.InstallationState; |
| import org.apache.sling.installer.api.info.Resource; |
| import org.apache.sling.installer.api.info.ResourceGroup; |
| import org.apache.sling.installer.api.tasks.ResourceState; |
| import org.junit.Before; |
| import org.ops4j.pax.exam.Option; |
| import org.osgi.framework.Bundle; |
| import org.osgi.framework.BundleContext; |
| import org.osgi.framework.BundleException; |
| import org.osgi.framework.Constants; |
| import org.osgi.framework.FrameworkEvent; |
| import org.osgi.framework.FrameworkListener; |
| import org.osgi.framework.ServiceReference; |
| import org.osgi.framework.SynchronousBundleListener; |
| import org.osgi.framework.Version; |
| import org.osgi.framework.namespace.PackageNamespace; |
| import org.osgi.framework.wiring.BundleCapability; |
| import org.osgi.framework.wiring.BundleWiring; |
| 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; |
| |
| /** Base class for OsgiInstaller testing */ |
| 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 volatile int packageRefreshEventsCount; |
| private volatile ServiceTracker configAdminTracker; |
| |
| protected volatile OsgiInstaller installer; |
| |
| protected volatile ResourceChangeListener resourceChangeListener; |
| |
| protected volatile InfoProvider infoProvider; |
| |
| private final static long WAIT_FOR_CHANGE_TIMEOUT = 5000L; |
| |
| public static final long WAIT_FOR_ACTION_TIMEOUT_MSEC = 6000; |
| public static final String BUNDLE_BASE_NAME = "org.apache.sling.installer.it-" + POM_VERSION; |
| |
| @Inject |
| protected BundleContext bundleContext; |
| |
| public static final String URL_SCHEME = "OsgiInstallerTest"; |
| |
| static abstract class Condition { |
| abstract boolean isTrue() throws Exception; |
| String additionalInfo() { return null; } |
| void onFailure() { } |
| long getMsecBetweenEvaluations() { return 100L; } |
| } |
| |
| /** |
| * Helper method to get a service of the given type |
| */ |
| @SuppressWarnings("unchecked") |
| protected <T> T getService(Class<T> clazz) { |
| final ServiceReference ref = bundleContext.getServiceReference(clazz.getName()); |
| assertNotNull("getService(" + clazz.getName() + ") must find ServiceReference", ref); |
| final T result = (T)(bundleContext.getService(ref)); |
| assertNotNull("getService(" + clazz.getName() + ") must find service", result); |
| return result; |
| } |
| |
| /** Set up the installer service. */ |
| protected void setupInstaller() { |
| installer = getService(OsgiInstaller.class); |
| resourceChangeListener = getService(ResourceChangeListener.class); |
| infoProvider = getService(InfoProvider.class); |
| } |
| |
| @Before |
| public void setup() { |
| configAdminTracker = new ServiceTracker(bundleContext, ConfigurationAdmin.class.getName(), null); |
| configAdminTracker.open(); |
| } |
| |
| /** Tear down everything. */ |
| public void tearDown() { |
| synchronized (this) { |
| if (configAdminTracker != null) { |
| configAdminTracker.close(); |
| configAdminTracker = null; |
| } |
| } |
| } |
| |
| /** |
| * Restart the installer. |
| */ |
| protected void restartInstaller() throws BundleException { |
| final String symbolicName = "org.apache.sling.installer.core"; |
| final Bundle b = findBundle(symbolicName); |
| if (b == null) { |
| fail("Bundle " + symbolicName + " not found"); |
| } |
| log(LogService.LOG_INFO, "Restarting " + symbolicName + " bundle"); |
| b.stop(); |
| b.start(); |
| setupInstaller(); |
| } |
| |
| protected void generateBundleEvent() throws Exception { |
| // install a bundle manually to generate a bundle event |
| final File f = getTestBundle("org.apache.sling.installer.it-" + POM_VERSION + "-testbundle-1.0.jar"); |
| final InputStream is = new FileInputStream(f); |
| Bundle b = null; |
| try { |
| b = bundleContext.installBundle(getClass().getName(), is); |
| b.start(); |
| final long timeout = System.currentTimeMillis() + 2000L; |
| while(b.getState() != Bundle.ACTIVE && System.currentTimeMillis() < timeout) { |
| sleep(10L); |
| } |
| } finally { |
| is.close(); |
| if (b != null) { |
| b.uninstall(); |
| } |
| } |
| } |
| |
| /** |
| * @see org.osgi.framework.FrameworkListener#frameworkEvent(org.osgi.framework.FrameworkEvent) |
| */ |
| @Override |
| public void frameworkEvent(FrameworkEvent event) { |
| if (event.getType() == FrameworkEvent.PACKAGES_REFRESHED) { |
| packageRefreshEventsCount++; |
| } |
| } |
| |
| protected void refreshPackages() { |
| bundleContext.addFrameworkListener(this); |
| final int MAX_REFRESH_PACKAGES_WAIT_SECONDS = 5; |
| final int targetEventCount = packageRefreshEventsCount + 1; |
| final long timeout = System.currentTimeMillis() + MAX_REFRESH_PACKAGES_WAIT_SECONDS * 1000L; |
| |
| final PackageAdmin pa = getService(PackageAdmin.class); |
| pa.refreshPackages(null); |
| |
| try { |
| while(true) { |
| if(System.currentTimeMillis() > timeout) { |
| break; |
| } |
| if(packageRefreshEventsCount >= targetEventCount) { |
| break; |
| } |
| sleep(250L); |
| } |
| } finally { |
| bundleContext.removeFrameworkListener(this); |
| } |
| } |
| |
| /** |
| * Encode the value for the ldap filter: \, *, (, and ) should be escaped. |
| */ |
| private static String encode(final String value) { |
| return value.replace("\\", "\\\\") |
| .replace("*", "\\*") |
| .replace("(", "\\(") |
| .replace(")", "\\)"); |
| } |
| |
| /** |
| * Find the configuration with the given pid. |
| */ |
| protected Configuration findConfiguration(final String pid) throws Exception { |
| final ConfigurationAdmin ca = this.waitForConfigAdmin(true); |
| if (ca != null) { |
| final Configuration[] cfgs = ca.listConfigurations("(" + Constants.SERVICE_PID + "=" + encode(pid) + ")"); |
| if (cfgs != null && cfgs.length > 0 ) { |
| if ( cfgs.length == 1 ) { |
| return cfgs[0]; |
| } |
| throw new IllegalStateException("More than one configuration for " + pid); |
| } |
| } |
| return null; |
| } |
| |
| /** |
| * Find the configuration with the given factory pid. |
| */ |
| protected Configuration findFactoryConfiguration(final String factoryPid) throws Exception { |
| final ConfigurationAdmin ca = this.waitForConfigAdmin(true); |
| if (ca != null) { |
| final Configuration[] cfgs = ca.listConfigurations("(" |
| + ConfigurationAdmin.SERVICE_FACTORYPID + "=" + encode(factoryPid) + ")"); |
| if (cfgs != null && cfgs.length > 0 ) { |
| if ( cfgs.length == 1 ) { |
| return cfgs[0]; |
| } |
| throw new IllegalStateException("More than one factory configuration for " + factoryPid); |
| } |
| } |
| return null; |
| } |
| |
| protected void waitForCondition(String info, Condition c) throws Exception { |
| this.waitForCondition(info, c, WAIT_FOR_CHANGE_TIMEOUT); |
| } |
| |
| protected void waitForCondition(String info, Condition c, final long timeOut) throws Exception { |
| final long end = System.currentTimeMillis() + timeOut; |
| do { |
| if(c.isTrue()) { |
| return; |
| } |
| sleep(c.getMsecBetweenEvaluations()); |
| } while(System.currentTimeMillis() < end); |
| |
| if(c.additionalInfo() != null) { |
| info += " " + c.additionalInfo(); |
| } |
| |
| c.onFailure(); |
| fail("WaitForCondition failed: " + info); |
| } |
| |
| protected Configuration waitForFactoryConfigValue(final String info, |
| final String factoryPid, |
| final String key, |
| final String value) |
| throws Exception { |
| final long end = System.currentTimeMillis() + WAIT_FOR_CHANGE_TIMEOUT; |
| do { |
| final Configuration c = waitForFactoryConfiguration(info, factoryPid, true); |
| if (value.equals(c.getProperties().get(key))) { |
| return c; |
| } |
| sleep(100L); |
| } while(System.currentTimeMillis() < end); |
| fail("Did not get " + key + "=" + value + " for factory config " + factoryPid); |
| return null; |
| } |
| |
| protected Configuration waitForConfigValue(final String info, |
| final String pid, |
| final String key, |
| final String value) |
| throws Exception { |
| final long end = System.currentTimeMillis() + WAIT_FOR_CHANGE_TIMEOUT; |
| do { |
| final Configuration c = waitForConfiguration(info, pid, true); |
| if (value.equals(c.getProperties().get(key))) { |
| return c; |
| } |
| sleep(100L); |
| } while(System.currentTimeMillis() < end); |
| fail("Did not get " + key + "=" + value + " for config " + pid); |
| return null; |
| } |
| |
| /** |
| * Wait for a configuration. |
| */ |
| protected Configuration waitForConfiguration(final String info, |
| final String pid, |
| final boolean shouldBePresent) |
| throws Exception { |
| return this.waitForConfiguration(info, pid, null, shouldBePresent); |
| } |
| |
| /** |
| * Wait for a factory configuration. |
| */ |
| protected Configuration waitForFactoryConfiguration(final String info, |
| final String factoryPid, |
| final boolean shouldBePresent) |
| throws Exception { |
| return this.waitForConfiguration(info, null, factoryPid, shouldBePresent); |
| } |
| |
| /** |
| * Internal method to wait for a configuration |
| */ |
| private Configuration waitForConfiguration(final String info, |
| final String pid, |
| final String factoryPid, |
| final boolean shouldBePresent) |
| throws Exception { |
| final String logKey = factoryPid == null ? "config" : "factory config"; |
| String msg; |
| if (info == null) { |
| msg = ""; |
| } else { |
| msg = info + ": "; |
| } |
| |
| Configuration result = null; |
| final long start = System.currentTimeMillis(); |
| final long end = start + WAIT_FOR_CHANGE_TIMEOUT; |
| log(LogService.LOG_DEBUG, "Starting " + logKey + " check at " + start + "; ending by " + end); |
| do { |
| if ( factoryPid != null ) { |
| result = findFactoryConfiguration(factoryPid); |
| } else { |
| result = findConfiguration(pid); |
| } |
| if ((shouldBePresent && result != null) || |
| (!shouldBePresent && result == null)) { |
| break; |
| } |
| log(LogService.LOG_DEBUG, logKey + " check failed at " + System.currentTimeMillis() + "; sleeping"); |
| sleep(25); |
| } while(System.currentTimeMillis() < end); |
| |
| if (shouldBePresent && result == null) { |
| fail(msg + logKey + " not found (" + (factoryPid != null ? factoryPid : pid) + ")"); |
| } else if (!shouldBePresent && result != null) { |
| fail(msg + logKey + " is still present (" + (factoryPid != null ? factoryPid : pid) + ")"); |
| } |
| return result; |
| } |
| |
| protected Bundle findBundle(String symbolicName) { |
| for(Bundle b : bundleContext.getBundles()) { |
| if (symbolicName.equals(b.getSymbolicName())) { |
| return b; |
| } |
| } |
| return null; |
| } |
| |
| protected Bundle assertBundle(String info, String symbolicName, String version, int state) { |
| final Bundle b = findBundle(symbolicName); |
| if(info == null) { |
| info = ""; |
| } else { |
| info += ": "; |
| } |
| assertNotNull(info + "Expected bundle " + symbolicName + " to be installed", b); |
| if(version != null) { |
| assertEquals(info + "Expected bundle " + symbolicName + " to be version " + version, |
| version, b.getHeaders().get(Constants.BUNDLE_VERSION)); |
| } |
| if(state >= 0) { |
| assertEquals(info + "Expected bundle " + symbolicName + " to be in state " + state, |
| state, b.getState()); |
| } |
| return b; |
| } |
| |
| protected File getTestBundle(String bundleName) { |
| return new File(System.getProperty("osgi.installer.base.dir"), bundleName); |
| } |
| |
| protected InstallableResource[] getInstallableResource(File testBundle) throws IOException { |
| return getInstallableResource(testBundle, null); |
| } |
| |
| protected String[] getNonInstallableResourceUrl(File testBundle) throws IOException { |
| return new String[] {testBundle.getAbsolutePath()}; |
| } |
| |
| protected InstallableResource[] getInstallableResource(File testBundle, String digest) throws IOException { |
| return getInstallableResource(testBundle, digest, InstallableResource.DEFAULT_PRIORITY); |
| } |
| |
| protected InstallableResource[] getInstallableResource(File testBundle, String digest, int priority) throws IOException { |
| final String url = testBundle.getAbsolutePath(); |
| if (digest == null) { |
| digest = String.valueOf(testBundle.lastModified()); |
| } |
| final InstallableResource result = new MockInstallableResource(url, new FileInputStream(testBundle), digest, null, priority); |
| return new InstallableResource[] {result}; |
| } |
| |
| protected InstallableResource[] getInstallableResource(String configPid, Dictionary<String, Object> data) { |
| return getInstallableResource(configPid, copy(data), InstallableResource.DEFAULT_PRIORITY); |
| } |
| |
| protected InstallableResource[] getInstallableResource(String configPid, Dictionary<String, Object> data, int priority) { |
| final InstallableResource result = new MockInstallableResource("/" + configPid, copy(data), null, null, priority); |
| return new InstallableResource[] {result}; |
| } |
| |
| protected Dictionary<String, Object> copy(Dictionary<String, Object> data) { |
| final Dictionary<String, Object> copy = new Hashtable<String, Object>(); |
| final Enumeration<String> keys = data.keys(); |
| while(keys.hasMoreElements()) { |
| final String key = keys.nextElement(); |
| copy.put(key, data.get(key)); |
| } |
| return copy; |
| } |
| |
| protected ConfigurationAdmin waitForConfigAdmin(final boolean shouldBePresent) { |
| ConfigurationAdmin result = null; |
| |
| final int timeout = 5; |
| final long waitUntil = System.currentTimeMillis() + (timeout * 1000L); |
| boolean isPresent; |
| do { |
| result = (ConfigurationAdmin)configAdminTracker.getService(); |
| isPresent = result != null; |
| if ( shouldBePresent == isPresent ) { |
| return result; |
| } |
| } while(System.currentTimeMillis() < waitUntil); |
| |
| assertEquals("Expected ConfigurationAdmin to be " + (shouldBePresent ? "present" : "absent"), |
| shouldBePresent, isPresent); |
| return result; |
| } |
| |
| protected Bundle getConfigAdminBundle() { |
| this.waitForConfigAdmin(true); |
| return this.configAdminTracker.getServiceReference().getBundle(); |
| } |
| |
| /** |
| * Helper method for sleeping. |
| */ |
| protected void sleep(long msec) { |
| try { |
| Thread.sleep(msec); |
| } catch(InterruptedException ignored) { |
| } |
| } |
| |
| protected void log(int level, String msg) { |
| final LogService log = getService(LogService.class); |
| log.log(level, msg); |
| } |
| |
| protected String requiredServices() { |
| return "resourcetransformer:org.osgi.service.cm,installtaskfactory:org.osgi.service.cm"; |
| } |
| |
| protected Option[] defaultConfiguration() { |
| String vmOpt = "-Dosgi.installer.testing"; |
| |
| // This runs in the VM that runs the build, but the tests run in another one. |
| // Make all osgi.installer.* system properties available to OSGi framework VM |
| for(Object o : System.getProperties().keySet()) { |
| final String key = (String)o; |
| if(key.startsWith("osgi.installer.")) { |
| vmOpt += " -D" + key + "=" + System.getProperty(key); |
| } |
| } |
| |
| // optional debugging |
| final String paxDebugLevel = System.getProperty("pax.exam.log.level", "INFO"); |
| |
| String localRepo = System.getProperty("maven.repo.local", ""); |
| |
| return options( |
| |
| junitBundles(), |
| when( localRepo.length() > 0 ).useOptions( |
| systemProperty("org.ops4j.pax.url.mvn.localRepository").value(localRepo) |
| ), |
| systemProperty( "org.ops4j.pax.logging.DefaultServiceLog.level" ).value(paxDebugLevel), |
| frameworkProperty("sling.installer.requiredservices").value(requiredServices()), |
| provision( |
| mavenBundle("org.apache.sling", "org.apache.sling.commons.log", "4.0.6"), |
| mavenBundle("org.apache.sling", "org.apache.sling.commons.logservice", "1.0.6"), |
| |
| mavenBundle("org.slf4j", "slf4j-api", "1.7.5"), |
| mavenBundle("org.slf4j", "jcl-over-slf4j", "1.7.5"), |
| mavenBundle("org.slf4j", "log4j-over-slf4j", "1.7.5"), |
| |
| mavenBundle("org.apache.felix", "org.apache.felix.scr", "2.0.6"), |
| mavenBundle("org.apache.felix", "org.apache.felix.configadmin", "1.8.12"), |
| mavenBundle("org.apache.felix", "org.apache.felix.metatype", "1.1.2"), |
| mavenBundle("org.apache.sling", "org.apache.sling.installer.core", POM_VERSION).startLevel(5), |
| mavenBundle("org.apache.sling", "org.apache.sling.installer.factory.configuration", CONFIG_VERSION).startLevel(5) |
| ) |
| ); |
| } |
| |
| protected Object startObservingBundleEvents() { |
| final BundleEventListener listener = new BundleEventListener(); |
| this.bundleContext.addBundleListener(listener); |
| return listener; |
| } |
| |
| public static final class BundleEvent { |
| public final String symbolicName; |
| public final Version version; |
| public final int state; |
| |
| public BundleEvent(final String sn, final String v, final int s) { |
| this.symbolicName = sn; |
| this.version = (v == null ? null : Version.parseVersion(v)); |
| this.state = s; |
| } |
| |
| public BundleEvent(final String sn, final int s) { |
| this(sn, null, s); |
| } |
| |
| @Override |
| public String toString() { |
| return "BundleEvent " + symbolicName + ", version=" + version + ", state="+state; |
| } |
| } |
| |
| protected void waitForBundleEvents(final String msg, final Object l, BundleEvent... events) |
| throws Exception { |
| final BundleEventListener listener = (BundleEventListener)l; |
| try { |
| listener.wait(msg, events, WAIT_FOR_ACTION_TIMEOUT_MSEC); |
| } finally { |
| this.bundleContext.removeBundleListener(listener); |
| } |
| } |
| |
| protected void waitForBundleEvents(final String msg, final Object l, long timeout, BundleEvent... events) |
| throws Exception { |
| final BundleEventListener listener = (BundleEventListener)l; |
| try { |
| listener.wait(msg, events, timeout); |
| } finally { |
| this.bundleContext.removeBundleListener(listener); |
| } |
| } |
| |
| protected void assertNoBundleEvents(final String msg, final Object l, final String symbolicName) { |
| final BundleEventListener listener = (BundleEventListener)l; |
| try { |
| listener.assertNoBundleEvents(msg, symbolicName); |
| } finally { |
| this.bundleContext.removeBundleListener(listener); |
| } |
| } |
| |
| protected boolean isPackageExported(Bundle b, String packageName) { |
| final BundleWiring wiring = b.adapt(BundleWiring.class); |
| assertNotNull("Expecting non-null BundleWiring for bundle " + b, wiring); |
| for(BundleCapability c : wiring.getCapabilities(PackageNamespace.PACKAGE_NAMESPACE)) { |
| if(packageName.equals(c.getAttributes().get(PackageNamespace.PACKAGE_NAMESPACE))) { |
| return true; |
| } |
| } |
| return false; |
| } |
| |
| public void logInstalledBundles() { |
| for(Bundle b : bundleContext.getBundles()) { |
| log(LogService.LOG_DEBUG, "Installed bundle: " + b.getSymbolicName()); |
| } |
| } |
| |
| protected Resource waitForResource(final String url, |
| final ResourceState state) { |
| final long start = System.currentTimeMillis(); |
| final long end = start + WAIT_FOR_CHANGE_TIMEOUT; |
| |
| do { |
| final InstallationState is = this.infoProvider.getInstallationState(); |
| for(final ResourceGroup rg : (state == ResourceState.INSTALL || state == ResourceState.UNINSTALL ? is.getActiveResources() : is.getInstalledResources())) { |
| for(final Resource rsrc : rg.getResources()) { |
| if ( url.equals(rsrc.getURL()) ) { |
| if ( rsrc.getState() == state ) { |
| return rsrc; |
| } |
| } |
| } |
| } |
| sleep(50); |
| } while ( System.currentTimeMillis() < end); |
| fail("Resource " + url + " not found with state " + state + " : " + this.infoProvider.getInstallationState()); |
| return null; |
| } |
| |
| private final class BundleEventListener implements SynchronousBundleListener { |
| |
| private final List<BundleEvent> events = new ArrayList<BundleEvent>(); |
| |
| @Override |
| public void bundleChanged(org.osgi.framework.BundleEvent event) { |
| synchronized ( this ) { |
| events.add(new BundleEvent(event.getBundle().getSymbolicName(), event.getBundle().getVersion().toString(), event.getType())); |
| } |
| } |
| |
| public void wait(final String msg, final BundleEvent[] checkEvents, final long timeoutMsec) |
| throws Exception { |
| if ( checkEvents == null || checkEvents.length == 0 ) { |
| return; |
| } |
| final long start = System.currentTimeMillis(); |
| final long end = start + timeoutMsec; |
| log(LogService.LOG_DEBUG, "Starting event check at " + start + "; ending by " + end); |
| while ( System.currentTimeMillis() < end ) { |
| synchronized ( this) { |
| if ( this.events.size() >= checkEvents.length ) { |
| int found = 0; |
| for(final BundleEvent e : checkEvents ) { |
| int startIndex = 0; |
| final int oldFound = found; |
| while ( oldFound == found && startIndex < this.events.size() ) { |
| final BundleEvent bundleEvent = this.events.get(startIndex); |
| // first check symbolic name |
| if ( e.symbolicName == null || e.symbolicName.equals(bundleEvent.symbolicName) ) { |
| if ( e.version == null || e.version.equals(bundleEvent.version) ) { |
| if ( e.state == bundleEvent.state ) { |
| found++; |
| } |
| } |
| } |
| if ( oldFound == found ) { |
| startIndex++; |
| } |
| } |
| } |
| if ( found == checkEvents.length ) { |
| return; |
| } |
| } |
| } |
| sleep(100); |
| } |
| logInstalledBundles(); |
| final StringBuilder sb = new StringBuilder(); |
| sb.append(msg); |
| sb.append(" : Expected events=[\n"); |
| for(final BundleEvent be : checkEvents) { |
| sb.append(be); |
| sb.append("\n"); |
| } |
| sb.append("]\nreceived events=[\n"); |
| for(final BundleEvent be : this.events) { |
| sb.append(be); |
| sb.append("\n"); |
| } |
| sb.append("]\n"); |
| fail(sb.toString()); |
| } |
| |
| public void assertNoBundleEvents(final String msg, final String symbolicName) { |
| boolean found = false; |
| synchronized ( this ) { |
| if ( symbolicName == null ) { |
| found = this.events.size() > 0; |
| } else { |
| for(BundleEvent e : this.events ) { |
| if ( symbolicName.equals(e.symbolicName) ) { |
| found = true; |
| break; |
| } |
| } |
| } |
| } |
| if ( found ) { |
| fail(msg + " : Expected to receive no bundle events for bundle " + symbolicName); |
| } |
| } |
| } |
| } |