You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Only Gzip checks that async compression output is byte-identical to sync; Deflate, ZLib, Brotli and AES have no such test (async-surface spec) #83
A fake-async implementation reaches for the synchronous path and throws; a genuine one passes. This
is deterministic and machine-independent. Each converted provider gets:
1. An `AsyncOnlyStream` test proving it never touches the synchronous members.
2. A round-trip test asserting the async path produces byte-identical output to the sync path.
3. A cancellation test asserting an already-cancelled token is honoured before work begins.
An AsyncOnlyStream test proving it never touches the synchronous members.
A round-trip test asserting the async path produces byte-identical output to the sync path.
A cancellation test asserting an already-cancelled token is honoured before work begins.
Items 1 and 3 are covered for every converted provider. Item 2 is covered for Gzip only: GzipAsyncCompression_ProducesTheSameBytesAsTheSynchronousPathAsync (Essentials.Tests/AsyncStreamIoTests.cs:75).
The other converted providers have only round trips:
Deflate, ZLib and Brotli.CompressionProvider_RoundTripsThroughAsyncOnlyStreamsAsync, which runs over StreamingCompressionProviders.
Elsewhere.ProviderContractTests and RoundTripTests also only round-trip the async path back to the original.
Why it matters
A round trip only shows that async compress and async decompress agree with each other. It does not show that the async path emits the same stream as the sync path. Two kinds of divergence would pass every current test while producing output the sync path, or another consumer, may not accept:
a different compression level, or a missing final flush or footer, as long as the async decompressor tolerates it;
an AES async path that writes the IV or padding differently from TryEncrypt.
Data written by TryCompressAsync and later read through the synchronous API is exactly the case the spec's byte-identity test exists to protect.
Acceptance criteria
A [DynamicData] test over Deflate, ZLib and Brotli, mirroring the Gzip one. For a fixed payload, the bytes TryCompressAsync writes into an AsyncOnlyStream equal the bytes the synchronous TryCompress produces.
An AES test with a fixed key and IV. The bytes TryEncryptAsync writes into an AsyncOnlyStream equal the synchronous TryEncrypt output.
Optionally, the Gzip-specific test folds into the parameterised one.
Test-only change, tagged [patch].
Dependencies
None. Release 1 of the spec has shipped (PR #14 and PR #15), and this closes its remaining test gap. Release 2, the ValueTask migration, is tracked under #8.
Category: Improvement (test coverage gap against the async-surface spec)
Priority: Low. This is a test-only change and no misbehaviour has been observed. It guards against a silent sync/async output divergence, though, so it is worth doing before the Release 2 ValueTask migration (Most async methods are Task.Run wrappers, not genuine async I/O #8) touches these code paths again.
Suggested area / assignment:Essentials.Tests/AsyncStreamIoTests.cs, compression and encryption providers
Already in progress: No open PR references this issue.
Recommended next step: Parameterise the Gzip byte-identity test with [DynamicData] over Deflate, ZLib and Brotli. Add an AES fixed-key/IV test comparing TryEncryptAsync against TryEncrypt. Tag the change [patch].
Activity
matt-edmondson commentedon Oct 6, 2026
Triage
ValueTaskmigration (Most async methods are Task.Run wrappers, not genuine async I/O #8) touches these code paths again.Essentials.Tests/AsyncStreamIoTests.cs, compression and encryption providersRecommended next step: Parameterise the Gzip byte-identity test with
[DynamicData]over Deflate, ZLib and Brotli. Add an AES fixed-key/IV test comparingTryEncryptAsyncagainstTryEncrypt. Tag the change[patch].Generated by Claude Code