| /******************************************************************************* |
| * Copyright (c) 2000, 2019 IBM Corporation and others. |
| * |
| * This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License 2.0 |
| * which accompanies this distribution, and is available at |
| * https://www.eclipse.org/legal/epl-2.0/ |
| * |
| * SPDX-License-Identifier: EPL-2.0 |
| * |
| * Contributors: |
| * IBM Corporation - initial API and implementation |
| *******************************************************************************/ |
| package org.eclipse.core.tests.runtime; |
| |
| import static java.util.Collections.emptyMap; |
| |
| import java.io.*; |
| import java.nio.file.Files; |
| import java.util.*; |
| import java.util.jar.*; |
| import org.eclipse.core.runtime.*; |
| import org.eclipse.osgi.framework.log.FrameworkLog; |
| import org.osgi.framework.*; |
| |
| /** |
| * Test cases for the Platform API |
| */ |
| public class PlatformTest extends RuntimeTest { |
| private FrameworkLog logService; |
| private ServiceReference<FrameworkLog> logRef; |
| private java.io.File originalLocation; |
| |
| /** |
| * Need a zero argument constructor to satisfy the test harness. |
| * This constructor should not do any real work nor should it be |
| * called by user code. |
| */ |
| public PlatformTest() { |
| super(null); |
| } |
| |
| public PlatformTest(String name) { |
| super(name); |
| } |
| |
| @Override |
| protected void setUp() throws Exception { |
| super.setUp(); |
| //ensure platform locations are initialized |
| Platform.getLogFileLocation(); |
| |
| //setup reference to log service, and remember original log location |
| logRef = RuntimeTestsPlugin.getContext().getServiceReference(FrameworkLog.class); |
| logService = RuntimeTestsPlugin.getContext().getService(logRef); |
| originalLocation = logService.getFile(); |
| } |
| |
| @Override |
| protected void tearDown() throws Exception { |
| //undo any damage done by log location test |
| super.tearDown(); |
| logService.setFile(originalLocation, true); |
| RuntimeTestsPlugin.getContext().ungetService(logRef); |
| } |
| |
| public void testGetCommandLine() { |
| assertNotNull("1.0", Platform.getCommandLineArgs()); |
| } |
| |
| public void testGetLocation() { |
| assertNotNull("1.0", Platform.getLocation()); |
| } |
| |
| /** |
| * API test for {@link Platform#getResourceBundle(org.osgi.framework.Bundle)} |
| */ |
| public void testGetResourceBundle() { |
| //ensure it returns non-null for bundle with a resource bundle |
| ResourceBundle bundle = Platform.getResourceBundle(Platform.getBundle("org.eclipse.core.runtime")); |
| assertNotNull(bundle); |
| //ensure it throws exception for bundle with no resource bundle |
| boolean failed = false; |
| try { |
| bundle = Platform.getResourceBundle(Platform.getBundle("org.eclipse.core.tests.runtime")); |
| } catch (MissingResourceException e) { |
| //expected |
| failed = true; |
| } |
| assertTrue(failed); |
| } |
| |
| public void testGetLogLocation() throws IOException { |
| IPath initialLocation = Platform.getLogFileLocation(); |
| System.out.println(Platform.getLogFileLocation()); |
| Platform.getStateLocation(Platform.getBundle("org.eclipse.equinox.common"));//causes DataArea to be initialzed |
| System.out.println(Platform.getLogFileLocation()); |
| |
| assertNotNull("1.0", initialLocation); |
| |
| //ensure result is same as log service |
| IPath logPath = new Path(logService.getFile().getAbsolutePath()); |
| assertEquals("2.0", logPath, initialLocation); |
| |
| //changing log service location should change log location |
| File newLocation = File.createTempFile("testGetLogLocation", null); |
| logService.setFile(newLocation, true); |
| assertEquals("3.0", new Path(newLocation.getAbsolutePath()), Platform.getLogFileLocation()); |
| |
| //when log is non-local, should revert to default location |
| logService.setWriter(new StringWriter(), true); |
| assertEquals("4.0", initialLocation, Platform.getLogFileLocation()); |
| } |
| |
| public void testRunnable() { |
| final Vector<Throwable> exceptions = new Vector<>(); |
| |
| final List<IStatus> collected = new ArrayList<>(); |
| |
| // add a log listener to ensure that we report using the right plug-in id |
| ILogListener logListener = new ILogListener() { |
| @Override |
| public void logging(IStatus status, String plugin) { |
| collected.add(status); |
| } |
| }; |
| Platform.addLogListener(logListener); |
| |
| final Exception exception = new Exception("PlatformTest.testRunnable: this exception is thrown on purpose as part of the test."); |
| ISafeRunnable runnable = new ISafeRunnable() { |
| @Override |
| public void handleException(Throwable t) { |
| exceptions.addElement(t); |
| } |
| |
| @Override |
| public void run() throws Exception { |
| throw exception; |
| } |
| }; |
| |
| SafeRunner.run(runnable); |
| |
| Platform.removeLogListener(logListener); |
| |
| assertEquals("1.0", exceptions.size(), 1); |
| assertEquals("1.1", exception, exceptions.firstElement()); |
| |
| // ensures the status object produced has the right plug-in id (bug 83614) |
| assertEquals("2.0", collected.size(), 1); |
| assertEquals("2.1", RuntimeTest.PI_RUNTIME_TESTS, collected.get(0).getPlugin()); |
| } |
| |
| /** |
| * Test for method {@link Platform#isFragment(Bundle)}. |
| * <p> |
| * This test creates a simple bundle and a fragment for it, packages them to |
| * jars and installs them into the OSGi container. |
| * </p> |
| * <p> |
| * The test checks that {@link Platform#isFragment(Bundle)} returns |
| * <code>false</code> for the host bundle and <code>true</code> for the fragment |
| * bundle. |
| * </p> |
| */ |
| public void testIsFragment() throws Exception { |
| String bundleName = getName(); |
| File config = RuntimeTestsPlugin.getContext().getDataFile(bundleName); |
| Files.createDirectories(config.toPath()); |
| |
| Map<String, String> headers = new HashMap<>(); |
| headers.put(Constants.BUNDLE_SYMBOLICNAME, bundleName); |
| headers.put(Constants.BUNDLE_VERSION, "1.0.0"); |
| File testBundleJarFile = createBundle(config, bundleName, headers, emptyMap()); |
| Bundle hostBundle = getContext().installBundle(testBundleJarFile.getName(), |
| new FileInputStream(testBundleJarFile)); |
| assertNotNull(hostBundle); |
| |
| assertFalse(Platform.isFragment(hostBundle)); |
| |
| String fragmentName = bundleName + "_fragment"; |
| headers.put(Constants.BUNDLE_SYMBOLICNAME, fragmentName); |
| headers.put(Constants.BUNDLE_VERSION, "1.0.0"); |
| headers.put(Constants.FRAGMENT_HOST, bundleName); |
| testBundleJarFile = createBundle(config, fragmentName, headers, emptyMap()); |
| Bundle fragmentBundle = getContext().installBundle(testBundleJarFile.getName(), |
| new FileInputStream(testBundleJarFile)); |
| assertNotNull(fragmentBundle); |
| |
| assertTrue(Platform.isFragment(fragmentBundle)); |
| } |
| |
| /** |
| * Test for method {@link Platform#getBundle(String)}. |
| * <p> |
| * This test creates 2 bundles with the same symbolic name in 2 versions, |
| * packages them to jars and installs them into the OSGi container. |
| * </p> |
| * <p> |
| * After installing the bundles they are in {@link Bundle#INSTALLED} state, |
| * which are filtered out when querying the Platform for bundles. The test |
| * checks that the bundles are not returned by the method yet. |
| * </p> |
| * <p> |
| * Next, the test starts the bundles which makes them visible. It is checked |
| * that {@link Platform#getBundle(String)} returns the bundle with the highest |
| * version. |
| * </p> |
| * <p> |
| * The bundle with the highest version is uninstalled then, and afterwards the |
| * bundle with the lower version will be returned by the Platform. |
| * </p> |
| * <p> |
| * Last, the second bundle is also uninstalled, and the test checks that no |
| * bundle is returned by Platform. |
| * </p> |
| */ |
| public void testGetBundle() throws Exception { |
| Map<String, Bundle> bundles = createSimpleTestBundles("1.0.0", "2.0.0"); |
| Bundle bundle; |
| |
| bundle = Platform.getBundle(getName()); |
| assertNull(getName() + " bundle just installed, but not started => expect null result", bundle); |
| for (Bundle b : bundles.values()) { |
| b.start(); |
| } |
| |
| // now get it from Platform |
| // 2 versions installed, highest version should be returned |
| bundle = Platform.getBundle(getName()); |
| assertNotNull("bundle must be available", bundle); |
| assertEquals("2.0.0", bundle.getVersion().toString()); |
| |
| // uninstall it; now lower version will be returned |
| bundle.uninstall(); |
| bundle = Platform.getBundle(getName()); |
| assertNotNull("bundle must be available", bundle); |
| assertEquals("1.0.0", bundle.getVersion().toString()); |
| |
| // uninstall it; no bundle available |
| bundle.uninstall(); |
| bundle = Platform.getBundle(getName()); |
| assertNull(getName() + " bundle => expect null result", bundle); |
| } |
| |
| /** |
| * Test for method {@link Platform#getBundles(String, String)}. |
| * <p> |
| * This test creates 3 bundles with the same symbolic name in 3 versions, |
| * packages them to jars and installs them into the OSGi container. |
| * </p> |
| * <p> |
| * First, the test checks that the method returns no result, since the bundles |
| * are in {@link Bundle#INSTALLED} state, which are filtered out by the method. |
| * The bundles are started then to become visible. |
| * </p> |
| * <p> |
| * Next, it is tested that the method returns all bundle in descending version |
| * order when no version constraint is given. |
| * </p> |
| * <p> |
| * Then different version constraints are given and it is tested that the |
| * expected number of bundles in the expected order are returned by |
| * {@link Platform#getBundles(String, String)}. |
| * </p> |
| */ |
| public void testGetBundles() throws Exception { |
| Map<String, Bundle> bundles = createSimpleTestBundles("1.0.0", "3.0.0", "2.0.0"); |
| Bundle bundle; |
| |
| bundle = Platform.getBundle(getName()); |
| assertNull(getName() + " bundle just installed, but not started => expect null result", bundle); |
| for (Bundle b : bundles.values()) { |
| b.start(); |
| } |
| |
| Bundle[] result = Platform.getBundles(getName(), null); // no version constraint => get all 3 |
| assertNotNull(getName() + " bundle not available", bundles); |
| assertEquals(3, result.length); |
| assertEquals(3, result[0].getVersion().getMajor()); // 3.0.0 version first |
| assertEquals(1, result[2].getVersion().getMajor()); // 1.0.0 version last |
| |
| result = Platform.getBundles(getName(), "2.0.0"); |
| assertEquals(2, result.length); |
| assertEquals(3, result[0].getVersion().getMajor()); // 3.0.0 version first |
| assertEquals(2, result[1].getVersion().getMajor()); // 2.0.0 version last |
| |
| result = Platform.getBundles(getName(), "[1.0.0,2.0.0)"); |
| assertEquals(1, result.length); |
| assertEquals(1, result[0].getVersion().getMajor()); // 1.0.0 version |
| |
| result = Platform.getBundles(getName(), "[1.1.0,2.0.0)"); |
| assertNull("no match => null result", result); |
| } |
| |
| /** |
| * Helper method to create empty bundles with just name and version given. The |
| * bundles are packaged to jars and installed into the container. The jars are |
| * marked for deletion on exit. |
| */ |
| private Map<String, Bundle> createSimpleTestBundles(String... versions) throws BundleException, IOException { |
| Map<String, Bundle> bundles = new HashMap<>(); |
| String bundleName = getName(); |
| File config = RuntimeTestsPlugin.getContext().getDataFile(bundleName); |
| Files.createDirectories(config.toPath()); |
| |
| for (String v : versions) { |
| Map<String, String> headers = new HashMap<>(); |
| headers.put(Constants.BUNDLE_SYMBOLICNAME, bundleName); |
| headers.put(Constants.BUNDLE_VERSION, v); |
| File testBundleJarFile = createBundle(config, bundleName + "_" + v, headers, emptyMap()); |
| Bundle testBundle = getContext().installBundle(testBundleJarFile.getName(), |
| new FileInputStream(testBundleJarFile)); |
| assertNotNull(testBundle); |
| bundles.put(v, testBundle); |
| } |
| return bundles; |
| } |
| |
| // copied from |
| // org.eclipse.osgi.tests.bundles.SystemBundleTests.createBundle(File, String, |
| // Map<String, String>, Map<String, String>...) |
| @SafeVarargs |
| static File createBundle(File outputDir, String bundleName, Map<String, String> headers, |
| Map<String, String>... entries) throws IOException { |
| Manifest m = new Manifest(); |
| Attributes attributes = m.getMainAttributes(); |
| attributes.putValue("Manifest-Version", "1.0"); |
| for (Map.Entry<String, String> entry : headers.entrySet()) { |
| attributes.putValue(entry.getKey(), entry.getValue()); |
| } |
| File file = new File(outputDir, "bundle" + bundleName + ".jar"); //$NON-NLS-1$ //$NON-NLS-2$ |
| try (JarOutputStream jos = new JarOutputStream(new FileOutputStream(file), m)) { |
| if (entries != null) { |
| for (Map<String, String> entryMap : entries) { |
| for (Map.Entry<String, String> entry : entryMap.entrySet()) { |
| jos.putNextEntry(new JarEntry(entry.getKey())); |
| if (entry.getValue() != null) { |
| jos.write(entry.getValue().getBytes()); |
| } |
| jos.closeEntry(); |
| } |
| } |
| } |
| jos.flush(); |
| } |
| file.deleteOnExit(); |
| return file; |
| } |
| } |