forked from TrueCloudLab/frostfs-node
[#1231] policer: Add EC node-off unit test
Signed-off-by: Dmitrii Stepanov <d.stepanov@yadro.com>
This commit is contained in:
parent
cfd5e3d403
commit
8eb591d668
1 changed files with 145 additions and 0 deletions
|
@ -563,3 +563,148 @@ func TestECChunkRestore(t *testing.T) {
|
|||
require.NoError(t, err)
|
||||
require.EqualValues(t, string(expectedData), string(actualData), "invalid restored objects")
|
||||
}
|
||||
|
||||
func TestECChunkRestoreNodeOff(t *testing.T) {
|
||||
// node0 has chunk0, node1 has chunk1, node2 has chunk2, node3 is out of netmap
|
||||
t.Parallel()
|
||||
|
||||
payload := make([]byte, 64)
|
||||
rand.Read(payload)
|
||||
parentAddress := oidtest.Address()
|
||||
parentObject := objectSDK.New()
|
||||
parentObject.SetContainerID(parentAddress.Container())
|
||||
parentObject.SetPayload(payload)
|
||||
parentObject.SetPayloadSize(64)
|
||||
objectSDK.CalculateAndSetPayloadChecksum(parentObject)
|
||||
err := objectSDK.CalculateAndSetID(parentObject)
|
||||
require.NoError(t, err)
|
||||
id, _ := parentObject.ID()
|
||||
parentAddress.SetObject(id)
|
||||
|
||||
chunkIDs := make([]oid.ID, 4)
|
||||
c, err := erasurecode.NewConstructor(3, 1)
|
||||
require.NoError(t, err)
|
||||
key, err := keys.NewPrivateKey()
|
||||
require.NoError(t, err)
|
||||
chunks, err := c.Split(parentObject, &key.PrivateKey)
|
||||
require.NoError(t, err)
|
||||
for i, ch := range chunks {
|
||||
chunkIDs[i], _ = ch.ID()
|
||||
}
|
||||
|
||||
var policy netmapSDK.PlacementPolicy
|
||||
require.NoError(t, policy.DecodeString("EC 3.1"))
|
||||
|
||||
cnr := &container.Container{}
|
||||
cnr.Value.Init()
|
||||
cnr.Value.SetPlacementPolicy(policy)
|
||||
containerSrc := containerSrc{
|
||||
get: func(id cid.ID) (*container.Container, error) {
|
||||
if id.Equals(parentAddress.Container()) {
|
||||
return cnr, nil
|
||||
}
|
||||
return nil, new(apistatus.ContainerNotFound)
|
||||
},
|
||||
}
|
||||
|
||||
nodes := make([]netmapSDK.NodeInfo, 3)
|
||||
for i := range nodes {
|
||||
nodes[i].SetPublicKey([]byte{byte(i)})
|
||||
}
|
||||
|
||||
placementBuilder := func(cnr cid.ID, obj *oid.ID, p netmapSDK.PlacementPolicy) ([][]netmapSDK.NodeInfo, error) {
|
||||
if cnr.Equals(parentAddress.Container()) && obj.Equals(parentAddress.Object()) {
|
||||
return [][]netmapSDK.NodeInfo{nodes}, nil
|
||||
}
|
||||
return nil, errors.New("unexpected placement build")
|
||||
}
|
||||
remoteHeadFn := func(_ context.Context, ni netmapSDK.NodeInfo, a oid.Address, raw bool) (*objectSDK.Object, error) {
|
||||
require.True(t, raw, "remote header for parent object must be called with raw flag")
|
||||
index := int(ni.PublicKey()[0])
|
||||
require.True(t, index == 1 || index == 2, "invalid node to get parent header")
|
||||
require.True(t, a == parentAddress, "invalid address to get remote header")
|
||||
if index == 1 {
|
||||
ei := objectSDK.NewECInfo()
|
||||
var ch objectSDK.ECChunk
|
||||
ch.SetID(chunkIDs[1])
|
||||
ch.Index = uint32(1)
|
||||
ch.Total = 4
|
||||
ei.AddChunk(ch)
|
||||
return nil, objectSDK.NewECInfoError(ei)
|
||||
}
|
||||
if index == 2 {
|
||||
ei := objectSDK.NewECInfo()
|
||||
var ch objectSDK.ECChunk
|
||||
ch.SetID(chunkIDs[2])
|
||||
ch.Index = uint32(2)
|
||||
ch.Total = 4
|
||||
ei.AddChunk(ch)
|
||||
return nil, objectSDK.NewECInfoError(ei)
|
||||
}
|
||||
|
||||
return nil, new(apistatus.ObjectNotFound)
|
||||
}
|
||||
|
||||
localHeadFn := func(_ context.Context, a oid.Address) (*objectSDK.Object, error) {
|
||||
require.True(t, a == parentAddress, "invalid address to get remote header")
|
||||
ei := objectSDK.NewECInfo()
|
||||
var ch objectSDK.ECChunk
|
||||
ch.SetID(chunkIDs[0])
|
||||
ch.Index = uint32(0)
|
||||
ch.Total = 4
|
||||
ei.AddChunk(ch)
|
||||
return nil, objectSDK.NewECInfoError(ei)
|
||||
}
|
||||
|
||||
var replicatedObj []*objectSDK.Object
|
||||
p := New(
|
||||
WithContainerSource(containerSrc),
|
||||
WithPlacementBuilder(placementBuilderFunc(placementBuilder)),
|
||||
WithNetmapKeys(announcedKeysFunc(func(k []byte) bool {
|
||||
return bytes.Equal(k, nodes[0].PublicKey())
|
||||
})),
|
||||
WithRemoteObjectHeaderFunc(remoteHeadFn),
|
||||
WithLocalObjectHeaderFunc(localHeadFn),
|
||||
WithReplicator(&testReplicator{
|
||||
handleLocalPutTask: func(ctx context.Context, task replicator.Task) {
|
||||
if task.Obj != nil {
|
||||
replicatedObj = append(replicatedObj, task.Obj)
|
||||
}
|
||||
},
|
||||
}),
|
||||
WithLocalObjectGetFunc(func(ctx context.Context, a oid.Address) (*objectSDK.Object, error) {
|
||||
require.True(t, a.Container() == parentAddress.Container() && a.Object() == chunkIDs[0], "invalid local object request")
|
||||
return chunks[0], nil
|
||||
}),
|
||||
WithRemoteObjectGetFunc(func(ctx context.Context, ni netmapSDK.NodeInfo, a oid.Address) (*objectSDK.Object, error) {
|
||||
index := ni.PublicKey()[0]
|
||||
return chunks[index], nil
|
||||
}),
|
||||
WithPool(testPool(t)),
|
||||
WithKeyStorage(util.NewKeyStorage(&key.PrivateKey, nil, nil)),
|
||||
)
|
||||
|
||||
var chunkAddress oid.Address
|
||||
chunkAddress.SetContainer(parentAddress.Container())
|
||||
chunkAddress.SetObject(chunkIDs[0])
|
||||
objInfo := objectcore.Info{
|
||||
Address: chunkAddress,
|
||||
Type: objectSDK.TypeRegular,
|
||||
ECInfo: &objectcore.ECInfo{
|
||||
ParentID: parentAddress.Object(),
|
||||
Index: 0,
|
||||
Total: 4,
|
||||
},
|
||||
}
|
||||
err = p.processObject(context.Background(), objInfo)
|
||||
require.NoError(t, err)
|
||||
|
||||
require.Equal(t, 1, len(replicatedObj), "invalid replicated objects count")
|
||||
chunks[3].SetSignature(nil)
|
||||
expectedData, err := chunks[3].MarshalJSON()
|
||||
require.NoError(t, err)
|
||||
replicatedObj[0].SetSignature(nil)
|
||||
actualData, err := replicatedObj[0].MarshalJSON()
|
||||
require.NoError(t, err)
|
||||
require.EqualValues(t, string(expectedData), string(actualData), "invalid restored objects")
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue