2019-07-15 20:58:39 +01:00
|
|
|
// Copyright (C) 2019 Storj Labs, Inc.
|
|
|
|
// See LICENSE for copying information.
|
|
|
|
|
2023-06-29 14:26:52 +01:00
|
|
|
package checker_test
|
2019-07-15 20:58:39 +01:00
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
|
|
|
"testing"
|
|
|
|
"time"
|
|
|
|
|
2020-12-22 19:07:07 +00:00
|
|
|
"github.com/stretchr/testify/require"
|
2019-07-15 20:58:39 +01:00
|
|
|
"go.uber.org/zap"
|
2022-06-28 12:53:39 +01:00
|
|
|
"golang.org/x/sync/errgroup"
|
2019-07-15 20:58:39 +01:00
|
|
|
|
2023-06-29 14:26:52 +01:00
|
|
|
"storj.io/common/storj"
|
|
|
|
"storj.io/common/storj/location"
|
2019-12-27 11:48:47 +00:00
|
|
|
"storj.io/common/testcontext"
|
|
|
|
"storj.io/common/testrand"
|
2023-06-29 14:26:52 +01:00
|
|
|
"storj.io/storj/private/testplanet"
|
|
|
|
"storj.io/storj/satellite"
|
2021-04-21 13:42:57 +01:00
|
|
|
"storj.io/storj/satellite/metabase"
|
2022-10-31 21:33:17 +00:00
|
|
|
"storj.io/storj/satellite/nodeevents"
|
2023-07-07 09:31:58 +01:00
|
|
|
"storj.io/storj/satellite/nodeselection"
|
2019-07-28 06:55:36 +01:00
|
|
|
"storj.io/storj/satellite/overlay"
|
2023-06-29 14:26:52 +01:00
|
|
|
"storj.io/storj/satellite/repair/checker"
|
2019-07-15 20:58:39 +01:00
|
|
|
)
|
|
|
|
|
|
|
|
func TestReliabilityCache_Concurrent(t *testing.T) {
|
|
|
|
ctx := testcontext.New(t)
|
|
|
|
defer ctx.Cleanup()
|
|
|
|
|
2023-07-06 13:35:26 +01:00
|
|
|
overlayCache, err := overlay.NewService(zap.NewNop(), fakeOverlayDB{}, fakeNodeEvents{}, overlay.NewPlacementRules().CreateFilters, "", "", overlay.Config{
|
2022-06-28 12:53:39 +01:00
|
|
|
NodeSelectionCache: overlay.UploadSelectionCacheConfig{
|
|
|
|
Staleness: 2 * time.Nanosecond,
|
|
|
|
},
|
|
|
|
})
|
2020-12-22 19:07:07 +00:00
|
|
|
require.NoError(t, err)
|
2022-06-28 12:53:39 +01:00
|
|
|
cacheCtx, cacheCancel := context.WithCancel(ctx)
|
|
|
|
defer cacheCancel()
|
|
|
|
ctx.Go(func() error { return overlayCache.Run(cacheCtx) })
|
|
|
|
defer ctx.Check(overlayCache.Close)
|
2019-07-15 20:58:39 +01:00
|
|
|
|
2023-07-06 13:35:26 +01:00
|
|
|
cache := checker.NewReliabilityCache(overlayCache, time.Millisecond, overlay.NewPlacementRules().CreateFilters, []string{})
|
2022-06-28 12:53:39 +01:00
|
|
|
var group errgroup.Group
|
2019-07-15 20:58:39 +01:00
|
|
|
for i := 0; i < 10; i++ {
|
2022-06-28 12:53:39 +01:00
|
|
|
group.Go(func() error {
|
2019-07-15 20:58:39 +01:00
|
|
|
for i := 0; i < 10000; i++ {
|
2020-12-14 17:33:03 +00:00
|
|
|
pieces := []metabase.Piece{{StorageNode: testrand.NodeID()}}
|
2022-06-28 12:53:39 +01:00
|
|
|
_, err := cache.MissingPieces(ctx, time.Now(), pieces)
|
2019-07-15 20:58:39 +01:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
})
|
|
|
|
}
|
2022-06-28 12:53:39 +01:00
|
|
|
require.NoError(t, group.Wait())
|
2019-07-15 20:58:39 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
type fakeOverlayDB struct{ overlay.DB }
|
2022-10-31 21:33:17 +00:00
|
|
|
type fakeNodeEvents struct{ nodeevents.DB }
|
2019-07-15 20:58:39 +01:00
|
|
|
|
2023-08-21 12:59:54 +01:00
|
|
|
func (fakeOverlayDB) GetParticipatingNodes(context.Context, time.Duration, time.Duration) ([]nodeselection.SelectedNode, error) {
|
2023-07-07 09:31:58 +01:00
|
|
|
return []nodeselection.SelectedNode{
|
2023-08-21 12:59:54 +01:00
|
|
|
{ID: testrand.NodeID(), Online: true},
|
|
|
|
{ID: testrand.NodeID(), Online: true},
|
|
|
|
{ID: testrand.NodeID(), Online: true},
|
|
|
|
{ID: testrand.NodeID(), Online: true},
|
|
|
|
}, nil
|
2019-07-15 20:58:39 +01:00
|
|
|
}
|
2023-06-29 14:26:52 +01:00
|
|
|
|
|
|
|
func TestReliabilityCache_OutOfPlacementPieces(t *testing.T) {
|
|
|
|
testplanet.Run(t, testplanet.Config{
|
|
|
|
SatelliteCount: 1, StorageNodeCount: 4, UplinkCount: 1,
|
|
|
|
Reconfigure: testplanet.Reconfigure{
|
|
|
|
Satellite: func(log *zap.Logger, index int, config *satellite.Config) {
|
|
|
|
config.Overlay.Node.AsOfSystemTime.Enabled = false
|
|
|
|
config.Overlay.Node.AsOfSystemTime.DefaultInterval = 0
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}, func(t *testing.T, ctx *testcontext.Context, planet *testplanet.Planet) {
|
2023-07-06 13:35:26 +01:00
|
|
|
overlayService := planet.Satellites[0].Overlay.Service
|
2023-06-29 14:26:52 +01:00
|
|
|
config := planet.Satellites[0].Config.Checker
|
|
|
|
|
2023-07-06 13:35:26 +01:00
|
|
|
rules := overlay.NewPlacementRules()
|
|
|
|
rules.AddLegacyStaticRules()
|
|
|
|
cache := checker.NewReliabilityCache(overlayService, config.ReliabilityCacheStaleness, rules.CreateFilters, []string{})
|
2023-06-29 14:26:52 +01:00
|
|
|
|
|
|
|
nodesPlacement := func(location location.CountryCode, nodes ...*testplanet.StorageNode) {
|
|
|
|
for _, node := range nodes {
|
2023-07-06 13:35:26 +01:00
|
|
|
err := overlayService.TestNodeCountryCode(ctx, node.ID(), location.String())
|
2023-06-29 14:26:52 +01:00
|
|
|
require.NoError(t, err)
|
|
|
|
}
|
|
|
|
require.NoError(t, cache.Refresh(ctx))
|
|
|
|
}
|
|
|
|
|
|
|
|
allPieces := metabase.Pieces{
|
|
|
|
metabase.Piece{Number: 0, StorageNode: planet.StorageNodes[0].ID()},
|
|
|
|
metabase.Piece{Number: 1, StorageNode: planet.StorageNodes[1].ID()},
|
|
|
|
metabase.Piece{Number: 2, StorageNode: planet.StorageNodes[2].ID()},
|
|
|
|
metabase.Piece{Number: 3, StorageNode: planet.StorageNodes[3].ID()},
|
|
|
|
}
|
|
|
|
|
|
|
|
pieces, err := cache.OutOfPlacementPieces(ctx, time.Now().Add(-time.Hour), metabase.Pieces{}, storj.EU)
|
|
|
|
require.NoError(t, err)
|
|
|
|
require.Empty(t, pieces)
|
|
|
|
|
|
|
|
nodesPlacement(location.Poland, planet.StorageNodes...)
|
|
|
|
pieces, err = cache.OutOfPlacementPieces(ctx, time.Now().Add(-time.Hour), allPieces, storj.EU)
|
|
|
|
require.NoError(t, err)
|
|
|
|
require.Empty(t, pieces)
|
|
|
|
|
|
|
|
pieces, err = cache.OutOfPlacementPieces(ctx, time.Now().Add(-time.Hour), allPieces, storj.US)
|
|
|
|
require.NoError(t, err)
|
|
|
|
require.ElementsMatch(t, allPieces, pieces)
|
|
|
|
|
|
|
|
nodesPlacement(location.UnitedStates, planet.StorageNodes[:2]...)
|
|
|
|
pieces, err = cache.OutOfPlacementPieces(ctx, time.Now().Add(-time.Hour), allPieces, storj.EU)
|
|
|
|
require.NoError(t, err)
|
|
|
|
require.ElementsMatch(t, allPieces[:2], pieces)
|
|
|
|
|
|
|
|
pieces, err = cache.OutOfPlacementPieces(ctx, time.Now().Add(-time.Hour), allPieces, storj.US)
|
|
|
|
require.NoError(t, err)
|
|
|
|
require.ElementsMatch(t, allPieces[2:], pieces)
|
|
|
|
})
|
|
|
|
}
|