[#34] Client: Add rules deserialization
All checks were successful
DCO / DCO (pull_request) Successful in 23s
lint-build / dotnet8.0 (pull_request) Successful in 44s
lint-build / dotnet8.0 (push) Successful in 43s

Signed-off-by: Pavel Gross <p.gross@yadro.com>
This commit is contained in:
Pavel Gross 2025-02-27 17:35:19 +03:00
parent bd8eb7cc60
commit 8835b23ed3
18 changed files with 426 additions and 52 deletions

View file

@ -1,8 +1,10 @@
using System.Diagnostics.CodeAnalysis;
using FrostFS.SDK.Client;
using FrostFS.SDK.SmokeTests;
namespace FrostFS.SDK.Tests.Smoke;
[SuppressMessage("Reliability", "CA2007:Consider calling ConfigureAwait on the awaited task", Justification = "Default Value is correct for tests")]
public class InterceptorTests() : SmokeTestsBase
{
[Fact]

View file

@ -124,11 +124,16 @@ public class ObjectTests(ITestOutputHelper testOutputHelper) : SmokeTestsBase
var hashes = await client.GetRangeHashAsync(rangeParam, default);
var objectRange = bytes.AsMemory().Slice(100, 64).ToArray();
var expectedHash = SHA256.HashData(objectRange);
foreach (var h in hashes)
{
var x = h[..32].ToArray();
Assert.NotNull(x);
Assert.True(x.Length > 0);
// Assert.True(expectedHash.SequenceEqual(h.ToArray()));
}
}

View file

@ -6,8 +6,6 @@ using FrostFS.SDK.Client.Interfaces;
using FrostFS.SDK.Cryptography;
using FrostFS.SDK.SmokeTests;
using Microsoft.Extensions.Options;
namespace FrostFS.SDK.Tests.Smoke;
[SuppressMessage("Reliability", "CA2007:Consider calling ConfigureAwait on the awaited task", Justification = "Default Value is correct for tests")]

View file

@ -1,7 +1,6 @@
using System.Collections.ObjectModel;
using System.Diagnostics.CodeAnalysis;
using System.Security.Cryptography;
using System.Security.Principal;
using System.Text;
using FrostFS.SDK.Client;
using FrostFS.SDK.Client.Interfaces;
@ -10,7 +9,6 @@ using FrostFS.SDK.Cryptography;
using Grpc.Core;
using Microsoft.Extensions.Options;
using Xunit.Abstractions;
namespace FrostFS.SDK.Tests.Smoke;
@ -121,7 +119,7 @@ public abstract class SmokeTestsBase
{
Status = RuleStatus.Allow,
Actions = new Actions(inverted: false, names: ["*"]),
Resources = new Resource (inverted: false, names: [$"native:object/*"]),
Resources = new Resources (inverted: false, names: [$"native:object/*"]),
Any = false,
Conditions = []
}

View file

@ -0,0 +1,167 @@
using System.Text;
using FrostFS.SDK.Client;
namespace FrostFS.SDK.Tests.Unit;
public class ApeTests : ContainerTestsBase
{
[Fact]
public void ApeRule1Test()
{
var chain = new FrostFsChain
{
ID = Encoding.ASCII.GetBytes("chain-id-test"),
Rules = [
new FrostFsRule
{
Status = RuleStatus.Allow,
Actions = new Actions(inverted: false, names: ["*"]),
Resources = new Resources (inverted: false, names: [$"native:object/*"]),
Any = false,
Conditions = []
}
],
MatchType = RuleMatchType.DenyPriority
};
var serialized = RuleSerializer.Serialize(chain);
var restoredChain = RuleSerializer.Deserialize(serialized);
Assert.True(chain.ID.SequenceEqual(restoredChain.ID));
Assert.Equal(chain.MatchType, restoredChain.MatchType);
CompareRules(chain.Rules, restoredChain.Rules);
}
[Fact]
public void ApeRule2Test()
{
var chain = new FrostFsChain
{
ID = Encoding.ASCII.GetBytes("dumptext"),
Rules = [
new FrostFsRule
{
Status = RuleStatus.AccessDenied,
Actions = new Actions(inverted: true, names: ["put,get"]),
Resources = new Resources (inverted: true, names: [$"native:object/*,blablabla"]),
Any = true,
Conditions = [
new () {
Key = "key",
Value = "value",
Kind = ConditionKindType.Resource,
Op = ConditionType.CondStringEquals
},
new () {
Key = "key1",
Value = "value1",
Kind = ConditionKindType.Request,
Op = ConditionType.CondNumericGreaterThan
}
]
}
],
MatchType = RuleMatchType.FirstMatch
};
var serialized = RuleSerializer.Serialize(chain);
var restoredChain = RuleSerializer.Deserialize(serialized);
Assert.True(chain.ID.SequenceEqual(restoredChain.ID));
Assert.Equal(chain.MatchType, restoredChain.MatchType);
CompareRules(chain.Rules, restoredChain.Rules);
}
[Fact]
public void NegativeDeserialize1Test()
{
try
{
_ = RuleSerializer.Deserialize(null);
Assert.Fail("Error is expected");
}
catch (ArgumentNullException)
{
}
}
[Fact]
public void NegativeDeserialize2Test()
{
try
{
_ = RuleSerializer.Deserialize([]);
Assert.Fail("Error is expected");
}
catch (FrostFsException)
{
}
}
[Fact]
public void NegativeDeserialize3Test()
{
try
{
_ = RuleSerializer.Deserialize([1, 2, 3]);
Assert.Fail("Error is expected");
}
catch (FrostFsException)
{
}
}
[Fact]
public void NegativeDeserialize4Test()
{
try
{
//"\x00\x00:aws:iam::namespace:group/so\x82\x82\x82\x82\x82\x82u\x82"
_ = RuleSerializer.Deserialize([0x00, 0x00, 0x3A, 0x77, 0x73, 0x3A, 0x69, 0x61, 0x6D, 0x3A, 0x3A, 0x6E, 0x61, 0x6D, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x3A, 0x67, 0x72, 0x6F, 0x75, 0x70, 0x2F, 0x73, 0x6F, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x75, 0x82]);
Assert.Fail("Error is expected");
}
catch (FrostFsException)
{
}
}
private static void CompareRules(FrostFsRule[] rules1, FrostFsRule[] rules2)
{
Assert.NotNull(rules1);
Assert.NotNull(rules2);
Assert.Equal(rules1.Length, rules2.Length);
for (int ri = 0; ri < rules1.Length; ri++)
{
var rule1 = rules1[ri];
var rule2 = rules2[ri];
Assert.Equal(rule1.Status, rule2.Status);
Assert.Equal(rule1.Any, rule2.Any);
Assert.Equal(rule1.Actions, rule2.Actions);
Assert.Equal(rule1.Resources, rule2.Resources);
bool cond1Empty = rule1.Conditions == null || rule1.Conditions.Length == 0;
bool cond2Empty = rule2.Conditions == null || rule2.Conditions.Length == 0;
if (cond1Empty && cond2Empty)
{
return;
}
Assert.Equal(cond1Empty, cond2Empty);
Assert.Equal(rule1.Conditions!.Length, rule2.Conditions!.Length);
for (int i = 0; i < rule1.Conditions.Length; i++)
{
Assert.Equal(rule1.Conditions[i], rule2.Conditions[i]);
}
}
}
}

View file

@ -111,12 +111,12 @@ public class ObjectTest : ObjectTestsBase
Assert.NotNull(header1.Split.SplitId);
Assert.Null(header1.Split.Previous);
Assert.Equal(bytes[..blockSize], payload1);
Assert.Equal(SHA256.HashData(bytes.AsMemory().Slice(0, blockSize).ToArray()), SHA256.HashData(payload1));
Assert.True(header1.Attributes.Count == 0);
Assert.Equal(header1.Split.SplitId, header2.Split.SplitId);
Assert.Equal(objIds.ElementAt(0), header2.Split.Previous.Value);
Assert.Equal(bytes[blockSize..(blockSize * 2)], payload2);
Assert.Equal(SHA256.HashData(bytes.AsMemory().Slice(blockSize, blockSize).ToArray()), SHA256.HashData(payload2));
Assert.True(header2.Attributes.Count == 0);
// last part
@ -124,7 +124,7 @@ public class ObjectTest : ObjectTestsBase
Assert.NotNull(header3.Split.ParentHeader);
Assert.NotNull(header3.Split.ParentSignature);
Assert.Equal(header2.Split.SplitId, header3.Split.SplitId);
Assert.Equal(bytes[(fileLength / blockSize * blockSize)..fileLength], payload3);
Assert.Equal(SHA256.HashData(bytes.AsMemory().Slice(fileLength - fileLength % blockSize, fileLength % blockSize).ToArray()), SHA256.HashData(payload3));
Assert.True(header3.Attributes.Count == 0);
//link object