ping_test.go 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. package client // import "github.com/docker/docker/client"
  2. import (
  3. "context"
  4. "errors"
  5. "io"
  6. "net/http"
  7. "strings"
  8. "testing"
  9. "gotest.tools/v3/assert"
  10. is "gotest.tools/v3/assert/cmp"
  11. )
  12. // TestPingFail tests that when a server sends a non-successful response that we
  13. // can still grab API details, when set.
  14. // Some of this is just exercising the code paths to make sure there are no
  15. // panics.
  16. func TestPingFail(t *testing.T) {
  17. var withHeader bool
  18. client := &Client{
  19. client: newMockClient(func(req *http.Request) (*http.Response, error) {
  20. resp := &http.Response{StatusCode: http.StatusInternalServerError}
  21. if withHeader {
  22. resp.Header = http.Header{}
  23. resp.Header.Set("API-Version", "awesome")
  24. resp.Header.Set("Docker-Experimental", "true")
  25. }
  26. resp.Body = io.NopCloser(strings.NewReader("some error with the server"))
  27. return resp, nil
  28. }),
  29. }
  30. ping, err := client.Ping(context.Background())
  31. assert.ErrorContains(t, err, "some error with the server")
  32. assert.Check(t, is.Equal(false, ping.Experimental))
  33. assert.Check(t, is.Equal("", ping.APIVersion))
  34. withHeader = true
  35. ping2, err := client.Ping(context.Background())
  36. assert.ErrorContains(t, err, "some error with the server")
  37. assert.Check(t, is.Equal(true, ping2.Experimental))
  38. assert.Check(t, is.Equal("awesome", ping2.APIVersion))
  39. }
  40. // TestPingWithError tests the case where there is a protocol error in the ping.
  41. // This test is mostly just testing that there are no panics in this code path.
  42. func TestPingWithError(t *testing.T) {
  43. client := &Client{
  44. client: newMockClient(func(req *http.Request) (*http.Response, error) {
  45. resp := &http.Response{StatusCode: http.StatusInternalServerError}
  46. resp.Header = http.Header{}
  47. resp.Header.Set("API-Version", "awesome")
  48. resp.Header.Set("Docker-Experimental", "true")
  49. resp.Body = io.NopCloser(strings.NewReader("some error with the server"))
  50. return resp, errors.New("some error")
  51. }),
  52. }
  53. ping, err := client.Ping(context.Background())
  54. assert.ErrorContains(t, err, "some error")
  55. assert.Check(t, is.Equal(false, ping.Experimental))
  56. assert.Check(t, is.Equal("", ping.APIVersion))
  57. }
  58. // TestPingSuccess tests that we are able to get the expected API headers/ping
  59. // details on success.
  60. func TestPingSuccess(t *testing.T) {
  61. client := &Client{
  62. client: newMockClient(func(req *http.Request) (*http.Response, error) {
  63. resp := &http.Response{StatusCode: http.StatusOK}
  64. resp.Header = http.Header{}
  65. resp.Header.Set("API-Version", "awesome")
  66. resp.Header.Set("Docker-Experimental", "true")
  67. resp.Body = io.NopCloser(strings.NewReader("OK"))
  68. return resp, nil
  69. }),
  70. }
  71. ping, err := client.Ping(context.Background())
  72. assert.NilError(t, err)
  73. assert.Check(t, is.Equal(true, ping.Experimental))
  74. assert.Check(t, is.Equal("awesome", ping.APIVersion))
  75. }
  76. // TestPingHeadFallback tests that the client falls back to GET if HEAD fails.
  77. func TestPingHeadFallback(t *testing.T) {
  78. tests := []struct {
  79. status int
  80. expected string
  81. }{
  82. {
  83. status: http.StatusOK,
  84. expected: http.MethodHead,
  85. },
  86. {
  87. status: http.StatusInternalServerError,
  88. expected: http.MethodHead,
  89. },
  90. {
  91. status: http.StatusNotFound,
  92. expected: "HEAD, GET",
  93. },
  94. {
  95. status: http.StatusMethodNotAllowed,
  96. expected: "HEAD, GET",
  97. },
  98. }
  99. for _, tc := range tests {
  100. tc := tc
  101. t.Run(http.StatusText(tc.status), func(t *testing.T) {
  102. var reqs []string
  103. client := &Client{
  104. client: newMockClient(func(req *http.Request) (*http.Response, error) {
  105. reqs = append(reqs, req.Method)
  106. resp := &http.Response{StatusCode: http.StatusOK}
  107. if req.Method == http.MethodHead {
  108. resp.StatusCode = tc.status
  109. }
  110. resp.Header = http.Header{}
  111. resp.Header.Add("API-Version", strings.Join(reqs, ", "))
  112. return resp, nil
  113. }),
  114. }
  115. ping, _ := client.Ping(context.Background())
  116. assert.Check(t, is.Equal(ping.APIVersion, tc.expected))
  117. })
  118. }
  119. }