dfregress - An automated test driver and framework
authorAlex Hornung <ahornung@gmail.com>
Sun, 30 Oct 2011 01:21:59 +0000 (01:21 +0000)
committerAlex Hornung <ahornung@gmail.com>
Mon, 14 Nov 2011 20:33:51 +0000 (20:33 +0000)
commit6a7006f10516182dbc2d134ecce752158f3ce61b
tree4395cacd9e2fd6663b453e454253e1f9ff8d2d8a
parent01d3427a8154b7647d50d1122d7cf6ebf1229f08
dfregress - An automated test driver and framework

 * dfregress is a simple test framework and test automation driver. It
   supports both normal userland testcases and kernel test cases.

 * It's key aim is to make it simple, if not outright dead easy, to
   write test cases. A test case is a simple program using
   printf/fprintf and exit - no magic needed. A kernel test case is a
   very small module that just needs to implement a few functions and
   call a logging and result function.

 * Sample output of the text frontend (Frontends are explained further
   down the text): http://leaf.dragonflybsd.org/~alexh/dfregress.txt

 * dfregress is very UNIXy, it uses makefiles to build the testcases,
   stdout/stderr redirection from the testcases (no fancy output
   functions needed in the testcases) and evaluates the normal return
   value of the testcase (no need to call fancy functions).

 * For kernel testcases it is a bit different - you do have to call
   functions to log output and to log the result, but it is very simple,
   hardly any overhead.

 * The test driver assumes that testcases are in the testcases/
   directory, but it supports several command line options.

 * The tests to run, including several options, are specified in the
   runlist file. An example runlist including all the testcases is
   included as config/runlist.run. Options that can be specified are:
   - timeout: (in seconds) after which the test is aborted if it hasn't
     finished.
   - test type (userland, kernel or buildonly)
   - make: which 'make' tool to use to build the test cases. Defaults to
     'make', but could also be 'gmake', etc.
   - nobuild: doesn't build the testcase and tries to directly execute
     it.
   - pre, post: external pre-run and post-run commands, e.g. to set up a
     vn device and to tear it down. This is to avoid duplication in test
     cases, the common setup can be factored out.
   - intpre, intpost: similar to the above, but it assumes that the
     testcase, when passed the parameter 'pre', will do the pre-setup,
     and when passed 'post' will do the post-test cleanup/setup/etc.
   - any number of command line arguments that are passed to the test
     case. (See the crypto/ test examples in the runlist).

 * A range of sample testcases are available in
   test/dfregress/testcases/sample, including a kernel testcase sample.

 * Note that many of the test cases in the testcases/ directory have
   been copied from elsewhere in the main repository and are,
   temporarily at least, duplicated.

 * The test driver is completely separated from the frontends. The test
   driver outputs the test run results in an XML-like format (plist)
   that can easily be parsed using proplib. Python and Ruby also have
   plist modules that could be used to parse the output.

 * The only available frontend is a simple C program that will parse the
   intermediate format to an easy to read plain text format. Additional
   frontends can be written in any language, as long as it is possible
   to load plists. Frontends are in the fe/ directory.

 * XXX: the default options (currently just the timeout) are still
   hardcoded in config.c.

 * The NOTES file gives details on how the test execution occurs and
   what result code can be raised at which point. This document, and a look
   at the generated plist, is all you need to write a new frontend that,
   for example, generates beautiful HTML output.
   For completeness sake, a part of NOTES is reproduced under the main commit
   message - specifically the part detailing the execution of a single test
   case.

======
Execution of a single test case:
======
1) chdir to testcase directory
        - if it fails, set RESULT_PREFAIL (sysbuf is of interest), goto (6)

2) build testcase (make) (unless nobuild flag is set).
        + build_buf is used for stdout/stderr
        - if there is an internal driver error (that leads to not running the
          build command), set RESULT_PREFAIL (sysbuf is of interest), goto (6)
        - if the build command has a non-zero exit value, set the result to
          BUILDFAIL, unless it's a buildonly test case, in which it is set to
          the actual result value (TIMEOUT, SIGNALLED, FAIL)
          goto (6)

3) run 'pre' command if intpre or pre is set.
        + precmd_buf is used for stdout/stderr
        - if there is an internal driver error (that leads to not running the
          command), set RESULT_PREFAIL (sysbuf is of interest), goto (6)
        - if the pre command has a non-zero exit value, set RESULT_PREFAIL and
          goto (6)

