1
2
3
4 package e2e
5
6 import (
7 "context"
8 "fmt"
9 "time"
10
11 . "github.com/onsi/ginkgo/v2"
12 . "github.com/onsi/gomega"
13 "github.com/onsi/gomega/format"
14 v1 "k8s.io/api/core/v1"
15 "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
16 "k8s.io/klog/v2"
17 "k8s.io/kubectl/pkg/scheme"
18 "sigs.k8s.io/cli-utils/test/e2e/e2eutil"
19 "sigs.k8s.io/cli-utils/test/e2e/invconfig"
20 ctrl "sigs.k8s.io/controller-runtime"
21 "sigs.k8s.io/controller-runtime/pkg/client"
22 "sigs.k8s.io/controller-runtime/pkg/client/apiutil"
23 )
24
25 const (
26 ConfigMapTypeInvConfig = "ConfigMap"
27 CustomTypeInvConfig = "Custom"
28 )
29
30 var inventoryConfigs = map[string]invconfig.InventoryConfig{}
31 var inventoryConfigTypes = []string{
32 ConfigMapTypeInvConfig,
33 CustomTypeInvConfig,
34 }
35
36
37
38
39
40 func init() {
41 klog.InitFlags(nil)
42 klog.SetOutput(GinkgoWriter)
43 }
44
45 var defaultTestTimeout = 5 * time.Minute
46 var defaultBeforeTestTimeout = 30 * time.Second
47 var defaultAfterTestTimeout = 30 * time.Second
48
49 var c client.Client
50
51 var _ = BeforeSuite(func() {
52
53 format.MaxLength = 10000
54
55 cfg, err := ctrl.GetConfig()
56 Expect(err).NotTo(HaveOccurred())
57
58 cfg.UserAgent = e2eutil.UserAgent("test/e2e")
59
60 if e2eutil.IsFlowControlEnabled(cfg) {
61
62 klog.V(3).Infof("Client-side throttling disabled")
63 cfg.QPS = -1
64 cfg.Burst = -1
65 }
66
67 inventoryConfigs[ConfigMapTypeInvConfig] = invconfig.NewConfigMapTypeInvConfig(cfg)
68 inventoryConfigs[CustomTypeInvConfig] = invconfig.NewCustomTypeInvConfig(cfg)
69
70 mapper, err := apiutil.NewDynamicRESTMapper(cfg)
71 Expect(err).NotTo(HaveOccurred())
72
73 c, err = client.New(cfg, client.Options{
74 Scheme: scheme.Scheme,
75 Mapper: mapper,
76 })
77 Expect(err).NotTo(HaveOccurred())
78
79 ctx, cancel := context.WithTimeout(context.Background(), defaultBeforeTestTimeout)
80 defer cancel()
81 e2eutil.CreateInventoryCRD(ctx, c)
82 Expect(ctx.Err()).To(BeNil(), "BeforeSuite context cancelled or timed out")
83 })
84
85 var _ = AfterSuite(func() {
86 ctx, cancel := context.WithTimeout(context.Background(), defaultAfterTestTimeout)
87 defer cancel()
88 if c != nil {
89
90 e2eutil.DeleteInventoryCRD(ctx, c)
91 }
92 Expect(ctx.Err()).To(BeNil(), "AfterSuite context cancelled or timed out")
93 })
94
95 var _ = Describe("E2E", func() {
96 for i := range inventoryConfigTypes {
97 invType := inventoryConfigTypes[i]
98 Context(fmt.Sprintf("Inventory%s", invType), func() {
99 var invConfig invconfig.InventoryConfig
100
101 BeforeEach(func() {
102 invConfig = inventoryConfigs[invType]
103 })
104
105 Context("Basic", func() {
106 var namespace *v1.Namespace
107 var inventoryName string
108 var ctx context.Context
109 var cancel context.CancelFunc
110
111 BeforeEach(func() {
112 ctx, cancel = context.WithTimeout(context.Background(), defaultTestTimeout)
113 inventoryName = e2eutil.RandomString("test-inv-")
114 namespace = e2eutil.CreateRandomNamespace(ctx, c)
115 })
116
117 AfterEach(func() {
118 Expect(ctx.Err()).To(BeNil(), "test context cancelled or timed out")
119 cancel()
120
121 ctx, cancel = context.WithTimeout(context.Background(), defaultAfterTestTimeout)
122 defer cancel()
123
124 fields := struct{ Namespace string }{Namespace: namespace.GetName()}
125 objs := []*unstructured.Unstructured{
126 e2eutil.ManifestToUnstructured(cr),
127 e2eutil.ManifestToUnstructured(crd),
128 e2eutil.WithNamespace(e2eutil.ManifestToUnstructured(pod1), namespace.GetName()),
129 e2eutil.WithNamespace(e2eutil.ManifestToUnstructured(pod2), namespace.GetName()),
130 e2eutil.WithNamespace(e2eutil.ManifestToUnstructured(pod3), namespace.GetName()),
131 e2eutil.TemplateToUnstructured(podATemplate, fields),
132 e2eutil.TemplateToUnstructured(podBTemplate, fields),
133 e2eutil.WithNamespace(e2eutil.ManifestToUnstructured(deployment1), namespace.GetName()),
134 e2eutil.ManifestToUnstructured(apiservice1),
135 }
136 for _, obj := range objs {
137 e2eutil.DeleteUnstructuredIfExists(ctx, c, obj)
138 }
139 e2eutil.DeleteNamespace(ctx, c, namespace)
140 })
141
142 It("ApplyDestroy", func() {
143 applyAndDestroyTest(ctx, c, invConfig, inventoryName, namespace.GetName())
144 })
145
146 It("DryRun", func() {
147 dryRunTest(ctx, c, invConfig, inventoryName, namespace.GetName())
148 })
149
150 It("EmptySet", func() {
151 emptySetTest(ctx, c, invConfig, inventoryName, namespace.GetName())
152 })
153
154 It("DeletionPrevention", func() {
155 deletionPreventionTest(ctx, c, invConfig, inventoryName, namespace.GetName())
156 })
157
158 It("CustomResource", func() {
159 crdTest(ctx, c, invConfig, inventoryName, namespace.GetName())
160 })
161
162 It("ContinueOnError", func() {
163 continueOnErrorTest(ctx, c, invConfig, inventoryName, namespace.GetName())
164 })
165
166 It("ServerSideApply", func() {
167 serversideApplyTest(ctx, c, invConfig, inventoryName, namespace.GetName())
168 })
169
170 It("DependsOn", func() {
171 dependsOnTest(ctx, c, invConfig, inventoryName, namespace.GetName())
172 })
173
174 It("ApplyTimeMutation", func() {
175 mutationTest(ctx, c, invConfig, inventoryName, namespace.GetName())
176 })
177
178 It("DependencyFilter", func() {
179 dependencyFilterTest(ctx, c, invConfig, inventoryName, namespace.GetName())
180 })
181
182 It("LocalNamespacesFilter", func() {
183 namespaceFilterTest(ctx, c, invConfig, inventoryName, namespace.GetName())
184 })
185
186 It("PruneRetrievalError", func() {
187 pruneRetrieveErrorTest(ctx, c, invConfig, inventoryName, namespace.GetName())
188 })
189
190 It("ReconciliationFailure", func() {
191 reconciliationFailed(ctx, invConfig, inventoryName, namespace.GetName())
192 })
193
194 It("ReconciliationTimeout", func() {
195 reconciliationTimeout(ctx, invConfig, inventoryName, namespace.GetName())
196 })
197
198 It("SkipInvalid", func() {
199 skipInvalidTest(ctx, c, invConfig, inventoryName, namespace.GetName())
200 })
201
202 It("ExitEarly", func() {
203 exitEarlyTest(ctx, c, invConfig, inventoryName, namespace.GetName())
204 })
205 })
206
207 Context("InventoryPolicy", func() {
208 var namespace *v1.Namespace
209 var ctx context.Context
210 var cancel context.CancelFunc
211
212 BeforeEach(func() {
213 ctx, cancel = context.WithTimeout(context.Background(), defaultTestTimeout)
214 namespace = e2eutil.CreateRandomNamespace(ctx, c)
215 })
216
217 AfterEach(func() {
218 Expect(ctx.Err()).To(BeNil(), "test context cancelled or timed out")
219 cancel()
220
221 ctx, cancel = context.WithTimeout(context.Background(), defaultAfterTestTimeout)
222 defer cancel()
223 e2eutil.DeleteUnstructuredIfExists(ctx, c, e2eutil.WithNamespace(e2eutil.ManifestToUnstructured(deployment1), namespace.GetName()))
224 e2eutil.DeleteNamespace(ctx, c, namespace)
225 })
226
227 It("MustMatch", func() {
228 inventoryPolicyMustMatchTest(ctx, c, invConfig, namespace.GetName())
229 })
230
231 It("AdoptIfNoInventory", func() {
232 inventoryPolicyAdoptIfNoInventoryTest(ctx, c, invConfig, namespace.GetName())
233 })
234
235 It("AdoptAll", func() {
236 inventoryPolicyAdoptAllTest(ctx, c, invConfig, namespace.GetName())
237 })
238 })
239 })
240 }
241
242 Context("NameStrategy", func() {
243 var namespace *v1.Namespace
244 var inventoryName string
245 var ctx context.Context
246 var cancel context.CancelFunc
247
248 BeforeEach(func() {
249 ctx, cancel = context.WithTimeout(context.Background(), defaultTestTimeout)
250 inventoryName = e2eutil.RandomString("test-inv-")
251 namespace = e2eutil.CreateRandomNamespace(ctx, c)
252 })
253
254 AfterEach(func() {
255 Expect(ctx.Err()).To(BeNil(), "test context cancelled or timed out")
256 cancel()
257
258 ctx, cancel = context.WithTimeout(context.Background(), defaultAfterTestTimeout)
259 defer cancel()
260 e2eutil.DeleteUnstructuredIfExists(ctx, c, e2eutil.WithNamespace(e2eutil.ManifestToUnstructured(deployment1), namespace.GetName()))
261 e2eutil.DeleteNamespace(ctx, c, namespace)
262 })
263
264 It("InventoryIDMismatch", func() {
265 applyWithExistingInvTest(ctx, c, inventoryConfigs[CustomTypeInvConfig], inventoryName, namespace.GetName())
266 })
267 })
268 })
269
View as plain text