blob: c8ee4cdf32fb97fcb37985473388ae30d4ddd88a [file] [log] [blame]
/*******************************************************************************
* 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;
}
}