From b00b1289721c67f40e4e2304fdd1c98d876d50ed Mon Sep 17 00:00:00 2001 From: Marc Khouzam Date: Thu, 16 Feb 2012 21:40:09 -0500 Subject: [PATCH] Bug 362039: New postmortem JUnit tests --- .../dsf/gdb/tests/PostMortemCoreTest.java | 297 +++++++++++++++++- 1 file changed, 281 insertions(+), 16 deletions(-) diff --git a/dsf-gdb/org.eclipse.cdt.tests.dsf.gdb/src/org/eclipse/cdt/tests/dsf/gdb/tests/PostMortemCoreTest.java b/dsf-gdb/org.eclipse.cdt.tests.dsf.gdb/src/org/eclipse/cdt/tests/dsf/gdb/tests/PostMortemCoreTest.java index 9d7732ae838..47b2dff57c0 100644 --- a/dsf-gdb/org.eclipse.cdt.tests.dsf.gdb/src/org/eclipse/cdt/tests/dsf/gdb/tests/PostMortemCoreTest.java +++ b/dsf-gdb/org.eclipse.cdt.tests.dsf.gdb/src/org/eclipse/cdt/tests/dsf/gdb/tests/PostMortemCoreTest.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2011 Ericsson and others. + * Copyright (c) 2011, 2012 Ericsson 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 @@ -7,6 +7,8 @@ * * Contributors: * Ericsson - Initial Implementation + * Marc Khouzam (Ericsson) - Added test to handle different cases of core + * file specification (Bug 362039) *******************************************************************************/ package org.eclipse.cdt.tests.dsf.gdb.tests; @@ -14,6 +16,7 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; +import java.io.File; import java.util.HashMap; import java.util.Map; import java.util.concurrent.TimeUnit; @@ -40,12 +43,18 @@ import org.eclipse.cdt.tests.dsf.gdb.framework.BaseTestCase; import org.eclipse.cdt.tests.dsf.gdb.framework.SyncUtil; import org.eclipse.cdt.tests.dsf.gdb.launching.TestsPlugin; import org.eclipse.cdt.utils.Addr64; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Path; import org.eclipse.core.runtime.Status; +import org.eclipse.core.variables.VariablesPlugin; +import org.eclipse.debug.core.DebugException; import org.eclipse.debug.core.model.MemoryByte; import org.junit.After; import org.junit.Before; import org.junit.BeforeClass; +import org.junit.Ignore; import org.junit.Test; import org.junit.runner.RunWith; @@ -64,7 +73,27 @@ public class PostMortemCoreTest extends BaseTestCase { @BeforeClass public static void beforeClassMethod() { - setLaunchAttribute(ICDTLaunchConfigurationConstants.ATTR_PROGRAM_NAME, "data/launch/bin/ExpressionTestApp.exe"); + } + + @Override + @Before + public void baseBeforeMethod() throws Exception { + // The class BaseTestCase sets up the launch in its @BeforeClass method. + // Usually this is ok, because every test uses the same launch configuration. + // However, for some of the tests of this class, we are changing the launch + // configuration. Therefore, we need to reset it to the default + // before every test; that means in the @Before method instead of @BeforeClass + + // Reset the launch configuration + super.baseBeforeClassMethod(); + + // Set a working directory for GDB that is different than eclipse's directory. + // This allows us to make sure we properly handle finding the core file, + // especially in the case of a relative path + setLaunchAttribute(ICDTLaunchConfigurationConstants.ATTR_WORKING_DIRECTORY, "${workspace_loc}"); + // Because we just set a different working directory, we must use an absolute path for the program + String absoluteProgram = new Path("data/launch/bin/ExpressionTestApp.exe").toFile().getAbsolutePath(); + setLaunchAttribute(ICDTLaunchConfigurationConstants.ATTR_PROGRAM_NAME, absoluteProgram); // Set post-mortem launch setLaunchAttribute(ICDTLaunchConfigurationConstants.ATTR_DEBUGGER_START_MODE, @@ -72,12 +101,21 @@ public class PostMortemCoreTest extends BaseTestCase { // Set post-mortem type to core file setLaunchAttribute(IGDBLaunchConfigurationConstants.ATTR_DEBUGGER_POST_MORTEM_TYPE, IGDBLaunchConfigurationConstants.DEBUGGER_POST_MORTEM_CORE_FILE); - // Set core file path + // Set default core file path setLaunchAttribute(ICDTLaunchConfigurationConstants.ATTR_COREFILE_PATH, "data/launch/bin/core"); - } + + + // Can't run the launch right away because each test needs to first set some + // parameters. The individual tests will be responsible for starting the launch. + } + + // This method cannot be tagged as @Before, because the launch is not + // running yet. We have to call this manually after all the proper + // parameters have been set for the launch + public void performLaunch() throws Exception { + // perform the launch + super.baseBeforeMethod(); - @Before - public void init() throws Exception { fSession = getGDBLaunch().getSession(); fMemoryDmc = (IMemoryDMContext)SyncUtil.getContainerContext(); @@ -96,16 +134,192 @@ public class PostMortemCoreTest extends BaseTestCase { @After public void shutdown() throws Exception { - Runnable runnable = new Runnable() { - @Override - public void run() { - fSession.removeServiceEventListener(PostMortemCoreTest.this); - } - }; - fSession.getExecutor().submit(runnable).get(); - fExpService = null; - fMemoryService = null; - fServicesTracker.dispose(); + if (fSession != null) { + Runnable runnable = new Runnable() { + @Override + public void run() { + fSession.removeServiceEventListener(PostMortemCoreTest.this); + } + }; + fSession.getExecutor().submit(runnable).get(); + } + + fExpService = null; + fMemoryService = null; + if (fServicesTracker != null) fServicesTracker.dispose(); + } + + /** + * Test that we support specifying a core file with an absolute path. + */ + @Test + public void testAbsoluteCoreFilePath() throws Throwable { + File file = new File("data/launch/bin/core"); + assertTrue("Cannot find test file; " + file.toString(), file.exists()); + + String absoluteCoreFile = file.getAbsolutePath(); + + setLaunchAttribute(ICDTLaunchConfigurationConstants.ATTR_COREFILE_PATH, absoluteCoreFile); + + performLaunch(); + + // If the launch passed, we are ok, nothing more to check + } + + /** + * Test that we support specifying a core file with a relative path. + */ + @Test + public void testRelativeCoreFilePath() throws Throwable { + File file = new File("data/launch/bin/core"); + assertTrue("Cannot find test file; " + file.toString(), file.exists()); + + String relativeCoreFile = file.toString(); + + setLaunchAttribute(ICDTLaunchConfigurationConstants.ATTR_COREFILE_PATH, relativeCoreFile); + + performLaunch(); + + // If the launch passed, we are ok, nothing more to check + } + + /** + * Test that we handle specifying an invalid core file with an absolute path. + */ + @Test + public void testAbsoluteCoreFilePathInvalid() throws Throwable { + File file = new File("data/launch/bin/MultiThread.exe"); + assertTrue("Cannot find test file: " + file.toString(), file.exists()); + + String absoluteCoreFile = file.getAbsolutePath(); + + setLaunchAttribute(ICDTLaunchConfigurationConstants.ATTR_COREFILE_PATH, absoluteCoreFile); + + try { + performLaunch(); + } catch (DebugException e) { + // Success of the test + return; + } + + fail("Launch seems to have succeeded even though the specified core file is invalid"); + } + + /** + * Test that we handle specifying an invalid core file with a relative path. + */ + @Test + public void testRelativeCoreFilePathInvalid() throws Throwable { + File file = new File("data/launch/bin/MultiThread.exe"); + assertTrue("Cannot find test file: " + file.toString(), file.exists()); + + String relativeCoreFile = file.toString(); + + setLaunchAttribute(ICDTLaunchConfigurationConstants.ATTR_COREFILE_PATH, relativeCoreFile); + + try { + performLaunch(); + } catch (CoreException e) { + // Success of the test + return; + } + + fail("Launch seems to have succeeded even though the specified core file is invalid"); + } + + /** + * Test that we handle specifying a missing core file with an absolute path. + */ + @Test + public void testAbsoluteCoreFilePathMissing() throws Throwable { + File file = new File("data/launch/bin/MissingFile"); + assertTrue("Should not have found test file: " + file.toString(), !file.exists()); + + String absoluteCoreFile = file.getAbsolutePath(); + + setLaunchAttribute(ICDTLaunchConfigurationConstants.ATTR_COREFILE_PATH, absoluteCoreFile); + + try { + performLaunch(); + } catch (CoreException e) { + // Success of the test + return; + } + + fail("Launch seems to have succeeded even though the specified core file does not exist"); + } + + /** + * Test that we handle specifying a missing core file with a relative path. + */ + @Test + public void testRelativeCoreFilePathMissing() throws Throwable { + File file = new File("data/launch/bin/MissingFile"); + assertTrue("Should not have found test file: " + file.toString(), !file.exists()); + + String relativeCoreFile = file.toString(); + + setLaunchAttribute(ICDTLaunchConfigurationConstants.ATTR_COREFILE_PATH, relativeCoreFile); + + try { + performLaunch(); + } catch (CoreException e) { + // Success of the test + return; + } + + fail("Launch seems to have succeeded even though the specified core file does not exist"); + } + + /** + * Test that we support a valid core file path using variables. + */ + @Test + public void testCoreFilePathWithVariable() throws Throwable { + // I couldn't find an easy way to test with a variable. + // Here what we do here: + // create the variable for the workspace location and expand it + // The resulting path has a common part with the absolute core + // file path. Find that common part and count how many .. we + // have to insert to use the common part of the variablePath + // inside the absolute path. + // Then, send the variable itself, with all the .., and the + // absolute path, and make sure the variable gets translated + // properly. + + // Absolute path of the core file + File file = new File("data/launch/bin/core"); + String absoluteCoreFile = file.getAbsolutePath(); + + // Variable for workspace location + String variable = "${workspace_loc}"; + // Expand workspace location + String workspaceLocation = VariablesPlugin.getDefault().getStringVariableManager().performStringSubstitution(variable, false); + + // Path to the core file + IPath corePath = new Path(absoluteCoreFile); + // Prepare to find the common path between the core file and the workspace + IPath commonPath = new Path(workspaceLocation); + + StringBuffer backwards = new StringBuffer("/"); + // While the commonPath is not the prefix of the core file path + // remove one more segment of the potential commonPath + while (!commonPath.isPrefixOf(corePath)) { + commonPath = commonPath.removeLastSegments(1); + backwards.append("../"); + } + + // Remove the commonPath from the workspace path + IPath trailingPathCoreFile = corePath.removeFirstSegments(commonPath.segmentCount()); + + // Build the path using the variable unexpanded, the number of .. + // to remove all non-common segments, the trailing part of the + // path of the core file + String coreFile = variable + backwards.toString() + trailingPathCoreFile; + + setLaunchAttribute(ICDTLaunchConfigurationConstants.ATTR_COREFILE_PATH, coreFile); + + performLaunch(); } /** @@ -113,6 +327,8 @@ public class PostMortemCoreTest extends BaseTestCase { */ @Test public void testLiteralIntegerExpressions() throws Throwable { + performLaunch(); + // Create a map of expressions and their expected values. Map tests = new HashMap(); @@ -134,6 +350,8 @@ public class PostMortemCoreTest extends BaseTestCase { */ @Test public void testLiteralFloatingPointExpressions() throws Throwable { + performLaunch(); + // Create a map of expressions and their expected values. Map tests = new HashMap(); @@ -156,6 +374,8 @@ public class PostMortemCoreTest extends BaseTestCase { */ @Test public void testLocalVariables() throws Throwable { + performLaunch(); + // Create a map of expressions to expected values. Map tests1 = new HashMap(); @@ -186,6 +406,8 @@ public class PostMortemCoreTest extends BaseTestCase { @Test public void readMemoryArray() throws Throwable { + performLaunch(); + IAddress address = evaluateExpression(SyncUtil.getStackFrame(SyncUtil.getExecutionContext(0), 0), "&lBoolPtr2"); final int LENGTH = 4; @@ -201,6 +423,49 @@ public class PostMortemCoreTest extends BaseTestCase { assertEquals(buffer[3].getValue(), 0x12); } + /** + * Test that we support setting only the initial path with an absolute path. + */ + @Ignore("Can't test without the UI") + @Test + public void testAbsoluteInitialPath() throws Throwable { + } + /** + * Test that we support setting an invalid initial path with an absolute path. + */ + @Ignore("Can't test without the UI") + @Test + public void testAbsoluteInitialPathInvalid() throws Throwable { + } + /** + * Test that we support setting only the initial path with a relative path. + */ + @Ignore("Can't test without the UI") + @Test + public void testRelativeInitialPath() throws Throwable { + } + /** + * Test that we support an empty path + */ + @Ignore("Can't test without the UI") + @Test + public void testEmptyInitialPath() throws Throwable { + } + /** + * Test that we support a valid initial path using variables. + */ + @Ignore("Can't test without the UI") + @Test + public void testInitialPathWithVariable() throws Throwable { + } + /** + * Test that we support setting an invalid initial path with a relative path. + */ + @Ignore("Can't test without the UI") + @Test + public void testRelativeInitialPathInvalid() throws Throwable { + } + private IAddress evaluateExpression(IDMContext ctx, String expression) throws Throwable { // Create the expression and format contexts