Browse Source

allow finer grained details logic on when to release the pause.

pull/1644/head
Scott Williams 5 years ago
parent
commit
5ccfec917e
  1. 56
      tests/ImageSharp.Tests/Formats/Jpg/JpegDecoderTests.cs
  2. 33
      tests/ImageSharp.Tests/Formats/Jpg/JpegEncoderTests.cs
  3. 19
      tests/ImageSharp.Tests/Image/ImageTests.SaveAsync.cs
  4. 10
      tests/ImageSharp.Tests/TestUtilities/PausedStream.cs

56
tests/ImageSharp.Tests/Formats/Jpg/JpegDecoderTests.cs

@ -127,53 +127,53 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg
Assert.IsType<InvalidMemoryOperationException>(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<TaskCanceledException>(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<TaskCanceledException>(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<TaskCanceledException>(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<TaskCanceledException>(async () => await Image.IdentifyAsync("someFakeFile", cts.Token));
}
// DEBUG ONLY!

33
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<Rgba32>(5000, 5000);
return await Assert.ThrowsAsync<TaskCanceledException>(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<Rgba32>(5000, 5000);
await Assert.ThrowsAsync<TaskCanceledException>(async () =>
{
var encoder = new JpegEncoder() { Subsample = subsample };
await image.SaveAsync(pausedStream, encoder, cts.Token);
});
}
}
}

19
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<Rgba32>(5000, 5000);
return await Assert.ThrowsAsync<TaskCanceledException>(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<TaskCanceledException>(async () => await image.SaveAsync(pausedStream, encoder, cts.Token));
}
}
}

10
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<object> waitReached = new TaskCompletionSource<object>();
private readonly Stream innerStream;
private Action<Stream> onWaitingCallback;
public Task FirstWaitReached => this.waitReached.Task;
public void OnWaiting(Action<Stream> 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);

Loading…
Cancel
Save