Solution restructured to use multiple test projects
This commit is contained in:
350
test/AMWD.Common.Tests/Utilities/AsyncQueueTest.cs
Normal file
350
test/AMWD.Common.Tests/Utilities/AsyncQueueTest.cs
Normal file
@@ -0,0 +1,350 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace AMWD.Common.Tests.Utilities
|
||||
{
|
||||
[TestClass]
|
||||
public class AsyncQueueTest
|
||||
{
|
||||
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.AreEqual(1, _internalQueue.Count);
|
||||
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();
|
||||
available = true;
|
||||
});
|
||||
queue.Enqueue(element);
|
||||
task.Wait();
|
||||
|
||||
// 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();
|
||||
});
|
||||
queue.Enqueue(element);
|
||||
task.Wait();
|
||||
|
||||
// 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.AreEqual(2, _internalQueue.Count);
|
||||
Assert.AreEqual(queue.Count, _internalQueue.Count);
|
||||
}
|
||||
|
||||
[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);
|
||||
queue.Enqueue(new[] { _queueElement1, _queueElement2, _queueElement3 });
|
||||
});
|
||||
|
||||
// act
|
||||
var item = await queue.DequeueAsync();
|
||||
|
||||
// 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);
|
||||
queue.Enqueue(new[] { _queueElement1, _queueElement2, _queueElement3 });
|
||||
});
|
||||
|
||||
// act
|
||||
var items = await queue.DequeueManyAsync(2);
|
||||
|
||||
// assert
|
||||
Assert.AreEqual(1, queue.Count);
|
||||
Assert.IsNotNull(items);
|
||||
Assert.AreEqual(2, items.Length);
|
||||
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);
|
||||
queue.Enqueue(new[] { _queueElement1, _queueElement2, _queueElement3 });
|
||||
});
|
||||
|
||||
// act
|
||||
var items = await queue.DequeueAvailableAsync();
|
||||
|
||||
// assert
|
||||
Assert.AreEqual(0, queue.Count);
|
||||
Assert.IsNotNull(items);
|
||||
Assert.AreEqual(3, items.Length);
|
||||
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);
|
||||
queue.Enqueue(new[] { _queueElement1, _queueElement2, _queueElement3 });
|
||||
});
|
||||
|
||||
// act
|
||||
var items = await queue.DequeueAvailableAsync(2);
|
||||
|
||||
// assert
|
||||
Assert.AreEqual(1, queue.Count);
|
||||
Assert.IsNotNull(items);
|
||||
Assert.AreEqual(2, items.Length);
|
||||
Assert.AreEqual(_queueElement1, items[0]);
|
||||
Assert.AreEqual(_queueElement2, items[1]);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
[ExpectedException(typeof(ArgumentOutOfRangeException))]
|
||||
public async Task ShouldThrowArumentOutOfRangeException()
|
||||
{
|
||||
// arrange
|
||||
_internalQueue.Clear();
|
||||
var queue = GetQueue();
|
||||
|
||||
// act
|
||||
await queue.DequeueManyAsync(-2);
|
||||
|
||||
// assert - ArgumentOutOfRangeException expected
|
||||
Assert.Fail();
|
||||
}
|
||||
|
||||
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; }
|
||||
}
|
||||
}
|
||||
}
|
||||
635
test/AMWD.Common.Tests/Utilities/CryptographyHelperTest.cs
Normal file
635
test/AMWD.Common.Tests/Utilities/CryptographyHelperTest.cs
Normal file
@@ -0,0 +1,635 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text.RegularExpressions;
|
||||
using AMWD.Common.Tests.Utils;
|
||||
|
||||
namespace UnitTests.Common.Utilities
|
||||
{
|
||||
[TestClass]
|
||||
public partial class CryptographyHelperTests
|
||||
{
|
||||
private string _keyFile;
|
||||
private CryptographyHelper _cryptoHelper;
|
||||
|
||||
[TestInitialize]
|
||||
public void Initialize()
|
||||
{
|
||||
_keyFile = Path.GetTempFileName();
|
||||
_cryptoHelper = new CryptographyHelper(_keyFile);
|
||||
}
|
||||
|
||||
[TestCleanup]
|
||||
public void Cleanup()
|
||||
{
|
||||
File.Delete(_keyFile);
|
||||
}
|
||||
|
||||
#region Static
|
||||
|
||||
#region Encryption
|
||||
|
||||
#region AES
|
||||
|
||||
[TestMethod]
|
||||
public void ShouldEncryptAesWithoutSalt() // required to test the encryption itself
|
||||
{
|
||||
// arrange
|
||||
using var _ = CryptographyHelperSaltMock.Create(0);
|
||||
|
||||
byte[] bytes = [0xaf, 0xfe];
|
||||
string str = "ABC";
|
||||
string password1 = "P@ssw0rd!";
|
||||
string password2 = "P@ssw0rd";
|
||||
|
||||
byte[] expectedBytes = [0x7c, 0x7b, 0x77, 0x56, 0x91, 0x1a, 0xd9, 0xc0, 0x72, 0x70, 0x36, 0x88, 0x9f, 0xb4, 0xb5, 0xbc];
|
||||
|
||||
// act
|
||||
byte[] cipherBytes1 = CryptographyHelper.AesEncrypt(bytes, password1);
|
||||
string cipherStr1 = CryptographyHelper.AesEncrypt(str, password1);
|
||||
byte[] cipherBytes2 = CryptographyHelper.AesEncrypt(bytes, password2);
|
||||
string cipherStr2 = CryptographyHelper.AesEncrypt(str, password2);
|
||||
|
||||
// assert
|
||||
CollectionAssert.AreEqual(expectedBytes, cipherBytes1);
|
||||
Assert.AreEqual("ueLuhFNpCuYmx8v3hczHtg==", cipherStr1);
|
||||
|
||||
CollectionAssert.AreNotEqual(expectedBytes, cipherBytes2);
|
||||
Assert.AreNotEqual("ueLuhFNpCuYmx8v3hczHtg==", cipherStr2);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void ShouldDecryptAesWithoutSalt() // required to test the decryption itself
|
||||
{
|
||||
// arrange
|
||||
using var _ = CryptographyHelperSaltMock.Create(0);
|
||||
|
||||
string cipherStr = "ueLuhFNpCuYmx8v3hczHtg==";
|
||||
byte[] cipherBytes = [0x7c, 0x7b, 0x77, 0x56, 0x91, 0x1a, 0xd9, 0xc0, 0x72, 0x70, 0x36, 0x88, 0x9f, 0xb4, 0xb5, 0xbc];
|
||||
|
||||
string password1 = "P@ssw0rd!";
|
||||
string password2 = "P@ssw0rd";
|
||||
|
||||
byte[] expectedBytes = [0xaf, 0xfe];
|
||||
|
||||
// act
|
||||
byte[] plainBytes1 = CryptographyHelper.AesDecrypt(cipherBytes, password1);
|
||||
string plainStr1 = CryptographyHelper.AesDecrypt(cipherStr, password1);
|
||||
|
||||
try
|
||||
{
|
||||
CryptographyHelper.AesDecrypt(cipherBytes, password2);
|
||||
Assert.Fail();
|
||||
}
|
||||
catch (CryptographicException)
|
||||
{ }
|
||||
|
||||
try
|
||||
{
|
||||
CryptographyHelper.AesDecrypt(cipherStr, password2);
|
||||
Assert.Fail();
|
||||
}
|
||||
catch (CryptographicException)
|
||||
{ }
|
||||
|
||||
// assert
|
||||
CollectionAssert.AreEqual(expectedBytes, plainBytes1);
|
||||
Assert.AreEqual("ABC", plainStr1);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void ShouldEncryptDecryptAesBytes()
|
||||
{
|
||||
// arrange
|
||||
byte[] plain = [0xaf, 0xfe];
|
||||
string password = "P@ssw0rd!";
|
||||
|
||||
// act
|
||||
byte[] cipher1 = CryptographyHelper.AesEncrypt(plain, password);
|
||||
byte[] cipher2 = CryptographyHelper.AesEncrypt(plain, password);
|
||||
|
||||
byte[] plain1 = CryptographyHelper.AesDecrypt(cipher1, password);
|
||||
byte[] plain2 = CryptographyHelper.AesDecrypt(cipher2, password);
|
||||
|
||||
// assert
|
||||
CollectionAssert.AreNotEqual(cipher1, cipher2);
|
||||
Assert.AreEqual(24, cipher1.Length);
|
||||
Assert.AreEqual(24, cipher2.Length);
|
||||
CollectionAssert.AreEqual(plain, plain1);
|
||||
CollectionAssert.AreEqual(plain, plain2);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void ShouldEncryptDecryptAesString()
|
||||
{
|
||||
// arrange
|
||||
string plain = "ABC";
|
||||
string password = "P@ssw0rd!";
|
||||
|
||||
// act
|
||||
string cipher1 = CryptographyHelper.AesEncrypt(plain, password);
|
||||
string cipher2 = CryptographyHelper.AesEncrypt(plain, password);
|
||||
|
||||
string plain1 = CryptographyHelper.AesDecrypt(cipher1, password);
|
||||
string plain2 = CryptographyHelper.AesDecrypt(cipher2, password);
|
||||
|
||||
// assert
|
||||
Assert.AreNotEqual(cipher1, cipher2);
|
||||
Assert.AreEqual(32, cipher1.Length);
|
||||
Assert.AreEqual(32, cipher2.Length);
|
||||
Assert.AreEqual(plain, plain1);
|
||||
Assert.AreEqual(plain, plain2);
|
||||
}
|
||||
|
||||
#endregion AES
|
||||
|
||||
#region TripleDES
|
||||
|
||||
[TestMethod]
|
||||
public void ShouldEncryptTdesWithoutSalt() // required to test the encryption itself
|
||||
{
|
||||
// arrange
|
||||
using var _ = CryptographyHelperSaltMock.Create(0);
|
||||
|
||||
byte[] bytes = [0xaf, 0xfe];
|
||||
string str = "ABC";
|
||||
string password1 = "P@ssw0rd!";
|
||||
string password2 = "P@ssw0rd";
|
||||
|
||||
byte[] expectedBytes = [0xbf, 0x59, 0x1f, 0x48, 0x69, 0xab, 0x18, 0xc7];
|
||||
|
||||
// act
|
||||
byte[] cipherBytes1 = CryptographyHelper.TripleDesEncrypt(bytes, password1);
|
||||
string cipherStr1 = CryptographyHelper.TripleDesEncrypt(str, password1);
|
||||
byte[] cipherBytes2 = CryptographyHelper.TripleDesEncrypt(bytes, password2);
|
||||
string cipherStr2 = CryptographyHelper.TripleDesEncrypt(str, password2);
|
||||
|
||||
// assert
|
||||
CollectionAssert.AreEqual(expectedBytes, cipherBytes1);
|
||||
Assert.AreEqual("1l74soBuuEI=", cipherStr1);
|
||||
|
||||
CollectionAssert.AreNotEqual(expectedBytes, cipherBytes2);
|
||||
Assert.AreNotEqual("1l74soBuuEI=", cipherStr2);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void ShouldDecryptTdesWithoutSalt() // required to test the decryption itself
|
||||
{
|
||||
// arrange
|
||||
using var _ = CryptographyHelperSaltMock.Create(0);
|
||||
|
||||
string cipherStr = "1l74soBuuEI=";
|
||||
byte[] cipherBytes = [0xbf, 0x59, 0x1f, 0x48, 0x69, 0xab, 0x18, 0xc7];
|
||||
|
||||
string password1 = "P@ssw0rd!";
|
||||
string password2 = "P@ssw0rd";
|
||||
|
||||
byte[] expectedBytes = [0xaf, 0xfe];
|
||||
|
||||
// act
|
||||
byte[] plainBytes1 = CryptographyHelper.TripleDesDecrypt(cipherBytes, password1);
|
||||
string plainStr1 = CryptographyHelper.TripleDesDecrypt(cipherStr, password1);
|
||||
|
||||
try
|
||||
{
|
||||
CryptographyHelper.TripleDesDecrypt(cipherBytes, password2);
|
||||
Assert.Fail();
|
||||
}
|
||||
catch (CryptographicException)
|
||||
{ }
|
||||
|
||||
try
|
||||
{
|
||||
CryptographyHelper.TripleDesDecrypt(cipherStr, password2);
|
||||
Assert.Fail();
|
||||
}
|
||||
catch (CryptographicException)
|
||||
{ }
|
||||
|
||||
// assert
|
||||
CollectionAssert.AreEqual(expectedBytes, plainBytes1);
|
||||
Assert.AreEqual("ABC", plainStr1);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void ShouldEncryptDecryptTdesBytes()
|
||||
{
|
||||
// arrange
|
||||
byte[] plain = [0xaf, 0xfe];
|
||||
string password = "P@ssw0rd!";
|
||||
|
||||
// act
|
||||
byte[] cipher1 = CryptographyHelper.TripleDesEncrypt(plain, password);
|
||||
byte[] cipher2 = CryptographyHelper.TripleDesEncrypt(plain, password);
|
||||
|
||||
byte[] plain1 = CryptographyHelper.TripleDesDecrypt(cipher1, password);
|
||||
byte[] plain2 = CryptographyHelper.TripleDesDecrypt(cipher2, password);
|
||||
|
||||
// assert
|
||||
CollectionAssert.AreNotEqual(cipher1, cipher2);
|
||||
Assert.AreEqual(16, cipher1.Length);
|
||||
Assert.AreEqual(16, cipher2.Length);
|
||||
CollectionAssert.AreEqual(plain, plain1);
|
||||
CollectionAssert.AreEqual(plain, plain2);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void ShouldEncryptDecryptTdesString()
|
||||
{
|
||||
// arrange
|
||||
string plain = "ABC";
|
||||
string password = "P@ssw0rd!";
|
||||
|
||||
// act
|
||||
string cipher1 = CryptographyHelper.TripleDesEncrypt(plain, password);
|
||||
string cipher2 = CryptographyHelper.TripleDesEncrypt(plain, password);
|
||||
|
||||
string plain1 = CryptographyHelper.TripleDesDecrypt(cipher1, password);
|
||||
string plain2 = CryptographyHelper.TripleDesDecrypt(cipher2, password);
|
||||
|
||||
// assert
|
||||
Assert.AreNotEqual(cipher1, cipher2);
|
||||
Assert.AreEqual(24, cipher1.Length);
|
||||
Assert.AreEqual(24, cipher2.Length);
|
||||
Assert.AreEqual(plain, plain1);
|
||||
Assert.AreEqual(plain, plain2);
|
||||
}
|
||||
|
||||
#endregion TripleDES
|
||||
|
||||
#endregion Encryption
|
||||
|
||||
#region Hash
|
||||
|
||||
[TestMethod]
|
||||
public void ShouldReturnMd5Hash()
|
||||
{
|
||||
// arrange
|
||||
string text = "Hello World!";
|
||||
byte[] bytes = [0xde, 0xad, 0xbe, 0xef];
|
||||
string fileName = Path.GetTempFileName();
|
||||
|
||||
// act
|
||||
string textHash = CryptographyHelper.Md5(text);
|
||||
string bytesHash = CryptographyHelper.Md5(bytes);
|
||||
|
||||
File.WriteAllText(fileName, text);
|
||||
string fileHash = CryptographyHelper.Md5File(fileName);
|
||||
File.Delete(fileName);
|
||||
|
||||
// assert
|
||||
Assert.AreEqual("ed076287532e86365e841e92bfc50d8c", textHash);
|
||||
Assert.AreEqual("2f249230a8e7c2bf6005ccd2679259ec", bytesHash);
|
||||
Assert.AreEqual("ed076287532e86365e841e92bfc50d8c", fileHash);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void ShouldReturnSha1Hash()
|
||||
{
|
||||
// arrange
|
||||
string text = "Hello World!";
|
||||
byte[] bytes = [0xde, 0xad, 0xbe, 0xef];
|
||||
string fileName = Path.GetTempFileName();
|
||||
|
||||
// act
|
||||
string textHash = CryptographyHelper.Sha1(text);
|
||||
string bytesHash = CryptographyHelper.Sha1(bytes);
|
||||
|
||||
File.WriteAllText(fileName, text);
|
||||
string fileHash = CryptographyHelper.Sha1File(fileName);
|
||||
File.Delete(fileName);
|
||||
|
||||
// assert
|
||||
Assert.AreEqual("2ef7bde608ce5404e97d5f042f95f89f1c232871", textHash);
|
||||
Assert.AreEqual("d78f8bb992a56a597f6c7a1fb918bb78271367eb", bytesHash);
|
||||
Assert.AreEqual("2ef7bde608ce5404e97d5f042f95f89f1c232871", fileHash);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void ShouldReturnSha256Hash()
|
||||
{
|
||||
// arrange
|
||||
string text = "Hello World!";
|
||||
byte[] bytes = [0xde, 0xad, 0xbe, 0xef];
|
||||
string fileName = Path.GetTempFileName();
|
||||
|
||||
// act
|
||||
string textHash = CryptographyHelper.Sha256(text);
|
||||
string bytesHash = CryptographyHelper.Sha256(bytes);
|
||||
|
||||
File.WriteAllText(fileName, text);
|
||||
string fileHash = CryptographyHelper.Sha256File(fileName);
|
||||
File.Delete(fileName);
|
||||
|
||||
// assert
|
||||
Assert.AreEqual("7f83b1657ff1fc53b92dc18148a1d65dfc2d4b1fa3d677284addd200126d9069", textHash);
|
||||
Assert.AreEqual("5f78c33274e43fa9de5659265c1d917e25c03722dcb0b8d27db8d5feaa813953", bytesHash);
|
||||
Assert.AreEqual("7f83b1657ff1fc53b92dc18148a1d65dfc2d4b1fa3d677284addd200126d9069", fileHash);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void ShouldReturnSha512Hash()
|
||||
{
|
||||
// arrange
|
||||
string text = "Hello World!";
|
||||
byte[] bytes = [0xde, 0xad, 0xbe, 0xef];
|
||||
string fileName = Path.GetTempFileName();
|
||||
|
||||
// act
|
||||
string textHash = CryptographyHelper.Sha512(text);
|
||||
string bytesHash = CryptographyHelper.Sha512(bytes);
|
||||
|
||||
File.WriteAllText(fileName, text);
|
||||
string fileHash = CryptographyHelper.Sha512File(fileName);
|
||||
File.Delete(fileName);
|
||||
|
||||
// assert
|
||||
Assert.AreEqual("861844d6704e8573fec34d967e20bcfef3d424cf48be04e6dc08f2bd58c729743371015ead891cc3cf1c9d34b49264b510751b1ff9e537937bc46b5d6ff4ecc8", textHash);
|
||||
Assert.AreEqual("1284b2d521535196f22175d5f558104220a6ad7680e78b49fa6f20e57ea7b185d71ec1edb137e70eba528dedb141f5d2f8bb53149d262932b27cf41fed96aa7f", bytesHash);
|
||||
Assert.AreEqual("861844d6704e8573fec34d967e20bcfef3d424cf48be04e6dc08f2bd58c729743371015ead891cc3cf1c9d34b49264b510751b1ff9e537937bc46b5d6ff4ecc8", fileHash);
|
||||
}
|
||||
|
||||
#endregion Hash
|
||||
|
||||
#region Random
|
||||
|
||||
[TestMethod]
|
||||
public void ShouldReturnRandomBytes()
|
||||
{
|
||||
// arrange
|
||||
int length1 = 12;
|
||||
int length2 = 12;
|
||||
int length3 = 42;
|
||||
|
||||
// act
|
||||
byte[] bytes1 = CryptographyHelper.GetRandomBytes(length1);
|
||||
byte[] bytes2 = CryptographyHelper.GetRandomBytes(length2);
|
||||
byte[] bytes3 = CryptographyHelper.GetRandomBytes(length3);
|
||||
|
||||
// assert
|
||||
Assert.AreEqual(length1, bytes1.Length);
|
||||
Assert.AreEqual(length2, bytes2.Length);
|
||||
Assert.AreEqual(length3, bytes3.Length);
|
||||
|
||||
Assert.IsTrue(bytes1.Length == bytes2.Length);
|
||||
CollectionAssert.AreNotEqual(bytes1, bytes2);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void ShouldReturnRandomString()
|
||||
{
|
||||
// arrange
|
||||
int length1 = 12;
|
||||
int length2 = 12;
|
||||
int length3 = 42;
|
||||
|
||||
// act
|
||||
string str1 = CryptographyHelper.GetRandomString(length1);
|
||||
string str2 = CryptographyHelper.GetRandomString(length2);
|
||||
string str3 = CryptographyHelper.GetRandomString(length3);
|
||||
|
||||
// assert
|
||||
Assert.AreEqual(length1, str1.Length);
|
||||
Assert.AreEqual(length2, str2.Length);
|
||||
Assert.AreEqual(length3, str3.Length);
|
||||
|
||||
Assert.IsTrue(str1.Length == str2.Length);
|
||||
Assert.IsFalse(str1 == str2);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void ShouldReturnRandomStringWithPool()
|
||||
{
|
||||
// arrange
|
||||
int length = 12;
|
||||
string pool = "0123456789abcdef";
|
||||
|
||||
// act
|
||||
string str1 = CryptographyHelper.GetRandomString(length, pool);
|
||||
string str2 = CryptographyHelper.GetRandomString(length, pool);
|
||||
|
||||
// assert
|
||||
Assert.AreEqual(length, str1.Length);
|
||||
Assert.AreEqual(length, str2.Length);
|
||||
Assert.IsFalse(str1 == str2);
|
||||
Assert.IsFalse(RandomStringWithPoolRegex().IsMatch(str1));
|
||||
Assert.IsFalse(RandomStringWithPoolRegex().IsMatch(str2));
|
||||
}
|
||||
|
||||
#endregion Random
|
||||
|
||||
#region Secure probing
|
||||
|
||||
[TestMethod]
|
||||
public void ShouldTakeSameTimeToCompareString()
|
||||
{
|
||||
// arrange
|
||||
string str1 = "Hello World!";
|
||||
string str2 = "Hello World!";
|
||||
string str3 = "Hallo World!";
|
||||
string str4 = "Hello World?";
|
||||
string nullStr = null;
|
||||
string strLen = "Hello World";
|
||||
|
||||
var sw = new Stopwatch();
|
||||
|
||||
// act
|
||||
bool nullCompare = CryptographyHelper.SecureEquals(nullStr, str1);
|
||||
bool lenCompare = CryptographyHelper.SecureEquals(strLen, str1);
|
||||
|
||||
sw.Start();
|
||||
bool compare1 = CryptographyHelper.SecureEquals(str1, str2);
|
||||
long time1 = sw.ElapsedMilliseconds;
|
||||
|
||||
bool compare2 = CryptographyHelper.SecureEquals(str1, str3);
|
||||
long time2 = sw.ElapsedMilliseconds;
|
||||
|
||||
bool compare3 = CryptographyHelper.SecureEquals(str1, str4);
|
||||
long time3 = sw.ElapsedMilliseconds;
|
||||
sw.Stop();
|
||||
|
||||
// assert
|
||||
Assert.IsFalse(nullCompare);
|
||||
Assert.IsFalse(lenCompare);
|
||||
Assert.IsTrue(compare1);
|
||||
Assert.IsFalse(compare2);
|
||||
Assert.IsFalse(compare3);
|
||||
|
||||
Assert.AreEqual(time1, time2);
|
||||
Assert.AreEqual(time1, time3);
|
||||
Assert.AreEqual(time2, time3);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void ShouldTakeSameTimeToCompareBytes()
|
||||
{
|
||||
// arrange
|
||||
byte[] bytes1 = CryptographyHelper.GetRandomBytes(200);
|
||||
byte[] bytes2 = new byte[bytes1.Length];
|
||||
byte[] bytes3 = new byte[bytes1.Length];
|
||||
byte[] bytes4 = new byte[bytes1.Length];
|
||||
byte[] nullBytes = null;
|
||||
byte[] lenBytes = new byte[bytes1.Length + 1];
|
||||
|
||||
Array.Copy(bytes1, bytes2, bytes1.Length);
|
||||
Array.Copy(bytes1, bytes3, bytes1.Length);
|
||||
Array.Copy(bytes1, bytes4, bytes1.Length);
|
||||
|
||||
bytes3[10] = (byte)(bytes1[10] + 1);
|
||||
bytes4[190] = (byte)(bytes1[190] + 1);
|
||||
|
||||
var sw = new Stopwatch();
|
||||
|
||||
// act
|
||||
bool nullCompare = CryptographyHelper.SecureEquals(nullBytes, bytes1);
|
||||
bool lenCompare = CryptographyHelper.SecureEquals(lenBytes, bytes1);
|
||||
|
||||
sw.Start();
|
||||
bool compare1 = CryptographyHelper.SecureEquals(bytes1, bytes2);
|
||||
long time1 = sw.ElapsedMilliseconds;
|
||||
|
||||
bool compare2 = CryptographyHelper.SecureEquals(bytes1, bytes3);
|
||||
long time2 = sw.ElapsedMilliseconds;
|
||||
|
||||
bool compare3 = CryptographyHelper.SecureEquals(bytes1, bytes4);
|
||||
long time3 = sw.ElapsedMilliseconds;
|
||||
sw.Stop();
|
||||
|
||||
// assert
|
||||
Assert.IsFalse(nullCompare);
|
||||
Assert.IsFalse(lenCompare);
|
||||
Assert.IsTrue(compare1);
|
||||
Assert.IsFalse(compare2);
|
||||
Assert.IsFalse(compare3);
|
||||
|
||||
Assert.AreEqual(time1, time2);
|
||||
Assert.AreEqual(time1, time3);
|
||||
Assert.AreEqual(time2, time3);
|
||||
}
|
||||
|
||||
#endregion Secure probing
|
||||
|
||||
#endregion Static
|
||||
|
||||
#region Instance
|
||||
|
||||
[TestMethod]
|
||||
public void ShouldCreateDefaultFile()
|
||||
{
|
||||
// arrange
|
||||
string executingAssemblyDir = AppContext.BaseDirectory;
|
||||
string filePath = Path.Combine(executingAssemblyDir, "crypto.key");
|
||||
|
||||
// act
|
||||
bool fileExistsBefore = File.Exists(filePath);
|
||||
var helper = new CryptographyHelper();
|
||||
bool fileExistsAfter = File.Exists(filePath);
|
||||
string content = fileExistsAfter ? File.ReadAllText(filePath) : null;
|
||||
File.Delete(filePath);
|
||||
|
||||
// assert
|
||||
Assert.IsFalse(fileExistsBefore);
|
||||
Assert.IsNotNull(helper);
|
||||
Assert.IsTrue(fileExistsAfter);
|
||||
Assert.IsTrue(!string.IsNullOrWhiteSpace(content));
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void ShouldEncryptAesUsingKeyFile()
|
||||
{
|
||||
// arrange
|
||||
string str = "Hello World!";
|
||||
byte[] bytes = CryptographyHelper.GetRandomBytes(32);
|
||||
|
||||
string password = File.ReadAllText(_keyFile);
|
||||
|
||||
// act
|
||||
string cipherStr = _cryptoHelper.EncryptAes(str);
|
||||
byte[] cipherBytes = _cryptoHelper.EncryptAes(bytes);
|
||||
|
||||
string plainStr = CryptographyHelper.AesDecrypt(cipherStr, password);
|
||||
byte[] plainBytes = CryptographyHelper.AesDecrypt(cipherBytes, password);
|
||||
|
||||
// assert
|
||||
Assert.AreNotEqual(str, cipherStr);
|
||||
Assert.AreEqual(str, plainStr);
|
||||
CollectionAssert.AreNotEqual(bytes, cipherBytes);
|
||||
CollectionAssert.AreEqual(bytes, plainBytes);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void ShouldDecryptAesUsingKeyFile()
|
||||
{
|
||||
// arrange
|
||||
string str = "Hello World!";
|
||||
byte[] bytes = CryptographyHelper.GetRandomBytes(32);
|
||||
|
||||
string password = File.ReadAllText(_keyFile);
|
||||
|
||||
// act
|
||||
string cipherStr = CryptographyHelper.AesEncrypt(str, password);
|
||||
byte[] cipherBytes = CryptographyHelper.AesEncrypt(bytes, password);
|
||||
|
||||
string plainStr = _cryptoHelper.DecryptAes(cipherStr);
|
||||
byte[] plainBytes = _cryptoHelper.DecryptAes(cipherBytes);
|
||||
|
||||
// assert
|
||||
Assert.AreNotEqual(str, cipherStr);
|
||||
Assert.AreEqual(str, plainStr);
|
||||
CollectionAssert.AreNotEqual(bytes, cipherBytes);
|
||||
CollectionAssert.AreEqual(bytes, plainBytes);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void ShouldEncryptTdesUsingKeyFile()
|
||||
{
|
||||
// arrange
|
||||
string str = "Hello World!";
|
||||
byte[] bytes = CryptographyHelper.GetRandomBytes(32);
|
||||
|
||||
string password = File.ReadAllText(_keyFile);
|
||||
|
||||
// act
|
||||
string cipherStr = _cryptoHelper.EncryptTripleDes(str);
|
||||
byte[] cipherBytes = _cryptoHelper.EncryptTripleDes(bytes);
|
||||
|
||||
string plainStr = CryptographyHelper.TripleDesDecrypt(cipherStr, password);
|
||||
byte[] plainBytes = CryptographyHelper.TripleDesDecrypt(cipherBytes, password);
|
||||
|
||||
// assert
|
||||
Assert.AreNotEqual(str, cipherStr);
|
||||
Assert.AreEqual(str, plainStr);
|
||||
CollectionAssert.AreNotEqual(bytes, cipherBytes);
|
||||
CollectionAssert.AreEqual(bytes, plainBytes);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void ShouldDecryptTdesUsingKeyFile()
|
||||
{
|
||||
// arrange
|
||||
string str = "Hello World!";
|
||||
byte[] bytes = CryptographyHelper.GetRandomBytes(32);
|
||||
|
||||
string password = File.ReadAllText(_keyFile);
|
||||
|
||||
// act
|
||||
string cipherStr = CryptographyHelper.TripleDesEncrypt(str, password);
|
||||
byte[] cipherBytes = CryptographyHelper.TripleDesEncrypt(bytes, password);
|
||||
|
||||
string plainStr = _cryptoHelper.DecryptTripleDes(cipherStr);
|
||||
byte[] plainBytes = _cryptoHelper.DecryptTripleDes(cipherBytes);
|
||||
|
||||
// assert
|
||||
Assert.AreNotEqual(str, cipherStr);
|
||||
Assert.AreEqual(str, plainStr);
|
||||
CollectionAssert.AreNotEqual(bytes, cipherBytes);
|
||||
CollectionAssert.AreEqual(bytes, plainBytes);
|
||||
}
|
||||
|
||||
[GeneratedRegex("[^0-9a-f]")]
|
||||
private static partial Regex RandomStringWithPoolRegex();
|
||||
|
||||
#endregion Instance
|
||||
}
|
||||
}
|
||||
283
test/AMWD.Common.Tests/Utilities/DelayedTaskTest.cs
Normal file
283
test/AMWD.Common.Tests/Utilities/DelayedTaskTest.cs
Normal file
@@ -0,0 +1,283 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using AMWD.Common.Utilities;
|
||||
|
||||
namespace AMWD.Common.Tests.Utilities
|
||||
{
|
||||
[TestClass]
|
||||
public class DelayedTaskTest
|
||||
{
|
||||
[TestMethod]
|
||||
public void ShouldCreateNewDelayedTaskNotStarting()
|
||||
{
|
||||
// arrange
|
||||
int executionCount = 0;
|
||||
var delay = TimeSpan.FromMilliseconds(100);
|
||||
void Action() { executionCount++; }
|
||||
|
||||
// act
|
||||
var cts = new CancellationTokenSource(delay.Add(TimeSpan.FromSeconds(1)));
|
||||
var delayedTask = DelayedTask.Create(Action, delay);
|
||||
SpinWait.SpinUntil(() => executionCount > 0 || cts.IsCancellationRequested);
|
||||
|
||||
// assert
|
||||
Assert.IsNotNull(delayedTask);
|
||||
Assert.AreEqual(delay, delayedTask.Delay);
|
||||
Assert.IsFalse(delayedTask.IsRunning);
|
||||
Assert.IsFalse(delayedTask.IsWaitingToRun);
|
||||
Assert.IsNull(delayedTask.Exception);
|
||||
Assert.AreEqual(0, executionCount);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void ShouldCreateNewDelayedTaskStarting()
|
||||
{
|
||||
// arrange
|
||||
int executionCount = 0;
|
||||
var delay = TimeSpan.FromMilliseconds(100);
|
||||
void Action() { executionCount++; }
|
||||
|
||||
// act
|
||||
var cts = new CancellationTokenSource(delay.Add(TimeSpan.FromSeconds(1)));
|
||||
var delayedTask = DelayedTask.Run(Action, delay);
|
||||
SpinWait.SpinUntil(() => executionCount > 0 || cts.IsCancellationRequested);
|
||||
|
||||
// assert
|
||||
Assert.IsNotNull(delayedTask);
|
||||
Assert.AreEqual(delay, delayedTask.Delay);
|
||||
Assert.IsFalse(delayedTask.IsRunning);
|
||||
Assert.IsFalse(delayedTask.IsWaitingToRun);
|
||||
Assert.IsNull(delayedTask.Exception);
|
||||
Assert.AreEqual(1, executionCount);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void ShouldRunOnceAfterReset()
|
||||
{
|
||||
// arrange
|
||||
int executionCount = 0;
|
||||
var delay = TimeSpan.FromMilliseconds(100);
|
||||
void Action() { executionCount++; }
|
||||
|
||||
// act
|
||||
var cts = new CancellationTokenSource(delay.Add(TimeSpan.FromSeconds(1)));
|
||||
var delayedTask = DelayedTask.Create(Action, delay);
|
||||
delayedTask.Reset();
|
||||
SpinWait.SpinUntil(() => executionCount > 0 || cts.IsCancellationRequested);
|
||||
|
||||
// assert
|
||||
Assert.IsNotNull(delayedTask);
|
||||
Assert.AreEqual(delay, delayedTask.Delay);
|
||||
Assert.IsFalse(delayedTask.IsRunning);
|
||||
Assert.IsFalse(delayedTask.IsWaitingToRun);
|
||||
Assert.IsNull(delayedTask.Exception);
|
||||
Assert.AreEqual(1, executionCount);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void ShouldCancelWaitingTask()
|
||||
{
|
||||
// arrange
|
||||
int executionCount = 0;
|
||||
var delay = TimeSpan.FromMilliseconds(100);
|
||||
void Action() { executionCount++; }
|
||||
|
||||
// act
|
||||
var cts = new CancellationTokenSource(delay.Add(TimeSpan.FromSeconds(1)));
|
||||
var delayedTask = DelayedTask.Run(Action, delay);
|
||||
delayedTask.Cancel();
|
||||
SpinWait.SpinUntil(() => executionCount > 0 || cts.IsCancellationRequested);
|
||||
|
||||
// assert
|
||||
Assert.IsNotNull(delayedTask);
|
||||
Assert.AreEqual(delay, delayedTask.Delay);
|
||||
Assert.IsFalse(delayedTask.IsRunning);
|
||||
Assert.IsFalse(delayedTask.IsWaitingToRun);
|
||||
Assert.IsNull(delayedTask.Exception);
|
||||
Assert.AreEqual(0, executionCount);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public async Task ShouldResetRunningDelay()
|
||||
{
|
||||
// arrange
|
||||
int executionCount = 0;
|
||||
var sw = new Stopwatch();
|
||||
|
||||
var delay = TimeSpan.FromMilliseconds(200);
|
||||
void Action() { sw.Stop(); executionCount++; }
|
||||
|
||||
// act
|
||||
var cts = new CancellationTokenSource(delay.Add(TimeSpan.FromSeconds(1)));
|
||||
sw.Start();
|
||||
var delayedTask = DelayedTask.Run(Action, delay);
|
||||
await Task.Delay(50);
|
||||
delayedTask.Reset();
|
||||
SpinWait.SpinUntil(() => executionCount > 0 || cts.IsCancellationRequested);
|
||||
|
||||
// assert
|
||||
Assert.IsNotNull(delayedTask);
|
||||
Assert.AreEqual(delay, delayedTask.Delay);
|
||||
Assert.IsFalse(delayedTask.IsRunning);
|
||||
Assert.IsFalse(delayedTask.IsWaitingToRun);
|
||||
Assert.IsNull(delayedTask.Exception);
|
||||
Assert.AreEqual(1, executionCount);
|
||||
// delta of 60ms as the precision below 50ms is really bad for System.Timer
|
||||
Assert.AreEqual(250, sw.ElapsedMilliseconds, 60);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public async Task ShouldNotExecutedImmediateOnCreated()
|
||||
{
|
||||
// arrange
|
||||
int executionCount = 0;
|
||||
var sw = new Stopwatch();
|
||||
|
||||
var delay = TimeSpan.FromMilliseconds(200);
|
||||
void Action() { sw.Stop(); executionCount++; }
|
||||
|
||||
// act
|
||||
var cts = new CancellationTokenSource(delay.Add(TimeSpan.FromSeconds(1)));
|
||||
sw.Start();
|
||||
var delayedTask = DelayedTask.Create(Action, delay);
|
||||
await Task.Delay(50);
|
||||
bool isSuccess = delayedTask.ExecutePending();
|
||||
SpinWait.SpinUntil(() => executionCount > 0 || cts.IsCancellationRequested);
|
||||
sw.Stop();
|
||||
|
||||
// assert
|
||||
Assert.IsNotNull(delayedTask);
|
||||
Assert.AreEqual(delay, delayedTask.Delay);
|
||||
Assert.IsFalse(delayedTask.IsRunning);
|
||||
Assert.IsFalse(delayedTask.IsWaitingToRun);
|
||||
Assert.IsNull(delayedTask.Exception);
|
||||
Assert.AreEqual(0, executionCount);
|
||||
// delta of 60ms as the precision below 50ms is really bad for System.Timer
|
||||
Assert.AreEqual(1250, sw.ElapsedMilliseconds, 60);
|
||||
Assert.IsFalse(isSuccess);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public async Task ShouldExecuteImmediateOnExecutePendingWhenRunning()
|
||||
{
|
||||
// arrange
|
||||
int executionCount = 0;
|
||||
var sw = new Stopwatch();
|
||||
|
||||
var delay = TimeSpan.FromMilliseconds(200);
|
||||
void Action() { sw.Stop(); executionCount++; }
|
||||
|
||||
// act
|
||||
var cts = new CancellationTokenSource(delay.Add(TimeSpan.FromSeconds(1)));
|
||||
sw.Start();
|
||||
var delayedTask = DelayedTask.Run(Action, delay);
|
||||
await Task.Delay(50);
|
||||
bool isSuccess = delayedTask.ExecutePending();
|
||||
SpinWait.SpinUntil(() => executionCount > 0 || cts.IsCancellationRequested);
|
||||
|
||||
// assert
|
||||
Assert.IsNotNull(delayedTask);
|
||||
Assert.AreEqual(delay, delayedTask.Delay);
|
||||
Assert.IsFalse(delayedTask.IsRunning);
|
||||
Assert.IsFalse(delayedTask.IsWaitingToRun);
|
||||
Assert.IsNull(delayedTask.Exception);
|
||||
Assert.AreEqual(1, executionCount);
|
||||
// delta of 60ms as the precision below 50ms is really bad for System.Timer
|
||||
Assert.AreEqual(50, sw.ElapsedMilliseconds, 60);
|
||||
Assert.IsTrue(isSuccess);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void ShouldReturnAnAwaiter()
|
||||
{
|
||||
// arrange
|
||||
int executionCount = 0;
|
||||
var delay = TimeSpan.FromMilliseconds(100);
|
||||
void Action() { executionCount++; }
|
||||
var delayedTask = DelayedTask.Create(Action, delay);
|
||||
|
||||
// act
|
||||
delayedTask.Reset();
|
||||
var awaiter = delayedTask.GetAwaiter();
|
||||
SpinWait.SpinUntil(() => awaiter.IsCompleted);
|
||||
|
||||
// assert
|
||||
Assert.IsNotNull(delayedTask);
|
||||
Assert.IsNotNull(awaiter);
|
||||
Assert.IsFalse(delayedTask.IsRunning);
|
||||
Assert.IsFalse(delayedTask.IsWaitingToRun);
|
||||
Assert.IsNull(delayedTask.Exception);
|
||||
Assert.AreEqual(1, executionCount);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void ShouldHaveAnExceptionSet()
|
||||
{
|
||||
// arrange
|
||||
var delay = TimeSpan.FromMilliseconds(100);
|
||||
static void Action() { throw new Exception("TEST :D"); }
|
||||
|
||||
// act
|
||||
var delayedTask = DelayedTask.Run(Action, delay);
|
||||
|
||||
var awaiter = delayedTask.GetAwaiter();
|
||||
SpinWait.SpinUntil(() => awaiter.IsCompleted);
|
||||
|
||||
// assert
|
||||
Assert.IsNotNull(delayedTask);
|
||||
Assert.IsFalse(delayedTask.IsRunning);
|
||||
Assert.IsFalse(delayedTask.IsWaitingToRun);
|
||||
Assert.IsNotNull(delayedTask.Exception);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void ShouldUseExceptionHandler()
|
||||
{
|
||||
// arrange
|
||||
string exceptionText = null;
|
||||
var delay = TimeSpan.FromMilliseconds(100);
|
||||
void Action() { throw new Exception("TEST :D"); }
|
||||
void ExceptionHandler(Exception ex) { exceptionText = ex.Message; }
|
||||
|
||||
// act
|
||||
var delayedTask = DelayedTask.Run(Action, delay)
|
||||
.WithExceptionHandler(ExceptionHandler);
|
||||
|
||||
var awaiter = delayedTask.GetAwaiter();
|
||||
SpinWait.SpinUntil(() => awaiter.IsCompleted);
|
||||
|
||||
// assert
|
||||
Assert.IsNotNull(delayedTask);
|
||||
Assert.IsFalse(delayedTask.IsRunning);
|
||||
Assert.IsFalse(delayedTask.IsWaitingToRun);
|
||||
Assert.IsNotNull(delayedTask.Exception);
|
||||
Assert.AreEqual("TEST :D", exceptionText);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public async Task ShouldReturnNormalTask()
|
||||
{
|
||||
// arrange
|
||||
int executionCount = 0;
|
||||
var delay = TimeSpan.FromMilliseconds(100);
|
||||
void Action() { executionCount++; }
|
||||
var delayedTask = DelayedTask.Create(Action, delay);
|
||||
|
||||
// act
|
||||
delayedTask.Reset();
|
||||
var task = delayedTask.Task;
|
||||
await task;
|
||||
|
||||
// assert
|
||||
Assert.IsNotNull(delayedTask);
|
||||
Assert.IsNotNull(task);
|
||||
Assert.IsInstanceOfType(task, typeof(Task));
|
||||
Assert.IsFalse(delayedTask.IsRunning);
|
||||
Assert.IsFalse(delayedTask.IsWaitingToRun);
|
||||
Assert.AreEqual(1, executionCount);
|
||||
Assert.AreEqual(TaskStatus.RanToCompletion, task.Status);
|
||||
}
|
||||
}
|
||||
}
|
||||
130
test/AMWD.Common.Tests/Utilities/DelayedTaskWithResultTest.cs
Normal file
130
test/AMWD.Common.Tests/Utilities/DelayedTaskWithResultTest.cs
Normal file
@@ -0,0 +1,130 @@
|
||||
using System;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using AMWD.Common.Utilities;
|
||||
|
||||
namespace AMWD.Common.Tests.Utilities
|
||||
{
|
||||
[TestClass]
|
||||
public class DelayedTaskWithResultTest
|
||||
{
|
||||
[TestMethod]
|
||||
public void ShouldCreateNewDelayedTaskNotStarting()
|
||||
{
|
||||
// arrange
|
||||
int executionCount = 0;
|
||||
var delay = TimeSpan.FromMilliseconds(100);
|
||||
int[] Function() { executionCount++; return [42, 21]; }
|
||||
|
||||
// act
|
||||
var cts = new CancellationTokenSource(delay.Add(TimeSpan.FromSeconds(1)));
|
||||
var delayedTaskWithResult = DelayedTask.Create(Function, delay);
|
||||
SpinWait.SpinUntil(() => executionCount > 0 || cts.IsCancellationRequested);
|
||||
|
||||
// assert
|
||||
Assert.IsNotNull(delayedTaskWithResult);
|
||||
Assert.AreEqual(delay, delayedTaskWithResult.Delay);
|
||||
Assert.IsFalse(delayedTaskWithResult.IsRunning);
|
||||
Assert.IsFalse(delayedTaskWithResult.IsWaitingToRun);
|
||||
Assert.IsNull(delayedTaskWithResult.Exception);
|
||||
Assert.AreEqual(0, executionCount);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
[System.Diagnostics.CodeAnalysis.SuppressMessage("Performance", "CA1861")]
|
||||
public async Task ShouldCreateNewDelayedTaskStarting()
|
||||
{
|
||||
// arrange
|
||||
int executionCount = 0;
|
||||
var delay = TimeSpan.FromMilliseconds(100);
|
||||
int[] Function() { executionCount++; return [42, 21]; }
|
||||
|
||||
// act
|
||||
var delayedTaskWithResult = DelayedTask.Run(Function, delay);
|
||||
int[] result = await delayedTaskWithResult;
|
||||
|
||||
// assert
|
||||
Assert.IsNotNull(delayedTaskWithResult);
|
||||
Assert.AreEqual(delay, delayedTaskWithResult.Delay);
|
||||
Assert.IsFalse(delayedTaskWithResult.IsRunning);
|
||||
Assert.IsFalse(delayedTaskWithResult.IsWaitingToRun);
|
||||
Assert.IsNull(delayedTaskWithResult.Exception);
|
||||
Assert.AreEqual(1, executionCount);
|
||||
CollectionAssert.AreEqual(new[] { 42, 21 }, result);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void ShouldHaveAnExceptionSet()
|
||||
{
|
||||
// arrange
|
||||
var delay = TimeSpan.FromMilliseconds(100);
|
||||
#pragma warning disable CS0162 // Unreachable Code detected.
|
||||
static int[] Function() { throw new Exception("TEST :D"); return [42, 21]; }
|
||||
#pragma warning restore CS0162 // Unreachable Code detected
|
||||
|
||||
// act
|
||||
var delayedTaskWithResult = DelayedTask.Run(Function, delay);
|
||||
|
||||
var awaiter = delayedTaskWithResult.GetAwaiter();
|
||||
SpinWait.SpinUntil(() => awaiter.IsCompleted);
|
||||
|
||||
// assert
|
||||
Assert.IsNotNull(delayedTaskWithResult);
|
||||
Assert.IsFalse(delayedTaskWithResult.IsRunning);
|
||||
Assert.IsFalse(delayedTaskWithResult.IsWaitingToRun);
|
||||
Assert.IsNotNull(delayedTaskWithResult.Exception);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void ShouldUseExceptionHandler()
|
||||
{
|
||||
// arrange
|
||||
string exceptionText = null;
|
||||
var delay = TimeSpan.FromMilliseconds(100);
|
||||
#pragma warning disable CS0162 // Unreachable Code detected.
|
||||
static int[] Function() { throw new Exception("TEST :D"); return [42, 21]; }
|
||||
#pragma warning restore CS0162 // Unreachable Code detected
|
||||
void ExceptionHandler(Exception ex) { exceptionText = ex.Message; }
|
||||
|
||||
// act
|
||||
var delayedTaskWithResult = DelayedTask.Run(Function, delay)
|
||||
.WithExceptionHandler(ExceptionHandler);
|
||||
|
||||
var awaiter = delayedTaskWithResult.GetAwaiter();
|
||||
SpinWait.SpinUntil(() => awaiter.IsCompleted);
|
||||
|
||||
// assert
|
||||
Assert.IsNotNull(delayedTaskWithResult);
|
||||
Assert.IsFalse(delayedTaskWithResult.IsRunning);
|
||||
Assert.IsFalse(delayedTaskWithResult.IsWaitingToRun);
|
||||
Assert.IsNotNull(delayedTaskWithResult.Exception);
|
||||
Assert.AreEqual("TEST :D", exceptionText);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
[System.Diagnostics.CodeAnalysis.SuppressMessage("Performance", "CA1861")]
|
||||
public async Task ShouldReturnNormalTask()
|
||||
{
|
||||
// arrange
|
||||
int executionCount = 0;
|
||||
var delay = TimeSpan.FromMilliseconds(100);
|
||||
int[] Function() { executionCount++; return [42, 21]; }
|
||||
var delayedTaskWithResult = DelayedTask.Create(Function, delay);
|
||||
|
||||
// act
|
||||
delayedTaskWithResult.Reset();
|
||||
var task = delayedTaskWithResult.Task;
|
||||
int[] result = await task;
|
||||
|
||||
// assert
|
||||
Assert.IsNotNull(delayedTaskWithResult);
|
||||
Assert.IsNotNull(task);
|
||||
Assert.IsInstanceOfType(task, typeof(Task));
|
||||
Assert.IsFalse(delayedTaskWithResult.IsRunning);
|
||||
Assert.IsFalse(delayedTaskWithResult.IsWaitingToRun);
|
||||
Assert.AreEqual(1, executionCount);
|
||||
Assert.AreEqual(TaskStatus.RanToCompletion, task.Status);
|
||||
CollectionAssert.AreEqual(new int[] { 42, 21 }, result);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user