21
21
import io .javaoperatorsdk .operator .MockKubernetesClient ;
22
22
import io .javaoperatorsdk .operator .OperatorException ;
23
23
import io .javaoperatorsdk .operator .TestUtils ;
24
- import io .javaoperatorsdk .operator .api .config .Cloner ;
25
- import io .javaoperatorsdk .operator .api .config .ConfigurationServiceProvider ;
26
- import io .javaoperatorsdk .operator .api .config .ControllerConfiguration ;
27
- import io .javaoperatorsdk .operator .api .config .MockControllerConfiguration ;
24
+ import io .javaoperatorsdk .operator .api .config .*;
28
25
import io .javaoperatorsdk .operator .api .reconciler .Cleaner ;
29
26
import io .javaoperatorsdk .operator .api .reconciler .Context ;
30
27
import io .javaoperatorsdk .operator .api .reconciler .DeleteControl ;
@@ -133,7 +130,7 @@ void addFinalizerOnNewResource() {
133
130
verify (reconciler , never ())
134
131
.reconcile (ArgumentMatchers .eq (testCustomResource ), any ());
135
132
verify (customResourceFacade , times (1 ))
136
- .replaceResourceWithLock (
133
+ .updateResource (
137
134
argThat (testCustomResource -> testCustomResource .hasFinalizer (DEFAULT_FINALIZER )));
138
135
assertThat (testCustomResource .hasFinalizer (DEFAULT_FINALIZER )).isTrue ();
139
136
}
@@ -155,20 +152,20 @@ void updatesOnlyStatusSubResourceIfFinalizerSet() {
155
152
reconciliationDispatcher .handleExecution (executionScopeWithCREvent (testCustomResource ));
156
153
157
154
verify (customResourceFacade , times (1 )).patchStatus (eq (testCustomResource ), any ());
158
- verify (customResourceFacade , never ()).replaceResourceWithLock (any ());
155
+ verify (customResourceFacade , never ()).updateResource (any ());
159
156
}
160
157
161
158
@ Test
162
159
void updatesBothResourceAndStatusIfFinalizerSet () {
163
160
testCustomResource .addFinalizer (DEFAULT_FINALIZER );
164
161
165
162
reconciler .reconcile = (r , c ) -> UpdateControl .updateResourceAndStatus (testCustomResource );
166
- when (customResourceFacade .replaceResourceWithLock (testCustomResource ))
163
+ when (customResourceFacade .updateResource (testCustomResource ))
167
164
.thenReturn (testCustomResource );
168
165
169
166
reconciliationDispatcher .handleExecution (executionScopeWithCREvent (testCustomResource ));
170
167
171
- verify (customResourceFacade , times (1 )).replaceResourceWithLock (testCustomResource );
168
+ verify (customResourceFacade , times (1 )).updateResource (testCustomResource );
172
169
verify (customResourceFacade , times (1 )).updateStatus (testCustomResource );
173
170
}
174
171
@@ -182,7 +179,7 @@ void patchesStatus() {
182
179
183
180
verify (customResourceFacade , times (1 )).patchStatus (eq (testCustomResource ), any ());
184
181
verify (customResourceFacade , never ()).updateStatus (any ());
185
- verify (customResourceFacade , never ()).replaceResourceWithLock (any ());
182
+ verify (customResourceFacade , never ()).updateResource (any ());
186
183
}
187
184
188
185
@ Test
@@ -214,7 +211,7 @@ void removesDefaultFinalizerOnDeleteIfSet() {
214
211
reconciliationDispatcher .handleExecution (executionScopeWithCREvent (testCustomResource ));
215
212
216
213
assertThat (postExecControl .isFinalizerRemoved ()).isTrue ();
217
- verify (customResourceFacade , times (1 )).replaceResourceWithLock (testCustomResource );
214
+ verify (customResourceFacade , times (1 )).updateResource (testCustomResource );
218
215
}
219
216
220
217
@ Test
@@ -223,7 +220,7 @@ void retriesFinalizerRemovalWithFreshResource() {
223
220
markForDeletion (testCustomResource );
224
221
var resourceWithFinalizer = TestUtils .testCustomResource ();
225
222
resourceWithFinalizer .addFinalizer (DEFAULT_FINALIZER );
226
- when (customResourceFacade .replaceResourceWithLock (testCustomResource ))
223
+ when (customResourceFacade .updateResource (testCustomResource ))
227
224
.thenThrow (new KubernetesClientException (null , 409 , null ))
228
225
.thenReturn (testCustomResource );
229
226
when (customResourceFacade .getResource (any (), any ())).thenReturn (resourceWithFinalizer );
@@ -232,15 +229,15 @@ void retriesFinalizerRemovalWithFreshResource() {
232
229
reconciliationDispatcher .handleExecution (executionScopeWithCREvent (testCustomResource ));
233
230
234
231
assertThat (postExecControl .isFinalizerRemoved ()).isTrue ();
235
- verify (customResourceFacade , times (2 )).replaceResourceWithLock (any ());
232
+ verify (customResourceFacade , times (2 )).updateResource (any ());
236
233
verify (customResourceFacade , times (1 )).getResource (any (), any ());
237
234
}
238
235
239
236
@ Test
240
237
void throwsExceptionIfFinalizerRemovalRetryExceeded () {
241
238
testCustomResource .addFinalizer (DEFAULT_FINALIZER );
242
239
markForDeletion (testCustomResource );
243
- when (customResourceFacade .replaceResourceWithLock (any ()))
240
+ when (customResourceFacade .updateResource (any ()))
244
241
.thenThrow (new KubernetesClientException (null , 409 , null ));
245
242
when (customResourceFacade .getResource (any (), any ()))
246
243
.thenAnswer ((Answer <TestCustomResource >) invocationOnMock -> createResourceWithFinalizer ());
@@ -252,7 +249,7 @@ void throwsExceptionIfFinalizerRemovalRetryExceeded() {
252
249
assertThat (postExecControl .getRuntimeException ()).isPresent ();
253
250
assertThat (postExecControl .getRuntimeException ().get ())
254
251
.isInstanceOf (OperatorException .class );
255
- verify (customResourceFacade , times (MAX_FINALIZER_REMOVAL_RETRY )).replaceResourceWithLock (any ());
252
+ verify (customResourceFacade , times (MAX_FINALIZER_REMOVAL_RETRY )).updateResource (any ());
256
253
verify (customResourceFacade , times (MAX_FINALIZER_REMOVAL_RETRY - 1 )).getResource (any (),
257
254
any ());
258
255
}
@@ -261,15 +258,15 @@ void throwsExceptionIfFinalizerRemovalRetryExceeded() {
261
258
void throwsExceptionIfFinalizerRemovalClientExceptionIsNotConflict () {
262
259
testCustomResource .addFinalizer (DEFAULT_FINALIZER );
263
260
markForDeletion (testCustomResource );
264
- when (customResourceFacade .replaceResourceWithLock (any ()))
261
+ when (customResourceFacade .updateResource (any ()))
265
262
.thenThrow (new KubernetesClientException (null , 400 , null ));
266
263
267
264
var res =
268
265
reconciliationDispatcher .handleExecution (executionScopeWithCREvent (testCustomResource ));
269
266
270
267
assertThat (res .getRuntimeException ()).isPresent ();
271
268
assertThat (res .getRuntimeException ().get ()).isInstanceOf (KubernetesClientException .class );
272
- verify (customResourceFacade , times (1 )).replaceResourceWithLock (any ());
269
+ verify (customResourceFacade , times (1 )).updateResource (any ());
273
270
verify (customResourceFacade , never ()).getResource (any (), any ());
274
271
}
275
272
@@ -315,7 +312,7 @@ void doesNotRemovesTheSetFinalizerIfTheDeleteNotMethodInstructsIt() {
315
312
reconciliationDispatcher .handleExecution (executionScopeWithCREvent (testCustomResource ));
316
313
317
314
assertEquals (1 , testCustomResource .getMetadata ().getFinalizers ().size ());
318
- verify (customResourceFacade , never ()).replaceResourceWithLock (any ());
315
+ verify (customResourceFacade , never ()).updateResource (any ());
319
316
}
320
317
321
318
@ Test
@@ -325,21 +322,21 @@ void doesNotUpdateTheResourceIfNoUpdateUpdateControlIfFinalizerSet() {
325
322
reconciler .reconcile = (r , c ) -> UpdateControl .noUpdate ();
326
323
327
324
reconciliationDispatcher .handleExecution (executionScopeWithCREvent (testCustomResource ));
328
- verify (customResourceFacade , never ()).replaceResourceWithLock (any ());
325
+ verify (customResourceFacade , never ()).updateResource (any ());
329
326
verify (customResourceFacade , never ()).updateStatus (testCustomResource );
330
327
}
331
328
332
329
@ Test
333
330
void addsFinalizerIfNotMarkedForDeletionAndEmptyCustomResourceReturned () {
334
331
removeFinalizers (testCustomResource );
335
332
reconciler .reconcile = (r , c ) -> UpdateControl .noUpdate ();
336
- when (customResourceFacade .replaceResourceWithLock (any ())).thenReturn (testCustomResource );
333
+ when (customResourceFacade .updateResource (any ())).thenReturn (testCustomResource );
337
334
338
335
var postExecControl =
339
336
reconciliationDispatcher .handleExecution (executionScopeWithCREvent (testCustomResource ));
340
337
341
338
assertEquals (1 , testCustomResource .getMetadata ().getFinalizers ().size ());
342
- verify (customResourceFacade , times (1 )).replaceResourceWithLock (any ());
339
+ verify (customResourceFacade , times (1 )).updateResource (any ());
343
340
assertThat (postExecControl .updateIsStatusPatch ()).isFalse ();
344
341
assertThat (postExecControl .getUpdatedCustomResource ()).isPresent ();
345
342
}
@@ -351,7 +348,7 @@ void doesNotCallDeleteIfMarkedForDeletionButNotOurFinalizer() {
351
348
352
349
reconciliationDispatcher .handleExecution (executionScopeWithCREvent (testCustomResource ));
353
350
354
- verify (customResourceFacade , never ()).replaceResourceWithLock (any ());
351
+ verify (customResourceFacade , never ()).updateResource (any ());
355
352
verify (reconciler , never ()).cleanup (eq (testCustomResource ), any ());
356
353
}
357
354
@@ -477,7 +474,7 @@ void updateObservedGenerationOnCustomResourceUpdate() throws Exception {
477
474
when (config .isGenerationAware ()).thenReturn (true );
478
475
when (reconciler .reconcile (any (), any ()))
479
476
.thenReturn (UpdateControl .updateResource (observedGenResource ));
480
- when (facade .replaceResourceWithLock (any ())).thenReturn (observedGenResource );
477
+ when (facade .updateResource (any ())).thenReturn (observedGenResource );
481
478
when (facade .updateStatus (observedGenResource )).thenReturn (observedGenResource );
482
479
var dispatcher = init (observedGenResource , reconciler , config , facade , true );
483
480
@@ -629,6 +626,48 @@ void canSkipSchedulingMaxDelayIf() {
629
626
assertThat (control .getReScheduleDelay ()).isNotPresent ();
630
627
}
631
628
629
+ @ Test
630
+ void noRequestOnConditionalUpdates () {
631
+ checkConditionalUpdate ((r , c ) -> UpdateControl .patchStatusIfChanged (testCustomResource ));
632
+ checkConditionalUpdate (
633
+ (r , c ) -> UpdateControl .updateResourceAndPatchStatusIfChanged (testCustomResource ));
634
+ checkConditionalUpdate ((r , c ) -> UpdateControl .updateResourceIfChanged (testCustomResource ));
635
+ checkConditionalUpdate (
636
+ (r , c ) -> UpdateControl .updateResourceAndStatusIfChanged (testCustomResource ));
637
+ }
638
+
639
+
640
+ @ Test
641
+ void conditionalUpdateSpecChangedNoStatus () {
642
+ testCustomResource .addFinalizer (DEFAULT_FINALIZER );
643
+ when (customResourceFacade .updateResource (any ())).thenAnswer (a -> a .getArguments ()[0 ]);
644
+
645
+ reconciler .reconcile = (r , c ) -> {
646
+ // in this test the cloning is turned off for easier verification, but required here
647
+ r = ConfigurationService .DEFAULT_CLONER .clone (r );
648
+ r .getSpec ().setValue ("otherValue" );
649
+ return UpdateControl .updateResourceAndPatchStatusIfChanged (r );
650
+ };
651
+
652
+ reconciliationDispatcher .handleExecution (executionScopeWithCREvent (testCustomResource ));
653
+
654
+ verify (customResourceFacade , never ()).patchStatus (any (), any ());
655
+ verify (customResourceFacade , times (1 )).updateResource (any ());
656
+ }
657
+
658
+ private void checkConditionalUpdate (
659
+ BiFunction <TestCustomResource , Context , UpdateControl <TestCustomResource >> r ) {
660
+ testCustomResource .addFinalizer (DEFAULT_FINALIZER );
661
+
662
+ reconciler .reconcile = r ;
663
+
664
+ reconciliationDispatcher .handleExecution (executionScopeWithCREvent (testCustomResource ));
665
+
666
+ verify (customResourceFacade , never ()).patchStatus (any (), any ());
667
+ verify (customResourceFacade , never ()).updateResource (any ());
668
+ verify (customResourceFacade , never ()).updateStatus (any ());
669
+ }
670
+
632
671
private ObservedGenCustomResource createObservedGenCustomResource () {
633
672
ObservedGenCustomResource observedGenCustomResource = new ObservedGenCustomResource ();
634
673
observedGenCustomResource .setMetadata (new ObjectMeta ());
0 commit comments