2019-03-18 10:55:06 +00:00
|
|
|
// Copyright (C) 2019 Storj Labs, Inc.
|
|
|
|
// See LICENSE for copying information.
|
|
|
|
|
|
|
|
package orders_test
|
|
|
|
|
|
|
|
import (
|
|
|
|
"testing"
|
2019-07-02 17:06:12 +01:00
|
|
|
"time"
|
2019-03-18 10:55:06 +00:00
|
|
|
|
|
|
|
"github.com/google/go-cmp/cmp"
|
|
|
|
"github.com/stretchr/testify/require"
|
|
|
|
|
|
|
|
"storj.io/storj/pkg/pb"
|
2019-07-28 06:55:36 +01:00
|
|
|
"storj.io/storj/pkg/signing"
|
2019-03-18 10:55:06 +00:00
|
|
|
"storj.io/storj/pkg/storj"
|
2019-11-14 19:46:15 +00:00
|
|
|
"storj.io/storj/private/testcontext"
|
|
|
|
"storj.io/storj/private/testidentity"
|
|
|
|
"storj.io/storj/private/testrand"
|
2019-03-18 10:55:06 +00:00
|
|
|
"storj.io/storj/storagenode"
|
|
|
|
"storj.io/storj/storagenode/orders"
|
|
|
|
"storj.io/storj/storagenode/storagenodedb/storagenodedbtest"
|
|
|
|
)
|
|
|
|
|
2019-07-19 18:40:27 +01:00
|
|
|
func TestDB(t *testing.T) {
|
2019-03-18 10:55:06 +00:00
|
|
|
storagenodedbtest.Run(t, func(t *testing.T, db storagenode.DB) {
|
|
|
|
ctx := testcontext.New(t)
|
|
|
|
defer ctx.Cleanup()
|
|
|
|
|
|
|
|
ordersdb := db.Orders()
|
|
|
|
|
2019-04-08 19:15:19 +01:00
|
|
|
storagenode := testidentity.MustPregeneratedSignedIdentity(0, storj.LatestIDVersion())
|
2019-03-18 10:55:06 +00:00
|
|
|
|
2019-04-08 19:15:19 +01:00
|
|
|
satellite0 := testidentity.MustPregeneratedSignedIdentity(1, storj.LatestIDVersion())
|
2019-03-18 10:55:06 +00:00
|
|
|
|
|
|
|
piece := storj.NewPieceID()
|
|
|
|
|
|
|
|
// basic test
|
2019-03-21 13:24:26 +00:00
|
|
|
emptyUnsent, err := ordersdb.ListUnsent(ctx, 100)
|
2019-03-18 10:55:06 +00:00
|
|
|
require.NoError(t, err)
|
2019-03-21 13:24:26 +00:00
|
|
|
require.Len(t, emptyUnsent, 0)
|
|
|
|
|
|
|
|
emptyArchive, err := ordersdb.ListArchived(ctx, 100)
|
|
|
|
require.NoError(t, err)
|
|
|
|
require.Len(t, emptyArchive, 0)
|
2019-03-18 10:55:06 +00:00
|
|
|
|
2019-07-02 17:06:12 +01:00
|
|
|
now := time.Now()
|
2019-03-18 10:55:06 +00:00
|
|
|
|
2019-07-11 21:51:40 +01:00
|
|
|
piecePublicKey, piecePrivateKey, err := storj.NewPieceKey()
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
2019-08-16 15:53:22 +01:00
|
|
|
infos := make([]*orders.Info, 2)
|
|
|
|
for i := 0; i < len(infos); i++ {
|
|
|
|
|
|
|
|
serialNumber := testrand.SerialNumber()
|
|
|
|
limit, err := signing.SignOrderLimit(ctx, signing.SignerFromFullIdentity(satellite0), &pb.OrderLimit{
|
|
|
|
SerialNumber: serialNumber,
|
|
|
|
SatelliteId: satellite0.ID,
|
|
|
|
UplinkPublicKey: piecePublicKey,
|
|
|
|
StorageNodeId: storagenode.ID,
|
|
|
|
PieceId: piece,
|
|
|
|
Limit: 100,
|
|
|
|
Action: pb.PieceAction_GET,
|
|
|
|
OrderCreation: now.AddDate(0, 0, -1),
|
|
|
|
PieceExpiration: now,
|
|
|
|
OrderExpiration: now,
|
|
|
|
})
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
order, err := signing.SignUplinkOrder(ctx, piecePrivateKey, &pb.Order{
|
|
|
|
SerialNumber: serialNumber,
|
|
|
|
Amount: 50,
|
|
|
|
})
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
infos[i] = &orders.Info{
|
|
|
|
Limit: limit,
|
|
|
|
Order: order,
|
|
|
|
}
|
2019-03-19 18:30:27 +00:00
|
|
|
}
|
2019-03-18 10:55:06 +00:00
|
|
|
|
|
|
|
// basic add
|
2019-08-16 15:53:22 +01:00
|
|
|
err = ordersdb.Enqueue(ctx, infos[0])
|
2019-03-18 10:55:06 +00:00
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
// duplicate add
|
2019-08-16 15:53:22 +01:00
|
|
|
err = ordersdb.Enqueue(ctx, infos[0])
|
2019-03-18 10:55:06 +00:00
|
|
|
require.Error(t, err, "duplicate add")
|
|
|
|
|
|
|
|
unsent, err := ordersdb.ListUnsent(ctx, 100)
|
|
|
|
require.NoError(t, err)
|
2019-08-16 15:53:22 +01:00
|
|
|
require.Empty(t, cmp.Diff([]*orders.Info{infos[0]}, unsent, cmp.Comparer(pb.Equal)))
|
|
|
|
|
|
|
|
// Another add
|
|
|
|
err = ordersdb.Enqueue(ctx, infos[1])
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
unsent, err = ordersdb.ListUnsent(ctx, 100)
|
|
|
|
require.NoError(t, err)
|
|
|
|
require.Empty(t,
|
|
|
|
cmp.Diff([]*orders.Info{infos[0], infos[1]}, unsent, cmp.Comparer(pb.Equal)),
|
|
|
|
)
|
2019-03-21 13:24:26 +00:00
|
|
|
|
|
|
|
// list by group
|
|
|
|
unsentGrouped, err := ordersdb.ListUnsentBySatellite(ctx)
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
expectedGrouped := map[storj.NodeID][]*orders.Info{
|
2019-06-27 19:52:50 +01:00
|
|
|
satellite0.ID: {
|
2019-08-16 15:53:22 +01:00
|
|
|
{Limit: infos[0].Limit, Order: infos[0].Order},
|
|
|
|
{Limit: infos[1].Limit, Order: infos[1].Order},
|
2019-03-21 13:24:26 +00:00
|
|
|
},
|
|
|
|
}
|
|
|
|
require.Empty(t, cmp.Diff(expectedGrouped, unsentGrouped, cmp.Comparer(pb.Equal)))
|
|
|
|
|
|
|
|
// test archival
|
2019-08-22 15:33:14 +01:00
|
|
|
archivedAt := time.Now().UTC()
|
|
|
|
err = ordersdb.Archive(ctx, archivedAt, orders.ArchiveRequest{
|
2019-08-16 15:53:22 +01:00
|
|
|
Satellite: satellite0.ID,
|
|
|
|
Serial: infos[0].Limit.SerialNumber,
|
|
|
|
Status: orders.StatusAccepted,
|
|
|
|
})
|
2019-03-21 13:24:26 +00:00
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
// duplicate archive
|
2019-08-22 15:33:14 +01:00
|
|
|
err = ordersdb.Archive(ctx, archivedAt, orders.ArchiveRequest{
|
2019-08-16 15:53:22 +01:00
|
|
|
Satellite: satellite0.ID,
|
|
|
|
Serial: infos[0].Limit.SerialNumber,
|
|
|
|
Status: orders.StatusRejected,
|
|
|
|
})
|
|
|
|
require.Error(t, err)
|
|
|
|
require.True(t,
|
|
|
|
orders.OrderNotFoundError.Has(err),
|
|
|
|
"expected orders.OrderNotFoundError class",
|
|
|
|
)
|
|
|
|
|
|
|
|
// one new archive and one duplicated
|
2019-08-22 15:33:14 +01:00
|
|
|
err = ordersdb.Archive(ctx, archivedAt, orders.ArchiveRequest{
|
2019-08-16 15:53:22 +01:00
|
|
|
Satellite: satellite0.ID,
|
|
|
|
Serial: infos[0].Limit.SerialNumber,
|
|
|
|
Status: orders.StatusRejected,
|
|
|
|
}, orders.ArchiveRequest{
|
|
|
|
Satellite: satellite0.ID,
|
|
|
|
Serial: infos[1].Limit.SerialNumber,
|
|
|
|
Status: orders.StatusRejected,
|
|
|
|
})
|
2019-03-21 13:24:26 +00:00
|
|
|
require.Error(t, err)
|
2019-08-16 15:53:22 +01:00
|
|
|
require.True(t,
|
|
|
|
orders.OrderNotFoundError.Has(err),
|
|
|
|
"expected ErrUnsentOrderNotFoundError class",
|
|
|
|
)
|
2019-03-21 13:24:26 +00:00
|
|
|
|
|
|
|
// shouldn't be in unsent list
|
|
|
|
unsent, err = ordersdb.ListUnsent(ctx, 100)
|
|
|
|
require.NoError(t, err)
|
|
|
|
require.Len(t, unsent, 0)
|
|
|
|
|
|
|
|
// it should now be in the archive
|
|
|
|
archived, err := ordersdb.ListArchived(ctx, 100)
|
|
|
|
require.NoError(t, err)
|
2019-08-16 15:53:22 +01:00
|
|
|
require.Len(t, archived, 2)
|
2019-03-21 13:24:26 +00:00
|
|
|
|
|
|
|
require.Empty(t, cmp.Diff([]*orders.ArchivedInfo{
|
|
|
|
{
|
2019-08-16 15:53:22 +01:00
|
|
|
Limit: infos[0].Limit,
|
|
|
|
Order: infos[0].Order,
|
2019-03-21 13:24:26 +00:00
|
|
|
|
|
|
|
Status: orders.StatusAccepted,
|
|
|
|
ArchivedAt: archived[0].ArchivedAt,
|
|
|
|
},
|
2019-08-16 15:53:22 +01:00
|
|
|
{
|
|
|
|
Limit: infos[1].Limit,
|
|
|
|
Order: infos[1].Order,
|
|
|
|
|
|
|
|
Status: orders.StatusRejected,
|
|
|
|
ArchivedAt: archived[1].ArchivedAt,
|
|
|
|
},
|
2019-03-21 13:24:26 +00:00
|
|
|
}, archived, cmp.Comparer(pb.Equal)))
|
|
|
|
|
2019-08-15 17:56:33 +01:00
|
|
|
// with 1 hour ttl, archived order should not be deleted
|
|
|
|
n, err := db.Orders().CleanArchive(ctx, time.Hour)
|
|
|
|
require.NoError(t, err)
|
|
|
|
require.Equal(t, 0, n)
|
|
|
|
|
|
|
|
// with 1 nanosecond ttl, archived order should be deleted
|
|
|
|
n, err = db.Orders().CleanArchive(ctx, time.Nanosecond)
|
|
|
|
require.NoError(t, err)
|
2019-08-16 15:53:22 +01:00
|
|
|
require.Equal(t, 2, n)
|
2019-03-18 10:55:06 +00:00
|
|
|
})
|
|
|
|
}
|
2019-07-19 18:40:27 +01:00
|
|
|
|
|
|
|
func TestDB_Trivial(t *testing.T) {
|
|
|
|
storagenodedbtest.Run(t, func(t *testing.T, db storagenode.DB) {
|
|
|
|
ctx := testcontext.New(t)
|
|
|
|
defer ctx.Cleanup()
|
|
|
|
|
|
|
|
satelliteID, serial := testrand.NodeID(), testrand.SerialNumber()
|
|
|
|
|
|
|
|
{ // Ensure Enqueue works at all
|
|
|
|
err := db.Orders().Enqueue(ctx, &orders.Info{
|
|
|
|
Order: &pb.Order{},
|
|
|
|
Limit: &pb.OrderLimit{
|
|
|
|
SatelliteId: satelliteID,
|
|
|
|
SerialNumber: serial,
|
|
|
|
OrderExpiration: time.Now(),
|
|
|
|
},
|
|
|
|
})
|
|
|
|
require.NoError(t, err)
|
|
|
|
}
|
|
|
|
|
|
|
|
{ // Ensure ListUnsent works at all
|
2019-08-13 20:08:05 +01:00
|
|
|
infos, err := db.Orders().ListUnsent(ctx, 1)
|
2019-07-19 18:40:27 +01:00
|
|
|
require.NoError(t, err)
|
2019-08-13 20:08:05 +01:00
|
|
|
require.Len(t, infos, 1)
|
2019-07-19 18:40:27 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
{ // Ensure ListUnsentBySatellite works at all
|
2019-08-13 20:08:05 +01:00
|
|
|
infos, err := db.Orders().ListUnsentBySatellite(ctx)
|
2019-07-19 18:40:27 +01:00
|
|
|
require.NoError(t, err)
|
2019-08-13 20:08:05 +01:00
|
|
|
require.Len(t, infos, 1)
|
|
|
|
require.Contains(t, infos, satelliteID)
|
|
|
|
require.Len(t, infos[satelliteID], 1)
|
2019-07-19 18:40:27 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
{ // Ensure Archive works at all
|
2019-08-22 15:33:14 +01:00
|
|
|
err := db.Orders().Archive(ctx, time.Now().UTC(), orders.ArchiveRequest{satelliteID, serial, orders.StatusAccepted})
|
2019-07-19 18:40:27 +01:00
|
|
|
require.NoError(t, err)
|
|
|
|
}
|
|
|
|
|
|
|
|
{ // Ensure ListArchived works at all
|
2019-08-13 20:08:05 +01:00
|
|
|
infos, err := db.Orders().ListArchived(ctx, 1)
|
2019-07-19 18:40:27 +01:00
|
|
|
require.NoError(t, err)
|
2019-08-13 20:08:05 +01:00
|
|
|
require.Len(t, infos, 1)
|
2019-07-19 18:40:27 +01:00
|
|
|
}
|
2019-08-15 17:56:33 +01:00
|
|
|
{ // Ensure CleanArchive works at all
|
|
|
|
n, err := db.Orders().CleanArchive(ctx, time.Nanosecond)
|
|
|
|
require.NoError(t, err)
|
|
|
|
require.Equal(t, 1, n)
|
|
|
|
}
|
2019-07-19 18:40:27 +01:00
|
|
|
})
|
|
|
|
}
|