a66503b444
This commit pulls the big switch! We have been setting up piecewise reverifications (the workers for which can be scaled independently of the core) for several commits now, and this commit actually begins making use of them. The core of this commit is fairly small, but it requires changing the semantics in all the tests that relate to reverifications, so it ends up being a large change. The changes to the tests are mostly mechanical and repetitive, though, so reviewers needn't worry much. Refs: https://github.com/storj/storj/issues/5230 Change-Id: Ibb421cc021664fd6e0096ffdf5b402a69b2d6f18
162 lines
4.0 KiB
Go
162 lines
4.0 KiB
Go
// Copyright (C) 2019 Storj Labs, Inc.
|
|
// See LICENSE for copying information.
|
|
|
|
package audit
|
|
|
|
import (
|
|
"context"
|
|
"testing"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
"github.com/vivint/infectious"
|
|
|
|
"storj.io/common/storj"
|
|
"storj.io/common/testrand"
|
|
"storj.io/storj/satellite/metabase"
|
|
)
|
|
|
|
func TestFailingAudit(t *testing.T) {
|
|
const (
|
|
required = 8
|
|
total = 14
|
|
)
|
|
|
|
f, err := infectious.NewFEC(required, total)
|
|
require.NoError(t, err)
|
|
|
|
shares := make([]infectious.Share, total)
|
|
output := func(s infectious.Share) {
|
|
shares[s.Number] = s.DeepCopy()
|
|
}
|
|
|
|
// the data to encode must be padded to a multiple of required, hence the
|
|
// underscores.
|
|
err = f.Encode([]byte("hello, world! __"), output)
|
|
require.NoError(t, err)
|
|
|
|
modifiedShares := make([]infectious.Share, len(shares))
|
|
for i := range shares {
|
|
modifiedShares[i] = shares[i].DeepCopy()
|
|
}
|
|
|
|
modifiedShares[0].Data[1] = '!'
|
|
modifiedShares[2].Data[0] = '#'
|
|
modifiedShares[3].Data[1] = '!'
|
|
modifiedShares[4].Data[0] = 'b'
|
|
|
|
badPieceNums := []int{0, 2, 3, 4}
|
|
|
|
ctx := context.Background()
|
|
auditPkgShares := make(map[int]Share, len(modifiedShares))
|
|
for i := range modifiedShares {
|
|
auditPkgShares[modifiedShares[i].Number] = Share{
|
|
PieceNum: modifiedShares[i].Number,
|
|
Data: append([]byte(nil), modifiedShares[i].Data...),
|
|
}
|
|
}
|
|
|
|
pieceNums, correctedShares, err := auditShares(ctx, 8, 14, auditPkgShares)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
for i, num := range pieceNums {
|
|
if num != badPieceNums[i] {
|
|
t.Fatal("expected nums in pieceNums to be same as in badPieceNums")
|
|
}
|
|
}
|
|
|
|
require.Equal(t, shares, correctedShares)
|
|
}
|
|
|
|
func TestNotEnoughShares(t *testing.T) {
|
|
const (
|
|
required = 8
|
|
total = 14
|
|
)
|
|
|
|
f, err := infectious.NewFEC(required, total)
|
|
require.NoError(t, err)
|
|
|
|
shares := make([]infectious.Share, total)
|
|
output := func(s infectious.Share) {
|
|
shares[s.Number] = s.DeepCopy()
|
|
}
|
|
|
|
// the data to encode must be padded to a multiple of required, hence the
|
|
// underscores.
|
|
err = f.Encode([]byte("hello, world! __"), output)
|
|
require.NoError(t, err)
|
|
|
|
ctx := context.Background()
|
|
auditPkgShares := make(map[int]Share, len(shares))
|
|
for i := range shares {
|
|
auditPkgShares[shares[i].Number] = Share{
|
|
PieceNum: shares[i].Number,
|
|
Data: append([]byte(nil), shares[i].Data...),
|
|
}
|
|
}
|
|
_, _, err = auditShares(ctx, 20, 40, auditPkgShares)
|
|
require.NotNil(t, err)
|
|
require.Contains(t, err.Error(), "must specify at least the number of required shares")
|
|
}
|
|
|
|
func TestCreatePendingAudits(t *testing.T) {
|
|
const (
|
|
required = 8
|
|
total = 14
|
|
)
|
|
|
|
f, err := infectious.NewFEC(required, total)
|
|
require.NoError(t, err)
|
|
|
|
shares := make([]infectious.Share, total)
|
|
output := func(s infectious.Share) {
|
|
shares[s.Number] = s.DeepCopy()
|
|
}
|
|
|
|
// The data to encode must be padded to a multiple of required, hence the
|
|
// underscores.
|
|
err = f.Encode([]byte("hello, world! __"), output)
|
|
require.NoError(t, err)
|
|
|
|
testNodeID := testrand.NodeID()
|
|
|
|
ctx := context.Background()
|
|
const pieceNum = 1
|
|
contained := make(map[int]storj.NodeID)
|
|
contained[pieceNum] = testNodeID
|
|
|
|
segment := testSegment()
|
|
segmentInfo := metabase.Segment{
|
|
StreamID: segment.StreamID,
|
|
Position: segment.Position,
|
|
RootPieceID: testrand.PieceID(),
|
|
Redundancy: storj.RedundancyScheme{
|
|
Algorithm: storj.ReedSolomon,
|
|
RequiredShares: required,
|
|
TotalShares: total,
|
|
ShareSize: int32(len(shares[0].Data)),
|
|
},
|
|
}
|
|
|
|
pending, err := createPendingAudits(ctx, contained, segment)
|
|
require.NoError(t, err)
|
|
require.Equal(t, 1, len(pending))
|
|
assert.Equal(t, testNodeID, pending[0].Locator.NodeID)
|
|
assert.Equal(t, segmentInfo.StreamID, pending[0].Locator.StreamID)
|
|
assert.Equal(t, segmentInfo.Position, pending[0].Locator.Position)
|
|
assert.Equal(t, pieceNum, pending[0].Locator.PieceNum)
|
|
assert.EqualValues(t, 0, pending[0].ReverifyCount)
|
|
}
|
|
|
|
func testSegment() Segment {
|
|
return Segment{
|
|
StreamID: testrand.UUID(),
|
|
Position: metabase.SegmentPosition{
|
|
Index: uint32(testrand.Intn(100)),
|
|
},
|
|
}
|
|
}
|