mirror of
https://github.com/project-zot/zot.git
synced 2025-02-17 23:45:36 -05:00
compliance: cleanup compliance test code
zot ci/cd tests are too stict, so separate and relax them for compliance tests. Location header is set in some cases, but some clarification is needed in URL construction. Fix some incorrect compliance tests.
This commit is contained in:
parent
e76804af4f
commit
a57f085749
5 changed files with 124 additions and 81 deletions
|
@ -42,6 +42,7 @@ func (c *Controller) Run() error {
|
|||
handlers.PrintRecoveryStack(false)))
|
||||
|
||||
c.Router = engine
|
||||
c.Router.UseEncodedPath()
|
||||
_ = NewRouteHandler(c)
|
||||
|
||||
c.ImageStore = storage.NewImageStore(c.Config.Storage.RootDirectory, c.Log)
|
||||
|
|
|
@ -6,7 +6,7 @@ import "regexp"
|
|||
var (
|
||||
// alphaNumericRegexp defines the alpha numeric atom, typically a
|
||||
// component of names. This only allows lower case characters and digits.
|
||||
alphaNumericRegexp = match(`[a-z0-9]+`)
|
||||
alphaNumericRegexp = match(`[a-zA-Z0-9]+`)
|
||||
|
||||
// separatorRegexp defines the separators allowed to be embedded in name
|
||||
// components. This allow one period, one or two underscore and multiple
|
||||
|
|
|
@ -838,7 +838,7 @@ func (rh *RouteHandler) DeleteBlobUpload(w http.ResponseWriter, r *http.Request)
|
|||
return
|
||||
}
|
||||
|
||||
w.WriteHeader(http.StatusOK)
|
||||
w.WriteHeader(http.StatusNoContent)
|
||||
}
|
||||
|
||||
type RepositoryList struct {
|
||||
|
|
|
@ -5,8 +5,9 @@ type Config struct {
|
|||
Port string
|
||||
Version string
|
||||
OutputJSON bool
|
||||
Compliance bool
|
||||
}
|
||||
|
||||
func NewConfig() *Config {
|
||||
return &Config{}
|
||||
return &Config{Compliance: true}
|
||||
}
|
||||
|
|
|
@ -19,6 +19,20 @@ import (
|
|||
"gopkg.in/resty.v1"
|
||||
)
|
||||
|
||||
func Location(baseURL string, resp *resty.Response, config *compliance.Config) string {
|
||||
// For some API responses, the Location header is set and is supposed to
|
||||
// indicate an opaque value. However, it is not clear if this value is an
|
||||
// absolute URL (https://server:port/v2/...) or just a path (/v2/...)
|
||||
// zot implements the latter as per the spec, but some registries appear to
|
||||
// return the former - this needs to be clarified
|
||||
loc := resp.Header().Get("Location")
|
||||
if config.Compliance {
|
||||
return loc
|
||||
}
|
||||
|
||||
return baseURL + loc
|
||||
}
|
||||
|
||||
func CheckWorkflows(t *testing.T, config *compliance.Config) {
|
||||
if config == nil || config.Address == "" || config.Port == "" {
|
||||
panic("insufficient config")
|
||||
|
@ -70,140 +84,152 @@ func CheckWorkflows(t *testing.T, config *compliance.Config) {
|
|||
So(resp.StatusCode(), ShouldEqual, 200)
|
||||
So(resp.String(), ShouldNotBeEmpty)
|
||||
r := resp.Result().(*api.RepositoryList)
|
||||
So(len(r.Repositories), ShouldBeGreaterThan, 0)
|
||||
So(r.Repositories[0], ShouldEqual, "a/b/c/d")
|
||||
So(r.Repositories[1], ShouldEqual, "z")
|
||||
if !config.Compliance {
|
||||
// stricter check for zot ci/cd
|
||||
So(len(r.Repositories), ShouldBeGreaterThan, 0)
|
||||
So(r.Repositories[0], ShouldEqual, "a/b/c/d")
|
||||
So(r.Repositories[1], ShouldEqual, "z")
|
||||
}
|
||||
})
|
||||
|
||||
Convey("Get images in a repository", func() {
|
||||
Print("\nGet images in a repository")
|
||||
// non-existent repository should fail
|
||||
resp, err := resty.R().Get(baseURL + "/v2/repo/tags/list")
|
||||
resp, err := resty.R().Get(baseURL + "/v2/repo1/tags/list")
|
||||
So(err, ShouldBeNil)
|
||||
So(resp.StatusCode(), ShouldEqual, 404)
|
||||
So(resp.String(), ShouldNotBeEmpty)
|
||||
|
||||
// after newly created upload should succeed
|
||||
resp, err = resty.R().Post(baseURL + "/v2/repo/blobs/uploads/")
|
||||
resp, err = resty.R().Post(baseURL + "/v2/repo1/blobs/uploads/")
|
||||
So(err, ShouldBeNil)
|
||||
So(resp.StatusCode(), ShouldEqual, 202)
|
||||
|
||||
resp, err = resty.R().Get(baseURL + "/v2/repo/tags/list")
|
||||
resp, err = resty.R().Get(baseURL + "/v2/repo1/tags/list")
|
||||
So(err, ShouldBeNil)
|
||||
So(resp.StatusCode(), ShouldEqual, 200)
|
||||
So(resp.String(), ShouldNotBeEmpty)
|
||||
if !config.Compliance {
|
||||
// stricter check for zot ci/cd
|
||||
So(resp.StatusCode(), ShouldEqual, 200)
|
||||
So(resp.String(), ShouldNotBeEmpty)
|
||||
}
|
||||
})
|
||||
|
||||
Convey("Monolithic blob upload", func() {
|
||||
Print("\nMonolithic blob upload")
|
||||
resp, err := resty.R().Post(baseURL + "/v2/repo/blobs/uploads/")
|
||||
resp, err := resty.R().Post(baseURL + "/v2/repo2/blobs/uploads/")
|
||||
So(err, ShouldBeNil)
|
||||
So(resp.StatusCode(), ShouldEqual, 202)
|
||||
loc := resp.Header().Get("Location")
|
||||
loc := Location(baseURL, resp, config)
|
||||
So(loc, ShouldNotBeEmpty)
|
||||
|
||||
resp, err = resty.R().Get(baseURL + loc)
|
||||
resp, err = resty.R().Get(loc)
|
||||
So(err, ShouldBeNil)
|
||||
So(resp.StatusCode(), ShouldEqual, 204)
|
||||
|
||||
resp, err = resty.R().Get(baseURL + "/v2/repo/tags/list")
|
||||
resp, err = resty.R().Get(baseURL + "/v2/repo2/tags/list")
|
||||
So(err, ShouldBeNil)
|
||||
So(resp.StatusCode(), ShouldEqual, 200)
|
||||
So(resp.String(), ShouldNotBeEmpty)
|
||||
if !config.Compliance {
|
||||
// stricter check for zot ci/cd
|
||||
So(resp.StatusCode(), ShouldEqual, 200)
|
||||
So(resp.String(), ShouldNotBeEmpty)
|
||||
}
|
||||
|
||||
// without a "?digest=<>" should fail
|
||||
content := []byte("this is a blob")
|
||||
digest := godigest.FromBytes(content)
|
||||
So(digest, ShouldNotBeNil)
|
||||
resp, err = resty.R().Put(baseURL + loc)
|
||||
resp, err = resty.R().Put(loc)
|
||||
So(err, ShouldBeNil)
|
||||
So(resp.StatusCode(), ShouldEqual, 400)
|
||||
// without the Content-Length should fail
|
||||
resp, err = resty.R().SetQueryParam("digest", digest.String()).Put(baseURL + loc)
|
||||
resp, err = resty.R().SetQueryParam("digest", digest.String()).Put(loc)
|
||||
So(err, ShouldBeNil)
|
||||
So(resp.StatusCode(), ShouldEqual, 400)
|
||||
// without any data to send, should fail
|
||||
resp, err = resty.R().SetQueryParam("digest", digest.String()).
|
||||
SetHeader("Content-Type", "application/octet-stream").Put(baseURL + loc)
|
||||
SetHeader("Content-Type", "application/octet-stream").Put(loc)
|
||||
So(err, ShouldBeNil)
|
||||
So(resp.StatusCode(), ShouldEqual, 400)
|
||||
// monolithic blob upload: success
|
||||
resp, err = resty.R().SetQueryParam("digest", digest.String()).
|
||||
SetHeader("Content-Type", "application/octet-stream").SetBody(content).Put(baseURL + loc)
|
||||
SetHeader("Content-Type", "application/octet-stream").SetBody(content).Put(loc)
|
||||
So(err, ShouldBeNil)
|
||||
So(resp.StatusCode(), ShouldEqual, 201)
|
||||
blobLoc := resp.Header().Get("Location")
|
||||
blobLoc := Location(baseURL, resp, config)
|
||||
So(blobLoc, ShouldNotBeEmpty)
|
||||
So(resp.Header().Get("Content-Length"), ShouldEqual, "0")
|
||||
So(resp.Header().Get(api.DistContentDigestKey), ShouldNotBeEmpty)
|
||||
// upload reference should now be removed
|
||||
resp, err = resty.R().Get(baseURL + loc)
|
||||
resp, err = resty.R().Get(loc)
|
||||
So(err, ShouldBeNil)
|
||||
So(resp.StatusCode(), ShouldEqual, 404)
|
||||
// blob reference should be accessible
|
||||
resp, err = resty.R().Get(baseURL + blobLoc)
|
||||
resp, err = resty.R().Get(blobLoc)
|
||||
So(err, ShouldBeNil)
|
||||
So(resp.StatusCode(), ShouldEqual, 200)
|
||||
})
|
||||
|
||||
Convey("Monolithic blob upload with multiple name components", func() {
|
||||
Print("\nMonolithic blob upload with multiple name components")
|
||||
resp, err := resty.R().Post(baseURL + "/v2/repo1/repo2/repo3/blobs/uploads/")
|
||||
resp, err := resty.R().Post(baseURL + "/v2/repo10/repo20/repo30/blobs/uploads/")
|
||||
So(err, ShouldBeNil)
|
||||
So(resp.StatusCode(), ShouldEqual, 202)
|
||||
loc := resp.Header().Get("Location")
|
||||
loc := Location(baseURL, resp, config)
|
||||
So(loc, ShouldNotBeEmpty)
|
||||
|
||||
resp, err = resty.R().Get(baseURL + loc)
|
||||
resp, err = resty.R().Get(loc)
|
||||
So(err, ShouldBeNil)
|
||||
So(resp.StatusCode(), ShouldEqual, 204)
|
||||
|
||||
resp, err = resty.R().Get(baseURL + "/v2/repo1/repo2/repo3/tags/list")
|
||||
resp, err = resty.R().Get(baseURL + "/v2/repo10/repo20/repo30/tags/list")
|
||||
So(err, ShouldBeNil)
|
||||
So(resp.StatusCode(), ShouldEqual, 200)
|
||||
So(resp.String(), ShouldNotBeEmpty)
|
||||
if !config.Compliance {
|
||||
// stricter check for zot ci/cd
|
||||
So(resp.StatusCode(), ShouldEqual, 200)
|
||||
So(resp.String(), ShouldNotBeEmpty)
|
||||
}
|
||||
|
||||
// without a "?digest=<>" should fail
|
||||
content := []byte("this is a blob")
|
||||
digest := godigest.FromBytes(content)
|
||||
So(digest, ShouldNotBeNil)
|
||||
resp, err = resty.R().Put(baseURL + loc)
|
||||
resp, err = resty.R().Put(loc)
|
||||
So(err, ShouldBeNil)
|
||||
So(resp.StatusCode(), ShouldEqual, 400)
|
||||
// without the Content-Length should fail
|
||||
resp, err = resty.R().SetQueryParam("digest", digest.String()).Put(baseURL + loc)
|
||||
resp, err = resty.R().SetQueryParam("digest", digest.String()).Put(loc)
|
||||
So(err, ShouldBeNil)
|
||||
So(resp.StatusCode(), ShouldEqual, 400)
|
||||
// without any data to send, should fail
|
||||
resp, err = resty.R().SetQueryParam("digest", digest.String()).
|
||||
SetHeader("Content-Type", "application/octet-stream").Put(baseURL + loc)
|
||||
SetHeader("Content-Type", "application/octet-stream").Put(loc)
|
||||
So(err, ShouldBeNil)
|
||||
So(resp.StatusCode(), ShouldEqual, 400)
|
||||
// monolithic blob upload: success
|
||||
resp, err = resty.R().SetQueryParam("digest", digest.String()).
|
||||
SetHeader("Content-Type", "application/octet-stream").SetBody(content).Put(baseURL + loc)
|
||||
SetHeader("Content-Type", "application/octet-stream").SetBody(content).Put(loc)
|
||||
So(err, ShouldBeNil)
|
||||
So(resp.StatusCode(), ShouldEqual, 201)
|
||||
blobLoc := resp.Header().Get("Location")
|
||||
blobLoc := Location(baseURL, resp, config)
|
||||
So(blobLoc, ShouldNotBeEmpty)
|
||||
So(resp.Header().Get("Content-Length"), ShouldEqual, "0")
|
||||
So(resp.Header().Get(api.DistContentDigestKey), ShouldNotBeEmpty)
|
||||
// upload reference should now be removed
|
||||
resp, err = resty.R().Get(baseURL + loc)
|
||||
resp, err = resty.R().Get(loc)
|
||||
So(err, ShouldBeNil)
|
||||
So(resp.StatusCode(), ShouldEqual, 404)
|
||||
// blob reference should be accessible
|
||||
resp, err = resty.R().Get(baseURL + blobLoc)
|
||||
resp, err = resty.R().Get(blobLoc)
|
||||
So(err, ShouldBeNil)
|
||||
So(resp.StatusCode(), ShouldEqual, 200)
|
||||
})
|
||||
|
||||
Convey("Chunked blob upload", func() {
|
||||
Print("\nChunked blob upload")
|
||||
resp, err := resty.R().Post(baseURL + "/v2/repo/blobs/uploads/")
|
||||
resp, err := resty.R().Post(baseURL + "/v2/repo3/blobs/uploads/")
|
||||
So(err, ShouldBeNil)
|
||||
So(resp.StatusCode(), ShouldEqual, 202)
|
||||
loc := resp.Header().Get("Location")
|
||||
loc := Location(baseURL, resp, config)
|
||||
So(loc, ShouldNotBeEmpty)
|
||||
|
||||
var buf bytes.Buffer
|
||||
|
@ -215,12 +241,12 @@ func CheckWorkflows(t *testing.T, config *compliance.Config) {
|
|||
// write first chunk
|
||||
contentRange := fmt.Sprintf("%d-%d", 0, len(chunk1))
|
||||
resp, err = resty.R().SetHeader("Content-Type", "application/octet-stream").
|
||||
SetHeader("Content-Range", contentRange).SetBody(chunk1).Patch(baseURL + loc)
|
||||
SetHeader("Content-Range", contentRange).SetBody(chunk1).Patch(loc)
|
||||
So(err, ShouldBeNil)
|
||||
So(resp.StatusCode(), ShouldEqual, 202)
|
||||
|
||||
// check progress
|
||||
resp, err = resty.R().Get(baseURL + loc)
|
||||
resp, err = resty.R().Get(loc)
|
||||
So(err, ShouldBeNil)
|
||||
So(resp.StatusCode(), ShouldEqual, 204)
|
||||
r := resp.Header().Get("Range")
|
||||
|
@ -230,7 +256,7 @@ func CheckWorkflows(t *testing.T, config *compliance.Config) {
|
|||
// write same chunk should fail
|
||||
contentRange = fmt.Sprintf("%d-%d", 0, len(chunk1))
|
||||
resp, err = resty.R().SetHeader("Content-Type", "application/octet-stream").
|
||||
SetHeader("Content-Range", contentRange).SetBody(chunk1).Patch(baseURL + loc)
|
||||
SetHeader("Content-Range", contentRange).SetBody(chunk1).Patch(loc)
|
||||
So(err, ShouldBeNil)
|
||||
So(resp.StatusCode(), ShouldEqual, 400)
|
||||
So(resp.String(), ShouldNotBeEmpty)
|
||||
|
@ -247,31 +273,31 @@ func CheckWorkflows(t *testing.T, config *compliance.Config) {
|
|||
contentRange = fmt.Sprintf("%d-%d", len(chunk1), len(buf.Bytes()))
|
||||
resp, err = resty.R().SetQueryParam("digest", digest.String()).
|
||||
SetHeader("Content-Range", contentRange).
|
||||
SetHeader("Content-Type", "application/octet-stream").SetBody(chunk2).Put(baseURL + loc)
|
||||
SetHeader("Content-Type", "application/octet-stream").SetBody(chunk2).Put(loc)
|
||||
So(err, ShouldBeNil)
|
||||
So(resp.StatusCode(), ShouldEqual, 201)
|
||||
blobLoc := resp.Header().Get("Location")
|
||||
blobLoc := Location(baseURL, resp, config)
|
||||
So(err, ShouldBeNil)
|
||||
So(resp.StatusCode(), ShouldEqual, 201)
|
||||
So(blobLoc, ShouldNotBeEmpty)
|
||||
So(resp.Header().Get("Content-Length"), ShouldEqual, "0")
|
||||
So(resp.Header().Get(api.DistContentDigestKey), ShouldNotBeEmpty)
|
||||
// upload reference should now be removed
|
||||
resp, err = resty.R().Get(baseURL + loc)
|
||||
resp, err = resty.R().Get(loc)
|
||||
So(err, ShouldBeNil)
|
||||
So(resp.StatusCode(), ShouldEqual, 404)
|
||||
// blob reference should be accessible
|
||||
resp, err = resty.R().Get(baseURL + blobLoc)
|
||||
resp, err = resty.R().Get(blobLoc)
|
||||
So(err, ShouldBeNil)
|
||||
So(resp.StatusCode(), ShouldEqual, 200)
|
||||
})
|
||||
|
||||
Convey("Chunked blob upload with multiple name components", func() {
|
||||
Print("\nChunked blob upload with multiple name components")
|
||||
resp, err := resty.R().Post(baseURL + "/v2/repo4/repo5/repo6/blobs/uploads/")
|
||||
resp, err := resty.R().Post(baseURL + "/v2/repo40/repo50/repo60/blobs/uploads/")
|
||||
So(err, ShouldBeNil)
|
||||
So(resp.StatusCode(), ShouldEqual, 202)
|
||||
loc := resp.Header().Get("Location")
|
||||
loc := Location(baseURL, resp, config)
|
||||
So(loc, ShouldNotBeEmpty)
|
||||
|
||||
var buf bytes.Buffer
|
||||
|
@ -283,12 +309,12 @@ func CheckWorkflows(t *testing.T, config *compliance.Config) {
|
|||
// write first chunk
|
||||
contentRange := fmt.Sprintf("%d-%d", 0, len(chunk1))
|
||||
resp, err = resty.R().SetHeader("Content-Type", "application/octet-stream").
|
||||
SetHeader("Content-Range", contentRange).SetBody(chunk1).Patch(baseURL + loc)
|
||||
SetHeader("Content-Range", contentRange).SetBody(chunk1).Patch(loc)
|
||||
So(err, ShouldBeNil)
|
||||
So(resp.StatusCode(), ShouldEqual, 202)
|
||||
|
||||
// check progress
|
||||
resp, err = resty.R().Get(baseURL + loc)
|
||||
resp, err = resty.R().Get(loc)
|
||||
So(err, ShouldBeNil)
|
||||
So(resp.StatusCode(), ShouldEqual, 204)
|
||||
r := resp.Header().Get("Range")
|
||||
|
@ -298,7 +324,7 @@ func CheckWorkflows(t *testing.T, config *compliance.Config) {
|
|||
// write same chunk should fail
|
||||
contentRange = fmt.Sprintf("%d-%d", 0, len(chunk1))
|
||||
resp, err = resty.R().SetHeader("Content-Type", "application/octet-stream").
|
||||
SetHeader("Content-Range", contentRange).SetBody(chunk1).Patch(baseURL + loc)
|
||||
SetHeader("Content-Range", contentRange).SetBody(chunk1).Patch(loc)
|
||||
So(err, ShouldBeNil)
|
||||
So(resp.StatusCode(), ShouldEqual, 400)
|
||||
So(resp.String(), ShouldNotBeEmpty)
|
||||
|
@ -315,21 +341,21 @@ func CheckWorkflows(t *testing.T, config *compliance.Config) {
|
|||
contentRange = fmt.Sprintf("%d-%d", len(chunk1), len(buf.Bytes()))
|
||||
resp, err = resty.R().SetQueryParam("digest", digest.String()).
|
||||
SetHeader("Content-Range", contentRange).
|
||||
SetHeader("Content-Type", "application/octet-stream").SetBody(chunk2).Put(baseURL + loc)
|
||||
SetHeader("Content-Type", "application/octet-stream").SetBody(chunk2).Put(loc)
|
||||
So(err, ShouldBeNil)
|
||||
So(resp.StatusCode(), ShouldEqual, 201)
|
||||
blobLoc := resp.Header().Get("Location")
|
||||
blobLoc := Location(baseURL, resp, config)
|
||||
So(err, ShouldBeNil)
|
||||
So(resp.StatusCode(), ShouldEqual, 201)
|
||||
So(blobLoc, ShouldNotBeEmpty)
|
||||
So(resp.Header().Get("Content-Length"), ShouldEqual, "0")
|
||||
So(resp.Header().Get(api.DistContentDigestKey), ShouldNotBeEmpty)
|
||||
// upload reference should now be removed
|
||||
resp, err = resty.R().Get(baseURL + loc)
|
||||
resp, err = resty.R().Get(loc)
|
||||
So(err, ShouldBeNil)
|
||||
So(resp.StatusCode(), ShouldEqual, 404)
|
||||
// blob reference should be accessible
|
||||
resp, err = resty.R().Get(baseURL + blobLoc)
|
||||
resp, err = resty.R().Get(blobLoc)
|
||||
So(err, ShouldBeNil)
|
||||
So(resp.StatusCode(), ShouldEqual, 200)
|
||||
})
|
||||
|
@ -337,25 +363,25 @@ func CheckWorkflows(t *testing.T, config *compliance.Config) {
|
|||
Convey("Create and delete uploads", func() {
|
||||
Print("\nCreate and delete uploads")
|
||||
// create a upload
|
||||
resp, err := resty.R().Post(baseURL + "/v2/repo/blobs/uploads/")
|
||||
resp, err := resty.R().Post(baseURL + "/v2/repo4/blobs/uploads/")
|
||||
So(err, ShouldBeNil)
|
||||
So(resp.StatusCode(), ShouldEqual, 202)
|
||||
loc := resp.Header().Get("Location")
|
||||
loc := Location(baseURL, resp, config)
|
||||
So(loc, ShouldNotBeEmpty)
|
||||
|
||||
// delete this upload
|
||||
resp, err = resty.R().Delete(baseURL + loc)
|
||||
resp, err = resty.R().Delete(loc)
|
||||
So(err, ShouldBeNil)
|
||||
So(resp.StatusCode(), ShouldEqual, 200)
|
||||
So(resp.StatusCode(), ShouldEqual, 204)
|
||||
})
|
||||
|
||||
Convey("Create and delete blobs", func() {
|
||||
Print("\nCreate and delete blobs")
|
||||
// create a upload
|
||||
resp, err := resty.R().Post(baseURL + "/v2/repo/blobs/uploads/")
|
||||
resp, err := resty.R().Post(baseURL + "/v2/repo5/blobs/uploads/")
|
||||
So(err, ShouldBeNil)
|
||||
So(resp.StatusCode(), ShouldEqual, 202)
|
||||
loc := resp.Header().Get("Location")
|
||||
loc := Location(baseURL, resp, config)
|
||||
So(loc, ShouldNotBeEmpty)
|
||||
|
||||
content := []byte("this is a blob")
|
||||
|
@ -363,15 +389,15 @@ func CheckWorkflows(t *testing.T, config *compliance.Config) {
|
|||
So(digest, ShouldNotBeNil)
|
||||
// monolithic blob upload
|
||||
resp, err = resty.R().SetQueryParam("digest", digest.String()).
|
||||
SetHeader("Content-Type", "application/octet-stream").SetBody(content).Put(baseURL + loc)
|
||||
SetHeader("Content-Type", "application/octet-stream").SetBody(content).Put(loc)
|
||||
So(err, ShouldBeNil)
|
||||
So(resp.StatusCode(), ShouldEqual, 201)
|
||||
blobLoc := resp.Header().Get("Location")
|
||||
blobLoc := Location(baseURL, resp, config)
|
||||
So(blobLoc, ShouldNotBeEmpty)
|
||||
So(resp.Header().Get(api.DistContentDigestKey), ShouldNotBeEmpty)
|
||||
|
||||
// delete this blob
|
||||
resp, err = resty.R().Delete(baseURL + blobLoc)
|
||||
resp, err = resty.R().Delete(blobLoc)
|
||||
So(err, ShouldBeNil)
|
||||
So(resp.StatusCode(), ShouldEqual, 202)
|
||||
So(resp.Header().Get("Content-Length"), ShouldEqual, "0")
|
||||
|
@ -380,21 +406,21 @@ func CheckWorkflows(t *testing.T, config *compliance.Config) {
|
|||
Convey("Mount blobs", func() {
|
||||
Print("\nMount blobs from another repository")
|
||||
// create a upload
|
||||
resp, err := resty.R().Post(baseURL + "/v2/repo/blobs/uploads/?digest=\"abc\"&&from=\"xyz\"")
|
||||
resp, err := resty.R().Post(baseURL + "/v2/repo6/blobs/uploads/?digest=\"abc\"&&from=\"xyz\"")
|
||||
So(err, ShouldBeNil)
|
||||
So(resp.StatusCode(), ShouldEqual, 405)
|
||||
So(resp.StatusCode(), ShouldBeIn, []int{201, 202, 405})
|
||||
})
|
||||
|
||||
Convey("Manifests", func() {
|
||||
Print("\nManifests")
|
||||
// create a blob/layer
|
||||
resp, err := resty.R().Post(baseURL + "/v2/repo/blobs/uploads/")
|
||||
resp, err := resty.R().Post(baseURL + "/v2/repo7/blobs/uploads/")
|
||||
So(err, ShouldBeNil)
|
||||
So(resp.StatusCode(), ShouldEqual, 202)
|
||||
loc := resp.Header().Get("Location")
|
||||
loc := Location(baseURL, resp, config)
|
||||
So(loc, ShouldNotBeEmpty)
|
||||
|
||||
resp, err = resty.R().Get(baseURL + loc)
|
||||
resp, err = resty.R().Get(loc)
|
||||
So(err, ShouldBeNil)
|
||||
So(resp.StatusCode(), ShouldEqual, 204)
|
||||
content := []byte("this is a blob")
|
||||
|
@ -402,7 +428,7 @@ func CheckWorkflows(t *testing.T, config *compliance.Config) {
|
|||
So(digest, ShouldNotBeNil)
|
||||
// monolithic blob upload: success
|
||||
resp, err = resty.R().SetQueryParam("digest", digest.String()).
|
||||
SetHeader("Content-Type", "application/octet-stream").SetBody(content).Put(baseURL + loc)
|
||||
SetHeader("Content-Type", "application/octet-stream").SetBody(content).Put(loc)
|
||||
So(err, ShouldBeNil)
|
||||
So(resp.StatusCode(), ShouldEqual, 201)
|
||||
blobLoc := resp.Header().Get("Location")
|
||||
|
@ -417,7 +443,7 @@ func CheckWorkflows(t *testing.T, config *compliance.Config) {
|
|||
digest = godigest.FromBytes(content)
|
||||
So(digest, ShouldNotBeNil)
|
||||
resp, err = resty.R().SetHeader("Content-Type", "application/vnd.oci.image.manifest.v1+json").
|
||||
SetBody(content).Put(baseURL + "/v2/repo/manifests/test:1.0")
|
||||
SetBody(content).Put(baseURL + "/v2/repo7/manifests/test:1.0")
|
||||
So(err, ShouldBeNil)
|
||||
So(resp.StatusCode(), ShouldEqual, 201)
|
||||
d := resp.Header().Get(api.DistContentDigestKey)
|
||||
|
@ -425,48 +451,63 @@ func CheckWorkflows(t *testing.T, config *compliance.Config) {
|
|||
So(d, ShouldEqual, digest.String())
|
||||
|
||||
// check/get by tag
|
||||
resp, err = resty.R().Head(baseURL + "/v2/repo/manifests/test:1.0")
|
||||
resp, err = resty.R().Head(baseURL + "/v2/repo7/manifests/test:1.0")
|
||||
So(err, ShouldBeNil)
|
||||
So(resp.StatusCode(), ShouldEqual, 200)
|
||||
resp, err = resty.R().Get(baseURL + "/v2/repo/manifests/test:1.0")
|
||||
resp, err = resty.R().Get(baseURL + "/v2/repo7/manifests/test:1.0")
|
||||
So(err, ShouldBeNil)
|
||||
So(resp.StatusCode(), ShouldEqual, 200)
|
||||
So(resp.Body(), ShouldNotBeEmpty)
|
||||
// check/get by reference
|
||||
resp, err = resty.R().Head(baseURL + "/v2/repo/manifests/" + digest.String())
|
||||
resp, err = resty.R().Head(baseURL + "/v2/repo7/manifests/" + digest.String())
|
||||
So(err, ShouldBeNil)
|
||||
So(resp.StatusCode(), ShouldEqual, 200)
|
||||
resp, err = resty.R().Get(baseURL + "/v2/repo/manifests/" + digest.String())
|
||||
resp, err = resty.R().Get(baseURL + "/v2/repo7/manifests/" + digest.String())
|
||||
So(err, ShouldBeNil)
|
||||
So(resp.StatusCode(), ShouldEqual, 200)
|
||||
So(resp.Body(), ShouldNotBeEmpty)
|
||||
|
||||
// delete manifest
|
||||
resp, err = resty.R().Delete(baseURL + "/v2/repo/manifests/test:1.0")
|
||||
resp, err = resty.R().Delete(baseURL + "/v2/repo7/manifests/test:1.0")
|
||||
So(err, ShouldBeNil)
|
||||
So(resp.StatusCode(), ShouldEqual, 200)
|
||||
// delete again should fail
|
||||
resp, err = resty.R().Delete(baseURL + "/v2/repo/manifests/" + digest.String())
|
||||
resp, err = resty.R().Delete(baseURL + "/v2/repo7/manifests/" + digest.String())
|
||||
So(err, ShouldBeNil)
|
||||
So(resp.StatusCode(), ShouldEqual, 404)
|
||||
|
||||
// check/get by tag
|
||||
resp, err = resty.R().Head(baseURL + "/v2/repo/manifests/test:1.0")
|
||||
resp, err = resty.R().Head(baseURL + "/v2/repo7/manifests/test:1.0")
|
||||
So(err, ShouldBeNil)
|
||||
So(resp.StatusCode(), ShouldEqual, 404)
|
||||
resp, err = resty.R().Get(baseURL + "/v2/repo/manifests/test:1.0")
|
||||
resp, err = resty.R().Get(baseURL + "/v2/repo7/manifests/test:1.0")
|
||||
So(err, ShouldBeNil)
|
||||
So(resp.StatusCode(), ShouldEqual, 404)
|
||||
So(resp.Body(), ShouldNotBeEmpty)
|
||||
// check/get by reference
|
||||
resp, err = resty.R().Head(baseURL + "/v2/repo/manifests/" + digest.String())
|
||||
resp, err = resty.R().Head(baseURL + "/v2/repo7/manifests/" + digest.String())
|
||||
So(err, ShouldBeNil)
|
||||
So(resp.StatusCode(), ShouldEqual, 404)
|
||||
resp, err = resty.R().Get(baseURL + "/v2/repo/manifests/" + digest.String())
|
||||
resp, err = resty.R().Get(baseURL + "/v2/repo7/manifests/" + digest.String())
|
||||
So(err, ShouldBeNil)
|
||||
So(resp.StatusCode(), ShouldEqual, 404)
|
||||
So(resp.Body(), ShouldNotBeEmpty)
|
||||
})
|
||||
|
||||
// this is an additional test for repository names (alphanumeric)
|
||||
Convey("Repository names", func() {
|
||||
Print("\nRepository names")
|
||||
// create a blob/layer
|
||||
resp, err := resty.R().Post(baseURL + "/v2/repotest/blobs/uploads/")
|
||||
So(err, ShouldBeNil)
|
||||
So(resp.StatusCode(), ShouldEqual, 202)
|
||||
resp, err = resty.R().Post(baseURL + "/v2/repotest123/blobs/uploads/")
|
||||
So(err, ShouldBeNil)
|
||||
So(resp.StatusCode(), ShouldEqual, 202)
|
||||
resp, err = resty.R().Post(baseURL + "/v2/repoTest123/blobs/uploads/")
|
||||
So(err, ShouldBeNil)
|
||||
So(resp.StatusCode(), ShouldEqual, 202)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue