64 lines
2.5 KiB
C#
64 lines
2.5 KiB
C#
using WxAgent.Core;
|
|
using Xunit;
|
|
|
|
namespace WxAgent.Core.Tests;
|
|
|
|
public sealed class InterprocessCommandGateTests
|
|
{
|
|
[Fact]
|
|
public async Task SeparateInstancesShareAnExclusiveLease()
|
|
{
|
|
var path = Path.Combine(Path.GetTempPath(), "wx-gate-" + Guid.NewGuid(), "commands.lock");
|
|
try
|
|
{
|
|
using var first = new InterprocessCommandGate(path);
|
|
using var second = new InterprocessCommandGate(path);
|
|
using var timeout = new CancellationTokenSource(TimeSpan.FromSeconds(5));
|
|
await first.WaitAsync(timeout.Token);
|
|
var waiting = second.WaitAsync(timeout.Token);
|
|
Assert.False(waiting.IsCompleted);
|
|
first.Release();
|
|
await waiting;
|
|
second.Release();
|
|
}
|
|
finally { Directory.Delete(Path.GetDirectoryName(path)!, recursive: true); }
|
|
}
|
|
|
|
[Fact]
|
|
public async Task CancelledContentionDoesNotPoisonTheLocalQueue()
|
|
{
|
|
var path = Path.Combine(Path.GetTempPath(), "wx-gate-" + Guid.NewGuid(), "commands.lock");
|
|
try
|
|
{
|
|
using var first = new InterprocessCommandGate(path);
|
|
using var second = new InterprocessCommandGate(path);
|
|
using var timeout = new CancellationTokenSource(TimeSpan.FromSeconds(5));
|
|
await first.WaitAsync(timeout.Token);
|
|
using var cancelled = new CancellationTokenSource(TimeSpan.FromMilliseconds(100));
|
|
await Assert.ThrowsAnyAsync<OperationCanceledException>(() => second.WaitAsync(cancelled.Token));
|
|
first.Release();
|
|
await second.WaitAsync(timeout.Token);
|
|
second.Release();
|
|
}
|
|
finally { Directory.Delete(Path.GetDirectoryName(path)!, recursive: true); }
|
|
}
|
|
|
|
[Fact]
|
|
public async Task NonContentionIoErrorsAreNotRetried()
|
|
{
|
|
var path = Path.Combine(Path.GetTempPath(), "wx-gate-" + Guid.NewGuid(), "commands.lock");
|
|
Directory.CreateDirectory(path); // A directory cannot be opened as the lock file.
|
|
try
|
|
{
|
|
using var gate = new InterprocessCommandGate(path);
|
|
using var timeout = new CancellationTokenSource(TimeSpan.FromSeconds(5));
|
|
var error = await Record.ExceptionAsync(() => gate.WaitAsync(timeout.Token));
|
|
Assert.True(error is IOException or UnauthorizedAccessException);
|
|
Directory.Delete(path);
|
|
await gate.WaitAsync(timeout.Token);
|
|
gate.Release();
|
|
}
|
|
finally { Directory.Delete(Path.GetDirectoryName(path)!, recursive: true); }
|
|
}
|
|
}
|