Patchwork [8/9] testsuite: Add script to quickly re-run tests

login
register
mail settings
Submitter Alan Hayward
Date May 14, 2019, 3:12 p.m.
Message ID <20190514151238.8765-9-alan.hayward@arm.com>
Download mbox | patch
Permalink /patch/32684/
State New
Headers show

Comments

Alan Hayward - May 14, 2019, 3:12 p.m.
Using the .cmd and .in files created by a test it is fairly simple
to manually re-run a test.  For gdbserver tests, the .replay log
can also be used.

Document the process required to do this.

In addition create a script to automate the process.

2019-05-14  Alan Hayward  <alan.hayward@arm.com>

	* README (Re-running Tests Outside The Testsuite): New section.
	* lib/gdbserver-support.exp (gdbserver_run): Mark kill as optional.
	* replaytest: New test.
---
 gdb/testsuite/README                    |  23 ++++
 gdb/testsuite/lib/gdbserver-support.exp |   2 +-
 gdb/testsuite/replaytest                | 147 ++++++++++++++++++++++++
 3 files changed, 171 insertions(+), 1 deletion(-)
 create mode 100755 gdb/testsuite/replaytest

-- 
2.20.1 (Apple Git-117)

Patch

diff --git a/gdb/testsuite/README b/gdb/testsuite/README

index 98fc8d1b852..b5fbb456bee 100644

--- a/gdb/testsuite/README

+++ b/gdb/testsuite/README

@@ -95,6 +95,29 @@  example:

 
 The script will output its analysis report to the standard output.
 
+Re-running Tests Outside The Testsuite

+**************************************

+

+When running a test, the arguments used to run GDB are saved to gdb.cmd

+and any commands sent to GDB are saved to gdb.in.  As well as being a

+reference of the commands run, they can be used to manually re-run a test

+by giving the .in file as a batch file to a GDB launched with the arguments

+in the .cmd file.  For many tests you can use just the .in file:

+	$ gdb -x gdb.in

+

+Tests that run GDB multiple times will append .1, .2, .3 etc to the end

+of each .cmd and .in file.

+

+For tests requiring gdbserver, this can by executing the contents of

+gdbserver.cmd.  Alternatively, the gdbserver.replay file (created when

+running the test with GDBSERVER_DEBUG="replay") can be used with the

+gdbreplay test.

+

+This process can be automated with the "replaytest" script.

+For example:

+	$ replaytest gdb testsuite/outputs/gdb.base/store

+For more details see the documentation in the script.

+

 Running the Performance Tests
 *****************************
 
diff --git a/gdb/testsuite/lib/gdbserver-support.exp b/gdb/testsuite/lib/gdbserver-support.exp

index 2ccc717ef60..ade99c0ea16 100644

--- a/gdb/testsuite/lib/gdbserver-support.exp

+++ b/gdb/testsuite/lib/gdbserver-support.exp

