requirements_test.go 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183
  1. package main
  2. import (
  3. "context"
  4. "fmt"
  5. "net/http"
  6. "os"
  7. "os/exec"
  8. "strings"
  9. "testing"
  10. "time"
  11. "github.com/containerd/containerd/plugin"
  12. "github.com/docker/docker/api/types"
  13. "github.com/docker/docker/api/types/swarm"
  14. "github.com/docker/docker/client"
  15. "github.com/docker/docker/integration-cli/cli"
  16. "github.com/docker/docker/integration-cli/requirement"
  17. "github.com/docker/docker/testutil/registry"
  18. )
  19. func DaemonIsWindows() bool {
  20. return testEnv.DaemonInfo.OSType == "windows"
  21. }
  22. func DaemonIsLinux() bool {
  23. return testEnv.DaemonInfo.OSType == "linux"
  24. }
  25. func OnlyDefaultNetworks(ctx context.Context) bool {
  26. apiClient, err := client.NewClientWithOpts(client.FromEnv)
  27. if err != nil {
  28. return false
  29. }
  30. networks, err := apiClient.NetworkList(ctx, types.NetworkListOptions{})
  31. if err != nil || len(networks) > 0 {
  32. return false
  33. }
  34. return true
  35. }
  36. func IsAmd64() bool {
  37. return testEnv.DaemonVersion.Arch == "amd64"
  38. }
  39. func NotArm64() bool {
  40. return testEnv.DaemonVersion.Arch != "arm64"
  41. }
  42. func NotPpc64le() bool {
  43. return testEnv.DaemonVersion.Arch != "ppc64le"
  44. }
  45. func UnixCli() bool {
  46. return isUnixCli
  47. }
  48. func GitHubActions() bool {
  49. return os.Getenv("GITHUB_ACTIONS") != ""
  50. }
  51. func Network() bool {
  52. // Set a timeout on the GET at 15s
  53. const timeout = 15 * time.Second
  54. const url = "https://hub.docker.com"
  55. c := http.Client{
  56. Timeout: timeout,
  57. }
  58. resp, err := c.Get(url)
  59. if err != nil && strings.Contains(err.Error(), "use of closed network connection") {
  60. panic(fmt.Sprintf("Timeout for GET request on %s", url))
  61. }
  62. if resp != nil {
  63. resp.Body.Close()
  64. }
  65. return err == nil
  66. }
  67. func Apparmor() bool {
  68. if strings.HasPrefix(testEnv.DaemonInfo.OperatingSystem, "SUSE Linux Enterprise Server ") {
  69. return false
  70. }
  71. buf, err := os.ReadFile("/sys/module/apparmor/parameters/enabled")
  72. return err == nil && len(buf) > 1 && buf[0] == 'Y'
  73. }
  74. // containerdSnapshotterEnabled checks if the daemon in the test-environment is
  75. // configured with containerd-snapshotters enabled.
  76. func containerdSnapshotterEnabled() bool {
  77. for _, v := range testEnv.DaemonInfo.DriverStatus {
  78. if v[0] == "driver-type" {
  79. return v[1] == string(plugin.SnapshotPlugin)
  80. }
  81. }
  82. return false
  83. }
  84. func IPv6() bool {
  85. cmd := exec.Command("test", "-f", "/proc/net/if_inet6")
  86. return cmd.Run() != nil
  87. }
  88. func UserNamespaceROMount() bool {
  89. // quick case--userns not enabled in this test run
  90. if os.Getenv("DOCKER_REMAP_ROOT") == "" {
  91. return true
  92. }
  93. if _, _, err := dockerCmdWithError("run", "--rm", "--read-only", "busybox", "date"); err != nil {
  94. return false
  95. }
  96. return true
  97. }
  98. func NotUserNamespace() bool {
  99. root := os.Getenv("DOCKER_REMAP_ROOT")
  100. return root == ""
  101. }
  102. func UserNamespaceInKernel() bool {
  103. if _, err := os.Stat("/proc/self/uid_map"); os.IsNotExist(err) {
  104. /*
  105. * This kernel-provided file only exists if user namespaces are
  106. * supported
  107. */
  108. return false
  109. }
  110. // We need extra check on redhat based distributions
  111. if f, err := os.Open("/sys/module/user_namespace/parameters/enable"); err == nil {
  112. defer f.Close()
  113. b := make([]byte, 1)
  114. _, _ = f.Read(b)
  115. return string(b) != "N"
  116. }
  117. return true
  118. }
  119. func IsPausable() bool {
  120. if testEnv.DaemonInfo.OSType == "windows" {
  121. return testEnv.DaemonInfo.Isolation.IsHyperV()
  122. }
  123. return true
  124. }
  125. // RegistryHosting returns whether the host can host a registry (v2) or not
  126. func RegistryHosting() bool {
  127. // for now registry binary is built only if we're running inside
  128. // container through `make test`. Figure that out by testing if
  129. // registry binary is in PATH.
  130. _, err := exec.LookPath(registry.V2binary)
  131. return err == nil
  132. }
  133. func RuntimeIsWindowsContainerd() bool {
  134. return os.Getenv("DOCKER_WINDOWS_CONTAINERD_RUNTIME") == "1"
  135. }
  136. func SwarmInactive() bool {
  137. return testEnv.DaemonInfo.Swarm.LocalNodeState == swarm.LocalNodeStateInactive
  138. }
  139. func TODOBuildkit() bool {
  140. return os.Getenv("DOCKER_BUILDKIT") == ""
  141. }
  142. func DockerCLIVersion(t testing.TB) string {
  143. out := cli.DockerCmd(t, "--version").Stdout()
  144. version := strings.Fields(out)
  145. if len(version) < 3 {
  146. t.Fatal("unknown version output", version)
  147. }
  148. return version[2]
  149. }
  150. // testRequires checks if the environment satisfies the requirements
  151. // for the test to run or skips the tests.
  152. func testRequires(t *testing.T, requirements ...requirement.Test) {
  153. t.Helper()
  154. requirement.Is(t, requirements...)
  155. }