349 lines
8.0 KiB
C#
349 lines
8.0 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Reflection;
|
|
using System.Threading.Tasks;
|
|
|
|
namespace AMWD.Common.Tests.Utilities
|
|
{
|
|
[TestClass]
|
|
public class AsyncQueueTest
|
|
{
|
|
public TestContext TestContext { get; set; }
|
|
|
|
private Queue<TestElement> _internalQueue;
|
|
|
|
private TestElement _queueElement1;
|
|
private TestElement _queueElement2;
|
|
private TestElement _queueElement3;
|
|
|
|
[TestInitialize]
|
|
public void InitializeTest()
|
|
{
|
|
_queueElement1 = new TestElement
|
|
{
|
|
Number = 111,
|
|
Text = "one"
|
|
};
|
|
_queueElement2 = new TestElement
|
|
{
|
|
Number = 222,
|
|
Text = "two"
|
|
};
|
|
_queueElement3 = new TestElement
|
|
{
|
|
Number = 333,
|
|
Text = "three"
|
|
};
|
|
|
|
_internalQueue = new Queue<TestElement>();
|
|
_internalQueue.Enqueue(_queueElement1);
|
|
_internalQueue.Enqueue(_queueElement2);
|
|
_internalQueue.Enqueue(_queueElement3);
|
|
}
|
|
|
|
[TestMethod]
|
|
public void ShouldEnqueueItem()
|
|
{
|
|
// arrange
|
|
var element = new TestElement { Number = 1, Text = "Hello" };
|
|
|
|
_internalQueue.Clear();
|
|
var queue = GetQueue();
|
|
|
|
// act
|
|
queue.Enqueue(element);
|
|
|
|
// assert
|
|
Assert.HasCount(1, _internalQueue);
|
|
Assert.AreEqual(_internalQueue.Count, queue.Count);
|
|
}
|
|
|
|
[TestMethod]
|
|
public void ShouldEnqueueItemAndResetAvailableToken()
|
|
{
|
|
// arrange
|
|
var element = new TestElement { Number = 1, Text = "Hello" };
|
|
bool available = false;
|
|
|
|
_internalQueue.Clear();
|
|
var queue = GetQueue();
|
|
|
|
// act
|
|
var task = Task.Run(async () =>
|
|
{
|
|
await queue.WaitAsync(TestContext.CancellationToken);
|
|
available = true;
|
|
}, TestContext.CancellationToken);
|
|
queue.Enqueue(element);
|
|
task.Wait(TestContext.CancellationToken);
|
|
|
|
// assert
|
|
Assert.IsTrue(available);
|
|
}
|
|
|
|
[TestMethod]
|
|
public void ShouldEnqueueItemAndResetDequeueToken()
|
|
{
|
|
// arrange
|
|
var element = new TestElement { Number = 1, Text = "Hello" };
|
|
TestElement callback = null;
|
|
|
|
_internalQueue.Clear();
|
|
var queue = GetQueue();
|
|
|
|
// act
|
|
var task = Task.Run(async () =>
|
|
{
|
|
callback = await queue.DequeueAsync(TestContext.CancellationToken);
|
|
}, TestContext.CancellationToken);
|
|
queue.Enqueue(element);
|
|
task.Wait(TestContext.CancellationToken);
|
|
|
|
// assert
|
|
Assert.IsNotNull(callback);
|
|
Assert.AreEqual(element, callback);
|
|
}
|
|
|
|
[TestMethod]
|
|
public void ShouldEnqueueMultipleItems()
|
|
{
|
|
// arrange
|
|
var elements = new TestElement[]
|
|
{
|
|
new() { Number = 1, Text = "Hello" },
|
|
new() { Number = 2, Text = "World" },
|
|
};
|
|
_internalQueue.Clear();
|
|
var queue = GetQueue();
|
|
|
|
// act
|
|
queue.Enqueue(elements);
|
|
|
|
// assert
|
|
Assert.HasCount(2, _internalQueue);
|
|
Assert.HasCount(queue.Count, _internalQueue);
|
|
}
|
|
|
|
[TestMethod]
|
|
public void ShouldPeekAValue()
|
|
{
|
|
// arrange
|
|
var queue = GetQueue();
|
|
|
|
// act
|
|
bool isSuccess = queue.TryPeek(out var item);
|
|
|
|
// assert
|
|
Assert.IsTrue(isSuccess);
|
|
Assert.IsNotNull(item);
|
|
Assert.AreEqual(_queueElement1, item);
|
|
Assert.AreEqual(3, queue.Count);
|
|
}
|
|
|
|
[TestMethod]
|
|
public void ShouldNotPeekAValue()
|
|
{
|
|
// arrange
|
|
_internalQueue.Clear();
|
|
var queue = GetQueue();
|
|
|
|
// act
|
|
bool isSuccess = queue.TryPeek(out var item);
|
|
|
|
// assert
|
|
Assert.IsFalse(isSuccess);
|
|
Assert.IsNull(item);
|
|
}
|
|
|
|
[TestMethod]
|
|
public void ShouldDequeueAValue()
|
|
{
|
|
// arrange
|
|
var queue = GetQueue();
|
|
|
|
// act
|
|
bool isSuccess = queue.TryDequeue(out var item);
|
|
|
|
// assert
|
|
Assert.IsTrue(isSuccess);
|
|
Assert.IsNotNull(item);
|
|
Assert.AreEqual(_queueElement1, item);
|
|
Assert.AreEqual(2, queue.Count);
|
|
}
|
|
|
|
[TestMethod]
|
|
public void ShouldNotDequeueAValue()
|
|
{
|
|
// arrange
|
|
_internalQueue.Clear();
|
|
var queue = GetQueue();
|
|
|
|
// act
|
|
bool isSuccess = queue.TryDequeue(out var item);
|
|
|
|
// assert
|
|
Assert.IsFalse(isSuccess);
|
|
Assert.IsNull(item);
|
|
}
|
|
|
|
[TestMethod]
|
|
public void ShouldRemoveAValue()
|
|
{
|
|
// arrange
|
|
var queue = GetQueue();
|
|
|
|
// act
|
|
queue.Remove(_queueElement2);
|
|
var item1 = queue.Dequeue();
|
|
var item2 = queue.Dequeue();
|
|
|
|
// assert
|
|
Assert.AreEqual(0, queue.Count);
|
|
Assert.AreEqual(_queueElement1, item1);
|
|
Assert.AreEqual(_queueElement3, item2);
|
|
}
|
|
|
|
[TestMethod]
|
|
public void ShouldNotRemoveAValue()
|
|
{
|
|
// arrange
|
|
var queue = GetQueue();
|
|
|
|
// act
|
|
queue.Remove(null);
|
|
var item1 = queue.Dequeue();
|
|
var item2 = queue.Dequeue();
|
|
var item3 = queue.Dequeue();
|
|
|
|
// assert
|
|
Assert.AreEqual(0, queue.Count);
|
|
Assert.AreEqual(_queueElement1, item1);
|
|
Assert.AreEqual(_queueElement2, item2);
|
|
Assert.AreEqual(_queueElement3, item3);
|
|
}
|
|
|
|
[TestMethod]
|
|
public async Task ShouldAwaitOneDequeue()
|
|
{
|
|
// arrange
|
|
_internalQueue.Clear();
|
|
var queue = GetQueue();
|
|
|
|
var task = Task.Run(async () =>
|
|
{
|
|
await Task.Delay(1000, TestContext.CancellationToken);
|
|
queue.Enqueue([_queueElement1, _queueElement2, _queueElement3]);
|
|
}, TestContext.CancellationToken);
|
|
|
|
// act
|
|
var item = await queue.DequeueAsync(TestContext.CancellationToken);
|
|
|
|
// assert
|
|
Assert.AreEqual(2, queue.Count);
|
|
Assert.IsNotNull(item);
|
|
Assert.AreEqual(_queueElement1, item);
|
|
}
|
|
|
|
[TestMethod]
|
|
public async Task ShouldAwaitManyDequeue()
|
|
{
|
|
// arrange
|
|
_internalQueue.Clear();
|
|
var queue = GetQueue();
|
|
|
|
var task = Task.Run(async () =>
|
|
{
|
|
await Task.Delay(1000, TestContext.CancellationToken);
|
|
queue.Enqueue([_queueElement1, _queueElement2, _queueElement3]);
|
|
}, TestContext.CancellationToken);
|
|
|
|
// act
|
|
var items = await queue.DequeueManyAsync(2, TestContext.CancellationToken);
|
|
|
|
// assert
|
|
Assert.AreEqual(1, queue.Count);
|
|
Assert.IsNotNull(items);
|
|
Assert.HasCount(2, items);
|
|
Assert.AreEqual(_queueElement1, items[0]);
|
|
Assert.AreEqual(_queueElement2, items[1]);
|
|
}
|
|
|
|
[TestMethod]
|
|
public async Task ShouldAwaitAllDequeue()
|
|
{
|
|
// arrange
|
|
_internalQueue.Clear();
|
|
var queue = GetQueue();
|
|
|
|
var task = Task.Run(async () =>
|
|
{
|
|
await Task.Delay(1000, TestContext.CancellationToken);
|
|
queue.Enqueue([_queueElement1, _queueElement2, _queueElement3]);
|
|
}, TestContext.CancellationToken);
|
|
|
|
// act
|
|
var items = await queue.DequeueAvailableAsync(cancellationToken: TestContext.CancellationToken);
|
|
|
|
// assert
|
|
Assert.AreEqual(0, queue.Count);
|
|
Assert.IsNotNull(items);
|
|
Assert.HasCount(3, items);
|
|
Assert.AreEqual(_queueElement1, items[0]);
|
|
Assert.AreEqual(_queueElement2, items[1]);
|
|
Assert.AreEqual(_queueElement3, items[2]);
|
|
}
|
|
|
|
[TestMethod]
|
|
public async Task ShouldAwaitAvailableDequeue()
|
|
{
|
|
// arrange
|
|
_internalQueue.Clear();
|
|
var queue = GetQueue();
|
|
|
|
var task = Task.Run(async () =>
|
|
{
|
|
await Task.Delay(1000, TestContext.CancellationToken);
|
|
queue.Enqueue([_queueElement1, _queueElement2, _queueElement3]);
|
|
}, TestContext.CancellationToken);
|
|
|
|
// act
|
|
var items = await queue.DequeueAvailableAsync(2, TestContext.CancellationToken);
|
|
|
|
// assert
|
|
Assert.AreEqual(1, queue.Count);
|
|
Assert.IsNotNull(items);
|
|
Assert.HasCount(2, items);
|
|
Assert.AreEqual(_queueElement1, items[0]);
|
|
Assert.AreEqual(_queueElement2, items[1]);
|
|
}
|
|
|
|
[TestMethod]
|
|
public async Task ShouldThrowArumentOutOfRangeException()
|
|
{
|
|
// arrange
|
|
_internalQueue.Clear();
|
|
var queue = GetQueue();
|
|
|
|
// act & assert
|
|
await Assert.ThrowsExactlyAsync<ArgumentOutOfRangeException>(() => queue.DequeueManyAsync(-2, TestContext.CancellationToken));
|
|
}
|
|
|
|
private AsyncQueue<TestElement> GetQueue()
|
|
{
|
|
var asyncQueue = new AsyncQueue<TestElement>();
|
|
|
|
var field = asyncQueue.GetType().GetField("_queue", BindingFlags.Instance | BindingFlags.NonPublic);
|
|
field.SetValue(asyncQueue, _internalQueue);
|
|
|
|
return asyncQueue;
|
|
}
|
|
|
|
private class TestElement
|
|
{
|
|
public int Number { get; set; }
|
|
|
|
public string Text { get; set; }
|
|
}
|
|
}
|
|
}
|