Search in sources :

Example 1 with TimeoutException

use of io.strimzi.operator.common.operator.resource.TimeoutException in project strimzi by strimzi.

the class KafkaRollerTest method pod1NotReadyAfterRolling.

@Test
public void pod1NotReadyAfterRolling(VertxTestContext testContext) throws InterruptedException {
    PodOperator podOps = mockPodOps(podId -> podId == 1 ? failedFuture(new TimeoutException("Timeout")) : succeededFuture());
    StatefulSet sts = buildStatefulSet();
    TestingKafkaRoller kafkaRoller = rollerWithControllers(sts, podOps, 2);
    // On the first reconciliation we expect it to abort when it gets to pod 1
    doFailingRollingRestart(testContext, kafkaRoller, asList(0, 1, 2, 3, 4), KafkaRoller.FatalProblem.class, "Error while waiting for restarted pod c-kafka-1 to become ready", asList(1));
    // On the next reconciliation only pod 2 (controller) would need rolling, and we expect it to fail in the same way
    kafkaRoller = rollerWithControllers(sts, podOps, 2);
    clearRestarted();
    doFailingRollingRestart(testContext, kafkaRoller, asList(2, 3, 4), KafkaRoller.FatalProblem.class, "Error while waiting for non-restarted pod c-kafka-1 to become ready", emptyList());
}
Also used : PodOperator(io.strimzi.operator.common.operator.resource.PodOperator) StatefulSet(io.fabric8.kubernetes.api.model.apps.StatefulSet) TimeoutException(io.strimzi.operator.common.operator.resource.TimeoutException) Test(org.junit.jupiter.api.Test)

Example 2 with TimeoutException

use of io.strimzi.operator.common.operator.resource.TimeoutException in project strimzi by strimzi.

the class KafkaRollerTest method mockPodOps.

private PodOperator mockPodOps(Function<Integer, Future<Void>> readiness) {
    PodOperator podOps = mock(PodOperator.class);
    when(podOps.get(any(), any())).thenAnswer(invocation -> new PodBuilder().withNewMetadata().withNamespace(invocation.getArgument(0)).withName(invocation.getArgument(1)).endMetadata().build());
    when(podOps.readiness(any(), any(), any(), anyLong(), anyLong())).thenAnswer(invocationOnMock -> {
        String podName = invocationOnMock.getArgument(2);
        return readiness.apply(podName2Number(podName));
    });
    when(podOps.isReady(anyString(), anyString())).thenAnswer(invocationOnMock -> {
        String podName = invocationOnMock.getArgument(1);
        Future<Void> ready = readiness.apply(podName2Number(podName));
        if (ready.succeeded()) {
            return true;
        } else {
            if (ready.cause() instanceof TimeoutException) {
                return false;
            } else {
                throw ready.cause();
            }
        }
    });
    return podOps;
}
Also used : PodOperator(io.strimzi.operator.common.operator.resource.PodOperator) PodBuilder(io.fabric8.kubernetes.api.model.PodBuilder) ArgumentMatchers.anyString(org.mockito.ArgumentMatchers.anyString) TimeoutException(io.strimzi.operator.common.operator.resource.TimeoutException)

Example 3 with TimeoutException

use of io.strimzi.operator.common.operator.resource.TimeoutException in project strimzi by strimzi.

the class KafkaRollerTest method pod3NotReadyAfterRolling.

@Test
public void pod3NotReadyAfterRolling(VertxTestContext testContext) throws InterruptedException {
    PodOperator podOps = mockPodOps(podId -> podId == 3 ? failedFuture(new TimeoutException("Timeout")) : succeededFuture());
    StatefulSet sts = buildStatefulSet();
    TestingKafkaRoller kafkaRoller = rollerWithControllers(sts, podOps, 2);
    // On the first reconciliation we expect it to abort when it gets to pod 3 (but not 2, which is controller)
    doFailingRollingRestart(testContext, kafkaRoller, asList(0, 1, 2, 3, 4), KafkaRoller.FatalProblem.class, "Error while waiting for restarted pod c-kafka-3 to become ready", asList(3));
    // On the next reconciliation only pods 2 (controller) and 4 would need rolling, and we expect it to fail in the same way
    kafkaRoller = rollerWithControllers(sts, podOps, 2);
    clearRestarted();
    doFailingRollingRestart(testContext, kafkaRoller, asList(0, 1, 2, 4), KafkaRoller.FatalProblem.class, "Error while waiting for non-restarted pod c-kafka-3 to become ready", emptyList());
}
Also used : PodOperator(io.strimzi.operator.common.operator.resource.PodOperator) StatefulSet(io.fabric8.kubernetes.api.model.apps.StatefulSet) TimeoutException(io.strimzi.operator.common.operator.resource.TimeoutException) Test(org.junit.jupiter.api.Test)

Example 4 with TimeoutException

use of io.strimzi.operator.common.operator.resource.TimeoutException in project strimzi by strimzi.

