1// SPDX-License-Identifier: MIT
2
3package e2e
4
5import (
6 "context"
7 "os/exec"
8 "strings"
9 "testing"
10 "time"
11
12 "bnema.dev/ermite-runner/internal/execstream"
13 "bnema.dev/ermite-runner/internal/execstream/execpb"
14 "bnema.dev/ermite-runner/internal/sandbox"
15)
16
17func TestContainerSetupGoFindsToolcache(t *testing.T) {
18 image := needE2E(t)
19 ctx, cancel := context.WithTimeout(context.Background(), 5*time.Minute)
20 defer cancel()
21 // Distinguish a missing cache from an unavailable image or Docker daemon.
22 out, err := exec.CommandContext(ctx, "docker", "run", "--rm", "--entrypoint", "sh", image, "-c", "if test -d /opt/hostedtoolcache/go/1.27.1; then echo present; else echo absent; fi").CombinedOutput()
23 if err != nil {
24 t.Fatalf("probe toolcache: %v\n%s", err, out)
25 }
26 if strings.TrimSpace(string(out)) == "absent" {
27 t.Skip("test image has no Go 1.27.1 toolcache")
28 }
29 d := newDriver(t, image)
30 sb, err := d.New()
31 if err != nil {
32 t.Fatal(err)
33 }
34 defer func() {
35 if err := sb.Stop(context.Background()); err != nil {
36 t.Error(err)
37 }
38 }()
39 conn, err := sb.Start(ctx, sandbox.JobSpec{JobID: "e2e-toolcache"})
40 if err != nil {
41 t.Fatal(err)
42 }
43 spec := jobSpec(`on: push
44jobs:
45 j:
46 runs-on: x
47 steps:
48 - uses: actions/setup-go@v7
49 with:
50 go-version: '1.27.1'
51 cache: false
52 - run: go version
53`)
54 var logs []string
55 var result *execpb.JobResult
56 _, exit, err := execstream.DriveJob(conn, &execpb.Run{Job: spec}, nil, execstream.JobHandler{
57 Resolve: func(_ context.Context, r *execpb.ResolveRequest) *execpb.ResolveResponse {
58 resp := &execpb.ResolveResponse{}
59 for _, ref := range r.Uses {
60 if ref != "actions/setup-go@v7" {
61 return &execpb.ResolveResponse{Error: "unexpected action: " + ref}
62 }
63 resp.Actions = append(resp.Actions, &execpb.ResolvedAction{Ref: ref, NameWithOwner: "actions/setup-go", ResolvedSha: "v7", TarballUrl: "https://codeload.github.com/actions/setup-go/tar.gz/refs/tags/v7"})
64 }
65 return resp
66 },
67 Log: func(l *execpb.Log) { logs = append(logs, l.Text) },
68 JobResult: func(r *execpb.JobResult) { result = r },
69 })
70 all := strings.Join(logs, "\n")
71 if err != nil {
72 t.Fatalf("drive: %v\n%s", err, all)
73 }
74 if result == nil || result.Conclusion != execpb.StepConclusion_STEP_CONCLUSION_SUCCESS || exit == nil || exit.Code != 0 {
75 t.Fatalf("result %v exit %v\n%s", result, exit, all)
76 }
77 for _, want := range []string{"Found in cache", "go version go1.27.1"} {
78 if !strings.Contains(all, want) {
79 t.Errorf("log lacks %q\n%s", want, all)
80 }
81 }
82}