Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 26 additions & 1 deletion .ci/magician/cmd/sandbox_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@
package cmd

import (
"os"
"path/filepath"
"strings"
"testing"

"magician/exec"
Expand All @@ -26,14 +29,36 @@ type sandbox struct {
Runner ExecRunner
}

// Routes some commands to fake sandbox scripts, bypassing $PATH.
type interceptingRunner struct {
*exec.Runner
sbDir string
}

func (s *interceptingRunner) Run(name string, args []string, env map[string]string) (string, error) {
// Only intercept bare commands (git, make, etc.)
if !strings.Contains(name, string(filepath.Separator)) {
sandboxBin := filepath.Join(s.sbDir, name)
if _, err := os.Stat(sandboxBin); err == nil {
name = sandboxBin
}
}
return s.Runner.Run(name, args, env)
}

func newSandbox(t *testing.T) *sandbox {
dir := t.TempDir()

runner, err := exec.NewRunner()
realRunner, err := exec.NewRunner()
if err != nil {
t.Fatalf("Failed to create runner: %v", err)
}

runner := &interceptingRunner{
Runner: realRunner,
sbDir: dir,
}

if err := runner.PushDir(dir); err != nil {
t.Fatalf("Failed to push dir: %v", err)
}
Expand Down
96 changes: 50 additions & 46 deletions .ci/magician/cmd/vcr_merge_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@ import (
"os"
"strings"
"testing"

"github.com/google/go-cmp/cmp"
)

func TestExecVCRMerge(t *testing.T) {
Expand All @@ -15,33 +13,16 @@ func TestExecVCRMerge(t *testing.T) {
baseBranch string
commitSha string
lsReturnedError bool
calledMethods []string
}{
{
name: "base branch is main",
baseBranch: "main",
commitSha: "sha",
calledMethods: []string{
"gcloud storage ls gs://ci-vcr-cassettes/refs/heads/auto-pr-123/fixtures/",
"gcloud storage cp gs://ci-vcr-cassettes/refs/heads/auto-pr-123/fixtures/* gs://ci-vcr-cassettes/fixtures/",
"gcloud storage rm --recursive gs://ci-vcr-cassettes/refs/heads/auto-pr-123/",
"gcloud storage ls gs://ci-vcr-cassettes/beta/refs/heads/auto-pr-123/fixtures/",
"gcloud storage cp gs://ci-vcr-cassettes/beta/refs/heads/auto-pr-123/fixtures/* gs://ci-vcr-cassettes/beta/fixtures/",
"gcloud storage rm --recursive gs://ci-vcr-cassettes/beta/refs/heads/auto-pr-123/",
},
},
{
name: "base branch is not main",
baseBranch: "test-branch",
commitSha: "sha",
calledMethods: []string{
"gcloud storage ls gs://ci-vcr-cassettes/refs/heads/auto-pr-123/fixtures/",
"gcloud storage cp gs://ci-vcr-cassettes/refs/heads/auto-pr-123/fixtures/* gs://ci-vcr-cassettes/refs/branches/test-branch/fixtures/",
"gcloud storage rm --recursive gs://ci-vcr-cassettes/refs/heads/auto-pr-123/",
"gcloud storage ls gs://ci-vcr-cassettes/beta/refs/heads/auto-pr-123/fixtures/",
"gcloud storage cp gs://ci-vcr-cassettes/beta/refs/heads/auto-pr-123/fixtures/* gs://ci-vcr-cassettes/beta/refs/branches/test-branch/fixtures/",
"gcloud storage rm --recursive gs://ci-vcr-cassettes/beta/refs/heads/auto-pr-123/",
},
},
{
name: "pr not found",
Expand All @@ -53,10 +34,6 @@ func TestExecVCRMerge(t *testing.T) {
commitSha: "sha",
lsReturnedError: true,
baseBranch: "main",
calledMethods: []string{
"gcloud storage ls gs://ci-vcr-cassettes/refs/heads/auto-pr-123/fixtures/",
"gcloud storage ls gs://ci-vcr-cassettes/beta/refs/heads/auto-pr-123/fixtures/",
},
},
}

Expand All @@ -67,34 +44,61 @@ func TestExecVCRMerge(t *testing.T) {
},
calledMethods: make(map[string][][]any),
}
for _, test := range testCases {
t.Run(test.name, func(t *testing.T) {
runner := &mockRunner{
cwd: "cwd",
calledMethods: make(map[string][]ParameterList),
cmdResults: make(map[string]string),
}
if test.lsReturnedError {
runner.notifyError = true
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
sb := newSandbox(t)

// Intercepts the hardcoded `gcloud storage` commands and translates gs:// URLs into local directory operations.
fakeGcloud := `#!/bin/bash
if [ "$1" = "storage" ]; then
if [ "$2" = "ls" ]; then
TARGET=$(echo $3 | sed 's|gs://|gs/|')
ls "$TARGET" > /dev/null 2>&1
exit $?
elif [ "$2" = "cp" ]; then
SRC=$(echo $3 | sed 's|gs://|gs/|' | sed 's|/\*$||')
DEST=$(echo $4 | sed 's|gs://|gs/|')
mkdir -p "$DEST"
cp -r "$SRC"/* "$DEST"
elif [ "$2" = "rm" ]; then
TARGET=$(echo $4 | sed 's|gs://|gs/|')
rm -r "$TARGET"
fi
fi`
sb.Runner.WriteFile("gcloud", fakeGcloud)
sb.Runner.MustRun("chmod", []string{"+x", "gcloud"}, nil)

if !tc.lsReturnedError && tc.name != "pr not found" {
sb.Runner.MustRun("mkdir", []string{"-p", "gs/ci-vcr-cassettes/refs/heads/auto-pr-123/fixtures"}, nil)
sb.Runner.MustRun("mkdir", []string{"-p", "gs/ci-vcr-cassettes/beta/refs/heads/auto-pr-123/fixtures"}, nil)
sb.Runner.WriteFile("gs/ci-vcr-cassettes/refs/heads/auto-pr-123/fixtures/dummy1.txt", "data")
sb.Runner.WriteFile("gs/ci-vcr-cassettes/beta/refs/heads/auto-pr-123/fixtures/dummy2.txt", "data")
}
err := execVCRMerge(githubClient, test.commitSha, test.baseBranch, runner)

err := execVCRMerge(githubClient, tc.commitSha, tc.baseBranch, sb.Runner)
if err != nil {
t.Fatalf("execVCRMerge = %s, want = nil", err)
t.Fatalf("execVCRMerge() failed: %v", err)
}

got, ok := runner.Calls("Run")
if !ok && test.calledMethods != nil {
t.Fatalf("execVCRMerge() expect %d calls, got none", len(test.calledMethods))
}
var want []ParameterList
for _, cmd := range test.calledMethods {
words := strings.Split(cmd, " ")
if len(words) > 0 {
want = append(want, []any{"cwd", words[0], words[1:], map[string]string(nil)})
if !tc.lsReturnedError && tc.name != "pr not found" {
destBranchPath := ""
if tc.baseBranch != "main" {
destBranchPath = "/refs/branches/" + tc.baseBranch
}

if _, err := os.Stat(sb.Dir + "/gs/ci-vcr-cassettes" + destBranchPath + "/fixtures/dummy1.txt"); os.IsNotExist(err) {
t.Fatalf("Expected file to be copied to /gs/ci-vcr-cassettes%s/fixtures/dummy1.txt", destBranchPath)
}
if _, err := os.Stat(sb.Dir + "/gs/ci-vcr-cassettes/beta" + destBranchPath + "/fixtures/dummy2.txt"); os.IsNotExist(err) {
t.Fatalf("Expected file to be copied to /gs/ci-vcr-cassettes/beta%s/fixtures/dummy2.txt", destBranchPath)
}

if _, err := os.Stat(sb.Dir + "/gs/ci-vcr-cassettes/refs/heads/auto-pr-123/"); !os.IsNotExist(err) {
t.Fatalf("Expected source directory /gs/ci-vcr-cassettes/refs/heads/auto-pr-123/ to be deleted")
}
if _, err := os.Stat(sb.Dir + "/gs/ci-vcr-cassettes/beta/refs/heads/auto-pr-123/"); !os.IsNotExist(err) {
t.Fatalf("Expected source directory /gs/ci-vcr-cassettes/beta/refs/heads/auto-pr-123/ to be deleted")
}
}
if diff := cmp.Diff(want, got); diff != "" {
t.Fatalf("execVCRMerge() executed commands diff = %s\n want = %+v, got = %+v", diff, want, got)
}
})
}
Expand Down
Loading