Search in sources :

Example 76 with StrimziPodSet

use of io.strimzi.api.kafka.model.StrimziPodSet in project strimzi-kafka-operator by strimzi.

the class ManualPodCleanerTest method manualPodCleanup.

private void manualPodCleanup(VertxTestContext context, boolean useStrimziPodSets, List<Pod> pods, List<PersistentVolumeClaim> pvcs, List<String> podsToBeDeleted, List<String> pvcsToBeDeleted) {
    ResourceOperatorSupplier supplier = ResourceUtils.supplierWithMocks(false);
    StrimziPodSetOperator mockPodSetOps = supplier.strimziPodSetOperator;
    StatefulSetOperator mockStsOps = supplier.stsOperations;
    ArgumentCaptor<StatefulSet> stsReconciliationCaptor = ArgumentCaptor.forClass(StatefulSet.class);
    ArgumentCaptor<StrimziPodSet> podSetReconciliationCaptor = ArgumentCaptor.forClass(StrimziPodSet.class);
    if (useStrimziPodSets) {
        when(mockPodSetOps.getAsync(any(), eq(CONTROLLER_NAME))).thenReturn(Future.succeededFuture(new StrimziPodSetBuilder().withNewMetadata().withName(CONTROLLER_NAME).endMetadata().withNewSpec().withPods(PodSetUtils.podsToMaps(pods)).endSpec().build()));
        when(mockPodSetOps.reconcile(any(), any(), eq(CONTROLLER_NAME), podSetReconciliationCaptor.capture())).thenReturn(Future.succeededFuture());
    } else {
        when(mockStsOps.getAsync(any(), eq(CONTROLLER_NAME))).thenReturn(Future.succeededFuture(new StatefulSetBuilder().withNewMetadata().withName(CONTROLLER_NAME).endMetadata().build()));
        when(mockStsOps.deleteAsync(any(), any(), eq(CONTROLLER_NAME), anyBoolean())).thenReturn(Future.succeededFuture());
        when(mockStsOps.reconcile(any(), any(), eq(CONTROLLER_NAME), stsReconciliationCaptor.capture())).thenReturn(Future.succeededFuture());
    }
    PodOperator mockPodOps = supplier.podOperations;
    when(mockPodOps.listAsync(any(), eq(SELECTOR))).thenReturn(Future.succeededFuture(pods));
    ArgumentCaptor<String> podDeletionCaptor = ArgumentCaptor.forClass(String.class);
    when(mockPodOps.deleteAsync(any(), any(), podDeletionCaptor.capture(), anyBoolean())).thenReturn(Future.succeededFuture());
    when(mockPodOps.readiness(any(), any(), any(), anyLong(), anyLong())).thenReturn(Future.succeededFuture());
    PvcOperator mockPvcOps = supplier.pvcOperations;
    when(mockPvcOps.listAsync(any(), eq(SELECTOR))).thenReturn(Future.succeededFuture(pvcs));
    ArgumentCaptor<String> pvcDeletionCaptor = ArgumentCaptor.forClass(String.class);
    when(mockPvcOps.deleteAsync(any(), any(), pvcDeletionCaptor.capture(), anyBoolean())).thenReturn(Future.succeededFuture());
    ArgumentCaptor<String> pvcReconciliationCaptor = ArgumentCaptor.forClass(String.class);
    when(mockPvcOps.reconcile(any(), any(), pvcReconciliationCaptor.capture(), any())).thenReturn(Future.succeededFuture());
    ClusterOperatorConfig config;
    if (useStrimziPodSets) {
        config = ResourceUtils.dummyClusterOperatorConfig(VERSIONS, ClusterOperatorConfig.DEFAULT_OPERATION_TIMEOUT_MS, "+UseStrimziPodSets");
    } else {
        config = ResourceUtils.dummyClusterOperatorConfig(VERSIONS, ClusterOperatorConfig.DEFAULT_OPERATION_TIMEOUT_MS);
    }
    ManualPodCleaner cleaner = new ManualPodCleaner(Reconciliation.DUMMY_RECONCILIATION, CONTROLLER_NAME, SELECTOR, config, supplier);
    Checkpoint async = context.checkpoint();
    cleaner.maybeManualPodCleaning(pvcs).onComplete(context.succeeding(v -> context.verify(() -> {
        if (useStrimziPodSets) {
            if (podsToBeDeleted.size() > 0) {
                // PodSet was reconciled twice => once teo remove the deleted pod and once to add it back
                assertThat(podSetReconciliationCaptor.getAllValues().size(), is(2));
                assertThat(podSetReconciliationCaptor.getAllValues().get(0).getSpec().getPods().size(), is(2));
                assertThat(podSetReconciliationCaptor.getAllValues().get(1).getSpec().getPods().size(), is(3));
            } else {
                assertThat(podSetReconciliationCaptor.getAllValues().size(), is(0));
            }
        } else {
            if (podsToBeDeleted.size() > 0) {
                // StatefulSet was deleted once and reconciled once to recreate it
                verify(mockStsOps, times(1)).deleteAsync(any(), any(), eq(CONTROLLER_NAME), anyBoolean());
                assertThat(stsReconciliationCaptor.getAllValues().size(), is(1));
                assertThat(stsReconciliationCaptor.getValue(), is(notNullValue()));
            } else {
                verify(mockStsOps, never()).deleteAsync(any(), any(), eq(CONTROLLER_NAME), anyBoolean());
                assertThat(stsReconciliationCaptor.getAllValues().size(), is(0));
            }
        }
        // Verify the deleted pod
        assertThat(podDeletionCaptor.getAllValues().size(), is(podsToBeDeleted.size()));
        assertThat(podDeletionCaptor.getAllValues(), is(podsToBeDeleted));
        // Verify the deleted and recreated pvc
        assertThat(pvcDeletionCaptor.getAllValues().size(), is(pvcsToBeDeleted.size()));
        assertThat(pvcDeletionCaptor.getAllValues(), is(pvcsToBeDeleted));
        assertThat(pvcReconciliationCaptor.getAllValues().size(), is(pvcsToBeDeleted.size()));
        assertThat(pvcReconciliationCaptor.getAllValues(), is(pvcsToBeDeleted));
        async.flag();
    })));
}
Also used : StatefulSetBuilder(io.fabric8.kubernetes.api.model.apps.StatefulSetBuilder) AbstractScalableResourceOperator(io.strimzi.operator.common.operator.resource.AbstractScalableResourceOperator) VertxTestContext(io.vertx.junit5.VertxTestContext) CoreMatchers.is(org.hamcrest.CoreMatchers.is) ArgumentMatchers.any(org.mockito.ArgumentMatchers.any) ArgumentMatchers.anyLong(org.mockito.ArgumentMatchers.anyLong) StrimziPodSetOperator(io.strimzi.operator.common.operator.resource.StrimziPodSetOperator) ArgumentMatchers.eq(org.mockito.ArgumentMatchers.eq) ArgumentMatchers.anyBoolean(org.mockito.ArgumentMatchers.anyBoolean) CoreMatchers.notNullValue(org.hamcrest.CoreMatchers.notNullValue) ArgumentCaptor(org.mockito.ArgumentCaptor) ExtendWith(org.junit.jupiter.api.extension.ExtendWith) PodBuilder(io.fabric8.kubernetes.api.model.PodBuilder) KafkaVersionTestUtils(io.strimzi.operator.cluster.KafkaVersionTestUtils) StrimziPodSetBuilder(io.strimzi.api.kafka.model.StrimziPodSetBuilder) Map(java.util.Map) PodOperator(io.strimzi.operator.common.operator.resource.PodOperator) ResourceOperatorSupplier(io.strimzi.operator.cluster.operator.resource.ResourceOperatorSupplier) ResourceUtils(io.strimzi.operator.cluster.ResourceUtils) MatcherAssert.assertThat(org.hamcrest.MatcherAssert.assertThat) StatefulSetOperator(io.strimzi.operator.cluster.operator.resource.StatefulSetOperator) KafkaVersion(io.strimzi.operator.cluster.model.KafkaVersion) Pod(io.fabric8.kubernetes.api.model.Pod) PodSetUtils(io.strimzi.operator.cluster.model.PodSetUtils) Mockito.times(org.mockito.Mockito.times) Mockito.when(org.mockito.Mockito.when) VertxExtension(io.vertx.junit5.VertxExtension) StatefulSet(io.fabric8.kubernetes.api.model.apps.StatefulSet) PvcOperator(io.strimzi.operator.common.operator.resource.PvcOperator) Future(io.vertx.core.Future) Mockito.verify(org.mockito.Mockito.verify) Test(org.junit.jupiter.api.Test) Reconciliation(io.strimzi.operator.common.Reconciliation) List(java.util.List) Mockito.never(org.mockito.Mockito.never) Labels(io.strimzi.operator.common.model.Labels) StrimziPodSet(io.strimzi.api.kafka.model.StrimziPodSet) PersistentVolumeClaim(io.fabric8.kubernetes.api.model.PersistentVolumeClaim) Checkpoint(io.vertx.junit5.Checkpoint) PersistentVolumeClaimBuilder(io.fabric8.kubernetes.api.model.PersistentVolumeClaimBuilder) Collections(java.util.Collections) ClusterOperatorConfig(io.strimzi.operator.cluster.ClusterOperatorConfig) StrimziPodSet(io.strimzi.api.kafka.model.StrimziPodSet) StrimziPodSetOperator(io.strimzi.operator.common.operator.resource.StrimziPodSetOperator) ClusterOperatorConfig(io.strimzi.operator.cluster.ClusterOperatorConfig) PodOperator(io.strimzi.operator.common.operator.resource.PodOperator) StrimziPodSetBuilder(io.strimzi.api.kafka.model.StrimziPodSetBuilder) PvcOperator(io.strimzi.operator.common.operator.resource.PvcOperator) StatefulSetOperator(io.strimzi.operator.cluster.operator.resource.StatefulSetOperator) StatefulSetBuilder(io.fabric8.kubernetes.api.model.apps.StatefulSetBuilder) ResourceOperatorSupplier(io.strimzi.operator.cluster.operator.resource.ResourceOperatorSupplier) Checkpoint(io.vertx.junit5.Checkpoint) StatefulSet(io.fabric8.kubernetes.api.model.apps.StatefulSet)

