storj/pkg/statdb/statdb_test.go

332 lines
11 KiB
Go

// Copyright (C) 2018 Storj Labs, Inc.
// See LICENSE for copying information.
package statdb_test
import (
"context"
"testing"
"github.com/stretchr/testify/assert"
"storj.io/storj/internal/testcontext"
"storj.io/storj/pkg/pb"
"storj.io/storj/pkg/statdb"
"storj.io/storj/pkg/storj"
"storj.io/storj/satellite/satellitedb"
"storj.io/storj/satellite/satellitedb/satellitedbtest"
)
func getRatio(s, t int) (success, total int64, ratio float64) {
ratio = float64(s) / float64(t)
return int64(s), int64(t), ratio
}
func TestStatdb(t *testing.T) {
satellitedbtest.Run(t, func(t *testing.T, db *satellitedb.DB) {
ctx := testcontext.New(t)
defer ctx.Cleanup()
testDatabase(ctx, t, db.StatDB())
})
}
func testDatabase(ctx context.Context, t *testing.T, sdb statdb.DB) {
nodeID := storj.NodeID{1, 2, 3, 4, 5}
{ // TestCreateNewAndWithStats
auditSuccessCount, auditCount, auditSuccessRatio := getRatio(4, 10)
uptimeSuccessCount, uptimeCount, uptimeRatio := getRatio(8, 25)
nodeStats := &pb.NodeStats{
AuditSuccessRatio: auditSuccessRatio,
UptimeRatio: uptimeRatio,
AuditCount: auditCount,
AuditSuccessCount: auditSuccessCount,
UptimeCount: uptimeCount,
UptimeSuccessCount: uptimeSuccessCount,
}
createReq := &statdb.CreateRequest{
Node: nodeID,
Stats: nodeStats,
}
resp, err := sdb.Create(ctx, createReq)
assert.NoError(t, err)
s := resp.Stats
assert.EqualValues(t, auditSuccessRatio, s.AuditSuccessRatio)
assert.EqualValues(t, uptimeRatio, s.UptimeRatio)
getReq := &statdb.GetRequest{
Node: nodeID,
}
getResp, err := sdb.Get(ctx, getReq)
assert.NoError(t, err)
assert.EqualValues(t, nodeID, getResp.Stats.NodeId)
assert.EqualValues(t, auditCount, getResp.Stats.AuditCount)
assert.EqualValues(t, auditSuccessCount, getResp.Stats.AuditSuccessCount)
assert.EqualValues(t, auditSuccessRatio, getResp.Stats.AuditSuccessRatio)
assert.EqualValues(t, uptimeCount, getResp.Stats.UptimeCount)
assert.EqualValues(t, uptimeSuccessCount, getResp.Stats.UptimeSuccessCount)
assert.EqualValues(t, uptimeRatio, getResp.Stats.UptimeRatio)
}
{ // TestCreateExists
auditSuccessCount, auditCount, auditSuccessRatio := getRatio(4, 10)
uptimeSuccessCount, uptimeCount, uptimeRatio := getRatio(8, 25)
nodeStats := &pb.NodeStats{
AuditSuccessRatio: auditSuccessRatio,
UptimeRatio: uptimeRatio,
AuditCount: auditCount,
AuditSuccessCount: auditSuccessCount,
UptimeCount: uptimeCount,
UptimeSuccessCount: uptimeSuccessCount,
}
createReq := &statdb.CreateRequest{
Node: nodeID,
Stats: nodeStats,
}
_, err := sdb.Create(ctx, createReq)
assert.Error(t, err)
}
{ // TestGetDoesNotExist
noNodeID := storj.NodeID{255, 255, 255, 255}
getReq := &statdb.GetRequest{
Node: noNodeID,
}
_, err := sdb.Get(ctx, getReq)
assert.Error(t, err)
}
{ // TestFindInvalidNodes
for _, tt := range []struct {
nodeID storj.NodeID
auditSuccessCount int64
auditCount int64
auditSuccessRatio float64
uptimeSuccessCount int64
uptimeCount int64
uptimeRatio float64
}{
{storj.NodeID{1}, 20, 20, 1, 20, 20, 1}, // good audit success
{storj.NodeID{2}, 5, 20, 0.25, 20, 20, 1}, // bad audit success, good uptime
{storj.NodeID{3}, 20, 20, 1, 5, 20, 0.25}, // good audit success, bad uptime
{storj.NodeID{4}, 0, 0, 0, 20, 20, 1}, // "bad" audit success, no audits
{storj.NodeID{5}, 20, 20, 1, 0, 0, 0.25}, // "bad" uptime success, no checks
{storj.NodeID{6}, 0, 1, 0, 5, 5, 1}, // bad audit success exactly one audit
{storj.NodeID{7}, 0, 20, 0, 20, 20, 1}, // bad ratios, excluded from query
} {
nodeStats := &pb.NodeStats{
AuditSuccessRatio: tt.auditSuccessRatio,
UptimeRatio: tt.uptimeRatio,
AuditCount: tt.auditCount,
AuditSuccessCount: tt.auditSuccessCount,
UptimeCount: tt.uptimeCount,
UptimeSuccessCount: tt.uptimeSuccessCount,
}
createReq := &statdb.CreateRequest{
Node: tt.nodeID,
Stats: nodeStats,
}
_, err := sdb.Create(ctx, createReq)
assert.NoError(t, err)
}
findInvalidNodesReq := &statdb.FindInvalidNodesRequest{
NodeIds: storj.NodeIDList{
storj.NodeID{1}, storj.NodeID{2},
storj.NodeID{3}, storj.NodeID{4},
storj.NodeID{5}, storj.NodeID{6},
},
MaxStats: &pb.NodeStats{
AuditSuccessRatio: 0.5,
UptimeRatio: 0.5,
},
}
resp, err := sdb.FindInvalidNodes(ctx, findInvalidNodesReq)
assert.NoError(t, err)
invalid := resp.InvalidIds
assert.Contains(t, invalid, storj.NodeID{2})
assert.Contains(t, invalid, storj.NodeID{3})
assert.Contains(t, invalid, storj.NodeID{6})
assert.Len(t, invalid, 3)
}
{ // TestUpdateExists
auditSuccessCount, auditCount, auditSuccessRatio := getRatio(4, 10)
uptimeSuccessCount, uptimeCount, uptimeRatio := getRatio(8, 25)
getReq := &statdb.GetRequest{
Node: nodeID,
}
getResp, err := sdb.Get(ctx, getReq)
assert.NoError(t, err)
assert.EqualValues(t, nodeID, getResp.Stats.NodeId)
assert.EqualValues(t, auditCount, getResp.Stats.AuditCount)
assert.EqualValues(t, auditSuccessCount, getResp.Stats.AuditSuccessCount)
assert.EqualValues(t, auditSuccessRatio, getResp.Stats.AuditSuccessRatio)
assert.EqualValues(t, uptimeCount, getResp.Stats.UptimeCount)
assert.EqualValues(t, uptimeSuccessCount, getResp.Stats.UptimeSuccessCount)
assert.EqualValues(t, uptimeRatio, getResp.Stats.UptimeRatio)
updateReq := &statdb.UpdateRequest{
Node: nodeID,
UpdateAuditSuccess: true,
AuditSuccess: true,
UpdateUptime: true,
IsUp: false,
}
updResp, err := sdb.Update(ctx, updateReq)
assert.NoError(t, err)
_, _, newAuditRatio := getRatio(int(auditSuccessCount+1), int(auditCount+1))
_, _, newUptimeRatio := getRatio(int(uptimeSuccessCount), int(uptimeCount+1))
stats := updResp.Stats
assert.EqualValues(t, newAuditRatio, stats.AuditSuccessRatio)
assert.EqualValues(t, newUptimeRatio, stats.UptimeRatio)
}
{ // TestUpdateUptimeExists
auditSuccessCount, auditCount, auditSuccessRatio := getRatio(5, 11)
uptimeSuccessCount, uptimeCount, uptimeRatio := getRatio(8, 26)
getReq := &statdb.GetRequest{
Node: nodeID,
}
getResp, err := sdb.Get(ctx, getReq)
assert.NoError(t, err)
assert.EqualValues(t, nodeID, getResp.Stats.NodeId)
assert.EqualValues(t, auditCount, getResp.Stats.AuditCount)
assert.EqualValues(t, auditSuccessCount, getResp.Stats.AuditSuccessCount)
assert.EqualValues(t, auditSuccessRatio, getResp.Stats.AuditSuccessRatio)
assert.EqualValues(t, uptimeCount, getResp.Stats.UptimeCount)
assert.EqualValues(t, uptimeSuccessCount, getResp.Stats.UptimeSuccessCount)
assert.EqualValues(t, uptimeRatio, getResp.Stats.UptimeRatio)
updateReq := &statdb.UpdateUptimeRequest{
Node: nodeID,
IsUp: false,
}
resp, err := sdb.UpdateUptime(ctx, updateReq)
assert.NoError(t, err)
_, _, newUptimeRatio := getRatio(int(uptimeSuccessCount), int(uptimeCount+1))
stats := resp.Stats
assert.EqualValues(t, auditSuccessRatio, stats.AuditSuccessRatio)
assert.EqualValues(t, auditCount, stats.AuditCount)
assert.EqualValues(t, newUptimeRatio, stats.UptimeRatio)
}
{ // TestUpdateAuditSuccessExists
auditSuccessCount, auditCount, auditSuccessRatio := getRatio(5, 11)
uptimeSuccessCount, uptimeCount, uptimeRatio := getRatio(8, 27)
getReq := &statdb.GetRequest{
Node: nodeID,
}
getResp, err := sdb.Get(ctx, getReq)
assert.NoError(t, err)
assert.EqualValues(t, nodeID, getResp.Stats.NodeId)
assert.EqualValues(t, auditCount, getResp.Stats.AuditCount)
assert.EqualValues(t, auditSuccessCount, getResp.Stats.AuditSuccessCount)
assert.EqualValues(t, auditSuccessRatio, getResp.Stats.AuditSuccessRatio)
assert.EqualValues(t, uptimeCount, getResp.Stats.UptimeCount)
assert.EqualValues(t, uptimeSuccessCount, getResp.Stats.UptimeSuccessCount)
assert.EqualValues(t, uptimeRatio, getResp.Stats.UptimeRatio)
updateReq := &statdb.UpdateAuditSuccessRequest{
Node: nodeID,
AuditSuccess: false,
}
resp, err := sdb.UpdateAuditSuccess(ctx, updateReq)
assert.NoError(t, err)
_, _, newAuditRatio := getRatio(int(auditSuccessCount), int(auditCount+1))
stats := resp.Stats
assert.EqualValues(t, newAuditRatio, stats.AuditSuccessRatio)
assert.EqualValues(t, auditCount+1, stats.AuditCount)
assert.EqualValues(t, uptimeRatio, stats.UptimeRatio)
}
{ // TestUpdateBatchExists
nodeID1 := storj.NodeID{255, 1}
nodeID2 := storj.NodeID{255, 2}
auditSuccessCount1, auditCount1, auditRatio1 := getRatio(4, 10)
uptimeSuccessCount1, uptimeCount1, uptimeRatio1 := getRatio(8, 25)
nodeStats := &pb.NodeStats{
AuditSuccessCount: auditSuccessCount1,
AuditCount: auditCount1,
AuditSuccessRatio: auditRatio1,
UptimeSuccessCount: uptimeSuccessCount1,
UptimeCount: uptimeCount1,
UptimeRatio: uptimeRatio1,
}
createReq := &statdb.CreateRequest{
Node: nodeID1,
Stats: nodeStats,
}
resp, err := sdb.Create(ctx, createReq)
assert.NoError(t, err)
s := resp.Stats
assert.EqualValues(t, auditRatio1, s.AuditSuccessRatio)
assert.EqualValues(t, uptimeRatio1, s.UptimeRatio)
auditSuccessCount2, auditCount2, auditRatio2 := getRatio(7, 10)
uptimeSuccessCount2, uptimeCount2, uptimeRatio2 := getRatio(8, 20)
nodeStats = &pb.NodeStats{
AuditSuccessCount: auditSuccessCount2,
AuditCount: auditCount2,
AuditSuccessRatio: auditRatio2,
UptimeSuccessCount: uptimeSuccessCount2,
UptimeCount: uptimeCount2,
UptimeRatio: uptimeRatio2,
}
createReq = &statdb.CreateRequest{
Node: nodeID2,
Stats: nodeStats,
}
resp, err = sdb.Create(ctx, createReq)
assert.NoError(t, err)
s = resp.Stats
assert.EqualValues(t, auditRatio2, s.AuditSuccessRatio)
assert.EqualValues(t, uptimeRatio2, s.UptimeRatio)
node1 := &statdb.UpdateRequest{
Node: nodeID1,
UpdateAuditSuccess: true,
AuditSuccess: true,
UpdateUptime: true,
IsUp: false,
}
node2 := &statdb.UpdateRequest{
Node: nodeID2,
UpdateAuditSuccess: true,
AuditSuccess: true,
UpdateUptime: false,
}
updateBatchReq := &statdb.UpdateBatchRequest{
NodeList: []*statdb.UpdateRequest{node1, node2},
}
batchUpdResp, err := sdb.UpdateBatch(ctx, updateBatchReq)
assert.NoError(t, err)
_, _, newAuditRatio1 := getRatio(int(auditSuccessCount1+1), int(auditCount1+1))
_, _, newUptimeRatio1 := getRatio(int(uptimeSuccessCount1), int(uptimeCount1+1))
_, _, newAuditRatio2 := getRatio(int(auditSuccessCount2+1), int(auditCount2+1))
stats1 := batchUpdResp.StatsList[0]
stats2 := batchUpdResp.StatsList[1]
assert.EqualValues(t, newAuditRatio1, stats1.AuditSuccessRatio)
assert.EqualValues(t, newUptimeRatio1, stats1.UptimeRatio)
assert.EqualValues(t, newAuditRatio2, stats2.AuditSuccessRatio)
assert.EqualValues(t, uptimeRatio2, stats2.UptimeRatio)
}
}