func TestImageStreamAdmissionEvaluatorUsage(t *testing.T) {
	for _, tc := range []struct {
		name           string
		oldSpec        *imageapi.ImageStreamSpec
		oldStatus      *imageapi.ImageStreamStatus
		newSpec        *imageapi.ImageStreamSpec
		newStatus      *imageapi.ImageStreamStatus
		expectedImages int64
	}{
		{
			name:           "empty image stream",
			oldStatus:      nil,
			newStatus:      &imageapi.ImageStreamStatus{},
			expectedImages: 0,
		},

		{
			name:      "new image stream with one image",
			oldStatus: nil,
			newStatus: &imageapi.ImageStreamStatus{
				Tags: map[string]imageapi.TagEventList{
					"latest": {
						Items: []imageapi.TagEvent{
							{
								DockerImageReference: fmt.Sprintf("172.30.12.34:5000/test/is@%s", baseImageWith1LayerDigest),
								Image:                baseImageWith1LayerDigest,
							},
						},
					},
				},
			},
			expectedImages: 1,
		},

		{
			name: "no change",
			oldSpec: &imageapi.ImageStreamSpec{
				Tags: map[string]imageapi.TagReference{
					"new": {
						Name: "new",
						From: &kapi.ObjectReference{
							Kind:      "ImageStreamImage",
							Namespace: "shared",
							Name:      fmt.Sprintf("is@%s", miscImageDigest),
						},
					},
				},
			},
			oldStatus: &imageapi.ImageStreamStatus{
				Tags: map[string]imageapi.TagEventList{
					"latest": {
						Items: []imageapi.TagEvent{
							{
								DockerImageReference: fmt.Sprintf("172.30.12.34:5000/test/is@%s", baseImageWith1LayerDigest),
								Image:                baseImageWith1LayerDigest,
							},
						},
					},
				},
			},
			newSpec: &imageapi.ImageStreamSpec{
				Tags: map[string]imageapi.TagReference{
					"new": {
						Name: "new",
						From: &kapi.ObjectReference{
							Kind:      "ImageStreamImage",
							Namespace: "shared",
							Name:      fmt.Sprintf("is@%s", miscImageDigest),
						},
					},
				},
			},
			newStatus: &imageapi.ImageStreamStatus{
				Tags: map[string]imageapi.TagEventList{
					"latest": {
						Items: []imageapi.TagEvent{
							{
								DockerImageReference: fmt.Sprintf("172.30.12.34:5000/test/is@%s", baseImageWith1LayerDigest),
								Image:                baseImageWith1LayerDigest,
							},
						},
					},
				},
			},
			// misc image is already present in common is
			expectedImages: 1,
		},

		{
			name: "adding two new tags",
			oldStatus: &imageapi.ImageStreamStatus{
				Tags: map[string]imageapi.TagEventList{
					"latest": {
						Items: []imageapi.TagEvent{
							{
								DockerImageReference: fmt.Sprintf("172.30.12.34:5000/test/is@%s", baseImageWith1LayerDigest),
								Image:                baseImageWith1LayerDigest,
							},
						},
					},
				},
			},
			newStatus: &imageapi.ImageStreamStatus{
				Tags: map[string]imageapi.TagEventList{
					"latest": {
						Items: []imageapi.TagEvent{
							{
								DockerImageReference: fmt.Sprintf("172.30.12.34:5000/test/is@%s", baseImageWith1LayerDigest),
								Image:                baseImageWith1LayerDigest,
							},
						},
					},
					"foo": {
						Items: []imageapi.TagEvent{
							{
								DockerImageReference: fmt.Sprintf("172.30.12.34:5000/test/sharedlayer@%s", childImageWith2LayersDigest),
								Image:                childImageWith2LayersDigest,
							},
						},
					},
					"bar": {
						Items: []imageapi.TagEvent{
							{
								DockerImageReference: fmt.Sprintf("172.30.12.34:5000/test/sharedlayer@%s", baseImageWith2LayersDigest),
								Image:                baseImageWith2LayersDigest,
							},
						},
					},
				},
			},
			expectedImages: 3,
		},

		{
			name: "adding an item and deleting the other tag",
			oldStatus: &imageapi.ImageStreamStatus{
				Tags: map[string]imageapi.TagEventList{
					"foo": {
						Items: []imageapi.TagEvent{
							{
								DockerImageReference: fmt.Sprintf("172.30.12.34:5000/test/sharedlayer@%s", miscImageDigest),
								Image:                miscImageDigest,
							},
						},
					},
					"bar": {
						Items: []imageapi.TagEvent{
							{
								DockerImageReference: fmt.Sprintf("172.30.12.34:5000/test/sharedlayer@%s", baseImageWith2LayersDigest),
								Image:                baseImageWith2LayersDigest,
							},
						},
					},
				},
			},
			newStatus: &imageapi.ImageStreamStatus{
				Tags: map[string]imageapi.TagEventList{
					"foo": {
						Items: []imageapi.TagEvent{
							{
								DockerImageReference: fmt.Sprintf("172.30.12.34:5000/test/sharedlayer@%s", childImageWith3LayersDigest),
								Image:                childImageWith3LayersDigest,
							},
							{
								DockerImageReference: fmt.Sprintf("172.30.12.34:5000/test/sharedlayer@%s", miscImageDigest),
								Image:                miscImageDigest,
							},
						},
					},
				},
			},
			// misc image is already present in common is
			expectedImages: 1,
		},

		{
			name: "adding a tag to spec",
			oldStatus: &imageapi.ImageStreamStatus{
				Tags: map[string]imageapi.TagEventList{
					"latest": {
						Items: []imageapi.TagEvent{
							{
								DockerImageReference: fmt.Sprintf("172.30.12.34:5000/test/is@%s", baseImageWith1LayerDigest),
								Image:                baseImageWith1LayerDigest,
							},
						},
					},
				},
			},
			newSpec: &imageapi.ImageStreamSpec{
				Tags: map[string]imageapi.TagReference{
					"new": {
						Name: "new",
						From: &kapi.ObjectReference{
							Kind:      "ImageStreamImage",
							Namespace: "shared",
							Name:      fmt.Sprintf("is@%s", baseImageWith2LayersDigest),
						},
					},
				},
			},
			newStatus: &imageapi.ImageStreamStatus{
				Tags: map[string]imageapi.TagEventList{
					"latest": {
						Items: []imageapi.TagEvent{
							{
								DockerImageReference: fmt.Sprintf("172.30.12.34:5000/test/is@%s", baseImageWith1LayerDigest),
								Image:                baseImageWith1LayerDigest,
							},
						},
					},
				},
			},
			expectedImages: 2,
		},

		{
			name: "adding a tag to status already present in spec",
			oldSpec: &imageapi.ImageStreamSpec{
				Tags: map[string]imageapi.TagReference{
					"latest": {
						Name: "new",
						From: &kapi.ObjectReference{
							Kind:      "ImageStreamImage",
							Namespace: "shared",
							Name:      fmt.Sprintf("is@%s", childImageWith2LayersDigest),
						},
					},
				},
			},
			newSpec: &imageapi.ImageStreamSpec{
				Tags: map[string]imageapi.TagReference{
					"latest": {
						Name: "new",
						From: &kapi.ObjectReference{
							Kind:      "ImageStreamImage",
							Namespace: "shared",
							Name:      fmt.Sprintf("is@%s", childImageWith2LayersDigest),
						},
					},
				},
			},
			newStatus: &imageapi.ImageStreamStatus{
				Tags: map[string]imageapi.TagEventList{
					"latest": {
						Items: []imageapi.TagEvent{
							{
								DockerImageReference: fmt.Sprintf("172.30.12.34:5000/test/is@%s", baseImageWith2LayersDigest),
								Image:                childImageWith2LayersDigest,
							},
						},
					},
				},
			},
			expectedImages: 1,
		},

		{
			name: "refer to image in another namespace already present",
			newSpec: &imageapi.ImageStreamSpec{
				Tags: map[string]imageapi.TagReference{
					"misc": {
						Name: "misc",
						From: &kapi.ObjectReference{
							Kind:      "ImageStreamImage",
							Namespace: "shared",
							Name:      fmt.Sprintf("is@%s", miscImageDigest),
						},
					},
				},
			},
			expectedImages: 0,
		},

		{
			name: "refer to imagestreamimage in the same namespace",
			newSpec: &imageapi.ImageStreamSpec{
				Tags: map[string]imageapi.TagReference{
					"commonisi": {
						Name: "commonisi",
						From: &kapi.ObjectReference{
							Kind: "ImageStreamImage",
							Name: fmt.Sprintf("common@%s", miscImageDigest),
						},
					},
				},
			},
			expectedImages: 0,
		},

		{
			name: "refer to imagestreamtag in the same namespace",
			newSpec: &imageapi.ImageStreamSpec{
				Tags: map[string]imageapi.TagReference{
					"commonist": {
						Name: "commonist",
						From: &kapi.ObjectReference{
							Kind: "ImageStreamTag",
							Name: "common:misc",
						},
					},
				},
			},
			expectedImages: 0,
		},
	} {

		var newIS, oldIS *imageapi.ImageStream

		if tc.oldStatus != nil || tc.oldSpec != nil {
			oldIS = &imageapi.ImageStream{
				ObjectMeta: kapi.ObjectMeta{
					Namespace: "test",
					Name:      "is",
				},
			}
			if tc.oldSpec != nil {
				oldIS.Spec = *tc.oldSpec
			}
			if tc.oldStatus != nil {
				oldIS.Status = *tc.oldStatus
			}
		}

		if tc.newStatus != nil || tc.newSpec != nil {
			newIS = &imageapi.ImageStream{
				ObjectMeta: kapi.ObjectMeta{
					Namespace: "test",
					Name:      "is",
				},
			}
			if tc.newSpec != nil {
				newIS.Spec = *tc.newSpec
			}
			if tc.newStatus != nil {
				newIS.Status = *tc.newStatus
			}
		}

		commonIS := imageapi.ImageStream{
			ObjectMeta: kapi.ObjectMeta{
				Namespace: "test",
				Name:      "common",
			},
			Status: imageapi.ImageStreamStatus{
				Tags: map[string]imageapi.TagEventList{
					"misc": {
						Items: []imageapi.TagEvent{
							{
								DockerImageReference: fmt.Sprintf("172.30.12.34:5000/test/common@%s", miscImageDigest),
								Image:                miscImageDigest,
							},
						},
					},
				},
			},
		}
		iss := []imageapi.ImageStream{commonIS}
		if oldIS != nil {
			iss = append(iss, *oldIS)
		}

		fakeClient := &testclient.Fake{}
		fakeClient.AddReactor("get", "imagestreams", getFakeImageStreamGetHandler(t, iss...))
		fakeClient.AddReactor("list", "imagestreams", getFakeImageStreamListHandler(t, iss...))
		fakeClient.AddReactor("get", "images", getFakeImageGetHandler(t, "test"))

		evaluator := NewImageStreamAdmissionEvaluator(fakeClient)

		usage := evaluator.Usage(newIS)

		if len(usage) != len(expectedResources) {
			t.Errorf("[%s]: got unexpected number of computed resources: %d != %d", tc.name, len(usage), len(expectedResources))
		}

		expectedUsage := kapi.ResourceList{
			imageapi.ResourceImages: *resource.NewQuantity(tc.expectedImages, resource.DecimalSI),
		}

		masked := kquota.Mask(usage, expectedResources)
		if len(masked) != len(expectedUsage) {
			for k := range usage {
				if _, exists := masked[k]; !exists {
					t.Errorf("[%s]: got unexpected resource %q from Usage() method", tc.name, k)
				}
			}

			for k := range expectedUsage {
				if _, exists := masked[k]; !exists {
					t.Errorf("[%s]: expected resource %q not computed", tc.name, k)
				}
			}
		}

		for rname, expectedValue := range expectedUsage {
			if v, exists := masked[rname]; exists {
				if v.Cmp(expectedValue) != 0 {
					t.Errorf("[%s]: got unexpected usage for %q: %s != %s", tc.name, rname, v.String(), expectedValue.String())
				}
			}
		}
	}
}