From 982fab3ecd7ba1d4a5f4dc1c48c08836a8224175 Mon Sep 17 00:00:00 2001 From: Manfred Liiv Date: Mon, 16 Jan 2023 17:17:36 +0000 Subject: [PATCH] add failing currentUIDFilter e2e test demonstrating https://github.com/kubernetes-sigs/cli-utils/issues/613 --- test/e2e/current_uid_filter_test.go | 107 ++++++++++++++++++++++++++++ test/e2e/e2e_test.go | 4 ++ 2 files changed, 111 insertions(+) create mode 100644 test/e2e/current_uid_filter_test.go diff --git a/test/e2e/current_uid_filter_test.go b/test/e2e/current_uid_filter_test.go new file mode 100644 index 00000000..1e34f106 --- /dev/null +++ b/test/e2e/current_uid_filter_test.go @@ -0,0 +1,107 @@ +// Copyright 2021 The Kubernetes Authors. +// SPDX-License-Identifier: Apache-2.0 + +package e2e + +import ( + "context" + "fmt" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + "sigs.k8s.io/cli-utils/pkg/apply" + "sigs.k8s.io/cli-utils/test/e2e/e2eutil" + "sigs.k8s.io/cli-utils/test/e2e/invconfig" + "sigs.k8s.io/controller-runtime/pkg/client" +) + +const v1EventTemplate = ` +apiVersion: v1 +involvedObject: + apiVersion: v1 + kind: Pod + name: pod + namespace: {{.Namespace}} +kind: Event +message: Back-off restarting failed container +metadata: + name: test + namespace: {{.Namespace}} +reason: BackOff +type: Warning +` + +const v1EventsEventTemplate = ` +apiVersion: events.k8s.io/v1 +eventTime: null +kind: Event +metadata: + name: test + namespace: {{.Namespace}} +note: Back-off restarting failed container +reason: BackOff +regarding: + apiVersion: v1 + kind: Pod + name: pod + namespace: {{.Namespace}} +type: Warning +` + +// Note this tests the scenario of "cohabitating" k8s objects (an object available via multiple apiGroups), but having the same UID. +// As of k8s 1.25 an example of such "cohabitating" kinds is Event which is available via both "v1" and "events.k8s.io/v1". +// When the user upgrades from one apiGroup to the other: +// - should not result in object being pruned +// - object pruning should be skipped due to CurrentUIDFilter (even though a diff is found) +// - inventory should not double-track the object i.e. we should hold reference only to the object with the groupKind that was most recently applied +func currentUIDFilterTest(ctx context.Context, c client.Client, invConfig invconfig.InventoryConfig, inventoryName, namespaceName string) { + applier := invConfig.ApplierFactoryFunc() + inventoryID := fmt.Sprintf("%s-%s", inventoryName, namespaceName) + inventoryInfo := invconfig.CreateInventoryInfo(invConfig, inventoryName, namespaceName, inventoryID) + + templateFields := struct{ Namespace string }{Namespace: namespaceName} + v1Event := e2eutil.TemplateToUnstructured(v1EventTemplate, templateFields) + v1EventsEvent := e2eutil.TemplateToUnstructured(v1EventsEventTemplate, templateFields) + + By("Apply resource with deprecated groupKind") + resources := []*unstructured.Unstructured{ + v1Event, + } + err := e2eutil.Run(applier.Run(ctx, inventoryInfo, resources, apply.ApplierOptions{})) + Expect(err).ToNot(HaveOccurred()) + + By("Verify resource available in both apiGroups") + objDeprecated := e2eutil.AssertUnstructuredExists(ctx, c, v1Event) + objNew := e2eutil.AssertUnstructuredExists(ctx, c, v1EventsEvent) + + By("Verify UID matches for cohabitating resources") + uid := objDeprecated.GetUID() + Expect(uid).ToNot(BeEmpty()) + Expect(objDeprecated.GetUID()).To(Equal(objNew.GetUID())) + + By("Verify only 1 item in inventory") + invConfig.InvSizeVerifyFunc(ctx, c, inventoryName, namespaceName, inventoryID, 1, 1) + + By("Apply resource with new groupKind") + resources = []*unstructured.Unstructured{ + v1EventsEvent, + } + err = e2eutil.Run(applier.Run(ctx, inventoryInfo, resources, apply.ApplierOptions{})) + Expect(err).ToNot(HaveOccurred()) + + By("Verify resource still available in both apiGroups") + objDeprecated = e2eutil.AssertUnstructuredExists(ctx, c, v1Event) + objNew = e2eutil.AssertUnstructuredExists(ctx, c, v1EventsEvent) + + By("Verify UID matches for cohabitating resources") + Expect(objDeprecated.GetUID()).To(Equal(objNew.GetUID())) + + By("Verify UID matches the UID from previous apply") + Expect(objDeprecated.GetUID()).To(Equal(uid)) + + By("Verify still only 1 item in inventory") + // Expecting statusCount=2: + // one object applied and one prune skipped + invConfig.InvSizeVerifyFunc(ctx, c, inventoryName, namespaceName, inventoryID, 1, 2) +} diff --git a/test/e2e/e2e_test.go b/test/e2e/e2e_test.go index 1ad8ce80..b28e3f57 100644 --- a/test/e2e/e2e_test.go +++ b/test/e2e/e2e_test.go @@ -183,6 +183,10 @@ var _ = Describe("E2E", func() { namespaceFilterTest(ctx, c, invConfig, inventoryName, namespace.GetName()) }) + It("CurrentUIDFilter", func() { + currentUIDFilterTest(ctx, c, invConfig, inventoryName, namespace.GetName()) + }) + It("PruneRetrievalError", func() { pruneRetrieveErrorTest(ctx, c, invConfig, inventoryName, namespace.GetName()) })