blob: 4cec9b0ba5494f3a29cfdff30fc2da719ab770ca [file] [log] [blame]
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
<HTML
><HEAD
><TITLE
>Adding A New Tool</TITLE
><META
NAME="GENERATOR"
CONTENT="Modular DocBook HTML Stylesheet Version 1.76b+
"><LINK
REL="HOME"
TITLE="DejaGnu"
HREF="book1.html"><LINK
REL="UP"
TITLE="Extending DejaGnu"
HREF="c1099.html"><LINK
REL="PREVIOUS"
TITLE="Extending DejaGnu"
HREF="c1099.html"><LINK
REL="NEXT"
TITLE="Adding A New Target"
HREF="x1195.html"></HEAD
><BODY
CLASS="SECT1"
BGCOLOR="#FFFFFF"
TEXT="#000000"
LINK="#0000FF"
VLINK="#840084"
ALINK="#0000FF"
><DIV
CLASS="NAVHEADER"
><TABLE
SUMMARY="Header navigation table"
WIDTH="100%"
BORDER="0"
CELLPADDING="0"
CELLSPACING="0"
><TR
><TH
COLSPAN="3"
ALIGN="center"
>DejaGnu: The GNU Testing Framework</TH
></TR
><TR
><TD
WIDTH="10%"
ALIGN="left"
VALIGN="bottom"
><A
HREF="c1099.html"
ACCESSKEY="P"
>&#60;&#60;&#60; Previous</A
></TD
><TD
WIDTH="80%"
ALIGN="center"
VALIGN="bottom"
>Extending DejaGnu</TD
><TD
WIDTH="10%"
ALIGN="right"
VALIGN="bottom"
><A
HREF="x1195.html"
ACCESSKEY="N"
>Next &#62;&#62;&#62;</A
></TD
></TR
></TABLE
><HR
ALIGN="LEFT"
WIDTH="100%"></DIV
><DIV
CLASS="SECT1"
><H1
CLASS="SECT1"
><A
NAME="ADDTOOL"
></A
>Adding A New Tool</H1
><P
>In general, the best way to learn how to write (code or even prose)
is to read something similar. This principle applies to test cases and
to testsuites. Unfortunately, well-established testsuites have a way
of developing their own conventions: as test writers become more
experienced with DejaGnu and with Tcl, they accumulate more utilities,
and take advantage of more and more features of
<SPAN
CLASS="PRODUCTNAME"
>Expect</SPAN
> and <SPAN
CLASS="PRODUCTNAME"
>Tcl</SPAN
> in
general.</P
><P
>Inspecting such established testsuites may make the prospect of
creating an entirely new testsuite appear overwhelming. Nevertheless,
it is quite straightforward to get a new testsuite going.</P
><P
>There is one testsuite that is guaranteed not to grow more
elaborate over time: both it and the tool it tests were created expressly
to illustrate what it takes to get started with DejaGnu. The
<TT
CLASS="FILENAME"
>example/</TT
> directory of the DejaGnu distribution
contains both an interactive tool called <B
CLASS="COMMAND"
>calc</B
>, and a
testsuite for it. Reading this testsuite, and experimenting with it,
is a good way to supplement the information in this section. (Thanks to
Robert Lupton for creating calc and its testsuite---and also the first
version of this section of the manual!)</P
><P
>To help orient you further in this task, here is an outline of the
steps to begin building a testsuite for a program example.</P
><P
></P
><UL
><LI
STYLE="list-style-type: disc"
><P
>Create or select a directory to contain your new
collection of tests. Change into that directory (shown here as
<TT
CLASS="FILENAME"
>testsuite</TT
>):</P
><P
>Create a <TT
CLASS="FILENAME"
>configure.in</TT
> file in this directory,
to control configuration-dependent choices for your tests. So far as
DejaGnu is concerned, the important thing is to set a value for the
variable <SPAN
CLASS="SYMBOL"
>target_abbrev</SPAN
>; this value is the link to the
init file you will write soon. (For simplicity, we assume the
environment is Unix, and use <I
CLASS="EMPHASIS"
>unix</I
> as the
value.)</P
><P
>What else is needed in <TT
CLASS="FILENAME"
>configure.in</TT
> depends on
the requirements of your tool, your intended test environments, and which
configure system you use. This example is a minimal configure.in for use
with <SPAN
CLASS="PRODUCTNAME"
>GNU Autoconf</SPAN
>. </P
></LI
><LI
STYLE="list-style-type: disc"
><P
>Create <TT
CLASS="FILENAME"
>Makefile.in</TT
> (if you are using
Autoconf), or <TT
CLASS="FILENAME"
>Makefile.am</TT
>(if you are using
Automake), the source file used by configure to build your
<TT
CLASS="FILENAME"
>Makefile</TT
>. If you are using GNU Automake.just add the
keyword <I
CLASS="EMPHASIS"
>dejagnu</I
> to the
<I
CLASS="EMPHASIS"
>AUTOMAKE_OPTIONS</I
> variable in your
<TT
CLASS="FILENAME"
>Makefile.am</TT
> file. This will add all the Makefile
support needed to run DejaGnu, and support the <A
HREF="c401.html#MAKECHECK"
>Make Check</A
>
target.</P
><P
>You also need to include two targets important to DejaGnu:
<I
CLASS="EMPHASIS"
>check</I
>, to run the tests, and
<I
CLASS="EMPHASIS"
>site.exp</I
>, to set up the Tcl copies of
configuration-dependent values. This is called the <A
HREF="c848.html#LOCAL"
>Local Config File</A
>
The check target must run the <B
CLASS="COMMAND"
>runtest</B
> program to
execute the tests.</P
><P
>The <TT
CLASS="FILENAME"
>site.exp</TT
> target should usually set up
(among other things) the $tool variable for the name of your program. If
the local site.exp file is setup correctly, it is possible to execute the
tests by merely typing <B
CLASS="COMMAND"
>runtest</B
> on the command
line.</P
><DIV
CLASS="EXAMPLE"
><A
NAME="AEN1145"
></A
><P
><B
>Example 1. Sample Makefile.in Fragment</B
></P
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="90%"
><TR
><TD
><PRE
CLASS="PROGRAMLISTING"
> # Look for a local version of DejaGnu, otherwise use one in the path
RUNTEST = `if test -f $(top_srcdir)/../dejagnu/runtest; then \
echo $(top_srcdir) ../dejagnu/runtest; \
else \
echo runtest; \
fi`
# The flags to pass to runtest
RUNTESTFLAGS =
# Execute the tests
check: site.exp all
$(RUNTEST) $(RUNTESTFLAGS) \
--tool <SPAN
CLASS="SYMBOL"
>${example}</SPAN
> --srcdir $(srcdir)
# Make the local config file
site.exp: ./config.status Makefile
@echo "Making a new config file..."
-@rm -f ./tmp?
@touch site.exp
-@mv site.exp site.bak
@echo "## these variables are automatically\
generated by make ##" &#62; ./tmp0
@echo "# Do not edit here. If you wish to\
override these values" &#62;&#62; ./tmp0
@echo "# add them to the last section" &#62;&#62; ./tmp0
@echo "set host_os ${host_os}" &#62;&#62; ./tmp0
@echo "set host_alias ${host_alias}" &#62;&#62; ./tmp0
@echo "set host_cpu ${host_cpu}" &#62;&#62; ./tmp0
@echo "set host_vendor ${host_vendor}" &#62;&#62; ./tmp0
@echo "set target_os ${target_os}" &#62;&#62; ./tmp0
@echo "set target_alias ${target_alias}" &#62;&#62; ./tmp0
@echo "set target_cpu ${target_cpu}" &#62;&#62; ./tmp0
@echo "set target_vendor ${target_vendor}" &#62;&#62; ./tmp0
@echo "set host_triplet ${host_canonical}" &#62;&#62; ./tmp0
@echo "set target_triplet ${target_canonical}"&#62;&#62;./tmp0
@echo "set tool binutils" &#62;&#62; ./tmp0
@echo "set srcdir ${srcdir}" &#62;&#62; ./tmp0
@echo "set objdir `pwd`" &#62;&#62; ./tmp0
@echo "set <SPAN
CLASS="SYMBOL"
>${examplename}</SPAN
> <SPAN
CLASS="SYMBOL"
>${example}</SPAN
>" &#62;&#62; ./tmp0
@echo "## All variables above are generated by\
configure. Do Not Edit ##" &#62;&#62; ./tmp0
@cat ./tmp0 &#62; site.exp
@sed &#60; site.bak \
-e '1,/^## All variables above are.*##/ d' \
&#62;&#62; site.exp
-@rm -f ./tmp?
</PRE
></TD
></TR
></TABLE
></DIV
></LI
><LI
STYLE="list-style-type: disc"
><P
>Create a directory (in <TT
CLASS="FILENAME"
>testsuite</TT
>)
called <TT
CLASS="FILENAME"
>config</TT
>. Make a <I
CLASS="EMPHASIS"
>Tool Init
File</I
> in this directory. Its name must start with the
<SPAN
CLASS="SYMBOL"
>target_abbrev</SPAN
> value, or be named
<TT
CLASS="FILENAME"
>default.exp</TT
> so call it
<TT
CLASS="FILENAME"
>config/unix.exp</TT
> for our Unix based example. This
is the file that contains the target-dependent procedures.
Fortunately, on Unix, most of them do not have to do very much in
order for <B
CLASS="COMMAND"
>runtest</B
> to run.</P
><P
>If the program being tested is not interactive, you can get
away with this minimal <TT
CLASS="FILENAME"
>unix.exp</TT
> to begin
with:</P
><DIV
CLASS="EXAMPLE"
><A
NAME="AEN1162"
></A
><P
><B
>Example 2. Simple Batch Program Tool Init File</B
></P
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="90%"
><TR
><TD
><PRE
CLASS="PROGRAMLISTING"
>&#13; proc foo_exit {} {}
proc foo_version {} {}
</PRE
></TD
></TR
></TABLE
></DIV
><P
>If the program being tested is interactive, however, you might
as well define a <I
CLASS="EMPHASIS"
>start</I
> routine and invoke it by
using an init file like this:</P
><DIV
CLASS="EXAMPLE"
><A
NAME="AEN1167"
></A
><P
><B
>Example 3. Simple Interactive Program Tool Init File</B
></P
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="90%"
><TR
><TD
><PRE
CLASS="PROGRAMLISTING"
>
proc foo_exit {} {}
proc foo_version {} {}
proc foo_start {} {
global ${examplename}
spawn ${examplename}
expect {
-re "" {}
}
}
# Start the program running we want to test
foo_start
</PRE
></TD
></TR
></TABLE
></DIV
></LI
><LI
STYLE="list-style-type: disc"
><P
>Create a directory whose name begins with your tool's
name, to contain tests. For example, if your tool's name is
<I
CLASS="EMPHASIS"
>gcc</I
>, then the directories all need to start with
<I
CLASS="EMPHASIS"
>"gcc."</I
>.</P
></LI
><LI
STYLE="list-style-type: disc"
><P
>Create a sample test file. Its name must end with
<TT
CLASS="FILENAME"
>.exp</TT
>. You can use
<TT
CLASS="FILENAME"
>first-try.exp</TT
>. To begin with, just write there a
line of Tcl code to issue a message.</P
><DIV
CLASS="EXAMPLE"
><A
NAME="AEN1178"
></A
><P
><B
>Example 4. Testing A New Tool Config</B
></P
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="90%"
><TR
><TD
><PRE
CLASS="PROGRAMLISTING"
>&#13; send_user "Testing: one, two...\n"
</PRE
></TD
></TR
></TABLE
></DIV
></LI
><LI
STYLE="list-style-type: disc"
><P
>Back in the <TT
CLASS="FILENAME"
>testsuite</TT
> (top
level) directory, run <B
CLASS="COMMAND"
>configure</B
>. Typically you do
this while in the build directory. You may have to specify more of a
path, if a suitable configure is not available in your execution
path.</P
></LI
><LI
STYLE="list-style-type: disc"
><P
>e now ready to triumphantly type <B
CLASS="COMMAND"
>make
check</B
> or <B
CLASS="COMMAND"
>runtest</B
>. You should see
something like this:</P
><DIV
CLASS="EXAMPLE"
><A
NAME="AEN1189"
></A
><P
><B
>Example 5. Example Test Case Run</B
></P
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="90%"
><TR
><TD
><PRE
CLASS="SCREEN"
> Test Run By rhl on Fri Jan 29 16:25:44 EST 1993
=== example tests ===
Running ./example.0/first-try.exp ...
Testing: one, two...
=== example Summary ===
</PRE
></TD
></TR
></TABLE
></DIV
><P
>There is no output in the summary, because so far the example
does not call any of the procedures that establish a test
outcome.</P
></LI
><LI
STYLE="list-style-type: disc"
><P
>Write some real tests. For an interactive tool, you
should probably write a real exit routine in fairly short order. In
any case, you should also write a real version routine
soon. </P
></LI
></UL
></DIV
><DIV
CLASS="NAVFOOTER"
><HR
ALIGN="LEFT"
WIDTH="100%"><TABLE
SUMMARY="Footer navigation table"
WIDTH="100%"
BORDER="0"
CELLPADDING="0"
CELLSPACING="0"
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
><A
HREF="c1099.html"
ACCESSKEY="P"
>&#60;&#60;&#60; Previous</A
></TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
><A
HREF="book1.html"
ACCESSKEY="H"
>Home</A
></TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
><A
HREF="x1195.html"
ACCESSKEY="N"
>Next &#62;&#62;&#62;</A
></TD
></TR
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
>Extending DejaGnu</TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
><A
HREF="c1099.html"
ACCESSKEY="U"
>Up</A
></TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
>Adding A New Target</TD
></TR
></TABLE
></DIV
></BODY
></HTML
>