[#210] subnet: Refactor and document package functionality

Signed-off-by: Leonard Lyubich <leonard@nspcc.ru>
This commit is contained in:
Leonard Lyubich 2022-06-15 10:12:35 +03:00 committed by LeL
parent 6709b00c89
commit eb3b990812
13 changed files with 276 additions and 216 deletions

View file

@ -36,13 +36,31 @@ func (p *PlacementPolicy) ToV2() *netmap.PlacementPolicy {
// SubnetID returns subnet to select nodes from. // SubnetID returns subnet to select nodes from.
func (p *PlacementPolicy) SubnetID() *subnetid.ID { func (p *PlacementPolicy) SubnetID() *subnetid.ID {
return (*subnetid.ID)( idv2 := (*netmap.PlacementPolicy)(p).GetSubnetID()
(*netmap.PlacementPolicy)(p).GetSubnetID()) if idv2 == nil {
return nil
}
var id subnetid.ID
err := id.ReadFromV2(*idv2)
if err != nil {
panic(err) // will disappear after netmap package refactor
}
return &id
} }
// SetSubnetID sets subnet to select nodes from. // SetSubnetID sets subnet to select nodes from.
func (p *PlacementPolicy) SetSubnetID(subnet *subnetid.ID) { func (p *PlacementPolicy) SetSubnetID(subnet *subnetid.ID) {
(*netmap.PlacementPolicy)(p).SetSubnetID((*refs.SubnetID)(subnet)) var idv2 *refs.SubnetID
if subnet != nil {
idv2 = new(refs.SubnetID)
subnet.WriteToV2(idv2)
}
(*netmap.PlacementPolicy)(p).SetSubnetID(idv2)
} }
// Replicas returns list of object replica descriptors. // Replicas returns list of object replica descriptors.

View file

@ -2,6 +2,7 @@ package netmap
import ( import (
"errors" "errors"
"fmt"
"github.com/nspcc-dev/neofs-api-go/v2/netmap" "github.com/nspcc-dev/neofs-api-go/v2/netmap"
"github.com/nspcc-dev/neofs-api-go/v2/refs" "github.com/nspcc-dev/neofs-api-go/v2/refs"
@ -48,9 +49,12 @@ func (i *NodeInfo) IterateSubnets(f func(subnetid.ID) error) error {
var id subnetid.ID var id subnetid.ID
return netmap.IterateSubnets((*netmap.NodeInfo)(i), func(idv2 refs.SubnetID) error { return netmap.IterateSubnets((*netmap.NodeInfo)(i), func(idv2 refs.SubnetID) error {
id.FromV2(idv2) err := id.ReadFromV2(idv2)
if err != nil {
return fmt.Errorf("invalid subnet: %w", err)
}
err := f(id) err = f(id)
if errors.Is(err, ErrRemoveSubnet) { if errors.Is(err, ErrRemoveSubnet) {
return netmap.ErrRemoveSubnet return netmap.ErrRemoveSubnet
} }
@ -66,7 +70,7 @@ var errAbortSubnetIter = errors.New("abort subnet iterator")
// Function is NPE-safe: nil NodeInfo always belongs to zero subnet only. // Function is NPE-safe: nil NodeInfo always belongs to zero subnet only.
func BelongsToSubnet(node *NodeInfo, id subnetid.ID) bool { func BelongsToSubnet(node *NodeInfo, id subnetid.ID) bool {
err := node.IterateSubnets(func(id_ subnetid.ID) error { err := node.IterateSubnets(func(id_ subnetid.ID) error {
if id.Equals(&id_) { if id.Equals(id_) {
return errAbortSubnetIter return errAbortSubnetIter
} }

View file

@ -12,7 +12,7 @@ func TestNodeInfoSubnets(t *testing.T) {
t.Run("enter subnet", func(t *testing.T) { t.Run("enter subnet", func(t *testing.T) {
var id subnetid.ID var id subnetid.ID
id.SetNumber(13) id.SetNumeric(13)
var node netmap.NodeInfo var node netmap.NodeInfo
@ -35,8 +35,8 @@ func TestNodeInfoSubnets(t *testing.T) {
t.Run("not last", func(t *testing.T) { t.Run("not last", func(t *testing.T) {
var id, idrm subnetid.ID var id, idrm subnetid.ID
id.SetNumber(13) id.SetNumeric(13)
idrm.SetNumber(23) idrm.SetNumeric(23)
var node netmap.NodeInfo var node netmap.NodeInfo
@ -44,7 +44,7 @@ func TestNodeInfoSubnets(t *testing.T) {
node.EnterSubnet(idrm) node.EnterSubnet(idrm)
err := node.IterateSubnets(func(id subnetid.ID) error { err := node.IterateSubnets(func(id subnetid.ID) error {
if subnetid.IsZero(id) || id.Equals(&idrm) { if subnetid.IsZero(id) || id.Equals(idrm) {
return netmap.ErrRemoveSubnet return netmap.ErrRemoveSubnet
} }
@ -100,7 +100,7 @@ func TestEnterSubnet(t *testing.T) {
node.ExitSubnet(id) node.ExitSubnet(id)
require.False(t, netmap.BelongsToSubnet(&node, id)) require.False(t, netmap.BelongsToSubnet(&node, id))
id.SetNumber(10) id.SetNumeric(10)
node.EnterSubnet(id) node.EnterSubnet(id)
require.True(t, netmap.BelongsToSubnet(&node, id)) require.True(t, netmap.BelongsToSubnet(&node, id))
require.False(t, netmap.BelongsToSubnet(&node, subnetid.ID{})) require.False(t, netmap.BelongsToSubnet(&node, subnetid.ID{}))
@ -113,8 +113,8 @@ func TestEnterSubnet(t *testing.T) {
func TestBelongsToSubnet(t *testing.T) { func TestBelongsToSubnet(t *testing.T) {
var id, idMiss, idZero subnetid.ID var id, idMiss, idZero subnetid.ID
id.SetNumber(13) id.SetNumeric(13)
idMiss.SetNumber(23) idMiss.SetNumeric(23)
var node netmap.NodeInfo var node netmap.NodeInfo

10
subnet/doc.go Normal file
View file

@ -0,0 +1,10 @@
/*
Package subnet collects functionality related to the NeoFS subnets.
Subnet of a particular NeoFS network consists of a subset of the storage nodes
of that network. Subnet of the whole network is called zero. Info type acts as
a subnet descriptor. Each subnet is owned by the user who created it. Information
about all subnets is stored in the Subnet contract of the NeoFS Sidechain.
*/
package subnet

10
subnet/id/doc.go Normal file
View file

@ -0,0 +1,10 @@
/*
Package subnetid provides primitives to work with subnet identification in NeoFS.
ID type is used for global subnet identity inside the NeoFS network.
Using package types in an application is recommended to potentially work with
different protocol versions with which these types are compatible.
*/
package subnetid

View file

@ -2,95 +2,104 @@ package subnetid
import ( import (
"fmt" "fmt"
"strconv"
"github.com/nspcc-dev/neofs-api-go/v2/refs" "github.com/nspcc-dev/neofs-api-go/v2/refs"
) )
// ID represents NeoFS subnet identifier. // ID represents unique identifier of the subnet in the NeoFS network.
// //
// The type is compatible with the corresponding message from NeoFS API V2 protocol. // ID is mutually compatible with github.com/nspcc-dev/neofs-api-go/v2/refs.SubnetID
// message. See ReadFromV2 / WriteToV2 methods.
// //
// Zero value and nil pointer is equivalent to zero subnet ID. // Instances can be created using built-in var declaration. Zero value is
type ID refs.SubnetID // equivalent to identifier of the zero subnet (whole NeoFS network).
type ID struct {
// FromV2 initializes ID from refs.SubnetID message structure. Must not be called on nil. m refs.SubnetID
//
// Note: nil refs.SubnetID corresponds to zero ID value or nil pointer to it.
func (x *ID) FromV2(msg refs.SubnetID) {
*x = ID(msg)
} }
// WriteToV2 writes ID to refs.SubnetID message structure. The message must not be nil. // ReadFromV2 reads ID from the refs.SubnetID message. Checks if the
// message conforms to NeoFS API V2 protocol.
// //
// Note: nil ID corresponds to zero refs.SubnetID value or nil pointer to it. // See also WriteToV2.
func (x *ID) ReadFromV2(msg refs.SubnetID) error {
x.m = msg
return nil
}
// WriteToV2 writes ID to refs.SubnetID message structure. The message MUST NOT
// be nil.
//
// See also ReadFromV2.
func (x ID) WriteToV2(msg *refs.SubnetID) { func (x ID) WriteToV2(msg *refs.SubnetID) {
*msg = refs.SubnetID(x) *msg = x.m
} }
// Equals returns true iff both instances identify the same subnet. // Equals defines a comparison relation between two ID instances.
// //
// Method is NPE-safe: nil pointer equals to pointer to zero value. // Note that comparison using '==' operator is not recommended since it MAY result
func (x *ID) Equals(x2 *ID) bool { // in loss of compatibility.
return (*refs.SubnetID)(x).GetValue() == (*refs.SubnetID)(x2).GetValue() func (x ID) Equals(x2 ID) bool {
return x.m.GetValue() == x2.m.GetValue()
} }
// MarshalText encodes ID into text format according to particular NeoFS API protocol. // EncodeToString encodes ID into NeoFS API protocol string (base10 encoding).
// Supported versions:
// * V2 (see refs.SubnetID type).
// //
// Implements encoding.TextMarshaler. // See also DecodeString.
func (x *ID) MarshalText() ([]byte, error) { func (x ID) EncodeToString() string {
return (*refs.SubnetID)(x).MarshalText() return strconv.FormatUint(uint64(x.m.GetValue()), 10)
} }
// UnmarshalText decodes ID from the text according to particular NeoFS API protocol. // DecodeString decodes string calculated using EncodeToString. Returns
// Must not be called on nil. Supported versions: // an error if s is malformed.
// * V2 (see refs.SubnetID type). func (x *ID) DecodeString(s string) error {
// num, err := strconv.ParseUint(s, 10, 32)
// Implements encoding.TextUnmarshaler.
func (x *ID) UnmarshalText(text []byte) error {
return (*refs.SubnetID)(x).UnmarshalText(text)
}
// String returns string representation of ID using MarshalText.
// Returns string with message on error.
//
// Implements fmt.Stringer.
func (x *ID) String() string {
text, err := x.MarshalText()
if err != nil { if err != nil {
return fmt.Sprintf("<invalid> %v", err) return fmt.Errorf("invalid numeric value: %w", err)
} }
return string(text) x.m.SetValue(uint32(num))
return nil
} }
// Marshal encodes ID into a binary format of NeoFS API V2 protocol (Protocol Buffers with direct field order). // String implements fmt.Stringer.
func (x *ID) Marshal() ([]byte, error) {
return (*refs.SubnetID)(x).StableMarshal(nil), nil
}
// Unmarshal decodes ID from NeoFS API V2 binary format (see Marshal). Must not be called on nil.
// //
// Note: empty data corresponds to zero ID value or nil pointer to it. // String is designed to be human-readable, and its format MAY differ between
// SDK versions. String MAY return same result as EncodeToString. String MUST NOT
// be used to encode ID into NeoFS protocol string.
func (x ID) String() string {
return "#" + strconv.FormatUint(uint64(x.m.GetValue()), 10)
}
// Marshal encodes ID into a binary format of the NeoFS API protocol
// (Protocol Buffers with direct field order).
//
// See also Unmarshal.
func (x ID) Marshal() []byte {
return x.m.StableMarshal(nil)
}
// Unmarshal decodes binary ID calculated using Marshal. Returns an error
// describing a format violation.
func (x *ID) Unmarshal(data []byte) error { func (x *ID) Unmarshal(data []byte) error {
return (*refs.SubnetID)(x).Unmarshal(data) return x.m.Unmarshal(data)
} }
// SetNumber sets ID value in uint32 format. Must not be called on nil. // SetNumeric sets ID value in numeric format. By default, number is 0 which
// By default, number is 0 which refers to zero subnet. // refers to the zero subnet.
func (x *ID) SetNumber(num uint32) { func (x *ID) SetNumeric(num uint32) {
(*refs.SubnetID)(x).SetValue(num) x.m.SetValue(num)
} }
// IsZero returns true iff the ID refers to zero subnet. // IsZero compares id with zero subnet ID.
func IsZero(id ID) bool { func IsZero(id ID) bool {
return id.Equals(nil) return id.Equals(ID{})
} }
// MakeZero makes ID to refer to zero subnet. Arg must not be nil (it is already zero). // MakeZero makes ID to refer to zero subnet.
// //
// Makes no sense to call on zero value (e.g. declared using var). // Makes no sense to call on zero value (e.g. declared using var).
func MakeZero(id *ID) { func MakeZero(id *ID) {
id.SetNumber(0) id.SetNumeric(0)
} }

View file

@ -14,26 +14,26 @@ func TestIsZero(t *testing.T) {
require.True(t, subnetid.IsZero(id)) require.True(t, subnetid.IsZero(id))
id.SetNumber(13) id.SetNumeric(13)
require.False(t, subnetid.IsZero(id)) require.False(t, subnetid.IsZero(id))
id.SetNumber(0) id.SetNumeric(0)
require.True(t, subnetid.IsZero(id)) require.True(t, subnetid.IsZero(id))
} }
func TestID_FromV2(t *testing.T) { func TestID_ReadFromV2(t *testing.T) {
const num = 13 const num = 13
var id1 subnetid.ID var id1 subnetid.ID
id1.SetNumber(num) id1.SetNumeric(num)
var idv2 refs.SubnetID var idv2 refs.SubnetID
idv2.SetValue(num) idv2.SetValue(num)
var id2 subnetid.ID var id2 subnetid.ID
id2.FromV2(idv2) require.NoError(t, id2.ReadFromV2(idv2))
require.True(t, id1.Equals(&id2)) require.True(t, id1.Equals(id2))
} }
func TestID_WriteToV2(t *testing.T) { func TestID_WriteToV2(t *testing.T) {
@ -47,7 +47,7 @@ func TestID_WriteToV2(t *testing.T) {
id.WriteToV2(&idv2) id.WriteToV2(&idv2)
require.Zero(t, idv2.GetValue()) require.Zero(t, idv2.GetValue())
id.SetNumber(num) id.SetNumeric(num)
id.WriteToV2(&idv2) id.WriteToV2(&idv2)
require.EqualValues(t, num, idv2.GetValue()) require.EqualValues(t, num, idv2.GetValue())
@ -58,36 +58,30 @@ func TestID_Equals(t *testing.T) {
var id1, id2, idOther, id0 subnetid.ID var id1, id2, idOther, id0 subnetid.ID
id0.Equals(nil) id0.Equals(subnetid.ID{})
id1.SetNumber(num) id1.SetNumeric(num)
id2.SetNumber(num) id2.SetNumeric(num)
idOther.SetNumber(num + 1) idOther.SetNumeric(num + 1)
require.True(t, id1.Equals(&id2)) require.True(t, id1.Equals(id2))
require.False(t, id1.Equals(&idOther)) require.False(t, id1.Equals(idOther))
require.False(t, id2.Equals(&idOther)) require.False(t, id2.Equals(idOther))
} }
func TestSubnetIDEncoding(t *testing.T) { func TestSubnetIDEncoding(t *testing.T) {
id := subnetidtest.ID() id := subnetidtest.ID()
t.Run("binary", func(t *testing.T) { t.Run("binary", func(t *testing.T) {
data, err := id.Marshal()
require.NoError(t, err)
var id2 subnetid.ID var id2 subnetid.ID
require.NoError(t, id2.Unmarshal(data)) require.NoError(t, id2.Unmarshal(id.Marshal()))
require.True(t, id2.Equals(id)) require.True(t, id2.Equals(id))
}) })
t.Run("text", func(t *testing.T) { t.Run("text", func(t *testing.T) {
data, err := id.MarshalText()
require.NoError(t, err)
var id2 subnetid.ID var id2 subnetid.ID
require.NoError(t, id2.UnmarshalText(data)) require.NoError(t, id2.DecodeString(id.EncodeToString()))
require.True(t, id2.Equals(id)) require.True(t, id2.Equals(id))
}) })
@ -95,12 +89,12 @@ func TestSubnetIDEncoding(t *testing.T) {
func TestMakeZero(t *testing.T) { func TestMakeZero(t *testing.T) {
var id subnetid.ID var id subnetid.ID
id.SetNumeric(13)
id.SetNumber(13)
require.False(t, subnetid.IsZero(id)) require.False(t, subnetid.IsZero(id))
subnetid.MakeZero(&id) subnetid.MakeZero(&id)
require.True(t, subnetid.IsZero(id)) require.True(t, subnetid.IsZero(id))
require.Equal(t, subnetid.ID{}, id)
} }

13
subnet/id/test/doc.go Normal file
View file

@ -0,0 +1,13 @@
/*
Package subnetidtest provides functions for convenient testing of subnetid package API.
Note that importing the package into source files is highly discouraged.
Random instance generation functions can be useful when testing expects any value, e.g.:
import subnetidtest "github.com/nspcc-dev/neofs-sdk-go/suibnet/id/test"
value := subnetidtest.ID()
// test the value
*/
package subnetidtest

View file

@ -6,11 +6,8 @@ import (
subnetid "github.com/nspcc-dev/neofs-sdk-go/subnet/id" subnetid "github.com/nspcc-dev/neofs-sdk-go/subnet/id"
) )
// ID generates and returns random subnetid.ID using math/rand.Uint32. // ID generates and returns random subnetid.ID.
func ID() *subnetid.ID { func ID() (x subnetid.ID) {
var id subnetid.ID x.SetNumeric(rand.Uint32())
return
id.SetNumber(rand.Uint32())
return &id
} }

View file

@ -1,6 +1,8 @@
package subnet package subnet
import ( import (
"fmt"
"github.com/nspcc-dev/neofs-api-go/v2/refs" "github.com/nspcc-dev/neofs-api-go/v2/refs"
"github.com/nspcc-dev/neofs-api-go/v2/subnet" "github.com/nspcc-dev/neofs-api-go/v2/subnet"
subnetid "github.com/nspcc-dev/neofs-sdk-go/subnet/id" subnetid "github.com/nspcc-dev/neofs-sdk-go/subnet/id"
@ -9,102 +11,99 @@ import (
// Info represents information about NeoFS subnet. // Info represents information about NeoFS subnet.
// //
// The type is compatible with the corresponding message from NeoFS API V2 protocol. // Instances can be created using built-in var declaration.
type Info struct {
id subnetid.ID
owner user.ID
}
// Marshal encodes Info into a binary format of the NeoFS API protocol
// (Protocol Buffers with direct field order).
// //
// Zero value and nil pointer to it represents zero subnet w/o an owner. // See also Unmarshal.
type Info subnet.Info func (x Info) Marshal() []byte {
var id refs.SubnetID
x.id.WriteToV2(&id)
// FromV2 initializes Info from subnet.Info message structure. Must not be called on nil. var owner refs.OwnerID
func (x *Info) FromV2(msg subnet.Info) { x.owner.WriteToV2(&owner)
*x = Info(msg)
var m subnet.Info
m.SetID(&id)
m.SetOwner(&owner)
return m.StableMarshal(nil)
} }
// WriteToV2 writes Info to subnet.Info message structure. The message must not be nil. // Unmarshal decodes binary Info calculated using Marshal. Returns an error
func (x Info) WriteToV2(msg *subnet.Info) { // describing a format violation.
*msg = subnet.Info(x)
}
// Marshal encodes Info into a binary format of NeoFS API V2 protocol (Protocol Buffers with direct field order).
func (x *Info) Marshal() ([]byte, error) {
return (*subnet.Info)(x).StableMarshal(nil), nil
}
// Unmarshal decodes Info from NeoFS API V2 binary format (see Marshal). Must not be called on nil.
//
// Note: empty data corresponds to zero Info value or nil pointer to it.
func (x *Info) Unmarshal(data []byte) error { func (x *Info) Unmarshal(data []byte) error {
return (*subnet.Info)(x).Unmarshal(data) var m subnet.Info
err := m.Unmarshal(data)
if err != nil {
return err
}
id := m.ID()
if id != nil {
err = x.id.ReadFromV2(*id)
if err != nil {
return fmt.Errorf("invalid ID: %w", err)
}
} else {
subnetid.MakeZero(&x.id)
}
owner := m.Owner()
if owner != nil {
err = x.owner.ReadFromV2(*owner)
if err != nil {
return fmt.Errorf("invalid owner: %w", err)
}
} else {
x.owner = user.ID{}
}
return nil
} }
// SetID sets the identifier of the subnet that Info describes. // SetID sets the identifier of the subnet that Info describes.
//
// See also ID.
func (x *Info) SetID(id subnetid.ID) { func (x *Info) SetID(id subnetid.ID) {
infov2 := (*subnet.Info)(x) x.id = id
idv2 := infov2.ID()
if idv2 == nil {
idv2 = new(refs.SubnetID)
infov2.SetID(idv2)
}
id.WriteToV2(idv2)
} }
// ReadID reads the identifier of the subnet that Info describes. Arg must not be nil. // ID returns subnet identifier set using SetID.
func (x Info) ReadID(id *subnetid.ID) { //
infov2 := (subnet.Info)(x) // Zero Info refers to the zero subnet.
func (x Info) ID() subnetid.ID {
idv2 := infov2.ID() return x.id
if idv2 == nil {
subnetid.MakeZero(id)
return
}
id.FromV2(*idv2)
} }
// SetOwner sets subnet owner ID. // SetOwner sets identifier of the subnet owner.
func (x *Info) SetOwner(id user.ID) { func (x *Info) SetOwner(id user.ID) {
infov2 := (*subnet.Info)(x) x.owner = id
idv2 := infov2.Owner()
if idv2 == nil {
idv2 = new(refs.OwnerID)
infov2.SetOwner(idv2)
}
id.WriteToV2(idv2)
} }
// ReadOwner reads the identifier of the subnet that Info describes. // Owner returns subnet owner set using SetOwner.
// Must be called only if owner is set (see HasOwner). Arg must not be nil. //
func (x Info) ReadOwner(id *user.ID) { // Zero Info has no owner which is incorrect according to the
infov2 := (subnet.Info)(x) // NeoFS API protocol.
func (x Info) Owner() user.ID {
id2 := infov2.Owner() return x.owner
if id2 == nil {
*id = user.ID{}
return
}
if ownerV2 := infov2.Owner(); ownerV2 != nil {
_ = id.ReadFromV2(*ownerV2)
}
} }
// IsOwner checks subnet ownership. // AssertOwnership checks if the given info describes the subnet owned by the
func IsOwner(info Info, id user.ID) bool { // given user.
var id2 user.ID func AssertOwnership(info Info, id user.ID) bool {
return id.Equals(info.Owner())
info.ReadOwner(&id2)
return id.Equals(id2)
} }
// IDEquals checks if ID refers to subnet that Info describes. // AssertReference checks if the given info describes the subnet referenced by
func IDEquals(info Info, id subnetid.ID) bool { // the given id.
id2 := new(subnetid.ID) func AssertReference(info Info, id subnetid.ID) bool {
return id.Equals(info.ID())
info.ReadID(id2)
return id.Equals(id2)
} }

View file

@ -3,11 +3,10 @@ package subnet_test
import ( import (
"testing" "testing"
subnetv2 "github.com/nspcc-dev/neofs-api-go/v2/subnet"
subnettest "github.com/nspcc-dev/neofs-api-go/v2/subnet/test"
. "github.com/nspcc-dev/neofs-sdk-go/subnet" . "github.com/nspcc-dev/neofs-sdk-go/subnet"
subnetid "github.com/nspcc-dev/neofs-sdk-go/subnet/id" subnetid "github.com/nspcc-dev/neofs-sdk-go/subnet/id"
"github.com/nspcc-dev/neofs-sdk-go/user" subnetidtest "github.com/nspcc-dev/neofs-sdk-go/subnet/id/test"
subnettest "github.com/nspcc-dev/neofs-sdk-go/subnet/test"
usertest "github.com/nspcc-dev/neofs-sdk-go/user/test" usertest "github.com/nspcc-dev/neofs-sdk-go/user/test"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
) )
@ -15,55 +14,35 @@ import (
func TestInfoZero(t *testing.T) { func TestInfoZero(t *testing.T) {
var info Info var info Info
var id subnetid.ID require.Zero(t, info.ID())
info.ReadID(&id) require.True(t, subnetid.IsZero(info.ID()))
require.True(t, subnetid.IsZero(id))
} }
func TestInfo_SetID(t *testing.T) { func TestInfo_SetID(t *testing.T) {
var ( id := subnetidtest.ID()
id subnetid.ID
info Info
)
id.SetNumber(222)
var info Info
info.SetID(id) info.SetID(id)
require.True(t, IDEquals(info, id)) require.Equal(t, id, info.ID())
require.True(t, AssertReference(info, id))
} }
func TestInfo_SetOwner(t *testing.T) { func TestInfo_SetOwner(t *testing.T) {
var ( id := *usertest.ID()
id user.ID
info Info
)
id = *usertest.ID()
require.False(t, IsOwner(info, id))
var info Info
info.SetOwner(id) info.SetOwner(id)
require.True(t, IsOwner(info, id)) require.Equal(t, id, info.Owner())
require.True(t, AssertOwnership(info, id))
} }
func TestInfo_WriteToV2(t *testing.T) { func TestInfo_Marshal(t *testing.T) {
var ( info := subnettest.Info()
infoTo, infoFrom Info
infoV2From, infoV2To subnetv2.Info var info2 Info
) require.NoError(t, info2.Unmarshal(info.Marshal()))
infoV2From = *subnettest.GenerateSubnetInfo(false) require.Equal(t, info, info2)
infoFrom.FromV2(infoV2From)
infoFrom.WriteToV2(&infoV2To)
infoTo.FromV2(infoV2To)
require.Equal(t, infoV2From, infoV2To)
require.Equal(t, infoFrom, infoTo)
} }

13
subnet/test/doc.go Normal file
View file

@ -0,0 +1,13 @@
/*
Package subnettest provides functions for convenient testing of subnet package API.
Note that importing the package into source files is highly discouraged.
Random instance generation functions can be useful when testing expects any value, e.g.:
import subnettest "github.com/nspcc-dev/neofs-sdk-go/suibnet/test"
value := subnettest.Info()
// test the value
*/
package subnettest

14
subnet/test/subnet.go Normal file
View file

@ -0,0 +1,14 @@
package subnettest
import (
"github.com/nspcc-dev/neofs-sdk-go/subnet"
subnetidtest "github.com/nspcc-dev/neofs-sdk-go/subnet/id/test"
usertest "github.com/nspcc-dev/neofs-sdk-go/user/test"
)
// Info generates and returns random subnet.Info.
func Info() (x subnet.Info) {
x.SetID(subnetidtest.ID())
x.SetOwner(*usertest.ID())
return
}