diff options
Diffstat (limited to 'internal/pkg/pkg_test.go')
| -rw-r--r-- | internal/pkg/pkg_test.go | 131 |
1 files changed, 131 insertions, 0 deletions
diff --git a/internal/pkg/pkg_test.go b/internal/pkg/pkg_test.go index 9a397898..1239bed3 100644 --- a/internal/pkg/pkg_test.go +++ b/internal/pkg/pkg_test.go @@ -197,6 +197,35 @@ func newStubFile( } } +// 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(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(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( @@ -1490,6 +1519,108 @@ func TestCache(t *testing.T) { "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, nil}, + + {"substitute", _a, base.Append( + "identifier", + pkg.Encode(_wantIdent.Value()), + ), _wantOutput, nil}, + + {"mismatch", kca, nil, nil, &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/4HqRo4uTwRQjfy3d2cujMoDC_pC4iv20h4a7NYlx0UdbVuky18o5iK78TFEfPX2U": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/MGWmEfjut2QE2xPJwTsmUzpff4BN_FEnQ7T0j7gvUCCiugJQNwqt9m151fm9D1yU")}, + "identifier/7AZcJm58ghFyTVf_v2baSntgpsxkP5el7ti9dC77C29n8YTEqQW9jRW92KGNdYnz": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/fHkl_RuHOoc4rso__nV-qreikovd6Yhrq5mpBlkf5hmPGaxDlik2bYOQ4dhUQjtl")}, + "identifier/c4aCI00C-ZVyo_FQDQLl1OYK4U_kjzxwrLdFDiXMHnbMcZXCkXo_nxUWauScZ_4V": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/MGWmEfjut2QE2xPJwTsmUzpff4BN_FEnQ7T0j7gvUCCiugJQNwqt9m151fm9D1yU")}, + "identifier/cNoG77frXGRCJa7fUi1INKUEQg7L4qrX5acsSv-wqZdGZT7dQwM93rD3at6kSFFF": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/OLBgp1GsljhM2TJ-sbHjaiH9txEUvgdDTAzHv2P24donTt6_529l-9Ua0vFImLlb")}, + "identifier/gvCqzexZVqXjF8B5lKMcP5onmq3jJ6AKqzOW_WN0Fl2yTr9NKhPt9l_ClD2EOSlS": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/fHkl_RuHOoc4rso__nV-qreikovd6Yhrq5mpBlkf5hmPGaxDlik2bYOQ4dhUQjtl")}, + + "status": {Mode: fs.ModeDir | 0700}, + "status/gvCqzexZVqXjF8B5lKMcP5onmq3jJ6AKqzOW_WN0Fl2yTr9NKhPt9l_ClD2EOSlS": {Mode: 0400, Data: []byte("\x00")}, + + "substitute": {Mode: fs.ModeDir | 0700}, + "substitute/qOYrxy9ztKeOA96Os811_0Ox5sd8FBOxis6psJAnRJL5MLazFMaqmd4g7t7k1OHk": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/MGWmEfjut2QE2xPJwTsmUzpff4BN_FEnQ7T0j7gvUCCiugJQNwqt9m151fm9D1yU")}, + + "work": {Mode: fs.ModeDir | 0700}, + }}, } checkWithCache(t, testCases) } |
