satellite/metabase: handle copies with GetStreamPieceCountByNodeID
We missed proper handling of object copies for method GetStreamPieceCountByNodeID which is used by metabase.GetObjectIPs. That caused some lack of IPs returned when queriyng IPs of copy and broke things like pices map on linksharing. Fixes https://github.com/storj/storj/issues/5406 Change-Id: I9574776f34880788c2dc9ff78a6ae20d44fe628f
This commit is contained in:
parent
1cb2eb4c3b
commit
0759cbdc7f
@ -32,6 +32,10 @@ func (db *DB) GetStreamPieceCountByNodeID(ctx context.Context, opts GetStreamPie
|
||||
SELECT remote_alias_pieces
|
||||
FROM segments
|
||||
WHERE stream_id = $1 AND remote_alias_pieces IS NOT null
|
||||
UNION
|
||||
SELECT remote_alias_pieces
|
||||
FROM segments
|
||||
WHERE stream_id = (SELECT ancestor_stream_id FROM segment_copies WHERE stream_id = $1) AND remote_alias_pieces IS NOT null
|
||||
`, opts.StreamID))(func(rows tagsql.Rows) error {
|
||||
for rows.Next() {
|
||||
var aliasPieces AliasPieces
|
||||
|
@ -150,5 +150,72 @@ func TestGetStreamPieceCountByNodeID(t *testing.T) {
|
||||
},
|
||||
}.Check(ctx, t, db)
|
||||
})
|
||||
|
||||
t.Run("segments copy", func(t *testing.T) {
|
||||
defer metabasetest.DeleteAll{}.Check(ctx, t, db)
|
||||
|
||||
encryptedKey := testrand.Bytes(32)
|
||||
encryptedKeyNonce := testrand.Bytes(32)
|
||||
|
||||
testNodeIDs := make([]storj.NodeID, 3)
|
||||
for i := range testNodeIDs {
|
||||
testNodeIDs[i] = testrand.NodeID()
|
||||
}
|
||||
|
||||
// each segment will have one test node ID
|
||||
originalObj, _ := metabasetest.CreateTestObject{
|
||||
CreateSegment: func(object metabase.Object, index int) metabase.Segment {
|
||||
metabasetest.CommitSegment{
|
||||
Opts: metabase.CommitSegment{
|
||||
ObjectStream: obj,
|
||||
Position: metabase.SegmentPosition{Part: 0, Index: uint32(index)},
|
||||
RootPieceID: testrand.PieceID(),
|
||||
|
||||
Pieces: metabase.Pieces{
|
||||
{Number: 1, StorageNode: testNodeIDs[index]},
|
||||
},
|
||||
|
||||
EncryptedKey: encryptedKey,
|
||||
EncryptedKeyNonce: encryptedKeyNonce,
|
||||
|
||||
EncryptedSize: 1024,
|
||||
PlainSize: 512,
|
||||
PlainOffset: 0,
|
||||
Redundancy: metabasetest.DefaultRedundancy,
|
||||
},
|
||||
}.Check(ctx, t, db)
|
||||
|
||||
return metabase.Segment{}
|
||||
},
|
||||
}.Run(ctx, t, db, obj, byte(len(testNodeIDs)))
|
||||
|
||||
copyStream := metabasetest.RandObjectStream()
|
||||
_, _, _ = metabasetest.CreateObjectCopy{
|
||||
OriginalObject: originalObj,
|
||||
CopyObjectStream: ©Stream,
|
||||
}.Run(ctx, t, db)
|
||||
|
||||
metabasetest.GetStreamPieceCountByNodeID{
|
||||
Opts: metabase.GetStreamPieceCountByNodeID{
|
||||
StreamID: obj.StreamID,
|
||||
},
|
||||
Result: map[storj.NodeID]int64{
|
||||
testNodeIDs[0]: 1,
|
||||
testNodeIDs[1]: 1,
|
||||
testNodeIDs[2]: 1,
|
||||
},
|
||||
}.Check(ctx, t, db)
|
||||
|
||||
metabasetest.GetStreamPieceCountByNodeID{
|
||||
Opts: metabase.GetStreamPieceCountByNodeID{
|
||||
StreamID: copyStream.StreamID,
|
||||
},
|
||||
Result: map[storj.NodeID]int64{
|
||||
testNodeIDs[0]: 1,
|
||||
testNodeIDs[1]: 1,
|
||||
testNodeIDs[2]: 1,
|
||||
},
|
||||
}.Check(ctx, t, db)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
@ -900,10 +900,32 @@ func TestEndpoint_Object_With_StorageNodes(t *testing.T) {
|
||||
|
||||
require.NoError(t, uplnk.CreateBucket(uplinkCtx, sat, bucketName))
|
||||
require.NoError(t, uplnk.Upload(uplinkCtx, sat, bucketName, "jones", testrand.Bytes(20*memory.KB)))
|
||||
|
||||
project, err := uplnk.OpenProject(ctx, planet.Satellites[0])
|
||||
require.NoError(t, err)
|
||||
defer ctx.Check(project.Close)
|
||||
|
||||
// make a copy
|
||||
_, err = project.CopyObject(ctx, bucketName, "jones", bucketName, "jones_copy", nil)
|
||||
require.NoError(t, err)
|
||||
|
||||
ips, err := object.GetObjectIPs(ctx, uplink.Config{}, access, bucketName, "jones")
|
||||
require.NoError(t, err)
|
||||
require.True(t, len(ips) > 0)
|
||||
|
||||
copyIPs, err := object.GetObjectIPs(ctx, uplink.Config{}, access, bucketName, "jones_copy")
|
||||
require.NoError(t, err)
|
||||
|
||||
sort.Slice(ips, func(i, j int) bool {
|
||||
return bytes.Compare(ips[i], ips[j]) < 0
|
||||
})
|
||||
sort.Slice(copyIPs, func(i, j int) bool {
|
||||
return bytes.Compare(copyIPs[i], copyIPs[j]) < 0
|
||||
})
|
||||
|
||||
// verify that orignal and copy has the same results
|
||||
require.Equal(t, ips, copyIPs)
|
||||
|
||||
// verify it's a real IP with valid host and port
|
||||
for _, ip := range ips {
|
||||
host, port, err := net.SplitHostPort(string(ip))
|
||||
|
Loading…
Reference in New Issue
Block a user