Skip to content

Commit 2ecf6a7

Browse files
Add tests for layers
1 parent a476c00 commit 2ecf6a7

File tree

2 files changed

+234
-95
lines changed

2 files changed

+234
-95
lines changed

test/extended/images/layers.go

Lines changed: 181 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,181 @@
1+
package images
2+
3+
import (
4+
"fmt"
5+
"time"
6+
7+
g "github.com/onsi/ginkgo"
8+
o "github.com/onsi/gomega"
9+
10+
kapi "k8s.io/api/core/v1"
11+
"k8s.io/apimachinery/pkg/api/errors"
12+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
13+
"k8s.io/apimachinery/pkg/util/wait"
14+
15+
buildapi "github.com/openshift/api/build/v1"
16+
imageapi "github.com/openshift/api/image/v1"
17+
buildclientset "github.com/openshift/client-go/build/clientset/versioned"
18+
imageclientset "github.com/openshift/client-go/image/clientset/versioned"
19+
exutil "github.com/openshift/origin/test/extended/util"
20+
)
21+
22+
var _ = g.Describe("[Feature:ImageLayers] Image layer subresource", func() {
23+
defer g.GinkgoRecover()
24+
var oc *exutil.CLI
25+
var ns []string
26+
27+
g.AfterEach(func() {
28+
if g.CurrentGinkgoTestDescription().Failed {
29+
for _, s := range ns {
30+
exutil.DumpPodLogsStartingWithInNamespace("", s, oc)
31+
}
32+
}
33+
})
34+
35+
oc = exutil.NewCLI("image-layers", exutil.KubeConfigPath())
36+
37+
g.It("should return layers from tagged images", func() {
38+
ns = []string{oc.Namespace()}
39+
client := imageclientset.NewForConfigOrDie(oc.UserConfig()).Image()
40+
isi, err := client.ImageStreamImports(oc.Namespace()).Create(&imageapi.ImageStreamImport{
41+
ObjectMeta: metav1.ObjectMeta{
42+
Name: "1",
43+
},
44+
Spec: imageapi.ImageStreamImportSpec{
45+
Import: true,
46+
Images: []imageapi.ImageImportSpec{
47+
{
48+
From: kapi.ObjectReference{Kind: "DockerImage", Name: "busybox:latest"},
49+
To: &kapi.LocalObjectReference{Name: "busybox"},
50+
},
51+
{
52+
From: kapi.ObjectReference{Kind: "DockerImage", Name: "mysql:latest"},
53+
To: &kapi.LocalObjectReference{Name: "mysql"},
54+
},
55+
},
56+
},
57+
})
58+
o.Expect(err).NotTo(o.HaveOccurred())
59+
o.Expect(isi.Status.Images).To(o.HaveLen(2))
60+
for _, image := range isi.Status.Images {
61+
o.Expect(image.Image).ToNot(o.BeNil(), fmt.Sprintf("image %s %#v", image.Tag, image.Status))
62+
}
63+
64+
// TODO: we may race here with the cache, if this is a problem, loop
65+
g.By("verifying that layers for imported images are correct")
66+
var busyboxLayers []string
67+
for i := 0; ; i++ {
68+
layers, err := client.ImageStreams(oc.Namespace()).Layers("1")
69+
o.Expect(err).NotTo(o.HaveOccurred())
70+
for i, image := range isi.Status.Images {
71+
l, ok := layers.Images[image.Image.Name]
72+
o.Expect(ok).To(o.BeTrue())
73+
o.Expect(len(l.Layers)).To(o.BeNumerically(">", 0))
74+
o.Expect(l.Manifest).ToNot(o.BeNil())
75+
for _, layerID := range l.Layers {
76+
o.Expect(layers.Blobs).To(o.HaveKey(layerID))
77+
o.Expect(layers.Blobs[layerID].MediaType).NotTo(o.BeEmpty())
78+
}
79+
if i == 0 {
80+
busyboxLayers = l.Layers
81+
}
82+
}
83+
if len(busyboxLayers) > 0 {
84+
break
85+
}
86+
time.Sleep(time.Second)
87+
o.Expect(i).To(o.BeNumerically("<", 10), "Timed out waiting for layers to have expected data, got\n%#v\n%#v", layers, isi.Status.Images)
88+
}
89+
90+
_, err = client.ImageStreams(oc.Namespace()).Create(&imageapi.ImageStream{
91+
ObjectMeta: metav1.ObjectMeta{
92+
Name: "output",
93+
},
94+
})
95+
o.Expect(err).NotTo(o.HaveOccurred())
96+
97+
layers, err := client.ImageStreams(oc.Namespace()).Layers("output")
98+
o.Expect(err).NotTo(o.HaveOccurred())
99+
o.Expect(layers.Images).To(o.BeEmpty())
100+
o.Expect(layers.Blobs).To(o.BeEmpty())
101+
102+
_, err = client.ImageStreams(oc.Namespace()).Layers("doesnotexist")
103+
o.Expect(err).To(o.HaveOccurred())
104+
o.Expect(errors.IsNotFound(err)).To(o.BeTrue())
105+
106+
dockerfile := `
107+
FROM a
108+
RUN mkdir -p /var/lib && echo "a" > /var/lib/file
109+
`
110+
111+
g.By("running a build based on our tagged layer")
112+
buildClient := buildclientset.NewForConfigOrDie(oc.UserConfig()).Build()
113+
_, err = buildClient.Builds(oc.Namespace()).Create(&buildapi.Build{
114+
ObjectMeta: metav1.ObjectMeta{
115+
Name: "output",
116+
},
117+
Spec: buildapi.BuildSpec{
118+
CommonSpec: buildapi.CommonSpec{
119+
Source: buildapi.BuildSource{
120+
Dockerfile: &dockerfile,
121+
},
122+
Strategy: buildapi.BuildStrategy{
123+
DockerStrategy: &buildapi.DockerBuildStrategy{
124+
From: &kapi.ObjectReference{Kind: "ImageStreamTag", Name: "1:busybox"},
125+
},
126+
},
127+
Output: buildapi.BuildOutput{
128+
To: &kapi.ObjectReference{Kind: "ImageStreamTag", Name: "output:latest"},
129+
},
130+
},
131+
},
132+
})
133+
o.Expect(err).NotTo(o.HaveOccurred())
134+
135+
newNamespace := oc.CreateProject()
136+
ns = append(ns)
137+
138+
g.By("waiting for the build to finish")
139+
var lastBuild *buildapi.Build
140+
err = wait.Poll(time.Second, time.Minute, func() (bool, error) {
141+
build, err := buildClient.Builds(oc.Namespace()).Get("output", metav1.GetOptions{})
142+
if err != nil {
143+
return false, err
144+
}
145+
o.Expect(build.Status.Phase).NotTo(o.Or(o.Equal(buildapi.BuildPhaseFailed), o.Equal(buildapi.BuildPhaseError), o.Equal(buildapi.BuildPhaseCancelled)))
146+
lastBuild = build
147+
return build.Status.Phase == buildapi.BuildPhaseComplete, nil
148+
})
149+
o.Expect(err).NotTo(o.HaveOccurred())
150+
151+
g.By("checking the layers for the built image")
152+
layers, err = client.ImageStreams(oc.Namespace()).Layers("output")
153+
o.Expect(err).NotTo(o.HaveOccurred())
154+
to := lastBuild.Status.Output.To
155+
o.Expect(to).NotTo(o.BeNil())
156+
o.Expect(layers.Images).To(o.HaveKey(to.ImageDigest))
157+
builtImageLayers := layers.Images[to.ImageDigest]
158+
o.Expect(len(builtImageLayers.Layers)).To(o.Equal(len(busyboxLayers)+1), fmt.Sprintf("%#v", layers.Images))
159+
for i := range busyboxLayers {
160+
o.Expect(busyboxLayers[i]).To(o.Equal(builtImageLayers.Layers[i]))
161+
}
162+
163+
g.By("tagging the built image into another namespace")
164+
_, err = client.ImageStreamTags(newNamespace).Create(&imageapi.ImageStreamTag{
165+
ObjectMeta: metav1.ObjectMeta{
166+
Name: "output:latest",
167+
},
168+
Tag: &imageapi.TagReference{
169+
Name: "copied",
170+
From: &kapi.ObjectReference{Kind: "ImageStreamTag", Namespace: oc.Namespace(), Name: "output:latest"},
171+
},
172+
})
173+
o.Expect(err).NotTo(o.HaveOccurred())
174+
175+
g.By("checking that the image shows up in the other namespace")
176+
layers, err = client.ImageStreams(newNamespace).Layers("output")
177+
o.Expect(err).NotTo(o.HaveOccurred())
178+
o.Expect(layers.Images).To(o.HaveKey(to.ImageDigest))
179+
o.Expect(layers.Images[to.ImageDigest]).To(o.Equal(builtImageLayers))
180+
})
181+
})

0 commit comments

Comments
 (0)