/******************************************************************************* * Copyright (c) 2007, 2014 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * IBM Corporation - initial API and implementation *******************************************************************************/ package org.eclipse.osgi.tests.appadmin; import java.util.*; import junit.framework.Test; import junit.framework.TestSuite; import org.eclipse.core.tests.session.ConfigurationSessionTestSuite; import org.eclipse.core.tests.session.SetupManager.SetupException; import org.eclipse.osgi.tests.OSGiTest; import org.eclipse.osgi.tests.OSGiTestsActivator; import org.eclipse.osgi.tests.bundles.BundleInstaller; import org.osgi.framework.*; import org.osgi.service.application.*; import org.osgi.util.tracker.ServiceTracker; import org.osgi.util.tracker.ServiceTrackerCustomizer; public class ApplicationAdminTest extends OSGiTest { public static final String testRunnerApp = "org.eclipse.pde.junit.runtime.coretestapplicationnonmain"; //$NON-NLS-1$ public static final String testResults = "test.results"; //$NON-NLS-1$ public static final String SUCCESS = "success"; //$NON-NLS-1$ public static final String ADDED = "added"; //$NON-NLS-1$ public static final String MODIFIED = "modified"; //$NON-NLS-1$ public static final String REMOVED = "removed"; //$NON-NLS-1$ public static final String simpleResults = "test.simpleResults"; //$NON-NLS-1$ public static final String[] tests = new String[] {"testSimpleApp", "testInvalidArgs", "testAsyncValue01", "testAsyncValue02", "testAsyncValue03", "testAsyncValue04", "testAsyncValue05", "testAsyncValue06", "testExitValue01", "testExitValue02", "testExitValue03", "testExitValue04", "testExitValue05", "testExitValue06", "testExitValue07", "testExitValue08", "testExitValue09", "testExitValue10", "testGlobalSingleton", "testCardinality01", "testCardinality02", "testMainThreaded01", "testMainThreaded02", "testHandleEvents01", "testDescriptorEvents01", "testPersistentLock01", "testPersistentLock02", "testPersistentLock03", "testPersistentSchedule01", "testPersistentSchedule02", "testPersistentSchedule03", "testPersistentSchedule04", "testPersistentSchedule05", "testPersistentSchedule06", //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$//$NON-NLS-4$//$NON-NLS-5$//$NON-NLS-6$//$NON-NLS-7$//$NON-NLS-8$//$NON-NLS-9$//$NON-NLS-10$//$NON-NLS-11$//$NON-NLS-12$//$NON-NLS-13$//$NON-NLS-14$//$NON-NLS-15$//$NON-NLS-16$//$NON-NLS-17$//$NON-NLS-18$//$NON-NLS-19$//$NON-NLS-20$//$NON-NLS-21$//$NON-NLS-22$//$NON-NLS-23$//$NON-NLS-24$//$NON-NLS-25$//$NON-NLS-26$//$NON-NLS-27$//$NON-NLS-28$//$NON-NLS-29$ "testPersistentSchedule07", "testPersistentSchedule08", "testFailedApplication01", "testDestroyBeforeStart01", "testDestroyBeforeStart02"}; private static final String PI_OSGI_SERVICES = "org.eclipse.osgi.services"; //$NON-NLS-1$ private static final String PI_OSGI_UTIL = "org.eclipse.osgi.util"; public static Test suite() { TestSuite suite = new TestSuite(ApplicationAdminTest.class.getName()); ConfigurationSessionTestSuite appAdminSessionTest = new ConfigurationSessionTestSuite(PI_OSGI_TESTS, ApplicationAdminTest.class.getName()); String[] ids = ConfigurationSessionTestSuite.MINIMAL_BUNDLE_SET; for (int i = 0; i < ids.length; i++) appAdminSessionTest.addBundle(ids[i]); appAdminSessionTest.addBundle(PI_OSGI_UTIL); appAdminSessionTest.addBundle(PI_OSGI_SERVICES); appAdminSessionTest.addBundle(PI_OSGI_TESTS); appAdminSessionTest.setApplicationId(testRunnerApp); try { appAdminSessionTest.getSetup().setSystemProperty("eclipse.application.registerDescriptors", "true"); //$NON-NLS-1$//$NON-NLS-2$ } catch (SetupException e) { throw new RuntimeException(e); } // we add tests the hard way so we can control the order of the tests. for (int i = 0; i < tests.length; i++) appAdminSessionTest.addTest(new ApplicationAdminTest(tests[i])); suite.addTest(appAdminSessionTest); return suite; } public ApplicationAdminTest(String name) { super(name); } private ApplicationDescriptor getApplication(String appName) { try { BundleContext context = getContext(); assertNotNull("BundleContext is null!!", context); //$NON-NLS-1$ Class appDescClass = ApplicationDescriptor.class; assertNotNull("ApplicationDescriptor.class is null!!", appDescClass); //$NON-NLS-1$ ServiceReference[] refs = context.getServiceReferences(appDescClass.getName(), "(" + ApplicationDescriptor.APPLICATION_PID + "=" + appName + ")"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ if (refs == null || refs.length == 0) { refs = getContext().getServiceReferences(ApplicationDescriptor.class.getName(), null); String availableApps = ""; //$NON-NLS-1$ if (refs != null) { for (int i = 0; i < refs.length; i++) { availableApps += refs[i].getProperty(ApplicationDescriptor.APPLICATION_PID); if (i < refs.length - 1) availableApps += ","; //$NON-NLS-1$ } } fail("Could not find app pid: " + appName + " available apps are: " + availableApps); //$NON-NLS-1$ //$NON-NLS-2$ } ApplicationDescriptor result = (ApplicationDescriptor) getContext().getService(refs[0]); if (result != null) getContext().ungetService(refs[0]); else fail("Could not get application descriptor service: " + appName); //$NON-NLS-1$ return result; } catch (InvalidSyntaxException e) { fail("Could not create app filter", e); //$NON-NLS-1$ } return null; } private HashMap getArguments() { HashMap args = new HashMap(); args.put(testResults, new HashMap()); return args; } public void testSimpleApp() { ApplicationDescriptor app = getApplication(PI_OSGI_TESTS + ".simpleApp"); //$NON-NLS-1$ HashMap args = getArguments(); HashMap results = (HashMap) args.get(testResults); try { ApplicationHandle handle = app.launch(args); handle.destroy(); } catch (Throwable e) { fail("failed to launch simpleApp", e); //$NON-NLS-1$ } String result = (String) results.get(simpleResults); assertEquals("Check application result", SUCCESS, result); //$NON-NLS-1$ } private void doInvalidScheduleArgs(ApplicationDescriptor app, String id, Map invalidArgs, String topic, String eventFilter, boolean recurring, boolean invalidKeys, boolean invalidValues) { ScheduledApplication sched = null; try { sched = app.schedule(id, invalidArgs, topic, eventFilter, recurring); try { sched.remove(); } catch (Throwable t) { // nothing } if (invalidKeys || invalidValues) fail("Should have failed with invalid arguments"); //$NON-NLS-1$ } catch (InvalidSyntaxException e) { fail("Failed to schedule an application", e); //$NON-NLS-1$ } catch (IllegalArgumentException e) { if (!invalidKeys) fail("Failed to schedule an application", e); //$NON-NLS-1$ } catch (ApplicationException e) { if (!invalidValues) fail("Failed to schedule an application", e); //$NON-NLS-1$ if (e.getErrorCode() != ApplicationException.APPLICATION_INVALID_STARTUP_ARGUMENT) fail("Failed to schedule an application", e); //$NON-NLS-1$ } } public void testInvalidArgs() { ApplicationDescriptor app = getApplication(PI_OSGI_TESTS + ".simpleApp"); //$NON-NLS-1$ HashMap args = new HashMap(); args.put("test.arg1", Boolean.TRUE); //$NON-NLS-1$ args.put("test.arg2", new Integer(34)); //$NON-NLS-1$ args.put("test.arg3", new Long(34)); //$NON-NLS-1$ doInvalidScheduleArgs(app, "schedule.testargs", args, "org/osgi/application/timer", "(minute=*)", true, false, false); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ args.put("test.arg4", this); //$NON-NLS-1$ doInvalidScheduleArgs(app, "schedule.testargs", args, "org/osgi/application/timer", "(minute=*)", true, false, true); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ Collection list = new ArrayList(); args.put("test.arg4", list); //$NON-NLS-1$ doInvalidScheduleArgs(app, "schedule.testargs", args, "org/osgi/application/timer", "(minute=*)", true, false, false); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ list.add(this); args.put("test.arg4", list); //$NON-NLS-1$ doInvalidScheduleArgs(app, "schedule.testargs", args, "org/osgi/application/timer", "(minute=*)", true, false, true); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ list.clear(); list.add("test"); //$NON-NLS-1$ list.add(new Integer(0)); list.add(new Long(0)); list.add(new Float(0)); list.add(new Double(0)); list.add(new Byte((byte) 0)); list.add(new Short((short) 1)); list.add(new Character((char) 0)); list.add(Boolean.TRUE); doInvalidScheduleArgs(app, "schedule.testargs", args, "org/osgi/application/timer", "(minute=*)", true, false, false); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ args.put("test.arg5", new String[0]); //$NON-NLS-1$ args.put("test.arg6", new int[0]); //$NON-NLS-1$ args.put("test.arg7", new long[0]); //$NON-NLS-1$ args.put("test.arg8", new float[0]); //$NON-NLS-1$ args.put("test.arg9", new double[0]); //$NON-NLS-1$ args.put("test.arg10", new byte[0]); //$NON-NLS-1$ args.put("test.arg11", new short[0]); //$NON-NLS-1$ args.put("test.arg12", new char[0]); //$NON-NLS-1$ args.put("test.arg12", new boolean[0]); //$NON-NLS-1$ doInvalidScheduleArgs(app, "schedule.testargs", args, "org/osgi/application/timer", "(minute=*)", true, false, false); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ args.put("test.arg13", "test"); //$NON-NLS-1$ //$NON-NLS-2$ args.put("test.arg14", new Integer(0)); //$NON-NLS-1$ args.put("test.arg15", new Long(0)); //$NON-NLS-1$ args.put("test.arg16", new Float(0)); //$NON-NLS-1$ args.put("test.arg17", new Double(0)); //$NON-NLS-1$ args.put("test.arg18", new Byte((byte) 0)); //$NON-NLS-1$ args.put("test.arg19", new Short((short) 1)); //$NON-NLS-1$ args.put("test.arg20", new Character((char) 0)); //$NON-NLS-1$ args.put("test.arg21", Boolean.TRUE); //$NON-NLS-1$ doInvalidScheduleArgs(app, "schedule.testargs", args, "org/osgi/application/timer", "(minute=*)", true, false, false); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ Map testMap = new HashMap(); args.put("test.arg22", testMap); //$NON-NLS-1$ doInvalidScheduleArgs(app, "schedule.testargs", args, "org/osgi/application/timer", "(minute=*)", true, false, true); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ args.clear(); args.put(new Long(0), "test"); //$NON-NLS-1$ doInvalidScheduleArgs(app, "schedule.testargs", args, "org/osgi/application/timer", "(minute=*)", true, true, false); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ } public void testExitValue01() { // simple getExitValue test ApplicationDescriptor app = getApplication(PI_OSGI_TESTS + ".exitValueApp"); //$NON-NLS-1$ ApplicationHandle handle = null; try { handle = app.launch(null); } catch (ApplicationException e) { fail("failed to launch simpleApp", e); //$NON-NLS-1$ } assertNotNull("app handle is null", handle); //$NON-NLS-1$ String value = null; try { value = (String) handle.getExitValue(10000); } catch (Exception e) { fail("unexpected exception waiting for exit value", e); //$NON-NLS-1$ } assertNotNull("value is null", value); //$NON-NLS-1$ assertEquals("exit value is incorrect", ExitValueApp.exitValue, value); //$NON-NLS-1$ } public void testExitValue02() { // getExitValue test when called from a service listener during service unregistration ApplicationDescriptor app = getApplication(PI_OSGI_TESTS + ".exitValueApp"); //$NON-NLS-1$ final Object[] result = new Object[1]; ServiceTrackerCustomizer trackerCustomizer = new ServiceTrackerCustomizer() { public Object addingService(ServiceReference reference) { return getContext().getService(reference); } public void modifiedService(ServiceReference reference, Object service) { // nothing } public void removedService(ServiceReference reference, Object service) { try { result[0] = ((ApplicationHandle) service).getExitValue(10000); } catch (Exception e) { result[0] = e; } } }; ServiceTracker tracker = null; try { tracker = new ServiceTracker(getContext(), FrameworkUtil.createFilter("(&(objectClass=" + ApplicationHandle.class.getName() + ")(" + ApplicationHandle.APPLICATION_DESCRIPTOR + "=" + app.getApplicationId() + "))"), trackerCustomizer); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ } catch (InvalidSyntaxException e) { fail("unexpected syntax exception for tracker", e); //$NON-NLS-1$ } tracker.open(); ApplicationHandle handle = null; try { handle = app.launch(null); } catch (ApplicationException e) { fail("failed to launch simpleApp", e); //$NON-NLS-1$ } assertNotNull("app handle is null", handle); //$NON-NLS-1$ String value = null; try { value = (String) handle.getExitValue(10000); } catch (Exception e) { fail("unexpected exception waiting for exit value", e); //$NON-NLS-1$ } assertNotNull("value is null", value); //$NON-NLS-1$ assertEquals("exit value is incorrect", ExitValueApp.exitValue, value); //$NON-NLS-1$ assertEquals("value from service unregister is different", value, result[0]); //$NON-NLS-1$ } public void testExitValue03() { // getExitValue test when called from a service listener during service property modified (STOPPING) ApplicationDescriptor app = getApplication(PI_OSGI_TESTS + ".exitValueApp"); //$NON-NLS-1$ final Object[] result = new Object[1]; ServiceTrackerCustomizer trackerCustomizer = new ServiceTrackerCustomizer() { public Object addingService(ServiceReference reference) { return getContext().getService(reference); } public void modifiedService(ServiceReference reference, Object service) { if (!"org.eclipse.equinox.app.stopped".equals(reference.getProperty(ApplicationHandle.APPLICATION_STATE))) //$NON-NLS-1$ return; try { result[0] = ((ApplicationHandle) service).getExitValue(10000); } catch (Exception e) { result[0] = e; } } public void removedService(ServiceReference reference, Object service) { // nothing } }; ServiceTracker tracker = null; try { tracker = new ServiceTracker(getContext(), FrameworkUtil.createFilter("(&(objectClass=" + ApplicationHandle.class.getName() + ")(" + ApplicationHandle.APPLICATION_DESCRIPTOR + "=" + app.getApplicationId() + "))"), trackerCustomizer); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ } catch (InvalidSyntaxException e) { fail("unexpected syntax exception for tracker", e); //$NON-NLS-1$ } tracker.open(); ApplicationHandle handle = null; try { handle = app.launch(null); } catch (ApplicationException e) { fail("failed to launch simpleApp", e); //$NON-NLS-1$ } assertNotNull("app handle is null", handle); //$NON-NLS-1$ String value = null; try { value = (String) handle.getExitValue(10000); } catch (Exception e) { fail("unexpected exception waiting for exit value", e); //$NON-NLS-1$ } assertNotNull("value is null", value); //$NON-NLS-1$ assertEquals("exit value is incorrect", ExitValueApp.exitValue, value); //$NON-NLS-1$ assertEquals("value from service unregister is different", value, result[0]); //$NON-NLS-1$ } public void testExitValue04() { // getExitValue test with destroy called while waiting for an exit value ApplicationDescriptor app = getApplication(PI_OSGI_TESTS + ".exitValueApp"); //$NON-NLS-1$ ApplicationHandle handle = null; try { handle = app.launch(null); } catch (ApplicationException e) { fail("failed to launch simpleApp", e); //$NON-NLS-1$ } assertNotNull("app handle is null", handle); //$NON-NLS-1$ final ApplicationHandle destroyHandle = handle; new Thread(new Runnable() { public void run() { try { Thread.sleep(1000); destroyHandle.destroy(); } catch (InterruptedException e) { // nothing } } }).start(); String value = null; try { value = (String) handle.getExitValue(10000); } catch (Exception e) { fail("unexpected exception waiting for exit value", e); //$NON-NLS-1$ } assertNotNull("value is null", value); //$NON-NLS-1$ assertEquals("exit value is incorrect", ExitValueApp.exitValue, value); //$NON-NLS-1$ } public void testExitValue05() { // getExitValue test with destroy called before getting an exit value ApplicationDescriptor app = getApplication(PI_OSGI_TESTS + ".exitValueApp"); //$NON-NLS-1$ ApplicationHandle handle = null; try { handle = app.launch(null); } catch (ApplicationException e) { fail("failed to launch simpleApp", e); //$NON-NLS-1$ } assertNotNull("app handle is null", handle); //$NON-NLS-1$ handle.destroy(); String value = null; try { value = (String) handle.getExitValue(10000); } catch (Exception e) { fail("unexpected exception waiting for exit value", e); //$NON-NLS-1$ } assertNotNull("value is null", value); //$NON-NLS-1$ assertEquals("exit value is incorrect", ExitValueApp.exitValue, value); //$NON-NLS-1$ } public void testExitValue06() { // getExitValue test; expecting an ApplicationException because the exit value is not available ApplicationDescriptor app = getApplication(PI_OSGI_TESTS + ".exitValueApp"); //$NON-NLS-1$ ApplicationHandle handle = null; try { handle = app.launch(null); } catch (ApplicationException e) { fail("failed to launch simpleApp", e); //$NON-NLS-1$ } assertNotNull("app handle is null", handle); //$NON-NLS-1$ try { handle.getExitValue(100); fail("Expected an ApplicationException for exit value not available"); //$NON-NLS-1$ } catch (ApplicationException e) { assertEquals("Unexpected error type", ApplicationException.APPLICATION_EXITVALUE_NOT_AVAILABLE, e.getErrorCode()); //$NON-NLS-1$ } catch (InterruptedException e) { fail("Unexpected interrupted exception waiting for exit value", e); //$NON-NLS-1$ } } public void testExitValue07() { //getExitValue test; called with timeout 0 ApplicationDescriptor app = getApplication(PI_OSGI_TESTS + ".exitValueApp"); //$NON-NLS-1$ ApplicationHandle handle = null; try { handle = app.launch(null); } catch (ApplicationException e) { fail("failed to launcher simpleApp", e); //$NON-NLS-1$ } assertNotNull("app handle is null", handle); //$NON-NLS-1$ String value = null; try { value = (String) handle.getExitValue(0); } catch (Exception e) { fail("unexpected exception waiting for exit value", e); //$NON-NLS-1$ } assertNotNull("value is null", value); //$NON-NLS-1$ assertEquals("exit value is incorrect", ExitValueApp.exitValue, value); //$NON-NLS-1$ } public void testExitValue08() { //getExitValue test; called with timeout -1 ApplicationDescriptor app = getApplication(PI_OSGI_TESTS + ".exitValueApp"); //$NON-NLS-1$ ApplicationHandle handle = null; try { handle = app.launch(null); } catch (ApplicationException e) { fail("failed to launcher simpleApp", e); //$NON-NLS-1$ } assertNotNull("app handle is null", handle); //$NON-NLS-1$ try { handle.getExitValue(-1); fail("Expected an ApplicationException for exit value not available"); //$NON-NLS-1$ } catch (ApplicationException e) { assertEquals("Unexpected error type", ApplicationException.APPLICATION_EXITVALUE_NOT_AVAILABLE, e.getErrorCode()); //$NON-NLS-1$ } catch (InterruptedException e) { fail("Unexpected interrupted exception waiting for exit value", e); //$NON-NLS-1$ } } public void testExitValue09() { //getExitValue test; application returns null ApplicationDescriptor app = getApplication(PI_OSGI_TESTS + ".exitValueApp"); //$NON-NLS-1$ ApplicationHandle handle = null; HashMap args = getArguments(); args.put(ExitValueApp.returnNullResult, Boolean.TRUE); try { handle = app.launch(args); } catch (ApplicationException e) { fail("failed to launcher simpleApp", e); //$NON-NLS-1$ } assertNotNull("app handle is null", handle); //$NON-NLS-1$ try { assertNull("expected null return value", handle.getExitValue(0)); } catch (Exception e) { fail("unexpected exception waiting for exit value", e); //$NON-NLS-1$ } } public void testExitValue10() { //getExitValue test; called with timeout 0 after the result is available ApplicationDescriptor app = getApplication(PI_OSGI_TESTS + ".exitValueApp"); //$NON-NLS-1$ ApplicationHandle handle = null; try { handle = app.launch(null); } catch (ApplicationException e) { fail("failed to launch simpleApp", e); //$NON-NLS-1$ } assertNotNull("app handle is null", handle); //$NON-NLS-1$ String value = null; try { // waiting for app to exit handle.getExitValue(10000); // app exited now get the result with 0 timeout value = (String) handle.getExitValue(0); } catch (Exception e) { fail("unexpected exception waiting for exit value", e); //$NON-NLS-1$ } assertNotNull("value is null", value); //$NON-NLS-1$ assertEquals("exit value is incorrect", ExitValueApp.exitValue, value); //$NON-NLS-1$ try { // app exited now get the result with -1 timeout; we know the value is ready from above value = (String) handle.getExitValue(-1); } catch (Exception e) { fail("unexpected exception waiting for exit value", e); //$NON-NLS-1$ } assertNotNull("value is null", value); //$NON-NLS-1$ assertEquals("exit value is incorrect", ExitValueApp.exitValue, value); //$NON-NLS-1$ } public void testAsyncValue01() { //setValue test; called with timeout 0 after the result is available ApplicationDescriptor app = getApplication(PI_OSGI_TESTS + ".exitValueApp"); //$NON-NLS-1$ Map args = new HashMap(); args.put(ExitValueApp.returnAsyncResult, Boolean.TRUE); ApplicationHandle handle = null; try { handle = app.launch(args); } catch (ApplicationException e) { fail("failed to launch simpleApp", e); //$NON-NLS-1$ } assertNotNull("app handle is null", handle); //$NON-NLS-1$ String value = null; try { // waiting for app to exit handle.getExitValue(10000); // app exited now get the result with 0 timeout value = (String) handle.getExitValue(0); } catch (Exception e) { fail("unexpected exception waiting for exit value", e); //$NON-NLS-1$ } assertNotNull("value is null", value); //$NON-NLS-1$ assertEquals("exit value is incorrect", ExitValueApp.exitValue, value); //$NON-NLS-1$ try { // app exited now get the result with -1 timeout; we know the value is ready from above value = (String) handle.getExitValue(-1); } catch (Exception e) { fail("unexpected exception waiting for exit value", e); //$NON-NLS-1$ } assertNotNull("value is null", value); //$NON-NLS-1$ assertEquals("exit value is incorrect", ExitValueApp.exitValue, value); //$NON-NLS-1$ } public void testAsyncValue02() { //setValue test; called with timeout -1 ApplicationDescriptor app = getApplication(PI_OSGI_TESTS + ".exitValueApp"); //$NON-NLS-1$ ApplicationHandle handle = null; Map args = new HashMap(); args.put(ExitValueApp.returnAsyncResult, Boolean.TRUE); try { handle = app.launch(args); } catch (ApplicationException e) { fail("failed to launcher simpleApp", e); //$NON-NLS-1$ } assertNotNull("app handle is null", handle); //$NON-NLS-1$ try { handle.getExitValue(-1); fail("Expected an ApplicationException for exit value not available"); //$NON-NLS-1$ } catch (ApplicationException e) { assertEquals("Unexpected error type", ApplicationException.APPLICATION_EXITVALUE_NOT_AVAILABLE, e.getErrorCode()); //$NON-NLS-1$ } catch (InterruptedException e) { fail("Unexpected interrupted exception waiting for exit value", e); //$NON-NLS-1$ } } public void testAsyncValue03() { //setValue test; application returns null ApplicationDescriptor app = getApplication(PI_OSGI_TESTS + ".exitValueApp"); //$NON-NLS-1$ ApplicationHandle handle = null; HashMap args = getArguments(); args.put(ExitValueApp.returnNullResult, Boolean.TRUE); args.put(ExitValueApp.returnAsyncResult, Boolean.TRUE); try { handle = app.launch(args); } catch (ApplicationException e) { fail("failed to launcher simpleApp", e); //$NON-NLS-1$ } assertNotNull("app handle is null", handle); //$NON-NLS-1$ try { assertNull("expected null return value", handle.getExitValue(0)); } catch (Exception e) { fail("unexpected exception waiting for exit value", e); //$NON-NLS-1$ } } public void testAsyncValue04() { // setValue test with destroy called while waiting for an exit value ApplicationDescriptor app = getApplication(PI_OSGI_TESTS + ".exitValueApp"); //$NON-NLS-1$ HashMap args = getArguments(); args.put(ExitValueApp.returnAsyncResult, Boolean.TRUE); ApplicationHandle handle = null; try { handle = app.launch(null); } catch (ApplicationException e) { fail("failed to launch simpleApp", e); //$NON-NLS-1$ } assertNotNull("app handle is null", handle); //$NON-NLS-1$ final ApplicationHandle destroyHandle = handle; new Thread(new Runnable() { public void run() { try { Thread.sleep(1000); destroyHandle.destroy(); } catch (InterruptedException e) { // nothing } } }).start(); String value = null; try { value = (String) handle.getExitValue(10000); } catch (Exception e) { fail("unexpected exception waiting for exit value", e); //$NON-NLS-1$ } assertNotNull("value is null", value); //$NON-NLS-1$ assertEquals("exit value is incorrect", ExitValueApp.exitValue, value); //$NON-NLS-1$ } public void testAsyncValue05() { // test calling setValue to early ApplicationDescriptor app = getApplication(PI_OSGI_TESTS + ".exitValueApp"); //$NON-NLS-1$ Map args = new HashMap(); args.put(ExitValueApp.setAsyncEarly, Boolean.TRUE); ApplicationHandle handle = null; try { handle = app.launch(args); } catch (ApplicationException e) { fail("failed to launch simpleApp", e); //$NON-NLS-1$ } assertNotNull("app handle is null", handle); //$NON-NLS-1$ String value = null; try { // waiting for app to exit value = (String) handle.getExitValue(10000); } catch (Exception e) { fail("unexpected exception waiting for exit value", e); //$NON-NLS-1$ } assertNotNull("value is null", value); //$NON-NLS-1$ assertEquals("exit value is incorrect", ExitValueApp.exitValue, value); //$NON-NLS-1$ } public void testAsyncValue06() { // test calling setValue with wrong application instance ApplicationDescriptor app = getApplication(PI_OSGI_TESTS + ".exitValueApp"); //$NON-NLS-1$ Map args = new HashMap(); args.put(ExitValueApp.returnAsyncResult, Boolean.TRUE); args.put(ExitValueApp.setAsyncWrongApp, Boolean.TRUE); ApplicationHandle handle = null; try { handle = app.launch(args); } catch (ApplicationException e) { fail("failed to launch simpleApp", e); //$NON-NLS-1$ } assertNotNull("app handle is null", handle); //$NON-NLS-1$ String value = null; try { // waiting for app to exit value = (String) handle.getExitValue(10000); } catch (Exception e) { fail("unexpected exception waiting for exit value", e); //$NON-NLS-1$ } assertNotNull("value is null", value); //$NON-NLS-1$ assertEquals("exit value is incorrect", ExitValueApp.exitValue, value); //$NON-NLS-1$ } public void testGlobalSingleton() { ApplicationDescriptor app = getApplication(PI_OSGI_TESTS + ".globalSingletonApp"); //$NON-NLS-1$ HashMap args = getArguments(); try { ApplicationHandle handle = app.launch(args); handle.destroy(); fail("should not be able to launch a global singleton app: " + app.getApplicationId()); //$NON-NLS-1$ } catch (ApplicationException e) { assertEquals("check error code", ApplicationException.APPLICATION_NOT_LAUNCHABLE, e.getErrorCode()); //$NON-NLS-1$ } } private void doTestCardinality01(String appID, int cardinality, boolean hasMax) { ApplicationDescriptor app = getApplication(appID); ArrayList instances = new ArrayList(); int i = 0; try { for (; i <= cardinality; i++) { instances.add(app.launch(null)); if (i == cardinality && hasMax) { fail("Expected an ApplicationException."); } } } catch (ApplicationException e) { if (!hasMax || i != cardinality) fail("Unexpected ApplicationException", e); //$NON-NLS-1$ assertEquals("check error code", ApplicationException.APPLICATION_NOT_LAUNCHABLE, e.getErrorCode()); //$NON-NLS-1$ } finally { for (Iterator handles = instances.iterator(); handles.hasNext();) { ((ApplicationHandle) handles.next()).destroy(); } } assertEquals("Did not launch the correct # of concurrent instances", instances.size(), cardinality + (hasMax ? 0 : 1)); //$NON-NLS-1$ } public void testCardinality01() { doTestCardinality01(PI_OSGI_TESTS + ".testCardinality01", 5, true); //$NON-NLS-1$ } public void testCardinality02() { doTestCardinality01(PI_OSGI_TESTS + ".testCardinality02", 20, false); //$NON-NLS-1$ } private void doTestMainThreaded(String appID) { ApplicationDescriptor app = getApplication(appID); ArrayList instances = new ArrayList(); try { instances.add(app.launch(null)); instances.add(app.launch(null)); } catch (ApplicationException e) { if (instances.size() == 0) fail("Unable to launch a main threaded application", e); //$NON-NLS-1$ assertEquals("check error code", ApplicationException.APPLICATION_NOT_LAUNCHABLE, e.getErrorCode()); //$NON-NLS-1$ } finally { for (Iterator handles = instances.iterator(); handles.hasNext();) { ((ApplicationHandle) handles.next()).destroy(); } } assertEquals("Did not launch the correct # of main app instances", instances.size(), 1); //$NON-NLS-1$ } public void testMainThreaded01() { doTestMainThreaded(PI_OSGI_TESTS + ".testMainThreaded01"); //$NON-NLS-1$ } public void testMainThreaded02() { doTestMainThreaded(PI_OSGI_TESTS + ".testMainThreaded02"); //$NON-NLS-1$ } public void testHandleEvents01() throws InvalidSyntaxException { ApplicationDescriptor app = getApplication(PI_OSGI_TESTS + ".simpleApp"); //$NON-NLS-1$ ApplicationHandleTracker handleTracker = new ApplicationHandleTracker(getContext()); ServiceTracker tracker = new ServiceTracker(getContext(), FrameworkUtil.createFilter("(&(objectClass=" + ApplicationHandle.class.getName() + ")(" + ApplicationHandle.APPLICATION_DESCRIPTOR + "=" + app.getApplicationId() + "))"), handleTracker); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ tracker.open(); try { ApplicationHandle handle = app.launch(null); handleTracker.waitForEvent(handle.getInstanceId(), ApplicationHandle.RUNNING); handle.destroy(); handleTracker.waitForEvent(handle.getInstanceId(), REMOVED); String[][] events = handleTracker.getEvents(); String[][] expected = new String[][] {new String[] {handle.getInstanceId(), "org.eclipse.equinox.app.starting"}, new String[] {handle.getInstanceId(), ApplicationHandle.RUNNING}, new String[] {handle.getInstanceId(), ApplicationHandle.STOPPING}, new String[] {handle.getInstanceId(), "org.eclipse.equinox.app.stopped"}, new String[] {handle.getInstanceId(), "removed"}}; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ assertEquals("Check expected # events", expected.length, events.length); //$NON-NLS-1$ for (int i = 0; i < events.length; i++) { assertEquals("Check expected event id for #" + i, expected[i][0], events[i][0]); //$NON-NLS-1$ assertEquals("Check expected event state for #" + i, expected[i][1], events[i][1]); //$NON-NLS-1$ } } catch (ApplicationException e) { fail("failed to launch application", e); //$NON-NLS-1$ } finally { tracker.close(); } } public void testDescriptorEvents01() throws InvalidSyntaxException, BundleException { BundleInstaller bundleInstaller = null; try { bundleInstaller = new BundleInstaller(OSGiTestsActivator.TEST_FILES_ROOT + "internal/plugins/appAdminTests", getContext()); //$NON-NLS-1$ } catch (InvalidSyntaxException e) { fail("Failed to create bundle installer", e); //$NON-NLS-1$ } String testAppPID = "appadmin.test01.simpleApp"; //$NON-NLS-1$ ApplicationDescriptorTracker descriptionTracker = new ApplicationDescriptorTracker(getContext()); ServiceTracker tracker = new ServiceTracker(getContext(), FrameworkUtil.createFilter("(&(objectClass=" + ApplicationDescriptor.class.getName() + ")(" + ApplicationDescriptor.APPLICATION_PID + "=" + testAppPID + "))"), descriptionTracker); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ tracker.open(); try { Bundle test01 = bundleInstaller.installBundle("appadmin.test01"); //$NON-NLS-1$ assertTrue("Check if test bundle is resolved: " + test01.getSymbolicName(), bundleInstaller.resolveBundles(new Bundle[] {test01})); //$NON-NLS-1$ descriptionTracker.waitForEvent(testAppPID, ADDED, Boolean.FALSE, Boolean.TRUE); ApplicationDescriptor app = getApplication(testAppPID); app.lock(); Boolean locked = (Boolean) app.getProperties("").get(ApplicationDescriptor.APPLICATION_LOCKED); //$NON-NLS-1$ assertTrue("Application should be locked", locked.booleanValue()); //$NON-NLS-1$ descriptionTracker.waitForEvent(testAppPID, MODIFIED, Boolean.TRUE, Boolean.TRUE); app.unlock(); descriptionTracker.waitForEvent(testAppPID, MODIFIED, Boolean.FALSE, Boolean.TRUE); ApplicationHandle handle = null; try { handle = app.launch(null); } catch (ApplicationException e) { fail("failed to launch app: " + app.getApplicationId(), e); //$NON-NLS-1$ } descriptionTracker.waitForEvent(testAppPID, MODIFIED, Boolean.FALSE, Boolean.FALSE); handle.destroy(); descriptionTracker.waitForEvent(testAppPID, MODIFIED, Boolean.FALSE, Boolean.TRUE); test01.uninstall(); descriptionTracker.waitForEvent(testAppPID, REMOVED, Boolean.FALSE, Boolean.TRUE); } finally { bundleInstaller.shutdown(); tracker.close(); } } public void testPersistentLock01() { ApplicationDescriptor app = getApplication(PI_OSGI_TESTS + ".simpleApp"); //$NON-NLS-1$ app.lock(); } public void testPersistentLock02() { ApplicationDescriptor app = getApplication(PI_OSGI_TESTS + ".simpleApp"); //$NON-NLS-1$ try { ApplicationHandle handle = app.launch(null); handle.destroy(); fail("The application should be locked: " + app.getApplicationId()); //$NON-NLS-1$ } catch (ApplicationException e) { assertEquals("check error code", ApplicationException.APPLICATION_LOCKED, e.getErrorCode()); //$NON-NLS-1$ } app.unlock(); try { ApplicationHandle handle = app.launch(null); handle.destroy(); } catch (Throwable e) { fail("failed to launch simpleApp", e); //$NON-NLS-1$ } } public void testPersistentLock03() { ApplicationDescriptor app = getApplication(PI_OSGI_TESTS + ".simpleApp"); //$NON-NLS-1$ try { ApplicationHandle handle = app.launch(null); handle.destroy(); } catch (Throwable e) { fail("failed to launch simpleApp", e); //$NON-NLS-1$ } } public void testPersistentSchedule01() { ApplicationDescriptor app = getApplication(PI_OSGI_TESTS + ".simpleApp"); //$NON-NLS-1$ try { HashMap args = new HashMap(); args.put("test.arg1", Boolean.TRUE); //$NON-NLS-1$ args.put("test.arg2", new Integer(34)); //$NON-NLS-1$ args.put("test.arg3", new Long(34)); //$NON-NLS-1$ app.schedule("schedule.1", args, "org/osgi/application/timer", "(minute=*)", true); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ } catch (InvalidSyntaxException e) { fail("Failed to schedule an application", e); //$NON-NLS-1$ } catch (ApplicationException e) { fail("Failed to schedule an application", e); //$NON-NLS-1$ } } public void testPersistentSchedule02() throws InvalidSyntaxException { ScheduledApplication scheduledApp = getScheduleApplication("schedule.1", true); //$NON-NLS-1$ ApplicationHandleTracker handleTracker = new ApplicationHandleTracker(getContext()); ServiceTracker tracker = new ServiceTracker(getContext(), FrameworkUtil.createFilter("(&(objectClass=" + ApplicationHandle.class.getName() + ")(" + ApplicationHandle.APPLICATION_DESCRIPTOR + "=" + scheduledApp.getApplicationDescriptor().getApplicationId() + "))"), handleTracker); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ tracker.open(); try { ApplicationHandle handle = (ApplicationHandle) tracker.waitForService(61000); assertNotNull("Should find an application handle", handle); //$NON-NLS-1$ handleTracker.waitForEvent(handle.getInstanceId(), ApplicationHandle.RUNNING); handle.destroy(); handleTracker.waitForEvent(handle.getInstanceId(), REMOVED); HashMap results = null; try { results = (HashMap) handle.getExitValue(1000); } catch (ApplicationException e) { fail("Unexpected application exception waiting for an exit value", e); //$NON-NLS-1$ } assertNotNull("Null results", results); //$NON-NLS-1$ HashMap args = new HashMap(); args.put("test.arg1", Boolean.TRUE); //$NON-NLS-1$ args.put("test.arg2", new Integer(34)); //$NON-NLS-1$ args.put("test.arg3", new Long(34)); //$NON-NLS-1$ for (Iterator iEntries = args.entrySet().iterator(); iEntries.hasNext();) { Map.Entry entry = (Map.Entry) iEntries.next(); assertEquals("key: " + entry.getKey(), entry.getValue(), results.get(entry.getKey())); //$NON-NLS-1$ } } catch (InterruptedException e) { fail("got interupted", e); //$NON-NLS-1$ } finally { tracker.close(); scheduledApp.remove(); } } public void testPersistentSchedule03() { ScheduledApplication scheduledApp = getScheduleApplication("schedule.1", false); //$NON-NLS-1$ if (scheduledApp != null) { scheduledApp.remove(); fail("Scheduled application should not be found: " + scheduledApp.getScheduleId()); //$NON-NLS-1$ } } public void testPersistentSchedule04() { ApplicationDescriptor app = getApplication(PI_OSGI_TESTS + ".simpleApp"); //$NON-NLS-1$ try { // lock the app so that it cannot be launched with a scheduled app.lock(); HashMap args = new HashMap(); args.put("test.arg1", Boolean.TRUE); //$NON-NLS-1$ args.put("test.arg2", new Integer(34)); //$NON-NLS-1$ args.put("test.arg3", new Long(34)); //$NON-NLS-1$ // make it non-recurring app.schedule("schedule.2", args, "org/osgi/application/timer", "(minute=*)", false); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ } catch (InvalidSyntaxException e) { fail("Failed to schedule an application", e); //$NON-NLS-1$ } catch (ApplicationException e) { fail("Failed to schedule an application", e); //$NON-NLS-1$ } } public void testPersistentSchedule05() throws InvalidSyntaxException { ScheduledApplication scheduledApp = getScheduleApplication("schedule.2", true); //$NON-NLS-1$ ApplicationHandleTracker handleTracker = new ApplicationHandleTracker(getContext()); ServiceTracker tracker = new ServiceTracker(getContext(), FrameworkUtil.createFilter("(&(objectClass=" + ApplicationHandle.class.getName() + ")(" + ApplicationHandle.APPLICATION_DESCRIPTOR + "=" + scheduledApp.getApplicationDescriptor().getApplicationId() + "))"), handleTracker); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ tracker.open(); ApplicationHandle badHandle = null; try { badHandle = (ApplicationHandle) tracker.waitForService(61000); assertNull("Should not find an application handle", badHandle); //$NON-NLS-1$ // unlock app then try again scheduledApp.getApplicationDescriptor().unlock(); ApplicationHandle handle = (ApplicationHandle) tracker.waitForService(61000); assertNotNull("Should find an application handle", handle); //$NON-NLS-1$ handleTracker.waitForEvent(handle.getInstanceId(), ApplicationHandle.RUNNING); handle.destroy(); handleTracker.waitForEvent(handle.getInstanceId(), REMOVED); HashMap results = null; try { results = (HashMap) handle.getExitValue(1000); } catch (ApplicationException e) { fail("Unexpected application exception waiting for an exit value", e); //$NON-NLS-1$ } assertNotNull("Null results", results); //$NON-NLS-1$ HashMap args = new HashMap(); args.put("test.arg1", Boolean.TRUE); //$NON-NLS-1$ args.put("test.arg2", new Integer(34)); //$NON-NLS-1$ args.put("test.arg3", new Long(34)); //$NON-NLS-1$ for (Iterator iEntries = args.entrySet().iterator(); iEntries.hasNext();) { Map.Entry entry = (Map.Entry) iEntries.next(); assertEquals("key: " + entry.getKey(), entry.getValue(), results.get(entry.getKey())); //$NON-NLS-1$ } // should not find the scheduled app anymore // sleeping here to allow for the scheduled app to disappear; could use service events instead Thread.sleep(1000); scheduledApp = getScheduleApplication("schedule.2", false); //$NON-NLS-1$ if (scheduledApp != null) { // TODO disabling the failure here. Just print the error message for now (bug 372848) System.out.println("Scheduled application should not be found: " + scheduledApp.getScheduleId()); //$NON-NLS-1$ // try sleeping some more to see if it helps Thread.sleep(5000); scheduledApp = getScheduleApplication("schedule.2", false); //$NON-NLS-1$ if (scheduledApp != null) { System.out.println(" -- Still found after waiting 5 seconds: " + scheduledApp.getScheduleId()); //$NON-NLS-1$ } } } catch (InterruptedException e) { fail("got interupted", e); //$NON-NLS-1$ } finally { if (badHandle != null) badHandle.destroy(); tracker.close(); if (scheduledApp != null) scheduledApp.remove(); } } public void testPersistentSchedule06() { ScheduledApplication scheduledApp = getScheduleApplication("schedule.2", false); //$NON-NLS-1$ if (scheduledApp != null) { scheduledApp.remove(); fail("Scheduled application should not be found: " + scheduledApp.getScheduleId()); //$NON-NLS-1$ } } public void testPersistentSchedule07() { ApplicationDescriptor app = getApplication(PI_OSGI_TESTS + ".simpleApp"); //$NON-NLS-1$ try { app.schedule("schedule.duplicate1", null, "org/osgi/application/timer", "(minute=*)", true); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ } catch (InvalidSyntaxException e) { fail("Failed to schedule an application", e); //$NON-NLS-1$ } catch (ApplicationException e) { fail("Failed to schedule an application", e); //$NON-NLS-1$ } try { app.schedule("schedule.duplicate1", null, "org/osgi/application/timer", "(minute=*)", true); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ fail("should not be able to create a duplicate scheduled application id"); //$NON-NLS-1$ } catch (InvalidSyntaxException e) { fail("Failed to schedule an application", e); //$NON-NLS-1$ } catch (ApplicationException e) { assertEquals("check error code", ApplicationException.APPLICATION_DUPLICATE_SCHEDULE_ID, e.getErrorCode()); //$NON-NLS-1$ } } public void testPersistentSchedule08() { ScheduledApplication scheduledApp = getScheduleApplication("schedule.duplicate1", true); //$NON-NLS-1$ try { scheduledApp.getApplicationDescriptor().schedule("schedule.duplicate1", null, "org/osgi/application/timer", "(minute=*)", true); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ fail("should not be able to create a duplicate scheduled application id"); //$NON-NLS-1$ } catch (InvalidSyntaxException e) { fail("Failed to schedule an application", e); //$NON-NLS-1$ } catch (ApplicationException e) { assertEquals("check error code", ApplicationException.APPLICATION_DUPLICATE_SCHEDULE_ID, e.getErrorCode()); //$NON-NLS-1$ } finally { scheduledApp.remove(); } } public void testFailedApplication01() throws InvalidSyntaxException { ApplicationDescriptor app = getApplication(PI_OSGI_TESTS + ".failedApp"); //$NON-NLS-1$ ApplicationHandleTracker handleTracker = new ApplicationHandleTracker(getContext()); ServiceTracker tracker = new ServiceTracker(getContext(), FrameworkUtil.createFilter("(&(objectClass=" + ApplicationHandle.class.getName() + ")(" + ApplicationHandle.APPLICATION_DESCRIPTOR + "=" + app.getApplicationId() + "))"), handleTracker); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ tracker.open(); try { ApplicationHandle handle = app.launch(null); handleTracker.waitForEvent(handle.getInstanceId(), REMOVED); String[][] events = handleTracker.getEvents(); String[][] expected = new String[][] {new String[] {handle.getInstanceId(), "org.eclipse.equinox.app.starting"}, new String[] {handle.getInstanceId(), ApplicationHandle.STOPPING}, new String[] {handle.getInstanceId(), "org.eclipse.equinox.app.stopped"}, new String[] {handle.getInstanceId(), "removed"}}; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ assertEquals("Check expected # events", expected.length, events.length); //$NON-NLS-1$ for (int i = 0; i < events.length; i++) { assertEquals("Check expected event id for #" + i, expected[i][0], events[i][0]); //$NON-NLS-1$ assertEquals("Check expected event state for #" + i, expected[i][1], events[i][1]); //$NON-NLS-1$ } } catch (ApplicationException e) { fail("failed to launch application", e); //$NON-NLS-1$ } finally { tracker.close(); } } public void testDestroyBeforeStart01() throws InvalidSyntaxException { ApplicationDescriptor app = getApplication(PI_OSGI_TESTS + ".simpleApp"); //$NON-NLS-1$ HashMap args = getArguments(); HashMap results = (HashMap) args.get(testResults); ServiceTrackerCustomizer trackerCustomizer = new ServiceTrackerCustomizer() { public Object addingService(ServiceReference reference) { ApplicationHandle handle = (ApplicationHandle) getContext().getService(reference); handle.destroy(); return handle; } public void modifiedService(ServiceReference reference, Object service) { // nothing } public void removedService(ServiceReference reference, Object service) { // nothing } }; ServiceTracker tracker = new ServiceTracker(getContext(), FrameworkUtil.createFilter("(&(objectClass=" + ApplicationHandle.class.getName() + ")(" + ApplicationHandle.APPLICATION_DESCRIPTOR + "=" + app.getApplicationId() + "))"), trackerCustomizer); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ tracker.open(); try { ApplicationHandle handle = app.launch(args); handle.destroy(); } catch (Throwable e) { fail("failed to launch simpleApp", e); //$NON-NLS-1$ } finally { tracker.close(); } String result = (String) results.get(simpleResults); assertNull("Check application result", result); //$NON-NLS-1$ } public void testDestroyBeforeStart02() throws InvalidSyntaxException { ApplicationDescriptor app = getApplication(PI_OSGI_TESTS + ".testMainThreaded01"); //$NON-NLS-1$ HashMap args = getArguments(); HashMap results = (HashMap) args.get(testResults); ServiceTrackerCustomizer trackerCustomizer = new ServiceTrackerCustomizer() { public Object addingService(ServiceReference reference) { ApplicationHandle handle = (ApplicationHandle) getContext().getService(reference); handle.destroy(); return handle; } public void modifiedService(ServiceReference reference, Object service) { // nothing } public void removedService(ServiceReference reference, Object service) { // nothing } }; ServiceTracker tracker = new ServiceTracker(getContext(), FrameworkUtil.createFilter("(&(objectClass=" + ApplicationHandle.class.getName() + ")(" + ApplicationHandle.APPLICATION_DESCRIPTOR + "=" + app.getApplicationId() + "))"), trackerCustomizer); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ tracker.open(); try { ApplicationHandle handle = app.launch(args); handle.destroy(); } catch (Throwable e) { fail("failed to launch simpleApp", e); //$NON-NLS-1$ } finally { tracker.close(); } String result = (String) results.get(simpleResults); assertNull("Check application result", result); //$NON-NLS-1$ } private ScheduledApplication getScheduleApplication(String scheduleID, boolean failOnMissing) { try { BundleContext context = getContext(); assertNotNull("BundleContext is null!!", context); //$NON-NLS-1$ Class schedAppClass = ScheduledApplication.class; assertNotNull("ScheduledApplication.class is null!!", schedAppClass); //$NON-NLS-1$ ServiceReference[] refs = getContext().getServiceReferences(schedAppClass.getName(), "(" + ScheduledApplication.SCHEDULE_ID + "=" + scheduleID + ")"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ if (refs == null || refs.length == 0) { if (!failOnMissing) return null; refs = getContext().getServiceReferences(ScheduledApplication.class.getName(), null); String availableScheds = ""; //$NON-NLS-1$ if (refs != null) { for (int i = 0; i < refs.length; i++) { availableScheds += refs[i].getProperty(ScheduledApplication.SCHEDULE_ID); if (i < refs.length - 1) availableScheds += ","; //$NON-NLS-1$ } } fail("Could not find schedule: " + scheduleID + " available apps are: " + availableScheds); //$NON-NLS-1$ //$NON-NLS-2$ } ScheduledApplication result = (ScheduledApplication) getContext().getService(refs[0]); if (result != null) getContext().ungetService(refs[0]); else fail("Could not get scheduled application: " + scheduleID); //$NON-NLS-1$ return result; } catch (InvalidSyntaxException e) { fail("Could not create app filter", e); //$NON-NLS-1$ } return null; } public static class ApplicationHandleTracker implements ServiceTrackerCustomizer { private ArrayList events = new ArrayList(); private BundleContext bc; public ApplicationHandleTracker(BundleContext bc) { this.bc = bc; } public synchronized Object addingService(ServiceReference reference) { String instance = (String) reference.getProperty(ApplicationHandle.APPLICATION_PID); String state = (String) reference.getProperty(ApplicationHandle.APPLICATION_STATE); events.add(new String[] {instance, state}); Object result = bc.getService(reference); notifyAll(); return result; } public synchronized void modifiedService(ServiceReference reference, Object service) { String instance = (String) reference.getProperty(ApplicationHandle.APPLICATION_PID); String state = (String) reference.getProperty(ApplicationHandle.APPLICATION_STATE); events.add(new String[] {instance, state}); notifyAll(); } public synchronized void removedService(ServiceReference reference, Object service) { String instance = (String) reference.getProperty(ApplicationHandle.APPLICATION_PID); events.add(new String[] {instance, REMOVED}); notifyAll(); } // Note that this method assumes you call it before the event actually gets posted. // It only looks at the last event that was saved. public synchronized void waitForEvent(String instance, String state) { long delay = 5000; long startTime = System.currentTimeMillis(); boolean found = eventFound(instance, state); while (delay > 0 && !found) { try { wait(5000); delay -= System.currentTimeMillis() - startTime; } catch (InterruptedException e) { // do nothing } found = eventFound(instance, state); } if (!found) { Object[][] foundEvents = getEvents(); String foundEventsMsg; if (foundEvents.length > 0) { StringBuffer eventsBuffer = new StringBuffer(); eventsBuffer.append("\nFound the following events: \n"); //$NON-NLS-1$ for (int i = 0; i < foundEvents.length; i++) eventsBuffer.append(" handle event: ").append(foundEvents[i][0]).append(" ").append(foundEvents[i][1]).append("\n"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ foundEventsMsg = eventsBuffer.toString(); } else { foundEventsMsg = "\nNo events recorded"; //$NON-NLS-1$ } fail("failed waiting for handle event: " + instance + " " + state + foundEventsMsg); //$NON-NLS-1$ //$NON-NLS-2$ } } public synchronized String[][] getEvents() { return (String[][]) events.toArray(new String[events.size()][]); } private boolean eventFound(String instance, String state) { if (events.size() == 0) return false; String[] event = (String[]) events.get(events.size() - 1); if (instance.equals(event[0]) && state.equals(event[1])) return true; return false; } } public static class ApplicationDescriptorTracker implements ServiceTrackerCustomizer { private BundleContext bc; private ArrayList events = new ArrayList(); public ApplicationDescriptorTracker(BundleContext bc) { this.bc = bc; } public synchronized Object addingService(ServiceReference reference) { String pid = (String) reference.getProperty(ApplicationDescriptor.APPLICATION_PID); Boolean locked = (Boolean) reference.getProperty(ApplicationDescriptor.APPLICATION_LOCKED); Boolean launchable = (Boolean) reference.getProperty(ApplicationDescriptor.APPLICATION_LAUNCHABLE); events.add(new Object[] {pid, ADDED, locked, launchable}); Object result = bc.getService(reference); notifyAll(); return result; } public synchronized void modifiedService(ServiceReference reference, Object service) { String pid = (String) reference.getProperty(ApplicationDescriptor.APPLICATION_PID); Boolean locked = (Boolean) reference.getProperty(ApplicationDescriptor.APPLICATION_LOCKED); Boolean launchable = (Boolean) reference.getProperty(ApplicationDescriptor.APPLICATION_LAUNCHABLE); events.add(new Object[] {pid, MODIFIED, locked, launchable}); notifyAll(); } public synchronized void removedService(ServiceReference reference, Object service) { String pid = (String) reference.getProperty(ApplicationDescriptor.APPLICATION_PID); Boolean locked = (Boolean) reference.getProperty(ApplicationDescriptor.APPLICATION_LOCKED); Boolean launchable = (Boolean) reference.getProperty(ApplicationDescriptor.APPLICATION_LAUNCHABLE); events.add(new Object[] {pid, REMOVED, locked, launchable}); notifyAll(); } // Note that this method assumes you call it before the event actually gets posted. // It only looks at the last event that was saved. public synchronized void waitForEvent(String pid, String type, Boolean locked, Boolean launchable) { long delay = 5000; long startTime = System.currentTimeMillis(); boolean found = eventFound(pid, type, locked, launchable); while (delay > 0 && !found) { try { wait(5000); delay -= System.currentTimeMillis() - startTime; } catch (InterruptedException e) { // do nothing } found = eventFound(pid, type, locked, launchable); } if (!found) { Object[][] foundEvents = getEvents(); String foundEventsMsg; if (foundEvents.length > 0) { StringBuffer eventsBuffer = new StringBuffer(); eventsBuffer.append("\nFound the following events: \n"); //$NON-NLS-1$ for (int i = 0; i < foundEvents.length; i++) eventsBuffer.append(" descriptor event: ").append(foundEvents[i][0]).append(" ").append(foundEvents[i][1]).append(" ").append(foundEvents[i][2]).append(" ").append(foundEvents[i][3]).append("\n"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ foundEventsMsg = eventsBuffer.toString(); } else { foundEventsMsg = "\nNo events recorded"; //$NON-NLS-1$ } fail("failed waiting for descriptor event: " + pid + " " + type + " " + locked + " " + launchable + foundEventsMsg); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ } } public synchronized Object[][] getEvents() { return (Object[][]) events.toArray(new Object[events.size()][]); } private boolean eventFound(String pid, String type, Boolean locked, Boolean launchable) { if (events.size() == 0) return false; Object[] event = (Object[]) events.get(events.size() - 1); if (pid.equals(event[0]) && type.equals(event[1]) && locked.equals(event[2]) && launchable.equals(event[3])) return true; return false; } } }