Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

6 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

FaultCam

FaultCam CI

FaultCam is for developers who test software that consumes IP-camera streams. Real cameras are awkward CI dependencies: they are scarce, stateful, hard to reset, and often disappear exactly when a failure must be reproduced. FaultCam replaces that hardware dependency with a versioned YAML scenario and a small C++20 RTSP camera server, then runs a real client and judges the declared outcome automatically.

In about three minutes you can prove a normal decode, inject a disconnect/reconnect, inspect the client's observable reaction, receive an automatic PASS/FAIL result, and rerun the deterministic timeline. FaultCam is a test double; it is not an NVR, recorder, player, transcoder, general media server, full ONVIF device, or a claim to clone any particular camera.

简体中文

Three-minute demonstration

Prerequisites are CMake 3.20+, a C++20 compiler, and exactly FFmpeg 8.1.2 on PATH. The example builds the test probe as well as the product:

cmake -S . -B build -DFAULTCAM_BUILD_TESTS=ON
cmake --build build --config Release --parallel
ctest --test-dir build -C Release -R "^(ffmpeg_h264_tcp_decode|regression_disconnect_reconnect|scenario_determinism)$" --output-on-failure

Those three tests mean:

  • ffmpeg_h264_tcp_decode: unmodified FFmpeg decodes normal H.264/TCP frames and the harness checks the frame count.
  • regression_disconnect_reconnect: FaultCam closes the first media session at frame 8; the probe reconnects, receives media on connection two, and the runner evaluates all scenario assertions.
  • scenario_determinism: two independent server runs are compared after documented dynamic fields are removed.

The fault test writes JSON, JSONL, and JUnit evidence under build/regression-reports/. On PowerShell, the observable reaction and each automatic assertion can be read directly:

$r = Get-Content build/regression-reports/regression_disconnect_reconnect.json -Raw |
  ConvertFrom-Json
$r.status
$r.client_stdout
$r.events | Where-Object action -eq disconnect_reconnect
$r.assertions | Select-Object type, value, passed, detail

status: passed, FAULTCAM_PROBE_PASS action=disconnect_reconnect, a disconnect_reconnect event, and only passed: true assertions form the PASS result. Any missing reaction, wrong client exit, timeout, late reconnect, missing second-session media, or dead server makes CTest fail. Repeating the same CTest command reruns the deterministic check rather than trusting a saved report.

For an interactive normal camera:

.\build\Release\faultcam.exe serve scenarios\normal.yml --duration-ms 15000

Then decode it from another terminal:

ffmpeg -nostdin -hide_banner -v error -rtsp_transport tcp `
  -i rtsp://127.0.0.1:8554/live -t 3 -map 0:v:0 -f null -

For single-config generators on Linux, use build/faultcam instead of build/Release/faultcam.exe. The CTest commands are otherwise the same; -C Release is harmless for a single-config build.

Product boundary

The default faultcam::faultcam library and faultcam CLI own:

  • bounded YAML scenario loading and semantic validation;
  • an independent RTSP 1.0 server for OPTIONS, DESCRIBE, SETUP, PLAY, PAUSE, keepalive, and TEARDOWN;
  • interleaved TCP and UDP-unicast RTP/RTCP;
  • H.264, H.265, PCMA, PCMU, and RFC 3640 AAC fixture delivery;
  • Basic and Digest authentication;
  • deterministic protocol, packet, timestamp, RTCP, stall, disconnect, and multi-track faults;
  • a supervised client runner with dynamic-port tokens, credential redaction, stable exit codes, and JSON/JSONL/JUnit reports;
  • 37 executable, single-purpose regression scenarios: 5 normal/authentication/SDP cases plus 32 scenario-level oracles, one for each accepted fault action name or compatibility alias.

The default build exposes only serve, run, inspect, and version. It installs neither capture/ONVIF headers nor their libraries, CMake targets, scenarios, or CLI surface.

Capture import/export and ONVIF-lite are separate experimental extensions and are both OFF by default:

-DFAULTCAM_ENABLE_EXPERIMENTAL_CAPTURE=ON   # faultcam::capture; import and --pcapng
-DFAULTCAM_ENABLE_EXPERIMENTAL_ONVIF=ON     # faultcam::onvif; non-conformant ONVIF-lite

The old FAULTCAM_ENABLE_EXPERIMENTAL=ON switch remains only as a deprecated compatibility alias that enables both extensions. Experimental functionality is not part of core-v1 acceptance.

Runner contract

faultcam run starts the server on an operating-system-selected free port and expands {rtsp_url}, {rtsp_port}, {rtsp_host}, {rtsp_mount}, and {mount} independently in each client argument:

.\build\Release\faultcam.exe run `
  --scenario scenarios\regressions\25-media-stall-control-alive.yml `
  --json artifacts\demo-stall.json --jsonl artifacts\demo-stall.jsonl `
  --junit artifacts\demo-stall.xml --timeout-ms 15000 -- `
  .\build\Release\faultcam_rtsp_probe.exe "{rtsp_url}" `
  expect-action media_stall --timeout-ms 2400

