storj/satellite/audit/verifier_unit_test.go
paul cannon a66503b444 satellite/audit: Begin using piecewise reverifications
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
2022-12-16 14:21:13 +00:00

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)),
},
}
}