diff options
| author | Ophestra <cat@gensokyo.uk> | 2026-08-29 18:58:06 +0900 |
|---|---|---|
| committer | Ophestra <cat@gensokyo.uk> | 2026-08-29 18:58:06 +0900 |
| commit | c2d900ec74e03e9c782cfe7b7ce06ff62cda6601 (patch) | |
| tree | fb13320bfdc62d810aa59769e8809dc2f707919e /pkg/tar_test.go | |
| parent | bd4f29909e0750a4660eaf48e3169777a265b0ab (diff) | |
Closes #43.
Signed-off-by: Ophestra <cat@gensokyo.uk>
Diffstat (limited to 'pkg/tar_test.go')
| -rw-r--r-- | pkg/tar_test.go | 225 |
1 files changed, 225 insertions, 0 deletions
diff --git a/pkg/tar_test.go b/pkg/tar_test.go new file mode 100644 index 00000000..5462714f --- /dev/null +++ b/pkg/tar_test.go @@ -0,0 +1,225 @@ +package pkg_test + +import ( + "archive/tar" + "bytes" + "crypto/sha512" + "errors" + "io/fs" + "net/http" + "os" + "testing" + "testing/fstest" + + "hakurei.app/check" + "hakurei.app/internal/stub" + "hakurei.app/pkg" +) + +func TestTar(t *testing.T) { + t.Parallel() + + want := expectsFS{ + ".": {Mode: fs.ModeDir | 0500}, + + "checksum": {Mode: fs.ModeDir | 0500}, + "checksum/1TL00Qb8dcqayX7wTO8WNaraHvY6b-KCsctLDTrb64QBCmxj_-byK1HdIUwMaFEP": {Mode: fs.ModeDir | 0500}, + "checksum/1TL00Qb8dcqayX7wTO8WNaraHvY6b-KCsctLDTrb64QBCmxj_-byK1HdIUwMaFEP/check": {Mode: 0400, Data: []byte{0, 0}}, + "checksum/1TL00Qb8dcqayX7wTO8WNaraHvY6b-KCsctLDTrb64QBCmxj_-byK1HdIUwMaFEP/lib": {Mode: fs.ModeDir | 0500}, + "checksum/1TL00Qb8dcqayX7wTO8WNaraHvY6b-KCsctLDTrb64QBCmxj_-byK1HdIUwMaFEP/lib/pkgconfig": {Mode: fs.ModeDir | 0500}, + "checksum/1TL00Qb8dcqayX7wTO8WNaraHvY6b-KCsctLDTrb64QBCmxj_-byK1HdIUwMaFEP/lib/libedac.so": {Mode: fs.ModeSymlink | 0777, Data: []byte("/proc/nonexistent/libedac.so")}, + + "identifier": {Mode: fs.ModeDir | 0500}, + "identifier/HnySzeLQvSBZuTUcvfmLEX_OmH4yJWWH788NxuLuv7kVn8_uPM6Ks4rqFWM2NZJY": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/1TL00Qb8dcqayX7wTO8WNaraHvY6b-KCsctLDTrb64QBCmxj_-byK1HdIUwMaFEP")}, + "identifier/Zx5ZG9BAwegNT3zQwCySuI2ktCXxNgxirkGLFjW4FW06PtojYVaCdtEw8yuntPLa": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/1TL00Qb8dcqayX7wTO8WNaraHvY6b-KCsctLDTrb64QBCmxj_-byK1HdIUwMaFEP")}, + + "work": {Mode: fs.ModeDir | 0500}, + } + wantEncode := pkg.Encode(want.hash()) + + wantExpand := expectsFS{ + ".": {Mode: fs.ModeDir | 0500}, + + "libedac.so": {Mode: fs.ModeSymlink | 0777, Data: []byte("/proc/nonexistent/libedac.so")}, + } + wantExpandEncode := pkg.Encode(wantExpand.hash()) + + checkWithCache(t, []cacheTestCase{ + {"http", 0, nil, func(t *testing.T, base *check.Absolute, c *pkg.Cache) { + checkTarHTTP(t, base, c, fstest.MapFS{ + ".": {Mode: fs.ModeDir | 0700}, + + "checksum": {Mode: fs.ModeDir | 0700}, + "checksum/1TL00Qb8dcqayX7wTO8WNaraHvY6b-KCsctLDTrb64QBCmxj_-byK1HdIUwMaFEP": {Mode: fs.ModeDir | 0700}, + "checksum/1TL00Qb8dcqayX7wTO8WNaraHvY6b-KCsctLDTrb64QBCmxj_-byK1HdIUwMaFEP/check": {Mode: 0400, Data: []byte{0, 0}}, + "checksum/1TL00Qb8dcqayX7wTO8WNaraHvY6b-KCsctLDTrb64QBCmxj_-byK1HdIUwMaFEP/lib": {Mode: fs.ModeDir | 0700}, + "checksum/1TL00Qb8dcqayX7wTO8WNaraHvY6b-KCsctLDTrb64QBCmxj_-byK1HdIUwMaFEP/lib/pkgconfig": {Mode: fs.ModeDir | 0700}, + "checksum/1TL00Qb8dcqayX7wTO8WNaraHvY6b-KCsctLDTrb64QBCmxj_-byK1HdIUwMaFEP/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/1TL00Qb8dcqayX7wTO8WNaraHvY6b-KCsctLDTrb64QBCmxj_-byK1HdIUwMaFEP")}, + "identifier/Zx5ZG9BAwegNT3zQwCySuI2ktCXxNgxirkGLFjW4FW06PtojYVaCdtEw8yuntPLa": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/1TL00Qb8dcqayX7wTO8WNaraHvY6b-KCsctLDTrb64QBCmxj_-byK1HdIUwMaFEP")}, + + "work": {Mode: fs.ModeDir | 0700}, + }, want) + }, expectsFS{ + ".": {Mode: fs.ModeDir | 0700}, + + "checksum": {Mode: fs.ModeDir | 0700}, + "checksum/" + wantEncode: {Mode: fs.ModeDir | 0500}, + "checksum/" + wantEncode + "/checksum": {Mode: fs.ModeDir | 0500}, + "checksum/" + wantEncode + "/checksum/1TL00Qb8dcqayX7wTO8WNaraHvY6b-KCsctLDTrb64QBCmxj_-byK1HdIUwMaFEP": {Mode: fs.ModeDir | 0500}, + "checksum/" + wantEncode + "/checksum/1TL00Qb8dcqayX7wTO8WNaraHvY6b-KCsctLDTrb64QBCmxj_-byK1HdIUwMaFEP/check": {Mode: 0400, Data: []byte{0, 0}}, + "checksum/" + wantEncode + "/checksum/1TL00Qb8dcqayX7wTO8WNaraHvY6b-KCsctLDTrb64QBCmxj_-byK1HdIUwMaFEP/lib": {Mode: fs.ModeDir | 0500}, + "checksum/" + wantEncode + "/checksum/1TL00Qb8dcqayX7wTO8WNaraHvY6b-KCsctLDTrb64QBCmxj_-byK1HdIUwMaFEP/lib/libedac.so": {Mode: fs.ModeSymlink | 0777, Data: []byte("/proc/nonexistent/libedac.so")}, + "checksum/" + wantEncode + "/checksum/1TL00Qb8dcqayX7wTO8WNaraHvY6b-KCsctLDTrb64QBCmxj_-byK1HdIUwMaFEP/lib/pkgconfig": {Mode: fs.ModeDir | 0500}, + "checksum/" + wantEncode + "/identifier": {Mode: fs.ModeDir | 0500}, + "checksum/" + wantEncode + "/identifier/HnySzeLQvSBZuTUcvfmLEX_OmH4yJWWH788NxuLuv7kVn8_uPM6Ks4rqFWM2NZJY": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/1TL00Qb8dcqayX7wTO8WNaraHvY6b-KCsctLDTrb64QBCmxj_-byK1HdIUwMaFEP")}, + "checksum/" + wantEncode + "/identifier/Zx5ZG9BAwegNT3zQwCySuI2ktCXxNgxirkGLFjW4FW06PtojYVaCdtEw8yuntPLa": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/1TL00Qb8dcqayX7wTO8WNaraHvY6b-KCsctLDTrb64QBCmxj_-byK1HdIUwMaFEP")}, + "checksum/" + wantEncode + "/work": {Mode: fs.ModeDir | 0500}, + + "identifier": {Mode: fs.ModeDir | 0700}, + "identifier/snWp53xxNdx6cV5KSJqzyVWzLlTsFd8udOisIu8Rgxly09mGcxufYCoQ5CQrHDyZ": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/" + wantEncode)}, + "identifier/v9DUj2R4YK_3ae0m9VuUYI-HJysDDCENu1k10thxioycRzFH1Qejw5bBGukm4IdL": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/" + wantEncode)}, + + "substitute": {Mode: fs.ModeDir | 0700}, + + "temp": {Mode: fs.ModeDir | 0700}, + "work": {Mode: fs.ModeDir | 0700}, + }}, + + {"http expand", 0, nil, func(t *testing.T, base *check.Absolute, c *pkg.Cache) { + checkTarHTTP(t, base, c, fstest.MapFS{ + ".": {Mode: fs.ModeDir | 0700}, + + "lib": {Mode: fs.ModeDir | 0700}, + "lib/libedac.so": {Mode: fs.ModeSymlink | 0777, Data: []byte("/proc/nonexistent/libedac.so")}, + }, wantExpand) + }, expectsFS{ + ".": {Mode: fs.ModeDir | 0700}, + + "checksum": {Mode: fs.ModeDir | 0700}, + "checksum/" + wantExpandEncode: {Mode: fs.ModeDir | 0500}, + "checksum/" + wantExpandEncode + "/libedac.so": {Mode: fs.ModeSymlink | 0777, Data: []byte("/proc/nonexistent/libedac.so")}, + + "identifier": {Mode: fs.ModeDir | 0700}, + "identifier/1SuvgGltcsgqps9tWqjULG8RCdpx_6KVWXdsMd5xPKvdtysOxqpE-3bLu4j0WpGk": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/" + wantExpandEncode)}, + "identifier/snWp53xxNdx6cV5KSJqzyVWzLlTsFd8udOisIu8Rgxly09mGcxufYCoQ5CQrHDyZ": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/" + wantExpandEncode)}, + + "substitute": {Mode: fs.ModeDir | 0700}, + + "temp": {Mode: fs.ModeDir | 0700}, + "work": {Mode: fs.ModeDir | 0700}, + }}, + }) +} + +func checkTarHTTP( + t *testing.T, + base *check.Absolute, + c *pkg.Cache, + testdataFsys fs.FS, + want expectsKnown, +) { + var testdata string + { + var buf bytes.Buffer + w := tar.NewWriter(&buf) + if err := w.AddFS(testdataFsys); err != nil { + t.Fatalf("AddFS: error = %v", err) + } + if err := w.Close(); err != nil { + t.Fatalf("Close: error = %v", err) + } + testdata = buf.String() + } + + testdataChecksum := func() pkg.Checksum { + h := sha512.New384() + h.Write([]byte(testdata)) + return (pkg.Checksum)(h.Sum(nil)) + }() + + var transport http.Transport + client := http.Client{Transport: &transport} + transport.RegisterProtocol("file", http.NewFileTransportFS(fstest.MapFS{ + "testdata": {Data: []byte(testdata), Mode: 0400}, + })) + + tarDir := stubArtifact{ + kind: pkg.KindExec, + params: []byte("directory containing a single regular file"), + cure: func(t *pkg.TContext) error { + work := t.GetWorkDir() + if err := os.MkdirAll(work.String(), 0700); err != nil { + return err + } + return os.WriteFile( + work.Append("sample.tar.gz").String(), + []byte(testdata), + 0400, + ) + }, + } + tarDirMulti := stubArtifact{ + kind: pkg.KindExec, + params: []byte("directory containing a multiple entries"), + cure: func(t *pkg.TContext) error { + work := t.GetWorkDir() + if err := os.MkdirAll(work.Append( + "garbage", + ).String(), 0700); err != nil { + return err + } + return os.WriteFile( + work.Append("sample.tar.gz").String(), + []byte(testdata), + 0400, + ) + }, + } + tarDirType := stubArtifact{ + kind: pkg.KindExec, + params: []byte("directory containing a symbolic link"), + cure: func(t *pkg.TContext) error { + work := t.GetWorkDir() + if err := os.MkdirAll(work.String(), 0700); err != nil { + return err + } + return os.Symlink( + work.String(), + work.Append("sample.tar.gz").String(), + ) + }, + } + // destroy these to avoid including it in flatten test case + defer newDestroyArtifactFunc(&tarDir)(t, base, c) + defer newDestroyArtifactFunc(&tarDirMulti)(t, base, c) + defer newDestroyArtifactFunc(&tarDirType)(t, base, c) + + cureMany(t, c, []cureStep{ + {"file", pkg.NewTar(pkg.NewHTTPGet( + &client, + "file:///testdata", + testdataChecksum, + )), ignorePathname, want, pkg.WNew, nil}, + + {"directory", pkg.NewTar(&tarDir), ignorePathname, want, pkg.WNew, nil}, + + {"multiple entries", pkg.NewTar(&tarDirMulti), nil, nil, pkg.WNew, errors.New( + "input directory does not contain a single regular file", + )}, + + {"bad type", pkg.NewTar(&tarDirType), nil, nil, pkg.WNew, errors.New( + "input directory does not contain a single regular file", + )}, + + {"error passthrough", pkg.NewTar(&stubArtifact{ + kind: pkg.KindExec, + params: []byte("doomed artifact"), + cure: func(t *pkg.TContext) error { + return stub.UniqueError(0xcafe) + }, + }), nil, nil, pkg.WNew, stub.UniqueError(0xcafe)}, + }) +} |
