We are testing our code using the kubernetes client.
We experienced some interesting behaviour, in case of deletion e.g. a config map:
GET return 200, DELETE returns 200: delete() returns trueGET return 200, DELETE returns 404: delete() returns trueGET return 404, DELETE is not called at all: delete() returns falseGET return 200, DELETE returns 400: delete() throws KubernetesClientExceptionGET return 400: delete() throws KubernetesClientExceptionSo we wonder, if it is really consistent, that 200/404 returns true and 404/nc returns false. Both should return true or both should return false.
So we wonder, is it perhaps a bug?
According io.fabric8.kubernetes.client.dsl.base.BaseOperation.delete() it is meant to return false in case of 404
try {
deleteList();
return true;
} catch (KubernetesClientException e) {
if (e.getCode() != 404) {
throw e;
}
return false;
}
Here is the test example:
// GET return 200
// DELETE return 200
// kubernetesClient.delete() return TRUE
server.expect().get().withPath(format("/api/v1/namespaces/{}/configmaps?labelSelector={}%3D{}", namespace, name, value)).andReturn(200, configMapList).once();
server.expect().delete().withPath(format("/api/v1/namespaces/{}/configmaps/{}", namespace, configMapName)).andReturn(200, StringUtils.EMPTY).once();
actual = kubernetesClient.configMaps().inNamespace(namespace).withLabelSelector(labelSelector).delete();
assertTrue(actual)
// GET return 200
// DELETE return 404
// kubernetesClient.delete() return TRUE
server.expect().get().withPath(format("/api/v1/namespaces/{}/configmaps?labelSelector={}%3D{}", namespace, name, value)).andReturn(200, configMapList).once();
server.expect().delete().withPath(format("/api/v1/namespaces/{}/configmaps/{}", namespace, configMapName)).andReturn(404, StringUtils.EMPTY).once();
actual = kubernetesClient.configMaps().inNamespace(namespace).withLabelSelector(labelSelector).delete();
assertTrue(actual)
// GET return 404
// kubernetesClient.delete() return FALSE
server.expect().get().withPath(format("/api/v1/namespaces/{}/configmaps?labelSelector={}%3D{}", namespace, name, value)).andReturn(404, StringUtils.EMPTY).once();
actual = kubernetesClient.configMaps().inNamespace(namespace).withLabelSelector(labelSelector).delete();
assertFalse(actual)
// GET return 200
// DELETE return 400
// kubernetesClient.delete() throws KubernetesClientException
server.expect().get().withPath(format("/api/v1/namespaces/{}/configmaps?labelSelector={}%3D{}", namespace, name, value)).andReturn(200, configMapList).once();
server.expect().delete().withPath(format("/api/v1/namespaces/{}/configmaps/{}", namespace, configMapName)).andReturn(400, StringUtils.EMPTY).once();
try {
kubernetesClient.configMaps().inNamespace(namespace).withLabelSelector(labelSelector).delete();
fail();
} catch (io.fabric8.kubernetes.client.KubernetesClientException e) {
assertTrue(true);
}
// GET return 400
// kubernetesClient.delete() throws KubernetesClientException
server.expect().get().withPath(format("/api/v1/namespaces/{}/configmaps?labelSelector={}%3D{}", namespace, name, value)).andReturn(400, StringUtils.EMPTY).once();
try {
kubernetesClient.configMaps().inNamespace(namespace).withLabelSelector(labelSelector).delete();
fail();
} catch (io.fabric8.kubernetes.client.KubernetesClientException e) {
assertTrue(true);
}