Skip to content

Commit

Permalink
object: Improve testing and increase coverage (#629)
Browse files Browse the repository at this point in the history
  • Loading branch information
cthulhu-rider authored Nov 13, 2024
2 parents a9b67e4 + 3834fac commit ece099d
Show file tree
Hide file tree
Showing 18 changed files with 1,787 additions and 859 deletions.
428 changes: 172 additions & 256 deletions eacl/enums.go

Large diffs are not rendered by default.

40 changes: 22 additions & 18 deletions eacl/enums_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package eacl_test

import (
"fmt"
"testing"

v2acl "github.com/nspcc-dev/neofs-api-go/v2/acl"
Expand Down Expand Up @@ -225,34 +226,37 @@ func TestAction_String(t *testing.T) {
})
}

type enum interface{ ~uint32 }
type enum interface {
~uint32
fmt.Stringer
}

func testEnumToString[T enum](t testing.TB, m map[T]string, f func(T) string) {
func testEnumToString[T enum](t testing.TB, m map[T]string) {
for n, s := range m {
require.Equal(t, s, f(n))
require.Equal(t, s, n.String())
}
}

func testEnumFromString[T enum](t *testing.T, m map[T]string, f func(string) (T, bool)) {
func testEnumDecodeString[T enum](t *testing.T, m map[T]string, f func(*T, string) bool) {
t.Run("invalid", func(t *testing.T) {
for _, s := range []string{"", "foo", "1.2"} {
_, ok := f(s)
require.False(t, ok)
require.False(t, f(new(T), s))
}
})
for n, s := range m {
v, ok := f(s)
var res T
ok := f(&res, s)
require.True(t, ok)
require.Equal(t, n, v)
require.Equal(t, n, res)
}
}

func TestActionToString(t *testing.T) {
testEnumToString(t, actionStrings, eacl.ActionToString)
testEnumToString(t, actionStrings)
}

func TestActionFromString(t *testing.T) {
testEnumFromString(t, actionStrings, eacl.ActionFromString)
testEnumDecodeString(t, actionStrings, (*eacl.Action).DecodeString)
}

func TestRoleProto(t *testing.T) {
Expand Down Expand Up @@ -284,11 +288,11 @@ func TestRole_String(t *testing.T) {
}

func TestRoleToString(t *testing.T) {
testEnumToString(t, roleStrings, eacl.RoleToString)
testEnumToString(t, roleStrings)
}

func TestRoleFromString(t *testing.T) {
testEnumFromString(t, roleStrings, eacl.RoleFromString)
testEnumDecodeString(t, roleStrings, (*eacl.Role).DecodeString)
}

func TestOperationProto(t *testing.T) {
Expand Down Expand Up @@ -328,11 +332,11 @@ func TestOperation_String(t *testing.T) {
}

func TestOperationToString(t *testing.T) {
testEnumToString(t, opStrings, eacl.OperationToString)
testEnumToString(t, opStrings)
}

func TestOperationFromString(t *testing.T) {
testEnumFromString(t, opStrings, eacl.OperationFromString)
testEnumDecodeString(t, opStrings, (*eacl.Operation).DecodeString)
}

func TestMatchProto(t *testing.T) {
Expand Down Expand Up @@ -372,11 +376,11 @@ func TestMatch_String(t *testing.T) {
}

func TestMatcherToString(t *testing.T) {
testEnumToString(t, matcherStrings, eacl.MatcherToString)
testEnumToString(t, matcherStrings)
}

func TestMatcherFromString(t *testing.T) {
testEnumFromString(t, matcherStrings, eacl.MatcherFromString)
testEnumDecodeString(t, matcherStrings, (*eacl.Match).DecodeString)
}

func TestFilterHeaderTypeProto(t *testing.T) {
Expand Down Expand Up @@ -408,9 +412,9 @@ func TestFilterHeaderType_String(t *testing.T) {
}

func TestHeaderTypeToString(t *testing.T) {
testEnumToString(t, headerTypeStrings, eacl.HeaderTypeToString)
testEnumToString(t, headerTypeStrings)
}

func TestHeaderTypeFromString(t *testing.T) {
testEnumFromString(t, headerTypeStrings, eacl.HeaderTypeFromString)
testEnumDecodeString(t, headerTypeStrings, (*eacl.FilterHeaderType).DecodeString)
}
2 changes: 1 addition & 1 deletion eacl/record.go
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,7 @@ func (r *Record) AddObjectPayloadHashFilter(m Match, h checksum.Checksum) {
// The m must not be [MatchNotPresent] or numeric (e.g. [MatchNumGT]).
// Deprecated: use [ConstructRecord] with [NewObjectPropertyFilter] instead.
func (r *Record) AddObjectTypeFilter(m Match, t object.Type) {
r.SetFilters(append(r.Filters(), NewObjectPropertyFilter(FilterObjectType, m, t.EncodeToString())))
r.SetFilters(append(r.Filters(), NewObjectPropertyFilter(FilterObjectType, m, t.String())))
}

// AddObjectHomomorphicHashFilter adds filter by object payload homomorphic hash value.
Expand Down
31 changes: 28 additions & 3 deletions object/link.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package object

import (
"fmt"

v2object "github.com/nspcc-dev/neofs-api-go/v2/object"
"github.com/nspcc-dev/neofs-api-go/v2/refs"
oid "github.com/nspcc-dev/neofs-sdk-go/object/id"
Expand Down Expand Up @@ -41,7 +43,23 @@ func (l *Link) Marshal() []byte {
//
// See also [Link.Marshal].
func (l *Link) Unmarshal(data []byte) error {
return (*v2object.Link)(l).Unmarshal(data)
m := (*v2object.Link)(l)
err := m.Unmarshal(data)
if err != nil {
return err
}

var id oid.ID
var i int
m.IterateChildren(func(mo v2object.MeasuredObject) {
if err == nil {
if err = id.ReadFromV2(mo.ID); err != nil {
err = fmt.Errorf("invalid member #%d: %w", i, err)
}
}
i++
})
return err
}

// MeasuredObject groups object ID and its size length. It is compatible with
Expand All @@ -63,7 +81,11 @@ func (m *MeasuredObject) SetObjectID(id oid.ID) {
// See also [MeasuredObject.SetObjectID].
func (m *MeasuredObject) ObjectID() oid.ID {
var id oid.ID
_ = id.ReadFromV2(m.ID)
if m.ID.GetValue() != nil {
if err := id.ReadFromV2(m.ID); err != nil {
panic(fmt.Errorf("invalid ID: %w", err))
}
}

return id
}
Expand All @@ -88,8 +110,11 @@ func (m *MeasuredObject) ObjectSize() uint32 {
func (l *Link) Objects() []MeasuredObject {
res := make([]MeasuredObject, (*v2object.Link)(l).NumberOfChildren())
var i int

var id oid.ID
(*v2object.Link)(l).IterateChildren(func(object v2object.MeasuredObject) {
if err := id.ReadFromV2(object.ID); err != nil {
panic(fmt.Errorf("invalid member #%d: %w", i, err))
}
res[i] = MeasuredObject(object)
i++
})
Expand Down
104 changes: 85 additions & 19 deletions object/link_test.go
Original file line number Diff line number Diff line change
@@ -1,38 +1,104 @@
package object_test

import (
"slices"
"testing"

"github.com/nspcc-dev/neofs-sdk-go/object"
objecttest "github.com/nspcc-dev/neofs-sdk-go/object/test"
oid "github.com/nspcc-dev/neofs-sdk-go/object/id"
"github.com/stretchr/testify/require"
)

func TestLinkEncoding(t *testing.T) {
link := *objecttest.Link()
var (
anyValidMeasuredObjects []object.MeasuredObject // set by init.
)

t.Run("binary", func(t *testing.T) {
data := link.Marshal()
var validLink object.Link // set by init.

var link2 object.Link
require.NoError(t, link2.Unmarshal(data))
func init() {
anyValidMeasuredObjects = make([]object.MeasuredObject, 3)
anyValidMeasuredObjects[0].SetObjectSize(2473604180)
anyValidMeasuredObjects[0].SetObjectID(oid.ID{22, 197, 235, 181, 5, 250, 3, 235, 44, 72, 182, 111, 153, 102, 51, 102, 159,
140, 45, 99, 49, 239, 153, 40, 115, 14, 122, 54, 234, 22, 40, 17})
anyValidMeasuredObjects[1].SetObjectSize(2257112744)
anyValidMeasuredObjects[1].SetObjectID(oid.ID{251, 27, 231, 203, 246, 154, 82, 100, 130, 18, 38, 45, 77, 24, 73, 14, 101,
240, 94, 211, 254, 55, 32, 76, 29, 234, 229, 252, 181, 122, 51, 174})
anyValidMeasuredObjects[2].SetObjectSize(3532081186)
anyValidMeasuredObjects[2].SetObjectID(oid.ID{227, 93, 189, 146, 92, 112, 76, 244, 236, 3, 94, 40, 212, 131, 229, 216,
130, 248, 195, 85, 23, 68, 65, 234, 106, 157, 101, 185, 227, 85, 182, 106})

require.Equal(t, link, link2)
})
validLink.SetObjects(anyValidMeasuredObjects)
}

func TestWriteLink(t *testing.T) {
link := objecttest.Link()
var link2 object.Link
var o object.Object
// corresponds to validLink.
var validBinLink = []byte{
10, 42, 10, 34, 10, 32, 22, 197, 235, 181, 5, 250, 3, 235, 44, 72, 182, 111, 153, 102, 51, 102, 159, 140, 45, 99, 49, 239,
153, 40, 115, 14, 122, 54, 234, 22, 40, 17, 16, 212, 232, 192, 155, 9, 10, 42, 10, 34, 10, 32, 251, 27, 231, 203, 246,
154, 82, 100, 130, 18, 38, 45, 77, 24, 73, 14, 101, 240, 94, 211, 254, 55, 32, 76, 29, 234, 229, 252, 181, 122, 51, 174,
16, 168, 157, 163, 180, 8, 10, 42, 10, 34, 10, 32, 227, 93, 189, 146, 92, 112, 76, 244, 236, 3, 94, 40, 212, 131, 229, 216,
130, 248, 195, 85, 23, 68, 65, 234, 106, 157, 101, 185, 227, 85, 182, 106, 16, 162, 144, 157, 148, 13,
}

o.WriteLink(*link)
func TestLink_SetObjects(t *testing.T) {
var l object.Link
require.Empty(t, l.Objects())

require.NoError(t, o.ReadLink(&link2))
require.Equal(t, *link, link2)
l.SetObjects(anyValidMeasuredObjects)
require.Equal(t, anyValidMeasuredObjects, l.Objects())

otherObjs := slices.Clone(anyValidMeasuredObjects)
for i := range otherObjs {
otherObjs[i].SetObjectSize(otherObjs[i].ObjectSize() + 1)
}
l.SetObjects(otherObjs)
require.Equal(t, otherObjs, l.Objects())
}

func TestLink_Marshal(t *testing.T) {
require.Equal(t, validBinLink, validLink.Marshal())
}

func TestLink_Unmarshal(t *testing.T) {
t.Run("invalid", func(t *testing.T) {
t.Run("protobuf", func(t *testing.T) {
err := new(object.Link).Unmarshal([]byte("Hello, world!"))
require.ErrorContains(t, err, "proto")
require.ErrorContains(t, err, "cannot parse invalid wire-format data")
})
for _, tc := range []struct {
name, err string
b []byte
}{
{name: "members/empty value", err: "invalid member #1: invalid length 0",
b: []byte{10, 36, 10, 34, 10, 32, 178, 74, 58, 219, 46, 3, 110, 125, 220, 81, 238, 35, 27, 6, 228, 193, 190,
224, 77, 44, 18, 56, 117, 173, 70, 246, 8, 139, 247, 174, 53, 60, 10, 2, 10, 0, 10, 36, 10, 34, 10, 32, 206,
228, 247, 217, 41, 247, 159, 215, 79, 226, 53, 153, 133, 16, 102, 104, 2, 234, 35, 220, 236, 112, 101,
24, 235, 126, 173, 229, 161, 202, 197, 242}},
{name: "members/undersize", err: "invalid member #1: invalid length 31",
b: []byte{10, 36, 10, 34, 10, 32, 178, 74, 58, 219, 46, 3, 110, 125, 220, 81, 238, 35, 27, 6, 228, 193, 190,
224, 77, 44, 18, 56, 117, 173, 70, 246, 8, 139, 247, 174, 53, 60, 10, 35, 10, 33, 10, 31, 229, 77, 63, 235,
2, 9, 165, 123, 116, 123, 47, 65, 22, 34, 214, 76, 45, 225, 21, 46, 135, 32, 116, 172, 67, 213, 243, 57,
253, 127, 179, 10, 36, 10, 34, 10, 32, 206, 228, 247, 217, 41, 247, 159, 215, 79, 226, 53, 153, 133, 16,
102, 104, 2, 234, 35, 220, 236, 112, 101, 24, 235, 126, 173, 229, 161, 202, 197, 242}},
{name: "members/oversize", err: "invalid member #1: invalid length 33",
b: []byte{10, 36, 10, 34, 10, 32, 178, 74, 58, 219, 46, 3, 110, 125, 220, 81, 238, 35, 27, 6, 228, 193, 190,
224, 77, 44, 18, 56, 117, 173, 70, 246, 8, 139, 247, 174, 53, 60, 10, 37, 10, 35, 10, 33, 229, 77, 63, 235,
2, 9, 165, 123, 116, 123, 47, 65, 22, 34, 214, 76, 45, 225, 21, 46, 135, 32, 116, 172, 67, 213, 243, 57,
253, 127, 179, 235, 1, 10, 36, 10, 34, 10, 32, 206, 228, 247, 217, 41, 247, 159, 215, 79, 226, 53, 153,
133, 16, 102, 104, 2, 234, 35, 220, 236, 112, 101, 24, 235, 126, 173, 229, 161, 202, 197, 242}},
} {
t.Run(tc.name, func(t *testing.T) {
require.EqualError(t, new(object.Link).Unmarshal(tc.b), tc.err)
})
}
})

// corrupt payload
o.Payload()[0]++
l := validLink
// zero
require.NoError(t, l.Unmarshal(nil))
require.Zero(t, l)

require.Error(t, o.ReadLink(&link2))
// filled
require.NoError(t, l.Unmarshal(validBinLink))
require.Equal(t, validLink, l)
}
24 changes: 22 additions & 2 deletions object/lock.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package object

import (
"fmt"

v2object "github.com/nspcc-dev/neofs-api-go/v2/object"
"github.com/nspcc-dev/neofs-api-go/v2/refs"
oid "github.com/nspcc-dev/neofs-sdk-go/object/id"
Expand Down Expand Up @@ -41,7 +43,9 @@ func (x Lock) ReadMembers(buf []oid.ID) {
var i int

(*v2object.Lock)(&x).IterateMembers(func(idV2 refs.ObjectID) {
_ = buf[i].ReadFromV2(idV2)
if err := buf[i].ReadFromV2(idV2); err != nil {
panic(fmt.Errorf("invalid member #%d: %w", i, err))
}
i++
})
}
Expand Down Expand Up @@ -74,5 +78,21 @@ func (x Lock) Marshal() []byte {
//
// See also [Lock.Marshal].
func (x *Lock) Unmarshal(data []byte) error {
return (*v2object.Lock)(x).Unmarshal(data)
m := (*v2object.Lock)(x)
err := m.Unmarshal(data)
if err != nil {
return err
}

var id oid.ID
var i int
m.IterateMembers(func(mid refs.ObjectID) {
if err == nil {
if err = id.ReadFromV2(mid); err != nil {
err = fmt.Errorf("invalid member #%d: %w", i, err)
}
}
i++
})
return err
}
Loading

0 comments on commit ece099d

Please sign in to comment.