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

Commit6c170bd

Browse files
committed
feat(scaletest): addprebuilds scaletest command
1 parentfff0900 commit6c170bd

File tree

2 files changed

+289
-0
lines changed

2 files changed

+289
-0
lines changed

‎cli/exp_scaletest.go‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ func (r *RootCmd) scaletestCmd() *serpent.Command {
6565
r.scaletestAutostart(),
6666
r.scaletestNotifications(),
6767
r.scaletestSMTP(),
68+
r.scaletestPrebuilds(),
6869
},
6970
}
7071

‎cli/exp_scaletest_prebuilds.go‎

Lines changed: 288 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,288 @@
1+
//go:build !slim
2+
3+
package cli
4+
5+
import (
6+
"fmt"
7+
"net/http"
8+
"os/signal"
9+
"strconv"
10+
"sync"
11+
"time"
12+
13+
"github.com/prometheus/client_golang/prometheus"
14+
"github.com/prometheus/client_golang/prometheus/promhttp"
15+
"golang.org/x/xerrors"
16+
17+
"github.com/coder/coder/v2/codersdk"
18+
"github.com/coder/coder/v2/scaletest/harness"
19+
"github.com/coder/coder/v2/scaletest/prebuilds"
20+
"github.com/coder/quartz"
21+
"github.com/coder/serpent"
22+
)
23+
24+
func (r*RootCmd)scaletestPrebuilds()*serpent.Command {
25+
var (
26+
numTemplatesint64
27+
numPresetsint64
28+
numPresetPrebuildsint64
29+
templateVersionJobTimeout time.Duration
30+
prebuildWorkspaceTimeout time.Duration
31+
noCleanupbool
32+
33+
tracingFlags=&scaletestTracingFlags{}
34+
timeoutStrategy=&timeoutFlags{}
35+
cleanupStrategy=newScaletestCleanupStrategy()
36+
output=&scaletestOutputFlags{}
37+
prometheusFlags=&scaletestPrometheusFlags{}
38+
)
39+
40+
cmd:=&serpent.Command{
41+
Use:"prebuilds",
42+
Short:"Creates prebuild workspaces on the Coder server.",
43+
Handler:func(inv*serpent.Invocation)error {
44+
ctx:=inv.Context()
45+
client,err:=r.InitClient(inv)
46+
iferr!=nil {
47+
returnerr
48+
}
49+
50+
notifyCtx,stop:=signal.NotifyContext(ctx,StopSignals...)
51+
deferstop()
52+
ctx=notifyCtx
53+
54+
me,err:=requireAdmin(ctx,client)
55+
iferr!=nil {
56+
returnerr
57+
}
58+
59+
client.HTTPClient=&http.Client{
60+
Transport:&codersdk.HeaderTransport{
61+
Transport:http.DefaultTransport,
62+
Header:map[string][]string{
63+
codersdk.BypassRatelimitHeader: {"true"},
64+
},
65+
},
66+
}
67+
68+
ifnumTemplates<=0 {
69+
returnxerrors.Errorf("--num-templates must be greater than 0")
70+
}
71+
ifnumPresets<=0 {
72+
returnxerrors.Errorf("--num-presets must be greater than 0")
73+
}
74+
ifnumPresetPrebuilds<=0 {
75+
returnxerrors.Errorf("--num-preset-prebuilds must be greater than 0")
76+
}
77+
78+
outputs,err:=output.parse()
79+
iferr!=nil {
80+
returnxerrors.Errorf("parse output flags: %w",err)
81+
}
82+
83+
tracerProvider,closeTracing,tracingEnabled,err:=tracingFlags.provider(ctx)
84+
iferr!=nil {
85+
returnxerrors.Errorf("create tracer provider: %w",err)
86+
}
87+
deferfunc() {
88+
_,_=fmt.Fprintln(inv.Stderr,"\nUploading traces...")
89+
iferr:=closeTracing(ctx);err!=nil {
90+
_,_=fmt.Fprintf(inv.Stderr,"\nError uploading traces: %+v\n",err)
91+
}
92+
_,_=fmt.Fprintf(inv.Stderr,"Waiting %s for prometheus metrics to be scraped\n",prometheusFlags.Wait)
93+
<-time.After(prometheusFlags.Wait)
94+
}()
95+
tracer:=tracerProvider.Tracer(scaletestTracerName)
96+
97+
reg:=prometheus.NewRegistry()
98+
metrics:=prebuilds.NewMetrics(reg)
99+
100+
logger:=inv.Logger
101+
prometheusSrvClose:=ServeHandler(ctx,logger,promhttp.HandlerFor(reg, promhttp.HandlerOpts{}),prometheusFlags.Address,"prometheus")
102+
deferprometheusSrvClose()
103+
104+
err=client.PutPrebuildsSettings(ctx, codersdk.PrebuildsSettings{
105+
ReconciliationPaused:true,
106+
})
107+
iferr!=nil {
108+
returnxerrors.Errorf("pause prebuilds: %w",err)
109+
}
110+
111+
setupBarrier:=new(sync.WaitGroup)
112+
setupBarrier.Add(int(numTemplates))
113+
deletionBarrier:=new(sync.WaitGroup)
114+
deletionBarrier.Add(int(numTemplates))
115+
116+
th:=harness.NewTestHarness(timeoutStrategy.wrapStrategy(harness.ConcurrentExecutionStrategy{}),cleanupStrategy.toStrategy())
117+
118+
fori:=rangenumTemplates {
119+
id:=strconv.Itoa(int(i))
120+
cfg:= prebuilds.Config{
121+
OrganizationID:me.OrganizationIDs[0],
122+
NumPresets:int(numPresets),
123+
NumPresetPrebuilds:int(numPresetPrebuilds),
124+
TemplateVersionJobTimeout:templateVersionJobTimeout,
125+
PrebuildWorkspaceTimeout:prebuildWorkspaceTimeout,
126+
Metrics:metrics,
127+
SetupBarrier:setupBarrier,
128+
DeletionBarrier:deletionBarrier,
129+
Clock:quartz.NewReal(),
130+
}
131+
err:=cfg.Validate()
132+
iferr!=nil {
133+
returnxerrors.Errorf("validate config: %w",err)
134+
}
135+
136+
varrunner harness.Runnable=prebuilds.NewRunner(client,cfg)
137+
iftracingEnabled {
138+
runner=&runnableTraceWrapper{
139+
tracer:tracer,
140+
spanName:fmt.Sprintf("prebuilds/%s",id),
141+
runner:runner,
142+
}
143+
}
144+
145+
th.AddRun("prebuilds",id,runner)
146+
}
147+
148+
_,_=fmt.Fprintf(inv.Stderr,"Creating %d templates with %d presets and %d prebuilds per preset...\n",
149+
numTemplates,numPresets,numPresetPrebuilds)
150+
_,_=fmt.Fprintf(inv.Stderr,"Total expected prebuilds: %d\n",numTemplates*numPresets*numPresetPrebuilds)
151+
152+
testCtx,testCancel:=timeoutStrategy.toContext(ctx)
153+
defertestCancel()
154+
155+
runErrCh:=make(chanerror,1)
156+
gofunc() {
157+
runErrCh<-th.Run(testCtx)
158+
}()
159+
160+
_,_=fmt.Fprintln(inv.Stderr,"Waiting for all templates to be created...")
161+
setupBarrier.Wait()
162+
_,_=fmt.Fprintln(inv.Stderr,"All templates created")
163+
164+
err=client.PutPrebuildsSettings(ctx, codersdk.PrebuildsSettings{
165+
ReconciliationPaused:false,
166+
})
167+
iferr!=nil {
168+
returnxerrors.Errorf("resume prebuilds: %w",err)
169+
}
170+
171+
err=<-runErrCh
172+
iferr!=nil {
173+
returnxerrors.Errorf("run test harness (harness failure, not a test failure): %w",err)
174+
}
175+
176+
// If the command was interrupted, skip cleanup & stats
177+
ifnotifyCtx.Err()!=nil {
178+
returnnotifyCtx.Err()
179+
}
180+
181+
if!noCleanup {
182+
_,_=fmt.Fprintln(inv.Stderr,"\nStarting cleanup (prebuild deletion test)...")
183+
184+
err=client.PutPrebuildsSettings(ctx, codersdk.PrebuildsSettings{
185+
ReconciliationPaused:true,
186+
})
187+
iferr!=nil {
188+
returnxerrors.Errorf("pause prebuilds for deletion: %w",err)
189+
}
190+
191+
cleanupCtx,cleanupCancel:=cleanupStrategy.toContext(ctx)
192+
defercleanupCancel()
193+
194+
cleanupErrCh:=make(chanerror,1)
195+
gofunc() {
196+
cleanupErrCh<-th.Cleanup(cleanupCtx)
197+
}()
198+
199+
_,_=fmt.Fprintln(inv.Stderr,"Waiting for all templates to be updated with 0 prebuilds...")
200+
deletionBarrier.Wait()
201+
_,_=fmt.Fprintln(inv.Stderr,"All templates updated")
202+
203+
err=client.PutPrebuildsSettings(ctx, codersdk.PrebuildsSettings{
204+
ReconciliationPaused:false,
205+
})
206+
iferr!=nil {
207+
returnxerrors.Errorf("resume prebuilds for deletion: %w",err)
208+
}
209+
210+
err=<-cleanupErrCh
211+
iferr!=nil {
212+
returnxerrors.Errorf("cleanup tests: %w",err)
213+
}
214+
215+
// If the cleanup was interrupted, skip stats
216+
ifnotifyCtx.Err()!=nil {
217+
returnnotifyCtx.Err()
218+
}
219+
}
220+
221+
res:=th.Results()
222+
for_,o:=rangeoutputs {
223+
err=o.write(res,inv.Stdout)
224+
iferr!=nil {
225+
returnxerrors.Errorf("write output %q to %q: %w",o.format,o.path,err)
226+
}
227+
}
228+
229+
ifres.TotalFail>0 {
230+
returnxerrors.New("prebuild creation test failed, see above for more details")
231+
}
232+
233+
returnnil
234+
},
235+
}
236+
237+
cmd.Options= serpent.OptionSet{
238+
{
239+
Flag:"num-templates",
240+
Env:"CODER_SCALETEST_PREBUILDS_NUM_TEMPLATES",
241+
Default:"1",
242+
Description:"Number of templates to create for the test.",
243+
Value:serpent.Int64Of(&numTemplates),
244+
},
245+
{
246+
Flag:"num-presets",
247+
Env:"CODER_SCALETEST_PREBUILDS_NUM_PRESETS",
248+
Default:"1",
249+
Description:"Number of presets per template.",
250+
Value:serpent.Int64Of(&numPresets),
251+
},
252+
{
253+
Flag:"num-preset-prebuilds",
254+
Env:"CODER_SCALETEST_PREBUILDS_NUM_PRESET_PREBUILDS",
255+
Default:"1",
256+
Description:"Number of prebuilds per preset.",
257+
Value:serpent.Int64Of(&numPresetPrebuilds),
258+
},
259+
{
260+
Flag:"template-version-job-timeout",
261+
Env:"CODER_SCALETEST_PREBUILDS_TEMPLATE_VERSION_JOB_TIMEOUT",
262+
Default:"5m",
263+
Description:"Timeout for template version provisioning jobs.",
264+
Value:serpent.DurationOf(&templateVersionJobTimeout),
265+
},
266+
{
267+
Flag:"prebuild-workspace-timeout",
268+
Env:"CODER_SCALETEST_PREBUILDS_WORKSPACE_TIMEOUT",
269+
Default:"10m",
270+
Description:"Timeout for all prebuild workspaces to be created/deleted.",
271+
Value:serpent.DurationOf(&prebuildWorkspaceTimeout),
272+
},
273+
{
274+
Flag:"skip-cleanup",
275+
Env:"CODER_SCALETEST_PREBUILDS_SKIP_CLEANUP",
276+
Description:"Skip cleanup (deletion test) and leave resources intact.",
277+
Value:serpent.BoolOf(&noCleanup),
278+
},
279+
}
280+
281+
tracingFlags.attach(&cmd.Options)
282+
timeoutStrategy.attach(&cmd.Options)
283+
cleanupStrategy.attach(&cmd.Options)
284+
output.attach(&cmd.Options)
285+
prometheusFlags.attach(&cmd.Options)
286+
287+
returncmd
288+
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp