Skip to content

Commit 3012f36

Browse files
committed
Run e2e tests using a custom type for inventory
1 parent 32bf6f6 commit 3012f36

File tree

6 files changed

+422
-115
lines changed

6 files changed

+422
-115
lines changed

test/e2e/apply_and_destroy_test.go

Lines changed: 5 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -9,20 +9,17 @@ import (
99

1010
. "github.com/onsi/ginkgo"
1111
. "github.com/onsi/gomega"
12-
v1 "k8s.io/api/core/v1"
1312
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
14-
"k8s.io/apimachinery/pkg/types"
1513
"sigs.k8s.io/cli-utils/pkg/apply"
1614
"sigs.k8s.io/cli-utils/pkg/apply/event"
17-
"sigs.k8s.io/cli-utils/pkg/inventory"
1815
"sigs.k8s.io/controller-runtime/pkg/client"
1916
)
2017

21-
func applyAndDestroyTest(c client.Client, inventoryName, namespaceName string) {
18+
func applyAndDestroyTest(c client.Client, invConfig InventoryConfig, inventoryName, namespaceName string) {
2219
By("Apply resources")
23-
applier := newApplier()
20+
applier := invConfig.ApplierFactoryFunc()
2421

25-
inv := inventory.WrapInventoryInfoObj(cmInventoryManifest(inventoryName, namespaceName, "test"))
22+
inv := invConfig.InvWrapperFunc(invConfig.InventoryFactoryFunc(inventoryName, namespaceName, "test"))
2623

2724
resources := []*unstructured.Unstructured{
2825
deploymentManifest(namespaceName),
@@ -55,18 +52,10 @@ func applyAndDestroyTest(c client.Client, inventoryName, namespaceName string) {
5552
Expect(err).ToNot(HaveOccurred())
5653

5754
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))
55+
invConfig.InvSizeVerifyFunc(c, inventoryName, namespaceName, 1)
6756

6857
By("Destroy resources")
69-
destroyer := newDestroyer()
58+
destroyer := invConfig.DestroyerFactoryFunc()
7059

7160
destroyerEvents := runCollectNoErr(destroyer.Run(inv))
7261
err = verifyEvents([]expEvent{

test/e2e/common_test.go

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,10 @@ package e2e
55

66
import (
77
"fmt"
8+
"strings"
89
"time"
910

11+
. "github.com/onsi/gomega"
1012
appsv1 "k8s.io/api/apps/v1"
1113
v1 "k8s.io/api/core/v1"
1214
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@@ -16,6 +18,7 @@ import (
1618
"sigs.k8s.io/cli-utils/pkg/common"
1719
"sigs.k8s.io/cli-utils/pkg/kstatus/status"
1820
"sigs.k8s.io/cli-utils/pkg/object"
21+
"sigs.k8s.io/kustomize/kyaml/yaml"
1922
)
2023

2124
func randomString(prefix string) string {
@@ -24,6 +27,26 @@ func randomString(prefix string) string {
2427
return fmt.Sprintf("%s%s", prefix, randomSuffix)
2528
}
2629

30+
func runWithNoErr(ch <-chan event.Event) {
31+
runCollectNoErr(ch)
32+
}
33+
34+
func runCollect(ch <-chan event.Event) []event.Event {
35+
var events []event.Event
36+
for e := range ch {
37+
events = append(events, e)
38+
}
39+
return events
40+
}
41+
42+
func runCollectNoErr(ch <-chan event.Event) []event.Event {
43+
events := runCollect(ch)
44+
for _, e := range events {
45+
Expect(e.Type).NotTo(Equal(event.ErrorType))
46+
}
47+
return events
48+
}
49+
2750
func cmInventoryManifest(name, namespace, id string) *unstructured.Unstructured {
2851
cm := &v1.ConfigMap{
2952
TypeMeta: metav1.TypeMeta{
@@ -47,6 +70,21 @@ func cmInventoryManifest(name, namespace, id string) *unstructured.Unstructured
4770
}
4871
}
4972

73+
func customInventoryManifest(name, namespace, id string) *unstructured.Unstructured {
74+
u := manifestToUnstructured([]byte(strings.TrimSpace(`
75+
apiVersion: cli-utils.example.io/v1alpha1
76+
kind: Inventory
77+
metadata:
78+
name: PLACEHOLDER
79+
`)))
80+
u.SetName(name)
81+
u.SetNamespace(namespace)
82+
u.SetLabels(map[string]string{
83+
common.InventoryLabel: id,
84+
})
85+
return u
86+
}
87+
5088
func deploymentManifest(namespace string) *unstructured.Unstructured {
5189
dep := &appsv1.Deployment{
5290
TypeMeta: metav1.TypeMeta{
@@ -90,6 +128,17 @@ func deploymentManifest(namespace string) *unstructured.Unstructured {
90128
}
91129
}
92130

131+
func manifestToUnstructured(manifest []byte) *unstructured.Unstructured {
132+
u := make(map[string]interface{})
133+
err := yaml.Unmarshal(manifest, &u)
134+
if err != nil {
135+
panic(err)
136+
}
137+
return &unstructured.Unstructured{
138+
Object: u,
139+
}
140+
}
141+
93142
func updateReplicas(u *unstructured.Unstructured, replicas int) *unstructured.Unstructured {
94143
err := unstructured.SetNestedField(u.Object, int64(replicas), "spec", "replicas")
95144
if err != nil {

test/e2e/crd_test.go

Lines changed: 4 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -13,18 +13,16 @@ import (
1313
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
1414
"sigs.k8s.io/cli-utils/pkg/apply"
1515
"sigs.k8s.io/cli-utils/pkg/apply/event"
16-
"sigs.k8s.io/cli-utils/pkg/inventory"
1716
"sigs.k8s.io/cli-utils/pkg/kstatus/status"
1817
"sigs.k8s.io/cli-utils/pkg/object"
1918
"sigs.k8s.io/controller-runtime/pkg/client"
20-
"sigs.k8s.io/kustomize/kyaml/yaml"
2119
)
2220

23-
func crdTest(_ client.Client, inventoryName, namespaceName string) {
21+
func crdTest(_ client.Client, invConfig InventoryConfig, inventoryName, namespaceName string) {
2422
By("apply a set of resources that includes both a crd and a cr")
25-
applier := newApplier()
23+
applier := invConfig.ApplierFactoryFunc()
2624

27-
inv := inventory.WrapInventoryInfoObj(cmInventoryManifest(inventoryName, namespaceName, "test"))
25+
inv := invConfig.InvWrapperFunc(invConfig.InventoryFactoryFunc(inventoryName, namespaceName, "test"))
2826

2927
resources := []*unstructured.Unstructured{
3028
deploymentManifest(namespaceName),
@@ -79,7 +77,7 @@ func crdTest(_ client.Client, inventoryName, namespaceName string) {
7977
Expect(err).ToNot(HaveOccurred())
8078

8179
By("destroy the resources, including the crd")
82-
destroyer := newDestroyer()
80+
destroyer := invConfig.DestroyerFactoryFunc()
8381
destroyerEvents := runCollectNoErr(destroyer.Run(inv))
8482
err = verifyEvents([]expEvent{
8583
{
@@ -161,14 +159,3 @@ metadata:
161159
spec:
162160
replicas: 4
163161
`))
164-
165-
func manifestToUnstructured(manifest []byte) *unstructured.Unstructured {
166-
u := make(map[string]interface{})
167-
err := yaml.Unmarshal(manifest, &u)
168-
if err != nil {
169-
panic(err)
170-
}
171-
return &unstructured.Unstructured{
172-
Object: u,
173-
}
174-
}

test/e2e/customprovider/provider.go

Lines changed: 185 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,185 @@
1+
// Copyright 2020 The Kubernetes Authors.
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
package customprovider
5+
6+
import (
7+
"strings"
8+
9+
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
10+
"k8s.io/apimachinery/pkg/runtime/schema"
11+
"k8s.io/kubectl/pkg/cmd/util"
12+
"sigs.k8s.io/cli-utils/pkg/common"
13+
"sigs.k8s.io/cli-utils/pkg/inventory"
14+
"sigs.k8s.io/cli-utils/pkg/object"
15+
"sigs.k8s.io/cli-utils/pkg/provider"
16+
)
17+
18+
var InventoryCRD = []byte(strings.TrimSpace(`
19+
apiVersion: apiextensions.k8s.io/v1
20+
kind: CustomResourceDefinition
21+
metadata:
22+
name: inventories.cli-utils.example.io
23+
spec:
24+
conversion:
25+
strategy: None
26+
group: cli-utils.example.io
27+
names:
28+
kind: Inventory
29+
listKind: InventoryList
30+
plural: inventories
31+
singular: inventory
32+
scope: Namespaced
33+
versions:
34+
- name: v1alpha1
35+
schema:
36+
openAPIV3Schema:
37+
description: Example for cli-utils e2e tests
38+
properties:
39+
apiVersion:
40+
type: string
41+
kind:
42+
type: string
43+
metadata:
44+
type: object
45+
spec:
46+
properties:
47+
inventory:
48+
items:
49+
properties:
50+
group:
51+
type: string
52+
kind:
53+
type: string
54+
name:
55+
type: string
56+
namespace:
57+
type: string
58+
required:
59+
- group
60+
- kind
61+
- name
62+
- namespace
63+
type: object
64+
type: array
65+
type: object
66+
type: object
67+
served: true
68+
storage: true
69+
subresources: {}
70+
`))
71+
72+
var InventoryGVK = schema.GroupVersionKind{
73+
Group: "cli-utils.example.io",
74+
Version: "v1alpha1",
75+
Kind: "Inventory",
76+
}
77+
78+
var _ provider.Provider = &CustomProvider{}
79+
80+
func NewCustomProvider(f util.Factory) provider.Provider {
81+
return &CustomProvider{
82+
factory: f,
83+
}
84+
}
85+
86+
type CustomProvider struct {
87+
factory util.Factory
88+
}
89+
90+
func (c *CustomProvider) Factory() util.Factory {
91+
return c.factory
92+
}
93+
94+
func (c *CustomProvider) InventoryClient() (inventory.InventoryClient, error) {
95+
return inventory.NewInventoryClient(c.factory, WrapInventoryObj, invToUnstructuredFunc)
96+
}
97+
98+
func invToUnstructuredFunc(inv inventory.InventoryInfo) *unstructured.Unstructured {
99+
switch invInfo := inv.(type) {
100+
case *InventoryCustomType:
101+
return invInfo.inv
102+
default:
103+
return nil
104+
}
105+
}
106+
107+
func WrapInventoryObj(obj *unstructured.Unstructured) inventory.Inventory {
108+
return &InventoryCustomType{inv: obj}
109+
}
110+
111+
func WrapInventoryInfoObj(obj *unstructured.Unstructured) inventory.InventoryInfo {
112+
return &InventoryCustomType{inv: obj}
113+
}
114+
115+
var _ inventory.Inventory = &InventoryCustomType{}
116+
var _ inventory.InventoryInfo = &InventoryCustomType{}
117+
118+
type InventoryCustomType struct {
119+
inv *unstructured.Unstructured
120+
}
121+
122+
func (i InventoryCustomType) Namespace() string {
123+
return i.inv.GetNamespace()
124+
}
125+
126+
func (i InventoryCustomType) Name() string {
127+
return i.inv.GetName()
128+
}
129+
130+
func (i InventoryCustomType) ID() string {
131+
labels := i.inv.GetLabels()
132+
id, found := labels[common.InventoryLabel]
133+
if !found {
134+
return ""
135+
}
136+
return id
137+
}
138+
139+
func (i InventoryCustomType) Load() ([]object.ObjMetadata, error) {
140+
var inv []object.ObjMetadata
141+
s, found, err := unstructured.NestedSlice(i.inv.Object, "spec", "inventory")
142+
if err != nil {
143+
return inv, err
144+
}
145+
if !found {
146+
return inv, nil
147+
}
148+
for _, item := range s {
149+
m := item.(map[string]interface{})
150+
namespace, _, _ := unstructured.NestedString(m, "namespace")
151+
name, _, _ := unstructured.NestedString(m, "name")
152+
group, _, _ := unstructured.NestedString(m, "group")
153+
kind, _, _ := unstructured.NestedString(m, "kind")
154+
obj, err := object.CreateObjMetadata(namespace, name, schema.GroupKind{
155+
Group: group,
156+
Kind: kind,
157+
})
158+
if err != nil {
159+
return inv, err
160+
}
161+
inv = append(inv, obj)
162+
}
163+
return inv, nil
164+
}
165+
166+
func (i InventoryCustomType) Store(objs []object.ObjMetadata) error {
167+
var inv []interface{}
168+
for _, obj := range objs {
169+
inv = append(inv, map[string]interface{}{
170+
"group": obj.GroupKind.Group,
171+
"kind": obj.GroupKind.Kind,
172+
"namespace": obj.Namespace,
173+
"name": obj.Name,
174+
})
175+
}
176+
if len(inv) > 0 {
177+
return unstructured.SetNestedSlice(i.inv.Object, inv, "spec", "inventory")
178+
}
179+
unstructured.RemoveNestedField(i.inv.Object, "spec")
180+
return nil
181+
}
182+
183+
func (i InventoryCustomType) GetObject() (*unstructured.Unstructured, error) {
184+
return i.inv, nil
185+
}

0 commit comments

Comments
 (0)