storj/pkg/audit/cursor_test.go

208 lines
6.0 KiB
Go
Raw Normal View History

2019-01-24 20:15:10 +00:00
// Copyright (C) 2019 Storj Labs, Inc.
// See LICENSE for copying information.
2019-01-23 19:58:44 +00:00
package audit_test
Satellite Peer (#1034) * add satellite peer * Add overlay * reorganize kademlia * add RunRefresh * add refresh to storagenode.Peer * add discovery * add agreements and metainfo * rename * add datarepair checker * add repair * add todo notes for audit * add testing interface * add into testplanet * fixes * fix compilation errors * fix compilation errors * make testplanet run * remove audit refrences * ensure that audit tests run * dev * checker tests compilable * fix discovery * fix compilation * fix * fix * dev * fix * disable auth * fixes * revert go.mod/sum * fix linter errors * fix * fix copyright * Add address param for SN dashboard (#1076) * Rename storj-sdk to storj-sim (#1078) * Storagenode logs and config improvements (#1075) * Add more info to SN logs * remove config-dir from user config * add output where config was stored * add message for successful connection * fix linter * remove storage.path from user config * resolve config path * move success message to info * log improvements * Remove captplanet (#1070) * pkg/server: include production cert (#1082) Change-Id: Ie8e6fe78550be83c3bd797db7a1e58d37c684792 * Generate Payments Report (#1079) * memory.Size: autoformat sizes based on value entropy (#1081) * Jj/bytes (#1085) * run tally and rollup * sets dev default tally and rollup intervals * nonessential storj-sim edits (#1086) * Closing context doesn't stop storage node (#1084) * Print when cancelled * Close properly * Don't log nil * Don't print error when closing dashboard * Fix panic in inspector if ping fails (#1088) * Consolidate identity management to identity cli commands (#1083) * Consolidate identity management: Move identity cretaion/signing out of storagenode setup command. * fixes * linters * Consolidate identity management: Move identity cretaion/signing out of storagenode setup command. * fixes * sava backups before saving signed certs * add "-prebuilt-test-cmds" test flag * linters * prepare cli tests for travis * linter fixes * more fixes * linter gods * sp/sdk/sim * remove ca.difficulty * remove unused difficulty * return setup to its rightful place * wip travis * Revert "wip travis" This reverts commit 56834849dcf066d3cc0a4f139033fc3f6d7188ca. * typo in travis.yaml * remove tests * remove more * make it only create one identity at a time for consistency * add config-dir for consitency * add identity creation to storj-sim * add flags * simplify * fix nolint and compile * prevent overwrite and pass difficulty, concurrency, and parent creds * goimports
2019-01-18 13:54:08 +00:00
import (
"crypto/rand"
"math"
"math/big"
"reflect"
"testing"
"time"
"github.com/golang/protobuf/ptypes/timestamp"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"storj.io/storj/internal/testcontext"
"storj.io/storj/internal/testplanet"
"storj.io/storj/internal/teststorj"
2019-01-23 19:58:44 +00:00
"storj.io/storj/pkg/audit"
"storj.io/storj/pkg/pb"
"storj.io/storj/pkg/pointerdb"
"storj.io/storj/pkg/storage/meta"
"storj.io/storj/pkg/storj"
)
func TestAuditSegment(t *testing.T) {
testplanet.Run(t, testplanet.Config{
SatelliteCount: 1, StorageNodeCount: 4, UplinkCount: 1,
}, func(t *testing.T, ctx *testcontext.Context, planet *testplanet.Planet) {
type pathCount struct {
path storj.Path
count int
}
// note: to simulate better,
// change limit in library to 5 in
// list api call, default is 0 == 1000 listing
//populate pointerdb with 10 non-expired pointers of test data
tests, cursor, pointerdb := populateTestData(t, planet, &timestamp.Timestamp{Seconds: time.Now().Unix() + 3000})
t.Run("NextStripe", func(t *testing.T) {
for _, tt := range tests {
t.Run(tt.bm, func(t *testing.T) {
assert1 := assert.New(t)
stripe, err := cursor.NextStripe(ctx)
if err != nil {
assert1.Error(err)
assert1.Nil(stripe)
}
if stripe != nil {
assert1.Nil(err)
}
})
}
})
// test to see how random paths are
t.Run("probabilisticTest", func(t *testing.T) {
list, _, err := pointerdb.List("", "", "", true, 10, meta.None)
require.NoError(t, err)
require.Len(t, list, 10)
// get count of items picked at random
uniquePathCounted := []pathCount{}
pathCounter := []pathCount{}
// get a list of 100 paths generated from random
for i := 0; i < 100; i++ {
randomNum, err := rand.Int(rand.Reader, big.NewInt(int64(len(list))))
if err != nil {
t.Error("num error: failed to get num")
}
pointerItem := list[randomNum.Int64()]
path := pointerItem.Path
val := pathCount{path: path, count: 1}
pathCounter = append(pathCounter, val)
}
// get a count for paths in list
for _, pc := range pathCounter {
skip := false
for i, up := range uniquePathCounted {
if reflect.DeepEqual(pc.path, up.path) {
up.count = up.count + 1
uniquePathCounted[i] = up
skip = true
break
}
}
if !skip {
uniquePathCounted = append(uniquePathCounted, pc)
}
}
// Section: binomial test for randomness
n := float64(100) // events
p := float64(.10) // theoretical probability of getting 1/10 paths
m := n * p
s := math.Sqrt(m * (1 - p)) // binomial distribution
// if values fall outside of the critical values of test statistics (ie Z value)
// in a 2-tail test
// we can assume, 95% confidence, it's not sampling according to a 10% probability
for _, v := range uniquePathCounted {
z := (float64(v.count) - m) / s
if z <= -1.96 || z >= 1.96 {
t.Log(false)
} else {
t.Log(true)
}
}
})
})
}
func makePutRequest(path storj.Path, expiration *timestamp.Timestamp) pb.PutRequest {
var rps []*pb.RemotePiece
rps = append(rps, &pb.RemotePiece{
PieceNum: 1,
NodeId: teststorj.NodeIDFromString("testId"),
})
pr := pb.PutRequest{
Path: path,
Pointer: &pb.Pointer{
ExpirationDate: expiration,
Type: pb.Pointer_REMOTE,
Remote: &pb.RemoteSegment{
Redundancy: &pb.RedundancyScheme{
Type: pb.RedundancyScheme_RS,
MinReq: 1,
Total: 3,
RepairThreshold: 2,
SuccessThreshold: 3,
ErasureShareSize: 2,
},
RootPieceId: teststorj.PieceIDFromString("testId"),
RemotePieces: rps,
},
SegmentSize: int64(10),
},
}
return pr
}
func TestDeleteExpired(t *testing.T) {
testplanet.Run(t, testplanet.Config{
SatelliteCount: 1, StorageNodeCount: 4, UplinkCount: 1,
}, func(t *testing.T, ctx *testcontext.Context, planet *testplanet.Planet) {
//populate pointerdb with 10 expired pointers of test data
tests, cursor, pointerdb := populateTestData(t, planet, &timestamp.Timestamp{})
//make sure it they're in there
list, _, err := pointerdb.List("", "", "", true, 10, meta.None)
require.NoError(t, err)
require.Len(t, list, 10)
// make sure its all null and no errors
t.Run("NextStripe", func(t *testing.T) {
for _, tt := range tests {
t.Run(tt.bm, func(t *testing.T) {
stripe, err := cursor.NextStripe(ctx)
require.NoError(t, err)
require.Nil(t, stripe)
})
}
})
//make sure it they're not in there anymore
list, _, err = pointerdb.List("", "", "", true, 10, meta.None)
require.NoError(t, err)
require.Len(t, list, 0)
})
}
type testData struct {
bm string
path storj.Path
}
func populateTestData(t *testing.T, planet *testplanet.Planet, expiration *timestamp.Timestamp) ([]testData, *audit.Cursor, *pointerdb.Service) {
tests := []testData{
{bm: "success-1", path: "folder1/file1"},
{bm: "success-2", path: "foodFolder1/file1/file2"},
{bm: "success-3", path: "foodFolder1/file1/file2/foodFolder2/file3"},
{bm: "success-4", path: "projectFolder/project1.txt/"},
{bm: "success-5", path: "newProjectFolder/project2.txt"},
{bm: "success-6", path: "Pictures/image1.png"},
{bm: "success-7", path: "Pictures/Nature/mountains.png"},
{bm: "success-8", path: "Pictures/City/streets.png"},
{bm: "success-9", path: "Pictures/Animals/Dogs/dogs.png"},
{bm: "success-10", path: "Nada/ビデオ/😶"},
}
pointerdb := planet.Satellites[0].Metainfo.Service
allocation := planet.Satellites[0].Metainfo.Allocation
cache := planet.Satellites[0].Overlay.Service
cursor := audit.NewCursor(pointerdb, allocation, cache, planet.Satellites[0].Identity)
// put 10 pointers in db with expirations
t.Run("putToDB", func(t *testing.T) {
for _, tt := range tests {
t.Run(tt.bm, func(t *testing.T) {
putRequest := makePutRequest(tt.path, expiration)
require.NoError(t, pointerdb.Put(tt.path, putRequest.Pointer))
})
}
})
return tests, cursor, pointerdb
}