the class Util method waitFor.

/**
 * Invoke the given {@code completed} supplier on a pooled thread approximately every {@code pollIntervalMs}
 * milliseconds until it returns true or {@code timeoutMs} milliseconds have elapsed.
 * @param reconciliation The reconciliation
 * @param vertx The vertx instance.
 * @param logContext A string used for context in logging.
 * @param logState The state we are waiting for use in log messages
 * @param pollIntervalMs The poll interval in milliseconds.
 * @param timeoutMs The timeout, in milliseconds.
 * @param completed Determines when the wait is complete by returning true.
 * @param failOnError Determine whether a given error thrown by {@code completed},
 *                    should result in the immediate completion of the returned Future.
 * @return A future that completes when the given {@code completed} indicates readiness.
 */
public static Future<Void> waitFor(Reconciliation reconciliation, Vertx vertx, String logContext, String logState, long pollIntervalMs, long timeoutMs, BooleanSupplier completed, Predicate<Throwable> failOnError) {
    Promise<Void> promise = Promise.promise();
    LOGGER.debugCr(reconciliation, "Waiting for {} to get {}", logContext, logState);
    long deadline = System.currentTimeMillis() + timeoutMs;
    Handler<Long> handler = new Handler<Long>() {

        @Override
        public void handle(Long timerId) {
            vertx.createSharedWorkerExecutor("kubernetes-ops-pool").executeBlocking(future -> {
                try {
                    if (completed.getAsBoolean()) {
                        future.complete();
                    } else {
                        LOGGER.traceCr(reconciliation, "{} is not {}", logContext, logState);
                        future.fail("Not " + logState + " yet");
                    }
                } catch (Throwable e) {
                    LOGGER.warnCr(reconciliation, "Caught exception while waiting for {} to get {}", logContext, logState, e);
                    future.fail(e);
                }
            }, true, res -> {
                if (res.succeeded()) {
                    LOGGER.debugCr(reconciliation, "{} is {}", logContext, logState);
                    promise.complete();
                } else {
                    if (failOnError.test(res.cause())) {
                        promise.fail(res.cause());
                    } else {
                        long timeLeft = deadline - System.currentTimeMillis();
                        if (timeLeft <= 0) {
                            String exceptionMessage = String.format("Exceeded timeout of %dms while waiting for %s to be %s", timeoutMs, logContext, logState);
                            LOGGER.errorCr(reconciliation, exceptionMessage);
                            promise.fail(new TimeoutException(exceptionMessage));
                        } else {
                            // Schedule ourselves to run again
                            vertx.setTimer(Math.min(pollIntervalMs, timeLeft), this);
                        }
                    }
                }
            });
        }
    };
    // Call the handler ourselves the first time
    handler.handle(null);
    return promise.future();
}
Also used : Handler(io.vertx.core.Handler) TimeoutException(io.strimzi.operator.common.operator.resource.TimeoutException)

Example 5 with TimeoutException

use of io.strimzi.operator.common.operator.resource.TimeoutException in project strimzi-kafka-operator by strimzi.

the class KafkaRollerTest method mockPodOps.

private PodOperator mockPodOps(Function<Integer, Future<Void>> readiness) {
    PodOperator podOps = mock(PodOperator.class);
    when(podOps.get(any(), any())).thenAnswer(invocation -> new PodBuilder().withNewMetadata().withNamespace(invocation.getArgument(0)).withName(invocation.getArgument(1)).endMetadata().build());
    when(podOps.readiness(any(), any(), any(), anyLong(), anyLong())).thenAnswer(invocationOnMock -> {
        String podName = invocationOnMock.getArgument(2);
        return readiness.apply(podName2Number(podName));
    });
    when(podOps.isReady(anyString(), anyString())).thenAnswer(invocationOnMock -> {
        String podName = invocationOnMock.getArgument(1);
        Future<Void> ready = readiness.apply(podName2Number(podName));
        if (ready.succeeded()) {
            return true;
        } else {
            if (ready.cause() instanceof TimeoutException) {
                return false;
            } else {
                throw ready.cause();
            }
        }
    });
    return podOps;
}
Also used : PodOperator(io.strimzi.operator.common.operator.resource.PodOperator) PodBuilder(io.fabric8.kubernetes.api.model.PodBuilder) ArgumentMatchers.anyString(org.mockito.ArgumentMatchers.anyString) TimeoutException(io.strimzi.operator.common.operator.resource.TimeoutException)

Aggregations

TimeoutException (io.strimzi.operator.common.operator.resource.TimeoutException)12 PodOperator (io.strimzi.operator.common.operator.resource.PodOperator)10 StatefulSet (io.fabric8.kubernetes.api.model.apps.StatefulSet)8 Test (org.junit.jupiter.api.Test)8 PodBuilder (io.fabric8.kubernetes.api.model.PodBuilder)2 Handler (io.vertx.core.Handler)2 ArgumentMatchers.anyString (org.mockito.ArgumentMatchers.anyString)2