mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Quota: Do not count folders towards dashboard quota (#32519)
For dashboard quota fix so that folders are not counted as dashboards. Fixes #31317 Co-authored-by: Marcus Efraimsson <marcus.efraimsson@gmail.com>
This commit is contained in:
parent
c2e761f28e
commit
83abaa8bdf
@ -75,7 +75,12 @@ func (qs *QuotaService) QuotaReached(c *models.ReqContext, target string) (bool,
|
|||||||
if !c.IsSignedIn {
|
if !c.IsSignedIn {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
query := models.GetOrgQuotaByTargetQuery{OrgId: c.OrgId, Target: scope.Target, Default: scope.DefaultLimit, IsNgAlertEnabled: qs.Cfg.IsNgAlertEnabled()}
|
query := models.GetOrgQuotaByTargetQuery{
|
||||||
|
OrgId: c.OrgId,
|
||||||
|
Target: scope.Target,
|
||||||
|
Default: scope.DefaultLimit,
|
||||||
|
IsNgAlertEnabled: qs.Cfg.IsNgAlertEnabled(),
|
||||||
|
}
|
||||||
if err := bus.Dispatch(&query); err != nil {
|
if err := bus.Dispatch(&query); err != nil {
|
||||||
return true, err
|
return true, err
|
||||||
}
|
}
|
||||||
@ -130,8 +135,16 @@ func (qs *QuotaService) getQuotaScopes(target string) ([]models.QuotaScope, erro
|
|||||||
return scopes, nil
|
return scopes, nil
|
||||||
case "dashboard":
|
case "dashboard":
|
||||||
scopes = append(scopes,
|
scopes = append(scopes,
|
||||||
models.QuotaScope{Name: "global", Target: target, DefaultLimit: qs.Cfg.Quota.Global.Dashboard},
|
models.QuotaScope{
|
||||||
models.QuotaScope{Name: "org", Target: target, DefaultLimit: qs.Cfg.Quota.Org.Dashboard},
|
Name: "global",
|
||||||
|
Target: target,
|
||||||
|
DefaultLimit: qs.Cfg.Quota.Global.Dashboard,
|
||||||
|
},
|
||||||
|
models.QuotaScope{
|
||||||
|
Name: "org",
|
||||||
|
Target: target,
|
||||||
|
DefaultLimit: qs.Cfg.Quota.Org.Dashboard,
|
||||||
|
},
|
||||||
)
|
)
|
||||||
return scopes, nil
|
return scopes, nil
|
||||||
case "data_source":
|
case "data_source":
|
||||||
|
@ -9,7 +9,10 @@ import (
|
|||||||
"github.com/grafana/grafana/pkg/setting"
|
"github.com/grafana/grafana/pkg/setting"
|
||||||
)
|
)
|
||||||
|
|
||||||
const ALERT_RULE_TARGET = "alert_rule"
|
const (
|
||||||
|
alertRuleTarget = "alert_rule"
|
||||||
|
dashboardTarget = "dashboard"
|
||||||
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
bus.AddHandler("sql", GetOrgQuotaByTarget)
|
bus.AddHandler("sql", GetOrgQuotaByTarget)
|
||||||
@ -38,9 +41,15 @@ func GetOrgQuotaByTarget(query *models.GetOrgQuotaByTargetQuery) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var used int64
|
var used int64
|
||||||
if query.Target != ALERT_RULE_TARGET || query.IsNgAlertEnabled {
|
if query.Target != alertRuleTarget || query.IsNgAlertEnabled {
|
||||||
// get quota used.
|
// get quota used.
|
||||||
rawSQL := fmt.Sprintf("SELECT COUNT(*) as count from %s where org_id=?", dialect.Quote(query.Target))
|
rawSQL := fmt.Sprintf("SELECT COUNT(*) AS count FROM %s WHERE org_id=?",
|
||||||
|
dialect.Quote(query.Target))
|
||||||
|
|
||||||
|
if query.Target == dashboardTarget {
|
||||||
|
rawSQL += fmt.Sprintf(" AND is_folder=%s", dialect.BooleanStr(false))
|
||||||
|
}
|
||||||
|
|
||||||
resp := make([]*targetCount, 0)
|
resp := make([]*targetCount, 0)
|
||||||
if err := x.SQL(rawSQL, query.OrgId).Find(&resp); err != nil {
|
if err := x.SQL(rawSQL, query.OrgId).Find(&resp); err != nil {
|
||||||
return err
|
return err
|
||||||
@ -85,7 +94,7 @@ func GetOrgQuotas(query *models.GetOrgQuotasQuery) error {
|
|||||||
result := make([]*models.OrgQuotaDTO, len(quotas))
|
result := make([]*models.OrgQuotaDTO, len(quotas))
|
||||||
for i, q := range quotas {
|
for i, q := range quotas {
|
||||||
var used int64
|
var used int64
|
||||||
if q.Target != ALERT_RULE_TARGET || query.IsNgAlertEnabled {
|
if q.Target != alertRuleTarget || query.IsNgAlertEnabled {
|
||||||
// get quota used.
|
// get quota used.
|
||||||
rawSQL := fmt.Sprintf("SELECT COUNT(*) as count from %s where org_id=?", dialect.Quote(q.Target))
|
rawSQL := fmt.Sprintf("SELECT COUNT(*) as count from %s where org_id=?", dialect.Quote(q.Target))
|
||||||
resp := make([]*targetCount, 0)
|
resp := make([]*targetCount, 0)
|
||||||
@ -149,7 +158,7 @@ func GetUserQuotaByTarget(query *models.GetUserQuotaByTargetQuery) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var used int64
|
var used int64
|
||||||
if query.Target != ALERT_RULE_TARGET || query.IsNgAlertEnabled {
|
if query.Target != alertRuleTarget || query.IsNgAlertEnabled {
|
||||||
// get quota used.
|
// get quota used.
|
||||||
rawSQL := fmt.Sprintf("SELECT COUNT(*) as count from %s where user_id=?", dialect.Quote(query.Target))
|
rawSQL := fmt.Sprintf("SELECT COUNT(*) as count from %s where user_id=?", dialect.Quote(query.Target))
|
||||||
resp := make([]*targetCount, 0)
|
resp := make([]*targetCount, 0)
|
||||||
@ -196,7 +205,7 @@ func GetUserQuotas(query *models.GetUserQuotasQuery) error {
|
|||||||
result := make([]*models.UserQuotaDTO, len(quotas))
|
result := make([]*models.UserQuotaDTO, len(quotas))
|
||||||
for i, q := range quotas {
|
for i, q := range quotas {
|
||||||
var used int64
|
var used int64
|
||||||
if q.Target != ALERT_RULE_TARGET || query.IsNgAlertEnabled {
|
if q.Target != alertRuleTarget || query.IsNgAlertEnabled {
|
||||||
// get quota used.
|
// get quota used.
|
||||||
rawSQL := fmt.Sprintf("SELECT COUNT(*) as count from %s where user_id=?", dialect.Quote(q.Target))
|
rawSQL := fmt.Sprintf("SELECT COUNT(*) as count from %s where user_id=?", dialect.Quote(q.Target))
|
||||||
resp := make([]*targetCount, 0)
|
resp := make([]*targetCount, 0)
|
||||||
@ -249,10 +258,15 @@ func UpdateUserQuota(cmd *models.UpdateUserQuotaCmd) error {
|
|||||||
|
|
||||||
func GetGlobalQuotaByTarget(query *models.GetGlobalQuotaByTargetQuery) error {
|
func GetGlobalQuotaByTarget(query *models.GetGlobalQuotaByTargetQuery) error {
|
||||||
var used int64
|
var used int64
|
||||||
if query.Target != ALERT_RULE_TARGET || query.IsNgAlertEnabled {
|
if query.Target != alertRuleTarget || query.IsNgAlertEnabled {
|
||||||
// get quota used.
|
// get quota used.
|
||||||
|
rawSQL := fmt.Sprintf("SELECT COUNT(*) AS count FROM %s",
|
||||||
|
dialect.Quote(query.Target))
|
||||||
|
|
||||||
|
if query.Target == dashboardTarget {
|
||||||
|
rawSQL += fmt.Sprintf(" WHERE is_folder=%s", dialect.BooleanStr(false))
|
||||||
|
}
|
||||||
|
|
||||||
rawSQL := fmt.Sprintf("SELECT COUNT(*) as count from %s", dialect.Quote(query.Target))
|
|
||||||
resp := make([]*targetCount, 0)
|
resp := make([]*targetCount, 0)
|
||||||
if err := x.SQL(rawSQL).Find(&resp); err != nil {
|
if err := x.SQL(rawSQL).Find(&resp); err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -8,247 +8,285 @@ import (
|
|||||||
|
|
||||||
"github.com/grafana/grafana/pkg/models"
|
"github.com/grafana/grafana/pkg/models"
|
||||||
"github.com/grafana/grafana/pkg/setting"
|
"github.com/grafana/grafana/pkg/setting"
|
||||||
. "github.com/smartystreets/goconvey/convey"
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestQuotaCommandsAndQueries(t *testing.T) {
|
func TestQuotaCommandsAndQueries(t *testing.T) {
|
||||||
Convey("Testing Quota commands & queries", t, func() {
|
InitTestDB(t)
|
||||||
InitTestDB(t)
|
userId := int64(1)
|
||||||
userId := int64(1)
|
orgId := int64(0)
|
||||||
orgId := int64(0)
|
|
||||||
|
|
||||||
setting.Quota = setting.QuotaSettings{
|
setting.Quota = setting.QuotaSettings{
|
||||||
Enabled: true,
|
Enabled: true,
|
||||||
Org: &setting.OrgQuota{
|
Org: &setting.OrgQuota{
|
||||||
User: 5,
|
User: 5,
|
||||||
Dashboard: 5,
|
Dashboard: 5,
|
||||||
DataSource: 5,
|
DataSource: 5,
|
||||||
ApiKey: 5,
|
ApiKey: 5,
|
||||||
AlertRule: 5,
|
AlertRule: 5,
|
||||||
},
|
},
|
||||||
User: &setting.UserQuota{
|
User: &setting.UserQuota{
|
||||||
Org: 5,
|
Org: 5,
|
||||||
},
|
},
|
||||||
Global: &setting.GlobalQuota{
|
Global: &setting.GlobalQuota{
|
||||||
Org: 5,
|
Org: 5,
|
||||||
User: 5,
|
User: 5,
|
||||||
Dashboard: 5,
|
Dashboard: 5,
|
||||||
DataSource: 5,
|
DataSource: 5,
|
||||||
ApiKey: 5,
|
ApiKey: 5,
|
||||||
Session: 5,
|
Session: 5,
|
||||||
AlertRule: 5,
|
AlertRule: 5,
|
||||||
},
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
// create a new org and add user_id 1 as admin.
|
||||||
|
// we will then have an org with 1 user. and a user
|
||||||
|
// with 1 org.
|
||||||
|
userCmd := models.CreateOrgCommand{
|
||||||
|
Name: "TestOrg",
|
||||||
|
UserId: 1,
|
||||||
|
}
|
||||||
|
|
||||||
|
err := CreateOrg(&userCmd)
|
||||||
|
require.NoError(t, err)
|
||||||
|
orgId = userCmd.Result.Id
|
||||||
|
|
||||||
|
t.Run("Given saved org quota for users", func(t *testing.T) {
|
||||||
|
orgCmd := models.UpdateOrgQuotaCmd{
|
||||||
|
OrgId: orgId,
|
||||||
|
Target: "org_user",
|
||||||
|
Limit: 10,
|
||||||
}
|
}
|
||||||
|
err := UpdateOrgQuota(&orgCmd)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
// create a new org and add user_id 1 as admin.
|
t.Run("Should be able to get saved quota by org id and target", func(t *testing.T) {
|
||||||
// we will then have an org with 1 user. and a user
|
|
||||||
// with 1 org.
|
|
||||||
userCmd := models.CreateOrgCommand{
|
|
||||||
Name: "TestOrg",
|
|
||||||
UserId: 1,
|
|
||||||
}
|
|
||||||
|
|
||||||
err := CreateOrg(&userCmd)
|
|
||||||
So(err, ShouldBeNil)
|
|
||||||
orgId = userCmd.Result.Id
|
|
||||||
|
|
||||||
Convey("Given saved org quota for users", func() {
|
|
||||||
orgCmd := models.UpdateOrgQuotaCmd{
|
|
||||||
OrgId: orgId,
|
|
||||||
Target: "org_user",
|
|
||||||
Limit: 10,
|
|
||||||
}
|
|
||||||
err := UpdateOrgQuota(&orgCmd)
|
|
||||||
So(err, ShouldBeNil)
|
|
||||||
|
|
||||||
Convey("Should be able to get saved quota by org id and target", func() {
|
|
||||||
query := models.GetOrgQuotaByTargetQuery{OrgId: orgId, Target: "org_user", Default: 1}
|
|
||||||
err = GetOrgQuotaByTarget(&query)
|
|
||||||
|
|
||||||
So(err, ShouldBeNil)
|
|
||||||
So(query.Result.Limit, ShouldEqual, 10)
|
|
||||||
})
|
|
||||||
Convey("Should be able to get default quota by org id and target", func() {
|
|
||||||
query := models.GetOrgQuotaByTargetQuery{OrgId: 123, Target: "org_user", Default: 11}
|
|
||||||
err = GetOrgQuotaByTarget(&query)
|
|
||||||
|
|
||||||
So(err, ShouldBeNil)
|
|
||||||
So(query.Result.Limit, ShouldEqual, 11)
|
|
||||||
})
|
|
||||||
Convey("Should be able to get used org quota when rows exist", func() {
|
|
||||||
query := models.GetOrgQuotaByTargetQuery{OrgId: orgId, Target: "org_user", Default: 11}
|
|
||||||
err = GetOrgQuotaByTarget(&query)
|
|
||||||
|
|
||||||
So(err, ShouldBeNil)
|
|
||||||
So(query.Result.Used, ShouldEqual, 1)
|
|
||||||
})
|
|
||||||
Convey("Should be able to get used org quota when no rows exist", func() {
|
|
||||||
query := models.GetOrgQuotaByTargetQuery{OrgId: 2, Target: "org_user", Default: 11}
|
|
||||||
err = GetOrgQuotaByTarget(&query)
|
|
||||||
|
|
||||||
So(err, ShouldBeNil)
|
|
||||||
So(query.Result.Used, ShouldEqual, 0)
|
|
||||||
})
|
|
||||||
Convey("Should be able to get zero used org alert quota when table does not exist (ngalert is not enabled - default case)", func() {
|
|
||||||
query := models.GetOrgQuotaByTargetQuery{OrgId: 2, Target: "alert", Default: 11}
|
|
||||||
err = GetOrgQuotaByTarget(&query)
|
|
||||||
|
|
||||||
So(err, ShouldBeNil)
|
|
||||||
So(query.Result.Used, ShouldEqual, 0)
|
|
||||||
})
|
|
||||||
Convey("Should be able to quota list for org", func() {
|
|
||||||
query := models.GetOrgQuotasQuery{OrgId: orgId}
|
|
||||||
err = GetOrgQuotas(&query)
|
|
||||||
|
|
||||||
So(err, ShouldBeNil)
|
|
||||||
So(len(query.Result), ShouldEqual, 5)
|
|
||||||
for _, res := range query.Result {
|
|
||||||
limit := 5 // default quota limit
|
|
||||||
used := 0
|
|
||||||
if res.Target == "org_user" {
|
|
||||||
limit = 10 // customized quota limit.
|
|
||||||
used = 1
|
|
||||||
}
|
|
||||||
So(res.Limit, ShouldEqual, limit)
|
|
||||||
So(res.Used, ShouldEqual, used)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
})
|
|
||||||
Convey("Given saved user quota for org", func() {
|
|
||||||
userQuotaCmd := models.UpdateUserQuotaCmd{
|
|
||||||
UserId: userId,
|
|
||||||
Target: "org_user",
|
|
||||||
Limit: 10,
|
|
||||||
}
|
|
||||||
err := UpdateUserQuota(&userQuotaCmd)
|
|
||||||
So(err, ShouldBeNil)
|
|
||||||
|
|
||||||
Convey("Should be able to get saved quota by user id and target", func() {
|
|
||||||
query := models.GetUserQuotaByTargetQuery{UserId: userId, Target: "org_user", Default: 1}
|
|
||||||
err = GetUserQuotaByTarget(&query)
|
|
||||||
|
|
||||||
So(err, ShouldBeNil)
|
|
||||||
So(query.Result.Limit, ShouldEqual, 10)
|
|
||||||
})
|
|
||||||
Convey("Should be able to get default quota by user id and target", func() {
|
|
||||||
query := models.GetUserQuotaByTargetQuery{UserId: 9, Target: "org_user", Default: 11}
|
|
||||||
err = GetUserQuotaByTarget(&query)
|
|
||||||
|
|
||||||
So(err, ShouldBeNil)
|
|
||||||
So(query.Result.Limit, ShouldEqual, 11)
|
|
||||||
})
|
|
||||||
Convey("Should be able to get used user quota when rows exist", func() {
|
|
||||||
query := models.GetUserQuotaByTargetQuery{UserId: userId, Target: "org_user", Default: 11}
|
|
||||||
err = GetUserQuotaByTarget(&query)
|
|
||||||
|
|
||||||
So(err, ShouldBeNil)
|
|
||||||
So(query.Result.Used, ShouldEqual, 1)
|
|
||||||
})
|
|
||||||
Convey("Should be able to get used user quota when no rows exist", func() {
|
|
||||||
query := models.GetUserQuotaByTargetQuery{UserId: 2, Target: "org_user", Default: 11}
|
|
||||||
err = GetUserQuotaByTarget(&query)
|
|
||||||
|
|
||||||
So(err, ShouldBeNil)
|
|
||||||
So(query.Result.Used, ShouldEqual, 0)
|
|
||||||
})
|
|
||||||
Convey("Should be able to quota list for user", func() {
|
|
||||||
query := models.GetUserQuotasQuery{UserId: userId}
|
|
||||||
err = GetUserQuotas(&query)
|
|
||||||
|
|
||||||
So(err, ShouldBeNil)
|
|
||||||
So(len(query.Result), ShouldEqual, 1)
|
|
||||||
So(query.Result[0].Limit, ShouldEqual, 10)
|
|
||||||
So(query.Result[0].Used, ShouldEqual, 1)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
Convey("Should be able to global user quota", func() {
|
|
||||||
query := models.GetGlobalQuotaByTargetQuery{Target: "user", Default: 5}
|
|
||||||
err = GetGlobalQuotaByTarget(&query)
|
|
||||||
So(err, ShouldBeNil)
|
|
||||||
|
|
||||||
So(query.Result.Limit, ShouldEqual, 5)
|
|
||||||
So(query.Result.Used, ShouldEqual, 0)
|
|
||||||
})
|
|
||||||
Convey("Should be able to global org quota", func() {
|
|
||||||
query := models.GetGlobalQuotaByTargetQuery{Target: "org", Default: 5}
|
|
||||||
err = GetGlobalQuotaByTarget(&query)
|
|
||||||
So(err, ShouldBeNil)
|
|
||||||
|
|
||||||
So(query.Result.Limit, ShouldEqual, 5)
|
|
||||||
So(query.Result.Used, ShouldEqual, 1)
|
|
||||||
})
|
|
||||||
Convey("Should be able to get zero used global alert quota when table does not exist (ngalert is not enabled - default case)", func() {
|
|
||||||
query := models.GetGlobalQuotaByTargetQuery{Target: "alert_rule", Default: 5}
|
|
||||||
err = GetGlobalQuotaByTarget(&query)
|
|
||||||
So(err, ShouldBeNil)
|
|
||||||
|
|
||||||
So(query.Result.Limit, ShouldEqual, 5)
|
|
||||||
So(query.Result.Used, ShouldEqual, 0)
|
|
||||||
})
|
|
||||||
|
|
||||||
// related: https://github.com/grafana/grafana/issues/14342
|
|
||||||
Convey("Should org quota updating is successful even if it called multiple time", func() {
|
|
||||||
orgCmd := models.UpdateOrgQuotaCmd{
|
|
||||||
OrgId: orgId,
|
|
||||||
Target: "org_user",
|
|
||||||
Limit: 5,
|
|
||||||
}
|
|
||||||
err := UpdateOrgQuota(&orgCmd)
|
|
||||||
So(err, ShouldBeNil)
|
|
||||||
|
|
||||||
query := models.GetOrgQuotaByTargetQuery{OrgId: orgId, Target: "org_user", Default: 1}
|
query := models.GetOrgQuotaByTargetQuery{OrgId: orgId, Target: "org_user", Default: 1}
|
||||||
err = GetOrgQuotaByTarget(&query)
|
err = GetOrgQuotaByTarget(&query)
|
||||||
So(err, ShouldBeNil)
|
|
||||||
So(query.Result.Limit, ShouldEqual, 5)
|
|
||||||
|
|
||||||
// XXX: resolution of `Updated` column is 1sec, so this makes delay
|
require.NoError(t, err)
|
||||||
time.Sleep(1 * time.Second)
|
require.Equal(t, int64(10), query.Result.Limit)
|
||||||
|
|
||||||
orgCmd = models.UpdateOrgQuotaCmd{
|
|
||||||
OrgId: orgId,
|
|
||||||
Target: "org_user",
|
|
||||||
Limit: 10,
|
|
||||||
}
|
|
||||||
err = UpdateOrgQuota(&orgCmd)
|
|
||||||
So(err, ShouldBeNil)
|
|
||||||
|
|
||||||
query = models.GetOrgQuotaByTargetQuery{OrgId: orgId, Target: "org_user", Default: 1}
|
|
||||||
err = GetOrgQuotaByTarget(&query)
|
|
||||||
So(err, ShouldBeNil)
|
|
||||||
So(query.Result.Limit, ShouldEqual, 10)
|
|
||||||
})
|
})
|
||||||
|
|
||||||
// related: https://github.com/grafana/grafana/issues/14342
|
t.Run("Should be able to get default quota by org id and target", func(t *testing.T) {
|
||||||
Convey("Should user quota updating is successful even if it called multiple time", func() {
|
query := models.GetOrgQuotaByTargetQuery{OrgId: 123, Target: "org_user", Default: 11}
|
||||||
userQuotaCmd := models.UpdateUserQuotaCmd{
|
err = GetOrgQuotaByTarget(&query)
|
||||||
UserId: userId,
|
|
||||||
Target: "org_user",
|
require.NoError(t, err)
|
||||||
Limit: 5,
|
require.Equal(t, int64(11), query.Result.Limit)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("Should be able to get used org quota when rows exist", func(t *testing.T) {
|
||||||
|
query := models.GetOrgQuotaByTargetQuery{OrgId: orgId, Target: "org_user", Default: 11}
|
||||||
|
err = GetOrgQuotaByTarget(&query)
|
||||||
|
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Equal(t, int64(1), query.Result.Used)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("Should be able to get used org quota when no rows exist", func(t *testing.T) {
|
||||||
|
query := models.GetOrgQuotaByTargetQuery{OrgId: 2, Target: "org_user", Default: 11}
|
||||||
|
err = GetOrgQuotaByTarget(&query)
|
||||||
|
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Equal(t, int64(0), query.Result.Used)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("Should be able to get zero used org alert quota when table does not exist (ngalert is not enabled - default case)", func(t *testing.T) {
|
||||||
|
query := models.GetOrgQuotaByTargetQuery{OrgId: 2, Target: "alert", Default: 11}
|
||||||
|
err = GetOrgQuotaByTarget(&query)
|
||||||
|
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Equal(t, int64(0), query.Result.Used)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("Should be able to quota list for org", func(t *testing.T) {
|
||||||
|
query := models.GetOrgQuotasQuery{OrgId: orgId}
|
||||||
|
err = GetOrgQuotas(&query)
|
||||||
|
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Len(t, query.Result, 5)
|
||||||
|
for _, res := range query.Result {
|
||||||
|
limit := int64(5) // default quota limit
|
||||||
|
used := int64(0)
|
||||||
|
if res.Target == "org_user" {
|
||||||
|
limit = 10 // customized quota limit.
|
||||||
|
used = 1
|
||||||
|
}
|
||||||
|
require.Equal(t, limit, res.Limit)
|
||||||
|
require.Equal(t, used, res.Used)
|
||||||
}
|
}
|
||||||
err := UpdateUserQuota(&userQuotaCmd)
|
|
||||||
So(err, ShouldBeNil)
|
|
||||||
|
|
||||||
query := models.GetUserQuotaByTargetQuery{UserId: userId, Target: "org_user", Default: 1}
|
|
||||||
err = GetUserQuotaByTarget(&query)
|
|
||||||
So(err, ShouldBeNil)
|
|
||||||
So(query.Result.Limit, ShouldEqual, 5)
|
|
||||||
|
|
||||||
// XXX: resolution of `Updated` column is 1sec, so this makes delay
|
|
||||||
time.Sleep(1 * time.Second)
|
|
||||||
|
|
||||||
userQuotaCmd = models.UpdateUserQuotaCmd{
|
|
||||||
UserId: userId,
|
|
||||||
Target: "org_user",
|
|
||||||
Limit: 10,
|
|
||||||
}
|
|
||||||
err = UpdateUserQuota(&userQuotaCmd)
|
|
||||||
So(err, ShouldBeNil)
|
|
||||||
|
|
||||||
query = models.GetUserQuotaByTargetQuery{UserId: userId, Target: "org_user", Default: 1}
|
|
||||||
err = GetUserQuotaByTarget(&query)
|
|
||||||
So(err, ShouldBeNil)
|
|
||||||
So(query.Result.Limit, ShouldEqual, 10)
|
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
t.Run("Given saved org quota for dashboards", func(t *testing.T) {
|
||||||
|
orgCmd := models.UpdateOrgQuotaCmd{
|
||||||
|
OrgId: orgId,
|
||||||
|
Target: dashboardTarget,
|
||||||
|
Limit: 10,
|
||||||
|
}
|
||||||
|
err := UpdateOrgQuota(&orgCmd)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
t.Run("Should be able to get saved quota by org id and target", func(t *testing.T) {
|
||||||
|
query := models.GetOrgQuotaByTargetQuery{OrgId: orgId, Target: dashboardTarget, Default: 1}
|
||||||
|
err = GetOrgQuotaByTarget(&query)
|
||||||
|
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Equal(t, int64(10), query.Result.Limit)
|
||||||
|
require.Equal(t, int64(0), query.Result.Used)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("Given saved user quota for org", func(t *testing.T) {
|
||||||
|
userQuotaCmd := models.UpdateUserQuotaCmd{
|
||||||
|
UserId: userId,
|
||||||
|
Target: "org_user",
|
||||||
|
Limit: 10,
|
||||||
|
}
|
||||||
|
err := UpdateUserQuota(&userQuotaCmd)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
t.Run("Should be able to get saved quota by user id and target", func(t *testing.T) {
|
||||||
|
query := models.GetUserQuotaByTargetQuery{UserId: userId, Target: "org_user", Default: 1}
|
||||||
|
err = GetUserQuotaByTarget(&query)
|
||||||
|
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Equal(t, int64(10), query.Result.Limit)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("Should be able to get default quota by user id and target", func(t *testing.T) {
|
||||||
|
query := models.GetUserQuotaByTargetQuery{UserId: 9, Target: "org_user", Default: 11}
|
||||||
|
err = GetUserQuotaByTarget(&query)
|
||||||
|
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Equal(t, int64(11), query.Result.Limit)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("Should be able to get used user quota when rows exist", func(t *testing.T) {
|
||||||
|
query := models.GetUserQuotaByTargetQuery{UserId: userId, Target: "org_user", Default: 11}
|
||||||
|
err = GetUserQuotaByTarget(&query)
|
||||||
|
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Equal(t, int64(1), query.Result.Used)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("Should be able to get used user quota when no rows exist", func(t *testing.T) {
|
||||||
|
query := models.GetUserQuotaByTargetQuery{UserId: 2, Target: "org_user", Default: 11}
|
||||||
|
err = GetUserQuotaByTarget(&query)
|
||||||
|
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Equal(t, int64(0), query.Result.Used)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("Should be able to quota list for user", func(t *testing.T) {
|
||||||
|
query := models.GetUserQuotasQuery{UserId: userId}
|
||||||
|
err = GetUserQuotas(&query)
|
||||||
|
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Len(t, query.Result, 1)
|
||||||
|
require.Equal(t, int64(10), query.Result[0].Limit)
|
||||||
|
require.Equal(t, int64(1), query.Result[0].Used)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("Should be able to global user quota", func(t *testing.T) {
|
||||||
|
query := models.GetGlobalQuotaByTargetQuery{Target: "user", Default: 5}
|
||||||
|
err = GetGlobalQuotaByTarget(&query)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
require.Equal(t, int64(5), query.Result.Limit)
|
||||||
|
require.Equal(t, int64(0), query.Result.Used)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("Should be able to global org quota", func(t *testing.T) {
|
||||||
|
query := models.GetGlobalQuotaByTargetQuery{Target: "org", Default: 5}
|
||||||
|
err = GetGlobalQuotaByTarget(&query)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
require.Equal(t, int64(5), query.Result.Limit)
|
||||||
|
require.Equal(t, int64(1), query.Result.Used)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("Should be able to get zero used global alert quota when table does not exist (ngalert is not enabled - default case)", func(t *testing.T) {
|
||||||
|
query := models.GetGlobalQuotaByTargetQuery{Target: "alert_rule", Default: 5}
|
||||||
|
err = GetGlobalQuotaByTarget(&query)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
require.Equal(t, int64(5), query.Result.Limit)
|
||||||
|
require.Equal(t, int64(0), query.Result.Used)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("Should be able to global dashboard quota", func(t *testing.T) {
|
||||||
|
query := models.GetGlobalQuotaByTargetQuery{Target: dashboardTarget, Default: 5}
|
||||||
|
err = GetGlobalQuotaByTarget(&query)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
require.Equal(t, int64(5), query.Result.Limit)
|
||||||
|
require.Equal(t, int64(0), query.Result.Used)
|
||||||
|
})
|
||||||
|
|
||||||
|
// related: https://github.com/grafana/grafana/issues/14342
|
||||||
|
t.Run("Should org quota updating is successful even if it called multiple time", func(t *testing.T) {
|
||||||
|
orgCmd := models.UpdateOrgQuotaCmd{
|
||||||
|
OrgId: orgId,
|
||||||
|
Target: "org_user",
|
||||||
|
Limit: 5,
|
||||||
|
}
|
||||||
|
err := UpdateOrgQuota(&orgCmd)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
query := models.GetOrgQuotaByTargetQuery{OrgId: orgId, Target: "org_user", Default: 1}
|
||||||
|
err = GetOrgQuotaByTarget(&query)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Equal(t, int64(5), query.Result.Limit)
|
||||||
|
|
||||||
|
// XXX: resolution of `Updated` column is 1sec, so this makes delay
|
||||||
|
time.Sleep(1 * time.Second)
|
||||||
|
|
||||||
|
orgCmd = models.UpdateOrgQuotaCmd{
|
||||||
|
OrgId: orgId,
|
||||||
|
Target: "org_user",
|
||||||
|
Limit: 10,
|
||||||
|
}
|
||||||
|
err = UpdateOrgQuota(&orgCmd)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
query = models.GetOrgQuotaByTargetQuery{OrgId: orgId, Target: "org_user", Default: 1}
|
||||||
|
err = GetOrgQuotaByTarget(&query)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Equal(t, int64(10), query.Result.Limit)
|
||||||
|
})
|
||||||
|
|
||||||
|
// related: https://github.com/grafana/grafana/issues/14342
|
||||||
|
t.Run("Should user quota updating is successful even if it called multiple time", func(t *testing.T) {
|
||||||
|
userQuotaCmd := models.UpdateUserQuotaCmd{
|
||||||
|
UserId: userId,
|
||||||
|
Target: "org_user",
|
||||||
|
Limit: 5,
|
||||||
|
}
|
||||||
|
err := UpdateUserQuota(&userQuotaCmd)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
query := models.GetUserQuotaByTargetQuery{UserId: userId, Target: "org_user", Default: 1}
|
||||||
|
err = GetUserQuotaByTarget(&query)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Equal(t, int64(5), query.Result.Limit)
|
||||||
|
|
||||||
|
// XXX: resolution of `Updated` column is 1sec, so this makes delay
|
||||||
|
time.Sleep(1 * time.Second)
|
||||||
|
|
||||||
|
userQuotaCmd = models.UpdateUserQuotaCmd{
|
||||||
|
UserId: userId,
|
||||||
|
Target: "org_user",
|
||||||
|
Limit: 10,
|
||||||
|
}
|
||||||
|
err = UpdateUserQuota(&userQuotaCmd)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
query = models.GetUserQuotaByTargetQuery{UserId: userId, Target: "org_user", Default: 1}
|
||||||
|
err = GetUserQuotaByTarget(&query)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Equal(t, int64(10), query.Result.Limit)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user