1 /*******************************************************************************
2  * Copyright (c) 2000, 2020 IBM Corporation and others.
3  *
4  * This program and the accompanying materials
5  * are made available under the terms of the Eclipse Public License 2.0
6  * which accompanies this distribution, and is available at
7  * https://www.eclipse.org/legal/epl-2.0/
8  *
9  * SPDX-License-Identifier: EPL-2.0
10  *
11  * Contributors:
12  *     IBM Corporation - initial API and implementation
13  *     Jesper Steen Møller - bug 422029: [1.8] Enable debug evaluation support for default methods
14  *     Jesper Steen Møller - bug 426903: [1.8] Cannot evaluate super call to default method
15  *     Jesper Steen Møller - bug 341232
16  *******************************************************************************/
17 package org.eclipse.jdt.debug.tests;
18 
19 import java.io.File;
20 import java.io.PrintWriter;
21 import java.io.StringWriter;
22 import java.util.ArrayList;
23 import java.util.Arrays;
24 import java.util.Collection;
25 import java.util.Collections;
26 import java.util.HashMap;
27 import java.util.HashSet;
28 import java.util.List;
29 import java.util.Map;
30 import java.util.Set;
31 import java.util.stream.Collectors;
32 
33 import org.eclipse.core.resources.IFile;
34 import org.eclipse.core.resources.IFolder;
35 import org.eclipse.core.resources.IMarker;
36 import org.eclipse.core.resources.IMarkerDelta;
37 import org.eclipse.core.resources.IProject;
38 import org.eclipse.core.resources.IResource;
39 import org.eclipse.core.resources.IncrementalProjectBuilder;
40 import org.eclipse.core.resources.ResourcesPlugin;
41 import org.eclipse.core.runtime.CoreException;
42 import org.eclipse.core.runtime.IPath;
43 import org.eclipse.core.runtime.IProgressMonitor;
44 import org.eclipse.core.runtime.IStatus;
45 import org.eclipse.core.runtime.OperationCanceledException;
46 import org.eclipse.core.runtime.Path;
47 import org.eclipse.core.runtime.Platform;
48 import org.eclipse.core.runtime.Status;
49 import org.eclipse.core.runtime.jobs.Job;
50 import org.eclipse.core.runtime.preferences.IEclipsePreferences;
51 import org.eclipse.core.runtime.preferences.InstanceScope;
52 import org.eclipse.debug.core.DebugEvent;
53 import org.eclipse.debug.core.DebugException;
54 import org.eclipse.debug.core.DebugPlugin;
55 import org.eclipse.debug.core.IBreakpointListener;
56 import org.eclipse.debug.core.IBreakpointManager;
57 import org.eclipse.debug.core.ILaunch;
58 import org.eclipse.debug.core.ILaunchConfiguration;
59 import org.eclipse.debug.core.ILaunchConfigurationType;
60 import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
61 import org.eclipse.debug.core.ILaunchDelegate;
62 import org.eclipse.debug.core.ILaunchManager;
63 import org.eclipse.debug.core.model.IBreakpoint;
64 import org.eclipse.debug.core.model.IDebugTarget;
65 import org.eclipse.debug.core.model.ILineBreakpoint;
66 import org.eclipse.debug.core.model.IProcess;
67 import org.eclipse.debug.core.model.IThread;
68 import org.eclipse.debug.core.model.IValue;
69 import org.eclipse.debug.core.model.IVariable;
70 import org.eclipse.debug.internal.core.LaunchDelegate;
71 import org.eclipse.debug.internal.core.LaunchManager;
72 import org.eclipse.debug.internal.ui.DebugUIPlugin;
73 import org.eclipse.debug.internal.ui.IInternalDebugUIConstants;
74 import org.eclipse.debug.internal.ui.breakpoints.provisional.IBreakpointOrganizer;
75 import org.eclipse.debug.internal.ui.launchConfigurations.LaunchConfigurationManager;
76 import org.eclipse.debug.internal.ui.launchConfigurations.LaunchConfigurationPresentationManager;
77 import org.eclipse.debug.internal.ui.launchConfigurations.LaunchConfigurationsDialog;
78 import org.eclipse.debug.internal.ui.launchConfigurations.LaunchShortcutExtension;
79 import org.eclipse.debug.internal.ui.preferences.IDebugPreferenceConstants;
80 import org.eclipse.debug.internal.ui.views.breakpoints.BreakpointOrganizerManager;
81 import org.eclipse.debug.internal.ui.views.console.ProcessConsole;
82 import org.eclipse.debug.ui.DebugUITools;
83 import org.eclipse.debug.ui.IDebugModelPresentation;
84 import org.eclipse.debug.ui.IDebugUIConstants;
85 import org.eclipse.debug.ui.IDebugView;
86 import org.eclipse.debug.ui.ILaunchConfigurationDialog;
87 import org.eclipse.debug.ui.ILaunchConfigurationTabGroup;
88 import org.eclipse.debug.ui.actions.ToggleBreakpointAction;
89 import org.eclipse.jdt.core.IAccessRule;
90 import org.eclipse.jdt.core.IBuffer;
91 import org.eclipse.jdt.core.IClassFile;
92 import org.eclipse.jdt.core.IClasspathAttribute;
93 import org.eclipse.jdt.core.IClasspathEntry;
94 import org.eclipse.jdt.core.ICompilationUnit;
95 import org.eclipse.jdt.core.IField;
96 import org.eclipse.jdt.core.IJavaElement;
97 import org.eclipse.jdt.core.IJavaProject;
98 import org.eclipse.jdt.core.IMember;
99 import org.eclipse.jdt.core.IMethod;
100 import org.eclipse.jdt.core.IPackageFragment;
101 import org.eclipse.jdt.core.IPackageFragmentRoot;
102 import org.eclipse.jdt.core.ISourceRange;
103 import org.eclipse.jdt.core.IType;
104 import org.eclipse.jdt.core.JavaCore;
105 import org.eclipse.jdt.core.JavaModelException;
106 import org.eclipse.jdt.core.Signature;
107 import org.eclipse.jdt.debug.core.IJavaClassPrepareBreakpoint;
108 import org.eclipse.jdt.debug.core.IJavaDebugTarget;
109 import org.eclipse.jdt.debug.core.IJavaExceptionBreakpoint;
110 import org.eclipse.jdt.debug.core.IJavaLineBreakpoint;
111 import org.eclipse.jdt.debug.core.IJavaMethodBreakpoint;
112 import org.eclipse.jdt.debug.core.IJavaObject;
113 import org.eclipse.jdt.debug.core.IJavaPatternBreakpoint;
114 import org.eclipse.jdt.debug.core.IJavaStackFrame;
115 import org.eclipse.jdt.debug.core.IJavaStratumLineBreakpoint;
116 import org.eclipse.jdt.debug.core.IJavaTargetPatternBreakpoint;
117 import org.eclipse.jdt.debug.core.IJavaThread;
118 import org.eclipse.jdt.debug.core.IJavaVariable;
119 import org.eclipse.jdt.debug.core.IJavaWatchpoint;
120 import org.eclipse.jdt.debug.core.JDIDebugModel;
121 import org.eclipse.jdt.debug.eval.EvaluationManager;
122 import org.eclipse.jdt.debug.eval.IAstEvaluationEngine;
123 import org.eclipse.jdt.debug.eval.IEvaluationListener;
124 import org.eclipse.jdt.debug.eval.IEvaluationResult;
125 import org.eclipse.jdt.debug.testplugin.DebugElementEventWaiter;
126 import org.eclipse.jdt.debug.testplugin.DebugElementKindEventDetailWaiter;
127 import org.eclipse.jdt.debug.testplugin.DebugElementKindEventWaiter;
128 import org.eclipse.jdt.debug.testplugin.DebugEventWaiter;
129 import org.eclipse.jdt.debug.testplugin.JavaProjectHelper;
130 import org.eclipse.jdt.debug.testplugin.JavaTestPlugin;
131 import org.eclipse.jdt.debug.tests.core.LiteralTests17;
132 import org.eclipse.jdt.debug.tests.refactoring.MemberParser;
133 import org.eclipse.jdt.debug.ui.IJavaDebugUIConstants;
134 import org.eclipse.jdt.internal.debug.core.model.JDIDebugTarget;
135 import org.eclipse.jdt.internal.debug.eval.ast.engine.ASTEvaluationEngine;
136 import org.eclipse.jdt.internal.debug.ui.BreakpointUtils;
137 import org.eclipse.jdt.internal.debug.ui.IJDIPreferencesConstants;
138 import org.eclipse.jdt.internal.debug.ui.JDIDebugUIPlugin;
139 import org.eclipse.jdt.launching.IJavaLaunchConfigurationConstants;
140 import org.eclipse.jdt.launching.IVMInstall;
141 import org.eclipse.jdt.launching.JavaRuntime;
142 import org.eclipse.jdt.launching.environments.IExecutionEnvironment;
143 import org.eclipse.jface.dialogs.ErrorDialog;
144 import org.eclipse.jface.dialogs.MessageDialogWithToggle;
145 import org.eclipse.jface.preference.IPreferenceStore;
146 import org.eclipse.jface.text.BadPositionCategoryException;
147 import org.eclipse.jface.text.Document;
148 import org.eclipse.jface.text.IDocument;
149 import org.eclipse.jface.text.IRegion;
150 import org.eclipse.jface.text.Position;
151 import org.eclipse.jface.text.source.IVerticalRulerInfo;
152 import org.eclipse.jface.util.SafeRunnable;
153 import org.eclipse.swt.widgets.Display;
154 import org.eclipse.ui.IEditorPart;
155 import org.eclipse.ui.IWorkbench;
156 import org.eclipse.ui.IWorkbenchPage;
157 import org.eclipse.ui.IWorkbenchWindow;
158 import org.eclipse.ui.PartInitException;
159 import org.eclipse.ui.PlatformUI;
160 import org.eclipse.ui.console.IConsole;
161 import org.eclipse.ui.console.IHyperlink;
162 import org.eclipse.ui.console.TextConsole;
163 import org.eclipse.ui.ide.IDE;
164 import org.eclipse.ui.internal.console.ConsoleHyperlinkPosition;
165 import org.eclipse.ui.intro.IIntroManager;
166 import org.eclipse.ui.intro.IIntroPart;
167 import org.eclipse.ui.progress.UIJob;
168 import org.eclipse.ui.progress.WorkbenchJob;
169 import org.osgi.service.prefs.BackingStoreException;
170 
171 import com.sun.jdi.InternalException;
172 import com.sun.jdi.InvocationException;
173 
174 import junit.framework.TestCase;
175 
176 /**
177  * Tests for launch configurations
178  */
179 @SuppressWarnings("deprecation")
180 public abstract class AbstractDebugTest extends TestCase implements  IEvaluationListener {
181 
182 	public static final String MULTI_OUTPUT_PROJECT_NAME = "MultiOutput";
183 	public static final String BOUND_EE_PROJECT_NAME = "BoundEE";
184 	public static final String ONE_FOUR_PROJECT_NAME = "DebugTests";
185 	public static final String ONE_FOUR_PROJECT_CLOSED_NAME = "ClosedDebugTests";
186 	public static final String ONE_FIVE_PROJECT_NAME = "OneFive";
187 	public static final String ONE_SEVEN_PROJECT_NAME = "OneSeven";
188 	public static final String ONE_EIGHT_PROJECT_NAME = "OneEight";
189 	public static final String NINE_PROJECT_NAME = "Nine";
190 	public static final String BOUND_JRE_PROJECT_NAME = "BoundJRE";
191 	public static final String CLONE_SUFFIX = "Clone";
192 
193 	final String[] LAUNCH_CONFIG_NAMES_1_4 = {"LargeSourceFile", "LotsOfFields", "Breakpoints", "InstanceVariablesTests", "LocalVariablesTests", "LocalVariableTests2", "StaticVariablesTests",
194 			"DropTests", "ThrowsNPE", "ThrowsException", "org.eclipse.debug.tests.targets.Watchpoint",
195 			"org.eclipse.debug.tests.targets.BreakpointsLocationBug344984", "org.eclipse.debug.tests.targets.CallLoop", "A",
196 			"HitCountLooper", "CompileError", "MultiThreadedLoop", "HitCountException", "MultiThreadedException", "MultiThreadedList", "MethodLoop", "StepFilterOne",
197 			"StepFilterFour", "EvalArrayTests", "EvalSimpleTests", "EvalTypeTests", "EvalNestedTypeTests", "EvalTypeHierarchyTests",
198 			"EvalAnonymousClassVariableTests", "WorkingDirectoryTest",
199 			"OneToTen", "OneToTenPrint", "FloodConsole", "ConditionalStepReturn", "VariableChanges", "DefPkgReturnType", "InstanceFilterObject", "org.eclipse.debug.tests.targets.CallStack",
200 			"org.eclipse.debug.tests.targets.ThreadStack", "org.eclipse.debug.tests.targets.HcrClass", "org.eclipse.debug.tests.targets.StepIntoSelectionClass",
201 			"WatchItemTests", "ArrayTests", "ByteArrayTests", "PerfLoop", "Console80Chars", "ConsoleStackTrace", "ConsoleVariableLineLength", "StackTraces",
202 			"ConsoleInput", "PrintConcatenation", "VariableDetails", "org.eclipse.debug.tests.targets.ArrayDetailTests", "ArrayDetailTestsDef", "ForceReturnTests",
203 			"ForceReturnTestsTwo", "LogicalStructures", "BreakpointListenerTest", "LaunchHistoryTest", "LaunchHistoryTest2", "RunnableAppletImpl", "java6.AllInstancesTests",
204 			"bug329294", "bug401270", "org.eclipse.debug.tests.targets.HcrClass2", "org.eclipse.debug.tests.targets.HcrClass3", "org.eclipse.debug.tests.targets.HcrClass4",
205 			"org.eclipse.debug.tests.targets.HcrClass5", "org.eclipse.debug.tests.targets.HcrClass6", "org.eclipse.debug.tests.targets.HcrClass7", "org.eclipse.debug.tests.targets.HcrClass8",
206 			"org.eclipse.debug.tests.targets.HcrClass9", "TestContributedStepFilterClass", "TerminateAll_01", "TerminateAll_02", "StepResult1",
207 			"StepResult2", "StepResult3", "StepUncaught", "TriggerPoint_01", "BulkThreadCreationTest", "MethodExitAndException",
208 			"Bug534319earlyStart", "Bug534319lateStart", "Bug534319singleThread", "Bug534319startBetwen", "MethodCall", "Bug538303", "Bug540243",
209 			"OutSync", "OutSync2", "ConsoleOutputUmlaut", "ErrorRecurrence" };
210 
211 	/**
212 	 * the default timeout
213 	 */
214 	public static final int DEFAULT_TIMEOUT = 30000;
215 
216 	//constants
217 	protected static final String JAVA = "java"; //$NON-NLS-1$
218 	protected static final String JAVA_EXTENSION = ".java"; //$NON-NLS-1$
219 	protected static final String LAUNCHCONFIGURATIONS = "launchConfigurations"; //$NON-NLS-1$
220 	protected static final String LAUNCH_EXTENSION = ".launch"; //$NON-NLS-1$
221 	protected static final String LOCAL_JAVA_APPLICATION_TYPE_ID = "org.eclipse.jdt.launching.localJavaApplication"; //$NON-NLS-1$
222 	protected static final String JAVA_LAUNCH_SHORTCUT_ID = "org.eclipse.jdt.debug.ui.localJavaShortcut"; //$NON-NLS-1$
223 	protected static final String TEST_LAUNCH_SHORTCUT = "org.eclipse.jdt.debug.tests.testShortCut";
224 
225 	/**
226 	 * an evaluation result
227 	 */
228 	public IEvaluationResult fEvaluationResult;
229 
230 	/**
231 	 * The last relevant event set - for example, that caused
232 	 * a thread to suspend
233 	 */
234 	protected DebugEvent[] fEventSet;
235 
236 	private static boolean loadedPrefs = false;
237 	private static boolean loaded14 = false;
238 	private static boolean loaded15 = false;
239 	private static boolean loaded17 = false;
240 	private static boolean loaded18 = false;
241 	private static boolean loaded9 = false;
242 	private static boolean loadedEE = false;
243 	private static boolean loadedJRE = false;
244 	private static boolean loadedMulti = false;
245 	private static boolean welcomeClosed = false;
246 
247 	/**
248 	 * Constructor
249 	 * @param name
250 	 */
AbstractDebugTest(String name)251 	public AbstractDebugTest(String name) {
252 		super(name);
253 		// set error dialog to non-blocking to avoid hanging the UI during test
254 		ErrorDialog.AUTOMATED_MODE = true;
255 		SafeRunnable.setIgnoreErrors(true);
256 	}
257 
258 	@Override
setUp()259 	protected void setUp() throws Exception {
260 		TestUtil.log(IStatus.INFO, getName(), "setUp");
261 		super.setUp();
262 		setPreferences();
263 		IProject pro = ResourcesPlugin.getWorkspace().getRoot().getProject(ONE_FOUR_PROJECT_NAME);
264 		loaded14 = pro.exists();
265 		pro = ResourcesPlugin.getWorkspace().getRoot().getProject(ONE_FIVE_PROJECT_NAME);
266 		loaded15 = pro.exists();
267 		pro = ResourcesPlugin.getWorkspace().getRoot().getProject(ONE_SEVEN_PROJECT_NAME);
268 		loaded17 = pro.exists();
269 		pro = ResourcesPlugin.getWorkspace().getRoot().getProject(ONE_EIGHT_PROJECT_NAME);
270 		loaded18 = pro.exists();
271 		pro = ResourcesPlugin.getWorkspace().getRoot().getProject(NINE_PROJECT_NAME);
272 		loaded9 = pro.exists();
273 		pro = ResourcesPlugin.getWorkspace().getRoot().getProject(BOUND_JRE_PROJECT_NAME);
274 		loadedJRE = pro.exists();
275 		pro = ResourcesPlugin.getWorkspace().getRoot().getProject(BOUND_EE_PROJECT_NAME);
276 		loadedEE = pro.exists();
277 		pro = ResourcesPlugin.getWorkspace().getRoot().getProject(MULTI_OUTPUT_PROJECT_NAME);
278 		loadedMulti = pro.exists();
279 		assertWelcomeScreenClosed();
280 	}
281 
setPreferences()282 	synchronized void setPreferences() throws BackingStoreException {
283 		if(!loadedPrefs) {
284 	        IPreferenceStore debugUIPreferences = DebugUIPlugin.getDefault().getPreferenceStore();
285 	        // Don't prompt for perspective switching
286 	        debugUIPreferences.setValue(IInternalDebugUIConstants.PREF_SWITCH_PERSPECTIVE_ON_SUSPEND, MessageDialogWithToggle.ALWAYS);
287 	        debugUIPreferences.setValue(IInternalDebugUIConstants.PREF_SWITCH_TO_PERSPECTIVE, MessageDialogWithToggle.ALWAYS);
288 	        debugUIPreferences.setValue(IInternalDebugUIConstants.PREF_RELAUNCH_IN_DEBUG_MODE, MessageDialogWithToggle.NEVER);
289 	        debugUIPreferences.setValue(IInternalDebugUIConstants.PREF_WAIT_FOR_BUILD, MessageDialogWithToggle.ALWAYS);
290 	        debugUIPreferences.setValue(IInternalDebugUIConstants.PREF_CONTINUE_WITH_COMPILE_ERROR, MessageDialogWithToggle.ALWAYS);
291 	        debugUIPreferences.setValue(IInternalDebugUIConstants.PREF_SAVE_DIRTY_EDITORS_BEFORE_LAUNCH, MessageDialogWithToggle.NEVER);
292 
293 	        String property = System.getProperty("debug.workbenchActivation");
294 	        boolean activate = property != null && property.equals("on");
295 	        debugUIPreferences.setValue(IDebugPreferenceConstants.CONSOLE_OPEN_ON_ERR, activate);
296 	        debugUIPreferences.setValue(IDebugPreferenceConstants.CONSOLE_OPEN_ON_OUT, activate);
297 	        debugUIPreferences.setValue(IInternalDebugUIConstants.PREF_ACTIVATE_DEBUG_VIEW, activate);
298 	        debugUIPreferences.setValue(IDebugUIConstants.PREF_ACTIVATE_WORKBENCH, activate);
299 
300 	        IPreferenceStore jdiUIPreferences = JDIDebugUIPlugin.getDefault().getPreferenceStore();
301 	        // Turn off suspend on uncaught exceptions
302 	        jdiUIPreferences.setValue(IJDIPreferencesConstants.PREF_SUSPEND_ON_UNCAUGHT_EXCEPTIONS, false);
303 	        jdiUIPreferences.setValue(IJDIPreferencesConstants.PREF_SUSPEND_ON_COMPILATION_ERRORS, false);
304 	        // Don't warn about HCR failures
305 	        jdiUIPreferences.setValue(IJDIPreferencesConstants.PREF_ALERT_HCR_FAILED, false);
306 	        jdiUIPreferences.setValue(IJDIPreferencesConstants.PREF_ALERT_HCR_NOT_SUPPORTED, false);
307 	        jdiUIPreferences.setValue(IJDIPreferencesConstants.PREF_ALERT_OBSOLETE_METHODS, false);
308 	        // Set the timeout preference to a high value, to avoid timeouts while
309 	        // testing
310 	        JDIDebugModel.getPreferences().setDefault(JDIDebugModel.PREF_REQUEST_TIMEOUT, 10000);
311 	        // turn off monitor information
312 	        jdiUIPreferences.setValue(IJavaDebugUIConstants.PREF_SHOW_MONITOR_THREAD_INFO, false);
313 
314 	        //make sure we are auto-refreshing external workspace changes
315 	        IEclipsePreferences node = InstanceScope.INSTANCE.getNode(ResourcesPlugin.PI_RESOURCES);
316 	        if(node != null) {
317 	        	node.putBoolean(ResourcesPlugin.PREF_AUTO_REFRESH, true);
318 	        	node.putBoolean(ResourcesPlugin.PREF_LIGHTWEIGHT_AUTO_REFRESH, true);
319 	        	node.flush();
320 	        }
321 	        loadedPrefs = true;
322 		}
323     }
324 
325 	/**
326 	 * Creates the Java 1.4 compliant project
327 	 */
assert14Project()328 	synchronized void assert14Project() {
329 		IJavaProject jp = null;
330 		ArrayList<ILaunchConfiguration> cfgs = new ArrayList<>(1);
331         try {
332 	        if (!loaded14) {
333 	        	try {
334 	        		jp = JavaProjectHelper.createJavaProject(ONE_FOUR_PROJECT_CLOSED_NAME);
335 	        		jp.getProject().close(null);
336 	        	}
337 	        	catch(Exception e) {
338 	        		handleProjectCreationException(e, ONE_FOUR_PROJECT_CLOSED_NAME, jp);
339 	        	}
340 				jp = createProject(ONE_FOUR_PROJECT_NAME, JavaProjectHelper.TEST_SRC_DIR.toString(), JavaProjectHelper.JAVA_SE_1_7_EE_NAME, false);
341 	        	IPackageFragmentRoot src = jp.findPackageFragmentRoot(new Path(ONE_FOUR_PROJECT_NAME).append(JavaProjectHelper.SRC_DIR).makeAbsolute());
342 	        	assertNotNull("The 'src' package fragment root should not be null", src);
343 	        	File root = JavaTestPlugin.getDefault().getFileInPlugin(new Path("testjars"));
344 		        JavaProjectHelper.importFilesFromDirectory(root, src.getPath(), null);
345 		        IPath path = src.getPath().append("A.jar");
346 		        JavaProjectHelper.addLibrary(jp, path);
347 
348 		        //add a closed project optional classpath entry
349 		        //see https://bugs.eclipse.org/bugs/show_bug.cgi?id=380918
350 		        IClasspathEntry entry = JavaCore.newProjectEntry(
351 		        		new Path(ONE_FOUR_PROJECT_CLOSED_NAME).makeAbsolute(),
352 		        		new IAccessRule[0],
353 		        		false,
354 		        		new IClasspathAttribute[] {JavaCore.newClasspathAttribute(IClasspathAttribute.OPTIONAL, Boolean.TRUE.toString())},
355 		        		false);
356 		        JavaProjectHelper.addToClasspath(jp, entry);
357 
358 		        // create launch configurations
359 		        for (int i = 0; i < LAUNCH_CONFIG_NAMES_1_4.length; i++) {
360 		        	cfgs.add(createLaunchConfiguration(jp, LAUNCH_CONFIG_NAMES_1_4[i]));
361 				}
362 		        loaded14 = true;
363 		        waitForBuild();
364 	        }
365         }
366         catch(Exception e) {
367         	try {
368         		if(jp != null) {
369         			jp.getProject().delete(true,  true, null);
370         		}
371 	        	for (int i = 0; i < cfgs.size(); i++) {
372 					cfgs.get(i).delete();
373 				}
374         	}
375         	catch (CoreException ce) {
376         		//ignore
377 			}
378 			handleProjectCreationException(e, ONE_FOUR_PROJECT_NAME, jp);
379         }
380     }
381 
382 	/**
383 	 * Creates the Java 1.5 compliant project
384 	 */
assert15Project()385 	void assert15Project() {
386 		IJavaProject jp = null;
387 		ArrayList<ILaunchConfiguration> cfgs = new ArrayList<>(1);
388         try {
389 	        if (!loaded15) {
390 				jp = createProject(ONE_FIVE_PROJECT_NAME, JavaProjectHelper.TEST_1_5_SRC_DIR.toString(), JavaProjectHelper.JAVA_SE_1_7_EE_NAME, true);
391 				cfgs.add(createLaunchConfiguration(jp, "a.b.c.MethodBreakpoints"));
392 				cfgs.add(createLaunchConfiguration(jp, "a.b.c.IntegerAccess"));
393 				cfgs.add(createLaunchConfiguration(jp, "a.b.c.StepIntoSelectionWithGenerics"));
394 				cfgs.add(createLaunchConfiguration(jp, "a.b.c.ConditionalsNearGenerics"));
395 				cfgs.add(createLaunchConfiguration(jp, "a.b.c.bug329294WithGenerics"));
396 				cfgs.add(createLaunchConfiguration(jp, "a.b.c.bug403028"));
397 				cfgs.add(createLaunchConfiguration(jp, "a.b.c.bug484686"));
398 				cfgs.add(createLaunchConfiguration(jp, "a.b.c.GenericMethodEntryTest"));
399 				cfgs.add(createLaunchConfiguration(jp, "org.eclipse.debug.tests.targets.HcrClass", true));
400 				loaded15 = true;
401 				waitForBuild();
402 	        }
403         }
404         catch(Exception e) {
405         	try {
406         		if(jp != null) {
407 		        	jp.getProject().delete(true,  true, null);
408 		        	for (int i = 0; i < cfgs.size(); i++) {
409 						cfgs.get(i).delete();
410 					}
411         		}
412         	}
413         	catch (CoreException ce) {
414         		//ignore
415 			}
416 			handleProjectCreationException(e, ONE_FIVE_PROJECT_NAME, jp);
417         }
418 	}
419 
420 	/**
421 	 * Creates the Java 1.7 compliant project
422 	 */
assert17Project()423 	synchronized void assert17Project() {
424 		IJavaProject jp = null;
425 		ArrayList<ILaunchConfiguration> cfgs = new ArrayList<>(1);
426         try {
427 	        if (!loaded17) {
428 	        	jp = createProject(ONE_SEVEN_PROJECT_NAME, JavaProjectHelper.TEST_1_7_SRC_DIR.toString(), JavaProjectHelper.JAVA_SE_1_7_EE_NAME, false);
429 	    		cfgs.add(createLaunchConfiguration(jp, LiteralTests17.LITERAL_TYPE_NAME));
430 				cfgs.add(createLaunchConfiguration(jp, "ThreadNameChange"));
431 	    		loaded17 = true;
432 	    		waitForBuild();
433 	        }
434         }
435         catch(Exception e) {
436         	try {
437         		if(jp != null) {
438 		        	jp.getProject().delete(true,  true, null);
439 		        	for (int i = 0; i < cfgs.size(); i++) {
440 						cfgs.get(i).delete();
441 					}
442         		}
443         	}
444         	catch (CoreException ce) {
445         		//ignore
446 			}
447 			handleProjectCreationException(e, ONE_SEVEN_PROJECT_NAME, jp);
448         }
449 	}
450 
451 	/**
452 	 * Creates the Java 1.8 compliant project
453 	 */
assert18Project()454 	synchronized void assert18Project() {
455 		IJavaProject jp = null;
456 		ArrayList<ILaunchConfiguration> cfgs = new ArrayList<>(1);
457         try {
458 	        if (!loaded18) {
459 	        	jp = createProject(ONE_EIGHT_PROJECT_NAME, JavaProjectHelper.TEST_1_8_SRC_DIR.toString(), JavaProjectHelper.JAVA_SE_1_8_EE_NAME, false);
460 	    		cfgs.add(createLaunchConfiguration(jp, "EvalTest18"));
461 	    		cfgs.add(createLaunchConfiguration(jp, "FunctionalCaptureTest18"));
462 	    		cfgs.add(createLaunchConfiguration(jp, "EvalTestIntf18"));
463 				cfgs.add(createLaunchConfiguration(jp, "EvalIntfSuperDefault"));
464 				cfgs.add(createLaunchConfiguration(jp, "DebugHoverTest18"));
465 				cfgs.add(createLaunchConfiguration(jp, "DebugHoverTest2Lambdas"));
466 				cfgs.add(createLaunchConfiguration(jp, "Bug317045"));
467 				cfgs.add(createLaunchConfiguration(jp, "Bug549394"));
468 				cfgs.add(createLaunchConfiguration(jp, "Bug541110"));
469 				cfgs.add(createLaunchConfiguration(jp, "ClosureVariableTest_Bug542989"));
470 				cfgs.add(createLaunchConfiguration(jp, "Bug404097BreakpointInLocalClass"));
471 				cfgs.add(createLaunchConfiguration(jp, "Bug404097BreakpointInAnonymousLocalClass"));
472 				cfgs.add(createLaunchConfiguration(jp, "Bug404097BreakpointInLambda"));
473 				cfgs.add(createLaunchConfiguration(jp, "Bug404097BreakpointUsingInnerClass"));
474 				cfgs.add(createLaunchConfiguration(jp, "Bug404097BreakpointUsingLocalClass"));
475 				cfgs.add(createLaunchConfiguration(jp, "Bug560392"));
476 				cfgs.add(createLaunchConfiguration(jp, "Bug561715"));
477 				cfgs.add(createLaunchConfiguration(jp, "Bug562056"));
478 				cfgs.add(createLaunchConfiguration(jp, "RemoteEvaluator"));
479 	    		loaded18 = true;
480 	    		waitForBuild();
481 	        }
482         }
483         catch(Exception e) {
484         	try {
485         		if(jp != null) {
486 		        	jp.getProject().delete(true,  true, null);
487 		        	for (int i = 0; i < cfgs.size(); i++) {
488 						cfgs.get(i).delete();
489 					}
490         		}
491         	}
492         	catch (CoreException ce) {
493         		//ignore
494 			}
495 			handleProjectCreationException(e, ONE_EIGHT_PROJECT_NAME, jp);
496         }
497 	}
498 
499 	/**
500 	 * Creates the Java 9 compliant project
501 	 */
assert9Project()502 	synchronized void assert9Project() {
503 		IJavaProject jp = null;
504 		ArrayList<ILaunchConfiguration> cfgs = new ArrayList<>(1);
505 		try {
506 			if (!loaded9) {
507 				jp = createProject(NINE_PROJECT_NAME, JavaProjectHelper.TEST_9_SRC_DIR.toString(), JavaProjectHelper.JAVA_SE_9_EE_NAME, false);
508 				cfgs.add(createLaunchConfiguration(jp, "LogicalStructures"));
509 				loaded9 = true;
510 				waitForBuild();
511 			}
512 		} catch (Exception e) {
513 			try {
514 				if (jp != null) {
515 					jp.getProject().delete(true, true, null);
516 					for (int i = 0; i < cfgs.size(); i++) {
517 						cfgs.get(i).delete();
518 					}
519 				}
520 			} catch (CoreException ce) {
521 				// ignore
522 			}
523 			handleProjectCreationException(e, NINE_PROJECT_NAME, jp);
524 		}
525 	}
526 
527 	/**
528 	 * Creates the 'BoundJRE' project used for the JRE testing
529 	 */
assertBoundJreProject()530 	synchronized void assertBoundJreProject() {
531 		IJavaProject jp = null;
532 		try {
533 	        if (!loadedJRE) {
534 		        jp =JavaProjectHelper.createJavaProject(BOUND_JRE_PROJECT_NAME);
535 		        JavaProjectHelper.addSourceContainer(jp, JavaProjectHelper.SRC_DIR, JavaProjectHelper.BIN_DIR);
536 		        // add VM specific JRE container
537 		        IPath path = JavaRuntime.newJREContainerPath(JavaRuntime.getDefaultVMInstall());
538 		        JavaProjectHelper.addContainerEntry(jp, path);
539 		        loadedJRE = true;
540 		        waitForBuild();
541 	        }
542 		}
543 		catch(Exception e) {
544         	try {
545         		if(jp != null) {
546         			jp.getProject().delete(true,  true, null);
547         		}
548         	}
549         	catch (CoreException ce) {
550         		//ignore
551 			}
552 			handleProjectCreationException(e, BOUND_JRE_PROJECT_NAME, jp);
553         }
554 	}
555 
556 	/**
557 	 * Creates the 'BoundEE' project for EE testing
558 	 */
assertBoundeEeProject()559 	void assertBoundeEeProject() {
560 		IJavaProject jp = null;
561 		try {
562 	        if(!loadedEE) {
563 		        // create project with two src folders and output locations
564 		        jp = JavaProjectHelper.createJavaProject(BOUND_EE_PROJECT_NAME);
565 		        JavaProjectHelper.addSourceContainer(jp, JavaProjectHelper.SRC_DIR, JavaProjectHelper.BIN_DIR);
566 
567 		        // add VM specific JRE container
568 				IExecutionEnvironment j2se14 = JavaRuntime.getExecutionEnvironmentsManager().getEnvironment(JavaProjectHelper.JAVA_SE_1_7_EE_NAME);
569 		        assertNotNull("Missing J2SE-1.4 environment", j2se14);
570 		        IPath path = JavaRuntime.newJREContainerPath(j2se14);
571 		        JavaProjectHelper.addContainerEntry(jp, path);
572 		        loadedEE = true;
573 		        waitForBuild();
574 	        }
575 		}
576 		catch(Exception e) {
577         	try {
578         		if(jp != null) {
579         			jp.getProject().delete(true,  true, null);
580         		}
581         	}
582         	catch (CoreException ce) {
583         		//ignore
584 			}
585 			handleProjectCreationException(e, BOUND_EE_PROJECT_NAME, jp);
586         }
587 	}
588 
589 	/**
590 	 * Creates the 'MultiOutput' project for source / binary output testing
591 	 */
assertMultioutputProject()592 	synchronized void assertMultioutputProject() {
593 		IJavaProject jp = null;
594 		try {
595 	        if(!loadedMulti) {
596 		        // create project with two src folders and output locations
597 		        jp = JavaProjectHelper.createJavaProject(MULTI_OUTPUT_PROJECT_NAME);
598 		        JavaProjectHelper.addSourceContainer(jp, "src1", "bin1");
599 		        JavaProjectHelper.addSourceContainer(jp, "src2", "bin2");
600 
601 		        // add rt.jar
602 		        IVMInstall vm = JavaRuntime.getDefaultVMInstall();
603 		        assertNotNull("No default JRE", vm);
604 		        JavaProjectHelper.addContainerEntry(jp, new Path(JavaRuntime.JRE_CONTAINER));
605 		        loadedMulti = true;
606 		        waitForBuild();
607 	        }
608 		}
609 		catch(Exception e) {
610         	try {
611         		if(jp != null) {
612         			jp.getProject().delete(true,  true, null);
613         		}
614         	}
615         	catch (CoreException ce) {
616         		//ignore
617 			}
618 			handleProjectCreationException(e, MULTI_OUTPUT_PROJECT_NAME, jp);
619         }
620 	}
621 
622 	/**
623 	 * Ensure the welcome screen is closed because in 4.x the debug perspective opens a giant fast-view causing issues
624 	 *
625 	 * @throws Exception
626 	 * @since 3.8
627 	 */
assertWelcomeScreenClosed()628 	protected final void assertWelcomeScreenClosed() throws Exception {
629 		if(!welcomeClosed && PlatformUI.isWorkbenchRunning()) {
630 			final IWorkbench wb = PlatformUI.getWorkbench();
631 			if (wb == null) {
632 				return;
633 			}
634 			// In UI thread we don't need to run a job
635 			if (Display.getCurrent() != null) {
636 				closeIntro(wb);
637 				return;
638 			}
639 
640 			UIJob job = new UIJob("close welcome screen for debug test suite") {
641 				@Override
642 				public IStatus runInUIThread(IProgressMonitor monitor) {
643 					closeIntro(wb);
644 					return Status.OK_STATUS;
645 				}
646 
647 			};
648 			job.setPriority(Job.INTERACTIVE);
649 			job.setSystem(true);
650 			job.schedule();
651 		}
652 	}
653 
closeIntro(final IWorkbench wb)654 	private static void closeIntro(final IWorkbench wb) {
655 		IWorkbenchWindow window = wb.getActiveWorkbenchWindow();
656 		if (window != null) {
657 			IIntroManager im = wb.getIntroManager();
658 			IIntroPart intro = im.getIntro();
659 			if (intro != null) {
660 				welcomeClosed = im.closeIntro(intro);
661 			}
662 		}
663 	}
664 
handleProjectCreationException(Exception e, String pname, IJavaProject jp)665 	void handleProjectCreationException(Exception e, String pname, IJavaProject jp) {
666 		StringWriter buf = new StringWriter();
667 		String msg = e.getMessage();
668     	if(msg == null) {
669 			msg = "could not acquire message for exception class: " + e.getClass();
670     	}
671 		buf.write("Failed to create the '" + pname + "' test project.\n");
672 		buf.write("'jp' is " + (jp != null ? "not " : "") + " 'null'\n");
673 		buf.write("Stack tace:\n");
674 		e.printStackTrace(new PrintWriter(buf));
675 		fail(buf.toString());
676 	}
677 
678 	/**
679 	 * Sets the contents of the given {@link ICompilationUnit} to be the new contents provided
680 	 * @param unit
681 	 * @param contents the new {@link String} contents, cannot be <code>null</code>
682 	 * @throws JavaModelException
683 	 */
setFileContents(ICompilationUnit unit, String contents)684 	protected void setFileContents(ICompilationUnit unit, String contents) throws JavaModelException {
685 		assertNotNull("You cannot set the new contents of an ICompilationUnit to null", contents);
686 		IBuffer buffer = unit.getBuffer();
687 		buffer.setContents(contents);
688 		unit.save(null, true);
689 		waitForBuild();
690 	}
691 
692 	/**
693 	 * Sets the last relevant event set
694 	 *
695 	 * @param set event set
696 	 */
setEventSet(DebugEvent[] set)697 	protected void setEventSet(DebugEvent[] set) {
698 		fEventSet = set;
699 	}
700 
701 	/**
702 	 * Returns the last relevant event set
703 	 *
704 	 * @return event set
705 	 */
getEventSet()706 	protected DebugEvent[] getEventSet() {
707 		return fEventSet;
708 	}
709 
710 	/**
711 	 * Returns the launch manager
712 	 *
713 	 * @return launch manager
714 	 */
getLaunchManager()715 	protected ILaunchManager getLaunchManager() {
716 		return DebugPlugin.getDefault().getLaunchManager();
717 	}
718 
719 	/**
720 	 * Returns the singleton instance of the <code>LaunchConfigurationManager</code>
721 	 *
722 	 * @return the singleton instance of the <code>LaunchConfigurationManager</code>
723 	 * @since 3.3
724 	 */
getLaunchConfigurationManager()725 	protected LaunchConfigurationManager getLaunchConfigurationManager() {
726 		return DebugUIPlugin.getDefault().getLaunchConfigurationManager();
727 	}
728 
729 	/**
730 	 * Returns the breakpoint manager
731 	 *
732 	 * @return breakpoint manager
733 	 */
getBreakpointManager()734 	protected IBreakpointManager getBreakpointManager() {
735 		return DebugPlugin.getDefault().getBreakpointManager();
736 	}
737 
738 	/**
739 	 * Returns the project context for the current test - each
740 	 * test must implement this method
741 	 */
getProjectContext()742 	protected IJavaProject getProjectContext() {
743 		return get14Project();
744 	}
745 
746 	/**
747 	 * Returns the 'DebugTests' project.
748 	 *
749 	 * @return the test project
750 	 */
get14Project()751 	protected IJavaProject get14Project() {
752 		assert14Project();
753 		return getJavaProject(ONE_FOUR_PROJECT_NAME);
754 	}
755 
756 	/**
757 	 * Returns the {@link IBreakpointOrganizer} with the given id or <code>null</code>
758 	 * if no such organizer exists
759 	 * @param id
760 	 * @return the {@link IBreakpointOrganizer} or <code>null</code>
761 	 * @since 3.8.100
762 	 */
getOrganizer(String id)763 	protected IBreakpointOrganizer getOrganizer(String id) {
764 		return BreakpointOrganizerManager.getDefault().getOrganizer(id);
765 	}
766 
767 	/**
768 	 * Returns the 'OneFive' project.
769 	 *
770 	 * @return the test project
771 	 */
get15Project()772 	protected IJavaProject get15Project() {
773 		assert15Project();
774 		return getJavaProject(ONE_FIVE_PROJECT_NAME);
775 	}
776 
777 	/**
778 	 * Returns the 'OneSeven' project.
779 	 *
780 	 * @return the test project
781 	 */
get17Project()782 	protected IJavaProject get17Project() {
783 		assert17Project();
784 		return getJavaProject(ONE_SEVEN_PROJECT_NAME);
785 	}
786 
787 	/**
788 	 * Returns the 'OneEight' project.
789 	 *
790 	 * @return the test project
791 	 */
get18Project()792 	protected IJavaProject get18Project() {
793 		assert18Project();
794 		return getJavaProject(ONE_EIGHT_PROJECT_NAME);
795 	}
796 
797 	/**
798 	 * Returns the 'Nine' project, used for Java 9 tests.
799 	 *
800 	 * @return the test project
801 	 */
get9Project()802 	protected IJavaProject get9Project() {
803 		assert9Project();
804 		return getJavaProject(NINE_PROJECT_NAME);
805 	}
806 
807 	/**
808 	 * Returns the 'BoundJRE' project
809 	 *
810 	 * @return the test project
811 	 */
getBoundJreProject()812 	protected IJavaProject getBoundJreProject() {
813 		assertBoundJreProject();
814 		return getJavaProject(BOUND_JRE_PROJECT_NAME);
815 	}
816 
817 	/**
818 	 * Returns the 'BoundEE' project
819 	 *
820 	 * @return the test project
821 	 */
getBoundEeProject()822 	protected IJavaProject getBoundEeProject() {
823 		assertBoundeEeProject();
824 		return getJavaProject(BOUND_EE_PROJECT_NAME);
825 	}
826 
827 	/**
828 	 * Returns the 'MultiOutput' project
829 	 *
830 	 * @return the test project
831 	 */
getMultiOutputProject()832 	protected IJavaProject getMultiOutputProject() {
833 		assertMultioutputProject();
834 		return getJavaProject(MULTI_OUTPUT_PROJECT_NAME);
835 	}
836 
837 	/**
838 	 * Returns the Java project with the given name.
839 	 *
840 	 * @param name project name
841 	 * @return the Java project with the given name
842 	 */
getJavaProject(String name)843 	protected IJavaProject getJavaProject(String name) {
844 		IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject(name);
845 		return JavaCore.create(project);
846 	}
847 
848 	/**
849 	 * Creates a new {@link IJavaProject} with the given name and optionally initializing it from the given
850 	 * resource path from the testing bundle.
851 	 * <br><br>
852 	 * The project has the default <code>src</code> and <code>bin</code> folders. It is also created with a default
853 	 * <code>launchConfigurations</code> folder.
854 	 *
855 	 * @param name the name for the project
856 	 * @param contentpath the path within the jdt.debug test bundle to initialize the source from
857 	 * @param ee the level of execution environment to use
858 	 * @param if an existing project should be deleted
859 	 * @return the new Java project
860 	 * @throws Exception
861 	 */
createProject(String name, String contentpath, String ee, boolean delete)862 	protected IJavaProject createProject(String name, String contentpath, String ee, boolean delete) throws Exception {
863 		IProject pro = ResourcesPlugin.getWorkspace().getRoot().getProject(name);
864         if (pro.exists() && delete) {
865         	try {
866         		pro.delete(true, true, null);
867         	}
868         	catch(Exception e) {}
869         }
870         // create project and import source
871         IJavaProject jp = JavaProjectHelper.createJavaProject(name, JavaProjectHelper.BIN_DIR);
872         IPackageFragmentRoot src = JavaProjectHelper.addSourceContainer(jp, JavaProjectHelper.SRC_DIR);
873         File root = JavaTestPlugin.getDefault().getFileInPlugin(new Path(contentpath));
874         JavaProjectHelper.importFilesFromDirectory(root, src.getPath(), null);
875 
876         // add the EE library
877         IVMInstall vm = JavaRuntime.getDefaultVMInstall();
878         assertNotNull("No default JRE", vm);
879         IExecutionEnvironment environment = JavaRuntime.getExecutionEnvironmentsManager().getEnvironment(ee);
880         assertNotNull("The EE ["+ee+"] does not exist", environment);
881 		IPath containerPath = JavaRuntime.newJREContainerPath(environment);
882         JavaProjectHelper.addContainerEntry(jp, containerPath);
883         pro = jp.getProject();
884 
885         JavaProjectHelper.updateCompliance(jp, ee);
886 
887         // create launch configuration folder
888         IFolder folder = pro.getFolder("launchConfigurations");
889         if (!folder.exists()) {
890         	folder.create(true, true, null);
891         }
892         return jp;
893 	}
894 
895 	/**
896 	 * Creates a new {@link IJavaProject} with the given name and initializes the contents from the given
897 	 * resource path from the testing bundle.
898 	 * <br><br>
899 	 * The project has the default <code>src</code> and <code>bin</code> folders. It is also created with a default
900 	 * <code>launchConfigurations</code> folder.
901 	 *
902 	 * @param name the name for the project
903 	 * @param contentpath the path within the jdt.debug test bundle to initialize the source from
904 	 * @param ee the level of execution environment to use
905 	 * @param if an existing project should be deleted
906 	 * @return the new Java project
907 	 * @throws Exception
908 	 */
createJavaProjectClone(String name, String contentpath, String ee, boolean delete)909 	protected IJavaProject createJavaProjectClone(String name, String contentpath, String ee, boolean delete) throws Exception {
910 		IProject pro = ResourcesPlugin.getWorkspace().getRoot().getProject(name);
911 		String owner = "Creating project: " + name;
912         if (pro.exists() && delete) {
913 			pro.delete(true, true, null);
914 			TestUtil.waitForJobs(owner, 100, 10000);
915 			TestUtil.runEventLoop();
916         }
917         // create project and import source
918         IJavaProject jp = JavaProjectHelper.createJavaProject(name, JavaProjectHelper.BIN_DIR);
919 		TestUtil.waitForJobs(owner, 100, 10000);
920 		TestUtil.runEventLoop();
921 
922         JavaProjectHelper.addSourceContainer(jp, JavaProjectHelper.SRC_DIR);
923 		TestUtil.waitForJobs(owner, 100, 10000);
924 		TestUtil.runEventLoop();
925 
926         File root = JavaTestPlugin.getDefault().getFileInPlugin(new Path(contentpath));
927         JavaProjectHelper.importFilesFromDirectory(root, jp.getPath(), null);
928 
929 		TestUtil.waitForJobs(owner, 100, 10000);
930 		TestUtil.runEventLoop();
931 
932         // add the EE library
933         IVMInstall vm = JavaRuntime.getDefaultVMInstall();
934         assertNotNull("No default JRE", vm);
935         IExecutionEnvironment environment = JavaRuntime.getExecutionEnvironmentsManager().getEnvironment(ee);
936         assertNotNull("The EE ["+ee+"] does not exist", environment);
937 		IPath containerPath = JavaRuntime.newJREContainerPath(environment);
938         JavaProjectHelper.addContainerEntry(jp, containerPath);
939         pro = jp.getProject();
940 
941         // create launch configuration folder
942         IFolder folder = pro.getFolder("launchConfigurations");
943         if (!folder.exists()) {
944         	folder.create(true, true, null);
945         }
946 		TestUtil.waitForJobs(owner, 100, 10000);
947 		TestUtil.runEventLoop();
948         return jp;
949 	}
950 
951 	/**
952 	 * Creates a new {@link IProject} with the given name and initializes the contents from the given
953 	 * resource path from the testing bundle.
954 	 *
955 	 * @param name the name for the project
956 	 * @param contentpath the path within the jdt.debug test bundle to initialize the source from
957 	 * @param if an existing project should be deleted
958 	 * @return the new project
959 	 * @throws Exception
960 	 */
createProjectClone(String name, String contentpath, boolean delete)961 	protected IProject createProjectClone(String name, String contentpath, boolean delete) throws Exception {
962 		IProject pro = ResourcesPlugin.getWorkspace().getRoot().getProject(name);
963 		String owner = "Creating project: " + name;
964         if (pro.exists() && delete) {
965 			pro.delete(true, true, null);
966 			TestUtil.waitForJobs(owner, 100, 10000);
967 			TestUtil.runEventLoop();
968         }
969         // create project and import source
970         IProject pj = JavaProjectHelper.createProject(name);
971 		TestUtil.waitForJobs(owner, 100, 10000);
972 		TestUtil.runEventLoop();
973 
974         File root = JavaTestPlugin.getDefault().getFileInPlugin(new Path(contentpath));
975         JavaProjectHelper.importFilesFromDirectory(root, pj.getFullPath(), null);
976 		TestUtil.waitForJobs(owner, 100, 10000);
977 		TestUtil.runEventLoop();
978         return pj;
979 	}
980 
981 	/**
982 	 * Returns the launch shortcut with the given id
983 	 * @param id
984 	 * @return the <code>LaunchShortcutExtension</code> with the given id,
985 	 * or <code>null</code> if none
986 	 *
987 	 * @since 3.3
988 	 */
getLaunchShortcutExtension(String id)989 	protected LaunchShortcutExtension getLaunchShortcutExtension(String id) {
990 		List<?> exts = getLaunchConfigurationManager().getLaunchShortcuts();
991 		LaunchShortcutExtension ext = null;
992 		for (int i = 0; i < exts.size(); i++) {
993 			ext = (LaunchShortcutExtension) exts.get(i);
994 			if(ext.getId().equals(id)) {
995 				return ext;
996 			}
997 		}
998 		return null;
999 	}
1000 
1001 	/**
1002 	 * New to 3.3 is the ability to have multiple delegates for a variety of overlapping mode combinations.
1003 	 * As such, for tests that launch specific configurations, must be check to ensure that there is a preferred
1004 	 * launch delegate available for the launch in the event there are duplicates. Otherwise the tests
1005 	 * will hang waiting for a user to select a resolution action.
1006 	 * @param configuration
1007 	 * @param modes
1008 	 * @throws CoreException
1009 	 *
1010 	 * @since 3.3
1011 	 */
ensurePreferredDelegate(ILaunchConfiguration configuration, Set<String> modes)1012 	protected void ensurePreferredDelegate(ILaunchConfiguration configuration, Set<String> modes) throws CoreException {
1013 		ILaunchConfigurationType type = configuration.getType();
1014 		ILaunchDelegate[] delegates = type.getDelegates(modes);
1015 		if(delegates.length > 1) {
1016 			type.setPreferredDelegate(modes, getDelegateById(type.getIdentifier(), LOCAL_JAVA_APPLICATION_TYPE_ID));
1017 		}
1018 	}
1019 
1020 	/**
1021 	 * Returns the LaunchDelegate for the specified ID
1022 	 * @param delegateId the id of the delegate to search for
1023 	 * @return the <code>LaunchDelegate</code> associated with the specified id or <code>null</code> if not found
1024 	 * @since 3.3
1025 	 */
getDelegateById(String typeId, String delegateId)1026 	protected ILaunchDelegate getDelegateById(String typeId, String delegateId) {
1027 		LaunchManager lm = (LaunchManager) getLaunchManager();
1028 		LaunchDelegate[] delegates = lm.getLaunchDelegates(typeId);
1029 		for(int i = 0; i < delegates.length; i++) {
1030 			if(delegates[i].getId().equals(delegateId)) {
1031 				return delegates[i];
1032 			}
1033 		}
1034 		return null;
1035 	}
1036 
1037 	/**
1038 	 * Returns the source folder with the given name in the given project.
1039 	 *
1040 	 * @param project
1041 	 * @param name source folder name
1042 	 * @return package fragment root
1043 	 */
getPackageFragmentRoot(IJavaProject project, String name)1044 	protected IPackageFragmentRoot getPackageFragmentRoot(IJavaProject project, String name) {
1045 		IProject p = project.getProject();
1046 		return project.getPackageFragmentRoot(p.getFolder(name));
1047 	}
1048 
1049 	/**
1050 	 * Returns the <code>IHyperLink</code> at the given offset in the specified document
1051 	 * or <code>null</code> if the offset does not point to an <code>IHyperLink</code>
1052 	 * @param offset
1053 	 * @param doc
1054 	 * @return the <code>IHyperLink</code> at the given offset or <code>null</code>
1055 	 */
getHyperlink(int offset, IDocument doc)1056 	protected IHyperlink getHyperlink(int offset, IDocument doc) {
1057 		if (offset >= 0 && doc != null) {
1058 			Position[] positions = null;
1059 			try {
1060 				positions = doc.getPositions(ConsoleHyperlinkPosition.HYPER_LINK_CATEGORY);
1061 			} catch (BadPositionCategoryException ex) {
1062 				// no links have been added
1063 				return null;
1064 			}
1065 			for (int i = 0; i < positions.length; i++) {
1066 				Position position = positions[i];
1067 				if (offset >= position.getOffset() && offset <= (position.getOffset() + position.getLength())) {
1068 					return ((ConsoleHyperlinkPosition)position).getHyperLink();
1069 				}
1070 			}
1071 		}
1072 		return null;
1073 	}
1074 
1075 	/**
1076 	 * Launches the given configuration and waits for an event. Returns the
1077 	 * source of the event. If the event is not received, the launch is
1078 	 * terminated and an exception is thrown.
1079 	 *
1080 	 * @param configuration the configuration to launch
1081 	 * @param waiter the event waiter to use
1082 	 * @return Object the source of the event
1083 	 * @exception Exception if the event is never received.
1084 	 */
launchAndWait(ILaunchConfiguration configuration, DebugEventWaiter waiter)1085 	protected Object launchAndWait(ILaunchConfiguration configuration, DebugEventWaiter waiter) throws CoreException {
1086 	    return launchAndWait(configuration, waiter, true);
1087 	}
1088 
1089 	/**
1090 	 * Launches the given configuration in debug mode and waits for an event.
1091 	 * Returns the source of the event. If the event is not received, the
1092 	 * launch is terminated and an exception is thrown.
1093 	 *
1094 	 * @param configuration the configuration to launch
1095 	 * @param waiter the event waiter to use
1096 	 * @param register whether to register the launch
1097 	 * @return Object the source of the event
1098 	 * @exception Exception if the event is never received.
1099 	 */
launchAndWait(ILaunchConfiguration configuration, DebugEventWaiter waiter, boolean register)1100 	protected Object launchAndWait(ILaunchConfiguration configuration, DebugEventWaiter waiter, boolean register) throws CoreException {
1101 		return launchAndWait(configuration, ILaunchManager.DEBUG_MODE, waiter, register);
1102 	}
1103 
1104 	/**
1105 	 * Launches the given configuration and waits for an event. Returns the
1106 	 * source of the event. If the event is not received, the launch is
1107 	 * terminated and an exception is thrown.
1108 	 *
1109 	 * @param configuration the configuration to launch
1110 	 * @param mode the mode to launch the configuration in
1111 	 * @param waiter the event waiter to use
1112 	 * @param register whether to register the launch
1113 	 * @return Object the source of the event
1114 	 * @exception Exception if the event is never received.
1115 	 */
launchAndWait(ILaunchConfiguration configuration, String mode, DebugEventWaiter waiter, boolean register)1116 	protected Object launchAndWait(ILaunchConfiguration configuration, String mode, DebugEventWaiter waiter, boolean register) throws CoreException {
1117 		ILaunch launch = configuration.launch(mode, null, false, register);
1118 		Object suspendee= waiter.waitForEvent();
1119 		if (suspendee == null) {
1120 			StringBuilder buf = new StringBuilder();
1121             buf.append("Test case: "); //$NON-NLS-1$
1122             buf.append(getName());
1123             buf.append("\n"); //$NON-NLS-1$
1124             buf.append("Never received event: "); //$NON-NLS-1$
1125             buf.append(waiter.getEventKindName());
1126             buf.append("\n"); //$NON-NLS-1$
1127             if (launch.isTerminated()) {
1128             	buf.append("Process exit value: "); //$NON-NLS-1$
1129             	buf.append(launch.getProcesses()[0].getExitValue());
1130                 buf.append("\n"); //$NON-NLS-1$
1131             }
1132             IConsole console = DebugUITools.getConsole(launch.getProcesses()[0]);
1133             if (console instanceof TextConsole) {
1134                 TextConsole textConsole = (TextConsole)console;
1135                 String string = textConsole.getDocument().get();
1136                 buf.append("Console output follows:\n"); //$NON-NLS-1$
1137                 buf.append(string);
1138             }
1139             buf.append("\n"); //$NON-NLS-1$
1140             DebugPlugin.log(new Status(IStatus.ERROR, "org.eclipse.jdt.debug.ui.tests", buf.toString())); //$NON-NLS-1$
1141 			try {
1142 				launch.terminate();
1143 			} catch (CoreException e) {
1144 				e.printStackTrace();
1145 				fail("Program did not suspend, and unable to terminate launch."); //$NON-NLS-1$
1146 			}
1147 			throw new TestAgainException("Program did not suspend, launch terminated.");
1148 		}
1149 		setEventSet(waiter.getEventSet());
1150 		assertNotNull("Program did not suspend, launch terminated.", suspendee); //$NON-NLS-1$
1151 		return suspendee;
1152 	}
1153 
1154 
1155 
1156 	/**
1157 	 * Launches the type with the given name, and waits for a
1158 	 * suspend event in that program. Returns the thread in which the suspend
1159 	 * event occurred.
1160 	 *
1161 	 * @param mainTypeName the program to launch
1162 	 * @return thread in which the first suspend event occurred
1163 	 */
launchAndSuspend(String mainTypeName)1164 	protected IJavaThread launchAndSuspend(String mainTypeName) throws Exception {
1165 		ILaunchConfiguration config = getLaunchConfiguration(mainTypeName);
1166 		assertNotNull("Could not locate launch configuration for " + mainTypeName, config); //$NON-NLS-1$
1167 		return launchAndSuspend(config);
1168 	}
1169 
1170 	/**
1171 	 * Launches the given configuration in debug mode, and waits for a
1172 	 * suspend event in that program. Returns the thread in which the suspend
1173 	 * event occurred.
1174 	 *
1175 	 * @param config the configuration to launch
1176 	 * @return thread in which the first suspend event occurred
1177 	 */
launchAndSuspend(ILaunchConfiguration config)1178 	protected IJavaThread launchAndSuspend(ILaunchConfiguration config) throws Exception {
1179 		DebugEventWaiter waiter= new DebugElementKindEventWaiter(DebugEvent.SUSPEND, IJavaThread.class);
1180 		waiter.setTimeout(DEFAULT_TIMEOUT);
1181 		waiter.setEnableUIEventLoopProcessing(enableUIEventLoopProcessingInWaiter());
1182 		Object suspendee = launchAndWait(config, waiter);
1183 		return (IJavaThread)suspendee;
1184 	}
1185 
1186 	/**
1187 	 * Launches the type with the given name, and waits for a breakpoint-caused
1188 	 * suspend event in that program. Returns the thread in which the suspend
1189 	 * event occurred.
1190 	 *
1191 	 * @param mainTypeName the program to launch
1192 	 * @return thread in which the first suspend event occurred
1193 	 */
launchToBreakpoint(String mainTypeName)1194 	protected IJavaThread launchToBreakpoint(String mainTypeName) throws Exception {
1195 		return launchToBreakpoint(getProjectContext(), mainTypeName);
1196 	}
1197 
1198 	/**
1199 	 * Launches the type with the given name, and waits for a breakpoint-caused
1200 	 * suspend event in that program. Returns the thread in which the suspend
1201 	 * event occurred.
1202 	 *
1203 	 * @param project the project the type is in
1204 	 * @param mainTypeName the program to launch
1205 	 * @return thread in which the first suspend event occurred
1206 	 */
launchToBreakpoint(IJavaProject project, String mainTypeName)1207 	protected IJavaThread launchToBreakpoint(IJavaProject project, String mainTypeName) throws Exception {
1208 		return launchToBreakpoint(project, mainTypeName, true);
1209 	}
1210 
1211 	/**
1212 	 * Launches the type with the given name, and waits for a breakpoint-caused
1213 	 * suspend event in that program. Returns the thread in which the suspend
1214 	 * event occurred.
1215 	 *
1216 	 * @param mainTypeName the program to launch
1217 	 * @param register whether to register the launch
1218 	 * @return thread in which the first suspend event occurred
1219 	 */
launchToBreakpoint(String mainTypeName, boolean register)1220 	protected IJavaThread launchToBreakpoint(String mainTypeName, boolean register) throws Exception {
1221 		return launchToBreakpoint(getProjectContext(), mainTypeName, register);
1222 	}
1223 
1224 	/**
1225 	 * Launches the type with the given name, and waits for a breakpoint-caused
1226 	 * suspend event in that program. Returns the thread in which the suspend
1227 	 * event occurred.
1228 	 *
1229 	 * @param mainTypeName the program to launch
1230 	 * @param register whether to register the launch
1231 	 * @return thread in which the first suspend event occurred
1232 	 */
launchToBreakpoint(IJavaProject project, String mainTypeName, boolean register)1233 	protected IJavaThread launchToBreakpoint(IJavaProject project, String mainTypeName, boolean register) throws Exception {
1234 		ILaunchConfiguration config = getLaunchConfiguration(project, mainTypeName);
1235 		assertNotNull("Could not locate launch configuration for " + mainTypeName, config); //$NON-NLS-1$
1236 		return launchToBreakpoint(config, register);
1237 	}
1238 
1239 	/**
1240 	 * Launches the type with the given name, and waits for a breakpoint-caused
1241 	 * suspend event in that program. Returns the thread in which the suspend
1242 	 * event occurred.
1243 	 *
1244 	 * @param mainTypeName the program to launch
1245 	 * @param register whether to register the launch
1246 	 * @return thread in which the first suspend event occurred
1247 	 */
launchToBreakpoint(IJavaProject project, String mainTypeName, String launchName, boolean register)1248 	protected IJavaThread launchToBreakpoint(IJavaProject project, String mainTypeName, String launchName, boolean register) throws Exception {
1249 		ILaunchConfiguration config = getLaunchConfiguration(project, launchName);
1250 		assertNotNull("Could not locate launch configuration for " + mainTypeName, config); //$NON-NLS-1$
1251 		return launchToBreakpoint(config, register);
1252 	}
1253 
1254 	/**
1255 	 * Launches the given configuration in debug mode, and waits for a breakpoint-caused
1256 	 * suspend event in that program. Returns the thread in which the suspend
1257 	 * event occurred.
1258 	 *
1259 	 * @param config the configuration to launch
1260 	 * @return thread in which the first suspend event occurred
1261 	 */
launchToBreakpoint(ILaunchConfiguration config)1262 	protected IJavaThread launchToBreakpoint(ILaunchConfiguration config) throws CoreException {
1263 	    return launchToBreakpoint(config, true);
1264 	}
1265 
1266 	/**
1267 	 * Launches the given configuration in debug mode, and waits for a breakpoint-caused
1268 	 * suspend event in that program. Returns the thread in which the suspend
1269 	 * event occurred.
1270 	 *
1271 	 * @param config the configuration to launch
1272 	 * @param whether to register the launch
1273 	 * @return thread in which the first suspend event occurred
1274 	 */
launchToBreakpoint(ILaunchConfiguration config, boolean register)1275 	protected IJavaThread launchToBreakpoint(ILaunchConfiguration config, boolean register) throws CoreException {
1276 		DebugEventWaiter waiter= new DebugElementKindEventDetailWaiter(DebugEvent.SUSPEND, IJavaThread.class, DebugEvent.BREAKPOINT);
1277 		waiter.setTimeout(DEFAULT_TIMEOUT);
1278 		waiter.setEnableUIEventLoopProcessing(enableUIEventLoopProcessingInWaiter());
1279 
1280 		Object suspendee= launchAndWait(config, waiter, register);
1281 		assertTrue("suspendee was not an IJavaThread", suspendee instanceof IJavaThread); //$NON-NLS-1$
1282 		return (IJavaThread)suspendee;
1283 	}
1284 
1285 	/**
1286 	 * Launches the type with the given name, and waits for a terminate
1287 	 * event in that program. Returns the debug target in which the suspend
1288 	 * event occurred.
1289 	 *
1290 	 * @param mainTypeName the program to launch
1291 	 * @param timeout the number of milliseconds to wait for a terminate event
1292 	 * @return debug target in which the terminate event occurred
1293 	 */
launchAndTerminate(String mainTypeName)1294 	protected IJavaDebugTarget launchAndTerminate(String mainTypeName) throws Exception {
1295 		ILaunchConfiguration config = getLaunchConfiguration(mainTypeName);
1296 		assertNotNull("Could not locate launch configuration for " + mainTypeName, config); //$NON-NLS-1$
1297 		return launchAndTerminate(config, DEFAULT_TIMEOUT);
1298 	}
1299 
1300 	/**
1301 	 * Launches the given configuration in debug mode, and waits for a terminate
1302 	 * event in that program. Returns the debug target in which the terminate
1303 	 * event occurred.
1304 	 *
1305 	 * @param config the configuration to launch
1306 	 * @param timeout the number of milliseconds to wait for a terminate event
1307 	 * @return thread in which the first suspend event occurred
1308 	 */
launchAndTerminate(ILaunchConfiguration config, int timeout)1309 	protected IJavaDebugTarget launchAndTerminate(ILaunchConfiguration config, int timeout) throws Exception {
1310 		return launchAndTerminate(config, timeout, true);
1311 	}
1312 
1313 	/**
1314 	 * Launches the given configuration in debug mode, and waits for a terminate
1315 	 * event in that program. Returns the debug target in which the terminate
1316 	 * event occurred.
1317 	 *
1318 	 * @param config the configuration to launch
1319 	 * @param timeout the number of milliseconds to wait for a terminate event
1320 	 * @param register whether to register the launch
1321 	 * @return thread in which the first suspend event occurred
1322 	 */
launchAndTerminate(ILaunchConfiguration config, int timeout, boolean register)1323 	protected IJavaDebugTarget launchAndTerminate(ILaunchConfiguration config, int timeout, boolean register) throws Exception {
1324 		DebugEventWaiter waiter= new DebugElementKindEventWaiter(DebugEvent.TERMINATE, IJavaDebugTarget.class);
1325 		waiter.setTimeout(timeout);
1326 		waiter.setEnableUIEventLoopProcessing(enableUIEventLoopProcessingInWaiter());
1327 
1328 		Object terminatee = launchAndWait(config, waiter, register);
1329 		assertNotNull("Program did not terminate.", terminatee); //$NON-NLS-1$
1330 		assertTrue("terminatee is not an IJavaDebugTarget", terminatee instanceof IJavaDebugTarget); //$NON-NLS-1$
1331 		IJavaDebugTarget debugTarget = (IJavaDebugTarget) terminatee;
1332 		assertTrue("debug target is not terminated", debugTarget.isTerminated() || debugTarget.isDisconnected()); //$NON-NLS-1$
1333 		return debugTarget;
1334 	}
1335 
1336 	/**
1337 	 * Launches the type with the given name, and waits for a line breakpoint suspend
1338 	 * event in that program. Returns the thread in which the suspend
1339 	 * event occurred.
1340 	 *
1341 	 * @param mainTypeName the program to launch
1342 	 * @param bp the breakpoint that should cause a suspend event
1343 	 * @return thread in which the first suspend event occurred
1344 	 */
launchToLineBreakpoint(String mainTypeName, ILineBreakpoint bp)1345 	protected IJavaThread launchToLineBreakpoint(String mainTypeName, ILineBreakpoint bp) throws Exception {
1346 		return launchToLineBreakpoint(mainTypeName, bp, true);
1347 	}
1348 
1349 	/**
1350 	 * Launches the type with the given name, and waits for a line breakpoint suspend
1351 	 * event in that program. Returns the thread in which the suspend
1352 	 * event occurred.
1353 	 *
1354 	 * @param mainTypeName the program to launch
1355 	 * @param bp the breakpoint that should cause a suspend event
1356 	 * @param register whether to register the launch
1357 	 * @return thread in which the first suspend event occurred
1358 	 */
launchToLineBreakpoint(String mainTypeName, ILineBreakpoint bp, boolean register)1359 	protected IJavaThread launchToLineBreakpoint(String mainTypeName, ILineBreakpoint bp, boolean register) throws Exception {
1360 		ILaunchConfiguration config = getLaunchConfiguration(mainTypeName);
1361 		assertNotNull("Could not locate launch configuration for " + mainTypeName, config); //$NON-NLS-1$
1362 		return launchToLineBreakpoint(config, bp, register);
1363 	}
1364 
1365 	/**
1366 	 * Launches the given configuration in debug mode, and waits for a line breakpoint
1367 	 * suspend event in that program. Returns the thread in which the suspend
1368 	 * event occurred.
1369 	 *
1370 	 * @param config the configuration to launch
1371 	 * @param bp the breakpoint that should cause a suspend event
1372 	 * @return thread in which the first suspend event occurred
1373 	 */
launchToLineBreakpoint(ILaunchConfiguration config, ILineBreakpoint bp, boolean register)1374 	protected IJavaThread launchToLineBreakpoint(ILaunchConfiguration config, ILineBreakpoint bp, boolean register) throws Exception {
1375 		DebugEventWaiter waiter= new DebugElementKindEventDetailWaiter(DebugEvent.SUSPEND, IJavaThread.class, DebugEvent.BREAKPOINT);
1376 		waiter.setTimeout(DEFAULT_TIMEOUT);
1377 		waiter.setEnableUIEventLoopProcessing(enableUIEventLoopProcessingInWaiter());
1378 
1379 		Object suspendee= launchAndWait(config, waiter, register);
1380 		assertTrue("suspendee was not an IJavaThread", suspendee instanceof IJavaThread); //$NON-NLS-1$
1381 		IJavaThread thread = (IJavaThread) suspendee;
1382 		IBreakpoint hit = getBreakpoint(thread);
1383 		assertNotNull("suspended, but not by breakpoint", hit); //$NON-NLS-1$
1384 		assertTrue("hit un-registered breakpoint", bp.equals(hit)); //$NON-NLS-1$
1385 		assertTrue("suspended, but not by line breakpoint", hit instanceof ILineBreakpoint); //$NON-NLS-1$
1386 		ILineBreakpoint breakpoint= (ILineBreakpoint) hit;
1387 		int lineNumber = breakpoint.getLineNumber();
1388 		int stackLine = thread.getTopStackFrame().getLineNumber();
1389 		assertTrue("line numbers of breakpoint and stack frame do not match", lineNumber == stackLine); //$NON-NLS-1$
1390 
1391 		return thread;
1392 	}
1393 
1394 	/**
1395 	 * Returns the standard java launch tab group
1396 	 * @return the standard java launch tab group
1397 	 * @throws CoreException
1398 	 *
1399 	 * @since 3.3
1400 	 */
getJavaLaunchGroup()1401 	protected ILaunchConfigurationTabGroup getJavaLaunchGroup() throws CoreException {
1402 		ILaunchConfigurationType javaType = getLaunchManager().getLaunchConfigurationType(IJavaLaunchConfigurationConstants.ID_JAVA_APPLICATION);
1403 		ILaunchConfigurationTabGroup standardGroup = LaunchConfigurationPresentationManager.getDefault().getTabGroup(javaType, ILaunchManager.DEBUG_MODE);
1404 		return standardGroup;
1405 	}
1406 
1407 	/**
1408 	 * Returns an instance of the launch configuration dialog on the the specified launch mode
1409 	 * @param modeid the id of the mode to open the launch dialog on
1410 	 * @return an new instance of <code>IlaunchConfigurationDialog</code>
1411 	 *
1412 	 * @since 3.3
1413 	 */
getLaunchConfigurationDialog(String modeid)1414 	protected ILaunchConfigurationDialog getLaunchConfigurationDialog(String modeid) {
1415 		return new LaunchConfigurationsDialog(null, DebugUIPlugin.getDefault().getLaunchConfigurationManager().getLaunchGroup(modeid));
1416 	}
1417 
1418 	/**
1419 	 * Resumes the given thread, and waits for another breakpoint-caused suspend event.
1420 	 * Returns the thread in which the suspend event occurs.
1421 	 *
1422 	 * @param thread thread to resume
1423 	 * @return thread in which the first suspend event occurs
1424 	 */
resume(IJavaThread thread)1425 	protected IJavaThread resume(IJavaThread thread) throws Exception {
1426 	    return resume(thread, DEFAULT_TIMEOUT);
1427 	}
1428 
1429 	/**
1430 	 * Resumes the given thread, and waits for another breakpoint-caused suspend event.
1431 	 * Returns the thread in which the suspend event occurs.
1432 	 *
1433 	 * @param thread thread to resume
1434 	 * @param timeout timeout in milliseconds
1435 	 * @return thread in which the first suspend event occurs
1436 	 */
resume(IJavaThread thread, int timeout)1437 	protected IJavaThread resume(IJavaThread thread, int timeout) throws Exception {
1438 		DebugEventWaiter waiter= new DebugElementKindEventDetailWaiter(DebugEvent.SUSPEND, IJavaThread.class, DebugEvent.BREAKPOINT);
1439 		waiter.setTimeout(timeout);
1440 		waiter.setEnableUIEventLoopProcessing(enableUIEventLoopProcessingInWaiter());
1441 
1442 		thread.resume();
1443 
1444 		Object suspendee= waiter.waitForEvent();
1445 		setEventSet(waiter.getEventSet());
1446 		assertNotNull("Program did not suspend.", suspendee); //$NON-NLS-1$
1447 		return (IJavaThread)suspendee;
1448 	}
1449 
1450 	/**
1451 	 * Resumes the given thread, and waits for a suspend event caused by the specified
1452 	 * line breakpoint.  Returns the thread in which the suspend event occurs.
1453 	 *
1454 	 * @param thread thread to resume
1455 	 * @return thread in which the first suspend event occurs
1456 	 */
resumeToLineBreakpoint(IJavaThread resumeThread, ILineBreakpoint bp)1457 	protected IJavaThread resumeToLineBreakpoint(IJavaThread resumeThread, ILineBreakpoint bp) throws Exception {
1458 		DebugEventWaiter waiter= new DebugElementKindEventDetailWaiter(DebugEvent.SUSPEND, IJavaThread.class, DebugEvent.BREAKPOINT);
1459 		waiter.setTimeout(DEFAULT_TIMEOUT);
1460 		waiter.setEnableUIEventLoopProcessing(enableUIEventLoopProcessingInWaiter());
1461 
1462 		resumeThread.resume();
1463 
1464 		Object suspendee= waiter.waitForEvent();
1465 		setEventSet(waiter.getEventSet());
1466 		assertNotNull("Program did not suspend.", suspendee); //$NON-NLS-1$
1467 		assertTrue("suspendee was not an IJavaThread", suspendee instanceof IJavaThread); //$NON-NLS-1$
1468 		IJavaThread thread = (IJavaThread) suspendee;
1469 		IBreakpoint hit = getBreakpoint(thread);
1470 		assertNotNull("suspended, but not by breakpoint", hit); //$NON-NLS-1$
1471 		assertTrue("hit un-registered breakpoint", bp.equals(hit)); //$NON-NLS-1$
1472 		assertTrue("suspended, but not by line breakpoint", hit instanceof ILineBreakpoint); //$NON-NLS-1$
1473 		ILineBreakpoint breakpoint= (ILineBreakpoint) hit;
1474 		int lineNumber = breakpoint.getLineNumber();
1475 		int stackLine = thread.getTopStackFrame().getLineNumber();
1476 		assertTrue("line numbers of breakpoint and stack frame do not match", lineNumber == stackLine); //$NON-NLS-1$
1477 
1478 		return (IJavaThread)suspendee;
1479 	}
1480 
1481 	/**
1482 	 * Resumes the given thread, and waits for the debug target
1483 	 * to terminate (i.e. finish/exit the program).
1484 	 *
1485 	 * @param thread thread to resume
1486 	 */
exit(IJavaThread thread)1487 	protected void exit(IJavaThread thread) throws Exception {
1488 		DebugEventWaiter waiter= new DebugElementKindEventWaiter(DebugEvent.TERMINATE, IProcess.class);
1489 		waiter.setTimeout(DEFAULT_TIMEOUT);
1490 		waiter.setEnableUIEventLoopProcessing(enableUIEventLoopProcessingInWaiter());
1491 
1492 		thread.resume();
1493 
1494 		Object suspendee= waiter.waitForEvent();
1495 		setEventSet(waiter.getEventSet());
1496 		assertNotNull("Program did not terminate.", suspendee); //$NON-NLS-1$
1497 	}
1498 
1499 	/**
1500 	 * Resumes the given thread, and waits the associated debug
1501 	 * target to terminate.
1502 	 *
1503 	 * @param thread thread to resume
1504 	 * @return the terminated debug target
1505 	 */
resumeAndExit(IJavaThread thread)1506 	protected IJavaDebugTarget resumeAndExit(IJavaThread thread) throws Exception {
1507 		DebugEventWaiter waiter= new DebugElementEventWaiter(DebugEvent.TERMINATE, thread.getDebugTarget());
1508 		waiter.setTimeout(DEFAULT_TIMEOUT);
1509 		waiter.setEnableUIEventLoopProcessing(enableUIEventLoopProcessingInWaiter());
1510 
1511 		thread.resume();
1512 
1513 		Object suspendee= waiter.waitForEvent();
1514 		setEventSet(waiter.getEventSet());
1515 		assertNotNull("Program did not terminate.", suspendee); //$NON-NLS-1$
1516 		IJavaDebugTarget target = (IJavaDebugTarget)suspendee;
1517 		assertTrue("program should have exited", target.isTerminated() || target.isDisconnected()); //$NON-NLS-1$
1518 		return target;
1519 	}
1520 
1521 	/**
1522 	 * Returns the launch configuration for the given main type
1523 	 *
1524 	 * @param mainTypeName program to launch
1525 	 * @see ProjectCreationDecorator
1526 	 */
getLaunchConfiguration(String mainTypeName)1527 	protected ILaunchConfiguration getLaunchConfiguration(String mainTypeName) {
1528 		return getLaunchConfiguration(getProjectContext(), mainTypeName);
1529 	}
1530 
1531 	/**
1532 	 * Returns the launch configuration for the given main type
1533 	 *
1534 	 * @param mainTypeName program to launch
1535 	 * @see ProjectCreationDecorator
1536 	 */
getLaunchConfiguration(IJavaProject project, String mainTypeName)1537 	protected ILaunchConfiguration getLaunchConfiguration(IJavaProject project, String mainTypeName) {
1538 		IFile file = project.getProject().getFolder(LAUNCHCONFIGURATIONS).getFile(mainTypeName + LAUNCH_EXTENSION);
1539 		ILaunchConfiguration config = getLaunchManager().getLaunchConfiguration(file);
1540 		assertNotNull("the configuration cannot be null", config);
1541 		assertTrue("Could not find launch configuration for " + mainTypeName, config.exists()); //$NON-NLS-1$
1542 		return config;
1543 	}
1544 
1545 	/**
1546 	 * Returns the launch configuration in the specified folder in the given project, for the given main type
1547 	 *
1548 	 * @param project the project to look in
1549 	 * @param containername the name of the container in the specified project to look for the config
1550 	 * @param mainTypeName program to launch
1551 	 * @see ProjectCreationDecorator
1552 	 */
getLaunchConfiguration(IJavaProject project, String containername, String mainTypeName)1553 	protected ILaunchConfiguration getLaunchConfiguration(IJavaProject project, String containername, String mainTypeName) {
1554 		IFile file = project.getProject().getFolder(containername).getFile(mainTypeName + LAUNCH_EXTENSION);
1555 		ILaunchConfiguration config = getLaunchManager().getLaunchConfiguration(file);
1556 		assertNotNull("the configuration cannot be null", config);
1557 		assertTrue("Could not find launch configuration for " + mainTypeName, config.exists()); //$NON-NLS-1$
1558 		return config;
1559 	}
1560 
1561 	/**
1562 	 * Returns the corresponding <code>IResource</code> from the <code>IJavaElement</code> with the
1563 	 * specified name
1564 	 * @param typeName the name of the <code>IJavaElement</code> to get the resource for
1565 	 * @return the corresponding <code>IResource</code> from the <code>IJavaElement</code> with the
1566 	 * specified name
1567 	 * @throws Exception
1568 	 */
getBreakpointResource(String typeName)1569 	protected IResource getBreakpointResource(String typeName) throws Exception {
1570 		IJavaElement element = getProjectContext().findElement(new Path(typeName + JAVA_EXTENSION));
1571 		IResource resource = element.getCorrespondingResource();
1572 		if (resource == null) {
1573 			resource = getProjectContext().getProject();
1574 		}
1575 		return resource;
1576 	}
1577 
1578 	/**
1579 	 * Returns the resource from the specified type or the project from the testing java project in the
1580 	 * event there is no resource from the specified type
1581 	 * @param type
1582 	 * @return
1583 	 * @throws Exception
1584 	 */
getBreakpointResource(IType type)1585 	protected IResource getBreakpointResource(IType type) throws Exception {
1586 		if (type == null) {
1587 			return getProjectContext().getProject();
1588 		}
1589 		IResource resource = type.getResource();
1590 		if (resource == null) {
1591 			resource = type.getJavaProject().getProject();
1592 		}
1593 		return resource;
1594 	}
1595 
1596 	/**
1597 	 * Creates and returns a line breakpoint at the given line number in the type with the
1598 	 * given name.
1599 	 *
1600 	 * @param lineNumber line number
1601 	 * @param typeName type name
1602 	 */
createLineBreakpoint(int lineNumber, String typeName)1603 	protected IJavaLineBreakpoint createLineBreakpoint(int lineNumber, String typeName) throws Exception {
1604 		IType type = getType(typeName);
1605 		assertNotNull("Could not find the requested IType: "+typeName, type);
1606 		return createLineBreakpoint(type, lineNumber);
1607 	}
1608 
1609 	/**
1610 	 * Creates am  new java line breakpoint
1611 	 * @param lineNumber
1612 	 * @param root
1613 	 * @param packageName
1614 	 * @param cuName
1615 	 * @param fullTargetName
1616 	 * @return a new line breakpoint
1617 	 */
createLineBreakpoint(int lineNumber, String root, String packageName, String cuName, String fullTargetName)1618 	protected IJavaLineBreakpoint createLineBreakpoint(int lineNumber, String root, String packageName, String cuName,
1619 			String fullTargetName) throws Exception{
1620 		IJavaProject javaProject = getProjectContext();
1621 		ICompilationUnit cunit = getCompilationUnit(javaProject, root, packageName, cuName);
1622 		assertNotNull("did not find requested Compilation Unit", cunit); //$NON-NLS-1$
1623 		IType targetType = (IType)(new MemberParser()).getDeepest(cunit,fullTargetName);
1624 		assertNotNull("did not find requested type", targetType); //$NON-NLS-1$
1625 		assertTrue("did not find type to install breakpoint in", targetType.exists()); //$NON-NLS-1$
1626 
1627 		return createLineBreakpoint(targetType, lineNumber);
1628 	}
1629 
1630 
1631 	/**
1632 	 * Creates a line breakpoint in the given type (may be a top level non public type)
1633 	 *
1634 	 * @param lineNumber line number to create the breakpoint at
1635 	 * @param packageName fully qualified package name containing the type, example "a.b.c"
1636 	 * @param cuName simple name of compilation unit containing the type, example "Something.java"
1637 	 * @param typeName $ qualified type name, example "Something" or "NonPublic" or "Something$Inner"
1638 	 * @return line breakpoint
1639 	 * @throws Exception
1640 	 */
createLineBreakpoint(int lineNumber, String packageName, String cuName, String typeName)1641 	protected IJavaLineBreakpoint createLineBreakpoint(int lineNumber, String packageName, String cuName, String typeName) throws Exception {
1642 		IType type = getType(packageName, cuName, typeName);
1643 		assertNotNull("Could not find the requested IType: "+typeName, type);
1644 		return createLineBreakpoint(type, lineNumber);
1645 	}
1646 
1647 	/**
1648 	 * Creates a line breakpoint in the given type at the given line number.
1649 	 *
1650 	 * @param type type in which to install the breakpoint
1651 	 * @param lineNumber line number to install the breakpoint at
1652 	 * @return line breakpoint
1653 	 * @throws Exception
1654 	 */
createLineBreakpoint(IType type, int lineNumber)1655 	protected IJavaLineBreakpoint createLineBreakpoint(IType type, int lineNumber) throws Exception {
1656 		assertNotNull("You cannot create a line breakpoint for a null IType", type);
1657 		IMember member = null;
1658 		IJavaElement sourceElement = null;
1659 		String source = null;
1660 		if (type.isBinary()) {
1661 			IClassFile classFile = type.getClassFile();
1662 			source = classFile.getSource();
1663 			sourceElement = classFile;
1664 		} else {
1665 			ICompilationUnit unit = type.getCompilationUnit();
1666 			source = unit.getSource();
1667 			sourceElement = unit;
1668 		}
1669 		// translate line number to offset
1670 		if (source != null) {
1671 			Document document = new Document(source);
1672 			IRegion region = document.getLineInformation(lineNumber);
1673 			if (sourceElement instanceof ICompilationUnit) {
1674 				member = (IMember) ((ICompilationUnit)sourceElement).getElementAt(region.getOffset());
1675 			} else {
1676 				member = (IMember) ((IClassFile)sourceElement).getElementAt(region.getOffset());
1677 			}
1678 		}
1679 		Map<String, Object> map = getExtraBreakpointAttributes(member);
1680 		IJavaLineBreakpoint bp = JDIDebugModel.createLineBreakpoint(getBreakpointResource(type), type.getFullyQualifiedName(), lineNumber, -1, -1, 0, true, map);
1681 		forceDeltas(bp);
1682 		return bp;
1683 	}
1684 
1685 	/**
1686 	 * Forces marker deltas to be sent based on breakpoint creation.
1687 	 *
1688 	 * @param breakpoint
1689 	 */
forceDeltas(IBreakpoint breakpoint)1690 	private void forceDeltas(IBreakpoint breakpoint) throws CoreException {
1691 		IProject project = breakpoint.getMarker().getResource().getProject();
1692 		if (project != null) {
1693 			project.build(IncrementalProjectBuilder.INCREMENTAL_BUILD, null);
1694 		}
1695 	}
1696 
1697 	/**
1698 	 * Returns the type in the test project based on the given name. The type name may refer to a
1699 	 * top level non public type.
1700 	 *
1701 	 * @param packageName package name, example "a.b.c"
1702 	 * @param cuName simple compilation unit name within the package, example "Something.java"
1703 	 * @param typeName simple dot qualified type name, example "Something" or "NonPublic" or "Something.Inner"
1704 	 * @return associated type or <code>null</code> if none
1705 	 * @throws Exception
1706 	 */
getType(String packageName, String cuName, String typeName)1707 	protected IType getType(String packageName, String cuName, String typeName) throws Exception {
1708 		IPackageFragment[] packageFragments = getProjectContext().getPackageFragments();
1709 		for (int i = 0; i < packageFragments.length; i++) {
1710 			IPackageFragment fragment = packageFragments[i];
1711 			if (fragment.getElementName().equals(packageName)) {
1712 				ICompilationUnit compilationUnit = fragment.getCompilationUnit(cuName);
1713 				String[] names = typeName.split("\\$"); //$NON-NLS-1$
1714 				IType type = compilationUnit.getType(names[0]);
1715 				for (int j = 1; j < names.length; j++) {
1716 					type = type.getType(names[j]);
1717 				}
1718 				if (type.exists()) {
1719 					return type;
1720 				}
1721 			}
1722 		}
1723 		return null;
1724 	}
1725 
1726 	/**
1727 	 * Creates and returns a map of java element breakpoint attributes for a breakpoint on the
1728 	 * given java element, or <code>null</code> if none
1729 	 *
1730 	 * @param element java element the breakpoint is associated with
1731 	 * @return map of breakpoint attributes or <code>null</code>
1732 	 * @throws Exception
1733 	 */
getExtraBreakpointAttributes(IMember element)1734 	protected Map<String, Object> getExtraBreakpointAttributes(IMember element) throws Exception {
1735 		if (element != null && element.exists()) {
1736 			Map<String, Object> map = new HashMap<>();
1737 			ISourceRange sourceRange = element.getSourceRange();
1738 			int start = sourceRange.getOffset();
1739 			int end = start + sourceRange.getLength();
1740 			IType type = null;
1741 			if (element instanceof IType) {
1742 				type = (IType) element;
1743 			} else {
1744 				type = element.getDeclaringType();
1745 			}
1746 			BreakpointUtils.addJavaBreakpointAttributesWithMemberDetails(map, type, start, end);
1747 			return map;
1748 		}
1749 		return null;
1750 	}
1751 
1752 	/**
1753 	 * Creates and returns a line breakpoint at the given line number in the type with the
1754 	 * given name and sets the specified condition on the breakpoint.
1755 	 *
1756 	 * @param lineNumber line number
1757 	 * @param typeName type name
1758 	 * @param condition condition
1759 	 */
createConditionalLineBreakpoint(int lineNumber, String typeName, String condition, boolean suspendOnTrue)1760 	protected IJavaLineBreakpoint createConditionalLineBreakpoint(int lineNumber, String typeName, String condition, boolean suspendOnTrue) throws Exception {
1761 		IJavaLineBreakpoint bp = createLineBreakpoint(lineNumber, typeName);
1762 		bp.setCondition(condition);
1763 		bp.setConditionEnabled(true);
1764 		bp.setConditionSuspendOnTrue(suspendOnTrue);
1765 		return bp;
1766 	}
1767 
1768 	/**
1769 	 * Creates and returns a pattern breakpoint at the given line number in the
1770 	 * source file with the given name.
1771 	 *
1772 	 * @param lineNumber line number
1773 	 * @param sourceName name of source file
1774 	 * @param pattern the pattern of the class file name
1775 	 */
createPatternBreakpoint(int lineNumber, String sourceName, String pattern)1776 	protected IJavaPatternBreakpoint createPatternBreakpoint(int lineNumber, String sourceName, String pattern) throws Exception {
1777 		return JDIDebugModel.createPatternBreakpoint(getProjectContext().getProject(), sourceName, pattern, lineNumber, -1, -1, 0, true, null);
1778 	}
1779 
1780 	/**
1781 	 * Creates and returns a target pattern breakpoint at the given line number in the
1782 	 * source file with the given name.
1783 	 *
1784 	 * @param lineNumber line number
1785 	 * @param sourceName name of source file
1786 	 */
createTargetPatternBreakpoint(int lineNumber, String sourceName)1787 	protected IJavaTargetPatternBreakpoint createTargetPatternBreakpoint(int lineNumber, String sourceName) throws Exception {
1788 		return JDIDebugModel.createTargetPatternBreakpoint(getProjectContext().getProject(), sourceName, lineNumber, -1, -1, 0, true, null);
1789 	}
1790 
1791 	/**
1792 	 * Creates and returns a stratum breakpoint at the given line number in the
1793 	 * source file with the given name.
1794 	 *
1795 	 * @param lineNumber line number
1796 	 * @param sourceName name of source file
1797 	 * @param stratum the stratum of the source file
1798 	 */
createStratumBreakpoint(int lineNumber, String sourceName, String stratum)1799 	protected IJavaStratumLineBreakpoint createStratumBreakpoint(int lineNumber, String sourceName, String stratum) throws Exception {
1800 		return JDIDebugModel.createStratumBreakpoint(getProjectContext().getProject(), stratum, sourceName, null, null, lineNumber, -1, -1, 0, true, null);
1801 	}
1802 
1803 	/**
1804 	 * Creates and returns a method breakpoint
1805 	 *
1806 	 * @param typeNamePattern type name pattern
1807 	 * @param methodName method name
1808 	 * @param methodSignature method signature or <code>null</code>
1809 	 * @param entry whether to break on entry
1810 	 * @param exit whether to break on exit
1811 	 */
createMethodBreakpoint(String typeNamePattern, String methodName, String methodSignature, boolean entry, boolean exit)1812 	protected IJavaMethodBreakpoint createMethodBreakpoint(String typeNamePattern, String methodName, String methodSignature, boolean entry, boolean exit) throws Exception {
1813 		return createMethodBreakpoint(getProjectContext(), typeNamePattern, methodName, methodSignature, entry, exit);
1814 	}
1815 
1816 	/**
1817 	 * Creates and returns a method breakpoint
1818 	 *
1819 	 * @param project java project
1820 	 * @param typeNamePattern type name pattern
1821 	 * @param methodName method name
1822 	 * @param methodSignature method signature or <code>null</code>
1823 	 * @param entry whether to break on entry
1824 	 * @param exit whether to break on exit
1825 	 */
createMethodBreakpoint(IJavaProject project, String typeNamePattern, String methodName, String methodSignature, boolean entry, boolean exit)1826 	protected IJavaMethodBreakpoint createMethodBreakpoint(IJavaProject project, String typeNamePattern, String methodName, String methodSignature, boolean entry, boolean exit) throws Exception {
1827 		IMethod method= null;
1828 		IResource resource = project.getProject();
1829 		if (methodSignature != null && methodName != null) {
1830 			IType type = project.findType(typeNamePattern);
1831 			if (type != null ) {
1832 				resource = getBreakpointResource(type);
1833 				method = type.getMethod(methodName, Signature.getParameterTypes(methodSignature));
1834 			}
1835 		}
1836 		Map<String, Object> map = getExtraBreakpointAttributes(method);
1837 		IJavaMethodBreakpoint bp = JDIDebugModel.createMethodBreakpoint(resource, typeNamePattern, methodName, methodSignature, entry, exit,false, -1, -1, -1, 0, true, map);
1838 		forceDeltas(bp);
1839 		return bp;
1840 	}
1841 
1842 	/**
1843 	 * Creates a method breakpoint in a fully specified type (potentially non public).
1844 	 *
1845 	 * @param packageName package name containing type to install breakpoint in, example "a.b.c"
1846 	 * @param cuName simple compilation unit name within package, example "Something.java"
1847 	 * @param typeName $ qualified type name within compilation unit, example "Something" or
1848 	 *  "NonPublic" or "Something$Inner"
1849 	 * @param methodName method or <code>null</code> for all methods
1850 	 * @param methodSignature JLS method signature or <code>null</code> for all methods with the given name
1851 	 * @param entry whether to break on entry
1852 	 * @param exit whether to break on exit
1853 	 * @return method breakpoint
1854 	 * @throws Exception
1855 	 */
createMethodBreakpoint(String packageName, String cuName, String typeName, String methodName, String methodSignature, boolean entry, boolean exit)1856 	protected IJavaMethodBreakpoint createMethodBreakpoint(String packageName, String cuName, String typeName, String methodName, String methodSignature, boolean entry, boolean exit) throws Exception {
1857 		IType type = getType(packageName, cuName, typeName);
1858 		assertNotNull("did not find type to install breakpoint in", type); //$NON-NLS-1$
1859 		IMethod method= null;
1860 		if (methodSignature != null && methodName != null) {
1861 			if (type != null ) {
1862 				method = type.getMethod(methodName, Signature.getParameterTypes(methodSignature));
1863 			}
1864 		}
1865 		Map<String, Object> map = getExtraBreakpointAttributes(method);
1866 		IJavaMethodBreakpoint bp = JDIDebugModel.createMethodBreakpoint(getBreakpointResource(type), type.getFullyQualifiedName(), methodName, methodSignature, entry, exit,false, -1, -1, -1, 0, true, map);
1867 		forceDeltas(bp);
1868 		return bp;
1869 	}
1870 
1871 
1872 	/**
1873 	 * Creates a MethodBreakPoint on the method specified at the given path.
1874 	 * Syntax:
1875 	 * Type$InnerType$MethodNameAndSignature$AnonymousTypeDeclarationNumber$FieldName
1876 	 * eg:<code>
1877 	 * public class Foo{
1878 	 * 		class Inner
1879 	 * 		{
1880 	 * 			public void aMethod()
1881 	 * 			{
1882 	 * 				Object anon = new Object(){
1883 	 * 					int anIntField;
1884 	 * 					String anonTypeMethod() {return "an Example";}
1885 	 * 				}
1886 	 * 			}
1887 	 * 		}
1888 	 * }</code>
1889 	 * Syntax to get the anonymous toString would be: Foo$Inner$aMethod()V$1$anonTypeMethod()QString
1890 	 * so, createMethodBreakpoint(packageName, cuName, "Foo$Inner$aMethod()V$1$anonTypeMethod()QString",true,false);
1891 	 */
createMethodBreakpoint(String root, String packageName, String cuName, String fullTargetName, boolean entry, boolean exit)1892 	protected IJavaMethodBreakpoint createMethodBreakpoint(String root, String packageName, String cuName,
1893 									String fullTargetName, boolean entry, boolean exit) throws Exception {
1894 
1895 		IJavaProject javaProject = getProjectContext();
1896 		ICompilationUnit cunit = getCompilationUnit(javaProject, root, packageName, cuName);
1897 		assertNotNull("did not find requested Compilation Unit", cunit); //$NON-NLS-1$
1898 		IMethod targetMethod = (IMethod)(new MemberParser()).getDeepest(cunit,fullTargetName);
1899 		assertNotNull("did not find requested method", targetMethod); //$NON-NLS-1$
1900 		assertTrue("Given method does not exist", targetMethod.exists()); //$NON-NLS-1$
1901 		IType methodParent = (IType)targetMethod.getParent();//safe - method's only parent = Type
1902 		assertNotNull("did not find type to install breakpoint in", methodParent); //$NON-NLS-1$
1903 
1904 		Map<String, Object> map = getExtraBreakpointAttributes(targetMethod);
1905 		IJavaMethodBreakpoint bp = JDIDebugModel.createMethodBreakpoint(getBreakpointResource(methodParent), methodParent.getFullyQualifiedName(),targetMethod.getElementName(), targetMethod.getSignature(), entry, exit,false, -1, -1, -1, 0, true, map);
1906 		forceDeltas(bp);
1907 		return bp;
1908 	}
1909 
1910 	/**
1911 	 * @param cu the Compilation where the target resides
1912 	 * @param target the full name of the target, as per MemberParser syntax
1913 	 * @return the requested Member
1914 	 */
getMember(ICompilationUnit cu, String target)1915 	protected IMember getMember(ICompilationUnit cu, String target) {
1916 		IMember toReturn = (new MemberParser()).getDeepest(cu,target);
1917 		return toReturn;
1918 	}
1919 
1920 	/**
1921 	 * Delegate method to get a resource with a specific name from the testing workspace 'src' folder
1922 	 * @param name the name of the <code>IResource</code> to get
1923 	 * @return the specified <code>IResource</code> or <code>null</code> if it does not exist
1924 	 *
1925 	 * @since 3.4
1926 	 */
getResource(String name)1927 	protected IResource getResource(String name) {
1928 		return ResourcesPlugin.getWorkspace().getRoot().findMember(new Path("/DebugTests/src/"+name));
1929 	}
1930 
1931 	/**
1932 	 * Creates and returns a class prepare breakpoint on the type with the given fully qualified name.
1933 	 *
1934 	 * @param typeName type on which to create the breakpoint
1935 	 * @return breakpoint
1936 	 * @throws Exception
1937 	 */
createClassPrepareBreakpoint(String typeName)1938 	protected IJavaClassPrepareBreakpoint createClassPrepareBreakpoint(String typeName) throws Exception {
1939 		return createClassPrepareBreakpoint(getType(typeName));
1940 	}
1941 
1942 	/**
1943 	 * Creates and returns a class prepare breakpoint on the type with the given fully qualified name.
1944 	 *
1945 	 * @param typeName type on which to create the breakpoint
1946 	 * @return breakpoint
1947 	 * @throws Exception
1948 	 */
createClassPrepareBreakpoint(String root, String packageName, String cuName, String fullTargetName)1949 	protected IJavaClassPrepareBreakpoint createClassPrepareBreakpoint(String root,
1950 			String packageName, String cuName, String fullTargetName) throws Exception {
1951 		ICompilationUnit cunit = getCompilationUnit(getProjectContext(), root, packageName, cuName);
1952 		IType type = (IType)getMember(cunit,fullTargetName);
1953 		assertTrue("Target type not found", type.exists()); //$NON-NLS-1$
1954 		return createClassPrepareBreakpoint(type);
1955 	}
1956 
1957 	/**
1958 	 * Creates a class prepare breakpoint in a fully specified type (potentially non public).
1959 	 *
1960 	 * @param packageName package name containing type to install breakpoint in, example "a.b.c"
1961 	 * @param cuName simple compilation unit name within package, example "Something.java"
1962 	 * @param typeName $ qualified type name within compilation unit, example "Something" or
1963 	 *  "NonPublic" or "Something$Inner"
1964 	 */
createClassPrepareBreakpoint(String packageName, String cuName, String typeName)1965 	protected IJavaClassPrepareBreakpoint createClassPrepareBreakpoint(String packageName, String cuName, String typeName) throws Exception {
1966 		return createClassPrepareBreakpoint(getType(packageName, cuName, typeName));
1967 	}
1968 
1969 	/**
1970 	 * Creates a class prepare breakpoint for the given type
1971 	 *
1972 	 * @param type type
1973 	 * @return class prepare breakpoint
1974 	 * @throws Exception
1975 	 */
createClassPrepareBreakpoint(IType type)1976 	protected IJavaClassPrepareBreakpoint createClassPrepareBreakpoint(IType type) throws Exception {
1977 		assertNotNull("type not specified for class prepare breakpoint", type); //$NON-NLS-1$
1978 		int kind = IJavaClassPrepareBreakpoint.TYPE_CLASS;
1979 		if (type.isInterface()) {
1980 			kind = IJavaClassPrepareBreakpoint.TYPE_INTERFACE;
1981 		}
1982 		Map<String, Object> map = getExtraBreakpointAttributes(type);
1983 		IJavaClassPrepareBreakpoint bp = JDIDebugModel.createClassPrepareBreakpoint(getBreakpointResource(type), type.getFullyQualifiedName(), kind, -1, -1, true, map);
1984 		forceDeltas(bp);
1985 		return bp;
1986 	}
1987 
1988 	/**
1989 	 * Returns the Java model type from the test project with the given name or <code>null</code>
1990 	 * if none.
1991 	 *
1992 	 * @param typeName
1993 	 * @return type or <code>null</code>
1994 	 * @throws Exception
1995 	 */
getType(String typeName)1996 	protected IType getType(String typeName) throws Exception {
1997 		return getProjectContext().findType(typeName);
1998 	}
1999 
2000 	/**
2001 	 * Creates and returns a watchpoint
2002 	 *
2003 	 * @param typeNmae type name
2004 	 * @param fieldName field name
2005 	 * @param access whether to suspend on field access
2006 	 * @param modification whether to suspend on field modification
2007 	 */
createWatchpoint(String typeName, String fieldName, boolean access, boolean modification)2008 	protected IJavaWatchpoint createWatchpoint(String typeName, String fieldName, boolean access, boolean modification) throws Exception {
2009 		IType type = getType(typeName);
2010 		return createWatchpoint(type, fieldName, access, modification);
2011 	}
2012 
2013 	/**
2014 	 * Creates and returns an exception breakpoint
2015 	 *
2016 	 * @param exName exception name
2017 	 * @param caught whether to suspend in caught locations
2018 	 * @param uncaught whether to suspend in uncaught locations
2019 	 */
createExceptionBreakpoint(String exName, boolean caught, boolean uncaught)2020 	protected IJavaExceptionBreakpoint createExceptionBreakpoint(String exName, boolean caught, boolean uncaught) throws Exception {
2021 		IType type = getType(exName);
2022 		Map<String, Object> map = getExtraBreakpointAttributes(type);
2023 		IJavaExceptionBreakpoint bp = JDIDebugModel.createExceptionBreakpoint(getBreakpointResource(type),exName, caught, uncaught, false, true, map);
2024 		forceDeltas(bp);
2025 		return bp;
2026 	}
2027 
2028 	/**
2029 	 * Creates and returns a watchpoint
2030 	 *
2031 	 * @param typeNmae type name
2032 	 * @param fieldName field name
2033 	 * @param access whether to suspend on field access
2034 	 * @param modification whether to suspend on field modification
2035 	 */
2036 /*	protected IJavaWatchpoint createWatchpoint(String typeName, String fieldName, boolean access, boolean modification) throws Exception {
2037 		IType type = getType(typeName);
2038 		return createWatchpoint(type, fieldName, access, modification);
2039 	}*/
2040 
2041 
2042 	/**
2043 	 * Creates a WatchPoint on the field specified at the given path.
2044 	 * Will create watchpoints on fields within anonymous types, inner types,
2045 	 * local (non-public) types, and public types.
2046 	 * @param root
2047 	 * @param packageName package name containing type to install breakpoint in, example "a.b.c"
2048 	 * @param cuName simple compilation unit name within package, example "Something.java"
2049 	 * @param fullTargetName - see below
2050 	 * @param access whether to suspend on access
2051 	 * @param modification whether to suspend on modification
2052 	 * @return a watchpoint
2053 	 * @throws Exception
2054 	 * @throws CoreException
2055 	 *
2056 	 * <p>
2057 	 * <pre>
2058 	 * Syntax example:
2059 	 * Type$InnerType$MethodNameAndSignature$AnonymousTypeDeclarationNumber$FieldName
2060 	 * eg:
2061 	 * public class Foo{
2062 	 * 		class Inner
2063 	 * 		{
2064 	 * 			public void aMethod()
2065 	 * 			{
2066 	 * 				Object anon = new Object(){
2067 	 * 					int anIntField;
2068 	 * 					String anonTypeMethod() {return "an Example";}
2069 	 * 				}
2070 	 * 			}
2071 	 * 		}
2072 	 * }</pre>
2073 	 * </p>
2074 	 * To get the anonymous toString, syntax of fullTargetName would be: <code>Foo$Inner$aMethod()V$1$anIntField</code>
2075 	 */
createNestedTypeWatchPoint(String root, String packageName, String cuName, String fullTargetName, boolean access, boolean modification)2076 	protected IJavaWatchpoint createNestedTypeWatchPoint(String root, String packageName, String cuName,
2077 			String fullTargetName, boolean access, boolean modification) throws Exception, CoreException {
2078 
2079 		ICompilationUnit cunit = getCompilationUnit(getProjectContext(), root, packageName, cuName);
2080 		IField field = (IField)getMember(cunit,fullTargetName);
2081 		assertNotNull("Path to field is not valid", field); //$NON-NLS-1$
2082 		assertTrue("Field is not valid", field.exists()); //$NON-NLS-1$
2083 		IType type = (IType)field.getParent();
2084 		return createWatchpoint(type, field.getElementName(), access, modification);
2085 	}
2086 
2087 
2088 	/**
2089 	 * Creates a watchpoint in a fully specified type (potentially non public).
2090 	 *
2091 	 * @param packageName package name containing type to install breakpoint in, example "a.b.c"
2092 	 * @param cuName simple compilation unit name within package, example "Something.java"
2093 	 * @param typeName $ qualified type name within compilation unit, example "Something" or
2094 	 *  "NonPublic" or "Something$Inner"
2095 	 * @param fieldName name of the field
2096 	 * @param access whether to suspend on access
2097 	 * @param modification whether to suspend on modification
2098 	 */
createWatchpoint(String packageName, String cuName, String typeName, String fieldName, boolean access, boolean modification)2099 	protected IJavaWatchpoint createWatchpoint(String packageName, String cuName, String typeName, String fieldName, boolean access, boolean modification) throws Exception {
2100 		IType type = getType(packageName, cuName, typeName);
2101 		return createWatchpoint(type, fieldName, access, modification);
2102 	}
2103 
2104 	/**
2105 	 * Creates a watchpoint on the specified field.
2106 	 *
2107 	 * @param type type containing the field
2108 	 * @param fieldName name of the field
2109 	 * @param access whether to suspend on access
2110 	 * @param modification whether to suspend on modification
2111 	 * @return watchpoint
2112 	 * @throws Exception
2113 	 */
createWatchpoint(IType type, String fieldName, boolean access, boolean modification)2114 	protected IJavaWatchpoint createWatchpoint(IType type, String fieldName, boolean access, boolean modification) throws Exception, CoreException {
2115 		assertNotNull("type not specified for watchpoint", type); //$NON-NLS-1$
2116 		IField field = type.getField(fieldName);
2117 		Map<String, Object> map = getExtraBreakpointAttributes(field);
2118 		IJavaWatchpoint wp = JDIDebugModel.createWatchpoint(getBreakpointResource(type), type.getFullyQualifiedName(), fieldName, -1, -1, -1, 0, true, map);
2119 		wp.setAccess(access);
2120 		wp.setModification(modification);
2121 		forceDeltas(wp);
2122 		return wp;
2123 	}
2124 
2125 	/**
2126 	 * Terminates the given thread and removes its launch
2127 	 */
terminateAndRemove(IJavaThread thread)2128 	protected void terminateAndRemove(IJavaThread thread) {
2129 		if (thread != null) {
2130 			terminateAndRemove((IJavaDebugTarget)thread.getDebugTarget());
2131 		}
2132 	}
2133 
2134 	/**
2135 	 * Terminates the given debug target and removes its launch.
2136 	 *
2137 	 * NOTE: all breakpoints are removed, all threads are resumed, and then
2138 	 * the target is terminated. This avoids defunct processes on Linux.
2139 	 */
terminateAndRemove(IJavaDebugTarget debugTarget)2140 	protected void terminateAndRemove(IJavaDebugTarget debugTarget) {
2141 		assertNotNull(getName()+" - you cannot terminate and remove a null debug target", debugTarget);
2142 	    ILaunch launch = debugTarget.getLaunch();
2143 		if (!(debugTarget.isTerminated() || debugTarget.isDisconnected())) {
2144 			IPreferenceStore jdiUIPreferences = JDIDebugUIPlugin.getDefault().getPreferenceStore();
2145 			jdiUIPreferences.setValue(IJDIPreferencesConstants.PREF_SUSPEND_ON_UNCAUGHT_EXCEPTIONS, false);
2146 
2147 			DebugEventWaiter waiter = new DebugElementEventWaiter(DebugEvent.TERMINATE, debugTarget);
2148 			waiter.setEnableUIEventLoopProcessing(enableUIEventLoopProcessingInWaiter());
2149 			try {
2150 				removeAllBreakpoints();
2151 				IThread[] threads = debugTarget.getThreads();
2152 				for (int i = 0; i < threads.length; i++) {
2153 					IThread thread = threads[i];
2154 					try {
2155 						if (thread.isSuspended()) {
2156 							thread.resume();
2157 						}
2158 					} catch (CoreException e) {
2159 					}
2160 				}
2161 				debugTarget.getDebugTarget().terminate();
2162 				waiter.waitForEvent();
2163 			} catch (CoreException e) {
2164 			}
2165 		}
2166 		TestUtil.waitForJobs(getName(), 100, 10000);
2167 		TestUtil.runEventLoop();
2168 		getLaunchManager().removeLaunch(launch);
2169         // ensure event queue is flushed
2170         DebugEventWaiter waiter = new DebugElementEventWaiter(DebugEvent.MODEL_SPECIFIC, this);
2171 		waiter.setEnableUIEventLoopProcessing(enableUIEventLoopProcessingInWaiter());
2172         DebugPlugin.getDefault().fireDebugEventSet(new DebugEvent[]{new DebugEvent(this, DebugEvent.MODEL_SPECIFIC)});
2173         waiter.waitForEvent();
2174 	}
2175 
2176 	/**
2177 	 * Deletes all existing breakpoints
2178 	 */
removeAllBreakpoints()2179 	protected void removeAllBreakpoints() {
2180 		IBreakpoint[] bps = getBreakpointManager().getBreakpoints();
2181 		try {
2182 			getBreakpointManager().removeBreakpoints(bps, true);
2183 		} catch (CoreException e) {
2184 		}
2185 	}
2186 
2187 	/**
2188 	 * Returns the first breakpoint the given thread is suspended
2189 	 * at, or <code>null</code> if none.
2190 	 *
2191 	 * @return the first breakpoint the given thread is suspended
2192 	 * at, or <code>null</code> if none
2193 	 */
getBreakpoint(IThread thread)2194 	protected IBreakpoint getBreakpoint(IThread thread) {
2195 		IBreakpoint[] bps = thread.getBreakpoints();
2196 		if (bps.length > 0) {
2197 			return bps[0];
2198 		}
2199 		return null;
2200 	}
2201 
2202 	/**
2203 	 * Evaluates the given snippet in the context of the given stack frame and returns
2204 	 * the result.
2205 	 *
2206 	 * @param snippet code snippet
2207 	 * @param frame stack frame context
2208 	 * @return evaluation result
2209 	 */
evaluate(String snippet, IJavaStackFrame frame)2210 	protected IEvaluationResult evaluate(String snippet, IJavaStackFrame frame) throws Exception {
2211 		DebugEventWaiter waiter= new DebugElementKindEventWaiter(DebugEvent.SUSPEND, IJavaThread.class);
2212 		waiter.setTimeout(DEFAULT_TIMEOUT);
2213 		waiter.setEnableUIEventLoopProcessing(enableUIEventLoopProcessingInWaiter());
2214 
2215 		IAstEvaluationEngine engine = EvaluationManager.newAstEvaluationEngine(getProjectContext(), (IJavaDebugTarget)frame.getDebugTarget());
2216 		try {
2217 			engine.evaluate(snippet, frame, this, DebugEvent.EVALUATION, true);
2218 
2219 			Object suspendee= waiter.waitForEvent();
2220 			setEventSet(waiter.getEventSet());
2221 			if(suspendee == null) {
2222 				throw new TestAgainException("Program did not suspend evaluating: \n\n"+snippet);
2223 			}
2224 			assertNotNull("Program did not suspend.", suspendee); //$NON-NLS-1$
2225 			return fEvaluationResult;
2226 		}
2227 		finally {
2228 			engine.dispose();
2229 		}
2230 	}
2231 
2232 	/**
2233 	 * Runs an evaluation using an embedded listener and the {@link #DEFAULT_TIMEOUT} for the operation
2234 	 * @param snippet the snippet to evaluate
2235 	 * @param thread the suspended thread to run the evaluation on
2236 	 * @return the {@link IEvaluationResult}
2237 	 * @throws Exception
2238 	 * @since 3.1.200
2239 	 */
evaluate(String snippet, IJavaThread thread)2240 	protected IEvaluationResult evaluate(String snippet, IJavaThread thread) throws Exception {
2241 		class Listener implements IEvaluationListener {
2242 			IEvaluationResult fResult;
2243 			@Override
2244 			public void evaluationComplete(IEvaluationResult result) {
2245 				fResult= result;
2246 			}
2247 		}
2248 		Listener listener= new Listener();
2249 		IJavaStackFrame frame = (IJavaStackFrame) thread.getTopStackFrame();
2250 		assertNotNull("There should be a stackframe", frame);
2251 		ASTEvaluationEngine engine = new ASTEvaluationEngine(getProjectContext(), (IJavaDebugTarget) thread.getDebugTarget());
2252 		try {
2253 			engine.evaluate(snippet, frame, listener, DebugEvent.EVALUATION_IMPLICIT, false);
2254 			long timeout = System.currentTimeMillis()+DEFAULT_TIMEOUT;
2255 			while(listener.fResult == null && System.currentTimeMillis() < timeout) {
2256 				Thread.sleep(100);
2257 			}
2258 			return listener.fResult;
2259 		}
2260 		finally {
2261 			engine.dispose();
2262 		}
2263 	}
2264 
2265 	/**
2266 	 * @see IEvaluationListener#evaluationComplete(IEvaluationResult)
2267 	 */
2268 	@Override
evaluationComplete(IEvaluationResult result)2269 	public void evaluationComplete(IEvaluationResult result) {
2270 		fEvaluationResult = result;
2271 	}
2272 
2273 	/**
2274 	 * Performs a step over in the given stack frame and returns when complete.
2275 	 *
2276 	 * @param frame stack frame to step in
2277 	 */
stepOver(IJavaStackFrame frame)2278 	protected IJavaThread stepOver(IJavaStackFrame frame) throws Exception {
2279 		DebugEventWaiter waiter= new DebugElementKindEventDetailWaiter(DebugEvent.SUSPEND, IJavaThread.class, DebugEvent.STEP_END);
2280 		waiter.setTimeout(DEFAULT_TIMEOUT);
2281 		waiter.setEnableUIEventLoopProcessing(enableUIEventLoopProcessingInWaiter());
2282 
2283 		frame.stepOver();
2284 
2285 		Object suspendee= waiter.waitForEvent();
2286 		setEventSet(waiter.getEventSet());
2287 		assertNotNull("Program did not suspend.", suspendee); //$NON-NLS-1$
2288 		return (IJavaThread) suspendee;
2289 	}
2290 
2291 	/**
2292 	 * Performs a step over in the given stack frame and returns when a breakpoint is hit.
2293 	 *
2294 	 * @param frame stack frame to step in
2295 	 */
stepOverToBreakpoint(IJavaStackFrame frame)2296 	protected IJavaThread stepOverToBreakpoint(IJavaStackFrame frame) throws Exception {
2297 		DebugEventWaiter waiter= new DebugElementKindEventDetailWaiter(DebugEvent.SUSPEND, IJavaThread.class, DebugEvent.BREAKPOINT);
2298 		waiter.setTimeout(DEFAULT_TIMEOUT);
2299 		waiter.setEnableUIEventLoopProcessing(enableUIEventLoopProcessingInWaiter());
2300 
2301 		frame.stepOver();
2302 
2303 		Object suspendee= waiter.waitForEvent();
2304 		setEventSet(waiter.getEventSet());
2305 		assertNotNull("Program did not suspend.", suspendee); //$NON-NLS-1$
2306 		return (IJavaThread) suspendee;
2307 	}
2308 
2309 	/**
2310 	 * Performs a step into in the given stack frame and returns when complete.
2311 	 *
2312 	 * @param frame stack frame to step in
2313 	 */
stepInto(IJavaStackFrame frame)2314 	protected IJavaThread stepInto(IJavaStackFrame frame) throws Exception {
2315 		DebugEventWaiter waiter= new DebugElementKindEventDetailWaiter(DebugEvent.SUSPEND, IJavaThread.class, DebugEvent.STEP_END);
2316 		waiter.setTimeout(DEFAULT_TIMEOUT);
2317 		waiter.setEnableUIEventLoopProcessing(enableUIEventLoopProcessingInWaiter());
2318 
2319 		frame.stepInto();
2320 
2321 		Object suspendee= waiter.waitForEvent();
2322 		setEventSet(waiter.getEventSet());
2323 		assertNotNull("Program did not suspend.", suspendee); //$NON-NLS-1$
2324 		return (IJavaThread) suspendee;
2325 	}
2326 
2327 	/**
2328 	 * Performs a step return in the given stack frame and returns when complete.
2329 	 *
2330 	 * @param frame stack frame to step return from
2331 	 */
stepReturn(IJavaStackFrame frame)2332 	protected IJavaThread stepReturn(IJavaStackFrame frame) throws Exception {
2333 		DebugEventWaiter waiter= new DebugElementKindEventDetailWaiter(DebugEvent.SUSPEND, IJavaThread.class, DebugEvent.STEP_END);
2334 		waiter.setTimeout(DEFAULT_TIMEOUT);
2335 		waiter.setEnableUIEventLoopProcessing(enableUIEventLoopProcessingInWaiter());
2336 
2337 		frame.stepReturn();
2338 
2339 		Object suspendee= waiter.waitForEvent();
2340 		setEventSet(waiter.getEventSet());
2341 		assertNotNull("Program did not suspend.", suspendee); //$NON-NLS-1$
2342 		return (IJavaThread) suspendee;
2343 	}
2344 
2345 	/**
2346 	 * Performs a step into with filters in the given stack frame and returns when
2347 	 * complete.
2348 	 *
2349 	 * @param frame stack frame to step in
2350 	 */
stepIntoWithFilters(IJavaStackFrame frame)2351 	protected IJavaThread stepIntoWithFilters(IJavaStackFrame frame) throws Exception {
2352 		return stepIntoWithFilters(frame, true);
2353 	}
2354 
2355 	/**
2356 	 * Performs a step into with filters in the given stack frame and returns when
2357 	 * complete.
2358 	 *
2359 	 * @param whether to step thru or step return from a filtered location
2360 	 * @param frame stack frame to step in
2361 	 */
stepIntoWithFilters(IJavaStackFrame frame, boolean stepThru)2362 	protected IJavaThread stepIntoWithFilters(IJavaStackFrame frame, boolean stepThru) throws Exception {
2363 		DebugEventWaiter waiter= new DebugElementKindEventWaiter(DebugEvent.SUSPEND, IJavaThread.class);
2364 		waiter.setTimeout(DEFAULT_TIMEOUT);
2365 		waiter.setEnableUIEventLoopProcessing(enableUIEventLoopProcessingInWaiter());
2366 
2367 		// turn filters on
2368 		IJavaDebugTarget target = (IJavaDebugTarget) frame.getDebugTarget();
2369 		try {
2370 			target.setStepFiltersEnabled(true);
2371 			target.setStepThruFilters(stepThru);
2372 			frame.stepInto();
2373 			Object suspendee= waiter.waitForEvent();
2374 			setEventSet(waiter.getEventSet());
2375 			assertNotNull("Program did not suspend.", suspendee); //$NON-NLS-1$
2376 			return (IJavaThread) suspendee;
2377 		} catch (DebugException e) {
2378 			tryTestAgain(e);
2379 		} finally {
2380 			// turn filters off
2381 			target.setStepFiltersEnabled(false);
2382 			target.setStepThruFilters(true);
2383 		}
2384 		return null;
2385 	}
2386 
2387 	/**
2388 	 * Performs a step return with filters in the given stack frame and returns when
2389 	 * complete.
2390 	 *
2391 	 * @param frame stack frame to step in
2392 	 */
stepReturnWithFilters(IJavaStackFrame frame)2393 	protected IJavaThread stepReturnWithFilters(IJavaStackFrame frame) throws Exception {
2394 		DebugEventWaiter waiter= new DebugElementKindEventWaiter(DebugEvent.SUSPEND, IJavaThread.class);
2395 		waiter.setTimeout(DEFAULT_TIMEOUT);
2396 		waiter.setEnableUIEventLoopProcessing(enableUIEventLoopProcessingInWaiter());
2397 
2398 		// turn filters on
2399 		IJavaDebugTarget target = (IJavaDebugTarget) frame.getDebugTarget();
2400 		try {
2401 			target.setStepFiltersEnabled(true);
2402 			frame.stepReturn();
2403 		} catch (DebugException e) {
2404 			tryTestAgain(e);
2405 		} finally {
2406 			// turn filters off
2407 			target.setStepFiltersEnabled(false);
2408 		}
2409 
2410 
2411 		Object suspendee= waiter.waitForEvent();
2412 		setEventSet(waiter.getEventSet());
2413 		assertNotNull("Program did not suspend.", suspendee); //$NON-NLS-1$
2414 		return (IJavaThread) suspendee;
2415 	}
2416 
2417 	/**
2418 	 * Performs a step over with filters in the given stack frame and returns when
2419 	 * complete.
2420 	 *
2421 	 * @param frame stack frame to step in
2422 	 */
stepOverWithFilters(IJavaStackFrame frame)2423 	protected IJavaThread stepOverWithFilters(IJavaStackFrame frame) throws Exception {
2424 		DebugEventWaiter waiter= new DebugElementKindEventWaiter(DebugEvent.SUSPEND, IJavaThread.class);
2425 		waiter.setTimeout(DEFAULT_TIMEOUT);
2426 		waiter.setEnableUIEventLoopProcessing(enableUIEventLoopProcessingInWaiter());
2427 
2428 		// turn filters on
2429 		IJavaDebugTarget target = (IJavaDebugTarget) frame.getDebugTarget();
2430 		try {
2431 			target.setStepFiltersEnabled(true);
2432 			frame.stepOver();
2433 		} catch (DebugException e) {
2434 			tryTestAgain(e);
2435 		} finally {
2436 			// turn filters off
2437 			target.setStepFiltersEnabled(false);
2438 		}
2439 
2440 
2441 		Object suspendee= waiter.waitForEvent();
2442 		setEventSet(waiter.getEventSet());
2443 		assertNotNull("Program did not suspend.", suspendee); //$NON-NLS-1$
2444 		return (IJavaThread) suspendee;
2445 	}
2446 
2447 	/**
2448 	 * Returns the compilation unit with the given name.
2449 	 *
2450 	 * @param project the project containing the CU
2451 	 * @param root the name of the source folder in the project
2452 	 * @param pkg the name of the package (empty string for default package)
2453 	 * @param name the name of the CU (ex. Something.java)
2454 	 * @return compilation unit
2455 	 */
getCompilationUnit(IJavaProject project, String root, String pkg, String name)2456 	protected ICompilationUnit getCompilationUnit(IJavaProject project, String root, String pkg, String name) {
2457 		IProject p = project.getProject();
2458 		IResource r = p.getFolder(root);
2459 		return project.getPackageFragmentRoot(r).getPackageFragment(pkg).getCompilationUnit(name);
2460 	}
2461 
2462     /**
2463      * Wait for builds to complete
2464      */
waitForBuild()2465     public static void waitForBuild() {
2466         boolean wasInterrupted = false;
2467         do {
2468             try {
2469                 Job.getJobManager().join(ResourcesPlugin.FAMILY_AUTO_BUILD, null);
2470                 Job.getJobManager().join(ResourcesPlugin.FAMILY_MANUAL_BUILD, null);
2471 				// Let also all other pending jobs proceed, ignore console jobs
2472 				TestUtil.waitForJobs("waitForBuild", 100, 1000, ProcessConsole.class);
2473                 wasInterrupted = false;
2474             } catch (OperationCanceledException e) {
2475                 e.printStackTrace();
2476             } catch (InterruptedException e) {
2477                 wasInterrupted = true;
2478             }
2479         } while (wasInterrupted);
2480     }
2481 
2482 
2483     /**
2484      * Finds the specified variable within the context of the specified stackframe. Returns null if a variable with
2485      * the given name does not exist
2486      * @param frame
2487      * @param name
2488      * @return the <code>IJavaVariable</code> with the given name or <code>null</code> if it
2489      * does not exist
2490      * @throws DebugException
2491      */
findVariable(IJavaStackFrame frame, String name)2492     protected IJavaVariable findVariable(IJavaStackFrame frame, String name) throws DebugException {
2493         IJavaVariable variable = frame.findVariable(name);
2494         if (variable == null) {
2495             // dump visible variables
2496             IDebugModelPresentation presentation = DebugUIPlugin.getModelPresentation();
2497             System.out.println("Could not find variable '" + name + "' in frame: " + presentation.getText(frame)); //$NON-NLS-1$ //$NON-NLS-2$
2498             System.out.println("Visible variables are:"); //$NON-NLS-1$
2499             IVariable[] variables = frame.getVariables();
2500             for (int i = 0; i < variables.length; i++) {
2501                 IVariable variable2 = variables[i];
2502                 System.out.println("\t" + presentation.getText(variable2)); //$NON-NLS-1$
2503             }
2504 			if (!frame.isStatic() && !frame.isNative()) {
2505 				IJavaObject ths = frame.getThis();
2506 				if (ths != null) {
2507 					variables = ths.getVariables();
2508 					for (int i = 0; i < variables.length; i++) {
2509 						IVariable variable2 = variables[i];
2510 						System.out.println("\t" + presentation.getText(variable2)); //$NON-NLS-1$
2511 					}
2512 				}
2513             }
2514         }
2515         return variable;
2516     }
2517 
2518 	/**
2519 	 * Returns if the local filesystem is case-sensitive or not
2520 	 * @return true if the local filesystem is case-sensitive, false otherwise
2521 	 */
isFileSystemCaseSensitive()2522 	protected boolean isFileSystemCaseSensitive() {
2523 		return Platform.OS_MACOSX.equals(Platform.getOS()) ? false : new File("a").compareTo(new File("A")) != 0; //$NON-NLS-1$ //$NON-NLS-2$
2524 	}
2525 
2526     /**
2527      * Creates a shared launch configuration for the type with the given name.
2528      */
createLaunchConfiguration(String mainTypeName)2529     protected ILaunchConfiguration createLaunchConfiguration(String mainTypeName) throws Exception {
2530         return createLaunchConfiguration(getProjectContext(), mainTypeName);
2531     }
2532 
2533     /**
2534      * Creates a shared launch configuration for the type with the given name.
2535      */
createLaunchConfiguration(IJavaProject project, String mainTypeName)2536     protected ILaunchConfiguration createLaunchConfiguration(IJavaProject project, String mainTypeName) throws Exception {
2537 		return createLaunchConfiguration(project, mainTypeName, false);
2538 	}
2539 
2540 	/**
2541 	 * Creates a shared launch configuration for the type with the given name.
2542 	 *
2543 	 * @param clone
2544 	 *            true if the launch config name should be different from the main type name
2545 	 */
createLaunchConfiguration(IJavaProject project, String mainTypeName, boolean clone)2546 	protected ILaunchConfiguration createLaunchConfiguration(IJavaProject project, String mainTypeName, boolean clone) throws Exception {
2547         ILaunchConfigurationType type = getLaunchManager().getLaunchConfigurationType(IJavaLaunchConfigurationConstants.ID_JAVA_APPLICATION);
2548 		String configName = clone ? mainTypeName + CLONE_SUFFIX : mainTypeName;
2549 		ILaunchConfigurationWorkingCopy config = type.newInstance(project.getProject().getFolder(LAUNCHCONFIGURATIONS), configName);
2550         config.setAttribute(IJavaLaunchConfigurationConstants.ATTR_MAIN_TYPE_NAME, mainTypeName);
2551         config.setAttribute(IJavaLaunchConfigurationConstants.ATTR_PROJECT_NAME, project.getElementName());
2552         setEnvironment(config);
2553 		Set<String> modes = new HashSet<>();
2554 		modes.add(ILaunchManager.RUN_MODE);
2555 		config.setPreferredLaunchDelegate(modes, LOCAL_JAVA_APPLICATION_TYPE_ID);
2556 		modes = new HashSet<>();
2557 		modes.add(ILaunchManager.DEBUG_MODE);
2558 		config.setPreferredLaunchDelegate(modes, LOCAL_JAVA_APPLICATION_TYPE_ID);
2559         // use 'java' instead of 'javaw' to launch tests (javaw is problematic
2560         // on JDK1.4.2)
2561         Map<String, String> map = new HashMap<>(1);
2562         map.put(IJavaLaunchConfigurationConstants.ATTR_JAVA_COMMAND, JAVA);
2563         config.setAttribute(IJavaLaunchConfigurationConstants.ATTR_VM_INSTALL_TYPE_SPECIFIC_ATTRS_MAP, map);
2564         return config.doSave();
2565     }
2566 
2567     /**
2568      * Creates a shared launch configuration for the type with the given name.
2569      */
createLaunchConfiguration(IJavaProject project, String containername, String mainTypeName)2570     protected ILaunchConfiguration createLaunchConfiguration(IJavaProject project, String containername, String mainTypeName) throws Exception {
2571         ILaunchConfigurationType type = getLaunchManager().getLaunchConfigurationType(IJavaLaunchConfigurationConstants.ID_JAVA_APPLICATION);
2572         ILaunchConfigurationWorkingCopy config = type.newInstance(project.getProject().getFolder(containername), mainTypeName);
2573         config.setAttribute(IJavaLaunchConfigurationConstants.ATTR_MAIN_TYPE_NAME, mainTypeName);
2574         config.setAttribute(IJavaLaunchConfigurationConstants.ATTR_PROJECT_NAME, project.getElementName());
2575         setEnvironment(config);
2576 		Set<String> modes = new HashSet<>();
2577 		modes.add(ILaunchManager.RUN_MODE);
2578 		config.setPreferredLaunchDelegate(modes, LOCAL_JAVA_APPLICATION_TYPE_ID);
2579 		modes = new HashSet<>();
2580 		modes.add(ILaunchManager.DEBUG_MODE);
2581 		config.setPreferredLaunchDelegate(modes, LOCAL_JAVA_APPLICATION_TYPE_ID);
2582         // use 'java' instead of 'javaw' to launch tests (javaw is problematic
2583         // on JDK1.4.2)
2584         Map<String, String> map = new HashMap<>(1);
2585         map.put(IJavaLaunchConfigurationConstants.ATTR_JAVA_COMMAND, JAVA);
2586         config.setAttribute(IJavaLaunchConfigurationConstants.ATTR_VM_INSTALL_TYPE_SPECIFIC_ATTRS_MAP, map);
2587         return config.doSave();
2588     }
2589 
setEnvironment(ILaunchConfigurationWorkingCopy workingCopy)2590     private void setEnvironment(ILaunchConfigurationWorkingCopy workingCopy) {
2591       Map<String, String> env = getLaunchManager().getNativeEnvironment().entrySet().stream()
2592         .filter(e -> !"JAVA_TOOL_OPTIONS".equals(e.getKey()))
2593         .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
2594       workingCopy.setAttribute(ILaunchManager.ATTR_APPEND_ENVIRONMENT_VARIABLES, false);
2595       workingCopy.setAttribute(ILaunchManager.ATTR_ENVIRONMENT_VARIABLES, env);
2596     }
2597 
2598 	/**
2599 	 * When a test throws the 'try again' exception, try it again.
2600 	 * @see junit.framework.TestCase#runBare()
2601 	 */
2602 	@Override
runBare()2603 	public void runBare() throws Throwable {
2604 		boolean tryAgain = true;
2605 		int attempts = 0;
2606 		while (tryAgain) {
2607 			try {
2608 				attempts++;
2609 				super.runBare();
2610 				tryAgain = false;
2611 			} catch (TestAgainException e) {
2612 				TestUtil.log(IStatus.ERROR, getName(), "Test failed attempt " + attempts + ". Re-testing.", e);
2613 				TestUtil.cleanUp(getName());
2614 				if (attempts > 4) {
2615 					// the next attempt will fail
2616 					break;
2617 				}
2618 			}
2619 		}
2620 		if (tryAgain) {
2621 			// last attempt and if it fails then we should fail, see bug 515988
2622 			super.runBare();
2623 		}
2624 	}
2625 
2626 	@Override
tearDown()2627 	protected void tearDown() throws Exception {
2628 		TestUtil.log(IStatus.INFO, getName(), "tearDown");
2629 		shutdownDebugTargets();
2630 		TestUtil.cleanUp(getName());
2631 		super.tearDown();
2632 	}
2633 
shutdownDebugTargets()2634 	protected void shutdownDebugTargets() {
2635 		ILaunchManager launchManager = DebugPlugin.getDefault().getLaunchManager();
2636 		IDebugTarget[] targets = launchManager.getDebugTargets();
2637 		for (IDebugTarget target : targets) {
2638 			if (target instanceof JDIDebugTarget) {
2639 				((JDIDebugTarget) target).shutdown();
2640 			}
2641 		}
2642 	}
2643 
2644 	/**
2645 	 * Opens and returns an editor on the given file or <code>null</code>
2646 	 * if none. The editor will be activated.
2647 	 *
2648 	 * @param file
2649 	 * @return editor or <code>null</code>
2650 	 */
openEditor(final IFile file)2651 	protected IEditorPart openEditor(final IFile file) throws PartInitException, InterruptedException {
2652 		Display display = DebugUIPlugin.getStandardDisplay();
2653 		if (Thread.currentThread().equals(display.getThread())) {
2654 			IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();
2655 			return IDE.openEditor(page, file, true);
2656 		}
2657 		final IEditorPart[] parts = new IEditorPart[1];
2658 		WorkbenchJob job = new WorkbenchJob(display, "open editor") {
2659 			@Override
2660 			public IStatus runInUIThread(IProgressMonitor monitor) {
2661 				IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();
2662 				try {
2663 					parts[0] = IDE.openEditor(page, file, true);
2664 				} catch (PartInitException e) {
2665 					return e.getStatus();
2666 				}
2667 				return Status.OK_STATUS;
2668 			}
2669 		};
2670 		job.schedule();
2671 		job.join();
2672 		return parts[0];
2673 	}
2674 
2675 	/**
2676 	 * Opens the {@link IDebugView} with the given id, does nothing if no such view exists.
2677 	 * This method can return <code>null</code>
2678 	 *
2679 	 * @param viewId
2680 	 * @return the handle to the {@link IDebugView} with the given id
2681 	 * @throws PartInitException
2682 	 * @throws InterruptedException
2683 	 * @since 3.8.100
2684 	 */
openDebugView(final String viewId)2685 	protected IDebugView openDebugView(final String viewId) throws PartInitException, InterruptedException {
2686 		if(viewId != null) {
2687 			Display display = DebugUIPlugin.getStandardDisplay();
2688 			if (Thread.currentThread().equals(display.getThread())) {
2689 				return doShowDebugView(viewId);
2690 			}
2691 			final IDebugView[] view = new IDebugView[1];
2692 			WorkbenchJob job = new WorkbenchJob("Showing the debug view: "+viewId) {
2693 				@Override
2694 				public IStatus runInUIThread(IProgressMonitor monitor) {
2695 					try {
2696 					view[0] = doShowDebugView(viewId);
2697 					}
2698 					catch(CoreException ce) {
2699 						return ce.getStatus();
2700 					}
2701 					return Status.OK_STATUS;
2702 				}
2703 			};
2704 			job.schedule();
2705 			job.join();
2706 			return view[0];
2707 		}
2708 		return null;
2709 	}
2710 
2711 	/**
2712 	 * Opens a debug view
2713 	 * @param viewId
2714 	 * @return return the debug view handle or <code>null</code>
2715 	 * @throws PartInitException
2716 	 * @since 3.8.100
2717 	 */
doShowDebugView(String viewId)2718 	private IDebugView doShowDebugView(String viewId) throws PartInitException {
2719 		IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
2720 		if(window != null) {
2721 			IWorkbenchPage page = window.getActivePage();
2722 			assertNotNull("We shold have found the active page to open the debug view in", page);
2723 			return (IDebugView) page.showView(viewId);
2724 		}
2725 		return null;
2726 	}
2727 
2728 	/**
2729 	 * Toggles a breakpoint in the editor at the given line number returning the breakpoint
2730 	 * or <code>null</code> if none.
2731 	 *
2732 	 * @param editor
2733 	 * @param lineNumber
2734 	 * @return returns the created breakpoint or <code>null</code> if none.
2735 	 * @throws InterruptedException
2736 	 */
toggleBreakpoint(final IEditorPart editor, int lineNumber)2737 	protected IBreakpoint toggleBreakpoint(final IEditorPart editor, int lineNumber) throws InterruptedException {
2738 		final IVerticalRulerInfo info = new VerticalRulerInfoStub(lineNumber-1); // sub 1, as the doc lines start at 0
2739 		WorkbenchJob job = new WorkbenchJob(DebugUIPlugin.getStandardDisplay(), "toggle breakpoint") {
2740 			@Override
2741 			public IStatus runInUIThread(IProgressMonitor monitor) {
2742 				ToggleBreakpointAction action = new ToggleBreakpointAction(editor, null, info);
2743 				action.run();
2744 				return Status.OK_STATUS;
2745 			}
2746 		};
2747 		final Object lock = new Object();
2748 		final IBreakpoint[] breakpoints = new IBreakpoint[1];
2749 		IBreakpointListener listener = new IBreakpointListener() {
2750 			@Override
2751 			public void breakpointRemoved(IBreakpoint breakpoint, IMarkerDelta delta) {
2752 			}
2753 			@Override
2754 			public void breakpointChanged(IBreakpoint breakpoint, IMarkerDelta delta) {
2755 			}
2756 			@Override
2757 			public void breakpointAdded(IBreakpoint breakpoint) {
2758 				synchronized (lock) {
2759 					breakpoints[0] = breakpoint;
2760 					lock.notifyAll();
2761 				}
2762 			}
2763 		};
2764 		IBreakpointManager manager = DebugPlugin.getDefault().getBreakpointManager();
2765 		manager.addBreakpointListener(listener);
2766 		synchronized (lock) {
2767 			job.schedule();
2768 			lock.wait(DEFAULT_TIMEOUT);
2769 		}
2770 		manager.removeBreakpointListener(listener);
2771 		return breakpoints[0];
2772 	}
2773 
2774 	/**
2775 	 * Closes all editors in the active workbench page.
2776 	 */
closeAllEditors()2777 	protected void closeAllEditors() {
2778 	    Runnable closeAll = new Runnable() {
2779             @Override
2780 			public void run() {
2781                 IWorkbenchWindow activeWorkbenchWindow = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
2782                 activeWorkbenchWindow.getActivePage().closeAllEditors(false);
2783             }
2784         };
2785         Display display = DebugUIPlugin.getStandardDisplay();
2786         display.syncExec(closeAll);
2787 	}
2788 
2789 	/**
2790 	 * Returns the version level of the class files being run, based on the system property <code>java.class.version</code>
2791 	 * @return the version level of the class files being run in the current VM
2792 	 *
2793 	 *  @since 3.6
2794 	 */
getClassFileVersion()2795 	protected String getClassFileVersion() {
2796 		String version = System.getProperty("java.class.version");
2797 		if(version.compareTo("48.0") <= 0) {
2798 			return JavaCore.VERSION_1_4;
2799 		}
2800 		if(version.compareTo("49.0") <= 0) {
2801 			return JavaCore.VERSION_1_5;
2802 		}
2803 		return JavaCore.VERSION_1_6;
2804 	}
2805 
2806 	/**
2807 	 * Determines if the test should be attempted again based on the error code.
2808 	 * See bug 297071.
2809 	 *
2810 	 * @param e Debug Exception
2811 	 * @throws TestAgainException
2812 	 * @throws DebugException
2813 	 */
tryTestAgain(DebugException e)2814 	protected void tryTestAgain(DebugException e) throws Exception {
2815 		Throwable cause = e.getCause();
2816 		if (cause instanceof InternalException) {
2817 			int code = ((InternalException)cause).errorCode();
2818 			if (code == 13) {
2819 				throw new TestAgainException("Retest - exception during test: "+getName()+": "+e.getMessage());
2820 			}
2821 		}
2822 		throw e;
2823 	}
2824 
2825 	/**
2826 	 * Perform the actual evaluation (inspect)
2827 	 * @param thread
2828 	 * @return the result of the evaluation
2829 	 * @throws Exception
2830 	 */
doEval(IJavaThread thread, String snippet)2831 	protected IValue doEval(IJavaThread thread, String snippet) throws Exception{
2832 		class Listener implements IEvaluationListener {
2833 			IEvaluationResult fResult;
2834 
2835 			@Override
2836 			public void evaluationComplete(IEvaluationResult result) {
2837 				fResult= result;
2838 			}
2839 
2840 			public IEvaluationResult getResult() {
2841 				return fResult;
2842 			}
2843 		}
2844 		Listener listener = new Listener();
2845 		IJavaStackFrame frame = (IJavaStackFrame) thread.getTopStackFrame();
2846 		assertNotNull("There should be a stackframe", frame);
2847 		ASTEvaluationEngine engine = new ASTEvaluationEngine(getProjectContext(), (IJavaDebugTarget) thread.getDebugTarget());
2848 		try {
2849 			engine.evaluate(snippet, frame, listener, DebugEvent.EVALUATION_IMPLICIT, false);
2850 			long timeout = System.currentTimeMillis() + 5000;
2851 			while(listener.getResult() == null && System.currentTimeMillis() < timeout) {
2852 				Thread.sleep(100);
2853 			}
2854 			IEvaluationResult result = listener.getResult();
2855 			assertNotNull("The evaluation should have result: ", result);
2856 			assertNull("Evaluation of '" + snippet + "' should not have exception : " + findCause(result.getException()), result.getException());
2857 
2858 			String firstError = result.hasErrors() ? result.getErrorMessages()[0] : "";
2859 			assertFalse("The evaluation of '\" + snippet + \"'  should not have errors : " + firstError, result.hasErrors());
2860 			return listener.getResult().getValue();
2861 		}
2862 		finally {
2863 			engine.dispose();
2864 		}
2865 	}
2866 
findCause(DebugException problem)2867 	private static Object findCause(DebugException problem) {
2868 		if (problem == null) {
2869 			return null;
2870 		}
2871 		Throwable cause = problem.getCause();
2872 		if (cause instanceof InvocationException) {
2873 			return ((InvocationException)cause).exception().toString();
2874 		}
2875 		return cause;
2876 	}
2877 
2878 	/**
2879 	 * @return true if the UI event loop should be proicessed during wait operations on UI thread
2880 	 */
enableUIEventLoopProcessingInWaiter()2881 	protected boolean enableUIEventLoopProcessingInWaiter() {
2882 		return false;
2883 	}
2884 
assertNoErrorMarkersExist()2885 	protected void assertNoErrorMarkersExist() throws Exception {
2886 		IJavaProject javaProject = getProjectContext();
2887 		assertNotNull("Java test project cannot be null", javaProject);
2888 		IProject project = javaProject.getProject();
2889 		assertNotNull("test project cannot be null", project);
2890 		IProject[] projects = { project };
2891 		assertNoErrorMarkersExist(projects);
2892 	}
2893 
assertNoErrorMarkersExist(IProject[] projects)2894 	protected void assertNoErrorMarkersExist(IProject[] projects) throws Exception {
2895 		for (IProject project : projects) {
2896 			assertNoErrorMarkersExist(project);
2897 		}
2898 	}
2899 
assertNoErrorMarkersExist(IProject project)2900 	protected void assertNoErrorMarkersExist(IProject project) throws Exception {
2901 		if (project.isAccessible()) {
2902 			IMarker[] projectMarkers = project.findMarkers(null, false, IResource.DEPTH_INFINITE);
2903 			List<IMarker> errorMarkers = Arrays.stream(projectMarkers).filter(marker -> isErrorMarker(marker)).collect(Collectors.toList());
2904 			String projectErrors = toString(errorMarkers);
2905 			assertEquals("found errors on project " + project + ":" + System.lineSeparator() + projectErrors, Collections.EMPTY_LIST, errorMarkers);
2906 		}
2907 	}
2908 
isErrorMarker(IMarker marker)2909 	private static boolean isErrorMarker(IMarker marker) {
2910 		return marker.getAttribute(IMarker.SEVERITY, -1) == IMarker.SEVERITY_ERROR;
2911 	}
2912 
toString(Collection<IMarker> markers)2913 	private static String toString(Collection<IMarker> markers) {
2914 		StringBuilder markersInfo = new StringBuilder();
2915 		for (IMarker marker : markers) {
2916 			markersInfo.append(marker);
2917 		}
2918 		return markersInfo.toString();
2919 	}
2920 }
2921