f14fabc90a
This change adds a new forget-satellite sub-command to the storagenode CLI which cleans up untrusted satellite data. Issue: https://github.com/storj/storj/issues/6068 Change-Id: Iafa109fdc98afdba7582f568a61c22222da65f02
211 lines
5.1 KiB
Go
211 lines
5.1 KiB
Go
// Copyright (C) 2019 Storj Labs, Inc.
|
|
// See LICENSE for copying information.
|
|
|
|
package trust_test
|
|
|
|
import (
|
|
"context"
|
|
"os"
|
|
"path/filepath"
|
|
"testing"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
"github.com/zeebo/errs"
|
|
|
|
"storj.io/common/testcontext"
|
|
"storj.io/storj/storagenode/trust"
|
|
)
|
|
|
|
func TestCacheLoadCreatesDirectory(t *testing.T) {
|
|
ctx := testcontext.New(t)
|
|
defer ctx.Cleanup()
|
|
|
|
cachePath := filepath.Join(ctx.Dir(), "sub", "cache.json")
|
|
|
|
_, err := trust.LoadCache(cachePath)
|
|
require.NoError(t, err)
|
|
|
|
fi, err := os.Stat(filepath.Dir(cachePath))
|
|
require.NoError(t, err, "cache directory should exist")
|
|
require.True(t, fi.IsDir())
|
|
|
|
_, err = os.Stat(cachePath)
|
|
require.True(t, os.IsNotExist(err), "cache file should not exist")
|
|
}
|
|
|
|
func TestCacheLoadFailure(t *testing.T) {
|
|
ctx := testcontext.New(t)
|
|
defer ctx.Cleanup()
|
|
|
|
cachePath := ctx.File("cache.json")
|
|
|
|
// Use the directory itself as the path
|
|
_, err := trust.LoadCache(ctx.Dir())
|
|
assert.Error(t, err)
|
|
|
|
// Load malformed JSON
|
|
require.NoError(t, os.WriteFile(cachePath, []byte("BAD"), 0644))
|
|
_, err = trust.LoadCache(cachePath)
|
|
assert.EqualError(t, err, "trust: malformed cache: invalid character 'B' looking for beginning of value")
|
|
}
|
|
|
|
func TestCachePersistence(t *testing.T) {
|
|
url1, err := trust.ParseSatelliteURL("121RTSDpyNZVcEU84Ticf2L1ntiuUimbWgfATz21tuvgk3vzoA6@foo.test:7777")
|
|
require.NoError(t, err)
|
|
|
|
url2, err := trust.ParseSatelliteURL("12L9ZFwhzVpuEKMUNUqkaTLGzwY9G24tbiigLiXpmZWKwmcNDDs@b.bar.test:7777")
|
|
require.NoError(t, err)
|
|
|
|
entry1 := trust.Entry{
|
|
SatelliteURL: url1,
|
|
Authoritative: false,
|
|
}
|
|
|
|
entry2 := trust.Entry{
|
|
SatelliteURL: url2,
|
|
Authoritative: true,
|
|
}
|
|
|
|
for _, tt := range []struct {
|
|
name string
|
|
entriesBefore map[string][]trust.Entry
|
|
lookup []trust.Entry
|
|
set []trust.Entry
|
|
save bool
|
|
entriesAfter map[string][]trust.Entry
|
|
}{
|
|
{
|
|
name: "new cache without save",
|
|
},
|
|
{
|
|
name: "new cache with save",
|
|
save: true,
|
|
entriesAfter: map[string][]trust.Entry{},
|
|
},
|
|
{
|
|
name: "set without save",
|
|
set: []trust.Entry{entry1, entry2},
|
|
save: false,
|
|
},
|
|
{
|
|
name: "set and save",
|
|
set: []trust.Entry{entry1, entry2},
|
|
save: true,
|
|
entriesAfter: map[string][]trust.Entry{
|
|
"key": {entry1, entry2},
|
|
},
|
|
},
|
|
{
|
|
name: "replace without saving",
|
|
entriesBefore: map[string][]trust.Entry{
|
|
"key": {entry1},
|
|
},
|
|
lookup: []trust.Entry{entry1},
|
|
set: []trust.Entry{entry1, entry2},
|
|
save: false,
|
|
entriesAfter: map[string][]trust.Entry{
|
|
"key": {entry1},
|
|
},
|
|
},
|
|
{
|
|
name: "replace and save",
|
|
entriesBefore: map[string][]trust.Entry{
|
|
"key": {entry1},
|
|
},
|
|
lookup: []trust.Entry{entry1},
|
|
set: []trust.Entry{entry1, entry2},
|
|
save: true,
|
|
entriesAfter: map[string][]trust.Entry{
|
|
"key": {entry1, entry2},
|
|
},
|
|
},
|
|
} {
|
|
tt := tt // quiet linting
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
ctx := testcontext.New(t)
|
|
defer ctx.Cleanup()
|
|
|
|
cachePath := ctx.File("cache.json")
|
|
|
|
if tt.entriesBefore != nil {
|
|
require.NoError(t, trust.SaveCacheData(cachePath, &trust.CacheData{Entries: tt.entriesBefore}))
|
|
}
|
|
|
|
cache, err := trust.LoadCache(cachePath)
|
|
require.NoError(t, err)
|
|
|
|
entries, ok := cache.Lookup("key")
|
|
if tt.lookup == nil {
|
|
require.False(t, ok, "lookup should fail")
|
|
require.Nil(t, entries, "failed lookup should produce nil entries slice")
|
|
} else {
|
|
require.True(t, ok, "lookup should succeed")
|
|
require.Equal(t, tt.lookup, entries)
|
|
}
|
|
|
|
if tt.set != nil {
|
|
cache.Set("key", tt.set)
|
|
}
|
|
|
|
if tt.save {
|
|
require.NoError(t, cache.Save(context.Background()))
|
|
}
|
|
|
|
cacheAfter, err := trust.LoadCacheData(cachePath)
|
|
if tt.entriesAfter == nil {
|
|
require.Error(t, err)
|
|
if !assert.True(t, os.IsNotExist(errs.Unwrap(err)), "cache file should not exist") {
|
|
require.FailNow(t, "Expected cache file to not exist", "err=%w", err)
|
|
}
|
|
} else {
|
|
require.NoError(t, err)
|
|
require.Equal(t, &trust.CacheData{Entries: tt.entriesAfter}, cacheAfter)
|
|
}
|
|
})
|
|
}
|
|
|
|
}
|
|
|
|
func TestCache_DeleteSatelliteEntry(t *testing.T) {
|
|
url1, err := trust.ParseSatelliteURL("121RTSDpyNZVcEU84Ticf2L1ntiuUimbWgfATz21tuvgk3vzoA6@foo.test:7777")
|
|
require.NoError(t, err)
|
|
|
|
url2, err := trust.ParseSatelliteURL("12L9ZFwhzVpuEKMUNUqkaTLGzwY9G24tbiigLiXpmZWKwmcNDDs@b.bar.test:7777")
|
|
require.NoError(t, err)
|
|
|
|
entry1 := trust.Entry{
|
|
SatelliteURL: url1,
|
|
Authoritative: false,
|
|
}
|
|
|
|
entry2 := trust.Entry{
|
|
SatelliteURL: url2,
|
|
Authoritative: true,
|
|
}
|
|
|
|
entriesBefore := map[string][]trust.Entry{
|
|
"key": {entry1, entry2},
|
|
}
|
|
|
|
expectedEntriesAfter := map[string][]trust.Entry{
|
|
"key": {entry2},
|
|
}
|
|
|
|
ctx := testcontext.New(t)
|
|
defer ctx.Cleanup()
|
|
|
|
cachePath := ctx.File("cache.json")
|
|
require.NoError(t, trust.SaveCacheData(cachePath, &trust.CacheData{Entries: entriesBefore}))
|
|
|
|
cache, err := trust.LoadCache(cachePath)
|
|
require.NoError(t, err)
|
|
|
|
cache.DeleteSatelliteEntry(url1.ID)
|
|
require.NoError(t, cache.Save(ctx))
|
|
|
|
cacheAfter, err := trust.LoadCacheData(cachePath)
|
|
require.NoError(t, err)
|
|
require.Equal(t, &trust.CacheData{Entries: expectedEntriesAfter}, cacheAfter)
|
|
}
|