Skip to content

Commit 568f0e6

Browse files
committed
Add tests for the tag attestations
Adds tests for the new tag attestation. Signed-off-by: Adolfo García Veytia (Puerco) <puerco@carabiner.dev>
1 parent 9aafee1 commit 568f0e6

3 files changed

Lines changed: 154 additions & 12 deletions

File tree

pkg/attest/statement_test.go

Lines changed: 90 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,9 @@ import (
2929
"google.golang.org/protobuf/testing/protocmp"
3030
)
3131

32-
func TestCommitStatement(t *testing.T) {
32+
// newTestRepo creates an in-memory repo with the given remote configuration.
33+
func newTestRepo(t *testing.T, remoteURL string) (*git.Repository, *memory.Storage) {
34+
t.Helper()
3335
storage := memory.NewStorage()
3436
repo := &git.Repository{
3537
Storer: storage,
@@ -38,12 +40,36 @@ func TestCommitStatement(t *testing.T) {
3840
Remotes: map[string]*config.RemoteConfig{
3941
"origin": {
4042
Name: "origin",
41-
URLs: []string{"git@github.com:wlynch/gitsign.git"},
43+
URLs: []string{remoteURL},
4244
},
4345
},
4446
}); err != nil {
4547
t.Fatalf("error setting git config: %v", err)
4648
}
49+
return repo, storage
50+
}
51+
52+
// storeObject writes raw object bytes into the storage and returns the hash.
53+
func storeObject(t *testing.T, storage *memory.Storage, objType plumbing.ObjectType, raw []byte) plumbing.Hash {
54+
t.Helper()
55+
obj := storage.NewEncodedObject()
56+
obj.SetType(objType)
57+
w, err := obj.Writer()
58+
if err != nil {
59+
t.Fatalf("error getting git object writer: %v", err)
60+
}
61+
if _, err = w.Write(raw); err != nil {
62+
t.Fatalf("error writing git object: %v", err)
63+
}
64+
h, err := storage.SetEncodedObject(obj)
65+
if err != nil {
66+
t.Fatalf("error storing git object: %v", err)
67+
}
68+
return h
69+
}
70+
71+
func TestCommitStatement(t *testing.T) {
72+
repo, storage := newTestRepo(t, "git@github.com:wlynch/gitsign.git")
4773

4874
// Expect files in testdata directory:
4975
// foo.in.txt -> foo.out.json
@@ -58,24 +84,53 @@ func TestCommitStatement(t *testing.T) {
5884
if err != nil {
5985
t.Fatalf("error reading input: %v", err)
6086
}
61-
obj := storage.NewEncodedObject()
62-
obj.SetType(plumbing.CommitObject)
63-
w, err := obj.Writer()
87+
h := storeObject(t, storage, plumbing.CommitObject, raw)
88+
89+
got, err := CommitStatement(repo, "origin", h.String())
6490
if err != nil {
65-
t.Fatalf("error getting git object writer: %v", err)
91+
t.Fatalf("statement(): %v", err)
6692
}
67-
_, err = w.Write(raw)
93+
94+
wantRaw, err := os.ReadFile(fmt.Sprintf("testdata/%s.out.json", tc))
6895
if err != nil {
69-
t.Fatalf("error writing git commit: %v", err)
96+
t.Fatalf("error reading want json: %v", err)
97+
}
98+
99+
want := &intoto.Statement{}
100+
if err := protojson.Unmarshal(wantRaw, want); err != nil {
101+
t.Fatalf("error decoding want json: %v", err)
102+
}
103+
104+
if diff := cmp.Diff(want, got, protocmp.Transform()); diff != "" {
105+
t.Error(diff)
70106
}
71-
h, err := storage.SetEncodedObject(obj)
107+
})
108+
}
109+
}
110+
111+
func TestTagStatement(t *testing.T) {
112+
repo, storage := newTestRepo(t, "git@github.com:wlynch/gitsign.git")
113+
114+
// IMPORTANT: When generating new test files, use `git cat-file tag <tagname> > foo.in.txt`.
115+
for _, tc := range []string{
116+
"fulcio-tag",
117+
} {
118+
t.Run(tc, func(t *testing.T) {
119+
raw, err := os.ReadFile(fmt.Sprintf("testdata/%s.in.txt", tc))
72120
if err != nil {
73-
t.Fatalf("error storing git commit: %v", err)
121+
t.Fatalf("error reading input: %v", err)
74122
}
123+
h := storeObject(t, storage, plumbing.TagObject, raw)
75124

76-
got, err := CommitStatement(repo, "origin", h.String())
125+
// Create a tag reference pointing to the stored tag object.
126+
tagRef := plumbing.NewHashReference(plumbing.NewTagReferenceName(tc), h)
127+
if err := storage.SetReference(tagRef); err != nil {
128+
t.Fatalf("error setting tag reference: %v", err)
129+
}
130+
131+
got, err := TagStatement(repo, "origin", tc)
77132
if err != nil {
78-
t.Fatalf("statement(): %v", err)
133+
t.Fatalf("TagStatement(): %v", err)
79134
}
80135

81136
wantRaw, err := os.ReadFile(fmt.Sprintf("testdata/%s.out.json", tc))
@@ -94,3 +149,26 @@ func TestCommitStatement(t *testing.T) {
94149
})
95150
}
96151
}
152+
153+
func TestTagStatementLightweight(t *testing.T) {
154+
repo, storage := newTestRepo(t, "git@github.com:wlynch/gitsign.git")
155+
156+
// Store a commit object so the lightweight tag has something to point to.
157+
raw, err := os.ReadFile("testdata/fulcio-cert.in.txt")
158+
if err != nil {
159+
t.Fatalf("error reading input: %v", err)
160+
}
161+
commitHash := storeObject(t, storage, plumbing.CommitObject, raw)
162+
163+
// Create a lightweight tag (ref pointing directly at the commit).
164+
tagRef := plumbing.NewHashReference(plumbing.NewTagReferenceName("lightweight"), commitHash)
165+
if err := storage.SetReference(tagRef); err != nil {
166+
t.Fatalf("error setting tag reference: %v", err)
167+
}
168+
169+
// Lightweight tags are not annotated, so TagStatement should return an error.
170+
_, err = TagStatement(repo, "origin", "lightweight")
171+
if err == nil {
172+
t.Fatal("expected error for lightweight tag, got nil")
173+
}
174+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
object dd51a25b4f9fa103ca6f5cdca4183fa15cb3e627
2+
type commit
3+
tag v0.14.0
4+
tagger Billy Lynch <billy@chainguard.dev> 1769622626 -0500
5+
6+
v0.14.0
7+
-----BEGIN SIGNED MESSAGE-----
8+
MIIELwYJKoZIhvcNAQcCoIIEIDCCBBwCAQExDTALBglghkgBZQMEAgEwCwYJKoZI
9+
hvcNAQcBoIIC0TCCAs0wggJToAMCAQICFHX4oNpDnR17SVpco2KLU+Lk4cGZMAoG
10+
CCqGSM49BAMDMDcxFTATBgNVBAoTDHNpZ3N0b3JlLmRldjEeMBwGA1UEAxMVc2ln
11+
c3RvcmUtaW50ZXJtZWRpYXRlMB4XDTI2MDEyODE3NTAyN1oXDTI2MDEyODE4MDAy
12+
N1owADBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABDEEyshqZPYaNaswQ7HfxREu
13+
3CKrEAAvf7bwQgWu93i4uN44VzJsW6dxV+7LBmUYP1wqyW03EthlUerMenbRtOOj
14+
ggFyMIIBbjAOBgNVHQ8BAf8EBAMCB4AwEwYDVR0lBAwwCgYIKwYBBQUHAwMwHQYD
15+
VR0OBBYEFIX1lG52urQX/ffvXImAVZvAjznAMB8GA1UdIwQYMBaAFN/T6c9WJBGW
16+
+ajY6ShVosYuGGQ/MCIGA1UdEQEB/wQYMBaBFGJpbGx5QGNoYWluZ3VhcmQuZGV2
17+
MCkGCisGAQQBg78wAQEEG2h0dHBzOi8vYWNjb3VudHMuZ29vZ2xlLmNvbTArBgor
18+
BgEEAYO/MAEIBB0MG2h0dHBzOi8vYWNjb3VudHMuZ29vZ2xlLmNvbTCBigYKKwYB
19+
BAHWeQIEAgR8BHoAeAB2AN09MGrGxxEyYxkeHJlnNwKiSl643jyt/4eKcoAvKe6O
20+
AAABnAW6ZYYAAAQDAEcwRQIhAKyeO8OIbBRLAq0PBuJpDlL9m8bbUO97Scd5PFQ6
21+
bi1ZAiBNHC+SXcQ9tLzlPzNvKRniiKZ1UJuzX+LMt9eUYTd/1DAKBggqhkjOPQQD
22+
AwNoADBlAjEAquQWpoWTaWwNYU8aXRUxJTzoUsxM7Tdjgzz7mEcDsz5KD55nsFnJ
23+
xos0TZXioYoPAjBsmOdaJIh0zIzOj/N6B4VQr+txDqEovFwzcnDFmz2A8Y8CVUR1
24+
ZOb6gAGmo7RDzYAxggEkMIIBIAIBATBPMDcxFTATBgNVBAoTDHNpZ3N0b3JlLmRl
25+
djEeMBwGA1UEAxMVc2lnc3RvcmUtaW50ZXJtZWRpYXRlAhR1+KDaQ50de0laXKNi
26+
i1Pi5OHBmTALBglghkgBZQMEAgGgaTAYBgkqhkiG9w0BCQMxCwYJKoZIhvcNAQcB
27+
MBwGCSqGSIb3DQEJBTEPFw0yNjAxMjgxNzUwMjdaMC8GCSqGSIb3DQEJBDEiBCC5
28+
j6i3ZTOxHPKTcA0Ub1oUtIxfJJ7xfbneBgnUJwakqTAKBggqhkjOPQQDAgRGMEQC
29+
IB8DIWqlTucRQEeSNpuEqUeVXhn4/DlYshDfwn5upV09AiB4gZOaUDX70vYSBup4
30+
luA5kuL+Nx6AafURfB2WxO8Krw==
31+
-----END SIGNED MESSAGE-----
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
{
2+
"type": "https://in-toto.io/Statement/v1",
3+
"predicateType": "https://gitsign.sigstore.dev/predicate/tag/v0.1",
4+
"subject": [
5+
{
6+
"name": "git@github.com:wlynch/gitsign.git",
7+
"digest": {
8+
"sha1": "59b806d0c7932446ca9375b36ea3d421cc673224",
9+
"gitTag": "59b806d0c7932446ca9375b36ea3d421cc673224"
10+
}
11+
}
12+
],
13+
"predicate": {
14+
"source": {
15+
"object": "dd51a25b4f9fa103ca6f5cdca4183fa15cb3e627",
16+
"object_type": "commit",
17+
"tag": "v0.14.0",
18+
"tagger": {
19+
"name": "Billy Lynch",
20+
"email": "billy@chainguard.dev",
21+
"date": "2026-01-28T17:50:26Z"
22+
},
23+
"message": "v0.14.0\n"
24+
},
25+
"signature": "-----BEGIN SIGNED MESSAGE-----\nMIIELwYJKoZIhvcNAQcCoIIEIDCCBBwCAQExDTALBglghkgBZQMEAgEwCwYJKoZI\nhvcNAQcBoIIC0TCCAs0wggJToAMCAQICFHX4oNpDnR17SVpco2KLU+Lk4cGZMAoG\nCCqGSM49BAMDMDcxFTATBgNVBAoTDHNpZ3N0b3JlLmRldjEeMBwGA1UEAxMVc2ln\nc3RvcmUtaW50ZXJtZWRpYXRlMB4XDTI2MDEyODE3NTAyN1oXDTI2MDEyODE4MDAy\nN1owADBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABDEEyshqZPYaNaswQ7HfxREu\n3CKrEAAvf7bwQgWu93i4uN44VzJsW6dxV+7LBmUYP1wqyW03EthlUerMenbRtOOj\nggFyMIIBbjAOBgNVHQ8BAf8EBAMCB4AwEwYDVR0lBAwwCgYIKwYBBQUHAwMwHQYD\nVR0OBBYEFIX1lG52urQX/ffvXImAVZvAjznAMB8GA1UdIwQYMBaAFN/T6c9WJBGW\n+ajY6ShVosYuGGQ/MCIGA1UdEQEB/wQYMBaBFGJpbGx5QGNoYWluZ3VhcmQuZGV2\nMCkGCisGAQQBg78wAQEEG2h0dHBzOi8vYWNjb3VudHMuZ29vZ2xlLmNvbTArBgor\nBgEEAYO/MAEIBB0MG2h0dHBzOi8vYWNjb3VudHMuZ29vZ2xlLmNvbTCBigYKKwYB\nBAHWeQIEAgR8BHoAeAB2AN09MGrGxxEyYxkeHJlnNwKiSl643jyt/4eKcoAvKe6O\nAAABnAW6ZYYAAAQDAEcwRQIhAKyeO8OIbBRLAq0PBuJpDlL9m8bbUO97Scd5PFQ6\nbi1ZAiBNHC+SXcQ9tLzlPzNvKRniiKZ1UJuzX+LMt9eUYTd/1DAKBggqhkjOPQQD\nAwNoADBlAjEAquQWpoWTaWwNYU8aXRUxJTzoUsxM7Tdjgzz7mEcDsz5KD55nsFnJ\nxos0TZXioYoPAjBsmOdaJIh0zIzOj/N6B4VQr+txDqEovFwzcnDFmz2A8Y8CVUR1\nZOb6gAGmo7RDzYAxggEkMIIBIAIBATBPMDcxFTATBgNVBAoTDHNpZ3N0b3JlLmRl\ndjEeMBwGA1UEAxMVc2lnc3RvcmUtaW50ZXJtZWRpYXRlAhR1+KDaQ50de0laXKNi\ni1Pi5OHBmTALBglghkgBZQMEAgGgaTAYBgkqhkiG9w0BCQMxCwYJKoZIhvcNAQcB\nMBwGCSqGSIb3DQEJBTEPFw0yNjAxMjgxNzUwMjdaMC8GCSqGSIb3DQEJBDEiBCC5\nj6i3ZTOxHPKTcA0Ub1oUtIxfJJ7xfbneBgnUJwakqTAKBggqhkjOPQQDAgRGMEQC\nIB8DIWqlTucRQEeSNpuEqUeVXhn4/DlYshDfwn5upV09AiB4gZOaUDX70vYSBup4\nluA5kuL+Nx6AafURfB2WxO8Krw==\n-----END SIGNED MESSAGE-----\n",
26+
"signer_info": [
27+
{
28+
"attributes": "MWkwGAYJKoZIhvcNAQkDMQsGCSqGSIb3DQEHATAcBgkqhkiG9w0BCQUxDxcNMjYwMTI4MTc1MDI3WjAvBgkqhkiG9w0BCQQxIgQguY+ot2UzsRzyk3ANFG9aFLSMXySe8X253gYJ1CcGpKk=",
29+
"certificate": "-----BEGIN CERTIFICATE-----\nMIICzTCCAlOgAwIBAgIUdfig2kOdHXtJWlyjYotT4uThwZkwCgYIKoZIzj0EAwMw\nNzEVMBMGA1UEChMMc2lnc3RvcmUuZGV2MR4wHAYDVQQDExVzaWdzdG9yZS1pbnRl\ncm1lZGlhdGUwHhcNMjYwMTI4MTc1MDI3WhcNMjYwMTI4MTgwMDI3WjAAMFkwEwYH\nKoZIzj0CAQYIKoZIzj0DAQcDQgAEMQTKyGpk9ho1qzBDsd/FES7cIqsQAC9/tvBC\nBa73eLi43jhXMmxbp3FX7ssGZRg/XCrJbTcS2GVR6sx6dtG046OCAXIwggFuMA4G\nA1UdDwEB/wQEAwIHgDATBgNVHSUEDDAKBggrBgEFBQcDAzAdBgNVHQ4EFgQUhfWU\nbna6tBf99+9ciYBVm8CPOcAwHwYDVR0jBBgwFoAU39Ppz1YkEZb5qNjpKFWixi4Y\nZD8wIgYDVR0RAQH/BBgwFoEUYmlsbHlAY2hhaW5ndWFyZC5kZXYwKQYKKwYBBAGD\nvzABAQQbaHR0cHM6Ly9hY2NvdW50cy5nb29nbGUuY29tMCsGCisGAQQBg78wAQgE\nHQwbaHR0cHM6Ly9hY2NvdW50cy5nb29nbGUuY29tMIGKBgorBgEEAdZ5AgQCBHwE\negB4AHYA3T0wasbHETJjGR4cmWc3AqJKXrjePK3/h4pygC8p7o4AAAGcBbplhgAA\nBAMARzBFAiEArJ47w4hsFEsCrQ8G4mkOUv2bxttQ73tJx3k8VDpuLVkCIE0cL5Jd\nxD20vOU/M28pGeKIpnVQm7Nf4sy315RhN3/UMAoGCCqGSM49BAMDA2gAMGUCMQCq\n5BamhZNpbA1hTxpdFTElPOhSzEztN2ODPPuYRwOzPkoPnmewWcnGizRNleKhig8C\nMGyY51okiHTMjM6P83oHhVCv63EOoSi8XDNycMWbPYDxjwJVRHVk5vqAAaajtEPN\ngA==\n-----END CERTIFICATE-----\n"
30+
}
31+
]
32+
}
33+
}

0 commit comments

Comments
 (0)