c456018554ccc605c0b478da9c2f0b96d12c4914
[platform/upstream/btrfs-progs.git] / tests / README.md
1 # Btrfs-progs tests
2
3 A testsuite covering functionality of btrfs-progs, ie. the checker, image, mkfs
4 and similar tools. There are no additional requirements on kernel features
5 (other than `CONFIG_BTRFS_FS` built-in or module), the
6 tests build on top of the core functionality like snapshots and device
7 management. In some cases optional features are turned on by mkfs and the
8 filesystem image could be mounted, such tests might fail if there's lack of
9 support.
10
11 ## Quick start
12
13 Run the tests from the top directory:
14
15 ```shell
16 $ make test
17 $ make test-fsck
18 $ make test-convert
19 ```
20
21 or selectively from the `tests/` directory:
22
23 ```shell
24 $ ./fsck-tests.sh
25 $ ./misc-tests.sh
26 ```
27
28 The verbose output of the tests is logged into a file named after the test
29 category, eg. `fsck-tests-results.txt`.
30
31 ## Selective testing
32
33 The tests are prefixed by a number for ordering and uniqueness. To run a
34 particular test use:
35
36 ```shell
37 $ make TEST=MASK test
38 ```
39
40 where `MASK` is a glob expression that will execute only tests
41 that match the MASK. Here the test number comes handy:
42
43 ```shell
44 $ make TEST=001\* test-fsck
45 $ TEST=001\* ./fsck-tests.sh
46 ```
47
48 will run the first test in fsck-tests subdirectory.
49
50
51 ## Test structure
52
53 *tests/fsck-tests/:*
54
55   * tests targeted at bugs that are fixable by fsck
56
57 *tests/convert-tests/:*
58
59   * coverage tests of ext2/3/4 and btrfs-convert options
60
61 *tests/fuzz-tests/:*
62
63   * collection of fuzzed or crafted images
64   * tests that are supposed to run various utilities on the images and not
65     crash
66
67 *tests/cli-tests/:*
68
69   * tests for command line interface, option coverage, weird option combinations that should not work
70   * not necessary to do any functional testing, could be rather lightweight
71   * functional tests should go to to other test dirs
72   * the driver script will only execute `./test.sh` in the test directory
73
74 *tests/misc-tests/:*
75
76   * anything that does not fit to the above, the test driver script will only
77     execute `./test.sh` in the test directory
78
79 *tests/common, tests/common.convert:*
80
81   * script with shell helpers, separated by functionality
82
83 *tests/test.img:*
84
85   * default testing image, the file is never deleted by the scripts but
86     truncated to 0 bytes, so it keeps it's permissions. It's eg. possible to
87     host it on NFS, make it `chmod a+w` for root.
88
89
90 ## Other tuning, environment variables
91
92 ### Instrumentation
93
94 It's possible to wrap the tested commands to utilities that might do more
95 checking or catch failures at runtime. This can be done by setting the
96 `INSTRUMENT` environment variable:
97
98 ```shell
99 INSTRUMENT=valgrind ./fuzz-tests.sh    # in tests/
100 make INSTRUMENT=valgrind test-fuzz     # in the top directory
101 ```
102
103 The variable is prepended to the command *unquoted*, all sorts of shell tricks
104 are possible.
105
106 Note: instrumentation is not applied to privileged commands (anything that uses
107 the root helper).
108
109 ### Verbosity, test tuning
110
111 * `TEST_LOG=tty` -- setting the variable will print all commands executed by
112   some of the wrappers (`run_check` etc), other commands are not printed to the
113   terminal (but the full output is in the log)
114
115 * `TEST_LOG=dump` -- dump the entire testing log when a test fails
116
117 * `TEST_ENABLE_OVERRIDE` -- defined either as make arguments or via
118   `tests/common.local` to enable additional arguments to some commands, using
119   the variable(s) below (default: false, enable by setting to 'true')
120
121 * `TEST_ARGS_CHECK` -- user-defined arguments to `btrfs check`, before the
122   test-specific arguments
123
124 Multiple values can be separated by `,`.
125
126 ### Permissions
127
128 Some commands require root privileges (to mount/umount, access loop devices).
129 It is assumed that `sudo` will work in some way (no password, password asked
130 and cached). Note that instrumentation is not applied in this case, for safety
131 reasons. You need to modify the test script instead.
132
133 ### Cleanup
134
135 The tests are supposed to cleanup after themselves if they pass. In case of
136 failure, the rest of the tests are skipped and intermediate files, mounts and
137 loop devices are kept. This should help to investigate the test failure but at
138 least the mounts and loop devices need to be cleaned before the next run.
139
140 This is partially done by the script `clean-tests.sh`, you may want to check
141 the loop devices as they are managed on a per-test basis.
142
143 ### Prototyping tests, quick tests
144
145 There's a script `test-console.sh` that will run shell commands in a loop and
146 logs the output with the testing environment set up.
147
148 ### Runtime dependencies
149
150 The tests use some common system utilities like `find`, `rm`, `dd`. Additionally,
151 specific tests need the following packages installed: `acl`, `attr`,
152 `e2fsprogs`, `reiserfsprogs`
153
154
155 ## New test
156
157 1. Pick the category for the new test or fallback to `misc-tests` if not sure. For
158 an easy start copy an existing `test.sh` script from some test that might be
159 close to the purpose of your new test. The environment setup includes the
160 common scripts and/or prepares the test devices. Other scripts contain examples
161 how to do mkfs, mount, unmount, check, etc.
162
163 2. Use the highest unused number in the sequence, write a short descriptive title
164 and join by dashes `-`. This will become the directory name, eg. `012-subvolume-sync-must-wait`.
165
166 3. Write a short description of the bug and how it's tested to the comment at the
167 begining of `test.sh`. You don't need to add the file to git yet. Don't forget
168 to make the file executable, otherwise it's not going to be executed by the
169 infrastructure.
170
171 4. Write the test commands, comment anything that's not obvious.
172
173 5. **Test your test.** Use the `TEST` variable to jump right to your test:
174 ```shell
175 $ make TEST=012\* tests-misc           # from top directory
176 $ TEST=012\* ./misc-tests.sh           # from tests/
177 ```
178
179 6. The commit changelog should reference a commit that either introduced or
180   fixed the bug (or both). Subject line of the shall mention the name of the
181   new directory for ease of search, eg. `btrfs-progs: tests: add 012-subvolume-sync-must-wait`
182
183
184 ### Crafted/fuzzed images
185
186 Images that are create by fuzzing or specially crafted to trigger some error
187 conditions should be added to the directory *fuzz-tests/images*, accompanied by
188 a textual description of the source (bugzilla, mail), the reporter, brief
189 description of the problem or the stack trace.
190
191 If you have a fix for the problem, please submit it prior to the test image, so
192 the fuzz tests always succeed when run on random checked out. This helps
193 bisectability.
194
195
196 # Coding style, best practices
197
198 ## do
199
200 * quote all variables by default, any path, even the TOP could need that, and
201   we use it everywhere
202   * there are exceptions:
203     * `$SUDO_HELPER` as it might be intentionally unset
204     * the variable is obviously set to a value that does not require it
205 * use `#!/bin/bash` explicitly
206 * check for all external dependencies (`check_prereq_global`)
207 * check for internal dependencies (`check_prereq`), though the basic set is
208   always built when the tests are started through make
209 * use functions instead of repeating code
210   * generic helpers could be factored to the `common` script
211 * cleanup after successful test
212 * use common helpers and variables
213
214 ## do not
215
216 * pull external dependencies if we can find a way to replace them: example is
217   `xfs_io` that's conveniently used in fstests but we'd require `xfsprogs`,
218   so use `dd` instead
219 * throw away (redirect to */dev/null*) output of commands unless it's justified
220   (ie. really too much text, unnecessary slowdown) -- the test output log is
221   regenerated all the time and we need to be able to analyze test failures or
222   just observe how the tests progress
223 * cleanup after failed test -- the testsuite stops on first failure and the
224   developer can eg. access the environment that the test created and do further
225   debugging
226   * this might change in the future so the tests cover as much as possible, but
227     this would require to enhance all tests with a cleanup phase