github.com/moby/docker@v26.1.3+incompatible/daemon/containerd/image_delete_test.go (about) 1 package containerd 2 3 import ( 4 "context" 5 "testing" 6 7 "github.com/containerd/containerd/images" 8 "github.com/containerd/containerd/metadata" 9 "github.com/containerd/containerd/namespaces" 10 "github.com/containerd/log/logtest" 11 "github.com/docker/docker/container" 12 daemonevents "github.com/docker/docker/daemon/events" 13 dimages "github.com/docker/docker/daemon/images" 14 "gotest.tools/v3/assert" 15 is "gotest.tools/v3/assert/cmp" 16 ) 17 18 func TestImageDelete(t *testing.T) { 19 ctx := namespaces.WithNamespace(context.TODO(), "testing") 20 21 for _, tc := range []struct { 22 ref string 23 starting []images.Image 24 remaining []images.Image 25 err error 26 // TODO: Records 27 // TODO: Containers 28 // TODO: Events 29 }{ 30 { 31 ref: "nothingthere", 32 err: dimages.ErrImageDoesNotExist{Ref: nameTag("nothingthere", "latest")}, 33 }, 34 { 35 ref: "justoneimage", 36 starting: []images.Image{ 37 { 38 Name: "docker.io/library/justoneimage:latest", 39 Target: desc(10), 40 }, 41 }, 42 }, 43 { 44 ref: "justoneref", 45 starting: []images.Image{ 46 { 47 Name: "docker.io/library/justoneref:latest", 48 Target: desc(10), 49 }, 50 { 51 Name: "docker.io/library/differentrepo:latest", 52 Target: desc(10), 53 }, 54 }, 55 remaining: []images.Image{ 56 { 57 Name: "docker.io/library/differentrepo:latest", 58 Target: desc(10), 59 }, 60 }, 61 }, 62 { 63 ref: "hasdigest", 64 starting: []images.Image{ 65 { 66 Name: "docker.io/library/hasdigest:latest", 67 Target: desc(10), 68 }, 69 { 70 Name: "docker.io/library/hasdigest@" + digestFor(10).String(), 71 Target: desc(10), 72 }, 73 }, 74 }, 75 { 76 ref: digestFor(11).String(), 77 starting: []images.Image{ 78 { 79 Name: "docker.io/library/byid:latest", 80 Target: desc(11), 81 }, 82 { 83 Name: "docker.io/library/byid@" + digestFor(11).String(), 84 Target: desc(11), 85 }, 86 }, 87 }, 88 { 89 ref: "bydigest@" + digestFor(12).String(), 90 starting: []images.Image{ 91 { 92 Name: "docker.io/library/bydigest:latest", 93 Target: desc(12), 94 }, 95 { 96 Name: "docker.io/library/bydigest@" + digestFor(12).String(), 97 Target: desc(12), 98 }, 99 }, 100 }, 101 { 102 ref: "onerefoftwo", 103 starting: []images.Image{ 104 { 105 Name: "docker.io/library/onerefoftwo:latest", 106 Target: desc(12), 107 }, 108 { 109 Name: "docker.io/library/onerefoftwo:other", 110 Target: desc(12), 111 }, 112 { 113 Name: "docker.io/library/onerefoftwo@" + digestFor(12).String(), 114 Target: desc(12), 115 }, 116 }, 117 remaining: []images.Image{ 118 { 119 Name: "docker.io/library/onerefoftwo:other", 120 Target: desc(12), 121 }, 122 { 123 Name: "docker.io/library/onerefoftwo@" + digestFor(12).String(), 124 Target: desc(12), 125 }, 126 }, 127 }, 128 { 129 ref: "otherreporemaining", 130 starting: []images.Image{ 131 { 132 Name: "docker.io/library/otherreporemaining:latest", 133 Target: desc(12), 134 }, 135 { 136 Name: "docker.io/library/otherreporemaining@" + digestFor(12).String(), 137 Target: desc(12), 138 }, 139 { 140 Name: "docker.io/library/someotherrepo:latest", 141 Target: desc(12), 142 }, 143 }, 144 remaining: []images.Image{ 145 { 146 Name: "docker.io/library/someotherrepo:latest", 147 Target: desc(12), 148 }, 149 }, 150 }, 151 { 152 ref: "repoanddigest@" + digestFor(15).String(), 153 starting: []images.Image{ 154 { 155 Name: "docker.io/library/repoanddigest:latest", 156 Target: desc(15), 157 }, 158 { 159 Name: "docker.io/library/repoanddigest:latest@" + digestFor(15).String(), 160 Target: desc(15), 161 }, 162 { 163 Name: "docker.io/library/someotherrepo:latest", 164 Target: desc(15), 165 }, 166 }, 167 remaining: []images.Image{ 168 { 169 Name: "docker.io/library/someotherrepo:latest", 170 Target: desc(15), 171 }, 172 }, 173 }, 174 { 175 ref: "repoanddigestothertags@" + digestFor(15).String(), 176 starting: []images.Image{ 177 { 178 Name: "docker.io/library/repoanddigestothertags:v1", 179 Target: desc(15), 180 }, 181 { 182 Name: "docker.io/library/repoanddigestothertags:v1@" + digestFor(15).String(), 183 Target: desc(15), 184 }, 185 { 186 Name: "docker.io/library/repoanddigestothertags:v2", 187 Target: desc(15), 188 }, 189 { 190 Name: "docker.io/library/repoanddigestothertags:v2@" + digestFor(15).String(), 191 Target: desc(15), 192 }, 193 { 194 Name: "docker.io/library/someotherrepo:latest", 195 Target: desc(15), 196 }, 197 }, 198 remaining: []images.Image{ 199 { 200 Name: "docker.io/library/someotherrepo:latest", 201 Target: desc(15), 202 }, 203 }, 204 }, 205 { 206 ref: "repoanddigestzerocase@" + digestFor(16).String(), 207 starting: []images.Image{ 208 { 209 Name: "docker.io/library/someotherrepo:latest", 210 Target: desc(16), 211 }, 212 }, 213 remaining: []images.Image{ 214 { 215 Name: "docker.io/library/someotherrepo:latest", 216 Target: desc(16), 217 }, 218 }, 219 err: dimages.ErrImageDoesNotExist{Ref: nameDigest("repoanddigestzerocase", digestFor(16))}, 220 }, 221 } { 222 tc := tc 223 t.Run(tc.ref, func(t *testing.T) { 224 t.Parallel() 225 ctx := logtest.WithT(ctx, t) 226 mdb := newTestDB(ctx, t) 227 service := &ImageService{ 228 images: metadata.NewImageStore(mdb), 229 containers: emptyTestContainerStore(), 230 eventsService: daemonevents.New(), 231 } 232 for _, img := range tc.starting { 233 if _, err := service.images.Create(ctx, img); err != nil { 234 t.Fatalf("failed to create image %q: %v", img.Name, err) 235 } 236 } 237 238 _, err := service.ImageDelete(ctx, tc.ref, false, false) 239 if tc.err == nil { 240 assert.NilError(t, err) 241 } else { 242 assert.Error(t, err, tc.err.Error()) 243 } 244 245 all, err := service.images.List(ctx) 246 assert.NilError(t, err) 247 assert.Assert(t, is.Len(tc.remaining, len(all))) 248 249 // Order should match 250 for i := range all { 251 assert.Check(t, is.Equal(all[i].Name, tc.remaining[i].Name), "image[%d]", i) 252 assert.Check(t, is.Equal(all[i].Target.Digest, tc.remaining[i].Target.Digest), "image[%d]", i) 253 // TODO: Check labels too 254 } 255 }) 256 } 257 258 } 259 260 type testContainerStore struct{} 261 262 func emptyTestContainerStore() container.Store { 263 return &testContainerStore{} 264 } 265 266 func (*testContainerStore) Add(string, *container.Container) {} 267 268 func (*testContainerStore) Get(string) *container.Container { 269 return nil 270 } 271 272 func (*testContainerStore) Delete(string) {} 273 274 func (*testContainerStore) List() []*container.Container { 275 return []*container.Container{} 276 } 277 278 func (*testContainerStore) Size() int { 279 return 0 280 } 281 282 func (*testContainerStore) First(container.StoreFilter) *container.Container { 283 return nil 284 } 285 286 func (*testContainerStore) ApplyAll(container.StoreReducer) {}