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  }