67dbb68818
Test / Create distribution (push) Successful in 56s
Test / Sandbox (push) Successful in 2m43s
Test / ShareFS (push) Successful in 3m57s
Test / Hakurei (push) Successful in 4m3s
Test / Sandbox (race detector) (push) Successful in 5m34s
Test / Hakurei (race detector) (push) Successful in 6m36s
Test / Flake checks (push) Successful in 1m5s
This enables changing the behaviour of an artifact implementation without changing its IR structure. Unfortunately this changes the IR header structure resulting in many rebuilds. Signed-off-by: Ophestra <cat@gensokyo.uk>
241 lines
6.4 KiB
Go
241 lines
6.4 KiB
Go
package pkg_test
|
|
|
|
import (
|
|
"bytes"
|
|
"io"
|
|
"io/fs"
|
|
"maps"
|
|
"reflect"
|
|
"testing"
|
|
"testing/fstest"
|
|
"unsafe"
|
|
|
|
"hakurei.app/check"
|
|
"hakurei.app/internal/pkg"
|
|
)
|
|
|
|
func TestArchive(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
type entry struct {
|
|
path string
|
|
mode fs.FileMode
|
|
data string
|
|
}
|
|
testCases := []struct {
|
|
name string
|
|
fsys fs.FS
|
|
entries []entry
|
|
sum pkg.Checksum
|
|
err error
|
|
}{
|
|
{"bad type", fstest.MapFS{
|
|
".": {Mode: fs.ModeDir | 0700},
|
|
"invalid": {Mode: fs.ModeCharDevice | 0400},
|
|
}, nil, pkg.Checksum{}, pkg.InvalidFileModeError(
|
|
fs.ModeCharDevice | 0400,
|
|
)},
|
|
|
|
{"coldboot", fstest.MapFS{
|
|
".": {Mode: fs.ModeDir | 0700},
|
|
|
|
"devices": {Mode: fs.ModeDir | 0700},
|
|
"devices/uevent": {Mode: 0600, Data: []byte("add")},
|
|
"devices/empty": {Mode: fs.ModeDir | 0700},
|
|
|
|
"devices/sub": {Mode: fs.ModeDir | 0700},
|
|
"devices/sub/uevent": {Mode: 0600, Data: []byte("add")},
|
|
|
|
"block": {Mode: fs.ModeDir | 0700},
|
|
"block/uevent": {Mode: 0600},
|
|
}, []entry{
|
|
{".", fs.ModeDir | 0700, ""},
|
|
|
|
{"block", fs.ModeDir | 0700, ""},
|
|
{"block/uevent", 0600, ""},
|
|
|
|
{"devices", fs.ModeDir | 0700, ""},
|
|
{"devices/empty", fs.ModeDir | 0700, ""},
|
|
{"devices/sub", fs.ModeDir | 0700, ""},
|
|
{"devices/sub/uevent", 0600, "add"},
|
|
{"devices/uevent", 0600, "add"},
|
|
}, pkg.MustDecode("mEy_Lf5KotThm7OwMx7yTKZh5HCCyaB41pVAvI9uDMgVQFM91iosBLYsRm8bDsX8"), nil},
|
|
|
|
{"empty", fstest.MapFS{
|
|
".": {Mode: fs.ModeDir | 0700},
|
|
"checksum": {Mode: fs.ModeDir | 0700},
|
|
"identifier": {Mode: fs.ModeDir | 0700},
|
|
"work": {Mode: fs.ModeDir | 0700},
|
|
}, []entry{
|
|
{".", fs.ModeDir | 0700, ""},
|
|
{"checksum", fs.ModeDir | 0700, ""},
|
|
{"identifier", fs.ModeDir | 0700, ""},
|
|
{"work", fs.ModeDir | 0700, ""},
|
|
}, pkg.MustDecode("E4vEZKhCcL2gPZ2Tt59FS3lDng-d_2SKa2i5G_RbDfwGn6EemptFaGLPUDiOa94C"), nil},
|
|
|
|
{"sample directory step garbage", fstest.MapFS{
|
|
".": {Mode: fs.ModeDir | 0500},
|
|
|
|
"lib": {Mode: fs.ModeDir | 0500},
|
|
"lib/check": {Mode: 0400},
|
|
|
|
"lib/pkgconfig": {Mode: fs.ModeDir | 0500},
|
|
}, []entry{
|
|
{".", fs.ModeDir | 0500, ""},
|
|
|
|
{"lib", fs.ModeDir | 0500, ""},
|
|
{"lib/check", 0400, ""},
|
|
|
|
{"lib/pkgconfig", fs.ModeDir | 0500, ""},
|
|
}, pkg.MustDecode("CUx-3hSbTWPsbMfDhgalG4Ni_GmR9TnVX8F99tY_P5GtkYvczg9RrF5zO0jX9XYT"), nil},
|
|
}
|
|
for _, tc := range testCases {
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
t.Run("roundtrip", func(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
var buf bytes.Buffer
|
|
if err := pkg.Write(
|
|
tc.fsys,
|
|
".",
|
|
&buf,
|
|
); !reflect.DeepEqual(err, tc.err) {
|
|
t.Fatalf("Flatten: error = %v, want %v", err, tc.err)
|
|
} else if tc.err != nil {
|
|
return
|
|
}
|
|
|
|
r := pkg.NewReader(bytes.NewReader(buf.Bytes()))
|
|
var got []entry
|
|
for {
|
|
h, err := r.Next()
|
|
if err != nil {
|
|
if err == io.EOF {
|
|
break
|
|
}
|
|
t.Fatalf("Next: error = %v", err)
|
|
}
|
|
|
|
var data []byte
|
|
if data, err = io.ReadAll(r); err != nil {
|
|
t.Fatalf("Read: error = %v", err)
|
|
}
|
|
|
|
got = append(got, entry{
|
|
path: h.Path,
|
|
mode: h.Mode,
|
|
data: unsafe.String(unsafe.SliceData(data), len(data)),
|
|
})
|
|
}
|
|
|
|
if !reflect.DeepEqual(got, tc.entries) {
|
|
t.Fatalf("Reader: %#v, want %#v", got, tc.entries)
|
|
}
|
|
})
|
|
|
|
if tc.err != nil {
|
|
return
|
|
}
|
|
|
|
t.Run("hash", func(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
var got pkg.Checksum
|
|
if err := pkg.SumFS(&got, tc.fsys, "."); err != nil {
|
|
t.Fatalf("SumFS: error = %v", err)
|
|
} else if got != tc.sum {
|
|
t.Fatalf("SumFS: %v", &pkg.ChecksumMismatchError{
|
|
Got: got,
|
|
Want: tc.sum,
|
|
})
|
|
}
|
|
})
|
|
})
|
|
}
|
|
}
|
|
|
|
var archiveTestdata = fstest.MapFS{
|
|
".": {Mode: fs.ModeDir | 0700},
|
|
|
|
"devices": {Mode: fs.ModeDir | 0700},
|
|
"devices/uevent": {Mode: 0600, Data: []byte("add")},
|
|
"devices/empty": {Mode: fs.ModeDir | 0700},
|
|
|
|
"devices/sub": {Mode: fs.ModeDir | 0700},
|
|
"devices/sub/uevent": {Mode: 0600, Data: []byte("add")},
|
|
|
|
"block": {Mode: fs.ModeDir | 0700},
|
|
"block/uevent": {Mode: 0600},
|
|
}
|
|
|
|
func TestArchiveArtifact(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
want := maps.Clone(archiveTestdata)
|
|
want["."].Mode = fs.ModeDir | 0500
|
|
|
|
checkWithCache(t, []cacheTestCase{
|
|
{"unpack", 0, nil, func(t *testing.T, base *check.Absolute, c *pkg.Cache) {
|
|
var buf bytes.Buffer
|
|
if err := pkg.Write(archiveTestdata, ".", &buf); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
cureMany(t, c, []cureStep{
|
|
{"sample", pkg.NewArchive(
|
|
pkg.NewFile("", buf.Bytes()),
|
|
), ignorePathname, expectsFS(want), pkg.WNew, nil},
|
|
})
|
|
}, expectsFS{
|
|
".": {Mode: fs.ModeDir | 0700},
|
|
|
|
"checksum": {Mode: fs.ModeDir | 0700},
|
|
"checksum/CBPcoVHuVUTVRCMbRl8J30RSSzm_tyfuXaZ-HlZsanY1sY50meOVmgaWDrGKbx9F": {Mode: fs.ModeDir | 0500},
|
|
"checksum/CBPcoVHuVUTVRCMbRl8J30RSSzm_tyfuXaZ-HlZsanY1sY50meOVmgaWDrGKbx9F/block": {Mode: fs.ModeDir | 0700},
|
|
"checksum/CBPcoVHuVUTVRCMbRl8J30RSSzm_tyfuXaZ-HlZsanY1sY50meOVmgaWDrGKbx9F/block/uevent": {Mode: 0600},
|
|
"checksum/CBPcoVHuVUTVRCMbRl8J30RSSzm_tyfuXaZ-HlZsanY1sY50meOVmgaWDrGKbx9F/devices": {Mode: fs.ModeDir | 0700},
|
|
"checksum/CBPcoVHuVUTVRCMbRl8J30RSSzm_tyfuXaZ-HlZsanY1sY50meOVmgaWDrGKbx9F/devices/empty": {Mode: fs.ModeDir | 0700},
|
|
"checksum/CBPcoVHuVUTVRCMbRl8J30RSSzm_tyfuXaZ-HlZsanY1sY50meOVmgaWDrGKbx9F/devices/sub": {Mode: fs.ModeDir | 0700},
|
|
"checksum/CBPcoVHuVUTVRCMbRl8J30RSSzm_tyfuXaZ-HlZsanY1sY50meOVmgaWDrGKbx9F/devices/sub/uevent": {Mode: 0600, Data: []byte("add")},
|
|
"checksum/CBPcoVHuVUTVRCMbRl8J30RSSzm_tyfuXaZ-HlZsanY1sY50meOVmgaWDrGKbx9F/devices/uevent": {Mode: 0600, Data: []byte("add")},
|
|
|
|
"identifier": {Mode: fs.ModeDir | 0700},
|
|
"identifier/5woPJTvOnyFA0LpN6fMlw5Z6d3-cfpfNnmEwy5uV8cJi66xQKcfoGNCdVPApuVPW": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/CBPcoVHuVUTVRCMbRl8J30RSSzm_tyfuXaZ-HlZsanY1sY50meOVmgaWDrGKbx9F")},
|
|
|
|
"substitute": {Mode: fs.ModeDir | 0700},
|
|
"work": {Mode: fs.ModeDir | 0700},
|
|
}},
|
|
})
|
|
}
|
|
|
|
func BenchmarkArchiveRead(b *testing.B) {
|
|
var buf bytes.Buffer
|
|
if err := pkg.Write(archiveTestdata, ".", &buf); err != nil {
|
|
b.Fatal(err)
|
|
}
|
|
testdata := buf.Bytes()
|
|
|
|
for b.Loop() {
|
|
r := pkg.NewReader(bytes.NewReader(testdata))
|
|
for {
|
|
_, err := r.Next()
|
|
if err != nil {
|
|
if err == io.EOF {
|
|
break
|
|
}
|
|
b.Fatal(err)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
func BenchmarkArchiveWrite(b *testing.B) {
|
|
for b.Loop() {
|
|
if err := pkg.Write(archiveTestdata, ".", io.Discard); err != nil {
|
|
b.Fatal(err)
|
|
}
|
|
}
|
|
}
|