Receiving Messages

System Testing for C

CALLBACK Instruction

The event management provides an asynchronous mechanism to receive messages. This mechanism needs the definition of a callback for each couple communication type, message type.

A procedre should do a non-blocking read for a specific message type on a specific communication type.

The MESSAGE_DATE instruction lets you mark the right moment of the reception of messages. The NO_MESSAGE instruction exits from the callback and indicates that no message has been read.

The callback to receive messages from our system under test could be:

CALLBACK message_t: msg ON appl_comm: id

CALL mbx_get_message ( &id, &msg, 0 ) @@ errcode

MESSAGE_DATE

IF ( errcode == err_empty ) THEN

NO_MESSAGE

END IF

IF ( errcode != err_ok ) THEN

ERROR

END IF

END CALLBACK

In this example, msg is an output formal parameter of the callback. Its type is message_t.

When multiple connections are used, the input formal parameter id is used to know where to read a message on the communication type appl_comm.

The reading is done by the function call to mbx_get_message. The return code is stored into the variable errcode. The value err_empty for the return code means that no message has been read. Another value than err_ok or err_empty means that an error occurred during the reading. The NO_MESSAGE and ERROR instructions make the callback to return.

The script must have one CALLBACK for each message type - channel type pair used by any WAITTIL instructions.

The name of each CALLBACK in the generated C code is made up with the signature of the message type and channel type for each CALLBACK found in the test script.

DEF_MESSAGE Instruction

The DEF_MESSAGE instruction defines the values of a reference message declared with the MESSAGE instruction. A reference message is a set of field values as expected by the virtual tester from the system under test. Any undefined fields are not compared to the receive message.

DEF_MESSAGE ack, EV= { type => ACK }

DEF_MESSAGE data, EV= {

& type => DATA,

& applname => "SATURN",

& userdata => "hello world !" }

To learn more about the DEF_MESSAGE Instruction, see the Messages and Data Management chapter.

WAITTIL Instruction

The WAITTIL instruction allows the test script to wait for events or conditions. WAITTIL is made of two Boolean expressions: an expected condition, and a failure condition. The script execution pauses until one of the two expressions becomes true.

In the following example, the WAITTIL instruction receives all the messages sent to the Virtual Tester on a known connection. As soon as a received message matches the reference message ack, the WAITTIL exits normally. Otherwise, if any message matching the reference message ack is received during 3000ms (300 x 10ms, the default time unit), the WAITTIL exits with an error. The scenario execution is interrupted.

WAITTIL ( MATCHING(ack, appl_ch), WTIME == 300)

The time unit is configurable in the Target Deployment Port depending on the target platform.

To receive a message on the appropriate channel, the generated code calls a CALLBACK named with the signature of the expected message type (first parameter) and the channel type (second parameter).

The message type is provided by the MESSAGE instruction. The channel type is provided by the CHANNEL instruction.

Therefore, in the generated code, the SEND instruction calls the following function:

CALLBACK_message_t_appl_comm(message, appl_ch)

which corresponds to the following line in the test script:

CALLBACK message_t ... ON appl_comm

If the channel parameter is omitted in the WAITTIL instruction, the generated code calls all CALLBACK instructions that read the corresponding message type on all known channel types.

In the example given above, the status of the reference event variable ack is tested using the function MATCHING() which identifies if the last incoming event corresponds to the content of the variable ack. WTIME is a reserved keyword valuated with the time expired since the beginning of the WAITTIL instruction.

The WAITTIL Boolean conditions are described using C or C++ conditions including operators to manipulate events:

  • MATCHING: does the last event match the specified reference event?

  • MATCHED: did the Virtual Tester receive an event matching the specified event?

  • NOMATCHING: is the last event different from the specified reference event?

  • NOMATCHED: did the Virtual Tester receive an event different from the specified event?

The different combinations of these operators allow an easy an extensive definition of event sequences:

-- I expect evt1 on channel1 before my_timeout is reached

WAITTIL (MATCHING(evt1, channel1), WTIME>my_timeout)

-- I expect evt1 then evt2 on one channel before my_timeout is reached

WAITTIL (MATCHED(evt1)&& MATCHING(evt2), WTIME>my_timeout)

-- I expect to receive nothing during my_time

WAITTIL (WTIME>my_time, MATCHING(empty_evt))

-- I expect evtA or evtB before my_timeout is reached

WAITTIL (MATCHING(evtA)||MATCHING(evtB), WTIME>my_timeout)

*

After the WAITTIL instruction, the value of these operators is available until the next call to WAITTIL.

Example

The following test script describes a simple use of our stack. First of all, some resources are allocated and a connection is established with the communication stack (mbx_init). This connection is made known by the Virtual Tester with the ADD_ID instruction. Then, the Virtual Tester registers (mbx_register) onto the stack giving its application name (JUPITER).

The Virtual Tester sends a message to an application under test (SATURN), and waits for the acknowledgment sent back by the stack with the WAITTIL instructions. Finally, the Virtual Tester unregisters (mbx_unregister) and frees the allocated resources (mbx_end).

HEADER "SystemTest 1st example: sending & receiving a message","1.0",""

COMMTYPE appl_comm IS appl_id_t

MESSAGE message_t: message, ack, data, neg_ack

CHANNEL appl_comm: appl_ch

#appl_id_t id;

#int errcode;

PROCSEND message_t: msg ON appl_comm: id

CALL mbx_send_message ( &id, &msg) @ err_ok

END PROCSEND

CALLBACK message_t: msg ON appl_comm: id

CALL mbx_get_message ( &id, &msg, 0 ) @@ errcode

MESSAGE_DATE

IF ( errcode == err_empty ) THEN

NO_MESSAGE

END IF

IF ( errcode != err_ok ) THEN

ERROR

END IF

END CALLBACK

SCENARIO first_scenario

FAMILY nominal

COMMENT Initialize, register, send data

COMMENT wait acknowledgement, unregister and release

CALL mbx_init(&id) @ err_ok @ errcode

ADD_ID(appl_ch,id)

VAR id.applname, INIT="JUPITER"

CALL mbx_register(&id) @ err_ok @ errcode

VAR message, INIT={

& type=>DATA,

& applname=>"SATURN",

& userdata=>"hello Saturn!"}

SEND ( message, appl_ch )

COMMENT Negative acknowledgment expected

COMMENT (Saturn is not running !)

DEF_MESSAGE ack, EV={type=>ACK}

WAITTIL (MATCHING(ack), WTIME==10)

CALL mbx_unregister(&id) @ err_ok @ errcode

CLEAR_ID(appl_ch)

CALL mbx_end(&id) @ err_ok @ errcode

END SCENARIO

Related Topics

Event Management | Basic Declarations | Sending Messages | Messages and Data Management