You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@karaf.apache.org by cs...@apache.org on 2012/09/28 12:15:54 UTC

svn commit: r1391384 - in /karaf/trunk/features/core/src: main/java/org/apache/karaf/features/internal/ test/java/org/apache/karaf/features/ test/java/org/apache/karaf/features/internal/

Author: cschneider
Date: Fri Sep 28 10:15:53 2012
New Revision: 1391384

URL: http://svn.apache.org/viewvc?rev=1391384&view=rev
Log:
KARAF-608 Making installBundleIfNeeded independent of InstallationState and so easier to mock. Adding Apache headers 

Added:
    karaf/trunk/features/core/src/test/java/org/apache/karaf/features/internal/BundleManagerTest.java   (with props)
Modified:
    karaf/trunk/features/core/src/main/java/org/apache/karaf/features/internal/BootFeaturesInstaller.java
    karaf/trunk/features/core/src/main/java/org/apache/karaf/features/internal/BundleManager.java
    karaf/trunk/features/core/src/main/java/org/apache/karaf/features/internal/FeatureConfigInstaller.java
    karaf/trunk/features/core/src/main/java/org/apache/karaf/features/internal/FeaturesServiceImpl.java
    karaf/trunk/features/core/src/main/java/org/apache/karaf/features/internal/InstallationState.java
    karaf/trunk/features/core/src/test/java/org/apache/karaf/features/FeaturesServiceTest.java
    karaf/trunk/features/core/src/test/java/org/apache/karaf/features/internal/FeaturesServiceImplTest.java

Modified: karaf/trunk/features/core/src/main/java/org/apache/karaf/features/internal/BootFeaturesInstaller.java
URL: http://svn.apache.org/viewvc/karaf/trunk/features/core/src/main/java/org/apache/karaf/features/internal/BootFeaturesInstaller.java?rev=1391384&r1=1391383&r2=1391384&view=diff
==============================================================================
--- karaf/trunk/features/core/src/main/java/org/apache/karaf/features/internal/BootFeaturesInstaller.java (original)
+++ karaf/trunk/features/core/src/main/java/org/apache/karaf/features/internal/BootFeaturesInstaller.java Fri Sep 28 10:15:53 2012
@@ -1,3 +1,19 @@
+/*
+ * 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.karaf.features.internal;
 
 import java.util.Arrays;

Modified: karaf/trunk/features/core/src/main/java/org/apache/karaf/features/internal/BundleManager.java
URL: http://svn.apache.org/viewvc/karaf/trunk/features/core/src/main/java/org/apache/karaf/features/internal/BundleManager.java?rev=1391384&r1=1391383&r2=1391384&view=diff
==============================================================================
--- karaf/trunk/features/core/src/main/java/org/apache/karaf/features/internal/BundleManager.java (original)
+++ karaf/trunk/features/core/src/main/java/org/apache/karaf/features/internal/BundleManager.java Fri Sep 28 10:15:53 2012
@@ -1,9 +1,26 @@
+/*
+ * 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.karaf.features.internal;
 
 import java.io.BufferedInputStream;
 import java.io.File;
 import java.io.IOException;
 import java.io.InputStream;
+import java.net.MalformedURLException;
 import java.net.URL;
 import java.util.ArrayList;
 import java.util.Arrays;
@@ -62,24 +79,14 @@ public class BundleManager {
         this.refreshTimeout = refreshTimeout;
     }
     
-    long installBundleIfNeeded(InstallationState state, String bundleLocation, int startLevel, String regionName, boolean verbose) throws IOException, BundleException {
-        Bundle b = doInstallBundleIfNeeded(state, bundleLocation, startLevel, verbose);
-        installToRegion(state, regionName, b);
-        return b.getBundleId();
+    public BundleInstallerResult installBundleIfNeeded(String bundleLocation, int startLevel, String regionName) throws IOException, BundleException {
+        BundleInstallerResult result = doInstallBundleIfNeeded(bundleLocation, startLevel);
+        installToRegion(regionName, result.bundle, result.isNew);
+        return result;
     }
 
-    private Bundle doInstallBundleIfNeeded(InstallationState state, String bundleLocation, int startLevel, boolean verbose) throws IOException, BundleException {
-        InputStream is;
-        LOGGER.debug("Checking " + bundleLocation);
-        try {
-            String protocol = bundleLocation.substring(0, bundleLocation.indexOf(":"));
-            waitForUrlHandler(protocol);
-            URL bundleUrl = new URL(bundleLocation);
-            is = new BufferedInputStream(bundleUrl.openStream());
-        } catch (RuntimeException e) {
-            LOGGER.error(e.getMessage());
-            throw e;
-        }
+    private BundleInstallerResult doInstallBundleIfNeeded(String bundleLocation, int startLevel) throws IOException, BundleException {
+        InputStream is = getInputStreamForBundle(bundleLocation);
         try {
             is.mark(256 * 1024);
             JarInputStream jar = new JarInputStream(is);
@@ -98,19 +105,10 @@ public class BundleManager {
             }
             String vStr = m.getMainAttributes().getValue(Constants.BUNDLE_VERSION);
             Version v = vStr == null ? Version.emptyVersion : Version.parseVersion(vStr);
-            for (Bundle b : bundleContext.getBundles()) {
-                if (b.getSymbolicName() != null && b.getSymbolicName().equals(sn)) {
-                    vStr = (String) b.getHeaders().get(Constants.BUNDLE_VERSION);
-                    Version bv = vStr == null ? Version.emptyVersion : Version.parseVersion(vStr);
-                    if (v.equals(bv)) {
-                        LOGGER.debug("Found installed bundle: " + b);
-                        if (verbose) {
-                            System.out.println("Found installed bundle: " + b);
-                        }
-                        state.bundles.add(b);
-                        return b;
-                    }
-                }
+            Bundle existingBundle = findInstalled(sn, v);
+            if (existingBundle != null) {
+                LOGGER.debug("Found installed bundle: " + existingBundle);
+                return new BundleInstallerResult(existingBundle, false);
             }
             try {
                 is.reset();
@@ -119,25 +117,49 @@ public class BundleManager {
                 is = new BufferedInputStream(new URL(bundleLocation).openStream());
             }
             LOGGER.debug("Installing bundle " + bundleLocation);
-            if (verbose) {
-                System.out.println("Installing bundle " + bundleLocation);
-            }
             Bundle b = bundleContext.installBundle(bundleLocation, is);
             
             if (startLevel > 0) {
                 b.adapt(BundleStartLevel.class).setStartLevel(startLevel);
             }
 
-            state.bundles.add(b);
-            state.installed.add(b);
-            return b;
+            return new BundleInstallerResult(b, true);
         } finally {
             is.close();
         }
     }
+
+    private Bundle findInstalled(String symbolicName, Version version) {
+        String vStr;
+        for (Bundle b : bundleContext.getBundles()) {
+            if (b.getSymbolicName() != null && b.getSymbolicName().equals(symbolicName)) {
+                vStr = (String) b.getHeaders().get(Constants.BUNDLE_VERSION);
+                Version bv = vStr == null ? Version.emptyVersion : Version.parseVersion(vStr);
+                if (version.equals(bv)) {
+                    return b;
+                }
+            }
+        }
+        return null;
+    }
+
+    private InputStream getInputStreamForBundle(String bundleLocation) throws MalformedURLException, IOException {
+        InputStream is;
+        LOGGER.debug("Checking " + bundleLocation);
+        try {
+            String protocol = bundleLocation.substring(0, bundleLocation.indexOf(":"));
+            waitForUrlHandler(protocol);
+            URL bundleUrl = new URL(bundleLocation);
+            is = new BufferedInputStream(bundleUrl.openStream());
+        } catch (RuntimeException e) {
+            LOGGER.error(e.getMessage());
+            throw e;
+        }
+        return is;
+    }
     
-    private void installToRegion(InstallationState state, String region, Bundle b) throws BundleException {
-        if (region != null && state.installed.contains(b)) {
+    private void installToRegion(String region, Bundle b, boolean isNew) throws BundleException {
+        if (region != null && isNew) {
             if (regionsPersistence != null) {
                 regionsPersistence.install(b, region);
             } else {
@@ -373,4 +395,16 @@ public class BundleManager {
             }
         }
     }
+    
+    public static class BundleInstallerResult {
+        Bundle bundle;
+        boolean isNew;
+
+        public BundleInstallerResult(Bundle bundle, boolean isNew) {
+            super();
+            this.bundle = bundle;
+            this.isNew = isNew;
+        }
+
+    }
 }

Modified: karaf/trunk/features/core/src/main/java/org/apache/karaf/features/internal/FeatureConfigInstaller.java
URL: http://svn.apache.org/viewvc/karaf/trunk/features/core/src/main/java/org/apache/karaf/features/internal/FeatureConfigInstaller.java?rev=1391384&r1=1391383&r2=1391384&view=diff
==============================================================================
--- karaf/trunk/features/core/src/main/java/org/apache/karaf/features/internal/FeatureConfigInstaller.java (original)
+++ karaf/trunk/features/core/src/main/java/org/apache/karaf/features/internal/FeatureConfigInstaller.java Fri Sep 28 10:15:53 2012
@@ -1,3 +1,19 @@
+/*
+ * 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.karaf.features.internal;
 
 import java.io.BufferedInputStream;

Modified: karaf/trunk/features/core/src/main/java/org/apache/karaf/features/internal/FeaturesServiceImpl.java
URL: http://svn.apache.org/viewvc/karaf/trunk/features/core/src/main/java/org/apache/karaf/features/internal/FeaturesServiceImpl.java?rev=1391384&r1=1391383&r2=1391384&view=diff
==============================================================================
--- karaf/trunk/features/core/src/main/java/org/apache/karaf/features/internal/FeaturesServiceImpl.java (original)
+++ karaf/trunk/features/core/src/main/java/org/apache/karaf/features/internal/FeaturesServiceImpl.java Fri Sep 28 10:15:53 2012
@@ -54,6 +54,7 @@ import org.apache.karaf.features.Feature
 import org.apache.karaf.features.Repository;
 import org.apache.karaf.features.RepositoryEvent;
 import org.apache.karaf.features.Resolver;
+import org.apache.karaf.features.internal.BundleManager.BundleInstallerResult;
 import org.apache.karaf.util.collections.CopyOnWriteArrayIdentityList;
 import org.osgi.framework.Bundle;
 import org.osgi.framework.BundleException;
@@ -78,7 +79,7 @@ public class FeaturesServiceImpl impleme
 
     private long resolverTimeout = 5000;
     private Set<URI> uris;
-    private Map<URI, RepositoryImpl> repositories = new HashMap<URI, RepositoryImpl>();
+    private Map<URI, Repository> repositories = new HashMap<URI, Repository>();
     private Map<String, Map<String, Feature>> features;
     private Map<Feature, Set<Long>> installed = new HashMap<Feature, Set<Long>>();
     private List<FeaturesListener> listeners = new CopyOnWriteArrayIdentityList<FeaturesListener>();
@@ -133,6 +134,7 @@ public class FeaturesServiceImpl impleme
      * @param uri the features repository URI.
      */
     public void validateRepository(URI uri) throws Exception {
+        
         FeatureValidationUtil.validate(uri);
     }
 
@@ -155,7 +157,7 @@ public class FeaturesServiceImpl impleme
      */
     public void addRepository(URI uri, boolean install) throws Exception {
         if (!repositories.containsKey(uri)) {
-            RepositoryImpl repositoryImpl = this.internalAddRepository(uri);
+            Repository repositoryImpl = this.internalAddRepository(uri);
             saveState();
             if (install) {
                 for (Feature feature : repositoryImpl.getFeatures()) {
@@ -202,7 +204,7 @@ public class FeaturesServiceImpl impleme
      * @return the internal <code>RepositoryImpl</code> representation.
      * @throws Exception in case of adding failure.
      */
-    protected RepositoryImpl internalAddRepository(URI uri) throws Exception {
+    protected Repository internalAddRepository(URI uri) throws Exception {
         validateRepository(uri);
         RepositoryImpl repo = new RepositoryImpl(uri);
         repositories.put(uri, repo);
@@ -233,7 +235,7 @@ public class FeaturesServiceImpl impleme
     public void removeRepository(URI uri, boolean uninstall) throws Exception {
         if (repositories.containsKey(uri)) {
             if (uninstall) {
-                RepositoryImpl repositoryImpl = repositories.get(uri);
+                Repository repositoryImpl = repositories.get(uri);
                 for (Feature feature : repositoryImpl.getFeatures()) {
                     this.uninstallFeature(feature.getName(), feature.getVersion());
                 }
@@ -262,7 +264,7 @@ public class FeaturesServiceImpl impleme
      * @throws Exception in case of restore failure.
      */
     public void restoreRepository(URI uri) throws Exception {
-    	repositories.put(uri, (RepositoryImpl)repo.get());
+    	repositories.put(uri, repo.get());
     	callListeners(new RepositoryEvent(repo.get(), RepositoryEvent.EventType.RepositoryAdded, false));
         features = null;
     }
@@ -273,7 +275,7 @@ public class FeaturesServiceImpl impleme
      * @return the list of features repository.
      */
     public Repository[] listRepositories() {
-        Collection<RepositoryImpl> repos = repositories.values();
+        Collection<Repository> repos = repositories.values();
         return repos.toArray(new Repository[repos.size()]);
     }
     
@@ -504,9 +506,21 @@ public class FeaturesServiceImpl impleme
         
         for (BundleInfo bInfo : resolve(feature)) {
             int startLevel = getBundleStartLevel(bInfo.getStartLevel(),feature.getStartLevel());
-            long bundleId = bundleManager.installBundleIfNeeded(state, bInfo.getLocation(), startLevel, feature.getRegion(), verbose);
-            bundles.add(bundleId);
-            state.bundleInfos.put(bundleId, bInfo);
+            BundleInstallerResult result = bundleManager.installBundleIfNeeded(bInfo.getLocation(), startLevel, feature.getRegion());
+            state.bundles.add(result.bundle);
+            if (result.isNew) {
+                state.installed.add(result.bundle);
+            }
+            if (verbose) {
+                if (result.isNew) {
+                    System.out.println("Found installed bundle: " + result.bundle);
+                } else {
+                    System.out.println("Installing bundle " + bInfo.getLocation());
+                }
+            }
+
+            bundles.add(result.bundle.getBundleId());
+            state.bundleInfos.put(result.bundle.getBundleId(), bInfo);
 
         }
         state.features.put(feature, bundles);

Modified: karaf/trunk/features/core/src/main/java/org/apache/karaf/features/internal/InstallationState.java
URL: http://svn.apache.org/viewvc/karaf/trunk/features/core/src/main/java/org/apache/karaf/features/internal/InstallationState.java?rev=1391384&r1=1391383&r2=1391384&view=diff
==============================================================================
--- karaf/trunk/features/core/src/main/java/org/apache/karaf/features/internal/InstallationState.java (original)
+++ karaf/trunk/features/core/src/main/java/org/apache/karaf/features/internal/InstallationState.java Fri Sep 28 10:15:53 2012
@@ -1,3 +1,19 @@
+/*
+ * 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.karaf.features.internal;
 
 import java.util.HashMap;
@@ -10,7 +26,7 @@ import org.apache.karaf.features.BundleI
 import org.apache.karaf.features.Feature;
 import org.osgi.framework.Bundle;
 
-class InstallationState {
+public class InstallationState {
     final Set<Bundle> installed = new HashSet<Bundle>();
     final Set<Bundle> bundles = new TreeSet<Bundle>();
     final Map<Long, BundleInfo> bundleInfos = new HashMap<Long, BundleInfo>();

Modified: karaf/trunk/features/core/src/test/java/org/apache/karaf/features/FeaturesServiceTest.java
URL: http://svn.apache.org/viewvc/karaf/trunk/features/core/src/test/java/org/apache/karaf/features/FeaturesServiceTest.java?rev=1391384&r1=1391383&r2=1391384&view=diff
==============================================================================
--- karaf/trunk/features/core/src/test/java/org/apache/karaf/features/FeaturesServiceTest.java (original)
+++ karaf/trunk/features/core/src/test/java/org/apache/karaf/features/FeaturesServiceTest.java Fri Sep 28 10:15:53 2012
@@ -16,6 +16,13 @@
  */
 package org.apache.karaf.features;
 
+import static org.easymock.EasyMock.eq;
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.isA;
+import static org.easymock.EasyMock.replay;
+import static org.easymock.EasyMock.reset;
+import static org.easymock.EasyMock.verify;
+
 import java.io.File;
 import java.io.FileWriter;
 import java.io.IOException;
@@ -23,16 +30,12 @@ import java.io.InputStream;
 import java.io.PrintWriter;
 import java.net.MalformedURLException;
 import java.net.URI;
-import java.net.URL;
 import java.util.Arrays;
 import java.util.Collections;
-import java.util.Dictionary;
 import java.util.EnumSet;
 import java.util.Hashtable;
 import java.util.List;
-import java.util.Map;
 import java.util.concurrent.CopyOnWriteArraySet;
-import java.util.jar.JarInputStream;
 
 import junit.framework.TestCase;
 
@@ -42,14 +45,10 @@ import org.easymock.EasyMock;
 import org.junit.Assert;
 import org.osgi.framework.Bundle;
 import org.osgi.framework.BundleContext;
-import org.osgi.framework.Constants;
-import org.osgi.framework.FrameworkListener;
 import org.osgi.framework.wiring.FrameworkWiring;
 import org.osgi.service.blueprint.container.BlueprintContainer;
 import org.slf4j.LoggerFactory;
 
-import static org.easymock.EasyMock.*;
-
 public class FeaturesServiceTest extends TestCase {
 
     File dataFile;
@@ -253,18 +252,14 @@ public class FeaturesServiceTest extends
 
         // loads the state
         BundleManager bundleManager = EasyMock.createMock(BundleManager.class);
-
         expect(bundleManager.getDataFile(EasyMock.<String>anyObject())).andReturn(dataFile).anyTimes();
 
         replay(bundleManager);
-
         FeaturesServiceImpl svc = new FeaturesServiceImpl(bundleManager);
+        EasyMock.verify(bundleManager);
 
-        // Adds Repository
         svc.addRepository(uri);                                                     
-        
-        // Removes Repository
-        svc.removeRepository(uri);        
+        svc.removeRepository(uri);
     }
 
     // Tests install of a Repository that includes a feature
@@ -834,85 +829,6 @@ public class FeaturesServiceTest extends
 //        verify(preferencesService, prefs, repositoriesNode, featuresNode, bundleContext, installedBundle1, installedBundle2);
     }
 
-    public void testInstallFeatureWithHostToRefresh() throws Exception {
-        String bundle1 = getJarUrl(BlueprintContainer.class);
-        String bundle2 = getJarUrl(LoggerFactory.class);
-
-        File tmp = File.createTempFile("karaf", ".feature");
-        PrintWriter pw = new PrintWriter(new FileWriter(tmp));
-        pw.println("<features name=\"test\" xmlns=\"http://karaf.apache.org/xmlns/features/v1.0.0\">");
-        pw.println("  <feature name='f1'>");
-        pw.println("    <bundle>" + bundle1 + "</bundle>");
-        pw.println("    <bundle>" + bundle2 + "</bundle>");
-        pw.println("  </feature>");
-        pw.println("</features>");
-        pw.close();
-
-        URI uri = tmp.toURI();
-
-        JarInputStream j = new JarInputStream(new URL(bundle1).openStream());
-        Dictionary<String,String> headers = new Hashtable();
-        for (Map.Entry e : j.getManifest().getMainAttributes().entrySet()) {
-            headers.put(e.getKey().toString(), e.getValue().toString());
-        }
-
-        // loads the state
-        BundleContext bundleContext = EasyMock.createMock(BundleContext.class);
-        Bundle framework = EasyMock.createMock(Bundle.class);
-        FrameworkWiring wiring = EasyMock.createMock(FrameworkWiring.class);
-        Bundle installedBundle1 = EasyMock.createMock(Bundle.class);
-        Bundle installedBundle2 = EasyMock.createMock(Bundle.class);
-
-        // required since the sorted set uses it
-        expect(installedBundle1.compareTo(EasyMock.<Bundle>anyObject())).andReturn(0).anyTimes();
-        expect(installedBundle2.compareTo(EasyMock.<Bundle>anyObject())).andReturn(0).anyTimes();
-
-        // Installs feature f1
-        expect(bundleContext.createFilter(EasyMock.<String>anyObject())).andReturn(null).anyTimes();
-        expect(installedBundle1.getBundleId()).andReturn(12345L);
-        expect(installedBundle1.getBundleId()).andReturn(12345L);
-        expect(installedBundle1.getBundleId()).andReturn(12345L);
-        expect(installedBundle1.getSymbolicName()).andReturn(headers.get(Constants.BUNDLE_SYMBOLICNAME)).anyTimes();
-        expect(installedBundle1.getHeaders()).andReturn(headers).anyTimes();
-        expect(bundleContext.getBundles()).andReturn(new Bundle[] { installedBundle1 });
-
-        expect(bundleContext.installBundle(eq(bundle2), isA(InputStream.class))).andReturn(installedBundle2);
-        expect(bundleContext.getBundles()).andReturn(new Bundle[] { installedBundle1, installedBundle2 });
-        expect(installedBundle2.getBundleId()).andReturn(54321L);
-        expect(installedBundle2.getBundleId()).andReturn(54321L);
-        expect(installedBundle2.getBundleId()).andReturn(54321L);
-        expect(installedBundle2.getSymbolicName()).andReturn("fragment").anyTimes();
-        Dictionary d = new Hashtable();
-        d.put(Constants.FRAGMENT_HOST, headers.get(Constants.BUNDLE_SYMBOLICNAME));
-        expect(installedBundle2.getHeaders()).andReturn(d).anyTimes();
-
-        expect(installedBundle1.getState()).andReturn(Bundle.ACTIVE);
-        expect(installedBundle1.getState()).andReturn(Bundle.ACTIVE);
-        expect(installedBundle2.getState()).andReturn(Bundle.INSTALLED);
-        expect(installedBundle2.getState()).andReturn(Bundle.INSTALLED);
-
-        //
-        // This is the real test to make sure the host is actually refreshed
-        //
-        expect(bundleContext.getBundle()).andReturn(framework).anyTimes();
-        expect(framework.adapt(FrameworkWiring.class)).andReturn(wiring).anyTimes();
-        wiring.refreshBundles(eq(Collections.singleton(installedBundle1)), (FrameworkListener) anyObject());
-
-        expect(bundleContext.getDataFile(EasyMock.<String>anyObject())).andReturn(dataFile).anyTimes();
-
-        replay(wiring, framework, bundleContext, installedBundle1, installedBundle2);
-
-        FeaturesServiceImpl svc = new FeaturesServiceImpl(new BundleManager(bundleContext));
-        svc.addRepository(uri);
-
-        List<Feature> features = Arrays.asList(svc.listFeatures());
-        Collections.reverse(features);
-        svc.installFeatures(new CopyOnWriteArraySet<Feature>(features),
-                            EnumSet.noneOf(FeaturesService.Option.class));
-
-//        verify(preferencesService, prefs, repositoriesNode, featuresNode, bundleContext, installedBundle1, installedBundle2);
-    }
-
     /**
      * This test checks schema validation of submited uri.
      */

Added: karaf/trunk/features/core/src/test/java/org/apache/karaf/features/internal/BundleManagerTest.java
URL: http://svn.apache.org/viewvc/karaf/trunk/features/core/src/test/java/org/apache/karaf/features/internal/BundleManagerTest.java?rev=1391384&view=auto
==============================================================================
--- karaf/trunk/features/core/src/test/java/org/apache/karaf/features/internal/BundleManagerTest.java (added)
+++ karaf/trunk/features/core/src/test/java/org/apache/karaf/features/internal/BundleManagerTest.java Fri Sep 28 10:15:53 2012
@@ -0,0 +1,69 @@
+/*
+ * 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.karaf.features.internal;
+
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.replay;
+
+import java.util.Dictionary;
+import java.util.Hashtable;
+import java.util.Set;
+
+import junit.framework.Assert;
+
+import org.easymock.EasyMock;
+import org.junit.Test;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+
+public class BundleManagerTest {
+
+    public Bundle createDummyBundle(long id, String symbolicName, Dictionary<String,String> headers) {
+        Bundle bundle = EasyMock.createNiceMock(Bundle.class);
+        expect(bundle.getBundleId()).andReturn(id).anyTimes();
+        expect(bundle.getSymbolicName()).andReturn(symbolicName);
+        expect(bundle.getHeaders()).andReturn(headers).anyTimes();
+        replay(bundle);
+        return bundle;
+    }
+    
+    @Test
+    public void testfindBundlestoRefreshWithHostToRefresh() throws Exception {
+        Bundle hostBundle = createDummyBundle(12345l, "Host", new Hashtable<String, String>());
+        
+        Hashtable<String, String> d = new Hashtable<String, String>();
+        d.put(Constants.FRAGMENT_HOST, "Host");
+        Bundle fragmentBundle = createDummyBundle(54321l, "fragment", d);
+
+        BundleContext bundleContext = EasyMock.createMock(BundleContext.class);
+        BundleManager bundleManager = new BundleManager(bundleContext);
+
+        // Host was already installed, fragment is new
+        InstallationState state = new InstallationState();
+        state.bundles.add(hostBundle);
+        state.bundles.add(fragmentBundle);
+        state.installed.add(fragmentBundle);
+        
+        replay(bundleContext);
+        Set<Bundle> bundles = bundleManager.findBundlesToRefresh(state);
+        EasyMock.verify(bundleContext);
+
+        Assert.assertEquals(1, bundles.size());
+        Assert.assertEquals(hostBundle, bundles.iterator().next());
+    } 
+}

Propchange: karaf/trunk/features/core/src/test/java/org/apache/karaf/features/internal/BundleManagerTest.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: karaf/trunk/features/core/src/test/java/org/apache/karaf/features/internal/FeaturesServiceImplTest.java
URL: http://svn.apache.org/viewvc/karaf/trunk/features/core/src/test/java/org/apache/karaf/features/internal/FeaturesServiceImplTest.java?rev=1391384&r1=1391383&r2=1391384&view=diff
==============================================================================
--- karaf/trunk/features/core/src/test/java/org/apache/karaf/features/internal/FeaturesServiceImplTest.java (original)
+++ karaf/trunk/features/core/src/test/java/org/apache/karaf/features/internal/FeaturesServiceImplTest.java Fri Sep 28 10:15:53 2012
@@ -26,6 +26,7 @@ import java.net.URLClassLoader;
 import java.util.EnumSet;
 import java.util.HashMap;
 import java.util.HashSet;
+import java.util.Hashtable;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
@@ -35,10 +36,9 @@ import junit.framework.TestCase;
 
 import org.apache.felix.utils.manifest.Clause;
 import org.apache.karaf.features.Feature;
-import org.apache.karaf.features.FeaturesService;
+import org.apache.karaf.features.internal.BundleManager.BundleInstallerResult;
 import org.easymock.EasyMock;
 import org.osgi.framework.Bundle;
-import org.osgi.framework.BundleException;
 
 /**
  * Test cases for {@link FeaturesServiceImpl}
@@ -172,22 +172,29 @@ public class FeaturesServiceImplTest ext
         }
         
     }
+    
+    public Bundle createDummyBundle(long id, String symbolicName) {
+        Bundle bundle = EasyMock.createNiceMock(Bundle.class);
+        expect(bundle.getBundleId()).andReturn(id).anyTimes();
+        expect(bundle.getSymbolicName()).andReturn(symbolicName);
+        expect(bundle.getHeaders()).andReturn(new Hashtable<String, String>());
+        replay(bundle);
+        return bundle;
+    }
 
     /**
      * This test ensures that every feature get installed only once, even if it appears multiple times in the list
      * of transitive feature dependencies (KARAF-1600)
      */
+    @SuppressWarnings("unchecked")
     public void testNoDuplicateFeaturesInstallation() throws Exception {
         final List<Feature> installed = new LinkedList<Feature>();
-
-        BundleManager bundleLoader = new BundleManager(null, null) {
-            @Override
-            long installBundleIfNeeded(InstallationState state, String bundleLocation, int startLevel, String regionName, boolean verbose) throws IOException, BundleException {
-                return 10l;
-            }
-        };
-
-        final FeaturesServiceImpl impl = new FeaturesServiceImpl(bundleLoader, null) {
+        BundleManager bundleManager = EasyMock.createMock(BundleManager.class);
+        expect(bundleManager.installBundleIfNeeded(EasyMock.anyObject(String.class), EasyMock.anyInt(), EasyMock.anyObject(String.class)))
+            .andReturn(new BundleInstallerResult(createDummyBundle(1l, ""), true)).anyTimes();
+        bundleManager.refreshBundles(EasyMock.anyObject(InstallationState.class), EasyMock.anyObject(EnumSet.class));
+        EasyMock.expectLastCall();
+        final FeaturesServiceImpl impl = new FeaturesServiceImpl(bundleManager, null) {
             // override methods which refers to bundle context to avoid mocking everything
             @Override
             protected boolean loadState() {
@@ -207,19 +214,15 @@ public class FeaturesServiceImplTest ext
             }
 
         };
+        replay(bundleManager);
         impl.addRepository(getClass().getResource("repo2.xml").toURI());
+        impl.installFeature("all");
 
-        try {
-            impl.installFeature("all");
-
-            // copying the features to a set to filter out the duplicates
-            Set<Feature> noduplicates = new HashSet<Feature>();
-            noduplicates.addAll(installed);
+        // copying the features to a set to filter out the duplicates
+        Set<Feature> noduplicates = new HashSet<Feature>();
+        noduplicates.addAll(installed);
 
-            assertEquals("Every feature should only have been installed once", installed.size(), noduplicates.size());
-        } catch (Exception e) {
-            fail(String.format("Service should not throw any exceptions: %s", e));
-        }
+        assertEquals("Every feature should only have been installed once", installed.size(), noduplicates.size());
     }
 
     public void testGetOptionalImportsOnly() {