fix Conformance testing failure

1, Return DIGEST_INVALID error in delete manifest instead of NOT_FOUND
2, Disable return 500 in immutable middleware
3, Return empty array in catalog and tags API instead of null

Signed-off-by: wang yan <wangyan@vmware.com>
This commit is contained in:
wang yan 2020-03-08 00:16:26 +08:00
parent e86d3a728c
commit 18bd2f162c
9 changed files with 35 additions and 13 deletions

View File

@ -96,6 +96,8 @@ const (
PROJECTPOLICYVIOLATION = "PROJECTPOLICYVIOLATION"
// ViolateForeignKeyConstraintCode is the error code for violating foreign key constraint error
ViolateForeignKeyConstraintCode = "VIOLATE_FOREIGN_KEY_CONSTRAINT"
// DIGESTINVALID ...
DIGESTINVALID = "DIGEST_INVALID"
)
// New ...

View File

@ -29,6 +29,7 @@ import (
var (
codeMap = map[string]int{
ierror.BadRequestCode: http.StatusBadRequest,
ierror.DIGESTINVALID: http.StatusBadRequest,
ierror.UnAuthorizedCode: http.StatusUnauthorized,
ierror.ForbiddenCode: http.StatusForbidden,
ierror.DENIED: http.StatusForbidden,

View File

@ -6,6 +6,7 @@ import (
"github.com/goharbor/harbor/src/api/artifact"
"github.com/goharbor/harbor/src/api/tag"
common_util "github.com/goharbor/harbor/src/common/utils"
"github.com/goharbor/harbor/src/common/utils/log"
internal_errors "github.com/goharbor/harbor/src/internal/error"
serror "github.com/goharbor/harbor/src/server/error"
"github.com/goharbor/harbor/src/server/middleware"
@ -46,10 +47,8 @@ func handlePush(req *http.Request) error {
TagOption: &tag.Option{WithImmutableStatus: true},
})
if err != nil {
if internal_errors.IsErr(err, internal_errors.NotFoundCode) {
return nil
}
return err
log.Debugf("failed to list artifact, %v", err.Error())
return nil
}
_, repoName := common_util.ParseRepository(art.Repository)

View File

@ -52,7 +52,7 @@ func (r *repositoryHandler) ServeHTTP(w http.ResponseWriter, req *http.Request)
}
}
var repoNames []string
repoNames := make([]string, 0)
// get all repositories
// ToDo filter out the untagged repos
repoRecords, err := r.repoCtl.List(req.Context(), nil)

View File

@ -19,6 +19,7 @@ import (
"github.com/goharbor/harbor/src/api/repository"
"github.com/goharbor/harbor/src/common/utils/log"
"github.com/goharbor/harbor/src/internal"
ierror "github.com/goharbor/harbor/src/internal/error"
serror "github.com/goharbor/harbor/src/server/error"
"github.com/goharbor/harbor/src/server/router"
"github.com/opencontainers/go-digest"
@ -51,6 +52,18 @@ func getManifest(w http.ResponseWriter, req *http.Request) {
func deleteManifest(w http.ResponseWriter, req *http.Request) {
repository := router.Param(req.Context(), ":splat")
reference := router.Param(req.Context(), ":reference")
// v2 doesn't support delete by tag
// add parse digest here is to return ErrDigestInvalidFormat before GetByReference throws an NOT_FOUND(404)
// Do not add the logic into GetByReference as it's a shared method for PUT/GET/DELETE/Internal call,
// and NOT_FOUND satisfy PUT/GET/Internal call.
if _, err := digest.Parse(reference); err != nil {
switch err {
case digest.ErrDigestInvalidFormat:
serror.SendError(w, ierror.New(nil).WithCode(ierror.DIGESTINVALID).
WithMessage(digest.ErrDigestInvalidFormat.Error()))
return
}
}
art, err := artifact.Ctl.GetByReference(req.Context(), repository, reference, nil)
if err != nil {
serror.SendError(w, err)

View File

@ -15,6 +15,9 @@
package registry
import (
"context"
beegocontext "github.com/astaxie/beego/context"
"github.com/goharbor/harbor/src/server/router"
"net/http"
"net/http/httptest"
"testing"
@ -99,7 +102,7 @@ func (m *manifestTestSuite) TestDeleteManifest() {
mock.OnAnything(m.artCtl, "GetByReference").Return(nil, ierror.New(nil).WithCode(ierror.NotFoundCode))
deleteManifest(w, req)
m.Equal(http.StatusNotFound, w.Code)
m.Equal(http.StatusBadRequest, w.Code)
// reset the mock
m.SetupTest()
@ -116,7 +119,10 @@ func (m *manifestTestSuite) TestDeleteManifest() {
}
w.WriteHeader(http.StatusOK)
})
req = httptest.NewRequest(http.MethodDelete, "/v2/library/hello-world/manifests/latest", nil)
req = httptest.NewRequest(http.MethodDelete, "/v2/library/hello-world/manifests/sha256:418fb88ec412e340cdbef913b8ca1bbe8f9e8dc705f9617414c1f2c8db980180", nil)
input := &beegocontext.BeegoInput{}
input.SetParam(":reference", "sha527:418fb88ec412e340cdbef913b8ca1bbe8f9e8dc705f9617414c1f2c8db980180")
*req = *(req.WithContext(context.WithValue(req.Context(), router.ContextKeyInput{}, input)))
w = &httptest.ResponseRecorder{}
mock.OnAnything(m.artCtl, "GetByReference").Return(&artifact.Artifact{}, nil)
mock.OnAnything(m.artCtl, "Delete").Return(nil)

View File

@ -70,7 +70,7 @@ func (t *tagHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
}
}
var tagNames []string
tagNames := make([]string, 0)
t.repositoryName = router.Param(req.Context(), ":splat")
repository, err := t.repoCtl.GetByName(req.Context(), t.repositoryName)

View File

@ -23,7 +23,8 @@ import (
"path/filepath"
)
type contextKeyInput struct{}
// ContextKeyInput ...
type ContextKeyInput struct{}
// NewRoute creates a new route
func NewRoute() *Route {
@ -83,7 +84,7 @@ func (r *Route) Handler(handler http.Handler) {
middlewares = append(middlewares, r.middlewares...)
filterFunc := beego.FilterFunc(func(ctx *beegocontext.Context) {
ctx.Request = ctx.Request.WithContext(
context.WithValue(ctx.Request.Context(), contextKeyInput{}, ctx.Input))
context.WithValue(ctx.Request.Context(), ContextKeyInput{}, ctx.Input))
// TODO remove the WithMiddlewares?
middleware.WithMiddlewares(handler, middlewares...).
ServeHTTP(ctx.ResponseWriter, ctx.Request)
@ -123,7 +124,7 @@ func Param(ctx context.Context, key string) string {
if ctx == nil {
return ""
}
input, ok := ctx.Value(contextKeyInput{}).(*beegocontext.BeegoInput)
input, ok := ctx.Value(ContextKeyInput{}).(*beegocontext.BeegoInput)
if !ok {
return ""
}

View File

@ -65,13 +65,13 @@ func (r *routerTestSuite) TestParam() {
r.Empty(value)
// context contains wrong type input
value = Param(context.WithValue(context.Background(), contextKeyInput{}, &Route{}), "key")
value = Param(context.WithValue(context.Background(), ContextKeyInput{}, &Route{}), "key")
r.Empty(value)
// success
input := &beegocontext.BeegoInput{}
input.SetParam("key", "value")
value = Param(context.WithValue(context.Background(), contextKeyInput{}, input), "key")
value = Param(context.WithValue(context.Background(), ContextKeyInput{}, input), "key")
r.Equal("value", value)
}