Test Point Testing in C/C++

From STRIDE Wiki
Revision as of 23:06, 2 April 2009 by Timd (talk | contribs) (New page: Testpoints provide an easy-to-use framework for solving a class of common yet difficult unit testing problems: ''How can I observe and verify activity that occurs in another thread?'' ...)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search

Testpoints provide an easy-to-use framework for solving a class of common yet difficult unit testing problems:

How can I observe and verify activity that occurs in another thread?

A couple of common scenarios that become a lot more testable via testpoints include:

  • Verification of State machine operation
  • Verification of communication drivers


Instrumenting Target Threads

Target threads are instrumented by placing a line of the following form into the source code:

...
srTEST_POINT("testpoint name");
...

When this code is executed it broadcasts a message via the STRIDE runtime which is detected by the test (IM) thread if it is currently looking for testpoints (i.e. in a srTEST_POINT_WAIT()). We refer to this as a "testpoint hit".


Instrumenting the Test Thread

The test thread is instrumented using these steps:

  1. Specify an expectation set (i.e. the testpoints that are expected to be hit)
  2. Register the expectation set with the STRIDE runtime
  3. Wait for the expectation set to be satisfied or a timeout to occur


Specifying the Expectation Set

An expectation set is an array of srTestPointExpect_t structures. srTestPointExpect_t is typdef'd as follows:

typedef struct
{
    /* the label value is considered the testpoint's identity */
    const srCHAR *  label;
    /* count specifies the number of times the testpoint is expected to be hit */ 
    srDWORD         count;
    /* data specifies an optional string data payload */
    const srCHAR *  data;
} srTestPointExpect_t;
Basic Example

A typical delcaration of an expectation set looks like this:

    srTestPointExpect_t expected[]= {
        {"START"}, 
        {"ACTIVE"}, 
        {"IDLE"},
        {"END"}, 
        {0}};

This example specifies the expectation of one hit each of the testpoints "START", "ACTIVE", "IDLE", and "END".

A few things to note:

  • The end of the array is marked by a srTestPointExpect_t set to all zero values
  • Structure members we omit in the array declaration are set to 0 by the compiler
  • A count value of either 0 or 1 is interpreted as 1
  • A data value 0 indicates that there is no payload data associated with this testpoint

Registering the Expectation Set

To register an expectation set, we call srTestPointExpect and receive a handle to identify the expectation set in the next step.

The registration looks like this:

srWORD handle;
srTestPointExpect(expected, &handle);

Waiting for the Expectation Set to be Satisfied

The final step is to wait for the expectation to be satisfied. We do this using the srTEST_POINT_WAIT() macro as shown below.

srTEST_POINT_WAIT(handle, expect_flags, timeout);

The macro takes three arguments

Expect Flags

Argument Description
handle The handle returned from the call to srTestPointExpect() used to register the expectation set
expect_flags Value that customizes the expectation in terms of testpoint hit order and testpoint exclusivity
timeout Timeout value in milliseconds; 0 means infinite timeout
srTestPointExpect
Expect Flags Unexpected Testpoint
causes test failure
Out of order Testpoint
causes failure
0
srTEST_POINT_WAIT_ORDER X
srTEST_POINT_WAIT_STRICT X
srTEST_POINT_WAIT_ORDER | srTEST_POINT_WAIT_STRICT X X