@@ -18,6 +18,7 @@ import com.nhaarman.mockitokotlin2.doReturn
18
18
import com.nhaarman.mockitokotlin2.mock
19
19
import com.nhaarman.mockitokotlin2.never
20
20
import com.nhaarman.mockitokotlin2.spy
21
+ import com.nhaarman.mockitokotlin2.times
21
22
import com.nhaarman.mockitokotlin2.verify
22
23
import com.nhaarman.mockitokotlin2.whenever
23
24
import com.redhat.devtools.intellij.kubernetes.model.client.KubeClientAdapter
@@ -28,6 +29,8 @@ import io.fabric8.kubernetes.api.model.APIResource
28
29
import io.fabric8.kubernetes.api.model.GenericKubernetesResource
29
30
import io.fabric8.kubernetes.api.model.GenericKubernetesResourceList
30
31
import io.fabric8.kubernetes.api.model.HasMetadata
32
+ import io.fabric8.kubernetes.api.model.ManagedFieldsEntry
33
+ import io.fabric8.kubernetes.api.model.ObjectMeta
31
34
import io.fabric8.kubernetes.api.model.ObjectMetaBuilder
32
35
import io.fabric8.kubernetes.api.model.PodBuilder
33
36
import io.fabric8.kubernetes.client.KubernetesClientException
@@ -185,6 +188,84 @@ class NonCachingSingleResourceOperatorTest {
185
188
// then
186
189
}
187
190
191
+ @Test
192
+ fun `#create should call #patch(SERVER_SIDE_APPLY) if resource has a name and NO managed fields` () {
193
+ // given
194
+ val metadata = ObjectMetaBuilder ().build().apply {
195
+ managedFields = null
196
+ }
197
+ val hasName = PodBuilder (namespacedCoreResource)
198
+ .withMetadata(metadata)
199
+ .build()
200
+ hasName.metadata.name = " yoda"
201
+ hasName.metadata.generateName = null
202
+ val apiResource = namespacedApiResource(namespacedCoreResource)
203
+ val operator = NonCachingSingleResourceOperator (clientAdapter, createAPIResources(apiResource))
204
+ // when
205
+ operator .create(hasName)
206
+ // then
207
+ verify(resourceOp)
208
+ .patch(argThat(ArgumentMatcher <PatchContext > { context ->
209
+ context.patchType == PatchType .SERVER_SIDE_APPLY
210
+ }))
211
+ }
212
+
213
+ @Test
214
+ fun `#create should call #create if resource has no name` () {
215
+ // given
216
+ val hasNoName = PodBuilder (namespacedCoreResource)
217
+ .withNewMetadata()
218
+ .withManagedFields(ManagedFieldsEntry ())
219
+ .endMetadata()
220
+ .build()
221
+ val apiResource = namespacedApiResource(namespacedCoreResource)
222
+ val operator = NonCachingSingleResourceOperator (clientAdapter, createAPIResources(apiResource))
223
+ // when
224
+ operator .create(hasNoName)
225
+ // then
226
+ verify(resourceOp)
227
+ .create()
228
+ }
229
+
230
+ @Test
231
+ fun `#create should remove resourceVersion and uid before calling #create` () {
232
+ // given
233
+ val metadata = mock<ObjectMeta >()
234
+ val genericResource = mock<GenericKubernetesResource > {
235
+ on { getMetadata() } doReturn metadata
236
+ }
237
+ val hasNoName = PodBuilder (namespacedCoreResource)
238
+ .withMetadata(metadata)
239
+ .build()
240
+ val apiResource = namespacedApiResource(namespacedCoreResource)
241
+ val operator = NonCachingSingleResourceOperator (clientAdapter, createAPIResources(apiResource))
242
+ { resource -> genericResource }
243
+ // when
244
+ operator .create(hasNoName)
245
+ // then
246
+ verify(resourceOp).create() // make sure #create was called as this only applies when #create is called
247
+ verify(metadata, times(2 )).setResourceVersion(null ) //
248
+ verify(metadata, times(2 )).setUid(null )
249
+ }
250
+
251
+ @Test
252
+ fun `#create should call #create if resource has a name but managed fields` () {
253
+ // given
254
+ val hasNameAndManagedFields = PodBuilder (namespacedCoreResource)
255
+ .withNewMetadata()
256
+ .withManagedFields(ManagedFieldsEntry ())
257
+ .withName(" obiwan" )
258
+ .endMetadata()
259
+ .build()
260
+ val apiResource = namespacedApiResource(namespacedCoreResource)
261
+ val operator = NonCachingSingleResourceOperator (clientAdapter, createAPIResources(apiResource))
262
+ // when
263
+ operator .create(hasNameAndManagedFields)
264
+ // then
265
+ verify(resourceOp)
266
+ .create()
267
+ }
268
+
188
269
@Test
189
270
fun `#replace should call #inNamespace for namespaced resource` () {
190
271
// given
@@ -210,11 +291,40 @@ class NonCachingSingleResourceOperatorTest {
210
291
}
211
292
212
293
@Test
213
- fun `#replace should call #patch() if resource has a name` () {
294
+ fun `#replace should call #patch(STRATEGIC_MERGE ) if resource has a name and managed fields ` () {
214
295
// given
215
- val hasName = PodBuilder (namespacedCoreResource).build()
216
- hasName.metadata.name = " yoda"
217
- hasName.metadata.generateName = null
296
+ val metadata = ObjectMetaBuilder ()
297
+ .withManagedFields(ManagedFieldsEntry ())
298
+ .build().apply {
299
+ name = " yoda"
300
+ generateName = null
301
+ }
302
+ val hasName = PodBuilder (namespacedCoreResource)
303
+ .withMetadata(metadata)
304
+ .build()
305
+ val apiResource = namespacedApiResource(namespacedCoreResource)
306
+ val operator = NonCachingSingleResourceOperator (clientAdapter, createAPIResources(apiResource))
307
+ // when
308
+ operator .replace(hasName)
309
+ // then
310
+ verify(resourceOp)
311
+ .patch(argThat(ArgumentMatcher <PatchContext > { context ->
312
+ context.patchType == PatchType .STRATEGIC_MERGE
313
+ }))
314
+ }
315
+
316
+ @Test
317
+ fun `#replace should call #patch(SERVER_SIDE_APPLY) if resource has a name and NO managed fields` () {
318
+ // given
319
+ val metadata = ObjectMetaBuilder ()
320
+ .build().apply {
321
+ name = " yoda"
322
+ generateName = null
323
+ managedFields = null
324
+ }
325
+ val hasName = PodBuilder (namespacedCoreResource)
326
+ .withMetadata(metadata)
327
+ .build()
218
328
val apiResource = namespacedApiResource(namespacedCoreResource)
219
329
val operator = NonCachingSingleResourceOperator (clientAdapter, createAPIResources(apiResource))
220
330
// when
@@ -229,9 +339,10 @@ class NonCachingSingleResourceOperatorTest {
229
339
@Test
230
340
fun `#replace should call #create() if resource has NO name but has generateName` () {
231
341
// given
232
- val hasGeneratedName = PodBuilder (namespacedCoreResource).build()
233
- hasGeneratedName.metadata.name = null
234
- hasGeneratedName.metadata.generateName = " storm trooper clone"
342
+ val hasGeneratedName = PodBuilder (namespacedCoreResource).build().apply {
343
+ metadata.name = null
344
+ metadata.generateName = " storm trooper clone"
345
+ }
235
346
val operator = NonCachingSingleResourceOperator (
236
347
clientAdapter,
237
348
createAPIResources(namespacedApiResource(hasGeneratedName))
@@ -246,9 +357,10 @@ class NonCachingSingleResourceOperatorTest {
246
357
@Test(expected = ResourceException ::class )
247
358
fun `#replace should throw if resource has NO name NOR generateName` () {
248
359
// given
249
- val generatedName = PodBuilder (namespacedCoreResource).build()
250
- generatedName.metadata.name = null
251
- generatedName.metadata.generateName = null
360
+ val generatedName = PodBuilder (namespacedCoreResource).build().apply {
361
+ metadata.name = null
362
+ metadata.generateName = null
363
+ }
252
364
val apiResource = namespacedApiResource(namespacedCustomResource)
253
365
val operator = NonCachingSingleResourceOperator (clientAdapter, createAPIResources(apiResource))
254
366
// when
@@ -306,8 +418,10 @@ class NonCachingSingleResourceOperatorTest {
306
418
@Test
307
419
fun `#watch should return NULL if resource has NO name` () {
308
420
// given
309
- val unnamed = PodBuilder (namespacedCoreResource).build()
310
- unnamed.metadata.name = null
421
+ val unnamed = PodBuilder (namespacedCoreResource).build().apply {
422
+ metadata.name = null
423
+ }
424
+
311
425
val apiResource = namespacedApiResource(unnamed)
312
426
val operator = NonCachingSingleResourceOperator (clientAdapter, createAPIResources(apiResource))
313
427
// when
0 commit comments