Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

Table of Contents
maxLevel1
Note
titleHelper Keywords

Throughout this topic, helper keywords are used to represent complete paths

...

:

  • <C/C++test_runtime_root> =

...

  • <CPPTEST_INSTALL_DIR>/bin/engine/runtime
  • <C/C++test_runtime_sources> =

...

  • <CPPTEST_INSTALL_DIR>/bin/engine/runtime/src
  • <C/C++test_includes> =

...

  • <CPPTEST_INSTALL_DIR>/bin/engine/runtime/include

Introduction

The C/C++test runtime library is distributed with the C++test installation in the form of C source and header files. The source for the runtime library is located in the directories referenced in the above box

...

  1. Build the runtime library using the provided makefiles or one of the preconfigured IDE projects located in <C/C++test_runtime_root>/runtime/projects.
  2. Add the resulting .a file to Project Properties> C/C++test> Build Options> Linker Option
    • Use an absolute path, or use ${workspace_loc} and ${project_loc} variables if the runtime library is in the same workspace..

    • The best option is to have the library file in some fixed location so that multiple users can point to it without changes.
    • Using a regular environment variable for the runtime library is also supported.

...

The library can be configured to support features that are available on the target platform, or to block those that are not. The default configuration is full-featured, but you might need to block troublesome features—especially if you experience compile-time or runtime crashes. Embedded developers are familiar with the pros and cons of the platform(s) they use, and should be able to build an appropriately - configured library and append its path to the linker command line.

...

In some cases, you may want to prepare a custom build of the C++test runtime library. You can build the C/C++test runtime library using the Makefilein the <C/C++test_runtime_sources> directory. You can also use one of the provided preconfigured IDE projects to build the runtime library; these are available in <C/C++test_runtime_root>/runtime/projects. Optionally, you can create an IDE project on your own.

Basically, building Building the runtime library involves selecting the communication channel, then running the IDE builder or 'make' Make in the directory containing the Makefile. You may also need to change the compiler and platform-specific configuration if the default one causes problems or if there is no default configuration for your compiler and target platform (see Configuring the C++test Runtime Library).

...

The following test execution step should be used for automated building of the C/C++test runtime:

Code Block
<BuildRuntimeLibStep additionalFlags="<build options>" />

This execution step will compile all source files found in the C++test Runtime library source location using the environment (compiler executable, build options) of the tested project. The compiled objects will then be linked into a test executable. The additionalFlags attribute is optional and can be used to specify additional build options.

Note
iconfalse
titleImportant Note - Removing the Runtime Library from Build Settings

Before C/C++test builds the unit testing runtime automatically (as a part of the test execution flow), ensure that the C++test runtime library is removed from the Build Settings> Linker options.

...

The first step in manually building the runtime library is to choose one of the communication channel implementations that will be used by the runtime. The  following communication channel implementations are in the C/C++test runtime distribution:

...

  • CPPTEST_USE_FILE_COMMUNICATIONS
  • CPPTEST_USE_FILE_SPLIT_COMMUNICATIONS
  • CPPTEST_USE_FILE_BUFFERED_COMMUNICATION
  • CPPTEST_USE_UNIX_SOCKET_COMMUNICATION
  • CPPTEST_USE_WIN_SOCKET_COMMUNICATION
  • CPPTEST_USE_RS232_WIN_COMMUNICATION
  • CPPTEST_USE_RS232_UNIX_COMMUNICATION
  • CPPTEST_USE_RS232_STM32F103ZE_COMMUNICATION
  • CPPTEST_USE_CUSTOM_COMMUNICATION

Building the C/C++test Runtime Library with

...

Make
Anchor
Building the C++test Runtime Library with 'make'
Building the C++test Runtime Library with 'make'

Calling the 'make' command in the directory containing the Makefile will compile the runtime sources with the gcc compiler and will create the C/C++test runtime library using the ar library tool. To change the compiler and library tool, you need to specify the target configuration at the 'make' Make command line. For example:

Code Block

...

make TARGET_CFG=WR_DKM_gcc3_4_simlinux_VxWorks6_4.mk

