aboutsummaryrefslogtreecommitdiffhomepage
path: root/internal/pkg/pkg_test.go
diff options
context:
space:
mode:
Diffstat (limited to 'internal/pkg/pkg_test.go')
-rw-r--r--internal/pkg/pkg_test.go139
1 files changed, 139 insertions, 0 deletions
diff --git a/internal/pkg/pkg_test.go b/internal/pkg/pkg_test.go
index 99171f88..2f5cc424 100644
--- a/internal/pkg/pkg_test.go
+++ b/internal/pkg/pkg_test.go
@@ -4,6 +4,7 @@ import (
"archive/tar"
"bytes"
"crypto/sha512"
+ "encoding/base64"
"encoding/binary"
"errors"
"fmt"
@@ -190,6 +191,7 @@ func checkWithCache(t *testing.T, testCases []cacheTestCase) {
}
})
+ var scrubFunc func() error // scrub after hashing
if c, err := pkg.New(base); err != nil {
t.Fatalf("New: error = %v", err)
} else {
@@ -197,6 +199,7 @@ func checkWithCache(t *testing.T, testCases []cacheTestCase) {
tc.early(t, base)
}
tc.f(t, base, c)
+ scrubFunc = c.Scrub
}
if checksum, err := pkg.HashDir(base); err != nil {
@@ -207,6 +210,10 @@ func checkWithCache(t *testing.T, testCases []cacheTestCase) {
Want: tc.want,
})
}
+
+ if err := scrubFunc(); err != nil {
+ t.Fatal("cache contains inconsistencies\n\n" + err.Error())
+ }
})
}
}
@@ -560,12 +567,14 @@ func TestCache(t *testing.T) {
}()
<-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
@@ -585,6 +594,13 @@ func TestCache(t *testing.T) {
}}, nil, pkg.Checksum{}, errors.New("non-file artifact produced regular file")},
})
+ wantErrScrub := &pkg.ScrubError{
+ Errs: []error{errors.New("scrub began with pending artifacts")},
+ }
+ if err := c.Scrub(); !reflect.DeepEqual(err, wantErrScrub) {
+ t.Fatalf("Scrub: error = %#v, want %#v", err, wantErrScrub)
+ }
+
identPendingVal := reflect.ValueOf(c).Elem().FieldByName("identPending")
identPending := reflect.NewAt(
identPendingVal.Type(),
@@ -593,6 +609,74 @@ func TestCache(t *testing.T) {
notify := identPending[pkg.ID{0xff}]
go close(n)
<-notify
+ <-wCureDone
+ }, pkg.MustDecode("E4vEZKhCcL2gPZ2Tt59FS3lDng-d_2SKa2i5G_RbDfwGn6EemptFaGLPUDiOa94C")},
+
+ {"scrub", 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}),
+ ), pkg.Checksum{0xff, 0}, 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 := &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: []error{
+ pkg.InvalidFileModeError(fs.ModeSymlink),
+ base64.CorruptInputError(4),
+ base64.CorruptInputError(8),
+ &os.PathError{
+ Op: "readlink",
+ Path: base.Append("identifier", pkg.Encode(pkg.ID{0xfe, 0xff})).String(),
+ Err: syscall.EINVAL,
+ },
+ base64.CorruptInputError(4),
+ },
+ }
+ if err := c.Scrub(); !reflect.DeepEqual(err, wantErr) {
+ t.Fatalf("Scrub: error =\n%s\nwant\n%s", err, wantErr)
+ }
}, pkg.MustDecode("E4vEZKhCcL2gPZ2Tt59FS3lDng-d_2SKa2i5G_RbDfwGn6EemptFaGLPUDiOa94C")},
}
checkWithCache(t, testCases)
@@ -640,6 +724,61 @@ func TestErrors(t *testing.T) {
}
}
+func TestScrubError(t *testing.T) {
+ t.Parallel()
+
+ testCases := []struct {
+ name string
+ err pkg.ScrubError
+ want string
+ unwrap []error
+ }{
+ {"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: []error{
+ stub.UniqueError(0xcafe),
+ stub.UniqueError(0xbad),
+ stub.UniqueError(0xff),
+ },
+ }, `checksum mismatches:
+got AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA instead of CH3AiUrCCcVOjOYLaMKKK1Da78989JtfHeIsxMzWOQFiN4mrCLDYpoDxLWqJWCUN
+
+dangling identifiers:
+deadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef
+cafebabecafebabecafebabecafebabecafebabecafebabecafebabecafebabe
+
+errors during scrub:
+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 TestNew(t *testing.T) {
t.Parallel()