Skip to main content
aboutsummaryrefslogtreecommitdiffstats
blob: 0338b87372cf4f41da9ba3533c60b3c52546c30e (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
/*******************************************************************************
 * 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 List<Throwable> exceptions = new ArrayList<>();

		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.add(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.get(0));

		// 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;
	}
}

Back to the top