@@ -20,15 +20,20 @@ package root
20
20
import (
21
21
"bytes"
22
22
"context"
23
+ "encoding/json"
23
24
"fmt"
25
+ "io"
24
26
"net/http"
25
27
"net/http/httptest"
26
28
"net/url"
27
29
"os"
30
+ "strings"
28
31
"testing"
29
32
30
33
"github.com/opencontainers/go-digest"
31
34
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
35
+ "oras.land/oras-go/v2"
36
+ "oras.land/oras-go/v2/content"
32
37
"oras.land/oras-go/v2/content/memory"
33
38
"oras.land/oras-go/v2/registry/remote"
34
39
"oras.land/oras/cmd/oras/internal/display/status"
@@ -197,3 +202,143 @@ func Test_doCopy_mounted(t *testing.T) {
197
202
t .Fatal (err )
198
203
}
199
204
}
205
+
206
+ func Test_prepareCopyOption_nonIndex (t * testing.T ) {
207
+ ctx := context .Background ()
208
+ root := ocispec.Descriptor {
209
+ MediaType : ocispec .MediaTypeImageManifest ,
210
+ }
211
+ if _ , err := prepareCopyOption (ctx , nil , nil , root , oras.ExtendedCopyOptions {}); err != nil {
212
+ t .Errorf ("prepareCopyOption() error = %v, wantErr false" , err )
213
+ }
214
+ }
215
+
216
+ var errMockedFetch = fmt .Errorf ("fetch error" )
217
+
218
+ // fetchFailingReadOnlyGraphTarget is a mock implementation of oras.ReadOnlyGraphTarget
219
+ type fetchFailingReadOnlyGraphTarget struct {
220
+ oras.ReadOnlyGraphTarget
221
+ }
222
+
223
+ // Fetch simulates a failure when fetching content from the source.
224
+ func (m * fetchFailingReadOnlyGraphTarget ) Fetch (ctx context.Context , target ocispec.Descriptor ) (io.ReadCloser , error ) {
225
+ return nil , errMockedFetch
226
+ }
227
+
228
+ func Test_prepareCopyOption_fetchFailure (t * testing.T ) {
229
+ ctx := context .Background ()
230
+ src := & fetchFailingReadOnlyGraphTarget {}
231
+ dst := memory .New ()
232
+ root := ocispec.Descriptor {
233
+ MediaType : ocispec .MediaTypeImageIndex ,
234
+ Digest : digest .FromString ("nonexistent" ),
235
+ Size : int64 (len ("nonexistent" )),
236
+ }
237
+
238
+ if _ , err := prepareCopyOption (ctx , src , dst , root , oras.ExtendedCopyOptions {}); err != errMockedFetch {
239
+ t .Errorf ("prepareCopyOption() error = %v, want %v" , err , errMockedFetch )
240
+ }
241
+ }
242
+
243
+ func Test_recursiveCopy_prepareCopyOptionFailure (t * testing.T ) {
244
+ ctx := context .Background ()
245
+ src := & fetchFailingReadOnlyGraphTarget {}
246
+ dst := memory .New ()
247
+ root := ocispec.Descriptor {
248
+ MediaType : ocispec .MediaTypeImageIndex ,
249
+ Digest : digest .FromString ("nonexistent" ),
250
+ Size : int64 (len ("nonexistent" )),
251
+ }
252
+
253
+ if _ , err := prepareCopyOption (ctx , src , dst , root , oras.ExtendedCopyOptions {}); err != errMockedFetch {
254
+ t .Errorf ("prepareCopyOption() error = %v, want %v" , err , errMockedFetch )
255
+ }
256
+ }
257
+
258
+ // invalidJSONReadOnlyGraphTarget is a mock implementation of oras.ReadOnlyGraphTarget
259
+ // that returns invalid JSON data to simulate a JSON unmarshalling failure.
260
+ type invalidJSONReadOnlyGraphTarget struct {
261
+ oras.ReadOnlyGraphTarget
262
+ }
263
+
264
+ // Fetch simulates a successful fetch of invalid JSON data.
265
+ func (m * invalidJSONReadOnlyGraphTarget ) Fetch (ctx context.Context , target ocispec.Descriptor ) (io.ReadCloser , error ) {
266
+ // Return invalid JSON data
267
+ return io .NopCloser (strings .NewReader ("invalid-json" )), nil
268
+ }
269
+
270
+ func Test_prepareCopyOption_jsonUnmarshalFailure (t * testing.T ) {
271
+ ctx := context .Background ()
272
+ src := & invalidJSONReadOnlyGraphTarget {}
273
+ dst := memory .New ()
274
+ root := ocispec.Descriptor {
275
+ MediaType : ocispec .MediaTypeImageIndex ,
276
+ Digest : digest .FromString ("invalid-json" ),
277
+ Size : int64 (len ("invalid-json" )),
278
+ }
279
+ _ , err := prepareCopyOption (ctx , src , dst , root , oras.ExtendedCopyOptions {})
280
+ if _ , ok := err .(* json.SyntaxError ); ! ok {
281
+ t .Errorf ("prepareCopyOption() error = %v, want json.SyntaxError" , err )
282
+ }
283
+ }
284
+
285
+ // mockReferrersFailingSource is a mock implementation of oras.ReadOnlyGraphTarget
286
+ // that simulates a failure when fetching referrers.
287
+ type mockReferrersFailingSource struct {
288
+ oras.ReadOnlyGraphTarget
289
+ indexContent string
290
+ }
291
+
292
+ // Fetch simulates successful fetching of index content.
293
+ func (m * mockReferrersFailingSource ) Fetch (ctx context.Context , target ocispec.Descriptor ) (io.ReadCloser , error ) {
294
+ // Return valid JSON data to pass the fetch step
295
+ return io .NopCloser (strings .NewReader (m .indexContent )), nil
296
+ }
297
+
298
+ func Test_prepareCopyOption_referrersFailure (t * testing.T ) {
299
+
300
+ ctx := context .Background ()
301
+ mockedIndex := `{"schemaVersion":2,"manifests":[{"mediaType":"application/vnd.oci.image.manifest.v1+json","digest":"sha256:44136fa355b3678a1146ad16f7e8649e94fb4fc21fe77e8310c060f61caaff8a","size":2}]}`
302
+ src := & mockReferrersFailingSource {indexContent : mockedIndex }
303
+ dst := memory .New ()
304
+ root := ocispec.Descriptor {
305
+ MediaType : ocispec .MediaTypeImageIndex ,
306
+ Digest : digest .FromString (mockedIndex ),
307
+ Size : int64 (len (mockedIndex )),
308
+ }
309
+ errMockedReferrers := fmt .Errorf ("failed to get referrers" )
310
+ opts := oras.ExtendedCopyOptions {
311
+ ExtendedCopyGraphOptions : oras.ExtendedCopyGraphOptions {
312
+ FindPredecessors : func (ctx context.Context , src content.ReadOnlyGraphStorage , desc ocispec.Descriptor ) ([]ocispec.Descriptor , error ) {
313
+ return nil , errMockedReferrers
314
+ },
315
+ },
316
+ }
317
+
318
+ if _ , err := prepareCopyOption (ctx , src , dst , root , opts ); err != errMockedReferrers {
319
+ t .Errorf ("prepareCopyOption() error = %v, wantErr %v" , err , errMockedReferrers )
320
+ }
321
+ }
322
+
323
+ func Test_prepareCopyOption_noReferrers (t * testing.T ) {
324
+ ctx := context .Background ()
325
+ mockedIndex := `{"schemaVersion":2,"manifests":[{"mediaType":"application/vnd.oci.image.manifest.v1+json","digest":"sha256:44136fa355b3678a1146ad16f7e8649e94fb4fc21fe77e8310c060f61caaff8a","size":2}]}`
326
+ src := & mockReferrersFailingSource {indexContent : mockedIndex }
327
+ dst := memory .New ()
328
+ root := ocispec.Descriptor {
329
+ MediaType : ocispec .MediaTypeImageIndex ,
330
+ Digest : digest .FromString (mockedIndex ),
331
+ Size : int64 (len (mockedIndex )),
332
+ }
333
+ opts := oras.ExtendedCopyOptions {
334
+ ExtendedCopyGraphOptions : oras.ExtendedCopyGraphOptions {
335
+ FindPredecessors : func (ctx context.Context , src content.ReadOnlyGraphStorage , desc ocispec.Descriptor ) ([]ocispec.Descriptor , error ) {
336
+ return nil , nil
337
+ },
338
+ },
339
+ }
340
+
341
+ if _ , err := prepareCopyOption (ctx , src , dst , root , opts ); err != nil {
342
+ t .Errorf ("prepareCopyOption() error = %v, wantErr false" , err )
343
+ }
344
+ }
0 commit comments