| /******************************************************************************* |
| * Copyright (c) 2000, 2020 IBM Corporation and others. |
| * |
| * This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License 2.0 |
| * which accompanies this distribution, and is available at |
| * https://www.eclipse.org/legal/epl-2.0/ |
| * |
| * SPDX-License-Identifier: EPL-2.0 |
| * |
| * Contributors: |
| * IBM Corporation - initial API and implementation |
| * 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.Arrays; |
| import java.util.Collection; |
| import java.util.Collections; |
| import java.util.HashMap; |
| import java.util.HashSet; |
| import java.util.List; |
| import java.util.Map; |
| import java.util.Set; |
| import java.util.stream.Collectors; |
| |
| import org.eclipse.core.resources.IFile; |
| import org.eclipse.core.resources.IFolder; |
| import org.eclipse.core.resources.IMarker; |
| 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.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.console.ConsoleHyperlinkPosition; |
| 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 com.sun.jdi.InvocationException; |
| |
| 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 NINE_PROJECT_NAME = "Nine"; |
| 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", "StepUncaught", "TriggerPoint_01", "BulkThreadCreationTest", "MethodExitAndException", |
| "Bug534319earlyStart", "Bug534319lateStart", "Bug534319singleThread", "Bug534319startBetwen", "MethodCall", "Bug538303", "Bug540243", |
| "OutSync", "OutSync2", "ConsoleOutputUmlaut", "ErrorRecurrence" }; |
| |
| /** |
| * 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 loaded9 = 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(NINE_PROJECT_NAME); |
| loaded9 = 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); |
| |
| //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.JAVA_SE_1_7_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.JAVA_SE_1_7_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)); |
| cfgs.add(createLaunchConfiguration(jp, "ThreadNameChange")); |
| 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, "FunctionalCaptureTest18")); |
| cfgs.add(createLaunchConfiguration(jp, "EvalTestIntf18")); |
| cfgs.add(createLaunchConfiguration(jp, "EvalIntfSuperDefault")); |
| cfgs.add(createLaunchConfiguration(jp, "DebugHoverTest18")); |
| cfgs.add(createLaunchConfiguration(jp, "DebugHoverTest2Lambdas")); |
| cfgs.add(createLaunchConfiguration(jp, "Bug317045")); |
| cfgs.add(createLaunchConfiguration(jp, "Bug549394")); |
| cfgs.add(createLaunchConfiguration(jp, "Bug541110")); |
| cfgs.add(createLaunchConfiguration(jp, "ClosureVariableTest_Bug542989")); |
| cfgs.add(createLaunchConfiguration(jp, "Bug404097BreakpointInLocalClass")); |
| cfgs.add(createLaunchConfiguration(jp, "Bug404097BreakpointInAnonymousLocalClass")); |
| cfgs.add(createLaunchConfiguration(jp, "Bug404097BreakpointInLambda")); |
| cfgs.add(createLaunchConfiguration(jp, "Bug404097BreakpointUsingInnerClass")); |
| cfgs.add(createLaunchConfiguration(jp, "Bug404097BreakpointUsingLocalClass")); |
| cfgs.add(createLaunchConfiguration(jp, "Bug560392")); |
| cfgs.add(createLaunchConfiguration(jp, "Bug561715")); |
| cfgs.add(createLaunchConfiguration(jp, "Bug562056")); |
| cfgs.add(createLaunchConfiguration(jp, "RemoteEvaluator")); |
| cfgs.add(createLaunchConfiguration(jp, "AnonymousEvaluator")); |
| 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_EIGHT_PROJECT_NAME, jp); |
| } |
| } |
| |
| /** |
| * Creates the Java 9 compliant project |
| */ |
| synchronized void assert9Project() { |
| IJavaProject jp = null; |
| ArrayList<ILaunchConfiguration> cfgs = new ArrayList<>(1); |
| try { |
| if (!loaded9) { |
| jp = createProject(NINE_PROJECT_NAME, JavaProjectHelper.TEST_9_SRC_DIR.toString(), JavaProjectHelper.JAVA_SE_9_EE_NAME, false); |
| cfgs.add(createLaunchConfiguration(jp, "LogicalStructures")); |
| loaded9 = 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, NINE_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.JAVA_SE_1_7_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 'OneEight' project. |
| * |
| * @return the test project |
| */ |
| protected IJavaProject get18Project() { |
| assert18Project(); |
| return getJavaProject(ONE_EIGHT_PROJECT_NAME); |
| } |
| |
| /** |
| * Returns the 'Nine' project, used for Java 9 tests. |
| * |
| * @return the test project |
| */ |
| protected IJavaProject get9Project() { |
| assert9Project(); |
| return getJavaProject(NINE_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) { |
| StringBuilder buf = new StringBuilder(); |
| 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); |
| waiter.setEnableUIEventLoopProcessing(enableUIEventLoopProcessingInWaiter()); |
| 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); |
| waiter.setEnableUIEventLoopProcessing(enableUIEventLoopProcessingInWaiter()); |
| |
| 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); |
| waiter.setEnableUIEventLoopProcessing(enableUIEventLoopProcessingInWaiter()); |
| |
| 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); |
| waiter.setEnableUIEventLoopProcessing(enableUIEventLoopProcessingInWaiter()); |
| |
| 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); |
| waiter.setEnableUIEventLoopProcessing(enableUIEventLoopProcessingInWaiter()); |
| |
| 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); |
| waiter.setEnableUIEventLoopProcessing(enableUIEventLoopProcessingInWaiter()); |
| |
| 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); |
| waiter.setEnableUIEventLoopProcessing(enableUIEventLoopProcessingInWaiter()); |
| |
| 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); |
| waiter.setEnableUIEventLoopProcessing(enableUIEventLoopProcessingInWaiter()); |
| |
| 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); |
| waiter.setEnableUIEventLoopProcessing(enableUIEventLoopProcessingInWaiter()); |
| 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) { |
| } |
| } |
| TestUtil.waitForJobs(getName(), 100, 10000); |
| TestUtil.runEventLoop(); |
| getLaunchManager().removeLaunch(launch); |
| // ensure event queue is flushed |
| DebugEventWaiter waiter = new DebugElementEventWaiter(DebugEvent.MODEL_SPECIFIC, this); |
| waiter.setEnableUIEventLoopProcessing(enableUIEventLoopProcessingInWaiter()); |
| 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); |
| waiter.setEnableUIEventLoopProcessing(enableUIEventLoopProcessingInWaiter()); |
| |
| 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); |
| waiter.setEnableUIEventLoopProcessing(enableUIEventLoopProcessingInWaiter()); |
| |
| 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); |
| waiter.setEnableUIEventLoopProcessing(enableUIEventLoopProcessingInWaiter()); |
| |
| 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); |
| waiter.setEnableUIEventLoopProcessing(enableUIEventLoopProcessingInWaiter()); |
| |
| 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); |
| waiter.setEnableUIEventLoopProcessing(enableUIEventLoopProcessingInWaiter()); |
| |
| 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); |
| waiter.setEnableUIEventLoopProcessing(enableUIEventLoopProcessingInWaiter()); |
| |
| // 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); |
| waiter.setEnableUIEventLoopProcessing(enableUIEventLoopProcessingInWaiter()); |
| |
| // 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); |
| waiter.setEnableUIEventLoopProcessing(enableUIEventLoopProcessingInWaiter()); |
| |
| // 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()); |
| setEnvironment(config); |
| 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()); |
| setEnvironment(config); |
| 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(); |
| } |
| |
| private void setEnvironment(ILaunchConfigurationWorkingCopy workingCopy) { |
| Map<String, String> env = getLaunchManager().getNativeEnvironment().entrySet().stream() |
| .filter(e -> !"JAVA_TOOL_OPTIONS".equals(e.getKey())) |
| .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)); |
| workingCopy.setAttribute(ILaunchManager.ATTR_APPEND_ENVIRONMENT_VARIABLES, false); |
| workingCopy.setAttribute(ILaunchManager.ATTR_ENVIRONMENT_VARIABLES, env); |
| } |
| |
| /** |
| * 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("Evaluation of '" + snippet + "' should not have exception : " + findCause(result.getException()), result.getException()); |
| |
| String firstError = result.hasErrors() ? result.getErrorMessages()[0] : ""; |
| assertFalse("The evaluation of '\" + snippet + \"' should not have errors : " + firstError, result.hasErrors()); |
| return listener.getResult().getValue(); |
| } |
| finally { |
| engine.dispose(); |
| } |
| } |
| |
| private static Object findCause(DebugException problem) { |
| if (problem == null) { |
| return null; |
| } |
| Throwable cause = problem.getCause(); |
| if (cause instanceof InvocationException) { |
| return ((InvocationException)cause).exception().toString(); |
| } |
| return cause; |
| } |
| |
| /** |
| * @return true if the UI event loop should be proicessed during wait operations on UI thread |
| */ |
| protected boolean enableUIEventLoopProcessingInWaiter() { |
| return false; |
| } |
| |
| protected void assertNoErrorMarkersExist() throws Exception { |
| IJavaProject javaProject = getProjectContext(); |
| assertNotNull("Java test project cannot be null", javaProject); |
| IProject project = javaProject.getProject(); |
| assertNotNull("test project cannot be null", project); |
| IProject[] projects = { project }; |
| assertNoErrorMarkersExist(projects); |
| } |
| |
| protected void assertNoErrorMarkersExist(IProject[] projects) throws Exception { |
| for (IProject project : projects) { |
| assertNoErrorMarkersExist(project); |
| } |
| } |
| |
| protected void assertNoErrorMarkersExist(IProject project) throws Exception { |
| if (project.isAccessible()) { |
| IMarker[] projectMarkers = project.findMarkers(null, false, IResource.DEPTH_INFINITE); |
| List<IMarker> errorMarkers = Arrays.stream(projectMarkers).filter(marker -> isErrorMarker(marker)).collect(Collectors.toList()); |
| String projectErrors = toString(errorMarkers); |
| assertEquals("found errors on project " + project + ":" + System.lineSeparator() + projectErrors, Collections.EMPTY_LIST, errorMarkers); |
| } |
| } |
| |
| private static boolean isErrorMarker(IMarker marker) { |
| return marker.getAttribute(IMarker.SEVERITY, -1) == IMarker.SEVERITY_ERROR; |
| } |
| |
| private static String toString(Collection<IMarker> markers) { |
| StringBuilder markersInfo = new StringBuilder(); |
| for (IMarker marker : markers) { |
| markersInfo.append(marker); |
| } |
| return markersInfo.toString(); |
| } |
| } |