storj/pkg/piecestore/psserver/psdb/psdb_test.go

325 lines
6.5 KiB
Go
Raw Normal View History

// Copyright (C) 2018 Storj Labs, Inc.
// See LICENSE for copying information.
package psdb
import (
2018-09-08 16:34:55 +01:00
"bytes"
2018-10-30 16:43:09 +00:00
"context"
"io/ioutil"
"os"
"path/filepath"
2018-09-08 16:34:55 +01:00
"strconv"
"testing"
"time"
"github.com/gogo/protobuf/proto"
_ "github.com/mattn/go-sqlite3"
"storj.io/storj/pkg/pb"
)
var ctx = context.Background()
2018-09-08 16:34:55 +01:00
const concurrency = 10
2018-10-30 16:43:09 +00:00
func newDB(t testing.TB) (*DB, func()) {
2018-09-08 16:34:55 +01:00
tmpdir, err := ioutil.TempDir("", "storj-psdb")
if err != nil {
2018-09-08 16:34:55 +01:00
t.Fatal(err)
}
2018-09-08 16:34:55 +01:00
dbpath := filepath.Join(tmpdir, "psdb.db")
2018-09-08 16:34:55 +01:00
db, err := Open(ctx, "", dbpath)
if err != nil {
2018-09-08 16:34:55 +01:00
t.Fatal(err)
}
2018-09-08 16:34:55 +01:00
return db, func() {
err := db.Close()
if err != nil {
t.Fatal(err)
}
2018-09-08 16:34:55 +01:00
err = os.RemoveAll(tmpdir)
if err != nil {
t.Fatal(err)
}
}
}
2018-10-30 16:43:09 +00:00
func TestNewInmemory(t *testing.T) {
db, err := OpenInMemory(context.Background(), "")
if err != nil {
t.Fatal(err)
}
if err := db.Close(); err != nil {
t.Fatal(err)
}
}
2018-09-08 16:34:55 +01:00
func TestHappyPath(t *testing.T) {
2018-10-30 16:43:09 +00:00
db, cleanup := newDB(t)
2018-09-08 16:34:55 +01:00
defer cleanup()
2018-09-08 16:34:55 +01:00
type TTL struct {
ID string
Expiration int64
}
2018-09-08 16:34:55 +01:00
tests := []TTL{
{ID: "", Expiration: 0},
{ID: "\x00", Expiration: ^int64(0)},
{ID: "test", Expiration: 666},
}
2018-09-08 16:34:55 +01:00
t.Run("Add", func(t *testing.T) {
for P := 0; P < concurrency; P++ {
t.Run("#"+strconv.Itoa(P), func(t *testing.T) {
t.Parallel()
for _, ttl := range tests {
err := db.AddTTL(ttl.ID, ttl.Expiration, 0)
2018-09-08 16:34:55 +01:00
if err != nil {
t.Fatal(err)
}
}
})
}
2018-09-08 16:34:55 +01:00
})
2018-09-08 16:34:55 +01:00
t.Run("Get", func(t *testing.T) {
for P := 0; P < concurrency; P++ {
t.Run("#"+strconv.Itoa(P), func(t *testing.T) {
t.Parallel()
for _, ttl := range tests {
expiration, err := db.GetTTLByID(ttl.ID)
if err != nil {
t.Fatal(err)
}
if ttl.Expiration != expiration {
t.Fatalf("expected %d got %d", ttl.Expiration, expiration)
}
}
})
}
})
2018-09-08 16:34:55 +01:00
t.Run("Delete", func(t *testing.T) {
for P := 0; P < concurrency; P++ {
t.Run("Delete", func(t *testing.T) {
t.Parallel()
for _, ttl := range tests {
err := db.DeleteTTLByID(ttl.ID)
if err != nil {
t.Fatal(err)
}
}
})
}
2018-09-08 16:34:55 +01:00
})
2018-09-08 16:34:55 +01:00
t.Run("Get Deleted", func(t *testing.T) {
for P := 0; P < concurrency; P++ {
t.Run("#"+strconv.Itoa(P), func(t *testing.T) {
t.Parallel()
for _, ttl := range tests {
expiration, err := db.GetTTLByID(ttl.ID)
if err == nil {
t.Fatal(err)
}
if expiration != 0 {
t.Fatalf("expected expiration 0 got %d", expiration)
}
}
})
}
})
bandwidthAllocation := func(satelliteID string, total int64) []byte {
2018-09-08 16:34:55 +01:00
return serialize(t, &pb.RenterBandwidthAllocation_Data{
PayerAllocation: &pb.PayerBandwidthAllocation{
Data: serialize(t, &pb.PayerBandwidthAllocation_Data{
SatelliteId: []byte(satelliteID),
}),
},
Total: total,
2018-09-08 16:34:55 +01:00
})
}
2018-09-08 16:34:55 +01:00
//TODO: use better data
allocationTests := []*pb.RenterBandwidthAllocation{
{
2018-09-08 16:34:55 +01:00
Signature: []byte("signed by test"),
Data: bandwidthAllocation("AB", 0),
2018-09-08 16:34:55 +01:00
},
{
Signature: []byte("signed by sigma"),
Data: bandwidthAllocation("AB", 10),
2018-09-08 16:34:55 +01:00
},
{
Signature: []byte("signed by sigma"),
Data: bandwidthAllocation("AB", 98),
2018-09-08 16:34:55 +01:00
},
{
Signature: []byte("signed by test"),
Data: bandwidthAllocation("AB", 3),
},
}
2018-09-08 16:34:55 +01:00
t.Run("Bandwidth Allocation", func(t *testing.T) {
for P := 0; P < concurrency; P++ {
t.Run("#"+strconv.Itoa(P), func(t *testing.T) {
t.Parallel()
for _, test := range allocationTests {
err := db.WriteBandwidthAllocToDB(test)
if err != nil {
t.Fatal(err)
}
agreements, err := db.GetBandwidthAllocationBySignature(test.Signature)
if err != nil {
t.Fatal(err)
}
found := false
for _, agreement := range agreements {
if bytes.Equal(agreement, test.Data) {
found = true
break
}
}
if !found {
t.Fatal("did not find added bandwidth allocation")
}
}
})
}
})
t.Run("Get all Bandwidth Allocations", func(t *testing.T) {
for P := 0; P < concurrency; P++ {
t.Run("#"+strconv.Itoa(P), func(t *testing.T) {
t.Parallel()
agreementGroups, err := db.GetBandwidthAllocations()
if err != nil {
t.Fatal(err)
}
found := false
for _, agreements := range agreementGroups {
for _, agreement := range agreements {
for _, test := range allocationTests {
if bytes.Equal(agreement.Agreement, test.Data) {
found = true
break
}
}
}
}
if !found {
t.Fatal("did not find added bandwidth allocation")
}
2018-09-08 16:34:55 +01:00
})
}
})
}
func TestBandwidthUsage(t *testing.T) {
2018-10-30 16:43:09 +00:00
db, cleanup := newDB(t)
defer cleanup()
type BWUSAGE struct {
size int64
timenow time.Time
}
bwtests := []BWUSAGE{
{size: 1000, timenow: time.Now()},
}
var bwTotal int64
t.Run("AddBandwidthUsed", func(t *testing.T) {
for P := 0; P < concurrency; P++ {
bwTotal = bwTotal + bwtests[0].size
t.Run("#"+strconv.Itoa(P), func(t *testing.T) {
t.Parallel()
for _, bw := range bwtests {
err := db.AddBandwidthUsed(bw.size)
if err != nil {
t.Fatal(err)
}
}
})
}
})
t.Run("GetTotalBandwidthBetween", func(t *testing.T) {
for P := 0; P < concurrency; P++ {
t.Run("#"+strconv.Itoa(P), func(t *testing.T) {
t.Parallel()
for _, bw := range bwtests {
size, err := db.GetTotalBandwidthBetween(bw.timenow, bw.timenow)
if err != nil {
t.Fatal(err)
}
if bwTotal != size {
t.Fatalf("expected %d got %d", bw.size, size)
}
}
})
}
})
t.Run("GetBandwidthUsedByDay", func(t *testing.T) {
for P := 0; P < concurrency; P++ {
t.Run("#"+strconv.Itoa(P), func(t *testing.T) {
t.Parallel()
for _, bw := range bwtests {
size, err := db.GetBandwidthUsedByDay(bw.timenow)
if err != nil {
t.Fatal(err)
}
if bwTotal != size {
t.Fatalf("expected %d got %d", bw.size, size)
}
}
})
}
})
}
2018-09-08 16:34:55 +01:00
func BenchmarkWriteBandwidthAllocation(b *testing.B) {
2018-10-30 16:43:09 +00:00
db, cleanup := newDB(b)
2018-09-08 16:34:55 +01:00
defer cleanup()
2018-09-08 16:34:55 +01:00
const WritesPerLoop = 10
2018-09-08 16:34:55 +01:00
data := serialize(b, &pb.RenterBandwidthAllocation_Data{
PayerAllocation: &pb.PayerBandwidthAllocation{},
Total: 156,
})
2018-09-08 16:34:55 +01:00
b.RunParallel(func(b *testing.PB) {
for b.Next() {
for i := 0; i < WritesPerLoop; i++ {
_ = db.WriteBandwidthAllocToDB(&pb.RenterBandwidthAllocation{
Signature: []byte("signed by test"),
Data: data,
})
}
}
2018-09-08 16:34:55 +01:00
})
}
2018-09-08 16:34:55 +01:00
func serialize(t testing.TB, v proto.Message) []byte {
data, err := proto.Marshal(v)
if err != nil {
t.Fatal(err)
}
return data
}