Skip to content

Commit a8205d0

Browse files
committed
Add more e2e tests for inventory policy
1 parent 2103e10 commit a8205d0

File tree

4 files changed

+529
-128
lines changed

4 files changed

+529
-128
lines changed

test/e2e/apply_and_destroy_test.go

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
// Copyright 2020 The Kubernetes Authors.
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
package e2e
5+
6+
import (
7+
"context"
8+
"time"
9+
10+
. "github.com/onsi/ginkgo"
11+
. "github.com/onsi/gomega"
12+
v1 "k8s.io/api/core/v1"
13+
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
14+
"k8s.io/apimachinery/pkg/types"
15+
"sigs.k8s.io/cli-utils/pkg/apply"
16+
"sigs.k8s.io/cli-utils/pkg/apply/event"
17+
"sigs.k8s.io/cli-utils/pkg/inventory"
18+
"sigs.k8s.io/controller-runtime/pkg/client"
19+
)
20+
21+
func applyAndDestroyTest(c client.Client, inventoryName, namespaceName string) {
22+
By("Apply resources")
23+
applier := newApplier()
24+
25+
inv := inventory.WrapInventoryInfoObj(cmInventoryManifest(inventoryName, namespaceName, "test"))
26+
27+
resources := []*unstructured.Unstructured{
28+
deploymentManifest(namespaceName),
29+
}
30+
31+
applyCh := applier.Run(context.TODO(), inv, resources, apply.Options{
32+
ReconcileTimeout: 2 * time.Minute,
33+
EmitStatusEvents: true,
34+
})
35+
36+
var applierEvents []event.Event
37+
for e := range applyCh {
38+
Expect(e.Type).NotTo(Equal(event.ErrorType))
39+
applierEvents = append(applierEvents, e)
40+
}
41+
err := verifyEvents([]expEvent{
42+
{
43+
eventType: event.InitType,
44+
},
45+
{
46+
eventType: event.ApplyType,
47+
},
48+
{
49+
eventType: event.ApplyType,
50+
},
51+
{
52+
eventType: event.PruneType,
53+
},
54+
}, applierEvents)
55+
Expect(err).ToNot(HaveOccurred())
56+
57+
By("Verify inventory")
58+
var cm v1.ConfigMap
59+
err = c.Get(context.TODO(), types.NamespacedName{
60+
Name: inventoryName,
61+
Namespace: namespaceName,
62+
}, &cm)
63+
Expect(err).ToNot(HaveOccurred())
64+
65+
data := cm.Data
66+
Expect(len(data)).To(Equal(1))
67+
68+
By("Destroy resources")
69+
destroyer := newDestroyer()
70+
err = destroyer.Initialize()
71+
Expect(err).NotTo(HaveOccurred())
72+
73+
destroyCh := destroyer.Run(inv)
74+
75+
var destroyerEvents []event.Event
76+
for e := range destroyCh {
77+
Expect(e.Type).NotTo(Equal(event.ErrorType))
78+
destroyerEvents = append(destroyerEvents, e)
79+
}
80+
err = verifyEvents([]expEvent{
81+
{
82+
eventType: event.DeleteType,
83+
},
84+
{
85+
eventType: event.DeleteType,
86+
},
87+
}, destroyerEvents)
88+
Expect(err).ToNot(HaveOccurred())
89+
}

test/e2e/common_test.go

