From 112b114805211ddcda31972a8791955b86e1ae87 Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Mon, 5 Dec 2022 00:24:06 +0100 Subject: [PATCH] with BufferedReadStream decoder cancellation works for all decoders, we can test it globally --- .../Formats/Jpg/JpegDecoderTests.cs | 81 ------------------- .../Image/ImageTests.Decode_Cancellation.cs | 62 +++++++++++--- 2 files changed, 49 insertions(+), 94 deletions(-) diff --git a/tests/ImageSharp.Tests/Formats/Jpg/JpegDecoderTests.cs b/tests/ImageSharp.Tests/Formats/Jpg/JpegDecoderTests.cs index 906c3b818a..a545f8542f 100644 --- a/tests/ImageSharp.Tests/Formats/Jpg/JpegDecoderTests.cs +++ b/tests/ImageSharp.Tests/Formats/Jpg/JpegDecoderTests.cs @@ -251,87 +251,6 @@ public partial class JpegDecoderTests Assert.IsType(ex.InnerException); } - private static readonly TestFile CancellationTestFile = TestFile.Create(TestImages.Jpeg.Baseline.Jpeg420Small); - - public static readonly TheoryData CancellationData = new() - { - { false, 0 }, - { false, 0.5 }, - { false, 0.9 }, - { true, 0 }, - { true, 0.5 }, - { true, 0.9 }, - }; - - [Theory] - [MemberData(nameof(CancellationData))] - public async Task DecodeAsync_IsCancellable(bool useMemoryStream, double percentageOfStreamReadToCancel) - { - CancellationTokenSource cts = new(); - using IPausedStream pausedStream = useMemoryStream ? - new PausedMemoryStream(CancellationTestFile.Bytes) : - new PausedStream(CancellationTestFile.FullPath); - - pausedStream.OnWaiting(s => - { - if (s.Position >= s.Length * percentageOfStreamReadToCancel) - { - cts.Cancel(); - pausedStream.Release(); - } - else - { - pausedStream.Next(); - } - }); - - Configuration configuration = Configuration.CreateDefaultInstance(); - configuration.FileSystem = new SingleStreamFileSystem((Stream)pausedStream); - DecoderOptions options = new() - { - Configuration = configuration - }; - - TimeSpan testTimeout = TimeSpan.FromSeconds(10); - - await Assert.ThrowsAnyAsync(async () => - { - using Image image = await Image.LoadAsync(options, "someFakeFile", cts.Token); - }).WaitAsync(testTimeout); - } - - [Theory] - [MemberData(nameof(CancellationData))] - public async Task Identify_IsCancellable(bool useMemoryStream, double percentageOfStreamReadToCancel) - { - CancellationTokenSource cts = new(); - using IPausedStream pausedStream = useMemoryStream ? - new PausedMemoryStream(CancellationTestFile.Bytes) : - new PausedStream(CancellationTestFile.FullPath); - - pausedStream.OnWaiting(s => - { - if (s.Position >= s.Length * percentageOfStreamReadToCancel) - { - cts.Cancel(); - pausedStream.Release(); - } - else - { - pausedStream.Next(); - } - }); - - Configuration configuration = Configuration.CreateDefaultInstance(); - configuration.FileSystem = new SingleStreamFileSystem((Stream)pausedStream); - DecoderOptions options = new() - { - Configuration = configuration - }; - - await Assert.ThrowsAnyAsync(async () => await Image.IdentifyAsync(options, "someFakeFile", cts.Token)); - } - [Theory] [WithFileCollection(nameof(UnsupportedTestJpegs), PixelTypes.Rgba32)] public void ThrowsNotSupported_WithUnsupportedJpegs(TestImageProvider provider) diff --git a/tests/ImageSharp.Tests/Image/ImageTests.Decode_Cancellation.cs b/tests/ImageSharp.Tests/Image/ImageTests.Decode_Cancellation.cs index 7b1897cda0..c93831491f 100644 --- a/tests/ImageSharp.Tests/Image/ImageTests.Decode_Cancellation.cs +++ b/tests/ImageSharp.Tests/Image/ImageTests.Decode_Cancellation.cs @@ -16,16 +16,47 @@ public partial class ImageTests public Decode_Cancellation() => this.TopLevelConfiguration.StreamProcessingBufferSize = 128; - private static readonly string TestFile = Path.Combine(TestEnvironment.InputImagesDirectoryFullPath, TestImages.Bmp.Car); + private static TheoryData GetTestData() + { + string[] testFileForEachCodec = new[] + { + TestImages.Png.BikeSmall, + TestImages.Jpeg.Baseline.Jpeg420Small, + TestImages.Bmp.Car, + TestImages.Tiff.RgbUncompressed, + TestImages.Gif.Kumin, + TestImages.Tga.Bit32PalRleBottomLeft, + TestImages.Webp.TestPatternOpaqueSmall, + TestImages.Pbm.GrayscaleBinaryWide + }; + + double[] percentages = new[] { 0, 0.5, 0.9 }; + + TheoryData data = new(); + + foreach (string file in testFileForEachCodec) + { + foreach (double p in percentages) + { + data.Add(false, file, p); + data.Add(true, file, p); + } + } + + return data; + } - public static readonly TheoryData Percentages = new() { 0, 0.5, 0.9 }; + public static TheoryData TestData { get; } = GetTestData(); [Theory] - [MemberData(nameof(Percentages))] - public async Task IdentifyAsync_IsCancellable(double percentageOfStreamReadToCancel) + [MemberData(nameof(TestData))] + public async Task IdentifyAsync_IsCancellable(bool useMemoryStream, string file, double percentageOfStreamReadToCancel) { CancellationTokenSource cts = new(); - using PausedStream pausedStream = new(TestFile); + using IPausedStream pausedStream = useMemoryStream ? + new PausedMemoryStream(TestFile.Create(file).Bytes) : + new PausedStream(TestFile.GetInputFileFullPath(file)); + pausedStream.OnWaiting(s => { if (s.Position >= s.Length * percentageOfStreamReadToCancel) @@ -40,21 +71,26 @@ public partial class ImageTests }); Configuration configuration = Configuration.CreateDefaultInstance(); - configuration.FileSystem = new SingleStreamFileSystem(pausedStream); + configuration.FileSystem = new SingleStreamFileSystem((Stream)pausedStream); DecoderOptions options = new() { Configuration = configuration }; - await Assert.ThrowsAsync(async () => await Image.IdentifyAsync(options, "someFakeFile", cts.Token)); + await Assert.ThrowsAnyAsync( + async () => await Image.IdentifyAsync(options, "someFakeFile", cts.Token)) + .WaitAsync(TimeSpan.FromSeconds(10)); } [Theory] - [MemberData(nameof(Percentages))] - public async Task LoadAsync_IsCancellable(double percentageOfStreamReadToCancel) + [MemberData(nameof(TestData))] + public async Task LoadAsync_IsCancellable(bool useMemoryStream, string file, double percentageOfStreamReadToCancel) { CancellationTokenSource cts = new(); - using PausedStream pausedStream = new(TestFile); + using IPausedStream pausedStream = useMemoryStream ? + new PausedMemoryStream(TestFile.Create(file).Bytes) : + new PausedStream(TestFile.GetInputFileFullPath(file)); + pausedStream.OnWaiting(s => { if (s.Position >= s.Length * percentageOfStreamReadToCancel) @@ -69,16 +105,16 @@ public partial class ImageTests }); Configuration configuration = Configuration.CreateDefaultInstance(); - configuration.FileSystem = new SingleStreamFileSystem(pausedStream); + configuration.FileSystem = new SingleStreamFileSystem((Stream)pausedStream); DecoderOptions options = new() { Configuration = configuration }; - await Assert.ThrowsAsync(async () => + await Assert.ThrowsAnyAsync(async () => { using Image image = await Image.LoadAsync(options, "someFakeFile", cts.Token); - }); + }).WaitAsync(TimeSpan.FromSeconds(10)); } protected override Stream CreateStream() => this.TestFormat.CreateAsyncSemaphoreStream(this.notifyWaitPositionReachedSemaphore, this.continueSemaphore, this.isTestStreamSeekable);