124 lines
3.5 KiB
Go
124 lines
3.5 KiB
Go
// SPDX-License-Identifier: AGPL-3.0-only
|
|
|
|
package releaseartifact
|
|
|
|
import (
|
|
"os"
|
|
"path/filepath"
|
|
"strings"
|
|
"testing"
|
|
)
|
|
|
|
func TestEvidenceManifestBindsReviewedContentAndIdentity(t *testing.T) {
|
|
directory := evidenceFixture(t)
|
|
identity := evidenceIdentity()
|
|
checksum, err := WriteEvidenceManifest(directory, identity)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if !digestPattern.MatchString(checksum) {
|
|
t.Fatalf("manifest checksum = %q", checksum)
|
|
}
|
|
if err := VerifyEvidenceManifest(directory, identity); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
path := filepath.Join(directory, requiredEvidenceFiles[0])
|
|
if err := os.WriteFile(path, []byte("# Changed after review\n"), 0o600); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if err := VerifyEvidenceManifest(directory, identity); err == nil {
|
|
t.Fatal("changed evidence bytes were accepted")
|
|
}
|
|
}
|
|
|
|
func TestEvidenceManifestRejectsCandidateMismatchAndUnknownFields(t *testing.T) {
|
|
t.Run("candidate identity", func(t *testing.T) {
|
|
directory := evidenceFixture(t)
|
|
identity := evidenceIdentity()
|
|
if _, err := WriteEvidenceManifest(directory, identity); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
identity.Commit = strings.Repeat("d", 40)
|
|
if err := VerifyEvidenceManifest(directory, identity); err == nil {
|
|
t.Fatal("mismatched candidate was accepted")
|
|
}
|
|
})
|
|
|
|
t.Run("unknown manifest field", func(t *testing.T) {
|
|
directory := evidenceFixture(t)
|
|
identity := evidenceIdentity()
|
|
if _, err := WriteEvidenceManifest(directory, identity); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
path := filepath.Join(directory, evidenceManifestName)
|
|
contents, err := os.ReadFile(path)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
contents = []byte(strings.Replace(string(contents), `"files":`, `"unexpected": true, "files":`, 1))
|
|
if err := os.Chmod(path, 0o600); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if err := os.WriteFile(path, contents, 0o600); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if err := VerifyEvidenceManifest(directory, identity); err == nil {
|
|
t.Fatal("unknown manifest field was accepted")
|
|
}
|
|
})
|
|
}
|
|
|
|
func TestEvidenceManifestRejectsSymlinkAndPlaceholderDocuments(t *testing.T) {
|
|
t.Run("symlink", func(t *testing.T) {
|
|
directory := evidenceFixture(t)
|
|
name := requiredEvidenceFiles[0]
|
|
path := filepath.Join(directory, name)
|
|
target := filepath.Join(directory, "target.md")
|
|
if err := os.WriteFile(target, []byte("# Target\n"), 0o600); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if err := os.Remove(path); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if err := os.Symlink(target, path); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if _, err := WriteEvidenceManifest(directory, evidenceIdentity()); err == nil {
|
|
t.Fatal("symlinked evidence was accepted")
|
|
}
|
|
})
|
|
|
|
t.Run("placeholder", func(t *testing.T) {
|
|
directory := evidenceFixture(t)
|
|
if err := os.WriteFile(filepath.Join(directory, requiredEvidenceFiles[0]), []byte("not reviewed\n"), 0o600); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if _, err := WriteEvidenceManifest(directory, evidenceIdentity()); err == nil {
|
|
t.Fatal("heading-free placeholder was accepted")
|
|
}
|
|
})
|
|
}
|
|
|
|
func evidenceFixture(t *testing.T) string {
|
|
t.Helper()
|
|
directory := t.TempDir()
|
|
for _, name := range requiredEvidenceFiles {
|
|
if err := os.WriteFile(filepath.Join(directory, name), []byte("# Reviewed "+name+"\n\nExact bounded evidence.\n"), 0o600); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
}
|
|
return directory
|
|
}
|
|
|
|
func evidenceIdentity() EvidenceIdentity {
|
|
return EvidenceIdentity{
|
|
Repository: "gamertan/sandwich-hime",
|
|
Version: "v1.0.0-rc.1",
|
|
Commit: strings.Repeat("a", 40),
|
|
Tree: strings.Repeat("b", 40),
|
|
ReviewedBy: "release operator",
|
|
ReviewedAt: "2026-08-23T18:00:00Z",
|
|
}
|
|
}
|