Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit2d00b50

Browse files
authored
chore: remove excess join in GetQuotaConsumedForUser query (#15338)
Filter is applied in original workspace query. We do not need to join`workspaces` twice. Use build_number instead of `created_at`for determining the last build.
1 parent886dcbe commit2d00b50

File tree

4 files changed

+115
-24
lines changed

4 files changed

+115
-24
lines changed

‎coderd/database/dbgen/dbgen.go‎

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -288,6 +288,15 @@ func WorkspaceBuild(t testing.TB, db database.Store, orig database.WorkspaceBuil
288288
iferr!=nil {
289289
returnerr
290290
}
291+
292+
iforig.DailyCost>0 {
293+
err=db.UpdateWorkspaceBuildCostByID(genCtx, database.UpdateWorkspaceBuildCostByIDParams{
294+
ID:buildID,
295+
DailyCost:orig.DailyCost,
296+
})
297+
require.NoError(t,err)
298+
}
299+
291300
build,err=db.GetWorkspaceBuildByID(genCtx,buildID)
292301
iferr!=nil {
293302
returnerr

‎coderd/database/queries.sql.go‎

Lines changed: 5 additions & 11 deletions
Some generated files are not rendered by default. Learn more aboutcustomizing how changed files appear on GitHub.

‎coderd/database/queries/quotas.sql‎

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -28,23 +28,17 @@ FROM
2828
INNER JOIN
2929
workspacesonwb.workspace_id=workspaces.id
3030
WHERE
31+
-- Only return workspaces that match the user + organization.
32+
-- Quotas are calculated per user per organization.
33+
NOTworkspaces.deletedAND
3134
workspaces.owner_id= @owner_idAND
3235
workspaces.organization_id= @organization_id
3336
ORDER BY
3437
wb.workspace_id,
35-
wb.created_atDESC
38+
wb.build_numberDESC
3639
)
3740
SELECT
3841
coalesce(SUM(daily_cost),0)::BIGINT
3942
FROM
40-
workspaces
41-
INNER JOIN latest_buildsON
42-
latest_builds.workspace_id=workspaces.id
43-
WHERE
44-
NOT deletedAND
45-
-- We can likely remove these conditions since we check above.
46-
-- But it does not hurt to be defensive and make sure future query changes
47-
-- do not break anything.
48-
workspaces.owner_id= @owner_idAND
49-
workspaces.organization_id= @organization_id
43+
latest_builds
5044
;

‎enterprise/coderd/workspacequota_test.go‎

Lines changed: 96 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import (
2121
"github.com/coder/coder/v2/coderd/database/dbgen"
2222
"github.com/coder/coder/v2/coderd/database/dbtestutil"
2323
"github.com/coder/coder/v2/coderd/database/dbtime"
24+
"github.com/coder/coder/v2/coderd/rbac"
2425
"github.com/coder/coder/v2/coderd/util/ptr"
2526
"github.com/coder/coder/v2/codersdk"
2627
"github.com/coder/coder/v2/enterprise/coderd/coderdenttest"
@@ -31,9 +32,13 @@ import (
3132
)
3233

3334
funcverifyQuota(ctx context.Context,t*testing.T,client*codersdk.Client,organizationIDstring,consumed,totalint) {
35+
verifyQuotaUser(ctx,t,client,organizationID,codersdk.Me,consumed,total)
36+
}
37+
38+
funcverifyQuotaUser(ctx context.Context,t*testing.T,client*codersdk.Client,organizationIDstring,userstring,consumed,totalint) {
3439
t.Helper()
3540

36-
got,err:=client.WorkspaceQuota(ctx,organizationID,codersdk.Me)
41+
got,err:=client.WorkspaceQuota(ctx,organizationID,user)
3742
require.NoError(t,err)
3843
require.EqualValues(t, codersdk.WorkspaceQuota{
3944
Budget:total,
@@ -43,7 +48,7 @@ func verifyQuota(ctx context.Context, t *testing.T, client *codersdk.Client, org
4348
// Remove this check when the deprecated endpoint is removed.
4449
// This just makes sure the deprecated endpoint is still working
4550
// as intended. It will only work for the default organization.
46-
deprecatedGot,err:=deprecatedQuotaEndpoint(ctx,client,codersdk.Me)
51+
deprecatedGot,err:=deprecatedQuotaEndpoint(ctx,client,user)
4752
require.NoError(t,err,"deprecated endpoint")
4853
// Only continue to check if the values differ
4954
ifdeprecatedGot.Budget!=got.Budget||deprecatedGot.CreditsConsumed!=got.CreditsConsumed {
@@ -300,6 +305,95 @@ func TestWorkspaceQuota(t *testing.T) {
300305
verifyQuota(ctx,t,owner,first.OrganizationID.String(),0,30)
301306
verifyQuota(ctx,t,owner,second.ID.String(),0,15)
302307
})
308+
309+
// ManyWorkspaces uses dbfake and dbgen to insert a scenario into the db.
310+
t.Run("ManyWorkspaces",func(t*testing.T) {
311+
t.Parallel()
312+
313+
owner,db,first:=coderdenttest.NewWithDatabase(t,&coderdenttest.Options{
314+
LicenseOptions:&coderdenttest.LicenseOptions{
315+
Features: license.Features{
316+
codersdk.FeatureTemplateRBAC:1,
317+
codersdk.FeatureMultipleOrganizations:1,
318+
},
319+
},
320+
})
321+
client,_:=coderdtest.CreateAnotherUser(t,owner,first.OrganizationID,rbac.RoleOwner())
322+
323+
// Prepopulate database. Use dbfake as it is quicker and
324+
// easier than the api.
325+
ctx:=testutil.Context(t,testutil.WaitLong)
326+
327+
user:=dbgen.User(t,db, database.User{})
328+
noise:=dbgen.User(t,db, database.User{})
329+
330+
second:=dbfake.Organization(t,db).
331+
Members(user,noise).
332+
EveryoneAllowance(10).
333+
Group(database.Group{
334+
QuotaAllowance:25,
335+
},user,noise).
336+
Group(database.Group{
337+
QuotaAllowance:30,
338+
},noise).
339+
Do()
340+
341+
third:=dbfake.Organization(t,db).
342+
Members(noise).
343+
EveryoneAllowance(7).
344+
Do()
345+
346+
verifyQuotaUser(ctx,t,client,second.Org.ID.String(),user.ID.String(),0,35)
347+
verifyQuotaUser(ctx,t,client,second.Org.ID.String(),noise.ID.String(),0,65)
348+
349+
// Workspaces owned by the user
350+
consumed:=0
351+
fori:=0;i<2;i++ {
352+
constcost=5
353+
dbfake.WorkspaceBuild(t,db,
354+
database.WorkspaceTable{
355+
OwnerID:user.ID,
356+
OrganizationID:second.Org.ID,
357+
}).
358+
Seed(database.WorkspaceBuild{
359+
DailyCost:cost,
360+
}).Do()
361+
consumed+=cost
362+
}
363+
364+
// Add some noise
365+
// Workspace by the user in the third org
366+
dbfake.WorkspaceBuild(t,db,
367+
database.WorkspaceTable{
368+
OwnerID:user.ID,
369+
OrganizationID:third.Org.ID,
370+
}).
371+
Seed(database.WorkspaceBuild{
372+
DailyCost:10,
373+
}).Do()
374+
375+
// Workspace by another user in third org
376+
dbfake.WorkspaceBuild(t,db,
377+
database.WorkspaceTable{
378+
OwnerID:noise.ID,
379+
OrganizationID:third.Org.ID,
380+
}).
381+
Seed(database.WorkspaceBuild{
382+
DailyCost:10,
383+
}).Do()
384+
385+
// Workspace by another user in second org
386+
dbfake.WorkspaceBuild(t,db,
387+
database.WorkspaceTable{
388+
OwnerID:noise.ID,
389+
OrganizationID:second.Org.ID,
390+
}).
391+
Seed(database.WorkspaceBuild{
392+
DailyCost:10,
393+
}).Do()
394+
395+
verifyQuotaUser(ctx,t,client,second.Org.ID.String(),user.ID.String(),consumed,35)
396+
})
303397
}
304398

305399
// nolint:paralleltest,tparallel // Tests must run serially

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp