github.com/damirazo/docker@v1.9.0/integration-cli/requirements.go (about) 1 package main 2 3 import ( 4 "encoding/json" 5 "fmt" 6 "io/ioutil" 7 "log" 8 "net/http" 9 "os" 10 "os/exec" 11 "strings" 12 "time" 13 14 "github.com/go-check/check" 15 ) 16 17 type testCondition func() bool 18 19 type testRequirement struct { 20 Condition testCondition 21 SkipMessage string 22 } 23 24 // List test requirements 25 var ( 26 daemonExecDriver string 27 28 DaemonIsWindows = testRequirement{ 29 func() bool { return daemonPlatform == "windows" }, 30 "Test requires a Windows daemon", 31 } 32 DaemonIsLinux = testRequirement{ 33 func() bool { return daemonPlatform == "linux" }, 34 "Test requires a Linux daemon", 35 } 36 SameHostDaemon = testRequirement{ 37 func() bool { return isLocalDaemon }, 38 "Test requires docker daemon to runs on the same machine as CLI", 39 } 40 UnixCli = testRequirement{ 41 func() bool { return isUnixCli }, 42 "Test requires posix utilities or functionality to run.", 43 } 44 ExecSupport = testRequirement{ 45 func() bool { return supportsExec }, 46 "Test requires 'docker exec' capabilities on the tested daemon.", 47 } 48 Network = testRequirement{ 49 func() bool { 50 // Set a timeout on the GET at 15s 51 var timeout = time.Duration(15 * time.Second) 52 var url = "https://hub.docker.com" 53 54 client := http.Client{ 55 Timeout: timeout, 56 } 57 58 resp, err := client.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 "Test requires network availability, environment variable set to none to run in a non-network enabled mode.", 68 } 69 Apparmor = testRequirement{ 70 func() bool { 71 buf, err := ioutil.ReadFile("/sys/module/apparmor/parameters/enabled") 72 return err == nil && len(buf) > 1 && buf[0] == 'Y' 73 }, 74 "Test requires apparmor is enabled.", 75 } 76 RegistryHosting = testRequirement{ 77 func() bool { 78 // for now registry binary is built only if we're running inside 79 // container through `make test`. Figure that out by testing if 80 // registry binary is in PATH. 81 _, err := exec.LookPath(v2binary) 82 return err == nil 83 }, 84 fmt.Sprintf("Test requires an environment that can host %s in the same host", v2binary), 85 } 86 NotaryHosting = testRequirement{ 87 func() bool { 88 // for now notary binary is built only if we're running inside 89 // container through `make test`. Figure that out by testing if 90 // notary-server binary is in PATH. 91 _, err := exec.LookPath(notaryBinary) 92 return err == nil 93 }, 94 fmt.Sprintf("Test requires an environment that can host %s in the same host", notaryBinary), 95 } 96 NativeExecDriver = testRequirement{ 97 func() bool { 98 if daemonExecDriver == "" { 99 // get daemon info 100 status, body, err := sockRequest("GET", "/info", nil) 101 if err != nil || status != http.StatusOK { 102 log.Fatalf("sockRequest failed for /info: %v", err) 103 } 104 105 type infoJSON struct { 106 ExecutionDriver string 107 } 108 var info infoJSON 109 if err = json.Unmarshal(body, &info); err != nil { 110 log.Fatalf("unable to unmarshal body: %v", err) 111 } 112 113 daemonExecDriver = info.ExecutionDriver 114 } 115 116 return strings.HasPrefix(daemonExecDriver, "native") 117 }, 118 "Test requires the native (libcontainer) exec driver.", 119 } 120 NotOverlay = testRequirement{ 121 func() bool { 122 cmd := exec.Command("grep", "^overlay / overlay", "/proc/mounts") 123 if err := cmd.Run(); err != nil { 124 return true 125 } 126 return false 127 }, 128 "Test requires underlying root filesystem not be backed by overlay.", 129 } 130 IPv6 = testRequirement{ 131 func() bool { 132 cmd := exec.Command("test", "-f", "/proc/net/if_inet6") 133 134 if err := cmd.Run(); err != nil { 135 return true 136 } 137 return false 138 }, 139 "Test requires support for IPv6", 140 } 141 NotGCCGO = testRequirement{ 142 func() bool { 143 out, err := exec.Command("go", "version").Output() 144 if err != nil && strings.Contains(string(out), "gccgo") { 145 return true 146 } 147 return false 148 }, 149 "Test requires native Golang compiler instead of GCCGO", 150 } 151 NotUserNamespace = testRequirement{ 152 func() bool { 153 root := os.Getenv("DOCKER_REMAP_ROOT") 154 if root != "" { 155 return false 156 } 157 return true 158 }, 159 "Test cannot be run when remapping root", 160 } 161 ) 162 163 // testRequires checks if the environment satisfies the requirements 164 // for the test to run or skips the tests. 165 func testRequires(c *check.C, requirements ...testRequirement) { 166 for _, r := range requirements { 167 if !r.Condition() { 168 c.Skip(r.SkipMessage) 169 } 170 } 171 }