1
16
17 package instrumentation
18
19 import (
20 "context"
21 "encoding/json"
22 "time"
23
24 v1 "k8s.io/api/core/v1"
25 apiequality "k8s.io/apimachinery/pkg/api/equality"
26 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
27 "k8s.io/apimachinery/pkg/util/wait"
28 "k8s.io/kubernetes/test/e2e/framework"
29 "k8s.io/kubernetes/test/e2e/instrumentation/common"
30 admissionapi "k8s.io/pod-security-admission/api"
31
32 "github.com/google/go-cmp/cmp"
33 "github.com/onsi/ginkgo/v2"
34 "github.com/onsi/gomega"
35 "k8s.io/apimachinery/pkg/types"
36 )
37
38 const (
39 eventRetryPeriod = 1 * time.Second
40 eventRetryTimeout = 1 * time.Minute
41 )
42
43 var _ = common.SIGDescribe("Events", func() {
44 f := framework.NewDefaultFramework("events")
45 f.NamespacePodSecurityLevel = admissionapi.LevelPrivileged
46
47
58 framework.ConformanceIt("should manage the lifecycle of an event", func(ctx context.Context) {
59
60
61
62 eventTestName := "event-test"
63
64 ginkgo.By("creating a test event")
65
66 _, err := f.ClientSet.CoreV1().Events(f.Namespace.Name).Create(ctx, &v1.Event{
67 ObjectMeta: metav1.ObjectMeta{
68 Name: eventTestName,
69 Labels: map[string]string{
70 "testevent-constant": "true",
71 },
72 },
73 Message: "This is a test event",
74 Reason: "Test",
75 Type: "Normal",
76 Count: 1,
77 InvolvedObject: v1.ObjectReference{
78 Namespace: f.Namespace.Name,
79 },
80 }, metav1.CreateOptions{})
81 framework.ExpectNoError(err, "failed to create test event")
82
83 ginkgo.By("listing all events in all namespaces")
84
85 eventsList, err := f.ClientSet.CoreV1().Events("").List(ctx, metav1.ListOptions{
86 LabelSelector: "testevent-constant=true",
87 })
88 framework.ExpectNoError(err, "failed list all events")
89
90 foundCreatedEvent := false
91 var eventCreatedName string
92 for _, val := range eventsList.Items {
93 if val.ObjectMeta.Name == eventTestName && val.ObjectMeta.Namespace == f.Namespace.Name {
94 foundCreatedEvent = true
95 eventCreatedName = val.ObjectMeta.Name
96 break
97 }
98 }
99 if !foundCreatedEvent {
100 framework.Failf("unable to find test event %s in namespace %s, full list of events is %+v", eventTestName, f.Namespace.Name, eventsList.Items)
101 }
102
103 ginkgo.By("patching the test event")
104
105 eventPatchMessage := "This is a test event - patched"
106 eventPatch, err := json.Marshal(map[string]interface{}{
107 "message": eventPatchMessage,
108 })
109 framework.ExpectNoError(err, "failed to marshal the patch JSON payload")
110
111 _, err = f.ClientSet.CoreV1().Events(f.Namespace.Name).Patch(ctx, eventTestName, types.StrategicMergePatchType, []byte(eventPatch), metav1.PatchOptions{})
112 framework.ExpectNoError(err, "failed to patch the test event")
113
114 ginkgo.By("fetching the test event")
115
116 event, err := f.ClientSet.CoreV1().Events(f.Namespace.Name).Get(ctx, eventCreatedName, metav1.GetOptions{})
117 framework.ExpectNoError(err, "failed to fetch the test event")
118 gomega.Expect(event.Message).To(gomega.Equal(eventPatchMessage), "test event message does not match patch message")
119
120 ginkgo.By("updating the test event")
121
122 testEvent, err := f.ClientSet.CoreV1().Events(f.Namespace.Name).Get(ctx, event.Name, metav1.GetOptions{})
123 framework.ExpectNoError(err, "failed to get test event")
124
125 testEvent.Series = &v1.EventSeries{
126 Count: 100,
127 LastObservedTime: metav1.MicroTime{Time: time.Unix(1505828956, 0)},
128 }
129
130
131 testEvent.ObjectMeta.ResourceVersion = ""
132 testEvent.ObjectMeta.ManagedFields = nil
133
134 _, err = f.ClientSet.CoreV1().Events(f.Namespace.Name).Update(ctx, testEvent, metav1.UpdateOptions{})
135 framework.ExpectNoError(err, "failed to update the test event")
136
137 ginkgo.By("getting the test event")
138 event, err = f.ClientSet.CoreV1().Events(f.Namespace.Name).Get(ctx, testEvent.Name, metav1.GetOptions{})
139 framework.ExpectNoError(err, "failed to get test event")
140
141 event.ObjectMeta.ResourceVersion = ""
142 event.ObjectMeta.ManagedFields = nil
143 if !apiequality.Semantic.DeepEqual(testEvent, event) {
144 framework.Failf("test event wasn't properly updated: %v", cmp.Diff(testEvent, event))
145 }
146
147 ginkgo.By("deleting the test event")
148
149 err = f.ClientSet.CoreV1().Events(f.Namespace.Name).Delete(ctx, eventCreatedName, metav1.DeleteOptions{})
150 framework.ExpectNoError(err, "failed to delete the test event")
151
152 ginkgo.By("listing all events in all namespaces")
153
154 eventsList, err = f.ClientSet.CoreV1().Events("").List(ctx, metav1.ListOptions{
155 LabelSelector: "testevent-constant=true",
156 })
157 framework.ExpectNoError(err, "fail to list all events")
158 foundCreatedEvent = false
159 for _, val := range eventsList.Items {
160 if val.ObjectMeta.Name == eventTestName && val.ObjectMeta.Namespace == f.Namespace.Name {
161 foundCreatedEvent = true
162 break
163 }
164 }
165 if foundCreatedEvent {
166 framework.Failf("Should not have found test event %s in namespace %s, full list of events %+v", eventTestName, f.Namespace.Name, eventsList.Items)
167 }
168 })
169
170
176 framework.ConformanceIt("should delete a collection of events", func(ctx context.Context) {
177 eventTestNames := []string{"test-event-1", "test-event-2", "test-event-3"}
178
179 ginkgo.By("Create set of events")
180
181 for _, eventTestName := range eventTestNames {
182 eventMessage := "This is " + eventTestName
183 _, err := f.ClientSet.CoreV1().Events(f.Namespace.Name).Create(ctx, &v1.Event{
184
185 ObjectMeta: metav1.ObjectMeta{
186 Name: eventTestName,
187 Labels: map[string]string{"testevent-set": "true"},
188 },
189 Message: eventMessage,
190 Reason: "Test",
191 Type: "Normal",
192 Count: 1,
193 InvolvedObject: v1.ObjectReference{
194 Namespace: f.Namespace.Name,
195 },
196 }, metav1.CreateOptions{})
197 framework.ExpectNoError(err, "failed to create event")
198 framework.Logf("created %v", eventTestName)
199 }
200
201 ginkgo.By("get a list of Events with a label in the current namespace")
202
203 eventList, err := f.ClientSet.CoreV1().Events(f.Namespace.Name).List(ctx, metav1.ListOptions{
204 LabelSelector: "testevent-set=true",
205 })
206 framework.ExpectNoError(err, "failed to get a list of events")
207
208 gomega.Expect(eventList.Items).To(gomega.HaveLen(len(eventTestNames)), "looking for expected number of pod templates events")
209
210 ginkgo.By("delete collection of events")
211
212
213 framework.Logf("requesting DeleteCollection of events")
214 err = f.ClientSet.CoreV1().Events(f.Namespace.Name).DeleteCollection(ctx, metav1.DeleteOptions{}, metav1.ListOptions{
215 LabelSelector: "testevent-set=true"})
216 framework.ExpectNoError(err, "failed to delete the test event")
217
218 ginkgo.By("check that the list of events matches the requested quantity")
219
220 err = wait.PollUntilContextTimeout(ctx, eventRetryPeriod, eventRetryTimeout, true, checkEventListQuantity(f, "testevent-set=true", 0))
221 framework.ExpectNoError(err, "failed to count required events")
222 })
223
224 })
225
226 func checkEventListQuantity(f *framework.Framework, label string, quantity int) func(ctx context.Context) (bool, error) {
227 return func(ctx context.Context) (bool, error) {
228 var err error
229
230 framework.Logf("requesting list of events to confirm quantity")
231
232 eventList, err := f.ClientSet.CoreV1().Events(f.Namespace.Name).List(ctx, metav1.ListOptions{
233 LabelSelector: label})
234
235 if err != nil {
236 return false, err
237 }
238
239 if len(eventList.Items) != quantity {
240 return false, err
241 }
242 return true, nil
243 }
244 }
245
View as plain text