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