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

org.opennms.smoketest.utils.TestContainerUtils Maven / Gradle / Ivy

/*
 * Licensed to The OpenNMS Group, Inc (TOG) under one or more
 * contributor license agreements.  See the LICENSE.md file
 * distributed with this work for additional information
 * regarding copyright ownership.
 *
 * TOG licenses this file to You under the GNU Affero General
 * Public License Version 3 (the "License") or (at your option)
 * any later version.  You may not use this file except in
 * compliance with the License.  You may obtain a copy of the
 * License at:
 *
 *      https://www.gnu.org/licenses/agpl-3.0.txt
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
 * either express or implied.  See the License for the specific
 * language governing permissions and limitations under the
 * License.
 */
package org.opennms.smoketest.utils;

import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.testcontainers.containers.Container;

import com.github.dockerjava.api.DockerClient;
import com.github.dockerjava.api.command.CreateContainerCmd;
import com.github.dockerjava.api.exception.DockerException;
import com.github.dockerjava.api.model.ExposedPort;
import com.github.dockerjava.api.model.HostConfig;
import com.github.dockerjava.api.model.InternetProtocol;
import com.github.dockerjava.api.model.Ports;
import com.google.common.io.CharStreams;

public class TestContainerUtils {

    private static final Logger LOG = LoggerFactory.getLogger(TestContainerUtils.class);

    // Constants used when setting UID/GID behavior to match OpenShift
    public static final int OPENSHIFT_CONTAINER_UID_RANGE_MIN = 1000600000;
    public static final int OPENSHIFT_CONTAINER_UID_RANGE_MAX = 1000700000;
    public static final int OPENSHIFT_CONTAINER_GID = 0;

    private static final int NUM_CPUS_PER_CONTAINER = 2;

    /**
     * Set memory and CPU limits on the container in oder to help provide
     * more consistent timing across systems and runs.
     *
     * @param cmd reference to the create container command, obtain with withCreateContainerCmdModifier
     */
    public static void setGlobalMemAndCpuLimits(CreateContainerCmd cmd) {
        HostConfig hostConfig = cmd.getHostConfig();
        if (hostConfig == null) {
            hostConfig = new HostConfig();
        }
        hostConfig.withMemory(4 * 1024 * 1024 * 1024L); // Hard limit to 4GB of memory
        // cpu-period denotes the period in which container CPU utilisation is tracked
        hostConfig.withCpuPeriod(TimeUnit.MILLISECONDS.toMicros(100));
        // cpu-quota is the total amount of CPU time that a container can use in each cpu-period
        // say this is equal to the cpu-period set above, then the container can use 1 CPU at 100%
        // if this is 2x the cpu-period. then the container can use 2 CPUs at 100%, and so on...
        hostConfig.withCpuQuota(hostConfig.getCpuPeriod() * NUM_CPUS_PER_CONTAINER);
    }

    /**
     * Reach into the container, pull the contents of a file, and return it as a string.
     *
     * @param container container
     * @param pathInContainer path to the file in the container
     * @return the contents of the file as a string
     */
    public static String getFileFromContainerAsString(Container container, Path pathInContainer) {
        return (String)container.copyFileFromContainer(pathInContainer.toString(),
                is -> CharStreams.toString(new InputStreamReader((InputStream)is, StandardCharsets.UTF_8)));
    }

    /**
     * Retrieves the internal IP address of the container.
     *
     * @param container container
     * @return ip address
     */
    public static String getInternalIpAddress(Container container) {
        return container.getContainerInfo().getNetworkSettings().getNetworks()
                .entrySet().iterator().next().getValue().getIpAddress();
    }

    /**
     * Restarts the container.
     *
     * @param container container to restart
     */
    public static void restartContainer(Container container) {
        final DockerClient docker = container.getDockerClient();
        final String id = container.getContainerId();
        try {
            LOG.info("Restarting container: {} -> {}", container.getDockerImageName(), id);
            docker.restartContainerCmd(container.getContainerId()).exec();
            LOG.info("Container restarted: {} -> {}", container.getDockerImageName(), id);
        } catch (DockerException e) {
            LOG.warn("Unexpected exception while restarting container {}", id, e);
        }
    }

    /**
     * Workaround for UDP ports -- see https://github.com/testcontainers/testcontainers-java/issues/554
     *
     * @param cmd
     * @param ports
     */
    public static void exposePortsAsUdp(CreateContainerCmd cmd, int... ports) {
        // Add already exposed TCP ports
        List exposedPorts = new ArrayList<>();
        for (ExposedPort p : cmd.getExposedPorts()) {
            exposedPorts.add(p);
        }
        // Add our UDP portts
        for (int port : ports) {
            exposedPorts.add(ExposedPort.udp(port));
        }
        cmd.withExposedPorts(exposedPorts);

        // Add previous port bindings
        final var hostConfig = cmd.getHostConfig();
        if (hostConfig != null) {
            Ports portBindings = hostConfig.getPortBindings();
            // Add port bindings for our UDP ports
            for (int port : ports) {
                portBindings.bind(ExposedPort.udp(port), Ports.Binding.empty());
            }
            hostConfig.withPortBindings(portBindings);
        }
    }

    /**
     * Workaround for UDP ports -- see https://github.com/testcontainers/testcontainers-java/issues/554
     *
     * @param container
     * @param port
     * @return
     */
    //
    public static int getMappedUdpPort(Container container, int port) {
        final ExposedPort searchForPort = new ExposedPort(port, InternetProtocol.UDP);
        final Ports.Binding[] bindings = container.getContainerInfo()
                .getNetworkSettings()
                .getPorts()
                .getBindings()
                .get(searchForPort);
        if (bindings == null || bindings.length == 0) {
            throw new RuntimeException("No exposed port bindings found for " + searchForPort);
        }
        return Integer.parseInt(bindings[0].getHostPortSpec());
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy