@@ -2,6 +2,7 @@ package images
22
33import (
44 "context"
5+ "encoding/json"
56 "os"
67 "path/filepath"
78 "strings"
@@ -165,6 +166,28 @@ func TestListImages(t *testing.T) {
165166 require .NotEmpty (t , images [0 ].Digest )
166167}
167168
169+ func TestListImages_IncludesDigestOnlyImages (t * testing.T ) {
170+ dataDir := t .TempDir ()
171+ p := paths .New (dataDir )
172+ mgr , err := NewManager (p , 1 , nil )
173+ require .NoError (t , err )
174+
175+ const digestRef = "docker.io/library/alpine@sha256:029a752048e32e843bd6defe3841186fb8d19a28dae8ec287f433bb9d6d1ad85"
176+ seedReadyDigestOnlyImageMetadata (t , p , digestRef , map [string ]string {
177+ "qa" : "pr43-qa-20260323134902" ,
178+ "surface" : "image" ,
179+ })
180+
181+ images , err := mgr .ListImages (context .Background ())
182+ require .NoError (t , err )
183+ require .Len (t , images , 1 )
184+ require .Equal (t , digestRef , images [0 ].Name )
185+ require .Equal (t , map [string ]string {
186+ "qa" : "pr43-qa-20260323134902" ,
187+ "surface" : "image" ,
188+ }, map [string ]string (images [0 ].Tags ))
189+ }
190+
168191func TestGetImage (t * testing.T ) {
169192 dataDir := t .TempDir ()
170193 mgr , err := NewManager (paths .New (dataDir ), 1 , nil )
@@ -235,6 +258,27 @@ func TestDeleteImage(t *testing.T) {
235258 require .True (t , os .IsNotExist (err ), "digest directory should be deleted when orphaned" )
236259}
237260
261+ func TestDeleteImageByDigest (t * testing.T ) {
262+ dataDir := t .TempDir ()
263+ p := paths .New (dataDir )
264+ mgr , err := NewManager (p , 1 , nil )
265+ require .NoError (t , err )
266+
267+ ctx := context .Background ()
268+ const digestRef = "docker.io/library/alpine@sha256:029a752048e32e843bd6defe3841186fb8d19a28dae8ec287f433bb9d6d1ad85"
269+ seedReadyDigestOnlyImageMetadata (t , p , digestRef , map [string ]string {
270+ "qa" : "pr43-delete-20260323134902" ,
271+ })
272+
273+ err = mgr .DeleteImage (ctx , digestRef )
274+ require .NoError (t , err )
275+
276+ ref , err := ParseNormalizedRef (digestRef )
277+ require .NoError (t , err )
278+ _ , err = os .Stat (digestDir (p , ref .Repository (), ref .DigestHex ()))
279+ require .True (t , os .IsNotExist (err ), "digest directory should be deleted when deleting by digest" )
280+ }
281+
238282func TestDeleteImageNotFound (t * testing.T ) {
239283 dataDir := t .TempDir ()
240284 mgr , err := NewManager (paths .New (dataDir ), 1 , nil )
@@ -402,6 +446,38 @@ func countFiles(dir string) (int, error) {
402446 return len (entries ), nil
403447}
404448
449+ func seedReadyDigestOnlyImageMetadata (t * testing.T , p * paths.Paths , imageRef string , imageTags map [string ]string ) {
450+ t .Helper ()
451+
452+ ref , err := ParseNormalizedRef (imageRef )
453+ require .NoError (t , err )
454+ require .True (t , ref .IsDigest (), "test helper expects a digest reference" )
455+
456+ digestDirPath := p .ImageDigestDir (ref .Repository (), ref .DigestHex ())
457+ require .NoError (t , os .MkdirAll (digestDirPath , 0o755 ))
458+ require .NoError (t , os .WriteFile (p .ImageDigestPath (ref .Repository (), ref .DigestHex ()), []byte ("rootfs" ), 0o644 ))
459+
460+ meta := struct {
461+ Name string `json:"name"`
462+ Digest string `json:"digest"`
463+ Status string `json:"status"`
464+ SizeBytes int64 `json:"size_bytes"`
465+ Tags map [string ]string `json:"tags,omitempty"`
466+ CreatedAt time.Time `json:"created_at"`
467+ }{
468+ Name : imageRef ,
469+ Digest : ref .Digest (),
470+ Status : StatusReady ,
471+ SizeBytes : int64 (len ("rootfs" )),
472+ Tags : imageTags ,
473+ CreatedAt : time .Now ().UTC (),
474+ }
475+
476+ data , err := json .Marshal (meta )
477+ require .NoError (t , err )
478+ require .NoError (t , os .WriteFile (p .ImageMetadata (ref .Repository (), ref .DigestHex ()), data , 0o644 ))
479+ }
480+
405481// TestImportLocalImageFromOCICache is an integration test that simulates the full
406482// builder image import flow used by buildBuilderFromDockerfile:
407483//
0 commit comments