aboutsummaryrefslogtreecommitdiffhomepage
path: root/internal/pkg/pkg_test.go
diff options
context:
space:
mode:
authorOphestra <cat@gensokyo.uk>2026-08-29 18:58:06 +0900
committerOphestra <cat@gensokyo.uk>2026-08-29 18:58:06 +0900
commitc2d900ec74e03e9c782cfe7b7ce06ff62cda6601 (patch)
treefb13320bfdc62d810aa59769e8809dc2f707919e /internal/pkg/pkg_test.go
parentbd4f29909e0750a4660eaf48e3169777a265b0ab (diff)
pkg: move from internalHEADstagingmasterdevelop
Closes #43. Signed-off-by: Ophestra <cat@gensokyo.uk>
Diffstat (limited to 'internal/pkg/pkg_test.go')
-rw-r--r--internal/pkg/pkg_test.go2375
1 files changed, 0 insertions, 2375 deletions
diff --git a/internal/pkg/pkg_test.go b/internal/pkg/pkg_test.go
deleted file mode 100644
index b23948f8..00000000
--- a/internal/pkg/pkg_test.go
+++ /dev/null
@@ -1,2375 +0,0 @@
-package pkg_test
-
-import (
- "archive/tar"
- "bytes"
- "context"
- "crypto/sha512"
- "encoding/base64"
- "errors"
- "fmt"
- "io"
- "io/fs"
- "log"
- "net/http"
- "os"
- "path/filepath"
- "reflect"
- "strconv"
- "strings"
- "sync"
- "syscall"
- "testing"
- "testing/fstest"
- "time"
- "unique"
- "unsafe"
-
- "hakurei.app/check"
- "hakurei.app/container"
- "hakurei.app/fhs"
- "hakurei.app/internal/info"
- "hakurei.app/internal/landlock"
- "hakurei.app/internal/pkg"
- "hakurei.app/internal/stub"
- "hakurei.app/message"
-)
-
-var skipLock = func() pkg.CacheAttr {
- var attr pkg.CacheAttr
- *(*bool)(unsafe.Pointer(reflect.ValueOf(&attr).
- Elem().
- FieldByName("skipLock").
- UnsafeAddr())) = true
- return attr
-}()
-
-var (
- // extension is a string uniquely identifying a set of custom [Artifact]
- // implementations registered by calling [Register].
- //
- //go:linkname extension hakurei.app/internal/pkg.extension
- extension string
-
- // opened is false if [Open] was never called.
- //
- //go:linkname opened hakurei.app/internal/pkg.opened
- opened bool
-
- // irArtifact refers to artifact IR interpretation functions and must not be
- // written to directly.
- //
- //go:linkname irArtifact hakurei.app/internal/pkg.irArtifact
- irArtifact map[pkg.Kind]pkg.IRReadFunc
-
- // statusHeader is the header written to all status files in dirStatus.
- //
- //go:linkname statusHeader hakurei.app/internal/pkg.statusHeader
- statusHeader string
-)
-
-// newRContext returns the address of a new [pkg.RContext] unsafely created for
-// the specified [testing.TB].
-func newRContext(tb testing.TB, c *pkg.Cache) *pkg.RContext {
- var r pkg.RContext
- rContextVal := reflect.ValueOf(&r).Elem().FieldByName("ctx")
- reflect.NewAt(
- rContextVal.Type(),
- unsafe.Pointer(rContextVal.UnsafeAddr()),
- ).Elem().Set(reflect.ValueOf(tb.Context()))
- rCacheVal := reflect.ValueOf(&r).Elem().FieldByName("cache")
- reflect.NewAt(
- rCacheVal.Type(),
- unsafe.Pointer(rCacheVal.UnsafeAddr()),
- ).Elem().Set(reflect.ValueOf(c))
- return &r
-}
-
-// overrideIdent overrides the ID method of [Artifact].
-type overrideIdent struct {
- id pkg.ID
- pkg.TrivialArtifact
-}
-
-func (a overrideIdent) ID() pkg.ID { return a.id }
-
-// overrideIdentFile overrides the ID method of [FileArtifact].
-type overrideIdentFile struct {
- id pkg.ID
- pkg.FileArtifact
-}
-
-func (a overrideIdentFile) ID() pkg.ID { return a.id }
-
-// A knownIdentArtifact implements [pkg.KnownIdent] and [Artifact]
-type knownIdentArtifact interface {
- pkg.KnownIdent
- pkg.TrivialArtifact
-}
-
-// A knownIdentFile implements [pkg.KnownIdent] and [FileArtifact]
-type knownIdentFile interface {
- pkg.KnownIdent
- pkg.FileArtifact
-}
-
-// overrideChecksum overrides the Checksum method of [Artifact].
-type overrideChecksum struct {
- checksum pkg.Checksum
- knownIdentArtifact
-}
-
-func (a overrideChecksum) Checksum() pkg.Checksum { return a.checksum }
-
-// overrideChecksumFile overrides the Checksum method of [FileArtifact].
-type overrideChecksumFile struct {
- checksum pkg.Checksum
- knownIdentFile
-}
-
-func (a overrideChecksumFile) Checksum() pkg.Checksum { return a.checksum }
-
-// A stubArtifact implements [TrivialArtifact] with hardcoded behaviour.
-type stubArtifact struct {
- kind pkg.Kind
- params []byte
- deps []pkg.Artifact
-
- cure func(t *pkg.TContext) error
-}
-
-func (a *stubArtifact) Kind() pkg.Kind { return a.kind }
-func (a *stubArtifact) Params(ctx *pkg.IContext) { ctx.Write(a.params) }
-func (a *stubArtifact) Inputs() []pkg.Artifact { return a.deps }
-func (a *stubArtifact) Cure(t *pkg.TContext) error { return a.cure(t) }
-func (*stubArtifact) IsExclusive() bool { return false }
-
-// A stubArtifactF implements [FloodArtifact] with hardcoded behaviour.
-type stubArtifactF struct {
- kind pkg.Kind
- params []byte
- deps []pkg.Artifact
- excl bool
-
- cure func(f *pkg.FContext) error
-}
-
-func (a *stubArtifactF) Kind() pkg.Kind { return a.kind }
-func (a *stubArtifactF) Params(ctx *pkg.IContext) { ctx.Write(a.params) }
-func (a *stubArtifactF) Inputs() []pkg.Artifact { return a.deps }
-func (a *stubArtifactF) Cure(f *pkg.FContext) error { return a.cure(f) }
-func (a *stubArtifactF) IsExclusive() bool { return a.excl }
-
-// A stubFile implements [FileArtifact] with hardcoded behaviour.
-type stubFile struct {
- data []byte
- err error
-
- stubArtifact
-}
-
-func (*stubFile) IsExecutable() bool { return false }
-
-func (a *stubFile) Cure(*pkg.RContext) (io.ReadCloser, error) {
- return io.NopCloser(bytes.NewReader(a.data)), a.err
-}
-
-// newStubFile returns an implementation of [pkg.File] with hardcoded behaviour.
-func newStubFile(
- kind pkg.Kind,
- id pkg.ID,
- sum *pkg.Checksum,
- data []byte,
- err error,
-) pkg.FileArtifact {
- f := overrideIdentFile{id, &stubFile{data, err, stubArtifact{
- kind,
- nil,
- nil,
- func(*pkg.TContext) error {
- panic("unreachable")
- },
- }}}
- if sum == nil {
- return f
- } else {
- return overrideChecksumFile{*sum, f}
- }
-}
-
-// stubExtern implements [External] with hardcoded prepared outcomes.
-type stubExtern struct {
- artifact map[unique.Handle[pkg.ID]]pkg.Checksum
- checksum map[unique.Handle[pkg.Checksum]]fstest.MapFS
- status map[unique.Handle[pkg.ID]]string
-}
-
-func (e stubExtern) Artifact(_ context.Context, id unique.Handle[pkg.ID]) (*pkg.Checksum, error) {
- if checksum, ok := e.artifact[id]; ok {
- return &checksum, nil
- }
- return nil, nil
-}
-
-func (e stubExtern) Checksum(checksum unique.Handle[pkg.Checksum]) pkg.Artifact {
- var buf bytes.Buffer
- if err := pkg.Write(e.checksum[checksum], ".", &buf); err != nil {
- panic(err)
- }
- return pkg.NewArchive(pkg.NewFile("", buf.Bytes()))
-}
-
-func (e stubExtern) Status(_ *pkg.RContext, id unique.Handle[pkg.ID]) (io.ReadCloser, error) {
- if status, ok := e.status[id]; ok {
- return io.NopCloser(strings.NewReader(status)), nil
- }
- return nil, nil
-}
-
-// destroyArtifact removes all traces of an [Artifact] from the on-disk cache.
-// Do not use this in a test case without a very good reason to do so.
-func destroyArtifact(
- t *testing.T,
- base *check.Absolute,
- c *pkg.Cache,
- a pkg.Artifact,
-) {
- if pathname, checksum, err := c.Cure(a); err != nil {
- t.Fatalf("Cure: error = %v", err)
- } else if err = os.Remove(pathname.String()); err != nil {
- t.Fatal(err)
- } else {
- p := base.Append(
- "checksum",
- pkg.Encode(checksum.Value()),
- )
- if err = filepath.WalkDir(p.String(), func(
- path string,
- d fs.DirEntry,
- err error,
- ) error {
- if err != nil {
- return err
- }
- if d.IsDir() {
- return os.Chmod(path, 0700)
- }
- return nil
- }); err != nil && !errors.Is(err, os.ErrNotExist) {
- t.Fatal(err)
- }
- if err = os.RemoveAll(p.String()); err != nil {
- t.Fatal(err)
- }
- }
-}
-
-// newDestroyArtifactFunc returns a function that calls destroyArtifact.
-func newDestroyArtifactFunc(a pkg.Artifact) func(
- t *testing.T,
- base *check.Absolute,
- c *pkg.Cache,
-) {
- return func(
- t *testing.T,
- base *check.Absolute,
- c *pkg.Cache,
- ) {
- destroyArtifact(t, base, c, a)
- }
-}
-
-// destroyStatus counts non-substitution status entries and destroys them.
-func destroyStatus(t *testing.T, base *check.Absolute, c, s int) {
- dents, err := os.ReadDir(base.Append("status").String())
- if err != nil {
- t.Fatal(err)
- }
-
- var gotC, gotS int
- for _, dent := range dents {
- if err = os.Remove(base.Append(
- "status",
- dent.Name(),
- ).String()); err != nil {
- t.Fatal(err)
- }
-
- if dent.Type().IsRegular() {
- gotC++
- continue
- }
- if dent.Type()&fs.ModeSymlink == fs.ModeSymlink {
- gotS++
- continue
- }
- t.Errorf("%s: %s", dent.Name(), dent.Type())
- }
-
- if gotC != c {
- t.Errorf("status: c = %d, want %d", gotC, c)
- }
- if gotS != s {
- t.Errorf("status: s = %d, want %d", gotS, s)
- }
-}
-
-func TestIdent(t *testing.T) {
- t.Parallel()
-
- testCases := []struct {
- name string
- a pkg.Artifact
- want unique.Handle[pkg.ID]
- }{
- {"decompress", &stubArtifact{
- pkg.KindDecompress,
- []byte{pkg.Gzip, 0, 0, 0, 0, 0, 0, 0},
- []pkg.Artifact{
- overrideIdent{pkg.ID{}, new(stubArtifact)},
- },
- nil,
- }, unique.Make[pkg.ID](pkg.MustDecode(
- "fkmge-H56Ph2LzNNbEUjTypes8LfOxrF_CEXg07kq6ho_nbTNvzQde9-bjB7gyB_",
- ))},
- }
-
- msg := message.New(log.New(os.Stderr, "ident: ", 0))
- msg.SwapVerbose(true)
- var cache *pkg.Cache
- if a, err := check.NewAbs(t.TempDir()); err != nil {
- t.Fatal(err)
- } else if cache, err = pkg.Open(t.Context(), msg, a, nil); err != nil {
- t.Fatal(err)
- }
- t.Cleanup(cache.Close)
-
- for _, tc := range testCases {
- t.Run(tc.name, func(t *testing.T) {
- t.Parallel()
-
- if got := cache.Ident(tc.a); got != tc.want {
- t.Errorf("Ident: %s, want %s",
- pkg.Encode(got.Value()),
- pkg.Encode(tc.want.Value()),
- )
- }
- })
- }
-}
-
-// An expectsKnown describes an expected file or directory.
-type expectsKnown interface {
- // hash returns the checksum of the represented data.
- hash() (checksum pkg.Checksum)
-}
-
-// An expectsChecksum is a prepared checksum value.
-type expectsChecksum pkg.Checksum
-
-// hash returns e.
-func (e expectsChecksum) hash() pkg.Checksum { return e }
-
-// An expectsFile is the contents of a file expected by the test suite.
-type expectsFile []byte
-
-// hash computes the checksum of e.
-func (e expectsFile) hash() (checksum pkg.Checksum) {
- h := sha512.New384()
- h.Write(e)
- h.Sum(checksum[:0])
- return
-}
-
-// An expectsFS describes the state of a filesystem expected by the test suite.
-type expectsFS fstest.MapFS
-
-// hash computes the checksum of e.
-func (e expectsFS) hash() (checksum pkg.Checksum) {
- if err := pkg.SumFS(&checksum, fstest.MapFS(e), "."); err != nil {
- panic(err)
- }
- return
-}
-
-// expectsFrom generates expectsFS for a filesystem directory.
-func expectsFrom(pathname string) string {
- var buf strings.Builder
- buf.WriteString("expectsFS{\n")
- if err := filepath.WalkDir(pathname, func(path string, d fs.DirEntry, err error) error {
- if err != nil {
- return err
- }
-
- var rel string
- if rel, err = filepath.Rel(pathname, path); err != nil {
- return err
- }
- buf.WriteString("\t" + strconv.Quote(rel) + ": {Mode: ")
-
- var fi fs.FileInfo
- if fi, err = d.Info(); err != nil {
- return err
- }
- mode := fi.Mode()
-
- switch {
- case mode.IsDir():
- buf.WriteString("fs.ModeDir | 0" +
- strconv.FormatInt(int64(mode&^fs.ModeDir), 8))
-
- case mode&fs.ModeSymlink != 0:
- buf.WriteString("fs.ModeSymlink | 0" +
- strconv.FormatInt(int64(mode&^fs.ModeSymlink), 8) +
- ", Data: []byte(")
- var linkname string
- if linkname, err = os.Readlink(path); err != nil {
- return err
- }
- buf.WriteString(strconv.Quote(linkname))
- buf.WriteByte(')')
-
- case mode.IsRegular():
- buf.WriteString("0" + strconv.FormatInt(int64(mode), 8))
- var p []byte
- if p, err = os.ReadFile(path); err != nil {
- return err
- }
-
- if len(p) > 0 {
- buf.WriteString(", Data: []byte(")
- buf.WriteString(strconv.Quote(unsafe.String(unsafe.SliceData(p), len(p))))
- buf.WriteByte(')')
- }
- }
- buf.WriteString("},\n")
- return nil
- }); err != nil {
- panic(err)
- }
- buf.WriteString("}")
- return buf.String()
-}
-
-// cacheTestCase is a test case passed to checkWithCache where a new instance
-// of [pkg.Cache] is prepared for the test case, and is validated and removed
-// on test completion.
-type cacheTestCase struct {
- name string
- flags int
- early func(t *testing.T, base *check.Absolute)
- f func(t *testing.T, base *check.Absolute, c *pkg.Cache)
- want expectsFS
-}
-
-const (
- // checkDestroySubstitutes arranges for substitutes to be destroyed before
- // measurement during checkWithCache.
- checkDestroySubstitutes = 1 << (iota + 32)
-)
-
-// makeBase returns a [pkg.Cache] base directory created for tb.
-func makeBase(tb testing.TB) (base *check.Absolute) {
- tb.Helper()
-
- base = check.MustAbs(tb.TempDir())
- if err := os.Chmod(base.String(), 0700); err != nil {
- tb.Fatal(err)
- }
- tb.Cleanup(func() {
- if err := filepath.WalkDir(base.String(), func(path string, d fs.DirEntry, err error) error {
- if err != nil {
- tb.Error(err)
- return nil
- }
- if !d.IsDir() {
- return nil
- }
- return os.Chmod(path, 0700)
- }); err != nil {
- tb.Fatal(err)
- }
- })
- return
-}
-
-// checkWithCache runs a slice of cacheTestCase.
-func checkWithCache(t *testing.T, testCases []cacheTestCase) {
- t.Helper()
-
- for _, tc := range testCases {
- t.Run(tc.name, func(t *testing.T) {
- t.Helper()
- t.Parallel()
-
- base := makeBase(t)
- msg := message.New(log.New(os.Stderr, "cache: ", 0))
- msg.SwapVerbose(testing.Verbose())
-
- flags := tc.flags | pkg.CSuppressInit
-
- if info.CanDegrade {
- if _, err := landlock.GetABI(); err != nil {
- if !errors.Is(err, syscall.ENOSYS) {
- t.Fatalf("LandlockGetABI: error = %v", err)
- }
- flags |= pkg.CHostAbstract
- t.Log("Landlock LSM is unavailable, setting CHostAbstract")
- }
- }
-
- var scrubFunc func() error // scrub after hashing
- if c, err := pkg.Open(t.Context(), msg, base, &pkg.CacheAttr{
- Cures: 1 << 4,
- Flags: flags,
- }); err != nil {
- t.Fatalf("Open: error = %v", err)
- } else {
- t.Cleanup(c.Close)
- if tc.early != nil {
- tc.early(t, base)
- }
- tc.f(t, base, c)
- scrubFunc = func() error {
- err = c.Scrub(1 << 7)
- idents, checksums, cleanErr := c.Clean(false, false)
- if len(idents) > 0 {
- t.Errorf("destroyed %d idents", len(idents))
- }
- if len(checksums) > 0 {
- t.Errorf("destroyed %d checksums", len(checksums))
- }
- return errors.Join(err, cleanErr)
- }
- }
-
- var restoreTemp bool
- if _, err := os.Lstat(base.Append("temp").String()); err != nil {
- if !errors.Is(err, os.ErrNotExist) {
- t.Fatal(err)
- }
- } else {
- restoreTemp = true
- }
-
- // destroy lock and variant file to avoid changing cache checksums
- for _, s := range []string{
- "lock",
- "variant",
- } {
- pathname := base.Append(s)
- if p, err := os.ReadFile(pathname.String()); err != nil {
- t.Fatal(err)
- } else if len(p) != 0 {
- t.Fatalf("file %q: %q", s, string(p))
- }
- if err := os.Remove(pathname.String()); err != nil {
- t.Fatal(err)
- }
- }
-
- // destroy non-deterministic substitutes
- if tc.flags&checkDestroySubstitutes != 0 {
- substitute := base.Append("substitute")
- if err := os.RemoveAll(substitute.String()); err != nil {
- t.Fatal(err)
- } else if err = os.Mkdir(substitute.String(), 0700); err != nil {
- t.Fatal(err)
- }
- }
-
- // destroy empty status directory
- if err := syscall.Rmdir(base.Append("status").String()); err != nil {
- if !errors.Is(err, syscall.ENOTEMPTY) {
- t.Fatal(err)
- }
- }
-
- // destroy empty fault directory
- if err := os.Remove(base.Append("fault").String()); err != nil {
- t.Fatal(err)
- }
-
- want := tc.want.hash()
-
- var checksum pkg.Checksum
- if err := pkg.SumDir(&checksum, base); err != nil {
- t.Fatalf("SumDir: error = %v", err)
- } else if checksum != want {
- t.Fatal(expectsFrom(base.String()))
- }
-
- if err := scrubFunc(); err != nil {
- t.Fatal("cache contains inconsistencies\n\n" + err.Error())
- }
-
- if restoreTemp {
- if err := os.Mkdir(
- base.Append("temp").String(),
- 0700,
- ); err != nil {
- t.Fatal(err)
- }
- }
-
- // validate again to make sure scrub did not condemn anything
- if err := pkg.SumDir(&checksum, base); err != nil {
- t.Fatalf("SumDir: error = %v", err)
- } else if checksum != want {
- t.Fatalf("(scrubbed) %s", expectsFrom(base.String()))
- }
- })
- }
-}
-
-// A cureStep contains an [Artifact] to be cured, and the expected outcome.
-type cureStep struct {
- name string
-
- a pkg.Artifact
-
- pathname *check.Absolute
- output expectsKnown
- whence int
- err error
-}
-
-// ignorePathname is passed to cureMany to skip the pathname check.
-var ignorePathname = check.MustAbs("/\x00")
-
-// cureMany cures many artifacts against a [Cache] and checks their outcomes.
-func cureMany(t *testing.T, c *pkg.Cache, steps []cureStep) {
- t.Helper()
-
- makeChecksumH := func(checksum pkg.Checksum) unique.Handle[pkg.Checksum] {
- if checksum == (pkg.Checksum{}) {
- return unique.Handle[pkg.Checksum]{}
- }
- return unique.Make(checksum)
- }
-
- for _, step := range steps {
- t.Log("cure step:", step.name)
- if pathname, checksum, whence, err := c.CureWhence(step.a); !reflect.DeepEqual(err, step.err) {
- faults, _err := c.ReadFaults(step.a)
- if _err != nil {
- t.Errorf("ReadFaults: error = %v", _err)
- }
-
- var p []byte
- for _, fault := range faults {
- p, _err = os.ReadFile(fault.String())
- if _err != nil {
- t.Error(_err)
- continue
- }
- t.Log(string(p))
- t.Logf("faulting cure terminated %s ago", time.Since(faults[0].Time()))
- }
- t.Fatalf("Cure: error = %v, want %v", err, step.err)
- } else if step.whence != whence {
- t.Fatalf("Cure: whence = %s, want %s", pkg.WhenceString(whence), pkg.WhenceString(step.whence))
- } else if step.pathname != ignorePathname && !pathname.Is(step.pathname) {
- t.Fatalf("Cure: pathname = %q, want %q", pathname, step.pathname)
- } else if step.output == nil || checksum != makeChecksumH(step.output.hash()) {
- if pathname != nil {
- if name, _err := filepath.EvalSymlinks(pathname.String()); _err != nil {
- t.Fatal(_err)
- } else {
- t.Fatal(expectsFrom(name))
- }
- } else if checksum != (unique.Handle[pkg.Checksum]{}) {
- t.Fatalf("Cure: unexpected checksum %s", pkg.Encode(checksum.Value()))
- }
- } else {
- v := any(err)
- if err == nil {
- v = pathname
- }
- var checksumVal pkg.Checksum
- if checksum != (unique.Handle[pkg.Checksum]{}) {
- checksumVal = checksum.Value()
- }
- t.Log(pkg.Encode(checksumVal)+":", v)
- }
- }
-}
-
-// newWantScrubError returns the address to a new [ScrubError] for base.
-func newWantScrubError(base *check.Absolute) *pkg.ScrubError {
- return &pkg.ScrubError{
- ChecksumMismatches: []pkg.ChecksumMismatchError{
- {Got: pkg.MustDecode(
- "vsAhtPNo4waRNOASwrQwcIPTqb3SBuJOXw2G4T1mNmVZM-wrQTRllmgXqcIIoRcX",
- ), Want: pkg.Checksum{0xff, 0}},
- },
- DanglingIdentifiers: []pkg.ID{
- {0xfe, 0},
- {0xfe, 0xfe},
- {0xfe, 0xff},
- },
- Errs: map[unique.Handle[string]][]error{
- base.Append("checksum", "__8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA").Handle(): {
- pkg.InvalidFileModeError(fs.ModeSymlink),
- },
-
- base.Append("checksum", "invalid").Handle(): {
- base64.CorruptInputError(4),
- },
-
- base.Append("nonexistent").Handle(): {
- base64.CorruptInputError(8),
- },
-
- base.Append("identifier", pkg.Encode(pkg.ID{0xfe, 0xff})).Handle(): {
- &os.PathError{
- Op: "readlink",
- Path: base.Append(
- "identifier",
- pkg.Encode(pkg.ID{0xfe, 0xff}),
- ).String(),
- Err: syscall.EINVAL,
- },
- },
- base.Append("identifier", "invalid").Handle(): {
- base64.CorruptInputError(4),
- },
- },
- }
-}
-
-func TestCache(t *testing.T) {
- t.Parallel()
-
- testdata := expectsFile("" +
- "\x00\x00\x00\x00" +
- "\xad\x0b\x00" +
- "\x04" +
- "\xfe\xfe\x00\x00" +
- "\xfe\xca\x00\x00")
-
- testCases := []cacheTestCase{
- {"file", pkg.CValidateKnown | pkg.CAssumeChecksum, nil, func(t *testing.T, base *check.Absolute, c *pkg.Cache) {
- identifier := (pkg.ID)(bytes.Repeat([]byte{
- 0x75, 0xe6, 0x9d, 0x6d, 0xe7, 0x9f,
- }, 8))
- wantPathname := base.Append(
- "identifier",
- "deadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef",
- )
- identifier0 := (pkg.ID)(bytes.Repeat([]byte{
- 0x71, 0xa7, 0xde, 0x6d, 0xa6, 0xde,
- }, 8))
- wantPathname0 := base.Append(
- "identifier",
- "cafebabecafebabecafebabecafebabecafebabecafebabecafebabecafebabe",
- )
- failingFile := newStubFile(
- pkg.KindHTTPGet,
- pkg.ID{0xff, 3},
- nil,
- nil, struct {
- _ []byte
- stub.UniqueError
- }{UniqueError: 0xbad},
- )
-
- cureMany(t, c, []cureStep{
- {"initial file", newStubFile(
- pkg.KindHTTPGet,
- identifier,
- new(testdata.hash()),
- testdata, nil,
- ), wantPathname, testdata, pkg.WNew, nil},
-
- {"identical content", newStubFile(
- pkg.KindHTTPGet,
- identifier0,
- new(testdata.hash()),
- testdata, nil,
- ), wantPathname0, testdata, pkg.WCache, nil},
-
- {"existing entry", newStubFile(
- pkg.KindHTTPGet,
- identifier,
- new(testdata.hash()),
- testdata, nil,
- ), wantPathname, testdata, pkg.WCache, nil},
-
- {"checksum mismatch", newStubFile(
- pkg.KindHTTPGet,
- pkg.ID{0xff, 0},
- new(pkg.Checksum),
- testdata, nil,
- ), nil, nil, pkg.WNew, &pkg.ChecksumMismatchError{
- Got: testdata.hash(),
- }},
-
- {"store without validation", newStubFile(
- pkg.KindHTTPGet,
- pkg.MustDecode("vsAhtPNo4waRNOASwrQwcIPTqb3SBuJOXw2G4T1mNmVZM-wrQTRllmgXqcIIoRcX"),
- nil,
- []byte{0}, nil,
- ), base.Append(
- "identifier",
- "vsAhtPNo4waRNOASwrQwcIPTqb3SBuJOXw2G4T1mNmVZM-wrQTRllmgXqcIIoRcX",
- ), expectsChecksum{
- 0xbe, 0xc0, 0x21, 0xb4, 0xf3, 0x68,
- 0xe3, 0x06, 0x91, 0x34, 0xe0, 0x12,
- 0xc2, 0xb4, 0x30, 0x70, 0x83, 0xd3,
- 0xa9, 0xbd, 0xd2, 0x06, 0xe2, 0x4e,
- 0x5f, 0x0d, 0x86, 0xe1, 0x3d, 0x66,
- 0x36, 0x65, 0x59, 0x33, 0xec, 0x2b,
- 0x41, 0x34, 0x65, 0x96, 0x68, 0x17,
- 0xa9, 0xc2, 0x08, 0xa1, 0x17, 0x17,
- }, pkg.WNew, nil},
-
- {"incomplete implementation", struct{ pkg.Artifact }{&stubArtifact{
- kind: pkg.KindExec,
- params: []byte("artifact overridden to be incomplete"),
- }}, nil, nil, pkg.WNew, pkg.InvalidArtifactError(pkg.MustDecode(
- "poVrv3zNINbHd-WUJihwgWQwJpbHURFHfpY7Zux-ztto_bQhhS5PdpbNMjdkXv-V",
- ))},
-
- {"error passthrough", newStubFile(
- pkg.KindHTTPGet,
- pkg.ID{0xff, 1},
- nil,
- nil, stub.UniqueError(0xcafe),
- ), nil, nil, pkg.WNew, stub.UniqueError(0xcafe)},
-
- {"error caching", newStubFile(
- pkg.KindHTTPGet,
- pkg.ID{0xff, 1},
- nil,
- nil, nil,
- ), nil, nil, pkg.WCache, stub.UniqueError(0xcafe)},
-
- {"cache hit bad type", overrideChecksum{testdata.hash(), overrideIdent{pkg.ID{0xff, 2}, &stubArtifact{
- kind: pkg.KindTar,
- }}}, nil, nil, pkg.WCache, pkg.InvalidFileModeError(
- 0400,
- )},
-
- {"noncomparable error", &stubArtifactF{
- kind: pkg.KindExec,
- params: []byte("artifact with dependency returning noncomparable error"),
- deps: []pkg.Artifact{failingFile},
-
- cure: func(f *pkg.FContext) error {
- panic("attempting to cure impossible artifact")
- },
- }, nil, nil, pkg.WNew, pkg.InputError{
- failingFile: struct {
- _ []byte
- stub.UniqueError
- }{UniqueError: 0xbad},
- }},
- })
-
- if c0, err := pkg.Open(
- t.Context(),
- message.New(nil),
- base, &skipLock,
- ); err != nil {
- t.Fatalf("open: error = %v", err)
- } else {
- t.Cleanup(c.Close) // check doubled cancel
- cureMany(t, c0, []cureStep{
- {"cache hit ident", overrideIdent{
- id: identifier,
- }, wantPathname, testdata, pkg.WCache, nil},
-
- {"cache miss checksum match", newStubFile(
- pkg.KindHTTPGet,
- testdata.hash(),
- nil,
- testdata,
- nil,
- ), base.Append(
- "identifier",
- pkg.Encode(testdata.hash()),
- ), testdata, pkg.WNew, nil},
- })
-
- // cure after close
- c.Close()
- if _, _, err = c.Cure(&stubArtifactF{
- kind: pkg.KindExec,
- params: []byte("unreachable artifact cured after cancel"),
- deps: []pkg.Artifact{pkg.NewFile("", []byte("unreachable dependency"))},
- }); !reflect.DeepEqual(err, context.Canceled) {
- t.Fatalf("(closed) Cure: error = %v", err)
- }
- }
- }, expectsFS{
- ".": {Mode: fs.ModeDir | 0700},
-
- "checksum": {Mode: fs.ModeDir | 0700},
- "checksum/vsAhtPNo4waRNOASwrQwcIPTqb3SBuJOXw2G4T1mNmVZM-wrQTRllmgXqcIIoRcX": {Mode: 0400, Data: []byte{0}},
- "checksum/0bSFPu5Tnd-2Jj0Mv6co23PW2t3BmHc7eLFj9TgY3eIBg8zislo7xZYNBqovVLcq": {Mode: 0400, Data: []byte{0, 0, 0, 0, 0xad, 0xb, 0, 4, 0xfe, 0xfe, 0, 0, 0xfe, 0xca, 0, 0}},
-
- "identifier": {Mode: fs.ModeDir | 0700},
- "identifier/vsAhtPNo4waRNOASwrQwcIPTqb3SBuJOXw2G4T1mNmVZM-wrQTRllmgXqcIIoRcX": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/vsAhtPNo4waRNOASwrQwcIPTqb3SBuJOXw2G4T1mNmVZM-wrQTRllmgXqcIIoRcX")},
- "identifier/0bSFPu5Tnd-2Jj0Mv6co23PW2t3BmHc7eLFj9TgY3eIBg8zislo7xZYNBqovVLcq": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/0bSFPu5Tnd-2Jj0Mv6co23PW2t3BmHc7eLFj9TgY3eIBg8zislo7xZYNBqovVLcq")},
- "identifier/cafebabecafebabecafebabecafebabecafebabecafebabecafebabecafebabe": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/0bSFPu5Tnd-2Jj0Mv6co23PW2t3BmHc7eLFj9TgY3eIBg8zislo7xZYNBqovVLcq")},
- "identifier/deadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/0bSFPu5Tnd-2Jj0Mv6co23PW2t3BmHc7eLFj9TgY3eIBg8zislo7xZYNBqovVLcq")},
-
- "substitute": {Mode: fs.ModeDir | 0700},
-
- "work": {Mode: fs.ModeDir | 0700},
- }},
-
- {"directory", pkg.CAssumeChecksum, nil, func(t *testing.T, base *check.Absolute, c *pkg.Cache) {
- id := pkg.MustDecode(
- "HnySzeLQvSBZuTUcvfmLEX_OmH4yJWWH788NxuLuv7kVn8_uPM6Ks4rqFWM2NZJY",
- )
- makeSample := func(t *pkg.TContext) error {
- work := t.GetWorkDir()
- if err := os.Mkdir(work.String(), 0700); err != nil {
- return err
- }
-
- if err := os.WriteFile(
- work.Append("check").String(),
- []byte{0, 0},
- 0400,
- ); err != nil {
- return err
- }
-
- if err := os.MkdirAll(work.Append(
- "lib",
- "pkgconfig",
- ).String(), 0700); err != nil {
- return err
- }
-
- return os.Symlink(
- "/proc/nonexistent/libedac.so",
- work.Append(
- "lib",
- "libedac.so",
- ).String(),
- )
- }
- want := expectsFS{
- ".": {Mode: fs.ModeDir | 0500},
-
- "check": {Mode: 0400, Data: []byte{0, 0}},
-
- "lib": {Mode: fs.ModeDir | 0700},
- "lib/libedac.so": {Mode: fs.ModeSymlink | 0777, Data: []byte("/proc/nonexistent/libedac.so")},
-
- "lib/pkgconfig": {Mode: fs.ModeDir | 0700},
- }
- wantPathname := base.Append(
- "identifier",
- pkg.Encode(id),
- )
-
- id0 := pkg.MustDecode(
- "Zx5ZG9BAwegNT3zQwCySuI2ktCXxNgxirkGLFjW4FW06PtojYVaCdtEw8yuntPLa",
- )
- wantPathname0 := base.Append(
- "identifier",
- pkg.Encode(id0),
- )
-
- makeGarbage := func(work *check.Absolute, wantErr error) error {
- if err := os.Mkdir(work.String(), 0700); err != nil {
- return err
- }
-
- mode := fs.FileMode(0)
- if wantErr == nil {
- mode = 0500
- }
-
- if err := os.MkdirAll(work.Append(
- "lib",
- "pkgconfig",
- ).String(), 0700); err != nil {
- return err
- }
-
- if err := os.WriteFile(work.Append(
- "lib",
- "check",
- ).String(), nil, 0400&mode); err != nil {
- return err
- }
-
- if err := os.Chmod(work.Append(
- "lib",
- "pkgconfig",
- ).String(), 0500&mode); err != nil {
- return err
- }
- if err := os.Chmod(work.Append(
- "lib",
- ).String(), 0500&mode); err != nil {
- return err
- }
-
- return wantErr
- }
-
- cureMany(t, c, []cureStep{
- {"initial directory", overrideChecksum{want.hash(), overrideIdent{id, &stubArtifact{
- kind: pkg.KindTar,
- cure: makeSample,
- }}}, wantPathname, want, pkg.WNew, nil},
-
- {"identical identifier", overrideChecksum{want.hash(), overrideIdent{id, &stubArtifact{
- kind: pkg.KindTar,
- }}}, wantPathname, want, pkg.WCache, nil},
-
- {"identical checksum", overrideIdent{id0, &stubArtifact{
- kind: pkg.KindTar,
- cure: makeSample,
- }}, wantPathname0, want, pkg.WNew, nil},
-
- {"cure fault", overrideIdent{pkg.ID{0xff, 0}, &stubArtifact{
- kind: pkg.KindTar,
- cure: func(t *pkg.TContext) error {
- return makeGarbage(t.GetWorkDir(), stub.UniqueError(0xcafe))
- },
- }}, nil, nil, pkg.WNew, stub.UniqueError(0xcafe)},
-
- {"checksum mismatch", overrideChecksum{pkg.Checksum{}, overrideIdent{pkg.ID{0xff, 1}, &stubArtifact{
- kind: pkg.KindTar,
- cure: func(t *pkg.TContext) error {
- return makeGarbage(t.GetWorkDir(), nil)
- },
- }}}, nil, nil, pkg.WNew, &pkg.ChecksumMismatchError{
- Got: pkg.MustDecode(
- "CUx-3hSbTWPsbMfDhgalG4Ni_GmR9TnVX8F99tY_P5GtkYvczg9RrF5zO0jX9XYT",
- ),
- }},
-
- {"cache hit bad type", newStubFile(
- pkg.KindHTTPGet,
- pkg.ID{0xff, 2},
- new(want.hash()),
- testdata, nil,
- ), nil, nil, pkg.WCache, pkg.InvalidFileModeError(
- fs.ModeDir | 0500,
- )},
-
- {"openFile directory", overrideIdent{pkg.ID{0xff, 3}, &stubArtifact{
- kind: pkg.KindTar,
- cure: func(t *pkg.TContext) error {
- r, err := t.Open(overrideChecksumFile{checksum: want.hash()})
- if err != nil {
- panic(err)
- }
- _, err = io.ReadAll(r)
- return err
- },
- }}, nil, nil, pkg.WNew, &os.PathError{
- Op: "read",
- Path: base.Append(
- "checksum",
- pkg.Encode(want.hash()),
- ).String(),
- Err: syscall.EISDIR,
- }},
-
- {"no output", overrideIdent{pkg.ID{0xff, 4}, &stubArtifact{
- kind: pkg.KindTar,
- cure: func(t *pkg.TContext) error {
- return nil
- },
- }}, nil, nil, pkg.WNew, pkg.NoOutputError{}},
-
- {"file output", overrideIdent{pkg.ID{0xff, 5}, &stubArtifact{
- kind: pkg.KindTar,
- cure: func(t *pkg.TContext) error {
- return os.WriteFile(t.GetWorkDir().String(), []byte{0}, 0400)
- },
- }}, nil, nil, pkg.WNew, errors.New("non-file artifact produced regular file")},
-
- {"symlink output", overrideIdent{pkg.ID{0xff, 6}, &stubArtifact{
- kind: pkg.KindTar,
- cure: func(t *pkg.TContext) error {
- return os.Symlink(
- t.GetWorkDir().String(),
- t.GetWorkDir().String(),
- )
- },
- }}, nil, nil, pkg.WNew, pkg.InvalidFileModeError(
- fs.ModeSymlink | 0777,
- )},
-
- {"alternative", &stubArtifactF{
- kind: pkg.KindExec,
- params: []byte("substitutable artifact"),
- deps: []pkg.Artifact{newStubFile(
- pkg.KindHTTPGet,
- pkg.ID{0xff, 8},
- nil,
- []byte("substitutable dependency"),
- nil,
- )},
-
- cure: func(f *pkg.FContext) error {
- return makeSample(&f.TContext)
- },
- }, base.Append(
- "identifier",
- "gIH5eti07nBAhVti3ZTn8EIGOBCZWWvNpxg5CmCZlDzIC4mBdomPmQLeEpf1IQg9",
- ), want, pkg.WNew, nil},
-
- {"substitutable", &stubArtifactF{
- kind: pkg.KindExec,
- params: []byte("substitutable artifact"),
- deps: []pkg.Artifact{newStubFile(
- pkg.KindHTTPGet,
- pkg.ID{0xff, 10},
- nil,
- []byte("substitutable dependency"),
- nil,
- )},
-
- cure: func(f *pkg.FContext) error {
- panic("substitution missed")
- },
- }, base.Append(
- "identifier",
- "VGjpp7NVw3OYLpgOQumfM0KcJgY3suz6torykUczcg4bGT24ySkPn5hy-4dNqqkR",
- ), want, pkg.WSubstitute, nil},
- })
-
- if c0, err := pkg.Open(
- t.Context(),
- message.New(nil),
- base, &skipLock,
- ); err != nil {
- t.Fatalf("open: error = %v", err)
- } else {
- t.Cleanup(c.Close)
- cureMany(t, c0, []cureStep{
- {"substitutable", &stubArtifactF{
- kind: pkg.KindExec,
- params: []byte("substitutable artifact"),
- deps: []pkg.Artifact{newStubFile(
- pkg.KindHTTPGet,
- pkg.ID{0xff, 0xff, 0xfd, 0xfd},
- nil,
- []byte("substitutable dependency"),
- nil,
- )},
-
- cure: func(f *pkg.FContext) error {
- panic("substitution missed")
- },
- }, base.Append(
- "identifier",
- "zeZ4JEZ0atAKl6Am67cBID6-KR18nZGgeYfU4qTuYaWhQC4eAn0dyTXdIBH9Bos8",
- ), want, pkg.WSubstitute, nil},
- })
- }
-
- if dents, err := os.ReadDir(base.Append("status").String()); err != nil {
- t.Fatal(err)
- } else if len(dents) > 0 {
- t.Errorf("ReadDir: %v", dents)
- }
-
- }, expectsFS{
- ".": {Mode: fs.ModeDir | 0700},
-
- "checksum": {Mode: fs.ModeDir | 0700},
- "checksum/7lfQ4QwSpV8nw7IDh0JiQ_jqUPrPv3_Vfie034RxsSy-cy4vO8DVvxgpx2LW08oO": {Mode: 0400, Data: []byte("substitutable dependency")},
- "checksum/qRN6in76LndiiOZJheHkwyW8UT1N5-f-bXvHfDvwrMw2fSkOoZdh8pWE1qhLk65b": {Mode: fs.ModeDir | 0500},
- "checksum/qRN6in76LndiiOZJheHkwyW8UT1N5-f-bXvHfDvwrMw2fSkOoZdh8pWE1qhLk65b/check": {Mode: 0400, Data: []byte{0, 0}},
- "checksum/qRN6in76LndiiOZJheHkwyW8UT1N5-f-bXvHfDvwrMw2fSkOoZdh8pWE1qhLk65b/lib": {Mode: fs.ModeDir | 0700},
- "checksum/qRN6in76LndiiOZJheHkwyW8UT1N5-f-bXvHfDvwrMw2fSkOoZdh8pWE1qhLk65b/lib/pkgconfig": {Mode: fs.ModeDir | 0700},
- "checksum/qRN6in76LndiiOZJheHkwyW8UT1N5-f-bXvHfDvwrMw2fSkOoZdh8pWE1qhLk65b/lib/libedac.so": {Mode: fs.ModeSymlink | 0777, Data: []byte("/proc/nonexistent/libedac.so")},
-
- "identifier": {Mode: fs.ModeDir | 0700},
- "identifier/HnySzeLQvSBZuTUcvfmLEX_OmH4yJWWH788NxuLuv7kVn8_uPM6Ks4rqFWM2NZJY": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/qRN6in76LndiiOZJheHkwyW8UT1N5-f-bXvHfDvwrMw2fSkOoZdh8pWE1qhLk65b")},
- "identifier/Zx5ZG9BAwegNT3zQwCySuI2ktCXxNgxirkGLFjW4FW06PtojYVaCdtEw8yuntPLa": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/qRN6in76LndiiOZJheHkwyW8UT1N5-f-bXvHfDvwrMw2fSkOoZdh8pWE1qhLk65b")},
- "identifier/zeZ4JEZ0atAKl6Am67cBID6-KR18nZGgeYfU4qTuYaWhQC4eAn0dyTXdIBH9Bos8": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/qRN6in76LndiiOZJheHkwyW8UT1N5-f-bXvHfDvwrMw2fSkOoZdh8pWE1qhLk65b")},
- "identifier/___9_QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/7lfQ4QwSpV8nw7IDh0JiQ_jqUPrPv3_Vfie034RxsSy-cy4vO8DVvxgpx2LW08oO")},
- "identifier/_wgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/7lfQ4QwSpV8nw7IDh0JiQ_jqUPrPv3_Vfie034RxsSy-cy4vO8DVvxgpx2LW08oO")},
- "identifier/_woAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/7lfQ4QwSpV8nw7IDh0JiQ_jqUPrPv3_Vfie034RxsSy-cy4vO8DVvxgpx2LW08oO")},
- "identifier/VGjpp7NVw3OYLpgOQumfM0KcJgY3suz6torykUczcg4bGT24ySkPn5hy-4dNqqkR": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/qRN6in76LndiiOZJheHkwyW8UT1N5-f-bXvHfDvwrMw2fSkOoZdh8pWE1qhLk65b")},
- "identifier/gIH5eti07nBAhVti3ZTn8EIGOBCZWWvNpxg5CmCZlDzIC4mBdomPmQLeEpf1IQg9": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/qRN6in76LndiiOZJheHkwyW8UT1N5-f-bXvHfDvwrMw2fSkOoZdh8pWE1qhLk65b")},
-
- "substitute": {Mode: fs.ModeDir | 0700},
- "substitute/nWPg893oqn_YNN8kgfZrs_LVLwP90e0mKxqU8UwoazQh-yBPwhoviD7of6YALx-M": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/qRN6in76LndiiOZJheHkwyW8UT1N5-f-bXvHfDvwrMw2fSkOoZdh8pWE1qhLk65b")},
-
- "work": {Mode: fs.ModeDir | 0700},
- }},
-
- {"pending", pkg.CValidateKnown, nil, func(t *testing.T, base *check.Absolute, c *pkg.Cache) {
- wantErr := stub.UniqueError(0xcafe)
- n, ready := make(chan struct{}), make(chan struct{})
- go func() {
- if _, _, err := c.Cure(overrideIdent{pkg.ID{0xff}, &stubArtifact{
- kind: pkg.KindTar,
- cure: func(t *pkg.TContext) error {
- close(ready)
- <-n
- return wantErr
- },
- }}); !reflect.DeepEqual(err, wantErr) {
- panic(fmt.Sprintf("Cure: error = %v, want %v", err, wantErr))
- }
- }()
-
- <-ready
- wCureDone := make(chan struct{})
- go func() {
- if _, _, err := c.Cure(overrideIdent{pkg.ID{0xff}, &stubArtifact{
- kind: pkg.KindTar,
- }}); !reflect.DeepEqual(err, wantErr) {
- panic(fmt.Sprintf("Cure: error = %v, want %v", err, wantErr))
- }
- close(wCureDone)
- }()
-
- // check cache activity while a cure is blocking
- cureMany(t, c, []cureStep{
- {"error passthrough", newStubFile(
- pkg.KindHTTPGet,
- pkg.ID{0xff, 1},
- nil,
- nil, stub.UniqueError(0xbad),
- ), nil, nil, pkg.WNew, stub.UniqueError(0xbad)},
-
- {"file output", overrideIdent{pkg.ID{0xff, 2}, &stubArtifact{
- kind: pkg.KindTar,
- cure: func(t *pkg.TContext) error {
- return os.WriteFile(
- t.GetWorkDir().String(),
- []byte{0},
- 0400,
- )
- },
- }}, nil, nil, pkg.WNew, errors.New(
- "non-file artifact produced regular file",
- )},
- })
-
- wantErrScrub := &pkg.ScrubError{
- Errs: map[unique.Handle[string]][]error{
- base.Handle(): {errors.New("scrub began with pending artifacts")},
- },
- }
- if err := c.Scrub(1 << 6); !reflect.DeepEqual(err, wantErrScrub) {
- t.Fatalf("Scrub: error = %#v, want %#v", err, wantErrScrub)
- }
-
- notify := c.Done(unique.Make(pkg.ID{0xff}))
- go close(n)
- if notify != nil {
- <-notify
- }
- for c.Done(unique.Make(pkg.ID{0xff})) != nil {
- }
- <-wCureDone
- }, expectsFS{
- ".": {Mode: fs.ModeDir | 0700},
- "checksum": {Mode: fs.ModeDir | 0700},
- "identifier": {Mode: fs.ModeDir | 0700},
- "substitute": {Mode: fs.ModeDir | 0700},
- "work": {Mode: fs.ModeDir | 0700},
- }},
-
- {"cancel abort block", pkg.CValidateKnown, nil, func(t *testing.T, base *check.Absolute, c *pkg.Cache) {
- var wg sync.WaitGroup
- defer wg.Wait()
-
- var started sync.WaitGroup
- defer started.Wait()
-
- blockCures := func(d byte, e stub.UniqueError, n int) {
- started.Add(n)
- for i := range n {
- wg.Go(func() {
- if _, _, err := c.Cure(overrideIdent{pkg.ID{d, byte(i)}, &stubArtifact{
- kind: pkg.KindTar,
- cure: func(t *pkg.TContext) error {
- started.Done()
- <-t.Unwrap().Done()
- return e + stub.UniqueError(i)
- },
- }}); !reflect.DeepEqual(err, e+stub.UniqueError(i)) {
- panic(err)
- }
- })
- }
- started.Wait()
- }
-
- blockCures(0xfd, 0xbad, 16)
- c.Abort()
- wg.Wait()
-
- blockCures(0xfd, 0xcafe, 16)
- c.Abort()
- wg.Wait()
-
- blockCures(0xff, 0xbad, 1)
- if !c.Cancel(unique.Make(pkg.ID{0xff})) {
- t.Fatal("missed cancellation")
- }
- wg.Wait()
-
- blockCures(0xff, 0xcafe, 1)
- if !c.Cancel(unique.Make(pkg.ID{0xff})) {
- t.Fatal("missed cancellation")
- }
- wg.Wait()
-
- for c.Cancel(unique.Make(pkg.ID{0xff})) {
- }
-
- c.Close()
- c.Abort()
- }, expectsFS{
- ".": {Mode: fs.ModeDir | 0700},
- "checksum": {Mode: fs.ModeDir | 0700},
- "identifier": {Mode: fs.ModeDir | 0700},
- "substitute": {Mode: fs.ModeDir | 0700},
- "work": {Mode: fs.ModeDir | 0700},
- }},
-
- {"no assume checksum", 0, nil, func(t *testing.T, base *check.Absolute, c *pkg.Cache) {
- makeGarbage := func(work *check.Absolute, wantErr error) error {
- if err := os.Mkdir(work.String(), 0700); err != nil {
- return err
- }
-
- if err := os.WriteFile(work.Append(
- "check",
- ).String(), nil, 0400); err != nil {
- return err
- }
-
- return wantErr
- }
-
- want := expectsChecksum(pkg.MustDecode(
- "Aubi5EG4_Y8DhL9bQ3Q4HFBhLRF7X5gt9D3CNCQfT-TeBtlRXc7Zi_JYZEMoCC7M",
- ))
-
- cureMany(t, c, []cureStep{
- {"create", overrideChecksum{want.hash(), overrideIdent{pkg.ID{0xff, 0}, &stubArtifact{
- kind: pkg.KindTar,
- cure: func(t *pkg.TContext) error {
- return makeGarbage(t.GetWorkDir(), nil)
- },
- }}}, base.Append(
- "identifier",
- pkg.Encode(pkg.ID{0xff, 0}),
- ), want, pkg.WNew, nil},
-
- {"reject", overrideChecksum{want.hash(), overrideIdent{pkg.ID{0xfe, 1}, &stubArtifact{
- kind: pkg.KindTar,
- cure: func(t *pkg.TContext) error {
- return makeGarbage(t.GetWorkDir(), stub.UniqueError(0xbad))
- },
- }}}, nil, nil, pkg.WNew, stub.UniqueError(0xbad)},
-
- {"match", overrideChecksum{want.hash(), overrideIdent{pkg.ID{0xff, 1}, &stubArtifact{
- kind: pkg.KindTar,
- cure: func(t *pkg.TContext) error {
- return makeGarbage(t.GetWorkDir(), nil)
- },
- }}}, base.Append(
- "identifier",
- pkg.Encode(pkg.ID{0xff, 1}),
- ), want, pkg.WNew, nil},
- })
- }, expectsFS{
- ".": {Mode: fs.ModeDir | 0700},
-
- "checksum": {Mode: fs.ModeDir | 0700},
- "checksum/Aubi5EG4_Y8DhL9bQ3Q4HFBhLRF7X5gt9D3CNCQfT-TeBtlRXc7Zi_JYZEMoCC7M": {Mode: fs.ModeDir | 0500},
- "checksum/Aubi5EG4_Y8DhL9bQ3Q4HFBhLRF7X5gt9D3CNCQfT-TeBtlRXc7Zi_JYZEMoCC7M/check": {Mode: 0400, Data: []byte{}},
-
- "identifier": {Mode: fs.ModeDir | 0700},
- "identifier/_wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/Aubi5EG4_Y8DhL9bQ3Q4HFBhLRF7X5gt9D3CNCQfT-TeBtlRXc7Zi_JYZEMoCC7M")},
- "identifier/_wEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/Aubi5EG4_Y8DhL9bQ3Q4HFBhLRF7X5gt9D3CNCQfT-TeBtlRXc7Zi_JYZEMoCC7M")},
-
- "substitute": {Mode: fs.ModeDir | 0700},
-
- "work": {Mode: fs.ModeDir | 0700},
- }},
-
- {"scrub", 0, nil, func(t *testing.T, base *check.Absolute, c *pkg.Cache) {
- cureMany(t, c, []cureStep{
- {"bad measured file", newStubFile(
- pkg.KindHTTPGet,
- pkg.Checksum{0xfe, 0},
- &pkg.Checksum{0xff, 0},
- []byte{0}, nil,
- ), base.Append(
- "identifier",
- pkg.Encode(pkg.Checksum{0xfe, 0}),
- ), expectsChecksum{0xff, 0}, pkg.WNew, nil},
- })
-
- for _, p := range [][]string{
- {"identifier", "invalid"},
- {"identifier", pkg.Encode(pkg.ID{0xfe, 0xff})},
- {"checksum", "invalid"},
- } {
- if err := os.WriteFile(
- base.Append(p...).String(),
- nil,
- 0400,
- ); err != nil {
- t.Fatal(err)
- }
- }
-
- for _, p := range [][]string{
- {"../nonexistent", "checksum", pkg.Encode(pkg.Checksum{0xff, 0xff})},
- {"../nonexistent", "identifier", pkg.Encode(pkg.Checksum{0xfe, 0xfe})},
- } {
- if err := os.Symlink(
- p[0],
- base.Append(p[1:]...).String(),
- ); err != nil {
- t.Fatal(err)
- }
- }
-
- wantErr := newWantScrubError(base)
- if err := c.Scrub(1 << 6); !reflect.DeepEqual(err, wantErr) {
- t.Fatalf("Scrub: error =\n%s\nwant\n%s", err, wantErr)
- }
- }, expectsFS{
- ".": {Mode: fs.ModeDir | 0700},
- "checksum": {Mode: fs.ModeDir | 0700},
- "identifier": {Mode: fs.ModeDir | 0700},
- "substitute": {Mode: fs.ModeDir | 0700},
- "work": {Mode: fs.ModeDir | 0700},
- }},
-
- {"status substitute clean", 0, nil, func(t *testing.T, base *check.Absolute, c *pkg.Cache) {
- destroyed := &stubArtifactF{
- kind: pkg.KindExec,
- params: []byte("destroyed"),
- deps: []pkg.Artifact{
- pkg.NewFile("destroyed-input", []byte("destroyed")),
- },
- cure: func(f *pkg.FContext) error {
- if w, err := f.GetStatusWriter(); err != nil {
- return err
- } else if _, err = w.Write([]byte("destroyed")); err != nil {
- return err
- }
-
- p := f.GetWorkDir()
- if err := os.MkdirAll(p.String(), 0755); err != nil {
- return err
- }
- return os.WriteFile(p.Append("result").String(), nil, 0444)
- },
- }
- substituted := new(*destroyed)
- substituted.deps = []pkg.Artifact{
- pkg.NewFile("destroyed-input-0", []byte("destroyed")),
- }
- substituted.cure = func(*pkg.FContext) error {
- panic("substitutable cure reached")
- }
-
- cureMany(t, c, []cureStep{
- {"destroyed", destroyed, base.Append(
- "identifier",
- pkg.Encode(c.Ident(destroyed).Value()),
- ), expectsFS{
- ".": {Mode: fs.ModeDir | 0500},
- "result": {Mode: 0444},
- }, pkg.WNew, nil},
-
- {"substituted", substituted, base.Append(
- "identifier",
- pkg.Encode(c.Ident(substituted).Value()),
- ), expectsFS{
- ".": {Mode: fs.ModeDir | 0500},
- "result": {Mode: 0444},
- }, pkg.WSubstitute, nil},
- })
- }, expectsFS{
- ".": {Mode: fs.ModeDir | 0700},
-
- "checksum": {Mode: fs.ModeDir | 0700},
- "checksum/UjZSrgz7_B7XMd9fHU7jM33UZhWlFgX0rz7JZbCBYR28bCS7jr_CAJdcDhi52ruE": {Mode: fs.ModeDir | 0500},
- "checksum/UjZSrgz7_B7XMd9fHU7jM33UZhWlFgX0rz7JZbCBYR28bCS7jr_CAJdcDhi52ruE/result": {Mode: 0444},
- "checksum/wILUy2izpj2sgKJVhGUGIAde1XVuqvp5BpFMIQHanT5Q8R6jK4QPVSrJsjZh-njV": {Mode: 0400, Data: []byte("destroyed")},
-
- "identifier": {Mode: fs.ModeDir | 0700},
- "identifier/CLyyxJWn1yUGFs_0KnJ4ZSU2hH4-elvGFRB36x14LrNrKBJPxvORhL9O4Rc7oeYU": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/wILUy2izpj2sgKJVhGUGIAde1XVuqvp5BpFMIQHanT5Q8R6jK4QPVSrJsjZh-njV")},
- "identifier/arv8a6z4i0x6pUb5Z2T-3iE4ETvyZj-uReHGKsS7uiBgMgKNEOzTGG3LIZb8vp0L": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/wILUy2izpj2sgKJVhGUGIAde1XVuqvp5BpFMIQHanT5Q8R6jK4QPVSrJsjZh-njV")},
- "identifier/heRgWhNJmhm898V68kw0ta76t4rP1o29tYW_TrdyBWXGfo37K3QWA7Z-JkLXAwcn": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/UjZSrgz7_B7XMd9fHU7jM33UZhWlFgX0rz7JZbCBYR28bCS7jr_CAJdcDhi52ruE")},
- "identifier/q-VoVBI3IjcWTqwIokpi3y05CP113CHgHslc-XWnhOvDULwzVc3q9Y5xOCm_YyLZ": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/UjZSrgz7_B7XMd9fHU7jM33UZhWlFgX0rz7JZbCBYR28bCS7jr_CAJdcDhi52ruE")},
-
- "status": {Mode: fs.ModeDir | 0700},
- "status/q-VoVBI3IjcWTqwIokpi3y05CP113CHgHslc-XWnhOvDULwzVc3q9Y5xOCm_YyLZ": {Mode: fs.ModeSymlink | 0777, Data: []byte("dP-6_wIDRRouOaOF-nkBy-IaUbLdYHbOUTrptu7j_qfW01mnHSjYJ0oykUmvUd2x")},
- "status/heRgWhNJmhm898V68kw0ta76t4rP1o29tYW_TrdyBWXGfo37K3QWA7Z-JkLXAwcn": {Mode: 0400, Data: []byte(statusHeader + "destroyed")},
- "status/dP-6_wIDRRouOaOF-nkBy-IaUbLdYHbOUTrptu7j_qfW01mnHSjYJ0oykUmvUd2x": {Mode: 0400, Data: []byte(statusHeader + "destroyed")},
-
- "substitute": {Mode: fs.ModeDir | 0700},
- "substitute/dP-6_wIDRRouOaOF-nkBy-IaUbLdYHbOUTrptu7j_qfW01mnHSjYJ0oykUmvUd2x": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/UjZSrgz7_B7XMd9fHU7jM33UZhWlFgX0rz7JZbCBYR28bCS7jr_CAJdcDhi52ruE")},
-
- "work": {Mode: fs.ModeDir | 0700},
- }},
-
- {"extern", 0, nil, func(t *testing.T, base *check.Absolute, c *pkg.Cache) {
- a := &stubArtifactF{
- kind: pkg.KindExec,
- params: []byte("extern"),
- }
- wantIdent := c.Ident(a)
- wantOutput := expectsFS{
- ".": {Mode: fs.ModeDir | 0500},
- "result": {Mode: fs.ModeSymlink | 0777, Data: []byte("/proc/nonexistent")},
- }
- var wantChecksum pkg.Checksum
- if err := pkg.SumFS(
- &wantChecksum,
- fstest.MapFS(wantOutput),
- ".",
- ); err != nil {
- t.Fatal(err)
- }
- wantChecksumH := unique.Make(wantChecksum)
-
- _a := &stubArtifactF{
- kind: pkg.KindExec,
- params: []byte("extern substitute"),
- deps: []pkg.Artifact{pkg.NewFile("", nil)},
- }
- _wantIdent := c.Ident(_a)
- _wantOutput := expectsFS{
- ".": {Mode: fs.ModeDir | 0500},
- }
- var _wantChecksum pkg.Checksum
- if err := pkg.SumFS(
- &_wantChecksum,
- fstest.MapFS(_wantOutput),
- ".",
- ); err != nil {
- t.Fatal(err)
- }
- _wantChecksumH := unique.Make(_wantChecksum)
-
- kca := pkg.NewExec(
- "", "",
- new(pkg.Checksum), 0, false, false,
- fhs.AbsRoot, nil, fhs.AbsRoot, nil,
- )
- kcIdent := c.Ident(kca)
-
- c.SetExternal(stubExtern{
- artifact: map[unique.Handle[pkg.ID]]pkg.Checksum{
- wantIdent: wantChecksum,
- _wantIdent: _wantChecksum,
- kcIdent: wantChecksum,
- },
- checksum: map[unique.Handle[pkg.Checksum]]fstest.MapFS{
- wantChecksumH: fstest.MapFS(wantOutput),
- _wantChecksumH: fstest.MapFS(_wantOutput),
- },
- status: map[unique.Handle[pkg.ID]]string{
- wantIdent: "\x00",
- kcIdent: "unreachable",
- },
- })
-
- cureMany(t, c, []cureStep{
- {"extern", a, base.Append(
- "identifier",
- pkg.Encode(wantIdent.Value()),
- ), wantOutput, pkg.WExternal, nil},
-
- {"substitute", _a, base.Append(
- "identifier",
- pkg.Encode(_wantIdent.Value()),
- ), _wantOutput, pkg.WExternal, nil},
-
- {"mismatch", kca, nil, nil, pkg.WExternal, &pkg.ChecksumMismatchError{
- Got: wantChecksum,
- }},
- })
- }, expectsFS{
- ".": {Mode: fs.ModeDir | 0700},
-
- "checksum": {Mode: fs.ModeDir | 0700},
- "checksum/MGWmEfjut2QE2xPJwTsmUzpff4BN_FEnQ7T0j7gvUCCiugJQNwqt9m151fm9D1yU": {Mode: fs.ModeDir | 0500},
- "checksum/OLBgp1GsljhM2TJ-sbHjaiH9txEUvgdDTAzHv2P24donTt6_529l-9Ua0vFImLlb": {Mode: 0400},
- "checksum/fHkl_RuHOoc4rso__nV-qreikovd6Yhrq5mpBlkf5hmPGaxDlik2bYOQ4dhUQjtl": {Mode: fs.ModeDir | 0500},
- "checksum/fHkl_RuHOoc4rso__nV-qreikovd6Yhrq5mpBlkf5hmPGaxDlik2bYOQ4dhUQjtl/result": {Mode: fs.ModeSymlink | 0777, Data: []byte("/proc/nonexistent")},
-
- "identifier": {Mode: fs.ModeDir | 0700},
- "identifier/k8yyhlBV3JpYzzywAnrRWkfp2TmgIDNC6FqMFwrrR2x0C3unBLveDNKgigOjG9MM": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/MGWmEfjut2QE2xPJwTsmUzpff4BN_FEnQ7T0j7gvUCCiugJQNwqt9m151fm9D1yU")},
- "identifier/Xys8hPpJsKirZmTTuT7SwQ6661TCp_ZRu8iUjPPD7pC5E3ll7xw4zhNlZ2PVcz_-": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/fHkl_RuHOoc4rso__nV-qreikovd6Yhrq5mpBlkf5hmPGaxDlik2bYOQ4dhUQjtl")},
- "identifier/8sInO_dhPW9kweit7jVuH_vtMkRxlZT7XE4_yEKPZmpGkgVxkmxz0OpXgbMsH6ET": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/MGWmEfjut2QE2xPJwTsmUzpff4BN_FEnQ7T0j7gvUCCiugJQNwqt9m151fm9D1yU")},
- "identifier/ofaXbB5gIza_7W4Rzo5XDe_8FwlCPKWn3TBcmGgFAkkTWMl5GXGmOzX89Jd2Mk2A": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/OLBgp1GsljhM2TJ-sbHjaiH9txEUvgdDTAzHv2P24donTt6_529l-9Ua0vFImLlb")},
- "identifier/8VL-egZySw-RbnHZtxGWdf5Z2v9S9CihrdFwa54Bc5EYMQcEgWEem7QrdCTWlCb8": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/fHkl_RuHOoc4rso__nV-qreikovd6Yhrq5mpBlkf5hmPGaxDlik2bYOQ4dhUQjtl")},
-
- "status": {Mode: fs.ModeDir | 0700},
- "status/8VL-egZySw-RbnHZtxGWdf5Z2v9S9CihrdFwa54Bc5EYMQcEgWEem7QrdCTWlCb8": {Mode: 0400, Data: []byte("\x00")},
-
- "substitute": {Mode: fs.ModeDir | 0700},
- "substitute/socGRnhdsJlJ4Z01ZwHFZdLzFH0rWvoaJrylcUKtvhBdGsE7VoYl-vdUuvfK8B4I": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/MGWmEfjut2QE2xPJwTsmUzpff4BN_FEnQ7T0j7gvUCCiugJQNwqt9m151fm9D1yU")},
-
- "work": {Mode: fs.ModeDir | 0700},
- }},
-
- {"extern shallow", pkg.CExternShallow, nil, func(t *testing.T, base *check.Absolute, c *pkg.Cache) {
- a := &stubArtifactF{
- kind: pkg.KindExec,
- params: []byte("extern"),
- }
- wantIdent := c.Ident(a)
- wantOutput := expectsFS{
- ".": {Mode: fs.ModeDir | 0500},
- "result": {Mode: fs.ModeSymlink | 0777, Data: []byte("/proc/nonexistent")},
- }
- var wantChecksum pkg.Checksum
- if err := pkg.SumFS(
- &wantChecksum,
- fstest.MapFS(wantOutput),
- ".",
- ); err != nil {
- t.Fatal(err)
- }
- wantChecksumH := unique.Make(wantChecksum)
-
- _a := &stubArtifactF{
- kind: pkg.KindExec,
- params: []byte("extern substitute"),
- deps: []pkg.Artifact{pkg.NewFile("", nil)},
- }
- _wantIdent := c.Ident(_a)
- _wantOutput := expectsFS{
- ".": {Mode: fs.ModeDir | 0500},
- }
- var _wantChecksum pkg.Checksum
- if err := pkg.SumFS(
- &_wantChecksum,
- fstest.MapFS(_wantOutput),
- ".",
- ); err != nil {
- t.Fatal(err)
- }
- _wantChecksumH := unique.Make(_wantChecksum)
-
- kca := pkg.NewExec(
- "", "",
- new(pkg.Checksum), 0, false, false,
- fhs.AbsRoot, nil, fhs.AbsRoot, nil,
- )
- kcIdent := c.Ident(kca)
-
- fia := &stubArtifactF{
- kind: pkg.KindExec,
- params: []byte("flood input"),
- deps: []pkg.Artifact{_a},
- }
- fiaIdent := c.Ident(fia)
-
- flia := &stubArtifactF{
- kind: pkg.KindExec,
- params: []byte("flood input local"),
- deps: []pkg.Artifact{_a},
- }
- fliaIdent := c.Ident(flia)
-
- h := &stubArtifactF{
- kind: pkg.KindExec,
- params: []byte("hanging input"),
- }
-
- fhia := &stubArtifactF{
- kind: pkg.KindExec,
- params: []byte("flood input local"),
- deps: []pkg.Artifact{h},
- }
- fhiaIdent := c.Ident(fhia)
-
- c.SetExternal(stubExtern{
- artifact: map[unique.Handle[pkg.ID]]pkg.Checksum{
- wantIdent: wantChecksum,
- _wantIdent: _wantChecksum,
- kcIdent: wantChecksum,
- fiaIdent: wantChecksum,
- fliaIdent: wantChecksum,
- fhiaIdent: wantChecksum,
- },
- checksum: map[unique.Handle[pkg.Checksum]]fstest.MapFS{
- wantChecksumH: fstest.MapFS(wantOutput),
- _wantChecksumH: fstest.MapFS(_wantOutput),
- },
- status: map[unique.Handle[pkg.ID]]string{
- wantIdent: "\x00",
- kcIdent: "unreachable",
- },
- })
-
- cureMany(t, c, []cureStep{
- {"extern", a, base.Append(
- "identifier",
- pkg.Encode(wantIdent.Value()),
- ), wantOutput, pkg.WExternal, nil},
-
- {"flood shallow extern", fia, base.Append(
- "identifier",
- pkg.Encode(fiaIdent.Value()),
- ), wantOutput, pkg.WExternal, nil},
-
- {"substitute", _a, base.Append(
- "identifier",
- pkg.Encode(_wantIdent.Value()),
- ), _wantOutput, pkg.WExternal, nil},
-
- {"flood shallow local", flia, base.Append(
- "identifier",
- pkg.Encode(fliaIdent.Value()),
- ), wantOutput, pkg.WExternal, nil},
-
- {"flood shallow hanging", fhia, nil, nil,
- pkg.WNew, pkg.HangingInputError(c.Ident(h))},
-
- {"mismatch", kca, nil, nil, pkg.WExternal, &pkg.ChecksumMismatchError{
- Got: wantChecksum,
- }},
- })
- }, expectsFS{
- ".": {Mode: fs.ModeDir | 0700},
-
- "checksum": {Mode: fs.ModeDir | 0700},
- "checksum/MGWmEfjut2QE2xPJwTsmUzpff4BN_FEnQ7T0j7gvUCCiugJQNwqt9m151fm9D1yU": {Mode: fs.ModeDir | 0500},
- "checksum/fHkl_RuHOoc4rso__nV-qreikovd6Yhrq5mpBlkf5hmPGaxDlik2bYOQ4dhUQjtl": {Mode: fs.ModeDir | 0500},
- "checksum/fHkl_RuHOoc4rso__nV-qreikovd6Yhrq5mpBlkf5hmPGaxDlik2bYOQ4dhUQjtl/result": {Mode: fs.ModeSymlink | 0777, Data: []byte("/proc/nonexistent")},
-
- "identifier": {Mode: fs.ModeDir | 0700},
- "identifier/3fYJjSiWhklt7TK9MPVLGk5_8AIU8ostTcFPXULJf_qeAVG6pmC-Cqqu4ZhEXRxn": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/fHkl_RuHOoc4rso__nV-qreikovd6Yhrq5mpBlkf5hmPGaxDlik2bYOQ4dhUQjtl")},
- "identifier/8VL-egZySw-RbnHZtxGWdf5Z2v9S9CihrdFwa54Bc5EYMQcEgWEem7QrdCTWlCb8": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/fHkl_RuHOoc4rso__nV-qreikovd6Yhrq5mpBlkf5hmPGaxDlik2bYOQ4dhUQjtl")},
- "identifier/8sInO_dhPW9kweit7jVuH_vtMkRxlZT7XE4_yEKPZmpGkgVxkmxz0OpXgbMsH6ET": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/MGWmEfjut2QE2xPJwTsmUzpff4BN_FEnQ7T0j7gvUCCiugJQNwqt9m151fm9D1yU")},
- "identifier/Xys8hPpJsKirZmTTuT7SwQ6661TCp_ZRu8iUjPPD7pC5E3ll7xw4zhNlZ2PVcz_-": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/fHkl_RuHOoc4rso__nV-qreikovd6Yhrq5mpBlkf5hmPGaxDlik2bYOQ4dhUQjtl")},
- "identifier/k8yyhlBV3JpYzzywAnrRWkfp2TmgIDNC6FqMFwrrR2x0C3unBLveDNKgigOjG9MM": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/MGWmEfjut2QE2xPJwTsmUzpff4BN_FEnQ7T0j7gvUCCiugJQNwqt9m151fm9D1yU")},
- "identifier/mXlNz_v77nW7jstn_rJn4RL7dCQlkakM0y-HjO6tkDubtzaj-wCmW1hIr2Gk64_O": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/fHkl_RuHOoc4rso__nV-qreikovd6Yhrq5mpBlkf5hmPGaxDlik2bYOQ4dhUQjtl")},
-
- "status": {Mode: fs.ModeDir | 0700},
- "status/8VL-egZySw-RbnHZtxGWdf5Z2v9S9CihrdFwa54Bc5EYMQcEgWEem7QrdCTWlCb8": {Mode: 0400, Data: []byte("\x00")},
-
- "substitute": {Mode: fs.ModeDir | 0700},
- "substitute/socGRnhdsJlJ4Z01ZwHFZdLzFH0rWvoaJrylcUKtvhBdGsE7VoYl-vdUuvfK8B4I": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/MGWmEfjut2QE2xPJwTsmUzpff4BN_FEnQ7T0j7gvUCCiugJQNwqt9m151fm9D1yU")},
- "substitute/MccYezQ4pshkeBV4w_aAEIwvZdKHL3OAgAkR3ouZ43EF94Ur1HBHaN7njPfJAj50": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/fHkl_RuHOoc4rso__nV-qreikovd6Yhrq5mpBlkf5hmPGaxDlik2bYOQ4dhUQjtl")},
- "substitute/VV5W0_DiA1iylaqbKFThp1ZpV_y1ccVS1XyqDnDaXoHQ-EEyPI4XFrQHcHOF2hWG": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/fHkl_RuHOoc4rso__nV-qreikovd6Yhrq5mpBlkf5hmPGaxDlik2bYOQ4dhUQjtl")},
-
- "work": {Mode: fs.ModeDir | 0700},
- }},
- }
- checkWithCache(t, testCases)
-}
-
-func TestErrors(t *testing.T) {
- t.Parallel()
-
- testCases := []struct {
- name string
- err error
- want string
- }{
- {"InvalidLookupError", pkg.InvalidLookupError{
- 0xff, 0xf0,
- }, "attempting to look up non-input artifact __AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"},
-
- {"InvalidArtifactError", pkg.InvalidArtifactError{
- 0xff, 0xfd,
- }, "artifact __0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA cannot be cured"},
-
- {"ChecksumMismatchError", &pkg.ChecksumMismatchError{
- Want: (pkg.Checksum)(bytes.Repeat([]byte{
- 0x75, 0xe6, 0x9d, 0x6d, 0xe7, 0x9f,
- }, 8)),
- }, "got AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" +
- " instead of deadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef"},
-
- {"ResponseStatusError", pkg.ResponseStatusError(
- http.StatusNotAcceptable,
- ), "the requested URL returned non-OK status: Not Acceptable"},
-
- {"DisallowedTypeflagError", pkg.DisallowedTypeflagError(
- tar.TypeChar,
- ), "disallowed typeflag '3'"},
-
- {"InvalidFileModeError", pkg.InvalidFileModeError(
- fs.ModeSymlink | 0777,
- ), "artifact did not produce a regular file or directory"},
-
- {"NoOutputError", pkg.NoOutputError{
- // empty struct
- }, "artifact cured successfully but did not produce any output"},
-
- {"IRKindError", &pkg.IRKindError{
- Got: pkg.IRKindEnd,
- Want: pkg.IRKindIdent,
- Ancillary: 0xcafebabe,
- }, "got terminator IR value (0xcafebabe) instead of ident"},
- {"IRKindError invalid", &pkg.IRKindError{
- Got: 0xbeef,
- Want: pkg.IRKindIdent,
- Ancillary: 0xcafe,
- }, "got invalid kind 48879 IR value (0xcafe) instead of ident"},
-
- {"UnsupportedVariantError", pkg.UnsupportedVariantError(
- "rosa",
- ), `unsupported variant "rosa"`},
-
- {"UnsupportedArchError zero", pkg.UnsupportedArchError(""),
- "invalid architecture name"},
- {"UnsupportedArchError", pkg.UnsupportedArchError("riscv64"),
- "unsupported architecture riscv64"},
- }
- for _, tc := range testCases {
- t.Run(tc.name, func(t *testing.T) {
- t.Parallel()
-
- if got := tc.err.Error(); got != tc.want {
- t.Errorf("Error: %q, want %q", got, tc.want)
- }
- })
- }
-}
-
-func TestScrubError(t *testing.T) {
- t.Parallel()
-
- testCases := []struct {
- name string
- err pkg.ScrubError
- want string
- unwrap []error
- }{
- {"sample", *newWantScrubError(
- fhs.AbsVarLib.Append("cure"),
- ), `checksum mismatches:
-got vsAhtPNo4waRNOASwrQwcIPTqb3SBuJOXw2G4T1mNmVZM-wrQTRllmgXqcIIoRcX instead of _wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-
-dangling identifiers:
-_gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-_v4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-_v8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-
-errors during scrub:
- /var/lib/cure/checksum/__8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA:
- artifact did not produce a regular file or directory
- /var/lib/cure/checksum/invalid:
- illegal base64 data at input byte 4
- /var/lib/cure/identifier/_v8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA:
- readlink /var/lib/cure/identifier/_v8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA: invalid argument
- /var/lib/cure/identifier/invalid:
- illegal base64 data at input byte 4
- /var/lib/cure/nonexistent:
- illegal base64 data at input byte 8
-`, []error{
- &pkg.ChecksumMismatchError{Got: pkg.MustDecode(
- "vsAhtPNo4waRNOASwrQwcIPTqb3SBuJOXw2G4T1mNmVZM-wrQTRllmgXqcIIoRcX",
- ), Want: pkg.Checksum{0xff, 0}},
-
- pkg.InvalidFileModeError(fs.ModeSymlink),
- base64.CorruptInputError(4),
-
- &os.PathError{
- Op: "readlink",
- Path: fhs.AbsVarLib.Append("cure").Append(
- "identifier",
- pkg.Encode(pkg.ID{0xfe, 0xff}),
- ).String(),
- Err: syscall.EINVAL,
- },
-
- base64.CorruptInputError(4),
- base64.CorruptInputError(8),
- }},
-
- {"full", pkg.ScrubError{
- ChecksumMismatches: []pkg.ChecksumMismatchError{
- {Want: pkg.MustDecode("CH3AiUrCCcVOjOYLaMKKK1Da78989JtfHeIsxMzWOQFiN4mrCLDYpoDxLWqJWCUN")},
- },
- DanglingIdentifiers: []pkg.ID{
- (pkg.ID)(bytes.Repeat([]byte{0x75, 0xe6, 0x9d, 0x6d, 0xe7, 0x9f}, 8)),
- (pkg.ID)(bytes.Repeat([]byte{0x71, 0xa7, 0xde, 0x6d, 0xa6, 0xde}, 8)),
- },
- Errs: map[unique.Handle[string]][]error{
- unique.Make("/proc/nonexistent"): {
- stub.UniqueError(0xcafe),
- stub.UniqueError(0xbad),
- stub.UniqueError(0xff),
- },
- },
- }, `checksum mismatches:
-got AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA instead of CH3AiUrCCcVOjOYLaMKKK1Da78989JtfHeIsxMzWOQFiN4mrCLDYpoDxLWqJWCUN
-
-dangling identifiers:
-deadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef
-cafebabecafebabecafebabecafebabecafebabecafebabecafebabecafebabe
-
-errors during scrub:
- /proc/nonexistent:
- unique error 51966 injected by the test suite
- unique error 2989 injected by the test suite
- unique error 255 injected by the test suite
-`, []error{
- &pkg.ChecksumMismatchError{Want: pkg.MustDecode("CH3AiUrCCcVOjOYLaMKKK1Da78989JtfHeIsxMzWOQFiN4mrCLDYpoDxLWqJWCUN")},
- stub.UniqueError(0xcafe),
- stub.UniqueError(0xbad),
- stub.UniqueError(0xff),
- }},
- }
- for _, tc := range testCases {
- t.Run(tc.name, func(t *testing.T) {
- t.Parallel()
-
- if got := tc.err.Error(); got != tc.want {
- t.Errorf("Error:\n\n%s\n\nwant\n\n%s", got, tc.want)
- }
-
- if unwrap := tc.err.Unwrap(); !reflect.DeepEqual(unwrap, tc.unwrap) {
- t.Errorf("Unwrap: %#v, want %#v", unwrap, tc.unwrap)
- }
- })
- }
-}
-
-func TestInputError(t *testing.T) {
- t.Parallel()
-
- makeIdent := func(ident ...byte) pkg.Artifact {
- var a overrideIdent
- copy(a.id[:], ident)
- // does not compare equal
- a.TrivialArtifact = new(stubArtifact)
- return a
- }
-
- testCases := []struct {
- name string
- err pkg.InputError
- want string
- unwrap []error
- }{
- {"simple", pkg.InputError{
- makeIdent(0xff, 9): stub.UniqueError(0xbad09),
- makeIdent(0xff, 0): stub.UniqueError(0xbad00),
- makeIdent(0xff, 0xf): stub.UniqueError(0xbad0f),
- makeIdent(0xff, 1): stub.UniqueError(0xbad01),
- }, `errors curing inputs:
- _wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA: unique error 765184 injected by the test suite
- _wEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA: unique error 765185 injected by the test suite
- _wkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA: unique error 765193 injected by the test suite
- _w8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA: unique error 765199 injected by the test suite`, []error{
- stub.UniqueError(0xbad00),
- stub.UniqueError(0xbad01),
- stub.UniqueError(0xbad09),
- stub.UniqueError(0xbad0f),
- }},
-
- {"dedup", pkg.InputError{
- makeIdent(0xff, 9): stub.UniqueError(0xbad09),
- makeIdent(0xff, 9): stub.UniqueError(0xbad09),
- makeIdent(0xff, 9): stub.UniqueError(0xbad09),
- makeIdent(0xff, 0): stub.UniqueError(0xbad00),
- makeIdent(0xff, 0): stub.UniqueError(0xbad00),
- makeIdent(0xff, 1): stub.UniqueError(0xbad01),
- }, `errors curing inputs:
- _wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA: unique error 765184 injected by the test suite
- _wEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA: unique error 765185 injected by the test suite
- _wkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA: unique error 765193 injected by the test suite`, []error{
- stub.UniqueError(0xbad00),
- stub.UniqueError(0xbad01),
- stub.UniqueError(0xbad09),
- }},
- }
- for _, tc := range testCases {
- t.Run(tc.name, func(t *testing.T) {
- t.Parallel()
-
- if got := tc.err.Error(); got != tc.want {
- t.Errorf("Error:\n%s\nwant\n%s", got, tc.want)
- }
-
- if unwrap := tc.err.Unwrap(); !reflect.DeepEqual(unwrap, tc.unwrap) {
- t.Errorf("Unwrap: %#v, want %#v", unwrap, tc.unwrap)
- }
- })
- }
-}
-
-// earlyFailureF is a [FloodArtifact] with a large dependency graph resulting in
-// a large [DependencyCureError].
-type earlyFailureF int
-
-func (earlyFailureF) Kind() pkg.Kind { return pkg.KindExec }
-func (earlyFailureF) Params(*pkg.IContext) {}
-func (earlyFailureF) IsExclusive() bool { return false }
-
-func (a earlyFailureF) Inputs() []pkg.Artifact {
- deps := make([]pkg.Artifact, a)
- for i := range deps {
- deps[i] = a - 1
- }
- return deps
-}
-
-func (a earlyFailureF) Cure(*pkg.FContext) error {
- if a != 0 {
- panic("unexpected cure on " + strconv.Itoa(int(a)))
- }
- return stub.UniqueError(0xcafe)
-}
-
-func BenchmarkEarlyDCE(b *testing.B) {
- msg := message.New(log.New(os.Stderr, "dce: ", 0))
- msg.SwapVerbose(testing.Verbose())
-
- for b.Loop() {
- b.StopTimer()
- c, err := pkg.Open(b.Context(), msg, check.MustAbs(b.TempDir()), nil)
- if err != nil {
- b.Fatal(err)
- }
- b.StartTimer()
- _, _, err = c.Cure(earlyFailureF(8))
- b.StopTimer()
- if !errors.Is(err, stub.UniqueError(0xcafe)) {
- b.Fatalf("Cure: error = %v", err)
- }
- c.Close()
- b.StartTimer()
- }
-}
-
-func TestDependencyCureErrorEarly(t *testing.T) {
- t.Parallel()
-
- checkWithCache(t, []cacheTestCase{
- {"early", 0, nil, func(t *testing.T, _ *check.Absolute, c *pkg.Cache) {
- _, _, err := c.Cure(earlyFailureF(8))
- if !errors.Is(err, stub.UniqueError(0xcafe)) {
- t.Fatalf("Cure: error = %v", err)
- }
- }, expectsFS{
- ".": {Mode: fs.ModeDir | 0700},
- "checksum": {Mode: fs.ModeDir | 0700},
- "identifier": {Mode: fs.ModeDir | 0700},
- "substitute": {Mode: fs.ModeDir | 0700},
- "work": {Mode: fs.ModeDir | 0700},
- }},
- })
-}
-
-func TestOpen(t *testing.T) {
- t.Parallel()
-
- t.Run("nonexistent", func(t *testing.T) {
- t.Parallel()
-
- wantErr := &os.PathError{
- Op: "mkdir",
- Path: container.Nonexistent,
- Err: syscall.ENOENT,
- }
- if _, err := pkg.Open(
- t.Context(),
- message.New(nil),
- check.MustAbs(container.Nonexistent),
- nil,
- ); !reflect.DeepEqual(err, wantErr) {
- t.Errorf("Open: error = %#v, want %#v", err, wantErr)
- }
- })
-
- t.Run("permission", func(t *testing.T) {
- t.Parallel()
-
- tempDir := check.MustAbs(t.TempDir())
- if err := os.Chmod(tempDir.String(), 0); err != nil {
- t.Fatal(err)
- } else {
- t.Cleanup(func() {
- if err = os.Chmod(tempDir.String(), 0700); err != nil {
- t.Fatal(err)
- }
- })
- }
-
- wantErr := &os.PathError{
- Op: "mkdir",
- Path: tempDir.Append("cache").String(),
- Err: syscall.EACCES,
- }
- if _, err := pkg.Open(
- t.Context(),
- message.New(nil),
- tempDir.Append("cache"),
- nil,
- ); !reflect.DeepEqual(err, wantErr) {
- t.Errorf("Open: error = %#v, want %#v", err, wantErr)
- }
- })
-
- t.Run("dirty", func(t *testing.T) {
- t.Parallel()
-
- tempDir := check.MustAbs(t.TempDir())
- if err := os.MkdirAll(tempDir.Append(
- "cache",
- "work",
- "dirty",
- ).String(), 0755); err != nil {
- t.Fatal(err)
- }
-
- wantErr := errors.New("work is not empty, scrub likely required")
- if _, err := pkg.Open(
- t.Context(),
- message.New(nil),
- tempDir.Append("cache"),
- nil,
- ); !reflect.DeepEqual(err, wantErr) {
- t.Errorf("Open: error = %#v, want %#v", err, wantErr)
- }
- })
-
- t.Run("scratch", func(t *testing.T) {
- t.Parallel()
-
- tempDir := check.MustAbs(t.TempDir())
- if err := os.MkdirAll(tempDir.Append(
- "cache",
- "scratch",
- ).String(), 0755); err != nil {
- t.Fatal(err)
- }
-
- wantErr := errors.New("scratch is present, scrub likely required")
- if _, err := pkg.Open(
- t.Context(),
- message.New(nil),
- tempDir.Append("cache"), nil,
- ); !reflect.DeepEqual(err, wantErr) {
- t.Errorf("Open: error = %#v, want %#v", err, wantErr)
- }
- })
-}
-
-func TestExtensionRegister(t *testing.T) {
- extensionOld := extension
- openedOld := opened
- t.Cleanup(func() { extension = extensionOld; opened = openedOld })
- extension = ""
- opened = false
-
- t.Run("set", func(t *testing.T) {
- t.Cleanup(func() { extension = "" })
-
- const want = "rosa"
- pkg.SetExtension(want)
- if got := pkg.Extension(); got != want {
- t.Fatalf("Extension: %q, want %q", got, want)
- }
- })
-
- t.Run("twice", func(t *testing.T) {
- t.Cleanup(func() { extension = "" })
-
- defer func() {
- const wantPanic = "attempting to set extension twice"
- if r := recover(); r != wantPanic {
- t.Errorf("panic: %#v, want %q", r, wantPanic)
- }
- }()
- pkg.SetExtension("rosa")
- pkg.SetExtension("rosa")
- })
-
- t.Run("invalid", func(t *testing.T) {
- defer func() {
- var wantPanic = pkg.ErrInvalidExtension
- if r := recover(); r != wantPanic {
- t.Errorf("panic: %#v, want %#v", r, wantPanic)
- }
- }()
- pkg.SetExtension(" ")
- })
-
- t.Run("opened", func(t *testing.T) {
- t.Cleanup(func() { opened = false })
-
- if _, err := pkg.Open(
- t.Context(),
- message.New(log.Default()),
- check.MustAbs(container.Nonexistent),
- nil,
- ); !errors.Is(err, os.ErrNotExist) {
- t.Fatalf("Open: error = %v", err)
- }
-
- t.Run("variant", func(t *testing.T) {
- defer func() {
- const wantPanic = "attempting to set extension after open"
- if r := recover(); r != wantPanic {
- t.Errorf("panic: %#v, want %q", r, wantPanic)
- }
- }()
- pkg.SetExtension("rosa")
- })
-
- t.Run("register", func(t *testing.T) {
- defer func() {
- const wantPanic = "attempting to register after open"
- if r := recover(); r != wantPanic {
- t.Errorf("panic: %#v, want %q", r, wantPanic)
- }
- }()
- pkg.Register(pkg.KindCustomOffset, nil)
- })
- })
-
- t.Run("incomplete", func(t *testing.T) {
- t.Cleanup(func() { delete(irArtifact, pkg.KindCustomOffset) })
-
- defer func() {
- const wantPanic = "attempting to open cache with incomplete variant setup"
- if r := recover(); r != wantPanic {
- t.Errorf("panic: %#v, want %q", r, wantPanic)
- }
- }()
- pkg.Register(pkg.KindCustomOffset, nil)
-
- t.Cleanup(func() { opened = false })
- _, _ = pkg.Open(nil, nil, nil, nil)
- panic("unreachable")
- })
-
- t.Run("create", func(t *testing.T) {
- t.Cleanup(func() { extension = "" })
- const want = "rosa"
- pkg.SetExtension(want)
-
- base := check.MustAbs(t.TempDir())
- t.Cleanup(func() { opened = false })
- if c, err := pkg.Open(t.Context(), nil, base, nil); err != nil {
- t.Fatal(err)
- } else {
- c.Close()
- }
-
- if got, err := os.ReadFile(base.Append("variant").String()); err != nil {
- t.Fatal(err)
- } else if string(got) != want {
- t.Fatalf("variant: %q", string(got))
- }
- })
-
- t.Run("access", func(t *testing.T) {
- base := check.MustAbs(t.TempDir())
- t.Cleanup(func() { opened = false })
-
- if err := os.WriteFile(base.Append("variant").String(), nil, 0); err != nil {
- t.Fatal(err)
- }
-
- wantErr := &os.PathError{
- Op: "open",
- Path: base.Append("variant").String(),
- Err: syscall.EACCES,
- }
- if _, err := pkg.Open(
- t.Context(), nil,
- base, nil,
- ); !reflect.DeepEqual(err, wantErr) {
- t.Fatalf("Open: error = %v, want %v", err, wantErr)
- }
- })
-
- t.Run("promote", func(t *testing.T) {
- t.Cleanup(func() { extension = "" })
- const want = "rosa"
- pkg.SetExtension(want)
-
- base := check.MustAbs(t.TempDir())
- t.Cleanup(func() { opened = false })
-
- variantPath := base.Append("variant")
- if err := os.WriteFile(variantPath.String(), nil, 0600); err != nil {
- t.Fatal(err)
- }
-
- if _, err := pkg.Open(
- t.Context(), nil,
- base,
- nil,
- ); !reflect.DeepEqual(err, pkg.ErrWouldPromote) {
- t.Fatalf("Open: error = %v", err)
- }
-
- if p, err := os.ReadFile(variantPath.String()); err != nil {
- t.Fatal(err)
- } else if len(p) != 0 {
- t.Fatalf("variant: %q", string(p))
- }
-
- if c, err := pkg.Open(
- t.Context(), nil,
- base, &pkg.CacheAttr{Flags: pkg.CPromoteVariant},
- ); err != nil {
- t.Fatalf("Open: error = %v", err)
- } else {
- c.Close()
- }
-
- if p, err := os.ReadFile(variantPath.String()); err != nil {
- t.Fatal(err)
- } else if string(p) != want {
- t.Fatalf("variant: %q, want %q", string(p), want)
- }
- })
-
- t.Run("open invalid", func(t *testing.T) {
- base := check.MustAbs(t.TempDir())
- t.Cleanup(func() { opened = false })
-
- variantPath := base.Append("variant")
- if err := os.WriteFile(variantPath.String(), make([]byte, 129), 0400); err != nil {
- t.Fatal(err)
- }
-
- if _, err := pkg.Open(
- t.Context(), nil,
- base, nil,
- ); !reflect.DeepEqual(err, pkg.ErrInvalidExtension) {
- t.Fatalf("Open: error = %v", err)
- }
- })
-
- t.Run("unsupported", func(t *testing.T) {
- base := check.MustAbs(t.TempDir())
- t.Cleanup(func() { opened = false })
-
- variantPath := base.Append("variant")
- if err := os.WriteFile(variantPath.String(), []byte("rosa"), 0400); err != nil {
- t.Fatal(err)
- }
-
- if _, err := pkg.Open(
- t.Context(), nil,
- base, nil,
- ); !reflect.DeepEqual(err, pkg.UnsupportedVariantError("rosa")) {
- t.Fatalf("Open: error = %v", err)
- }
- })
-}