netmap: properly process multiple REP #113

Merged
fyrchik merged 1 commit from fyrchik/frostfs-sdk-go:fix-multiple-rep into master 2023-07-11 14:21:37 +00:00
2 changed files with 74 additions and 21 deletions

View file

@ -188,7 +188,6 @@ func (m NetMap) ContainerNodes(p PlacementPolicy, pivot []byte) ([][]NodeInfo, e
for i := range p.replicas {
sName := p.replicas[i].GetSelector()
if sName == "" {
if len(p.selectors) == 0 {
var s netmap.Selector
s.SetCount(p.replicas[i].GetCount())
s.SetFilter(mainFilterName)
@ -198,20 +197,7 @@ func (m NetMap) ContainerNodes(p PlacementPolicy, pivot []byte) ([][]NodeInfo, e
return nil, err
}
result[i] = flattenNodes(nodes)
}
for i := range p.selectors {
if p.unique {
nodes, err := c.getSelection(p.selectors[i])
if err != nil {
return nil, err
}
result[i] = append(result[i], flattenNodes(nodes)...)
} else {
result[i] = append(result[i], flattenNodes(c.selections[p.selectors[i].GetName()])...)
}
}
if p.unique {
c.addUsedNodes(result[i]...)

View file

@ -282,6 +282,73 @@ func TestPlacementPolicy_Unique(t *testing.T) {
}
}
func TestPlacementPolicy_MultiREP(t *testing.T) {
nodes := []NodeInfo{
nodeInfoFromAttributes("ID", "1", "Country", "Russia", "City", "SPB"),
nodeInfoFromAttributes("ID", "2", "Country", "Germany", "City", "Berlin"),
nodeInfoFromAttributes("ID", "3", "Country", "Russia", "City", "Moscow"),
nodeInfoFromAttributes("ID", "4", "Country", "France", "City", "Paris"),
nodeInfoFromAttributes("ID", "5", "Country", "France", "City", "Lyon"),
nodeInfoFromAttributes("ID", "6", "Country", "Russia", "City", "SPB"),
nodeInfoFromAttributes("ID", "7", "Country", "Russia", "City", "Moscow"),
nodeInfoFromAttributes("ID", "8", "Country", "Germany", "City", "Darmstadt"),
nodeInfoFromAttributes("ID", "9", "Country", "Germany", "City", "Frankfurt"),
nodeInfoFromAttributes("ID", "10", "Country", "Russia", "City", "SPB"),
nodeInfoFromAttributes("ID", "11", "Country", "Russia", "City", "Moscow"),
nodeInfoFromAttributes("ID", "12", "Country", "Germany", "City", "London"),
}
for i := range nodes {
pub := make([]byte, 33)
rand.Read(pub)
nodes[i].SetPublicKey(pub)
}
var nm NetMap
nm.SetNodes(nodes)
ss := []Selector{newSelector("SameRU", "City", 2, "FromRU", (*Selector).SelectDistinct)}
fs := []Filter{newFilter("FromRU", "Country", "Russia", netmap.EQ)}
for _, unique := range []bool{false, true} {
for _, additional := range []int{0, 1, 2} {
t.Run(fmt.Sprintf("unique=%t, additional=%d", unique, additional), func(t *testing.T) {
rs := []ReplicaDescriptor{newReplica(1, "SameRU")}
for i := 0; i < additional; i++ {
rs = append(rs, newReplica(1, ""))
}
p := newPlacementPolicy(3, rs, ss, fs)
p.unique = unique
v, err := nm.ContainerNodes(p, []byte{1})
require.NoError(t, err)
require.Equal(t, 1+additional, len(v))
require.Equal(t, 6, len(v[0]))
for i := 1; i < additional; i++ {
require.Equal(t, 3, len(v[i]))
if !unique {
require.Equal(t, v[1], v[i])
}
}
if unique {
seen := make(map[string]bool)
for i := range v {
for j := range v[i] {
attr := v[i][j].Attribute("ID")
require.NotEmpty(t, attr)
require.False(t, seen[attr])
seen[attr] = true
}
}
}
})
}
}
}
func TestPlacementPolicy_ProcessSelectorsExceptForNodes(t *testing.T) {
p := newPlacementPolicy(1, nil,
[]Selector{