Files
server-deploy/internal/aptrepo/artifacts_test.go

100 lines
2.6 KiB
Go

package aptrepo
import (
"crypto/sha256"
"fmt"
"os"
"path"
"path/filepath"
"reflect"
"testing"
"server-deploy/internal/installplan"
)
func artifactFixture(t *testing.T) (string, installplan.Lock) {
t.Helper()
dir := t.TempDir()
index := fixtureIndex()
lock, err := Resolve(fixtureRelease(index), index, "resolute", "amd64", fixturePins(), fixtureNow)
if err != nil {
t.Fatal(err)
}
for i := range lock.Packages {
p := &lock.Packages[i]
data := []byte("artifact fixture " + p.Name)
p.Size = uint64(len(data))
p.Digest = fmt.Sprintf("sha256:%x", sha256.Sum256(data))
if err := os.WriteFile(filepath.Join(dir, path.Base(p.Filename)), data, 0600); err != nil {
t.Fatal(err)
}
}
return dir, lock
}
func TestArtifactBytesAndIdentity(t *testing.T) {
dir, lock := artifactFixture(t)
before := lock
before.Packages = append([]installplan.Package(nil), lock.Packages...)
if err := verifyArtifacts(dir, lock); err != nil {
t.Fatal(err)
}
if !reflect.DeepEqual(before, lock) {
t.Fatal("lock mutated")
}
for _, p := range lock.Packages {
data, err := os.ReadFile(filepath.Join(dir, path.Base(p.Filename)))
if err != nil || string(data) != "artifact fixture "+p.Name {
t.Fatal("artifact modified")
}
}
}
func TestArtifactRejectsTamperWithoutPartialSuccess(t *testing.T) {
for _, kind := range []string{"same-size", "truncated", "extra-byte", "missing", "directory", "bad-lock", "relative-root", "extra-file"} {
t.Run(kind, func(t *testing.T) {
dir, lock := artifactFixture(t)
p := lock.Packages[4] // The last artifact must fail the whole set.
filename := filepath.Join(dir, path.Base(p.Filename))
switch kind {
case "same-size":
data := []byte("artifact fixture " + p.Name)
data[0] = 'X'
if err := os.WriteFile(filename, data, 0600); err != nil {
t.Fatal(err)
}
case "truncated":
if err := os.Truncate(filename, int64(p.Size)-1); err != nil {
t.Fatal(err)
}
case "extra-byte":
if err := os.Truncate(filename, int64(p.Size)+1); err != nil {
t.Fatal(err)
}
case "missing":
if err := os.Remove(filename); err != nil {
t.Fatal(err)
}
case "directory":
if err := os.Remove(filename); err != nil {
t.Fatal(err)
}
if err := os.Mkdir(filename, 0700); err != nil {
t.Fatal(err)
}
case "bad-lock":
lock.Packages[0].Filename = "../../secret.deb"
case "relative-root":
dir = "relative"
case "extra-file":
if err := os.WriteFile(filepath.Join(dir, "unexpected.deb"), []byte("x"), 0600); err != nil {
t.Fatal(err)
}
}
if err := verifyArtifacts(dir, lock); err == nil {
t.Fatal("invalid artifacts accepted")
}
})
}
}