client/ping_test.go
4f0d95fa
 package client // import "github.com/docker/docker/client"
27ef09a4
 
 import (
7d62e40f
 	"context"
27ef09a4
 	"errors"
 	"io/ioutil"
 	"net/http"
 	"strings"
 	"testing"
 
38457285
 	"gotest.tools/assert"
 	is "gotest.tools/assert/cmp"
27ef09a4
 )
 
 // TestPingFail tests that when a server sends a non-successful response that we
 // can still grab API details, when set.
f781ec45
 // Some of this is just exercising the code paths to make sure there are no
27ef09a4
 // panics.
 func TestPingFail(t *testing.T) {
 	var withHeader bool
 	client := &Client{
 		client: newMockClient(func(req *http.Request) (*http.Response, error) {
 			resp := &http.Response{StatusCode: http.StatusInternalServerError}
 			if withHeader {
 				resp.Header = http.Header{}
 				resp.Header.Set("API-Version", "awesome")
 				resp.Header.Set("Docker-Experimental", "true")
 			}
 			resp.Body = ioutil.NopCloser(strings.NewReader("some error with the server"))
 			return resp, nil
 		}),
 	}
 
 	ping, err := client.Ping(context.Background())
46b80550
 	assert.ErrorContains(t, err, "some error with the server")
6be0f709
 	assert.Check(t, is.Equal(false, ping.Experimental))
 	assert.Check(t, is.Equal("", ping.APIVersion))
27ef09a4
 
 	withHeader = true
 	ping2, err := client.Ping(context.Background())
46b80550
 	assert.ErrorContains(t, err, "some error with the server")
6be0f709
 	assert.Check(t, is.Equal(true, ping2.Experimental))
 	assert.Check(t, is.Equal("awesome", ping2.APIVersion))
27ef09a4
 }
 
 // TestPingWithError tests the case where there is a protocol error in the ping.
 // This test is mostly just testing that there are no panics in this code path.
 func TestPingWithError(t *testing.T) {
 	client := &Client{
 		client: newMockClient(func(req *http.Request) (*http.Response, error) {
 			resp := &http.Response{StatusCode: http.StatusInternalServerError}
 			resp.Header = http.Header{}
 			resp.Header.Set("API-Version", "awesome")
 			resp.Header.Set("Docker-Experimental", "true")
 			resp.Body = ioutil.NopCloser(strings.NewReader("some error with the server"))
 			return resp, errors.New("some error")
 		}),
 	}
 
 	ping, err := client.Ping(context.Background())
46b80550
 	assert.ErrorContains(t, err, "some error")
6be0f709
 	assert.Check(t, is.Equal(false, ping.Experimental))
 	assert.Check(t, is.Equal("", ping.APIVersion))
27ef09a4
 }
 
 // TestPingSuccess tests that we are able to get the expected API headers/ping
 // details on success.
 func TestPingSuccess(t *testing.T) {
 	client := &Client{
 		client: newMockClient(func(req *http.Request) (*http.Response, error) {
46b80550
 			resp := &http.Response{StatusCode: http.StatusOK}
27ef09a4
 			resp.Header = http.Header{}
 			resp.Header.Set("API-Version", "awesome")
 			resp.Header.Set("Docker-Experimental", "true")
46b80550
 			resp.Body = ioutil.NopCloser(strings.NewReader("OK"))
27ef09a4
 			return resp, nil
 		}),
 	}
 	ping, err := client.Ping(context.Background())
46b80550
 	assert.NilError(t, err)
6be0f709
 	assert.Check(t, is.Equal(true, ping.Experimental))
 	assert.Check(t, is.Equal("awesome", ping.APIVersion))
27ef09a4
 }
7e7e100b
 
 // TestPingHeadFallback tests that the client falls back to GET if HEAD fails.
 func TestPingHeadFallback(t *testing.T) {
 	tests := []struct {
 		status   int
 		expected string
 	}{
 		{
 			status:   http.StatusOK,
 			expected: "HEAD",
 		},
 		{
 			status:   http.StatusInternalServerError,
 			expected: "HEAD",
 		},
 		{
 			status:   http.StatusNotFound,
 			expected: "HEAD, GET",
 		},
 		{
 			status:   http.StatusMethodNotAllowed,
 			expected: "HEAD, GET",
 		},
 	}
 
 	for _, tc := range tests {
 		tc := tc
 		t.Run(http.StatusText(tc.status), func(t *testing.T) {
 			var reqs []string
 			client := &Client{
 				client: newMockClient(func(req *http.Request) (*http.Response, error) {
 					reqs = append(reqs, req.Method)
 					resp := &http.Response{StatusCode: http.StatusOK}
 					if req.Method == http.MethodHead {
 						resp.StatusCode = tc.status
 					}
 					resp.Header = http.Header{}
 					resp.Header.Add("API-Version", strings.Join(reqs, ", "))
 					return resp, nil
 				}),
 			}
 			ping, _ := client.Ping(context.Background())
 			assert.Check(t, is.Equal(ping.APIVersion, tc.expected))
 		})
 	}
 }