Capture DUT values
Station runtime v0.3.0 can attach named values to test reports on HTF v0.1.4. Use captures for identifiers or measurements that should be searchable without parsing console logs. Each observation keeps its DUT, run, lane, stage, optional subtest, capture time, and configuration revision.
Map a built-in stage output
Add a capture mapping to a stage. The mapping's key is the report field; its value is the output produced by that stage:
stages:
- name: Read hardware ID
kind: hardware_id
programmer: jlink_1
capture:
device.hardware_id: hardware_id
Configure jlink_1 locally with a supported target as described in Station configuration. Only explicit captures are persisted; other context outputs remain available to later stages. If this stage does not produce hardware_id, HTF records a capture warning. It does not reuse an earlier stage's output or change the hardware outcome.
An existing infuse_validation_rtt stage can capture modem outputs with this mapping; retain its programmer, transport, and test settings:
capture:
modem.imei: validation.modem.imei
sim.iccid: validation.modem.iccid
sim.imsi: validation.modem.imsi
modem.model: validation.modem.model
modem.firmware_version: validation.modem.firmware_version
The validator exports VAL fields as validation.<test>.<field> and recognises modem INFO identifiers. A MODEM PASS can verify modem values even if another subtest fails. Contradictory modem values remain unverified.
Capture in a custom stage
After reading a value from your hardware, call the stage context:
context.capture("modem.imei", imei)
context.capture("sim.iccid", iccid)
Return the usual StageResult. Captures inherit the stage's pass/fail outcome by default. Set verified=True with subtest="MODEM" only after that subtest successfully validates the value:
context.capture("modem.imei", imei, verified=True, subtest="MODEM")
Captures that inherit a failed or interrupted stage outcome remain unverified. An explicitly verified successful subtest can still contribute values when the overall stage fails or is interrupted. Conflicting values within a stage are always unverified. Use separate keys, such as bluetooth.hardware_id and modem.hardware_id, for different components or parallel lanes.
Field limits
| Item | Limit |
|---|---|
| Field key | Up to 128 characters; lowercase names such as modem.imei, with letters, digits, and underscores in each segment. Each segment starts with a letter. |
| Value | A non-empty string or integer, stored as a string; up to 512 UTF-16 code units on the server. |
| Subtest name | Up to 128 UTF-16 code units on the server. |
| Observations | Up to 64 per stage and 1,024 per run. |
Pass long identifiers and values with leading zeros as strings. ASCII characters each use one UTF-16 unit; characters such as many emoji use two. The Python runtime counts Unicode code points, so a value or subtest with those characters can pass its local length check and still exceed the server limit.
context.capture() returns False and adds a warning for an invalid value or a local limit violation; the hardware result remains intact. Identical captures with the same metadata within a stage are coalesced. Keep credentials out of captures as well as logs.
Inspect a local result
A caller of run_once() can inspect structured data directly:
report = result.report() # JSON-ready stages, observations, and warnings
values = result.captured_values # Successful values from this run
observations = result.observations
Calls without a server run ID retain captures in this local result but omit them from MQTT messages. Use a run started through HTF for production capture history.
Keep reports across disconnects
Capture-bearing messages are written to .htf-cache/report-outbox/<station-id> before upload. Keep the directory on persistent storage, writable by the station account. Listening stations retry after disconnects and restarts, with backoff from 10 seconds to 10 minutes. The station removes a report only after the server acknowledges its database commit.
Permanent rejections move to rejected/ with the original envelope and reason. The active queue holds 10,000 reports; additional messages wait in deferred/. Provide disk space for all three directories. A disk-write failure logs report_storage_failed and attempts live delivery, but that report has no durable disk copy. Captures are persisted at stage completion or interruption, rather than at every hardware read.
See DUT capture history to inspect reports, retests, and identifier changes. Follow Upgrade a station before enabling captures on an existing jig.