Everything on this page runs on one Mac with no Thunderbolt cable, no second machine, and no Apple Silicon requirement (except where noted). CI runs the first two suites on every push/PR.
Covers the wire protocol (framing, corrupt-length rejection, unknown-type
skipping, input-event encoder parity with JSONDecoder), the discovered-
receiver model (which IP is dialed per transport), connection diagnostics
(link-local interface scoping, failure-detail composition), and the
automation parsers behind targetbridge:// URLs and --connect launch args.
cd TargetBridge-Sender
xcodegen generate # only needed after changing project.yml or adding files
xcodebuild test -project TargetBridge.xcodeproj -scheme TBDisplaySender -destination 'platform=macOS'Test sources live in TargetBridge-Sender/TBDisplaySenderTests/.
Unit tests for the streaming packet parser in net.c — fragmented and
contiguous feeds, the NUL-sentinel guarantee, corrupt/oversized length
rejection, and multi-megabyte payloads fed in socket-sized chunks.
Pure POSIX: needs no ffmpeg, SDL, or pkgconf.
cd TargetBridge-Receiver/TBReceiverC
make testTest sources live in TargetBridge-Receiver/TBReceiverC/tests/.
TargetBridge-Receiver/TBReceiverC/tests/mock_sender.py (stdlib-only
Python 3) speaks the full wire protocol against a running receiver:
| Mode | What it exercises |
|---|---|
handshake |
HELLO / heartbeat / TEARDOWN lifecycle |
stream |
PARAM_SETS + AVCC H.264 frames (generated via the ffmpeg CLI) |
hang |
idle watchdog: silent sender is reaped after ~10s |
badlen |
parser rejects a corrupt 0xFFFFFFFF length and disconnects |
drop |
abrupt mid-packet disconnect returns receiver to waiting |
# terminal 1
cd TargetBridge-Receiver/TBReceiverC && make && ./tbreceiver --windowed
# terminal 2
python3 TargetBridge-Receiver/TBReceiverC/tests/mock_sender.py --mode stream --duration 5Builds the receiver, launches it windowed, and drives all mock-sender phases with pass/fail assertions on the receiver's log:
TargetBridge-Receiver/scripts/loopback_smoke.sh # full run
TargetBridge-Receiver/scripts/loopback_smoke.sh --no-stream # skip the H.264 phaseNeeds a GUI session (an SDL window opens briefly) and the receiver build
deps (brew install ffmpeg sdl2 pkgconf), so it is a local dev tool rather
than a CI job.
The receiver binds 0.0.0.0:54321 and accepts any peer, so an Apple
Silicon Mac can stream to a receiver running on itself over the LAN
interface (the sender refuses 127.0.0.1, so use the machine's own LAN IP
for both ends):
open build/TargetBridge.app # sender: pick the LAN interface, enter the Mac's own LAN IP
./tbreceiver --windowed # receiver on the same MacThis exercises the true capture → encode → decode → render path minus the Thunderbolt link itself.
The sender logs its connection lifecycle (dial target, interface, waiting/ failed states, timeouts) to unified logging:
log stream --predicate 'subsystem == "com.targetbridge.sender"'The receiver logs to stderr; under the LaunchAgent that lands in
~/Library/Logs/TargetBridgeReceiver.launchd.err.log.