Skip to content

Commit 2a7d476

Browse files
committed
Set up E2e tests with kind for the apply library
1 parent b9ff655 commit 2a7d476

File tree

5 files changed

+237
-13
lines changed

5 files changed

+237
-13
lines changed

Makefile

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,11 @@ lint:
4646
$(GOPATH)/bin/golangci-lint run ./...
4747

4848
test:
49-
go test -race -cover ./...
49+
go test -race -cover ./cmd/... ./pkg/...
50+
51+
test-e2e: $(MYGOBIN)/ginkgo $(MYGOBIN)/kind
52+
kind delete cluster --name=cli-utils-e2e && kind create cluster --name=cli-utils-e2e
53+
$(GOPATH)/bin/ginkgo ./test/e2e/...
5054

5155
vet:
5256
go vet ./...
@@ -62,6 +66,9 @@ build-with-race-detector:
6266
.PHONY: verify-kapply-e2e
6367
verify-kapply-e2e: test-examples-e2e-kapply
6468

69+
$(MYGOBIN)/ginkgo:
70+
go get github.com/onsi/ginkgo/[email protected]
71+
6572
$(MYGOBIN)/mdrip:
6673
go install github.com/monopole/mdrip
6774

@@ -77,14 +84,7 @@ test-examples-e2e-kapply: $(MYGOBIN)/mdrip $(MYGOBIN)/kind
7784
)
7885

7986
$(MYGOBIN)/kind:
80-
( \
81-
set -e; \
82-
d=$(shell mktemp -d); cd $$d; \
83-
wget -O ./kind https://github.com/kubernetes-sigs/kind/releases/download/v0.7.0/kind-$(shell uname)-amd64; \
84-
chmod +x ./kind; \
85-
mv ./kind $(MYGOBIN); \
86-
rm -rf $$d; \
87-
)
87+
go get sigs.k8s.io/[email protected]
8888

8989
.PHONY: nuke
9090
nuke: clean