@@ -484,7 +484,7 @@  proc gdbserver_run { child_args } {

     # Kill anything running before we try to start gdbserver, in case
     # we are sharing a serial connection.
     global gdb_prompt
-    send_gdb "kill\n"

+    send_gdb "kill\n" optional

     gdb_expect 120 {
 	-re "Kill the program being debugged. .y or n. $" {
 	    send_gdb "y\n"
diff --git a/gdb/testsuite/replaytest b/gdb/testsuite/replaytest

new file mode 100755
index 00000000000..4c11d9735f3

--- /dev/null

+++ b/gdb/testsuite/replaytest

@@ -0,0 +1,147 @@ 

+#!/bin/bash

+

+# Copyright (C) 2019 Free Software Foundation, Inc.

+#

+# This file is part of GDB.

+#

+# This program is free software; you can redistribute it and/or modify

+# it under the terms of the GNU General Public License as published by

+# the Free Software Foundation; either version 3 of the License, or

+# (at your option) any later version.

+#

+# This program is distributed in the hope that it will be useful,

+# but WITHOUT ANY WARRANTY; without even the implied warranty of

+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the

+# GNU General Public License for more details.

+#

+# You should have received a copy of the GNU General Public License

+# along with this program.  If not, see <http://www.gnu.org/licenses/>.

+

+#

+# This script uses GDB to replay previously run tests using the .in and

+# .cmd files from the output directory of a test.

+#

+# For example:

+#    $ replaytest gdb testsuite/outputs/gdb.base/store

+#

+#

+# For tests that have been runing using gdbserver (for example with

+# board file native-gdbserver), the test script should be run in two

+# terminals, using gdbserver and gdb modes.

+#

+# For example, in two different terminals:

+#    $ replaytest -b gdbserver testsuite/outputs/gdb.base/store

+#    $ replaytest -b gdb testsuite/outputs/gdb.base/store

+#

+# Alternatively, instead of running gdbserver, the gdbreplay tool can

+# be used instead. This uses the .replay file which is created when the

+# test is run with GDBSERVER_DEBUG="replay". gdbreplay must be in your

+# $PATH.

+#

+#

+# Tests that run GDB (and gdbserver) multiple times will create .1, .2

+# .3 etc files for each instance of GDB.  You can run a specified

+# instance using the -i flag

+#

+# For example:

+#    $ replaytest -b -i 23 gdb testsuite/outputs/gdb.base/infcall-nested-structs

+#

+# Note that to successfully run to the end of the test, the .in file must be

+# free from the answers to any interactive gdb prompts (for example the y from

+# a y/n question) or any command that causes gdb to report an error.

+#

+#

+# Usage: replaytest [-b] [-i instance] [-e] {gdb|gdbserver|replay} test_output_dir

+#

+#    -b : Run GDB in batch mode (ie: exit GDB at the end of the test).

+#    -i : Run the given instance of the test. Defaults to 0.

+#    -e : Don't run the test, just echo the command line instead.

+#

+#    test_output_dir : Directory containing all the test output files.

+#

+

+usage()

+{

+  echo "$0 [-b] [-i instance] [-e] {gdb|gdbserver|replay} test_output_dir"

+  exit 2

+}

+

+# Check file $1 exists, using test operator $2 (defaults to -e).

+check_exists()

+{

+  if [ ! ${2:-"-e"} "${1}" ]; then echo Error: Cannot find $1; exit 2; fi

+}

+

+# Run the given command in $1...n

+execute()

+{

+  if [ -n "$ECHO" ]

+  then

+    echo $@

+  else

+    # Pipe the command we want to run to a file then execute the file.  This

+    # ensures spaces within quoatation marks args get interpreted correctly.

+    OUTFILE=$(mktemp)

+    echo $@ > ${OUTFILE}

+    bash ${OUTFILE}

+    rm ${OUTFILE}

+  fi

+}

+

+# Parse command line

+while getopts bi:e line

+do

+  case $line in

+  b) EXTRA_GDBCMD="${EXTRA_GDBCMD} --batch";;

+  i) INSTANCE=".$OPTARG";;

+  e) ECHO=1;;

+  *) usage;;

+  esac

+done

+shift $(($OPTIND - 1))

+if [[ $# -ne 2 ]]; then usage; fi;

+MODE=$1

+TESTDIR=$2

+check_exists ${TESTDIR} -d

+

+

+case $MODE in

+

+"gdb") 

+  # Run the .in file through GDB by appending it to the end of the .cmd contents.

+  CMDFILE=${TESTDIR}/gdb.cmd${INSTANCE}

+  INFILE=${TESTDIR}/gdb.in${INSTANCE}

+  check_exists ${CMDFILE}

+  check_exists ${INFILE}

+  execute "$(cat $CMDFILE) ${EXTRA_GDBCMD} -x ${INFILE}"

+  ;;

+

+"gdbserver") 

+  # Run gdbserver using the .cmd file.

+  GDBSERVER_CMDFILE=${TESTDIR}/gdbserver.cmd${INSTANCE}

+  check_exists ${GDBSERVER_CMDFILE}

+  execute $(cat $GDBSERVER_CMDFILE)

+  ;;

+

+"replay") 

+  GDBSERVER_REPLAYFILE=${TESTDIR}/gdbserver.replay${INSTANCE}

+  check_exists ${GDBSERVER_REPLAYFILE}

+

+  # Extract the connection from the .cmd file.

+  GDBSERVER_CMDFILE=${TESTDIR}/gdbserver.cmd${INSTANCE}

+  check_exists ${GDBSERVER_CMDFILE}

+  GDBSERVER_HOST=$(grep -o '[^ ]*:[^ ]*' ${GDBSERVER_CMDFILE})

+

+  # Run the .replay file through gdbreplay.

+  execute gdbreplay ${GDBSERVER_REPLAYFILE} ${GDBSERVER_HOST}

+  ;;

+

+*)

+  echo "Unknown mode $MODE"

+  usage

+  ;;

+

+esac

+

+

+