/*******************************************************************************
* Copyright (c) 2008 QNX Software Systems and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* QNX Software Systems - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.debug.core.tests;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import junit.extensions.TestSetup;
import junit.framework.TestCase;
import junit.framework.TestSuite;
import org.eclipse.cdt.core.model.CModelException;
import org.eclipse.cdt.core.model.ICProject;
import org.eclipse.cdt.debug.core.cdi.CDIException;
import org.eclipse.cdt.debug.core.cdi.ICDIFunctionLocation;
import org.eclipse.cdt.debug.core.cdi.ICDILocation;
import org.eclipse.cdt.debug.core.cdi.ICDILocator;
import org.eclipse.cdt.debug.core.cdi.ICDISession;
import org.eclipse.cdt.debug.core.cdi.model.ICDIStackFrame;
import org.eclipse.cdt.debug.core.cdi.model.ICDITarget;
import org.eclipse.cdt.debug.core.model.ICBreakpointType;
import org.eclipse.cdt.debug.mi.core.MIException;
import org.eclipse.cdt.debug.testplugin.CDebugHelper;
import org.eclipse.cdt.debug.testplugin.CProjectHelper;
import org.eclipse.core.resources.IWorkspace;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.IncrementalProjectBuilder;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Path;
import org.eclipse.swt.widgets.Display;
import org.eclipse.ui.PlatformUI;
public abstract class AbstractDebugTest extends TestCase {
IWorkspace workspace;
IWorkspaceRoot root;
NullProgressMonitor monitor;
static ICProject testProject = null;
static ICDISession session = null;
static ICDITarget targets[] = null;
ICDITarget currentTarget;
static boolean oneTimeSetupDone = false;
@Override
protected void setUp() throws Exception {
super.setUp();
if (oneTimeSetupDone == false) {
oneTimeSetUp(); // this can happened when run junit failed test from UI, without invoking suite()
oneTimeSetupDone = false; // re-set it back so tarDownOnes will run
}
/***********************************************************************
* The tests assume that they have a working workspace and workspace
* root object to use to create projects/files in, so we need to get
* them setup first.
*/
workspace = ResourcesPlugin.getWorkspace();
root = workspace.getRoot();
monitor = new NullProgressMonitor();
if (workspace == null)
fail("Workspace was not setup"); //$NON-NLS-1$
if (root == null)
fail("Workspace root was not setup"); //$NON-NLS-1$
}
void createDebugSession() throws IOException, MIException, CModelException {
session = CDebugHelper.createSession(getProjectBinary(), testProject);
assertNotNull(session);
targets = session.getTargets();
assertNotNull(targets);
assertTrue(targets.length > 0);
currentTarget = targets[0];
}
/**
* Sets up the test fixture.
*
* Called before every test case method.
*
* Example code test the packages in the project
* "com.qnx.tools.ide.cdt.core"
*/
protected void oneTimeSetUp() throws CoreException, InvocationTargetException, IOException {
ResourcesPlugin.getWorkspace().getDescription().setAutoBuilding(false);
/***********************************************************************
* Create a new project and import the test source.
*/
Path imputFile = new Path(getProjectZip()); //$NON-NLS-1$
testProject = CProjectHelper.createCProjectWithImport(getProjectName(), imputFile); //$NON-NLS-1$
if (testProject == null)
fail("Unable to create project"); //$NON-NLS-1$
/* Build the test project.. */
testProject.getProject().build(IncrementalProjectBuilder.FULL_BUILD, null);
oneTimeSetupDone = true;
}
protected String getProjectName() {
return "filetest";
}
protected String getProjectZip() {
return "resources/debugTest.zip";
}
protected String getProjectBinary() {
return "main";
}
public static Display getDisplay() {
return PlatformUI.getWorkbench().getDisplay();
}
/**
* Dispatch ui events for at least msec - milliseconds
*
* @param msec -
* milliseconds delay
*/
public static void uimsleep(int msec) {
long cur = System.currentTimeMillis();
long pass = 0;
Display display = getDisplay();
while (pass < msec) {
if (!display.readAndDispatch())
display.sleep();
pass = System.currentTimeMillis() - cur;
}
}
/**
* Tears down the test fixture.
*
* Called after every test case method.
*/
protected void oneTimeTearDown() throws CoreException {
if (targets != null) {
try {
targets[0].terminate();
} catch (CDIException e) {
}
}
if (session != null) {
try {
session.terminate();
} catch (CDIException e) {
}
}
CProjectHelper.delete(testProject);
if (oneTimeSetupDone == false) {
oneTimeTearDown(); // this can happened when run junit failed test from UI, without invoking suite()
}
}
static class DebugTestWrapper extends TestSetup {
private AbstractDebugTest newInstance;
public DebugTestWrapper(Class clazz) {
super(new TestSuite(clazz));
/***********************************************************************
* Create a wrapper suite around the test suite we created above to
* allow us to only do the general setup once for all the tests. This is
* needed because the creation of the source and target projects takes a
* long time and we really only need to do it once. We could do the
* setup in the constructor, but we need to be able to remove everything
* when we are done.
*/
try {
newInstance = (AbstractDebugTest) clazz.newInstance();
} catch (Exception e) {
throw new IllegalArgumentException(e);
}
}
protected void setUp() throws FileNotFoundException, IOException, InterruptedException,
InvocationTargetException, CoreException {
newInstance.oneTimeSetUp();
}
protected void tearDown() throws FileNotFoundException, IOException, CoreException {
newInstance.oneTimeTearDown();
}
}
void pause() {
uimsleep(200);
}
public ICDILocator getCurrentLocator() throws CDIException {
return getCurrentFrame().getLocator();
}
public ICDIStackFrame getCurrentFrame() throws CDIException {
return currentTarget.getCurrentThread().getStackFrames()[0];
}
void waitSuspend(ICDITarget currentTarget) {
int loop;
loop = 0;
while ((currentTarget.isSuspended() == false) && (currentTarget.isTerminated() == false) && (loop < 20)) {
uimsleep(500);
loop++;
}
assertFalse("Target should be suspended, but it is terminated " + currentTarget.isTerminated(), currentTarget
.isTerminated());
assertTrue("Target should be suspended but it is not", currentTarget.isSuspended());
}
public void resumeCurrentTarget() throws CDIException{
currentTarget.resume(false);
}
void setBreakOnMain() throws CDIException {
ICDILocation location = null;
location = currentTarget.createFunctionLocation("", "main"); //$NON-NLS-1$
currentTarget.setFunctionBreakpoint(ICBreakpointType.TEMPORARY, (ICDIFunctionLocation) location, null, false);
}
@Override
protected void tearDown() throws Exception {
/* clean up the session */
if (session == null) {
session.terminate();
session = null;
}
super.tearDown();
}
}