Lines changed: 166 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,166 @@
1+
// Copyright 2020 The Kubernetes Authors.
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
package e2e
5+
6+
import (
7+
"fmt"
8+
"time"
9+
10+
appsv1 "k8s.io/api/apps/v1"
11+
v1 "k8s.io/api/core/v1"
12+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
13+
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
14+
"k8s.io/apimachinery/pkg/runtime"
15+
"sigs.k8s.io/cli-utils/pkg/apply/event"
16+
"sigs.k8s.io/cli-utils/pkg/common"
17+
"sigs.k8s.io/cli-utils/pkg/object"
18+
)
19+
20+
func randomString(prefix string) string {
21+
seed := time.Now().UTC().UnixNano()
22+
randomSuffix := common.RandomStr(seed)
23+
return fmt.Sprintf("%s%s", prefix, randomSuffix)
24+
}
25+
26+
func cmInventoryManifest(name, namespace, id string) *unstructured.Unstructured {
27+
cm := &v1.ConfigMap{
28+
TypeMeta: metav1.TypeMeta{
29+
APIVersion: v1.SchemeGroupVersion.String(),
30+
Kind: "ConfigMap",
31+
},
32+
ObjectMeta: metav1.ObjectMeta{
33+
Name: name,
34+
Namespace: namespace,
35+
Labels: map[string]string{
36+
common.InventoryLabel: id,
37+
},
38+
},
39+
}
40+
u, err := runtime.DefaultUnstructuredConverter.ToUnstructured(cm)
41+
if err != nil {
42+
panic(err)
43+
}
44+
return &unstructured.Unstructured{
45+
Object: u,
46+
}
47+
}
48+
49+
func deploymentManifest(namespace string) *unstructured.Unstructured {
50+
dep := &appsv1.Deployment{
51+
TypeMeta: metav1.TypeMeta{
52+
APIVersion: appsv1.SchemeGroupVersion.String(),
53+
Kind: "Deployment",
54+
},
55+
ObjectMeta: metav1.ObjectMeta{
56+
Name: "nginx-deployment",
57+
Namespace: namespace,
58+
},
59+
Spec: appsv1.DeploymentSpec{
60+
Replicas: func() *int32 { r := int32(4); return &r }(),
61+
Selector: &metav1.LabelSelector{
62+
MatchLabels: map[string]string{
63+
"app": "nginx",
64+
},
65+
},
66+
Template: v1.PodTemplateSpec{
67+
ObjectMeta: metav1.ObjectMeta{
68+
Labels: map[string]string{
69+
"app": "nginx",
70+
},
71+
},
72+
Spec: v1.PodSpec{
73+
Containers: []v1.Container{
74+
{
75+
Name: "nginx",
76+
Image: "nginx:1.19.6",
77+
},
78+
},
79+
},
80+
},
81+
},
82+
}
83+
u, err := runtime.DefaultUnstructuredConverter.ToUnstructured(dep)
84+
if err != nil {
85+
panic(err)
86+
}
87+
return &unstructured.Unstructured{
88+
Object: u,
89+
}
90+
}
91+
92+
func updateReplicas(u *unstructured.Unstructured, replicas int) *unstructured.Unstructured {
93+
err := unstructured.SetNestedField(u.Object, int64(replicas), "spec", "replicas")
94+
if err != nil {
95+
panic(err)
96+
}
97+
return u
98+
}
99+
100+
type expEvent struct {
101+
eventType event.Type
102+
103+
applyEvent *expApplyEvent
104+
}
105+
106+
type expApplyEvent struct {
107+
applyEventType event.ApplyEventType
108+
operation event.ApplyEventOperation
109+
identifier object.ObjMetadata
110+
error error
111+
}
112+
113+
func verifyEvents(expEvents []expEvent, events []event.Event) error {
114+
expEventIndex := 0
115+
for i := range events {
116+
e := events[i]
117+
ee := expEvents[expEventIndex]
118+
if isMatch(ee, e) {
119+
expEventIndex += 1
120+
if expEventIndex >= len(expEvents) {
121+
return nil
122+
}
123+
}
124+
}
125+
return fmt.Errorf("event %s not found", expEvents[expEventIndex].eventType)
126+
}
127+
128+
var nilIdentifier = object.ObjMetadata{}
129+
130+
func isMatch(ee expEvent, e event.Event) bool {
131+
if ee.eventType != e.Type {
132+
return false
133+
}
134+
135+
// nolint:gocritic
136+
switch e.Type {
137+
case event.ApplyType:
138+
aee := ee.applyEvent
139+
if aee == nil {
140+
return true
141+
}
142+
ae := e.ApplyEvent
143+
144+
if aee.applyEventType != ae.Type {
145+
return false
146+
}
147+
148+
if aee.applyEventType == event.ApplyEventResourceUpdate {
149+
if aee.operation != ae.Operation {
150+
return false
151+
}
152+
}
153+
154+
if aee.identifier != nilIdentifier {
155+
if aee.identifier != ae.Identifier {
156+
return false
157+
}
158+
}
159+
160+
if aee.error != nil {
161+
return ae.Error != nil
162+
}
163+
return ae.Error == nil
164+
}
165+
return true
166+
}

0 commit comments

Comments
 (0)