Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

test(e2e): add e2e specs for custom DNS rules #855

Merged
merged 21 commits into from
Mar 6, 2023
Merged
11 changes: 5 additions & 6 deletions test/e2e/internal/testdata/foobar/const.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,6 @@ limitations under the License.
package foobar

import (
"fmt"

"github.com/opencontainers/go-digest"
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
"oras.land/oras/test/e2e/internal/utils/match"
Expand Down Expand Up @@ -60,10 +58,11 @@ var (
{Digest: "2c26b46b68ff", Name: ImageLayerNames[1]},
{Digest: "fcde2b2edba5", Name: ImageLayerNames[2]},
}
ImageConfigName = "config.json"
Foo1BlobDigest = "sha256:2c26b46b68ffc68ff99b453c1d30413413422d706483bfa0f98a5e886266e7ae"
Foo1BlobContent = "foo"
Foo1BlobDescriptor = fmt.Sprintf(`{"mediaType":"application/octet-stream","digest":"%s","size":3}`, Foo1BlobDigest)
ImageConfigName = "config.json"

FooBlobDigest = "sha256:2c26b46b68ffc68ff99b453c1d30413413422d706483bfa0f98a5e886266e7ae"
FooBlobContent = "foo"
FooBlobDescriptor = `{"mediaType":"application/octet-stream","digest":"sha256:2c26b46b68ffc68ff99b453c1d30413413422d706483bfa0f98a5e886266e7ae","size":3}`
)

