|
|
|
@ -0,0 +1,81 @@ |
|
|
|
|
namespace EternalArrowBackup.TargetBinaryStorage.InMemoryBinaryStorage.Tests |
|
|
|
|
{ |
|
|
|
|
using System; |
|
|
|
|
using System.Collections.Generic; |
|
|
|
|
using System.Collections.Immutable; |
|
|
|
|
using System.Linq; |
|
|
|
|
using System.Threading; |
|
|
|
|
using System.Threading.Tasks; |
|
|
|
|
using System.Threading.Tasks.Dataflow; |
|
|
|
|
using Xunit; |
|
|
|
|
|
|
|
|
|
public static class StorageTests |
|
|
|
|
{ |
|
|
|
|
[Fact] |
|
|
|
|
[Trait("Category", "Simple")] |
|
|
|
|
public static async Task CheckStorage() |
|
|
|
|
{ |
|
|
|
|
var storageData = CreateStorageData(); |
|
|
|
|
var storage = new BinaryStorage(); |
|
|
|
|
|
|
|
|
|
foreach (var kvp in storageData) |
|
|
|
|
{ |
|
|
|
|
var blobId = kvp.Key; |
|
|
|
|
Assert.Null(await storage.GetBlobIfExists(blobId)); |
|
|
|
|
var blocks = kvp.Value.Item2; |
|
|
|
|
for (var i = 0; i < blocks.Length; i++) |
|
|
|
|
{ |
|
|
|
|
await storage.WriteBlock(blocks[i].Item2, blobId, i, blocks[i].Item1); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
await storage.WriteBlob(blobId, kvp.Value.Item1, blocks.Select(tuple => tuple.Item1).ToArray()); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
foreach (var kvp in storageData) |
|
|
|
|
{ |
|
|
|
|
var blobId = kvp.Key; |
|
|
|
|
var blobInfo = await storage.GetBlobIfExists(blobId); |
|
|
|
|
Assert.NotNull(blobInfo); |
|
|
|
|
Assert.Equal(kvp.Value.Item1, blobInfo.OriginalSize); |
|
|
|
|
Assert.InRange(blobInfo.UploadDate, DateTime.UtcNow.AddMinutes(-2), DateTime.UtcNow); |
|
|
|
|
Assert.Equal(kvp.Value.Item2.Select(tuple => tuple.Item1).ToArray(), blobInfo.BlockKeys); |
|
|
|
|
|
|
|
|
|
for (var i = 0; i < blobInfo.BlockKeys.Length; i++) |
|
|
|
|
{ |
|
|
|
|
var blockKey = blobInfo.BlockKeys[i]; |
|
|
|
|
Assert.Equal(kvp.Value.Item2[i].Item1, blockKey); |
|
|
|
|
|
|
|
|
|
var blockContent = await storage.RetrieveBlock(blobId, blockKey); |
|
|
|
|
Assert.Equal(kvp.Value.Item2[i].Item2, blockContent); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private static Dictionary<string, Tuple<long, Tuple<string, byte[]>[]>> CreateStorageData() |
|
|
|
|
{ |
|
|
|
|
var random = new Random(); |
|
|
|
|
var result = new Dictionary<string, Tuple<long, Tuple<string, byte[]>[]>>(); |
|
|
|
|
for (var i = 0; i < 2000; i++) |
|
|
|
|
{ |
|
|
|
|
var blobName = Guid.NewGuid().ToString(); |
|
|
|
|
var blocksCount = random.Next(0, 20); |
|
|
|
|
var blocks = new Tuple<string, byte[]>[blocksCount]; |
|
|
|
|
for (var j = 0; j < blocksCount; j++) |
|
|
|
|
{ |
|
|
|
|
var blockKey = Guid.NewGuid().ToString(); |
|
|
|
|
var blockContent = new byte[random.Next(0, 20)]; |
|
|
|
|
for (var k = 0; k < blockContent.Length; k++) |
|
|
|
|
{ |
|
|
|
|
blockContent[k] = (byte)random.Next(0, 255); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
blocks[j] = Tuple.Create(blockKey, blockContent); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
result[blobName] = Tuple.Create(((long)random.Next()) * random.Next(), blocks); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return result; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |