blob: 76e36a80ccd6e39ae68dc4b78798f11850fa1125 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2000, 2016 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
* Jesper Steen Møller - bug 422029: [1.8] Enable debug evaluation support for default methods
* Jesper Steen Møller - bug 426903: [1.8] Cannot evaluate super call to default method
* Jesper Steen Møller - bug 341232
*******************************************************************************/
package org.eclipse.jdt.debug.tests;
import java.io.File;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IMarkerDelta;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IncrementalProjectBuilder;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.OperationCanceledException;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.core.runtime.preferences.IEclipsePreferences;
import org.eclipse.core.runtime.preferences.InstanceScope;
import org.eclipse.debug.core.DebugEvent;
import org.eclipse.debug.core.DebugException;
import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.debug.core.IBreakpointListener;
import org.eclipse.debug.core.IBreakpointManager;
import org.eclipse.debug.core.ILaunch;
import org.eclipse.debug.core.ILaunchConfiguration;
import org.eclipse.debug.core.ILaunchConfigurationType;
import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
import org.eclipse.debug.core.ILaunchDelegate;
import org.eclipse.debug.core.ILaunchManager;
import org.eclipse.debug.core.model.IBreakpoint;
import org.eclipse.debug.core.model.IDebugTarget;
import org.eclipse.debug.core.model.ILineBreakpoint;
import org.eclipse.debug.core.model.IProcess;
import org.eclipse.debug.core.model.IThread;
import org.eclipse.debug.core.model.IValue;
import org.eclipse.debug.core.model.IVariable;
import org.eclipse.debug.internal.core.LaunchDelegate;
import org.eclipse.debug.internal.core.LaunchManager;
import org.eclipse.debug.internal.ui.DebugUIPlugin;
import org.eclipse.debug.internal.ui.IInternalDebugUIConstants;
import org.eclipse.debug.internal.ui.breakpoints.provisional.IBreakpointOrganizer;
import org.eclipse.debug.internal.ui.launchConfigurations.LaunchConfigurationManager;
import org.eclipse.debug.internal.ui.launchConfigurations.LaunchConfigurationPresentationManager;
import org.eclipse.debug.internal.ui.launchConfigurations.LaunchConfigurationsDialog;
import org.eclipse.debug.internal.ui.launchConfigurations.LaunchShortcutExtension;
import org.eclipse.debug.internal.ui.preferences.IDebugPreferenceConstants;
import org.eclipse.debug.internal.ui.views.breakpoints.BreakpointOrganizerManager;
import org.eclipse.debug.internal.ui.views.console.ProcessConsole;
import org.eclipse.debug.ui.DebugUITools;
import org.eclipse.debug.ui.IDebugModelPresentation;
import org.eclipse.debug.ui.IDebugUIConstants;
import org.eclipse.debug.ui.IDebugView;
import org.eclipse.debug.ui.ILaunchConfigurationDialog;
import org.eclipse.debug.ui.ILaunchConfigurationTabGroup;
import org.eclipse.debug.ui.actions.ToggleBreakpointAction;
import org.eclipse.jdt.core.IAccessRule;
import org.eclipse.jdt.core.IBuffer;
import org.eclipse.jdt.core.IClassFile;
import org.eclipse.jdt.core.IClasspathAttribute;
import org.eclipse.jdt.core.IClasspathEntry;
import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.IField;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IMember;
import org.eclipse.jdt.core.IMethod;
import org.eclipse.jdt.core.IPackageFragment;
import org.eclipse.jdt.core.IPackageFragmentRoot;
import org.eclipse.jdt.core.ISourceRange;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.core.Signature;
import org.eclipse.jdt.debug.core.IJavaClassPrepareBreakpoint;
import org.eclipse.jdt.debug.core.IJavaDebugTarget;
import org.eclipse.jdt.debug.core.IJavaExceptionBreakpoint;
import org.eclipse.jdt.debug.core.IJavaLineBreakpoint;
import org.eclipse.jdt.debug.core.IJavaMethodBreakpoint;
import org.eclipse.jdt.debug.core.IJavaObject;
import org.eclipse.jdt.debug.core.IJavaPatternBreakpoint;
import org.eclipse.jdt.debug.core.IJavaStackFrame;
import org.eclipse.jdt.debug.core.IJavaStratumLineBreakpoint;
import org.eclipse.jdt.debug.core.IJavaTargetPatternBreakpoint;
import org.eclipse.jdt.debug.core.IJavaThread;
import org.eclipse.jdt.debug.core.IJavaVariable;
import org.eclipse.jdt.debug.core.IJavaWatchpoint;
import org.eclipse.jdt.debug.core.JDIDebugModel;
import org.eclipse.jdt.debug.eval.EvaluationManager;
import org.eclipse.jdt.debug.eval.IAstEvaluationEngine;
import org.eclipse.jdt.debug.eval.IEvaluationListener;
import org.eclipse.jdt.debug.eval.IEvaluationResult;
import org.eclipse.jdt.debug.testplugin.DebugElementEventWaiter;
import org.eclipse.jdt.debug.testplugin.DebugElementKindEventDetailWaiter;
import org.eclipse.jdt.debug.testplugin.DebugElementKindEventWaiter;
import org.eclipse.jdt.debug.testplugin.DebugEventWaiter;
import org.eclipse.jdt.debug.testplugin.JavaProjectHelper;
import org.eclipse.jdt.debug.testplugin.JavaTestPlugin;
import org.eclipse.jdt.debug.tests.core.LiteralTests17;
import org.eclipse.jdt.debug.tests.refactoring.MemberParser;
import org.eclipse.jdt.debug.ui.IJavaDebugUIConstants;
import org.eclipse.jdt.internal.debug.core.model.JDIDebugTarget;
import org.eclipse.jdt.internal.debug.eval.ast.engine.ASTEvaluationEngine;
import org.eclipse.jdt.internal.debug.ui.BreakpointUtils;
import org.eclipse.jdt.internal.debug.ui.IJDIPreferencesConstants;
import org.eclipse.jdt.internal.debug.ui.JDIDebugUIPlugin;
import org.eclipse.jdt.launching.IJavaLaunchConfigurationConstants;
import org.eclipse.jdt.launching.IVMInstall;
import org.eclipse.jdt.launching.JavaRuntime;
import org.eclipse.jdt.launching.environments.IExecutionEnvironment;
import org.eclipse.jface.dialogs.ErrorDialog;
import org.eclipse.jface.dialogs.MessageDialogWithToggle;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.text.BadPositionCategoryException;
import org.eclipse.jface.text.Document;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IRegion;
import org.eclipse.jface.text.Position;
import org.eclipse.jface.text.source.IVerticalRulerInfo;
import org.eclipse.jface.util.SafeRunnable;
import org.eclipse.swt.widgets.Display;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchPreferenceConstants;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.console.IConsole;
import org.eclipse.ui.console.IHyperlink;
import org.eclipse.ui.console.TextConsole;
import org.eclipse.ui.ide.IDE;
import org.eclipse.ui.internal.WorkbenchWindow;
import org.eclipse.ui.internal.console.ConsoleHyperlinkPosition;
import org.eclipse.ui.internal.util.PrefUtil;
import org.eclipse.ui.intro.IIntroManager;
import org.eclipse.ui.intro.IIntroPart;
import org.eclipse.ui.progress.UIJob;
import org.eclipse.ui.progress.WorkbenchJob;
import org.osgi.service.prefs.BackingStoreException;
import com.sun.jdi.InternalException;
import junit.framework.TestCase;
/**
* Tests for launch configurations
*/
@SuppressWarnings("deprecation")
public abstract class AbstractDebugTest extends TestCase implements IEvaluationListener {
public static final String MULTI_OUTPUT_PROJECT_NAME = "MultiOutput";
public static final String BOUND_EE_PROJECT_NAME = "BoundEE";
public static final String ONE_FOUR_PROJECT_NAME = "DebugTests";
public static final String ONE_FOUR_PROJECT_CLOSED_NAME = "ClosedDebugTests";
public static final String ONE_FIVE_PROJECT_NAME = "OneFive";
public static final String ONE_SEVEN_PROJECT_NAME = "OneSeven";
public static final String ONE_EIGHT_PROJECT_NAME = "OneEight";
public static final String BOUND_JRE_PROJECT_NAME = "BoundJRE";
public static final String CLONE_SUFFIX = "Clone";
final String[] LAUNCH_CONFIG_NAMES_1_4 = {"LargeSourceFile", "LotsOfFields", "Breakpoints", "InstanceVariablesTests", "LocalVariablesTests", "LocalVariableTests2", "StaticVariablesTests",
"DropTests", "ThrowsNPE", "ThrowsException", "org.eclipse.debug.tests.targets.Watchpoint",
"org.eclipse.debug.tests.targets.BreakpointsLocationBug344984", "org.eclipse.debug.tests.targets.CallLoop", "A",
"HitCountLooper", "CompileError", "MultiThreadedLoop", "HitCountException", "MultiThreadedException", "MultiThreadedList", "MethodLoop", "StepFilterOne",
"StepFilterFour", "EvalArrayTests", "EvalSimpleTests", "EvalTypeTests", "EvalNestedTypeTests", "EvalTypeHierarchyTests",
"EvalAnonymousClassVariableTests", "WorkingDirectoryTest",
"OneToTen", "OneToTenPrint", "FloodConsole", "ConditionalStepReturn", "VariableChanges", "DefPkgReturnType", "InstanceFilterObject", "org.eclipse.debug.tests.targets.CallStack",
"org.eclipse.debug.tests.targets.ThreadStack", "org.eclipse.debug.tests.targets.HcrClass", "org.eclipse.debug.tests.targets.StepIntoSelectionClass",
"WatchItemTests", "ArrayTests", "ByteArrayTests", "PerfLoop", "Console80Chars", "ConsoleStackTrace", "ConsoleVariableLineLength", "StackTraces",
"ConsoleInput", "PrintConcatenation", "VariableDetails", "org.eclipse.debug.tests.targets.ArrayDetailTests", "ArrayDetailTestsDef", "ForceReturnTests",
"ForceReturnTestsTwo", "LogicalStructures", "BreakpointListenerTest", "LaunchHistoryTest", "LaunchHistoryTest2", "RunnableAppletImpl", "java6.AllInstancesTests",
"bug329294", "bug401270", "org.eclipse.debug.tests.targets.HcrClass2", "org.eclipse.debug.tests.targets.HcrClass3", "org.eclipse.debug.tests.targets.HcrClass4",
"org.eclipse.debug.tests.targets.HcrClass5", "org.eclipse.debug.tests.targets.HcrClass6", "org.eclipse.debug.tests.targets.HcrClass7", "org.eclipse.debug.tests.targets.HcrClass8",
"org.eclipse.debug.tests.targets.HcrClass9", "TestContributedStepFilterClass", "TerminateAll_01", "TerminateAll_02", "StepResult1",
"StepResult2", "StepResult3", "TriggerPoint_01" };
final String[] LAUNCH_CONFIG_NAMES_1_8 = {"LargeSourceFile"};
/**
* the default timeout
*/
public static final int DEFAULT_TIMEOUT = 30000;
//constants
protected static final String JAVA = "java"; //$NON-NLS-1$
protected static final String JAVA_EXTENSION = ".java"; //$NON-NLS-1$
protected static final String LAUNCHCONFIGURATIONS = "launchConfigurations"; //$NON-NLS-1$
protected static final String LAUNCH_EXTENSION = ".launch"; //$NON-NLS-1$
protected static final String LOCAL_JAVA_APPLICATION_TYPE_ID = "org.eclipse.jdt.launching.localJavaApplication"; //$NON-NLS-1$
protected static final String JAVA_LAUNCH_SHORTCUT_ID = "org.eclipse.jdt.debug.ui.localJavaShortcut"; //$NON-NLS-1$
protected static final String TEST_LAUNCH_SHORTCUT = "org.eclipse.jdt.debug.tests.testShortCut";
/**
* an evaluation result
*/
public IEvaluationResult fEvaluationResult;
/**
* The last relevant event set - for example, that caused
* a thread to suspend
*/
protected DebugEvent[] fEventSet;
private static boolean loadedPrefs = false;
private static boolean loaded14 = false;
private static boolean loaded15 = false;
private static boolean loaded17 = false;
private static boolean loaded18 = false;
private static boolean loadedEE = false;
private static boolean loadedJRE = false;
private static boolean loadedMulti = false;
private static boolean welcomeClosed = false;
/**
* Constructor
* @param name
*/
public AbstractDebugTest(String name) {
super(name);
// set error dialog to non-blocking to avoid hanging the UI during test
ErrorDialog.AUTOMATED_MODE = true;
SafeRunnable.setIgnoreErrors(true);
}
@Override
protected void setUp() throws Exception {
TestUtil.log(IStatus.INFO, getName(), "setUp");
super.setUp();
setPreferences();
IProject pro = ResourcesPlugin.getWorkspace().getRoot().getProject(ONE_FOUR_PROJECT_NAME);
loaded14 = pro.exists();
pro = ResourcesPlugin.getWorkspace().getRoot().getProject(ONE_FIVE_PROJECT_NAME);
loaded15 = pro.exists();
pro = ResourcesPlugin.getWorkspace().getRoot().getProject(ONE_SEVEN_PROJECT_NAME);
loaded17 = pro.exists();
pro = ResourcesPlugin.getWorkspace().getRoot().getProject(ONE_EIGHT_PROJECT_NAME);
loaded18 = pro.exists();
pro = ResourcesPlugin.getWorkspace().getRoot().getProject(BOUND_JRE_PROJECT_NAME);
loadedJRE = pro.exists();
pro = ResourcesPlugin.getWorkspace().getRoot().getProject(BOUND_EE_PROJECT_NAME);
loadedEE = pro.exists();
pro = ResourcesPlugin.getWorkspace().getRoot().getProject(MULTI_OUTPUT_PROJECT_NAME);
loadedMulti = pro.exists();
assertWelcomeScreenClosed();
}
synchronized void setPreferences() throws BackingStoreException {
if(!loadedPrefs) {
IPreferenceStore debugUIPreferences = DebugUIPlugin.getDefault().getPreferenceStore();
// Don't prompt for perspective switching
debugUIPreferences.setValue(IInternalDebugUIConstants.PREF_SWITCH_PERSPECTIVE_ON_SUSPEND, MessageDialogWithToggle.ALWAYS);
debugUIPreferences.setValue(IInternalDebugUIConstants.PREF_SWITCH_TO_PERSPECTIVE, MessageDialogWithToggle.ALWAYS);
debugUIPreferences.setValue(IInternalDebugUIConstants.PREF_RELAUNCH_IN_DEBUG_MODE, MessageDialogWithToggle.NEVER);
debugUIPreferences.setValue(IInternalDebugUIConstants.PREF_WAIT_FOR_BUILD, MessageDialogWithToggle.ALWAYS);
debugUIPreferences.setValue(IInternalDebugUIConstants.PREF_CONTINUE_WITH_COMPILE_ERROR, MessageDialogWithToggle.ALWAYS);
debugUIPreferences.setValue(IInternalDebugUIConstants.PREF_SAVE_DIRTY_EDITORS_BEFORE_LAUNCH, MessageDialogWithToggle.NEVER);
String property = System.getProperty("debug.workbenchActivation");
boolean activate = property != null && property.equals("on");
debugUIPreferences.setValue(IDebugPreferenceConstants.CONSOLE_OPEN_ON_ERR, activate);
debugUIPreferences.setValue(IDebugPreferenceConstants.CONSOLE_OPEN_ON_OUT, activate);
debugUIPreferences.setValue(IInternalDebugUIConstants.PREF_ACTIVATE_DEBUG_VIEW, activate);
debugUIPreferences.setValue(IDebugUIConstants.PREF_ACTIVATE_WORKBENCH, activate);
IPreferenceStore jdiUIPreferences = JDIDebugUIPlugin.getDefault().getPreferenceStore();
// Turn off suspend on uncaught exceptions
jdiUIPreferences.setValue(IJDIPreferencesConstants.PREF_SUSPEND_ON_UNCAUGHT_EXCEPTIONS, false);
jdiUIPreferences.setValue(IJDIPreferencesConstants.PREF_SUSPEND_ON_COMPILATION_ERRORS, false);
// Don't warn about HCR failures
jdiUIPreferences.setValue(IJDIPreferencesConstants.PREF_ALERT_HCR_FAILED, false);
jdiUIPreferences.setValue(IJDIPreferencesConstants.PREF_ALERT_HCR_NOT_SUPPORTED, false);
jdiUIPreferences.setValue(IJDIPreferencesConstants.PREF_ALERT_OBSOLETE_METHODS, false);
// Set the timeout preference to a high value, to avoid timeouts while
// testing
JDIDebugModel.getPreferences().setDefault(JDIDebugModel.PREF_REQUEST_TIMEOUT, 10000);
// turn off monitor information
jdiUIPreferences.setValue(IJavaDebugUIConstants.PREF_SHOW_MONITOR_THREAD_INFO, false);
// turn off workbench heap monitor
PrefUtil.getAPIPreferenceStore().setValue(IWorkbenchPreferenceConstants.SHOW_MEMORY_MONITOR, false);
IWorkbenchWindow[] windows = PlatformUI.getWorkbench().getWorkbenchWindows();
for (int i = 0; i < windows.length; i++) {
IWorkbenchWindow window = windows[i];
if(window instanceof WorkbenchWindow){
((WorkbenchWindow) window).showHeapStatus(false);
}
}
//make sure we are auto-refreshing external workspace changes
IEclipsePreferences node = InstanceScope.INSTANCE.getNode(ResourcesPlugin.PI_RESOURCES);
if(node != null) {
node.putBoolean(ResourcesPlugin.PREF_AUTO_REFRESH, true);
node.putBoolean(ResourcesPlugin.PREF_LIGHTWEIGHT_AUTO_REFRESH, true);
node.flush();
}
loadedPrefs = true;
}
}
/**
* Creates the Java 1.4 compliant project
*/
synchronized void assert14Project() {
IJavaProject jp = null;
ArrayList<ILaunchConfiguration> cfgs = new ArrayList<>(1);
try {
if (!loaded14) {
try {
jp = JavaProjectHelper.createJavaProject(ONE_FOUR_PROJECT_CLOSED_NAME);
jp.getProject().close(null);
}
catch(Exception e) {
handleProjectCreationException(e, ONE_FOUR_PROJECT_CLOSED_NAME, jp);
}
jp = createProject(ONE_FOUR_PROJECT_NAME, JavaProjectHelper.TEST_SRC_DIR.toString(), JavaProjectHelper.J2SE_1_4_EE_NAME, false);
IPackageFragmentRoot src = jp.findPackageFragmentRoot(new Path(ONE_FOUR_PROJECT_NAME).append(JavaProjectHelper.SRC_DIR).makeAbsolute());
assertNotNull("The 'src' package fragment root should not be null", src);
File root = JavaTestPlugin.getDefault().getFileInPlugin(new Path("testjars"));
JavaProjectHelper.importFilesFromDirectory(root, src.getPath(), null);
IPath path = src.getPath().append("A.jar");
JavaProjectHelper.addLibrary(jp, path);
//add a closed project optional classpath entry
//see https://bugs.eclipse.org/bugs/show_bug.cgi?id=380918
IClasspathEntry entry = JavaCore.newProjectEntry(
new Path(ONE_FOUR_PROJECT_CLOSED_NAME).makeAbsolute(),
new IAccessRule[0],
false,
new IClasspathAttribute[] {JavaCore.newClasspathAttribute(IClasspathAttribute.OPTIONAL, Boolean.TRUE.toString())},
false);
JavaProjectHelper.addToClasspath(jp, entry);
// create launch configurations
for (int i = 0; i < LAUNCH_CONFIG_NAMES_1_4.length; i++) {
cfgs.add(createLaunchConfiguration(jp, LAUNCH_CONFIG_NAMES_1_4[i]));
}
loaded14 = true;
waitForBuild();
}
}
catch(Exception e) {
try {
if(jp != null) {
jp.getProject().delete(true, true, null);
}
for (int i = 0; i < cfgs.size(); i++) {
cfgs.get(i).delete();
}
}
catch (CoreException ce) {
//ignore
}
handleProjectCreationException(e, ONE_FOUR_PROJECT_NAME, jp);
}
}
/**
* Creates the Java 1.5 compliant project
*/
void assert15Project() {
IJavaProject jp = null;
ArrayList<ILaunchConfiguration> cfgs = new ArrayList<>(1);
try {
if (!loaded15) {
jp = createProject(ONE_FIVE_PROJECT_NAME, JavaProjectHelper.TEST_1_5_SRC_DIR.toString(), JavaProjectHelper.J2SE_1_5_EE_NAME, true);
cfgs.add(createLaunchConfiguration(jp, "a.b.c.MethodBreakpoints"));
cfgs.add(createLaunchConfiguration(jp, "a.b.c.IntegerAccess"));
cfgs.add(createLaunchConfiguration(jp, "a.b.c.StepIntoSelectionWithGenerics"));
cfgs.add(createLaunchConfiguration(jp, "a.b.c.ConditionalsNearGenerics"));
cfgs.add(createLaunchConfiguration(jp, "a.b.c.bug329294WithGenerics"));
cfgs.add(createLaunchConfiguration(jp, "a.b.c.bug403028"));
cfgs.add(createLaunchConfiguration(jp, "a.b.c.bug484686"));
cfgs.add(createLaunchConfiguration(jp, "a.b.c.GenericMethodEntryTest"));
cfgs.add(createLaunchConfiguration(jp, "org.eclipse.debug.tests.targets.HcrClass", true));
loaded15 = true;
waitForBuild();
}
}
catch(Exception e) {
try {
if(jp != null) {
jp.getProject().delete(true, true, null);
for (int i = 0; i < cfgs.size(); i++) {
cfgs.get(i).delete();
}
}
}
catch (CoreException ce) {
//ignore
}
handleProjectCreationException(e, ONE_FIVE_PROJECT_NAME, jp);
}
}
/**
* Creates the Java 1.7 compliant project
*/
synchronized void assert17Project() {
IJavaProject jp = null;
ArrayList<ILaunchConfiguration> cfgs = new ArrayList<>(1);
try {
if (!loaded17) {
jp = createProject(ONE_SEVEN_PROJECT_NAME, JavaProjectHelper.TEST_1_7_SRC_DIR.toString(), JavaProjectHelper.JAVA_SE_1_7_EE_NAME, false);
cfgs.add(createLaunchConfiguration(jp, LiteralTests17.LITERAL_TYPE_NAME));
loaded17 = true;
waitForBuild();
}
}
catch(Exception e) {
try {
if(jp != null) {
jp.getProject().delete(true, true, null);
for (int i = 0; i < cfgs.size(); i++) {
cfgs.get(i).delete();
}
}
}
catch (CoreException ce) {
//ignore
}
handleProjectCreationException(e, ONE_SEVEN_PROJECT_NAME, jp);
}
}
/**
* Creates the Java 1.8 compliant project
*/
synchronized void assert18Project() {
IJavaProject jp = null;
ArrayList<ILaunchConfiguration> cfgs = new ArrayList<>(1);
try {
if (!loaded18) {
jp = createProject(ONE_EIGHT_PROJECT_NAME, JavaProjectHelper.TEST_1_8_SRC_DIR.toString(), JavaProjectHelper.JAVA_SE_1_8_EE_NAME, false);
cfgs.add(createLaunchConfiguration(jp, "EvalTest18"));
cfgs.add(createLaunchConfiguration(jp, "EvalTestIntf18"));
cfgs.add(createLaunchConfiguration(jp, "EvalIntfSuperDefault"));
loaded18 = true;
waitForBuild();
}
}
catch(Exception e) {
try {
if(jp != null) {
jp.getProject().delete(true, true, null);
for (int i = 0; i < cfgs.size(); i++) {
cfgs.get(i).delete();
}
}
}
catch (CoreException ce) {
//ignore
}
handleProjectCreationException(e, ONE_SEVEN_PROJECT_NAME, jp);
}
}
/**
* Creates the 'BoundJRE' project used for the JRE testing
*/
synchronized void assertBoundJreProject() {
IJavaProject jp = null;
try {
if (!loadedJRE) {
jp =JavaProjectHelper.createJavaProject(BOUND_JRE_PROJECT_NAME);
JavaProjectHelper.addSourceContainer(jp, JavaProjectHelper.SRC_DIR, JavaProjectHelper.BIN_DIR);
// add VM specific JRE container
IPath path = JavaRuntime.newJREContainerPath(JavaRuntime.getDefaultVMInstall());
JavaProjectHelper.addContainerEntry(jp, path);
loadedJRE = true;
waitForBuild();
}
}
catch(Exception e) {
try {
if(jp != null) {
jp.getProject().delete(true, true, null);
}
}
catch (CoreException ce) {
//ignore
}
handleProjectCreationException(e, BOUND_JRE_PROJECT_NAME, jp);
}
}
/**
* Creates the 'BoundEE' project for EE testing
*/
void assertBoundeEeProject() {
IJavaProject jp = null;
try {
if(!loadedEE) {
// create project with two src folders and output locations
jp = JavaProjectHelper.createJavaProject(BOUND_EE_PROJECT_NAME);
JavaProjectHelper.addSourceContainer(jp, JavaProjectHelper.SRC_DIR, JavaProjectHelper.BIN_DIR);
// add VM specific JRE container
IExecutionEnvironment j2se14 = JavaRuntime.getExecutionEnvironmentsManager().getEnvironment(JavaProjectHelper.J2SE_1_4_EE_NAME);
assertNotNull("Missing J2SE-1.4 environment", j2se14);
IPath path = JavaRuntime.newJREContainerPath(j2se14);
JavaProjectHelper.addContainerEntry(jp, path);
loadedEE = true;
waitForBuild();
}
}
catch(Exception e) {
try {
if(jp != null) {
jp.getProject().delete(true, true, null);
}
}
catch (CoreException ce) {
//ignore
}
handleProjectCreationException(e, BOUND_EE_PROJECT_NAME, jp);
}
}
/**
* Creates the 'MultiOutput' project for source / binary output testing
*/
synchronized void assertMultioutputProject() {
IJavaProject jp = null;
try {
if(!loadedMulti) {
// create project with two src folders and output locations
jp = JavaProjectHelper.createJavaProject(MULTI_OUTPUT_PROJECT_NAME);
JavaProjectHelper.addSourceContainer(jp, "src1", "bin1");
JavaProjectHelper.addSourceContainer(jp, "src2", "bin2");
// add rt.jar
IVMInstall vm = JavaRuntime.getDefaultVMInstall();
assertNotNull("No default JRE", vm);
JavaProjectHelper.addContainerEntry(jp, new Path(JavaRuntime.JRE_CONTAINER));
loadedMulti = true;
waitForBuild();
}
}
catch(Exception e) {
try {
if(jp != null) {
jp.getProject().delete(true, true, null);
}
}
catch (CoreException ce) {
//ignore
}
handleProjectCreationException(e, MULTI_OUTPUT_PROJECT_NAME, jp);
}
}
/**
* Ensure the welcome screen is closed because in 4.x the debug perspective opens a giant fast-view causing issues
*
* @throws Exception
* @since 3.8
*/
protected final void assertWelcomeScreenClosed() throws Exception {
if(!welcomeClosed && PlatformUI.isWorkbenchRunning()) {
final IWorkbench wb = PlatformUI.getWorkbench();
if (wb == null) {
return;
}
// In UI thread we don't need to run a job
if (Display.getCurrent() != null) {
closeIntro(wb);
return;
}
UIJob job = new UIJob("close welcome screen for debug test suite") {
@Override
public IStatus runInUIThread(IProgressMonitor monitor) {
closeIntro(wb);
return Status.OK_STATUS;
}
};
job.setPriority(Job.INTERACTIVE);
job.setSystem(true);
job.schedule();
}
}
private static void closeIntro(final IWorkbench wb) {
IWorkbenchWindow window = wb.getActiveWorkbenchWindow();
if (window != null) {
IIntroManager im = wb.getIntroManager();
IIntroPart intro = im.getIntro();
if (intro != null) {
welcomeClosed = im.closeIntro(intro);
}
}
}
void handleProjectCreationException(Exception e, String pname, IJavaProject jp) {
StringWriter buf = new StringWriter();
String msg = e.getMessage();
if(msg == null) {
msg = "could not acquire message for exception class: " + e.getClass();
}
buf.write("Failed to create the '" + pname + "' test project.\n");
buf.write("'jp' is " + (jp != null ? "not " : "") + " 'null'\n");
buf.write("Stack tace:\n");
e.printStackTrace(new PrintWriter(buf));
fail(buf.toString());
}
/**
* Sets the contents of the given {@link ICompilationUnit} to be the new contents provided
* @param unit
* @param contents the new {@link String} contents, cannot be <code>null</code>
* @throws JavaModelException
*/
protected void setFileContents(ICompilationUnit unit, String contents) throws JavaModelException {
assertNotNull("You cannot set the new contents of an ICompilationUnit to null", contents);
IBuffer buffer = unit.getBuffer();
buffer.setContents(contents);
unit.save(null, true);
waitForBuild();
}
/**
* Sets the last relevant event set
*
* @param set event set
*/
protected void setEventSet(DebugEvent[] set) {
fEventSet = set;
}
/**
* Returns the last relevant event set
*
* @return event set
*/
protected DebugEvent[] getEventSet() {
return fEventSet;
}
/**
* Returns the launch manager
*
* @return launch manager
*/
protected ILaunchManager getLaunchManager() {
return DebugPlugin.getDefault().getLaunchManager();
}
/**
* Returns the singleton instance of the <code>LaunchConfigurationManager</code>
*
* @return the singleton instance of the <code>LaunchConfigurationManager</code>
* @since 3.3
*/
protected LaunchConfigurationManager getLaunchConfigurationManager() {
return DebugUIPlugin.getDefault().getLaunchConfigurationManager();
}
/**
* Returns the breakpoint manager
*
* @return breakpoint manager
*/
protected IBreakpointManager getBreakpointManager() {
return DebugPlugin.getDefault().getBreakpointManager();
}
/**
* Returns the project context for the current test - each
* test must implement this method
*/
protected IJavaProject getProjectContext() {
return get14Project();
}
/**
* Returns the 'DebugTests' project.
*
* @return the test project
*/
protected IJavaProject get14Project() {
assert14Project();
return getJavaProject(ONE_FOUR_PROJECT_NAME);
}
/**
* Returns the {@link IBreakpointOrganizer} with the given id or <code>null</code>
* if no such organizer exists
* @param id
* @return the {@link IBreakpointOrganizer} or <code>null</code>
* @since 3.8.100
*/
protected IBreakpointOrganizer getOrganizer(String id) {
return BreakpointOrganizerManager.getDefault().getOrganizer(id);
}
/**
* Returns the 'OneFive' project.
*
* @return the test project
*/
protected IJavaProject get15Project() {
assert15Project();
return getJavaProject(ONE_FIVE_PROJECT_NAME);
}
/**
* Returns the 'OneSeven' project.
*
* @return the test project
*/
protected IJavaProject get17Project() {
assert17Project();
return getJavaProject(ONE_SEVEN_PROJECT_NAME);
}
/**
* Returns the 'OneSeven' project.
*
* @return the test project
*/
protected IJavaProject get18Project() {
assert18Project();
return getJavaProject(ONE_EIGHT_PROJECT_NAME);
}
/**
* Returns the 'BoundJRE' project
*
* @return the test project
*/
protected IJavaProject getBoundJreProject() {
assertBoundJreProject();
return getJavaProject(BOUND_JRE_PROJECT_NAME);
}
/**
* Returns the 'BoundEE' project
*
* @return the test project
*/
protected IJavaProject getBoundEeProject() {
assertBoundeEeProject();
return getJavaProject(BOUND_EE_PROJECT_NAME);
}
/**
* Returns the 'MultiOutput' project
*
* @return the test project
*/
protected IJavaProject getMultiOutputProject() {
assertMultioutputProject();
return getJavaProject(MULTI_OUTPUT_PROJECT_NAME);
}
/**
* Returns the Java project with the given name.
*
* @param name project name
* @return the Java project with the given name
*/
protected IJavaProject getJavaProject(String name) {
IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject(name);
return JavaCore.create(project);
}
/**
* Creates a new {@link IJavaProject} with the given name and optionally initializing it from the given
* resource path from the testing bundle.
* <br><br>
* The project has the default <code>src</code> and <code>bin</code> folders. It is also created with a default
* <code>launchConfigurations</code> folder.
*
* @param name the name for the project
* @param contentpath the path within the jdt.debug test bundle to initialize the source from
* @param ee the level of execution environment to use
* @param if an existing project should be deleted
* @return the new Java project
* @throws Exception
*/
protected IJavaProject createProject(String name, String contentpath, String ee, boolean delete) throws Exception {
IProject pro = ResourcesPlugin.getWorkspace().getRoot().getProject(name);
if (pro.exists() && delete) {
try {
pro.delete(true, true, null);
}
catch(Exception e) {}
}
// create project and import source
IJavaProject jp = JavaProjectHelper.createJavaProject(name, JavaProjectHelper.BIN_DIR);
IPackageFragmentRoot src = JavaProjectHelper.addSourceContainer(jp, JavaProjectHelper.SRC_DIR);
File root = JavaTestPlugin.getDefault().getFileInPlugin(new Path(contentpath));
JavaProjectHelper.importFilesFromDirectory(root, src.getPath(), null);
// add the EE library
IVMInstall vm = JavaRuntime.getDefaultVMInstall();
assertNotNull("No default JRE", vm);
IExecutionEnvironment environment = JavaRuntime.getExecutionEnvironmentsManager().getEnvironment(ee);
assertNotNull("The EE ["+ee+"] does not exist", environment);
IPath containerPath = JavaRuntime.newJREContainerPath(environment);
JavaProjectHelper.addContainerEntry(jp, containerPath);
pro = jp.getProject();
JavaProjectHelper.updateCompliance(jp, ee);
// create launch configuration folder
IFolder folder = pro.getFolder("launchConfigurations");
if (!folder.exists()) {
folder.create(true, true, null);
}
return jp;
}
/**
* Creates a new {@link IJavaProject} with the given name and initializes the contents from the given
* resource path from the testing bundle.
* <br><br>
* The project has the default <code>src</code> and <code>bin</code> folders. It is also created with a default
* <code>launchConfigurations</code> folder.
*
* @param name the name for the project
* @param contentpath the path within the jdt.debug test bundle to initialize the source from
* @param ee the level of execution environment to use
* @param if an existing project should be deleted
* @return the new Java project
* @throws Exception
*/
protected IJavaProject createJavaProjectClone(String name, String contentpath, String ee, boolean delete) throws Exception {
IProject pro = ResourcesPlugin.getWorkspace().getRoot().getProject(name);
String owner = "Creating project: " + name;
if (pro.exists() && delete) {
pro.delete(true, true, null);
TestUtil.waitForJobs(owner, 100, 10000);
TestUtil.runEventLoop();
}
// create project and import source
IJavaProject jp = JavaProjectHelper.createJavaProject(name, JavaProjectHelper.BIN_DIR);
TestUtil.waitForJobs(owner, 100, 10000);
TestUtil.runEventLoop();
JavaProjectHelper.addSourceContainer(jp, JavaProjectHelper.SRC_DIR);
TestUtil.waitForJobs(owner, 100, 10000);
TestUtil.runEventLoop();
File root = JavaTestPlugin.getDefault().getFileInPlugin(new Path(contentpath));
JavaProjectHelper.importFilesFromDirectory(root, jp.getPath(), null);
TestUtil.waitForJobs(owner, 100, 10000);
TestUtil.runEventLoop();
// add the EE library
IVMInstall vm = JavaRuntime.getDefaultVMInstall();
assertNotNull("No default JRE", vm);
IExecutionEnvironment environment = JavaRuntime.getExecutionEnvironmentsManager().getEnvironment(ee);
assertNotNull("The EE ["+ee+"] does not exist", environment);
IPath containerPath = JavaRuntime.newJREContainerPath(environment);
JavaProjectHelper.addContainerEntry(jp, containerPath);
pro = jp.getProject();
// create launch configuration folder
IFolder folder = pro.getFolder("launchConfigurations");
if (!folder.exists()) {
folder.create(true, true, null);
}
TestUtil.waitForJobs(owner, 100, 10000);
TestUtil.runEventLoop();
return jp;
}
/**
* Creates a new {@link IProject} with the given name and initializes the contents from the given
* resource path from the testing bundle.
*
* @param name the name for the project
* @param contentpath the path within the jdt.debug test bundle to initialize the source from
* @param if an existing project should be deleted
* @return the new project
* @throws Exception
*/
protected IProject createProjectClone(String name, String contentpath, boolean delete) throws Exception {
IProject pro = ResourcesPlugin.getWorkspace().getRoot().getProject(name);
String owner = "Creating project: " + name;
if (pro.exists() && delete) {
pro.delete(true, true, null);
TestUtil.waitForJobs(owner, 100, 10000);
TestUtil.runEventLoop();
}
// create project and import source
IProject pj = JavaProjectHelper.createProject(name);
TestUtil.waitForJobs(owner, 100, 10000);
TestUtil.runEventLoop();
File root = JavaTestPlugin.getDefault().getFileInPlugin(new Path(contentpath));
JavaProjectHelper.importFilesFromDirectory(root, pj.getFullPath(), null);
TestUtil.waitForJobs(owner, 100, 10000);
TestUtil.runEventLoop();
return pj;
}
/**
* Returns the launch shortcut with the given id
* @param id
* @return the <code>LaunchShortcutExtension</code> with the given id,
* or <code>null</code> if none
*
* @since 3.3
*/
protected LaunchShortcutExtension getLaunchShortcutExtension(String id) {
List<?> exts = getLaunchConfigurationManager().getLaunchShortcuts();
LaunchShortcutExtension ext = null;
for (int i = 0; i < exts.size(); i++) {
ext = (LaunchShortcutExtension) exts.get(i);
if(ext.getId().equals(id)) {
return ext;
}
}
return null;
}
/**
* New to 3.3 is the ability to have multiple delegates for a variety of overlapping mode combinations.
* As such, for tests that launch specific configurations, must be check to ensure that there is a preferred
* launch delegate available for the launch in the event there are duplicates. Otherwise the tests
* will hang waiting for a user to select a resolution action.
* @param configuration
* @param modes
* @throws CoreException
*
* @since 3.3
*/
protected void ensurePreferredDelegate(ILaunchConfiguration configuration, Set<String> modes) throws CoreException {
ILaunchConfigurationType type = configuration.getType();
ILaunchDelegate[] delegates = type.getDelegates(modes);
if(delegates.length > 1) {
type.setPreferredDelegate(modes, getDelegateById(type.getIdentifier(), LOCAL_JAVA_APPLICATION_TYPE_ID));
}
}
/**
* Returns the LaunchDelegate for the specified ID
* @param delegateId the id of the delegate to search for
* @return the <code>LaunchDelegate</code> associated with the specified id or <code>null</code> if not found
* @since 3.3
*/
protected ILaunchDelegate getDelegateById(String typeId, String delegateId) {
LaunchManager lm = (LaunchManager) getLaunchManager();
LaunchDelegate[] delegates = lm.getLaunchDelegates(typeId);
for(int i = 0; i < delegates.length; i++) {
if(delegates[i].getId().equals(delegateId)) {
return delegates[i];
}
}
return null;
}
/**
* Returns the source folder with the given name in the given project.
*
* @param project
* @param name source folder name
* @return package fragment root
*/
protected IPackageFragmentRoot getPackageFragmentRoot(IJavaProject project, String name) {
IProject p = project.getProject();
return project.getPackageFragmentRoot(p.getFolder(name));
}
/**
* Returns the <code>IHyperLink</code> at the given offset in the specified document
* or <code>null</code> if the offset does not point to an <code>IHyperLink</code>
* @param offset
* @param doc
* @return the <code>IHyperLink</code> at the given offset or <code>null</code>
*/
protected IHyperlink getHyperlink(int offset, IDocument doc) {
if (offset >= 0 && doc != null) {
Position[] positions = null;
try {
positions = doc.getPositions(ConsoleHyperlinkPosition.HYPER_LINK_CATEGORY);
} catch (BadPositionCategoryException ex) {
// no links have been added
return null;
}
for (int i = 0; i < positions.length; i++) {
Position position = positions[i];
if (offset >= position.getOffset() && offset <= (position.getOffset() + position.getLength())) {
return ((ConsoleHyperlinkPosition)position).getHyperLink();
}
}
}
return null;
}
/**
* Launches the given configuration and waits for an event. Returns the
* source of the event. If the event is not received, the launch is
* terminated and an exception is thrown.
*
* @param configuration the configuration to launch
* @param waiter the event waiter to use
* @return Object the source of the event
* @exception Exception if the event is never received.
*/
protected Object launchAndWait(ILaunchConfiguration configuration, DebugEventWaiter waiter) throws CoreException {
return launchAndWait(configuration, waiter, true);
}
/**
* Launches the given configuration in debug mode and waits for an event.
* Returns the source of the event. If the event is not received, the
* launch is terminated and an exception is thrown.
*
* @param configuration the configuration to launch
* @param waiter the event waiter to use
* @param register whether to register the launch
* @return Object the source of the event
* @exception Exception if the event is never received.
*/
protected Object launchAndWait(ILaunchConfiguration configuration, DebugEventWaiter waiter, boolean register) throws CoreException {
return launchAndWait(configuration, ILaunchManager.DEBUG_MODE, waiter, register);
}
/**
* Launches the given configuration and waits for an event. Returns the
* source of the event. If the event is not received, the launch is
* terminated and an exception is thrown.
*
* @param configuration the configuration to launch
* @param mode the mode to launch the configuration in
* @param waiter the event waiter to use
* @param register whether to register the launch
* @return Object the source of the event
* @exception Exception if the event is never received.
*/
protected Object launchAndWait(ILaunchConfiguration configuration, String mode, DebugEventWaiter waiter, boolean register) throws CoreException {
ILaunch launch = configuration.launch(mode, null, false, register);
Object suspendee= waiter.waitForEvent();
if (suspendee == null) {
StringBuffer buf = new StringBuffer();
buf.append("Test case: "); //$NON-NLS-1$
buf.append(getName());
buf.append("\n"); //$NON-NLS-1$
buf.append("Never received event: "); //$NON-NLS-1$
buf.append(waiter.getEventKindName());
buf.append("\n"); //$NON-NLS-1$
if (launch.isTerminated()) {
buf.append("Process exit value: "); //$NON-NLS-1$
buf.append(launch.getProcesses()[0].getExitValue());
buf.append("\n"); //$NON-NLS-1$
}
IConsole console = DebugUITools.getConsole(launch.getProcesses()[0]);
if (console instanceof TextConsole) {
TextConsole textConsole = (TextConsole)console;
String string = textConsole.getDocument().get();
buf.append("Console output follows:\n"); //$NON-NLS-1$
buf.append(string);
}
buf.append("\n"); //$NON-NLS-1$
DebugPlugin.log(new Status(IStatus.ERROR, "org.eclipse.jdt.debug.ui.tests", buf.toString())); //$NON-NLS-1$
try {
launch.terminate();
} catch (CoreException e) {
e.printStackTrace();
fail("Program did not suspend, and unable to terminate launch."); //$NON-NLS-1$
}
throw new TestAgainException("Program did not suspend, launch terminated.");
}
setEventSet(waiter.getEventSet());
assertNotNull("Program did not suspend, launch terminated.", suspendee); //$NON-NLS-1$
return suspendee;
}
/**
* Launches the type with the given name, and waits for a
* suspend event in that program. Returns the thread in which the suspend
* event occurred.
*
* @param mainTypeName the program to launch
* @return thread in which the first suspend event occurred
*/
protected IJavaThread launchAndSuspend(String mainTypeName) throws Exception {
ILaunchConfiguration config = getLaunchConfiguration(mainTypeName);
assertNotNull("Could not locate launch configuration for " + mainTypeName, config); //$NON-NLS-1$
return launchAndSuspend(config);
}
/**
* Launches the given configuration in debug mode, and waits for a
* suspend event in that program. Returns the thread in which the suspend
* event occurred.
*
* @param config the configuration to launch
* @return thread in which the first suspend event occurred
*/
protected IJavaThread launchAndSuspend(ILaunchConfiguration config) throws Exception {
DebugEventWaiter waiter= new DebugElementKindEventWaiter(DebugEvent.SUSPEND, IJavaThread.class);
waiter.setTimeout(DEFAULT_TIMEOUT);
Object suspendee = launchAndWait(config, waiter);
return (IJavaThread)suspendee;
}
/**
* Launches the type with the given name, and waits for a breakpoint-caused
* suspend event in that program. Returns the thread in which the suspend
* event occurred.
*
* @param mainTypeName the program to launch
* @return thread in which the first suspend event occurred
*/
protected IJavaThread launchToBreakpoint(String mainTypeName) throws Exception {
return launchToBreakpoint(getProjectContext(), mainTypeName);
}
/**
* Launches the type with the given name, and waits for a breakpoint-caused
* suspend event in that program. Returns the thread in which the suspend
* event occurred.
*
* @param project the project the type is in
* @param mainTypeName the program to launch
* @return thread in which the first suspend event occurred
*/
protected IJavaThread launchToBreakpoint(IJavaProject project, String mainTypeName) throws Exception {
return launchToBreakpoint(project, mainTypeName, true);
}
/**
* Launches the type with the given name, and waits for a breakpoint-caused
* suspend event in that program. Returns the thread in which the suspend
* event occurred.
*
* @param mainTypeName the program to launch
* @param register whether to register the launch
* @return thread in which the first suspend event occurred
*/
protected IJavaThread launchToBreakpoint(String mainTypeName, boolean register) throws Exception {
return launchToBreakpoint(getProjectContext(), mainTypeName, register);
}
/**
* Launches the type with the given name, and waits for a breakpoint-caused
* suspend event in that program. Returns the thread in which the suspend
* event occurred.
*
* @param mainTypeName the program to launch
* @param register whether to register the launch
* @return thread in which the first suspend event occurred
*/
protected IJavaThread launchToBreakpoint(IJavaProject project, String mainTypeName, boolean register) throws Exception {
ILaunchConfiguration config = getLaunchConfiguration(project, mainTypeName);
assertNotNull("Could not locate launch configuration for " + mainTypeName, config); //$NON-NLS-1$
return launchToBreakpoint(config, register);
}
/**
* Launches the type with the given name, and waits for a breakpoint-caused
* suspend event in that program. Returns the thread in which the suspend
* event occurred.
*
* @param mainTypeName the program to launch
* @param register whether to register the launch
* @return thread in which the first suspend event occurred
*/
protected IJavaThread launchToBreakpoint(IJavaProject project, String mainTypeName, String launchName, boolean register) throws Exception {
ILaunchConfiguration config = getLaunchConfiguration(project, launchName);
assertNotNull("Could not locate launch configuration for " + mainTypeName, config); //$NON-NLS-1$
return launchToBreakpoint(config, register);
}
/**
* Launches the given configuration in debug mode, and waits for a breakpoint-caused
* suspend event in that program. Returns the thread in which the suspend
* event occurred.
*
* @param config the configuration to launch
* @return thread in which the first suspend event occurred
*/
protected IJavaThread launchToBreakpoint(ILaunchConfiguration config) throws CoreException {
return launchToBreakpoint(config, true);
}
/**
* Launches the given configuration in debug mode, and waits for a breakpoint-caused
* suspend event in that program. Returns the thread in which the suspend
* event occurred.
*
* @param config the configuration to launch
* @param whether to register the launch
* @return thread in which the first suspend event occurred
*/
protected IJavaThread launchToBreakpoint(ILaunchConfiguration config, boolean register) throws CoreException {
DebugEventWaiter waiter= new DebugElementKindEventDetailWaiter(DebugEvent.SUSPEND, IJavaThread.class, DebugEvent.BREAKPOINT);
waiter.setTimeout(DEFAULT_TIMEOUT);
Object suspendee= launchAndWait(config, waiter, register);
assertTrue("suspendee was not an IJavaThread", suspendee instanceof IJavaThread); //$NON-NLS-1$
return (IJavaThread)suspendee;
}
/**
* Launches the type with the given name, and waits for a terminate
* event in that program. Returns the debug target in which the suspend
* event occurred.
*
* @param mainTypeName the program to launch
* @param timeout the number of milliseconds to wait for a terminate event
* @return debug target in which the terminate event occurred
*/
protected IJavaDebugTarget launchAndTerminate(String mainTypeName) throws Exception {
ILaunchConfiguration config = getLaunchConfiguration(mainTypeName);
assertNotNull("Could not locate launch configuration for " + mainTypeName, config); //$NON-NLS-1$
return launchAndTerminate(config, DEFAULT_TIMEOUT);
}
/**
* Launches the given configuration in debug mode, and waits for a terminate
* event in that program. Returns the debug target in which the terminate
* event occurred.
*
* @param config the configuration to launch
* @param timeout the number of milliseconds to wait for a terminate event
* @return thread in which the first suspend event occurred
*/
protected IJavaDebugTarget launchAndTerminate(ILaunchConfiguration config, int timeout) throws Exception {
return launchAndTerminate(config, timeout, true);
}
/**
* Launches the given configuration in debug mode, and waits for a terminate
* event in that program. Returns the debug target in which the terminate
* event occurred.
*
* @param config the configuration to launch
* @param timeout the number of milliseconds to wait for a terminate event
* @param register whether to register the launch
* @return thread in which the first suspend event occurred
*/
protected IJavaDebugTarget launchAndTerminate(ILaunchConfiguration config, int timeout, boolean register) throws Exception {
DebugEventWaiter waiter= new DebugElementKindEventWaiter(DebugEvent.TERMINATE, IJavaDebugTarget.class);
waiter.setTimeout(timeout);
Object terminatee = launchAndWait(config, waiter, register);
assertNotNull("Program did not terminate.", terminatee); //$NON-NLS-1$
assertTrue("terminatee is not an IJavaDebugTarget", terminatee instanceof IJavaDebugTarget); //$NON-NLS-1$
IJavaDebugTarget debugTarget = (IJavaDebugTarget) terminatee;
assertTrue("debug target is not terminated", debugTarget.isTerminated() || debugTarget.isDisconnected()); //$NON-NLS-1$
return debugTarget;
}
/**
* Launches the type with the given name, and waits for a line breakpoint suspend
* event in that program. Returns the thread in which the suspend
* event occurred.
*
* @param mainTypeName the program to launch
* @param bp the breakpoint that should cause a suspend event
* @return thread in which the first suspend event occurred
*/
protected IJavaThread launchToLineBreakpoint(String mainTypeName, ILineBreakpoint bp) throws Exception {
return launchToLineBreakpoint(mainTypeName, bp, true);
}
/**
* Launches the type with the given name, and waits for a line breakpoint suspend
* event in that program. Returns the thread in which the suspend
* event occurred.
*
* @param mainTypeName the program to launch
* @param bp the breakpoint that should cause a suspend event
* @param register whether to register the launch
* @return thread in which the first suspend event occurred
*/
protected IJavaThread launchToLineBreakpoint(String mainTypeName, ILineBreakpoint bp, boolean register) throws Exception {
ILaunchConfiguration config = getLaunchConfiguration(mainTypeName);
assertNotNull("Could not locate launch configuration for " + mainTypeName, config); //$NON-NLS-1$
return launchToLineBreakpoint(config, bp, register);
}
/**
* Launches the given configuration in debug mode, and waits for a line breakpoint
* suspend event in that program. Returns the thread in which the suspend
* event occurred.
*
* @param config the configuration to launch
* @param bp the breakpoint that should cause a suspend event
* @return thread in which the first suspend event occurred
*/
protected IJavaThread launchToLineBreakpoint(ILaunchConfiguration config, ILineBreakpoint bp, boolean register) throws Exception {
DebugEventWaiter waiter= new DebugElementKindEventDetailWaiter(DebugEvent.SUSPEND, IJavaThread.class, DebugEvent.BREAKPOINT);
waiter.setTimeout(DEFAULT_TIMEOUT);
Object suspendee= launchAndWait(config, waiter, register);
assertTrue("suspendee was not an IJavaThread", suspendee instanceof IJavaThread); //$NON-NLS-1$
IJavaThread thread = (IJavaThread) suspendee;
IBreakpoint hit = getBreakpoint(thread);
assertNotNull("suspended, but not by breakpoint", hit); //$NON-NLS-1$
assertTrue("hit un-registered breakpoint", bp.equals(hit)); //$NON-NLS-1$
assertTrue("suspended, but not by line breakpoint", hit instanceof ILineBreakpoint); //$NON-NLS-1$
ILineBreakpoint breakpoint= (ILineBreakpoint) hit;
int lineNumber = breakpoint.getLineNumber();
int stackLine = thread.getTopStackFrame().getLineNumber();
assertTrue("line numbers of breakpoint and stack frame do not match", lineNumber == stackLine); //$NON-NLS-1$
return thread;
}
/**
* Returns the standard java launch tab group
* @return the standard java launch tab group
* @throws CoreException
*
* @since 3.3
*/
protected ILaunchConfigurationTabGroup getJavaLaunchGroup() throws CoreException {
ILaunchConfigurationType javaType = getLaunchManager().getLaunchConfigurationType(IJavaLaunchConfigurationConstants.ID_JAVA_APPLICATION);
ILaunchConfigurationTabGroup standardGroup = LaunchConfigurationPresentationManager.getDefault().getTabGroup(javaType, ILaunchManager.DEBUG_MODE);
return standardGroup;
}
/**
* Returns an instance of the launch configuration dialog on the the specified launch mode
* @param modeid the id of the mode to open the launch dialog on
* @return an new instance of <code>IlaunchConfigurationDialog</code>
*
* @since 3.3
*/
protected ILaunchConfigurationDialog getLaunchConfigurationDialog(String modeid) {
return new LaunchConfigurationsDialog(null, DebugUIPlugin.getDefault().getLaunchConfigurationManager().getLaunchGroup(modeid));
}
/**
* Resumes the given thread, and waits for another breakpoint-caused suspend event.
* Returns the thread in which the suspend event occurs.
*
* @param thread thread to resume
* @return thread in which the first suspend event occurs
*/
protected IJavaThread resume(IJavaThread thread) throws Exception {
return resume(thread, DEFAULT_TIMEOUT);
}
/**
* Resumes the given thread, and waits for another breakpoint-caused suspend event.
* Returns the thread in which the suspend event occurs.
*
* @param thread thread to resume
* @param timeout timeout in milliseconds
* @return thread in which the first suspend event occurs
*/
protected IJavaThread resume(IJavaThread thread, int timeout) throws Exception {
DebugEventWaiter waiter= new DebugElementKindEventDetailWaiter(DebugEvent.SUSPEND, IJavaThread.class, DebugEvent.BREAKPOINT);
waiter.setTimeout(timeout);
thread.resume();
Object suspendee= waiter.waitForEvent();
setEventSet(waiter.getEventSet());
assertNotNull("Program did not suspend.", suspendee); //$NON-NLS-1$
return (IJavaThread)suspendee;
}
/**
* Resumes the given thread, and waits for a suspend event caused by the specified
* line breakpoint. Returns the thread in which the suspend event occurs.
*
* @param thread thread to resume
* @return thread in which the first suspend event occurs
*/
protected IJavaThread resumeToLineBreakpoint(IJavaThread resumeThread, ILineBreakpoint bp) throws Exception {
DebugEventWaiter waiter= new DebugElementKindEventDetailWaiter(DebugEvent.SUSPEND, IJavaThread.class, DebugEvent.BREAKPOINT);
waiter.setTimeout(DEFAULT_TIMEOUT);
resumeThread.resume();
Object suspendee= waiter.waitForEvent();
setEventSet(waiter.getEventSet());
assertNotNull("Program did not suspend.", suspendee); //$NON-NLS-1$
assertTrue("suspendee was not an IJavaThread", suspendee instanceof IJavaThread); //$NON-NLS-1$
IJavaThread thread = (IJavaThread) suspendee;
IBreakpoint hit = getBreakpoint(thread);
assertNotNull("suspended, but not by breakpoint", hit); //$NON-NLS-1$
assertTrue("hit un-registered breakpoint", bp.equals(hit)); //$NON-NLS-1$
assertTrue("suspended, but not by line breakpoint", hit instanceof ILineBreakpoint); //$NON-NLS-1$
ILineBreakpoint breakpoint= (ILineBreakpoint) hit;
int lineNumber = breakpoint.getLineNumber();
int stackLine = thread.getTopStackFrame().getLineNumber();
assertTrue("line numbers of breakpoint and stack frame do not match", lineNumber == stackLine); //$NON-NLS-1$
return (IJavaThread)suspendee;
}
/**
* Resumes the given thread, and waits for the debug target
* to terminate (i.e. finish/exit the program).
*
* @param thread thread to resume
*/
protected void exit(IJavaThread thread) throws Exception {
DebugEventWaiter waiter= new DebugElementKindEventWaiter(DebugEvent.TERMINATE, IProcess.class);
waiter.setTimeout(DEFAULT_TIMEOUT);
thread.resume();
Object suspendee= waiter.waitForEvent();
setEventSet(waiter.getEventSet());
assertNotNull("Program did not terminate.", suspendee); //$NON-NLS-1$
}
/**
* Resumes the given thread, and waits the associated debug
* target to terminate.
*
* @param thread thread to resume
* @return the terminated debug target
*/
protected IJavaDebugTarget resumeAndExit(IJavaThread thread) throws Exception {
DebugEventWaiter waiter= new DebugElementEventWaiter(DebugEvent.TERMINATE, thread.getDebugTarget());
waiter.setTimeout(DEFAULT_TIMEOUT);
thread.resume();
Object suspendee= waiter.waitForEvent();
setEventSet(waiter.getEventSet());
assertNotNull("Program did not terminate.", suspendee); //$NON-NLS-1$
IJavaDebugTarget target = (IJavaDebugTarget)suspendee;
assertTrue("program should have exited", target.isTerminated() || target.isDisconnected()); //$NON-NLS-1$
return target;
}
/**
* Returns the launch configuration for the given main type
*
* @param mainTypeName program to launch
* @see ProjectCreationDecorator
*/
protected ILaunchConfiguration getLaunchConfiguration(String mainTypeName) {
return getLaunchConfiguration(getProjectContext(), mainTypeName);
}
/**
* Returns the launch configuration for the given main type
*
* @param mainTypeName program to launch
* @see ProjectCreationDecorator
*/
protected ILaunchConfiguration getLaunchConfiguration(IJavaProject project, String mainTypeName) {
IFile file = project.getProject().getFolder(LAUNCHCONFIGURATIONS).getFile(mainTypeName + LAUNCH_EXTENSION);
ILaunchConfiguration config = getLaunchManager().getLaunchConfiguration(file);
assertNotNull("the configuration cannot be null", config);
assertTrue("Could not find launch configuration for " + mainTypeName, config.exists()); //$NON-NLS-1$
return config;
}
/**
* Returns the launch configuration in the specified folder in the given project, for the given main type
*
* @param project the project to look in
* @param containername the name of the container in the specified project to look for the config
* @param mainTypeName program to launch
* @see ProjectCreationDecorator
*/
protected ILaunchConfiguration getLaunchConfiguration(IJavaProject project, String containername, String mainTypeName) {
IFile file = project.getProject().getFolder(containername).getFile(mainTypeName + LAUNCH_EXTENSION);
ILaunchConfiguration config = getLaunchManager().getLaunchConfiguration(file);
assertNotNull("the configuration cannot be null", config);
assertTrue("Could not find launch configuration for " + mainTypeName, config.exists()); //$NON-NLS-1$
return config;
}
/**
* Returns the corresponding <code>IResource</code> from the <code>IJavaElement</code> with the
* specified name
* @param typeName the name of the <code>IJavaElement</code> to get the resource for
* @return the corresponding <code>IResource</code> from the <code>IJavaElement</code> with the
* specified name
* @throws Exception
*/
protected IResource getBreakpointResource(String typeName) throws Exception {
IJavaElement element = getProjectContext().findElement(new Path(typeName + JAVA_EXTENSION));
IResource resource = element.getCorrespondingResource();
if (resource == null) {
resource = getProjectContext().getProject();
}
return resource;
}
/**
* Returns the resource from the specified type or the project from the testing java project in the
* event there is no resource from the specified type
* @param type
* @return
* @throws Exception
*/
protected IResource getBreakpointResource(IType type) throws Exception {
if (type == null) {
return getProjectContext().getProject();
}
IResource resource = type.getResource();
if (resource == null) {
resource = type.getJavaProject().getProject();
}
return resource;
}
/**
* Creates and returns a line breakpoint at the given line number in the type with the
* given name.
*
* @param lineNumber line number
* @param typeName type name
*/
protected IJavaLineBreakpoint createLineBreakpoint(int lineNumber, String typeName) throws Exception {
IType type = getType(typeName);
assertNotNull("Could not find the requested IType: "+typeName, type);
return createLineBreakpoint(type, lineNumber);
}
/**
* Creates am new java line breakpoint
* @param lineNumber
* @param root
* @param packageName
* @param cuName
* @param fullTargetName
* @return a new line breakpoint
*/
protected IJavaLineBreakpoint createLineBreakpoint(int lineNumber, String root, String packageName, String cuName,
String fullTargetName) throws Exception{
IJavaProject javaProject = getProjectContext();
ICompilationUnit cunit = getCompilationUnit(javaProject, root, packageName, cuName);
assertNotNull("did not find requested Compilation Unit", cunit); //$NON-NLS-1$
IType targetType = (IType)(new MemberParser()).getDeepest(cunit,fullTargetName);
assertNotNull("did not find requested type", targetType); //$NON-NLS-1$
assertTrue("did not find type to install breakpoint in", targetType.exists()); //$NON-NLS-1$
return createLineBreakpoint(targetType, lineNumber);
}
/**
* Creates a line breakpoint in the given type (may be a top level non public type)
*
* @param lineNumber line number to create the breakpoint at
* @param packageName fully qualified package name containing the type, example "a.b.c"
* @param cuName simple name of compilation unit containing the type, example "Something.java"
* @param typeName $ qualified type name, example "Something" or "NonPublic" or "Something$Inner"
* @return line breakpoint
* @throws Exception
*/
protected IJavaLineBreakpoint createLineBreakpoint(int lineNumber, String packageName, String cuName, String typeName) throws Exception {
IType type = getType(packageName, cuName, typeName);
assertNotNull("Could not find the requested IType: "+typeName, type);
return createLineBreakpoint(type, lineNumber);
}
/**
* Creates a line breakpoint in the given type at the given line number.
*
* @param type type in which to install the breakpoint
* @param lineNumber line number to install the breakpoint at
* @return line breakpoint
* @throws Exception
*/
protected IJavaLineBreakpoint createLineBreakpoint(IType type, int lineNumber) throws Exception {
assertNotNull("You cannot create a line breakpoint for a null IType", type);
IMember member = null;
IJavaElement sourceElement = null;
String source = null;
if (type.isBinary()) {
IClassFile classFile = type.getClassFile();
source = classFile.getSource();
sourceElement = classFile;
} else {
ICompilationUnit unit = type.getCompilationUnit();
source = unit.getSource();
sourceElement = unit;
}
// translate line number to offset
if (source != null) {
Document document = new Document(source);
IRegion region = document.getLineInformation(lineNumber);
if (sourceElement instanceof ICompilationUnit) {
member = (IMember) ((ICompilationUnit)sourceElement).getElementAt(region.getOffset());
} else {
member = (IMember) ((IClassFile)sourceElement).getElementAt(region.getOffset());
}
}
Map<String, Object> map = getExtraBreakpointAttributes(member);
IJavaLineBreakpoint bp = JDIDebugModel.createLineBreakpoint(getBreakpointResource(type), type.getFullyQualifiedName(), lineNumber, -1, -1, 0, true, map);
forceDeltas(bp);
return bp;
}
/**
* Forces marker deltas to be sent based on breakpoint creation.
*
* @param breakpoint
*/
private void forceDeltas(IBreakpoint breakpoint) throws CoreException {
IProject project = breakpoint.getMarker().getResource().getProject();
if (project != null) {
project.build(IncrementalProjectBuilder.INCREMENTAL_BUILD, null);
}
}
/**
* Returns the type in the test project based on the given name. The type name may refer to a
* top level non public type.
*
* @param packageName package name, example "a.b.c"
* @param cuName simple compilation unit name within the package, example "Something.java"
* @param typeName simple dot qualified type name, example "Something" or "NonPublic" or "Something.Inner"
* @return associated type or <code>null</code> if none
* @throws Exception
*/
protected IType getType(String packageName, String cuName, String typeName) throws Exception {
IPackageFragment[] packageFragments = getProjectContext().getPackageFragments();
for (int i = 0; i < packageFragments.length; i++) {
IPackageFragment fragment = packageFragments[i];
if (fragment.getElementName().equals(packageName)) {
ICompilationUnit compilationUnit = fragment.getCompilationUnit(cuName);
String[] names = typeName.split("\\$"); //$NON-NLS-1$
IType type = compilationUnit.getType(names[0]);
for (int j = 1; j < names.length; j++) {
type = type.getType(names[j]);
}
if (type.exists()) {
return type;
}
}
}
return null;
}
/**
* Creates and returns a map of java element breakpoint attributes for a breakpoint on the
* given java element, or <code>null</code> if none
*
* @param element java element the breakpoint is associated with
* @return map of breakpoint attributes or <code>null</code>
* @throws Exception
*/
protected Map<String, Object> getExtraBreakpointAttributes(IMember element) throws Exception {
if (element != null && element.exists()) {
Map<String, Object> map = new HashMap<>();
ISourceRange sourceRange = element.getSourceRange();
int start = sourceRange.getOffset();
int end = start + sourceRange.getLength();
IType type = null;
if (element instanceof IType) {
type = (IType) element;
} else {
type = element.getDeclaringType();
}
BreakpointUtils.addJavaBreakpointAttributesWithMemberDetails(map, type, start, end);
return map;
}
return null;
}
/**
* Creates and returns a line breakpoint at the given line number in the type with the
* given name and sets the specified condition on the breakpoint.
*
* @param lineNumber line number
* @param typeName type name
* @param condition condition
*/
protected IJavaLineBreakpoint createConditionalLineBreakpoint(int lineNumber, String typeName, String condition, boolean suspendOnTrue) throws Exception {
IJavaLineBreakpoint bp = createLineBreakpoint(lineNumber, typeName);
bp.setCondition(condition);
bp.setConditionEnabled(true);
bp.setConditionSuspendOnTrue(suspendOnTrue);
return bp;
}
/**
* Creates and returns a pattern breakpoint at the given line number in the
* source file with the given name.
*
* @param lineNumber line number
* @param sourceName name of source file
* @param pattern the pattern of the class file name
*/
protected IJavaPatternBreakpoint createPatternBreakpoint(int lineNumber, String sourceName, String pattern) throws Exception {
return JDIDebugModel.createPatternBreakpoint(getProjectContext().getProject(), sourceName, pattern, lineNumber, -1, -1, 0, true, null);
}
/**
* Creates and returns a target pattern breakpoint at the given line number in the
* source file with the given name.
*
* @param lineNumber line number
* @param sourceName name of source file
*/
protected IJavaTargetPatternBreakpoint createTargetPatternBreakpoint(int lineNumber, String sourceName) throws Exception {
return JDIDebugModel.createTargetPatternBreakpoint(getProjectContext().getProject(), sourceName, lineNumber, -1, -1, 0, true, null);
}
/**
* Creates and returns a stratum breakpoint at the given line number in the
* source file with the given name.
*
* @param lineNumber line number
* @param sourceName name of source file
* @param stratum the stratum of the source file
*/
protected IJavaStratumLineBreakpoint createStratumBreakpoint(int lineNumber, String sourceName, String stratum) throws Exception {
return JDIDebugModel.createStratumBreakpoint(getProjectContext().getProject(), stratum, sourceName, null, null, lineNumber, -1, -1, 0, true, null);
}
/**
* Creates and returns a method breakpoint
*
* @param typeNamePattern type name pattern
* @param methodName method name
* @param methodSignature method signature or <code>null</code>
* @param entry whether to break on entry
* @param exit whether to break on exit
*/
protected IJavaMethodBreakpoint createMethodBreakpoint(String typeNamePattern, String methodName, String methodSignature, boolean entry, boolean exit) throws Exception {
return createMethodBreakpoint(getProjectContext(), typeNamePattern, methodName, methodSignature, entry, exit);
}
/**
* Creates and returns a method breakpoint
*
* @param project java project
* @param typeNamePattern type name pattern
* @param methodName method name
* @param methodSignature method signature or <code>null</code>
* @param entry whether to break on entry
* @param exit whether to break on exit
*/
protected IJavaMethodBreakpoint createMethodBreakpoint(IJavaProject project, String typeNamePattern, String methodName, String methodSignature, boolean entry, boolean exit) throws Exception {
IMethod method= null;
IResource resource = project.getProject();
if (methodSignature != null && methodName != null) {
IType type = project.findType(typeNamePattern);
if (type != null ) {
resource = getBreakpointResource(type);
method = type.getMethod(methodName, Signature.getParameterTypes(methodSignature));
}
}
Map<String, Object> map = getExtraBreakpointAttributes(method);
IJavaMethodBreakpoint bp = JDIDebugModel.createMethodBreakpoint(resource, typeNamePattern, methodName, methodSignature, entry, exit,false, -1, -1, -1, 0, true, map);
forceDeltas(bp);
return bp;
}
/**
* Creates a method breakpoint in a fully specified type (potentially non public).
*
* @param packageName package name containing type to install breakpoint in, example "a.b.c"
* @param cuName simple compilation unit name within package, example "Something.java"
* @param typeName $ qualified type name within compilation unit, example "Something" or
* "NonPublic" or "Something$Inner"
* @param methodName method or <code>null</code> for all methods
* @param methodSignature JLS method signature or <code>null</code> for all methods with the given name
* @param entry whether to break on entry
* @param exit whether to break on exit
* @return method breakpoint
* @throws Exception
*/
protected IJavaMethodBreakpoint createMethodBreakpoint(String packageName, String cuName, String typeName, String methodName, String methodSignature, boolean entry, boolean exit) throws Exception {
IType type = getType(packageName, cuName, typeName);
assertNotNull("did not find type to install breakpoint in", type); //$NON-NLS-1$
IMethod method= null;
if (methodSignature != null && methodName != null) {
if (type != null ) {
method = type.getMethod(methodName, Signature.getParameterTypes(methodSignature));
}
}
Map<String, Object> map = getExtraBreakpointAttributes(method);
IJavaMethodBreakpoint bp = JDIDebugModel.createMethodBreakpoint(getBreakpointResource(type), type.getFullyQualifiedName(), methodName, methodSignature, entry, exit,false, -1, -1, -1, 0, true, map);
forceDeltas(bp);
return bp;
}
/**
* Creates a MethodBreakPoint on the method specified at the given path.
* Syntax:
* Type$InnerType$MethodNameAndSignature$AnonymousTypeDeclarationNumber$FieldName
* eg:<code>
* public class Foo{
* class Inner
* {
* public void aMethod()
* {
* Object anon = new Object(){
* int anIntField;
* String anonTypeMethod() {return "an Example";}
* }
* }
* }
* }</code>
* Syntax to get the anonymous toString would be: Foo$Inner$aMethod()V$1$anonTypeMethod()QString
* so, createMethodBreakpoint(packageName, cuName, "Foo$Inner$aMethod()V$1$anonTypeMethod()QString",true,false);
*/
protected IJavaMethodBreakpoint createMethodBreakpoint(String root, String packageName, String cuName,
String fullTargetName, boolean entry, boolean exit) throws Exception {
IJavaProject javaProject = getProjectContext();
ICompilationUnit cunit = getCompilationUnit(javaProject, root, packageName, cuName);
assertNotNull("did not find requested Compilation Unit", cunit); //$NON-NLS-1$
IMethod targetMethod = (IMethod)(new MemberParser()).getDeepest(cunit,fullTargetName);
assertNotNull("did not find requested method", targetMethod); //$NON-NLS-1$
assertTrue("Given method does not exist", targetMethod.exists()); //$NON-NLS-1$
IType methodParent = (IType)targetMethod.getParent();//safe - method's only parent = Type
assertNotNull("did not find type to install breakpoint in", methodParent); //$NON-NLS-1$
Map<String, Object> map = getExtraBreakpointAttributes(targetMethod);
IJavaMethodBreakpoint bp = JDIDebugModel.createMethodBreakpoint(getBreakpointResource(methodParent), methodParent.getFullyQualifiedName(),targetMethod.getElementName(), targetMethod.getSignature(), entry, exit,false, -1, -1, -1, 0, true, map);
forceDeltas(bp);
return bp;
}
/**
* @param cu the Compilation where the target resides
* @param target the full name of the target, as per MemberParser syntax
* @return the requested Member
*/
protected IMember getMember(ICompilationUnit cu, String target) {
IMember toReturn = (new MemberParser()).getDeepest(cu,target);
return toReturn;
}
/**
* Delegate method to get a resource with a specific name from the testing workspace 'src' folder
* @param name the name of the <code>IResource</code> to get
* @return the specified <code>IResource</code> or <code>null</code> if it does not exist
*
* @since 3.4
*/
protected IResource getResource(String name) {
return ResourcesPlugin.getWorkspace().getRoot().findMember(new Path("/DebugTests/src/"+name));
}
/**
* Creates and returns a class prepare breakpoint on the type with the given fully qualified name.
*
* @param typeName type on which to create the breakpoint
* @return breakpoint
* @throws Exception
*/
protected IJavaClassPrepareBreakpoint createClassPrepareBreakpoint(String typeName) throws Exception {
return createClassPrepareBreakpoint(getType(typeName));
}
/**
* Creates and returns a class prepare breakpoint on the type with the given fully qualified name.
*
* @param typeName type on which to create the breakpoint
* @return breakpoint
* @throws Exception
*/
protected IJavaClassPrepareBreakpoint createClassPrepareBreakpoint(String root,
String packageName, String cuName, String fullTargetName) throws Exception {
ICompilationUnit cunit = getCompilationUnit(getProjectContext(), root, packageName, cuName);
IType type = (IType)getMember(cunit,fullTargetName);
assertTrue("Target type not found", type.exists()); //$NON-NLS-1$
return createClassPrepareBreakpoint(type);
}
/**
* Creates a class prepare breakpoint in a fully specified type (potentially non public).
*
* @param packageName package name containing type to install breakpoint in, example "a.b.c"
* @param cuName simple compilation unit name within package, example "Something.java"
* @param typeName $ qualified type name within compilation unit, example "Something" or
* "NonPublic" or "Something$Inner"
*/
protected IJavaClassPrepareBreakpoint createClassPrepareBreakpoint(String packageName, String cuName, String typeName) throws Exception {
return createClassPrepareBreakpoint(getType(packageName, cuName, typeName));
}
/**
* Creates a class prepare breakpoint for the given type
*
* @param type type
* @return class prepare breakpoint
* @throws Exception
*/
protected IJavaClassPrepareBreakpoint createClassPrepareBreakpoint(IType type) throws Exception {
assertNotNull("type not specified for class prepare breakpoint", type); //$NON-NLS-1$
int kind = IJavaClassPrepareBreakpoint.TYPE_CLASS;
if (type.isInterface()) {
kind = IJavaClassPrepareBreakpoint.TYPE_INTERFACE;
}
Map<String, Object> map = getExtraBreakpointAttributes(type);
IJavaClassPrepareBreakpoint bp = JDIDebugModel.createClassPrepareBreakpoint(getBreakpointResource(type), type.getFullyQualifiedName(), kind, -1, -1, true, map);
forceDeltas(bp);
return bp;
}
/**
* Returns the Java model type from the test project with the given name or <code>null</code>
* if none.
*
* @param typeName
* @return type or <code>null</code>
* @throws Exception
*/
protected IType getType(String typeName) throws Exception {
return getProjectContext().findType(typeName);
}
/**
* Creates and returns a watchpoint
*
* @param typeNmae type name
* @param fieldName field name
* @param access whether to suspend on field access
* @param modification whether to suspend on field modification
*/
protected IJavaWatchpoint createWatchpoint(String typeName, String fieldName, boolean access, boolean modification) throws Exception {
IType type = getType(typeName);
return createWatchpoint(type, fieldName, access, modification);
}
/**
* Creates and returns an exception breakpoint
*
* @param exName exception name
* @param caught whether to suspend in caught locations
* @param uncaught whether to suspend in uncaught locations
*/
protected IJavaExceptionBreakpoint createExceptionBreakpoint(String exName, boolean caught, boolean uncaught) throws Exception {
IType type = getType(exName);
Map<String, Object> map = getExtraBreakpointAttributes(type);
IJavaExceptionBreakpoint bp = JDIDebugModel.createExceptionBreakpoint(getBreakpointResource(type),exName, caught, uncaught, false, true, map);
forceDeltas(bp);
return bp;
}
/**
* Creates and returns a watchpoint
*
* @param typeNmae type name
* @param fieldName field name
* @param access whether to suspend on field access
* @param modification whether to suspend on field modification
*/
/* protected IJavaWatchpoint createWatchpoint(String typeName, String fieldName, boolean access, boolean modification) throws Exception {
IType type = getType(typeName);
return createWatchpoint(type, fieldName, access, modification);
}*/
/**
* Creates a WatchPoint on the field specified at the given path.
* Will create watchpoints on fields within anonymous types, inner types,
* local (non-public) types, and public types.
* @param root
* @param packageName package name containing type to install breakpoint in, example "a.b.c"
* @param cuName simple compilation unit name within package, example "Something.java"
* @param fullTargetName - see below
* @param access whether to suspend on access
* @param modification whether to suspend on modification
* @return a watchpoint
* @throws Exception
* @throws CoreException
*
* <p>
* <pre>
* Syntax example:
* Type$InnerType$MethodNameAndSignature$AnonymousTypeDeclarationNumber$FieldName
* eg:
* public class Foo{
* class Inner
* {
* public void aMethod()
* {
* Object anon = new Object(){
* int anIntField;
* String anonTypeMethod() {return "an Example";}
* }
* }
* }
* }</pre>
* </p>
* To get the anonymous toString, syntax of fullTargetName would be: <code>Foo$Inner$aMethod()V$1$anIntField</code>
*/
protected IJavaWatchpoint createNestedTypeWatchPoint(String root, String packageName, String cuName,
String fullTargetName, boolean access, boolean modification) throws Exception, CoreException {
ICompilationUnit cunit = getCompilationUnit(getProjectContext(), root, packageName, cuName);
IField field = (IField)getMember(cunit,fullTargetName);
assertNotNull("Path to field is not valid", field); //$NON-NLS-1$
assertTrue("Field is not valid", field.exists()); //$NON-NLS-1$
IType type = (IType)field.getParent();
return createWatchpoint(type, field.getElementName(), access, modification);
}
/**
* Creates a watchpoint in a fully specified type (potentially non public).
*
* @param packageName package name containing type to install breakpoint in, example "a.b.c"
* @param cuName simple compilation unit name within package, example "Something.java"
* @param typeName $ qualified type name within compilation unit, example "Something" or
* "NonPublic" or "Something$Inner"
* @param fieldName name of the field
* @param access whether to suspend on access
* @param modification whether to suspend on modification
*/
protected IJavaWatchpoint createWatchpoint(String packageName, String cuName, String typeName, String fieldName, boolean access, boolean modification) throws Exception {
IType type = getType(packageName, cuName, typeName);
return createWatchpoint(type, fieldName, access, modification);
}
/**
* Creates a watchpoint on the specified field.
*
* @param type type containing the field
* @param fieldName name of the field
* @param access whether to suspend on access
* @param modification whether to suspend on modification
* @return watchpoint
* @throws Exception
*/
protected IJavaWatchpoint createWatchpoint(IType type, String fieldName, boolean access, boolean modification) throws Exception, CoreException {
assertNotNull("type not specified for watchpoint", type); //$NON-NLS-1$
IField field = type.getField(fieldName);
Map<String, Object> map = getExtraBreakpointAttributes(field);
IJavaWatchpoint wp = JDIDebugModel.createWatchpoint(getBreakpointResource(type), type.getFullyQualifiedName(), fieldName, -1, -1, -1, 0, true, map);
wp.setAccess(access);
wp.setModification(modification);
forceDeltas(wp);
return wp;
}
/**
* Terminates the given thread and removes its launch
*/
protected void terminateAndRemove(IJavaThread thread) {
if (thread != null) {
terminateAndRemove((IJavaDebugTarget)thread.getDebugTarget());
}
}
/**
* Terminates the given debug target and removes its launch.
*
* NOTE: all breakpoints are removed, all threads are resumed, and then
* the target is terminated. This avoids defunct processes on Linux.
*/
protected void terminateAndRemove(IJavaDebugTarget debugTarget) {
assertNotNull(getName()+" - you cannot terminate and remove a null debug target", debugTarget);
ILaunch launch = debugTarget.getLaunch();
if (!(debugTarget.isTerminated() || debugTarget.isDisconnected())) {
IPreferenceStore jdiUIPreferences = JDIDebugUIPlugin.getDefault().getPreferenceStore();
jdiUIPreferences.setValue(IJDIPreferencesConstants.PREF_SUSPEND_ON_UNCAUGHT_EXCEPTIONS, false);
DebugEventWaiter waiter = new DebugElementEventWaiter(DebugEvent.TERMINATE, debugTarget);
try {
removeAllBreakpoints();
IThread[] threads = debugTarget.getThreads();
for (int i = 0; i < threads.length; i++) {
IThread thread = threads[i];
try {
if (thread.isSuspended()) {
thread.resume();
}
} catch (CoreException e) {
}
}
debugTarget.getDebugTarget().terminate();
waiter.waitForEvent();
} catch (CoreException e) {
}
}
getLaunchManager().removeLaunch(launch);
// ensure event queue is flushed
DebugEventWaiter waiter = new DebugElementEventWaiter(DebugEvent.MODEL_SPECIFIC, this);
DebugPlugin.getDefault().fireDebugEventSet(new DebugEvent[]{new DebugEvent(this, DebugEvent.MODEL_SPECIFIC)});
waiter.waitForEvent();
}
/**
* Deletes all existing breakpoints
*/
protected void removeAllBreakpoints() {
IBreakpoint[] bps = getBreakpointManager().getBreakpoints();
try {
getBreakpointManager().removeBreakpoints(bps, true);
} catch (CoreException e) {
}
}
/**
* Returns the first breakpoint the given thread is suspended
* at, or <code>null</code> if none.
*
* @return the first breakpoint the given thread is suspended
* at, or <code>null</code> if none
*/
protected IBreakpoint getBreakpoint(IThread thread) {
IBreakpoint[] bps = thread.getBreakpoints();
if (bps.length > 0) {
return bps[0];
}
return null;
}
/**
* Evaluates the given snippet in the context of the given stack frame and returns
* the result.
*
* @param snippet code snippet
* @param frame stack frame context
* @return evaluation result
*/
protected IEvaluationResult evaluate(String snippet, IJavaStackFrame frame) throws Exception {
DebugEventWaiter waiter= new DebugElementKindEventWaiter(DebugEvent.SUSPEND, IJavaThread.class);
waiter.setTimeout(DEFAULT_TIMEOUT);
IAstEvaluationEngine engine = EvaluationManager.newAstEvaluationEngine(getProjectContext(), (IJavaDebugTarget)frame.getDebugTarget());
try {
engine.evaluate(snippet, frame, this, DebugEvent.EVALUATION, true);
Object suspendee= waiter.waitForEvent();
setEventSet(waiter.getEventSet());
if(suspendee == null) {
throw new TestAgainException("Program did not suspend evaluating: \n\n"+snippet);
}
assertNotNull("Program did not suspend.", suspendee); //$NON-NLS-1$
return fEvaluationResult;
}
finally {
engine.dispose();
}
}
/**
* Runs an evaluation using an embedded listener and the {@link #DEFAULT_TIMEOUT} for the operation
* @param snippet the snippet to evaluate
* @param thread the suspended thread to run the evaluation on
* @return the {@link IEvaluationResult}
* @throws Exception
* @since 3.1.200
*/
protected IEvaluationResult evaluate(String snippet, IJavaThread thread) throws Exception {
class Listener implements IEvaluationListener {
IEvaluationResult fResult;
@Override
public void evaluationComplete(IEvaluationResult result) {
fResult= result;
}
}
Listener listener= new Listener();
IJavaStackFrame frame = (IJavaStackFrame) thread.getTopStackFrame();
assertNotNull("There should be a stackframe", frame);
ASTEvaluationEngine engine = new ASTEvaluationEngine(getProjectContext(), (IJavaDebugTarget) thread.getDebugTarget());
try {
engine.evaluate(snippet, frame, listener, DebugEvent.EVALUATION_IMPLICIT, false);
long timeout = System.currentTimeMillis()+DEFAULT_TIMEOUT;
while(listener.fResult == null && System.currentTimeMillis() < timeout) {
Thread.sleep(100);
}
return listener.fResult;
}
finally {
engine.dispose();
}
}
/**
* @see IEvaluationListener#evaluationComplete(IEvaluationResult)
*/
@Override
public void evaluationComplete(IEvaluationResult result) {
fEvaluationResult = result;
}
/**
* Performs a step over in the given stack frame and returns when complete.
*
* @param frame stack frame to step in
*/
protected IJavaThread stepOver(IJavaStackFrame frame) throws Exception {
DebugEventWaiter waiter= new DebugElementKindEventDetailWaiter(DebugEvent.SUSPEND, IJavaThread.class, DebugEvent.STEP_END);
waiter.setTimeout(DEFAULT_TIMEOUT);
frame.stepOver();
Object suspendee= waiter.waitForEvent();
setEventSet(waiter.getEventSet());
assertNotNull("Program did not suspend.", suspendee); //$NON-NLS-1$
return (IJavaThread) suspendee;
}
/**
* Performs a step over in the given stack frame and returns when a breakpoint is hit.
*
* @param frame stack frame to step in
*/
protected IJavaThread stepOverToBreakpoint(IJavaStackFrame frame) throws Exception {
DebugEventWaiter waiter= new DebugElementKindEventDetailWaiter(DebugEvent.SUSPEND, IJavaThread.class, DebugEvent.BREAKPOINT);
waiter.setTimeout(DEFAULT_TIMEOUT);
frame.stepOver();
Object suspendee= waiter.waitForEvent();
setEventSet(waiter.getEventSet());
assertNotNull("Program did not suspend.", suspendee); //$NON-NLS-1$
return (IJavaThread) suspendee;
}
/**
* Performs a step into in the given stack frame and returns when complete.
*
* @param frame stack frame to step in
*/
protected IJavaThread stepInto(IJavaStackFrame frame) throws Exception {
DebugEventWaiter waiter= new DebugElementKindEventDetailWaiter(DebugEvent.SUSPEND, IJavaThread.class, DebugEvent.STEP_END);
waiter.setTimeout(DEFAULT_TIMEOUT);
frame.stepInto();
Object suspendee= waiter.waitForEvent();
setEventSet(waiter.getEventSet());
assertNotNull("Program did not suspend.", suspendee); //$NON-NLS-1$
return (IJavaThread) suspendee;
}
/**
* Performs a step return in the given stack frame and returns when complete.
*
* @param frame stack frame to step return from
*/
protected IJavaThread stepReturn(IJavaStackFrame frame) throws Exception {
DebugEventWaiter waiter= new DebugElementKindEventDetailWaiter(DebugEvent.SUSPEND, IJavaThread.class, DebugEvent.STEP_END);
waiter.setTimeout(DEFAULT_TIMEOUT);
frame.stepReturn();
Object suspendee= waiter.waitForEvent();
setEventSet(waiter.getEventSet());
assertNotNull("Program did not suspend.", suspendee); //$NON-NLS-1$
return (IJavaThread) suspendee;
}
/**
* Performs a step into with filters in the given stack frame and returns when
* complete.
*
* @param frame stack frame to step in
*/
protected IJavaThread stepIntoWithFilters(IJavaStackFrame frame) throws Exception {
return stepIntoWithFilters(frame, true);
}
/**
* Performs a step into with filters in the given stack frame and returns when
* complete.
*
* @param whether to step thru or step return from a filtered location
* @param frame stack frame to step in
*/
protected IJavaThread stepIntoWithFilters(IJavaStackFrame frame, boolean stepThru) throws Exception {
DebugEventWaiter waiter= new DebugElementKindEventWaiter(DebugEvent.SUSPEND, IJavaThread.class);
waiter.setTimeout(DEFAULT_TIMEOUT);
// turn filters on
IJavaDebugTarget target = (IJavaDebugTarget) frame.getDebugTarget();
try {
target.setStepFiltersEnabled(true);
target.setStepThruFilters(stepThru);
frame.stepInto();
Object suspendee= waiter.waitForEvent();
setEventSet(waiter.getEventSet());
assertNotNull("Program did not suspend.", suspendee); //$NON-NLS-1$
return (IJavaThread) suspendee;
} catch (DebugException e) {
tryTestAgain(e);
} finally {
// turn filters off
target.setStepFiltersEnabled(false);
target.setStepThruFilters(true);
}
return null;
}
/**
* Performs a step return with filters in the given stack frame and returns when
* complete.
*
* @param frame stack frame to step in
*/
protected IJavaThread stepReturnWithFilters(IJavaStackFrame frame) throws Exception {
DebugEventWaiter waiter= new DebugElementKindEventWaiter(DebugEvent.SUSPEND, IJavaThread.class);
waiter.setTimeout(DEFAULT_TIMEOUT);
// turn filters on
IJavaDebugTarget target = (IJavaDebugTarget) frame.getDebugTarget();
try {
target.setStepFiltersEnabled(true);
frame.stepReturn();
} catch (DebugException e) {
tryTestAgain(e);
} finally {
// turn filters off
target.setStepFiltersEnabled(false);
}
Object suspendee= waiter.waitForEvent();
setEventSet(waiter.getEventSet());
assertNotNull("Program did not suspend.", suspendee); //$NON-NLS-1$
return (IJavaThread) suspendee;
}
/**
* Performs a step over with filters in the given stack frame and returns when
* complete.
*
* @param frame stack frame to step in
*/
protected IJavaThread stepOverWithFilters(IJavaStackFrame frame) throws Exception {
DebugEventWaiter waiter= new DebugElementKindEventWaiter(DebugEvent.SUSPEND, IJavaThread.class);
waiter.setTimeout(DEFAULT_TIMEOUT);
// turn filters on
IJavaDebugTarget target = (IJavaDebugTarget) frame.getDebugTarget();
try {
target.setStepFiltersEnabled(true);
frame.stepOver();
} catch (DebugException e) {
tryTestAgain(e);
} finally {
// turn filters off
target.setStepFiltersEnabled(false);
}
Object suspendee= waiter.waitForEvent();
setEventSet(waiter.getEventSet());
assertNotNull("Program did not suspend.", suspendee); //$NON-NLS-1$
return (IJavaThread) suspendee;
}
/**
* Returns the compilation unit with the given name.
*
* @param project the project containing the CU
* @param root the name of the source folder in the project
* @param pkg the name of the package (empty string for default package)
* @param name the name of the CU (ex. Something.java)
* @return compilation unit
*/
protected ICompilationUnit getCompilationUnit(IJavaProject project, String root, String pkg, String name) {
IProject p = project.getProject();
IResource r = p.getFolder(root);
return project.getPackageFragmentRoot(r).getPackageFragment(pkg).getCompilationUnit(name);
}
/**
* Wait for builds to complete
*/
public static void waitForBuild() {
boolean wasInterrupted = false;
do {
try {
Job.getJobManager().join(ResourcesPlugin.FAMILY_AUTO_BUILD, null);
Job.getJobManager().join(ResourcesPlugin.FAMILY_MANUAL_BUILD, null);
// Let also all other pending jobs proceed, ignore console jobs
TestUtil.waitForJobs("waitForBuild", 100, 1000, ProcessConsole.class);
wasInterrupted = false;
} catch (OperationCanceledException e) {
e.printStackTrace();
} catch (InterruptedException e) {
wasInterrupted = true;
}
} while (wasInterrupted);
}
/**
* Finds the specified variable within the context of the specified stackframe. Returns null if a variable with
* the given name does not exist
* @param frame
* @param name
* @return the <code>IJavaVariable</code> with the given name or <code>null</code> if it
* does not exist
* @throws DebugException
*/
protected IJavaVariable findVariable(IJavaStackFrame frame, String name) throws DebugException {
IJavaVariable variable = frame.findVariable(name);
if (variable == null) {
// dump visible variables
IDebugModelPresentation presentation = DebugUIPlugin.getModelPresentation();
System.out.println("Could not find variable '" + name + "' in frame: " + presentation.getText(frame)); //$NON-NLS-1$ //$NON-NLS-2$
System.out.println("Visible variables are:"); //$NON-NLS-1$
IVariable[] variables = frame.getVariables();
for (int i = 0; i < variables.length; i++) {
IVariable variable2 = variables[i];
System.out.println("\t" + presentation.getText(variable2)); //$NON-NLS-1$
}
if (!frame.isStatic() && !frame.isNative()) {
IJavaObject ths = frame.getThis();
if (ths != null) {
variables = ths.getVariables();
for (int i = 0; i < variables.length; i++) {
IVariable variable2 = variables[i];
System.out.println("\t" + presentation.getText(variable2)); //$NON-NLS-1$
}
}
}
}
return variable;
}
/**
* Returns if the local filesystem is case-sensitive or not
* @return true if the local filesystem is case-sensitive, false otherwise
*/
protected boolean isFileSystemCaseSensitive() {
return Platform.OS_MACOSX.equals(Platform.getOS()) ? false : new File("a").compareTo(new File("A")) != 0; //$NON-NLS-1$ //$NON-NLS-2$
}
/**
* Creates a shared launch configuration for the type with the given name.
*/
protected ILaunchConfiguration createLaunchConfiguration(String mainTypeName) throws Exception {
return createLaunchConfiguration(getProjectContext(), mainTypeName);
}
/**
* Creates a shared launch configuration for the type with the given name.
*/
protected ILaunchConfiguration createLaunchConfiguration(IJavaProject project, String mainTypeName) throws Exception {
return createLaunchConfiguration(project, mainTypeName, false);
}
/**
* Creates a shared launch configuration for the type with the given name.
*
* @param clone
* true if the launch config name should be different from the main type name
*/
protected ILaunchConfiguration createLaunchConfiguration(IJavaProject project, String mainTypeName, boolean clone) throws Exception {
ILaunchConfigurationType type = getLaunchManager().getLaunchConfigurationType(IJavaLaunchConfigurationConstants.ID_JAVA_APPLICATION);
String configName = clone ? mainTypeName + CLONE_SUFFIX : mainTypeName;
ILaunchConfigurationWorkingCopy config = type.newInstance(project.getProject().getFolder(LAUNCHCONFIGURATIONS), configName);
config.setAttribute(IJavaLaunchConfigurationConstants.ATTR_MAIN_TYPE_NAME, mainTypeName);
config.setAttribute(IJavaLaunchConfigurationConstants.ATTR_PROJECT_NAME, project.getElementName());
Set<String> modes = new HashSet<>();
modes.add(ILaunchManager.RUN_MODE);
config.setPreferredLaunchDelegate(modes, LOCAL_JAVA_APPLICATION_TYPE_ID);
modes = new HashSet<>();
modes.add(ILaunchManager.DEBUG_MODE);
config.setPreferredLaunchDelegate(modes, LOCAL_JAVA_APPLICATION_TYPE_ID);
// use 'java' instead of 'javaw' to launch tests (javaw is problematic
// on JDK1.4.2)
Map<String, String> map = new HashMap<>(1);
map.put(IJavaLaunchConfigurationConstants.ATTR_JAVA_COMMAND, JAVA);
config.setAttribute(IJavaLaunchConfigurationConstants.ATTR_VM_INSTALL_TYPE_SPECIFIC_ATTRS_MAP, map);
return config.doSave();
}
/**
* Creates a shared launch configuration for the type with the given name.
*/
protected ILaunchConfiguration createLaunchConfiguration(IJavaProject project, String containername, String mainTypeName) throws Exception {
ILaunchConfigurationType type = getLaunchManager().getLaunchConfigurationType(IJavaLaunchConfigurationConstants.ID_JAVA_APPLICATION);
ILaunchConfigurationWorkingCopy config = type.newInstance(project.getProject().getFolder(containername), mainTypeName);
config.setAttribute(IJavaLaunchConfigurationConstants.ATTR_MAIN_TYPE_NAME, mainTypeName);
config.setAttribute(IJavaLaunchConfigurationConstants.ATTR_PROJECT_NAME, project.getElementName());
Set<String> modes = new HashSet<>();
modes.add(ILaunchManager.RUN_MODE);
config.setPreferredLaunchDelegate(modes, LOCAL_JAVA_APPLICATION_TYPE_ID);
modes = new HashSet<>();
modes.add(ILaunchManager.DEBUG_MODE);
config.setPreferredLaunchDelegate(modes, LOCAL_JAVA_APPLICATION_TYPE_ID);
// use 'java' instead of 'javaw' to launch tests (javaw is problematic
// on JDK1.4.2)
Map<String, String> map = new HashMap<>(1);
map.put(IJavaLaunchConfigurationConstants.ATTR_JAVA_COMMAND, JAVA);
config.setAttribute(IJavaLaunchConfigurationConstants.ATTR_VM_INSTALL_TYPE_SPECIFIC_ATTRS_MAP, map);
return config.doSave();
}
/**
* When a test throws the 'try again' exception, try it again.
* @see junit.framework.TestCase#runBare()
*/
@Override
public void runBare() throws Throwable {
boolean tryAgain = true;
int attempts = 0;
while (tryAgain) {
try {
attempts++;
super.runBare();
tryAgain = false;
} catch (TestAgainException e) {
TestUtil.log(IStatus.ERROR, getName(), "Test failed attempt " + attempts + ". Re-testing.", e);
TestUtil.cleanUp(getName());
if (attempts > 4) {
// the next attempt will fail
break;
}
}
}
if (tryAgain) {
// last attempt and if it fails then we should fail, see bug 515988
super.runBare();
}
}
@Override
protected void tearDown() throws Exception {
TestUtil.log(IStatus.INFO, getName(), "tearDown");
shutdownDebugTargets();
TestUtil.cleanUp(getName());
super.tearDown();
}
protected void shutdownDebugTargets() {
ILaunchManager launchManager = DebugPlugin.getDefault().getLaunchManager();
IDebugTarget[] targets = launchManager.getDebugTargets();
for (IDebugTarget target : targets) {
if (target instanceof JDIDebugTarget) {
((JDIDebugTarget) target).shutdown();
}
}
}
/**
* Opens and returns an editor on the given file or <code>null</code>
* if none. The editor will be activated.
*
* @param file
* @return editor or <code>null</code>
*/
protected IEditorPart openEditor(final IFile file) throws PartInitException, InterruptedException {
Display display = DebugUIPlugin.getStandardDisplay();
if (Thread.currentThread().equals(display.getThread())) {
IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();
return IDE.openEditor(page, file, true);
}
final IEditorPart[] parts = new IEditorPart[1];
WorkbenchJob job = new WorkbenchJob(display, "open editor") {
@Override
public IStatus runInUIThread(IProgressMonitor monitor) {
IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();
try {
parts[0] = IDE.openEditor(page, file, true);
} catch (PartInitException e) {
return e.getStatus();
}
return Status.OK_STATUS;
}
};
job.schedule();
job.join();
return parts[0];
}
/**
* Opens the {@link IDebugView} with the given id, does nothing if no such view exists.
* This method can return <code>null</code>
*
* @param viewId
* @return the handle to the {@link IDebugView} with the given id
* @throws PartInitException
* @throws InterruptedException
* @since 3.8.100
*/
protected IDebugView openDebugView(final String viewId) throws PartInitException, InterruptedException {
if(viewId != null) {
Display display = DebugUIPlugin.getStandardDisplay();
if (Thread.currentThread().equals(display.getThread())) {
return doShowDebugView(viewId);
}
final IDebugView[] view = new IDebugView[1];
WorkbenchJob job = new WorkbenchJob("Showing the debug view: "+viewId) {
@Override
public IStatus runInUIThread(IProgressMonitor monitor) {
try {
view[0] = doShowDebugView(viewId);
}
catch(CoreException ce) {
return ce.getStatus();
}
return Status.OK_STATUS;
}
};
job.schedule();
job.join();
return view[0];
}
return null;
}
/**
* Opens a debug view
* @param viewId
* @return return the debug view handle or <code>null</code>
* @throws PartInitException
* @since 3.8.100
*/
private IDebugView doShowDebugView(String viewId) throws PartInitException {
IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
if(window != null) {
IWorkbenchPage page = window.getActivePage();
assertNotNull("We shold have found the active page to open the debug view in", page);
return (IDebugView) page.showView(viewId);
}
return null;
}
/**
* Toggles a breakpoint in the editor at the given line number returning the breakpoint
* or <code>null</code> if none.
*
* @param editor
* @param lineNumber
* @return returns the created breakpoint or <code>null</code> if none.
* @throws InterruptedException
*/
protected IBreakpoint toggleBreakpoint(final IEditorPart editor, int lineNumber) throws InterruptedException {
final IVerticalRulerInfo info = new VerticalRulerInfoStub(lineNumber-1); // sub 1, as the doc lines start at 0
WorkbenchJob job = new WorkbenchJob(DebugUIPlugin.getStandardDisplay(), "toggle breakpoint") {
@Override
public IStatus runInUIThread(IProgressMonitor monitor) {
ToggleBreakpointAction action = new ToggleBreakpointAction(editor, null, info);
action.run();
return Status.OK_STATUS;
}
};
final Object lock = new Object();
final IBreakpoint[] breakpoints = new IBreakpoint[1];
IBreakpointListener listener = new IBreakpointListener() {
@Override
public void breakpointRemoved(IBreakpoint breakpoint, IMarkerDelta delta) {
}
@Override
public void breakpointChanged(IBreakpoint breakpoint, IMarkerDelta delta) {
}
@Override
public void breakpointAdded(IBreakpoint breakpoint) {
synchronized (lock) {
breakpoints[0] = breakpoint;
lock.notifyAll();
}
}
};
IBreakpointManager manager = DebugPlugin.getDefault().getBreakpointManager();
manager.addBreakpointListener(listener);
synchronized (lock) {
job.schedule();
lock.wait(DEFAULT_TIMEOUT);
}
manager.removeBreakpointListener(listener);
return breakpoints[0];
}
/**
* Closes all editors in the active workbench page.
*/
protected void closeAllEditors() {
Runnable closeAll = new Runnable() {
@Override
public void run() {
IWorkbenchWindow activeWorkbenchWindow = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
activeWorkbenchWindow.getActivePage().closeAllEditors(false);
}
};
Display display = DebugUIPlugin.getStandardDisplay();
display.syncExec(closeAll);
}
/**
* Returns the version level of the class files being run, based on the system property <code>java.class.version</code>
* @return the version level of the class files being run in the current VM
*
* @since 3.6
*/
protected String getClassFileVersion() {
String version = System.getProperty("java.class.version");
if(version.compareTo("48.0") <= 0) {
return JavaCore.VERSION_1_4;
}
if(version.compareTo("49.0") <= 0) {
return JavaCore.VERSION_1_5;
}
return JavaCore.VERSION_1_6;
}
/**
* Determines if the test should be attempted again based on the error code.
* See bug 297071.
*
* @param e Debug Exception
* @throws TestAgainException
* @throws DebugException
*/
protected void tryTestAgain(DebugException e) throws Exception {
Throwable cause = e.getCause();
if (cause instanceof InternalException) {
int code = ((InternalException)cause).errorCode();
if (code == 13) {
throw new TestAgainException("Retest - exception during test: "+getName()+": "+e.getMessage());
}
}
throw e;
}
/**
* Perform the actual evaluation (inspect)
* @param thread
* @return the result of the evaluation
* @throws Exception
*/
protected IValue doEval(IJavaThread thread, String snippet) throws Exception{
class Listener implements IEvaluationListener {
IEvaluationResult fResult;
@Override
public void evaluationComplete(IEvaluationResult result) {
fResult= result;
}
public IEvaluationResult getResult() {
return fResult;
}
}
Listener listener = new Listener();
IJavaStackFrame frame = (IJavaStackFrame) thread.getTopStackFrame();
assertNotNull("There should be a stackframe", frame);
ASTEvaluationEngine engine = new ASTEvaluationEngine(getProjectContext(), (IJavaDebugTarget) thread.getDebugTarget());
try {
engine.evaluate(snippet, frame, listener, DebugEvent.EVALUATION_IMPLICIT, false);
long timeout = System.currentTimeMillis() + 5000;
while(listener.getResult() == null && System.currentTimeMillis() < timeout) {
Thread.sleep(100);
}
IEvaluationResult result = listener.getResult();
assertNotNull("The evaluation should have result: ", result);
assertNull("The evaluation should not have exception : " + result.getException(), result.getException());
String firstError = result.hasErrors() ? result.getErrorMessages()[0] : "";
assertFalse("The evaluation should not have errors : " + firstError, result.hasErrors());
return listener.getResult().getValue();
}
finally {
engine.dispose();
}
}
}