Every command of a check ran over the shared Go build cache beneath a throwaway tmpfs layer of its own, so the digests, the vet, the unit tests and the integration compile of one ask each compiled every package again. With Isolation.CacheLayer a command writes into a layer on disk of its own and Isolated moves it into the ask's kept layer when it ends; later commands read the kept layer above the shared cache, which stays unchanged (ADR 0541 §2, ADR 0448 §3). Empty CacheLayer keeps today's throwaway layer. Ported from feat/try-speed S2 (issue 1921).
65 lines
2.4 KiB
Go
65 lines
2.4 KiB
Go
package buildstep
|
|
|
|
import (
|
|
"strings"
|
|
"testing"
|
|
)
|
|
|
|
// The shared warm caches are read under a throwaway writable layer (novox/hq ADR 0448; issue 1309): a candidate's step
|
|
// writes into them as a build does, and nothing it writes outlives it or reaches a later build; only a trunk build
|
|
// writes them.
|
|
func TestACandidatesStepWritesTheCachesOnlyIntoAThrowawayLayer(t *testing.T) {
|
|
fixedSystem(t)
|
|
iso := Isolation{Workspace: "/w", Caches: []string{"/var/cache/go-build", "/var/cache/npm"}}
|
|
argv, err := iso.Command("go", "test")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
for _, c := range iso.Caches {
|
|
if !holds(argv, "--overlay-src", c, "--tmp-overlay", c) {
|
|
t.Errorf("the cache %s is not under a throwaway layer: %v", c, argv)
|
|
}
|
|
if holds(argv, "--bind", c, c) {
|
|
t.Errorf("a candidate's step writes the cache %s: %v", c, argv)
|
|
}
|
|
}
|
|
iso.WriteCaches = true
|
|
argv, _ = iso.Command("go", "build")
|
|
for _, c := range iso.Caches {
|
|
if !holds(argv, "--bind", c, c) || holds(argv, "--tmp-overlay", c) {
|
|
t.Errorf("a trunk build does not write the cache %s: %v", c, argv)
|
|
}
|
|
}
|
|
// 1921/S2: with a cache layer, a command reads the ask's kept layer above the shared cache and writes into a layer
|
|
// on disk of the ask's own, never into the shared cache and never into a throwaway tmpfs.
|
|
iso = Isolation{Workspace: "/w", Caches: []string{"/cache/gomod", "/cache/gobuild"}, CacheLayer: "/w/cachelayer"}
|
|
argv, err = iso.Command("go", "vet")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
for i, c := range iso.Caches {
|
|
if !holds(argv, "--overlay-src", c, "--overlay-src", keptLayer(iso.CacheLayer, i), "--overlay") {
|
|
t.Errorf("the cache %s is not read beneath the ask's kept layer: %v", c, argv)
|
|
}
|
|
if up := overlayOf(argv, c); up == "" || !strings.HasPrefix(up, "/w/cachelayer/") {
|
|
t.Errorf("the cache %s is written into %q, not a layer of the ask's own: %v", c, up, argv)
|
|
}
|
|
if holds(argv, "--tmp-overlay", c) || holds(argv, "--bind", c, c) {
|
|
t.Errorf("the cache %s is thrown away or written: %v", c, argv)
|
|
}
|
|
}
|
|
if _, err := (Isolation{Workspace: "/w", CacheLayer: "cachelayer"}).Command("go"); err == nil {
|
|
t.Error("a relative cache layer was taken")
|
|
}
|
|
}
|
|
|
|
// overlayOf answers the upper directory a command line gives the cache c, "" when it gives none.
|
|
func overlayOf(argv []string, c string) string {
|
|
for i := 0; i+3 < len(argv); i++ {
|
|
if argv[i] == "--overlay" && argv[i+3] == c {
|
|
return argv[i+1]
|
|
}
|
|
}
|
|
return ""
|
|
}
|