using System.Collections.Concurrent; using System.Collections.ObjectModel; using System.Diagnostics.CodeAnalysis; using FrostFS.SDK.Client; using Grpc.Core; namespace FrostFS.SDK.Tests.Smoke; [SuppressMessage("Reliability", "CA2007:Consider calling ConfigureAwait on the awaited task", Justification = "Default Value is correct for tests")] [SuppressMessage("Security", "CA5394:Do not use insecure randomness", Justification = "No secure purpose")] public class ContainerTests : SmokeTestsBase { [Fact] public async void FailCreateContainerByTimeoutTest() { var client = FrostFSClient.GetInstance(ClientOptions, GrpcChannel); try { _ = await CreateContainer(client, ctx: new CallContext(TimeSpan.FromMilliseconds(1)), token: null, unique: true, backupFactor: 1, selectors: [], filter: [], containerAttributes: [new("testKey1", "testValue1")], new FrostFsReplica(1)); Assert.Fail("Exception is expected"); } catch (RpcException ex) { Assert.Equal(StatusCode.DeadlineExceeded, ex.Status.StatusCode); } } [Fact] public async void CreateContainerTest1() { var client = FrostFSClient.GetInstance(ClientOptions, GrpcChannel); await Cleanup(client); client = FrostFSClient.GetInstance(ClientOptions, GrpcChannel); FrostFsContainerId containerId = await CreateContainer(client, ctx: default, token: null, unique: true, backupFactor: 1, selectors: [], filter: [], containerAttributes: [new("testKey1", "testValue1")], new FrostFsReplica(3)); Assert.NotNull(containerId); var container = await client.GetContainerAsync(new PrmContainerGet(containerId), default); Assert.NotNull(container); Assert.NotNull(container.Attributes); Assert.Equal("testKey1", container.Attributes[0].Key); Assert.Equal("testValue1", container.Attributes[0].Value); //Assert.Equal("true", container.Attributes[1].Value); // for cluster //Assert.Equal(2, container.Attributes.Count); //Assert.Equal("__SYSTEM__DISABLE_HOMOMORPHIC_HASHING", container.Attributes[1].Key); Assert.True(container.PlacementPolicy.HasValue); Assert.Equal(1u, container.PlacementPolicy.Value.BackupFactor); Assert.True(container.PlacementPolicy.Value.Unique); Assert.Empty(container.PlacementPolicy.Value.Selectors); Assert.Empty(container.PlacementPolicy.Value.Filters); Assert.Single(container.PlacementPolicy.Value.Replicas); Assert.Equal(3u, container.PlacementPolicy.Value.Replicas[0].Count); Assert.Equal(0u, container.PlacementPolicy.Value.Replicas[0].EcParityCount); Assert.Equal(0u, container.PlacementPolicy.Value.Replicas[0].EcDataCount); Assert.Equal("", container.PlacementPolicy.Value.Replicas[0].Selector); Assert.Equal(OwnerId!.ToString(), container.Owner!.Value); Assert.NotNull(container.Version); Assert.Equal(Version!.Major, container.Version.Major); Assert.Equal(Version.Minor, container.Version.Minor); } [Fact] public async void CreateContainerTest2() { var client = FrostFSClient.GetInstance(ClientOptions, GrpcChannel); await Cleanup(client); client = FrostFSClient.GetInstance(ClientOptions, GrpcChannel); Collection filters = [ new ("filter1", "filterKey1", 1, "testValue1", []), new ("filter2", "filterKey2", 2, "testValue2", [new ("subFilter2", "subFilterKey2", 3, "testValue3",[])]) ]; Collection selectors = [ new ("selector1") { Count = 1, Clause = 1, Attribute = "attribute1", Filter = "filter1" }, new ("selector2") { Count = 2, Clause = 2, Attribute = "attribute2", Filter = "filter2" }, ]; FrostFsContainerId containerId = await CreateContainer(client, ctx: default, token: null, unique: false, backupFactor: 2, selectors, filter: filters, containerAttributes: [], new FrostFsReplica(1)); Assert.NotNull(containerId); var container = await client.GetContainerAsync(new PrmContainerGet(containerId), default); Assert.NotNull(container); Assert.NotNull(container.Attributes); //Assert.Single(container.Attributes); //Assert.Equal("__SYSTEM__DISABLE_HOMOMORPHIC_HASHING", container.Attributes[0].Key); //Assert.Equal("true", container.Attributes[0].Value); Assert.True(container.PlacementPolicy.HasValue); Assert.Equal(2u, container.PlacementPolicy.Value.BackupFactor); Assert.False(container.PlacementPolicy.Value.Unique); Assert.NotEmpty(container.PlacementPolicy.Value.Selectors); Assert.Equal(2, container.PlacementPolicy.Value.Selectors.Count); var selector1 = container.PlacementPolicy.Value.Selectors[0]; Assert.Equal("selector1", selector1.Name); Assert.Equal(1, selector1.Clause); Assert.Equal(1u, selector1.Count); Assert.Equal("attribute1", selector1.Attribute); Assert.Equal("filter1", selector1.Filter); var selector2 = container.PlacementPolicy.Value.Selectors[1]; Assert.Equal("selector2", selector2.Name); Assert.Equal(2, selector2.Clause); Assert.Equal(2u, selector2.Count); Assert.Equal("attribute2", selector2.Attribute); Assert.Equal("filter2", selector2.Filter); Assert.NotEmpty(container.PlacementPolicy.Value.Filters); Assert.Equal(2, container.PlacementPolicy.Value.Filters.Count); var filter1 = container.PlacementPolicy.Value.Filters[0]; Assert.Equal("filter1", filter1.Name); Assert.Equal("filterKey1", filter1.Key); Assert.Equal("testValue1", filter1.Value); Assert.Equal(1, filter1.Operation); Assert.Empty(filter1.Filters); var filter2 = container.PlacementPolicy.Value.Filters[1]; Assert.Equal("filter2", filter2.Name); Assert.Equal("filterKey2", filter2.Key); Assert.Equal("testValue2", filter2.Value); Assert.Equal(2, filter2.Operation); Assert.NotEmpty(filter2.Filters); Assert.Single(filter2.Filters); var subFilter = filter2.Filters.First(); Assert.Equal("subFilter2", subFilter.Name); Assert.Equal("subFilterKey2", subFilter.Key); Assert.Equal("testValue3", subFilter.Value); Assert.Equal(3, subFilter.Operation); Assert.Empty(subFilter.Filters); Assert.Single(container.PlacementPolicy.Value.Replicas); Assert.Equal(1u, container.PlacementPolicy.Value.Replicas[0].Count); Assert.Equal(0u, container.PlacementPolicy.Value.Replicas[0].EcParityCount); Assert.Equal(0u, container.PlacementPolicy.Value.Replicas[0].EcDataCount); Assert.Equal("", container.PlacementPolicy.Value.Replicas[0].Selector); Assert.Equal(OwnerId!.ToString(), container.Owner!.Value); Assert.NotNull(container.Version); Assert.Equal(Version!.Major, container.Version.Major); Assert.Equal(Version.Minor, container.Version.Minor); } [Theory] [InlineData(1)] [InlineData(10)] public async void ListAndDeleteContainersTest(int countainerCount) { var client = FrostFSClient.GetInstance(ClientOptions, GrpcChannel); await Cleanup(client); var tasks = new Task[countainerCount]; var createdContainers = new ConcurrentDictionary(); for (int i = 0; i < countainerCount; i++) { int index = i; tasks[i] = Task.Run(async () => { FrostFsContainerId containerId = await CreateContainer(client, ctx: default, token: null, unique: true, backupFactor: 1, selectors: [], filter: [], containerAttributes: [new($"testKey{index}", $"testValue{index}")], new FrostFsReplica(3)); createdContainers.TryAdd(containerId.ToString(), index); }); } #pragma warning disable xUnit1031 // Timeout is used if (!Task.WaitAll(tasks, 20000)) { Assert.Fail("cannot create containers"); } #pragma warning restore xUnit1031 var containers = client.ListContainersAsync(new PrmContainerGetAll(), default); var receivedContainers = new List(); await foreach (var cntr in containers) { receivedContainers.Add(cntr.ToString()); } Assert.Equal(countainerCount, receivedContainers.Count); foreach (var cntrId in receivedContainers) { if (!createdContainers.TryGetValue(cntrId, out var index)) { Assert.Fail("Cannot find corresponding container"); } FrostFsContainerId container = new(cntrId); var containerInfo = await client.GetContainerAsync(new PrmContainerGet(container), default); Assert.NotNull(containerInfo); Assert.NotNull(containerInfo.Attributes); Assert.Contains(new FrostFsAttributePair($"testKey{index}", $"testValue{index}"), containerInfo.Attributes); } tasks = new Task[countainerCount]; for (int i = 0; i < receivedContainers.Count; i++) { tasks[i] = client.DeleteContainerAsync(new PrmContainerDelete(new FrostFsContainerId(receivedContainers[i]), lightWait), default); } await Task.WhenAll(tasks); await foreach (var _ in client.ListContainersAsync(default, default)) { Assert.Fail("Containers exist"); } } }