Example 77 with StrimziPodSet

use of io.strimzi.api.kafka.model.StrimziPodSet in project strimzi-kafka-operator by strimzi.

the class StrimziPodSetControllerIT method testCrSelector.

/**
 * Tests that the controller will ignore pods or node sets when the Kafka cluster they belong to doesn't match the
 * custom resource selector
 *
 * @param context   Test context
 */
@Test
public void testCrSelector(VertxTestContext context) {
    String podSetName = "matching-podset";
    String otherPodSetName = "other-podset";
    String podName = podSetName + "-0";
    String preExistingPodName = podSetName + "-1";
    String otherPodName = otherPodSetName + "-0";
    String otherPreExistingPodName = otherPodSetName + "-1";
    try {
        // Create the pod set which should be reconciled
        Pod pod = pod(podName, KAFKA_NAME, podSetName);
        Pod preExistingPod = pod(preExistingPodName, KAFKA_NAME, podSetName);
        client.pods().inNamespace(NAMESPACE).create(preExistingPod);
        podSetOp().inNamespace(NAMESPACE).create(podSet(podSetName, KAFKA_NAME, pod));
        // Create the pod set which should be ignored
        Pod otherPod = pod(otherPodName, OTHER_KAFKA_NAME, otherPodSetName);
        Pod otherPreExistingPod = pod(otherPreExistingPodName, OTHER_KAFKA_NAME, otherPodSetName);
        client.pods().inNamespace(NAMESPACE).create(otherPreExistingPod);
        podSetOp().inNamespace(NAMESPACE).create(podSet(otherPodSetName, OTHER_KAFKA_NAME, otherPod));
        // Check that the pre-existing pod for matching pod set is deleted
        TestUtils.waitFor("Wait for the pre-existing Pod to be deleted", 100, 10_000, () -> client.pods().inNamespace(NAMESPACE).withName(preExistingPodName).get() == null, () -> context.failNow("Test timed out waiting for pod deletion!"));
        // Check that the pod for matching pod set is ready
        TestUtils.waitFor("Wait for Pod to be ready", 100, 10_000, () -> client.pods().inNamespace(NAMESPACE).withName(podName).isReady(), () -> context.failNow("Test timed out waiting for pod readiness!"));
        // Check status of the matching pod set which should be updated
        TestUtils.waitFor("Wait for StrimziPodSetStatus", 100, 10_000, () -> {
            StrimziPodSet podSet = podSetOp().inNamespace(NAMESPACE).withName(podSetName).get();
            return podSet.getStatus().getCurrentPods() == 1 && podSet.getStatus().getReadyPods() == 1 && podSet.getStatus().getPods() == 1;
        }, () -> context.failNow("Pod stats do not match"));
        // Check that the non-matching pod set was ignored
        assertThat(client.pods().inNamespace(NAMESPACE).withName(otherPodName).get(), is(nullValue()));
        assertThat(podSetOp().inNamespace(NAMESPACE).withName(otherPodSetName).get().getStatus(), is(nullValue()));
        assertThat(client.pods().inNamespace(NAMESPACE).withName(otherPreExistingPodName).get(), is(notNullValue()));
        context.completeNow();
    } finally {
        podSetOp().inNamespace(NAMESPACE).withName(podSetName).delete();
        podSetOp().inNamespace(NAMESPACE).withName(otherPodSetName).delete();
        client.pods().inNamespace(NAMESPACE).withName(otherPreExistingPodName).delete();
        client.pods().inNamespace(NAMESPACE).withName(preExistingPodName).delete();
    }
}
Also used : StrimziPodSet(io.strimzi.api.kafka.model.StrimziPodSet) Pod(io.fabric8.kubernetes.api.model.Pod) Test(org.junit.jupiter.api.Test)

Example 78 with StrimziPodSet

use of io.strimzi.api.kafka.model.StrimziPodSet in project strimzi-kafka-operator by strimzi.

the class StrimziPodSetControllerIT method testPodUpdates.

/**
 * Tests updates to pods in the StrimziPodSet:
 *   - StrimziPodSetController should not roll the pods => the dedicated rollers do it
 *   - The pod should not be marked as current when it is updated
 *
 * @param context   Test context
 */
@Test
public void testPodUpdates(VertxTestContext context) {
    String podSetName = "pod-updates";
    String podName = podSetName + "-0";
    try {
        Pod originalPod = pod(podName, KAFKA_NAME, podSetName);
        podSetOp().inNamespace(NAMESPACE).create(podSet(podSetName, KAFKA_NAME, originalPod));
        // Wait until the pod is ready
        TestUtils.waitFor("Wait for Pod to be ready", 100, 10_000, () -> client.pods().inNamespace(NAMESPACE).withName(podName).isReady(), () -> context.failNow("Test timed out waiting for pod readiness!"));
        // Check status of the PodSet
        TestUtils.waitFor("Wait for StrimziPodSetStatus", 100, 10_000, () -> {
            StrimziPodSet podSet = podSetOp().inNamespace(NAMESPACE).withName(podSetName).get();
            return podSet.getStatus().getCurrentPods() == 1 && podSet.getStatus().getReadyPods() == 1 && podSet.getStatus().getPods() == 1;
        }, () -> context.failNow("Pod stats do not match"));
        // Get resource version to double check the pod was not deleted
        Pod initialPod = client.pods().inNamespace(NAMESPACE).withName(podName).get();
        String resourceVersion = initialPod.getMetadata().getResourceVersion();
        // Update the pod with a new revision and
        Pod updatedPod = pod(podName, KAFKA_NAME, podSetName);
        updatedPod.getMetadata().getAnnotations().put(PodRevision.STRIMZI_REVISION_ANNOTATION, "new-revision");
        updatedPod.getSpec().setTerminationGracePeriodSeconds(1L);
        podSetOp().inNamespace(NAMESPACE).withName(podSetName).patch(podSet(podSetName, KAFKA_NAME, updatedPod));
        // Check status of the PodSet
        TestUtils.waitFor("Wait for StrimziPodSetStatus", 100, 10_000, () -> {
            StrimziPodSet podSet = podSetOp().inNamespace(NAMESPACE).withName(podSetName).get();
            return podSet.getStatus().getCurrentPods() == 0 && podSet.getStatus().getReadyPods() == 1 && podSet.getStatus().getPods() == 1;
        }, () -> context.failNow("Pod stats do not match"));
        // Check the pod was not changed
        Pod actualPod = client.pods().inNamespace(NAMESPACE).withName(podName).get();
        assertThat(actualPod.getMetadata().getResourceVersion(), is(resourceVersion));
        assertThat(actualPod.getMetadata().getAnnotations().get(PodRevision.STRIMZI_REVISION_ANNOTATION), is(originalPod.getMetadata().getAnnotations().get(PodRevision.STRIMZI_REVISION_ANNOTATION)));
        assertThat(actualPod.getSpec().getTerminationGracePeriodSeconds(), is(0L));
        context.completeNow();
    } finally {
        podSetOp().inNamespace(NAMESPACE).withName(podSetName).delete();
    }
}
Also used : StrimziPodSet(io.strimzi.api.kafka.model.StrimziPodSet) Pod(io.fabric8.kubernetes.api.model.Pod) Test(org.junit.jupiter.api.Test)

