Browse code

Renamed LayerDeleter to LayerLinkDeleter

LayerDeleter suggests it is usable to delete just image layers. It is
suitable to delete image configs as well. In fact, it doesn't really
remove the layers, it just removes layer links from desired repository.
This LayerLinkDeleter is a more appropriate.

Signed-off-by: Michal Minář <miminar@redhat.com>

Michal Minář authored on 2016/09/07 22:34:23
Showing 3 changed files
... ...
@@ -233,21 +233,21 @@ func (o PruneImagesOptions) Run() error {
233 233
 
234 234
 	imageDeleter := &describingImageDeleter{w: w}
235 235
 	imageStreamDeleter := &describingImageStreamDeleter{w: w}
236
-	layerDeleter := &describingLayerDeleter{w: w}
236
+	layerLinkDeleter := &describingLayerLinkDeleter{w: w}
237 237
 	blobDeleter := &describingBlobDeleter{w: w}
238 238
 	manifestDeleter := &describingManifestDeleter{w: w}
239 239
 
240 240
 	if o.Confirm {
241 241
 		imageDeleter.delegate = prune.NewImageDeleter(o.Client.Images())
242 242
 		imageStreamDeleter.delegate = prune.NewImageStreamDeleter(o.Client)
243
-		layerDeleter.delegate = prune.NewLayerDeleter()
243
+		layerLinkDeleter.delegate = prune.NewLayerLinkDeleter()
244 244
 		blobDeleter.delegate = prune.NewBlobDeleter()
245 245
 		manifestDeleter.delegate = prune.NewManifestDeleter()
246 246
 	} else {
247 247
 		fmt.Fprintln(os.Stderr, "Dry run enabled - no modifications will be made. Add --confirm to remove images")
248 248
 	}
249 249
 
250
-	return o.Pruner.Prune(imageDeleter, imageStreamDeleter, layerDeleter, blobDeleter, manifestDeleter)
250
+	return o.Pruner.Prune(imageDeleter, imageStreamDeleter, layerLinkDeleter, blobDeleter, manifestDeleter)
251 251
 }
252 252
 
253 253
 // describingImageStreamDeleter prints information about each image stream update.
... ...
@@ -312,33 +312,32 @@ func (p *describingImageDeleter) DeleteImage(image *imageapi.Image) error {
312 312
 	return err
313 313
 }
314 314
 
