From 74003e5c10f548ddfb6a025d5b8e3c448a169133 Mon Sep 17 00:00:00 2001 From: Billy Zha Date: Fri, 17 Mar 2023 14:07:45 +0800 Subject: [PATCH] test(e2e): layout specs for `oras manifest push` (#880) Signed-off-by: Billy Zha --- go.mod | 2 +- go.sum | 4 +- test/e2e/go.mod | 2 +- test/e2e/suite/command/manifest.go | 89 ++++++++++++++++++++++++++++++ 4 files changed, 93 insertions(+), 4 deletions(-) diff --git a/go.mod b/go.mod index 6b4fa835d..054118f70 100644 --- a/go.mod +++ b/go.mod @@ -12,7 +12,7 @@ require ( github.com/spf13/cobra v1.6.1 github.com/spf13/pflag v1.0.5 gopkg.in/yaml.v3 v3.0.1 - oras.land/oras-go/v2 v2.0.1 + oras.land/oras-go/v2 v2.0.0-20230317034844-336b9fb9c68c ) require ( diff --git a/go.sum b/go.sum index fe691f0ac..c334e3ead 100644 --- a/go.sum +++ b/go.sum @@ -64,5 +64,5 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gotest.tools/v3 v3.0.2 h1:kG1BFyqVHuQoVQiR1bWGnfz/fmHvvuiSPIV7rvl360E= gotest.tools/v3 v3.0.2/go.mod h1:3SzNCllyD9/Y+b5r9JIKQ474KzkZyqLqEfYqMsX94Bk= -oras.land/oras-go/v2 v2.0.1 h1:fdnzCXT6yBQziJNJrCqaUPd6Ww7j6M0qLrtFA80tTeM= -oras.land/oras-go/v2 v2.0.1/go.mod h1:PWnWc/Kyyg7wUTUsDHshrsJkzuxXzreeMd6NrfdnFSo= +oras.land/oras-go/v2 v2.0.0-20230317034844-336b9fb9c68c h1:tIEkN9LOZGLh6MTGwSYkiXEBw9KeAWC9jbfa/Qoniqk= +oras.land/oras-go/v2 v2.0.0-20230317034844-336b9fb9c68c/go.mod h1:PWnWc/Kyyg7wUTUsDHshrsJkzuxXzreeMd6NrfdnFSo= diff --git a/test/e2e/go.mod b/test/e2e/go.mod index f455044ed..9107d1df3 100644 --- a/test/e2e/go.mod +++ b/test/e2e/go.mod @@ -8,7 +8,7 @@ require ( github.com/opencontainers/go-digest v1.0.0 github.com/opencontainers/image-spec v1.1.0-rc2 gopkg.in/yaml.v2 v2.4.0 - oras.land/oras-go/v2 v2.0.0-20230224055117-216f081e33ba + oras.land/oras-go/v2 v2.0.0-20230317034844-336b9fb9c68c ) require ( diff --git a/test/e2e/suite/command/manifest.go b/test/e2e/suite/command/manifest.go index 4c1f425d3..a087b3751 100644 --- a/test/e2e/suite/command/manifest.go +++ b/test/e2e/suite/command/manifest.go @@ -16,7 +16,9 @@ limitations under the License. package command import ( + "encoding/json" "fmt" + "os" "path/filepath" "regexp" "strings" @@ -511,3 +513,90 @@ var _ = Describe("OCI image layout users:", func() { }) }) }) + +var _ = Describe("OCI image layout users:", func() { + When("running `manifest push`", func() { + scratchSize := 2 + scratchDigest := "sha256:44136fa355b3678a1146ad16f7e8649e94fb4fc21fe77e8310c060f61caaff8a" + manifest := fmt.Sprintf(`{"schemaVersion":2,"mediaType":"application/vnd.oci.image.manifest.v1+json","config":{"mediaType":"application/vnd.oci.image.config.v1+json","digest":"%s","size":%d},"layers":[]}`, scratchDigest, scratchSize) + manifestDigest := "sha256:f20c43161d73848408ef247f0ec7111b19fe58ffebc0cbcaa0d2c8bda4967268" + prepare := func(layoutRoot string) { + ORAS("blob", "push", Flags.Layout, LayoutRef(layoutRoot, scratchDigest), "--size", "2", "-"). + WithInput(strings.NewReader("{}")).Exec() + } + validate := func(root string, digest string, tag string) { + path := filepath.Join(root, "index.json") + Expect(path).To(BeAnExistingFile()) + content, err := os.ReadFile(path) + Expect(err).NotTo(HaveOccurred()) + var index ocispec.Index + Expect(json.Unmarshal(content, &index)).ShouldNot(HaveOccurred()) + for _, m := range index.Manifests { + if m.Digest.String() == digest && + (tag == "" || tag == m.Annotations["org.opencontainers.image.ref.name"]) { + return + } + } + Fail(fmt.Sprintf("Failed to find manifest with digest %q and tag %q in index.json: \n%s", digest, tag, string(content))) + } + descriptor := "{\"mediaType\":\"application/vnd.oci.image.manifest.v1+json\",\"digest\":\"sha256:f20c43161d73848408ef247f0ec7111b19fe58ffebc0cbcaa0d2c8bda4967268\",\"size\":246}" + + It("should push a manifest from stdin", func() { + root := GinkgoT().TempDir() + prepare(root) + ORAS("manifest", "push", Flags.Layout, root, "-"). + MatchKeyWords("Pushed", root, "Digest:", manifestDigest). + WithInput(strings.NewReader(manifest)).Exec() + validate(root, manifestDigest, "") + }) + It("should push a manifest from stdin and tag", func() { + tag := "from-stdin" + root := GinkgoT().TempDir() + ref := LayoutRef(root, tag) + ORAS("manifest", "push", Flags.Layout, ref, "-"). + MatchKeyWords("Pushed", ref, "Digest:", manifestDigest). + WithInput(strings.NewReader(manifest)).Exec() + validate(root, manifestDigest, tag) + }) + + It("should push a manifest and output descriptor", func() { + root := GinkgoT().TempDir() + prepare(root) + ORAS("manifest", "push", Flags.Layout, root, "-", "--descriptor"). + MatchContent(descriptor). + WithInput(strings.NewReader(manifest)).Exec() + validate(root, manifestDigest, "") + }) + + It("should push a manifest from file", func() { + manifestPath := WriteTempFile("manifest.json", manifest) + root := filepath.Dir(manifestPath) + prepare(root) + tag := "from-file" + ref := LayoutRef(root, tag) + ORAS("manifest", "push", Flags.Layout, ref, manifestPath). + MatchKeyWords("Pushed", ref, "Digest:", manifestDigest). + WithInput(strings.NewReader(manifest)).Exec() + validate(root, manifestDigest, tag) + }) + + It("should push a manifest from stdin, only when media type flag is set", func() { + manifest := fmt.Sprintf(`{"schemaVersion":2,"config":{"mediaType":"application/vnd.oci.image.config.v1+json","digest":"%s","size":%d}}`, scratchDigest, scratchSize) + manifestDigest := "sha256:8fc649142bbc0a2aa5015d5ef5a922df9d2d7f2dcf3095dbebfaf7c271eca444" + + root := GinkgoT().TempDir() + prepare(root) + tag := "mediatype-flag" + ref := LayoutRef(root, tag) + ORAS("manifest", "push", Flags.Layout, ref, "-", "--media-type", "application/vnd.oci.image.manifest.v1+json"). + MatchKeyWords("Pushed", ref, "Digest:", manifestDigest). + WithInput(strings.NewReader(manifest)).Exec() + validate(root, manifestDigest, tag) + + ORAS("manifest", "push", Flags.Layout, ref, "-"). + WithInput(strings.NewReader(manifest)). + ExpectFailure(). + WithDescription("fail if no media type flag provided").Exec() + }) + }) +})