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) {}