From ba3239589443e4b908e13e448c748fbe470eb103 Mon Sep 17 00:00:00 2001 From: Evgeniy Kulikov Date: Tue, 28 Apr 2020 16:29:54 +0300 Subject: [PATCH 1/4] api: update to neofs-api v0.7.3 --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 9773c9b..62a92ec 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -PROTO_VERSION=v0.7.2 +PROTO_VERSION=v0.7.3 PROTO_URL=https://github.com/nspcc-dev/neofs-api/archive/$(PROTO_VERSION).tar.gz B=\033[0;1m From 7a7deb0b01a3fccff3647148ffa595c47f4c9548 Mon Sep 17 00:00:00 2001 From: Evgeniy Kulikov Date: Tue, 28 Apr 2020 16:30:47 +0300 Subject: [PATCH 2/4] proto: regenerate files --- object/types.pb.go | Bin 85297 -> 85256 bytes object/types.proto | 2 ++ 2 files changed, 2 insertions(+) diff --git a/object/types.pb.go b/object/types.pb.go index a24a2f1a798a88c173bc4125b21db0228126a486..97106c7bde6493f1526fbbcc1f09c27946b60cdc 100644 GIT binary patch delta 5451 zcmYkAJI>@(5Jm+O0T7T9Ak7F6(FA@!_JV}$wjCp)mI$1Z|JkepG)U}%4X_!i&Z(di ztNZ%idVcj)UH|p*i$6Yo@#o*m+ds>@w;$JcpZ)&!-TLjPU)FDa_`IFoe*O91dl)~w zZ=PM3&wbD5xbSQ~eD!6#IP%ZJrkUq3u;NyJKiXVrc!;j5Uin;DAA4MwSeh|L<7Y&K0q;Y9d*+EA z*&AVSWklXYFfQIUi14rxnKm>$*gAUv5v3D%77m}h-EsE7qBEcOv!7G{j1`yu@LLhx zgoXvxhsKy6j`e6;37&!8(KhmISwDGh= zK*q_QO0j{#>{gJVt#;13K<+QMB4Q7rcfbT&P4R||l}!t_EcmG>Mp7R}^y^h)8ZOgH z3_BgwY*sD|GlVPV?V%?0PrT^RGYJ6WW)u)~4frtgr#Fd6HS~?yGgSDwA!0_vf;Lwc zL&(`Sc7}d^o7K>`7a1oe8JLwIbp+->MvvLbe&G3p)W*PYR_h)}>n~jBIA-}o1>A`} z&h4JShm)s}co+brMxbN=i4}vP;eF^XSQx^HAx*Rqi|EdH8$a4!;1}V zWh#O!fbb+WSSIR`aKz`x)`O%!G!mg2e33TQ45TMQnEF>jVs0mWFvSZePGoFsQnt}+ zN!5W)%h$w6gc8xosRsXbZQ5~x;(N}=odFd-MX#iC!-pO#MP_SYu;mh~{O*C?!71ZX z1#RIN?t{ZRvXWcHb*=he?Zc}^pUK`xB!!Yy7f~S5qJ-x}sB9nu+FqR&$sJj}P|%8= z4gI2_XqOk^d1?^RGOpH}VxLhm5j^=*f3#vDYy!Y%kLH!2`i$C71?NqIYhihP=C-%dcu-W>VZ|HGS-FCMA8M3&j3dH z(378?1JZ|7XUS+}^#gV;?5sXJe_E;avr2u*^-$xA!mwS>qBrC3`lpB zRX8%6dVYuKSZQye)Jfewd80OiD;7uKT3Liq7je=MChW& z27=+?1*cl}3~9yv6x=JGIMtbGQ{ucZU{O>_YEZU=jL49ui!u=8o|E6Q^^PMlzzK%C zwCjHE{Mj)w$UHUJUrehLnUo@RT}ZV<`Sw*$0i8r@MbQeV4hW?J={=zw^T(@w9gxw! z6O#ngfKEq&8b63+O<_Q}#+(`g@Jc$cWNf^zQ9U97Ie$?sYKW0N(Abe5E4?}^8V% zNFvdMng2Lpua&cen6VX51$Wp$al0BEL!F^*f3m+tTvs;IP=-G=7htX60hyxpMEpFH6(fN6KHvmNkBr)1~#Bjvahe>2b^f-!0ht71`7!oo_=2Q6E_vaf=?062* zQu;tDZO*3NS?smfI@K1(nP^$eF6TUJL0N|p$uR!ag(c>nSTa_AiV+!`D3J&7Jccc> z$_sBaQjo#$Zth*d@na-B0wbv|3XMvV@0~T88x04HR%3=18+6mEJlmpeS=4(>MlsN~ zF)ynQ6HaX%&~LrtT5cBf?Ud-0s+Hcl>?~G;G;Y=Fp@V>x$f^S| zvY3rpYPucFlwn;B_5hh|mu>x>jZ*!3vDNk_yP){j7coG`scFb=;^vc!==V?Wqvq4N$vRQ#)Z6jt>)(F*?|*@hR09A2 delta 5394 zcmY+ItF9(h5QP(x5lm(bijc{KgapG8eZP>9@F1AJ`f-hFi~rpi9smOw9Pfa_;dl-N zwZE?d2eb2^?!9;2R;^lnet7@lm-jDz{&jl1e)aP4+w|$<`>#KF)UUpI{4u?K{P@-D z4}VW@zxb${A8)?<{a*H`&#SBJ$~q2ZUF)(g)ziz5tE*qi9~JAdmfzD<)|#!$Tz(%7 z&slfg4qJIrRb}nQvd$P74t~3*D+casYd)}G>MJ~}@v`H$&ljv^>9JPxw!*@uFW5QAZ6h#PdkvT#k8Nx%5#9kYcJ1bn z0vMZ#X(>j7g_=|iBxd8(YRne82&cfP^ zmcf8XfVggPV8_XY!`^*hrzMdSLDiOo=YxJl8N$AYE1^VDuHKSi=fHu9c#K4hx4dmh zTgU!}C$rvRv%%(RUN%C|TBhW9x&v0bC)g`+@;*u_a7F!OXAoycF-B6=@jPHqD5EC0 zgV#3K#P0(G6V4<8TkJ3TO0E`TAgY7AWs!ly&1o4(#=x=8LW^h)o9UFB~)SEn_ex7+s&86B#Bz3p;x% zoEL7cqwPzQ8W1)B#z<93(sYxhnQ)yZCctowDkm6sTVki8G?lXfPaE#u31l0vaEM9V zGpm_N5_4$(#LLrCvYN3Gk7w4(mACeI_M6Gjw6i90NYWEYIA*~d-Hzhp1{qFm%i#ET zjK$C>S#lJ)W-_>YBC4Ij$l@c{RXCaCN80QXQ@@fb_pi5{G1`3GYX3AmdESAuh2w51 z%g%5%Sq72p4HaFVIz}3o{A6N_ad!Y9=Zl@oImd`|d?yBhE}7<368g>t&8bw(o?Yia z)X9MZ8-X|pZ^=&@m!~Aw9lvCQV3AS=Daf=UUM|Pgj@u`x_lZcB(Om61sZk;prMHpH z+0i67J;nhwmqlNtQT8M?fXPU4FiMLT4pXrz$(qOrAafZ{dLgCbw?rtcq78}#sm2lMG_wo?q35NbMBJv61ba$K;a#y$_E$c-Ni~bT&LUs{*SWuTpvPtsXsxVD? z%uc7p#@kcxOj61@+^}MjlFS*!DE4booTup}Cr;84P*yegWn_Ou*O4TUVS_j!{*`Lw zYLX#yc6hPiWC*!<8=q;#ehL{Z=l20NLy{K@R$c6i45va)kY}l~(27(?s)8igEzAg& z_+*RUDZjd>yI4>-`|;;+2!#{7dOVht?1q#xMCCM7)F^|^tsfeGLqt-G0bMnp`5{UI zh86wuzYjj*$uCE`-rhHpdS@@^2(aJeLtn`3Er)A6oz*4^0a|iS2Xqbgok4?@;f2-` zJ;sn?lq$K^KFGEQLyBvU4cK&Ai5{`7%YCYHSbV{ zI|FiWMO_l4U}!% zV7FpHy!)R3iPF>RMhoz-E(z!DOnu2OElMwa=B&f7WbPUTVfJpb`;_Vqq{jY?*XFr)* zwMLLwF@PkzFBPlACYGH9qxX?XX~)w0;oujLGcW}N` Date: Tue, 28 Apr 2020 16:31:46 +0300 Subject: [PATCH 3/4] object: implement Stringify for Object --- object/types.go | 118 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 118 insertions(+) diff --git a/object/types.go b/object/types.go index 83b03c7..4acffbe 100644 --- a/object/types.go +++ b/object/types.go @@ -3,10 +3,14 @@ package object import ( "bytes" "context" + "fmt" + "io" + "reflect" "github.com/gogo/protobuf/proto" "github.com/nspcc-dev/neofs-api-go/internal" "github.com/nspcc-dev/neofs-api-go/refs" + "github.com/pkg/errors" ) type ( @@ -262,3 +266,117 @@ func (m Object) Address() *refs.Address { CID: m.SystemHeader.CID, } } + +func (m CreationPoint) String() string { + return fmt.Sprintf(`{UnixTime=%d Epoch=%d}`, m.UnixTime, m.Epoch) +} + +// Stringify converts object into string format. +func Stringify(dst io.Writer, obj *Object) error { + // put empty line + if _, err := fmt.Fprintln(dst); err != nil { + return err + } + + // put object line + if _, err := fmt.Fprintln(dst, "Object:"); err != nil { + return err + } + + // put system headers + if _, err := fmt.Fprintln(dst, "\tSystemHeader:"); err != nil { + return err + } + + sysHeaders := []string{"ID", "CID", "OwnerID", "Version", "PayloadLength", "CreatedAt"} + v := reflect.ValueOf(obj.SystemHeader) + for _, key := range sysHeaders { + if !v.FieldByName(key).IsValid() { + return errors.Errorf("invalid system header key: %q", key) + } + + val := v.FieldByName(key).Interface() + if _, err := fmt.Fprintf(dst, "\t\t- %s=%v\n", key, val); err != nil { + return err + } + } + + // put user headers + if _, err := fmt.Fprintln(dst, "\tUserHeaders:"); err != nil { + return err + } + + for _, header := range obj.Headers { + var ( + typ = reflect.ValueOf(header.Value) + key string + val interface{} + ) + + switch t := typ.Interface().(type) { + case *Header_Link: + key = "Link" + val = fmt.Sprintf(`{Type=%s ID=%s}`, t.Link.Type, t.Link.ID) + case *Header_Redirect: + key = "Redirect" + val = fmt.Sprintf(`{CID=%s OID=%s}`, t.Redirect.CID, t.Redirect.ObjectID) + case *Header_UserHeader: + key = "UserHeader" + val = fmt.Sprintf(`{Key=%s Val=%s}`, t.UserHeader.Key, t.UserHeader.Value) + case *Header_Transform: + key = "Transform" + val = t.Transform.Type.String() + case *Header_Tombstone: + key = "Tombstone" + val = "MARKED" + case *Header_Token: + key = "Token" + val = fmt.Sprintf("{"+ + "ID=%s OwnerID=%s Verb=%s Address=%s Created=%d ValidUntil=%d SessionKey=%02x Signature=%02x"+ + "}", + t.Token.Token_Info.ID, + t.Token.Token_Info.OwnerID, + t.Token.Token_Info.Verb, + t.Token.Token_Info.Address, + t.Token.Token_Info.Created, + t.Token.Token_Info.ValidUntil, + t.Token.Token_Info.SessionKey, + t.Token.Signature) + case *Header_HomoHash: + key = "HomoHash" + val = t.HomoHash + case *Header_PayloadChecksum: + key = "PayloadChecksum" + val = t.PayloadChecksum + case *Header_Integrity: + key = "Integrity" + val = fmt.Sprintf(`{Checksum=%02x Signature=%02x}`, + t.Integrity.HeadersChecksum, + t.Integrity.ChecksumSignature) + case *Header_StorageGroup: + key = "StorageGroup" + val = fmt.Sprintf(`{DataSize=%d Hash=%02x Lifetime={Unit=%s Value=%d}}`, + t.StorageGroup.ValidationDataSize, + t.StorageGroup.ValidationHash, + t.StorageGroup.Lifetime.Unit, + t.StorageGroup.Lifetime.Value) + case *Header_PublicKey: + key = "PublicKey" + val = t.PublicKey.Value + default: + key = "Unknown" + val = t + } + + if _, err := fmt.Fprintf(dst, "\t\t- Type=%s\n\t\t Value=%v\n", key, val); err != nil { + return err + } + } + + // put payload + if _, err := fmt.Fprintf(dst, "\tPayload: %#v\n", obj.Payload); err != nil { + return err + } + + return nil +} From 5ae4e14bfaf9b83019e6bb71783f6a6d36779f6a Mon Sep 17 00:00:00 2001 From: Evgeniy Kulikov Date: Tue, 28 Apr 2020 16:32:19 +0300 Subject: [PATCH 4/4] object: test coverage for stringify method --- object/types_test.go | 181 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 181 insertions(+) create mode 100644 object/types_test.go diff --git a/object/types_test.go b/object/types_test.go new file mode 100644 index 0000000..50e4e0b --- /dev/null +++ b/object/types_test.go @@ -0,0 +1,181 @@ +package object + +import ( + "bytes" + "testing" + + "github.com/nspcc-dev/neofs-api-go/refs" + "github.com/nspcc-dev/neofs-api-go/service" + "github.com/nspcc-dev/neofs-api-go/storagegroup" + "github.com/nspcc-dev/neofs-crypto/test" + "github.com/stretchr/testify/require" +) + +func TestStringify(t *testing.T) { + res := ` +Object: + SystemHeader: + - ID=7e0b9c6c-aabc-4985-949e-2680e577b48b + - CID=11111111111111111111111111111111 + - OwnerID=ALYeYC41emF6MrmUMc4a8obEPdgFhq9ran + - Version=1 + - PayloadLength=1 + - CreatedAt={UnixTime=1 Epoch=1} + UserHeaders: + - Type=Link + Value={Type=Child ID=7e0b9c6c-aabc-4985-949e-2680e577b48b} + - Type=Redirect + Value={CID=11111111111111111111111111111111 OID=7e0b9c6c-aabc-4985-949e-2680e577b48b} + - Type=UserHeader + Value={Key=test_key Val=test_value} + - Type=Transform + Value=Split + - Type=Tombstone + Value=MARKED + - Type=Token + Value={ID=7e0b9c6c-aabc-4985-949e-2680e577b48b OwnerID=ALYeYC41emF6MrmUMc4a8obEPdgFhq9ran Verb=Search Address=11111111111111111111111111111111/7e0b9c6c-aabc-4985-949e-2680e577b48b Created=1 ValidUntil=2 SessionKey=010203040506 Signature=010203040506} + - Type=HomoHash + Value=1111111111111111111111111111111111111111111111111111111111111111 + - Type=PayloadChecksum + Value=[1 2 3 4 5 6] + - Type=Integrity + Value={Checksum=010203040506 Signature=010203040506} + - Type=StorageGroup + Value={DataSize=5 Hash=31313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131 Lifetime={Unit=UnixTime Value=555}} + - Type=PublicKey + Value=[1 2 3 4 5 6] + Payload: []byte{0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7} +` + + key := test.DecodeKey(0) + + uid, err := refs.NewOwnerID(&key.PublicKey) + require.NoError(t, err) + + var oid refs.UUID + + require.NoError(t, oid.Parse("7e0b9c6c-aabc-4985-949e-2680e577b48b")) + + obj := &Object{ + SystemHeader: SystemHeader{ + Version: 1, + PayloadLength: 1, + ID: oid, + OwnerID: uid, + CID: CID{}, + CreatedAt: CreationPoint{ + UnixTime: 1, + Epoch: 1, + }, + }, + Payload: []byte{1, 2, 3, 4, 5, 6, 7}, + } + + // *Header_Link + obj.Headers = append(obj.Headers, Header{ + Value: &Header_Link{ + Link: &Link{ID: oid, Type: Link_Child}, + }, + }) + + // *Header_Redirect + obj.Headers = append(obj.Headers, Header{ + Value: &Header_Redirect{ + Redirect: &Address{ObjectID: oid, CID: CID{}}, + }, + }) + + // *Header_UserHeader + obj.Headers = append(obj.Headers, Header{ + Value: &Header_UserHeader{ + UserHeader: &UserHeader{ + Key: "test_key", + Value: "test_value", + }, + }, + }) + + // *Header_Transform + obj.Headers = append(obj.Headers, Header{ + Value: &Header_Transform{ + Transform: &Transform{ + Type: Transform_Split, + }, + }, + }) + + // *Header_Tombstone + obj.Headers = append(obj.Headers, Header{ + Value: &Header_Tombstone{ + Tombstone: &Tombstone{}, + }, + }) + + // *Header_Token + obj.Headers = append(obj.Headers, Header{ + Value: &Header_Token{ + Token: &Token{ + Signature: []byte{1, 2, 3, 4, 5, 6}, + Token_Info: service.Token_Info{ + ID: oid, + OwnerID: uid, + Verb: service.Token_Info_Search, + Address: service.Address{ObjectID: oid, CID: refs.CID{}}, + Created: 1, + ValidUntil: 2, + SessionKey: []byte{1, 2, 3, 4, 5, 6}, + }, + }, + }, + }) + + // *Header_HomoHash + obj.Headers = append(obj.Headers, Header{ + Value: &Header_HomoHash{ + HomoHash: Hash{}, + }, + }) + + // *Header_PayloadChecksum + obj.Headers = append(obj.Headers, Header{ + Value: &Header_PayloadChecksum{ + PayloadChecksum: []byte{1, 2, 3, 4, 5, 6}, + }, + }) + + // *Header_Integrity + obj.Headers = append(obj.Headers, Header{ + Value: &Header_Integrity{ + Integrity: &IntegrityHeader{ + HeadersChecksum: []byte{1, 2, 3, 4, 5, 6}, + ChecksumSignature: []byte{1, 2, 3, 4, 5, 6}, + }, + }, + }) + + // *Header_StorageGroup + obj.Headers = append(obj.Headers, Header{ + Value: &Header_StorageGroup{ + StorageGroup: &storagegroup.StorageGroup{ + ValidationDataSize: 5, + ValidationHash: storagegroup.Hash{}, + Lifetime: &storagegroup.StorageGroup_Lifetime{ + Unit: storagegroup.StorageGroup_Lifetime_UnixTime, + Value: 555, + }, + }, + }, + }) + + // *Header_PublicKey + obj.Headers = append(obj.Headers, Header{ + Value: &Header_PublicKey{ + PublicKey: &PublicKey{Value: []byte{1, 2, 3, 4, 5, 6}}, + }, + }) + + buf := new(bytes.Buffer) + + require.NoError(t, Stringify(buf, obj)) + require.Equal(t, res, buf.String()) +}