microsoft / microsoft/winappCli
Flaky test: Mp4SinkWriterEncoder_RealEncoderCoversValidationAndSuccessfulComplete intermittently fails with MF_E_SINK_NO_SAMPLES_PROCESSED
- Dominant language
- C#
- Stars
- 1.3k
- Forks
- 80
- Avg merge
- 3d 6h
- Merged PRs (30d)
- 51
Description
### Describe the bug
`Mp4SinkWriterEncoderTests.Mp4SinkWriterEncoder_RealEncoderCoversValidationAndSuccessfulComplete` intermittently fails in CI when the real Media Foundation H.264 encoder produces no output samples for a single-frame encode.
Seen on `main` in [run 34433989038](https://github.com/microsoft/winappCli/actions/runs/34433989038) (commit `8c62f868`), 1 failure out of 5409 tests:
```
failed Mp4SinkWriterEncoder_RealEncoderCoversValidationAndSuccessfulComplete (2s 884ms)
Test method WinApp.Cli.Tests.Mp4SinkWriterEncoderTests.Mp4SinkWriterEncoder_RealEncoderCoversValidationAndSuccessfulComplete threw exception:
System.Runtime.InteropServices.COMException: The operation failed because no samples were processed by the sink. (0xC00D4A44)
at ...IMFSinkWriter.Finalize()
at ...Mp4SinkWriterEncoder.Complete() in src/winapp-CLI/WinApp.UIAutomation.Recording/Mp4SinkWriterEncoder.cs:264
at WinApp.Cli.Tests.Mp4SinkWriterEncoderTests...() in src/winapp-CLI/WinApp.Cli.Tests/Mp4SinkWriterEncoderTests.cs:67
```
`0xC00D4A44` is `MF_E_SINK_NO_SAMPLES_PROCESSED`.
**Cause.** The test encodes exactly **one** 64×64 frame and then immediately calls `Complete()`, which calls `IMFSinkWriter.Finalize()`:
```csharp
encoder.WriteFrame(Enumerable.Repeat((byte)0x22, 64 * 64 * 4).ToArray(), 0, 10_000_000);
encoder.Complete();
```
H.264 MFTs buffer input, so a single frame can legitimately reach `Finalize()` before any compressed sample has reached the media sink. Whether it passes depends on which H.264 encoder MFT the host resolves and how it buffers, which makes it host-dependent rather than deterministic.
**This is a test-robustness problem, not a product bug.** In the real recording path, `UiRecordingService` already wraps `encoder.Complete()` in a `catch (Exception ex) when (IsRecoverableVideoOutputFailure(ex))`, and that predicate matches `ExternalException`, which `COMException` derives from. So `winapp ui record` degrades gracefully; only this unit test calls `Complete()` unguarded.
### To Reproduce
Not deterministically reproducible by design — it depends on the H.264 encoder MFT available on the host.
1. Run `dotnet test src/winapp-CLI/WinApp.Cli.Tests --filter "ClassName~Mp4SinkWriterEncoderTests"` repeatedly, or let CI run `main`.
2. On a host whose H.264 MFT buffers the single input frame past `Finalize()`, the test throws `COMException (0xC00D4A44)`.
Observed frequency on CI: 1 occurrence in [run 34433989038](https://github.com/microsoft/winappCli/actions/runs/34433989038); the two following `main` runs (`122a6592`, `4a2776ca`) both passed with the same code, so it is intermittent rather than a regression. `Mp4SinkWriterEncoder.cs` has not changed since #799 (2026-09-02).
### Expected behavior
The test should deterministically exercise encoder argument validation and a successful `Complete()`/publish, without depending on how a particular host's H.264 MFT buffers a single frame.
Suggested fix: write enough frames that the encoder must emit at least one compressed sample before finalizing (a short run of frames at the configured fps rather than exactly one). That preserves everything the test currently covers — the `expected 16384` short-buffer `ArgumentException`, the idempotent second `Complete()`, and the atomic publish assertions — while removing the single-frame dependency.
Tolerating `MF_E_SINK_NO_SAMPLES_PROCESSED` as inconclusive would also make CI green, but it would hollow out the assertion that a completed MP4 is actually published, so it is not preferred.
### OS Version and details
`windows-latest` GitHub-hosted runner (CI); .NET 10 SDK.
Contributor guide
No contributing guide indexed for this repository
Research direction
Start with Mp4SinkWriterEncoderTests.cs, especially Mp4SinkWriterEncoder_RealEncoderCoversValidationAndSuccessfulComplete, and run the filtered test command from the issue. Replace the single-frame setup with enough frames to ensure a compressed sample is produced before Complete(), while retaining the validation, idempotent completion, and atomic publish assertions.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- csharp
- Domain
- testing-qa
- Issue type
- Bug
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 86/100