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

Lines changed: 9 additions & 0 deletions
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

Lines changed: 3 additions & 0 deletions
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

Lines changed: 19 additions & 1 deletion
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

Lines changed: 50 additions & 0 deletions
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)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy