Skip to content

Commit 0bf9348

Browse files
Ameb8codex
andauthored
test(conformance): expand golden-frame coverage (#6)
* test(conformance): add golden CALL frame for bool and string payload Add a golden-frame conformance case for a CALL frame whose CBOR body contains an explicit boolean and a short string. This pins non-numeric scalar encoding byte-for-byte using the `set_enabled` intent with `{enabled: true, label: "ok"}` so ports can verify canonical CBOR output against the corpus. Co-Authored-By: OpenAI GPT-5.4 <noreply@openai.com> * test(conformance): add golden REPLY frame for explicit empty map Add a golden-frame conformance case for a REPLY frame whose payload is encoded as an explicit CBOR empty map. This complements the existing empty CALL coverage using a reply with `payload: {}` and `cbor_hex: "a0"` so ports verify that explicit empty reply bodies decode the same way. Co-Authored-By: OpenAI GPT-5.4 <noreply@openai.com> * test(conformance): add multi-field ERROR golden frame Add a golden-frame conformance case for an ERROR frame whose CBOR body carries multiple fields. This extends the current single-field error coverage using the `unknown` intent with `{status: 4, message: "unknown", code: 404}` so ports must preserve the full error map. Co-Authored-By: OpenAI GPT-5.4 <noreply@openai.com> * test(conformance): add EVENT golden frame for integer boundaries Add a golden-frame conformance case for an EVENT frame whose CBOR body contains unsigned integer boundary values. This pins canonical integer encoding byte-for-byte using the `motion_detected` intent with `{min: 0, max: 255}` so ports verify both single-byte and one-byte-argument unsigned forms. Co-Authored-By: OpenAI GPT-5.4 <noreply@openai.com> * test(conformance): add golden CALL frame for mixed-width sequence Add a golden-frame conformance case for a CALL frame whose sequence number uses mixed high and low bytes. This exercises big-endian sequence encoding using `seq: 0xff01` with the `set_color` intent and `{r: 255, g: 100, b: 0}` so ports cannot accidentally treat sequence bytes as little-endian. Co-Authored-By: OpenAI GPT-5.4 <noreply@openai.com> * test(conformance): assert UART wire bytes and frame CRC Extend the golden-frame conformance corpus so the optional `uart_wire_hex` and `crc16` fields are exercised by a real fixture instead of documented-only contract text. Populate both fields on `call with three small ints`, then update the reference conformance runner to assert them when present. This pins the full frame CRC as well as the COBS-wrapped UART bytes emitted by `wrap(...)`, giving ports a concrete byte-for-byte target for framing behavior in addition to the existing header and CBOR-body checks. Also sync the conformance README to the current `cbor_hex` schema and clarify that `uart_wire_hex` represents wrapped frame+CRC bytes without the trailing delimiter byte. Co-Authored-By: OpenAI GPT-5.4 <noreply@openai.com> --------- Co-authored-by: OpenAI GPT-5.4 <noreply@openai.com>
1 parent f68c451 commit 0bf9348

3 files changed

Lines changed: 67 additions & 8 deletions

File tree

tests/conformance/README.md

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,13 @@ A language-neutral set of golden-frame tests. Any DCP implementation should
44
be able to load `golden_frames.yaml` and verify that:
55

66
1. **Encode**: building a frame with the given fields produces the listed
7-
`wire_hex`.
8-
2. **Decode**: parsing the `wire_hex` reproduces the listed fields.
7+
header plus `cbor_hex`.
8+
2. **Decode**: parsing the frame bytes derived from the header and `cbor_hex`
9+
reproduces the listed fields.
910
3. **Framing**: when `uart_wire_hex` is present, COBS+CRC encoding of the
1011
frame produces those bytes; decoding them recovers the frame.
11-
4. **CRC**: `crc16` is the CRC-16/CCITT of the named bytes.
12+
4. **CRC**: when `crc16` is present, it is the CRC-16/CCITT of the frame
13+
bytes before UART wrapping.
1214

1315
The Python reference test runner is in `test_conformance.py` and can serve
1416
as a template for ports.
@@ -22,18 +24,20 @@ as a template for ports.
2224
intent: "set_brightness" # required: source string for the intent_id
2325
payload: # required: CBOR map contents
2426
level: 50.0
25-
wire_hex: "01 01 ..." # required: full DCP frame (header + cbor)
26-
uart_wire_hex: "0a 01 ..." # optional: COBS-wrapped on-the-wire bytes (no trailing 0x00)
27-
crc16: 0x29b1 # optional: CRC-16 of wire_hex bytes
27+
cbor_hex: "a1 65 ..." # required: CBOR body bytes only
28+
uart_wire_hex: "0a 01 ..." # optional: COBS-wrapped frame+CRC, no trailing 0x00
29+
crc16: 0x29b1 # optional: CRC-16 of full frame bytes
2830
```
2931
3032
Whitespace in hex is allowed and ignored. Hex is lowercase.
3133
3234
## Adding a new test
3335
3436
1. Pick a single concrete frame shape (call, reply, event, dry-run, error).
35-
2. Compute `wire_hex` from a known-good implementation.
36-
3. Where the spec is silent, prefer the simplest possible CBOR encoding (no
37+
2. Compute `cbor_hex` from a known-good implementation.
38+
3. Include `uart_wire_hex` and `crc16` when you want to pin framing and CRC
39+
behavior for that case.
40+
4. Where the spec is silent, prefer the simplest possible CBOR encoding (no
3741
indefinite-length, no tags).
3842

3943
If your implementation disagrees with a golden frame, **the golden is the

tests/conformance/golden_frames.yaml

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,13 @@
3232
value: 0.0
3333
cbor_hex: "a1 65 76 61 6c 75 65 fb 00 00 00 00 00 00 00 00"
3434

35+
- name: reply with empty-map body
36+
kind: 0x02
37+
seq: 8
38+
intent: "ping"
39+
payload: {}
40+
cbor_hex: "a0"
41+
3542
- name: dry-run call with one float
3643
kind: 0x81
3744
seq: 99
@@ -48,6 +55,16 @@
4855
status: 4
4956
cbor_hex: "a1 66 73 74 61 74 75 73 04"
5057

58+
- name: error with multi-field payload
59+
kind: 0x04
60+
seq: 13
61+
intent: "unknown"
62+
payload:
63+
status: 4
64+
message: unknown
65+
code: 404
66+
cbor_hex: "a3 66 73 74 61 74 75 73 04 67 6d 65 73 73 61 67 65 67 75 6e 6b 6e 6f 77 6e 64 63 6f 64 65 19 01 94"
67+
5168
- name: event with float payload
5269
kind: 0x03
5370
seq: 0
@@ -56,6 +73,15 @@
5673
confidence: 1.0
5774
cbor_hex: "a1 6a 63 6f 6e 66 69 64 65 6e 63 65 fb 3f f0 00 00 00 00 00 00"
5875

76+
- name: event with integer payload at boundaries
77+
kind: 0x03
78+
seq: 0
79+
intent: "motion_detected"
80+
payload:
81+
min: 0
82+
max: 255
83+
cbor_hex: "a2 63 6d 69 6e 00 63 6d 61 78 18 ff"
84+
5985
- name: call with three small ints
6086
kind: 0x01
6187
seq: 0x1234
@@ -65,6 +91,27 @@
6591
g: 100
6692
b: 0
6793
cbor_hex: "a3 61 72 18 ff 61 67 18 64 61 62 00"
94+
uart_wire_hex: "12 01 01 12 34 7a 22 a3 61 72 18 ff 61 67 18 64 61 62 03 94 ef"
95+
crc16: 0x94ef
96+
97+
- name: call with mixed-width sequence number
98+
kind: 0x01
99+
seq: 0xff01
100+
intent: "set_color"
101+
payload:
102+
r: 255
103+
g: 100
104+
b: 0
105+
cbor_hex: "a3 61 72 18 ff 61 67 18 64 61 62 00"
106+
107+
- name: call with explicit bool + string payload
108+
kind: 0x01
109+
seq: 6
110+
intent: "set_enabled"
111+
payload:
112+
enabled: true
113+
label: ok
114+
cbor_hex: "a2 67 65 6e 61 62 6c 65 64 f5 65 6c 61 62 65 6c 62 6f 6b"
68115

69116
- name: reply with bool
70117
kind: 0x02

tests/conformance/test_conformance.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,10 @@ def _build_frame(case: dict) -> bytes:
3636
return header + _hex(case.get("cbor_hex", ""))
3737

3838

39+
def _crc16_bytes(case: dict) -> bytes:
40+
return _hex(f"{int(case['crc16']):04x}")
41+
42+
3943
def load_cases() -> list[dict]:
4044
return yaml.safe_load(GOLDEN.read_text(encoding="utf-8"))
4145

@@ -90,6 +94,10 @@ def test_uart_wrap_roundtrip(case: dict):
9094
assert wire.endswith(b"\x00")
9195
assert b"\x00" not in wire[:-1]
9296
assert unwrap(wire[:-1]) == frame_bytes
97+
if "uart_wire_hex" in case:
98+
assert wire[:-1] == _hex(case["uart_wire_hex"])
99+
if "crc16" in case:
100+
assert wire[-3:-1] == _crc16_bytes(case)
93101

94102

95103
def test_intent_id_table():

0 commit comments

Comments
 (0)