FFmpeg's progress percentage is computed on every test and asserted by none #229

Closed
opened 2026-09-06 02:53:23 +00:00 by JMR-dev · 0 comments
JMR-dev commented 2026-09-06 02:53:23 +00:00 (Migrated from github.com)

Filed from the 2026-09-05 e2e read of the instrumented suite on main @ 4b02294.

FFmpegEngine computes a progress percentage on every instrumented test that touches it, and no test on any source set ever looks at the number.

app/src/main/java/org/libremediaconverter/ffmpeg/FFmpegEngine.kt:66-71

The statistics callback runs — every FFmpegEngineTest case passes durationMs = 3_000, so the arithmetic executes — but every call site in the test suite omits the onProgress lambda, so nothing observes what it produces.

What is and is not already covered

  • #196 (49249be) covered the worker's progress lambda, and did it with a fake engine. Its own commit message says HardwareFallbackTest "reaches runMedia3OrFallBack but its recording transcoder records the call and never invokes the callback".
  • ProgressNotificationTest (JVM) covers throttling and that updates reach WorkManager, driving a fake transcoder that reports whatever the test tells it to.

So the plumbing downstream of the number is well covered. The number itself is not — nothing has ever checked that FFmpeg's Statistics.getTime() becomes a sane percentage.

Mutation: replace the computed percent with a constant, or invert it to 100 - percent. Nothing reddens in either suite.

Shape

Cheap and headless. Call FFmpegEngine.transcode with an onProgress that collects, then assert the collected list is non-empty, monotonically non-decreasing, and within 0..100.

Do not copy Media3's caveat here. Media3EngineTest deliberately declines to assert progress fired because its polling is on a 250 ms tick and a 3 s clip can finish inside one tick (E3 in docs/e2e-read-findings.md). FFmpeg's statistics callback is driven by the encoder's own frame loop, not a timer, so it fires for every processed chunk — a non-empty assertion is safe here in a way it is not there. Verify that on one leg before relying on it; if it turns out to be flaky, assert the range and monotonicity of whatever arrives and say why the emptiness check was dropped, rather than deleting the test.

Bounds

Statistics.getTime() returns a double in the committed ffmpeg-kit-next-8.1.1-runtime.jar (checked with javap), so the division is not integer-truncating and a mid-conversion sample should not read 0. Worth an explicit assertion that at least one sample is strictly between 0 and 100 — a list of [0, 100] would satisfy a naive range check while proving nothing.

_Filed from the 2026-09-05 e2e read of the instrumented suite on `main` @ `4b02294`._ `FFmpegEngine` computes a progress percentage on every instrumented test that touches it, and no test on any source set ever looks at the number. ``` app/src/main/java/org/libremediaconverter/ffmpeg/FFmpegEngine.kt:66-71 ``` The statistics callback runs — every `FFmpegEngineTest` case passes `durationMs = 3_000`, so the arithmetic executes — but **every call site in the test suite omits the `onProgress` lambda**, so nothing observes what it produces. ## What is and is not already covered - #196 (`49249be`) covered the **worker's** progress lambda, and did it with a fake engine. Its own commit message says `HardwareFallbackTest` "reaches `runMedia3OrFallBack` but its recording transcoder records the call and never invokes the callback". - `ProgressNotificationTest` (JVM) covers throttling and that updates reach WorkManager, driving a fake transcoder that reports whatever the test tells it to. So the *plumbing* downstream of the number is well covered. **The number itself is not** — nothing has ever checked that FFmpeg's `Statistics.getTime()` becomes a sane percentage. *Mutation:* replace the computed `percent` with a constant, or invert it to `100 - percent`. Nothing reddens in either suite. ## Shape Cheap and headless. Call `FFmpegEngine.transcode` with an `onProgress` that collects, then assert the collected list is non-empty, monotonically non-decreasing, and within `0..100`. **Do not copy Media3's caveat here.** `Media3EngineTest` deliberately declines to assert progress fired because its polling is on a 250 ms tick and a 3 s clip can finish inside one tick (`E3` in `docs/e2e-read-findings.md`). FFmpeg's statistics callback is driven by the encoder's own frame loop, not a timer, so it fires for every processed chunk — a non-empty assertion is safe here in a way it is not there. **Verify that on one leg before relying on it**; if it turns out to be flaky, assert the range and monotonicity of whatever arrives and say why the emptiness check was dropped, rather than deleting the test. ## Bounds `Statistics.getTime()` returns a `double` in the committed `ffmpeg-kit-next-8.1.1-runtime.jar` (checked with `javap`), so the division is not integer-truncating and a mid-conversion sample should not read `0`. Worth an explicit assertion that at least one sample is strictly between 0 and 100 — a list of `[0, 100]` would satisfy a naive range check while proving nothing.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: JMR-dev/LibreMediaConverter#229