blob: e8bc3a9bc06cb2d1682f9442bec6c52d35cf59da [file] [log] [blame]
package main
import (
"context"
"fmt"
"net/http"
"os"
"os/exec"
"strings"
"testing"
"time"
"github.com/containerd/containerd/plugin"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/swarm"
"github.com/docker/docker/api/types/versions"
"github.com/docker/docker/client"
"github.com/docker/docker/integration-cli/requirement"
"github.com/docker/docker/testutil/registry"
)
func ArchitectureIsNot(arch string) bool {
return os.Getenv("DOCKER_ENGINE_GOARCH") != arch
}
func DaemonIsWindows() bool {
return testEnv.OSType == "windows"
}
func DaemonIsLinux() bool {
return testEnv.OSType == "linux"
}
func MinimumAPIVersion(version string) func() bool {
return func() bool {
return versions.GreaterThanOrEqualTo(testEnv.DaemonAPIVersion(), version)
}
}
func OnlyDefaultNetworks() bool {
apiClient, err := client.NewClientWithOpts(client.FromEnv)
if err != nil {
return false
}
networks, err := apiClient.NetworkList(context.TODO(), types.NetworkListOptions{})
if err != nil || len(networks) > 0 {
return false
}
return true
}
func IsAmd64() bool {
return os.Getenv("DOCKER_ENGINE_GOARCH") == "amd64"
}
func NotArm() bool {
return ArchitectureIsNot("arm")
}
func NotArm64() bool {
return ArchitectureIsNot("arm64")
}
func NotPpc64le() bool {
return ArchitectureIsNot("ppc64le")
}
func UnixCli() bool {
return isUnixCli
}
func GitHubActions() bool {
return os.Getenv("GITHUB_ACTIONS") != ""
}
func Network() bool {
// Set a timeout on the GET at 15s
const timeout = 15 * time.Second
const url = "https://hub.docker.com"
c := http.Client{
Timeout: timeout,
}
resp, err := c.Get(url)
if err != nil && strings.Contains(err.Error(), "use of closed network connection") {
panic(fmt.Sprintf("Timeout for GET request on %s", url))
}
if resp != nil {
resp.Body.Close()
}
return err == nil
}
func Apparmor() bool {
if strings.HasPrefix(testEnv.DaemonInfo.OperatingSystem, "SUSE Linux Enterprise Server ") {
return false
}
buf, err := os.ReadFile("/sys/module/apparmor/parameters/enabled")
return err == nil && len(buf) > 1 && buf[0] == 'Y'
}
func Devicemapper() bool {
return strings.HasPrefix(testEnv.DaemonInfo.Driver, "devicemapper")
}
// containerdSnapshotterEnabled checks if the daemon in the test-environment is
// configured with containerd-snapshotters enabled.
func containerdSnapshotterEnabled() bool {
for _, v := range testEnv.DaemonInfo.DriverStatus {
if v[0] == "driver-type" {
return v[1] == string(plugin.SnapshotPlugin)
}
}
return false
}
func IPv6() bool {
cmd := exec.Command("test", "-f", "/proc/net/if_inet6")
return cmd.Run() != nil
}
func UserNamespaceROMount() bool {
// quick case--userns not enabled in this test run
if os.Getenv("DOCKER_REMAP_ROOT") == "" {
return true
}
if _, _, err := dockerCmdWithError("run", "--rm", "--read-only", "busybox", "date"); err != nil {
return false
}
return true
}
func NotUserNamespace() bool {
root := os.Getenv("DOCKER_REMAP_ROOT")
return root == ""
}
func UserNamespaceInKernel() bool {
if _, err := os.Stat("/proc/self/uid_map"); os.IsNotExist(err) {
/*
* This kernel-provided file only exists if user namespaces are
* supported
*/
return false
}
// We need extra check on redhat based distributions
if f, err := os.Open("/sys/module/user_namespace/parameters/enable"); err == nil {
defer f.Close()
b := make([]byte, 1)
_, _ = f.Read(b)
return string(b) != "N"
}
return true
}
func IsPausable() bool {
if testEnv.OSType == "windows" {
return testEnv.DaemonInfo.Isolation.IsHyperV()
}
return true
}
// RegistryHosting returns whether the host can host a registry (v2) or not
func RegistryHosting() bool {
// for now registry binary is built only if we're running inside
// container through `make test`. Figure that out by testing if
// registry binary is in PATH.
_, err := exec.LookPath(registry.V2binary)
return err == nil
}
func RuntimeIsWindowsContainerd() bool {
return os.Getenv("DOCKER_WINDOWS_CONTAINERD_RUNTIME") == "1"
}
func SwarmInactive() bool {
return testEnv.DaemonInfo.Swarm.LocalNodeState == swarm.LocalNodeStateInactive
}
func TODOBuildkit() bool {
return os.Getenv("DOCKER_BUILDKIT") == ""
}
func DockerCLIVersion(t testing.TB) string {
out, _ := dockerCmd(t, "--version")
version := strings.Fields(out)
if len(version) < 3 {
t.Fatal("unknown version output", version)
}
return version[2]
}
// testRequires checks if the environment satisfies the requirements
// for the test to run or skips the tests.
func testRequires(t *testing.T, requirements ...requirement.Test) {
t.Helper()
requirement.Is(t, requirements...)
}