mirror of
git://sourceware.org/git/lvm2.git
synced 2024-12-21 13:34:40 +03:00
258 lines
8.9 KiB
Plaintext
258 lines
8.9 KiB
Plaintext
|
Building unit tests
|
||
|
===================
|
||
|
|
||
|
make unit-unit/unit-test
|
||
|
|
||
|
|
||
|
Running unit tests
|
||
|
==================
|
||
|
|
||
|
The tests leave no artifacts at the moment, so you can just run
|
||
|
unit-test/unit-test from wherever you want.
|
||
|
|
||
|
./unit-test <list|run> [pattern]
|
||
|
|
||
|
Listing tests
|
||
|
-------------
|
||
|
|
||
|
Every test has a symbolic path associated with it. Just like file paths they
|
||
|
are split into components separated by '/'s. The 'list' command will show you
|
||
|
a tree of these tests, along with some description text.
|
||
|
|
||
|
|
||
|
ejt@devel-vm1:~/lvm2/unit-test/$ ./unit-test list
|
||
|
base
|
||
|
data-struct
|
||
|
bitset
|
||
|
and ................................................. and all bits
|
||
|
equal ............................................... equality
|
||
|
get_next ............................................ get next set bit
|
||
|
list
|
||
|
splice .............................................. joining lists together
|
||
|
string
|
||
|
asprint ............................................. tests asprint
|
||
|
strncpy ............................................. tests string copying
|
||
|
device
|
||
|
bcache
|
||
|
block-size-multiple-page ............................ block size must be a multiple of page size
|
||
|
block-size-positive ................................. block size must be positive
|
||
|
blocks-get-evicted .................................. block get evicted with many reads
|
||
|
cache-blocks-positive ............................... nr cache blocks must be positive
|
||
|
create-destroy ...................................... simple create/destroy
|
||
|
flush-waits ......................................... flush waits for all dirty
|
||
|
get-reads ........................................... bcache_get() triggers read
|
||
|
prefetch-never-waits ................................ too many prefetches does not trigger a wait
|
||
|
prefetch-reads ...................................... prefetch issues a read
|
||
|
read-multiple-files ................................. read from multiple files
|
||
|
reads-cached ........................................ repeated reads are cached
|
||
|
writeback-occurs .................................... dirty data gets written back
|
||
|
zero-flag-dirties ................................... zeroed data counts as dirty
|
||
|
formatting
|
||
|
percent
|
||
|
0 ................................................... Pretty printing of percentages near 0%
|
||
|
100 ................................................. Pretty printing of percentages near 100%
|
||
|
regex
|
||
|
fingerprints .......................................... not sure
|
||
|
matching .............................................. test the matcher with a variety of regexes
|
||
|
dm
|
||
|
target
|
||
|
mirror
|
||
|
status .............................................. parsing mirror status
|
||
|
metadata
|
||
|
config
|
||
|
cascade ............................................... cascade
|
||
|
clone ................................................. duplicating a config tree
|
||
|
parse ................................................. parsing various
|
||
|
|
||
|
|
||
|
An optional 'pattern' argument may be specified to select subsets of tests.
|
||
|
This pattern is a posix regex and does a substring match, so you will need to
|
||
|
use anchors if you particularly want the match at the beginning or end of the
|
||
|
string.
|
||
|
|
||
|
ejt@devel-vm1:~/lvm2/unit-test/$ ./unit-test list data-struct
|
||
|
base
|
||
|
data-struct
|
||
|
bitset
|
||
|
and ................................................. and all bits
|
||
|
equal ............................................... equality
|
||
|
get_next ............................................ get next set bit
|
||
|
list
|
||
|
splice .............................................. joining lists together
|
||
|
string
|
||
|
asprint ............................................. tests asprint
|
||
|
strncpy ............................................. tests string copying
|
||
|
|
||
|
ejt@devel-vm1:~/lvm2/unit-test/$ ./unit-test list s$
|
||
|
base
|
||
|
device
|
||
|
bcache
|
||
|
flush-waits ......................................... flush waits for all dirty
|
||
|
get-reads ........................................... bcache_get() triggers read
|
||
|
prefetch-never-waits ................................ too many prefetches does not trigger a wait
|
||
|
prefetch-reads ...................................... prefetch issues a read
|
||
|
read-multiple-files ................................. read from multiple files
|
||
|
writeback-occurs .................................... dirty data gets written back
|
||
|
zero-flag-dirties ................................... zeroed data counts as dirty
|
||
|
regex
|
||
|
fingerprints .......................................... not sure
|
||
|
dm
|
||
|
target
|
||
|
mirror
|
||
|
status .............................................. parsing mirror status
|
||
|
|
||
|
|
||
|
Running tests
|
||
|
=============
|
||
|
|
||
|
'make run-unit-test' from the top level will run all unit tests. But I tend to
|
||
|
run it by hand to I can select just the tests I'm working on.
|
||
|
|
||
|
Use the 'run' command to run the tests. Currently all logging goes to stderr,
|
||
|
so the test runner prints a line at the start of the test and a line
|
||
|
indicating success or failure at the end.
|
||
|
|
||
|
ejt@devel-vm1:~/lvm2/unit-test/$ ./unit-test run bcache/block-size
|
||
|
[RUN ] /base/device/bcache/block-size-multiple-page
|
||
|
bcache block size must be a multiple of page size
|
||
|
bcache block size must be a multiple of page size
|
||
|
bcache block size must be a multiple of page size
|
||
|
bcache block size must be a multiple of page size
|
||
|
[ OK] /base/device/bcache/block-size-multiple-page
|
||
|
|
||
|
[RUN ] /base/device/bcache/block-size-positive
|
||
|
bcache must have a non zero block size
|
||
|
[ OK] /base/device/bcache/block-size-positive
|
||
|
|
||
|
|
||
|
2/2 tests passed
|
||
|
|
||
|
|
||
|
ejt@devel-vm1:~/lvm2/unit-test/$ ./unit-test run data-struct
|
||
|
[RUN ] /base/data-struct/bitset/and
|
||
|
[ OK] /base/data-struct/bitset/and
|
||
|
|
||
|
[RUN ] /base/data-struct/bitset/equal
|
||
|
[ OK] /base/data-struct/bitset/equal
|
||
|
|
||
|
[RUN ] /base/data-struct/bitset/get_next
|
||
|
[ OK] /base/data-struct/bitset/get_next
|
||
|
|
||
|
[RUN ] /base/data-struct/list/splice
|
||
|
[ OK] /base/data-struct/list/splice
|
||
|
|
||
|
[RUN ] /base/data-struct/string/asprint
|
||
|
[ OK] /base/data-struct/string/asprint
|
||
|
|
||
|
[RUN ] /base/data-struct/string/strncpy
|
||
|
[ OK] /base/data-struct/string/strncpy
|
||
|
|
||
|
|
||
|
6/6 tests passed
|
||
|
|
||
|
|
||
|
Writing tests
|
||
|
=============
|
||
|
|
||
|
[See unit-test/framework.h and unit-test/units.h for the details]
|
||
|
|
||
|
Tests are grouped together into 'suites', all tests in a suite share a
|
||
|
'fixture'. A fixture is a void * to any object you want; use it to set up any
|
||
|
common environment that you need for the tests to run (eg, creating a dm_pool).
|
||
|
|
||
|
Test suites have nothing to do with the test paths, you can have tests from
|
||
|
different suites with similar paths, the runner sorts things for you.
|
||
|
|
||
|
Put your tests in a file in unit-test/, with '_t' at the end of the name
|
||
|
(convention only, nothing relies on this).
|
||
|
|
||
|
#include "units.h"
|
||
|
|
||
|
Then write any fixtures you need:
|
||
|
|
||
|
eg,
|
||
|
static void *_mem_init(void) {
|
||
|
struct dm_pool *mem = dm_pool_create("bitset test", 1024);
|
||
|
if (!mem) {
|
||
|
fprintf(stderr, "out of memory\n");
|
||
|
exit(1);
|
||
|
}
|
||
|
|
||
|
return mem;
|
||
|
}
|
||
|
|
||
|
static void _mem_exit(void *mem)
|
||
|
{
|
||
|
dm_pool_destroy(mem);
|
||
|
}
|
||
|
|
||
|
Then write your tests, which should take the void * that was returned by your
|
||
|
fixture. Use the T_ASSERT* macros to indicate failure.
|
||
|
|
||
|
eg,
|
||
|
static void test_equal(void *fixture)
|
||
|
{
|
||
|
struct dm_pool *mem = fixture;
|
||
|
dm_bitset_t bs1 = dm_bitset_create(mem, NR_BITS);
|
||
|
dm_bitset_t bs2 = dm_bitset_create(mem, NR_BITS);
|
||
|
|
||
|
int i, j;
|
||
|
for (i = 0, j = 1; i < NR_BITS; i += j, j++) {
|
||
|
dm_bit_set(bs1, i);
|
||
|
dm_bit_set(bs2, i);
|
||
|
}
|
||
|
|
||
|
T_ASSERT(dm_bitset_equal(bs1, bs2));
|
||
|
T_ASSERT(dm_bitset_equal(bs2, bs1));
|
||
|
|
||
|
for (i = 0; i < NR_BITS; i++) {
|
||
|
bit_flip(bs1, i);
|
||
|
T_ASSERT(!dm_bitset_equal(bs1, bs2));
|
||
|
T_ASSERT(!dm_bitset_equal(bs2, bs1));
|
||
|
|
||
|
T_ASSERT(dm_bitset_equal(bs1, bs1)); /* comparing with self */
|
||
|
bit_flip(bs1, i);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
At the end of your test file you should write a function that builds one or
|
||
|
more test suites and adds them to the list of all suites that is passed in. I
|
||
|
tend to write a little macro (T) to save typing the same test path repeatedly.
|
||
|
|
||
|
eg,
|
||
|
#define T(path, desc, fn) register_test(ts, "/base/data-struct/bitset/" path, desc, fn)
|
||
|
|
||
|
void bitset_tests(struct dm_list *all_tests)
|
||
|
{
|
||
|
struct test_suite *ts = test_suite_create(_mem_init, _mem_exit);
|
||
|
if (!ts) {
|
||
|
fprintf(stderr, "out of memory\n");
|
||
|
exit(1);
|
||
|
}
|
||
|
|
||
|
T("get_next", "get next set bit", test_get_next);
|
||
|
T("equal", "equality", test_equal);
|
||
|
T("and", "and all bits", test_and);
|
||
|
|
||
|
dm_list_add(all_tests, &ts->list);
|
||
|
}
|
||
|
|
||
|
Then you need to declare your registration function and call it in units.h.
|
||
|
|
||
|
|
||
|
// Declare the function that adds tests suites here ...
|
||
|
...
|
||
|
void bitset_tests(struct dm_list *suites);
|
||
|
...
|
||
|
|
||
|
// ... and call it in here.
|
||
|
static inline void register_all_tests(struct dm_list *suites)
|
||
|
{
|
||
|
...
|
||
|
bitset_tests(suites);
|
||
|
...
|
||
|
}
|
||
|
|
||
|
Finally add your test file to the Makefile.in and rerun configure.
|
||
|
|