4. Running Tests

There are two ways to execute a testsuite. The most common way is when there is existing support in the Makefile. This support consists of a check target. The other way is to execute the runtest program directly. To run runtest directly from the command line requires either all the correct options, or the Local Config File must be setup correctly.

4.1. Make check

To run tests from an existing collection, first use configure as usual to set up the build directory. Then try typing:


      make check
      

If the check target exists, it usually saves you some trouble. For instance, it can set up any auxiliary programs or other files needed by the tests. The most common file the check builds is the site.exp. The site.exp file contains various variables that DejaGnu used to determine the configuration of the program being tested. This is mostly for supporting remote testing.

The check target is supported by GNU Automake. To have DejaGnu support added to your generated Makefile.in, just add the keyword dejagnu to the AUTOMAKE_OPTIONS variable in your Makefile.am file.

Once you have run make check to build any auxiliary files, you can invoke the test driver runtest directly to repeat the tests. You will also have to execute runtest directly for test collections with no check target in the Makefile.

4.2. Runtest

runtest is the executable test driver for DejaGnu. You can specify two kinds of things on the runtest command line: command line options, and Tcl variables for the test scripts. The options are listed alphabetically below.

runtest returns an exit code of 1 if any test has an unexpected result; otherwise (if all tests pass or fail as expected) it returns 0 as the exit code.

4.2.1. Output States

runtest flags the outcome of each test as one of these cases. A POSIX Conforming Test Framework for a discussion of how POSIX specifies the meanings of these cases.

PASS

The most desirable outcome: the test succeeded, and was expected to succeed.

XPASS

A pleasant kind of failure: a test was expected to fail, but succeeded. This may indicate progress; inspect the test case to determine whether you should amend it to stop expecting failure.

FAIL

A test failed, although it was expected to succeed. This may indicate regress; inspect the test case and the failing software to locate the bug.

XFAIL

A test failed, but it was expected to fail. This result indicates no change in a known bug. If a test fails because the operating system where the test runs lacks some facility required by the test, the outcome is UNSUPPORTED instead.

UNRESOLVED

Output from a test requires manual inspection; the testsuite could not automatically determine the outcome. For example, your tests can report this outcome is when a test does not complete as expected.

UNTESTED

A test case is not yet complete, and in particular cannot yet produce a PASS or FAIL. You can also use this outcome in dummy ``tests'' that note explicitly the absence of a real test case for a particular property.

UNSUPPORTED

A test depends on a conditionally available feature that does not exist (in the configured testing environment). For example, you can use this outcome to report on a test case that does not work on a particular target because its operating system support does not include a required subroutine.

runtest may also display the following messages:

ERROR

Indicates a major problem (detected by the test case itself) in running the test. This is usually an unrecoverable error, such as a missing file or loss of communication to the target. (POSIX testsuites should not emit this message; use UNSUPPORTED, UNTESTED, or UNRESOLVED instead, as appropriate.)

WARNING

Indicates a possible problem in running the test. Usually warnings correspond to recoverable errors, or display an important message about the following tests.

NOTE

An informational message about the test case.

4.2.2. Invoking Runtest

This is the full set of command line options that runtest recognizes. Arguments may be abbreviated to the shortest unique string.

--all (-a)

Display all test output. By default, runtest shows only the output of tests that produce unexpected results; that is, tests with status FAIL (unexpected failure), XPASS (unexpected success), or ERROR (a severe error in the test case itself). Specify --all to see output for tests with status PASS (success, as expected) XFAIL (failure, as expected), or WARNING (minor error in the test case itself).

--build [string]

string is a full configuration ``triple'' name as used by configure. This is the type of machine DejaGnu and the tools to be tested are built on. For a normal cross this is the same as the host, but for a canadian cross, they are separate.

--host [string]

string is a full configuration ``triple'' name as used by configure. Use this option to override the default string recorded by your configuration's choice of host. This choice does not change how anything is actually configured unless --build is also specified; it affects only DejaGnu procedures that compare the host string with particular values. The procedures ishost, istarget, isnative, and setupxfail} are affected by --host. In this usage, host refers to the machine that the tests are to be run on, which may not be the same as the build machine. If --build is also specified, then --host refers to the machine that the tests wil, be run on, not the machine DejaGnu is run on.

--host_board [name]

The host board to use.

--target [string]

