func TestImageStreamEvaluatorUsageStats(t *testing.T) { for _, tc := range []struct { name string iss []imageapi.ImageStream namespace string expectedISCount int64 }{ { name: "no image stream", iss: []imageapi.ImageStream{}, namespace: "test", expectedISCount: 0, }, { name: "one image stream", iss: []imageapi.ImageStream{ { ObjectMeta: kapi.ObjectMeta{ Namespace: "test", Name: "onetag", }, }, }, namespace: "test", expectedISCount: 1, }, { name: "two image streams", iss: []imageapi.ImageStream{ { ObjectMeta: kapi.ObjectMeta{ Namespace: "test", Name: "is1", }, }, { ObjectMeta: kapi.ObjectMeta{ Namespace: "test", Name: "is2", }, }, }, namespace: "test", expectedISCount: 2, }, { name: "two image streams in different namespaces", iss: []imageapi.ImageStream{ { ObjectMeta: kapi.ObjectMeta{ Namespace: "test", Name: "is1", }, }, { ObjectMeta: kapi.ObjectMeta{ Namespace: "other", Name: "is2", }, }, }, namespace: "test", expectedISCount: 1, }, } { fakeClient := &testclient.Fake{} fakeClient.AddReactor("list", "imagestreams", imagetest.GetFakeImageStreamListHandler(t, tc.iss...)) evaluator := NewImageStreamEvaluator(fakeClient) stats, err := evaluator.UsageStats(kquota.UsageStatsOptions{Namespace: tc.namespace}) if err != nil { t.Errorf("[%s]: could not get usage stats for namespace %q: %v", tc.name, tc.namespace, err) continue } expectedUsage := imagetest.ExpectedResourceListFor(tc.expectedISCount) expectedResources := kquota.ResourceNames(expectedUsage) if len(stats.Used) != len(expectedResources) { t.Errorf("[%s]: got unexpected number of computed resources: %d != %d", tc.name, len(stats.Used), len(expectedResources)) } masked := kquota.Mask(stats.Used, expectedResources) if len(masked) != len(expectedResources) { for k := range stats.Used { if _, exists := masked[k]; !exists { t.Errorf("[%s]: got unexpected resource %q from Usage() method", tc.name, k) } } for _, k := range expectedResources { 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()) } } } } }
func TestImageStreamTagEvaluatorUsage(t *testing.T) { for _, tc := range []struct { name string iss []imageapi.ImageStream ist imageapi.ImageStreamTag expectedISCount int64 }{ { name: "empty image stream", iss: []imageapi.ImageStream{ { ObjectMeta: kapi.ObjectMeta{ Namespace: "test", Name: "is", }, Status: imageapi.ImageStreamStatus{}, }, }, ist: imageapi.ImageStreamTag{ ObjectMeta: kapi.ObjectMeta{ Namespace: "test", Name: "is:dest", }, Tag: &imageapi.TagReference{ Name: "dest", From: &kapi.ObjectReference{ Kind: "ImageStreamImage", Namespace: "shared", Name: "is@" + imagetest.MiscImageDigest, }, }, }, expectedISCount: 0, }, { name: "no image stream", ist: imageapi.ImageStreamTag{ ObjectMeta: kapi.ObjectMeta{ Namespace: "test", Name: "is:dest", }, Tag: &imageapi.TagReference{ Name: "dest", From: &kapi.ObjectReference{ Kind: "ImageStreamImage", Namespace: "shared", Name: "is@" + imagetest.MiscImageDigest, }, }, }, expectedISCount: 1, }, { name: "no image stream using image stream tag", ist: imageapi.ImageStreamTag{ ObjectMeta: kapi.ObjectMeta{ Namespace: "test", Name: "is:dest", }, Tag: &imageapi.TagReference{ Name: "dest", From: &kapi.ObjectReference{ Kind: "ImageStreamTag", Namespace: "shared", Name: "is:latest", }, }, }, expectedISCount: 1, }, { name: "no tag given", ist: imageapi.ImageStreamTag{ ObjectMeta: kapi.ObjectMeta{ Namespace: "test", Name: "is:dest", }, Image: imageapi.Image{ ObjectMeta: kapi.ObjectMeta{ Name: imagetest.MiscImageDigest, Annotations: map[string]string{imageapi.ManagedByOpenShiftAnnotation: "true"}, }, DockerImageReference: imagetest.MakeDockerImageReference("shared", "is", imagetest.MiscImageDigest), DockerImageManifest: imagetest.MiscImageDigest, }, }, expectedISCount: 1, }, { name: "missing from", ist: imageapi.ImageStreamTag{ ObjectMeta: kapi.ObjectMeta{ Namespace: "test", Name: "is:dest", }, Tag: &imageapi.TagReference{ Name: "dest", }, Image: imageapi.Image{ ObjectMeta: kapi.ObjectMeta{ Name: imagetest.MiscImageDigest, Annotations: map[string]string{imageapi.ManagedByOpenShiftAnnotation: "true"}, }, DockerImageReference: imagetest.MakeDockerImageReference("test", "dest", imagetest.MiscImageDigest), DockerImageManifest: imagetest.MiscImage, }, }, expectedISCount: 1, }, { name: "update existing tag", iss: []imageapi.ImageStream{ { ObjectMeta: kapi.ObjectMeta{ Namespace: "test", Name: "havingtag", }, Status: imageapi.ImageStreamStatus{ Tags: map[string]imageapi.TagEventList{ "latest": { Items: []imageapi.TagEvent{ { DockerImageReference: imagetest.MakeDockerImageReference("test", "havingtag", imagetest.BaseImageWith1LayerDigest), Image: imagetest.BaseImageWith1LayerDigest, }, }, }, }, }, }, }, ist: imageapi.ImageStreamTag{ ObjectMeta: kapi.ObjectMeta{ Namespace: "test", Name: "havingtag:latest", }, Tag: &imageapi.TagReference{ Name: "latest", From: &kapi.ObjectReference{ Kind: "ImageStreamImage", Namespace: "shared", Name: "is@" + imagetest.ChildImageWith2LayersDigest, }, }, }, expectedISCount: 0, }, { name: "add a new tag with 2 image streams", iss: []imageapi.ImageStream{ { ObjectMeta: kapi.ObjectMeta{ Namespace: "test", Name: "is", }, }, { ObjectMeta: kapi.ObjectMeta{ Namespace: "other", Name: "is2", }, }, }, ist: imageapi.ImageStreamTag{ ObjectMeta: kapi.ObjectMeta{ Namespace: "test", Name: "destis:latest", }, Tag: &imageapi.TagReference{ Name: "latest", From: &kapi.ObjectReference{ Kind: "ImageStreamTag", Namespace: "other", Name: "is2:latest", }, }, }, expectedISCount: 1, }, } { fakeClient := &testclient.Fake{} fakeClient.AddReactor("get", "imagestreams", imagetest.GetFakeImageStreamGetHandler(t, tc.iss...)) evaluator := NewImageStreamTagEvaluator(fakeClient, fakeClient) usage := evaluator.Usage(&tc.ist) expectedUsage := imagetest.ExpectedResourceListFor(tc.expectedISCount) expectedResources := kquota.ResourceNames(expectedUsage) if len(usage) != len(expectedUsage) { t.Errorf("[%s]: got unexpected number of computed resources: %d != %d", tc.name, len(usage), len(expectedResources)) } 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()) } } } } }
func TestImageStreamEvaluatorUsage(t *testing.T) { for _, tc := range []struct { name string iss []imageapi.ImageStream expectedISCount int64 }{ { name: "new image stream", expectedISCount: 1, }, { name: "image stream already exists", iss: []imageapi.ImageStream{ { ObjectMeta: kapi.ObjectMeta{ Namespace: "test", Name: "is", }, }, }, expectedISCount: 1, }, { name: "new image stream in non-empty project", iss: []imageapi.ImageStream{ { ObjectMeta: kapi.ObjectMeta{ Namespace: "test", Name: "existing", }, }, }, expectedISCount: 1, }, } { newIS := &imageapi.ImageStream{ ObjectMeta: kapi.ObjectMeta{ Namespace: "test", Name: "is", }, } fakeClient := &testclient.Fake{} fakeClient.AddReactor("get", "imagestreams", imagetest.GetFakeImageStreamGetHandler(t, tc.iss...)) evaluator := NewImageStreamEvaluator(fakeClient) usage := evaluator.Usage(newIS) expectedUsage := imagetest.ExpectedResourceListFor(tc.expectedISCount) expectedResources := kquota.ResourceNames(expectedUsage) if len(usage) != len(expectedResources) { t.Errorf("[%s]: got unexpected number of computed resources: %d != %d", tc.name, len(usage), len(expectedResources)) } 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()) } } } } }
func TestImageStreamImportEvaluatorUsage(t *testing.T) { for _, tc := range []struct { name string iss []imageapi.ImageStream isiSpec imageapi.ImageStreamImportSpec expectedISCount int64 }{ { name: "nothing to import", isiSpec: imageapi.ImageStreamImportSpec{ Import: true, }, }, { name: "dry run", isiSpec: imageapi.ImageStreamImportSpec{ Import: false, Repository: &imageapi.RepositoryImportSpec{ From: kapi.ObjectReference{ Kind: "DockerImage", Name: "docker.io/library/fedora", }, }, }, }, { name: "wrong from kind", isiSpec: imageapi.ImageStreamImportSpec{ Import: true, Repository: &imageapi.RepositoryImportSpec{ From: kapi.ObjectReference{ Kind: "ImageStreamImage", Namespace: "test", Name: imageapi.MakeImageStreamImageName("someis", imagetest.BaseImageWith1LayerDigest), }, }, }, expectedISCount: 1, }, { name: "import from repository to empty project", isiSpec: imageapi.ImageStreamImportSpec{ Import: true, Repository: &imageapi.RepositoryImportSpec{ From: kapi.ObjectReference{ Kind: "DockerImage", Name: "docker.io/fedora", }, }, }, expectedISCount: 1, }, { name: "import from repository to existing image stream", iss: []imageapi.ImageStream{ { ObjectMeta: kapi.ObjectMeta{ Namespace: "test", Name: "havingtag", }, }, { ObjectMeta: kapi.ObjectMeta{ Namespace: "test", Name: "is", }, }, }, isiSpec: imageapi.ImageStreamImportSpec{ Import: true, Repository: &imageapi.RepositoryImportSpec{ From: kapi.ObjectReference{ Kind: "DockerImage", Name: "docker.io/fedora", }, }, }, // target image stream already exists expectedISCount: 0, }, { name: "import from repository to non-empty project", iss: []imageapi.ImageStream{ { ObjectMeta: kapi.ObjectMeta{ Namespace: "test", Name: "spec", }, }, }, isiSpec: imageapi.ImageStreamImportSpec{ Import: true, Repository: &imageapi.RepositoryImportSpec{ From: kapi.ObjectReference{ Kind: "DockerImage", Name: "docker.io/library/fedora", }, }, }, expectedISCount: 1, }, { name: "import images", isiSpec: imageapi.ImageStreamImportSpec{ Import: true, Images: []imageapi.ImageImportSpec{ { From: kapi.ObjectReference{ Kind: "DockerImage", Name: "docker.io/library/fedora:f23", }, }, }, }, expectedISCount: 1, }, { name: "import image and repository", isiSpec: imageapi.ImageStreamImportSpec{ Import: true, Images: []imageapi.ImageImportSpec{ { From: kapi.ObjectReference{ Kind: "DockerImage", Name: "docker.io/centos:latest", }, }, }, Repository: &imageapi.RepositoryImportSpec{ From: kapi.ObjectReference{ Kind: "DockerImage", Name: "docker.io/library/fedora", }, }, }, expectedISCount: 1, }, } { fakeClient := &testclient.Fake{} fakeClient.AddReactor("get", "imagestreams", imagetest.GetFakeImageStreamGetHandler(t, tc.iss...)) evaluator := NewImageStreamImportEvaluator(fakeClient) isi := &imageapi.ImageStreamImport{ ObjectMeta: kapi.ObjectMeta{ Namespace: "test", Name: "is", }, Spec: tc.isiSpec, } usage := evaluator.Usage(isi) expectedUsage := imagetest.ExpectedResourceListFor(tc.expectedISCount) expectedResources := kquota.ResourceNames(expectedUsage) if len(usage) != len(expectedResources) { t.Errorf("[%s]: got unexpected number of computed resources: %d != %d", tc.name, len(usage), len(expectedResources)) } 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()) } } } } }