package container_test import ( "crypto/sha256" "strconv" "testing" "time" v2container "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/container" v2netmap "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/netmap" "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/refs" "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container" cid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id" cidtest "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id/test" containertest "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/test" frostfscrypto "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/crypto" netmaptest "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/netmap/test" usertest "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/user/test" "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/version" "github.com/google/uuid" "github.com/nspcc-dev/neo-go/pkg/crypto/keys" "github.com/stretchr/testify/require" ) func TestPlacementPolicyEncoding(t *testing.T) { v := containertest.Container() t.Run("binary", func(t *testing.T) { var v2 container.Container require.NoError(t, v2.Unmarshal(v.Marshal())) require.Equal(t, v, v2) }) t.Run("json", func(t *testing.T) { data, err := v.MarshalJSON() require.NoError(t, err) var v2 container.Container require.NoError(t, v2.UnmarshalJSON(data)) require.Equal(t, v, v2) }) } func TestContainer_Init(t *testing.T) { val := containertest.Container() val.Init() var msg v2container.Container val.WriteToV2(&msg) binNonce := msg.GetNonce() var nonce uuid.UUID require.NoError(t, nonce.UnmarshalBinary(binNonce)) require.EqualValues(t, 4, nonce.Version()) verV2 := msg.GetVersion() require.NotNil(t, verV2) var ver version.Version require.NoError(t, ver.ReadFromV2(*verV2)) require.Equal(t, version.Current(), ver) var val2 container.Container require.NoError(t, val2.ReadFromV2(msg)) require.Equal(t, val, val2) } func TestContainer_Owner(t *testing.T) { var val container.Container require.Zero(t, val.Owner()) val = containertest.Container() owner := usertest.ID() val.SetOwner(owner) var msg v2container.Container val.WriteToV2(&msg) var msgOwner refs.OwnerID owner.WriteToV2(&msgOwner) require.Equal(t, &msgOwner, msg.GetOwnerID()) var val2 container.Container require.NoError(t, val2.ReadFromV2(msg)) require.True(t, val2.Owner().Equals(owner)) } func TestContainer_BasicACL(t *testing.T) { var val container.Container require.Zero(t, val.BasicACL()) val = containertest.Container() basicACL := containertest.BasicACL() val.SetBasicACL(basicACL) var msg v2container.Container val.WriteToV2(&msg) require.EqualValues(t, basicACL.Bits(), msg.GetBasicACL()) var val2 container.Container require.NoError(t, val2.ReadFromV2(msg)) require.Equal(t, basicACL, val2.BasicACL()) } func TestContainer_PlacementPolicy(t *testing.T) { var val container.Container require.Zero(t, val.PlacementPolicy()) val = containertest.Container() pp := netmaptest.PlacementPolicy() val.SetPlacementPolicy(pp) var msgPolicy v2netmap.PlacementPolicy pp.WriteToV2(&msgPolicy) var msg v2container.Container val.WriteToV2(&msg) require.Equal(t, &msgPolicy, msg.GetPlacementPolicy()) var val2 container.Container require.NoError(t, val2.ReadFromV2(msg)) require.Equal(t, pp, val2.PlacementPolicy()) } func assertContainsAttribute(t *testing.T, m v2container.Container, key, val string) { var msgAttr v2container.Attribute msgAttr.SetKey(key) msgAttr.SetValue(val) require.Contains(t, m.GetAttributes(), msgAttr) } func TestContainer_Attribute(t *testing.T) { const attrKey1, attrKey2 = v2container.SysAttributePrefix + "key1", v2container.SysAttributePrefix + "key2" const attrVal1, attrVal2 = "val1", "val2" val := containertest.Container() val.SetAttribute(attrKey1, attrVal1) val.SetAttribute(attrKey2, attrVal2) var i int val.IterateUserAttributes(func(key, val string) { i++ }) require.Equal(t, 1, i) var msg v2container.Container val.WriteToV2(&msg) require.GreaterOrEqual(t, len(msg.GetAttributes()), 2) assertContainsAttribute(t, msg, attrKey1, attrVal1) assertContainsAttribute(t, msg, attrKey2, attrVal2) var val2 container.Container require.NoError(t, val2.ReadFromV2(msg)) require.Equal(t, attrVal1, val2.Attribute(attrKey1)) require.Equal(t, attrVal2, val2.Attribute(attrKey2)) m := map[string]string{} val2.IterateAttributes(func(key, val string) { m[key] = val }) require.GreaterOrEqual(t, len(m), 2) require.Equal(t, attrVal1, m[attrKey1]) require.Equal(t, attrVal2, m[attrKey2]) val2.SetAttribute(attrKey1, attrVal1+"_") require.Equal(t, attrVal1+"_", val2.Attribute(attrKey1)) } func TestSetName(t *testing.T) { var val container.Container require.Panics(t, func() { container.SetName(&val, "") }) val = containertest.Container() const name = "some name" container.SetName(&val, name) var msg v2container.Container val.WriteToV2(&msg) assertContainsAttribute(t, msg, "Name", name) var val2 container.Container require.NoError(t, val2.ReadFromV2(msg)) require.Equal(t, name, container.Name(val2)) } func TestSetCreationTime(t *testing.T) { var val container.Container require.Zero(t, container.CreatedAt(val).Unix()) val = containertest.Container() creat := time.Now() container.SetCreationTime(&val, creat) var msg v2container.Container val.WriteToV2(&msg) assertContainsAttribute(t, msg, "Timestamp", strconv.FormatInt(creat.Unix(), 10)) var val2 container.Container require.NoError(t, val2.ReadFromV2(msg)) require.Equal(t, creat.Unix(), container.CreatedAt(val2).Unix()) } func TestDisableHomomorphicHashing(t *testing.T) { var val container.Container require.False(t, container.IsHomomorphicHashingDisabled(val)) val = containertest.Container() container.DisableHomomorphicHashing(&val) var msg v2container.Container val.WriteToV2(&msg) assertContainsAttribute(t, msg, v2container.SysAttributePrefix+"DISABLE_HOMOMORPHIC_HASHING", "true") var val2 container.Container require.NoError(t, val2.ReadFromV2(msg)) require.True(t, container.IsHomomorphicHashingDisabled(val2)) } func TestWriteDomain(t *testing.T) { var val container.Container require.Zero(t, container.ReadDomain(val).Name()) val = containertest.Container() const name = "domain name" var d container.Domain d.SetName(name) container.WriteDomain(&val, d) var msg v2container.Container val.WriteToV2(&msg) assertContainsAttribute(t, msg, v2container.SysAttributeName, name) assertContainsAttribute(t, msg, v2container.SysAttributeZone, "container") const zone = "domain zone" d.SetZone(zone) container.WriteDomain(&val, d) val.WriteToV2(&msg) assertContainsAttribute(t, msg, v2container.SysAttributeZone, zone) var val2 container.Container require.NoError(t, val2.ReadFromV2(msg)) require.Equal(t, d, container.ReadDomain(val2)) } func TestCalculateID(t *testing.T) { val := containertest.Container() require.False(t, container.AssertID(cidtest.ID(), val)) var id cid.ID container.CalculateID(&id, val) var msg refs.ContainerID id.WriteToV2(&msg) h := sha256.Sum256(val.Marshal()) require.Equal(t, h[:], msg.GetValue()) var id2 cid.ID require.NoError(t, id2.ReadFromV2(msg)) require.True(t, container.AssertID(id2, val)) } func TestCalculateSignature(t *testing.T) { key, err := keys.NewPrivateKey() require.NoError(t, err) val := containertest.Container() var sig frostfscrypto.Signature require.NoError(t, container.CalculateSignature(&sig, val, key.PrivateKey)) var msg refs.Signature sig.WriteToV2(&msg) var sig2 frostfscrypto.Signature require.NoError(t, sig2.ReadFromV2(msg)) require.True(t, container.VerifySignature(sig2, val)) }