@@ -38,11 +38,13 @@ import (
38
38
. "sigs.k8s.io/karpenter/pkg/utils/testing"
39
39
)
40
40
41
- var ctx context.Context
42
- var podEventsController * podevents.Controller
43
- var env * test.Environment
44
- var fakeClock * clock.FakeClock
45
- var cp * fake.CloudProvider
41
+ var (
42
+ ctx context.Context
43
+ podEventsController * podevents.Controller
44
+ env * test.Environment
45
+ fakeClock * clock.FakeClock
46
+ cp * fake.CloudProvider
47
+ )
46
48
47
49
func TestAPIs (t * testing.T ) {
48
50
ctx = TestContextWithLogger (t )
@@ -75,6 +77,7 @@ var _ = AfterEach(func() {
75
77
cp .Reset ()
76
78
ExpectCleanedUp (ctx , env .Client )
77
79
})
80
+
78
81
var _ = Describe ("PodEvents" , func () {
79
82
var nodePool * v1.NodePool
80
83
var nodeClaim * v1.NodeClaim
@@ -98,13 +101,31 @@ var _ = Describe("PodEvents", func() {
98
101
NodeName : node .Name ,
99
102
})
100
103
})
101
- It ("should set the nodeclaim lastPodEvent" , func () {
102
- ExpectApplied (ctx , env .Client , nodePool , nodeClaim , node , pod )
103
- timeToCheck := fakeClock .Now ().Truncate (time .Second )
104
+ It ("should set the nodeclaim lastPodEvent based on PodScheduled condition" , func () {
105
+ scheduledTime := fakeClock .Now ().Truncate (time .Second )
106
+ pod .Status .Conditions = []corev1.PodCondition {{
107
+ Type : corev1 .PodScheduled ,
108
+ Status : corev1 .ConditionTrue ,
109
+ LastTransitionTime : metav1.Time {Time : scheduledTime },
110
+ }}
111
+ ExpectApplied (ctx , env .Client , nodePool , node , nodeClaim , pod )
104
112
ExpectObjectReconciled (ctx , env .Client , podEventsController , pod )
105
113
106
114
nodeClaim = ExpectExists (ctx , env .Client , nodeClaim )
107
- Expect (nodeClaim .Status .LastPodEventTime .Time ).To (BeEquivalentTo (timeToCheck ))
115
+ Expect (nodeClaim .Status .LastPodEventTime .Time ).To (BeEquivalentTo (scheduledTime ))
116
+
117
+ // Update the PodScheduled condition's lastTransitionTime
118
+ newScheduledTime := fakeClock .Now ().Add (time .Minute ).Truncate (time .Second )
119
+ pod .Status .Conditions = []corev1.PodCondition {{
120
+ Type : corev1 .PodScheduled ,
121
+ Status : corev1 .ConditionTrue ,
122
+ LastTransitionTime : metav1.Time {Time : newScheduledTime },
123
+ }}
124
+ ExpectApplied (ctx , env .Client , pod )
125
+ ExpectObjectReconciled (ctx , env .Client , podEventsController , pod )
126
+
127
+ nodeClaim = ExpectExists (ctx , env .Client , nodeClaim )
128
+ Expect (nodeClaim .Status .LastPodEventTime .Time ).To (BeEquivalentTo (newScheduledTime ))
108
129
})
109
130
It ("should not set the nodeclaim lastPodEvent when the node does not exist" , func () {
110
131
ExpectApplied (ctx , env .Client , nodePool , nodeClaim , pod )
@@ -117,36 +138,74 @@ var _ = Describe("PodEvents", func() {
117
138
ExpectApplied (ctx , env .Client , nodePool , node , pod )
118
139
ExpectObjectReconciled (ctx , env .Client , podEventsController , pod )
119
140
})
120
- It ("should set the nodeclaim lastPodEvent when it's been set before" , func () {
121
- nodeClaim .Status .LastPodEventTime .Time = fakeClock .Now ().Add (- 5 * time .Minute )
141
+ It ("should set the nodeclaim lastPodEvent when pod becomes terminal" , func () {
142
+ // First set up a regular pod
143
+ scheduledTime := fakeClock .Now ().Truncate (time .Second )
144
+ pod .Status .Conditions = []corev1.PodCondition {{
145
+ Type : corev1 .PodScheduled ,
146
+ Status : corev1 .ConditionTrue ,
147
+ LastTransitionTime : metav1.Time {Time : scheduledTime },
148
+ }}
122
149
ExpectApplied (ctx , env .Client , nodePool , node , nodeClaim , pod )
123
- timeToCheck := fakeClock .Now ().Truncate (time .Second )
150
+ ExpectObjectReconciled (ctx , env .Client , podEventsController , pod )
151
+
152
+ // Make pod terminal now
153
+ timeToCheck := fakeClock .Now ().Add (time .Minute ).Truncate (time .Second )
154
+ fakeClock .SetTime (timeToCheck )
155
+ pod .Status .Phase = corev1 .PodSucceeded // Setting pod as terminal directly
156
+ ExpectApplied (ctx , env .Client , pod )
124
157
ExpectObjectReconciled (ctx , env .Client , podEventsController , pod )
125
158
126
159
nodeClaim = ExpectExists (ctx , env .Client , nodeClaim )
127
160
Expect (nodeClaim .Status .LastPodEventTime .Time ).To (BeEquivalentTo (timeToCheck ))
128
161
})
129
- It ("should only set the nodeclaim lastPodEvent once within the dedupe timeframe " , func () {
162
+ It ("should set the nodeclaim lastPodEvent when pod becomes terminating " , func () {
130
163
ExpectApplied (ctx , env .Client , nodePool , node , nodeClaim , pod )
131
- timeToCheck := fakeClock .Now ().Truncate (time .Second )
132
164
ExpectObjectReconciled (ctx , env .Client , podEventsController , pod )
133
165
134
- // Expect that the lastPodEventTime is set
166
+ timeToCheck := fakeClock .Now ().Truncate (time .Second )
167
+ fakeClock .SetTime (timeToCheck )
168
+ // Make pod terminating by deleting it
169
+ ExpectDeletionTimestampSet (ctx , env .Client , pod )
170
+ // Reconcile for the terminating pod
171
+ ExpectObjectReconciled (ctx , env .Client , podEventsController , pod )
135
172
nodeClaim = ExpectExists (ctx , env .Client , nodeClaim )
136
173
Expect (nodeClaim .Status .LastPodEventTime .Time ).To (BeEquivalentTo (timeToCheck ))
174
+ })
175
+ It ("should not update lastPodEvent when pod has no PodScheduled condition" , func () {
176
+ // Pod with no conditions
177
+ ExpectApplied (ctx , env .Client , nodePool , node , nodeClaim , pod )
178
+ ExpectObjectReconciled (ctx , env .Client , podEventsController , pod )
137
179
138
- // step through half of the dedupe timeout, and re-reconcile, expecting the status to not change
139
- fakeClock .Step (5 * time .Second )
180
+ nodeClaim = ExpectExists (ctx , env .Client , nodeClaim )
181
+ Expect (nodeClaim .Status .LastPodEventTime .Time .IsZero ()).To (BeTrue ())
182
+ })
183
+ It ("should not update lastPodEvent when PodScheduled condition is not True" , func () {
184
+ pod .Status .Conditions = []corev1.PodCondition {{
185
+ Type : corev1 .PodScheduled ,
186
+ Status : corev1 .ConditionFalse ,
187
+ LastTransitionTime : metav1.Time {Time : fakeClock .Now ()},
188
+ }}
189
+ ExpectApplied (ctx , env .Client , nodePool , node , nodeClaim , pod )
140
190
ExpectObjectReconciled (ctx , env .Client , podEventsController , pod )
141
191
142
192
nodeClaim = ExpectExists (ctx , env .Client , nodeClaim )
143
- Expect (nodeClaim .Status .LastPodEventTime .Time ).To (BeEquivalentTo (timeToCheck ))
193
+ Expect (nodeClaim .Status .LastPodEventTime .Time .IsZero ()).To (BeTrue ())
194
+ })
195
+ It ("should set the nodeclaim lastPodEvent when pod is already in a terminal state" , func () {
196
+ // Setup time
197
+ timeToCheck := fakeClock .Now ().Truncate (time .Second )
198
+ fakeClock .SetTime (timeToCheck )
144
199
145
- // step through rest of the dedupe timeout, and re-reconcile, expecting the status to change
146
- fakeClock .Step (5 * time .Second )
200
+ // Set the pod to a terminal state directly - mocks podutils.IsTerminal() return true
201
+ pod .Status .Phase = corev1 .PodSucceeded
202
+
203
+ // Apply objects and reconcile
204
+ ExpectApplied (ctx , env .Client , nodePool , node , nodeClaim , pod )
147
205
ExpectObjectReconciled (ctx , env .Client , podEventsController , pod )
148
206
207
+ // Verify the last pod event time is set
149
208
nodeClaim = ExpectExists (ctx , env .Client , nodeClaim )
150
- Expect (nodeClaim .Status .LastPodEventTime .Time ).ToNot (BeEquivalentTo (timeToCheck ))
209
+ Expect (nodeClaim .Status .LastPodEventTime .Time ).To (BeEquivalentTo (timeToCheck ))
151
210
})
152
211
})
0 commit comments