github.com/fabiokung/docker@v0.11.2-0.20170222101415-4534dcd49497/client/client_test.go (about) 1 package client 2 3 import ( 4 "bytes" 5 "encoding/json" 6 "io/ioutil" 7 "net/http" 8 "net/url" 9 "os" 10 "runtime" 11 "strings" 12 "testing" 13 14 "github.com/docker/docker/api" 15 "github.com/docker/docker/api/types" 16 "golang.org/x/net/context" 17 ) 18 19 func TestNewEnvClient(t *testing.T) { 20 if runtime.GOOS == "windows" { 21 t.Skip("skipping unix only test for windows") 22 } 23 cases := []struct { 24 envs map[string]string 25 expectedError string 26 expectedVersion string 27 }{ 28 { 29 envs: map[string]string{}, 30 expectedVersion: api.DefaultVersion, 31 }, 32 { 33 envs: map[string]string{ 34 "DOCKER_CERT_PATH": "invalid/path", 35 }, 36 expectedError: "Could not load X509 key pair: open invalid/path/cert.pem: no such file or directory. Make sure the key is not encrypted", 37 }, 38 { 39 envs: map[string]string{ 40 "DOCKER_CERT_PATH": "testdata/", 41 }, 42 expectedVersion: api.DefaultVersion, 43 }, 44 { 45 envs: map[string]string{ 46 "DOCKER_CERT_PATH": "testdata/", 47 "DOCKER_TLS_VERIFY": "1", 48 }, 49 expectedVersion: api.DefaultVersion, 50 }, 51 { 52 envs: map[string]string{ 53 "DOCKER_CERT_PATH": "testdata/", 54 "DOCKER_HOST": "https://notaunixsocket", 55 }, 56 expectedVersion: api.DefaultVersion, 57 }, 58 { 59 envs: map[string]string{ 60 "DOCKER_HOST": "host", 61 }, 62 expectedError: "unable to parse docker host `host`", 63 }, 64 { 65 envs: map[string]string{ 66 "DOCKER_HOST": "invalid://url", 67 }, 68 expectedVersion: api.DefaultVersion, 69 }, 70 { 71 envs: map[string]string{ 72 "DOCKER_API_VERSION": "anything", 73 }, 74 expectedVersion: "anything", 75 }, 76 { 77 envs: map[string]string{ 78 "DOCKER_API_VERSION": "1.22", 79 }, 80 expectedVersion: "1.22", 81 }, 82 } 83 for _, c := range cases { 84 recoverEnvs := setupEnvs(t, c.envs) 85 apiclient, err := NewEnvClient() 86 if c.expectedError != "" { 87 if err == nil { 88 t.Errorf("expected an error for %v", c) 89 } else if err.Error() != c.expectedError { 90 t.Errorf("expected an error %s, got %s, for %v", c.expectedError, err.Error(), c) 91 } 92 } else { 93 if err != nil { 94 t.Error(err) 95 } 96 version := apiclient.ClientVersion() 97 if version != c.expectedVersion { 98 t.Errorf("expected %s, got %s, for %v", c.expectedVersion, version, c) 99 } 100 } 101 102 if c.envs["DOCKER_TLS_VERIFY"] != "" { 103 // pedantic checking that this is handled correctly 104 tr := apiclient.client.Transport.(*http.Transport) 105 if tr.TLSClientConfig == nil { 106 t.Error("no TLS config found when DOCKER_TLS_VERIFY enabled") 107 } 108 109 if tr.TLSClientConfig.InsecureSkipVerify { 110 t.Error("TLS verification should be enabled") 111 } 112 } 113 114 recoverEnvs(t) 115 } 116 } 117 118 func setupEnvs(t *testing.T, envs map[string]string) func(*testing.T) { 119 oldEnvs := map[string]string{} 120 for key, value := range envs { 121 oldEnv := os.Getenv(key) 122 oldEnvs[key] = oldEnv 123 err := os.Setenv(key, value) 124 if err != nil { 125 t.Error(err) 126 } 127 } 128 return func(t *testing.T) { 129 for key, value := range oldEnvs { 130 err := os.Setenv(key, value) 131 if err != nil { 132 t.Error(err) 133 } 134 } 135 } 136 } 137 138 func TestGetAPIPath(t *testing.T) { 139 cases := []struct { 140 v string 141 p string 142 q url.Values 143 e string 144 }{ 145 {"", "/containers/json", nil, "/containers/json"}, 146 {"", "/containers/json", url.Values{}, "/containers/json"}, 147 {"", "/containers/json", url.Values{"s": []string{"c"}}, "/containers/json?s=c"}, 148 {"1.22", "/containers/json", nil, "/v1.22/containers/json"}, 149 {"1.22", "/containers/json", url.Values{}, "/v1.22/containers/json"}, 150 {"1.22", "/containers/json", url.Values{"s": []string{"c"}}, "/v1.22/containers/json?s=c"}, 151 {"v1.22", "/containers/json", nil, "/v1.22/containers/json"}, 152 {"v1.22", "/containers/json", url.Values{}, "/v1.22/containers/json"}, 153 {"v1.22", "/containers/json", url.Values{"s": []string{"c"}}, "/v1.22/containers/json?s=c"}, 154 {"v1.22", "/networks/kiwl$%^", nil, "/v1.22/networks/kiwl$%25%5E"}, 155 } 156 157 for _, cs := range cases { 158 c, err := NewClient("unix:///var/run/docker.sock", cs.v, nil, nil) 159 if err != nil { 160 t.Fatal(err) 161 } 162 g := c.getAPIPath(cs.p, cs.q) 163 if g != cs.e { 164 t.Fatalf("Expected %s, got %s", cs.e, g) 165 } 166 167 err = c.Close() 168 if nil != err { 169 t.Fatalf("close client failed, error message: %s", err) 170 } 171 } 172 } 173 174 func TestParseHost(t *testing.T) { 175 cases := []struct { 176 host string 177 proto string 178 addr string 179 base string 180 err bool 181 }{ 182 {"", "", "", "", true}, 183 {"foobar", "", "", "", true}, 184 {"foo://bar", "foo", "bar", "", false}, 185 {"tcp://localhost:2476", "tcp", "localhost:2476", "", false}, 186 {"tcp://localhost:2476/path", "tcp", "localhost:2476", "/path", false}, 187 } 188 189 for _, cs := range cases { 190 p, a, b, e := ParseHost(cs.host) 191 if cs.err && e == nil { 192 t.Fatalf("expected error, got nil") 193 } 194 if !cs.err && e != nil { 195 t.Fatal(e) 196 } 197 if cs.proto != p { 198 t.Fatalf("expected proto %s, got %s", cs.proto, p) 199 } 200 if cs.addr != a { 201 t.Fatalf("expected addr %s, got %s", cs.addr, a) 202 } 203 if cs.base != b { 204 t.Fatalf("expected base %s, got %s", cs.base, b) 205 } 206 } 207 } 208 209 func TestUpdateClientVersion(t *testing.T) { 210 client := &Client{ 211 client: newMockClient(func(req *http.Request) (*http.Response, error) { 212 splitQuery := strings.Split(req.URL.Path, "/") 213 queryVersion := splitQuery[1] 214 b, err := json.Marshal(types.Version{ 215 APIVersion: queryVersion, 216 }) 217 if err != nil { 218 return nil, err 219 } 220 return &http.Response{ 221 StatusCode: http.StatusOK, 222 Body: ioutil.NopCloser(bytes.NewReader(b)), 223 }, nil 224 }), 225 } 226 227 cases := []struct { 228 v string 229 }{ 230 {"1.20"}, 231 {"v1.21"}, 232 {"1.22"}, 233 {"v1.22"}, 234 } 235 236 for _, cs := range cases { 237 client.UpdateClientVersion(cs.v) 238 r, err := client.ServerVersion(context.Background()) 239 if err != nil { 240 t.Fatal(err) 241 } 242 if strings.TrimPrefix(r.APIVersion, "v") != strings.TrimPrefix(cs.v, "v") { 243 t.Fatalf("Expected %s, got %s", cs.v, r.APIVersion) 244 } 245 } 246 } 247 248 func TestNewEnvClientSetsDefaultVersion(t *testing.T) { 249 // Unset environment variables 250 envVarKeys := []string{ 251 "DOCKER_HOST", 252 "DOCKER_API_VERSION", 253 "DOCKER_TLS_VERIFY", 254 "DOCKER_CERT_PATH", 255 } 256 envVarValues := make(map[string]string) 257 for _, key := range envVarKeys { 258 envVarValues[key] = os.Getenv(key) 259 os.Setenv(key, "") 260 } 261 262 client, err := NewEnvClient() 263 if err != nil { 264 t.Fatal(err) 265 } 266 if client.version != api.DefaultVersion { 267 t.Fatalf("Expected %s, got %s", api.DefaultVersion, client.version) 268 } 269 270 expected := "1.22" 271 os.Setenv("DOCKER_API_VERSION", expected) 272 client, err = NewEnvClient() 273 if err != nil { 274 t.Fatal(err) 275 } 276 if client.version != expected { 277 t.Fatalf("Expected %s, got %s", expected, client.version) 278 } 279 280 // Restore environment variables 281 for _, key := range envVarKeys { 282 os.Setenv(key, envVarValues[key]) 283 } 284 }