[#67] Add unit tests
All checks were successful
DCO / DCO (pull_request) Successful in 21s
lint-build / dotnet8.0 (pull_request) Successful in 43s
lint-build / dotnet8.0 (push) Successful in 42s

Signed-off-by: Pavel Gross <p.gross@yadro.com>
This commit is contained in:
Pavel Gross 2025-04-23 00:30:34 +03:00
parent 20586d8ada
commit eebba7665b
13 changed files with 1094 additions and 233 deletions

View file

@ -1,5 +1,3 @@
using FrostFS.SDK;
namespace FrostFS.SDK.Client;
public readonly struct ObjectPartInfo(long offset, int length, FrostFsObjectId objectId) : System.IEquatable<ObjectPartInfo>

View file

@ -3,6 +3,7 @@ namespace FrostFS.SDK;
public class FrostFsResponseStatus(FrostFsStatusCode code, string? message = null, string? details = null)
{
public FrostFsStatusCode Code { get; set; } = code;
public string Message { get; set; } = message ?? string.Empty;
public string Details { get; set; } = details ?? string.Empty;

View file

@ -41,6 +41,8 @@ public class ObjectMocker(string key) : ObjectServiceBase(key)
public Collection<ByteString> RangeHashResponses { get; } = [];
public Action? Callback;
public override Mock<ObjectService.ObjectServiceClient> GetMock()
{
var mock = new Mock<ObjectService.ObjectServiceClient>();
@ -165,9 +167,14 @@ public class ObjectMocker(string key) : ObjectServiceBase(key)
It.IsAny<CancellationToken>()))
.Returns((PutSingleRequest r, Metadata m, DateTime? dt, CancellationToken ct) =>
{
Callback?.Invoke();
Verifier.CheckRequest(r);
PutSingleRequests.Add(r);
var req = r.Clone();
// Clone method does not clone the payload but keeps a reference
req.Body.Object.Payload = ByteString.CopyFrom(r.Body.Object.Payload.ToByteArray());
PutSingleRequests.Add(req);
return new AsyncUnaryCall<PutSingleResponse>(
Task.FromResult(putSingleResponse),

View file

@ -1,4 +1,5 @@
using System.Diagnostics.CodeAnalysis;
using FrostFS.Netmap;
using FrostFS.SDK.Client;
using FrostFS.SDK.Client.Mappers.GRPC;
using FrostFS.SDK.Cryptography;
@ -10,6 +11,27 @@ namespace FrostFS.SDK.Tests.Unit;
[SuppressMessage("Reliability", "CA2007:Consider calling ConfigureAwait on the awaited task", Justification = "Default Value is correct for tests")]
public class ContainerTest : ContainerTestsBase
{
[Theory]
[InlineData(1, "test", 0, 0)]
public void ReplicaToMessagelTest(int count, string selector, uint ecDataCount, uint ecParityCount)
{
FrostFsReplica replica = new()
{
Count = count,
Selector = selector,
EcDataCount = ecDataCount,
EcParityCount = ecParityCount
};
Replica message = replica.ToMessage();
Assert.Equal((uint)count, message.Count);
Assert.Equal(selector, message.Selector);
Assert.Equal(ecDataCount, message.EcDataCount);
Assert.Equal(ecParityCount, message.EcParityCount);
}
[Fact]
public async void CreateContainerTest()
{

View file

@ -0,0 +1,29 @@
using FrostFS.SDK.Client;
using FrostFS.SDK.Client.Mappers.GRPC;
namespace FrostFS.SDK.Tests.Unit;
public class MetaheaderTests
{
[Theory]
[InlineData(2, 13, 1, 1)]
[InlineData(200, 0, 1000000, 8)]
public void MetaheaderTest(int major, int minor, int epoch, int ttl)
{
MetaHeader metaHeader = new MetaHeader(
new FrostFsVersion(
major: 2,
minor: 13
),
epoch: 0,
ttl: 2
);
var result = metaHeader.ToMessage();
Assert.Equal((ulong)metaHeader.Epoch, result.Epoch);
Assert.Equal((ulong)metaHeader.Ttl, result.Ttl);
Assert.Equal((ulong)metaHeader.Version.Major, result.Version.Major);
Assert.Equal((ulong)metaHeader.Version.Minor, result.Version.Minor);
}
}

View file

@ -0,0 +1,101 @@
using FrostFS.Netmap;
using FrostFS.SDK.Client;
using Google.Protobuf;
namespace FrostFS.SDK.Tests.Unit;
public class NetmapSnapshotTests : NetworkTestsBase
{
[Theory]
[InlineData(false)]
[InlineData(true)]
public async void NetmapSnapshotTest(bool useContext)
{
var body = new NetmapSnapshotResponse.Types.Body
{
Netmap = new Netmap.Netmap { Epoch = 99 }
};
var nodeInfo1 = new NodeInfo
{
State = NodeInfo.Types.State.Online,
PublicKey = ByteString.CopyFrom([1, 2, 3])
};
nodeInfo1.Addresses.Add("address1");
nodeInfo1.Addresses.Add("address2");
nodeInfo1.Attributes.Add(new NodeInfo.Types.Attribute { Key = "key1", Value = "value1" });
nodeInfo1.Attributes.Add(new NodeInfo.Types.Attribute { Key = "key2", Value = "value2" });
var nodeInfo2 = new NodeInfo
{
State = NodeInfo.Types.State.Offline,
PublicKey = ByteString.CopyFrom([3, 4, 5])
};
nodeInfo2.Addresses.Add("address3");
nodeInfo2.Attributes.Add(new NodeInfo.Types.Attribute { Key = "key3", Value = "value3" });
body.Netmap.Nodes.Add(nodeInfo1);
body.Netmap.Nodes.Add(nodeInfo2);
Mocker.NetmapSnapshotResponse = new NetmapSnapshotResponse { Body = body };
var ctx = useContext
? new CallContext(TimeSpan.FromSeconds(20), Mocker.CancellationTokenSource.Token)
: default;
var validTimeoutFrom = DateTime.UtcNow.AddSeconds(20);
var result = await GetClient(DefaultSettings).GetNetmapSnapshotAsync(ctx);
var validTimeoutTo = DateTime.UtcNow.AddSeconds(20);
Assert.NotNull(result);
Assert.Equal(99u, result.Epoch);
Assert.Equal(2, result.NodeInfoCollection.Count);
var node1 = result.NodeInfoCollection[0];
Assert.Equal(NodeState.Online, node1.State);
Assert.Equal(2, node1.Addresses.Count);
Assert.Equal("address1", node1.Addresses.ElementAt(0));
Assert.Equal("address2", node1.Addresses.ElementAt(1));
Assert.Equal(2, node1.Attributes.Count);
Assert.Equal("key1", node1.Attributes.ElementAt(0).Key);
Assert.Equal("value1", node1.Attributes.ElementAt(0).Value);
Assert.Equal("key2", node1.Attributes.ElementAt(1).Key);
Assert.Equal("value2", node1.Attributes.ElementAt(1).Value);
var node2 = result.NodeInfoCollection[1];
Assert.Equal(NodeState.Offline, node2.State);
Assert.Single(node2.Addresses);
Assert.Equal("address3", node2.Addresses.ElementAt(0));
Assert.Single(node2.Attributes);
Assert.Equal("key3", node2.Attributes.ElementAt(0).Key);
Assert.Equal("value3", node2.Attributes.ElementAt(0).Value);
if (useContext)
{
Assert.NotNull(Mocker.NetmapSnapshotRequest);
Assert.Empty(Mocker.NetmapSnapshotRequest.MetaHeader.XHeaders);
Assert.Equal(Mocker.CancellationTokenSource.Token, Mocker.CancellationToken);
Assert.NotNull(Mocker.DateTime);
Assert.True(Mocker.DateTime.Value >= validTimeoutFrom);
Assert.True(Mocker.DateTime.Value <= validTimeoutTo);
}
else
{
Assert.NotNull(Mocker.NetmapSnapshotRequest);
Assert.Empty(Mocker.NetmapSnapshotRequest.MetaHeader.XHeaders);
Assert.Null(Mocker.DateTime);
}
}
}

View file

@ -0,0 +1,68 @@
using System.Diagnostics.CodeAnalysis;
using FrostFS.SDK.Client;
namespace FrostFS.SDK.Tests.Unit;
[SuppressMessage("Reliability", "CA2007:Consider calling ConfigureAwait on the awaited task", Justification = "Default Value is correct for tests")]
public class NetworkSettingsTests : NetworkTestsBase
{
[Theory]
[InlineData(false)]
[InlineData(true)]
public async void NetworkSettingsTest(bool useContext)
{
Mocker.Parameters.Add("AuditFee", [1]);
Mocker.Parameters.Add("BasicIncomeRate", [2]);
Mocker.Parameters.Add("ContainerFee", [3]);
Mocker.Parameters.Add("ContainerAliasFee", [4]);
Mocker.Parameters.Add("EpochDuration", [5]);
Mocker.Parameters.Add("InnerRingCandidateFee", [6]);
Mocker.Parameters.Add("MaxECDataCount", [7]);
Mocker.Parameters.Add("MaxECParityCount", [8]);
Mocker.Parameters.Add("MaxObjectSize", [9]);
Mocker.Parameters.Add("WithdrawFee", [10]);
Mocker.Parameters.Add("HomomorphicHashingDisabled", [1]);
Mocker.Parameters.Add("MaintenanceModeAllowed", [1]);
var ctx = useContext
? new CallContext(TimeSpan.FromSeconds(20), Mocker.CancellationTokenSource.Token)
: default;
var validTimeoutFrom = DateTime.UtcNow.AddSeconds(20);
var result = await GetClient(DefaultSettings).GetNetworkSettingsAsync(ctx);
var validTimeoutTo = DateTime.UtcNow.AddSeconds(20);
Assert.NotNull(result);
Assert.Equal(Mocker.Parameters["AuditFee"], [(byte)result.AuditFee]);
Assert.Equal(Mocker.Parameters["BasicIncomeRate"], [(byte)result.BasicIncomeRate]);
Assert.Equal(Mocker.Parameters["ContainerFee"], [(byte)result.ContainerFee]);
Assert.Equal(Mocker.Parameters["ContainerAliasFee"], [(byte)result.ContainerAliasFee]);
Assert.Equal(Mocker.Parameters["EpochDuration"], [(byte)result.EpochDuration]);
Assert.Equal(Mocker.Parameters["InnerRingCandidateFee"], [(byte)result.InnerRingCandidateFee]);
Assert.Equal(Mocker.Parameters["MaxECDataCount"], [(byte)result.MaxECDataCount]);
Assert.Equal(Mocker.Parameters["MaxECParityCount"], [(byte)result.MaxECParityCount]);
Assert.Equal(Mocker.Parameters["MaxObjectSize"], [(byte)result.MaxObjectSize]);
Assert.Equal(Mocker.Parameters["WithdrawFee"], [(byte)result.WithdrawFee]);
Assert.True(result.HomomorphicHashingDisabled);
Assert.True(result.MaintenanceModeAllowed);
if (useContext)
{
Assert.Equal(Mocker.CancellationTokenSource.Token, Mocker.CancellationToken);
Assert.NotNull(Mocker.DateTime);
Assert.True(Mocker.DateTime.Value >= validTimeoutFrom);
Assert.True(Mocker.DateTime.Value <= validTimeoutTo);
}
else
{
Assert.NotNull(Mocker.NetworkInfoRequest);
Assert.Empty(Mocker.NetworkInfoRequest.MetaHeader.XHeaders);
Assert.Null(Mocker.DateTime);
}
}
}

View file

@ -1,225 +0,0 @@
using System.Diagnostics.CodeAnalysis;
using FrostFS.Netmap;
using FrostFS.SDK.Client;
using Google.Protobuf;
namespace FrostFS.SDK.Tests.Unit;
[SuppressMessage("Reliability", "CA2007:Consider calling ConfigureAwait on the awaited task", Justification = "Default Value is correct for tests")]
public class NetworkTest : NetworkTestsBase
{
[Theory]
[InlineData(false)]
[InlineData(true)]
public async void NetworkSettingsTest(bool useContext)
{
Mocker.Parameters.Add("AuditFee", [1]);
Mocker.Parameters.Add("BasicIncomeRate", [2]);
Mocker.Parameters.Add("ContainerFee", [3]);
Mocker.Parameters.Add("ContainerAliasFee", [4]);
Mocker.Parameters.Add("EpochDuration", [5]);
Mocker.Parameters.Add("InnerRingCandidateFee", [6]);
Mocker.Parameters.Add("MaxECDataCount", [7]);
Mocker.Parameters.Add("MaxECParityCount", [8]);
Mocker.Parameters.Add("MaxObjectSize", [9]);
Mocker.Parameters.Add("WithdrawFee", [10]);
Mocker.Parameters.Add("HomomorphicHashingDisabled", [1]);
Mocker.Parameters.Add("MaintenanceModeAllowed", [1]);
var ctx = useContext
? new CallContext(TimeSpan.FromSeconds(20), Mocker.CancellationTokenSource.Token)
: default;
var validTimeoutFrom = DateTime.UtcNow.AddSeconds(20);
var result = await GetClient(DefaultSettings).GetNetworkSettingsAsync(ctx);
var validTimeoutTo = DateTime.UtcNow.AddSeconds(20);
Assert.NotNull(result);
Assert.Equal(Mocker.Parameters["AuditFee"], [(byte)result.AuditFee]);
Assert.Equal(Mocker.Parameters["BasicIncomeRate"], [(byte)result.BasicIncomeRate]);
Assert.Equal(Mocker.Parameters["ContainerFee"], [(byte)result.ContainerFee]);
Assert.Equal(Mocker.Parameters["ContainerAliasFee"], [(byte)result.ContainerAliasFee]);
Assert.Equal(Mocker.Parameters["EpochDuration"], [(byte)result.EpochDuration]);
Assert.Equal(Mocker.Parameters["InnerRingCandidateFee"], [(byte)result.InnerRingCandidateFee]);
Assert.Equal(Mocker.Parameters["MaxECDataCount"], [(byte)result.MaxECDataCount]);
Assert.Equal(Mocker.Parameters["MaxECParityCount"], [(byte)result.MaxECParityCount]);
Assert.Equal(Mocker.Parameters["MaxObjectSize"], [(byte)result.MaxObjectSize]);
Assert.Equal(Mocker.Parameters["WithdrawFee"], [(byte)result.WithdrawFee]);
Assert.True(result.HomomorphicHashingDisabled);
Assert.True(result.MaintenanceModeAllowed);
if (useContext)
{
Assert.Equal(Mocker.CancellationTokenSource.Token, Mocker.CancellationToken);
Assert.NotNull(Mocker.DateTime);
Assert.True(Mocker.DateTime.Value >= validTimeoutFrom);
Assert.True(Mocker.DateTime.Value <= validTimeoutTo);
}
else
{
Assert.NotNull(Mocker.NetworkInfoRequest);
Assert.Empty(Mocker.NetworkInfoRequest.MetaHeader.XHeaders);
Assert.Null(Mocker.DateTime);
}
}
[Theory]
[InlineData(false)]
[InlineData(true)]
public async void NetmapSnapshotTest(bool useContext)
{
var body = new NetmapSnapshotResponse.Types.Body
{
Netmap = new Netmap.Netmap { Epoch = 99 }
};
var nodeInfo1 = new NodeInfo
{
State = NodeInfo.Types.State.Online,
PublicKey = ByteString.CopyFrom([1, 2, 3])
};
nodeInfo1.Addresses.Add("address1");
nodeInfo1.Addresses.Add("address2");
nodeInfo1.Attributes.Add(new NodeInfo.Types.Attribute { Key = "key1", Value = "value1" });
nodeInfo1.Attributes.Add(new NodeInfo.Types.Attribute { Key = "key2", Value = "value2" });
var nodeInfo2 = new NodeInfo
{
State = NodeInfo.Types.State.Offline,
PublicKey = ByteString.CopyFrom([3, 4, 5])
};
nodeInfo2.Addresses.Add("address3");
nodeInfo2.Attributes.Add(new NodeInfo.Types.Attribute { Key = "key3", Value = "value3" });
body.Netmap.Nodes.Add(nodeInfo1);
body.Netmap.Nodes.Add(nodeInfo2);
Mocker.NetmapSnapshotResponse = new NetmapSnapshotResponse { Body = body };
var ctx = useContext
? new CallContext(TimeSpan.FromSeconds(20), Mocker.CancellationTokenSource.Token)
: default;
var validTimeoutFrom = DateTime.UtcNow.AddSeconds(20);
var result = await GetClient(DefaultSettings).GetNetmapSnapshotAsync(ctx);
var validTimeoutTo = DateTime.UtcNow.AddSeconds(20);
Assert.NotNull(result);
Assert.Equal(99u, result.Epoch);
Assert.Equal(2, result.NodeInfoCollection.Count);
var node1 = result.NodeInfoCollection[0];
Assert.Equal(NodeState.Online, node1.State);
Assert.Equal(2, node1.Addresses.Count);
Assert.Equal("address1", node1.Addresses.ElementAt(0));
Assert.Equal("address2", node1.Addresses.ElementAt(1));
Assert.Equal(2, node1.Attributes.Count);
Assert.Equal("key1", node1.Attributes.ElementAt(0).Key);
Assert.Equal("value1", node1.Attributes.ElementAt(0).Value);
Assert.Equal("key2", node1.Attributes.ElementAt(1).Key);
Assert.Equal("value2", node1.Attributes.ElementAt(1).Value);
var node2 = result.NodeInfoCollection[1];
Assert.Equal(NodeState.Offline, node2.State);
Assert.Single(node2.Addresses);
Assert.Equal("address3", node2.Addresses.ElementAt(0));
Assert.Single(node2.Attributes);
Assert.Equal("key3", node2.Attributes.ElementAt(0).Key);
Assert.Equal("value3", node2.Attributes.ElementAt(0).Value);
if (useContext)
{
Assert.NotNull(Mocker.NetmapSnapshotRequest);
Assert.Empty(Mocker.NetmapSnapshotRequest.MetaHeader.XHeaders);
Assert.Equal(Mocker.CancellationTokenSource.Token, Mocker.CancellationToken);
Assert.NotNull(Mocker.DateTime);
Assert.True(Mocker.DateTime.Value >= validTimeoutFrom);
Assert.True(Mocker.DateTime.Value <= validTimeoutTo);
}
else
{
Assert.NotNull(Mocker.NetmapSnapshotRequest);
Assert.Empty(Mocker.NetmapSnapshotRequest.MetaHeader.XHeaders);
Assert.Null(Mocker.DateTime);
}
}
[Theory]
[InlineData(false)]
[InlineData(true)]
public async void NodeInfoTest(bool useContext)
{
var body = new LocalNodeInfoResponse.Types.Body
{
NodeInfo = new NodeInfo()
{
State = NodeInfo.Types.State.Online,
PublicKey = ByteString.CopyFrom([1, 2, 3])
},
Version = new Refs.Version { Major = 2, Minor = 12 }
};
body.NodeInfo.Addresses.Add("address1");
body.NodeInfo.Addresses.Add("address2");
body.NodeInfo.Attributes.Add(new NodeInfo.Types.Attribute { Key = "key1", Value = "value1" });
body.NodeInfo.Attributes.Add(new NodeInfo.Types.Attribute { Key = "key2", Value = "value2" });
Mocker.NodeInfoResponse = new LocalNodeInfoResponse { Body = body };
var ctx = useContext
? new CallContext(TimeSpan.FromSeconds(20), Mocker.CancellationTokenSource.Token)
: default;
var validTimeoutFrom = DateTime.UtcNow.AddSeconds(20);
var result = await GetClient(DefaultSettings).GetNodeInfoAsync(ctx);
var validTimeoutTo = DateTime.UtcNow.AddSeconds(20);
Assert.NotNull(result);
Assert.Equal(NodeState.Online, result.State);
Assert.Equal(2, result.Addresses.Count);
Assert.Equal("address1", result.Addresses.ElementAt(0));
Assert.Equal("address2", result.Addresses.ElementAt(1));
Assert.Equal(2, result.Attributes.Count);
Assert.Equal("value1", result.Attributes["key1"]);
Assert.Equal("value2", result.Attributes["key2"]);
Assert.NotNull(Mocker.LocalNodeInfoRequest);
if (useContext)
{
Assert.Empty(Mocker.LocalNodeInfoRequest.MetaHeader.XHeaders);
Assert.Equal(Mocker.CancellationTokenSource.Token, Mocker.CancellationToken);
Assert.NotNull(Mocker.DateTime);
Assert.True(Mocker.DateTime.Value >= validTimeoutFrom);
Assert.True(Mocker.DateTime.Value <= validTimeoutTo);
}
else
{
Assert.Empty(Mocker.LocalNodeInfoRequest.MetaHeader.XHeaders);
Assert.Null(Mocker.DateTime);
}
}
}

View file

@ -0,0 +1,69 @@
using FrostFS.Netmap;
using FrostFS.SDK.Client;
using Google.Protobuf;
namespace FrostFS.SDK.Tests.Unit;
public class NodeInfoTests : NetworkTestsBase
{
[Theory]
[InlineData(false)]
[InlineData(true)]
public async void NodeInfoTest(bool useContext)
{
var body = new LocalNodeInfoResponse.Types.Body
{
NodeInfo = new NodeInfo()
{
State = NodeInfo.Types.State.Online,
PublicKey = ByteString.CopyFrom([1, 2, 3])
},
Version = new Refs.Version { Major = 2, Minor = 12 }
};
body.NodeInfo.Addresses.Add("address1");
body.NodeInfo.Addresses.Add("address2");
body.NodeInfo.Attributes.Add(new NodeInfo.Types.Attribute { Key = "key1", Value = "value1" });
body.NodeInfo.Attributes.Add(new NodeInfo.Types.Attribute { Key = "key2", Value = "value2" });
Mocker.NodeInfoResponse = new LocalNodeInfoResponse { Body = body };
var ctx = useContext
? new CallContext(TimeSpan.FromSeconds(20), Mocker.CancellationTokenSource.Token)
: default;
var validTimeoutFrom = DateTime.UtcNow.AddSeconds(20);
var result = await GetClient(DefaultSettings).GetNodeInfoAsync(ctx);
var validTimeoutTo = DateTime.UtcNow.AddSeconds(20);
Assert.NotNull(result);
Assert.Equal(NodeState.Online, result.State);
Assert.Equal(2, result.Addresses.Count);
Assert.Equal("address1", result.Addresses.ElementAt(0));
Assert.Equal("address2", result.Addresses.ElementAt(1));
Assert.Equal(2, result.Attributes.Count);
Assert.Equal("value1", result.Attributes["key1"]);
Assert.Equal("value2", result.Attributes["key2"]);
Assert.NotNull(Mocker.LocalNodeInfoRequest);
if (useContext)
{
Assert.Empty(Mocker.LocalNodeInfoRequest.MetaHeader.XHeaders);
Assert.Equal(Mocker.CancellationTokenSource.Token, Mocker.CancellationToken);
Assert.NotNull(Mocker.DateTime);
Assert.True(Mocker.DateTime.Value >= validTimeoutFrom);
Assert.True(Mocker.DateTime.Value <= validTimeoutTo);
}
else
{
Assert.Empty(Mocker.LocalNodeInfoRequest.MetaHeader.XHeaders);
Assert.Null(Mocker.DateTime);
}
}
}

View file

@ -6,8 +6,9 @@ using System.Text;
using FrostFS.Refs;
using FrostFS.SDK.Client;
using FrostFS.SDK.Client.Mappers.GRPC;
using FrostFS.SDK.Cryptography;
using Google.Protobuf;
using Org.BouncyCastle.Utilities;
namespace FrostFS.SDK.Tests.Unit;
@ -60,7 +61,7 @@ public class ObjectTest : ObjectTestsBase
var param = new PrmObjectClientCutPut(
Mocker.ObjectHeader,
payload: new MemoryStream(bytes),
bufferMaxSize: 1024);
bufferMaxSize: blockSize);
Random rnd = new();
@ -87,7 +88,7 @@ public class ObjectTest : ObjectTestsBase
// PART1
Assert.Equal(blockSize, objects[0].Payload.Length);
Assert.True(bytes.AsMemory(0, blockSize).ToArray().SequenceEqual(objects[0].Payload));
Assert.Equal(bytes.AsMemory(0, blockSize).ToArray(), objects[0].Payload);
Assert.NotNull(objects[0].Header.Split.SplitId);
Assert.Null(objects[0].Header.Split.Previous);
@ -96,7 +97,7 @@ public class ObjectTest : ObjectTestsBase
// PART2
Assert.Equal(blockSize, objects[1].Payload.Length);
Assert.True(bytes.AsMemory(blockSize, blockSize).ToArray().SequenceEqual(objects[1].Payload));
Assert.Equal(bytes.AsMemory(blockSize, blockSize).ToArray(), objects[1].Payload);
Assert.Equal(objects[0].Header.Split.SplitId, objects[1].Header.Split.SplitId);
Assert.True(objects[1].Header.Attributes.Count == 0);
@ -104,7 +105,7 @@ public class ObjectTest : ObjectTestsBase
// last part
Assert.Equal(bytes.Length % blockSize, objects[2].Payload.Length);
Assert.True(bytes.AsMemory(2 * blockSize).ToArray().SequenceEqual(objects[2].Payload));
Assert.Equal(bytes.AsMemory(2 * blockSize).ToArray(), objects[2].Payload);
Assert.NotNull(objects[3].Header.Split.Parent);
Assert.NotNull(objects[3].Header.Split.ParentHeader);
@ -128,6 +129,351 @@ public class ObjectTest : ObjectTestsBase
Assert.Equal(result.Value, modelObjId.ToString());
}
[Fact]
public async void ClientCutWithInterruptionOnFirstPartTest()
{
NetworkMocker.Parameters.Add("MaxObjectSize", [0x0, 0xa]);
var blockSize = 2560;
byte[] bytes = File.ReadAllBytes(@".\..\..\..\cat.jpg");
var fileLength = bytes.Length;
var splitId = Guid.NewGuid();
var progress = new UploadProgressInfo(splitId);
var param = new PrmObjectClientCutPut(
Mocker.ObjectHeader,
payload: new MemoryStream(bytes),
bufferMaxSize: blockSize,
progress: progress);
Random rnd = new();
Collection<byte[]> objIds = new([new byte[32], new byte[32], new byte[32]]);
rnd.NextBytes(objIds.ElementAt(0));
rnd.NextBytes(objIds.ElementAt(1));
rnd.NextBytes(objIds.ElementAt(2));
foreach (var objId in objIds)
Mocker.ResultObjectIds!.Add(objId);
int sentBlockCount = 0;
Mocker.Callback = () =>
{
if (++sentBlockCount == 1)
throw new FrostFsException("some error");
};
bool gotException = false;
try
{
var result = await GetClient().PutClientCutObjectAsync(param, default);
}
catch (FrostFsException ex)
{
if (ex.Message == "some error")
gotException = true;
}
Assert.True(gotException);
var singleObjects = Mocker.PutSingleRequests.ToArray();
Assert.Empty(singleObjects);
}
[Fact]
public async void ClientCutWithInterruptionOnMiddlePartTest()
{
NetworkMocker.Parameters.Add("MaxObjectSize", [0x0, 0xa]);
var blockSize = 2560;
byte[] bytes = File.ReadAllBytes(@".\..\..\..\cat.jpg");
var fileLength = bytes.Length;
var splitId = Guid.Parse("67e4bbe9-86ca-474d-9385-6569ce89db61");
var progress = new UploadProgressInfo(splitId);
var param = new PrmObjectClientCutPut(
Mocker.ObjectHeader,
payload: new MemoryStream(bytes),
bufferMaxSize: blockSize,
progress: progress);
Random rnd = new();
Collection<byte[]> objIds = new([new byte[32], new byte[32], new byte[32]]);
rnd.NextBytes(objIds.ElementAt(0));
rnd.NextBytes(objIds.ElementAt(1));
rnd.NextBytes(objIds.ElementAt(2));
foreach (var objId in objIds)
Mocker.ResultObjectIds!.Add(objId);
int sentBlockCount = 0;
Mocker.Callback = () =>
{
if (++sentBlockCount == 2)
throw new FrostFsException("some error");
};
bool gotException = false;
try
{
_ = await GetClient().PutClientCutObjectAsync(param, default);
}
catch (FrostFsException ex)
{
if (ex.Message == "some error")
gotException = true;
}
Assert.True(gotException);
var singleObjects = Mocker.PutSingleRequests.ToArray();
Assert.NotNull(Mocker.ClientStreamWriter?.Messages);
var objects = Mocker.PutSingleRequests.Select(o => o.Body.Object).ToArray();
Assert.Single(objects);
Assert.Single(progress.GetParts());
var part = progress.GetPart(0);
Assert.Equal(0, part.Offset);
Assert.Equal(2560, part.Length);
// PART1
Assert.Equal(blockSize, objects[0].Payload.Length);
Assert.Equal(bytes.AsMemory(0, blockSize).ToArray(), objects[0].Payload);
Assert.NotNull(objects[0].Header.Split.SplitId);
Assert.Null(objects[0].Header.Split.Previous);
Assert.True(objects[0].Header.Attributes.Count == 0);
Assert.Null(objects[0].Header.Split.Parent);
// resume uploading
sentBlockCount = 10;
var result = await GetClient().PutClientCutObjectAsync(param, default);
singleObjects = Mocker.PutSingleRequests.ToArray();
Assert.NotNull(Mocker.ClientStreamWriter?.Messages);
objects = Mocker.PutSingleRequests.Select(o => o.Body.Object).ToArray();
Assert.Equal(4, objects.Length);
// PART1
Assert.Equal(blockSize, objects[0].Payload.Length);
Assert.Equal(bytes.AsMemory(0, blockSize).ToArray(), objects[0].Payload);
Assert.NotNull(objects[0].Header.Split.SplitId);
Assert.Null(objects[0].Header.Split.Previous);
Assert.True(objects[0].Header.Attributes.Count == 0);
Assert.Null(objects[0].Header.Split.Parent);
// PART2
Assert.Equal(blockSize, objects[1].Payload.Length);
Assert.Equal(bytes.AsMemory(blockSize, blockSize).ToArray(), objects[1].Payload);
Assert.Equal(objects[0].Header.Split.SplitId, objects[1].Header.Split.SplitId);
Assert.True(objects[1].Header.Attributes.Count == 0);
Assert.Null(objects[1].Header.Split.Parent);
// last part
Assert.Equal(bytes.Length % blockSize, objects[2].Payload.Length);
Assert.Equal(bytes.AsMemory(2 * blockSize).ToArray(), objects[2].Payload);
Assert.NotNull(objects[3].Header.Split.Parent);
Assert.NotNull(objects[3].Header.Split.ParentHeader);
Assert.NotNull(objects[3].Header.Split.ParentSignature);
Assert.Equal(objects[2].Header.Split.SplitId, objects[3].Header.Split.SplitId);
Assert.True(objects[2].Header.Attributes.Count == 0);
// link object
Assert.Equal(objects[2].Header.Split.Parent, objects[3].Header.Split.Parent);
Assert.Equal(objects[2].Header.Split.ParentHeader, objects[3].Header.Split.ParentHeader);
Assert.Equal(objects[2].Header.Split.SplitId, objects[3].Header.Split.SplitId);
Assert.Equal(0, (int)objects[3].Header.PayloadLength);
Assert.True(objects[3].Header.Attributes.Count == 0);
Assert.Single(objects[3].Header.Split.ParentHeader.Attributes);
Assert.Equal("k", objects[3].Header.Split.ParentHeader.Attributes[0].Key);
Assert.Equal("v", objects[3].Header.Split.ParentHeader.Attributes[0].Value);
var modelObjId = FrostFsObjectId.FromHash(objects[3].Header.Split.Parent.Value.ToByteArray());
Assert.Equal(result.Value, modelObjId.ToString());
Assert.Equal(3, progress.GetParts().Count);
part = progress.GetPart(0);
Assert.Equal(0, part.Offset);
Assert.Equal(2560, part.Length);
part = progress.GetPart(1);
Assert.Equal(2560, part.Offset);
Assert.Equal(2560, part.Length);
part = progress.GetPart(2);
Assert.Equal(2 * 2560, part.Offset);
Assert.Equal(1620, part.Length);
}
[Fact]
public async void ClientCutWithInterruptionOnLastPartTest()
{
NetworkMocker.Parameters.Add("MaxObjectSize", [0x0, 0xa]);
var blockSize = 2560;
byte[] bytes = File.ReadAllBytes(@".\..\..\..\cat.jpg");
var fileLength = bytes.Length;
var splitId = Guid.Parse("67e4bbe9-86ca-474d-9385-6569ce89db61");
var progress = new UploadProgressInfo(splitId);
var param = new PrmObjectClientCutPut(
Mocker.ObjectHeader,
payload: new MemoryStream(bytes),
bufferMaxSize: blockSize,
progress: progress);
Random rnd = new();
Collection<byte[]> objIds = new([new byte[32], new byte[32], new byte[32]]);
rnd.NextBytes(objIds.ElementAt(0));
rnd.NextBytes(objIds.ElementAt(1));
rnd.NextBytes(objIds.ElementAt(2));
foreach (var objId in objIds)
Mocker.ResultObjectIds!.Add(objId);
int sentBlockCount = 0;
Mocker.Callback = () =>
{
if (++sentBlockCount == 3)
throw new FrostFsException("some error");
};
bool gotException = false;
try
{
_ = await GetClient().PutClientCutObjectAsync(param, default);
}
catch (FrostFsException ex)
{
if (ex.Message == "some error")
gotException = true;
}
Assert.True(gotException);
var singleObjects = Mocker.PutSingleRequests.ToArray();
Assert.NotNull(Mocker.ClientStreamWriter?.Messages);
var objects = Mocker.PutSingleRequests.Select(o => o.Body.Object).ToArray();
Assert.Equal(2, objects.Length);
Assert.Equal(2, progress.GetParts().Count);
var part = progress.GetPart(0);
Assert.Equal(0, part.Offset);
Assert.Equal(2560, part.Length);
part = progress.GetPart(1);
Assert.Equal(2560, part.Offset);
Assert.Equal(2560, part.Length);
// PART1
Assert.Equal(blockSize, objects[0].Payload.Length);
Assert.Equal(bytes.AsMemory(0, blockSize).ToArray(), objects[0].Payload);
Assert.NotNull(objects[0].Header.Split.SplitId);
Assert.Null(objects[0].Header.Split.Previous);
Assert.True(objects[0].Header.Attributes.Count == 0);
Assert.Null(objects[0].Header.Split.Parent);
// PART2
Assert.Equal(blockSize, objects[1].Payload.Length);
Assert.Equal(bytes.AsMemory(blockSize, blockSize).ToArray(), objects[1].Payload);
Assert.Equal(objects[0].Header.Split.SplitId, objects[1].Header.Split.SplitId);
Assert.True(objects[1].Header.Attributes.Count == 0);
Assert.Null(objects[1].Header.Split.Parent);
// resume uploading
sentBlockCount = 10;
var result = await GetClient().PutClientCutObjectAsync(param, default);
singleObjects = Mocker.PutSingleRequests.ToArray();
Assert.NotNull(Mocker.ClientStreamWriter?.Messages);
objects = Mocker.PutSingleRequests.Select(o => o.Body.Object).ToArray();
Assert.Equal(4, objects.Length);
// PART1
Assert.Equal(blockSize, objects[0].Payload.Length);
Assert.Equal(bytes.AsMemory(0, blockSize).ToArray(), objects[0].Payload);
Assert.NotNull(objects[0].Header.Split.SplitId);
Assert.Null(objects[0].Header.Split.Previous);
Assert.True(objects[0].Header.Attributes.Count == 0);
Assert.Null(objects[0].Header.Split.Parent);
// PART2
Assert.Equal(blockSize, objects[1].Payload.Length);
Assert.Equal(bytes.AsMemory(blockSize, blockSize).ToArray(), objects[1].Payload);
Assert.Equal(objects[0].Header.Split.SplitId, objects[1].Header.Split.SplitId);
Assert.True(objects[1].Header.Attributes.Count == 0);
Assert.Null(objects[1].Header.Split.Parent);
// last part
Assert.Equal(bytes.Length % blockSize, objects[2].Payload.Length);
Assert.Equal(bytes.AsMemory(2 * blockSize).ToArray(), objects[2].Payload);
Assert.NotNull(objects[3].Header.Split.Parent);
Assert.NotNull(objects[3].Header.Split.ParentHeader);
Assert.NotNull(objects[3].Header.Split.ParentSignature);
Assert.Equal(objects[2].Header.Split.SplitId, objects[3].Header.Split.SplitId);
Assert.True(objects[2].Header.Attributes.Count == 0);
// link object
Assert.Equal(objects[2].Header.Split.Parent, objects[3].Header.Split.Parent);
Assert.Equal(objects[2].Header.Split.ParentHeader, objects[3].Header.Split.ParentHeader);
Assert.Equal(objects[2].Header.Split.SplitId, objects[3].Header.Split.SplitId);
Assert.Equal(0, (int)objects[3].Header.PayloadLength);
Assert.True(objects[3].Header.Attributes.Count == 0);
Assert.Single(objects[3].Header.Split.ParentHeader.Attributes);
Assert.Equal("k", objects[3].Header.Split.ParentHeader.Attributes[0].Key);
Assert.Equal("v", objects[3].Header.Split.ParentHeader.Attributes[0].Value);
var modelObjId = FrostFsObjectId.FromHash(objects[3].Header.Split.Parent.Value.ToByteArray());
Assert.Equal(result.Value, modelObjId.ToString());
Assert.Equal(3, progress.GetParts().Count);
part = progress.GetPart(0);
Assert.Equal(0, part.Offset);
Assert.Equal(2560, part.Length);
part = progress.GetPart(1);
Assert.Equal(2560, part.Offset);
Assert.Equal(2560, part.Length);
part = progress.GetPart(2);
Assert.Equal(2 * 2560, part.Offset);
Assert.Equal(1620, part.Length);
}
[Fact]
public async void DeleteObject()
{

View file

@ -0,0 +1,99 @@
using System.Security.Cryptography;
using System.Text;
using FrostFS.SDK.Client;
using FrostFS.SDK.Cryptography;
namespace FrostFS.SDK.Tests.Unit;
public class ObjectToolsTests
{
internal readonly string key = "KwHDAJ66o8FoLBjVbjP2sWBmgBMGjt7Vv4boA7xQrBoAYBE397Aq";
[Fact]
public void CalculateObjectIdTest()
{
var payload = Encoding.UTF8.GetBytes("testPayload");
var payloadHash = SHA256.HashData(payload);
FrostFsContainerId containerId = new("test");
FrostFsObjectHeader header = new(containerId);
var ecdsaKey = key.LoadWif();
var owner = FrostFsOwner.FromKey(ecdsaKey);
var clientKey = new ClientKey(ecdsaKey);
var objId = ObjectTools.CalculateObjectId(header, payloadHash, owner, new FrostFsVersion(2, 13), clientKey);
Assert.NotNull(objId.Value);
Assert.Equal("HuAojwCYi62iUKr1FtSCCkMLLWv1uAnznF8iSb1bRV1N", objId.Value);
}
[Fact]
public void CalculateObjectIdTest1()
{
var payload = Encoding.UTF8.GetBytes("testPayload");
var payloadHash = SHA256.HashData(payload);
var ecdsaKey = key.LoadWif();
var owner = FrostFsOwner.FromKey(ecdsaKey);
var clientKey = new ClientKey(ecdsaKey);
FrostFsContainerId containerId = new("test");
FrostFsObjectHeader header = new(containerId, FrostFsObjectType.Regular, null, null, owner, new FrostFsVersion(2, 13));
var objId = ObjectTools.CalculateObjectId(header, payloadHash, owner, new FrostFsVersion(2, 13), clientKey);
Assert.NotNull(objId.Value);
Assert.Equal("HuAojwCYi62iUKr1FtSCCkMLLWv1uAnznF8iSb1bRV1N", objId.Value);
}
[Fact]
public void CalculateObjectIdWithAttrTest()
{
var payload = Encoding.UTF8.GetBytes("testPayload");
var payloadHash = SHA256.HashData(payload);
var ecdsaKey = key.LoadWif();
var owner = FrostFsOwner.FromKey(ecdsaKey);
var clientKey = new ClientKey(ecdsaKey);
FrostFsContainerId containerId = new("test");
FrostFsAttributePair[] attribs = [new("key", "val")];
FrostFsObjectHeader header = new(containerId, FrostFsObjectType.Regular, attribs, null, owner, new FrostFsVersion(2, 13));
var objId = ObjectTools.CalculateObjectId(header, payloadHash, owner, new FrostFsVersion(2, 13), clientKey);
Assert.NotNull(objId.Value);
Assert.Equal("4zq5NYEbzkrfmdKne3GnpavE24gU2PnuV17ZExb9hcn3", objId.Value);
}
[Fact]
public void CalculateObjectIdWithSplitIdTest()
{
var payload = Encoding.UTF8.GetBytes("testPayload");
var payloadHash = SHA256.HashData(payload);
var ecdsaKey = key.LoadWif();
var owner = FrostFsOwner.FromKey(ecdsaKey);
var clientKey = new ClientKey(ecdsaKey);
FrostFsContainerId containerId = new("test");
FrostFsAttributePair[] attribs = [new("key", "val")];
var guid = Guid.Parse("790a8d04-f5c3-4cd6-b46f-a78ee7e325f2");
SplitId splitId = new(guid);
FrostFsSplit split = new (splitId);
FrostFsObjectHeader header = new(containerId, FrostFsObjectType.Regular, attribs, split, owner, new FrostFsVersion(2, 13));
var objId = ObjectTools.CalculateObjectId(header, payloadHash, owner, new FrostFsVersion(2, 13), clientKey);
Assert.NotNull(objId.Value);
Assert.Equal("HCYzsuXyfe5LmQzi58hPQxExGPAFv7dU5TzEACLxM1os", objId.Value);
}
}

View file

@ -0,0 +1,307 @@
using System.Xml.Linq;
using FrostFS.Netmap;
using FrostFS.SDK.Client;
using Google.Protobuf.WellKnownTypes;
namespace FrostFS.SDK.Tests.Unit;
public class PlacementPolicyTests : NetworkTestsBase
{
[Theory]
[InlineData(true, 1)]
[InlineData(true, 3)]
[InlineData(true, 5)]
[InlineData(false, 1)]
[InlineData(false, 3)]
[InlineData(false, 5)]
public void PlacementPolicySimpleFullTest(bool unique, uint backupFactor)
{
PlacementPolicy policy = new()
{
ContainerBackupFactor = backupFactor,
Unique = unique
};
var result = policy.ToModel();
Assert.Equal(backupFactor, result.BackupFactor);
Assert.Equal(unique, result.Unique);
Assert.Empty(result.Filters);
Assert.Empty(result.Replicas);
Assert.Empty(result.Selectors);
}
[Fact]
public void PlacementPolicyFullTest()
{
PlacementPolicy policy = new()
{
ContainerBackupFactor = 3,
Unique = true
};
policy.Filters.AddRange(
[
new () { Name = "filter1", Key = "filterKey1", Op =Operation.Eq, Value = "testValue1" },
new () { Name = "filter2", Key = "filterKey2", Op =Operation.And, Value = "testValue2" }
]);
policy.Selectors.AddRange(
[
new () { Name = "name1", Attribute = "attrib1", Clause = Clause.Same, Count = 5, Filter = "filter1" },
new () { Name = "name2", Attribute = "attrib2", Clause = Clause.Distinct, Count = 4, Filter = "filter2" }
]);
policy.Replicas.AddRange(
[
new () { EcDataCount = 2, EcParityCount = 3, Count = 4, Selector = "selector1"},
new () { EcDataCount = 5, EcParityCount = 6, Count = 7, Selector = "selector2"},
]);
var result = policy.ToModel();
Assert.Equal(3L, result.BackupFactor);
Assert.True(result.Unique);
Assert.Equal(2, result.Filters.Count);
Assert.Equal(2, result.Replicas.Length);
Assert.Equal(2, result.Selectors.Count);
var rep0 = result.Replicas[0];
Assert.Equal(2u, rep0.EcDataCount);
Assert.Equal(3u, rep0.EcParityCount);
Assert.Equal(4, rep0.Count);
Assert.Equal("selector1", rep0.Selector);
var rep1 = result.Replicas[1];
Assert.Equal(5u, rep1.EcDataCount);
Assert.Equal(6u, rep1.EcParityCount);
Assert.Equal(7, rep1.Count);
Assert.Equal("selector2", rep1.Selector);
var f0 = result.Filters[0];
Assert.Equal("filterKey1", f0.Key);
Assert.Equal("filter1", f0.Name);
Assert.Equal(1, f0.Operation);
Assert.Equal("testValue1", f0.Value);
var f1 = result.Filters[1];
Assert.Equal("filterKey2", f1.Key);
Assert.Equal("filter2", f1.Name);
Assert.Equal(8, f1.Operation);
Assert.Equal("testValue2", f1.Value);
var s0 = result.Selectors[0];
Assert.Equal("name1", s0.Name);
Assert.Equal("attrib1", s0.Attribute);
Assert.Equal(1, s0.Clause);
Assert.Equal(5L, s0.Count);
Assert.Equal("filter1", s0.Filter);
var s1 = result.Selectors[1];
Assert.Equal("name2", s1.Name);
Assert.Equal("attrib2", s1.Attribute);
Assert.Equal(2, s1.Clause);
Assert.Equal(4L, s1.Count);
Assert.Equal("filter2", s1.Filter);
}
[Theory]
[InlineData(1, "test" , 0, 0)]
[InlineData(1, "", 1000, 9999)]
[InlineData(1, "some long text to test reasonable length of the selector name", 100000000, 100000001)]
[InlineData(100, "test2", 1, 1)]
[InlineData(1, " ", 2, 3)]
[InlineData(10, "!", 0, 0)]
[InlineData(1, "123", 0, 0)]
public void ReplicaToModelTest(uint count, string selector, uint ecDataCount, uint ecParityCount)
{
Replica replica = new ()
{
Count = count,
Selector = selector,
EcDataCount = ecDataCount,
EcParityCount = ecParityCount
};
FrostFsReplica model = replica.ToModel();
Assert.Equal(count, (uint)model.Count);
Assert.Equal(selector, model.Selector);
Assert.Equal(ecDataCount, model.EcDataCount);
Assert.Equal(ecParityCount, model.EcParityCount);
}
[Theory]
[InlineData(1, "test", 0, 0)]
[InlineData(1, "", 1000, 9999)]
[InlineData(1, "some long text to test reasonable length of the selector name", 100000000, 100000001)]
[InlineData(100, "test2", 1, 1)]
[InlineData(1, " ", 2, 3)]
[InlineData(10, "!", 0, 0)]
[InlineData(1, "123", 0, 0)]
public void ReplicaToMessagelTest(int count, string selector, uint ecDataCount, uint ecParityCount)
{
FrostFsReplica replica = new ()
{
Count = count,
Selector = selector,
EcDataCount = ecDataCount,
EcParityCount = ecParityCount
};
Replica message = replica.ToMessage();
Assert.Equal((uint)count, message.Count);
Assert.Equal(selector, message.Selector);
Assert.Equal(ecDataCount, message.EcDataCount);
Assert.Equal(ecParityCount, message.EcParityCount);
}
[Theory]
[InlineData("test", 1, 2, "attribute", "filter")]
[InlineData("test", 0, 0, "longlonglonglonglonglonglonglonglonglonglonglonglong attribute", "longlonglonglonglonglonglonglonglonglonglonglonglong filter")]
[InlineData("test", 0, 1, "attribute", "filter")]
public void SelectorToMessageTest(string name, uint count, int clause, string attr, string filter)
{
FrostFsSelector selector = new (name)
{
Count = count,
Clause = clause,
Attribute = attr,
Filter = filter,
};
var message = selector.ToMessage();
Assert.Equal(name, message.Name);
Assert.Equal(count, message.Count);
Assert.Equal(clause, (int)message.Clause);
Assert.Equal(attr, message.Attribute);
Assert.Equal(filter, message.Filter);
}
[Theory]
[InlineData("test", 1, Clause.Same, "attribute", "filter")]
[InlineData("test", 0, Clause.Distinct, "longlonglonglonglonglonglonglonglonglonglonglonglong attribute", "longlonglonglonglonglonglonglonglonglonglonglonglong filter")]
public void SelectorToModelTest(string name, uint count, Clause clause, string attr, string filter)
{
Selector selector = new ()
{
Name = name,
Count = count,
Clause = clause,
Attribute = attr,
Filter = filter
};
var model = selector.ToModel();
Assert.Equal(name, model.Name);
Assert.Equal(count, model.Count);
Assert.Equal((int)clause, model.Clause);
Assert.Equal(attr, model.Attribute);
Assert.Equal(filter, model.Filter);
}
[Theory]
[InlineData("", "", 1, "")]
[InlineData("name", "key", 1, "val")]
[InlineData("longlonglonglonglonglonglonglonglonglonglonglonglong name", "longlonglonglonglonglonglonglonglonglonglonglonglong key", 10, "longlonglonglonglonglonglonglonglonglonglonglonglong val")]
public void FilterToMessageTest(string name, string key, int operation, string value)
{
FrostFsFilter filter = new (name, key, operation, value, []);
var message = filter.ToMessage();
Assert.Equal(name, message.Name);
Assert.Equal(key, message.Key);
Assert.Equal(operation, (int)message.Op);
Assert.Equal(value, message.Value);
}
[Theory]
[InlineData("", "", 1, "")]
[InlineData("name", "key", 2, "val")]
[InlineData("longlonglonglonglonglonglonglonglonglonglonglonglong name", "longlonglonglonglonglonglonglonglonglonglonglonglong key", 10, "longlonglonglonglonglonglonglonglonglonglonglonglong val")]
public void SubFilterToMessageTest(string name, string key, int operation, string value)
{
FrostFsFilter subFilter = new(name, key, operation, value, []);
FrostFsFilter filter = new("name", "key", 1, "value", [subFilter]);
var message = filter.ToMessage();
Assert.Single(message.Filters);
var subfilter = message.Filters[0];
Assert.Equal(name, subfilter.Name);
Assert.Equal(key, subfilter.Key);
Assert.Equal(operation, (int)subfilter.Op);
Assert.Equal(value, subfilter.Value);
}
[Fact]
public void SubFiltersToMessageTest()
{
string[] names = ["", "name1", "some pretty long name for name test"];
string[] keys = ["", "key1", "some pretty long key for name test"];
int[] operations = [1, 2, 10];
string[] values = ["", "val1", "some pretty long value for name test"];
var subFilter = new FrostFsFilter[3];
for (int i = 0; i < 3; i++)
{
subFilter[i] = new FrostFsFilter(names[i], keys[i], operations[i], values[i], []);
}
FrostFsFilter filter = new("name", "key", 1, "value", subFilter);
var message = filter.ToMessage();
Assert.Equal(3, message.Filters.Count);
for (int i = 0; i < 3; i++)
{
var subfilter = message.Filters[i];
Assert.Equal(names[i], subfilter.Name);
Assert.Equal(keys[i], subfilter.Key);
Assert.Equal(operations[i], (int)subfilter.Op);
Assert.Equal(values[i], subfilter.Value);
}
}
[Theory]
[InlineData("", "", Operation.Unspecified, "")]
[InlineData("name", "key", Operation.Unspecified, "val")]
[InlineData("name", "key", Operation.And, "val")]
[InlineData("name", "key", Operation.Eq, "val")]
[InlineData("name", "key", Operation.Le, "val")]
[InlineData("name", "key", Operation.Like, "val")]
[InlineData("name", "key", Operation.Ge, "val")]
[InlineData("name", "key", Operation.Gt, "val")]
[InlineData("name", "key", Operation.Lt, "val")]
[InlineData("name", "key", Operation.Ne, "val")]
[InlineData("name", "key", Operation.Not, "val")]
[InlineData("name", "key", Operation.Or, "val")]
[InlineData("longlonglonglonglonglonglonglonglonglonglonglonglong name", "longlonglonglonglonglonglonglonglonglonglonglonglong key", Operation.Like, "longlonglonglonglonglonglonglonglonglonglonglonglong val")]
public void FrostFsFilterToModelTest(string name, string key, Operation operation, string value)
{
Filter filter = new()
{
Name = name,
Key = key,
Op = operation,
Value = value
};
var model = filter.ToModel();
Assert.Equal(name, model.Name);
Assert.Equal(key, model.Key);
Assert.Equal((int)operation, model.Operation);
Assert.Equal(value, model.Value);
}
}

View file

@ -0,0 +1,39 @@
using System.Text;
using FrostFS.SDK.Client;
using FrostFS.SDK.Client.Mappers.GRPC;
namespace FrostFS.SDK.Tests.Unit;
public class SignatureTests
{
[Theory]
[InlineData(Refs.SignatureScheme.EcdsaSha512)]
[InlineData(Refs.SignatureScheme.EcdsaRfc6979Sha256)]
[InlineData(Refs.SignatureScheme.EcdsaRfc6979Sha256WalletConnect)]
public void SignatureToMessageTest(Refs.SignatureScheme scheme)
{
var key = Encoding.UTF8.GetBytes("datafortest");
var sign = Encoding.UTF8.GetBytes("signdatafortest");
var frostFsScheme = scheme switch
{
Refs.SignatureScheme.EcdsaRfc6979Sha256 => SignatureScheme.EcdsaRfc6979Sha256,
Refs.SignatureScheme.EcdsaRfc6979Sha256WalletConnect => SignatureScheme.EcdsaRfc6979Sha256WalletConnect,
Refs.SignatureScheme.EcdsaSha512 => SignatureScheme.EcdsaSha512
};
FrostFsSignature signature = new()
{
Key = key,
Scheme = frostFsScheme,
Sign = sign
};
var result = signature.ToMessage();
Assert.Equal(scheme, result.Scheme);
Assert.Equal(sign, result.Sign.ToByteArray());
Assert.Equal(key, result.Key.ToByteArray());
}
}