/******************************************************************************* * 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(); } }