diff --git a/netmap/policy_test.go b/netmap/policy_test.go index 7c639c6..bf0c03b 100644 --- a/netmap/policy_test.go +++ b/netmap/policy_test.go @@ -82,6 +82,13 @@ CBF 1 SELECT 1 FROM Color FILTER (Color EQ Red OR Color EQ Blue OR Color EQ Yellow) AND Color NE Green AS Color`, }, + { + name: "non-ascii attributes in SELECT IN", + input: `REP 1 +CBF 1 +SELECT 1 IN SAME 'Цвет' FROM Colorful +FILTER 'Цвет' EQ 'Красный' OR 'Цвет' EQ 'Синий' AS Colorful`, + }, } for _, tc := range testCases { @@ -127,6 +134,11 @@ func TestDecodeSelectFilterExpr(t *testing.T) { SELECT 1 FROM R FILTER Color LIKE 'R' AS R `, + ` + CBF 1 + SELECT 1 IN SAME 'Цвет' FROM Colorful + FILTER 'Цвет' EQ 'Красный' OR 'Цвет' EQ 'Синий' AS Colorful + `, } { _, err := DecodeSelectFilterString(s) require.NoError(t, err) diff --git a/netmap/selector_test.go b/netmap/selector_test.go index 2d54987..6ef5883 100644 --- a/netmap/selector_test.go +++ b/netmap/selector_test.go @@ -6,6 +6,7 @@ import ( "encoding/binary" "fmt" mrand "math/rand" + "reflect" "slices" "strconv" "strings" @@ -13,6 +14,7 @@ import ( "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/netmap" "git.frostfs.info/TrueCloudLab/hrw" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) @@ -542,6 +544,66 @@ func TestPlacementPolicy_ProcessSelectorsExceptForNodes(t *testing.T) { } } +func TestPlacementPolicy_NonAsciiAttributes(t *testing.T) { + p := newPlacementPolicy( + 1, + []ReplicaDescriptor{ + newReplica(2, "Nodes"), + newReplica(2, "Nodes"), + }, + []Selector{ + newSelector("Nodes", "Цвет", 2, "Colorful", (*Selector).SelectSame), + }, + []Filter{ + newFilter("Colorful", "", "", netmap.OR, + newFilter("", "Цвет", "Красный", netmap.EQ), + newFilter("", "Цвет", "Синий", netmap.EQ), + ), + }, + ) + p.SetUnique(true) + + nodes := []NodeInfo{ + nodeInfoFromAttributes("Цвет", "Красный", "Форма", "Треугольник"), + nodeInfoFromAttributes("Цвет", "Красный", "Форма", "Круг"), + nodeInfoFromAttributes("Цвет", "Синий", "Форма", "Треугольник"), + nodeInfoFromAttributes("Цвет", "Синий", "Форма", "Круг"), + nodeInfoFromAttributes("Свойство", "Мягкий", "Форма", "Треугольник"), + nodeInfoFromAttributes("Свойство", "Теплый", "Форма", "Круг"), + } + for i := range nodes { + nodes[i].SetPublicKey([]byte{byte(i)}) + } + + redNodes := nodes[:2] + blueNodes := nodes[2:4] + + var nm NetMap + nm.SetNodes(nodes) + + pivot := make([]byte, 42) + _, _ = rand.Read(pivot) + + nodesPerReplica, err := nm.ContainerNodes(p, pivot) + require.NoError(t, err) + require.Len(t, nodesPerReplica, 2) + + for i := range nodesPerReplica { + slices.SortFunc(nodesPerReplica[i], func(n1, n2 NodeInfo) int { + pk1, pk2 := string(n1.PublicKey()), string(n2.PublicKey()) + return cmp.Compare(pk1, pk2) + }) + } + + redMatchFirst := reflect.DeepEqual(redNodes, nodesPerReplica[0]) + blueMatchFirst := reflect.DeepEqual(blueNodes, nodesPerReplica[0]) + + redMatchSecond := reflect.DeepEqual(redNodes, nodesPerReplica[1]) + blueMatchSecond := reflect.DeepEqual(blueNodes, nodesPerReplica[1]) + + assert.True(t, redMatchFirst && blueMatchSecond || blueMatchFirst && redMatchSecond) +} + func TestSelector_SetName(t *testing.T) { const name = "some name" var s Selector