Visual Assert – The Unit Testing Add-In for Visual C++
cfix – C/C++ Unit Testing for Win32 and NT
 
 

Multithreading

Multithreading

cfix test cases can make use of multithreading. Multithreading, however, introduces a set of challenges for cfix: In particular, any assertions and log statements executed on such child threads must be associated with the respective test case the child thread has been spawned by.

To allow such association, developers have to follow a few simple rules:

  • When a test case spawns a thread and this thread will call cfix API routines such as CFIX_ASSERT or CFIX_LOG, then CfixCreateThread (for user mode code) or CfixCreateSystemThread (for kernel mode code) should be used to create this thread. Direct usage of CreateThread and CreateSystemThread is discouraged.

    CfixCreateThread and CfixCreateSystemThread behave like their counterparts CreateThread and CreateSystemThread, but additionally register the thread with cfix.

    [Note]Note
    If a thread not created using CfixCreateThread or CfixCreateSystemThread calls the cfix API and, for example, causes an assertion to fail, a message will be printed on the debugger console and the thread will be terminated by cfix. The failure message will not be output on the console and no debugger break-in will be triggered. Moreover, the failed assertion will not cause the enclosing test case to be reported as having failed.
  • Child threads should terminate before the enclosing test case completes.

    As of cfix 1.5, this behavior is automatically enforced: After a test case ends, cfix will check the status of all child threads (i.e. all threads created using CfixCreateThread or CfixCreateSystemThread) and will wait for their termination. Not before all threads have terminated will the test case complete.

    This feature is referred to as Auto Joining.

    [Note]Note
    Any non-cfix related threads such as threads spawned by the code under test are not regarded by Auto Joining. Make sure that all these threads are stopped before the test case completes.
  • In some situations, using CfixCreateThread or CfixCreateSystemThread may not be feasible because of special constraints: For example, a thread may have to be started using the boost library or using AfxCreateThread.

    As of cfix 1.6, you can make use of the Anonymous Thread Auto-Registration feature in such situations in order to still allow APIs like CFIX_ASSERT or CFIX_LOG to be used on such threads.

When assertions fail or unhandled exceptions occur on registered child threads, these events are reported in the same manner they would be reported if they occured on the main thread.

It is crucial to notice, however, that a failed assertion or unhandled exception occuring on a registered child thread will not abort the entire enclosing test case -- rather, only the child thread is terminated, while the main thread as well as any other child threads will resume execution.

Regardless of whether further failed asseretions or unhandled exceptions will occur on the main thread, however, the enclosing test case will be reported as having failed.