315
-// describingLayerDeleter prints information about each repo layer link being
316
-// deleted. If a delegate exists, its DeleteLayer function is invoked prior to
317
-// returning.
318
-type describingLayerDeleter struct {
315
+// describingLayerLinkDeleter prints information about each repo layer link being deleted. If a delegate
316
+// exists, its DeleteLayerLink function is invoked prior to returning.
317
+type describingLayerLinkDeleter struct {
319 318
 	w             io.Writer
320
-	delegate      prune.LayerDeleter
319
+	delegate      prune.LayerLinkDeleter
321 320
 	headerPrinted bool
322 321
 }
323 322
 
324
-var _ prune.LayerDeleter = &describingLayerDeleter{}
323
+var _ prune.LayerLinkDeleter = &describingLayerLinkDeleter{}
325 324
 
326
-func (p *describingLayerDeleter) DeleteLayer(registryClient *http.Client, registryURL, repo, layer string) error {
325
+func (p *describingLayerLinkDeleter) DeleteLayerLink(registryClient *http.Client, registryURL, repo, name string) error {
327 326
 	if !p.headerPrinted {
328 327
 		p.headerPrinted = true
329 328
 		fmt.Fprintln(p.w, "\nDeleting registry repository layer links ...")
330
-		fmt.Fprintln(p.w, "REPO\tLAYER")
329
+		fmt.Fprintln(p.w, "REPO\tLAYER LINK")
331 330
 	}
332 331
 
333
-	fmt.Fprintf(p.w, "%s\t%s\n", repo, layer)
332
+	fmt.Fprintf(p.w, "%s\t%s\n", repo, name)
334 333
 
335 334
 	if p.delegate == nil {
336 335
 		return nil
337 336
 	}
338 337
 
339
-	err := p.delegate.DeleteLayer(registryClient, registryURL, repo, layer)
338
+	err := p.delegate.DeleteLayerLink(registryClient, registryURL, repo, name)
340 339
 	if err != nil {
341
-		fmt.Fprintf(os.Stderr, "error deleting repository %s layer link %s from the registry: %v\n", repo, layer, err)
340
+		fmt.Fprintf(os.Stderr, "error deleting repository %s layer link %s from the registry: %v\n", repo, name, err)
342 341
 	}
343 342
 
344 343
 	return err
... ...
@@ -72,11 +72,11 @@ type BlobDeleter interface {
72 72
 	DeleteBlob(registryClient *http.Client, registryURL, blob string) error
73 73
 }
74 74
 
75
-// LayerDeleter knows how to delete a repository layer link from the Docker registry.
76
-type LayerDeleter interface {
77
-	// DeleteLayer uses registryClient to ask the registry at registryURL to
75
+// LayerLinkDeleter knows how to delete a repository layer link from the Docker registry.
76
+type LayerLinkDeleter interface {
77
+	// DeleteLayerLink uses registryClient to ask the registry at registryURL to
78 78
 	// delete the repository layer link.
79
-	DeleteLayer(registryClient *http.Client, registryURL, repo, layer string) error
79
+	DeleteLayerLink(registryClient *http.Client, registryURL, repo, linkName string) error
80 80
 }
81 81
 
82 82
 // ManifestDeleter knows how to delete image manifest data for a repository from
... ...
@@ -130,12 +130,11 @@ type PrunerOptions struct {
130 130
 
131 131
 // Pruner knows how to prune images and layers.
132 132
 type Pruner interface {
133
-	// Prune uses imagePruner, streamPruner, layerPruner, blobPruner, and
133
+	// Prune uses imagePruner, streamPruner, layerLinkPruner, blobPruner, and
134 134
 	// manifestPruner to remove images that have been identified as candidates
135 135
 	// for pruning based on the Pruner's internal pruning algorithm.
136 136
 	// Please see NewPruner for details on the algorithm.
137
-	Prune(imagePruner ImageDeleter, streamPruner ImageStreamDeleter, layerPruner LayerDeleter,
138
-		blobPruner BlobDeleter, manifestPruner ManifestDeleter) error
137
+	Prune(imagePruner ImageDeleter, streamPruner ImageStreamDeleter, layerLinkPruner LayerLinkDeleter, blobPruner BlobDeleter, manifestPruner ManifestDeleter) error
139 138
 }
140 139
 
141 140
 // pruner is an object that knows how to prune a data set
... ...
@@ -776,10 +775,16 @@ func (p *pruner) determineRegistry(imageNodes []*imagegraph.ImageNode) (string,
776 776
 	return ref.Registry, nil
777 777
 }
778 778
 
779
-// Run identifies images eligible for pruning, invoking imagePruneFunc for each
780
-// image, and then it identifies layers eligible for pruning, invoking
781
-// layerPruneFunc for each registry URL that has layers that can be pruned.
782
-func (p *pruner) Prune(imagePruner ImageDeleter, streamPruner ImageStreamDeleter, layerPruner LayerDeleter, blobPruner BlobDeleter, manifestPruner ManifestDeleter) error {
779
+// Run identifies images eligible for pruning, invoking imagePruner for each image, and then it identifies
780
+// image layers eligible for pruning, invoking layerLinkPruner for each registry URL that has
781
+// layers that can be pruned.
782
+func (p *pruner) Prune(
783
+	imagePruner ImageDeleter,
784
+	streamPruner ImageStreamDeleter,
785
+	layerLinkPruner LayerLinkDeleter,
786
+	blobPruner BlobDeleter,
787
+	manifestPruner ManifestDeleter,
788
+) error {
783 789
 	allNodes := p.g.Nodes()
784 790
 
785 791
 	imageNodes := getImageNodes(allNodes)
... ...
@@ -804,7 +809,7 @@ func (p *pruner) Prune(imagePruner ImageDeleter, streamPruner ImageStreamDeleter
804 804
 	errs := []error{}
805 805
 
806 806
 	errs = append(errs, pruneStreams(p.g, prunableImageNodes, streamPruner)...)
807
-	errs = append(errs, pruneLayers(p.g, p.registryClient, registryURL, prunableLayers, layerPruner)...)
807
+	errs = append(errs, pruneLayers(p.g, p.registryClient, registryURL, prunableLayers, layerLinkPruner)...)
808 808
 	errs = append(errs, pruneBlobs(p.g, p.registryClient, registryURL, prunableLayers, blobPruner)...)
809 809
 	errs = append(errs, pruneManifests(p.g, p.registryClient, registryURL, prunableImageNodes, manifestPruner)...)
810 810
 
... ...
@@ -846,9 +851,15 @@ func streamLayerReferences(g graph.Graph, layerNode *imagegraph.ImageLayerNode)
846 846
 	return ret
847 847
 }
848 848
 
849
-// pruneLayers invokes layerPruner.DeleteLayer for each repository layer link to
849
+// pruneLayers invokes layerLinkDeleter.DeleteLayerLink for each repository layer link to
850 850
 // be deleted from the registry.
851
-func pruneLayers(g graph.Graph, registryClient *http.Client, registryURL string, layerNodes []*imagegraph.ImageLayerNode, layerPruner LayerDeleter) []error {
851
+func pruneLayers(
852
+	g graph.Graph,
853
+	registryClient *http.Client,
854
+	registryURL string,
855
+	layerNodes []*imagegraph.ImageLayerNode,
856
+	layerLinkDeleter LayerLinkDeleter,
857
+) []error {
852 858
 	errs := []error{}
853 859
 
854 860
 	for _, layerNode := range layerNodes {
... ...
@@ -860,7 +871,7 @@ func pruneLayers(g graph.Graph, registryClient *http.Client, registryURL string,
860 860
 			streamName := fmt.Sprintf("%s/%s", stream.Namespace, stream.Name)
861 861
 
862 862
 			glog.V(4).Infof("Pruning registry=%q, repo=%q, layer=%q", registryURL, streamName, layerNode.Layer)
863
-			if err := layerPruner.DeleteLayer(registryClient, registryURL, streamName, layerNode.Layer); err != nil {
863
+			if err := layerLinkDeleter.DeleteLayerLink(registryClient, registryURL, streamName, layerNode.Layer); err != nil {
864 864
 				errs = append(errs, fmt.Errorf("error pruning repo %q layer link %q: %v", streamName, layerNode.Layer, err))
865 865
 			}
866 866
 		}
... ...
@@ -1010,19 +1021,19 @@ func deleteFromRegistry(registryClient *http.Client, url string) error {
1010 1010
 	return err
1011 1011
 }
1012 1012
 
1013
-// layerDeleter removes a repository layer link from the registry.
1014
-type layerDeleter struct{}
1013
+// layerLinkDeleter removes a repository layer link from the registry.
1014
+type layerLinkDeleter struct{}
1015 1015
 
1016
-var _ LayerDeleter = &layerDeleter{}
1016
+var _ LayerLinkDeleter = &layerLinkDeleter{}
1017 1017
 
1018
-// NewLayerDeleter creates a new layerDeleter.
1019
-func NewLayerDeleter() LayerDeleter {
1020
-	return &layerDeleter{}
1018
+// NewLayerLinkDeleter creates a new layerLinkDeleter.
1019
+func NewLayerLinkDeleter() LayerLinkDeleter {
1020
+	return &layerLinkDeleter{}
1021 1021
 }
1022 1022
 
1023
-func (p *layerDeleter) DeleteLayer(registryClient *http.Client, registryURL, repoName, layer string) error {
1024
-	glog.V(4).Infof("Pruning registry %q, repo %q, layer %q", registryURL, repoName, layer)
1025
-	return deleteFromRegistry(registryClient, fmt.Sprintf("%s/v2/%s/blobs/%s", registryURL, repoName, layer))
1023
+func (p *layerLinkDeleter) DeleteLayerLink(registryClient *http.Client, registryURL, repoName, linkName string) error {
1024
+	glog.V(4).Infof("Pruning registry %q, repo %q, layer link %q", registryURL, repoName, linkName)
1025
+	return deleteFromRegistry(registryClient, fmt.Sprintf("%s/v2/%s/blobs/%s", registryURL, repoName, linkName))
1026 1026
 }
1027 1027
 
1028 1028
 // blobDeleter removes a blob from the registry.
... ...
@@ -372,14 +372,14 @@ func (p *fakeBlobDeleter) DeleteBlob(registryClient *http.Client, registryURL, b
372 372
 	return p.err
373 373
 }
374 374
 
375
-type fakeLayerDeleter struct {
375
+type fakeLayerLinkDeleter struct {
376 376
 	invocations sets.String
377 377
 	err         error
378 378
 }
379 379
 
380
-var _ LayerDeleter = &fakeLayerDeleter{}
380
+var _ LayerLinkDeleter = &fakeLayerLinkDeleter{}
381 381
 
382
-func (p *fakeLayerDeleter) DeleteLayer(registryClient *http.Client, registryURL, repo, layer string) error {
382
+func (p *fakeLayerLinkDeleter) DeleteLayerLink(registryClient *http.Client, registryURL, repo, layer string) error {
383 383
 	p.invocations.Insert(fmt.Sprintf("%s|%s|%s", registryURL, repo, layer))
384 384
 	return p.err
385 385
 }
... ...
@@ -404,20 +404,20 @@ func TestImagePruning(t *testing.T) {
404 404
 	registryURL := "registry"
405 405
 
406 406
 	tests := map[string]struct {
407
-		pruneOverSizeLimit     *bool
408
-		registryURLs           []string
409
-		images                 imageapi.ImageList
410
-		pods                   kapi.PodList
411
-		streams                imageapi.ImageStreamList
412
-		rcs                    kapi.ReplicationControllerList
413
-		bcs                    buildapi.BuildConfigList
414
-		builds                 buildapi.BuildList
415
-		dcs                    deployapi.DeploymentConfigList
416
-		limits                 map[string][]*kapi.LimitRange
417
-		expectedImageDeletions []string
418
-		expectedStreamUpdates  []string
419
-		expectedLayerDeletions []string
420
-		expectedBlobDeletions  []string
407
+		pruneOverSizeLimit         *bool
408
+		registryURLs               []string
409
+		images                     imageapi.ImageList
410
+		pods                       kapi.PodList
411
+		streams                    imageapi.ImageStreamList
412
+		rcs                        kapi.ReplicationControllerList
413
+		bcs                        buildapi.BuildConfigList
414
+		builds                     buildapi.BuildList
415
+		dcs                        deployapi.DeploymentConfigList
416
+		limits                     map[string][]*kapi.LimitRange
417
+		expectedImageDeletions     []string
418
+		expectedStreamUpdates      []string
419
+		expectedLayerLinkDeletions []string
420
+		expectedBlobDeletions      []string
421 421
 	}{
422 422
 		"1 pod - phase pending - don't prune": {
423 423
 			images: imageList(image("id", registryURL+"/foo/bar@id")),
... ...
@@ -735,7 +735,7 @@ func TestImagePruning(t *testing.T) {
735 735
 			),
736 736
 			expectedImageDeletions: []string{"id4"},
737 737
 			expectedStreamUpdates:  []string{"foo/bar|id4"},
738
-			expectedLayerDeletions: []string{
738
+			expectedLayerLinkDeletions: []string{
739 739
 				registryURL + "|foo/bar|layer5",
740 740
 				registryURL + "|foo/bar|layer6",
741 741
 				registryURL + "|foo/bar|layer7",
... ...
@@ -852,11 +852,11 @@ func TestImagePruning(t *testing.T) {
852 852
 
853 853
 		imageDeleter := &fakeImageDeleter{invocations: sets.NewString()}
854 854
 		streamDeleter := &fakeImageStreamDeleter{invocations: sets.NewString()}
855
-		layerDeleter := &fakeLayerDeleter{invocations: sets.NewString()}
855
+		layerLinkDeleter := &fakeLayerLinkDeleter{invocations: sets.NewString()}
856 856
 		blobDeleter := &fakeBlobDeleter{invocations: sets.NewString()}
857 857
 		manifestDeleter := &fakeManifestDeleter{invocations: sets.NewString()}
858 858
 
859
-		p.Prune(imageDeleter, streamDeleter, layerDeleter, blobDeleter, manifestDeleter)
859
+		p.Prune(imageDeleter, streamDeleter, layerLinkDeleter, blobDeleter, manifestDeleter)
860 860
 
861 861
 		expectedImageDeletions := sets.NewString(test.expectedImageDeletions...)
862 862
 		if !reflect.DeepEqual(expectedImageDeletions, imageDeleter.invocations) {
... ...
@@ -868,9 +868,9 @@ func TestImagePruning(t *testing.T) {
868 868
 			t.Errorf("%s: expected stream updates %q, got %q", name, expectedStreamUpdates.List(), streamDeleter.invocations.List())
869 869
 		}
870 870
 
871
-		expectedLayerDeletions := sets.NewString(test.expectedLayerDeletions...)
872
-		if !reflect.DeepEqual(expectedLayerDeletions, layerDeleter.invocations) {
873
-			t.Errorf("%s: expected layer deletions %q, got %q", name, expectedLayerDeletions.List(), layerDeleter.invocations.List())
871
+		expectedLayerLinkDeletions := sets.NewString(test.expectedLayerLinkDeletions...)
872
+		if !reflect.DeepEqual(expectedLayerLinkDeletions, layerLinkDeleter.invocations) {
873
+			t.Errorf("%s: expected layer link deletions %q, got %q", name, expectedLayerLinkDeletions.List(), layerLinkDeleter.invocations.List())
874 874
 		}
875 875
 
876 876
 		expectedBlobDeletions := sets.NewString(test.expectedBlobDeletions...)
... ...
@@ -925,8 +925,8 @@ func TestLayerDeleter(t *testing.T) {
925 925
 		actions = append(actions, req.Method+":"+req.URL.String())
926 926
 		return &http.Response{StatusCode: http.StatusServiceUnavailable, Body: ioutil.NopCloser(bytes.NewReader([]byte{}))}, nil
927 927
 	})
928
-	layerDeleter := NewLayerDeleter()
929
-	layerDeleter.DeleteLayer(client, "registry1", "repo", "layer1")
928
+	layerLinkDeleter := NewLayerLinkDeleter()
929
+	layerLinkDeleter.DeleteLayerLink(client, "registry1", "repo", "layer1")
930 930
 
931 931
 	if !reflect.DeepEqual(actions, []string{"DELETE:https://registry1/v2/repo/blobs/layer1",
932 932
 		"DELETE:http://registry1/v2/repo/blobs/layer1"}) {
... ...
@@ -942,8 +942,8 @@ func TestNotFoundLayerDeleter(t *testing.T) {
942 942
 		actions = append(actions, req.Method+":"+req.URL.String())
943 943
 		return &http.Response{StatusCode: http.StatusNotFound, Body: ioutil.NopCloser(bytes.NewReader([]byte{}))}, nil
944 944
 	})
945
-	layerDeleter := NewLayerDeleter()
946
-	layerDeleter.DeleteLayer(client, "registry1", "repo", "layer1")
945
+	layerLinkDeleter := NewLayerLinkDeleter()
946
+	layerLinkDeleter.DeleteLayerLink(client, "registry1", "repo", "layer1")
947 947
 
948 948
 	if !reflect.DeepEqual(actions, []string{"DELETE:https://registry1/v2/repo/blobs/layer1"}) {
949 949
 		t.Errorf("Unexpected actions %v", actions)
... ...
@@ -954,12 +954,12 @@ func TestRegistryPruning(t *testing.T) {
954 954
 	flag.Lookup("v").Value.Set(fmt.Sprint(*logLevel))
955 955
 
956 956
 	tests := map[string]struct {
957
-		images                    imageapi.ImageList
958
-		streams                   imageapi.ImageStreamList
959
-		expectedLayerDeletions    sets.String
960
-		expectedBlobDeletions     sets.String
961
-		expectedManifestDeletions sets.String
962
-		pingErr                   error
957
+		images                     imageapi.ImageList
958
+		streams                    imageapi.ImageStreamList
959
+		expectedLayerLinkDeletions sets.String
960
+		expectedBlobDeletions      sets.String
961
+		expectedManifestDeletions  sets.String
962
+		pingErr                    error
963 963
 	}{
964 964
 		"layers unique to id1 pruned": {
965 965
 			images: imageList(
... ...
@@ -979,7 +979,7 @@ func TestRegistryPruning(t *testing.T) {
979 979
 					),
980 980
 				)),
981 981
 			),
982
-			expectedLayerDeletions: sets.NewString(
982
+			expectedLayerLinkDeletions: sets.NewString(
983 983
 				"registry1|foo/bar|layer1",
984 984
 				"registry1|foo/bar|layer2",
985 985
 			),
... ...
@@ -1002,16 +1002,16 @@ func TestRegistryPruning(t *testing.T) {
1002 1002
 					),
1003 1003
 				)),
1004 1004
 			),
1005
-			expectedLayerDeletions:    sets.NewString(),
1006
-			expectedBlobDeletions:     sets.NewString(),
1007
-			expectedManifestDeletions: sets.NewString(),
1005
+			expectedLayerLinkDeletions: sets.NewString(),
1006
+			expectedBlobDeletions:      sets.NewString(),
1007
+			expectedManifestDeletions:  sets.NewString(),
1008 1008
 		},
1009 1009
 		"blobs pruned when streams have already been deleted": {
1010 1010
 			images: imageList(
1011 1011
 				imageWithLayers("id1", "registry1/foo/bar@id1", "layer1", "layer2", "layer3", "layer4"),
1012 1012
 				imageWithLayers("id2", "registry1/foo/bar@id2", "layer3", "layer4", "layer5", "layer6"),
1013 1013
 			),
1014
-			expectedLayerDeletions: sets.NewString(),
1014
+			expectedLayerLinkDeletions: sets.NewString(),
1015 1015
 			expectedBlobDeletions: sets.NewString(
1016 1016
 				"registry1|layer1",
1017 1017
 				"registry1|layer2",
... ...
@@ -1040,10 +1040,10 @@ func TestRegistryPruning(t *testing.T) {
1040 1040
 					),
1041 1041
 				)),
1042 1042
 			),
1043
-			expectedLayerDeletions:    sets.NewString(),
1044
-			expectedBlobDeletions:     sets.NewString(),
1045
-			expectedManifestDeletions: sets.NewString(),
1046
-			pingErr:                   errors.New("foo"),
1043
+			expectedLayerLinkDeletions: sets.NewString(),
1044
+			expectedBlobDeletions:      sets.NewString(),
1045
+			expectedManifestDeletions:  sets.NewString(),
1046
+			pingErr:                    errors.New("foo"),
1047 1047
 		},
1048 1048
 	}
1049 1049
 
... ...
@@ -1073,20 +1073,20 @@ func TestRegistryPruning(t *testing.T) {
1073 1073
 
1074 1074
 		imageDeleter := &fakeImageDeleter{invocations: sets.NewString()}
1075 1075
 		streamDeleter := &fakeImageStreamDeleter{invocations: sets.NewString()}
1076
-		layerDeleter := &fakeLayerDeleter{invocations: sets.NewString()}
1076
+		layerLinkDeleter := &fakeLayerLinkDeleter{invocations: sets.NewString()}
1077 1077
 		blobDeleter := &fakeBlobDeleter{invocations: sets.NewString()}
1078 1078
 		manifestDeleter := &fakeManifestDeleter{invocations: sets.NewString()}
1079 1079
 
1080
-		p.Prune(imageDeleter, streamDeleter, layerDeleter, blobDeleter, manifestDeleter)
1080
+		p.Prune(imageDeleter, streamDeleter, layerLinkDeleter, blobDeleter, manifestDeleter)
1081 1081
 
1082
-		if !reflect.DeepEqual(test.expectedLayerDeletions, layerDeleter.invocations) {
1083
-			t.Errorf("%s: expected layer deletions %#v, got %#v", name, test.expectedLayerDeletions, layerDeleter.invocations)
1082
+		if !reflect.DeepEqual(test.expectedLayerLinkDeletions, layerLinkDeleter.invocations) {
1083
+			t.Errorf("%s: expected layer link deletions %#v, got %#v", name, test.expectedLayerLinkDeletions.List(), layerLinkDeleter.invocations.List())
1084 1084
 		}
1085 1085
 		if !reflect.DeepEqual(test.expectedBlobDeletions, blobDeleter.invocations) {
1086
-			t.Errorf("%s: expected blob deletions %#v, got %#v", name, test.expectedBlobDeletions, blobDeleter.invocations)
1086
+			t.Errorf("%s: expected blob deletions %#v, got %#v", name, test.expectedBlobDeletions.List(), blobDeleter.invocations.List())
1087 1087
 		}
1088 1088
 		if !reflect.DeepEqual(test.expectedManifestDeletions, manifestDeleter.invocations) {
1089
-			t.Errorf("%s: expected manifest deletions %#v, got %#v", name, test.expectedManifestDeletions, manifestDeleter.invocations)
1089
+			t.Errorf("%s: expected manifest deletions %#v, got %#v", name, test.expectedManifestDeletions.List(), manifestDeleter.invocations.List())
1090 1090
 		}
1091 1091
 	}
1092 1092
 }