using qdr.fnd.core.pqueue.Configuration;
using qdr.fnd.core.pqueue.Enums;
using qdr.fnd.core.pqueue.Exceptions;
using qdr.fnd.core.pqueue.Storages;
using qdr.fnd.core.pqueue.test.Mocks;
using qdr.fnd.core.pqueue.test.Process.Mock;
using Quadarax.Foundation.Core.Logging;
using Quadarax.Foundation.Core.Value.Generators;
namespace qdr.fnd.core.pqueue.test
{
///
/// Complex test class for .
///
public class PsQueueTest
{
#region *** Queue Fields ***
private string _queueName;
private ILogger? _logger;
private PsQueueConfiguration? _configuration;
private IPsQueueStorage? _storageProvider;
#endregion
#region *** Queue Item Fields ***
private string _id = "id";
private string _owner = "owner";
private string _ownerRef = "ownerRef";
private string _providerClass = "providerClass";
private DateTime _created = DateTime.Now;
private PsStatusEnum _status = PsStatusEnum.New;
private bool _statusTrancient = false;
private string _statusMessage = "message";
private int _attemptsLeft = 3;
private TinyHash _hash = new TinyHash();
private IDictionary> _ItemStatuses = new Dictionary>();
#endregion
[SetUp]
public void Setup()
{
_queueName = "queueName";
_logger = new LoggerMock();
_configuration = new PsQueueConfiguration();
_storageProvider = new MemoryStorageProvider(_logger);
_providerClass = typeof(PsProcessProviderBaseMock).AssemblyQualifiedName!;
}
[Test(TestOf=typeof(PsQueue))]
public void ConstructorOk()
{
var queue = CreateQueue();
Assert.IsFalse(queue.IsRunning);
}
[Test(TestOf=typeof(PsQueue))]
public void ConstructorFail()
{
Assert.Throws(() => new PsQueueMock(string.Empty, _configuration!, _storageProvider!, _logger!));
Assert.Throws(() => new PsQueueMock(_queueName, null!, _storageProvider!, _logger!));
Assert.Throws(() => new PsQueueMock(_queueName, _configuration!, null!, _logger!));
}
[Test(TestOf=typeof(PsQueue))]
public void ValidateItemIdOk()
{
var queue = CreateQueue();
queue.TestValidateItemId("aaa");
}
[Test(TestOf=typeof(PsQueue))]
public void ValidateItemIdFail()
{
var queue = CreateQueue();
Assert.Throws(() => queue.TestValidateItemId(string.Empty));
Assert.Throws(() => queue.TestValidateItemId(null!));
}
[Test(TestOf=typeof(PsQueue))]
public void ValidateEmitterOk()
{
var queue = CreateQueue();
queue.TestValidateEmitter("aaa");
}
[Test(TestOf=typeof(PsQueue))]
public void ValidateEmitterFail()
{
var queue = CreateQueue();
Assert.Throws(() => queue.TestValidateEmitter(string.Empty));
Assert.Throws(() => queue.TestValidateEmitter(null!));
}
[Test(TestOf=typeof(PsQueue))]
public void ValidateItemOk()
{
var queue = CreateQueue();
var item = CreateQueueItem(_id);
queue.TestValidateItem(item);
}
[Test(TestOf=typeof(PsQueue))]
public void ValidateItemFail()
{
var queue = CreateQueue();
var item = CreateQueueItem(_id);
Assert.Throws(()=>queue.TestValidateItem(null!));
item.SetOwner(string.Empty, string.Empty);
var e = Assert.Throws(()=>queue.TestValidateItem(item));
Assert.That(e.Code, Is.EqualTo(PSQueueValidationException.ErrorCodes.OwnerRequired));
item.SetOwner(_owner, string.Empty);
e = Assert.Throws(()=>queue.TestValidateItem(item));
Assert.That(e.Code, Is.EqualTo(PSQueueValidationException.ErrorCodes.OwnerRefRequired));
item.SetOwner(_owner, _ownerRef);
item.ClearArguments();
Assert.Throws(() => queue.TestValidateItem(item));
}
[Test(TestOf=typeof(PsQueue))]
public void SetItemStatusInternalOk()
{
var queue = CreateQueue();
var item = CreateQueueItem(_id);
item.AddToStorage(queue.Storage);
var testStatus = PsStatusEnum.Pending;
var initStatus = item.Status;
Assert.That(item.Status, Is.Not.EqualTo(testStatus));
queue.TestSetItemStatusInternal(item, testStatus, false, _owner);
var changedItem = queue.Storage.GetItem(item.Id);
Assert.That(changedItem.Status, Is.EqualTo(testStatus));
Assert.That(changedItem.IsStatusTransient, Is.EqualTo(false));
Assert.That(_ItemStatuses[changedItem.Id].LastOrDefault(), Is.EqualTo(testStatus));
Assert.That(changedItem.StatusJournal.Count, Is.EqualTo(1));
Assert.That(changedItem.StatusJournal.FirstOrDefault()?.PreviousStatus, Is.EqualTo(initStatus));
queue.TestSetItemStatusInternal(item, null, true, _owner);
changedItem = queue.Storage.GetItem(item.Id);
Assert.That(changedItem.Status, Is.EqualTo(testStatus));
Assert.That(changedItem.IsStatusTransient, Is.EqualTo(true));
Assert.That(_ItemStatuses[changedItem.Id].LastOrDefault(), Is.EqualTo(testStatus));
Assert.That(changedItem.StatusJournal.Count, Is.EqualTo(2));
Assert.That(changedItem.StatusJournal.LastOrDefault()?.PreviousIsStatusTransient, Is.EqualTo(false));
Assert.That(changedItem.StatusJournal.LastOrDefault()?.PreviousStatus, Is.EqualTo(testStatus));
}
[Test(TestOf=typeof(PsQueue))]
public void SetItemStatusInternalFail()
{
var queue = CreateQueue();
var item = CreateQueueItem(_id);
item.AddToStorage(queue.Storage);
var testStatus = PsStatusEnum.DoneOk;
var initStatus = item.Status;
Assert.That(item.Status, Is.Not.EqualTo(testStatus));
var e1 = Assert.Throws(()=>queue.TestSetItemStatusInternal(item, null, false, _owner));
Assert.That(e1.Code, Is.EqualTo(PSQueueValidationException.ErrorCodes.InvalidStatusTransientCombination));
e1 = Assert.Throws(()=>queue.TestSetItemStatusInternal(item, PsStatusEnum.DoneOk, false, _owner));
Assert.That(e1.Code, Is.EqualTo(PSQueueValidationException.ErrorCodes.InvalidStatusTransition));
}
[Test(TestOf=typeof(PsQueue))]
public void ResolveProviderOk()
{
var queue = CreateQueue();
var arguments = PsProcessProviderBaseMock.CreateArguments();
var provider = queue.TestResolveProvider(_id, _providerClass, arguments);
Assert.That(provider, Is.Not.Null);
Assert.That(provider.ItemId, Is.EqualTo(_id));
Assert.That(provider.IsRunning, Is.EqualTo(false));
Assert.That(provider.Arguments.Values.Select(x=>x.Name), Is.EquivalentTo(arguments.Select(x=>x.Name)));
Assert.That(provider.Arguments.Values.Select(x=>x.Value), Is.EquivalentTo(arguments.Select(x=>x.Value)));
Assert.That(provider.Arguments.Values.Select(x=>x.ValueType), Is.EquivalentTo(arguments.Select(x=>x.ValueType)));
}
[Test(TestOf=typeof(PsQueue))]
public void ResolveProviderFail()
{
var queue = CreateQueue();
var arguments = PsProcessProviderBaseMock.CreateArguments();
var e1 = Assert.Throws(()=>queue.TestResolveProvider(_id, null!, arguments));
Assert.That(e1.Code, Is.EqualTo(PSQueueValidationException.ErrorCodes.ProcessProviderRequired));
e1 = Assert.Throws(()=>queue.TestResolveProvider(_id, string.Empty, arguments));
Assert.That(e1.Code, Is.EqualTo(PSQueueValidationException.ErrorCodes.ProcessProviderRequired));
e1 = Assert.Throws(()=>queue.TestResolveProvider(string.Empty, "aaa", arguments));
Assert.That(e1.Code, Is.EqualTo(PSQueueValidationException.ErrorCodes.ProcessProviderCannotResolve));
e1 = Assert.Throws(()=>queue.TestResolveProvider(string.Empty, _providerClass, arguments));
Assert.That(e1.Code, Is.EqualTo(PSQueueValidationException.ErrorCodes.ProcessProviderCannotResolve));
}
private PsQueueMock CreateQueue()
{
var ps = new PsQueueMock(_queueName, _configuration!, _storageProvider!, _logger!);
ps.ProcessItemStatusChanged += OnProcessItemStatusChanged;
return ps;
}
private void OnProcessItemStatusChanged(IPsQueue sender, PsQueueStatusChangedEventArgs e)
{
TestContext.WriteLine($"#StaChg: ItemId={e.ProcessQueueItemId}; newStatus={e.CurrentStatus}; isTransient='{e.CurrentIsStatusTransient}'");
if (_ItemStatuses.ContainsKey(e.ProcessQueueItemId))
_ItemStatuses[e.ProcessQueueItemId].Add(e.CurrentStatus);
else
_ItemStatuses.Add(e.ProcessQueueItemId, new List { e.CurrentStatus });
}
private PsQueueItemMock CreateQueueItem(string id)
{
var item = new PsQueueItemMock(id, _owner,_ownerRef,_providerClass,_created, PsProcessProviderBaseMock.CreateArguments(), _attemptsLeft);
return item;
}
}
}