Runner exit codes are 0 for all declared assertions passing, 2 for invalid command/scenario input, 3 for an assertion failure, 4 for a FaultCam internal error, and 5 for client launch/supervision failure. Capture-enabled builds additionally use 6 for rejected unsafe or unsupported imports. A client failure is a pass only when the scenario explicitly declares that result.

Verified local evidence

The current evidence record is described in docs/verification.md. Highlights from the 2026-07-26 local-only run are:

  • current default MSVC Release full inventory: 85/85 passed with 0 failures in 242.64 s, including all 37 executable regressions, all 10 fixed-FFmpeg tests, and all 3 Docker relay tests;
  • current Ubuntu 24.04 Release acceptance: 82/82 passed, comprising 35 core tests, all 37 regressions, and all 10 fixed-FFmpeg tests; the installed Linux consumer passed and both generated archives contained exactly 121 members with no forbidden or missing required content;
  • current Linux ASan and UBSan selections: 72/72 passed in each build, including all 37 regressions and 4 parser-boundary tests; all 20 inspected binaries linked the requested sanitizer runtime, with 0 ASan reports and 0 UBSan findings;
  • current local relay integrations passed with MediaMTX 1.19.1 and go2rtc 1.9.14: MediaMTX recovered its upstream and decoded 30 frames, while both go2rtc cases decoded 30 frames and the fault case proved second-connection recovery;
  • the final default/capture/ONVIF/both experimental matrix registered 72/72/72/73 tests, passed its 4/3/3/4 targeted boundary selections, and installed exactly 102/104/105/107 files with only the enabled optional surfaces present;
  • the final default Windows package installed 102 files; its ZIP and TGZ each contained the same 102 files in 121 total members, and the installed-package consumer passed with package registries disabled and explicit FaultCam_DIR discovery;
  • the current strict 30-minute normal soak passed 60/60 verifier assertions after 1,831.248 s wall clock, decoding 18,238 frames over 1,823.7 media seconds with 184 samples, 41,948 RTP packets, 1,217 RTCP packets, and clean natural shutdown;
  • the current reconnect soak passed 25/25 cycles over 50 connections in 90.499 s, with at least 30 second-connection RTP packets per cycle and a maximum server reconnect delay of 31 ms;
  • the current 2-camera/4-client, TCP/UDP, H.264/H.265 benchmark decoded 601 frames per client over 60 media seconds, sustained all four clients concurrently for 61.678 s, and recorded 4,954 RTP plus 168 RTCP packets;
  • the CI and release workflows are wired to the real core, FFmpeg, relay, sanitizer, installed-consumer, and package commands, and all corresponding local-equivalent commands passed. The separate public publication run for commit 673d24f also passed all five hosted CI jobs: GitHub Actions run 30290820645.

These are version- and source-specific artifacts, not timeless certification. The Ubuntu, sanitizer, reconnect-soak, and benchmark reruns share source fingerprint 899553aa19c2a14ed4fec4dacc6ade798895e6e1033916f11a1ba18b9ccacb11; the 30-minute harness records its bounded source subset as a5e23d4995ccd8764c3b32e2d623eff442ba806c6f8cc5281dd200cf9918330c. Current limitations and the standalone source-only repository audit are explicit in docs/limitations.md and docs/v1-audit.md.

Documentation

Build, install, and consume

cmake -S . -B build -DFAULTCAM_BUILD_TESTS=ON
cmake --build build --config Release --parallel
ctest --test-dir build -C Release --output-on-failure
cmake --install build --config Release --prefix install

The installed default package exports faultcam::faultcam. Feature builds additionally export faultcam::capture and/or faultcam::onvif. The verified default Windows ZIP/TGZ and Ubuntu ZIP/TGZ records are listed in docs/verification.md; archives should always be regenerated and inspected again after later source or documentation changes.

Safety and license

The default bind is 127.0.0.1. Use synthetic credentials and an explicit private test address only when remote access is genuinely required; never expose FaultCam to the public Internet. See docs/threat-model.md.

FaultCam is Apache-2.0 licensed. Dependency and test-asset notices are in THIRD_PARTY_NOTICES.md.

About

Scenario-driven RTSP virtual camera for reproducible audio/video failure testing.

Topics

Resources

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages