Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

storagenode/reputation: unit test coverage #5515

Open
wants to merge 8 commits into
base: main
Choose a base branch
from
57 changes: 57 additions & 0 deletions satellite/audit/reverifier_mock_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package audit_test

import (
"context"
"testing"
"time"

"go.uber.org/zap"

"storj.io/common/uuid"
"storj.io/storj/satellite/audit"
"storj.io/storj/satellite/metabase"
"storj.io/storj/satellite/overlay"
)

type mockVerifier struct{}

func (verifier *mockVerifier) DoReverifyPiece(ctx context.Context, logger *zap.Logger, locator *audit.PieceLocator) (audit.Outcome, overlay.ReputationStatus, error) {
return audit.OutcomeSuccess, overlay.ReputationStatus{}, nil
}

type mockDB struct{}

func (db *mockDB) Next(ctx context.Context, limit int) ([]audit.ReverificationJob, error) {
return []audit.ReverificationJob{}, nil
}

func (db *mockDB) Done(ctx context.Context, job audit.ReverificationJob, outcome audit.Outcome) error {
return nil
}

func TestReverifier_ReverifyPiece(t *testing.T) {
ctx := context.Background()
log := zap.NewNop()

verifier := &mockVerifier{}
db := &mockDB{}

reverifier := audit.NewReverifier(log, verifier, db, audit.Config{ReverificationRetryInterval: time.Hour})

var locator = &audit.PieceLocator{
StreamID: uuid.New(),
Position: metabase.SegmentPosition{},
NodeID: [32]byte{},
}
PieceNum: 0,
neo-cypher marked this conversation as resolved.
Show resolved Hide resolved
outcome, reputation, err := reverifier.ReverifyPiece(ctx, log, locator)
if err != nil {
t.Fatal("expected err to be nil but got", err)
}
if outcome != audit.OutcomeSuccess {
t.Fatal("expected outcome to be", audit.OutcomeSuccess, "but got", outcome)
}
if reputation != (overlay.ReputationStatus{}) {
t.Fatal("expected reputation to be", overlay.ReputationStatus{}, "but got", reputation)
}
}
65 changes: 65 additions & 0 deletions satellite/reputation/audithistory_cheat_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
package reputation_test

import (
"testing"
"time"

"storj.io/common/pb"
"storj.io/storj/satellite/reputation"
)

func Test_CheatAddAuditToHistory(t *testing.T) {
config := reputation.AuditHistoryConfig{
WindowSize: time.Hour,
TrackingPeriod: 2 * time.Hour,
GracePeriod: time.Hour,
OfflineThreshold: 0.6,
OfflineDQEnabled: true,
OfflineSuspensionEnabled: true,
}
// Define test cases
testCases := []struct {
desc string
online bool
auditTime time.Time
config reputation.AuditHistoryConfig
expected error
}{
{
desc: "Test adding audit to empty history",
online: true,
auditTime: time.Now(),
config: config,
expected: nil,
},
{
desc: "Test adding audit to existing window",
online: false,
auditTime: time.Now(),
config: reputation.AuditHistoryConfig{WindowSize: time.Hour, TrackingPeriod: time.Hour * 24},
expected: nil,
},
{
desc: "Test adding audit outside of tracking period",
online: true,
auditTime: time.Now().Add(-time.Hour * 48),
config: reputation.AuditHistoryConfig{WindowSize: time.Hour, TrackingPeriod: time.Hour * 24},
expected: nil,
},
}

for _, tc := range testCases {
t.Run(tc.desc, func(t *testing.T) {
// Define the initial audit history
a := &pb.AuditHistory{}

// Add audit to history
err := reputation.AddAuditToHistory(a, tc.online, tc.auditTime, tc.config)

// Check if the returned error is as expected
if err != tc.expected {
t.Fatalf("Expected error to be %v, but got %v", tc.expected, err)
}
})
}
}
53 changes: 53 additions & 0 deletions storagenode/nodestats/service_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
// Copyright (C) 2019 Storj Labs, Inc.
// See LICENSE for copying information.

package nodestats

import (
"context"
"reflect"
"testing"

"go.uber.org/zap"

"storj.io/common/rpc"
"storj.io/common/storj"
"storj.io/storj/storagenode/reputation"
"storj.io/storj/storagenode/trust"
)

func TestService_GetReputationStats(t *testing.T) {
type fields struct {
log *zap.Logger
dialer rpc.Dialer
trust *trust.Pool
}
type args struct {
ctx context.Context
satelliteID storj.NodeID
}
var tests []struct {
name string
fields fields
args args
want *reputation.Stats
wantErr bool
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
s := &Service{
log: tt.fields.log,
dialer: tt.fields.dialer,
trust: tt.fields.trust,
}
got, err := s.GetReputationStats(tt.args.ctx, tt.args.satelliteID)
if (err != nil) != tt.wantErr {
t.Errorf("Service.GetReputationStats() error = %v, wantErr %v", err, tt.wantErr)
return
}
if !reflect.DeepEqual(got, tt.want) {
t.Errorf("Service.GetReputationStats() = %v, want %v", got, tt.want)
}
})
}
}
126 changes: 126 additions & 0 deletions storagenode/reputation/service_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
// Copyright (C) 2023 Storj Labs, Inc.
// See LICENSE for copying information.

package reputation

import (
"context"
"testing"
"time"

"github.com/stretchr/testify/require"
"github.com/zeebo/assert"
"go.uber.org/zap"

"storj.io/common/storj"
"storj.io/storj/storagenode/notifications"
)

func TestNewService(t *testing.T) {
type args struct {
log *zap.Logger
db DB
nodeID storj.NodeID
notifications *notifications.Service
}
var tests []struct {
name string
args func(t *testing.T) args

want1 *Service
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
tArgs := tt.args(t)

got1 := NewService(tArgs.log, tArgs.db, tArgs.nodeID, tArgs.notifications)

assert.Equal(t, tt.want1, got1)
})
}
}

func TestService_Store(t *testing.T) {
type args struct {
ctx context.Context
stats Stats
satelliteID storj.NodeID
}
var tests []struct {
name string
init func(t *testing.T) *Service
inspect func(r *Service, t *testing.T)

args func(t *testing.T) args

wantErr bool
inspectErr func(err error, t *testing.T)
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
tArgs := tt.args(t)

receiver := tt.init(t)
err := receiver.Store(tArgs.ctx, tArgs.stats, tArgs.satelliteID)

if tt.inspect != nil {
tt.inspect(receiver, t)
}

if tt.wantErr {
require.Error(t, err)
if tt.inspectErr != nil {
tt.inspectErr(err, t)
}
}
})
}
}

func Test_isSuspended(t *testing.T) {
type args struct {
new Stats
old Stats
}
var tests []struct {
name string
args func(t *testing.T) args

want1 bool
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
tArgs := tt.args(t)

got1 := isSuspended(tArgs.new, tArgs.old)

assert.Equal(t, tt.want1, got1)
})
}
}

func Test_newSuspensionNotification(t *testing.T) {
type args struct {
satelliteID storj.NodeID
senderID storj.NodeID
time time.Time
}
var tests []struct {
name string
args func(t *testing.T) args

want1 notifications.NewNotification
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
tArgs := tt.args(t)

got1 := newSuspensionNotification(tArgs.satelliteID, tArgs.senderID, tArgs.time)

assert.Equal(t, tt.want1, got1)
})
}
}