0
Fork 0
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:
Ramkumar Chinchani 2019-12-23 22:32:52 -08:00
parent e76804af4f
commit a57f085749
5 changed files with 124 additions and 81 deletions

View file

@ -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)

View file

@ -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

View file

@ -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 {

View file

@ -5,8 +5,9 @@ type Config struct {
Port string
Version string
OutputJSON bool
Compliance bool
}
func NewConfig() *Config {
return &Config{}
return &Config{Compliance: true}
}

View file

@ -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)
})
})
}