Example 79 with StrimziPodSet

use of io.strimzi.api.kafka.model.StrimziPodSet in project strimzi-kafka-operator by strimzi.

the class StrimziPodSetControllerIT method testOwnerReferencePatching.

/**
 * Tests patching of the owner reference in pre-existing pods
 *
 * @param context   Test context
 */
@Test
public void testOwnerReferencePatching(VertxTestContext context) {
    String podSetName = "owner-reference";
    String podName = podSetName + "-0";
    try {
        Pod pod = pod(podName, KAFKA_NAME, podSetName);
        client.pods().inNamespace(NAMESPACE).create(pod);
        // Wait until the pod is ready
        TestUtils.waitFor("Wait for Pod to be ready", 100, 10_000, () -> client.pods().inNamespace(NAMESPACE).withName(podName).isReady(), () -> context.failNow("Test timed out waiting for pod readiness!"));
        podSetOp().inNamespace(NAMESPACE).create(podSet(podSetName, KAFKA_NAME, pod));
        // Check status of the PodSet
        TestUtils.waitFor("Wait for StrimziPodSetStatus", 100, 10_000, () -> {
            StrimziPodSet podSet = podSetOp().inNamespace(NAMESPACE).withName(podSetName).get();
            return podSet.getStatus().getCurrentPods() == 1 && podSet.getStatus().getReadyPods() == 1 && podSet.getStatus().getPods() == 1;
        }, () -> context.failNow("Pod stats do not match"));
        // Get the pod and check that the owner reference was set
        Pod actualPod = client.pods().inNamespace(NAMESPACE).withName(podName).get();
        checkOwnerReference(actualPod, podSetName);
        context.completeNow();
    } finally {
        podSetOp().inNamespace(NAMESPACE).withName(podSetName).delete();
    }
}
Also used : StrimziPodSet(io.strimzi.api.kafka.model.StrimziPodSet) Pod(io.fabric8.kubernetes.api.model.Pod) Test(org.junit.jupiter.api.Test)

Example 80 with StrimziPodSet

use of io.strimzi.api.kafka.model.StrimziPodSet in project strimzi-kafka-operator by strimzi.

the class StrimziPodSetControllerMockTest method testOwnerReferencePatching.

/**
 * Tests patching of the owner reference in pre-existing pods
 *
 * @param context   Test context
 */
@Test
public void testOwnerReferencePatching(VertxTestContext context) {
    String podSetName = "owner-reference";
    String podName = podSetName + "-0";
    try {
        Pod pod = pod(podName, KAFKA_NAME, podSetName);
        client.pods().inNamespace(NAMESPACE).create(pod);
        // Wait until the pod is ready
        TestUtils.waitFor("Wait for Pod to be ready", 100, 10_000, () -> client.pods().inNamespace(NAMESPACE).withName(podName).isReady(), () -> context.failNow("Test timed out waiting for pod readiness!"));
        podSetOp().inNamespace(NAMESPACE).create(podSet(podSetName, KAFKA_NAME, pod));
        // Check status of the PodSet
        TestUtils.waitFor("Wait for StrimziPodSetStatus", 100, 10_000, () -> {
            StrimziPodSet podSet = podSetOp().inNamespace(NAMESPACE).withName(podSetName).get();
            return podSet.getStatus().getCurrentPods() == 1 && podSet.getStatus().getReadyPods() == 1 && podSet.getStatus().getPods() == 1;
        }, () -> context.failNow("Pod stats do not match"));
        // Get the pod and check that the owner reference was set
        Pod actualPod = client.pods().inNamespace(NAMESPACE).withName(podName).get();
        checkOwnerReference(actualPod, podSetName);
        context.completeNow();
    } finally {
        podSetOp().inNamespace(NAMESPACE).withName(podSetName).delete();
    }
}
Also used : StrimziPodSet(io.strimzi.api.kafka.model.StrimziPodSet) Pod(io.fabric8.kubernetes.api.model.Pod) Test(org.junit.jupiter.api.Test)