The following configurations are available in the C/C++test runtime distribution (in <C++test_runtime_sources>/target/ directory):

...

NameDefaultDescription
CCgccCompiler executable used to compile C/C++test runtime sources.
CFLAGS
Flags used during compilation.
CC_OUT_DIR_FLAG
Flag used with a directory for storing compilation products:
$(CC_OUT_DIR_FLAG)"<output-dir>"
CC_OUT_FLAG-oFlag used with output file name. The
$(CC_OUT_FLAG)"<output-file-name>" is added to the compiler command line.
OBJ_EXToObject file extension used when creating an output file namefilename
LIBTOOLarExecutable that is able to create a library from compiled sources.
LIBTOOL_FLAGS-ruvFlags used with lib tool when creating a C/C++test runtime library
LIBTOOL_OUT_FLAG
Flag used with the output file namefilename. The
$(LIBTOOL_OUT_FLAG)"<output-file-name>" is added to the lib tool command line.
LIB_PREFIXlibThese variables are used when creating a C++test runtime library name:
$(LIB_PREFIX)$(LIB_NAME).$(LIB_EXT)
LIB_NAMEcpptestruntime
LIB_EXTa

The LD, LDFLAGS, LD_OUT_FLAG and OUT_EXT are also defined by available configurations, but they are not required to build the C/C++test runtime library. They are only used to build a simply simple test executable when the 'test' target from make file Makefile is called.

To create your own target configuration, make a copy of an existing one that best describes your target, then modify it as needed. To build the C/C++test runtime library with your new target configuration, add the  TARGET_DIR parameter to the 'make' command line:    

Code Block
 make TARGET_DIR=<directory with my target configuration>

...

 TARGET_CFG=MyTargetConfig.mk

You can also change the directory in which the runtime library is created (by default, it is set to ./build directory). To change this, add the OUT_DIR parameter to the 'make' Make command line. For example:    

Code Block
make OUT_DIR=<output directory for

...

 your C/C++test runtime library> ...

You can perform the build in the location where C/C++test is installed, or you can copy the C/C++test runtime source files and build them in a different location. In such cases, remember to adjust the path to C++test includes (which are stored in <C/C++test_includes>). To do this, modify the value of the CPPTEST_INC_DIR variable inside the make file to an absolute path. For example:

CPPTEST_INC_DIR=/usr/local/<CPPTEST_INSTALL_DIR>/bin/engine/runtime/include

Info
iconfalse
titleMulti-Thread Support

To build a custom Runtime Library with

...

multi-thread support, add "-DCPPTEST_THREADS_ENABLED=1" to the compiler command line.

Configuring the C/C++test Runtime Library
Anchor
Configuring the C++test Runtime Library
Configuring the C++test Runtime Library

...

Note
titleNote

