2020-09-17 15:37:44 +00:00
|
|
|
package placement
|
|
|
|
|
|
|
|
import (
|
|
|
|
"strconv"
|
|
|
|
"testing"
|
|
|
|
|
2020-09-18 15:14:26 +00:00
|
|
|
"github.com/nspcc-dev/neofs-api-go/pkg/container"
|
2020-09-17 15:37:44 +00:00
|
|
|
"github.com/nspcc-dev/neofs-api-go/pkg/netmap"
|
|
|
|
"github.com/nspcc-dev/neofs-api-go/pkg/object"
|
|
|
|
netmapV2 "github.com/nspcc-dev/neofs-node/pkg/morph/client/netmap"
|
|
|
|
"github.com/stretchr/testify/require"
|
|
|
|
)
|
|
|
|
|
|
|
|
type testBuilder struct {
|
|
|
|
vectors []netmap.Nodes
|
|
|
|
}
|
|
|
|
|
|
|
|
func (b testBuilder) BuildPlacement(*object.Address, *netmap.PlacementPolicy) ([]netmap.Nodes, error) {
|
|
|
|
return b.vectors, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func testNode(v uint32) netmapV2.NodeInfo {
|
|
|
|
n := netmapV2.NodeInfo{}
|
|
|
|
n.SetAddress("/ip4/0.0.0.0/tcp/" + strconv.Itoa(int(v)))
|
|
|
|
|
|
|
|
return n
|
|
|
|
}
|
|
|
|
|
|
|
|
func flattenVectors(vs []netmap.Nodes) netmap.Nodes {
|
|
|
|
v := make(netmap.Nodes, 0)
|
|
|
|
|
|
|
|
for i := range vs {
|
|
|
|
v = append(v, vs[i]...)
|
|
|
|
}
|
|
|
|
|
|
|
|
return v
|
|
|
|
}
|
|
|
|
|
2020-09-18 15:14:26 +00:00
|
|
|
func copyVectors(v []netmap.Nodes) []netmap.Nodes {
|
|
|
|
vc := make([]netmap.Nodes, 0, len(v))
|
|
|
|
|
|
|
|
for i := range v {
|
|
|
|
ns := make(netmap.Nodes, len(v[i]))
|
|
|
|
copy(ns, v[i])
|
|
|
|
|
|
|
|
vc = append(vc, ns)
|
|
|
|
}
|
|
|
|
|
|
|
|
return vc
|
|
|
|
}
|
|
|
|
|
2020-09-18 17:34:46 +00:00
|
|
|
func testPlacement(t *testing.T, ss, rs []int) ([]netmap.Nodes, *container.Container) {
|
2020-09-18 15:14:26 +00:00
|
|
|
nodes := make([]netmap.Nodes, 0, len(rs))
|
2020-09-18 17:34:46 +00:00
|
|
|
replicas := make([]*netmap.Replica, 0, len(rs))
|
2020-09-17 15:37:44 +00:00
|
|
|
num := uint32(0)
|
|
|
|
|
2020-09-18 17:34:46 +00:00
|
|
|
for i := range ss {
|
|
|
|
ns := make([]netmapV2.NodeInfo, 0, ss[i])
|
2020-09-17 15:37:44 +00:00
|
|
|
|
2020-09-18 17:34:46 +00:00
|
|
|
for j := 0; j < ss[i]; j++ {
|
2020-09-17 15:37:44 +00:00
|
|
|
ns = append(ns, testNode(num))
|
|
|
|
num++
|
|
|
|
}
|
|
|
|
|
2020-09-18 15:14:26 +00:00
|
|
|
nodes = append(nodes, netmap.NodesFromV2(ns))
|
|
|
|
|
2020-09-18 17:34:46 +00:00
|
|
|
s := new(netmap.Replica)
|
|
|
|
s.SetCount(uint32(rs[i]))
|
2020-09-18 15:14:26 +00:00
|
|
|
|
2020-09-18 17:34:46 +00:00
|
|
|
replicas = append(replicas, s)
|
2020-09-17 15:37:44 +00:00
|
|
|
}
|
|
|
|
|
2020-09-18 15:14:26 +00:00
|
|
|
policy := new(netmap.PlacementPolicy)
|
2020-09-18 17:34:46 +00:00
|
|
|
policy.SetReplicas(replicas)
|
2020-09-18 15:14:26 +00:00
|
|
|
|
|
|
|
return nodes, container.New(container.WithPolicy(policy))
|
2020-09-17 15:37:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func TestTraverserObjectScenarios(t *testing.T) {
|
|
|
|
t.Run("search scenario", func(t *testing.T) {
|
2020-09-18 17:34:46 +00:00
|
|
|
selectors := []int{2, 3}
|
|
|
|
replicas := []int{1, 2}
|
2020-09-18 15:14:26 +00:00
|
|
|
|
2020-09-18 17:34:46 +00:00
|
|
|
nodes, cnr := testPlacement(t, selectors, replicas)
|
2020-09-17 15:37:44 +00:00
|
|
|
|
2020-09-18 15:14:26 +00:00
|
|
|
nodesCopy := copyVectors(nodes)
|
2020-09-17 15:37:44 +00:00
|
|
|
|
|
|
|
tr, err := NewTraverser(
|
2020-09-18 15:14:26 +00:00
|
|
|
ForContainer(cnr),
|
|
|
|
UseBuilder(&testBuilder{vectors: nodesCopy}),
|
2020-09-17 15:37:44 +00:00
|
|
|
WithoutSuccessTracking(),
|
|
|
|
)
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
2020-09-18 17:34:46 +00:00
|
|
|
for i := range selectors {
|
2020-09-18 15:14:26 +00:00
|
|
|
addrs := tr.Next()
|
|
|
|
|
|
|
|
require.Len(t, addrs, len(nodes[i]))
|
2020-09-17 15:37:44 +00:00
|
|
|
|
2020-09-18 15:14:26 +00:00
|
|
|
for j, n := range nodes[i] {
|
|
|
|
require.Equal(t, n.NetworkAddress(), addrs[j].String())
|
|
|
|
}
|
2020-09-17 15:37:44 +00:00
|
|
|
}
|
|
|
|
|
2020-09-18 15:14:26 +00:00
|
|
|
require.Empty(t, tr.Next())
|
2020-09-17 15:37:44 +00:00
|
|
|
require.True(t, tr.Success())
|
|
|
|
})
|
|
|
|
|
|
|
|
t.Run("read scenario", func(t *testing.T) {
|
2020-09-18 17:34:46 +00:00
|
|
|
selectors := []int{5, 3}
|
|
|
|
replicas := []int{2, 2}
|
2020-09-17 15:37:44 +00:00
|
|
|
|
2020-09-18 17:34:46 +00:00
|
|
|
nodes, cnr := testPlacement(t, selectors, replicas)
|
2020-09-18 15:14:26 +00:00
|
|
|
|
|
|
|
nodesCopy := copyVectors(nodes)
|
2020-09-17 15:37:44 +00:00
|
|
|
|
|
|
|
tr, err := NewTraverser(
|
2020-09-18 15:14:26 +00:00
|
|
|
ForContainer(cnr),
|
|
|
|
UseBuilder(&testBuilder{vectors: nodesCopy}),
|
|
|
|
SuccessAfter(1),
|
2020-09-17 15:37:44 +00:00
|
|
|
)
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
2020-09-18 15:14:26 +00:00
|
|
|
fn := func(curVector int) {
|
2020-09-18 17:34:46 +00:00
|
|
|
for i := 0; i < selectors[curVector]; i++ {
|
2020-09-18 15:14:26 +00:00
|
|
|
addrs := tr.Next()
|
|
|
|
require.Len(t, addrs, 1)
|
2020-09-17 15:37:44 +00:00
|
|
|
|
2020-09-18 15:14:26 +00:00
|
|
|
require.Equal(t, nodes[curVector][i].NetworkAddress(), addrs[0].String())
|
|
|
|
}
|
2020-09-17 15:37:44 +00:00
|
|
|
|
2020-09-18 15:14:26 +00:00
|
|
|
require.Empty(t, tr.Next())
|
|
|
|
require.False(t, tr.Success())
|
2020-09-17 15:37:44 +00:00
|
|
|
|
2020-09-18 15:14:26 +00:00
|
|
|
tr.SubmitSuccess()
|
|
|
|
}
|
|
|
|
|
2020-09-18 17:34:46 +00:00
|
|
|
for i := range selectors {
|
2020-09-18 15:14:26 +00:00
|
|
|
fn(i)
|
2020-09-17 15:37:44 +00:00
|
|
|
|
2020-09-18 17:34:46 +00:00
|
|
|
if i < len(selectors)-1 {
|
2020-09-18 15:14:26 +00:00
|
|
|
require.False(t, tr.Success())
|
|
|
|
} else {
|
|
|
|
require.True(t, tr.Success())
|
|
|
|
}
|
|
|
|
}
|
2020-09-17 15:37:44 +00:00
|
|
|
})
|
|
|
|
|
|
|
|
t.Run("put scenario", func(t *testing.T) {
|
2020-09-18 17:34:46 +00:00
|
|
|
selectors := []int{5, 3}
|
|
|
|
replicas := []int{2, 2}
|
2020-09-18 15:14:26 +00:00
|
|
|
|
2020-09-18 17:34:46 +00:00
|
|
|
nodes, cnr := testPlacement(t, selectors, replicas)
|
2020-09-18 15:14:26 +00:00
|
|
|
|
|
|
|
nodesCopy := copyVectors(nodes)
|
2020-09-17 15:37:44 +00:00
|
|
|
|
|
|
|
tr, err := NewTraverser(
|
2020-09-18 15:14:26 +00:00
|
|
|
ForContainer(cnr),
|
|
|
|
UseBuilder(&testBuilder{vectors: nodesCopy}),
|
2020-09-17 15:37:44 +00:00
|
|
|
)
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
2020-09-18 15:14:26 +00:00
|
|
|
fn := func(curVector int) {
|
2020-09-18 17:34:46 +00:00
|
|
|
for i := 0; i+replicas[curVector] < selectors[curVector]; i += replicas[curVector] {
|
2020-09-18 15:14:26 +00:00
|
|
|
addrs := tr.Next()
|
2020-09-18 17:34:46 +00:00
|
|
|
require.Len(t, addrs, replicas[curVector])
|
2020-09-18 15:14:26 +00:00
|
|
|
|
|
|
|
for j := range addrs {
|
|
|
|
require.Equal(t, nodes[curVector][i+j].NetworkAddress(), addrs[j].String())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
require.Empty(t, tr.Next())
|
2020-09-17 15:37:44 +00:00
|
|
|
require.False(t, tr.Success())
|
2020-09-18 15:14:26 +00:00
|
|
|
|
2020-09-18 17:34:46 +00:00
|
|
|
for i := 0; i < replicas[curVector]; i++ {
|
2020-09-18 15:14:26 +00:00
|
|
|
tr.SubmitSuccess()
|
|
|
|
}
|
2020-09-17 15:37:44 +00:00
|
|
|
}
|
|
|
|
|
2020-09-18 17:34:46 +00:00
|
|
|
for i := range selectors {
|
2020-09-18 15:14:26 +00:00
|
|
|
fn(i)
|
|
|
|
|
2020-09-18 17:34:46 +00:00
|
|
|
if i < len(selectors)-1 {
|
2020-09-18 15:14:26 +00:00
|
|
|
require.False(t, tr.Success())
|
|
|
|
} else {
|
|
|
|
require.True(t, tr.Success())
|
|
|
|
}
|
|
|
|
}
|
2020-09-17 15:37:44 +00:00
|
|
|
})
|
|
|
|
}
|