From 5ccfec917e891e73904f9d541a864ae1ee4f416a Mon Sep 17 00:00:00 2001 From: Scott Williams Date: Fri, 28 May 2021 21:56:58 +0100 Subject: [PATCH] allow finer grained details logic on when to release the pause. --- .../Formats/Jpg/JpegDecoderTests.cs | 56 +++++++++---------- .../Formats/Jpg/JpegEncoderTests.cs | 33 ++++++----- .../Image/ImageTests.SaveAsync.cs | 19 ++----- .../TestUtilities/PausedStream.cs | 10 ++-- 4 files changed, 57 insertions(+), 61 deletions(-) diff --git a/tests/ImageSharp.Tests/Formats/Jpg/JpegDecoderTests.cs b/tests/ImageSharp.Tests/Formats/Jpg/JpegDecoderTests.cs index 1b561c20d7..478b0f3ffa 100644 --- a/tests/ImageSharp.Tests/Formats/Jpg/JpegDecoderTests.cs +++ b/tests/ImageSharp.Tests/Formats/Jpg/JpegDecoderTests.cs @@ -127,53 +127,53 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg Assert.IsType(ex.InnerException); } - [Fact] - public async Task Decode_IsCancellable() + [Theory] + [InlineData(0)] + [InlineData(0.5)] + [InlineData(0.9)] + public async Task Decode_IsCancellable(int percentageOfStreamReadToCancel) { + var cts = new CancellationTokenSource(); var file = Path.Combine(TestEnvironment.InputImagesDirectoryFullPath, TestImages.Jpeg.Baseline.Jpeg420Small); using var pausedStream = new PausedStream(file); - var cts = new CancellationTokenSource(); - - var testTask = Task.Run(async () => + pausedStream.OnWaiting(s => { - AsyncLocalSwitchableFilesystem.ConfigureFileSystemStream(pausedStream); - - return await Assert.ThrowsAsync(async () => + if (s.Position >= s.Length * percentageOfStreamReadToCancel) { - using Image image = await Image.LoadAsync("someFakeFile", cts.Token); - }); + cts.Cancel(); + pausedStream.Release(); + } + else + { + // allows this/next wait to unblock + pausedStream.Next(); + } }); - await pausedStream.FirstWaitReached; - cts.Cancel(); - - // allow testTask to try and continue now we know we have started but canceled - pausedStream.Release(); + AsyncLocalSwitchableFilesystem.ConfigureFileSystemStream(pausedStream); - await testTask; + await Assert.ThrowsAsync(async () => + { + using Image image = await Image.LoadAsync("someFakeFile", cts.Token); + }); } [Fact] public async Task Identify_IsCancellable() { - var file = Path.Combine(TestEnvironment.InputImagesDirectoryFullPath, TestImages.Jpeg.Baseline.Jpeg420Small); - using var pausedStream = new PausedStream(file); var cts = new CancellationTokenSource(); - var testTask = Task.Run(async () => + var file = Path.Combine(TestEnvironment.InputImagesDirectoryFullPath, TestImages.Jpeg.Baseline.Jpeg420Small); + using var pausedStream = new PausedStream(file); + pausedStream.OnWaiting(s => { - AsyncLocalSwitchableFilesystem.ConfigureFileSystemStream(pausedStream); - - return await Assert.ThrowsAsync(async () => await Image.IdentifyAsync("someFakeFile", cts.Token)); + cts.Cancel(); + pausedStream.Release(); }); - await pausedStream.FirstWaitReached; - cts.Cancel(); - - // allow testTask to try and continue now we know we have started but canceled - pausedStream.Release(); + AsyncLocalSwitchableFilesystem.ConfigureFileSystemStream(pausedStream); - await testTask; + await Assert.ThrowsAsync(async () => await Image.IdentifyAsync("someFakeFile", cts.Token)); } // DEBUG ONLY! diff --git a/tests/ImageSharp.Tests/Formats/Jpg/JpegEncoderTests.cs b/tests/ImageSharp.Tests/Formats/Jpg/JpegEncoderTests.cs index d7e77eabec..3c48865c71 100644 --- a/tests/ImageSharp.Tests/Formats/Jpg/JpegEncoderTests.cs +++ b/tests/ImageSharp.Tests/Formats/Jpg/JpegEncoderTests.cs @@ -315,26 +315,29 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg [InlineData(JpegSubsample.Ratio444)] public async Task Encode_IsCancellable(JpegSubsample subsample) { - using var pausedStream = new PausedStream(new MemoryStream()); var cts = new CancellationTokenSource(); - - var testTask = Task.Run(async () => + using var pausedStream = new PausedStream(new MemoryStream()); + pausedStream.OnWaiting(s => { - using var image = new Image(5000, 5000); - return await Assert.ThrowsAsync(async () => + // after some writing + if (s.Position >= 500) + { + cts.Cancel(); + pausedStream.Release(); + } + else { - var encoder = new JpegEncoder() { Subsample = subsample }; - await image.SaveAsync(pausedStream, encoder, cts.Token); - }); + // allows this/next wait to unblock + pausedStream.Next(); + } }); - await pausedStream.FirstWaitReached; - cts.Cancel(); - - // allow testTask to try and continue now we know we have started but canceled - pausedStream.Release(); - - await testTask; + using var image = new Image(5000, 5000); + await Assert.ThrowsAsync(async () => + { + var encoder = new JpegEncoder() { Subsample = subsample }; + await image.SaveAsync(pausedStream, encoder, cts.Token); + }); } } } diff --git a/tests/ImageSharp.Tests/Image/ImageTests.SaveAsync.cs b/tests/ImageSharp.Tests/Image/ImageTests.SaveAsync.cs index f34b74f899..8bb121349f 100644 --- a/tests/ImageSharp.Tests/Image/ImageTests.SaveAsync.cs +++ b/tests/ImageSharp.Tests/Image/ImageTests.SaveAsync.cs @@ -139,25 +139,16 @@ namespace SixLabors.ImageSharp.Tests var encoder = new PngEncoder() { CompressionLevel = PngCompressionLevel.BestCompression }; using var stream = new MemoryStream(); var asyncStream = new AsyncStreamWrapper(stream, () => false); - var pausedStream = new PausedStream(asyncStream); - var cts = new CancellationTokenSource(); - var testTask = Task.Run(async () => + var pausedStream = new PausedStream(asyncStream); + pausedStream.OnWaiting(s => { - AsyncLocalSwitchableFilesystem.ConfigureFileSystemStream(pausedStream); - - using var image = new Image(5000, 5000); - return await Assert.ThrowsAsync(async () => await image.SaveAsync(pausedStream, encoder, cts.Token)); + cts.Cancel(); + pausedStream.Release(); }); - await pausedStream.FirstWaitReached; - cts.Cancel(); - - // allow testTask to try and continue now we know we have started but canceled - pausedStream.Release(); - - await testTask; + await Assert.ThrowsAsync(async () => await image.SaveAsync(pausedStream, encoder, cts.Token)); } } } diff --git a/tests/ImageSharp.Tests/TestUtilities/PausedStream.cs b/tests/ImageSharp.Tests/TestUtilities/PausedStream.cs index bba4c61dc1..c6902b06a2 100644 --- a/tests/ImageSharp.Tests/TestUtilities/PausedStream.cs +++ b/tests/ImageSharp.Tests/TestUtilities/PausedStream.cs @@ -13,11 +13,13 @@ namespace SixLabors.ImageSharp.Tests.TestUtilities private readonly SemaphoreSlim slim = new SemaphoreSlim(0); private readonly CancellationTokenSource cancelationTokenSource = new CancellationTokenSource(); - private readonly TaskCompletionSource waitReached = new TaskCompletionSource(); private readonly Stream innerStream; + private Action onWaitingCallback; - public Task FirstWaitReached => this.waitReached.Task; + public void OnWaiting(Action onWaitingCallback) => this.onWaitingCallback = onWaitingCallback; + + public void OnWaiting(Action onWaitingCallback) => this.OnWaiting(_ => onWaitingCallback()); public void Release() { @@ -29,13 +31,13 @@ namespace SixLabors.ImageSharp.Tests.TestUtilities private void Wait() { - this.waitReached.TrySetResult(null); - if (this.cancelationTokenSource.IsCancellationRequested) { return; } + this.onWaitingCallback?.Invoke(this.innerStream); + try { this.slim.Wait(this.cancelationTokenSource.Token);