client_test.go 6.4 KB

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