Project

General

Profile

Unit Tests

Unit tests are used by developers of Suricata and advanced users who would like to contribute by debugging and testing the engine.
Unit tests are small pieces (units) of code which check certain code functionalities in Suricata. If Suricata's code is modified, developers can run unit tests to see if there are any unforeseen effects on other parts of the engine's code.
Unit tests will not be compiled with Suricata by default.
If you would like to compile Suricata with unit tests, enter the following during the configure-stage:
./configure --enable-unittests

The unit tests specific command line options can be found at Command Line Options.

Example:
You can run tests specifically on flowbits. This is how you should do that:
suricata -u -U flowbit

It is highly appreciated if you would run unit tests and report failing tests at Issues.

Caveats

Please do not compile Suricata with both --enable-debug-validation and --enable-unittests. Doing so will cause Suricata (as of 1.3b) to segfault on a failed test. This compilation combination is unsupported and will eventually throw an error condition rather than crash.

Victor advises "The debug validation is only meant to be used when processing packets (either from a pcap or from the wire)."

If you want extra verbosity for unit tests, please heed Victor's advice below:

The debug validation option enables some integrity tests at runtime. For
example making sure a flow is locked before it is modified. Making sure
data structures cannot have conflicting settings, etc.

If you want more info about the unittests, regular debug mode can help:

--enable-debug

Then, set the debug level from the commandline:

SC_LOG_LEVEL=Debug suricata -u

This will be very verbose. You can also add the SC_LOG_OP_FILTER to
limit the output, it is grep-like:

SC_LOG_LEVEL=Debug SC_LOG_OP_FILTER="(something|somethingelse)" suricata -u

This example will show all lines (debug, info, and all other levels)
that contain either something or somethingelse.

General Suricata Performance Considerations

Peter Manev provides some noteworthy caution for using Suricata in production:

"--enable-profiling --enable-debug --enable-debug-validation" - would make Suricata about 3-4 times slower (at least in my tests).
If you are inspecting a high traffic link, starting Suricata in verbose mode "-v", while being compiled with --enable-debug can lead to a huge size of suricata.log > 1 TB in a day

Writing Unit Tests

A unit test is a function with no arguments and returning 0 for failure or 1 for success. Instead of explicitly returning a value, FAIL_* and PASS macros should be used. For example:

void MyUnitTest(void)
{
    int n = 1;
    void *p = NULL;

    FAIL_IF(n != 1);
    FAIL_IF_NOT(n == 1);
    FAIL_IF_NOT_NULL(p);
    FAIL_IF_NULL(p);

    PASS;
}

Each unit test needs to be registered with UtRegisterTest(). Example:

    UtRegisterTest("MyUnitTest", MyUnitTest);

where the first argument is the name of the test, and the second argument is the function. Existing modules should already have a function that registers its unit tests. Otherwise the unit tests will need to be registered. Look for a module similar to your new module to see how best to register the unit tests or ask the development team for help.