@@ -3,13 +3,22 @@ package object_test
33import (
44 "bytes"
55 "crypto/rand"
6+ "encoding/binary"
67 "io"
78 "testing"
89
10+ "github.com/nspcc-dev/neo-go/pkg/crypto/keys"
911 iobject "github.com/nspcc-dev/neofs-node/internal/object"
12+ iprotobuf "github.com/nspcc-dev/neofs-node/internal/protobuf"
13+ "github.com/nspcc-dev/neofs-node/internal/testutil"
14+ neofscrypto "github.com/nspcc-dev/neofs-sdk-go/crypto"
1015 "github.com/nspcc-dev/neofs-sdk-go/object"
16+ oid "github.com/nspcc-dev/neofs-sdk-go/object/id"
17+ oidtest "github.com/nspcc-dev/neofs-sdk-go/object/id/test"
1118 objecttest "github.com/nspcc-dev/neofs-sdk-go/object/test"
19+ protoobject "github.com/nspcc-dev/neofs-sdk-go/proto/object"
1220 "github.com/stretchr/testify/require"
21+ "google.golang.org/protobuf/proto"
1322)
1423
1524func TestWriteWithoutPayload (t * testing.T ) {
@@ -97,3 +106,255 @@ func TestReadHeaderPrefix(t *testing.T) {
97106 require .Equal (t , expectedSize , len (payloadPrefix ))
98107 require .Equal (t , payload [:expectedSize ], payloadPrefix )
99108}
109+
110+ func TestRestoreLayoutWithCutPayload (t * testing.T ) {
111+ const pubkeyLen = 33
112+ id := oidtest .ID ()
113+ sig := neofscrypto .NewSignatureFromRawKey (neofscrypto .N3 , testutil .RandByteSlice (pubkeyLen ), testutil .RandByteSlice (keys .SignatureLen ))
114+ payload := []byte ("Hello, world!" )
115+
116+ obj := objecttest .Object ()
117+ obj .SetID (id )
118+ obj .SetSignature (& sig )
119+ obj .SetPayload (payload )
120+
121+ hdrLen := obj .HeaderLen ()
122+ hdrLenVarint := binary .PutVarint (make ([]byte , binary .MaxVarintLen64 ), int64 (hdrLen ))
123+
124+ encodeBuffer := func (obj []byte ) []byte {
125+ b := testutil .RandByteSlice (object .MaxHeaderLen * 2 )
126+ copy (b , obj )
127+ return b
128+ }
129+
130+ encodeObject := func (obj object.Object ) []byte {
131+ return encodeBuffer (obj .Marshal ())
132+ }
133+
134+ assertID := func (t * testing.T , data []byte , f iprotobuf.FieldBounds , off int ) {
135+ require .EqualValues (t , off , f .From )
136+ require .EqualValues (t , f .From + (1 + 1 ), f .ValueFrom )
137+ const idFldLen = 1 + 1 + 32
138+ require .EqualValues (t , f .ValueFrom + idFldLen , f .To )
139+ require .Equal (t , []byte {10 , idFldLen }, data [f .From :f .ValueFrom ])
140+ var gotID oid.ID
141+ require .NoError (t , gotID .Unmarshal (data [f .ValueFrom :f .To ]))
142+ require .Equal (t , obj .GetID (), gotID )
143+ }
144+ assertSignature := func (t * testing.T , data []byte , f iprotobuf.FieldBounds , off int ) {
145+ require .EqualValues (t , off , f .From )
146+ require .EqualValues (t , f .From + (1 + 1 ), f .ValueFrom )
147+ const sigFldLen = (1 + 1 + pubkeyLen ) + (1 + 1 + keys .SignatureLen ) + (1 + 1 )
148+ require .EqualValues (t , f .ValueFrom + sigFldLen , f .To )
149+ require .Equal (t , []byte {18 , sigFldLen }, data [f .From :f .ValueFrom ])
150+ var gotSig neofscrypto.Signature
151+ require .NoError (t , gotSig .Unmarshal (data [f .ValueFrom :f .To ]))
152+ require .Equal (t , sig , gotSig )
153+ }
154+ assertHeader := func (t * testing.T , data []byte , f iprotobuf.FieldBounds , off int ) {
155+ require .EqualValues (t , off , f .From )
156+ require .EqualValues (t , f .From + (1 + hdrLenVarint ), f .ValueFrom )
157+ require .EqualValues (t , f .ValueFrom + hdrLen , f .To )
158+ require .Equal (t , binary .AppendUvarint ([]byte {26 }, uint64 (hdrLen )), data [f .From :f .ValueFrom ])
159+ var gotHdr protoobject.Header
160+ require .NoError (t , proto .Unmarshal (data [f .ValueFrom :f .To ], & gotHdr ))
161+ require .True (t , proto .Equal (obj .ProtoMessage ().Header , & gotHdr ))
162+ }
163+
164+ t .Run ("empty" , func (t * testing.T ) {
165+ _ , _ , _ , err := iobject .RestoreLayoutWithCutPayload (nil )
166+ require .ErrorIs (t , err , io .ErrUnexpectedEOF )
167+ require .EqualError (t , err , "parse field tag: " + io .ErrUnexpectedEOF .Error ())
168+
169+ _ , _ , _ , err = iobject .RestoreLayoutWithCutPayload ([]byte {})
170+ require .ErrorIs (t , err , io .ErrUnexpectedEOF )
171+ require .EqualError (t , err , "parse field tag: " + io .ErrUnexpectedEOF .Error ())
172+ })
173+ t .Run ("payload tag" , func (t * testing.T ) {
174+ _ , _ , _ , err := iobject .RestoreLayoutWithCutPayload ([]byte {34 })
175+ require .ErrorIs (t , err , io .ErrUnexpectedEOF )
176+ require .EqualError (t , err , "parse field (#4,type=2): " + io .ErrUnexpectedEOF .Error ())
177+ })
178+ t .Run ("payload tag and len" , func (t * testing.T ) {
179+ idf , sigf , hdrf , err := iobject .RestoreLayoutWithCutPayload ([]byte {34 , 13 })
180+ require .NoError (t , err )
181+
182+ require .Negative (t , idf .From )
183+ require .Negative (t , sigf .From )
184+ require .Negative (t , hdrf .From )
185+ })
186+ t .Run ("payload" , func (t * testing.T ) {
187+ var obj object.Object
188+ obj .SetPayload (payload )
189+
190+ data := encodeObject (obj )
191+
192+ idf , sigf , hdrf , err := iobject .RestoreLayoutWithCutPayload (data )
193+ require .NoError (t , err )
194+
195+ require .Negative (t , idf .From )
196+ require .Negative (t , sigf .From )
197+ require .Negative (t , hdrf .From )
198+ })
199+ t .Run ("id,signature,payload" , func (t * testing.T ) {
200+ var obj object.Object
201+ obj .SetID (id )
202+ obj .SetSignature (& sig )
203+ obj .SetPayload (payload )
204+
205+ data := encodeObject (obj )
206+
207+ idf , sigf , hdrf , err := iobject .RestoreLayoutWithCutPayload (data )
208+ require .NoError (t , err )
209+
210+ assertID (t , data , idf , 0 )
211+ assertSignature (t , data , sigf , idf .To )
212+ require .Negative (t , hdrf .From )
213+ })
214+ t .Run ("id,header,payload" , func (t * testing.T ) {
215+ obj := obj
216+ obj .SetSignature (nil )
217+
218+ data := encodeObject (obj )
219+
220+ idf , sigf , hdrf , err := iobject .RestoreLayoutWithCutPayload (data )
221+ require .NoError (t , err )
222+
223+ assertID (t , data , idf , 0 )
224+ require .Negative (t , sigf .From )
225+ assertHeader (t , data , hdrf , idf .To )
226+ })
227+ t .Run ("id,signature" , func (t * testing.T ) {
228+ var obj object.Object
229+ obj .SetID (id )
230+ obj .SetSignature (& sig )
231+
232+ data := obj .Marshal ()
233+
234+ idf , sigf , hdrf , err := iobject .RestoreLayoutWithCutPayload (data )
235+ require .NoError (t , err )
236+
237+ assertID (t , data , idf , 0 )
238+ assertSignature (t , data , sigf , idf .To )
239+ require .Negative (t , hdrf .From )
240+ })
241+ t .Run ("id,header" , func (t * testing.T ) {
242+ obj := obj
243+ obj .SetSignature (nil )
244+ obj .SetPayload (nil )
245+
246+ data := encodeObject (obj )
247+
248+ idf , sigf , hdrf , err := iobject .RestoreLayoutWithCutPayload (data )
249+ require .NoError (t , err )
250+
251+ assertID (t , data , idf , 0 )
252+ require .Negative (t , sigf .From )
253+ assertHeader (t , data , hdrf , idf .To )
254+ })
255+ t .Run ("id,payload" , func (t * testing.T ) {
256+ var obj object.Object
257+ obj .SetID (id )
258+ obj .SetPayload (payload )
259+
260+ data := encodeObject (obj )
261+
262+ idf , sigf , hdrf , err := iobject .RestoreLayoutWithCutPayload (data )
263+ require .NoError (t , err )
264+
265+ assertID (t , data , idf , 0 )
266+ require .Negative (t , sigf .From )
267+ require .Negative (t , hdrf .From )
268+ })
269+ t .Run ("id" , func (t * testing.T ) {
270+ var obj object.Object
271+ obj .SetID (id )
272+
273+ data := obj .Marshal ()
274+
275+ idf , sigf , hdrf , err := iobject .RestoreLayoutWithCutPayload (data )
276+ require .NoError (t , err )
277+
278+ assertID (t , data , idf , 0 )
279+ require .Negative (t , sigf .From )
280+ require .Negative (t , hdrf .From )
281+ })
282+ t .Run ("signature,header,payload" , func (t * testing.T ) {
283+ obj := obj
284+ obj .SetID (oid.ID {})
285+
286+ data := encodeObject (obj )
287+
288+ idf , sigf , hdrf , err := iobject .RestoreLayoutWithCutPayload (data )
289+ require .NoError (t , err )
290+
291+ require .Negative (t , idf .From )
292+ assertSignature (t , data , sigf , 0 )
293+ assertHeader (t , data , hdrf , sigf .To )
294+ })
295+ t .Run ("signature,payload" , func (t * testing.T ) {
296+ var obj object.Object
297+ obj .SetSignature (& sig )
298+ obj .SetPayload (payload )
299+
300+ data := encodeObject (obj )
301+
302+ idf , sigf , hdrf , err := iobject .RestoreLayoutWithCutPayload (data )
303+ require .NoError (t , err )
304+
305+ require .Negative (t , idf .From )
306+ assertSignature (t , data , sigf , 0 )
307+ require .Negative (t , hdrf .From )
308+ })
309+ t .Run ("signature" , func (t * testing.T ) {
310+ var obj object.Object
311+ obj .SetSignature (& sig )
312+
313+ data := obj .Marshal ()
314+
315+ idf , sigf , hdrf , err := iobject .RestoreLayoutWithCutPayload (data )
316+ require .NoError (t , err )
317+
318+ require .Negative (t , idf .From )
319+ assertSignature (t , data , sigf , 0 )
320+ require .Negative (t , hdrf .From )
321+ })
322+ t .Run ("header,payload" , func (t * testing.T ) {
323+ obj := obj
324+ obj .SetID (oid.ID {})
325+ obj .SetSignature (nil )
326+
327+ data := encodeObject (obj )
328+
329+ idf , sigf , hdrf , err := iobject .RestoreLayoutWithCutPayload (data )
330+ require .NoError (t , err )
331+
332+ require .Negative (t , idf .From )
333+ require .Negative (t , sigf .From )
334+ assertHeader (t , data , hdrf , 0 )
335+ })
336+ t .Run ("header" , func (t * testing.T ) {
337+ obj := obj
338+ obj .SetID (oid.ID {})
339+ obj .SetSignature (nil )
340+ obj .SetPayload (nil )
341+
342+ data := encodeObject (obj )
343+
344+ idf , sigf , hdrf , err := iobject .RestoreLayoutWithCutPayload (data )
345+ require .NoError (t , err )
346+
347+ require .Negative (t , idf .From )
348+ require .Negative (t , sigf .From )
349+ assertHeader (t , data , hdrf , 0 )
350+ })
351+
352+ data := encodeObject (obj )
353+
354+ idf , sigf , hdrf , err := iobject .RestoreLayoutWithCutPayload (data )
355+ require .NoError (t , err )
356+
357+ assertID (t , data , idf , 0 )
358+ assertSignature (t , data , sigf , idf .To )
359+ assertHeader (t , data , hdrf , sigf .To )
360+ }
0 commit comments