Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Merge pull request #272 from mpoquet/SMPI_convert
[simgrid.git] / doc / manpage / tesh.pod
1 =encoding UTF-8
2
3 =head1 NAME
4
5 tesh -- testing shell
6
7 =head1 SYNOPSIS
8
9 B<tesh> [I<options>]... I<testsuite>
10
11 =head1 DESCRIPTION
12
13 Tesh is the testing shell, a specialized shell for running tests. It
14 provides the specified input to the tested commands, and check that
15 they produce the expected output and return the expected value.
16
17 =head1 OPTIONS
18
19   --help              : display help
20   --cd some/directory : ask tesh to switch the working directory before
21                         launching the tests
22   --setenv var=value  : set a specific environment variable
23   --cfg arg           : add parameter --cfg=arg to each command line
24   --log arg           : add parameter --log=arg to each command line
25   --ignore-jenkins    : ignore all cruft generated on SimGrid
26                         continuous integration servers
27
28
29 =head1 TEST SUITE FILE SYTAX
30
31 A test suite is composed of one or several I<command blocks> separated
32 by empty lines, each of them being composed of a command to run, its
33 input text and the expected output.
34
35 The first char of each line specifies the type of line according to
36 the following list. The second char of each line is ignored.
37
38  `$' command to run in foreground
39  `&' command to run in background
40
41  `<' input to pass to the command
42  `>' output expected from the command
43
44  `!' metacommand, which can be one of:
45      `timeout' <integer>|no
46      `expect signal' <signal name>
47      `expect return' <integer>
48      `output' <ignore|display>
49      `output sort' [integer]
50      `setenv <key>=<val>'
51      `ignore' <regexp>
52
53  `p' an informative message to print
54  `#' a comment
55
56 If the expected output do not match the produced output, or if the
57 command did not end as expected, Tesh provides an error message (see
58 the OUTPUT section below) and stops.
59
60 =head2 Command blocks examples
61
62 In a given command block, you can declare the command, its input and
63 its expected output in the order that you see fit.
64
65     $ cat
66     < TOTO
67     > TOTO
68
69     > TOTO
70     $ cat
71     < TOTO
72
73     > TOTO
74     < TOTO
75     $ cat
76
77 You can group several commands together, provided that they don't have
78 any input nor output.
79
80     $ mkdir testdir
81     $ cd testdir
82
83 =head2 Enforcing the command return code
84
85 By default, Tesh enforces that the tested command returns 0. If not,
86 it fails with an appropriate message and returns I<code+40> itself.
87
88 You specify that a given command block is expected to return another
89 code as follows:
90
91     # This command MUST return 42
92     ! expect return 42
93     $ sh -e "exit 42"
94
95 The I<expect return> construct applies only to the next command block.
96
97 =head2 Commands that are expected to raise signals
98
99 By default, Tesh detects when the command is killed by a signal (such
100 as SEGV on segfaults). This is usually unexpected and unfortunate. But
101 if not, you can specify that a given command block is expected to fail
102 with a signal as follows:
103
104     # This command MUST raise a segfault
105     ! expect signal SIGSEGV
106     $ ./some_failing_code
107
108 The I<expect signal> construct applies only to the next command block.
109
110 =head2 Timeouts
111
112 By default, no command is allowed to run more than 10 seconds. You can
113 change this value as follows:
114
115     # Allow some more time to the command
116     ! timeout 60
117     $ ./some_longer_command
118
119 You can also disable the timeout completely by passing "no" as a value:
120
121     # This command will never timeout
122     ! timeout no
123     $ ./some_very_long_but_safe_command
124
125 =head2 Setting environment variables
126
127 You can modify the environment of the tested commands as follows:
128
129     ! setenv PATH=/bin
130     $ my_command
131
132 You can also set an envirmnent variable from the command line:
133
134     tesh --setenv bindir=/opt/bin/
135
136 And then use it within the tesh file:
137
138     $ ${bindir}/myprogram
139
140 Tesh also supports perl default value for undefined variables:
141
142     $ ${bindir:=/usr/bin}/myprogram
143
144 =head2 Not enforcing the expected output 
145
146 By default, the commands output is matched against the one expected,
147 and an error is raised on discrepancy. Metacommands to change this:
148
149 =over 4
150
151 =item output ignore
152
153 The output is completely discarded.
154
155 =item output display
156
157 The output is displayed, but no error is issued if it differs from the
158 expected output.
159
160 =item output sort
161
162 The output and the expected output are sorted before comparison (see next section).
163
164 =back
165
166 =head2 Sorting output
167
168 If the order of the command output changes between runs, you want to
169 sort it before enforcing that it is exactly what you expect. In
170 SimGrid for example, this happens when parallel execution is
171 activated: User processes are run in parallel at each timestamp, and
172 the output is not reproducible anymore. Until you sort the lines.
173
174 You can sort the command output as follows:
175
176     ! output sort
177     $ ./some_multithreaded_command
178
179 Sorting lines this ways often makes the tesh output very intricate,
180 complicating the error analysis: the process logical order is defeated
181 by the lexicographical sort.
182
183 The solution is to prefix each line of your output with temporal
184 information so that lines can be grouped by timestamps. The
185 lexicographical sort then only applies to lines that occurred at the
186 same timestamp. Here is a SimGrid example:
187
188     # Sort only lines depending on the first 19 chars
189     ! output sort 19
190     $ ./some_simgrid_simulator --log=root.fmt:[%10.6r]%e(%i:%P@%h)%e%m%n
191
192 This approach may seem surprizing at the first glance but it does its job:
193
194 =over 4
195
196 =item Every timestamps remain separated, as it should; 
197
198 =item In each timestamp, the output order of processes become
199    reproducible: that's the lexicographical order of their name;
200
201 =item For each process, the order of its execution is preserved: its
202    messages within a given timestamp are not reordered.
203
204 =back
205
206 That way, tesh can do its job (no false positive, no false negative)
207 despite the unpredictable order of executions of processes within a
208 timestamp, and reported errors remain easy to analyze (execution of a
209 given process preserved).
210
211 This example is very SimGrid oriented, but the feature could even be
212 usable by others, who knows?
213
214 =head2 Ignoring some output
215
216 Some outputed lines can be ignored by setting the ignore command followed
217 by a regular expression:
218
219     ! ignore .*0x[0-9A-F]+\.
220     $  printf 'word\nMemory address: 0x42AA42.\nanotherword\n'
221     > word
222     > anotherword
223
224
225 =head2 Colored and formatted text
226
227 Tesh removes ANSI/VT100 control sequences from outputed text to make easier the writing of tests.
228
229     $ printf "I \033[0;31mlove\033[0m tesh\n"
230     > I love tesh
231
232
233
234 =head1 BUILTIN COMMANDS
235
236 =head2 mkfile: creating a file
237
238 This command creates a file of the name provided as argument, and adds
239 the content it gets as input.
240
241   $ mkfile myFile
242   > some content
243   > to the file
244
245 It is not possible to use the cat command, as one would expect,
246 because stream redirections are currently not implemented in Tesh.
247
248 =head1 BUGS, LIMITATIONS AND POSSIBLE IMPROVEMENTS
249
250 The main limitation is the lack of stream redirections in the commands
251 (">", "<" and "|" shell constructs and friends). The B<mkfile> builtin
252 command makes this situation bearable.
253
254 It would be nice if we could replace the tesh file completely with
255 command line flags when the output is not to be verified.
256
257
258 =cut