k8s.io/kubernetes@v1.29.3/test/e2e/instrumentation/events.go (about) 1 /* 2 Copyright 2020 The Kubernetes Authors. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package instrumentation 18 19 import ( 20 "context" 21 "encoding/json" 22 "time" 23 24 v1 "k8s.io/api/core/v1" 25 eventsv1 "k8s.io/api/events/v1" 26 apiequality "k8s.io/apimachinery/pkg/api/equality" 27 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 28 "k8s.io/apimachinery/pkg/util/strategicpatch" 29 corev1 "k8s.io/client-go/kubernetes/typed/core/v1" 30 typedeventsv1 "k8s.io/client-go/kubernetes/typed/events/v1" 31 "k8s.io/kubernetes/test/e2e/framework" 32 "k8s.io/kubernetes/test/e2e/instrumentation/common" 33 admissionapi "k8s.io/pod-security-admission/api" 34 35 "github.com/google/go-cmp/cmp" 36 "github.com/onsi/ginkgo/v2" 37 "github.com/onsi/gomega" 38 "k8s.io/apimachinery/pkg/types" 39 ) 40 41 func newTestEvent(namespace, name, label string) *eventsv1.Event { 42 someTime := metav1.MicroTime{Time: time.Unix(1505828956, 0)} 43 return &eventsv1.Event{ 44 ObjectMeta: metav1.ObjectMeta{ 45 Name: name, 46 Labels: map[string]string{ 47 label: "true", 48 }, 49 }, 50 Regarding: v1.ObjectReference{ 51 Namespace: namespace, 52 }, 53 EventTime: someTime, 54 Note: "This is " + name, 55 Action: "Do", 56 Reason: "Test", 57 Type: "Normal", 58 ReportingController: "test-controller", 59 ReportingInstance: "test-node", 60 } 61 } 62 63 func eventExistsInList(ctx context.Context, client typedeventsv1.EventInterface, namespace, name string) bool { 64 eventsList, err := client.List(ctx, metav1.ListOptions{ 65 LabelSelector: "testevent-constant=true", 66 }) 67 framework.ExpectNoError(err, "failed to list events") 68 69 for _, val := range eventsList.Items { 70 if val.ObjectMeta.Name == name && val.ObjectMeta.Namespace == namespace { 71 return true 72 } 73 } 74 return false 75 } 76 77 var _ = common.SIGDescribe("Events API", func() { 78 f := framework.NewDefaultFramework("events") 79 f.NamespacePodSecurityLevel = admissionapi.LevelPrivileged 80 var coreClient corev1.EventInterface 81 var client typedeventsv1.EventInterface 82 var clientAllNamespaces typedeventsv1.EventInterface 83 84 ginkgo.BeforeEach(func() { 85 coreClient = f.ClientSet.CoreV1().Events(f.Namespace.Name) 86 client = f.ClientSet.EventsV1().Events(f.Namespace.Name) 87 clientAllNamespaces = f.ClientSet.EventsV1().Events(metav1.NamespaceAll) 88 }) 89 90 /* 91 Release: v1.19 92 Testname: New Event resource lifecycle, testing a single event 93 Description: Create an event, the event MUST exist. 94 The event is patched with a new note, the check MUST have the update note. 95 The event is updated with a new series, the check MUST have the update series. 96 The event is deleted and MUST NOT show up when listing all events. 97 */ 98 framework.ConformanceIt("should ensure that an event can be fetched, patched, deleted, and listed", func(ctx context.Context) { 99 eventName := "event-test" 100 101 ginkgo.By("creating a test event") 102 _, err := client.Create(ctx, newTestEvent(f.Namespace.Name, eventName, "testevent-constant"), metav1.CreateOptions{}) 103 framework.ExpectNoError(err, "failed to create test event") 104 105 ginkgo.By("listing events in all namespaces") 106 foundCreatedEvent := eventExistsInList(ctx, clientAllNamespaces, f.Namespace.Name, eventName) 107 if !foundCreatedEvent { 108 framework.Failf("Failed to find test event %s in namespace %s, in list with cluster scope", eventName, f.Namespace.Name) 109 } 110 111 ginkgo.By("listing events in test namespace") 112 foundCreatedEvent = eventExistsInList(ctx, client, f.Namespace.Name, eventName) 113 if !foundCreatedEvent { 114 framework.Failf("Failed to find test event %s in namespace %s, in list with namespace scope", eventName, f.Namespace.Name) 115 } 116 117 ginkgo.By("listing events with field selection filtering on source") 118 filteredCoreV1List, err := coreClient.List(ctx, metav1.ListOptions{FieldSelector: "source=test-controller"}) 119 framework.ExpectNoError(err, "failed to get filtered list") 120 if len(filteredCoreV1List.Items) != 1 || filteredCoreV1List.Items[0].Name != eventName { 121 framework.Failf("expected single event, got %#v", filteredCoreV1List.Items) 122 } 123 124 ginkgo.By("listing events with field selection filtering on reportingController") 125 filteredEventsV1List, err := client.List(ctx, metav1.ListOptions{FieldSelector: "reportingController=test-controller"}) 126 framework.ExpectNoError(err, "failed to get filtered list") 127 if len(filteredEventsV1List.Items) != 1 || filteredEventsV1List.Items[0].Name != eventName { 128 framework.Failf("expected single event, got %#v", filteredEventsV1List.Items) 129 } 130 131 ginkgo.By("getting the test event") 132 testEvent, err := client.Get(ctx, eventName, metav1.GetOptions{}) 133 framework.ExpectNoError(err, "failed to get test event") 134 135 ginkgo.By("patching the test event") 136 oldData, err := json.Marshal(testEvent) 137 framework.ExpectNoError(err, "failed to marshal event") 138 newEvent := testEvent.DeepCopy() 139 eventSeries := &eventsv1.EventSeries{ 140 Count: 2, 141 LastObservedTime: metav1.MicroTime{Time: time.Unix(1505828951, 0)}, 142 } 143 newEvent.Series = eventSeries 144 newData, err := json.Marshal(newEvent) 145 framework.ExpectNoError(err, "failed to marshal new event") 146 patchBytes, err := strategicpatch.CreateTwoWayMergePatch(oldData, newData, eventsv1.Event{}) 147 framework.ExpectNoError(err, "failed to create two-way merge patch") 148 149 _, err = client.Patch(ctx, eventName, types.StrategicMergePatchType, patchBytes, metav1.PatchOptions{}) 150 framework.ExpectNoError(err, "failed to patch the test event") 151 152 ginkgo.By("getting the test event") 153 event, err := client.Get(ctx, eventName, metav1.GetOptions{}) 154 framework.ExpectNoError(err, "failed to get test event") 155 // clear ResourceVersion and ManagedFields which are set by control-plane 156 event.ObjectMeta.ResourceVersion = "" 157 testEvent.ObjectMeta.ResourceVersion = "" 158 event.ObjectMeta.ManagedFields = nil 159 testEvent.ObjectMeta.ManagedFields = nil 160 161 testEvent.Series = eventSeries 162 if !apiequality.Semantic.DeepEqual(testEvent, event) { 163 framework.Failf("test event wasn't properly patched: %v", cmp.Diff(testEvent, event)) 164 } 165 166 ginkgo.By("updating the test event") 167 testEvent.Series = &eventsv1.EventSeries{ 168 Count: 100, 169 LastObservedTime: metav1.MicroTime{Time: time.Unix(1505828956, 0)}, 170 } 171 _, err = client.Update(ctx, testEvent, metav1.UpdateOptions{}) 172 framework.ExpectNoError(err, "failed to update the test event") 173 174 ginkgo.By("getting the test event") 175 event, err = client.Get(ctx, eventName, metav1.GetOptions{}) 176 framework.ExpectNoError(err, "failed to get test event") 177 // clear ResourceVersion and ManagedFields which are set by control-plane 178 event.ObjectMeta.ResourceVersion = "" 179 event.ObjectMeta.ManagedFields = nil 180 if !apiequality.Semantic.DeepEqual(testEvent, event) { 181 framework.Failf("test event wasn't properly updated: %v", cmp.Diff(testEvent, event)) 182 } 183 184 ginkgo.By("deleting the test event") 185 err = client.Delete(ctx, eventName, metav1.DeleteOptions{}) 186 framework.ExpectNoError(err, "failed to delete the test event") 187 188 ginkgo.By("listing events in all namespaces") 189 foundCreatedEvent = eventExistsInList(ctx, clientAllNamespaces, f.Namespace.Name, eventName) 190 if foundCreatedEvent { 191 framework.Failf("Should not have found test event %s in namespace %s, in list with cluster scope after deletion", eventName, f.Namespace.Name) 192 } 193 194 ginkgo.By("listing events in test namespace") 195 foundCreatedEvent = eventExistsInList(ctx, client, f.Namespace.Name, eventName) 196 if foundCreatedEvent { 197 framework.Failf("Should not have found test event %s in namespace %s, in list with namespace scope after deletion", eventName, f.Namespace.Name) 198 } 199 }) 200 201 /* 202 Release: v1.19 203 Testname: New Event resource lifecycle, testing a list of events 204 Description: Create a list of events, the events MUST exist. 205 The events are deleted and MUST NOT show up when listing all events. 206 */ 207 framework.ConformanceIt("should delete a collection of events", func(ctx context.Context) { 208 eventNames := []string{"test-event-1", "test-event-2", "test-event-3"} 209 210 ginkgo.By("Create set of events") 211 for _, eventName := range eventNames { 212 _, err := client.Create(ctx, newTestEvent(f.Namespace.Name, eventName, "testevent-set"), metav1.CreateOptions{}) 213 framework.ExpectNoError(err, "failed to create event") 214 } 215 216 ginkgo.By("get a list of Events with a label in the current namespace") 217 eventList, err := client.List(ctx, metav1.ListOptions{ 218 LabelSelector: "testevent-set=true", 219 }) 220 framework.ExpectNoError(err, "failed to get a list of events") 221 gomega.Expect(eventList.Items).To(gomega.HaveLen(len(eventNames)), "unexpected event list: %#v", eventList) 222 223 ginkgo.By("delete a list of events") 224 framework.Logf("requesting DeleteCollection of events") 225 err = client.DeleteCollection(ctx, metav1.DeleteOptions{}, metav1.ListOptions{ 226 LabelSelector: "testevent-set=true", 227 }) 228 framework.ExpectNoError(err, "failed to delete the test event") 229 230 ginkgo.By("check that the list of events matches the requested quantity") 231 eventList, err = client.List(ctx, metav1.ListOptions{ 232 LabelSelector: "testevent-set=true", 233 }) 234 framework.ExpectNoError(err, "failed to get a list of events") 235 gomega.Expect(eventList.Items).To(gomega.BeEmpty(), "unexpected event list: %#v", eventList) 236 }) 237 })