Aggregations

StrimziPodSet (io.strimzi.api.kafka.model.StrimziPodSet)106 Pod (io.fabric8.kubernetes.api.model.Pod)84 Test (org.junit.jupiter.api.Test)62 Reconciliation (io.strimzi.operator.common.Reconciliation)58 Kafka (io.strimzi.api.kafka.model.Kafka)54 KafkaBuilder (io.strimzi.api.kafka.model.KafkaBuilder)50 ResourceOperatorSupplier (io.strimzi.operator.cluster.operator.resource.ResourceOperatorSupplier)44 StatefulSetOperator (io.strimzi.operator.cluster.operator.resource.StatefulSetOperator)44 Labels (io.strimzi.operator.common.model.Labels)44 PodOperator (io.strimzi.operator.common.operator.resource.PodOperator)44 Checkpoint (io.vertx.junit5.Checkpoint)44 CoreMatchers.is (org.hamcrest.CoreMatchers.is)44 MatcherAssert.assertThat (org.hamcrest.MatcherAssert.assertThat)44 GenericKafkaListenerBuilder (io.strimzi.api.kafka.model.listener.arraylistener.GenericKafkaListenerBuilder)42 Map (java.util.Map)42 KubernetesClient (io.fabric8.kubernetes.client.KubernetesClient)40 PlatformFeaturesAvailability (io.strimzi.operator.PlatformFeaturesAvailability)38 KafkaVersionTestUtils (io.strimzi.operator.cluster.KafkaVersionTestUtils)38 KafkaCluster (io.strimzi.operator.cluster.model.KafkaCluster)38 ArrayList (java.util.ArrayList)38