[#102] netmap: properly process multiple REP

Signed-off-by: Evgenii Stratonikov <e.stratonikov@yadro.com>
This commit is contained in:
Evgenii Stratonikov 2023-07-10 14:49:40 +03:00 committed by Evgenii Stratonikov
parent c359a7465a
commit 998fe1a7ab
2 changed files with 74 additions and 21 deletions

View file

@ -188,30 +188,16 @@ func (m NetMap) ContainerNodes(p PlacementPolicy, pivot []byte) ([][]NodeInfo, e
for i := range p.replicas { for i := range p.replicas {
sName := p.replicas[i].GetSelector() sName := p.replicas[i].GetSelector()
if sName == "" { if sName == "" {
if len(p.selectors) == 0 { var s netmap.Selector
var s netmap.Selector s.SetCount(p.replicas[i].GetCount())
s.SetCount(p.replicas[i].GetCount()) s.SetFilter(mainFilterName)
s.SetFilter(mainFilterName)
nodes, err := c.getSelection(s) nodes, err := c.getSelection(s)
if err != nil { if err != nil {
return nil, err return nil, err
}
result[i] = flattenNodes(nodes)
} }
for i := range p.selectors { result[i] = append(result[i], flattenNodes(nodes)...)
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 { if p.unique {
c.addUsedNodes(result[i]...) 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) { func TestPlacementPolicy_ProcessSelectorsExceptForNodes(t *testing.T) {
p := newPlacementPolicy(1, nil, p := newPlacementPolicy(1, nil,
[]Selector{ []Selector{