1*3117ece4Schristos# CLI tests 2*3117ece4Schristos 3*3117ece4SchristosThe CLI tests are focused on testing the zstd CLI. 4*3117ece4SchristosThey are intended to be simple tests that the CLI and arguments work as advertised. 5*3117ece4SchristosThey are not intended to test the library, only the code in `programs/`. 6*3117ece4SchristosThe library will get incidental coverage, but if you find yourself trying to trigger a specific condition in the library, this is the wrong tool. 7*3117ece4Schristos 8*3117ece4Schristos## Test runner usage 9*3117ece4Schristos 10*3117ece4SchristosThe test runner `run.py` will run tests against the in-tree build of `zstd` and `datagen` by default. Which means that `zstd` and `datagen` must be built. 11*3117ece4Schristos 12*3117ece4SchristosThe `zstd` binary used can be passed with `--zstd /path/to/zstd`. 13*3117ece4SchristosAdditionally, to run `zstd` through a tool like `valgrind` or `qemu`, set the `--exec-prefix 'valgrind -q'` flag. 14*3117ece4Schristos 15*3117ece4SchristosSimilarly, the `--datagen`, and `--zstdgrep` flags can be set to specify 16*3117ece4Schristosthe paths to their respective binaries. However, these tools do not use 17*3117ece4Schristosthe `EXEC_PREFIX`. 18*3117ece4Schristos 19*3117ece4SchristosEach test executes in its own scratch directory under `scratch/test/name`. E.g. `scratch/basic/help.sh/`. Normally these directories are removed after the test executes. However, the `--preserve` flag will preserve these directories after execution, and save the tests exit code, stdout, and stderr in the scratch directory to `exit`, `stderr`, and `stdout` respectively. This can be useful for debugging/editing a test and updating the expected output. 20*3117ece4Schristos 21*3117ece4Schristos### Running all the tests 22*3117ece4Schristos 23*3117ece4SchristosBy default the test runner `run.py` will run all the tests, and report the results. 24*3117ece4Schristos 25*3117ece4SchristosExamples: 26*3117ece4Schristos 27*3117ece4Schristos``` 28*3117ece4Schristos./run.py 29*3117ece4Schristos./run.py --preserve 30*3117ece4Schristos./run.py --zstd ../../build/programs/zstd --datagen ../../build/tests/datagen 31*3117ece4Schristos``` 32*3117ece4Schristos 33*3117ece4Schristos### Running specific tests 34*3117ece4Schristos 35*3117ece4SchristosA set of test names can be passed to the test runner `run.py` to only execute those tests. 36*3117ece4SchristosThis can be useful for writing or debugging a test, especially with `--preserve`. 37*3117ece4Schristos 38*3117ece4SchristosThe test name can either be the path to the test file, or the test name, which is the path relative to the test directory. 39*3117ece4Schristos 40*3117ece4SchristosExamples: 41*3117ece4Schristos 42*3117ece4Schristos``` 43*3117ece4Schristos./run.py basic/help.sh 44*3117ece4Schristos./run.py --preserve basic/help.sh basic/version.sh 45*3117ece4Schristos./run.py --preserve --verbose basic/help.sh 46*3117ece4Schristos``` 47*3117ece4Schristos 48*3117ece4Schristos### Updating exact output 49*3117ece4Schristos 50*3117ece4SchristosIf a test is failing because a `.stderr.exact` or `.stdout.exact` no longer matches, you can re-run the tests with `--set-exact-output` and the correct output will be written. 51*3117ece4Schristos 52*3117ece4SchristosExample: 53*3117ece4Schristos``` 54*3117ece4Schristos./run.py --set-exact-output 55*3117ece4Schristos./run.py basic/help.sh --set-exact-output 56*3117ece4Schristos``` 57*3117ece4Schristos 58*3117ece4Schristos## Writing a test 59*3117ece4Schristos 60*3117ece4SchristosTest cases are arbitrary executables, and can be written in any language, but are generally shell scripts. 61*3117ece4SchristosAfter the script executes, the exit code, stderr, and stdout are compared against the expectations. 62*3117ece4Schristos 63*3117ece4SchristosEach test is run in a clean directory that the test can use for intermediate files. This directory will be cleaned up at the end of the test, unless `--preserve` is passed to the test runner. Additionally, the `setup` script can prepare the directory before the test runs. 64*3117ece4Schristos 65*3117ece4Schristos### Calling zstd, utilities, and environment variables 66*3117ece4Schristos 67*3117ece4SchristosThe `$PATH` for tests is prepended with the `bin/` sub-directory, which contains helper scripts for ease of testing. 68*3117ece4SchristosThe `zstd` binary will call the zstd binary specified by `run.py` with the correct `$EXEC_PREFIX`. 69*3117ece4SchristosSimilarly, `datagen`, `unzstd`, `zstdgrep`, `zstdcat`, etc, are provided. 70*3117ece4Schristos 71*3117ece4SchristosHelper utilities like `cmp_size`, `println`, and `die` are provided here too. See their scripts for details. 72*3117ece4Schristos 73*3117ece4SchristosCommon shell script libraries are provided under `common/`, with helper variables and functions. They can be sourced with `source "$COMMON/library.sh`. 74*3117ece4Schristos 75*3117ece4SchristosLastly, environment variables are provided for testing, which can be listed when calling `run.py` with `--verbose`. 76*3117ece4SchristosThey are generally used by the helper scripts in `bin/` to coordinate everything. 77*3117ece4Schristos 78*3117ece4Schristos### Basic test case 79*3117ece4Schristos 80*3117ece4SchristosWhen executing your `$TEST` executable, by default the exit code is expected to be `0`. However, you can provide an alternate expected exit code in a `$TEST.exit` file. 81*3117ece4Schristos 82*3117ece4SchristosWhen executing your `$TEST` executable, by default the expected stderr and stdout are empty. However, you can override the default by providing one of three files: 83*3117ece4Schristos 84*3117ece4Schristos* `$TEST.{stdout,stderr}.exact` 85*3117ece4Schristos* `$TEST.{stdout,stderr}.glob` 86*3117ece4Schristos* `$TEST.{stdout,stderr}.ignore` 87*3117ece4Schristos 88*3117ece4SchristosIf you provide a `.exact` file, the output is expected to exactly match, byte-for-byte. 89*3117ece4Schristos 90*3117ece4SchristosIf you provide a `.glob` file, the output is expected to match the expected file, where each line is interpreted as a glob syntax. Additionally, a line containing only `...` matches all lines until the next expected line matches. 91*3117ece4Schristos 92*3117ece4SchristosIf you provide a `.ignore` file, the output is ignored. 93*3117ece4Schristos 94*3117ece4Schristos#### Passing examples 95*3117ece4Schristos 96*3117ece4SchristosAll these examples pass. 97*3117ece4Schristos 98*3117ece4SchristosExit 1, and change the expectation to be 1. 99*3117ece4Schristos 100*3117ece4Schristos``` 101*3117ece4Schristosexit-1.sh 102*3117ece4Schristos--- 103*3117ece4Schristos#!/bin/sh 104*3117ece4Schristosexit 1 105*3117ece4Schristos--- 106*3117ece4Schristos 107*3117ece4Schristosexit-1.sh.exit 108*3117ece4Schristos--- 109*3117ece4Schristos1 110*3117ece4Schristos--- 111*3117ece4Schristos``` 112*3117ece4Schristos 113*3117ece4SchristosCheck the stdout output exactly matches. 114*3117ece4Schristos 115*3117ece4Schristos``` 116*3117ece4Schristosecho.sh 117*3117ece4Schristos--- 118*3117ece4Schristos#!/bin/sh 119*3117ece4Schristosecho "hello world" 120*3117ece4Schristos--- 121*3117ece4Schristos 122*3117ece4Schristosecho.sh.stdout.exact 123*3117ece4Schristos--- 124*3117ece4Schristoshello world 125*3117ece4Schristos--- 126*3117ece4Schristos``` 127*3117ece4Schristos 128*3117ece4SchristosCheck the stderr output using a glob. 129*3117ece4Schristos 130*3117ece4Schristos``` 131*3117ece4Schristosrandom.sh 132*3117ece4Schristos--- 133*3117ece4Schristos#!/bin/sh 134*3117ece4Schristoshead -c 10 < /dev/urandom | xxd >&2 135*3117ece4Schristos--- 136*3117ece4Schristos 137*3117ece4Schristosrandom.sh.stderr.glob 138*3117ece4Schristos--- 139*3117ece4Schristos00000000: * * * * * * 140*3117ece4Schristos``` 141*3117ece4Schristos 142*3117ece4SchristosMultiple lines can be matched with ... 143*3117ece4Schristos 144*3117ece4Schristos``` 145*3117ece4Schristosrandom-num-lines.sh 146*3117ece4Schristos--- 147*3117ece4Schristos#!/bin/sh 148*3117ece4Schristosecho hello 149*3117ece4Schristosseq 0 $RANDOM 150*3117ece4Schristosecho world 151*3117ece4Schristos--- 152*3117ece4Schristos 153*3117ece4Schristosrandom-num-lines.sh.stdout.glob 154*3117ece4Schristos--- 155*3117ece4Schristoshello 156*3117ece4Schristos0 157*3117ece4Schristos... 158*3117ece4Schristosworld 159*3117ece4Schristos--- 160*3117ece4Schristos``` 161*3117ece4Schristos 162*3117ece4Schristos#### Failing examples 163*3117ece4Schristos 164*3117ece4SchristosExit code is expected to be 0, but is 1. 165*3117ece4Schristos 166*3117ece4Schristos``` 167*3117ece4Schristosexit-1.sh 168*3117ece4Schristos--- 169*3117ece4Schristos#!/bin/sh 170*3117ece4Schristosexit 1 171*3117ece4Schristos--- 172*3117ece4Schristos``` 173*3117ece4Schristos 174*3117ece4SchristosStdout is expected to be empty, but isn't. 175*3117ece4Schristos 176*3117ece4Schristos``` 177*3117ece4Schristosecho.sh 178*3117ece4Schristos--- 179*3117ece4Schristos#!/bin/sh 180*3117ece4Schristosecho hello world 181*3117ece4Schristos``` 182*3117ece4Schristos 183*3117ece4SchristosStderr is expected to be hello but is world. 184*3117ece4Schristos 185*3117ece4Schristos``` 186*3117ece4Schristoshello.sh 187*3117ece4Schristos--- 188*3117ece4Schristos#!/bin/sh 189*3117ece4Schristosecho world >&2 190*3117ece4Schristos--- 191*3117ece4Schristos 192*3117ece4Schristoshello.sh.stderr.exact 193*3117ece4Schristos--- 194*3117ece4Schristoshello 195*3117ece4Schristos--- 196*3117ece4Schristos``` 197*3117ece4Schristos 198*3117ece4Schristos### Setup & teardown scripts 199*3117ece4Schristos 200*3117ece4SchristosFinally, test writing can be eased with setup and teardown scripts. 201*3117ece4SchristosEach directory in the test directory is a test-suite consisting of all tests within that directory (but not sub-directories). 202*3117ece4SchristosThis test suite can come with 4 scripts to help test writing: 203*3117ece4Schristos 204*3117ece4Schristos* `setup_once` 205*3117ece4Schristos* `teardown_once` 206*3117ece4Schristos* `setup` 207*3117ece4Schristos* `teardown` 208*3117ece4Schristos 209*3117ece4SchristosThe `setup_once` and `teardown_once` are run once before and after all the tests in the suite respectively. 210*3117ece4SchristosThey operate in the scratch directory for the test suite, which is the parent directory of each scratch directory for each test case. 211*3117ece4SchristosThey can do work that is shared between tests to improve test efficiency. 212*3117ece4SchristosFor example, the `dictionaries/setup_once` script builds several dictionaries, for use in the `dictionaries` tests. 213*3117ece4Schristos 214*3117ece4SchristosThe `setup` and `teardown` scripts run before and after each test case respectively, in the test case's scratch directory. 215*3117ece4SchristosThese scripts can do work that is shared between test cases to make tests more succinct. 216*3117ece4SchristosFor example, the `dictionaries/setup` script copies the dictionaries built by the `dictionaries/setup_once` script into the test's scratch directory, to make them easier to use, and make sure they aren't accidentally modified. 217*3117ece4Schristos 218*3117ece4Schristos#### Examples 219*3117ece4Schristos 220*3117ece4Schristos``` 221*3117ece4Schristosbasic/setup 222*3117ece4Schristos--- 223*3117ece4Schristos#!/bin/sh 224*3117ece4Schristos# Create some files for testing with 225*3117ece4Schristosdatagen > file 226*3117ece4Schristosdatagen > file0 227*3117ece4Schristosdatagen > file1 228*3117ece4Schristos--- 229*3117ece4Schristos 230*3117ece4Schristosbasic/test.sh 231*3117ece4Schristos--- 232*3117ece4Schristos#!/bin/sh 233*3117ece4Schristoszstd file file0 file1 234*3117ece4Schristos--- 235*3117ece4Schristos 236*3117ece4Schristosdictionaries/setup_once 237*3117ece4Schristos--- 238*3117ece4Schristos#!/bin/sh 239*3117ece4Schristosset -e 240*3117ece4Schristos 241*3117ece4Schristosmkdir files/ dicts/ 242*3117ece4Schristosfor i in $(seq 10); do 243*3117ece4Schristos datagen -g1000 > files/$i 244*3117ece4Schristosdone 245*3117ece4Schristos 246*3117ece4Schristoszstd --train -r files/ -o dicts/0 247*3117ece4Schristos--- 248*3117ece4Schristos 249*3117ece4Schristosdictionaries/setup 250*3117ece4Schristos--- 251*3117ece4Schristos#!/bin/sh 252*3117ece4Schristos 253*3117ece4Schristos# Runs in the test case's scratch directory. 254*3117ece4Schristos# The test suite's scratch directory that 255*3117ece4Schristos# `setup_once` operates in is the parent directory. 256*3117ece4Schristoscp -r ../files ../dicts . 257*3117ece4Schristos--- 258*3117ece4Schristos``` 259