fix(quota): order by quotas only on support resources

Signed-off-by: He Weiwei <hweiwei@vmware.com>
This commit is contained in:
He Weiwei 2019-10-30 02:42:34 +00:00
parent 943c364612
commit 3c80832341
5 changed files with 90 additions and 9 deletions

View File

@ -220,16 +220,19 @@ func quotaOrderBy(query ...*models.QuotaQuery) string {
sort = sort[1:]
}
prefix := []string{"hard.", "used."}
for _, p := range prefix {
if strings.HasPrefix(sort, p) {
field := fmt.Sprintf("%s->>'%s'", strings.TrimSuffix(p, "."), strings.TrimPrefix(sort, p))
prefixes := []string{"hard.", "used."}
for _, prefix := range prefixes {
if strings.HasPrefix(sort, prefix) {
resource := strings.TrimPrefix(sort, prefix)
if types.IsValidResource(types.ResourceName(resource)) {
field := fmt.Sprintf("%s->>'%s'", strings.TrimSuffix(prefix, "."), resource)
orderBy = fmt.Sprintf("(%s) %s", castQuantity(field), order)
break
}
}
}
}
}
return orderBy
}

View File

@ -141,3 +141,36 @@ func (suite *QuotaDaoSuite) TestListQuotas() {
func TestRunQuotaDaoSuite(t *testing.T) {
suite.Run(t, new(QuotaDaoSuite))
}
func Test_quotaOrderBy(t *testing.T) {
query := func(sort string) []*models.QuotaQuery {
return []*models.QuotaQuery{
{Sorting: models.Sorting{Sort: sort}},
}
}
type args struct {
query []*models.QuotaQuery
}
tests := []struct {
name string
args args
want string
}{
{"no query", args{nil}, "b.creation_time DESC"},
{"order by unsupport field", args{query("unknow")}, "b.creation_time DESC"},
{"order by count of hard", args{query("hard.count")}, "(CAST( (CASE WHEN (hard->>'count') IS NULL THEN '0' WHEN (hard->>'count') = '-1' THEN '9223372036854775807' ELSE (hard->>'count') END) AS BIGINT )) ASC"},
{"order by storage of hard", args{query("hard.storage")}, "(CAST( (CASE WHEN (hard->>'storage') IS NULL THEN '0' WHEN (hard->>'storage') = '-1' THEN '9223372036854775807' ELSE (hard->>'storage') END) AS BIGINT )) ASC"},
{"order by unsupport hard resource", args{query("hard.unknow")}, "b.creation_time DESC"},
{"order by count of used", args{query("used.count")}, "(CAST( (CASE WHEN (used->>'count') IS NULL THEN '0' WHEN (used->>'count') = '-1' THEN '9223372036854775807' ELSE (used->>'count') END) AS BIGINT )) ASC"},
{"order by storage of used", args{query("used.storage")}, "(CAST( (CASE WHEN (used->>'storage') IS NULL THEN '0' WHEN (used->>'storage') = '-1' THEN '9223372036854775807' ELSE (used->>'storage') END) AS BIGINT )) ASC"},
{"order by unsupport used resource", args{query("used.unknow")}, "b.creation_time DESC"},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := quotaOrderBy(tt.args.query...); got != tt.want {
t.Errorf("quotaOrderBy() = %v, want %v", got, tt.want)
}
})
}
}

View File

@ -21,6 +21,7 @@ import (
"github.com/astaxie/beego/orm"
"github.com/goharbor/harbor/src/common/models"
"github.com/goharbor/harbor/src/pkg/types"
)
var (
@ -127,15 +128,19 @@ func quotaUsageOrderBy(query ...*models.QuotaUsageQuery) string {
} else {
sort := query[0].Sort
order := "asc"
order := "ASC"
if sort[0] == '-' {
order = "desc"
order = "DESC"
sort = sort[1:]
}
prefix := "used."
if strings.HasPrefix(sort, prefix) {
orderBy = fmt.Sprintf("used->>'%s' %s", strings.TrimPrefix(sort, prefix), order)
resource := strings.TrimPrefix(sort, prefix)
if types.IsValidResource(types.ResourceName(resource)) {
field := fmt.Sprintf("%s->>'%s'", strings.TrimSuffix(prefix, "."), resource)
orderBy = fmt.Sprintf("(%s) %s", castQuantity(field), order)
}
}
}
}

View File

@ -133,3 +133,33 @@ func (suite *QuotaUsageDaoSuite) TestListQuotaUsages() {
func TestRunQuotaUsageDaoSuite(t *testing.T) {
suite.Run(t, new(QuotaUsageDaoSuite))
}
func Test_quotaUsageOrderBy(t *testing.T) {
query := func(sort string) []*models.QuotaUsageQuery {
return []*models.QuotaUsageQuery{
{Sorting: models.Sorting{Sort: sort}},
}
}
type args struct {
query []*models.QuotaUsageQuery
}
tests := []struct {
name string
args args
want string
}{
{"no query", args{nil}, ""},
{"order by unsupport field", args{query("unknow")}, ""},
{"order by count of used", args{query("used.count")}, "(CAST( (CASE WHEN (used->>'count') IS NULL THEN '0' WHEN (used->>'count') = '-1' THEN '9223372036854775807' ELSE (used->>'count') END) AS BIGINT )) ASC"},
{"order by storage of used", args{query("used.storage")}, "(CAST( (CASE WHEN (used->>'storage') IS NULL THEN '0' WHEN (used->>'storage') = '-1' THEN '9223372036854775807' ELSE (used->>'storage') END) AS BIGINT )) ASC"},
{"order by unsupport used resource", args{query("used.unknow")}, ""},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := quotaUsageOrderBy(tt.args.query...); got != tt.want {
t.Errorf("quotaUsageOrderBy() = %v, want %v", got, tt.want)
}
})
}
}

View File

@ -135,3 +135,13 @@ func IsNegative(a ResourceList) []ResourceName {
}
return results
}
// IsValidResource returns true when resource was supported
func IsValidResource(resource ResourceName) bool {
switch resource {
case ResourceCount, ResourceStorage:
return true
default:
return false
}
}