diff --git a/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/dsl/internal/KubernetesListOperationsImpl.java b/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/dsl/internal/KubernetesListOperationsImpl.java index 78eb624be16..4410c301c3e 100644 --- a/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/dsl/internal/KubernetesListOperationsImpl.java +++ b/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/dsl/internal/KubernetesListOperationsImpl.java @@ -151,12 +151,12 @@ public Boolean delete(List lists) { @Override public Gettable fromServer() { - return new KubernetesListOperationsImpl(client, config, namespace, null, DeletionPropagation.BACKGROUND, true, deletingExisting, item, null); + return new KubernetesListOperationsImpl(client, config, namespace, null, context.getPropagationPolicy(), true, deletingExisting, item, null); } @Override public Createable deletingExisting() { - return new KubernetesListOperationsImpl(client, config, namespace, null, DeletionPropagation.BACKGROUND, fromServer, true, item, null); + return new KubernetesListOperationsImpl(client, config, namespace, null, context.getPropagationPolicy(), fromServer, true, item, null); } private List createItemsInKubernetesList(KubernetesList list) { diff --git a/kubernetes-itests/src/test/java/io/fabric8/kubernetes/RawCustomResourceIT.java b/kubernetes-itests/src/test/java/io/fabric8/kubernetes/RawCustomResourceIT.java index 79b4815dea7..0c0694ad32f 100644 --- a/kubernetes-itests/src/test/java/io/fabric8/kubernetes/RawCustomResourceIT.java +++ b/kubernetes-itests/src/test/java/io/fabric8/kubernetes/RawCustomResourceIT.java @@ -15,31 +15,13 @@ */ package io.fabric8.kubernetes; -import static org.assertj.core.api.Assertions.assertThat; -import static org.awaitility.Awaitility.await; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; - -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.nio.file.Files; -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.Map; -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.TimeUnit; - +import com.fasterxml.jackson.databind.ObjectMapper; import io.fabric8.commons.ClusterEntity; -import io.fabric8.kubernetes.api.model.Status; +import io.fabric8.kubernetes.client.KubernetesClient; import io.fabric8.kubernetes.client.Watcher; import io.fabric8.kubernetes.client.WatcherException; +import io.fabric8.kubernetes.client.dsl.base.CustomResourceDefinitionContext; import io.fabric8.kubernetes.client.utils.Serialization; -import org.apache.commons.io.FileUtils; import org.arquillian.cube.kubernetes.api.Session; import org.arquillian.cube.kubernetes.impl.requirement.RequiresKubernetes; import org.arquillian.cube.requirement.ArquillianConditionalRunner; @@ -50,10 +32,21 @@ import org.junit.Test; import org.junit.runner.RunWith; -import com.fasterxml.jackson.databind.ObjectMapper; +import java.io.IOException; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; -import io.fabric8.kubernetes.client.KubernetesClient; -import io.fabric8.kubernetes.client.dsl.base.CustomResourceDefinitionContext; +import static org.assertj.core.api.Assertions.assertThat; +import static org.awaitility.Awaitility.await; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; @RunWith(ArquillianConditionalRunner.class) @RequiresKubernetes diff --git a/kubernetes-itests/src/test/java/io/fabric8/kubernetes/ResourceIT.java b/kubernetes-itests/src/test/java/io/fabric8/kubernetes/ResourceIT.java index 4592fb4a590..f8d8d317d62 100644 --- a/kubernetes-itests/src/test/java/io/fabric8/kubernetes/ResourceIT.java +++ b/kubernetes-itests/src/test/java/io/fabric8/kubernetes/ResourceIT.java @@ -18,34 +18,44 @@ import io.fabric8.commons.ClusterEntity; import io.fabric8.kubernetes.api.model.ConfigMap; import io.fabric8.kubernetes.api.model.ConfigMapBuilder; +import io.fabric8.kubernetes.api.model.ContainerBuilder; import io.fabric8.kubernetes.api.model.DeletionPropagation; import io.fabric8.kubernetes.api.model.HasMetadata; import io.fabric8.kubernetes.api.model.IntOrString; import io.fabric8.kubernetes.api.model.KubernetesList; import io.fabric8.kubernetes.api.model.KubernetesListBuilder; +import io.fabric8.kubernetes.api.model.ObjectMetaBuilder; import io.fabric8.kubernetes.api.model.Pod; import io.fabric8.kubernetes.api.model.PodBuilder; import io.fabric8.kubernetes.api.model.PodListBuilder; +import io.fabric8.kubernetes.api.model.PodTemplateSpecBuilder; import io.fabric8.kubernetes.api.model.Service; import io.fabric8.kubernetes.api.model.ServiceBuilder; import io.fabric8.kubernetes.api.model.apps.Deployment; import io.fabric8.kubernetes.api.model.apps.DeploymentBuilder; +import io.fabric8.kubernetes.api.model.apps.DeploymentSpecBuilder; +import io.fabric8.kubernetes.api.model.apps.ReplicaSet; import io.fabric8.kubernetes.api.model.apps.ReplicaSetList; import io.fabric8.kubernetes.client.KubernetesClient; +import io.fabric8.kubernetes.client.utils.Utils; import org.arquillian.cube.kubernetes.api.Session; import org.arquillian.cube.kubernetes.impl.requirement.RequiresKubernetes; import org.arquillian.cube.requirement.ArquillianConditionalRunner; import org.jboss.arquillian.test.api.ArquillianResource; +import org.junit.After; import org.junit.AfterClass; import org.junit.Assert; +import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; import org.junit.runner.RunWith; import java.util.Collections; import java.util.List; +import java.util.UUID; import java.util.concurrent.Callable; import java.util.concurrent.TimeUnit; +import java.util.stream.Collectors; import static junit.framework.TestCase.assertNotNull; import static org.awaitility.Awaitility.await; @@ -56,35 +66,32 @@ @RunWith(ArquillianConditionalRunner.class) @RequiresKubernetes public class ResourceIT { + @ArquillianResource KubernetesClient client; @ArquillianResource Session session; - private final Deployment deployment = new DeploymentBuilder() - .withNewMetadata().withName("deploy1").endMetadata() - .withNewSpec() - .withReplicas(1) - .withNewSelector().withMatchLabels(Collections.singletonMap("run", "deploy1")).endSelector() - .withNewTemplate() - .withNewMetadata().withLabels(Collections.singletonMap("run", "deploy1")).endMetadata() - .withNewSpec() - .addNewContainer() - .withImage("httpd") - .withName("deploy1") - .addNewPort().withContainerPort(80).endPort() - .endContainer() - .endSpec() - .endTemplate() - .endSpec() - .build(); + private String deploymentName; + private Deployment deployment; @BeforeClass public static void init() { ClusterEntity.apply(ResourceIT.class.getResourceAsStream("/resource-it.yml")); } + @Before + public void setUp() { + deploymentName = UUID.randomUUID().toString(); + deployment = initDeployment(deploymentName); + } + + @After + public void tearDown() { + client.apps().deployments().withName(deploymentName).withGracePeriod(0L).delete(); + } + @Test public void get() { assertNotNull(client.pods().inNamespace(session.getNamespace()).withName("resource-pod-get").get()); @@ -162,30 +169,32 @@ public void delete() { } @Test - public void testDeleteExistingWithOrphanDeletion() { + public void testDeleteExistingWithOrphanDeletion() throws Exception { // Create Deployment client.resource(deployment).inNamespace(session.getNamespace()).createOrReplace(); await().atMost(30, TimeUnit.SECONDS).until(resourceIsReady(deployment)); - // get creationTimestamp of underlying replicaset. we expect this NOT to match later, meaning the orphan WAS deleted. - ReplicaSetList replicaSetList = client.apps().replicaSets().inNamespace(session.getNamespace()).withLabel("run", "deploy1").list(); + // get uid of underlying replicaset. we expect this NOT to match later, meaning the orphan WAS deleted. + ReplicaSetList replicaSetList = client.apps().replicaSets().inNamespace(session.getNamespace()).withLabel("run", deploymentName).list(); assertEquals(1, replicaSetList.getItems().size()); - String replicaSetCreationTimestamp = replicaSetList.getItems().get(0).getMetadata().getCreationTimestamp(); + String replicaSetUid = replicaSetList.getItems().get(0).getMetadata().getUid(); // Recreate deployment with deleteExisting - client.resource(deployment).inNamespace(session.getNamespace()).withPropagationPolicy(DeletionPropagation.FOREGROUND).deletingExisting().createOrReplace(); - await().atMost(30, TimeUnit.SECONDS).until(resourceIsReady(deployment)); - - // check that creationTimestamp DOES NOT MATCH original, meaning the orphan WAS deleted - replicaSetList = client.apps().replicaSets().inNamespace(session.getNamespace()).withLabel("run", "deploy1").list(); - assertEquals(1, replicaSetList.getItems().size()); - assertNotEquals(replicaSetCreationTimestamp, replicaSetList.getItems().get(0).getMetadata().getCreationTimestamp()); + client.resource(deployment).inNamespace(session.getNamespace()).deletingExisting().createOrReplace(); + final Callable> replicaSets = () -> client.apps().replicaSets() + .inNamespace(session.getNamespace()).withLabel("run", deploymentName).list().getItems().stream() + .filter(rs -> Utils.isNullOrEmpty(rs.getMetadata().getDeletionTimestamp())) + .collect(Collectors.toList()); + await().atMost(30, TimeUnit.SECONDS) + .until(() -> resourceIsReady(deployment).call() && replicaSets.call().size() == 1); + // check that uid DOES NOT MATCH original, meaning the orphan WAS deleted + assertNotEquals(replicaSetUid, replicaSets.call().iterator().next().getMetadata().getUid()); // cleanup - assertEquals(true, client.resource(deployment).inNamespace(session.getNamespace()).delete()); + assertEquals(true, client.resource(deployment).inNamespace(session.getNamespace()).withGracePeriod(0L).delete()); // Check whether child resources are also deleted await().atMost(30, TimeUnit.SECONDS) - .until(() -> client.apps().replicaSets().inNamespace(session.getNamespace()).withLabel("run", "deploy1").list().getItems().size() == 0); + .until(() -> client.apps().replicaSets().inNamespace(session.getNamespace()).withLabel("run", deploymentName).list().getItems().isEmpty()); } @Test @@ -194,10 +203,10 @@ public void testDeleteExistingWithoutOrphanDeletion() { client.resource(deployment).inNamespace(session.getNamespace()).createOrReplace(); await().atMost(30, TimeUnit.SECONDS).until(resourceIsReady(deployment)); - // get creationTimestamp of underlying replicaset. we expect this to match later, meaning the orphan was not deleted. - ReplicaSetList replicaSetList = client.apps().replicaSets().inNamespace(session.getNamespace()).withLabel("run", "deploy1").list(); + // get uid of underlying replicaset. we expect this to match later, meaning the orphan was not deleted. + ReplicaSetList replicaSetList = client.apps().replicaSets().inNamespace(session.getNamespace()).withLabel("run", deploymentName).list(); assertEquals(1, replicaSetList.getItems().size()); - String replicaSetCreationTimestamp = replicaSetList.getItems().get(0).getMetadata().getCreationTimestamp(); + String replicaSetUid= replicaSetList.getItems().get(0).getMetadata().getUid(); // Recreate deployment with deleteExisting client.resource(deployment) @@ -208,16 +217,16 @@ public void testDeleteExistingWithoutOrphanDeletion() { await().atMost(30, TimeUnit.SECONDS).until(resourceIsReady(deployment)); - // check that creationTimestamp matches original, meaning the orphan was not deleted - replicaSetList = client.apps().replicaSets().inNamespace(session.getNamespace()).withLabel("run", "deploy1").list(); + // check that uid matches original, meaning the orphan was not deleted + replicaSetList = client.apps().replicaSets().inNamespace(session.getNamespace()).withLabel("run", deploymentName).list(); assertEquals(1, replicaSetList.getItems().size()); - assertEquals(replicaSetCreationTimestamp, replicaSetList.getItems().get(0).getMetadata().getCreationTimestamp()); + assertEquals(replicaSetUid, replicaSetList.getItems().get(0).getMetadata().getUid()); // cleanup assertEquals(true, client.resource(deployment).inNamespace(session.getNamespace()).delete()); // Check whether child resources are also deleted await().atMost(30, TimeUnit.SECONDS) - .until(() -> client.apps().replicaSets().inNamespace(session.getNamespace()).withLabel("run", "deploy1").list().getItems().size() == 0); + .until(() -> client.apps().replicaSets().inNamespace(session.getNamespace()).withLabel("run", deploymentName).list().getItems().size() == 0); } @Test @@ -226,7 +235,7 @@ public void testDeletionWithOrphanDeletion() { client.resource(deployment).inNamespace(session.getNamespace()).createOrReplace(); await().atMost(30, TimeUnit.SECONDS).until(resourceIsReady(deployment)); // Check whether child resources are also created - assertEquals(1, client.apps().replicaSets().inNamespace(session.getNamespace()).withLabel("run", "deploy1").list().getItems().size()); + assertEquals(1, client.apps().replicaSets().inNamespace(session.getNamespace()).withLabel("run", deploymentName).list().getItems().size()); // Delete deployment Boolean deleted = client.resource(deployment).inNamespace(session.getNamespace()).withPropagationPolicy(DeletionPropagation.BACKGROUND).delete(); @@ -234,7 +243,7 @@ public void testDeletionWithOrphanDeletion() { // Check whether child resources are also deleted await().atMost(30, TimeUnit.SECONDS) - .until(() -> client.apps().replicaSets().inNamespace(session.getNamespace()).withLabel("run", "deploy1").list().getItems().size() == 0); + .until(() -> client.apps().replicaSets().inNamespace(session.getNamespace()).withLabel("run", deploymentName).list().getItems().size() == 0); } @Test @@ -243,7 +252,7 @@ public void testDeletionWithoutOrphanDeletion() { client.resource(deployment).inNamespace(session.getNamespace()).createOrReplace(); await().atMost(30, TimeUnit.SECONDS).until(resourceIsReady(deployment)); // Check whether child resources are also created - assertEquals(1, client.apps().replicaSets().inNamespace(session.getNamespace()).withLabel("run", "deploy1").list().getItems().size()); + assertEquals(1, client.apps().replicaSets().inNamespace(session.getNamespace()).withLabel("run", deploymentName).list().getItems().size()); // Delete deployment Boolean deleted = client.resource(deployment).inNamespace(session.getNamespace()).withPropagationPolicy(DeletionPropagation.ORPHAN).delete(); @@ -251,13 +260,13 @@ public void testDeletionWithoutOrphanDeletion() { // wait till deployment is deleted await().atMost(30, TimeUnit.SECONDS) - .until(() -> client.apps().deployments().inNamespace(session.getNamespace()).withLabel("run", "deploy1").list().getItems().size() == 0); + .until(() -> client.apps().deployments().inNamespace(session.getNamespace()).withLabel("run", deploymentName).list().getItems().size() == 0); // Check whether child resources are not deleted, they should be alive - assertEquals(1, client.apps().replicaSets().inNamespace(session.getNamespace()).withLabel("run", "deploy1").list().getItems().size()); + assertEquals(1, client.apps().replicaSets().inNamespace(session.getNamespace()).withLabel("run", deploymentName).list().getItems().size()); // cleanup resources which are not cleaned up during cascade deletion - client.apps().replicaSets().inNamespace(session.getNamespace()).withLabel("run", "deploy1").delete(); + client.apps().replicaSets().inNamespace(session.getNamespace()).withLabel("run", deploymentName).delete(); } private Callable resourceIsReady(HasMetadata resource) { @@ -272,4 +281,28 @@ private Callable resourceCleanedUp(HasMetadata resource) { public static void cleanup() { ClusterEntity.remove(ResourceIT.class.getResourceAsStream("/resource-it.yml")); } + + private static Deployment initDeployment(String name) { + return new DeploymentBuilder() + .withMetadata(new ObjectMetaBuilder() + .withName(name) + .build()) + .withSpec(new DeploymentSpecBuilder() + .withReplicas(1) + .withNewSelector().withMatchLabels(Collections.singletonMap("run", name)).endSelector() + .withTemplate(new PodTemplateSpecBuilder() + .withNewMetadata().withLabels(Collections.singletonMap("run", name)).endMetadata() + .withNewSpec() + .withTerminationGracePeriodSeconds(1L) + .addToContainers(new ContainerBuilder() + .withImage("busybox") + .withCommand("sh", "-c", "sleep 60") + .withName(name) + .addNewPort().withContainerPort(80).endPort() + .build()) + .endSpec() + .build()) + .build()) + .build(); + } }