Skip to content

Commit

Permalink
Merge branch 'main' into zot-fix
Browse files Browse the repository at this point in the history
  • Loading branch information
qweeah authored Aug 29, 2023
2 parents 273a4a2 + 9974dc4 commit e3b124b
Show file tree
Hide file tree
Showing 10 changed files with 64 additions and 71 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -54,5 +54,6 @@ test/e2e/testdata/distribution/mount_fallback/docker/
# OCI Layout Files ZOT storage files for local E2E testing
test/e2e/testdata/zot/
!test/e2e/testdata/zot/command/images
!test/e2e/testdata/zot/command/blobs
!test/e2e/testdata/zot/config.json
!test/e2e/testdata/zot/passwd_bcrypt
4 changes: 2 additions & 2 deletions test/e2e/internal/utils/prepare.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@ import (
"github.com/onsi/gomega/gbytes"
)

// CopyZotRepo copies oci layout data between repostories.
func CopyZotRepo(fromRepo string, toRepo string) {
// CopyZOTRepo copies oci layout data between repostories.
func CopyZOTRepo(fromRepo string, toRepo string) {
zotRoot := filepath.Join(TestDataRoot, "zot")
fromRepo = filepath.Join(zotRoot, fromRepo)
toRepo = filepath.Join(zotRoot, toRepo)
Expand Down
2 changes: 1 addition & 1 deletion test/e2e/internal/utils/testdata.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ const (
PreviewDesc = "** This command is in preview and under development. **"
ExampleDesc = "\nExample - "
ImageRepo = "command/images"
BlobRepo = "command/blobs"
ArtifactRepo = "command/artifacts"
Repo = "command/images"
Namespace = "command"
// env
RegHostKey = "ORAS_REGISTRY_HOST"
Expand Down
10 changes: 5 additions & 5 deletions test/e2e/suite/command/attach.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ var _ = Describe("1.1 registry users:", func() {
When("running attach command", func() {
It("should attach a file to a subject", func() {
testRepo := attachTestRepo("simple")
CopyZotRepo(ImageRepo, testRepo)
CopyZOTRepo(ImageRepo, testRepo)
subjectRef := RegistryRef(ZOTHost, testRepo, foobar.Tag)
ORAS("attach", "--artifact-type", "test/attach", subjectRef, fmt.Sprintf("%s:%s", foobar.AttachFileName, foobar.AttachFileMedia)).
WithWorkDir(PrepareTempFiles()).
Expand All @@ -84,7 +84,7 @@ var _ = Describe("1.1 registry users:", func() {
tempDir := PrepareTempFiles()
exportName := "manifest.json"
subjectRef := RegistryRef(ZOTHost, testRepo, foobar.Tag)
CopyZotRepo(ImageRepo, testRepo)
CopyZOTRepo(ImageRepo, testRepo)
// test
ORAS("attach", "--artifact-type", "test/attach", subjectRef, fmt.Sprintf("%s:%s", foobar.AttachFileName, foobar.AttachFileMedia), "--export-manifest", exportName).
WithWorkDir(tempDir).
Expand All @@ -102,7 +102,7 @@ var _ = Describe("1.1 registry users:", func() {
testRepo := attachTestRepo("image")
tempDir := PrepareTempFiles()
subjectRef := RegistryRef(ZOTHost, testRepo, foobar.Tag)
CopyZotRepo(ImageRepo, testRepo)
CopyZOTRepo(ImageRepo, testRepo)
// test
ORAS("attach", "--artifact-type", "test/attach", subjectRef, fmt.Sprintf("%s:%s", foobar.AttachFileName, foobar.AttachFileMedia)).
WithWorkDir(tempDir).
Expand All @@ -120,7 +120,7 @@ var _ = Describe("1.1 registry users:", func() {
absAttachFileName := filepath.Join(PrepareTempFiles(), foobar.AttachFileName)

subjectRef := RegistryRef(ZOTHost, testRepo, foobar.Tag)
CopyZotRepo(ImageRepo, testRepo)
CopyZOTRepo(ImageRepo, testRepo)
statusKey := foobar.AttachFileStateKey
statusKey.Name = absAttachFileName
ORAS("attach", "--artifact-type", "test/attach", subjectRef, fmt.Sprintf("%s:%s", absAttachFileName, foobar.AttachFileMedia), "--disable-path-validation").
Expand All @@ -133,7 +133,7 @@ var _ = Describe("1.1 registry users:", func() {
absAttachFileName := filepath.Join(PrepareTempFiles(), foobar.AttachFileName)

subjectRef := RegistryRef(ZOTHost, testRepo, foobar.Tag)
CopyZotRepo(ImageRepo, testRepo)
CopyZOTRepo(ImageRepo, testRepo)
statusKey := foobar.AttachFileStateKey
statusKey.Name = absAttachFileName
ORAS("attach", "--artifact-type", "test/attach", subjectRef, fmt.Sprintf("%s:%s", absAttachFileName, foobar.AttachFileMedia)).
Expand Down
99 changes: 44 additions & 55 deletions test/e2e/suite/command/blob.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,44 +39,46 @@ var _ = Describe("ORAS beginners:", func() {
When("running `blob push`", func() {
It("should fail to read blob content and password from stdin at the same time", func() {
repo := fmt.Sprintf(repoFmt, "push", "password-stdin")
ORAS("blob", "push", RegistryRef(Host, repo, ""), "--password-stdin", "-").
ORAS("blob", "push", RegistryRef(ZOTHost, repo, ""), "--password-stdin", "-").
ExpectFailure().
MatchErrKeyWords("Error: `-` read file from input and `--password-stdin` read password from input cannot be both used").Exec()
})
It("should fail to push a blob from stdin but no blob size provided", func() {
repo := fmt.Sprintf(repoFmt, "push", "no-size")
ORAS("blob", "push", RegistryRef(Host, repo, pushDigest), "-").
ORAS("blob", "push", RegistryRef(ZOTHost, repo, pushDigest), "-").
WithInput(strings.NewReader(pushContent)).
ExpectFailure().
MatchErrKeyWords("Error: `--size` must be provided if the blob is read from stdin").Exec()
})

It("should fail to push a blob from stdin if invalid blob size provided", func() {
content := "another-test"
digest := "sha256:c897eff15c4586525388034f8246346681cb48d75a619039c566c4939a18102e"
repo := fmt.Sprintf(repoFmt, "push", "invalid-stdin-size")
ORAS("blob", "push", RegistryRef(Host, repo, pushDigest), "-", "--size", "3").
WithInput(strings.NewReader(pushContent)).ExpectFailure().
ORAS("blob", "push", RegistryRef(ZOTHost, repo, digest), "-", "--size", "3").
WithInput(strings.NewReader(content)).ExpectFailure().
Exec()
})

It("should fail to push a blob from stdin if invalid digest provided", func() {
repo := fmt.Sprintf(repoFmt, "push", "invalid-stdin-digest")
ORAS("blob", "push", RegistryRef(Host, repo, invalidDigest), "-", "--size", strconv.Itoa(len(pushContent))).
ORAS("blob", "push", RegistryRef(ZOTHost, repo, invalidDigest), "-", "--size", strconv.Itoa(len(pushContent))).
WithInput(strings.NewReader(pushContent)).ExpectFailure().
Exec()
})

It("should fail to push a blob from file if invalid blob size provided", func() {
repo := fmt.Sprintf(repoFmt, "push", "invalid-file-digest")
blobPath := WriteTempFile("blob", pushContent)
ORAS("blob", "push", RegistryRef(Host, repo, pushDigest), blobPath, "--size", "3").
ORAS("blob", "push", RegistryRef(ZOTHost, repo, pushDigest), blobPath, "--size", "3").
ExpectFailure().
Exec()
})

It("should fail to push a blob from file if invalid digest provided", func() {
repo := fmt.Sprintf(repoFmt, "push", "invalid-stdin-size")
blobPath := WriteTempFile("blob", pushContent)
ORAS("blob", "push", RegistryRef(Host, repo, invalidDigest), blobPath, "--size", strconv.Itoa(len(pushContent))).
ORAS("blob", "push", RegistryRef(ZOTHost, repo, invalidDigest), blobPath, "--size", strconv.Itoa(len(pushContent))).
WithInput(strings.NewReader(pushContent)).ExpectFailure().
Exec()
})
Expand All @@ -99,22 +101,22 @@ var _ = Describe("ORAS beginners:", func() {
})

It("should fail if neither output path nor descriptor flag are not provided", func() {
ORAS("blob", "fetch", RegistryRef(Host, ImageRepo, "sha256:2c26b46b68ffc68ff99b453c1d30413413422d706483bfa0f98a5e886266e7ae")).
ORAS("blob", "fetch", RegistryRef(ZOTHost, ImageRepo, "sha256:2c26b46b68ffc68ff99b453c1d30413413422d706483bfa0f98a5e886266e7ae")).
ExpectFailure().Exec()
})

It("should fail if no digest provided", func() {
ORAS("blob", "fetch", RegistryRef(Host, ImageRepo, "")).
ORAS("blob", "fetch", RegistryRef(ZOTHost, ImageRepo, "")).
ExpectFailure().Exec()
})

It("should fail if provided digest doesn't existed", func() {
ORAS("blob", "fetch", RegistryRef(Host, ImageRepo, "sha256:2aaa2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a")).
ORAS("blob", "fetch", RegistryRef(ZOTHost, ImageRepo, "sha256:2aaa2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a")).
ExpectFailure().Exec()
})

It("should fail if output path points to stdout and descriptor flag is provided", func() {
ORAS("blob", "fetch", RegistryRef(Host, ImageRepo, ""), "--descriptor", "--output", "-").
ORAS("blob", "fetch", RegistryRef(ZOTHost, ImageRepo, ""), "--descriptor", "--output", "-").
ExpectFailure().Exec()
})

Expand All @@ -127,35 +129,35 @@ var _ = Describe("ORAS beginners:", func() {
When("running `blob delete`", func() {
It("should fail if no blob reference is provided", func() {
dstRepo := fmt.Sprintf(repoFmt, "delete", "no-ref")
ORAS("cp", RegistryRef(Host, ImageRepo, foobar.Digest), RegistryRef(Host, dstRepo, foobar.Digest)).Exec()
CopyZOTRepo(ImageRepo, dstRepo)
ORAS("blob", "delete").ExpectFailure().Exec()
ORAS("blob", "fetch", RegistryRef(Host, dstRepo, foobar.FooBlobDigest), "--output", "-").MatchContent(foobar.FooBlobContent).Exec()
ORAS("blob", "fetch", RegistryRef(ZOTHost, 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, foobar.FooBlobDigest), "--descriptor").ExpectFailure().Exec()
ORAS("blob", "fetch", RegistryRef(Host, dstRepo, foobar.FooBlobDigest), "--output", "-").MatchContent(foobar.FooBlobContent).Exec()
CopyZOTRepo(ImageRepo, dstRepo)
ORAS("blob", "delete", RegistryRef(ZOTHost, dstRepo, foobar.FooBlobDigest), "--descriptor").ExpectFailure().Exec()
ORAS("blob", "fetch", RegistryRef(ZOTHost, dstRepo, foobar.FooBlobDigest), "--output", "-").MatchContent(foobar.FooBlobContent).Exec()
})

It("should fail if the blob reference is not in the form of <name@digest>", func() {
dstRepo := fmt.Sprintf(repoFmt, "delete", "wrong-ref-form")
ORAS("blob", "delete", fmt.Sprintf("%s/%s:%s", Host, dstRepo, "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"), "--descriptor", "--force").ExpectFailure().Exec()
ORAS("blob", "delete", fmt.Sprintf("%s/%s:%s", Host, dstRepo, "test"), "--descriptor", "--force").ExpectFailure().Exec()
ORAS("blob", "delete", fmt.Sprintf("%s/%s@%s", Host, dstRepo, "test"), "--descriptor", "--force").ExpectFailure().Exec()
ORAS("blob", "delete", fmt.Sprintf("%s/%s:%s", ZOTHost, dstRepo, "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"), "--descriptor", "--force").ExpectFailure().Exec()
ORAS("blob", "delete", fmt.Sprintf("%s/%s:%s", ZOTHost, dstRepo, "test"), "--descriptor", "--force").ExpectFailure().Exec()
ORAS("blob", "delete", fmt.Sprintf("%s/%s@%s", ZOTHost, dstRepo, "test"), "--descriptor", "--force").ExpectFailure().Exec()
})

It("should fail to delete a non-existent blob without force flag set", func() {
toDeleteRef := RegistryRef(Host, ImageRepo, invalidDigest)
toDeleteRef := RegistryRef(ZOTHost, ImageRepo, invalidDigest)
ORAS("blob", "delete", toDeleteRef).
ExpectFailure().
MatchErrKeyWords(toDeleteRef, "the specified blob does not exist").
Exec()
})

It("should fail to delete a non-existent blob and output descriptor, with force flag set", func() {
toDeleteRef := RegistryRef(Host, ImageRepo, invalidDigest)
toDeleteRef := RegistryRef(ZOTHost, ImageRepo, invalidDigest)
ORAS("blob", "delete", toDeleteRef, "--force", "--descriptor").
ExpectFailure().
MatchErrKeyWords(toDeleteRef, "the specified blob does not exist").
Expand All @@ -169,28 +171,22 @@ var _ = Describe("1.1 registry users:", func() {
When("running `blob delete`", 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, foobar.FooBlobDigest)
CopyZOTRepo(BlobRepo, dstRepo)
toDeleteRef := RegistryRef(ZOTHost, dstRepo, foobar.FooBlobDigest)
ORAS("blob", "delete", toDeleteRef).
WithInput(strings.NewReader("y")).
MatchKeyWords("Deleted", toDeleteRef).Exec()
ORAS("blob", "delete", toDeleteRef).
WithDescription("validate").
WithInput(strings.NewReader("y")).
ExpectFailure().
MatchErrKeyWords("Error:", toDeleteRef, "the specified blob does not exist").Exec()
})

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, foobar.FooBlobDigest)
CopyZOTRepo(BlobRepo, dstRepo)
toDeleteRef := RegistryRef(ZOTHost, 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()
})

It("should return success when deleting a non-existent blob with force flag set", func() {
toDeleteRef := RegistryRef(Host, ImageRepo, invalidDigest)
toDeleteRef := RegistryRef(ZOTHost, ImageRepo, invalidDigest)
ORAS("blob", "delete", toDeleteRef, "--force").
MatchKeyWords("Missing", toDeleteRef).
Exec()
Expand All @@ -201,61 +197,54 @@ var _ = Describe("1.1 registry users:", func() {
mediaType := "test.media"
repo := fmt.Sprintf(repoFmt, "push", "blob-file-media-type")
blobPath := WriteTempFile("blob", pushContent)
ORAS("blob", "push", RegistryRef(Host, repo, ""), blobPath, "--media-type", mediaType, "--descriptor").
ORAS("blob", "push", RegistryRef(ZOTHost, repo, ""), blobPath, "--media-type", mediaType, "--descriptor").
MatchContent(fmt.Sprintf(pushDescFmt, mediaType)).Exec()
ORAS("blob", "fetch", RegistryRef(Host, repo, pushDigest), "--output", "-").MatchContent(pushContent).Exec()
ORAS("blob", "fetch", RegistryRef(ZOTHost, repo, pushDigest), "--output", "-").MatchContent(pushContent).Exec()

ORAS("blob", "push", RegistryRef(Host, repo, ""), blobPath, "-v").
ORAS("blob", "push", RegistryRef(ZOTHost, 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() {
mediaType := "test.media"
repo := fmt.Sprintf(repoFmt, "push", "blob-file-media-type")
ORAS("blob", "push", RegistryRef(Host, repo, pushDigest), "-", "--media-type", mediaType, "--descriptor", "--size", strconv.Itoa(len(pushContent))).
ORAS("blob", "push", RegistryRef(ZOTHost, repo, pushDigest), "-", "--media-type", mediaType, "--descriptor", "--size", strconv.Itoa(len(pushContent))).
WithInput(strings.NewReader(pushContent)).
MatchContent(fmt.Sprintf(pushDescFmt, mediaType)).Exec()
ORAS("blob", "fetch", RegistryRef(Host, repo, pushDigest), "--output", "-").MatchContent(pushContent).Exec()
ORAS("blob", "fetch", RegistryRef(ZOTHost, repo, pushDigest), "--output", "-").MatchContent(pushContent).Exec()
})
})

When("running `blob fetch`", func() {
It("should fetch blob descriptor ", func() {
ORAS("blob", "fetch", RegistryRef(Host, ImageRepo, foobar.FooBlobDigest), "--descriptor").
ORAS("blob", "fetch", RegistryRef(ZOTHost, 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.FooBlobDigest), "--output", "-").
ORAS("blob", "fetch", RegistryRef(ZOTHost, 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.FooBlobDigest), "--output", contentPath).
ORAS("blob", "fetch", RegistryRef(ZOTHost, ImageRepo, foobar.FooBlobDigest), "--output", contentPath).
WithWorkDir(tempDir).Exec()
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.FooBlobDigest), "--output", contentPath, "--descriptor").
MatchContent(foobar.FooBlobDescriptor).
WithWorkDir(tempDir).Exec()
contentPath := filepath.Join(GinkgoT().TempDir(), "fetched")
ORAS("blob", "fetch", RegistryRef(ZOTHost, ImageRepo, foobar.FooBlobDigest), "--output", contentPath, "--descriptor").
MatchContent(foobar.FooBlobDescriptor).Exec()
MatchFile(contentPath, foobar.FooBlobContent, DefaultTimeout)
})
})
})

var _ = Describe("OCI image layout users:", func() {
prepare := func(from string) string {
tmpRoot := GinkgoT().TempDir()
ORAS("cp", from, Flags.ToLayout, tmpRoot).WithDescription("prepare image from registry to OCI layout").Exec()
return tmpRoot
}
When("running `blob delete`", func() {
It("should not support deleting a blob", func() {
toDeleteRef := LayoutRef(prepare(RegistryRef(Host, ImageRepo, foobar.Tag)), foobar.FooBlobDigest)
toDeleteRef := LayoutRef(PrepareTempOCI(ImageRepo), foobar.FooBlobDigest)
ORAS("blob", "delete", Flags.Layout, toDeleteRef).
WithInput(strings.NewReader("y")).
MatchErrKeyWords("Error:", "unknown flag", Flags.Layout).
Expand All @@ -266,25 +255,25 @@ 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))
root := PrepareTempOCI(ImageRepo)
ORAS("blob", "fetch", Flags.Layout, 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))
root := PrepareTempOCI(ImageRepo)
ORAS("blob", "fetch", Flags.Layout, 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))
root := PrepareTempOCI(ImageRepo)
tempDir := GinkgoT().TempDir()
contentPath := filepath.Join(tempDir, "fetched")
ORAS("blob", "fetch", Flags.Layout, LayoutRef(root, foobar.FooBlobDigest), "--output", contentPath).
WithWorkDir(tempDir).Exec()
MatchFile(contentPath, foobar.FooBlobContent, DefaultTimeout)
})
It("should fetch blob descriptor and output content to a file", func() {
root := prepare(RegistryRef(Host, ImageRepo, foobar.Tag))
root := PrepareTempOCI(ImageRepo)
tempDir := GinkgoT().TempDir()
contentPath := filepath.Join(tempDir, "fetched")
ORAS("blob", "fetch", Flags.Layout, LayoutRef(root, foobar.FooBlobDigest), "--output", contentPath, "--descriptor").
Expand Down
2 changes: 1 addition & 1 deletion test/e2e/suite/command/discover.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ var _ = Describe("ORAS beginners:", func() {
})

It("should fail when no tag or digest found in provided subject reference", func() {
ORAS("discover", RegistryRef(Host, Repo, "")).ExpectFailure().MatchErrKeyWords("Error:", "invalid image reference").Exec()
ORAS("discover", RegistryRef(Host, ImageRepo, "")).ExpectFailure().MatchErrKeyWords("Error:", "invalid image reference").Exec()
})
})
})
Expand Down
Loading

0 comments on commit e3b124b

Please sign in to comment.