Skip to content

Commit 3488c4b

Browse files
authored
test(magician): refactor wait-for-commit to use testing sandbox (#17926)
1 parent 73468c1 commit 3488c4b

2 files changed

Lines changed: 96 additions & 133 deletions

File tree

.ci/magician/cmd/wait_for_commit.go

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -35,15 +35,14 @@ var waitForCommitCmd = &cobra.Command{
3535
return fmt.Errorf("error creating Runner: %w", err)
3636
}
3737

38-
return execWaitForCommit(syncBranchPrefix, baseBranch, sha, rnr)
38+
waitFunc := func() {
39+
time.Sleep(5 * time.Second)
40+
}
41+
return execWaitForCommit(syncBranchPrefix, baseBranch, sha, rnr, waitFunc)
3942
},
4043
}
4144

42-
var waitFunc = func() {
43-
time.Sleep(5 * time.Second)
44-
}
45-
46-
func execWaitForCommit(syncBranchPrefix, baseBranch, sha string, runner source.Runner) error {
45+
func execWaitForCommit(syncBranchPrefix, baseBranch, sha string, runner source.Runner, waitFunc func()) error {
4746
syncBranch := getSyncBranch(syncBranchPrefix, baseBranch)
4847
fmt.Println("SYNC_BRANCH: ", syncBranch)
4948

.ci/magician/cmd/wait_for_commit_test.go

Lines changed: 91 additions & 127 deletions
Original file line numberDiff line numberDiff line change
@@ -1,162 +1,126 @@
11
package cmd
22

33
import (
4-
"fmt"
54
"strings"
65
"testing"
7-
8-
"github.com/google/go-cmp/cmp"
96
)
107

11-
type runResult struct {
12-
out string
13-
err error
14-
}
15-
type waitForCommitMockRunner struct {
16-
mockRunner
17-
runResults map[string][]runResult
18-
}
19-
20-
func (mr *waitForCommitMockRunner) Run(name string, args []string, env map[string]string) (string, error) {
21-
mr.calledMethods["Run"] = append(mr.calledMethods["Run"], ParameterList{mr.cwd, name, args, env})
22-
cmd := fmt.Sprintf("%s %s %v %s", mr.cwd, name, args, sortedEnvString(env))
23-
if result, ok := mr.runResults[cmd]; ok {
24-
if result == nil {
25-
return "", fmt.Errorf("no results")
26-
}
27-
headRet := result[0]
28-
result = result[1:]
29-
mr.runResults[cmd] = result
30-
return headRet.out, headRet.err
31-
}
32-
return "", fmt.Errorf("unknown command %s\n", cmd)
33-
}
34-
358
func TestExecWaitForCommit(t *testing.T) {
369
testCases := []struct {
3710
name string
3811
baseBranch string
39-
calledMethods []string
40-
runResults map[string][]runResult
12+
syncBranch string
13+
setupRemote func(sb *sandbox, shas []string, targetBranch string)
14+
waitFunc func(sb *sandbox, shas []string, targetBranch string, calls int)
15+
expectedCalls int
16+
expectErr bool
4117
}{
4218
{
43-
name: "base branch is main",
19+
name: "already in sync branch",
4420
baseBranch: "main",
45-
calledMethods: []string{
46-
"git merge-base --is-ancestor sha origin/sync-branch",
47-
"git rev-parse --short origin/sync-branch",
48-
"git rev-parse --short sha~",
49-
"git fetch origin sync-branch",
50-
"git rev-parse --short origin/sync-branch",
51-
"git rev-parse --short sha~",
21+
syncBranch: "sync-branch",
22+
setupRemote: func(sb *sandbox, shas []string, targetBranch string) {
23+
sb.Runner.MustRun("git", []string{"push", "origin", shas[3] + ":refs/heads/" + targetBranch}, nil)
5224
},
53-
runResults: map[string][]runResult{
54-
"cwd git [merge-base --is-ancestor sha origin/sync-branch] map[]": {
55-
{
56-
out: "",
57-
err: fmt.Errorf("exit error 1"),
58-
},
59-
},
60-
"cwd git [rev-parse --short origin/sync-branch] map[]": {
61-
{
62-
out: "sha-x",
63-
},
64-
{
65-
out: "sha-z",
66-
},
67-
},
68-
"cwd git [rev-parse --short sha~] map[]": {
69-
{
70-
out: "sha-y",
71-
},
72-
{
73-
out: "sha-z",
74-
},
75-
},
76-
"cwd git [fetch origin sync-branch] map[]": {
77-
{
78-
out: "",
79-
},
80-
},
25+
waitFunc: func(sb *sandbox, shas []string, targetBranch string, calls int) {
8126
},
27+
expectedCalls: 0,
28+
expectErr: false,
29+
},
30+
{
31+
name: "needs update once",
32+
baseBranch: "main",
33+
syncBranch: "sync-branch",
34+
setupRemote: func(sb *sandbox, shas []string, targetBranch string) {
35+
sb.Runner.MustRun("git", []string{"push", "origin", shas[1] + ":refs/heads/" + targetBranch}, nil)
36+
},
37+
waitFunc: func(sb *sandbox, shas []string, targetBranch string, calls int) {
38+
sb.Runner.MustRun("git", []string{"push", "origin", shas[2] + ":refs/heads/" + targetBranch}, nil)
39+
},
40+
expectedCalls: 1,
41+
expectErr: false,
8242
},
8343
{
8444
name: "base branch is not main",
8545
baseBranch: "feature-branch",
86-
calledMethods: []string{
87-
"git merge-base --is-ancestor sha origin/sync-branch-feature-branch",
88-
"git rev-parse --short origin/sync-branch-feature-branch",
89-
"git rev-parse --short sha~",
90-
"git fetch origin sync-branch-feature-branch",
91-
"git rev-parse --short origin/sync-branch-feature-branch",
92-
"git rev-parse --short sha~",
46+
syncBranch: "sync-branch",
47+
setupRemote: func(sb *sandbox, shas []string, targetBranch string) {
48+
sb.Runner.MustRun("git", []string{"push", "origin", shas[1] + ":refs/heads/" + targetBranch}, nil)
9349
},
94-
runResults: map[string][]runResult{
95-
"cwd git [merge-base --is-ancestor sha origin/sync-branch-feature-branch] map[]": {
96-
{
97-
out: "",
98-
err: fmt.Errorf("exit error 1"),
99-
},
100-
},
101-
"cwd git [rev-parse --short origin/sync-branch-feature-branch] map[]": {
102-
{
103-
out: "sha-x",
104-
},
105-
{
106-
out: "sha-z",
107-
},
108-
},
109-
"cwd git [rev-parse --short sha~] map[]": {
110-
{
111-
out: "sha-y",
112-
},
113-
{
114-
out: "sha-z",
115-
},
116-
},
117-
"cwd git [fetch origin sync-branch-feature-branch] map[]": {
118-
{
119-
out: "",
120-
},
121-
},
50+
waitFunc: func(sb *sandbox, shas []string, targetBranch string, calls int) {
51+
sb.Runner.MustRun("git", []string{"push", "origin", shas[2] + ":refs/heads/" + targetBranch}, nil)
12252
},
53+
expectedCalls: 1,
54+
expectErr: false,
55+
},
56+
{
57+
name: "needs update multiple times",
58+
baseBranch: "main",
59+
syncBranch: "sync-branch",
60+
setupRemote: func(sb *sandbox, shas []string, targetBranch string) {
61+
sb.Runner.MustRun("git", []string{"push", "origin", shas[0] + ":refs/heads/" + targetBranch}, nil)
62+
},
63+
waitFunc: func(sb *sandbox, shas []string, targetBranch string, calls int) {
64+
if calls == 0 {
65+
sb.Runner.MustRun("git", []string{"push", "origin", shas[1] + ":refs/heads/" + targetBranch}, nil)
66+
} else if calls == 1 {
67+
sb.Runner.MustRun("git", []string{"push", "origin", shas[2] + ":refs/heads/" + targetBranch}, nil)
68+
}
69+
},
70+
expectedCalls: 2,
71+
expectErr: false,
72+
},
73+
{
74+
name: "error case bad sync branch",
75+
baseBranch: "main",
76+
syncBranch: "bad-branch",
77+
setupRemote: func(sb *sandbox, shas []string, targetBranch string) {
78+
},
79+
waitFunc: func(sb *sandbox, shas []string, targetBranch string, calls int) {},
80+
expectedCalls: 0,
81+
expectErr: true,
12382
},
12483
}
12584

126-
for _, test := range testCases {
127-
t.Run(test.name, func(t *testing.T) {
128-
origWaitFunc := waitFunc
129-
defer func() {
130-
waitFunc = origWaitFunc
131-
}()
132-
waitFunc = func() {}
85+
for _, tc := range testCases {
86+
tc := tc
87+
t.Run(tc.name, func(t *testing.T) {
88+
t.Parallel()
89+
sb := newSandbox(t)
90+
originDir := t.TempDir()
91+
sb.Runner.MustRun("git", []string{"init", "--bare", "-b", "main", originDir}, nil)
92+
sb.Runner.MustRun("git", []string{"remote", "add", "origin", originDir}, nil)
13393

134-
runner := &waitForCommitMockRunner{
135-
mockRunner: mockRunner{
136-
cwd: "cwd",
137-
calledMethods: make(map[string][]ParameterList),
138-
},
139-
runResults: test.runResults,
94+
var shas []string
95+
for _, msg := range []string{"Commit A", "Commit B", "Commit C", "Commit D"} {
96+
sb.Runner.MustRun("git", []string{"commit", "--allow-empty", "-m", msg}, nil)
97+
shas = append(shas, strings.TrimSpace(sb.Runner.MustRun("git", []string{"rev-parse", "HEAD"}, nil)))
14098
}
14199

142-
err := execWaitForCommit("sync-branch", test.baseBranch, "sha", runner)
143-
if err != nil {
144-
t.Fatalf("execWaitForCommit = %s, want = nil", err)
145-
}
100+
targetBranch := getSyncBranch(tc.syncBranch, tc.baseBranch)
101+
tc.setupRemote(sb, shas, targetBranch)
102+
sb.Runner.MustRun("git", []string{"fetch", "origin"}, nil)
146103

147-
got, ok := runner.Calls("Run")
148-
if !ok {
149-
t.Fatalf("execWaitForCommit() got no calls")
104+
calls := 0
105+
testWaitFunc := func() {
106+
tc.waitFunc(sb, shas, targetBranch, calls)
107+
calls++
150108
}
151-
var want []ParameterList
152-
for _, cmd := range test.calledMethods {
153-
words := strings.Split(cmd, " ")
154-
if len(words) > 0 {
155-
want = append(want, []any{"cwd", words[0], words[1:], map[string]string(nil)})
109+
110+
err := execWaitForCommit(tc.syncBranch, tc.baseBranch, shas[3], sb.Runner, testWaitFunc)
111+
112+
if tc.expectErr {
113+
if err == nil {
114+
t.Fatalf("expected error, got nil")
115+
}
116+
} else {
117+
if err != nil {
118+
t.Fatalf("execWaitForCommit() failed: %v", err)
156119
}
157120
}
158-
if diff := cmp.Diff(want, got); diff != "" {
159-
t.Fatalf("execWaitForCommit() executed commands diff = %s\n want = %+v, got = %+v", diff, want, got)
121+
122+
if calls != tc.expectedCalls {
123+
t.Fatalf("expected waitFunc to be called %d times, got %d", tc.expectedCalls, calls)
160124
}
161125
})
162126
}

0 commit comments

Comments
 (0)