1
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
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
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
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
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 })
238
View as plain text