forked from TrueCloudLab/frostfs-node
[#1255] node/session: Add persistent tests
Signed-off-by: Pavel Karpy <carpawell@nspcc.ru>
This commit is contained in:
parent
455b9fb325
commit
a884ad56d9
2 changed files with 252 additions and 0 deletions
226
pkg/services/session/storage/persistent/executor_test.go
Normal file
226
pkg/services/session/storage/persistent/executor_test.go
Normal file
|
@ -0,0 +1,226 @@
|
|||
package persistent
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"crypto/ecdsa"
|
||||
"crypto/elliptic"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
||||
"github.com/nspcc-dev/neofs-api-go/v2/refs"
|
||||
"github.com/nspcc-dev/neofs-api-go/v2/session"
|
||||
ownerSDK "github.com/nspcc-dev/neofs-sdk-go/owner"
|
||||
"github.com/stretchr/testify/require"
|
||||
"go.etcd.io/bbolt"
|
||||
)
|
||||
|
||||
func TestTokenStore(t *testing.T) {
|
||||
ts, err := NewTokenStore(filepath.Join(t.TempDir(), ".storage"))
|
||||
require.NoError(t, err)
|
||||
|
||||
defer ts.Close()
|
||||
|
||||
owner := new(refs.OwnerID)
|
||||
owner.SetValue([]byte{0, 1, 2, 3, 4, 5})
|
||||
|
||||
req := new(session.CreateRequestBody)
|
||||
req.SetOwnerID(owner)
|
||||
|
||||
const tokenNumber = 5
|
||||
|
||||
type tok struct {
|
||||
id []byte
|
||||
key []byte
|
||||
}
|
||||
|
||||
tokens := make([]tok, 0, tokenNumber)
|
||||
|
||||
for i := 0; i < tokenNumber; i++ {
|
||||
req.SetExpiration(uint64(i))
|
||||
|
||||
res, err := ts.Create(context.Background(), req)
|
||||
require.NoError(t, err)
|
||||
|
||||
tokens = append(tokens, tok{
|
||||
id: res.GetID(),
|
||||
key: res.GetSessionKey(),
|
||||
})
|
||||
}
|
||||
|
||||
for i, token := range tokens {
|
||||
savedToken := ts.Get(ownerSDK.NewIDFromV2(owner), token.id)
|
||||
|
||||
require.Equal(t, uint64(i), savedToken.ExpiredAt())
|
||||
|
||||
equalKeys(t, token.key, savedToken.SessionKey())
|
||||
}
|
||||
}
|
||||
|
||||
func TestTokenStore_Persistent(t *testing.T) {
|
||||
path := filepath.Join(t.TempDir(), ".storage")
|
||||
|
||||
ts, err := NewTokenStore(path)
|
||||
require.NoError(t, err)
|
||||
|
||||
owner := new(refs.OwnerID)
|
||||
owner.SetValue([]byte{0, 1, 2, 3, 4, 5})
|
||||
|
||||
const exp = 12345
|
||||
|
||||
req := new(session.CreateRequestBody)
|
||||
req.SetOwnerID(owner)
|
||||
req.SetExpiration(exp)
|
||||
|
||||
res, err := ts.Create(context.Background(), req)
|
||||
require.NoError(t, err)
|
||||
|
||||
id := res.GetID()
|
||||
pubKey := res.GetSessionKey()
|
||||
|
||||
// close db (stop the node)
|
||||
require.NoError(t, ts.Close())
|
||||
|
||||
// open persistent storage again
|
||||
ts, err = NewTokenStore(path)
|
||||
require.NoError(t, err)
|
||||
|
||||
defer ts.Close()
|
||||
|
||||
savedToken := ts.Get(ownerSDK.NewIDFromV2(owner), id)
|
||||
|
||||
equalKeys(t, pubKey, savedToken.SessionKey())
|
||||
}
|
||||
|
||||
func TestTokenStore_RemoveOld(t *testing.T) {
|
||||
tests := []*struct {
|
||||
epoch uint64
|
||||
id, key []byte
|
||||
}{
|
||||
{
|
||||
epoch: 1,
|
||||
},
|
||||
{
|
||||
epoch: 2,
|
||||
},
|
||||
{
|
||||
epoch: 3,
|
||||
},
|
||||
{
|
||||
epoch: 4,
|
||||
},
|
||||
{
|
||||
epoch: 5,
|
||||
},
|
||||
{
|
||||
epoch: 6,
|
||||
},
|
||||
}
|
||||
|
||||
ts, err := NewTokenStore(filepath.Join(t.TempDir(), ".storage"))
|
||||
require.NoError(t, err)
|
||||
|
||||
defer ts.Close()
|
||||
|
||||
owner := new(refs.OwnerID)
|
||||
owner.SetValue([]byte{0, 1, 2, 3, 4, 5})
|
||||
|
||||
req := new(session.CreateRequestBody)
|
||||
req.SetOwnerID(owner)
|
||||
|
||||
for _, test := range tests {
|
||||
req.SetExpiration(test.epoch)
|
||||
|
||||
res, err := ts.Create(context.Background(), req)
|
||||
require.NoError(t, err)
|
||||
|
||||
test.id = res.GetID()
|
||||
test.key = res.GetSessionKey()
|
||||
}
|
||||
|
||||
const currEpoch = 3
|
||||
|
||||
ts.RemoveOld(currEpoch)
|
||||
|
||||
for _, test := range tests {
|
||||
token := ts.Get(ownerSDK.NewIDFromV2(owner), test.id)
|
||||
|
||||
if test.epoch <= currEpoch {
|
||||
require.Nil(t, token)
|
||||
} else {
|
||||
equalKeys(t, test.key, token.SessionKey())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// This test was added to fix bolt's behaviour since the persistent
|
||||
// storage uses cursor and there is an issue about `cursor.Delete`
|
||||
// method: https://github.com/etcd-io/bbolt/issues/146.
|
||||
//
|
||||
// If this test is passing, TokenStore works correctly.
|
||||
func TestBolt_Cursor(t *testing.T) {
|
||||
db, err := bbolt.Open(filepath.Join(t.TempDir(), ".storage"), 0666, nil)
|
||||
require.NoError(t, err)
|
||||
|
||||
defer db.Close()
|
||||
|
||||
cursorKeys := make(map[string]struct{})
|
||||
|
||||
var bucketName = []byte("bucket")
|
||||
|
||||
err = db.Update(func(tx *bbolt.Tx) (err error) {
|
||||
b, err := tx.CreateBucket(bucketName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
put := func(s []byte) {
|
||||
if err == nil {
|
||||
err = b.Put(s, s)
|
||||
}
|
||||
}
|
||||
|
||||
put([]byte("1"))
|
||||
put([]byte("2"))
|
||||
put([]byte("3"))
|
||||
put([]byte("4"))
|
||||
|
||||
return
|
||||
})
|
||||
|
||||
err = db.Update(func(tx *bbolt.Tx) error {
|
||||
b := tx.Bucket(bucketName)
|
||||
c := b.Cursor()
|
||||
|
||||
for k, _ := c.First(); k != nil; k, _ = c.Next() {
|
||||
// fill key that was viewed
|
||||
cursorKeys[string(k)] = struct{}{}
|
||||
|
||||
if bytes.Equal(k, []byte("1")) {
|
||||
// delete the first one
|
||||
err = c.Delete()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
_, ok := cursorKeys["2"]
|
||||
if !ok {
|
||||
t.Fatal("unexpectedly skipped '2' value")
|
||||
}
|
||||
}
|
||||
|
||||
func equalKeys(t *testing.T, sessionKey []byte, savedPrivateKey *ecdsa.PrivateKey) {
|
||||
returnedPubKey, err := keys.NewPublicKeyFromBytes(sessionKey, elliptic.P256())
|
||||
require.NoError(t, err)
|
||||
|
||||
savedPubKey := (keys.PublicKey)(savedPrivateKey.PublicKey)
|
||||
|
||||
require.Equal(t, true, returnedPubKey.Equal(&savedPubKey))
|
||||
}
|
26
pkg/services/session/storage/persistent/util_test.go
Normal file
26
pkg/services/session/storage/persistent/util_test.go
Normal file
|
@ -0,0 +1,26 @@
|
|||
package persistent
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestPack(t *testing.T) {
|
||||
key, err := keys.NewPrivateKey()
|
||||
require.NoError(t, err)
|
||||
|
||||
const exp = 12345
|
||||
|
||||
raw, err := packToken(exp, &key.PrivateKey)
|
||||
require.NoError(t, err)
|
||||
|
||||
require.Equal(t, uint64(exp), epochFromToken(raw))
|
||||
|
||||
unpacked, err := unpackToken(raw)
|
||||
require.NoError(t, err)
|
||||
|
||||
require.Equal(t, uint64(exp), unpacked.ExpiredAt())
|
||||
require.Equal(t, true, key.Equal(unpacked.SessionKey()))
|
||||
}
|
Loading…
Reference in a new issue