func ImageConfigStateKey(configName string) match.StateKey {
Expand Down
62 changes: 29 additions & 33 deletions test/e2e/suite/command/blob.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,10 @@ import (
)

const (
pushContent = "test-blob"
pushDigest = "sha256:e1ca41574914ba00e8ed5c8fc78ec8efdfd48941c7e48ad74dad8ada7f2066d8"
invalidDigest = "sha256:0000000000000000000000000000000000000000000000000000000000000000"
pushDescFmt = `{"mediaType":"%s","digest":"sha256:e1ca41574914ba00e8ed5c8fc78ec8efdfd48941c7e48ad74dad8ada7f2066d8","size":9}`
deleteDigest = "sha256:fcde2b2edba56bf408601fb721fe9b5c338d10ee429ea04fae5511b68fbf8fb9"
deleteDescriptor = `{"mediaType":"application/octet-stream","digest":"sha256:fcde2b2edba56bf408601fb721fe9b5c338d10ee429ea04fae5511b68fbf8fb9","size":3}`
deleteContent = "bar"
pushContent = "test-blob"
pushDigest = "sha256:e1ca41574914ba00e8ed5c8fc78ec8efdfd48941c7e48ad74dad8ada7f2066d8"
invalidDigest = "sha256:0000000000000000000000000000000000000000000000000000000000000000"
pushDescFmt = `{"mediaType":"%s","digest":"sha256:e1ca41574914ba00e8ed5c8fc78ec8efdfd48941c7e48ad74dad8ada7f2066d8","size":9}`
)

var _ = Describe("ORAS beginners:", func() {
Expand Down Expand Up @@ -139,14 +136,14 @@ var _ = Describe("ORAS beginners:", func() {
dstRepo := fmt.Sprintf(repoFmt, "delete", "no-ref")
ORAS("cp", RegistryRef(Host, ImageRepo, foobar.Digest), RegistryRef(Host, dstRepo, foobar.Digest)).Exec()
ORAS("blob", "delete").ExpectFailure().Exec()
ORAS("blob", "fetch", RegistryRef(Host, dstRepo, deleteDigest), "--output", "-").MatchContent(deleteContent).Exec()
ORAS("blob", "fetch", RegistryRef(Host, dstRepo, foobar.FooBlobDigest), "--output", "-").MatchContent(foobar.FooBlobContent).Exec()
})

It("should fail if no force flag and descriptor flag is provided", func() {
dstRepo := fmt.Sprintf(repoFmt, "delete", "no-confirm")
ORAS("cp", RegistryRef(Host, ImageRepo, foobar.Digest), RegistryRef(Host, dstRepo, foobar.Digest)).Exec()
ORAS("blob", "delete", RegistryRef(Host, dstRepo, deleteDigest), "--descriptor").ExpectFailure().Exec()
ORAS("blob", "fetch", RegistryRef(Host, dstRepo, deleteDigest), "--output", "-").MatchContent(deleteContent).Exec()
ORAS("blob", "delete", RegistryRef(Host, dstRepo, foobar.FooBlobDigest), "--descriptor").ExpectFailure().Exec()
ORAS("blob", "fetch", RegistryRef(Host, dstRepo, foobar.FooBlobDigest), "--output", "-").MatchContent(foobar.FooBlobContent).Exec()
})

It("should fail if the blob reference is not in the form of <name@digest>", func() {
Expand Down Expand Up @@ -180,7 +177,7 @@ var _ = Describe("Common registry users:", func() {
It("should delete a blob with interactive confirmation", func() {
dstRepo := fmt.Sprintf(repoFmt, "delete", "prompt-confirmation")
ORAS("cp", RegistryRef(Host, ImageRepo, foobar.Digest), RegistryRef(Host, dstRepo, foobar.Digest)).Exec()
toDeleteRef := RegistryRef(Host, dstRepo, deleteDigest)
toDeleteRef := RegistryRef(Host, dstRepo, foobar.FooBlobDigest)
ORAS("blob", "delete", toDeleteRef).
WithInput(strings.NewReader("y")).
MatchKeyWords("Deleted", toDeleteRef).Exec()
Expand All @@ -194,8 +191,8 @@ var _ = Describe("Common registry users:", func() {
It("should delete a blob with force flag and output descriptor", func() {
dstRepo := fmt.Sprintf(repoFmt, "delete", "flag-confirmation")
ORAS("cp", RegistryRef(Host, ImageRepo, foobar.Digest), RegistryRef(Host, dstRepo, foobar.Digest)).Exec()
toDeleteRef := RegistryRef(Host, dstRepo, deleteDigest)
ORAS("blob", "delete", toDeleteRef, "--force", "--descriptor").MatchContent(deleteDescriptor).Exec()
toDeleteRef := RegistryRef(Host, dstRepo, foobar.FooBlobDigest)
ORAS("blob", "delete", toDeleteRef, "--force", "--descriptor").MatchContent(foobar.FooBlobDescriptor).Exec()
ORAS("blob", "delete", toDeleteRef).WithDescription("validate").ExpectFailure().MatchErrKeyWords("Error:", toDeleteRef, "the specified blob does not exist").Exec()
})

Expand All @@ -218,7 +215,6 @@ var _ = Describe("Common registry users:", func() {
ORAS("blob", "push", RegistryRef(Host, repo, ""), blobPath, "-v").
WithDescription("skip the pushing if the blob already exists in the target repo").
MatchKeyWords("Exists").Exec()

})

It("should push a blob from a stdin and output the descriptor with specific media-type", func() {
Expand All @@ -233,27 +229,27 @@ var _ = Describe("Common registry users:", func() {

When("running `blob fetch`", func() {
It("should fetch blob descriptor ", func() {
ORAS("blob", "fetch", RegistryRef(Host, ImageRepo, foobar.Foo1BlobDigest), "--descriptor").
MatchContent(foobar.Foo1BlobDescriptor).Exec()
ORAS("blob", "fetch", RegistryRef(Host, ImageRepo, foobar.FooBlobDigest), "--descriptor").
MatchContent(foobar.FooBlobDescriptor).Exec()
})
It("should fetch blob content and output to stdout", func() {
ORAS("blob", "fetch", RegistryRef(Host, ImageRepo, foobar.Foo1BlobDigest), "--output", "-").
MatchContent(foobar.Foo1BlobContent).Exec()
ORAS("blob", "fetch", RegistryRef(Host, ImageRepo, foobar.FooBlobDigest), "--output", "-").
MatchContent(foobar.FooBlobContent).Exec()
})
It("should fetch blob content and output to a file", func() {
tempDir := GinkgoT().TempDir()
contentPath := filepath.Join(tempDir, "fetched")
ORAS("blob", "fetch", RegistryRef(Host, ImageRepo, foobar.Foo1BlobDigest), "--output", contentPath).
ORAS("blob", "fetch", RegistryRef(Host, ImageRepo, foobar.FooBlobDigest), "--output", contentPath).
WithWorkDir(tempDir).Exec()
MatchFile(contentPath, foobar.Foo1BlobContent, DefaultTimeout)
MatchFile(contentPath, foobar.FooBlobContent, DefaultTimeout)
})
It("should fetch blob descriptor and output content to a file", func() {
tempDir := GinkgoT().TempDir()
contentPath := filepath.Join(tempDir, "fetched")
ORAS("blob", "fetch", RegistryRef(Host, ImageRepo, foobar.Foo1BlobDigest), "--output", contentPath, "--descriptor").
MatchContent(foobar.Foo1BlobDescriptor).
ORAS("blob", "fetch", RegistryRef(Host, ImageRepo, foobar.FooBlobDigest), "--output", contentPath, "--descriptor").
MatchContent(foobar.FooBlobDescriptor).
WithWorkDir(tempDir).Exec()
MatchFile(contentPath, foobar.Foo1BlobContent, DefaultTimeout)
MatchFile(contentPath, foobar.FooBlobContent, DefaultTimeout)
})
})
})
Expand All @@ -266,7 +262,7 @@ var _ = Describe("OCI image layout users:", func() {
}
When("running `blob delete`", func() {
It("should not support deleting a blob", func() {
toDeleteRef := LayoutRef(prepare(RegistryRef(Host, ImageRepo, foobar.Tag)), deleteDigest)
toDeleteRef := LayoutRef(prepare(RegistryRef(Host, ImageRepo, foobar.Tag)), foobar.FooBlobDigest)
ORAS("blob", "delete", LayoutFlag, toDeleteRef).
WithInput(strings.NewReader("y")).
MatchErrKeyWords("Error:", "unknown flag", LayoutFlag).
Expand All @@ -278,30 +274,30 @@ var _ = Describe("OCI image layout users:", func() {
When("running `blob fetch`", func() {
It("should fetch blob descriptor", func() {
root := prepare(RegistryRef(Host, ImageRepo, foobar.Tag))
ORAS("blob", "fetch", LayoutFlag, LayoutRef(root, foobar.Foo1BlobDigest), "--descriptor").
MatchContent(foobar.Foo1BlobDescriptor).Exec()
ORAS("blob", "fetch", LayoutFlag, LayoutRef(root, foobar.FooBlobDigest), "--descriptor").
MatchContent(foobar.FooBlobDescriptor).Exec()
})
It("should fetch blob content and output to stdout", func() {
root := prepare(RegistryRef(Host, ImageRepo, foobar.Tag))
ORAS("blob", "fetch", LayoutFlag, LayoutRef(root, foobar.Foo1BlobDigest), "--output", "-").
MatchContent(foobar.Foo1BlobContent).Exec()
ORAS("blob", "fetch", LayoutFlag, LayoutRef(root, foobar.FooBlobDigest), "--output", "-").
MatchContent(foobar.FooBlobContent).Exec()
})
It("should fetch blob content and output to a file", func() {
root := prepare(RegistryRef(Host, ImageRepo, foobar.Tag))
tempDir := GinkgoT().TempDir()
contentPath := filepath.Join(tempDir, "fetched")
ORAS("blob", "fetch", LayoutFlag, LayoutRef(root, foobar.Foo1BlobDigest), "--output", contentPath).
ORAS("blob", "fetch", LayoutFlag, LayoutRef(root, foobar.FooBlobDigest), "--output", contentPath).
WithWorkDir(tempDir).Exec()
MatchFile(contentPath, foobar.Foo1BlobContent, DefaultTimeout)
MatchFile(contentPath, foobar.FooBlobContent, DefaultTimeout)
})
It("should fetch blob descriptor and output content to a file", func() {
root := prepare(RegistryRef(Host, ImageRepo, foobar.Tag))
tempDir := GinkgoT().TempDir()
contentPath := filepath.Join(tempDir, "fetched")
ORAS("blob", "fetch", LayoutFlag, LayoutRef(root, foobar.Foo1BlobDigest), "--output", contentPath, "--descriptor").
MatchContent(foobar.Foo1BlobDescriptor).
ORAS("blob", "fetch", LayoutFlag, LayoutRef(root, foobar.FooBlobDigest), "--output", contentPath, "--descriptor").
MatchContent(foobar.FooBlobDescriptor).
WithWorkDir(tempDir).Exec()
MatchFile(contentPath, foobar.Foo1BlobContent, DefaultTimeout)
MatchFile(contentPath, foobar.FooBlobContent, DefaultTimeout)
})
})

Expand Down
44 changes: 20 additions & 24 deletions test/e2e/suite/command/cp.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ import (
"strings"

. "github.com/onsi/ginkgo/v2"
"github.com/onsi/gomega"
. "github.com/onsi/gomega"
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
"oras.land/oras-go/v2"
Expand Down Expand Up @@ -58,40 +57,42 @@ 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()
Expect(srcManifest).To(Equal(dstManifest))
}

var _ = Describe("Common registry users:", func() {
When("running `cp`", func() {
validate := func(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()
Expect(srcManifest).To(Equal(dstManifest))
}

It("should copy an image to a new repository via tag", func() {
src := RegistryRef(Host, ImageRepo, foobar.Tag)
dst := RegistryRef(Host, cpTestRepo("tag"), "copiedTag")
ORAS("cp", src, dst, "-v").MatchStatus(foobarStates, true, len(foobarStates)).Exec()
validate(src, dst)
CompareRef(src, dst)
})

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()
validate(src, dst)
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()
validate(src, dst)
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()
validate(src, dst)
CompareRef(src, dst)
})

It("should copy a multi-arch image and its referrers to a new repository via tag", func() {
Expand All @@ -103,7 +104,7 @@ var _ = Describe("Common registry users:", func() {
MatchKeyWords("Digest: " + ma.Digest).
Exec()
// validate
validate(RegistryRef(Host, ImageRepo, ma.Digest), dst)
CompareRef(RegistryRef(Host, ImageRepo, ma.Digest), dst)
var index ocispec.Index
bytes := ORAS("discover", dst, "-o", "json").
MatchKeyWords(ma.IndexReferrerDigest).
Expand All @@ -127,7 +128,7 @@ var _ = Describe("Common registry users:", func() {
MatchKeyWords("Digest: " + ma.Digest).
Exec()
// validate
validate(RegistryRef(Host, ImageRepo, ma.Digest), dst)
CompareRef(RegistryRef(Host, ImageRepo, ma.Digest), dst)
var index ocispec.Index
bytes := ORAS("discover", dst, "-o", "json").
MatchKeyWords(ma.IndexReferrerDigest).
Expand All @@ -150,7 +151,7 @@ var _ = Describe("Common registry users:", func() {
MatchStatus(ma.IndexStateKeys, true, len(ma.IndexStateKeys)).
MatchKeyWords("Digest: " + ma.LinuxAMD64.Digest.String()).
Exec()
validate(RegistryRef(Host, ImageRepo, ma.LinuxAMD64.Digest.String()), dst)
CompareRef(RegistryRef(Host, ImageRepo, ma.LinuxAMD64.Digest.String()), dst)
})

It("should copy a certain platform of image to a new repository via digest", func() {
Expand All @@ -161,7 +162,7 @@ var _ = Describe("Common registry users:", func() {
MatchStatus(ma.IndexStateKeys, true, len(ma.IndexStateKeys)).
MatchKeyWords("Digest: " + ma.LinuxAMD64.Digest.String()).
Exec()
validate(RegistryRef(Host, ImageRepo, ma.LinuxAMD64.Digest.String()), RegistryRef(Host, dstRepo, ma.LinuxAMD64.Digest.String()))
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() {
Expand All @@ -173,7 +174,7 @@ var _ = Describe("Common registry users:", func() {
MatchKeyWords("Digest: " + ma.LinuxAMD64.Digest.String()).
Exec()
// validate
validate(RegistryRef(Host, ImageRepo, ma.LinuxAMD64.Digest.String()), dst)
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()).
Expand Down Expand Up @@ -201,7 +202,7 @@ var _ = Describe("Common registry users:", func() {
Exec()
// validate
dstRef := RegistryRef(Host, dstRepo, ma.LinuxAMD64.Digest.String())
validate(RegistryRef(Host, ImageRepo, ma.LinuxAMD64.Digest.String()), dstRef)
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()).
Expand All @@ -228,26 +229,21 @@ var _ = Describe("Common registry users:", func() {
ORAS("cp", src, dst+":"+strings.Join(tags, ","), "-v").MatchStatus(foobarStates, true, len(foobarStates)).Exec()
for _, tag := range tags {
dst := RegistryRef(Host, dstRepo, tag)
validate(src, dst)
CompareRef(src, dst)
}
})
})
})

var _ = Describe("OCI spec 1.0 registry users:", func() {
When("running `cp`", func() {
validate := func(src, dst string) {
srcManifest := ORAS("manifest", "fetch", src).Exec().Out.Contents()
dstManifest := ORAS("manifest", "fetch", dst).Exec().Out.Contents()
gomega.Expect(srcManifest).To(gomega.Equal(dstManifest))
}
It("should copy an image artifact and its referrers from a registry to a fallback registry", func() {
repo := cpTestRepo("to-fallback")
stateKeys := append(append(foobarStates, foobar.ImageReferrersStateKeys...), foobar.ImageReferrerConfigStateKeys...)
src := RegistryRef(Host, ArtifactRepo, foobar.SignatureImageReferrer.Digest.String())
dst := RegistryRef(FallbackHost, repo, "")
ORAS("cp", "-r", src, dst, "-v").MatchStatus(stateKeys, true, len(stateKeys)).Exec()
validate(src, RegistryRef(FallbackHost, repo, foobar.SignatureImageReferrer.Digest.String()))
CompareRef(src, RegistryRef(FallbackHost, repo, foobar.SignatureImageReferrer.Digest.String()))
ORAS("discover", "-o", "tree", RegistryRef(FallbackHost, repo, foobar.Digest)).
WithDescription("discover referrer via subject").MatchKeyWords(foobar.SignatureImageReferrer.Digest.String(), foobar.SBOMImageReferrer.Digest.String()).Exec()
})
Expand All @@ -257,7 +253,7 @@ var _ = Describe("OCI spec 1.0 registry users:", func() {
src := RegistryRef(FallbackHost, ArtifactRepo, foobar.FallbackSBOMImageReferrer.Digest.String())
dst := RegistryRef(Host, repo, "")
ORAS("cp", "-r", src, dst, "-v").MatchStatus(stateKeys, true, len(stateKeys)).Exec()
validate(src, RegistryRef(Host, repo, foobar.FallbackSBOMImageReferrer.Digest.String()))
CompareRef(src, RegistryRef(Host, repo, foobar.FallbackSBOMImageReferrer.Digest.String()))
ORAS("discover", "-o", "tree", RegistryRef(Host, repo, foobar.Digest)).
WithDescription("discover referrer via subject").MatchKeyWords(foobar.FallbackSignatureImageReferrer.Digest.String(), foobar.FallbackSBOMImageReferrer.Digest.String()).Exec()
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@ Copyright The ORAS Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
Expand Down
Loading