Skip to content

Commit 9a09936

Browse files
Add tests for layers
1 parent b904906 commit 9a09936

File tree

2 files changed

+235
-95
lines changed

2 files changed

+235
-95
lines changed

test/extended/images/layers.go

Lines changed: 182 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,182 @@
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.Layers[image.Image.Name]
72+
o.Expect(ok).To(o.BeTrue())
73+
o.Expect(len(l)).To(o.BeNumerically(">", 0))
74+
for _, layerID := range l {
75+
o.Expect(layers.Blobs).To(o.HaveKey(layerID))
76+
o.Expect(layers.Blobs[layerID].MediaType).NotTo(o.BeEmpty())
77+
}
78+
if i == 0 {
79+
busyboxLayers = l
80+
}
81+
o.Expect(layers.Manifests).To(o.HaveKey(image.Image.Name))
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.Layers).To(o.BeEmpty())
100+
o.Expect(layers.Blobs).To(o.BeEmpty())
101+
o.Expect(layers.Manifests).To(o.BeEmpty())
102+
103+
_, err = client.ImageStreams(oc.Namespace()).Layers("doesnotexist")
104+
o.Expect(err).To(o.HaveOccurred())
105+
o.Expect(errors.IsNotFound(err)).To(o.BeTrue())
106+
107+
dockerfile := `
108+
FROM a
109+
RUN mkdir -p /var/lib && echo "a" > /var/lib/file
110+
`
111+
112+
g.By("running a build based on our tagged layer")
113+
buildClient := buildclientset.NewForConfigOrDie(oc.UserConfig()).Build()
114+
_, err = buildClient.Builds(oc.Namespace()).Create(&buildapi.Build{
115+
ObjectMeta: metav1.ObjectMeta{
116+
Name: "output",
117+
},
118+
Spec: buildapi.BuildSpec{
119+
CommonSpec: buildapi.CommonSpec{
120+
Source: buildapi.BuildSource{
121+
Dockerfile: &dockerfile,
122+
},
123+
Strategy: buildapi.BuildStrategy{
124+
DockerStrategy: &buildapi.DockerBuildStrategy{
125+
From: &kapi.ObjectReference{Kind: "ImageStreamTag", Name: "1:busybox"},
126+
},
127+
},
128+
Output: buildapi.BuildOutput{
129+
To: &kapi.ObjectReference{Kind: "ImageStreamTag", Name: "output:latest"},
130+
},
131+
},
132+
},
133+
})
134+
o.Expect(err).NotTo(o.HaveOccurred())
135+
136+
newNamespace := oc.CreateProject()
137+
ns = append(ns)
138+
139+
g.By("waiting for the build to finish")
140+
var lastBuild *buildapi.Build
141+
err = wait.Poll(time.Second, time.Minute, func() (bool, error) {
142+
build, err := buildClient.Builds(oc.Namespace()).Get("output", metav1.GetOptions{})
143+
if err != nil {
144+
return false, err
145+
}
146+
o.Expect(build.Status.Phase).NotTo(o.Or(o.Equal(buildapi.BuildPhaseFailed), o.Equal(buildapi.BuildPhaseError), o.Equal(buildapi.BuildPhaseCancelled)))
147+
lastBuild = build
148+
return build.Status.Phase == buildapi.BuildPhaseComplete, nil
149+
})
150+
o.Expect(err).NotTo(o.HaveOccurred())
151+
152+
g.By("checking the layers for the built image")
153+
layers, err = client.ImageStreams(oc.Namespace()).Layers("output")
154+
o.Expect(err).NotTo(o.HaveOccurred())
155+
to := lastBuild.Status.Output.To
156+
o.Expect(to).NotTo(o.BeNil())
157+
o.Expect(layers.Layers).To(o.HaveKey(to.ImageDigest))
158+
builtImageLayers := layers.Layers[to.ImageDigest]
159+
o.Expect(len(builtImageLayers)).To(o.Equal(len(busyboxLayers)+1), fmt.Sprintf("%#v", layers.Layers))
160+
for i := range busyboxLayers {
161+
o.Expect(busyboxLayers[i]).To(o.Equal(builtImageLayers[i]))
162+
}
163+
164+
g.By("tagging the built image into another namespace")
165+
_, err = client.ImageStreamTags(newNamespace).Create(&imageapi.ImageStreamTag{
166+
ObjectMeta: metav1.ObjectMeta{
167+
Name: "output:latest",
168+
},
169+
Tag: &imageapi.TagReference{
170+
Name: "copied",
171+
From: &kapi.ObjectReference{Kind: "ImageStreamTag", Namespace: oc.Namespace(), Name: "output:latest"},
172+
},
173+
})
174+
o.Expect(err).NotTo(o.HaveOccurred())
175+
176+
g.By("checking that the image shows up in the other namespace")
177+
layers, err = client.ImageStreams(newNamespace).Layers("output")
178+
o.Expect(err).NotTo(o.HaveOccurred())
179+
o.Expect(layers.Layers).To(o.HaveKey(to.ImageDigest))
180+
o.Expect(layers.Layers[to.ImageDigest]).To(o.Equal(builtImageLayers))
181+
})
182+
})

0 commit comments

Comments
 (0)