CAPL Script

CAPL Test Modules: Bounded Waits and Timeouts

Test one explicit promise

This example's promise is narrow: within 500 ms after waiting begins, observe a received CAN1 data frame with ID 0x200, at least two bytes and marker 0xAA. It checks heartbeat availability and a minimal payload contract. It does not prove a door locked, establish request/response causality or measure every transmission interval.

Use the sender from periodic timers. Create a CAPL test module with Test Feature Set support, and restrict this teaching setup to one CAN channel so that the same ID on another channel cannot release the wait. The source below contains one testcase and MainTest entry point; do not paste it into a simulation node as a timer program. Check licensing, module type, channel context and installed API support first.

A bounded wait needs return-value handling

TestWaitForMessage return Meaning Action here
1 Matching message event occurred Retrieve the triggering frame and inspect it
0 Timeout Report that no event was observed within the limit
-2 Resumed due to constraint violation Identify the interruption separately from timeout
-1 or another unexpected value Error, unavailable functionality or unexpected result Report the code; do not inspect stale data

The timeout is in milliseconds. The reference specifies that zero disables timeout control, so this example uses a bounded 500. After arrival, TestGetWaitEventMsgData retrieves the frame that released the wait. Its success value is zero, unlike the wait function's success value of one.

Example test module

The source has been checked against the available reference but has not been compiled or executed in CANoe. Its passing step means only that the observed frame met the listed conditions.

testcase TC_HeartbeatAvailability()
{
  long waitResult;
  long dataResult;
  message CAN1.0x200 observed;

  TestCaseTitle("HB-01", "Observe a valid heartbeat within 500 ms");
  TestStep("1", "Wait for ID 0x200 in the single-channel test setup");
  waitResult = TestWaitForMessage(0x200, 500);

  if (waitResult == 0)
  {
    TestStepFail("2", "Timeout: no matching message observed within 500 ms");
    return;
  }
  if (waitResult == -2)
  {
    TestStepFail("2", "Wait interrupted by a constraint violation");
    return;
  }
  if (waitResult != 1)
  {
    TestStepFail("2", "Wait failed or is unavailable: result=%d", waitResult);
    return;
  }

  dataResult = TestGetWaitEventMsgData(observed);
  if (dataResult != 0)
  {
    TestStepFail("3", "Could not retrieve the triggering frame: result=%d", dataResult);
    return;
  }
  if (observed.CAN != 1 || observed.DIR != Rx || observed.RTR != 0)
  {
    TestStepFail("3", "Unexpected channel, direction or frame type");
    return;
  }
  if (observed.DLC < 2)
  {
    TestStepFail("3", "Heartbeat payload is shorter than two bytes");
    return;
  }
  if (observed.byte(0) != 0xAA)
  {
    TestStepFail("4", "Wrong marker: expected 0xAA, got 0x%02X", observed.byte(0));
    return;
  }
  TestStepPass("4", "Observed a two-byte heartbeat with marker 0xAA");
}

void MainTest()
{
  TC_HeartbeatAvailability();
}

Checking data retrieval, channel, direction, frame type and DLC before reading the payload prevents a cached value or short frame from masquerading as a correct response. The example does not depend on a separate on message handler updating a global doorStatus variable in time.

Exercise failure paths too

This is a matrix to execute, not a passing test report. Before each run, isolate the intended sender and reset the test environment.

Scenario Action Expected branch to inspect
Normal heartbeat Run the two-byte AA heartbeat sender Final content check passes
No heartbeat Stop the sender with x, let already-submitted traffic clear, then run the testcase Timeout after the bounded wait
Short frame Controlled source sends the same ID with DLC 1 Length check fails
Wrong marker Use DLC 2 and change the first byte to AB Payload check fails despite arrival
Configuration problem Inspect module availability or triggered constraints Actual error/interruption code, not a fabricated timeout

If an invalid frame arrives before a valid one, this example fails on the first frame. A requirement that allows retries needs an overall deadline; repeatedly waiting a fresh 500 ms can exceed the promised total duration.

Availability is not functional correctness

A heartbeat can be unrelated to a command you just sent. A real request/response test needs a defined correlation field, state transition or sequence identifier, plus rules for old responses and unrelated cyclic traffic. Calling output does not by itself justify a “sent successfully” test verdict; TestWaitForMessage returning one does not prove that a door locked.

Use the timestamp walkthrough and interval analyzer for period stability. One successful bounded wait cannot replace multi-frame statistics.

Keep the executed source, tool version, bench configuration, expected values and full test report before calling results measured. API semantics follow the authorized references for TestWaitForMessage, TestGetWaitEventMsgData and TestStep. The Vector Test Feature Set tutorial is an additional vendor resource that may require login; its examples do not constitute execution evidence for this page.