github.com/noxiouz/docker@v0.7.3-0.20160629055221-3d231c78e8c5/integration-cli/requirements.go (about) 1 package main 2 3 import ( 4 "fmt" 5 "io/ioutil" 6 "net/http" 7 "os" 8 "os/exec" 9 "strings" 10 "time" 11 12 "github.com/docker/docker/utils" 13 "github.com/go-check/check" 14 ) 15 16 type testCondition func() bool 17 18 type testRequirement struct { 19 Condition testCondition 20 SkipMessage string 21 } 22 23 // List test requirements 24 var ( 25 DaemonIsWindows = testRequirement{ 26 func() bool { return daemonPlatform == "windows" }, 27 "Test requires a Windows daemon", 28 } 29 DaemonIsLinux = testRequirement{ 30 func() bool { return daemonPlatform == "linux" }, 31 "Test requires a Linux daemon", 32 } 33 ExperimentalDaemon = testRequirement{ 34 func() bool { return utils.ExperimentalBuild() }, 35 "Test requires an experimental daemon", 36 } 37 NotExperimentalDaemon = testRequirement{ 38 func() bool { return !utils.ExperimentalBuild() }, 39 "Test requires a non experimental daemon", 40 } 41 NotArm = testRequirement{ 42 func() bool { return os.Getenv("DOCKER_ENGINE_GOARCH") != "arm" }, 43 "Test requires a daemon not running on ARM", 44 } 45 NotPpc64le = testRequirement{ 46 func() bool { return os.Getenv("DOCKER_ENGINE_GOARCH") != "ppc64le" }, 47 "Test requires a daemon not running on ppc64le", 48 } 49 NotS390X = testRequirement{ 50 func() bool { return os.Getenv("DOCKER_ENGINE_GOARCH") != "s390x" }, 51 "Test requires a daemon not running on s390x", 52 } 53 SameHostDaemon = testRequirement{ 54 func() bool { return isLocalDaemon }, 55 "Test requires docker daemon to run on the same machine as CLI", 56 } 57 UnixCli = testRequirement{ 58 func() bool { return isUnixCli }, 59 "Test requires posix utilities or functionality to run.", 60 } 61 ExecSupport = testRequirement{ 62 func() bool { return supportsExec }, 63 "Test requires 'docker exec' capabilities on the tested daemon.", 64 } 65 Network = testRequirement{ 66 func() bool { 67 // Set a timeout on the GET at 15s 68 var timeout = time.Duration(15 * time.Second) 69 var url = "https://hub.docker.com" 70 71 client := http.Client{ 72 Timeout: timeout, 73 } 74 75 resp, err := client.Get(url) 76 if err != nil && strings.Contains(err.Error(), "use of closed network connection") { 77 panic(fmt.Sprintf("Timeout for GET request on %s", url)) 78 } 79 if resp != nil { 80 resp.Body.Close() 81 } 82 return err == nil 83 }, 84 "Test requires network availability, environment variable set to none to run in a non-network enabled mode.", 85 } 86 Apparmor = testRequirement{ 87 func() bool { 88 buf, err := ioutil.ReadFile("/sys/module/apparmor/parameters/enabled") 89 return err == nil && len(buf) > 1 && buf[0] == 'Y' 90 }, 91 "Test requires apparmor is enabled.", 92 } 93 RegistryHosting = testRequirement{ 94 func() bool { 95 // for now registry binary is built only if we're running inside 96 // container through `make test`. Figure that out by testing if 97 // registry binary is in PATH. 98 _, err := exec.LookPath(v2binary) 99 return err == nil 100 }, 101 fmt.Sprintf("Test requires an environment that can host %s in the same host", v2binary), 102 } 103 NotaryHosting = testRequirement{ 104 func() bool { 105 // for now notary binary is built only if we're running inside 106 // container through `make test`. Figure that out by testing if 107 // notary-server binary is in PATH. 108 _, err := exec.LookPath(notaryServerBinary) 109 return err == nil 110 }, 111 fmt.Sprintf("Test requires an environment that can host %s in the same host", notaryServerBinary), 112 } 113 NotaryServerHosting = testRequirement{ 114 func() bool { 115 // for now notary-server binary is built only if we're running inside 116 // container through `make test`. Figure that out by testing if 117 // notary-server binary is in PATH. 118 _, err := exec.LookPath(notaryServerBinary) 119 return err == nil 120 }, 121 fmt.Sprintf("Test requires an environment that can host %s in the same host", notaryServerBinary), 122 } 123 NotOverlay = testRequirement{ 124 func() bool { 125 return !strings.HasPrefix(daemonStorageDriver, "overlay") 126 }, 127 "Test requires underlying root filesystem not be backed by overlay.", 128 } 129 130 Devicemapper = testRequirement{ 131 func() bool { 132 return strings.HasPrefix(daemonStorageDriver, "devicemapper") 133 }, 134 "Test requires underlying root filesystem to be backed by devicemapper.", 135 } 136 137 IPv6 = testRequirement{ 138 func() bool { 139 cmd := exec.Command("test", "-f", "/proc/net/if_inet6") 140 141 if err := cmd.Run(); err != nil { 142 return true 143 } 144 return false 145 }, 146 "Test requires support for IPv6", 147 } 148 NotGCCGO = testRequirement{ 149 func() bool { 150 out, err := exec.Command("go", "version").Output() 151 if err == nil && strings.Contains(string(out), "gccgo") { 152 return false 153 } 154 return true 155 }, 156 "Test requires native Golang compiler instead of GCCGO", 157 } 158 UserNamespaceInKernel = testRequirement{ 159 func() bool { 160 if _, err := os.Stat("/proc/self/uid_map"); os.IsNotExist(err) { 161 /* 162 * This kernel-provided file only exists if user namespaces are 163 * supported 164 */ 165 return false 166 } 167 168 // We need extra check on redhat based distributions 169 if f, err := os.Open("/sys/module/user_namespace/parameters/enable"); err == nil { 170 b := make([]byte, 1) 171 _, _ = f.Read(b) 172 if string(b) == "N" { 173 return false 174 } 175 return true 176 } 177 178 return true 179 }, 180 "Kernel must have user namespaces configured and enabled.", 181 } 182 NotUserNamespace = testRequirement{ 183 func() bool { 184 root := os.Getenv("DOCKER_REMAP_ROOT") 185 if root != "" { 186 return false 187 } 188 return true 189 }, 190 "Test cannot be run when remapping root", 191 } 192 ) 193 194 // testRequires checks if the environment satisfies the requirements 195 // for the test to run or skips the tests. 196 func testRequires(c *check.C, requirements ...testRequirement) { 197 for _, r := range requirements { 198 if !r.Condition() { 199 c.Skip(r.SkipMessage) 200 } 201 } 202 }