Use this option to override the default setting (running native tests). string is a full configuration ``triple'' name of the form cpu-vendor-os as used by configure. This option changes the configuration runtest uses for the default tool names, and other setup information.

--debug (-de)

Turns on the expect internal debugging output. Debugging output is displayed as part of the runtest output, and logged to a file called dbg.log. The extra debugging output does not appear on standard output, unless the verbose level is greater than 2 (for instance, to see debug output immediately, specify --debug-v -v}). The debugging output shows all attempts at matching the test output of the tool with the scripted patterns describing expected output. The output generated with --strace also goes into dbg.log.

--help (-he)

Prints out a short summary of the runtest options, then exits (even if you also specify other options).

--ignore [name(s)]

The names of specific tests to ignore.

--objdir [path]

Use path as the top directory containing any auxiliary compiled test code. This defaults to .. Use this option to locate pre-compiled test code. You can normally prepare any auxiliary files needed with make.

--outdir [path]

Write output logs in directory path. The default is .}, the directory where you start runtest. This option affects only the summary and the detailed log files tool.sum and tool.log. The DejaGnu debug log dbg.log always appears (when requested) in the local directory.

--reboot [name]

Reboot the target board when runtest initializes. Usually, when running tests on a separate target board, it is safer to reboot the target to be certain of its state. However, when developing test scripts, rebooting takes a lot of time.

--srcdir [path]

Use path as the top directory for test scripts to run. runtest looks in this directory for any subdirectory whose name begins with the toolname (specified with --tool). For instance, with --toolgdb}, runtest uses tests in subdirectories gdb.* (with the usual shell-like filename expansion). If you do not use --srcdir, runtest looks for test directories under the current working directory.

--strace [number]

Turn on internal tracing for expect, to n levels deep. By adjusting the level, you can control the extent to which your output expands multi-level Tcl statements. This allows you to ignore some levels of case or if statements. Each procedure call or control structure counts as one ``level''. The output is recorded in the same file, dbg.log, used for output from --debug.

--connect [program]

Connect to a target testing environment as specified by type, if the target is not the computer running runtest. For example, use --connect to change the program used to connect to a ``bare board'' boot monitor. The choices for type in the DejaGnu 1.4 distribution are rlogin, telnet, rsh, tip, kermit, and mondfe.

The default for this option depends on the configuration most convenient communication method available, but often other alternatives work as well; you may find it useful to try alternative connect methods if you suspect a communication problem with your testing target.

--baud [number]

Set the default baud rate to something other than 9600. (Some serial interface programs, like tip, use a separate initialization file instead of this value.)

--target_board [name(s)]

The list of target boards to run tests on.

--tool[name(s)]

Specifies which testsuite to run, and what initialization module to use. --tool is used only for these two purposes. It is not used to name the executable program to test. Executable tool names (and paths) are recorded in site.exp and you can override them by specifying Tcl variables on the command line.

For example, including "--tool gcc" on the runtest command line runs tests from all test subdirectories whose names match gcc.*, and uses one of the initialization modules named config/*-gcc.exp. To specify the name of the compiler (perhaps as an alternative path to what runtest would use by default), use GCC=binname on the runtest command line.

--tool_exec [name]

The path to the tool executable to test.

--tool_opts [options]

A list of additional options to pass to the tool.

--verbose (-v)

Turns on more output. Repeating this option increases the amount of output displayed. Level one (-v) is simply test output. Level two (-v-v}) shows messages on options, configuration, and process control. Verbose messages appear in the detailed (*.log) log file, but not in the summary (*.sum) log file.

--version (-V)

Prints out the version numbers of DejaGnu, expect and Tcl, and exits without running any tests.

--D[0-1]

Start the internal Tcl debugger. The Tcl debugger supports breakpoints, single stepping, and other common debugging activities. See the document "Debugger for Tcl Applications" by Don Libes. (Distributed in PostScript form with expect as the file expect/tcl-debug.ps.. If you specify -D1, the expect shell stops at a breakpoint as soon as DejaGnu invokes it. If you specify -D0, DejaGnu starts as usual, but you can enter the debugger by sending an interrupt (e.g. by typing C-c).

testfile.exp[=arg(s)]

Specify the names of testsuites to run. By default, runtest runs all tests for the tool, but you can restrict it to particular testsuites by giving the names of the .exp expect scripts that control them. testsuite.exp may not include path information; use plain filenames.

testfile.exp="testfile1 ..."

Specify a subset of tests in a suite to run. For compiler or assembler tests, which often use a single .exp script covering many different source files, this option allows you to further restrict the tests by listing particular source files to compile. Some tools even support wildcards here. The wildcards supported depend upon the tool, but typically they are ?, *, and [chars].

tclvar=value

You can define Tcl variables for use by your test scripts in the same style used with make for environment variables. For example, runtest GDB=gdb.old defines a variable called GDB; when your scripts refer to $GDB in this run, they use the value gdb.old.

The default Tcl variables used for most tools are defined in the main DejaGnu Makefile; their values are captured in the site.exp file.

4.2.3. Common Options

Typically, you don't need must to use any command-line options. --tool used is only required when there are more than one testsuite in the same directory. The default options are in the local site.exp file, created by "make site.exp".

For example, if the directory gdb/testsuite contains a collection of DejaGnu tests for GDB, you can run them like this:


	  eg$ cd gdb/testsuite
	  eg$ runtest --tool gdb
	

Test output follows, ending with:


		=== gdb Summary ===

		# of expected passes 508
		# of expected failures 103
		/usr/latest/bin/gdb version 4.14.4 -nx
	

You can use the option --srcdir to point to some other directory containing a collection of tests:


	  eg$ runtest--srcdir /devo/gdb/testsuite
	

By default, runtest prints only the names of the tests it runs, output from any tests that have unexpected results, and a summary showing how many tests passed and how many failed. To display output from all tests (whether or not they behave as expected), use the --all option. For more verbose output about processes being run, communication, and so on, use --verbose. To see even more output, use multiple --verbose options. for a more detailed explanation of each runtest option.

Test output goes into two files in your current directory: summary output in tool.sum, and detailed output in tool.log. (tool refers to the collection of tests; for example, after a run with --tool gdb, look for output files gdb.sum and gdb.log.)

4.3. The files DejaGnu produces.

DejaGnu always writes two kinds of output files: summary logs and detailed logs. The contents of both of these are determined by your tests.

For troubleshooting, a third kind of output file is useful: use --debug to request an output file showing details of what Expect is doing internally.

4.3.1. Summary File

DejaGnu always produces a summary output file tool.sum. This summary shows the names of all test files run; for each test file, one line of output from each pass command (showing status PASS or XPASS) or fail command (status FAIL or XFAIL); trailing summary statistics that count passing and failing tests (expected and unexpected); and the full pathname and version number of the tool tested. (All possible outcomes, and all errors, are always reflected in the summary output file, regardless of whether or not you specify --all.)

If any of your tests use the procedures unresolved, unsupported, or runtested, the summary output also tabulates the corresponding outcomes.

For example, after runtest --tool binutils, look for a summary log in binutils.sum. Normally, DejaGnu writes this file in your current working directory; use the --outdir option to select a different directory.

Example 19. Here is a short sample summary log


	Test Run By rob on Mon May 25 21:40:57 PDT 1992
		 === gdb tests ===
	Running ./gdb.t00/echo.exp ...
	PASS:   Echo test
	Running ./gdb.all/help.exp ...
	PASS:   help add-symbol-file
	PASS:   help aliases
	PASS:   help breakpoint "bre" abbreviation
	FAIL:   help run "r" abbreviation
	Running ./gdb.t10/crossload.exp ...
	PASS:   m68k-elf (elf-big) explicit format; loaded
	XFAIL:  mips-ecoff (ecoff-bigmips) "ptype v_signed_char" signed C types
                === gdb Summary ===
	# of expected passes 5
	# of expected failures 1
	# of unexpected failures 1
	/usr/latest/bin/gdb version 4.6.5 -q
      

4.3.2. Log File

DejaGnu also saves a detailed log file tool.log, showing any output generated by tests as well as the summary output. For example, after runtest --tool binutils, look for a detailed log in binutils.log. Normally, DejaGnu writes this file in your current working directory; use the --outdir option to select a different directory.

Example 20. Here is a brief example showing a detailed log for G++ tests


	Test Run By rob on Mon May 25 21:40:43 PDT 1992

                === g++ tests ===

	--- Running ./g++.other/t01-1.exp ---
        PASS:   operate delete

	--- Running ./g++.other/t01-2.exp ---
        FAIL:   i960 bug EOF
	p0000646.C: In function `int  warn_return_1 ()':
	p0000646.C:109: warning: control reaches end of non-void function
	p0000646.C: In function `int  warn_return_arg (int)':
	p0000646.C:117: warning: control reaches end of non-void function
	p0000646.C: In function `int  warn_return_sum (int, int)':
	p0000646.C:125: warning: control reaches end of non-void function
	p0000646.C: In function `struct foo warn_return_foo ()':
	p0000646.C:132: warning: control reaches end of non-void function

	--- Running ./g++.other/t01-4.exp ---
        FAIL:   abort
	900403_04.C:8: zero width for bit-field `foo'
	--- Running ./g++.other/t01-3.exp ---
        FAIL:   segment violation
	900519_12.C:9: parse error before `;'
	900519_12.C:12: Segmentation violation
	/usr/latest/bin/gcc: Internal compiler error: program cc1plus got fatal signal

                === g++ Summary ===

	# of expected passes 1
	# of expected failures 3
	/usr/latest/bin/g++ version cygnus-2.0.1
	

4.3.3. Debug Log File

With the --debug option, you can request a log file showing the output from Expect itself, running in debugging mode. This file (dbg.log, in the directory where you start runtest) shows each pattern Expect considers in analyzing test output.

This file reflects each send command, showing the string sent as input to the tool under test; and each Expect command, showing each pattern it compares with the tool output.

Example 21. The log messages begin with a message of the form


	expect: does {tool output} (spawn_id n)
	 match pattern {expected pattern}?

        

For every unsuccessful match, Expect issues a no after this message; if other patterns are specified for the same Expect command, they are reflected also, but without the first part of the message (expect... match pattern).

When Expect finds a match, the log for the successful match ends with yes, followed by a record of the Expect variables set to describe a successful match.

Example 22. Here is an excerpt from the debugging log for a GDB test:


	send: sent {break gdbme.c:34\n} to spawn id 6
	expect: does {} (spawn_id 6) match pattern {Breakpoint.*at.* file
	gdbme.c, line 34.*\(gdb\) $}? no
	{.*\(gdb\) $}? no
	expect: does {} (spawn_id 0) match pattern {return} ? no
	{\(y or n\) }? no
	{buffer_full}? no
	{virtual}? no
	{memory}? no
	{exhausted}? no
	{Undefined}? no
	{command}? no
	break gdbme.c:34
	Breakpoint 8 at 0x23d8: file gdbme.c, line 34.
	(gdb) expect: does {break gdbme.c:34\r\nBreakpoint 8 at 0x23d8:
	file gdbme.c, line 34.\r\n(gdb) } (spawn_id 6) match pattern
	{Breakpoint.*at.* file gdbme.c, line 34.*\(gdb\) $}? yes
	expect: set expect_out(0,start) {18}
	expect: set expect_out(0,end) {71}
	expect: set expect_out(0,string) {Breakpoint 8 at 0x23d8: file
	gdbme.c, line 34.\r\n(gdb) }
	epect: set expect_out(spawn_id) {6}
	expect: set expect_out(buffer) {break gdbme.c:34\r\nBreakpoint 8
	at 0x23d8: file gdbme.c, line 34.\r\n(gdb) }
        PASS:   70      0       breakpoint line number in file
	

This example exhibits three properties of Expect and DejaGnu that might be surprising at first glance:

  • Empty output for the first attempted match. The first set of attempted matches shown ran against the output {} --- that is, no output. Expect begins attempting to match the patterns supplied immediately; often, the first pass is against incomplete output (or completely before all output, as in this case).

  • Interspersed tool output. The beginning of the log entry for the second attempted match may be hard to spot: this is because the prompt {(gdb) } appears on the same line, just before the expect: that marks the beginning of the log entry.

  • Fail-safe patterns. Many of the patterns tested are fail-safe patterns provided by GDB testing utilities, to reduce possible indeterminacy. It is useful to anticipate potential variations caused by extreme system conditions (GDB might issue the message virtual memory exhausted in rare circumstances), or by changes in the tested program (Undefined command is the likeliest outcome if the name of a tested command changes).

    The pattern {return} is a particularly interesting fail-safe to notice; it checks for an unexpected RET prompt. This may happen, for example, if the tested tool can filter output through a pager.

    These fail-safe patterns (like the debugging log itself) are primarily useful while developing test scripts. Use the error procedure to make the actions for fail-safe patterns produce messages starting with ERROR on standard output, and in the detailed log file.