OMD Conformance Tests
These tests check an Open Meet Display receiver or producer against the specification. A receiver runs groups A, B, and C; a producer runs group D. Each test has a check and an observable pass condition, so the list doubles as a test plan. A test marked must is required for conformance. One marked should is a strong recommendation, and one marked may is optional: if you do it, do it this way. A test’s id never changes, and an id the list skips is never reused.
Tools for running them:
- The message schema and the probe reply schema check shapes with any JSON Schema 2020-12 validator. They allow fields and kinds they do not define, as receivers must, so a misspelled key passes them: check your field names against the field reference.
omd-check.mjschecks a message, or a probe reply with--probe, and names the test each problem fails.- Each test that needs a crafted message names a fixture. The
fixture index lists them all with what a conforming receiver answers:
accept(200or204, and shown),ignore(200or204, and the board unchanged, which only you can see),refuse-400,refuse-422(withaccepts), oraccept-or-422(either is conforming). The test page sends them to your receiver from your browser, as a browser-based producer does.
You can run every test without us. If a test is ambiguous, that is a bug in the format: write to [email protected].
A. Messages
What a receiver does with the messages it is sent.
OMD-C1 — Every example is accepted (must)
- Check: send each example message to your receiver.
- Pass: each is answered
200or204. Each kind you show appears on the board as the message describes it; each kind you do not show changes nothing.
OMD-C2 — A message replaces what its target shows (must)
- Check: send
results-track-heat.json, thenc2-fewer-rows.omd.json, the same heat with its last row gone. - Pass: the board shows only the rows of the second message. The row that disappeared is gone from the board; rows are never merged across messages.
OMD-C3 — A kind you do not show is accepted and changes nothing (must)
- Check: send
c3-unknown-kind.omd.json, whoseomd.kindisschedule. - Pass:
200or204, and the board keeps what it showed. Refusing it would show the operator an error on every send.
OMD-C4 — A mode other than replace is accepted and changes nothing (must)
- Check: send
c4-unknown-mode.omd.json, whosedisplay.modeisappend. - Pass:
200or204, and the board keeps what it showed.
OMD-C5 — Fields you do not know are ignored (must)
- Check: send
c5-unknown-fields.omd.json, which adds fields at every level, including one prefixed with a product’s name. - Pass:
200or204, and the board shows the results exactly as it showsresults-track-heat.json.
OMD-C6 — A null field is treated as missing (must)
- Check: send
c6-nulls.omd.json, which sendsnullfor optional fields a producer would leave out. - Pass:
200or204, and the board shows what it shows when those fields are missing: nonull,None, or blank label printed.
OMD-C7 — Unknown values in open lists are shown or ignored (must)
- Check: send
c7-unknown-values.omd.json: a sport, gender, entry type, status, and scoring role this version does not define. - Pass:
200or204. Each unknown value is shown as text or ignored, and the row with the unknown status is shown without a place of its own. See Open and closed lists.
OMD-C8 — Names in any script are shown whole (must)
- Check: send
c8-utf8-names.omd.json, with names in accented Latin, Chinese, Malay, and Arabic script. - Pass:
200or204, and every name is shown as sent, without replacement characters. A name too wide for the board may be cut, never garbled.
OMD-C9 — Rows are shown in the order sent, as written (must)
- Check: send
results-xc-race.jsonandstart-list.json. - Pass: rows appear in the order of
rows, and every value (place, mark, wind, points) appears as written. The receiver does not sort, re-place, add up, or reformat them.
OMD-C10 — A later minor version is read (must)
- Check: send
c10-later-minor.omd.json, version1.7with a field 1.0 does not define. - Pass:
200or204, and the board shows it as the 1.0 message it would otherwise be.
OMD-C11 — A target you do not know is shown or refused by name (should)
- Check: send
c11-unknown-target.omd.json, whosedisplay.targetisno-such-board. - Pass: either
200or204and the message appears on your default surface, or422witherrorsnaming/display/target. Never a refusal that does not say which target.
B. HTTP POST
How a receiver answers over HTTP. The test page runs these from a browser on another origin, exactly as a browser-based producer does, so passing there proves CORS too.
OMD-C12 — The preflight is answered (must)
- Check: send
OPTIONSto your URL withOrigin,Access-Control-Request-Method: POST, andAccess-Control-Request-Headers: content-type. - Pass:
204(or200) withAccess-Control-Allow-Origin,Access-Control-Allow-MethodslistingGET,POST, andOPTIONS, andAccess-Control-Allow-HeaderslistingContent-Type.
OMD-C13 — Every reply carries the CORS header (must)
- Check: from a web page on another origin, send a message you accept, one you refuse
(
c16-not-json.txt), and the probe. - Pass: every reply, success or error, carries
Access-Control-Allow-Origin, so the browser shows the producer the status. Without it the operator sees “could not connect” for a message you received.
OMD-C14 — Allowed producers are named, with Vary: Origin (should)
- Check: set your receiver to allow
https://manager.2timer.apponly, then send the preflight and a message from that origin and from another. - Pass: the allowed origin gets
Access-Control-Allow-Origin: https://manager.2timer.appandVary: Origin; the other gets noAccess-Control-Allow-Origin.*is for testing only. See Security.
OMD-C15 — Accepted messages are answered within 5 seconds (must)
- Check: time the reply to each example and to
c3-unknown-kind.omd.json. - Pass:
200or204within 5 seconds, including for a kind you ignore. Draw after you answer, not before.
OMD-C16 — A body that is not JSON gets 400 (must)
- Check: send
c16-not-json.txtwithContent-Type: application/json. - Pass:
400, optionally with{ "errors": [{ "path": "", "message": "…" }] }, and the board keeps what it showed.
OMD-C17 — A message with no omd block gets 422 naming what you read (must)
- Check: send
c17-no-omd.omd.json, a message in the shape of a draft of this format:"format": "meet.display.v1"and noomdblock. - Pass:
422with a body whoseacceptslists the versions you read, such as["1.0"], and the board keeps what it showed.
OMD-C18 — A major you do not read gets 422 naming what you read (must)
- Check: send
c18-major-2.omd.json, version2.0. - Pass:
422withaccepts, anderrorsnaming/omd/version. The board keeps what it showed: never show half of a message from a version you do not read.
OMD-C19 — The receiver is reachable where the operator runs it (must)
- Check: run your receiver on another computer on the network, and send from a browser-based producer in Chrome at that computer’s address.
- Pass: the message arrives after the operator allows Chrome’s local-network prompt once. The
receiver listens on the network interface, not only
127.0.0.1, and its port is open in the firewall. Your documentation says the address, port, and path to enter.
C. Probe
How a receiver answers the probe: a GET on the URL it takes messages on, which a producer
sends before its first message.
OMD-C20 — The probe is answered (must)
- Check: send
GETto the URL you take messages on, from a web page on another origin. - Pass:
200with JSON that validates againstprobe-reply-v1:acceptslists1.0(or a later1.x), andgeneratorhas youridandname. The reply carriesAccess-Control-Allow-Origin.node omd-check.mjs --probe reply.jsonfinds nothing.
OMD-C21 — A probe changes nothing (must)
- Check: with a message on the board, send the probe three times.
- Pass: the board keeps what it showed, and the probes are not recorded as messages.
OMD-C22 — A receiver that is not ready says so (may)
- Check: start your receiver before its board or output is ready, and send the probe.
- Pass:
503withRetry-After, and200once it is ready. A receiver that is ready as soon as it answers never needs503.
OMD-C23 — Listed targets are ones you show (may)
- Check: read
targetsin your probe reply, and sendannouncement.jsonto each, changingdisplay.target. - Pass: each listed target shows the message on the surface it names. A target you take but do not list still works.
OMD-C24 — Your generator id never changes (should)
- Check: compare
generator.idin your probe reply across a restart and an upgrade of your product. - Pass: the same
id, a short name you picked once.nameandversionmay change;iddoes not.
D. Producer
What meet software that sends Open Meet Display does.
OMD-C25 — Every message validates (must)
- Check: capture what you send with the reference receiver
(
node omd-test-receiver.mjs --json), and runnode omd-check.mjson each message. - Pass: zero errors, for every kind you send, including a relay, a field event, and a non-finisher.
OMD-C26 — The producer probes and sends the newest version both read (must)
- Check: point your producer at the reference receiver, which answers the probe with
["1.0"], and send. - Pass: your producer sent
GETbefore its first message, and the message saysomd.version1.0. Pointed at a receiver that answersaccepts: ["2.0"]only, it sends nothing and tells the operator the receiver needs a newer version.
OMD-C27 — A receiver that does not answer the probe still gets messages (should)
- Check: run the reference receiver with
--draft, which answers the probe404, and send. - Pass: your producer still sends: the draft message that receiver was built against, or 1.0. It never refuses to send because the probe went unanswered.
OMD-C28 — Fields with no value are left out (should)
- Check: send a start list and look at the message.
- Pass: no
result,place,status, orpointskeys in a start list row, and nonullanywhere a producer has nothing to say.
OMD-C29 — Rows arrive in display order, paged to the board (must)
- Check: send results for a heat larger than the board’s rows per page.
- Pass: each message carries the rows that should be on screen now, sorted as they should appear, and no more than the board shows; the next page arrives as its own message.
OMD-C30 — The operator sets the destination (must)
- Check: open your producer’s display settings.
- Pass: the operator can enter the receiver’s address, port, path, and display target, and can test the connection. The test probes and says what answered, in words the operator understands.
