zotregistry.dev/zot@v1.4.4-0.20240314164342-eec277e14d20/pkg/extensions/sync/sync_internal_test.go (about) 1 //go:build sync 2 // +build sync 3 4 package sync 5 6 import ( 7 "bytes" 8 "context" 9 "encoding/json" 10 "fmt" 11 "os" 12 "path" 13 "testing" 14 15 dockerManifest "github.com/containers/image/v5/manifest" 16 "github.com/containers/image/v5/oci/layout" 17 "github.com/containers/image/v5/types" 18 godigest "github.com/opencontainers/go-digest" 19 ispec "github.com/opencontainers/image-spec/specs-go/v1" 20 "github.com/rs/zerolog" 21 . "github.com/smartystreets/goconvey/convey" 22 23 zerr "zotregistry.dev/zot/errors" 24 "zotregistry.dev/zot/pkg/extensions/config" 25 syncconf "zotregistry.dev/zot/pkg/extensions/config/sync" 26 "zotregistry.dev/zot/pkg/extensions/lint" 27 "zotregistry.dev/zot/pkg/extensions/monitoring" 28 client "zotregistry.dev/zot/pkg/extensions/sync/httpclient" 29 "zotregistry.dev/zot/pkg/log" 30 mTypes "zotregistry.dev/zot/pkg/meta/types" 31 "zotregistry.dev/zot/pkg/storage" 32 "zotregistry.dev/zot/pkg/storage/cache" 33 storageConstants "zotregistry.dev/zot/pkg/storage/constants" 34 "zotregistry.dev/zot/pkg/storage/local" 35 . "zotregistry.dev/zot/pkg/test/image-utils" 36 "zotregistry.dev/zot/pkg/test/inject" 37 "zotregistry.dev/zot/pkg/test/mocks" 38 ociutils "zotregistry.dev/zot/pkg/test/oci-utils" 39 ) 40 41 const ( 42 testImage = "zot-test" 43 testImageTag = "0.0.1" 44 45 host = "127.0.0.1:45117" 46 ) 47 48 var ErrTestError = fmt.Errorf("testError") 49 50 func TestInjectSyncUtils(t *testing.T) { 51 Convey("Inject errors in utils functions", t, func() { 52 repositoryReference := fmt.Sprintf("%s/%s", host, testImage) 53 ref, err := parseRepositoryReference(repositoryReference) 54 So(err, ShouldBeNil) 55 So(ref.Name(), ShouldEqual, repositoryReference) 56 57 injected := inject.InjectFailure(0) 58 if injected { 59 _, err = getRepoTags(context.Background(), &types.SystemContext{}, host, testImage) 60 So(err, ShouldNotBeNil) 61 } 62 63 injected = inject.InjectFailure(0) 64 _, err = getPolicyContext(log.NewLogger("debug", "")) 65 if injected { 66 So(err, ShouldNotBeNil) 67 } else { 68 So(err, ShouldBeNil) 69 } 70 71 log := log.Logger{Logger: zerolog.New(os.Stdout)} 72 metrics := monitoring.NewMetricsServer(false, log) 73 imageStore := local.NewImageStore(t.TempDir(), false, false, log, metrics, nil, nil) 74 injected = inject.InjectFailure(0) 75 76 ols := NewOciLayoutStorage(storage.StoreController{DefaultStore: imageStore}) 77 _, err = ols.GetImageReference(testImage, testImageTag) 78 if injected { 79 So(err, ShouldNotBeNil) 80 } else { 81 So(err, ShouldBeNil) 82 } 83 }) 84 } 85 86 func TestSyncInternal(t *testing.T) { 87 Convey("Verify parseRepositoryReference func", t, func() { 88 repositoryReference := fmt.Sprintf("%s/%s", host, testImage) 89 ref, err := parseRepositoryReference(repositoryReference) 90 So(err, ShouldBeNil) 91 So(ref.Name(), ShouldEqual, repositoryReference) 92 93 repositoryReference = fmt.Sprintf("%s/%s:tagged", host, testImage) 94 _, err = parseRepositoryReference(repositoryReference) 95 So(err, ShouldEqual, zerr.ErrInvalidRepositoryName) 96 97 repositoryReference = fmt.Sprintf("http://%s/%s", host, testImage) 98 _, err = parseRepositoryReference(repositoryReference) 99 So(err, ShouldNotBeNil) 100 101 repositoryReference = fmt.Sprintf("docker://%s/%s", host, testImage) 102 _, err = parseRepositoryReference(repositoryReference) 103 So(err, ShouldNotBeNil) 104 105 _, err = getFileCredentials("/path/to/inexistent/file") 106 So(err, ShouldNotBeNil) 107 108 tempFile, err := os.CreateTemp("", "sync-credentials-") 109 if err != nil { 110 panic(err) 111 } 112 113 content := []byte(`{`) 114 if err := os.WriteFile(tempFile.Name(), content, 0o600); err != nil { 115 panic(err) 116 } 117 118 _, err = getFileCredentials(tempFile.Name()) 119 So(err, ShouldNotBeNil) 120 121 srcCtx := &types.SystemContext{} 122 _, err = getRepoTags(context.Background(), srcCtx, host, testImage) 123 So(err, ShouldNotBeNil) 124 125 _, err = getRepoTags(context.Background(), srcCtx, host, testImage) 126 So(err, ShouldNotBeNil) 127 128 _, err = getFileCredentials("/invalid/path/to/file") 129 So(err, ShouldNotBeNil) 130 131 ok := isSupportedMediaType("unknown") 132 So(ok, ShouldBeFalse) 133 }) 134 } 135 136 func TestRemoteRegistry(t *testing.T) { 137 Convey("test remote registry", t, func() { 138 logger := log.NewLogger("debug", "") 139 cfg := client.Config{ 140 URL: "url", 141 TLSVerify: false, 142 } 143 144 client, err := client.New(cfg, logger) 145 So(err, ShouldBeNil) 146 147 remote := NewRemoteRegistry(client, logger) 148 imageRef, err := layout.NewReference("dir", "image") 149 So(err, ShouldBeNil) 150 _, _, _, err = remote.GetManifestContent(imageRef) 151 So(err, ShouldNotBeNil) 152 153 tags, err := remote.GetRepoTags("repo") 154 So(tags, ShouldBeEmpty) 155 So(err, ShouldNotBeNil) 156 }) 157 } 158 159 func TestService(t *testing.T) { 160 Convey("trigger fetch tags error", t, func() { 161 conf := syncconf.RegistryConfig{ 162 URLs: []string{"http://localhost"}, 163 } 164 165 service, err := New(conf, "", os.TempDir(), storage.StoreController{}, mocks.MetaDBMock{}, log.Logger{}) 166 So(err, ShouldBeNil) 167 168 err = service.SyncRepo(context.Background(), "repo") 169 So(err, ShouldNotBeNil) 170 }) 171 } 172 173 func TestSyncRepo(t *testing.T) { 174 Convey("trigger context error", t, func() { 175 conf := syncconf.RegistryConfig{ 176 URLs: []string{"http://localhost"}, 177 } 178 179 service, err := New(conf, "", os.TempDir(), storage.StoreController{}, mocks.MetaDBMock{}, log.Logger{}) 180 So(err, ShouldBeNil) 181 182 service.remote = mocks.SyncRemote{ 183 GetRepoTagsFn: func(repo string) ([]string, error) { 184 return []string{"repo1", "repo2"}, nil 185 }, 186 } 187 188 ctx, cancel := context.WithCancel(context.Background()) 189 cancel() 190 191 err = service.SyncRepo(ctx, "repo") 192 So(err, ShouldEqual, ctx.Err()) 193 }) 194 } 195 196 func TestDestinationRegistry(t *testing.T) { 197 Convey("make StoreController", t, func() { 198 dir := t.TempDir() 199 200 log := log.NewLogger("debug", "") 201 metrics := monitoring.NewMetricsServer(false, log) 202 cacheDriver, _ := storage.Create("boltdb", cache.BoltDBDriverParameters{ 203 RootDir: dir, 204 Name: "cache", 205 UseRelPaths: true, 206 }, log) 207 208 syncImgStore := local.NewImageStore(dir, true, true, log, metrics, nil, cacheDriver) 209 repoName := "repo" 210 211 storeController := storage.StoreController{DefaultStore: syncImgStore} 212 registry := NewDestinationRegistry(storeController, storeController, nil, log) 213 imageReference, err := registry.GetImageReference(repoName, "1.0") 214 So(err, ShouldBeNil) 215 So(imageReference, ShouldNotBeNil) 216 217 imgStore := getImageStoreFromImageReference(imageReference, repoName, "1.0") 218 219 // create a blob/layer 220 upload, err := imgStore.NewBlobUpload(repoName) 221 So(err, ShouldBeNil) 222 So(upload, ShouldNotBeEmpty) 223 224 content := []byte("this is a blob1") 225 buf := bytes.NewBuffer(content) 226 buflen := buf.Len() 227 digest := godigest.FromBytes(content) 228 So(digest, ShouldNotBeNil) 229 blob, err := imgStore.PutBlobChunkStreamed(repoName, upload, buf) 230 So(err, ShouldBeNil) 231 So(blob, ShouldEqual, buflen) 232 bdgst1 := digest 233 bsize1 := len(content) 234 235 err = imgStore.FinishBlobUpload(repoName, upload, buf, digest) 236 So(err, ShouldBeNil) 237 So(blob, ShouldEqual, buflen) 238 239 // push index image 240 var index ispec.Index 241 index.SchemaVersion = 2 242 index.MediaType = ispec.MediaTypeImageIndex 243 244 for i := 0; i < 4; i++ { 245 // upload image config blob 246 upload, err := imgStore.NewBlobUpload(repoName) 247 So(err, ShouldBeNil) 248 So(upload, ShouldNotBeEmpty) 249 250 cblob, cdigest := GetRandomImageConfig() 251 buf := bytes.NewBuffer(cblob) 252 buflen := buf.Len() 253 blob, err := imgStore.PutBlobChunkStreamed(repoName, upload, buf) 254 So(err, ShouldBeNil) 255 So(blob, ShouldEqual, buflen) 256 257 err = imgStore.FinishBlobUpload(repoName, upload, buf, cdigest) 258 So(err, ShouldBeNil) 259 So(blob, ShouldEqual, buflen) 260 261 // create a manifest 262 manifest := ispec.Manifest{ 263 Config: ispec.Descriptor{ 264 MediaType: ispec.MediaTypeImageConfig, 265 Digest: cdigest, 266 Size: int64(len(cblob)), 267 }, 268 Layers: []ispec.Descriptor{ 269 { 270 MediaType: ispec.MediaTypeImageLayer, 271 Digest: bdgst1, 272 Size: int64(bsize1), 273 }, 274 }, 275 } 276 manifest.SchemaVersion = 2 277 content, err = json.Marshal(manifest) 278 So(err, ShouldBeNil) 279 digest = godigest.FromBytes(content) 280 So(digest, ShouldNotBeNil) 281 _, _, err = imgStore.PutImageManifest(repoName, digest.String(), ispec.MediaTypeImageManifest, content) 282 So(err, ShouldBeNil) 283 284 index.Manifests = append(index.Manifests, ispec.Descriptor{ 285 Digest: digest, 286 MediaType: ispec.MediaTypeImageManifest, 287 Size: int64(len(content)), 288 }) 289 } 290 291 // upload index image 292 indexContent, err := json.Marshal(index) 293 So(err, ShouldBeNil) 294 indexDigest := godigest.FromBytes(indexContent) 295 So(indexDigest, ShouldNotBeNil) 296 297 _, _, err = imgStore.PutImageManifest(repoName, "1.0", ispec.MediaTypeImageIndex, indexContent) 298 So(err, ShouldBeNil) 299 300 Convey("sync index image", func() { 301 ok, err := registry.CanSkipImage(repoName, "1.0", indexDigest) 302 So(ok, ShouldBeFalse) 303 So(err, ShouldBeNil) 304 305 err = registry.CommitImage(imageReference, repoName, "1.0") 306 So(err, ShouldBeNil) 307 }) 308 309 Convey("trigger GetImageManifest error in CommitImage()", func() { 310 err = os.Chmod(imgStore.BlobPath(repoName, indexDigest), 0o000) 311 So(err, ShouldBeNil) 312 313 err = registry.CommitImage(imageReference, repoName, "1.0") 314 So(err, ShouldNotBeNil) 315 }) 316 317 Convey("trigger linter error in CommitImage()", func() { 318 defaultVal := true 319 linter := lint.NewLinter(&config.LintConfig{ 320 BaseConfig: config.BaseConfig{ 321 Enable: &defaultVal, 322 }, 323 MandatoryAnnotations: []string{"annot1"}, 324 }, log) 325 326 syncImgStore := local.NewImageStore(dir, true, true, log, metrics, linter, cacheDriver) 327 repoName := "repo" 328 329 storeController := storage.StoreController{DefaultStore: syncImgStore} 330 registry := NewDestinationRegistry(storeController, storeController, nil, log) 331 332 err = registry.CommitImage(imageReference, repoName, "1.0") 333 So(err, ShouldBeNil) 334 }) 335 336 Convey("trigger GetBlobContent on manifest error in CommitImage()", func() { 337 err = os.Chmod(imgStore.BlobPath(repoName, digest), 0o000) 338 So(err, ShouldBeNil) 339 340 err = registry.CommitImage(imageReference, repoName, "1.0") 341 So(err, ShouldNotBeNil) 342 }) 343 344 Convey("trigger copyBlob() error in CommitImage()", func() { 345 err = os.Chmod(imgStore.BlobPath(repoName, bdgst1), 0o000) 346 So(err, ShouldBeNil) 347 348 err = registry.CommitImage(imageReference, repoName, "1.0") 349 So(err, ShouldNotBeNil) 350 }) 351 352 Convey("trigger PutImageManifest error on index manifest in CommitImage()", func() { 353 err = os.MkdirAll(syncImgStore.BlobPath(repoName, indexDigest), storageConstants.DefaultDirPerms) 354 So(err, ShouldBeNil) 355 356 err = os.Chmod(syncImgStore.BlobPath(repoName, indexDigest), 0o000) 357 So(err, ShouldBeNil) 358 359 err = registry.CommitImage(imageReference, repoName, "1.0") 360 So(err, ShouldNotBeNil) 361 }) 362 363 Convey("trigger metaDB error on index manifest in CommitImage()", func() { 364 storeController := storage.StoreController{DefaultStore: syncImgStore} 365 registry := NewDestinationRegistry(storeController, storeController, mocks.MetaDBMock{ 366 SetRepoReferenceFn: func(ctx context.Context, repo string, reference string, imageMeta mTypes.ImageMeta) error { 367 if reference == "1.0" { 368 return zerr.ErrRepoMetaNotFound 369 } 370 371 return nil 372 }, 373 }, log) 374 375 err = registry.CommitImage(imageReference, repoName, "1.0") 376 So(err, ShouldNotBeNil) 377 }) 378 379 Convey("trigger metaDB error on image manifest in CommitImage()", func() { 380 storeController := storage.StoreController{DefaultStore: syncImgStore} 381 registry := NewDestinationRegistry(storeController, storeController, mocks.MetaDBMock{ 382 SetRepoReferenceFn: func(ctx context.Context, repo, reference string, imageMeta mTypes.ImageMeta) error { 383 return zerr.ErrRepoMetaNotFound 384 }, 385 }, log) 386 387 err = registry.CommitImage(imageReference, repoName, "1.0") 388 So(err, ShouldNotBeNil) 389 }) 390 391 Convey("push image", func() { 392 imageReference, err := registry.GetImageReference(repoName, "2.0") 393 So(err, ShouldBeNil) 394 So(imageReference, ShouldNotBeNil) 395 396 imgStore := getImageStoreFromImageReference(imageReference, repoName, "2.0") 397 398 // upload image 399 400 // create a blob/layer 401 upload, err := imgStore.NewBlobUpload(repoName) 402 So(err, ShouldBeNil) 403 So(upload, ShouldNotBeEmpty) 404 405 content := []byte("this is a blob1") 406 buf := bytes.NewBuffer(content) 407 buflen := buf.Len() 408 digest := godigest.FromBytes(content) 409 So(digest, ShouldNotBeNil) 410 blob, err := imgStore.PutBlobChunkStreamed(repoName, upload, buf) 411 So(err, ShouldBeNil) 412 So(blob, ShouldEqual, buflen) 413 bdgst1 := digest 414 bsize1 := len(content) 415 416 err = imgStore.FinishBlobUpload(repoName, upload, buf, digest) 417 So(err, ShouldBeNil) 418 So(blob, ShouldEqual, buflen) 419 420 // upload image config blob 421 upload, err = imgStore.NewBlobUpload(repoName) 422 So(err, ShouldBeNil) 423 So(upload, ShouldNotBeEmpty) 424 425 cblob, cdigest := GetRandomImageConfig() 426 buf = bytes.NewBuffer(cblob) 427 buflen = buf.Len() 428 blob, err = imgStore.PutBlobChunkStreamed(repoName, upload, buf) 429 So(err, ShouldBeNil) 430 So(blob, ShouldEqual, buflen) 431 432 err = imgStore.FinishBlobUpload(repoName, upload, buf, cdigest) 433 So(err, ShouldBeNil) 434 So(blob, ShouldEqual, buflen) 435 436 // create a manifest 437 manifest := ispec.Manifest{ 438 Config: ispec.Descriptor{ 439 MediaType: ispec.MediaTypeImageConfig, 440 Digest: cdigest, 441 Size: int64(len(cblob)), 442 }, 443 Layers: []ispec.Descriptor{ 444 { 445 MediaType: ispec.MediaTypeImageLayer, 446 Digest: bdgst1, 447 Size: int64(bsize1), 448 }, 449 }, 450 } 451 manifest.SchemaVersion = 2 452 content, err = json.Marshal(manifest) 453 So(err, ShouldBeNil) 454 digest = godigest.FromBytes(content) 455 So(digest, ShouldNotBeNil) 456 457 _, _, err = imgStore.PutImageManifest(repoName, "2.0", ispec.MediaTypeImageManifest, content) 458 So(err, ShouldBeNil) 459 460 Convey("sync image", func() { 461 ok, err := registry.CanSkipImage(repoName, "2.0", digest) 462 So(ok, ShouldBeFalse) 463 So(err, ShouldBeNil) 464 465 err = registry.CommitImage(imageReference, repoName, "2.0") 466 So(err, ShouldBeNil) 467 }) 468 }) 469 }) 470 } 471 472 func TestConvertDockerToOCI(t *testing.T) { 473 Convey("test converting docker to oci functions", t, func() { 474 dir := t.TempDir() 475 476 srcStorageCtlr := ociutils.GetDefaultStoreController(dir, log.NewLogger("debug", "")) 477 478 err := WriteImageToFileSystem(CreateDefaultImage(), "zot-test", "0.0.1", srcStorageCtlr) 479 So(err, ShouldBeNil) 480 481 imageRef, err := layout.NewReference(path.Join(dir, "zot-test"), "0.0.1") 482 So(err, ShouldBeNil) 483 484 imageSource, err := imageRef.NewImageSource(context.Background(), &types.SystemContext{}) 485 So(err, ShouldBeNil) 486 487 defer imageSource.Close() 488 489 Convey("trigger Unmarshal manifest error", func() { 490 _, err = convertDockerManifestToOCI(imageSource, []byte{}) 491 So(err, ShouldNotBeNil) 492 }) 493 494 Convey("trigger getImageConfigContent() error", func() { 495 manifestBuf, _, err := imageSource.GetManifest(context.Background(), nil) 496 So(err, ShouldBeNil) 497 498 var manifest ispec.Manifest 499 500 err = json.Unmarshal(manifestBuf, &manifest) 501 So(err, ShouldBeNil) 502 503 err = os.Chmod(path.Join(dir, "zot-test", "blobs/sha256", manifest.Config.Digest.Encoded()), 0o000) 504 So(err, ShouldBeNil) 505 506 _, err = convertDockerManifestToOCI(imageSource, manifestBuf) 507 So(err, ShouldNotBeNil) 508 }) 509 510 Convey("trigger Unmarshal config error", func() { 511 manifestBuf, _, err := imageSource.GetManifest(context.Background(), nil) 512 So(err, ShouldBeNil) 513 514 var manifest ispec.Manifest 515 516 err = json.Unmarshal(manifestBuf, &manifest) 517 So(err, ShouldBeNil) 518 519 err = os.WriteFile(path.Join(dir, "zot-test", "blobs/sha256", manifest.Config.Digest.Encoded()), 520 []byte{}, storageConstants.DefaultFilePerms) 521 So(err, ShouldBeNil) 522 523 _, err = convertDockerManifestToOCI(imageSource, manifestBuf) 524 So(err, ShouldNotBeNil) 525 }) 526 527 Convey("trigger convertDockerLayersToOCI error", func() { 528 manifestBuf, _, err := imageSource.GetManifest(context.Background(), nil) 529 So(err, ShouldBeNil) 530 531 var manifest ispec.Manifest 532 533 err = json.Unmarshal(manifestBuf, &manifest) 534 So(err, ShouldBeNil) 535 536 manifestDigest := godigest.FromBytes(manifestBuf) 537 538 manifest.Layers[0].MediaType = "unknown" 539 540 newManifest, err := json.Marshal(manifest) 541 So(err, ShouldBeNil) 542 543 err = os.WriteFile(path.Join(dir, "zot-test", "blobs/sha256", manifestDigest.Encoded()), 544 newManifest, storageConstants.DefaultFilePerms) 545 So(err, ShouldBeNil) 546 547 _, err = convertDockerManifestToOCI(imageSource, manifestBuf) 548 So(err, ShouldNotBeNil) 549 }) 550 551 Convey("trigger convertDockerIndexToOCI error", func() { 552 manifestBuf, _, err := imageSource.GetManifest(context.Background(), nil) 553 So(err, ShouldBeNil) 554 555 _, err = convertDockerIndexToOCI(imageSource, manifestBuf) 556 So(err, ShouldNotBeNil) 557 558 // make zot-test image an index image 559 560 var manifest ispec.Manifest 561 562 err = json.Unmarshal(manifestBuf, &manifest) 563 So(err, ShouldBeNil) 564 565 dockerNewManifest := ispec.Manifest{ 566 MediaType: dockerManifest.DockerV2Schema2MediaType, 567 Config: manifest.Config, 568 Layers: manifest.Layers, 569 } 570 571 dockerNewManifestBuf, err := json.Marshal(dockerNewManifest) 572 So(err, ShouldBeNil) 573 574 dockerManifestDigest := godigest.FromBytes(manifestBuf) 575 576 err = os.WriteFile(path.Join(dir, "zot-test", "blobs/sha256", dockerManifestDigest.Encoded()), 577 dockerNewManifestBuf, storageConstants.DefaultFilePerms) 578 So(err, ShouldBeNil) 579 580 var index ispec.Index 581 582 index.Manifests = append(index.Manifests, ispec.Descriptor{ 583 Digest: dockerManifestDigest, 584 Size: int64(len(dockerNewManifestBuf)), 585 MediaType: dockerManifest.DockerV2Schema2MediaType, 586 }) 587 588 index.MediaType = dockerManifest.DockerV2ListMediaType 589 590 dockerIndexBuf, err := json.Marshal(index) 591 So(err, ShouldBeNil) 592 593 dockerIndexDigest := godigest.FromBytes(dockerIndexBuf) 594 595 err = os.WriteFile(path.Join(dir, "zot-test", "blobs/sha256", dockerIndexDigest.Encoded()), 596 dockerIndexBuf, storageConstants.DefaultFilePerms) 597 So(err, ShouldBeNil) 598 599 // write index.json 600 601 var indexJSON ispec.Index 602 603 indexJSONBuf, err := os.ReadFile(path.Join(dir, "zot-test", "index.json")) 604 So(err, ShouldBeNil) 605 606 err = json.Unmarshal(indexJSONBuf, &indexJSON) 607 So(err, ShouldBeNil) 608 609 indexJSON.Manifests = append(indexJSON.Manifests, ispec.Descriptor{ 610 Digest: dockerIndexDigest, 611 Size: int64(len(dockerIndexBuf)), 612 MediaType: ispec.MediaTypeImageIndex, 613 Annotations: map[string]string{ 614 ispec.AnnotationRefName: "0.0.2", 615 }, 616 }) 617 618 indexJSONBuf, err = json.Marshal(indexJSON) 619 So(err, ShouldBeNil) 620 621 err = os.WriteFile(path.Join(dir, "zot-test", "index.json"), indexJSONBuf, storageConstants.DefaultFilePerms) 622 So(err, ShouldBeNil) 623 624 imageRef, err := layout.NewReference(path.Join(dir, "zot-test"), "0.0.2") 625 So(err, ShouldBeNil) 626 627 imageSource, err := imageRef.NewImageSource(context.Background(), &types.SystemContext{}) 628 So(err, ShouldBeNil) 629 630 _, err = convertDockerIndexToOCI(imageSource, dockerIndexBuf) 631 So(err, ShouldNotBeNil) 632 633 err = os.Chmod(path.Join(dir, "zot-test", "blobs/sha256", dockerManifestDigest.Encoded()), 0o000) 634 So(err, ShouldBeNil) 635 636 _, err = convertDockerIndexToOCI(imageSource, dockerIndexBuf) 637 So(err, ShouldNotBeNil) 638 }) 639 }) 640 } 641 642 func TestConvertDockerLayersToOCI(t *testing.T) { 643 Convey("test converting docker to oci functions", t, func() { 644 dockerLayers := []ispec.Descriptor{ 645 { 646 MediaType: dockerManifest.DockerV2Schema2ForeignLayerMediaType, 647 }, 648 { 649 MediaType: dockerManifest.DockerV2Schema2ForeignLayerMediaTypeGzip, 650 }, 651 { 652 MediaType: dockerManifest.DockerV2SchemaLayerMediaTypeUncompressed, 653 }, 654 { 655 MediaType: dockerManifest.DockerV2Schema2LayerMediaType, 656 }, 657 } 658 659 err := convertDockerLayersToOCI(dockerLayers) 660 So(err, ShouldBeNil) 661 662 So(dockerLayers[0].MediaType, ShouldEqual, ispec.MediaTypeImageLayerNonDistributable) //nolint: staticcheck 663 So(dockerLayers[1].MediaType, ShouldEqual, ispec.MediaTypeImageLayerNonDistributableGzip) //nolint: staticcheck 664 So(dockerLayers[2].MediaType, ShouldEqual, ispec.MediaTypeImageLayer) 665 So(dockerLayers[3].MediaType, ShouldEqual, ispec.MediaTypeImageLayerGzip) 666 }) 667 }