Add stable marshal for service package
Signed-off-by: Alex Vanin <alexey@nspcc.ru>
This commit is contained in:
parent
c96598713e
commit
c214d4d763
3 changed files with 1537 additions and 50 deletions
1118
v2/service/marshal.go
Normal file
1118
v2/service/marshal.go
Normal file
File diff suppressed because it is too large
Load diff
401
v2/service/marshal_test.go
Normal file
401
v2/service/marshal_test.go
Normal file
|
@ -0,0 +1,401 @@
|
|||
package service_test
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/nspcc-dev/neofs-api-go/v2/acl"
|
||||
"github.com/nspcc-dev/neofs-api-go/v2/refs"
|
||||
"github.com/nspcc-dev/neofs-api-go/v2/service"
|
||||
grpc "github.com/nspcc-dev/neofs-api-go/v2/service/grpc"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestSignature_StableMarshal(t *testing.T) {
|
||||
signatureFrom := generateSignature("Public Key", "Signature")
|
||||
transport := new(grpc.Signature)
|
||||
|
||||
t.Run("non empty", func(t *testing.T) {
|
||||
wire, err := signatureFrom.StableMarshal(nil)
|
||||
require.NoError(t, err)
|
||||
|
||||
err = transport.Unmarshal(wire)
|
||||
require.NoError(t, err)
|
||||
|
||||
signatureTo := service.SignatureFromGRPCMessage(transport)
|
||||
require.Equal(t, signatureFrom, signatureTo)
|
||||
})
|
||||
}
|
||||
|
||||
func TestVersion_StableMarshal(t *testing.T) {
|
||||
versionFrom := generateVersion(2, 0)
|
||||
transport := new(grpc.Version)
|
||||
|
||||
t.Run("non empty", func(t *testing.T) {
|
||||
wire, err := versionFrom.StableMarshal(nil)
|
||||
require.NoError(t, err)
|
||||
|
||||
err = transport.Unmarshal(wire)
|
||||
require.NoError(t, err)
|
||||
|
||||
versionTo := service.VersionFromGRPCMessage(transport)
|
||||
require.Equal(t, versionFrom, versionTo)
|
||||
})
|
||||
}
|
||||
|
||||
func TestXHeader_StableMarshal(t *testing.T) {
|
||||
xheaderFrom := generateXHeader("X-Header-Key", "X-Header-Value")
|
||||
transport := new(grpc.XHeader)
|
||||
|
||||
t.Run("non empty", func(t *testing.T) {
|
||||
wire, err := xheaderFrom.StableMarshal(nil)
|
||||
require.NoError(t, err)
|
||||
|
||||
err = transport.Unmarshal(wire)
|
||||
require.NoError(t, err)
|
||||
|
||||
xheaderTo := service.XHeaderFromGRPCMessage(transport)
|
||||
require.Equal(t, xheaderFrom, xheaderTo)
|
||||
})
|
||||
}
|
||||
|
||||
func TestTokenLifetime_StableMarshal(t *testing.T) {
|
||||
lifetimeFrom := generateLifetime(10, 20, 30)
|
||||
transport := new(grpc.TokenLifetime)
|
||||
|
||||
t.Run("non empty", func(t *testing.T) {
|
||||
wire, err := lifetimeFrom.StableMarshal(nil)
|
||||
require.NoError(t, err)
|
||||
|
||||
err = transport.Unmarshal(wire)
|
||||
require.NoError(t, err)
|
||||
|
||||
lifetimeTo := service.TokenLifetimeFromGRPCMessage(transport)
|
||||
require.Equal(t, lifetimeFrom, lifetimeTo)
|
||||
})
|
||||
}
|
||||
|
||||
func TestObjectSessionContext_StableMarshal(t *testing.T) {
|
||||
objectCtxFrom := generateObjectCtx("Object ID")
|
||||
transport := new(grpc.ObjectServiceContext)
|
||||
|
||||
t.Run("non empty", func(t *testing.T) {
|
||||
wire, err := objectCtxFrom.StableMarshal(nil)
|
||||
require.NoError(t, err)
|
||||
|
||||
err = transport.Unmarshal(wire)
|
||||
require.NoError(t, err)
|
||||
|
||||
objectCtxTo := service.ObjectSessionContextFromGRPCMessage(transport)
|
||||
require.Equal(t, objectCtxFrom, objectCtxTo)
|
||||
})
|
||||
}
|
||||
|
||||
func TestSessionTokenBody_StableMarshal(t *testing.T) {
|
||||
sessionTokenBodyFrom := generateSessionTokenBody("Session Token Body")
|
||||
transport := new(grpc.SessionToken_Body)
|
||||
|
||||
t.Run("non empty", func(t *testing.T) {
|
||||
wire, err := sessionTokenBodyFrom.StableMarshal(nil)
|
||||
require.NoError(t, err)
|
||||
|
||||
err = transport.Unmarshal(wire)
|
||||
require.NoError(t, err)
|
||||
|
||||
sessionTokenBodyTo := service.SessionTokenBodyFromGRPCMessage(transport)
|
||||
require.Equal(t, sessionTokenBodyFrom, sessionTokenBodyTo)
|
||||
})
|
||||
}
|
||||
|
||||
func TestSessionToken_StableMarshal(t *testing.T) {
|
||||
sessionTokenFrom := generateSessionToken("Session Token")
|
||||
transport := new(grpc.SessionToken)
|
||||
|
||||
t.Run("non empty", func(t *testing.T) {
|
||||
wire, err := sessionTokenFrom.StableMarshal(nil)
|
||||
require.NoError(t, err)
|
||||
|
||||
err = transport.Unmarshal(wire)
|
||||
require.NoError(t, err)
|
||||
|
||||
sessionTokenTo := service.SessionTokenFromGRPCMessage(transport)
|
||||
require.Equal(t, sessionTokenFrom, sessionTokenTo)
|
||||
})
|
||||
}
|
||||
|
||||
func TestBearerTokenBody_StableMarshal(t *testing.T) {
|
||||
bearerTokenBodyFrom := generateBearerTokenBody("Bearer Token Body")
|
||||
transport := new(grpc.BearerToken_Body)
|
||||
|
||||
t.Run("non empty", func(t *testing.T) {
|
||||
wire, err := bearerTokenBodyFrom.StableMarshal(nil)
|
||||
require.NoError(t, err)
|
||||
|
||||
err = transport.Unmarshal(wire)
|
||||
require.NoError(t, err)
|
||||
|
||||
bearerTokenBodyTo := service.BearerTokenBodyFromGRPCMessage(transport)
|
||||
require.Equal(t, bearerTokenBodyFrom, bearerTokenBodyTo)
|
||||
})
|
||||
}
|
||||
|
||||
func TestBearerToken_StableMarshal(t *testing.T) {
|
||||
bearerTokenFrom := generateBearerToken("Bearer Token")
|
||||
transport := new(grpc.BearerToken)
|
||||
|
||||
t.Run("non empty", func(t *testing.T) {
|
||||
wire, err := bearerTokenFrom.StableMarshal(nil)
|
||||
require.NoError(t, err)
|
||||
|
||||
err = transport.Unmarshal(wire)
|
||||
require.NoError(t, err)
|
||||
|
||||
bearerTokenTo := service.BearerTokenFromGRPCMessage(transport)
|
||||
require.Equal(t, bearerTokenFrom, bearerTokenTo)
|
||||
})
|
||||
}
|
||||
|
||||
func TestRequestMetaHeader_StableMarshal(t *testing.T) {
|
||||
metaHeaderOrigin := generateRequestMetaHeader(10, "Bearer One", "Session One")
|
||||
metaHeaderFrom := generateRequestMetaHeader(20, "Bearer Two", "Session Two")
|
||||
metaHeaderFrom.SetOrigin(metaHeaderOrigin)
|
||||
transport := new(grpc.RequestMetaHeader)
|
||||
|
||||
t.Run("non empty", func(t *testing.T) {
|
||||
wire, err := metaHeaderFrom.StableMarshal(nil)
|
||||
require.NoError(t, err)
|
||||
|
||||
err = transport.Unmarshal(wire)
|
||||
require.NoError(t, err)
|
||||
|
||||
metaHeaderTo := service.RequestMetaHeaderFromGRPCMessage(transport)
|
||||
require.Equal(t, metaHeaderFrom, metaHeaderTo)
|
||||
})
|
||||
}
|
||||
|
||||
func TestRequestVerificationHeader_StableMarshal(t *testing.T) {
|
||||
verifHeaderOrigin := generateRequestVerificationHeader("Key", "Inside")
|
||||
verifHeaderFrom := generateRequestVerificationHeader("Value", "Outside")
|
||||
verifHeaderFrom.SetOrigin(verifHeaderOrigin)
|
||||
transport := new(grpc.RequestVerificationHeader)
|
||||
|
||||
t.Run("non empty", func(t *testing.T) {
|
||||
wire, err := verifHeaderFrom.StableMarshal(nil)
|
||||
require.NoError(t, err)
|
||||
|
||||
err = transport.Unmarshal(wire)
|
||||
require.NoError(t, err)
|
||||
|
||||
verifHeaderTo := service.RequestVerificationHeaderFromGRPCMessage(transport)
|
||||
require.Equal(t, verifHeaderFrom, verifHeaderTo)
|
||||
})
|
||||
}
|
||||
|
||||
func TestResponseMetaHeader_StableMarshal(t *testing.T) {
|
||||
metaHeaderOrigin := generateResponseMetaHeader(10)
|
||||
metaHeaderFrom := generateResponseMetaHeader(20)
|
||||
metaHeaderFrom.SetOrigin(metaHeaderOrigin)
|
||||
transport := new(grpc.ResponseMetaHeader)
|
||||
|
||||
t.Run("non empty", func(t *testing.T) {
|
||||
wire, err := metaHeaderFrom.StableMarshal(nil)
|
||||
require.NoError(t, err)
|
||||
|
||||
err = transport.Unmarshal(wire)
|
||||
require.NoError(t, err)
|
||||
|
||||
metaHeaderTo := service.ResponseMetaHeaderFromGRPCMessage(transport)
|
||||
require.Equal(t, metaHeaderFrom, metaHeaderTo)
|
||||
})
|
||||
}
|
||||
|
||||
func TestResponseVerificationHeader_StableMarshal(t *testing.T) {
|
||||
verifHeaderOrigin := generateResponseVerificationHeader("Key", "Inside")
|
||||
verifHeaderFrom := generateResponseVerificationHeader("Value", "Outside")
|
||||
verifHeaderFrom.SetOrigin(verifHeaderOrigin)
|
||||
transport := new(grpc.ResponseVerificationHeader)
|
||||
|
||||
t.Run("non empty", func(t *testing.T) {
|
||||
wire, err := verifHeaderFrom.StableMarshal(nil)
|
||||
require.NoError(t, err)
|
||||
|
||||
err = transport.Unmarshal(wire)
|
||||
require.NoError(t, err)
|
||||
|
||||
verifHeaderTo := service.ResponseVerificationHeaderFromGRPCMessage(transport)
|
||||
require.Equal(t, verifHeaderFrom, verifHeaderTo)
|
||||
})
|
||||
}
|
||||
|
||||
func generateSignature(k, v string) *service.Signature {
|
||||
sig := new(service.Signature)
|
||||
sig.SetKey([]byte(k))
|
||||
sig.SetSign([]byte(v))
|
||||
|
||||
return sig
|
||||
}
|
||||
|
||||
func generateVersion(maj, min uint32) *service.Version {
|
||||
version := new(service.Version)
|
||||
version.SetMajor(maj)
|
||||
version.SetMinor(min)
|
||||
|
||||
return version
|
||||
}
|
||||
|
||||
func generateXHeader(k, v string) *service.XHeader {
|
||||
xheader := new(service.XHeader)
|
||||
xheader.SetKey(k)
|
||||
xheader.SetValue(v)
|
||||
|
||||
return xheader
|
||||
}
|
||||
|
||||
func generateLifetime(exp, nbf, iat uint64) *service.TokenLifetime {
|
||||
lifetime := new(service.TokenLifetime)
|
||||
lifetime.SetExp(exp)
|
||||
lifetime.SetNbf(nbf)
|
||||
lifetime.SetIat(iat)
|
||||
|
||||
return lifetime
|
||||
}
|
||||
|
||||
func generateObjectCtx(id string) *service.ObjectSessionContext {
|
||||
objectCtx := new(service.ObjectSessionContext)
|
||||
objectCtx.SetVerb(service.ObjectVerbPut)
|
||||
|
||||
cid := new(refs.ContainerID)
|
||||
cid.SetValue([]byte("ContainerID"))
|
||||
|
||||
oid := new(refs.ObjectID)
|
||||
oid.SetValue([]byte(id))
|
||||
|
||||
addr := new(refs.Address)
|
||||
addr.SetContainerID(cid)
|
||||
addr.SetObjectID(oid)
|
||||
|
||||
objectCtx.SetAddress(addr)
|
||||
|
||||
return objectCtx
|
||||
}
|
||||
|
||||
func generateEACL(n int, k, v string) *acl.Table {
|
||||
target := new(acl.TargetInfo)
|
||||
target.SetTarget(acl.TargetUser)
|
||||
|
||||
keys := make([][]byte, n)
|
||||
|
||||
for i := 0; i < n; i++ {
|
||||
s := fmt.Sprintf("Public Key %d", i+1)
|
||||
keys[i] = []byte(s)
|
||||
}
|
||||
|
||||
filter := new(acl.HeaderFilter)
|
||||
filter.SetHeaderType(acl.HeaderTypeObject)
|
||||
filter.SetMatchType(acl.MatchTypeStringEqual)
|
||||
filter.SetName(k)
|
||||
filter.SetValue(v)
|
||||
|
||||
record := new(acl.Record)
|
||||
record.SetOperation(acl.OperationHead)
|
||||
record.SetAction(acl.ActionDeny)
|
||||
record.SetTargets([]*acl.TargetInfo{target})
|
||||
record.SetFilters([]*acl.HeaderFilter{filter})
|
||||
|
||||
table := new(acl.Table)
|
||||
cid := new(refs.ContainerID)
|
||||
cid.SetValue([]byte("Container ID"))
|
||||
|
||||
table.SetContainerID(cid)
|
||||
table.SetRecords([]*acl.Record{record})
|
||||
|
||||
return table
|
||||
}
|
||||
|
||||
func generateSessionTokenBody(id string) *service.SessionTokenBody {
|
||||
owner := new(refs.OwnerID)
|
||||
owner.SetValue([]byte("Owner ID"))
|
||||
|
||||
tokenBody := new(service.SessionTokenBody)
|
||||
tokenBody.SetID([]byte(id))
|
||||
tokenBody.SetOwnerID(owner)
|
||||
tokenBody.SetSessionKey([]byte(id))
|
||||
tokenBody.SetLifetime(generateLifetime(1, 2, 3))
|
||||
tokenBody.SetContext(generateObjectCtx(id))
|
||||
|
||||
return tokenBody
|
||||
}
|
||||
|
||||
func generateSessionToken(id string) *service.SessionToken {
|
||||
sessionToken := new(service.SessionToken)
|
||||
sessionToken.SetBody(generateSessionTokenBody(id))
|
||||
sessionToken.SetSignature(generateSignature("id", id))
|
||||
|
||||
return sessionToken
|
||||
}
|
||||
|
||||
func generateBearerTokenBody(id string) *service.BearerTokenBody {
|
||||
owner := new(refs.OwnerID)
|
||||
owner.SetValue([]byte(id))
|
||||
|
||||
tokenBody := new(service.BearerTokenBody)
|
||||
tokenBody.SetOwnerID(owner)
|
||||
tokenBody.SetLifetime(generateLifetime(1, 2, 3))
|
||||
tokenBody.SetEACL(generateEACL(10, "id", id))
|
||||
|
||||
return tokenBody
|
||||
}
|
||||
|
||||
func generateBearerToken(id string) *service.BearerToken {
|
||||
bearerToken := new(service.BearerToken)
|
||||
bearerToken.SetBody(generateBearerTokenBody(id))
|
||||
bearerToken.SetSignature(generateSignature("id", id))
|
||||
|
||||
return bearerToken
|
||||
}
|
||||
|
||||
func generateRequestMetaHeader(n int, b, s string) *service.RequestMetaHeader {
|
||||
reqMetaHeader := new(service.RequestMetaHeader)
|
||||
reqMetaHeader.SetVersion(generateVersion(2, 0))
|
||||
reqMetaHeader.SetEpoch(uint64(n))
|
||||
reqMetaHeader.SetTTL(uint32(n))
|
||||
reqMetaHeader.SetXHeaders([]*service.XHeader{
|
||||
generateXHeader("key-one", "val-one"),
|
||||
generateXHeader("key-two", "val-two"),
|
||||
})
|
||||
reqMetaHeader.SetBearerToken(generateBearerToken(b))
|
||||
reqMetaHeader.SetSessionToken(generateSessionToken(s))
|
||||
|
||||
return reqMetaHeader
|
||||
}
|
||||
|
||||
func generateRequestVerificationHeader(k, v string) *service.RequestVerificationHeader {
|
||||
reqVerifHeader := new(service.RequestVerificationHeader)
|
||||
reqVerifHeader.SetBodySignature(generateSignature(k+"body", v+"body"))
|
||||
reqVerifHeader.SetMetaSignature(generateSignature(k+"meta", v+"meta"))
|
||||
reqVerifHeader.SetOriginSignature(generateSignature(k+"orig", v+"orig"))
|
||||
|
||||
return reqVerifHeader
|
||||
}
|
||||
|
||||
func generateResponseMetaHeader(n int) *service.ResponseMetaHeader {
|
||||
respMetaHeader := new(service.ResponseMetaHeader)
|
||||
respMetaHeader.SetVersion(generateVersion(2, 0))
|
||||
respMetaHeader.SetEpoch(uint64(n))
|
||||
respMetaHeader.SetTTL(uint32(n))
|
||||
respMetaHeader.SetXHeaders([]*service.XHeader{
|
||||
generateXHeader("key-one", "val-one"),
|
||||
generateXHeader("key-two", "val-two"),
|
||||
})
|
||||
|
||||
return respMetaHeader
|
||||
}
|
||||
|
||||
func generateResponseVerificationHeader(k, v string) *service.ResponseVerificationHeader {
|
||||
respVerifHeader := new(service.ResponseVerificationHeader)
|
||||
respVerifHeader.SetBodySignature(generateSignature(k+"body", v+"body"))
|
||||
respVerifHeader.SetMetaSignature(generateSignature(k+"meta", v+"meta"))
|
||||
respVerifHeader.SetOriginSignature(generateSignature(k+"orig", v+"orig"))
|
||||
|
||||
return respVerifHeader
|
||||
}
|
|
@ -256,22 +256,6 @@ func (r *RequestVerificationHeader) SetOrigin(v *RequestVerificationHeader) {
|
|||
}
|
||||
}
|
||||
|
||||
func (r *RequestVerificationHeader) StableMarshal(buf []byte) ([]byte, error) {
|
||||
if r == nil {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// TODO: do not use hack
|
||||
_, err := RequestVerificationHeaderToGRPCMessage(r).MarshalTo(buf)
|
||||
|
||||
return buf, err
|
||||
}
|
||||
|
||||
func (r *RequestVerificationHeader) StableSize() int {
|
||||
// TODO: do not use hack
|
||||
return RequestVerificationHeaderToGRPCMessage(r).Size()
|
||||
}
|
||||
|
||||
func (r *RequestMetaHeader) GetVersion() *Version {
|
||||
if r != nil {
|
||||
return r.version
|
||||
|
@ -370,61 +354,45 @@ func (r *RequestMetaHeader) SetOrigin(v *RequestMetaHeader) {
|
|||
}
|
||||
}
|
||||
|
||||
func (r *RequestMetaHeader) StableMarshal(buf []byte) ([]byte, error) {
|
||||
if r == nil {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// TODO: do not use hack
|
||||
_, err := RequestMetaHeaderToGRPCMessage(r).MarshalTo(buf)
|
||||
|
||||
return buf, err
|
||||
}
|
||||
|
||||
func (r *RequestMetaHeader) StableSize() int {
|
||||
// TODO: do not use hack
|
||||
return RequestMetaHeaderToGRPCMessage(r).Size()
|
||||
}
|
||||
|
||||
func (tl *TokenLifetime) GetExp() uint64 {
|
||||
if tl != nil {
|
||||
return tl.exp
|
||||
func (l *TokenLifetime) GetExp() uint64 {
|
||||
if l != nil {
|
||||
return l.exp
|
||||
}
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
func (tl *TokenLifetime) SetExp(v uint64) {
|
||||
if tl != nil {
|
||||
tl.exp = v
|
||||
func (l *TokenLifetime) SetExp(v uint64) {
|
||||
if l != nil {
|
||||
l.exp = v
|
||||
}
|
||||
}
|
||||
|
||||
func (tl *TokenLifetime) GetNbf() uint64 {
|
||||
if tl != nil {
|
||||
return tl.nbf
|
||||
func (l *TokenLifetime) GetNbf() uint64 {
|
||||
if l != nil {
|
||||
return l.nbf
|
||||
}
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
func (tl *TokenLifetime) SetNbf(v uint64) {
|
||||
if tl != nil {
|
||||
tl.nbf = v
|
||||
func (l *TokenLifetime) SetNbf(v uint64) {
|
||||
if l != nil {
|
||||
l.nbf = v
|
||||
}
|
||||
}
|
||||
|
||||
func (tl *TokenLifetime) GetIat() uint64 {
|
||||
if tl != nil {
|
||||
return tl.iat
|
||||
func (l *TokenLifetime) GetIat() uint64 {
|
||||
if l != nil {
|
||||
return l.iat
|
||||
}
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
func (tl *TokenLifetime) SetIat(v uint64) {
|
||||
if tl != nil {
|
||||
tl.iat = v
|
||||
func (l *TokenLifetime) SetIat(v uint64) {
|
||||
if l != nil {
|
||||
l.iat = v
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue