package crowbar

  1. Overview
  2. Docs
Write tests, let a fuzzer find failing cases

Install

Dune Dependency

Authors

Maintainers

Sources

v0.2.1.tar.gz
md5=c79be303acd3ba5f8a7477c533133d2b

Description

Crowbar is a library for testing code, combining QuickCheck-style property-based testing and the magical bug-finding powers of afl-fuzz.

Published: 04 Mar 2022

README

Crowbar

Crowbar is a library for testing code, combining QuickCheck-style property-based testing and the magical bug-finding powers of afl-fuzz.

TL;DR

There are some examples.

Some brief hints:

  1. Use an opam switch with AFL instrumentation enabled (e.g. opam sw 4.04.0+afl).

  2. Run in AFL mode with afl-fuzz -i in -o out -- ./_build/myprog.exe @@.

  3. If you run your executable without arguments, crowbar will perform some simple (non-AFL) testing instead.

  4. Test binaries have a small amount of documentation, available with --help.

writing tests

To test your software, come up with a property you'd like to test, then decide on the input you'd like for Crowbar to vary. A Crowbar test is some invocation of Crowbar.check_eq or Crowbar.check:

let identity x =
  Crowbar.check_eq x x

and instructions for running the test with generated items with Crowbar.add_test:

let () =
  Crowbar.(add_test ~name:"identity function" [int] (fun i -> identity i))

There are more examples available, with varying levels complexity.

building tests

Include crowbar in your list of dependencies via your favorite build system. The resulting executable is a Crowbar test. (Be sure to build a native-code executable, not bytecode.)

To build tests that run under AFL, you'll need to build your tests with a compiler that has AFL instrumentation enabled. (You can also enable it specifically for your build, although this is not recommended if your code has any dependencies, including the OCaml standard library). OCaml compiler variants with AFL enabled by default are available in opam with the +afl tag. All versions published starting with 4.05.0 are available, along with a backported 4.04.0.

$ opam switch 4.06.0+afl
$ eval `opam config env`
$ ./build_my_rad_test.sh # or your relevant build runes

running Tests

Crowbar tests have two modes:

  • a simple quickcheck-like mode for testing propositions against totally random input

  • a mode using afl-persistent to get good performance from afl-fuzz with OCaml's instrumentation enabled

Crowbar tests can be directly invoked with --help for more documentation at runtime.

fully random test mode

If you wish to use the quickcheck-like, fully random mode to run all tests distributed here, build the tests as above and then run the binary with no arguments.

$ ./my_rad_test.exe | head -5
the first test: PASS

the second test: PASS

AFL mode requirements

To run the tests in AFL mode, you'll need to install American Fuzzy Lop (latest source tarball, although your distribution may also have a package available).

Once afl-fuzz is available on your system, create an input directory with a non-empty file in it (or use test/input, conveniently provided in this repository), and an output directory for afl-fuzz to store its findings. Then, invoke your test binary:

afl-fuzz -i test/input -o output ./my_rad_test.exe @@

This will launch AFL, which will generate new test cases and track the exploration of the state space. When inputs are discovered which cause a property not to hold, they will be reported as crashes (along with actual crashes, although in the OCaml standard library these are rare). See the afl-fuzz documentation for more on AFL's excellent interface.

What bugs have you found?

An open issue has a list of issues discovered by testing with Crowbar. If you use Crowbar to improve your software, please let us know!

Dependencies (5)

  1. afl-persistent >= "1.1"
  2. cmdliner >= "1.1.0"
  3. ocplib-endian >= "0.6"
  4. ocaml >= "4.08"
  5. dune >= "2.9"

Dev Dependencies (7)

  1. odoc with-doc
  2. uutf with-test
  3. uunf with-test
  4. uucp with-test
  5. pprint with-test
  6. fpath with-test
  7. calendar >= "2.00" & with-test

Used by (53)

  1. art >= "0.2.0"
  2. buffer-pool
  3. build_path_prefix_map >= "0.3"
  4. bun >= "0.3.3"
  5. carton
  6. chamelon >= "0.0.9.1"
  7. cohttp >= "5.0.0" & < "6.0.0~alpha0"
  8. colombe < "0.2.0" | >= "0.4.2"
  9. conan
  10. conan-cli
  11. conan-database
  12. conan-lwt
  13. conan-unix
  14. cstruct >= "6.0.1"
  15. current_incr >= "0.6.1"
  16. data-encoding
  17. decompress >= "1.4.1"
  18. digestif >= "1.2.0"
  19. duff >= "0.3"
  20. eio
  21. eio-trace
  22. eqaf >= "0.4"
  23. git >= "3.0.0"
  24. http
  25. index
  26. json-data-encoding
  27. ke >= "0.5"
  28. mrmime < "0.2.0" | >= "0.5.0"
  29. optint >= "0.0.3"
  30. patch
  31. pecu >= "0.6"
  32. ppx_deriving_crowbar
  33. prbnmcn-linalg
  34. prbnmcn-proptest
  35. sendmail < "0.2.0"
  36. sendmail-lwt < "0.2.0"
  37. tezos-base >= "8.0" & < "10.2"
  38. tezos-crypto >= "9.0" & < "9.2"
  39. tezos-lwt-result-stdlib < "10.2"
  40. tezos-mockup >= "9.0" & < "10.2"
  41. tezos-protocol-environment >= "8.0" & < "10.2"
  42. tezos-proxy < "11.0"
  43. tezos-shell >= "8.0" & < "11.0"
  44. tezos-stdlib >= "8.0" & < "10.2"
  45. timedesc
  46. timere
  47. tls-eio >= "0.16.0"
  48. unstrctrd >= "0.3"
  49. uri >= "4.4.0"
  50. uri-re >= "4.4.0"
  51. xapi-rrd >= "1.8.2"
  52. yaml >= "3.0.0"
  53. yaml-sexp

Conflicts

None