Skip to content

Commit 0212475

Browse files
authored
feat(cli/exp): extend scaletest create-workspaces with --retry option (#11825)
Part of #11801
1 parent fdf9f03 commit 0212475

File tree

4 files changed

+81
-1
lines changed

4 files changed

+81
-1
lines changed

cli/exp_scaletest.go

+9
Original file line numberDiff line numberDiff line change
@@ -524,6 +524,7 @@ func (r *RootCmd) scaletestCleanup() *clibase.Cmd {
524524
func (r *RootCmd) scaletestCreateWorkspaces() *clibase.Cmd {
525525
var (
526526
count int64
527+
retry int64
527528
template string
528529

529530
noCleanup bool
@@ -644,6 +645,7 @@ func (r *RootCmd) scaletestCreateWorkspaces() *clibase.Cmd {
644645
RichParameterValues: richParameters,
645646
},
646647
NoWaitForAgents: noWaitForAgents,
648+
Retry: int(retry),
647649
},
648650
NoCleanup: noCleanup,
649651
}
@@ -753,6 +755,13 @@ func (r *RootCmd) scaletestCreateWorkspaces() *clibase.Cmd {
753755
Description: "Required: Number of workspaces to create.",
754756
Value: clibase.Int64Of(&count),
755757
},
758+
{
759+
Flag: "retry",
760+
Env: "CODER_SCALETEST_RETRY",
761+
Default: "0",
762+
Description: "Number of tries to create and bring up the workspace.",
763+
Value: clibase.Int64Of(&retry),
764+
},
756765
{
757766
Flag: "template",
758767
FlagShorthand: "t",

scaletest/workspacebuild/config.go

+3
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,9 @@ type Config struct {
1919
// NoWaitForAgents determines whether the test should wait for the workspace
2020
// agents to connect before returning.
2121
NoWaitForAgents bool `json:"no_wait_for_agents"`
22+
// Retry determines how many times to retry starting a workspace build if it
23+
// fails.
24+
Retry int `json:"retry"`
2225
}
2326

2427
func (c Config) Validate() error {

scaletest/workspacebuild/run.go

+19-1
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,25 @@ func (r *Runner) Run(ctx context.Context, _ string, logs io.Writer) error {
6666

6767
err = waitForBuild(ctx, logs, r.client, workspace.LatestBuild.ID)
6868
if err != nil {
69-
return xerrors.Errorf("wait for build: %w", err)
69+
for i := 0; i < r.cfg.Retry; i++ {
70+
_, _ = fmt.Fprintf(logs, "Retrying build %d/%d...\n", i+1, r.cfg.Retry)
71+
72+
workspace.LatestBuild, err = r.client.CreateWorkspaceBuild(ctx, workspace.ID, codersdk.CreateWorkspaceBuildRequest{
73+
Transition: codersdk.WorkspaceTransitionStart,
74+
RichParameterValues: req.RichParameterValues,
75+
TemplateVersionID: req.TemplateVersionID,
76+
})
77+
if err != nil {
78+
return xerrors.Errorf("create workspace build: %w", err)
79+
}
80+
err = waitForBuild(ctx, logs, r.client, workspace.LatestBuild.ID)
81+
if err == nil {
82+
break
83+
}
84+
}
85+
if err != nil {
86+
return xerrors.Errorf("wait for build: %w", err)
87+
}
7088
}
7189

7290
if r.cfg.NoWaitForAgents {

scaletest/workspacebuild/run_test.go

+50
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"bytes"
55
"context"
66
"fmt"
7+
"strings"
78
"testing"
89
"time"
910

@@ -230,4 +231,53 @@ func Test_Runner(t *testing.T) {
230231
require.Error(t, err)
231232
require.ErrorContains(t, err, "test error")
232233
})
234+
235+
t.Run("RetryBuild", func(t *testing.T) {
236+
t.Parallel()
237+
238+
ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitLong)
239+
defer cancel()
240+
241+
logger := slogtest.Make(t, &slogtest.Options{IgnoreErrors: true})
242+
client := coderdtest.New(t, &coderdtest.Options{
243+
IncludeProvisionerDaemon: true,
244+
Logger: &logger,
245+
})
246+
user := coderdtest.CreateFirstUser(t, client)
247+
248+
version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, &echo.Responses{
249+
Parse: echo.ParseComplete,
250+
ProvisionPlan: echo.PlanComplete,
251+
ProvisionApply: []*proto.Response{
252+
{
253+
Type: &proto.Response_Apply{
254+
Apply: &proto.ApplyComplete{
255+
Error: "test error",
256+
},
257+
},
258+
},
259+
},
260+
})
261+
262+
template := coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID)
263+
coderdtest.AwaitTemplateVersionJobCompleted(t, client, version.ID)
264+
265+
runner := workspacebuild.NewRunner(client, workspacebuild.Config{
266+
OrganizationID: user.OrganizationID,
267+
UserID: codersdk.Me,
268+
Request: codersdk.CreateWorkspaceRequest{
269+
TemplateID: template.ID,
270+
},
271+
Retry: 1,
272+
})
273+
274+
logs := bytes.NewBuffer(nil)
275+
err := runner.Run(ctx, "1", logs)
276+
logsStr := logs.String()
277+
t.Log("Runner logs:\n\n" + logsStr)
278+
require.Error(t, err)
279+
require.ErrorContains(t, err, "test error")
280+
require.Equal(t, 1, strings.Count(logsStr, "Retrying build"))
281+
require.Equal(t, 2*2, strings.Count(logsStr, "test error")) // once per error, once per logged sdk response.
282+
})
233283
}

0 commit comments

Comments
 (0)