/* * 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.felix.framework; import java.io.ByteArrayInputStream; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.jar.JarOutputStream; import java.util.jar.Manifest; import junit.framework.TestCase; import org.osgi.framework.Bundle; import org.osgi.framework.Constants; import org.osgi.framework.FrameworkListener; import org.osgi.service.packageadmin.ExportedPackage; public class UninstallBundleTest extends TestCase { private static final int DELAY = 1000; public void testUninstallBundleCleansUpRevision() throws Exception { Map<String, String> params = new HashMap<String, String>(); params.put(Constants.FRAMEWORK_SYSTEMPACKAGES, "org.osgi.framework; version=1.4.0," + "org.osgi.service.packageadmin; version=1.2.0," + "org.osgi.service.startlevel; version=1.1.0," + "org.osgi.util.tracker; version=1.3.3," + "org.osgi.service.url; version=1.0.0"); File cacheDir = File.createTempFile("felix-cache", ".dir"); cacheDir.delete(); cacheDir.mkdirs(); String cache = cacheDir.getPath(); params.put("felix.cache.profiledir", cache); params.put("felix.cache.dir", cache); params.put(Constants.FRAMEWORK_STORAGE, cache); String mfA = "Bundle-SymbolicName: A\n" + "Bundle-ManifestVersion: 2\n" + "Export-Package: org.foo.bar\n"; File bundleAFile = createBundle(mfA, cacheDir); String mfB = "Bundle-SymbolicName: B\n" + "Bundle-ManifestVersion: 2\n" + "Export-Package: org.foo.bbr\n"; File bundleBFile = createBundle(mfB, cacheDir); String mfC = "Bundle-SymbolicName: C\n" + "Bundle-ManifestVersion: 2\n" + "Import-Package: org.foo.bar, org.foo.bbr\n"; File bundleCFile = createBundle(mfC, cacheDir); final List<Bundle> shouldNotBeRefreshed = new ArrayList<Bundle>(); Felix felix = new Felix(params) { @Override void refreshPackages(Collection<Bundle> targets, FrameworkListener[] listeners) { if (targets != null) { for (Bundle b : targets) { if (shouldNotBeRefreshed.contains(b)) fail("Bundle " + b + " should not be refreshed"); } } super.refreshPackages(targets, listeners); } }; felix.init(); felix.start(); try { Bundle bundleA = felix.getBundleContext().installBundle(bundleAFile.toURI().toString()); bundleA.start(); Bundle bundleB = felix.getBundleContext().installBundle(bundleBFile.toURI().toString()); bundleB.start(); // This bundle is not going to be uninstalled, so it should not be refreshed shouldNotBeRefreshed.add(bundleB); Bundle bundleC = felix.getBundleContext().installBundle(bundleCFile.toURI().toString()); bundleC.start(); bundleA.uninstall(); boolean foundBar = false; for (ExportedPackage ep : felix.getExportedPackages((Bundle) null)) { if ("org.foo.bar".equals(ep.getName())) foundBar = true; } assertTrue("The system should still export org.foo.bar as C is importing it.", foundBar); bundleC.uninstall(); for (ExportedPackage ep : felix.getExportedPackages((Bundle) null)) { if ("org.foo.bar".equals(ep.getName())) fail("Should not export org.foo.bar any more!"); } boolean foundBbr = false; for (ExportedPackage ep : felix.getExportedPackages((Bundle) null)) { if ("org.foo.bbr".equals(ep.getName())) foundBbr = true; } assertTrue("The system should still export org.foo.bbr as it was not uninstalled.", foundBbr); } finally { felix.stop(); Thread.sleep(DELAY); deleteDir(cacheDir); } } private static File createBundle(String manifest, File tempDir) throws IOException { File f = File.createTempFile("felix-bundle", ".jar", tempDir); Manifest mf = new Manifest(new ByteArrayInputStream(manifest.getBytes("utf-8"))); mf.getMainAttributes().putValue("Manifest-Version", "1.0"); JarOutputStream os = new JarOutputStream(new FileOutputStream(f), mf); os.close(); return f; } private static void deleteDir(File root) throws IOException { if (root.isDirectory()) { for (File file : root.listFiles()) { deleteDir(file); } } assertTrue(root.delete()); } }