Include files used for building the runtime library (located in <C/C++test_includes>) are also included by the generated test harness (test source files automatically generated by C/C++test). If you need to modify these files, be extremely careful. Even a small mistake could cause the test harness compilation to fail. It is typically safe to introduce target-specific changes using the preprocessor conditional instructions (#ifdef...#endif).

The available compiler configurations are placed in the <C/C++test_includes>/config/ directory. There is also a cpptest_portinfo.h header file in the C/C++test include directory that determines which compiler configuration should be used when building the C/C++test runtime library. A compiler configuration header file defines a set of macros that adapt the runtime to the target platform. It also may define the macros that disable some C/cC++test features that cannot be supported on the target platform. The full list of features that can be disabled can be found in the cpptest_features.h header file.

...

NameDetails
CPPTEST_EXPORT, CPPTEST_IMPORTWhen building DLLs for Windows platform, these are expanded to __declspec(dllexport),
__declspec(dllimport), Microsoft-specific extensions for importing/exporting functions and data to and from a DLL.
CDECL_CALLWhen building with a Microsoft compiler, this is expanded to __cdecl Microsoft-specific extensions for calling convention.
CPPTEST_WCHAR_ENABLEDIf defined as 1, then the runtime library will be built with support for wchar types. When defined as 0, the C++test runtime library will be built without support for wchar types.
CPPTEST_SETJMP_ENABLEDIf defined as 1, signal handling routines are used to recover if an exception is thrown during test case execution. In this case, C++test logs the exception and tries to continue test cases execution.
CPPTEST_USE_ANSI_SETJMPIf defined as 1, then the following functions are used for signals handling: longjmp , setjmp. If 0, then siglongjmp and sigsetjmp are used. And analogically with data types: sigjmp_buf versus jmp_buf. Note that you need to have CPPTEST_SETJMP_ENABLED set to 1 for CPPTEST_USE_ANSI_SETJMP to take effect.
CPPTEST_USE_UNCAUGHT_EXCEPTION_CHECKINGIf defined as 1, then the uncaught_exception function is used for uncaught exception handling.
CPPTEST_USE_STD_NSDefine to 0 when C/C++test should not use the std namespace or when your compiler doesn't support namespaces.
CPPTEST_TIME_MODEThis macro controls which functions are used for time measuring. The list of allowed values is available in the cpptest_time.h header file.

...

Data emitted from the target via the TCP/IP sockets should be captured with the help of a socket listener. The listener is a simple utility program shipped with C/cC++test. It is located in <CPPTEST_INSTALL_DIR>/bin/ engine/runtime/<C/C++test_runtime_root>/listeners/socket_listener, and it accepts the following parameters:

...

  • Raw mode: In this mode, data is sent to a host machine without any verification. This is recommended for stable environments.
  • Safe: In this mode, checksum is computed for every packet. If the checksum is incorrect, the transfer  transfer is stopped. This mode is activated by adding the compilation flag - DCPPTEST_RS232_SAFE_MODE=1.

...

SymbolDescription
STX (0x02)Start of text
ETX (0x03)End of text
EOT (0x04)End of transmission
ENQ (0x05)Enquiry
ACK (0x06)Affirmative acknowledgement
NAK (0x15)Negative acknowledgment

In "safe" mode, the checksum is compute computed with exclusive-or. For "raw" mode, the checksum is not computed and zero value is sent for all frames.

...

In "safe mode", the client sends the ENQ to enquire about availability. It cannot start the transmission until it receives the ACK. After the client receives the ACK, it sends another frame. Every frame is confirmed with an ACK by the host machine. At the end, the client sends the EOT. In response, the host sends an ACK to complete the transmission.  Checksum The checksum is calculated only in safe mode. In the normal mode, it is always 0.

...

The following steps need to be accomplished in order to add another implementation of serial communication:

  1. Add a new file in the <CPPTEST_INSTALL_DIR>/bin/engine/runtime<C/C++test_runtime_root>/src/transport directory with the implementation of the custom serial communication. Follow this template:

    Code Block
    #define CPPTEST_RUNTIME_IMPLEMENTATION
    #include "cpptest_portinfo.h"
    #ifdef CPPTEST_USE_RS232_MYPLATFORM_COMMUNICATION
    #include "CppTestTransportRS232Common.h"
    int localRsInitInternalSerial(CppTestStreamParameters *par)
    {
      return RS_OK;
    }
    int localRsUninitInternalSerial(CppTestStreamParameters *par)
    {
      return RS_OK;
    }
    int localRsSendInternalByte(CppTestStreamParameters *par, unsigned char
    byte, unsigned char *is_send)
    {
      return RS_OK;
    }
    int localRsSendInternalStr(CppTestStreamParameters *par, unsigned char
    *bytes, int *nBytes)
    {
      return RS_OK;
    }
    int localRsRecvInternalByte(CppTestStreamParameters *par, unsigned char
    *pByte, unsigned char *is_recv)
    {
      return RS_OK;
    }
    int localFlushInternalRS(CppTestStreamParameters *par)
    {
      return RS_OK;
    }
    void localSetStop(int *stop_bit, int result)
    {
    }
    void localSetParity(int *parity, char *result)
    {
    }
    void localRsSleep(unsigned int msec)
    {
    }
    #endif
  2. Provide the implementation for the following functions:
    • int localFlushInternalRS(CppTestStreamParameters *par);
      Flush internal Serial port buffer. CppTestStreamParameters described below.
    • int localRsInitInternalSerial(CppTestStreamParameters *par);
      Init serial port.
    • localRsSendInternalByte(CppTestStreamParameters *par, unsigned char byte, unsigned char *is_send);
      Send one byte. Parameters are par (described below), byte to send and result.
    • int localRsSendInternalStr(CppTestStreamParameters *par, unsigned char bytes, int *nBytes);
      Send nBytes bytes. Parameters are par (described below), bytes to send and nBytes sent.
    • int localRsRecvInternalByte(CppTestStreamParameters *par, unsigned char *pByte, unsigned char *is_recv);
      Receiving one byte. Parameters are par (described below), received byte result.
    • int localRsUninitInternalSerial(CppTestStreamParameters *par);
      Close serial port.
    • void localSetStop(int *stop_bit, int result);
      Set stop bit transmission parameter.
    • void localSetParity(int *parity, char *result);
      Set parity transmission parameter.
    • char *localGetErrorText(void);
      Return buffer with ErrorText (if any).
    • void localRsSleep(unsigned int msec);
      Sleep implementation.

...

Data emitted from the target via the serial link should be captured with the help of a serial port listener. The listener is a simple utility program shipped with C/c++test. It is located in <CPPTEST_INSTALL_DIR>/bin/engine/runtime/<C/C++test_runtime_root>/listeners/rs232_listener, and it accepts the following parameters:

ParameterDescription
-d (--device)
COM,SPEED,PARIT Y,STOP,BYTE_SIZE.
Used device. e.g. -d 1,19200,N,1,8. We use the COM1 port, at a rate of 19200, no parity, one stop bit and 8 byte size.
-sf (--syncfile) <sync file>Filename to synchronize
-cn (--channel) number<mode>@<fil e path>Communication channel. C++test uses two channel -test log and coverage log. The mode can be 'b' for binary or 't' for text (default)
-to (--timeout)
<timeout in second>
Time to wait for results. If this is exceeded, the program stops.
-fi <file_name>File mode. Reads results from a binary file. All RS232 settings will be ignored.
-rm (--rawmode)Raw mode (no ACK and checksum). This option is required if transport was used in non safe mode.
-v (--verbose)Verbose mode.

...

This function is called at the beginning of the CppTest_InitializeRuntime function, even before C/C++test runtime library modules are initialized.

...

This function is called at the end of CppTest_FinalizeRuntime after the test results communication channel is closed. 

These functions are typically used if your project requires early initialization code to be executed, such as hardware-specific initialization code (e.g. disabling the watchdog timer) or any other type of initialization that is expected to happen very early in the execution sequence. Analogously for finalization code

Note
titleUsage of CppTest_Initialize/Finalize in Unit Testing and Application Monitoring

When running unit tests, the initialization code existing in your original project will be omitted from execution because the original application entry point (typically the main function) is replaced by C/C++test with an automatically generated test harness entry point. This is why the initialization/finalization code may need to be hooked via the CppTest_Initialize/Finalize function.

In Application Memory Monitoring mode, by contrast, there is usually no need to provide hardware initialization code in form of a C/C++test-specific function. This is because the original initialization code should be called for this purpose, since because C/C++test does not replace the application entry point in Application Monitoring mode. However, if you do need to perform a C/C++test-specific initialization/finalization in Application Monitoring mode, the CppTest_Initialize/Finalize functions can be used the same way.

...

CppTest_Initialize and CppTest_Finalize functions can be added directly to your project. You can also place them in a source file that does not belong to your project. The source file must be placed in a dedicated directory that is not a part of your originial original project and matches one of the locations specified in your test configuration:

...


When a definition of this function(s) is provided, C/C++test will detect it during test preparation and generate a call to it at an early stage of the test executable startup.

...

C++test ships with a dedicated wizard for automating the installation of CppTest_Initialize and CppTest_Finalize funtion function skeletons. If preferred, users can still manually add these functions.

...