Fill the shared module cache with the release by the probe before the real-go integration tests, and skip loudly when it cannot (issue 1560, ADR 0476)
This commit is contained in:
@@ -7,11 +7,14 @@ import (
|
||||
"bytes"
|
||||
"compress/gzip"
|
||||
"context"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/fs"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"sync"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
@@ -21,7 +24,52 @@ func TestMain(m *testing.M) {
|
||||
if len(os.Args) > 1 && os.Args[1] == busArg {
|
||||
os.Exit(runBus(os.Args[2:]))
|
||||
}
|
||||
os.Exit(m.Run())
|
||||
code := m.Run()
|
||||
releaseCleanup()
|
||||
os.Exit(code)
|
||||
}
|
||||
|
||||
// The module cache the real-go tests share, filled once by the probe as the module's start does (ADR 0476 §3): the
|
||||
// steps carry GOTOOLCHAIN=<RecipeGo> and fetch no toolchain, so a test that runs the real go needs the release in its
|
||||
// cache first.
|
||||
var (
|
||||
releaseOnce sync.Once
|
||||
releaseCache string
|
||||
releaseErr error
|
||||
)
|
||||
|
||||
// needRelease answers the cache with the recipe's release in it, filled by ProbeGo, and skips loudly when the probe
|
||||
// cannot have it (no network to Go's download service where the check runs); the build node has it (issues 1486, 1560).
|
||||
func needRelease(t *testing.T, home string) string {
|
||||
t.Helper()
|
||||
releaseOnce.Do(func() {
|
||||
releaseCache, releaseErr = os.MkdirTemp("", "release-cache")
|
||||
if releaseErr != nil {
|
||||
return
|
||||
}
|
||||
var v string
|
||||
if v, releaseErr = ProbeGo(home, releaseCache)(context.Background()); releaseErr == nil && v != RecipeGo {
|
||||
releaseErr = fmt.Errorf("the probe read %s", v)
|
||||
}
|
||||
})
|
||||
if releaseErr != nil {
|
||||
t.Skipf("NOT RUN: ADR 0476: the probe could not put %s into the module cache where this check runs (%v); proven live on a build node", RecipeGo, releaseErr)
|
||||
}
|
||||
return releaseCache
|
||||
}
|
||||
|
||||
// releaseCleanup removes the shared cache; Go writes its module cache read-only.
|
||||
func releaseCleanup() {
|
||||
if releaseCache == "" {
|
||||
return
|
||||
}
|
||||
filepath.WalkDir(releaseCache, func(p string, d fs.DirEntry, err error) error {
|
||||
if err == nil && d.IsDir() {
|
||||
os.Chmod(p, 0o755)
|
||||
}
|
||||
return nil
|
||||
})
|
||||
os.RemoveAll(releaseCache)
|
||||
}
|
||||
|
||||
// needTools skips, loudly, a test whose tools are not installed where the check runs (the mesh's Go toolchain image
|
||||
@@ -68,7 +116,7 @@ func TestUnitLevelRunsTheRealGoOnTheFixtureRepositories(t *testing.T) {
|
||||
for name, w := range want {
|
||||
tree := repository(t, name)
|
||||
home := t.TempDir()
|
||||
m := &Module{Home: home, Work: t.TempDir(), Cache: t.TempDir()}
|
||||
m := &Module{Home: home, Work: t.TempDir(), Cache: needRelease(t, home)}
|
||||
m.Run = StepRunner(home)
|
||||
res, err := m.runLevel(context.Background(), tree, levelOpts{level: LevelUnit, bounds: Bounds{Run: UnitBound}})
|
||||
if err != nil {
|
||||
@@ -111,7 +159,7 @@ func TestIntegrationLevelRunsAgainstARealStoreAndBusAndLeavesNothing(t *testing.
|
||||
t.Fatal(err)
|
||||
}
|
||||
home := t.TempDir()
|
||||
m := &Module{Recipe: Current(), Home: home, Work: work, Cache: t.TempDir()}
|
||||
m := &Module{Recipe: Current(), Home: home, Work: work, Cache: needRelease(t, home)}
|
||||
m.Run = StepRunner(home)
|
||||
res, err := m.integration(context.Background(), "ws1", filepath.Join(work, "ws1", "tree"), nil)
|
||||
if err != nil {
|
||||
@@ -149,7 +197,7 @@ func TestBuildTwiceGivesOneDigestAndOneExecutable(t *testing.T) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
home := t.TempDir()
|
||||
m := &Module{Home: home, Work: work, Cache: t.TempDir()}
|
||||
m := &Module{Home: home, Work: work, Cache: needRelease(t, home)}
|
||||
m.Run = StepRunner(home)
|
||||
args := map[string]any{"workspace": "ws1", "module": ".", "artifact": "tools"}
|
||||
first, err := m.build(context.Background(), args)
|
||||
|
||||
@@ -25,8 +25,11 @@ func TestTheProbePutsTheReleaseIntoTheCacheAndAStepReadsItOffline(t *testing.T)
|
||||
})
|
||||
})
|
||||
v, err := ProbeGo(home, cache)(context.Background())
|
||||
if err != nil || v != RecipeGo {
|
||||
t.Fatalf("probe = %q, %v; want %s", v, err, RecipeGo)
|
||||
if err != nil {
|
||||
t.Skipf("NOT RUN: ADR 0476: the probe could not put %s into the module cache where this check runs (%v); proven live on a build node", RecipeGo, err)
|
||||
}
|
||||
if v != RecipeGo {
|
||||
t.Fatalf("probe = %q; want %s", v, RecipeGo)
|
||||
}
|
||||
dirs, _ := filepath.Glob(filepath.Join(cache, "gomod", "golang.org", "toolchain@v0.0.1-"+RecipeGo+".*"))
|
||||
if len(dirs) != 1 {
|
||||
|
||||
Reference in New Issue
Block a user