From 38409ccc0699849e3fe9864a31d1f47a921b64c9 Mon Sep 17 00:00:00 2001 From: Billy Zha Date: Mon, 13 Mar 2023 01:26:34 +0000 Subject: [PATCH] test(e2e): add OCI layout specs for `oras cp` Signed-off-by: Billy Zha --- .../e2e/internal/testdata/multi_arch/const.go | 16 +- test/e2e/suite/command/cp.go | 406 ++++++++++-------- test/e2e/suite/command/pull.go | 2 +- 3 files changed, 236 insertions(+), 188 deletions(-) diff --git a/test/e2e/internal/testdata/multi_arch/const.go b/test/e2e/internal/testdata/multi_arch/const.go index 34d5cfb2f..799f897fb 100644 --- a/test/e2e/internal/testdata/multi_arch/const.go +++ b/test/e2e/internal/testdata/multi_arch/const.go @@ -22,12 +22,14 @@ import ( ) var ( - Tag = "multi" - Digest = "sha256:e2bfc9cc6a84ec2d7365b5a28c6bc5806b7fa581c9ad7883be955a64e3cc034f" - Manifest = `{"mediaType":"application/vnd.oci.image.index.v1+json","schemaVersion":2,"manifests":[{"mediaType":"application/vnd.oci.image.manifest.v1+json","digest":"sha256:9d84a5716c66a1d1b9c13f8ed157ba7d1edfe7f9b8766728b8a1f25c0d9c14c1","size":458,"platform":{"architecture":"amd64","os":"linux"}},{"mediaType":"application/vnd.oci.image.manifest.v1+json","digest":"sha256:4f93460061882467e6fb3b772dc6ab72130d9ac1906aed2fc7589a5cd145433c","size":458,"platform":{"architecture":"arm64","os":"linux"}},{"mediaType":"application/vnd.oci.image.manifest.v1+json","digest":"sha256:58efe73e78fe043ca31b89007a025c594ce12aa7e6da27d21c7b14b50112e255","size":458,"platform":{"architecture":"arm","os":"linux","variant":"v7"}}]}` - Descriptor = `{"mediaType":"application/vnd.oci.image.index.v1+json","digest":"sha256:e2bfc9cc6a84ec2d7365b5a28c6bc5806b7fa581c9ad7883be955a64e3cc034f","size":706}` - IndexReferrerDigest = "sha256:d3cf790759b006e1a2aeee52f9b1ee250bb848fce7e873b992b86bf9408f12d0" - IndexStateKeys = []match.StateKey{ + Tag = "multi" + Digest = "sha256:e2bfc9cc6a84ec2d7365b5a28c6bc5806b7fa581c9ad7883be955a64e3cc034f" + Manifest = `{"mediaType":"application/vnd.oci.image.index.v1+json","schemaVersion":2,"manifests":[{"mediaType":"application/vnd.oci.image.manifest.v1+json","digest":"sha256:9d84a5716c66a1d1b9c13f8ed157ba7d1edfe7f9b8766728b8a1f25c0d9c14c1","size":458,"platform":{"architecture":"amd64","os":"linux"}},{"mediaType":"application/vnd.oci.image.manifest.v1+json","digest":"sha256:4f93460061882467e6fb3b772dc6ab72130d9ac1906aed2fc7589a5cd145433c","size":458,"platform":{"architecture":"arm64","os":"linux"}},{"mediaType":"application/vnd.oci.image.manifest.v1+json","digest":"sha256:58efe73e78fe043ca31b89007a025c594ce12aa7e6da27d21c7b14b50112e255","size":458,"platform":{"architecture":"arm","os":"linux","variant":"v7"}}]}` + Descriptor = `{"mediaType":"application/vnd.oci.image.index.v1+json","digest":"sha256:e2bfc9cc6a84ec2d7365b5a28c6bc5806b7fa581c9ad7883be955a64e3cc034f","size":706}` + IndexReferrerDigest = "sha256:d3cf790759b006e1a2aeee52f9b1ee250bb848fce7e873b992b86bf9408f12d0" + IndexReferrerStateKey = match.StateKey{Digest: "d3cf790759b0", Name: "application/vnd.oci.image.manifest.v1+json"} + IndexReferrerConfigStateKey = match.StateKey{Digest: "44136fa355b3", Name: "referrer.index"} + IndexStateKeys = []match.StateKey{ {Digest: "2ef548696ac7", Name: "hello.tar"}, {Digest: "fe9dbc99451d", Name: "application/vnd.oci.image.config.v1+json"}, {Digest: "9d84a5716c66", Name: "application/vnd.oci.image.manifest.v1+json"}, @@ -59,7 +61,7 @@ var ( LayerName = "hello.tar" LinuxAMD64ReferrerStateKey = match.StateKey{Digest: "57e6462826c8", Name: "application/vnd.oci.image.manifest.v1+json"} LinuxAMD64ReferrerConfigStateKey = match.StateKey{Digest: "44136fa355b3", Name: "referrer.image"} - ImageStateKeys = []match.StateKey{ + LinuxAMD64StateKeys = []match.StateKey{ {Digest: "9d84a5716c66", Name: ocispec.MediaTypeImageManifest}, {Digest: "fe9dbc99451d", Name: ocispec.MediaTypeImageConfig}, {Digest: "2ef548696ac7", Name: "hello.tar"}, diff --git a/test/e2e/suite/command/cp.go b/test/e2e/suite/command/cp.go index 97d7bf2a2..4b49187fa 100644 --- a/test/e2e/suite/command/cp.go +++ b/test/e2e/suite/command/cp.go @@ -63,14 +63,13 @@ var _ = Describe("ORAS beginners:", func() { var foobarStates = append(foobar.ImageLayerStateKeys, foobar.ManifestStateKey, foobar.ImageConfigStateKey(oras.MediaTypeUnknownConfig)) func CompareRef(src, dst string) { - srcManifest := ORAS("manifest", "fetch", src).WithDescription("fetch from source for validation").Exec().Out.Contents() - dstManifest := ORAS("manifest", "fetch", dst).WithDescription("fetch from destination for validation").Exec().Out.Contents() + srcManifest := ORAS("manifest", "fetch", src).WithDescription("fetch from source to validate").Exec().Out.Contents() + dstManifest := ORAS("manifest", "fetch", dst).WithDescription("fetch from destination to validate").Exec().Out.Contents() Expect(srcManifest).To(Equal(dstManifest)) } var _ = Describe("Common registry users:", func() { When("running `cp`", func() { - It("should copy an image to a new repository via tag", func() { src := RegistryRef(Host, ImageRepo, foobar.Tag) dst := RegistryRef(Host, cpTestRepo("tag"), "copiedTag") @@ -101,11 +100,12 @@ var _ = Describe("Common registry users:", func() { }) It("should copy a multi-arch image and its referrers to a new repository via tag", func() { + stateKeys := append(ma.IndexStateKeys, ma.IndexReferrerStateKey, ma.IndexReferrerConfigStateKey) src := RegistryRef(Host, ArtifactRepo, ma.Tag) dstRepo := cpTestRepo("index-referrers") dst := RegistryRef(Host, dstRepo, "copiedTag") ORAS("cp", src, dst, "-r", "-v"). - MatchStatus(ma.IndexStateKeys, true, len(ma.IndexStateKeys)). + MatchStatus(stateKeys, true, len(stateKeys)). MatchKeyWords("Digest: " + ma.Digest). Exec() // validate @@ -125,11 +125,12 @@ var _ = Describe("Common registry users:", func() { }) It("should copy a multi-arch image and its referrers to a new repository via digest", func() { + stateKeys := append(ma.IndexStateKeys, ma.IndexReferrerStateKey, ma.IndexReferrerConfigStateKey) src := RegistryRef(Host, ArtifactRepo, ma.Tag) dstRepo := cpTestRepo("index-referrers-digest") dst := RegistryRef(Host, dstRepo, ma.Digest) ORAS("cp", src, dst, "-r", "-v"). - MatchStatus(ma.IndexStateKeys, true, len(ma.IndexStateKeys)). + MatchStatus(stateKeys, true, len(stateKeys)). MatchKeyWords("Digest: " + ma.Digest). Exec() // validate @@ -153,7 +154,7 @@ var _ = Describe("Common registry users:", func() { dst := RegistryRef(Host, cpTestRepo("platform-tag"), "copiedTag") ORAS("cp", src, dst, "--platform", "linux/amd64", "-v"). - MatchStatus(ma.IndexStateKeys, true, len(ma.IndexStateKeys)). + MatchStatus(ma.LinuxAMD64StateKeys, true, len(ma.LinuxAMD64StateKeys)). MatchKeyWords("Digest: " + ma.LinuxAMD64.Digest.String()). Exec() CompareRef(RegistryRef(Host, ImageRepo, ma.LinuxAMD64.Digest.String()), dst) @@ -164,18 +165,19 @@ var _ = Describe("Common registry users:", func() { dstRepo := cpTestRepo("platform-digest") dst := RegistryRef(Host, dstRepo, "") ORAS("cp", src, dst, "--platform", "linux/amd64", "-v"). - MatchStatus(ma.IndexStateKeys, true, len(ma.IndexStateKeys)). + MatchStatus(ma.LinuxAMD64StateKeys, true, len(ma.LinuxAMD64StateKeys)). MatchKeyWords("Digest: " + ma.LinuxAMD64.Digest.String()). Exec() CompareRef(RegistryRef(Host, ImageRepo, ma.LinuxAMD64.Digest.String()), RegistryRef(Host, dstRepo, ma.LinuxAMD64.Digest.String())) }) It("should copy a certain platform of image and its referrers to a new repository with tag", func() { + stateKeys := append(ma.LinuxAMD64StateKeys, ma.LinuxAMD64ReferrerStateKey, ma.LinuxAMD64ReferrerConfigStateKey) src := RegistryRef(Host, ArtifactRepo, ma.Tag) dstRepo := cpTestRepo("platform-referrers") dst := RegistryRef(Host, dstRepo, "copiedTag") ORAS("cp", src, dst, "-r", "--platform", "linux/amd64", "-v"). - MatchStatus(ma.IndexStateKeys, true, len(ma.IndexStateKeys)). + MatchStatus(stateKeys, true, len(stateKeys)). MatchKeyWords("Digest: " + ma.LinuxAMD64.Digest.String()). Exec() // validate @@ -199,10 +201,11 @@ var _ = Describe("Common registry users:", func() { }) It("should copy a certain platform of image and its referrers to a new repository without tagging", func() { + stateKeys := append(ma.LinuxAMD64StateKeys, ma.LinuxAMD64ReferrerStateKey, ma.LinuxAMD64ReferrerConfigStateKey) src := RegistryRef(Host, ArtifactRepo, ma.Tag) dstRepo := cpTestRepo("platform-referrers-no-tag") ORAS("cp", src, RegistryRef(Host, dstRepo, ""), "-r", "--platform", "linux/amd64", "-v"). - MatchStatus(ma.IndexStateKeys, true, len(ma.IndexStateKeys)). + MatchStatus(stateKeys, true, len(stateKeys)). MatchKeyWords("Digest: " + ma.LinuxAMD64.Digest.String()). Exec() // validate @@ -262,6 +265,59 @@ var _ = Describe("OCI spec 1.0 registry users:", func() { ORAS("discover", "-o", "tree", RegistryRef(Host, repo, foobar.Digest)). WithDescription("discover referrer via subject").MatchKeyWords(foobar.FallbackSignatureImageReferrer.Digest.String(), foobar.FallbackSBOMImageReferrer.Digest.String()).Exec() }) + + It("should copy an image from a fallback registry to an OCI image layout via digest", func() { + dstDir := GinkgoT().TempDir() + src := RegistryRef(FallbackHost, ArtifactRepo, foobar.Tag) + ORAS("cp", src, dstDir, "-v", Flags.ToLayout).MatchStatus(foobarStates, true, len(foobarStates)).Exec() + // validate + srcManifest := ORAS("manifest", "fetch", src).WithDescription("fetch from source to validate").Exec().Out.Contents() + dstManifest := ORAS("manifest", "fetch", LayoutRef(dstDir, foobar.Digest), Flags.Layout).WithDescription("fetch from destination to validate").Exec().Out.Contents() + Expect(srcManifest).To(Equal(dstManifest)) + }) + + It("should copy an image from an OCI image layout to a fallback registry via digest", func() { + layoutDir := GinkgoT().TempDir() + src := LayoutRef(layoutDir, foobar.Digest) + dst := RegistryRef(FallbackHost, cpTestRepo("from-layout-digest"), "copied") + // prepare + ORAS("cp", RegistryRef(FallbackHost, ArtifactRepo, foobar.Tag), layoutDir, Flags.ToLayout).Exec() + // test + ORAS("cp", src, dst, "-v", Flags.FromLayout).MatchStatus(foobarStates, true, len(foobarStates)).Exec() + // validate + srcManifest := ORAS("manifest", "fetch", src, Flags.Layout).WithDescription("fetch from source to validate").Exec().Out.Contents() + dstManifest := ORAS("manifest", "fetch", dst).WithDescription("fetch from destination to validate").Exec().Out.Contents() + Expect(srcManifest).To(Equal(dstManifest)) + }) + + It("should copy a certain platform of image and its referrers from an OCI image layout to a fallback registry", func() { + stateKeys := append(ma.LinuxAMD64StateKeys, ma.LinuxAMD64ReferrerStateKey, ma.LinuxAMD64ReferrerConfigStateKey) + fromDir := GinkgoT().TempDir() + src := LayoutRef(fromDir, ma.Tag) + dstRepo := cpTestRepo("platform-referrer-from-layout") + dst := RegistryRef(FallbackHost, dstRepo, "copied") + // prepare + ORAS("cp", RegistryRef(Host, ArtifactRepo, ma.Tag), src, Flags.ToLayout, "-r").Exec() + ORAS("cp", RegistryRef(Host, ArtifactRepo, ma.Tag), src, Flags.ToLayout, "-r", "--platform", "linux/amd64").Exec() + // test + ORAS("cp", src, Flags.FromLayout, dst, "-r", "-v", "--platform", "linux/amd64"). + MatchStatus(stateKeys, true, len(stateKeys)). + MatchKeyWords("Digest: " + ma.LinuxAMD64.Digest.String()). + Exec() + // validate + srcManifest := ORAS("manifest", "fetch", src, Flags.Layout, "--platform", "linux/amd64").WithDescription("fetch from source to validate").Exec().Out.Contents() + dstManifest := ORAS("manifest", "fetch", dst).WithDescription("fetch from destination to validate").Exec().Out.Contents() + Expect(srcManifest).To(Equal(dstManifest)) + ORAS("manifest", "fetch", RegistryRef(FallbackHost, dstRepo, ma.Digest)).WithDescription("not copy index").ExpectFailure().Exec() + var index ocispec.Index + bytes := ORAS("discover", dst, "-o", "json"). + MatchKeyWords(ma.LinuxAMD64Referrer.Digest.String()). + WithDescription("copy image referrer"). + Exec().Out.Contents() + Expect(json.Unmarshal(bytes, &index)).ShouldNot(HaveOccurred()) + Expect(len(index.Manifests)).To(Equal(1)) + Expect(index.Manifests[0].Digest.String()).To(Equal(ma.LinuxAMD64Referrer.Digest.String())) + }) }) }) @@ -272,8 +328,8 @@ var _ = Describe("OCI layout users:", func() { src := RegistryRef(Host, ImageRepo, foobar.Tag) ORAS("cp", src, dst, "-v", Flags.ToLayout).MatchStatus(foobarStates, true, len(foobarStates)).Exec() // validate - srcManifest := ORAS("manifest", "fetch", src).WithDescription("fetch from source for validation").Exec().Out.Contents() - dstManifest := ORAS("manifest", "fetch", dst, Flags.Layout).WithDescription("fetch from destination for validation").Exec().Out.Contents() + srcManifest := ORAS("manifest", "fetch", src).WithDescription("fetch from source to validate").Exec().Out.Contents() + dstManifest := ORAS("manifest", "fetch", dst, Flags.Layout).WithDescription("fetch from destination to validate").Exec().Out.Contents() Expect(srcManifest).To(Equal(dstManifest)) }) @@ -286,8 +342,8 @@ var _ = Describe("OCI layout users:", func() { // test ORAS("cp", src, dst, "-v", Flags.FromLayout).MatchStatus(foobarStates, true, len(foobarStates)).Exec() // validate - srcManifest := ORAS("manifest", "fetch", src, Flags.Layout).WithDescription("fetch from source for validation").Exec().Out.Contents() - dstManifest := ORAS("manifest", "fetch", dst).WithDescription("fetch from destination for validation").Exec().Out.Contents() + srcManifest := ORAS("manifest", "fetch", src, Flags.Layout).WithDescription("fetch from source to validate").Exec().Out.Contents() + dstManifest := ORAS("manifest", "fetch", dst).WithDescription("fetch from destination to validate").Exec().Out.Contents() Expect(srcManifest).To(Equal(dstManifest)) }) @@ -301,8 +357,8 @@ var _ = Describe("OCI layout users:", func() { // test ORAS("cp", src, dst, "-v", Flags.FromLayout, Flags.ToLayout).MatchStatus(foobarStates, true, len(foobarStates)).Exec() // validate - srcManifest := ORAS("manifest", "fetch", src, Flags.Layout).WithDescription("fetch from source for validation").Exec().Out.Contents() - dstManifest := ORAS("manifest", "fetch", dst, Flags.Layout).WithDescription("fetch from destination for validation").Exec().Out.Contents() + srcManifest := ORAS("manifest", "fetch", src, Flags.Layout).WithDescription("fetch from source to validate").Exec().Out.Contents() + dstManifest := ORAS("manifest", "fetch", dst, Flags.Layout).WithDescription("fetch from destination to validate").Exec().Out.Contents() Expect(srcManifest).To(Equal(dstManifest)) }) @@ -311,8 +367,8 @@ var _ = Describe("OCI layout users:", func() { src := RegistryRef(Host, ImageRepo, foobar.Tag) ORAS("cp", src, dstDir, "-v", Flags.ToLayout).MatchStatus(foobarStates, true, len(foobarStates)).Exec() // validate - srcManifest := ORAS("manifest", "fetch", src).WithDescription("fetch from source for validation").Exec().Out.Contents() - dstManifest := ORAS("manifest", "fetch", LayoutRef(dstDir, foobar.Digest), Flags.Layout).WithDescription("fetch from destination for validation").Exec().Out.Contents() + srcManifest := ORAS("manifest", "fetch", src).WithDescription("fetch from source to validate").Exec().Out.Contents() + dstManifest := ORAS("manifest", "fetch", LayoutRef(dstDir, foobar.Digest), Flags.Layout).WithDescription("fetch from destination to validate").Exec().Out.Contents() Expect(srcManifest).To(Equal(dstManifest)) }) @@ -325,8 +381,8 @@ var _ = Describe("OCI layout users:", func() { // test ORAS("cp", src, dst, "-v", Flags.FromLayout).MatchStatus(foobarStates, true, len(foobarStates)).Exec() // validate - srcManifest := ORAS("manifest", "fetch", src, Flags.Layout).WithDescription("fetch from source for validation").Exec().Out.Contents() - dstManifest := ORAS("manifest", "fetch", dst).WithDescription("fetch from destination for validation").Exec().Out.Contents() + srcManifest := ORAS("manifest", "fetch", src, Flags.Layout).WithDescription("fetch from source to validate").Exec().Out.Contents() + dstManifest := ORAS("manifest", "fetch", dst).WithDescription("fetch from destination to validate").Exec().Out.Contents() Expect(srcManifest).To(Equal(dstManifest)) }) @@ -340,169 +396,159 @@ var _ = Describe("OCI layout users:", func() { // test ORAS("cp", src, toDir, "-v", Flags.FromLayout, Flags.ToLayout).MatchStatus(foobarStates, true, len(foobarStates)).Exec() // validate - srcManifest := ORAS("manifest", "fetch", src, Flags.Layout).WithDescription("fetch from source for validation").Exec().Out.Contents() - dstManifest := ORAS("manifest", "fetch", dst, Flags.Layout).WithDescription("fetch from destination for validation").Exec().Out.Contents() + srcManifest := ORAS("manifest", "fetch", src, Flags.Layout).WithDescription("fetch from source to validate").Exec().Out.Contents() + dstManifest := ORAS("manifest", "fetch", dst, Flags.Layout).WithDescription("fetch from destination to validate").Exec().Out.Contents() Expect(srcManifest).To(Equal(dstManifest)) }) - // It("should copy an image to a new repository via digest", func() { - // src := RegistryRef(Host, ImageRepo, foobar.Digest) - // dst := RegistryRef(Host, cpTestRepo("digest"), "copiedTag") - // ORAS("cp", src, dst, "-v").MatchStatus(foobarStates, true, len(foobarStates)).Exec() - // CompareRef(src, dst) - // }) - - // It("should copy an image to a new repository via tag without tagging", func() { - // src := RegistryRef(Host, ImageRepo, foobar.Tag) - // dst := RegistryRef(Host, cpTestRepo("no-tagging"), foobar.Digest) - // ORAS("cp", src, dst, "-v").MatchStatus(foobarStates, true, len(foobarStates)).Exec() - // CompareRef(src, dst) - // }) - - // It("should copy an image and its referrers to a new repository", func() { - // stateKeys := append(append(foobarStates, foobar.ArtifactReferrerStateKeys...), foobar.ImageReferrerConfigStateKeys...) - // src := RegistryRef(Host, ArtifactRepo, foobar.Tag) - // dst := RegistryRef(Host, cpTestRepo("referrers"), foobar.Digest) - // ORAS("cp", "-r", src, dst, "-v").MatchStatus(stateKeys, true, len(stateKeys)).Exec() - // CompareRef(src, dst) - // }) - - // It("should copy a multi-arch image and its referrers to a new repository via tag", func() { - // src := RegistryRef(Host, ArtifactRepo, ma.Tag) - // dstRepo := cpTestRepo("index-referrers") - // dst := RegistryRef(Host, dstRepo, "copiedTag") - // ORAS("cp", src, dst, "-r", "-v"). - // MatchStatus(ma.IndexStateKeys, true, len(ma.IndexStateKeys)). - // MatchKeyWords("Digest: " + ma.Digest). - // Exec() - // // validate - // CompareRef(RegistryRef(Host, ImageRepo, ma.Digest), dst) - // var index ocispec.Index - // bytes := ORAS("discover", dst, "-o", "json"). - // MatchKeyWords(ma.IndexReferrerDigest). - // WithDescription("copy image referrer"). - // Exec().Out.Contents() - // Expect(json.Unmarshal(bytes, &index)).ShouldNot(HaveOccurred()) - // Expect(len(index.Manifests)).To(Equal(1)) - // Expect(index.Manifests[0].Digest.String()).To(Equal(ma.IndexReferrerDigest)) - // ORAS("manifest", "fetch", RegistryRef(Host, dstRepo, ma.LinuxAMD64Referrer.Digest.String())). - // WithDescription("not copy referrer of successor"). - // ExpectFailure(). - // Exec() - // }) - - // It("should copy a multi-arch image and its referrers to a new repository via digest", func() { - // src := RegistryRef(Host, ArtifactRepo, ma.Tag) - // dstRepo := cpTestRepo("index-referrers-digest") - // dst := RegistryRef(Host, dstRepo, ma.Digest) - // ORAS("cp", src, dst, "-r", "-v"). - // MatchStatus(ma.IndexStateKeys, true, len(ma.IndexStateKeys)). - // MatchKeyWords("Digest: " + ma.Digest). - // Exec() - // // validate - // CompareRef(RegistryRef(Host, ImageRepo, ma.Digest), dst) - // var index ocispec.Index - // bytes := ORAS("discover", dst, "-o", "json"). - // MatchKeyWords(ma.IndexReferrerDigest). - // WithDescription("copy image referrer"). - // Exec().Out.Contents() - // Expect(json.Unmarshal(bytes, &index)).ShouldNot(HaveOccurred()) - // Expect(len(index.Manifests)).To(Equal(1)) - // Expect(index.Manifests[0].Digest.String()).To(Equal(ma.IndexReferrerDigest)) - // ORAS("manifest", "fetch", RegistryRef(Host, dstRepo, ma.LinuxAMD64Referrer.Digest.String())). - // WithDescription("not copy referrer of successor"). - // ExpectFailure(). - // Exec() - // }) - - // It("should copy a certain platform of image to a new repository via tag", func() { - // src := RegistryRef(Host, ImageRepo, ma.Tag) - // dst := RegistryRef(Host, cpTestRepo("platform-tag"), "copiedTag") - - // ORAS("cp", src, dst, "--platform", "linux/amd64", "-v"). - // MatchStatus(ma.IndexStateKeys, true, len(ma.IndexStateKeys)). - // MatchKeyWords("Digest: " + ma.LinuxAMD64.Digest.String()). - // Exec() - // CompareRef(RegistryRef(Host, ImageRepo, ma.LinuxAMD64.Digest.String()), dst) - // }) - - // It("should copy a certain platform of image to a new repository via digest", func() { - // src := RegistryRef(Host, ImageRepo, ma.Digest) - // dstRepo := cpTestRepo("platform-digest") - // dst := RegistryRef(Host, dstRepo, "") - // ORAS("cp", src, dst, "--platform", "linux/amd64", "-v"). - // MatchStatus(ma.IndexStateKeys, true, len(ma.IndexStateKeys)). - // MatchKeyWords("Digest: " + ma.LinuxAMD64.Digest.String()). - // Exec() - // CompareRef(RegistryRef(Host, ImageRepo, ma.LinuxAMD64.Digest.String()), RegistryRef(Host, dstRepo, ma.LinuxAMD64.Digest.String())) - // }) - - // It("should copy a certain platform of image and its referrers to a new repository with tag", func() { - // src := RegistryRef(Host, ArtifactRepo, ma.Tag) - // dstRepo := cpTestRepo("platform-referrers") - // dst := RegistryRef(Host, dstRepo, "copiedTag") - // ORAS("cp", src, dst, "-r", "--platform", "linux/amd64", "-v"). - // MatchStatus(ma.IndexStateKeys, true, len(ma.IndexStateKeys)). - // MatchKeyWords("Digest: " + ma.LinuxAMD64.Digest.String()). - // Exec() - // // validate - // CompareRef(RegistryRef(Host, ImageRepo, ma.LinuxAMD64.Digest.String()), dst) - // var index ocispec.Index - // bytes := ORAS("discover", dst, "-o", "json", "--platform", "linux/amd64"). - // MatchKeyWords(ma.LinuxAMD64Referrer.Digest.String()). - // WithDescription("discover amd64 referrers"). - // Exec().Out.Contents() - // Expect(json.Unmarshal(bytes, &index)).ShouldNot(HaveOccurred()) - // Expect(len(index.Manifests)).To(Equal(1)) - // Expect(index.Manifests[0].Digest.String()).To(Equal(ma.LinuxAMD64Referrer.Digest.String())) - // ORAS("manifest", "fetch", RegistryRef(Host, dstRepo, ma.Digest)). - // WithDescription("not copy index"). - // ExpectFailure(). - // Exec() - // ORAS("manifest", "fetch", RegistryRef(Host, dstRepo, ma.IndexReferrerDigest)). - // WithDescription("not copy index referrer"). - // ExpectFailure(). - // Exec() - // }) - - // It("should copy a certain platform of image and its referrers to a new repository without tagging", func() { - // src := RegistryRef(Host, ArtifactRepo, ma.Tag) - // dstRepo := cpTestRepo("platform-referrers-no-tag") - // ORAS("cp", src, RegistryRef(Host, dstRepo, ""), "-r", "--platform", "linux/amd64", "-v"). - // MatchStatus(ma.IndexStateKeys, true, len(ma.IndexStateKeys)). - // MatchKeyWords("Digest: " + ma.LinuxAMD64.Digest.String()). - // Exec() - // // validate - // dstRef := RegistryRef(Host, dstRepo, ma.LinuxAMD64.Digest.String()) - // CompareRef(RegistryRef(Host, ImageRepo, ma.LinuxAMD64.Digest.String()), dstRef) - // var index ocispec.Index - // bytes := ORAS("discover", dstRef, "-o", "json", "--platform", "linux/amd64"). - // MatchKeyWords(ma.LinuxAMD64Referrer.Digest.String()). - // WithDescription("discover amd64 referrers"). - // Exec().Out.Contents() - // Expect(json.Unmarshal(bytes, &index)).ShouldNot(HaveOccurred()) - // Expect(len(index.Manifests)).To(Equal(1)) - // Expect(index.Manifests[0].Digest.String()).To(Equal(ma.LinuxAMD64Referrer.Digest.String())) - // ORAS("manifest", "fetch", RegistryRef(Host, dstRepo, ma.Digest)). - // WithDescription("not copy index"). - // ExpectFailure(). - // Exec() - // ORAS("manifest", "fetch", RegistryRef(Host, dstRepo, ma.IndexReferrerDigest)). - // WithDescription("not copy index referrer"). - // ExpectFailure(). - // Exec() - // }) - - // It("should copy an image to a new repository with multiple tagging", func() { - // src := RegistryRef(Host, ImageRepo, foobar.Digest) - // tags := []string{"tag1", "tag2", "tag3"} - // dstRepo := cpTestRepo("multi-tagging") - // dst := RegistryRef(Host, dstRepo, "") - // ORAS("cp", src, dst+":"+strings.Join(tags, ","), "-v").MatchStatus(foobarStates, true, len(foobarStates)).Exec() - // for _, tag := range tags { - // dst := RegistryRef(Host, dstRepo, tag) - // CompareRef(src, dst) - // } - // }) + It("should copy an image from a registry to an OCI image layout with multiple tagging", func() { + dstDir := GinkgoT().TempDir() + src := RegistryRef(Host, ImageRepo, foobar.Tag) + tags := []string{"tag1", "tag2", "tag3"} + // test + ORAS("cp", src, dstDir+":"+strings.Join(tags, ","), "-v", Flags.ToLayout).MatchStatus(foobarStates, true, len(foobarStates)).Exec() + // validate + srcManifest := ORAS("manifest", "fetch", src).WithDescription("fetch from source to validate").Exec().Out.Contents() + for _, tag := range tags { + dstManifest := ORAS("manifest", "fetch", LayoutRef(dstDir, tag), Flags.Layout).WithDescription("fetch from destination to validate").Exec().Out.Contents() + Expect(srcManifest).To(Equal(dstManifest)) + } + }) + + It("should copy a tagged image and its referrers from a registry to an OCI image layout", func() { + stateKeys := append(append(foobarStates, foobar.ArtifactReferrerStateKeys...), foobar.ImageReferrerConfigStateKeys...) + dst := LayoutRef(GinkgoT().TempDir(), "copied") + src := RegistryRef(Host, ArtifactRepo, foobar.Tag) + // test + ORAS("cp", "-r", src, dst, "-v", Flags.ToLayout).MatchStatus(stateKeys, true, len(stateKeys)).Exec() + // validate + srcManifest := ORAS("manifest", "fetch", src).WithDescription("fetch from source to validate").Exec().Out.Contents() + dstManifest := ORAS("manifest", "fetch", dst, Flags.Layout).WithDescription("fetch from destination to validate").Exec().Out.Contents() + Expect(srcManifest).To(Equal(dstManifest)) + }) + + It("should copy a image and its referrers from a registry to an OCI image layout via digest", func() { + stateKeys := append(append(foobarStates, foobar.ArtifactReferrerStateKeys...), foobar.ImageReferrerConfigStateKeys...) + toDir := GinkgoT().TempDir() + src := RegistryRef(Host, ArtifactRepo, foobar.Digest) + // test + ORAS("cp", "-r", src, toDir, "-v", Flags.ToLayout).MatchStatus(stateKeys, true, len(stateKeys)).Exec() + // validate + srcManifest := ORAS("manifest", "fetch", src).WithDescription("fetch from source to validate").Exec().Out.Contents() + dstManifest := ORAS("manifest", "fetch", LayoutRef(toDir, foobar.Digest), Flags.Layout).WithDescription("fetch from destination to validate").Exec().Out.Contents() + Expect(srcManifest).To(Equal(dstManifest)) + }) + + It("should copy a multi-arch image and its referrers from a registry to an OCI image layout a via tag", func() { + stateKeys := append(ma.IndexStateKeys, ma.IndexReferrerStateKey, ma.IndexReferrerConfigStateKey) + src := RegistryRef(Host, ArtifactRepo, ma.Tag) + toDir := GinkgoT().TempDir() + dst := LayoutRef(toDir, "copied") + // test + ORAS("cp", src, Flags.ToLayout, dst, "-r", "-v"). + MatchStatus(stateKeys, true, len(stateKeys)). + MatchKeyWords("Digest: " + ma.Digest). + Exec() + // validate + srcManifest := ORAS("manifest", "fetch", src).WithDescription("fetch from source to validate").Exec().Out.Contents() + dstManifest := ORAS("manifest", "fetch", dst, Flags.Layout).WithDescription("fetch from destination to validate").Exec().Out.Contents() + Expect(srcManifest).To(Equal(dstManifest)) + var index ocispec.Index + bytes := ORAS("discover", dst, "-o", "json", Flags.Layout). + MatchKeyWords(ma.IndexReferrerDigest). + WithDescription("copy image referrer"). + Exec().Out.Contents() + Expect(json.Unmarshal(bytes, &index)).ShouldNot(HaveOccurred()) + Expect(len(index.Manifests)).To(Equal(1)) + Expect(index.Manifests[0].Digest.String()).To(Equal(ma.IndexReferrerDigest)) + ORAS("manifest", "fetch", Flags.Layout, LayoutRef(toDir, ma.LinuxAMD64Referrer.Digest.String())). + WithDescription("not copy referrer of successor"). + ExpectFailure(). + Exec() + }) + + It("should copy a multi-arch image and its referrers from an OCI image layout to a registry via digest", func() { + stateKeys := append(ma.IndexStateKeys, ma.IndexReferrerStateKey, ma.IndexReferrerConfigStateKey) + fromDir := GinkgoT().TempDir() + src := LayoutRef(fromDir, ma.Tag) + dst := RegistryRef(Host, cpTestRepo("recursive-from-layout"), "copied") + // prepare + ORAS("cp", RegistryRef(Host, ArtifactRepo, ma.Tag), src, Flags.ToLayout, "-r").Exec() + // test + ORAS("cp", src, Flags.FromLayout, dst, "-r", "-v"). + MatchStatus(stateKeys, true, len(stateKeys)). + MatchKeyWords("Digest: " + ma.Digest). + Exec() + // validate + srcManifest := ORAS("manifest", "fetch", src, Flags.Layout).WithDescription("fetch from source to validate").Exec().Out.Contents() + dstManifest := ORAS("manifest", "fetch", dst).WithDescription("fetch from destination to validate").Exec().Out.Contents() + Expect(srcManifest).To(Equal(dstManifest)) + var index ocispec.Index + bytes := ORAS("discover", dst, "-o", "json"). + MatchKeyWords(ma.IndexReferrerDigest). + WithDescription("copy image referrer"). + Exec().Out.Contents() + Expect(json.Unmarshal(bytes, &index)).ShouldNot(HaveOccurred()) + Expect(len(index.Manifests)).To(Equal(1)) + Expect(index.Manifests[0].Digest.String()).To(Equal(ma.IndexReferrerDigest)) + ORAS("manifest", "fetch", LayoutRef(fromDir, ma.LinuxAMD64Referrer.Digest.String())). + WithDescription("not copy referrer of successor"). + ExpectFailure(). + Exec() + }) + + It("should copy a certain platform of image and its referrers from an OCI image layout to a registry", func() { + stateKeys := append(ma.LinuxAMD64StateKeys, ma.LinuxAMD64ReferrerStateKey, ma.LinuxAMD64ReferrerConfigStateKey) + fromDir := GinkgoT().TempDir() + src := LayoutRef(fromDir, ma.Tag) + dstRepo := cpTestRepo("platform-referrer-from-layout") + dst := RegistryRef(Host, dstRepo, "copied") + // prepare + ORAS("cp", RegistryRef(Host, ArtifactRepo, ma.Tag), src, Flags.ToLayout, "-r").Exec() + ORAS("cp", RegistryRef(Host, ArtifactRepo, ma.Tag), src, Flags.ToLayout, "-r", "--platform", "linux/amd64").Exec() + // test + ORAS("cp", src, Flags.FromLayout, dst, "-r", "-v", "--platform", "linux/amd64"). + MatchStatus(stateKeys, true, len(stateKeys)). + MatchKeyWords("Digest: " + ma.LinuxAMD64.Digest.String()). + Exec() + // validate + srcManifest := ORAS("manifest", "fetch", src, Flags.Layout, "--platform", "linux/amd64").WithDescription("fetch from source to validate").Exec().Out.Contents() + dstManifest := ORAS("manifest", "fetch", dst).WithDescription("fetch from destination to validate").Exec().Out.Contents() + Expect(srcManifest).To(Equal(dstManifest)) + ORAS("manifest", "fetch", RegistryRef(Host, dstRepo, ma.Digest)).WithDescription("not copy index").ExpectFailure().Exec() + var index ocispec.Index + bytes := ORAS("discover", dst, "-o", "json"). + MatchKeyWords(ma.LinuxAMD64Referrer.Digest.String()). + WithDescription("copy image referrer"). + Exec().Out.Contents() + Expect(json.Unmarshal(bytes, &index)).ShouldNot(HaveOccurred()) + Expect(len(index.Manifests)).To(Equal(1)) + Expect(index.Manifests[0].Digest.String()).To(Equal(ma.LinuxAMD64Referrer.Digest.String())) + }) + + It("should copy a certain platform of image and its referrers from a registry to an OCI image layout", func() { + stateKeys := append(ma.LinuxAMD64StateKeys, ma.LinuxAMD64ReferrerStateKey, ma.LinuxAMD64ReferrerConfigStateKey) + src := RegistryRef(Host, ArtifactRepo, ma.Tag) + toDir := GinkgoT().TempDir() + dst := LayoutRef(toDir, "copied") + // test + ORAS("cp", src, Flags.ToLayout, dst, "-r", "-v", "--platform", "linux/amd64"). + MatchStatus(stateKeys, true, len(stateKeys)). + MatchKeyWords("Digest: " + ma.LinuxAMD64.Digest.String()). + Exec() + // validate + srcManifest := ORAS("manifest", "fetch", src, "--platform", "linux/amd64").WithDescription("fetch from source to validate").Exec().Out.Contents() + dstManifest := ORAS("manifest", "fetch", dst, Flags.Layout).WithDescription("fetch from destination to validate").Exec().Out.Contents() + Expect(srcManifest).To(Equal(dstManifest)) + ORAS("manifest", "fetch", LayoutRef(toDir, ma.Digest)).WithDescription("not copy index").ExpectFailure().Exec() + var index ocispec.Index + bytes := ORAS("discover", dst, "-o", "json", Flags.Layout). + MatchKeyWords(ma.LinuxAMD64Referrer.Digest.String()). + WithDescription("copy image referrer"). + Exec().Out.Contents() + Expect(json.Unmarshal(bytes, &index)).ShouldNot(HaveOccurred()) + Expect(len(index.Manifests)).To(Equal(1)) + Expect(index.Manifests[0].Digest.String()).To(Equal(ma.LinuxAMD64Referrer.Digest.String())) + }) }) }) diff --git a/test/e2e/suite/command/pull.go b/test/e2e/suite/command/pull.go index db5895da1..2bcb95f36 100644 --- a/test/e2e/suite/command/pull.go +++ b/test/e2e/suite/command/pull.go @@ -91,7 +91,7 @@ var _ = Describe("Remote registry users:", func() { It("should pull specific platform", func() { ORAS("pull", RegistryRef(Host, ImageRepo, "multi"), "--platform", "linux/amd64", "-v", "-o", GinkgoT().TempDir()). - MatchStatus(multi_arch.ImageStateKeys, true, len(multi_arch.ImageStateKeys)).Exec() + MatchStatus(multi_arch.LinuxAMD64StateKeys, true, len(multi_arch.LinuxAMD64StateKeys)).Exec() }) }) })