[#29] Client: Add object placement methods
All checks were successful
DCO / DCO (pull_request) Successful in 1m7s
lint-build / dotnet8.0 (pull_request) Successful in 1m31s
lint-build / dotnet8.0 (push) Successful in 1m4s

Signed-off-by: Pavel Gross <p.gross@yadro.com>
This commit is contained in:
Pavel Gross 2024-12-24 17:32:29 +03:00
parent 8637515869
commit 568bdc67e8
25 changed files with 1382 additions and 32 deletions

View file

@ -0,0 +1,161 @@
using System.Diagnostics.CodeAnalysis;
using FrostFS.SDK.Client.Models.Netmap.Placement;
namespace FrostFS.SDK.Tests.Unit;
[SuppressMessage("Reliability", "CA2007:Consider calling ConfigureAwait on the awaited task", Justification = "Default Value is correct for tests")]
public class PlacementVectorTests
{
Dictionary<string, string>[] attribs;
public PlacementVectorTests()
{
var attribs1 = new Dictionary<string, string>
{
{"Country", "Germany" },
{"Price", "2" },
{"Capacity", "10000"}
};
var attribs2 = new Dictionary<string, string>
{
{"Country", "Germany" },
{"Price", "4" },
{"Capacity", "1"}
};
var attribs3 = new Dictionary<string, string>
{
{"Country", "France" },
{"Price", "3" },
{"Capacity", "10"}
};
var attribs4 = new Dictionary<string, string>
{
{"Country", "Russia" },
{"Price", "2" },
{"Capacity", "10000"}
};
var attribs5 = new Dictionary<string, string>
{
{"Country", "Russia" },
{"Price", "1" },
{"Capacity", "10000"}
};
var attribs6 = new Dictionary<string, string>
{
{"Country", "Russia" },
{"Capacity", "10000"}
};
var attribs7 = new Dictionary<string, string>
{
{"Country", "France" },
{"Price", "100" },
{"Capacity", "10000"}
};
var attribs8 = new Dictionary<string, string>
{
{"Country", "France" },
{"Price", "7" },
{"Capacity", "10000"}
};
var attribs9 = new Dictionary<string, string>
{
{"Country", "Russia" },
{"Price", "2" },
{"Capacity", "1"}
};
attribs = [attribs1, attribs2, attribs3, attribs4, attribs5, attribs6, attribs7, attribs8, attribs9];
}
[Fact]
public void PlacementVectorTest()
{
FrostFsVersion v = new(2, 13);
var addresses = new string[] { "localhost", "server1" };
var key1 = new byte[] { 1 };
var key2 = new byte[] { 2 };
var key3 = new byte[] { 3 };
var nodes = new List<FrostFsNodeInfo>
{
new(v, NodeState.Online, addresses.AsReadOnly(), attribs[5].AsReadOnly(), key1),
new(v, NodeState.Online, addresses.AsReadOnly(), attribs[0].AsReadOnly(), key2),
new(v, NodeState.Online, addresses.AsReadOnly(), attribs[8].AsReadOnly(), key3)
};
var netmap = new FrostFsNetmapSnapshot(100, nodes.AsReadOnly());
var arg = new FrostFsNodeInfo[1][];
var pivot = "objectID"u8.ToArray();
arg[0] = [.. nodes];
var result = netmap.PlacementVectors(arg, pivot);
Assert.Single(result);
Assert.Equal(3, result[0].Length);
Assert.Equal(key1, result[0][0].PublicKey);
Assert.Equal(key2, result[0][1].PublicKey);
Assert.Equal(key3, result[0][2].PublicKey);
}
[Fact]
public void TestPlacementPolicyUnique()
{
FrostFsVersion version = new(2, 13);
var p = new FrostFsPlacementPolicy(true, [new FrostFsReplica(1, "S"), new FrostFsReplica(1, "S")])
{
BackupFactor = 2
};
p.Selectors.Add(new FrostFsSelector("S")
{
Attribute = "City",
Count = 1,
Filter = "*",
Clause = (int)FrostFsClause.Same
});
List<FrostFsNodeInfo> nodes = [];
var cities = new string[] { "Moscow", "Berlin", "Shenzhen" };
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 3; j++)
{
var attr = new Dictionary<string, string> { { "City", cities[i] } };
var key = new byte[] { (byte)(i * 4 + j) };
var node = new FrostFsNodeInfo(version, NodeState.Online, [], attr, key);
nodes.Add(node);
}
}
var netMap = new FrostFsNetmapSnapshot(100, nodes.AsReadOnly());
var v = netMap.ContainerNodes(p, null);
Assert.Equal(2, v.Length);
Assert.Equal(2, v[0].Length);
Assert.Equal(2, v[1].Length);
for (int i = 0; i < v.Length; i++)
{
foreach (var ni in v[i])
{
for (int j = 0; j < i; j++)
{
foreach (var nj in v[j])
{
Assert.NotEqual(ni.Hash, nj.Hash);
}
}
}
}
}
}