go.mod

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@ require (
99
github.com/google/uuid v1.1.1
1010
github.com/kr/text v0.2.0 // indirect
1111
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e // indirect
12-
github.com/onsi/ginkgo v1.13.0 // indirect
12+
github.com/onsi/ginkgo v1.14.2
13+
github.com/onsi/gomega v1.10.1
1314
github.com/pkg/errors v0.9.1
1415
github.com/sirupsen/logrus v1.6.0 // indirect
1516
github.com/spf13/cobra v1.0.0

go.sum

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -340,8 +340,8 @@ github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB
340340
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
341341
github.com/onsi/ginkgo v1.11.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
342342
github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk=
343-
github.com/onsi/ginkgo v1.13.0 h1:M76yO2HkZASFjXL0HSoZJ1AYEmQxNJmY41Jx1zNUq1Y=
344-
github.com/onsi/ginkgo v1.13.0/go.mod h1:+REjRxOmWfHCjfv9TTWB1jD1Frx4XydAD3zm1lskyM0=
343+
github.com/onsi/ginkgo v1.14.2 h1:8mVmC9kjFFmA8H4pKMUhcblgifdkOIXPvbhN1T36q1M=
344+
github.com/onsi/ginkgo v1.14.2/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY=
345345
github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA=
346346
github.com/onsi/gomega v1.7.0 h1:XPnZz8VVBHjVsy1vzJmRwIcSwiUO+JFfrv/xGiigmME=
347347
github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
@@ -388,7 +388,6 @@ github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFR
388388
github.com/russross/blackfriday v1.5.2 h1:HyvC0ARfnZBqnXwABFeSZHpKvJHJJfPz81GNueLj0oo=
389389
github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
390390
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
391-
github.com/sclevine/agouti v3.0.0+incompatible/go.mod h1:b4WX9W9L1sfQKXeJf1mUTLZKJ48R1S7H23Ji7oFO5Bw=
392391
github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
393392
github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0=
394393
github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=

test/e2e/e2e_suite_test.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// Copyright 2020 The Kubernetes Authors.
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
package e2e
5+
6+
import (
7+
"testing"
8+
9+
. "github.com/onsi/ginkgo"
10+
. "github.com/onsi/gomega"
11+
)
12+
13+
func TestE2e(t *testing.T) {
14+
RegisterFailHandler(Fail)
15+
RunSpecs(t, "E2e Suite")
16+
}

test/e2e/e2e_test.go

Lines changed: 208 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,208 @@
1+
// Copyright 2020 The Kubernetes Authors.
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
package e2e
5+
6+
import (
7+
"context"
8+
"fmt"
9+
"time"
10+
11+
. "github.com/onsi/ginkgo"
12+
. "github.com/onsi/gomega"
13+
appsv1 "k8s.io/api/apps/v1"
14+
v1 "k8s.io/api/core/v1"
15+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
16+
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
17+
"k8s.io/apimachinery/pkg/runtime"
18+
"k8s.io/apimachinery/pkg/types"
19+
"k8s.io/cli-runtime/pkg/genericclioptions"
20+
"k8s.io/kubectl/pkg/cmd/util"
21+
"k8s.io/kubectl/pkg/scheme"
22+
"sigs.k8s.io/cli-utils/pkg/apply"
23+
"sigs.k8s.io/cli-utils/pkg/apply/event"
24+
"sigs.k8s.io/cli-utils/pkg/common"
25+
"sigs.k8s.io/cli-utils/pkg/inventory"
26+
"sigs.k8s.io/cli-utils/pkg/provider"
27+
"sigs.k8s.io/cli-utils/pkg/util/factory"
28+
ctrl "sigs.k8s.io/controller-runtime"
29+
"sigs.k8s.io/controller-runtime/pkg/client"
30+
"sigs.k8s.io/controller-runtime/pkg/client/apiutil"
31+
)
32+
33+
var _ = Describe("Applier", func() {
34+
35+
var c client.Client
36+
37+
BeforeSuite(func() {
38+
cfg, err := ctrl.GetConfig()
39+
Expect(err).NotTo(HaveOccurred())
40+
41+
mapper, err := apiutil.NewDynamicRESTMapper(cfg)
42+
Expect(err).NotTo(HaveOccurred())
43+
44+
c, err = client.New(cfg, client.Options{
45+
Scheme: scheme.Scheme,
46+
Mapper: mapper,
47+
})
48+
Expect(err).NotTo(HaveOccurred())
49+
})
50+
51+
var namespaceName string
52+
var namespace *v1.Namespace
53+
var inventoryName string
54+
55+
BeforeEach(func() {
56+
namespaceName = randomString("e2e-test-")
57+
namespace = &v1.Namespace{
58+
TypeMeta: metav1.TypeMeta{
59+
APIVersion: v1.SchemeGroupVersion.String(),
60+
Kind: "Namespace",
61+
},
62+
ObjectMeta: metav1.ObjectMeta{
63+
Name: namespaceName,
64+
},
65+
}
66+
inventoryName = randomString("test-inv-")
67+
err := c.Create(context.TODO(), namespace)
68+
Expect(err).ToNot(HaveOccurred())
69+
})
70+
71+
AfterEach(func() {
72+
err := c.Delete(context.TODO(), namespace)
73+
Expect(err).ToNot(HaveOccurred())
74+
})
75+
76+
It("Apply and destroy", func() {
77+
By("Apply resources")
78+
applier := newApplier()
79+
err := applier.Initialize()
80+
Expect(err).NotTo(HaveOccurred())
81+
82+
inv := inventory.WrapInventoryInfoObj(inventoryManifest(inventoryName, namespaceName))
83+
84+
resources := []*unstructured.Unstructured{
85+
deploymentManifest(namespaceName),
86+
}
87+
88+
applyCh := applier.Run(context.TODO(), inv, resources, apply.Options{
89+
ReconcileTimeout: 2 * time.Minute,
90+
EmitStatusEvents: true,
91+
})
92+
93+
for e := range applyCh {
94+
Expect(e.Type).NotTo(Equal(event.ErrorType))
95+
}
96+
97+
By("Verify inventory")
98+
var cm v1.ConfigMap
99+
err = c.Get(context.TODO(), types.NamespacedName{
100+
Name: inventoryName,
101+
Namespace: namespaceName,
102+
}, &cm)
103+
Expect(err).ToNot(HaveOccurred())
104+
105+
data := cm.Data
106+
Expect(len(data)).To(Equal(1))
107+
108+
By("Destroy resources")
109+
destroyer := newDestroyer()
110+
err = destroyer.Initialize()
111+
Expect(err).NotTo(HaveOccurred())
112+
113+
destroyCh := destroyer.Run(inv)
114+
115+
for e := range destroyCh {
116+
Expect(e.Type).NotTo(Equal(event.ErrorType))
117+
}
118+
})
119+
})
120+
121+
func inventoryManifest(name, namespace string) *unstructured.Unstructured {
122+
cm := &v1.ConfigMap{
123+
TypeMeta: metav1.TypeMeta{
124+
APIVersion: v1.SchemeGroupVersion.String(),
125+
Kind: "ConfigMap",
126+
},
127+
ObjectMeta: metav1.ObjectMeta{
128+
Name: name,
129+
Namespace: namespace,
130+
Labels: map[string]string{
131+
common.InventoryLabel: "test",
132+
},
133+
},
134+
}
135+
u, err := runtime.DefaultUnstructuredConverter.ToUnstructured(cm)
136+
if err != nil {
137+
panic(err)
138+
}
139+
return &unstructured.Unstructured{
140+
Object: u,
141+
}
142+
}
143+
144+
func deploymentManifest(namespace string) *unstructured.Unstructured {
145+
dep := &appsv1.Deployment{
146+
TypeMeta: metav1.TypeMeta{
147+
APIVersion: appsv1.SchemeGroupVersion.String(),
148+
Kind: "Deployment",
149+
},
150+
ObjectMeta: metav1.ObjectMeta{
151+
Name: "nginx-deployment",
152+
Namespace: namespace,
153+
},
154+
Spec: appsv1.DeploymentSpec{
155+
Replicas: func() *int32 { r := int32(4); return &r }(),
156+
Selector: &metav1.LabelSelector{
157+
MatchLabels: map[string]string{
158+
"app": "nginx",
159+
},
160+
},
161+
Template: v1.PodTemplateSpec{
162+
ObjectMeta: metav1.ObjectMeta{
163+
Labels: map[string]string{
164+
"app": "nginx",
165+
},
166+
},
167+
Spec: v1.PodSpec{
168+
Containers: []v1.Container{
169+
{
170+
Name: "nginx",
171+
Image: "nginx:1.19.6",
172+
},
173+
},
174+
},
175+
},
176+
},
177+
}
178+
u, err := runtime.DefaultUnstructuredConverter.ToUnstructured(dep)
179+
if err != nil {
180+
panic(err)
181+
}
182+
return &unstructured.Unstructured{
183+
Object: u,
184+
}
185+
}
186+
187+
func newApplier() *apply.Applier {
188+
return apply.NewApplier(newProvider())
189+
}
190+
191+
func newDestroyer() *apply.Destroyer {
192+
return apply.NewDestroyer(newProvider())
193+
}
194+
195+
func newProvider() provider.Provider {
196+
kubeConfigFlags := genericclioptions.NewConfigFlags(true).WithDeprecatedPasswordFlag()
197+
matchVersionKubeConfigFlags := util.NewMatchVersionFlags(&factory.CachingRESTClientGetter{
198+
Delegate: kubeConfigFlags,
199+
})
200+
f := util.NewFactory(matchVersionKubeConfigFlags)
201+
return provider.NewProvider(f)
202+
}
203+
204+
func randomString(prefix string) string {
205+
seed := time.Now().UTC().UnixNano()
206+
randomSuffix := common.RandomStr(seed)
207+
return fmt.Sprintf("%s%s", prefix, randomSuffix)
208+
}

0 commit comments

Comments
 (0)