4) run actual testcase, depending on type
        + stdout_buf is used for stdout
        + stderr_buf is used for stderr
        - for BUILDONLY: set RESULT_PASS since the build already succeeded
        - for userland and kernel: run the testcase, possibly as a different
          user (depending on the runas option), set the result to the actual
          result value (TIMEOUT, SIGNALLED, FAIL, NOTRUN)
        - if there is an internal driver error (that leads to not running the
          command), RESULT_NOTRUN is set (sysbuf is of interest)

5) run 'post' command if intpost or post is set.
        + postcmd_buf is used for stdout/stderr
        - if there is an internal driver error (that leads to not running the
          command), set RESULT_POSTFAIL (sysbuf is of interest), goto (6)
        - if the post command has a non-zero exit value, set RESULT_POSTFAIL
          and goto (6)

6) clean testcase directory (make clean) (unless nobuild flag is set).
        + cleanup_buf is used for stdout/stderr and system (driver error) buffer
        - no further action.

7) results are saved.
100 files changed:
test/dfregress/NOTES [new file with mode: 0644]
test/dfregress/config/defaults.conf [new file with mode: 0644]
test/dfregress/config/runlist.run [new file with mode: 0644]
test/dfregress/driver/Makefile [new file with mode: 0644]
test/dfregress/driver/config.c [new file with mode: 0644]
test/dfregress/driver/config.h [new file with mode: 0644]
test/dfregress/driver/kernel.c [new file with mode: 0644]
test/dfregress/driver/kernel.h [new file with mode: 0644]
test/dfregress/driver/main.c [new file with mode: 0644]
test/dfregress/driver/parser.c [new file with mode: 0644]
test/dfregress/driver/parser.h [new file with mode: 0644]
test/dfregress/driver/runlist.c [new file with mode: 0644]
test/dfregress/driver/runlist.h [new file with mode: 0644]
test/dfregress/driver/testcase.c [new file with mode: 0644]
test/dfregress/driver/testcase.h [new file with mode: 0644]
test/dfregress/driver/userland.c [new file with mode: 0644]
test/dfregress/driver/userland.h [new file with mode: 0644]
test/dfregress/fe/text/Makefile [new file with mode: 0644]
test/dfregress/fe/text/fe_text.c [new file with mode: 0644]
test/dfregress/framework/dfregress.h [new file with mode: 0644]
test/dfregress/framework/tbridge.h [new file with mode: 0644]
test/dfregress/framework/test.txt [new file with mode: 0644]
test/dfregress/kernel_bridge/Makefile [new file with mode: 0644]
test/dfregress/kernel_bridge/dfregress_bridge.c [new file with mode: 0644]
test/dfregress/kernel_bridge/safe_mem.c [new file with mode: 0644]
test/dfregress/testcases/Makefile [new file with mode: 0644]
test/dfregress/testcases/compiler/Makefile [new file with mode: 0644]
test/dfregress/testcases/compiler/div128/Makefile [new file with mode: 0644]
test/dfregress/testcases/compiler/div128/div128.c [new file with mode: 0644]
test/dfregress/testcases/crypto/Makefile [new file with mode: 0644]
test/dfregress/testcases/crypto/aes/Makefile [new file with mode: 0644]
test/dfregress/testcases/crypto/aes/aestest.c [new file with mode: 0644]
test/dfregress/testcases/crypto/aes/ecbnk44.txt [new file with mode: 0644]
test/dfregress/testcases/crypto/aes/ecbnk48.txt [new file with mode: 0644]
test/dfregress/testcases/crypto/aes/ecbnt44.txt [new file with mode: 0644]
test/dfregress/testcases/crypto/aes/ecbnt48.txt [new file with mode: 0644]
test/dfregress/testcases/crypto/aes/ecbvk44.txt [new file with mode: 0644]
test/dfregress/testcases/crypto/aes/ecbvk48.txt [new file with mode: 0644]
test/dfregress/testcases/crypto/aes/ecbvt44.txt [new file with mode: 0644]
test/dfregress/testcases/crypto/aes/ecbvt48.txt [new file with mode: 0644]
test/dfregress/testcases/crypto/aesctr/Makefile [new file with mode: 0644]
test/dfregress/testcases/crypto/aesctr/aesctr.c [new file with mode: 0644]
test/dfregress/testcases/crypto/aesxts/Makefile [new file with mode: 0644]
test/dfregress/testcases/crypto/aesxts/aes_xts.c [new file with mode: 0644]
test/dfregress/testcases/crypto/serpent/Makefile [new file with mode: 0644]
test/dfregress/testcases/crypto/serpent/serpent_test.c [new file with mode: 0644]
test/dfregress/testcases/crypto/serpent/serpentecb_vk.txt [new file with mode: 0644]
test/dfregress/testcases/crypto/serpent/serpentecb_vt.txt [new file with mode: 0644]
test/dfregress/testcases/crypto/twofish/Makefile [new file with mode: 0644]
test/dfregress/testcases/crypto/twofish/twofish_test.c [new file with mode: 0644]
test/dfregress/testcases/crypto/twofish/twofishecb_vk.txt [new file with mode: 0644]
test/dfregress/testcases/crypto/twofish/twofishecb_vt.txt [new file with mode: 0644]
test/dfregress/testcases/io/Makefile [new file with mode: 0644]
test/dfregress/testcases/io/kqueue_1/Makefile [new file with mode: 0644]
test/dfregress/testcases/io/kqueue_1/kqueue_1.c [new file with mode: 0644]
test/dfregress/testcases/io/kqueue_2/Makefile [new file with mode: 0644]
test/dfregress/testcases/io/kqueue_2/kqueue_2.c [new file with mode: 0644]
test/dfregress/testcases/io/pselect_1/Makefile [new file with mode: 0644]
test/dfregress/testcases/io/pselect_1/pselect_1.c [new file with mode: 0644]
test/dfregress/testcases/io/select_1/Makefile [new file with mode: 0644]
test/dfregress/testcases/io/select_1/select_1.c [new file with mode: 0644]
test/dfregress/testcases/io/select_2/Makefile [new file with mode: 0644]
test/dfregress/testcases/io/select_2/select_2.c [new file with mode: 0644]
test/dfregress/testcases/io/select_3/Makefile [new file with mode: 0644]
test/dfregress/testcases/io/select_3/select_3.c [new file with mode: 0644]
test/dfregress/testcases/io/select_4/Makefile [new file with mode: 0644]
test/dfregress/testcases/io/select_4/select_4.c [new file with mode: 0644]
test/dfregress/testcases/io/sendfd_1/Makefile [new file with mode: 0644]
test/dfregress/testcases/io/sendfd_1/sendfd_1.c [new file with mode: 0644]
test/dfregress/testcases/mem/Makefile [new file with mode: 0644]
test/dfregress/testcases/mem/mmap_1/Makefile [new file with mode: 0644]
test/dfregress/testcases/mem/mmap_1/mmap_1.c [new file with mode: 0644]
test/dfregress/testcases/mem/mmap_madvise_1/Makefile [new file with mode: 0644]
test/dfregress/testcases/mem/mmap_madvise_1/mmap_madvise_1.c [new file with mode: 0644]
test/dfregress/testcases/misc/Makefile [new file with mode: 0644]
test/dfregress/testcases/misc/sh_1/Makefile [new file with mode: 0644]
test/dfregress/testcases/misc/sh_1/sh_1.sh [new file with mode: 0644]
test/dfregress/testcases/priv/Makefile [new file with mode: 0644]
test/dfregress/testcases/priv/setreuid/Makefile [new file with mode: 0644]
test/dfregress/testcases/priv/setreuid/setreuid.c [new file with mode: 0644]
test/dfregress/testcases/sample/Makefile [new file with mode: 0644]
test/dfregress/testcases/sample/test1/Makefile [new file with mode: 0644]
test/dfregress/testcases/sample/test1/test1.c [new file with mode: 0644]
test/dfregress/testcases/sample/test2/Makefile [new file with mode: 0644]
test/dfregress/testcases/sample/test2/test2.c [new file with mode: 0644]
test/dfregress/testcases/sample/test3/Makefile [new file with mode: 0644]
test/dfregress/testcases/sample/test3/test3.c [new file with mode: 0644]
test/dfregress/testcases/sample/test4/Makefile [new file with mode: 0644]
test/dfregress/testcases/sample/test4/test4.c [new file with mode: 0644]
test/dfregress/testcases/sample/test5/Makefile [new file with mode: 0644]
test/dfregress/testcases/sample/test5/test5.c [new file with mode: 0644]
test/dfregress/testcases/sample/testb1/Makefile [new file with mode: 0644]
test/dfregress/testcases/sample/testb1/testb1.c [new file with mode: 0644]
test/dfregress/testcases/sample/testk1/Makefile [new file with mode: 0644]
test/dfregress/testcases/sample/testk1/testk1.c [new file with mode: 0644]
test/dfregress/testcases/sample/testk2/Makefile [new file with mode: 0644]
test/dfregress/testcases/sample/testk2/testk1.c [new file with mode: 0644]
test/dfregress/testcases/threads/Makefile [new file with mode: 0644]
test/dfregress/testcases/threads/umtx_errno/Makefile [new file with mode: 0644]
test/dfregress/testcases/threads/umtx_errno/umtx_errno.c [new file with mode: 0644]