2021-09-01 09:38:56 -05:00
|
|
|
//go:build integration
|
2020-10-16 02:46:14 -05:00
|
|
|
// +build integration
|
|
|
|
|
2015-09-15 04:10:46 -05:00
|
|
|
package sqlstore
|
|
|
|
|
|
|
|
import (
|
2021-09-20 10:05:30 -05:00
|
|
|
"context"
|
2015-09-15 04:10:46 -05:00
|
|
|
"testing"
|
2018-12-05 07:19:40 -06:00
|
|
|
"time"
|
2015-09-15 04:10:46 -05:00
|
|
|
|
2020-02-29 06:35:15 -06:00
|
|
|
"github.com/grafana/grafana/pkg/models"
|
2015-09-15 04:10:46 -05:00
|
|
|
"github.com/grafana/grafana/pkg/setting"
|
2021-05-12 16:44:46 -05:00
|
|
|
"github.com/stretchr/testify/require"
|
2015-09-15 04:10:46 -05:00
|
|
|
)
|
|
|
|
|
|
|
|
func TestQuotaCommandsAndQueries(t *testing.T) {
|
2021-09-20 10:05:30 -05:00
|
|
|
sqlStore := InitTestDB(t)
|
2021-05-12 16:44:46 -05:00
|
|
|
userId := int64(1)
|
|
|
|
orgId := int64(0)
|
|
|
|
|
|
|
|
setting.Quota = setting.QuotaSettings{
|
|
|
|
Enabled: true,
|
|
|
|
Org: &setting.OrgQuota{
|
|
|
|
User: 5,
|
|
|
|
Dashboard: 5,
|
|
|
|
DataSource: 5,
|
|
|
|
ApiKey: 5,
|
|
|
|
AlertRule: 5,
|
|
|
|
},
|
|
|
|
User: &setting.UserQuota{
|
|
|
|
Org: 5,
|
|
|
|
},
|
|
|
|
Global: &setting.GlobalQuota{
|
|
|
|
Org: 5,
|
|
|
|
User: 5,
|
|
|
|
Dashboard: 5,
|
|
|
|
DataSource: 5,
|
|
|
|
ApiKey: 5,
|
|
|
|
Session: 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,
|
2015-09-15 04:10:46 -05:00
|
|
|
}
|
2021-09-20 10:05:30 -05:00
|
|
|
err := sqlStore.UpdateOrgQuota(context.Background(), &orgCmd)
|
2021-05-12 16:44:46 -05:00
|
|
|
require.NoError(t, err)
|
2015-09-15 04:10:46 -05:00
|
|
|
|
2021-05-12 16:44:46 -05:00
|
|
|
t.Run("Should be able to get saved quota by org id and target", func(t *testing.T) {
|
|
|
|
query := models.GetOrgQuotaByTargetQuery{OrgId: orgId, Target: "org_user", Default: 1}
|
2021-09-20 10:05:30 -05:00
|
|
|
err = sqlStore.GetOrgQuotaByTarget(context.Background(), &query)
|
2015-09-15 04:10:46 -05:00
|
|
|
|
2021-05-12 16:44:46 -05:00
|
|
|
require.NoError(t, err)
|
|
|
|
require.Equal(t, int64(10), query.Result.Limit)
|
2015-09-15 04:10:46 -05:00
|
|
|
})
|
|
|
|
|
2021-05-12 16:44:46 -05:00
|
|
|
t.Run("Should be able to get default quota by org id and target", func(t *testing.T) {
|
|
|
|
query := models.GetOrgQuotaByTargetQuery{OrgId: 123, Target: "org_user", Default: 11}
|
2021-09-20 10:05:30 -05:00
|
|
|
err = sqlStore.GetOrgQuotaByTarget(context.Background(), &query)
|
2015-09-15 04:10:46 -05:00
|
|
|
|
2021-05-12 16:44:46 -05:00
|
|
|
require.NoError(t, err)
|
|
|
|
require.Equal(t, int64(11), query.Result.Limit)
|
2015-09-15 04:10:46 -05:00
|
|
|
})
|
|
|
|
|
2021-05-12 16:44:46 -05:00
|
|
|
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}
|
2021-09-20 10:05:30 -05:00
|
|
|
err = sqlStore.GetOrgQuotaByTarget(context.Background(), &query)
|
2021-05-04 11:16:28 -05:00
|
|
|
|
2021-05-12 16:44:46 -05:00
|
|
|
require.NoError(t, err)
|
|
|
|
require.Equal(t, int64(1), query.Result.Used)
|
2021-05-04 11:16:28 -05:00
|
|
|
})
|
2018-12-05 07:19:40 -06:00
|
|
|
|
2021-05-12 16:44:46 -05:00
|
|
|
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}
|
2021-09-20 10:05:30 -05:00
|
|
|
err = sqlStore.GetOrgQuotaByTarget(context.Background(), &query)
|
2018-12-05 07:19:40 -06:00
|
|
|
|
2021-05-12 16:44:46 -05:00
|
|
|
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}
|
2021-09-20 10:05:30 -05:00
|
|
|
err = sqlStore.GetOrgQuotaByTarget(context.Background(), &query)
|
2018-12-05 07:19:40 -06:00
|
|
|
|
2021-05-12 16:44:46 -05:00
|
|
|
require.NoError(t, err)
|
|
|
|
require.Equal(t, int64(0), query.Result.Used)
|
|
|
|
})
|
2018-12-05 07:19:40 -06:00
|
|
|
|
2021-05-12 16:44:46 -05:00
|
|
|
t.Run("Should be able to quota list for org", func(t *testing.T) {
|
|
|
|
query := models.GetOrgQuotasQuery{OrgId: orgId}
|
2021-09-20 10:05:30 -05:00
|
|
|
err = sqlStore.GetOrgQuotas(context.Background(), &query)
|
2021-05-12 16:44:46 -05:00
|
|
|
|
|
|
|
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)
|
2018-12-05 07:19:40 -06:00
|
|
|
}
|
2021-05-12 16:44:46 -05:00
|
|
|
})
|
|
|
|
})
|
|
|
|
|
|
|
|
t.Run("Given saved org quota for dashboards", func(t *testing.T) {
|
|
|
|
orgCmd := models.UpdateOrgQuotaCmd{
|
|
|
|
OrgId: orgId,
|
|
|
|
Target: dashboardTarget,
|
|
|
|
Limit: 10,
|
|
|
|
}
|
2021-09-20 10:05:30 -05:00
|
|
|
err := sqlStore.UpdateOrgQuota(context.Background(), &orgCmd)
|
2021-05-12 16:44:46 -05:00
|
|
|
require.NoError(t, err)
|
2018-12-05 07:19:40 -06:00
|
|
|
|
2021-05-12 16:44:46 -05:00
|
|
|
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}
|
2021-09-20 10:05:30 -05:00
|
|
|
err = sqlStore.GetOrgQuotaByTarget(context.Background(), &query)
|
2021-05-12 16:44:46 -05:00
|
|
|
|
|
|
|
require.NoError(t, err)
|
|
|
|
require.Equal(t, int64(10), query.Result.Limit)
|
|
|
|
require.Equal(t, int64(0), query.Result.Used)
|
2018-12-05 07:19:40 -06:00
|
|
|
})
|
2021-05-12 16:44:46 -05:00
|
|
|
})
|
2018-12-05 07:29:07 -06:00
|
|
|
|
2021-05-12 16:44:46 -05:00
|
|
|
t.Run("Given saved user quota for org", func(t *testing.T) {
|
|
|
|
userQuotaCmd := models.UpdateUserQuotaCmd{
|
|
|
|
UserId: userId,
|
|
|
|
Target: "org_user",
|
|
|
|
Limit: 10,
|
|
|
|
}
|
2021-09-20 10:05:30 -05:00
|
|
|
err := sqlStore.UpdateUserQuota(context.Background(), &userQuotaCmd)
|
2021-05-12 16:44:46 -05:00
|
|
|
require.NoError(t, err)
|
2018-12-05 07:29:07 -06:00
|
|
|
|
2021-05-12 16:44:46 -05:00
|
|
|
t.Run("Should be able to get saved quota by user id and target", func(t *testing.T) {
|
2020-02-29 06:35:15 -06:00
|
|
|
query := models.GetUserQuotaByTargetQuery{UserId: userId, Target: "org_user", Default: 1}
|
2021-09-20 10:05:30 -05:00
|
|
|
err = sqlStore.GetUserQuotaByTarget(context.Background(), &query)
|
2018-12-05 07:29:07 -06:00
|
|
|
|
2021-05-12 16:44:46 -05:00
|
|
|
require.NoError(t, err)
|
|
|
|
require.Equal(t, int64(10), query.Result.Limit)
|
|
|
|
})
|
2018-12-05 07:29:07 -06:00
|
|
|
|
2021-05-12 16:44:46 -05:00
|
|
|
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}
|
2021-09-20 10:05:30 -05:00
|
|
|
err = sqlStore.GetUserQuotaByTarget(context.Background(), &query)
|
2021-05-12 16:44:46 -05:00
|
|
|
|
|
|
|
require.NoError(t, err)
|
|
|
|
require.Equal(t, int64(11), query.Result.Limit)
|
|
|
|
})
|
2018-12-05 07:29:07 -06:00
|
|
|
|
2021-05-12 16:44:46 -05:00
|
|
|
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}
|
2021-09-20 10:05:30 -05:00
|
|
|
err = sqlStore.GetUserQuotaByTarget(context.Background(), &query)
|
2021-05-12 16:44:46 -05:00
|
|
|
|
|
|
|
require.NoError(t, err)
|
|
|
|
require.Equal(t, int64(1), query.Result.Used)
|
2018-12-05 07:29:07 -06:00
|
|
|
})
|
2021-05-12 16:44:46 -05:00
|
|
|
|
|
|
|
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}
|
2021-09-20 10:05:30 -05:00
|
|
|
err = sqlStore.GetUserQuotaByTarget(context.Background(), &query)
|
2021-05-12 16:44:46 -05:00
|
|
|
|
|
|
|
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}
|
2021-09-20 10:05:30 -05:00
|
|
|
err = sqlStore.GetUserQuotas(context.Background(), &query)
|
2021-05-12 16:44:46 -05:00
|
|
|
|
|
|
|
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}
|
2021-09-20 10:05:30 -05:00
|
|
|
err = sqlStore.GetGlobalQuotaByTarget(context.Background(), &query)
|
2021-05-12 16:44:46 -05:00
|
|
|
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}
|
2021-09-20 10:05:30 -05:00
|
|
|
err = sqlStore.GetGlobalQuotaByTarget(context.Background(), &query)
|
2021-05-12 16:44:46 -05:00
|
|
|
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}
|
2021-09-20 10:05:30 -05:00
|
|
|
err = sqlStore.GetGlobalQuotaByTarget(context.Background(), &query)
|
2021-05-12 16:44:46 -05:00
|
|
|
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}
|
2021-09-20 10:05:30 -05:00
|
|
|
err = sqlStore.GetGlobalQuotaByTarget(context.Background(), &query)
|
2021-05-12 16:44:46 -05:00
|
|
|
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,
|
|
|
|
}
|
2021-09-20 10:05:30 -05:00
|
|
|
err := sqlStore.UpdateOrgQuota(context.Background(), &orgCmd)
|
2021-05-12 16:44:46 -05:00
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
query := models.GetOrgQuotaByTargetQuery{OrgId: orgId, Target: "org_user", Default: 1}
|
2021-09-20 10:05:30 -05:00
|
|
|
err = sqlStore.GetOrgQuotaByTarget(context.Background(), &query)
|
2021-05-12 16:44:46 -05:00
|
|
|
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,
|
|
|
|
}
|
2021-09-20 10:05:30 -05:00
|
|
|
err = sqlStore.UpdateOrgQuota(context.Background(), &orgCmd)
|
2021-05-12 16:44:46 -05:00
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
query = models.GetOrgQuotaByTargetQuery{OrgId: orgId, Target: "org_user", Default: 1}
|
2021-09-20 10:05:30 -05:00
|
|
|
err = sqlStore.GetOrgQuotaByTarget(context.Background(), &query)
|
2021-05-12 16:44:46 -05:00
|
|
|
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,
|
|
|
|
}
|
2021-09-20 10:05:30 -05:00
|
|
|
err := sqlStore.UpdateUserQuota(context.Background(), &userQuotaCmd)
|
2021-05-12 16:44:46 -05:00
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
query := models.GetUserQuotaByTargetQuery{UserId: userId, Target: "org_user", Default: 1}
|
2021-09-20 10:05:30 -05:00
|
|
|
err = sqlStore.GetUserQuotaByTarget(context.Background(), &query)
|
2021-05-12 16:44:46 -05:00
|
|
|
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,
|
|
|
|
}
|
2021-09-20 10:05:30 -05:00
|
|
|
err = sqlStore.UpdateUserQuota(context.Background(), &userQuotaCmd)
|
2021-05-12 16:44:46 -05:00
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
query = models.GetUserQuotaByTargetQuery{UserId: userId, Target: "org_user", Default: 1}
|
2021-09-20 10:05:30 -05:00
|
|
|
err = sqlStore.GetUserQuotaByTarget(context.Background(), &query)
|
2021-05-12 16:44:46 -05:00
|
|
|
require.NoError(t, err)
|
|
|
|
require.Equal(t, int64(10), query.Result.Limit)
|
2015-09-15 04:10:46 -05:00
|
|
|
})
|
|
|
|
}
|