@@ -28,6 +28,7 @@ import (
2828 "github.com/awslabs/soci-snapshotter/util/testutil"
2929 "github.com/awslabs/soci-snapshotter/ztoc"
3030 "github.com/awslabs/soci-snapshotter/ztoc/compression"
31+ "github.com/stretchr/testify/assert"
3132)
3233
3334func TestSpanManager (t * testing.T ) {
@@ -48,14 +49,38 @@ func TestSpanManager(t *testing.T) {
4849 maxSpans : 100 ,
4950 },
5051 {
51- name : "span digest verification fails" ,
52+ name : "bad MaxSpanID" ,
53+ maxSpans : 5 ,
54+ expectedError : ErrIncorrectMaxSpanID ,
55+ },
56+ {
57+ name : "header verification fails" ,
5258 maxSpans : 100 ,
5359 sectionReader : io .NewSectionReader (readerFn (func (b []byte , _ int64 ) (int , error ) {
5460 sz := compression .Offset (len (b ))
5561 r := testutil .NewTestRand (t )
5662 copy (b , r .RandomByteData (int64 (sz ))) // populate with garbage data
5763 return len (b ), nil
5864 }), 0 , 10000000 ),
65+ expectedError : gzip .ErrHeader ,
66+ },
67+ {
68+ name : "span digest verification fails" ,
69+ maxSpans : 10 ,
70+ sectionReader : io .NewSectionReader (readerFn (func (b []byte , _ int64 ) (int , error ) {
71+ var r bytes.Buffer
72+ w := gzip .NewWriter (& r )
73+ w .Write ([]byte ("failing digest verification" ))
74+ w .Close ()
75+
76+ gz , err := io .ReadAll (& r )
77+ if err != nil {
78+ t .Fatalf ("error creating SectionReader: %v" , err )
79+ }
80+
81+ copy (b , gz )
82+ return len (b ), nil
83+ }), 0 , int64 (spanSize )* 10 ),
5984 expectedError : ErrIncorrectSpanDigest ,
6085 },
6186 }
@@ -84,13 +109,20 @@ func TestSpanManager(t *testing.T) {
84109 return
85110 }
86111
112+ if tc .expectedError == ErrIncorrectMaxSpanID {
113+ toc .MaxSpanID += 1
114+ }
115+
87116 if tc .sectionReader != nil {
88117 r = tc .sectionReader
89118 }
90119
91120 cache := cache .NewMemoryCache ()
92121 defer cache .Close ()
93- m := New (toc , r , cache , 0 )
122+ m , err := New (toc , r , cache , 0 )
123+ if err != nil {
124+ return
125+ }
94126
95127 // Test GetContent
96128 fileContentFromSpans , err := getFileContentFromSpans (m , toc , fileName )
@@ -133,7 +165,8 @@ func TestSpanManagerCache(t *testing.T) {
133165 }
134166 cache := cache .NewMemoryCache ()
135167 defer cache .Close ()
136- m := New (toc , r , cache , 0 )
168+ m , err := New (toc , r , cache , 0 )
169+ assert .Nil (t , err )
137170 spanID := 0
138171 err = m .resolveSpan (compression .SpanID (spanID ))
139172 if err != nil {
@@ -188,7 +221,8 @@ func TestStateTransition(t *testing.T) {
188221 }
189222 cache := cache .NewMemoryCache ()
190223 defer cache .Close ()
191- m := New (toc , r , cache , 0 )
224+ m , err := New (toc , r , cache , 0 )
225+ assert .Nil (t , err )
192226
193227 // check initial span states
194228 for i := uint32 (0 ); i <= uint32 (toc .MaxSpanID ); i ++ {
@@ -347,16 +381,19 @@ func TestSpanManagerRetries(t *testing.T) {
347381 for _ , tc := range testCases {
348382 t .Run (tc .name , func (t * testing.T ) {
349383 r := testutil .NewTestRand (t )
384+ randStr := string (r .RandomByteData (10000000 ))
385+
350386 entries := []testutil.TarEntry {
351- testutil .File ("test" , string ( r . RandomByteData ( 10000000 )) ),
387+ testutil .File ("test" , randStr ),
352388 }
353389 ztoc , sr , err := ztoc .BuildZtocReader (t , entries , gzip .DefaultCompression , 100000 )
354390 if err != nil {
355391 t .Fatal (err )
356392 }
357- rdr := & retryableReaderAt { inner : sr , maxErrors : tc .readerErrors }
393+ rdr := newRetryableReaderAt ( sr , tc .readerErrors )
358394 sr = io .NewSectionReader (rdr , 0 , 10000000 )
359- sm := New (ztoc , sr , cache .NewMemoryCache (), tc .spanManagerRetries )
395+ sm , err := New (ztoc , sr , cache .NewMemoryCache (), tc .spanManagerRetries )
396+ assert .Nil (t , err )
360397
361398 for i := 0 ; i < int (ztoc .MaxSpanID ); i ++ {
362399 rdr .errCount = 0
@@ -381,14 +418,24 @@ type retryableReaderAt struct {
381418 maxErrors int
382419}
383420
421+ func newRetryableReaderAt (inner * io.SectionReader , maxErrors int ) * retryableReaderAt {
422+ return & retryableReaderAt {
423+ inner : inner ,
424+ maxErrors : maxErrors ,
425+ errCount : - 1 , // First read needs to succeed to create spanmanager
426+ }
427+ }
428+
384429func (r * retryableReaderAt ) ReadAt (buf []byte , off int64 ) (int , error ) {
385430 n , err := r .inner .ReadAt (buf , off )
386431 if (err != nil && err != io .EOF ) || n != len (buf ) {
387432 return n , err
388433 }
389434 if r .errCount < r .maxErrors {
390435 r .errCount ++
391- buf [0 ] = buf [0 ] ^ 0xff
436+ if r .errCount > 0 {
437+ buf [0 ] = buf [0 ] ^ 0xff
438+ }
392439 }
393440 return n , err
394441}
0 commit comments