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