TESH(1)
π TESH(1) π
okay bestie, pull up a chair, because we're talking about tesh β that's the testing shell from the <pink>User Contributed Perl Documentation</pink> corner of the universe, and it's about to become your whole personality π«Ά
β¨ NAME β¨
tesh -- testing shell. yeah. that's it. that's the name. iconic behavior honestly π
πΈ SYNOPSIS πΈ
tesh [options]... testsuite
π DESCRIPTION π
so. Tesh is the testing shell β a specialized shell whose entire job, its main character energy, is running tests. it feeds the exact input you specified into the commands under test, then checks that they spit out the expected output and hand back the expected return value. it's giving strict bestie who checks your receipts, and honestly? we love her for it.
π OPTIONS π
pick your potions, babes:
--helpβ display help. the classic. the goat. when in doubt, ask for help π--cd some/directoryβ tells tesh to switch the working directory before it launches the tests. relocate first, slay second β¨--setenv var=valueβ set one specific environment variable, just the one, very demure, very mindful--cfg argβ bolts a--cfg=argparameter onto each command line--log argβ same deal, but it's--log=argthat gets added to each command line--ignore-jenkinsβ ignore all the cruft generated on SimGrid continuous integration servers. jenkins noise? not on our watch π
π¦ TEST SUITE FILE SYTAX π¦
(yes the heading says SYTAX. we do not discuss it. moving on π)
A test suite is composed of one or several command blocks separated by empty lines. each of them is composed of a command to run, its input text, and the expected output. that's the whole recipe.
the first char of each line specifies the type of line, according to this list. the second char of each line is ignored β so do whatever you want with it, bestie, live your truth.
`$'command to run in foreground`&'command to run in background`<'input to pass to the command`>'output expected from the command`!'metacommand, which can be one of:`timeout' <integer>|no`expect signal' <signal name>[|<signal name>]*`expect return' <integer>`output' <ignore|display>`output sort' [integer]`setenv <key>=<val>'`ignore' <regexp>
`p'an informative message to print`#'a comment
if the expected output do not match the produced output, or if the command did not end as expected, Tesh provides an error message (see the OUTPUT section below) and stops. no warning shot. just vibes over π
π Command blocks examples π
in a given command block, you can declare the command, its input and its expected output in the order that you see fit. truly flexible. truly free. we stan a non-controlling format.
$ cat
< TOTO
> TOTO
> TOTO
$ cat
< TOTO
> TOTO
< TOTO
$ cat
you can also group several commands together β provided that they don't have any input nor output. it's a package deal:
$ mkdir testdir
$ cd testdir
π₯ Enforcing the command return code π₯
by default, Tesh enforces that the tested command returns 0. if not, it fails with an appropriate message and returns code+40 itself. yes, it adds forty. it's dramatic like that and honestly? same.
you specify that a given command block is expected to return another code as follows:
# This command MUST return 42
! expect return 42
$ sh -e "exit 42"
the expect return construct applies only to the next command block. it's a one-block wonder, not a lifestyle π
π Commands that are expected to raise signals π
by default, Tesh detects when the command is killed by a signal (such as SEGV on segfaults). this is usually unexpected and unfortunate. but if it's not unexpected? if it's, dare we say, the plan? then you can specify that a given command block is expected to fail with a signal:
# This command MUST raise a segfault
! expect signal SIGSEGV
$ ./some_failing_code
the expect signal construct applies only to the next command block. again: one block, one moment, one iconic crash π
β° Timeouts β°
by default, no command is allowed to run more than 10 seconds. ten. that's the limit. you can change this value like so:
# Allow some more time to the command
! timeout 60
$ ./some_longer_command
you can also disable the timeout completely by passing no as a value:
# This command will never timeout
! timeout no
$ ./some_very_long_but_safe_command
"some_very_long_but_safe_command" β the name is doing a lot of emotional labor there, bestie. trust the process π«Ά
πΈ Setting environment variables πΈ
you can modify the environment of the tested commands like this:
! setenv PATH=/bin
$ my_command
you can also set an envirmnent variable from the command line:
tesh --setenv bindir=/opt/bin/
and then use it within the tesh file:
$ ${bindir}/myprogram
Tesh also supports perl default value for undefined variables β a little treat for the perl girlies:
$ ${bindir:=/usr/bin}/myprogram
π Not enforcing the expected output π
by default, the commands output is matched against the one expected, and an error is raised on discrepancy. if you'd rather not be perceived like that, here are the metacommands to change it:
output ignoreβ the output is completely discarded. gone. never happened. no thoughts, head empty β¨output displayβ the output is displayed, but no error is issued if it differs from the expected output. it's just showing off, not judgingoutput sortβ the output and the expected output are sorted before comparison (see next section). alphabetize and chill
β Sorting output β
if the order of the command output changes between runs, you want to sort it before enforcing that it is exactly what you expect. in SimGrid for example, this happens when parallel execution is activated: user processes are run in parallel at each timestamp, and the output is not reproducible anymore. until you sort the lines. sorting = the fix. periodt.
you can sort the command output as follows:
! output sort
$ ./some_multithreaded_command
sorting lines this ways often makes the tesh output very intricate, complicating the error analysis: the process logical order is defeated by the lexicographical sort. so it's giving chaos, a little bit.
the solution is to prefix each line of your output with temporal information so that lines can be grouped by timestamps. the lexicographical sort then only applies to lines that occurred at the same timestamp. here is a SimGrid example:
# Sort only lines depending on the first 19 chars
! output sort 19
$ ./some_simgrid_simulator --log=root.fmt:[%10.6r]%e(%i:%a@%h)%e%m%n
this approach may seem surprising at the first glance but it does its job. lowkey genius. highkey genius:
- Every timestamps remain separated, as it should;
- In each timestamp, the output order of processes become reproducible: that's the lexicographical order of their name;
- For each process, the order of its execution is preserved: its messages within a given timestamp are not reordered.
that way, tesh can do its job (no false positive, no false negative) despite the unpredictable order of executions of processes within a timestamp, and reported errors remain easy to analyze (execution of a given process preserved). the way that it just... works π
this example is very SimGrid oriented, but the feature could even be usable by others, who knows? manifesting it for the non-SimGrid girlies β¨
π§ Ignoring some output π§
some outputted lines can be ignored by setting the ignore command followed by a regular expression:
! ignore .*0x[0-9A-F]+\.
$ printf 'word\nMemory address: 0x42AA42.\nanotherword\n'
> word
> anotherword
memory addresses? not our problem. blocked and reported π
π Colored and formatted text π
Tesh removes ANSI/VT100 control sequences from outputted text to make easier the writing of tests. so you can be as β¨extraβ¨ as you want in the command, and still write a clean expectation:
$ printf "I \033[0;31mlove\033[0m tesh\n"
> I love tesh
see how the \033[0;31m just vanished? the drama was removed but the love remained. we love a glow-up that keeps the plot π
π BUILTIN COMMANDS π
π mkfile: creating a file π
this command creates a file of the name provided as argument, and adds the content it gets as input. give it a name, feed it words, and it delivers.
$ mkfile myFile
> some content
> to the file
it is not possible to use the cat command, as one would expect, because stream redirections are currently not implemented in Tesh. yeah. i know. i know. we cope with mkfile π
π¦ BUGS, LIMITATIONS AND POSSIBLE IMPROVEMENTS π¦
the main limitation is the lack of stream redirections in the commands (>, < and | shell constructs and friends). the mkfile builtin command makes this situation bearable. it's not a want, it's a need, and it's the best we've got bestie π«Ά
it would be nice if we could replace the tesh file completely with command line flags when the output is not to be verified. that's the dream. that's the vision board. someone make it happen β¨
okay that's the whole page, you're officially tesh-pilled, go write tests that slay π
and that's a wrap, gorgeous β this was perl v5.42.3, dated 2026-09-23, from your friendly neighborhood TESH(1). mwah π
π¦ where this page comes from
- ubuntu stonking: libsimgrid-dev 4.1-3 Β· LGPL-2.1-only
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms