Skip to content

Writing tests for ng_netapi modules

Andreas "Paul" Pauli edited this page Sep 3, 2015 · 9 revisions

Overview

gnrc_nettest provides functionality to test gnrc_netapi (see netapi) based modules. For every gnrc_netapi message call there are functions to test this message:

  • GNRC_NETAPI_MSG_TYPE_SND:
    • gnrc_nettest_send(): to test inner-stack modules (modules that get all their communication partners through gnrc_netreg)
    • gnrc_nettest_send_iface(): to test modules communicating with at least one gnrc_netif interface.
  • GNRC_NETAPI_MSG_TYPE_RCV: gnrc_nettest_receive()
  • GNRC_NETAPI_MSG_TYPE_GET: gnrc_nettest_get()
  • GNRC_NETAPI_MSG_TYPE_SET: gnrc_nettest_set()

There are also functions to manipulate the behavior of gnrc_nettest itself, so that you can set option behavior the module the module you like to test expects from its neighboring modules:

  • gnrc_nettest_register_get(): set a getter for an option.
  • gnrc_nettest_register_set(): set a setter for an option.

Initialization

In general the functions are implemented to be used with any unittest framework. For RIOT we use a modified version of embUnit, but it is not restricted to that. Furthermore, gnrc_nettest requires the main thread to have a packet queue so you have to initialize one. This means that your main.c has to look at minimum like this:

#include <stdio.h>

#include "net/gnrc/nettest.h"
#include "embUnit.h"
#include "msg.h"

#define MAIN_MSG_QUEUE_SIZE (4) /* As long as this value stays an exponential of 2
                                 * this can be adapted for your tests */

static msg_t msg_queue[MAIN_MSG_QUEUE_SIZE];

int main(void)
{
    if (gnrc_nettest_init() < 0) {
        puts("Error initializing nettest thread");
        return 1;
    }

    msg_init_queue(msg_queue, MAIN_MSG_QUEUE_SIZE);

    TESTS_START();
    /* TESTS_RUN(some_test_generator()); */
    TESTS_END();

    return 0;
}

Note that your tests have to generate some Test * objects (through some_test_generator() in this example) to have the tests actually run. Please refer to "Testing RIOT" for details on how to set up unittests.

Testing data tranfer

The tests for GNRC_NETAPI_MSG_TYPE_SND and GNRC_NETAPI_MSG_TYPE_RCV are based on the principle that a gnrc_netapi module gets some kind of input which triggers some kind of output. For gnrc_nettest both input and output must be handled through gnrc_netapi, other kinds of output or input (e.g. for interfaces) are out of scope of gnrc_nettest. Each of the test functions for this modules have four parameters that are relevant for this:

  • gnrc_pktsnip_t *in: the input that triggers the output
  • unsigned int exp_pkts: the numbers of packets expected in output (may be 0)
  • const kernel_pid_t *exp_senders: the expected senders of the output (may be NULL if exp_pkts is 0)
  • const gnrc_pktsnip_t **exp_out: the expected output packets (may be NULL if exp_pkts is 0)

If the module you test needs to set or get some kind of option from the layer it is supposed to output to (e.g. hardware address from the interface) you can use gnrc_nettest_register_get() and gnrc_nettest_register_set() to set getters/setters for these options for the neighboring layers.

If exp_pkts is 0, the tested module's priority MUST be equal or higher to the testing threads priority to ensure that the in packets are handled by the tested module.

Testing options

You can test getting and setting options with gnrc_nettest_get() and gnrc_nettest_set() by just using the parameters as documented.

If the module you test needs to set or get some kind of option to set or get its own options you can use gnrc_nettest_register_get() and gnrc_nettest_register_set() to set getters/setters for these options for the neighboring layers.

Example

Have look at tests/udp/ (currently PR'd at #3248) for an example.

Clone this wiki locally