This document describes Honeymelon's FFmpeg pipeline test infrastructure, including the test media corpus, the regression test harness, and how these are integrated into CI.
The FFmpeg pipeline test system ensures that:
- Normal media files are probed and converted successfully
- Edge cases (vertical video, audio-only, etc.) are handled correctly
- Known-bad files (corrupted, truncated, fake) fail gracefully with proper error classification
- No panics or unwrapped errors escape to the user
Test media files are located in test-media/ at the repository root:
test-media/
├── normal/ # Standard files that should work
│ ├── h264_aac_1080p.mp4 # H.264 + AAC, 1080p
│ ├── h264_aac_4k.mp4 # H.264 + AAC, 4K
│ ├── hevc_720p.mp4 # HEVC/H.265, 720p
│ ├── vp9_opus.webm # VP9 + Opus, WebM
│ ├── audio_stereo.mp3 # MP3 audio
│ ├── audio_lossless.flac # FLAC audio
│ ├── audio_pcm.wav # WAV audio
│ ├── image_test.png # PNG image
│ ├── image_photo.jpg # JPEG image
│ └── image_web.webp # WebP image
├── edge-cases/ # Unusual but valid files
│ ├── video_no_audio.mp4 # Video-only (no audio track)
│ ├── vertical_video.mp4 # Portrait orientation (720x1280)
│ ├── square_video.mp4 # Square aspect ratio (500x500)
│ └── audio_only.m4a # Audio-only M4A
└── known-bad/ # Files that should fail gracefully
├── zero_bytes.mp4 # Empty file (0 bytes)
├── random_data.mp4 # Random binary data
├── truncated.mp4 # Truncated MP4 file
└── text_as_mp4.mp4 # Plain text renamed as .mp4
Test media files are generated using FFmpeg's test sources. To regenerate them:
# From repository root
npm run download-ffmpeg # Ensure FFmpeg is available
# Generate normal files
src-tauri/bin/ffmpeg -y -f lavfi -i "testsrc=duration=1:size=1920x1080:rate=30" \
-f lavfi -i "sine=frequency=440:duration=1" \
-c:v libx264 -preset ultrafast -crf 28 \
-c:a aac -b:a 64k \
test-media/normal/h264_aac_1080p.mp4
# See test-media generation commands in src-tauri/tests/ffmpeg_pipeline.rs-
Install Node.js dependencies:
npm ci
-
Download FFmpeg binaries:
npm run download-ffmpeg
-
Verify FFmpeg is working:
src-tauri/bin/ffmpeg -version src-tauri/bin/ffprobe -version
cd src-tauri
cargo test --all-featurescd src-tauri
# Run all pipeline tests with output
cargo test --test ffmpeg_pipeline -- --nocapture
# Run specific test categories
cargo test --test ffmpeg_pipeline normal -- --nocapture # Normal files
cargo test --test ffmpeg_pipeline edge_case -- --nocapture # Edge cases
cargo test --test ffmpeg_pipeline known_bad -- --nocapture # Known-bad files
cargo test --test ffmpeg_pipeline full_pipeline -- --nocapture # End-to-end testWhen tests pass, you'll see output like:
Testing: normal/h264_aac_1080p.mp4
[OK] Probe OK: 1920x1080, 1.00s, video=h264, audio=aac
Testing: known-bad/random_data.mp4
[OK] Failed gracefully as expected
Full Pipeline Test: probe > convert > validate
Step 1: Probing input...
[OK] Probe OK: 1920x1080, 1.00s
Step 2: Validating input streams...
[OK] Input has video and audio
Step 3: Converting (transcode)...
[OK] Conversion completed: 67179 bytes
Step 4: Validating output...
[OK] Output validated: 1920x1080, 1.02s
Full pipeline test PASSED
test result: ok. 16 passed; 0 failed
The rust-check job runs on every PR and push to main/develop:
- Download FFmpeg binaries via
npm run download-ffmpeg - Verify FFmpeg binaries are present and executable
- Run Clippy for Rust linting
- Run Rust unit tests (
cargo test --lib) - Run Rust integration tests (
cargo test --tests) - Run FFmpeg pipeline regression tests (
cargo test --test ffmpeg_pipeline)
If any step fails, the entire CI fails and blocks the PR.
The pre-release-checks job runs before any release build:
- All linting and formatting checks
- Frontend tests with coverage
- Rust tests including FFmpeg pipeline regression tests
- FFmpeg binary verification
If pipeline tests fail, the release is blocked.
If FFmpeg pipeline tests fail in CI:
- GitHub Actions > Click the failed job
- Look for the step "Run FFmpeg pipeline regression tests"
- The output shows:
- Which file failed
- Whether it was expected to succeed or fail
- The error category (InputProblem, UnsupportedCombination, etc.)
Example failure output:
Testing: normal/h264_aac_1080p.mp4
assertion failed: Probe failed for normal/h264_aac_1080p.mp4: Some("Invalid data found")
Tests that standard media files:
- Probe successfully with correct stream detection
- Convert (remux) successfully
- Transcode successfully
- Produce valid output files
Tests that unusual but valid files:
- Video-only files (no audio) are detected correctly
- Vertical/portrait videos have correct dimensions
- Square videos have equal width/height
- Audio-only containers are handled
Tests that invalid files:
- Zero-byte files fail with
InputProblem - Random binary data fails gracefully
- Truncated files fail with proper error classification
- Non-media files renamed as media fail gracefully
When files fail, they should be classified into:
| Category | Description |
|---|---|
InputProblem |
File is corrupted, unsupported, or unreadable |
UnsupportedCombination |
Codec/container combination not supported |
ResourceIssue |
Disk full, permissions, I/O errors |
InternalPipelineError |
Bug in Honeymelon's argument construction |
Timeout |
Conversion exceeded time limit |
Cancelled |
User cancelled the job |
Unknown |
Unclassified error |
To add a new test file to the corpus:
- Add the file to the appropriate
test-media/subdirectory - Update
src-tauri/tests/ffmpeg_pipeline.rsto include the new file - Run tests locally to verify
- Commit both the test file and test code changes
Example for adding a new edge case:
#[test]
fn edge_case_new_format_probes_correctly() {
if !check_ffmpeg_available() || !check_test_media_available() {
eprintln!("⚠ Skipping test: Dependencies not available");
return;
}
let path = test_media_dir().join("edge-cases/new_format.mkv");
let result = probe_file(&path);
assert!(result.success, "Probe failed: {:?}", result.error);
// Add specific assertions...
}This means either FFmpeg binaries or test media files are missing:
npm run download-ffmpeg # Get FFmpeg
# Ensure test-media/ directory exists with filesIf test media files are missing (e.g., after a fresh clone), generate them:
# Quick generation script - see test-media section abovenpm run download-ffmpeg
ls -la src-tauri/bin/ # Should show ffmpeg and ffprobe- Check that test-media/ is committed to the repository
- Verify the CI workflow downloads FFmpeg before running tests
- Check for platform-specific issues (tests run on macOS in CI)