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

Commit8f78bad

Browse files
authored
feat(scaletest): switch notification trigger from creating a user to template deletion (#20512)
This PR refactors the notification scale test to use template admins and template deletion as the notification trigger. Additionally, I've added a configurable timeout for SMTP requests.Previously, notifications were triggered by creating/deleting a user, and notifications were received by users with the owner role. However, because of how many notifications were generated by the runners, we had too many notifications to reliably test notification delivery.
1 parent0f8f67e commit8f78bad

File tree

5 files changed

+91
-54
lines changed

5 files changed

+91
-54
lines changed

‎cli/exp_scaletest_notifications.go‎

Lines changed: 76 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
package cli
44

55
import (
6+
"bytes"
67
"context"
78
"fmt"
89
"net/http"
@@ -29,12 +30,13 @@ import (
2930

3031
func (r*RootCmd)scaletestNotifications()*serpent.Command {
3132
var (
32-
userCountint64
33-
ownerUserPercentagefloat64
34-
notificationTimeout time.Duration
35-
dialTimeout time.Duration
36-
noCleanupbool
37-
smtpAPIURLstring
33+
userCountint64
34+
templateAdminPercentagefloat64
35+
notificationTimeout time.Duration
36+
smtpRequestTimeout time.Duration
37+
dialTimeout time.Duration
38+
noCleanupbool
39+
smtpAPIURLstring
3840

3941
tracingFlags=&scaletestTracingFlags{}
4042

@@ -77,24 +79,24 @@ func (r *RootCmd) scaletestNotifications() *serpent.Command {
7779
returnxerrors.Errorf("--user-count must be greater than 0")
7880
}
7981

80-
ifownerUserPercentage<0||ownerUserPercentage>100 {
81-
returnxerrors.Errorf("--owner-user-percentage must be between 0 and 100")
82+
iftemplateAdminPercentage<0||templateAdminPercentage>100 {
83+
returnxerrors.Errorf("--template-admin-percentage must be between 0 and 100")
8284
}
8385

8486
ifsmtpAPIURL!=""&&!strings.HasPrefix(smtpAPIURL,"http://")&&!strings.HasPrefix(smtpAPIURL,"https://") {
8587
returnxerrors.Errorf("--smtp-api-url must start with http:// or https://")
8688
}
8789

88-
ownerUserCount:=int64(float64(userCount)*ownerUserPercentage/100)
89-
ifownerUserCount==0&&ownerUserPercentage>0 {
90-
ownerUserCount=1
90+
templateAdminCount:=int64(float64(userCount)*templateAdminPercentage/100)
91+
iftemplateAdminCount==0&&templateAdminPercentage>0 {
92+
templateAdminCount=1
9193
}
92-
regularUserCount:=userCount-ownerUserCount
94+
regularUserCount:=userCount-templateAdminCount
9395

9496
_,_=fmt.Fprintf(inv.Stderr,"Distribution plan:\n")
9597
_,_=fmt.Fprintf(inv.Stderr," Total users: %d\n",userCount)
96-
_,_=fmt.Fprintf(inv.Stderr,"Owner users: %d (%.1f%%)\n",ownerUserCount,ownerUserPercentage)
97-
_,_=fmt.Fprintf(inv.Stderr," Regular users: %d (%.1f%%)\n",regularUserCount,100.0-ownerUserPercentage)
98+
_,_=fmt.Fprintf(inv.Stderr,"Template admins: %d (%.1f%%)\n",templateAdminCount,templateAdminPercentage)
99+
_,_=fmt.Fprintf(inv.Stderr," Regular users: %d (%.1f%%)\n",regularUserCount,100.0-templateAdminPercentage)
98100

99101
outputs,err:=output.parse()
100102
iferr!=nil {
@@ -127,13 +129,12 @@ func (r *RootCmd) scaletestNotifications() *serpent.Command {
127129
_,_=fmt.Fprintln(inv.Stderr,"Creating users...")
128130

129131
dialBarrier:=&sync.WaitGroup{}
130-
ownerWatchBarrier:=&sync.WaitGroup{}
132+
templateAdminWatchBarrier:=&sync.WaitGroup{}
131133
dialBarrier.Add(int(userCount))
132-
ownerWatchBarrier.Add(int(ownerUserCount))
134+
templateAdminWatchBarrier.Add(int(templateAdminCount))
133135

134136
expectedNotificationIDs:=map[uuid.UUID]struct{}{
135-
notificationsLib.TemplateUserAccountCreated: {},
136-
notificationsLib.TemplateUserAccountDeleted: {},
137+
notificationsLib.TemplateTemplateDeleted: {},
137138
}
138139

139140
triggerTimes:=make(map[uuid.UUID]chan time.Time,len(expectedNotificationIDs))
@@ -142,19 +143,20 @@ func (r *RootCmd) scaletestNotifications() *serpent.Command {
142143
}
143144

144145
configs:=make([]notifications.Config,0,userCount)
145-
forrangeownerUserCount {
146+
forrangetemplateAdminCount {
146147
config:= notifications.Config{
147148
User: createusers.Config{
148149
OrganizationID:me.OrganizationIDs[0],
149150
},
150-
Roles: []string{codersdk.RoleOwner},
151+
Roles: []string{codersdk.RoleTemplateAdmin},
151152
NotificationTimeout:notificationTimeout,
152153
DialTimeout:dialTimeout,
153154
DialBarrier:dialBarrier,
154-
ReceivingWatchBarrier:ownerWatchBarrier,
155+
ReceivingWatchBarrier:templateAdminWatchBarrier,
155156
ExpectedNotificationsIDs:expectedNotificationIDs,
156157
Metrics:metrics,
157158
SMTPApiURL:smtpAPIURL,
159+
SMTPRequestTimeout:smtpRequestTimeout,
158160
}
159161
iferr:=config.Validate();err!=nil {
160162
returnxerrors.Errorf("validate config: %w",err)
@@ -170,17 +172,16 @@ func (r *RootCmd) scaletestNotifications() *serpent.Command {
170172
NotificationTimeout:notificationTimeout,
171173
DialTimeout:dialTimeout,
172174
DialBarrier:dialBarrier,
173-
ReceivingWatchBarrier:ownerWatchBarrier,
175+
ReceivingWatchBarrier:templateAdminWatchBarrier,
174176
Metrics:metrics,
175-
SMTPApiURL:smtpAPIURL,
176177
}
177178
iferr:=config.Validate();err!=nil {
178179
returnxerrors.Errorf("validate config: %w",err)
179180
}
180181
configs=append(configs,config)
181182
}
182183

183-
gotriggerUserNotifications(
184+
gotriggerNotifications(
184185
ctx,
185186
logger,
186187
client,
@@ -261,23 +262,30 @@ func (r *RootCmd) scaletestNotifications() *serpent.Command {
261262
Required:true,
262263
},
263264
{
264-
Flag:"owner-user-percentage",
265-
Env:"CODER_SCALETEST_NOTIFICATION_OWNER_USER_PERCENTAGE",
265+
Flag:"template-admin-percentage",
266+
Env:"CODER_SCALETEST_NOTIFICATION_TEMPLATE_ADMIN_PERCENTAGE",
266267
Default:"20.0",
267-
Description:"Percentage of users to assignOwner role to (0-100).",
268-
Value:serpent.Float64Of(&ownerUserPercentage),
268+
Description:"Percentage of users to assignTemplate Admin role to (0-100).",
269+
Value:serpent.Float64Of(&templateAdminPercentage),
269270
},
270271
{
271272
Flag:"notification-timeout",
272273
Env:"CODER_SCALETEST_NOTIFICATION_TIMEOUT",
273-
Default:"5m",
274+
Default:"10m",
274275
Description:"How long to wait for notifications after triggering.",
275276
Value:serpent.DurationOf(&notificationTimeout),
276277
},
278+
{
279+
Flag:"smtp-request-timeout",
280+
Env:"CODER_SCALETEST_SMTP_REQUEST_TIMEOUT",
281+
Default:"5m",
282+
Description:"Timeout for SMTP requests.",
283+
Value:serpent.DurationOf(&smtpRequestTimeout),
284+
},
277285
{
278286
Flag:"dial-timeout",
279287
Env:"CODER_SCALETEST_DIAL_TIMEOUT",
280-
Default:"2m",
288+
Default:"10m",
281289
Description:"Timeout for dialing the notification websocket endpoint.",
282290
Value:serpent.DurationOf(&dialTimeout),
283291
},
@@ -379,9 +387,9 @@ func computeNotificationLatencies(
379387
returnnil
380388
}
381389

382-
//triggerUserNotifications waits for all test users to connect,
383-
// then creates and deletes a testuser to trigger notification events for testing.
384-
functriggerUserNotifications(
390+
//triggerNotifications waits for all test users to connect,
391+
// then creates and deletes a testtemplate to trigger notification events for testing.
392+
functriggerNotifications(
385393
ctx context.Context,
386394
logger slog.Logger,
387395
client*codersdk.Client,
@@ -414,34 +422,49 @@ func triggerUserNotifications(
414422
return
415423
}
416424

417-
const (
418-
triggerUsername="scaletest-trigger-user"
419-
triggerEmail="scaletest-trigger@example.com"
420-
)
425+
logger.Info(ctx,"creating test template to test notifications")
426+
427+
// Upload empty template file.
428+
file,err:=client.Upload(ctx,codersdk.ContentTypeTar,bytes.NewReader([]byte{}))
429+
iferr!=nil {
430+
logger.Error(ctx,"upload test template",slog.Error(err))
431+
return
432+
}
433+
logger.Info(ctx,"test template uploaded",slog.F("file_id",file.ID))
421434

422-
logger.Info(ctx,"creating test user to test notifications",
423-
slog.F("username",triggerUsername),
424-
slog.F("email",triggerEmail),
425-
slog.F("org_id",orgID))
435+
// Create template version.
436+
version,err:=client.CreateTemplateVersion(ctx,orgID, codersdk.CreateTemplateVersionRequest{
437+
StorageMethod:codersdk.ProvisionerStorageMethodFile,
438+
FileID:file.ID,
439+
Provisioner:codersdk.ProvisionerTypeEcho,
440+
})
441+
iferr!=nil {
442+
logger.Error(ctx,"create test template version",slog.Error(err))
443+
return
444+
}
445+
logger.Info(ctx,"test template version created",slog.F("template_version_id",version.ID))
426446

427-
testUser,err:=client.CreateUserWithOrgs(ctx, codersdk.CreateUserRequestWithOrgs{
428-
OrganizationIDs: []uuid.UUID{orgID},
429-
Username:triggerUsername,
430-
Email:triggerEmail,
431-
Password:"test-password-123",
447+
// Create template.
448+
testTemplate,err:=client.CreateTemplate(ctx,orgID, codersdk.CreateTemplateRequest{
449+
Name:"scaletest-test-template",
450+
Description:"scaletest-test-template",
451+
VersionID:version.ID,
432452
})
433453
iferr!=nil {
434-
logger.Error(ctx,"create testuser",slog.Error(err))
454+
logger.Error(ctx,"create testtemplate",slog.Error(err))
435455
return
436456
}
437-
expectedNotifications[notificationsLib.TemplateUserAccountCreated]<-time.Now()
457+
logger.Info(ctx,"test template created",slog.F("template_id",testTemplate.ID))
438458

439-
err=client.DeleteUser(ctx,testUser.ID)
459+
// Delete template to trigger notification.
460+
err=client.DeleteTemplate(ctx,testTemplate.ID)
440461
iferr!=nil {
441-
logger.Error(ctx,"delete testuser",slog.Error(err))
462+
logger.Error(ctx,"delete testtemplate",slog.Error(err))
442463
return
443464
}
444-
expectedNotifications[notificationsLib.TemplateUserAccountDeleted]<-time.Now()
445-
close(expectedNotifications[notificationsLib.TemplateUserAccountCreated])
446-
close(expectedNotifications[notificationsLib.TemplateUserAccountDeleted])
465+
logger.Info(ctx,"test template deleted",slog.F("template_id",testTemplate.ID))
466+
467+
// Record expected notification.
468+
expectedNotifications[notificationsLib.TemplateTemplateDeleted]<-time.Now()
469+
close(expectedNotifications[notificationsLib.TemplateTemplateDeleted])
447470
}

‎scaletest/notifications/config.go‎

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,9 @@ type Config struct {
3737

3838
// SMTPApiUrl is the URL of the SMTP mock HTTP API
3939
SMTPApiURLstring`json:"smtp_api_url"`
40+
41+
// SMTPRequestTimeout is the timeout for SMTP requests.
42+
SMTPRequestTimeout time.Duration`json:"smtp_request_timeout"`
4043
}
4144

4245
func (cConfig)Validate()error {
@@ -61,6 +64,10 @@ func (c Config) Validate() error {
6164
returnxerrors.New("notification_timeout must be greater than 0")
6265
}
6366

67+
ifc.SMTPApiURL!=""&&c.SMTPRequestTimeout<=0 {
68+
returnxerrors.New("smtp_request_timeout must be set if smtp_api_url is set")
69+
}
70+
6471
ifc.DialTimeout<=0 {
6572
returnxerrors.New("dial_timeout must be greater than 0")
6673
}

‎scaletest/notifications/metrics.go‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,12 @@ func NewMetrics(reg prometheus.Registerer) *Metrics {
2828
Subsystem:"scaletest",
2929
Name:"notification_delivery_latency_seconds",
3030
Help:"Time between notification-creating action and receipt of notification by client",
31+
Buckets: []float64{
32+
1,5,10,30,60,
33+
120,180,240,300,360,420,480,540,600,660,720,780,840,900,
34+
1200,1500,1800,2100,2400,2700,3000,3300,3600,3900,4200,4500,
35+
5400,7200,
36+
},
3137
}, []string{"notification_id","notification_type"})
3238
errors:=prometheus.NewCounterVec(prometheus.CounterOpts{
3339
Namespace:"coderd",

‎scaletest/notifications/run.go‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -299,7 +299,7 @@ func (r *Runner) watchNotificationsSMTP(ctx context.Context, user codersdk.User,
299299

300300
apiURL:=fmt.Sprintf("%s/messages?email=%s",r.cfg.SMTPApiURL,user.Email)
301301
httpClient:=&http.Client{
302-
Timeout:10*time.Second,
302+
Timeout:r.cfg.SMTPRequestTimeout,
303303
}
304304

305305
constsmtpPollInterval=2*time.Second

‎scaletest/notifications/run_test.go‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -228,6 +228,7 @@ func TestRunWithSMTP(t *testing.T) {
228228
ReceivingWatchBarrier:receivingWatchBarrier,
229229
ExpectedNotificationsIDs:expectedNotificationsIDs,
230230
SMTPApiURL:smtpAPIServer.URL,
231+
SMTPRequestTimeout:testutil.WaitLong,
231232
}
232233
err:=runnerCfg.Validate()
233234
require.NoError(t,err)

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp