Skip to main content

The gNB Contract

Racora acts on the gNB through interfaces, never through its internals. The controller renders its configuration, drives it over its command WebSocket, seeds its O1 datastore and reads its telemetry; the platform only runs the image. Any image built from OCUDU that holds the lines below works with Racora: upstream OCUDU, CNS OCUDU, or another distribution of it, whatever base image or transport it is built on.

A new image is brought in as a candidate: an intake run builds it from a source ref or takes a published tag, every integration suite installs it, and a pin change makes it the one releases ship (Release Process). The table is what that run checks.

InterfaceWhat Racora relies onChecked by
The command WebSocket (port 8001 on every plane)The CU-CP commands cell_lock, cell_unlock, cell_bar, cell_unbar, cell_status, mobility_cell_set, mobility_cell_remove, mobility_neighbor_add, mobility_neighbor_remove, mobility_report_config_set, mobility_report_config_remove, mobility_periodic_report_set, trigger_handover, trigger_conditional_handover; the DU command pci_set; metrics_subscribe; a reply of {"cmd", "result"} or {"error"} with the rejection strings of Runtime Commandstest/ws-contract/matrix.jsonl, run by test/ws-contract-integration.sh; controller/tests/test_cucp_ws_client.py
The configurationThe YAML the controller renders parses and boots the planes: a DU's gnb_id, gnb_id_bit_length, gnb_du_id, cell_cfg, ru_sdr / ru_dummy / ru_ofh, f1ap, f1u, log, pcap, metrics, remote_control; the CU-CP overlay's gnb_id, gnb_id_bit_length, ran_node_name, cu_cp.amf, cu_cp.mobility, cu_cp.cells, max_nof_dustest/platform-integration.sh and test/telemetry-integration.sh (the planes come up on it in k3d); controller/tests/test_config_generator.py
F1, E1 and NGA DU's F1 Setup is accepted with the identity the controller declares (its NCI decodes to the CU-CP's gNB-Id); the CU-UP's E1; NG Setup with the network identitytest/lib/ran-assertions.sh and test/lib/core-assertions.sh in the k3d suites; the cell's DUServed condition on a running network
O1The 3GPP NRM with the OCUDU extensions: the controller's configuration seeds it and the adapter renders it back unchanged, the leaves the models make mandatory (gNBId, gNBIdLength, gNBCUName) carrying the controller's valuestest/check-o1-seed-roundtrip.py (CI job o1-seed-roundtrip); test/lib/o1-assertions.sh
TelemetryRANN-P JSON lines (rann_p_v2); a cucp.<cmd>.execute span per command, parented by the WebSocket traceparent; OTLP logs carrying trace ids; the log markers the dashboards read; the O1 PM stream namessidecars/rann-p-forwarder/tests/golden/rann_p_v2.jsonl (diffed against the gNB's copy by cross-repo-guards); test/telemetry-integration.sh; test/check-dashboard-markers.py; test/check-o1-dashboards.py
The imagegnb, ocucp, ocuup and odu on the path; file capabilities cap_sys_nice, cap_ipc_lock, cap_perfmon grantable; F1-C 38472, E1 38462, NG 38412, the WebSocket 8001, GTP-U 2152 and 2153; nothing beyond sh builtins (the probes walk /proc/net/sctp/eps)test/helm-gates.sh; the readiness of every plane in the k3d suites; gnb --version in the intake build

Changing the Contract​

An interface changes the way everything else here does: the test first, the line in this table in the same change, and a candidate run of the pinned gNB to see whether the stable image still holds it. test/gnb-contract-gate.py keeps the table and the tests in step: every path in the last column must exist, and every contract check must be named here. Adding an interface adds a test and a line; retiring one removes both, so nothing can still depend on it unseen.