/******************************************************************************* * Copyright (c) 2009, 2013 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.debug.tests.launching; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.NullProgressMonitor; import org.eclipse.core.runtime.Platform; import org.eclipse.debug.core.ILaunch; import org.eclipse.debug.core.ILaunchConfiguration; import org.eclipse.debug.core.ILaunchConfigurationType; import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy; import org.eclipse.debug.core.ILaunchManager; import org.eclipse.debug.internal.core.LaunchManager; import org.eclipse.debug.tests.launching.CancellingLaunchDelegate.CancellingLaunch; /** * * Variety of tests for the {@link org.eclipse.debug.internal.core.LaunchManager} * * @since 3.6 */ @SuppressWarnings("deprecation") public class LaunchManagerTests extends AbstractLaunchTest { /** * Constructor * @param name */ public LaunchManagerTests(String name) { super(name); } /** * Tests generating a valid launch configuration name */ public void testGenereateConfigName() { String configname = "launch_configuration"; //$NON-NLS-1$ String name = getLaunchManager().generateLaunchConfigurationName(configname); assertTrue("the name nust be '" + configname + "'", name.equals(configname)); //$NON-NLS-1$ //$NON-NLS-2$ } /** * Tests generating a launch configuration name with an unsupported char using * the deprecated method */ public void testGenereateConfigNameBadChar() { String configname = "config:name"; //$NON-NLS-1$ String name = getLaunchManager().generateUniqueLaunchConfigurationNameFrom(configname); assertEquals("config name should be '" + configname + "'", configname, name); //$NON-NLS-1$ //$NON-NLS-2$ } /** * Tests that a valid name is accepted as is. */ public void testGenerateValidName() { String configname = "thisisavalidname"; //$NON-NLS-1$ String name = getLaunchManager().generateLaunchConfigurationName(configname); assertEquals("Should be the same as the seed", configname, name); //$NON-NLS-1$ } /** * Tests generating a launch configuration name using a name that is an OS reserved * name. Win 32 test only. */ public void testGenerateConfigNameReservedName() { if(Platform.OS_WIN32.equals(Platform.getOS())) { String configname = "aux"; //$NON-NLS-1$ String name = getLaunchManager().generateUniqueLaunchConfigurationNameFrom(configname); assertEquals("config name should be 'aux'", configname, name); //$NON-NLS-1$ } } /** * Tests generating a configuration name that contains an invalid character */ public void testGenerateBadConfigName() { String configname = "config:name"; //$NON-NLS-1$ String name = getLaunchManager().generateLaunchConfigurationName(configname); assertEquals("config name should be 'config_name'", "config_name", name); //$NON-NLS-1$ //$NON-NLS-2$ } /** * Tests generating a name that conflicts with an OS reserved name. This test is for windows only as there * are no reserved names on other OS's. */ public void testGenerateConflictingName() { if(Platform.OS_WIN32.equals(Platform.getOS())) { String configname = "aux"; //$NON-NLS-1$ String name = getLaunchManager().generateLaunchConfigurationName(configname); assertEquals("config name should be 'launch_configuration'", "launch_configuration", name); //$NON-NLS-1$ //$NON-NLS-2$ } } /** * Tests generating a configuration name that contains an invalid character and where there * is another config with the replaced name already */ public void testGenerateBadCharConflict() throws Exception { String configname = "config:name"; //$NON-NLS-1$ String name = getLaunchManager().generateLaunchConfigurationName(configname); assertEquals("config name should be 'config_name'", "config_name", name); //$NON-NLS-1$ //$NON-NLS-2$ getLaunchConfiguration(name); name = getLaunchManager().generateLaunchConfigurationName(configname); assertEquals("config name should be 'config_name (1)'", "config_name (1)", name); //$NON-NLS-1$ //$NON-NLS-2$ ILaunchConfiguration config = getLaunchConfiguration("config_name"); //$NON-NLS-1$ config.delete(); } /** * Tests generating a name that conflicts with an OS reserved name and that * there is a config with the replaced name already. This test is for windows only as there * are no reserved names on other OS's. */ public void testGenerateBadNameConflict() throws Exception { if(Platform.OS_WIN32.equals(Platform.getOS())) { String configname = "com2"; //$NON-NLS-1$ String name = getLaunchManager().generateLaunchConfigurationName(configname); assertEquals("config name should be 'launch_configuration'", "launch_configuration", name); //$NON-NLS-1$ //$NON-NLS-2$ getLaunchConfiguration(name); name = getLaunchManager().generateLaunchConfigurationName(configname); assertEquals("config name should be 'launch_configuration (1)'", "launch_configuration (1)", name); //$NON-NLS-1$ //$NON-NLS-2$ ILaunchConfiguration config = getLaunchConfiguration("launch_configuration"); //$NON-NLS-1$ config.delete(); } } /** * Tests the {@link org.eclipse.debug.core.ILaunchManager#isValidLaunchConfigurationName(String)} method for correctness */ public void testValidateConfigGoodName() { String configname = "configname"; //$NON-NLS-1$ try { getLaunchManager().isValidLaunchConfigurationName(configname); } catch(IllegalArgumentException iae) { fail("the config name should not have thrown an exception during validation"); //$NON-NLS-1$ } } /** * Tests the {@link org.eclipse.debug.core.ILaunchManager#isValidLaunchConfigurationName(String)} method for correctness */ public void testValidateConfigBadCharName() { String configname = "config:name"; //$NON-NLS-1$ try { getLaunchManager().isValidLaunchConfigurationName(configname); } catch(IllegalArgumentException iae) { return; } fail("the config name should have thrown an exception during validation"); //$NON-NLS-1$ } /** * Tests the {@link org.eclipse.debug.core.ILaunchManager#isValidLaunchConfigurationName(String)} method for correctness */ public void testValidateConfigBadName() { if(Platform.OS_WIN32.equals(Platform.getOS())) { String configname = "com1"; //$NON-NLS-1$ try { getLaunchManager().isValidLaunchConfigurationName(configname); } catch(IllegalArgumentException iae) { return; } fail("the config name should have thrown an exception during validation"); //$NON-NLS-1$ } } /** * Tests that generating a configuration name when there exists a configuration with that name * already properly updates a '(N)' counter at the end */ public void testGenerateNameExistingConfig() throws Exception { String configname = "x.y.z.configname"; //$NON-NLS-1$ getLaunchConfiguration(configname); String name = getLaunchManager().generateLaunchConfigurationName(configname); assertEquals("the configuration name should have been " + configname + " (1)", configname + " (1)", name); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ getLaunchConfiguration(name); name = getLaunchManager().generateLaunchConfigurationName(name); assertEquals("the configuration name should have been " + configname + " (2)", configname + " (2)", name); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ ILaunchConfiguration config = getLaunchConfiguration(configname); if(config != null) { config.delete(); } config = getLaunchConfiguration(configname + " (1)"); //$NON-NLS-1$ if(config != null) { config.delete(); } } /** * Tests that removing an accelerator properly removes it without affecting the base string (readable) value */ public void testRemoveAcc() { String text = "&Remove"; //$NON-NLS-1$ String label = LaunchManager.removeAccelerators(text); assertEquals("the label should be 'Remove'", "Remove", label); //$NON-NLS-1$ //$NON-NLS-2$ text = "Remo&ve"; //$NON-NLS-1$ label = LaunchManager.removeAccelerators(text); assertEquals("the label should be 'Remove'", "Remove", label); //$NON-NLS-1$ //$NON-NLS-2$ } /** * Create a new configuration that will cancel one of the three checks: 1. * preLaunchCheck 2. finalLaunchCheck 3. buildForLaunch * * @param pre If the prelaunchCheck should cancel * @param fin If the fnalLaunchCheck should cancel * @param build If the buildForLaunch check should cancel * @return the new {@link ILaunchConfiguration} * @since 3.9.100 */ ILaunchConfiguration getCancellingConfiguration(boolean pre, boolean fin, boolean build) throws Exception { ILaunchConfigurationType type = getLaunchManager().getLaunchConfigurationType("cancelling.type"); //$NON-NLS-1$ if (type != null) { ILaunchConfigurationWorkingCopy copy = type.newInstance(null, getLaunchManager().generateLaunchConfigurationName("cancelling")); //$NON-NLS-1$ copy.setAttribute("cancel.preLaunchCheck", !pre); //$NON-NLS-1$ copy.setAttribute("cancel.finalLaunchCheck", !fin); //$NON-NLS-1$ copy.setAttribute("cancel.buildForLaunch", !build); //$NON-NLS-1$ return copy.doSave(); } return null; } /** * Checks if the expected number of cancelled launches appear in the manager * * @param count the expected count * @since 3.9.100 */ void hasCancellingLaunches(int count) { ILaunch[] launches = getLaunchManager().getLaunches(); int num = 0; for (int i = 0; i < launches.length; i++) { if (launches[i] instanceof CancellingLaunch) { num++; } } assertEquals("The number of expected launches is wrong", count, num); //$NON-NLS-1$ } /** * Tests if a launch is properly removed from the launch manager when * #preLaunchCheck is cancelled * * @throws Exception * @see https://bugs.eclipse.org/bugs/show_bug.cgi?id=437122 * @since 3.9.100 */ public void testCancelledPreLaunchCheck() throws Exception { ILaunchConfiguration config = getCancellingConfiguration(true, false, false); assertNotNull("The cancelling config should have been created", config); //$NON-NLS-1$ try { hasCancellingLaunches(0); config.launch("run", new NullProgressMonitor()); //$NON-NLS-1$ hasCancellingLaunches(0); } finally { ILaunch[] launches = getLaunchManager().getLaunches(); for (int i = 0; i < launches.length; i++) { getLaunchManager().removeLaunch(launches[i]); } config.delete(); } } /** * Tests if a launch is properly removed from the launch manager when * #finalLaunchCheck is cancelled * * @throws Exception * @see https://bugs.eclipse.org/bugs/show_bug.cgi?id=437122 * @since 3.9.100 */ public void testCancelledFinalLaunchCheck() throws Exception { ILaunchConfiguration config = getCancellingConfiguration(false, true, false); assertNotNull("The cancelling config should have been created", config); //$NON-NLS-1$ try { hasCancellingLaunches(0); config.launch("run", new NullProgressMonitor()); //$NON-NLS-1$ hasCancellingLaunches(0); } finally { ILaunch[] launches = getLaunchManager().getLaunches(); for (int i = 0; i < launches.length; i++) { getLaunchManager().removeLaunch(launches[i]); } config.delete(); } } /** * Tests if a launch is properly removed from the launch manager when * #buildFoLaunch is cancelled * * @throws Exception * @see https://bugs.eclipse.org/bugs/show_bug.cgi?id=437122 * @since 3.9.100 */ public void testCancelledBuildForLaunch() throws Exception { ILaunchConfiguration config = getCancellingConfiguration(false, false, true); assertNotNull("The cancelling config should have been created", config); //$NON-NLS-1$ try { hasCancellingLaunches(0); config.launch("run", new NullProgressMonitor()); //$NON-NLS-1$ hasCancellingLaunches(1); // XXX #buildForLaunch does not remove the // launch } finally { ILaunch[] launches = getLaunchManager().getLaunches(); for (int i = 0; i < launches.length; i++) { getLaunchManager().removeLaunch(launches[i]); } config.delete(); } } /** * There was a race condition in getting a unique name for a launch * configuration. * <p> * Note, due to the nature of the bug, it is possible that running this test * will not trigger the original bug. To increase the probability of hitting * the NPE in the unpatched code, increase the size of config. However, * increasing the number increases the runtime of the test substantially. */ public void testNPE_Bug484882() throws Exception { // In this thread continuously creates configs so that // org.eclipse.debug.internal.core.LaunchManager.clearConfigNameCache() // is called repeatedly. We also want to make lots of configurations so // the runtime of getAllSortedConfigNames (called by // isExistingLaunchConfigurationName // below) is long enough to hit the race condition. final boolean stop[] = new boolean[] { false }; final Throwable exception[] = new Throwable[] { null }; Thread thread = new Thread() { @Override public void run() { ILaunchConfiguration config[] = new ILaunchConfiguration[10000]; try { for (int i = 0; i < config.length && !stop[0]; i++) { config[i] = getLaunchConfiguration("Name" + i); //$NON-NLS-1$ } for (int i = 0; i < config.length; i++) { if (config[i] != null) { config[i].delete(); } } } catch (CoreException e) { exception[0] = e; } } }; thread.start(); try { ILaunchManager launchManager = getLaunchManager(); while (thread.isAlive()) { // This call generated an NPE launchManager.isExistingLaunchConfigurationName("Name"); //$NON-NLS-1$ } } finally { stop[0] = true; thread.join(1000); assertFalse(thread.isAlive()); if (exception[0] != null) { throw new Exception("Exception in Thread", exception[0]); //$NON-NLS-1$ } } } }