All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.fabric8.kubernetes.assertions.support.PodWatcher Maven / Gradle / Ivy

Go to download

This library provides a bunch of helpful assertj assertions for working with the kubernetes-api.

The newest version!
package io.fabric8.kubernetes.assertions.support;

import io.fabric8.kubernetes.api.KubernetesHelper;
import io.fabric8.kubernetes.api.model.Container;
import io.fabric8.kubernetes.api.model.Pod;
import io.fabric8.kubernetes.api.model.PodSpec;
import io.fabric8.kubernetes.assertions.PodSelectionAssert;
import io.fabric8.kubernetes.client.KubernetesClient;
import io.fabric8.kubernetes.client.KubernetesClientException;
import io.fabric8.kubernetes.client.Watcher;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.Closeable;
import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;

import static io.fabric8.kubernetes.api.KubernetesHelper.getName;
import static io.fabric8.kubernetes.assertions.support.LogHelpers.getRestartCount;
import static org.assertj.core.api.Assertions.fail;
import static org.fusesource.jansi.Ansi.Color.GREEN;
import static org.fusesource.jansi.Ansi.ansi;

/**
 *
 */
public class PodWatcher
        implements Watcher, Closeable
{
    private static final transient Logger LOG = LoggerFactory.getLogger(PodWatcher.class);

    private final PodSelectionAssert podSelectionAssert;
    private final long readyTimeoutMS;
    private final long readyPeriodMS;
    private Map podAsserts = new ConcurrentHashMap<>();
    private Map podLogWatchers = new ConcurrentHashMap<>();
    private CountDownLatch podReady = new CountDownLatch(1);
    private CountDownLatch podReadyForEntireDuration = new CountDownLatch(1);
    private File basedir;

    public PodWatcher(PodSelectionAssert podSelectionAssert, long readyTimeoutMS, long readyPeriodMS)
    {
        this.podSelectionAssert = podSelectionAssert;
        this.readyTimeoutMS = readyTimeoutMS;
        this.readyPeriodMS = readyPeriodMS;
    }

    public KubernetesClient getClient()
    {
        return podSelectionAssert.getClient();
    }

    public String getDescription()
    {
        return podSelectionAssert.getDescription();
    }

    public long getReadyTimeoutMS()
    {
        return readyTimeoutMS;
    }

    public long getReadyPeriodMS()
    {
        return readyPeriodMS;
    }

    /**
     * Lets load the current pods as we don't get watch events for current pods
     */
    public void loadCurrentPods()
    {
        List pods = podSelectionAssert.getPods();
        for (Pod pod : pods) {
            String name = getName(pod);
            if (!podAsserts.containsKey(name)) {
                onPod(name, pod);
            }
        }
    }

    @Override
    public void eventReceived(Action action, Pod pod)
    {
        String name = getName(pod);
        if (action.equals(Action.ERROR)) {
            LOG.warn("Got error for pod " + name);
        }
        else if (action.equals(Action.DELETED)) {
            closeCloser(name, this.podAsserts);
            closeCloser(name, this.podLogWatchers);
        }
        else {
            onPod(name, pod);
        }
    }

    protected void onPod(String name, Pod pod)
    {
        PodAsserter asserter = podAsserts.get(name);
        if (asserter == null) {
            asserter = new PodAsserter(this, name, pod);
            podAsserts.put(name, asserter);
        }
        else {
            asserter.updated(pod);
        }
        int restartCount = getRestartCount(pod);
        PodSpec spec = pod.getSpec();
        if (spec != null) {
            if (KubernetesHelper.isPodRunning(pod)) {
                List containers = spec.getContainers();
                for (Container container : containers) {
                    File logFileName = LogHelpers.getLogFileName(getBaseDir(), name, container, restartCount);
                    String key = logFileName.getName();
                    PodLogWatcher logWatcher = podLogWatchers.get(key);
                    if (logWatcher == null) {
                        try {
                            String containerName = container.getName();
                            logWatcher = new PodLogWatcher(this, name, pod, containerName, logFileName);
                            podLogWatchers.put(key, logWatcher);
                            LOG.info("Watching pod " + name + " container " + containerName + " log at file: " + logFileName.getAbsolutePath());
                        }
                        catch (Exception e) {
                            LOG.warn("Failed to create PodLogWatcher: " + e, e);
                        }
                    }
                }
            }
        }
        File yamlFile = new File(getBaseDir(), "target/test-pod-status/" + name + ".yml");
        yamlFile.getParentFile().mkdirs();
        try {
            KubernetesHelper.saveYaml(pod, yamlFile);
        }
        catch (IOException e) {
            LOG.warn("Failed to write " + yamlFile + ". " + e, e);
        }
    }

    public File getBaseDir()
    {
        if (basedir == null) {
            basedir = new File(System.getProperty("basedir", "."));
        }
        return basedir;
    }

    public void setBasedir(File basedir)
    {
        this.basedir = basedir;
    }

    @Override
    public void onClose(KubernetesClientException e)
    {
        LOG.info("onClose: " + e);
    }

    public void close()
    {
        closeAllClosers(podAsserts);
        closeAllClosers(podLogWatchers);
    }

    protected void closeAllClosers(Map closers)
    {
        while (!closers.isEmpty()) {
            Set keys = closers.keySet();
            for (String key : keys) {
                closeCloser(key, closers);
            }
        }
    }

    private void closeCloser(String name, Map closers)
    {
        Closeable closer = closers.remove(name);
        if (closer != null) {
            try {
                closer.close();
            }
            catch (Exception e) {
                LOG.warn("Failed to close " + closer + ". " + e, e);
            }
        }
    }

    public void waitForPodReady()
    {
        boolean ready = false;
        try {
            ready = podReady.await(readyTimeoutMS, TimeUnit.MILLISECONDS);
        }
        catch (InterruptedException e) {
            LOG.warn("Interupted waiting for podReady: " + e);
            ready = podReady.getCount() == 0L;
        }
        if (!ready) {
            fail(podSelectionAssert.getDescription() + " did not have a pod become Ready within " + readyTimeoutMS + " millis");
        }

        try {
            ready = podReadyForEntireDuration.await(readyPeriodMS * 2, TimeUnit.MILLISECONDS);
        }
        catch (InterruptedException e) {
            LOG.warn("Interupted waiting for podReadyForEntireDuration: " + e);
            ready = podReadyForEntireDuration.getCount() == 0L;
        }
        if (!ready) {
            fail(podSelectionAssert.getDescription() + " did not have a pod Ready for a duration of " + readyPeriodMS + " millis");
        }
    }

    public void podIsReadyForEntireDuration(String name, Pod pod)
    {
        String message = "Pod " + name + " has been Ready now for " + getReadyPeriodMS() + " millis!";
        LOG.info(ansi().fg(GREEN).a(message).reset().toString());
        podReadyForEntireDuration.countDown();
    }

    public void podIsReady(String name, Pod pod)
    {
        if (podReady.getCount() > 0) {
            String message = "Pod " + name + " is Ready!";
            LOG.info(ansi().fg(GREEN).a(message).reset().toString());
            podReady.countDown();
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy