github.com/AliyunContainerService/cli@v0.0.0-20181009023821-814ced4b30d0/cli/command/cli_test.go (about) 1 package command 2 3 import ( 4 "context" 5 "crypto/x509" 6 "os" 7 "runtime" 8 "testing" 9 10 cliconfig "github.com/docker/cli/cli/config" 11 "github.com/docker/cli/cli/config/configfile" 12 "github.com/docker/cli/cli/flags" 13 "github.com/docker/docker/api" 14 "github.com/docker/docker/api/types" 15 "github.com/docker/docker/client" 16 "github.com/pkg/errors" 17 "gotest.tools/assert" 18 is "gotest.tools/assert/cmp" 19 "gotest.tools/env" 20 "gotest.tools/fs" 21 ) 22 23 func TestNewAPIClientFromFlags(t *testing.T) { 24 host := "unix://path" 25 if runtime.GOOS == "windows" { 26 host = "npipe://./" 27 } 28 opts := &flags.CommonOptions{Hosts: []string{host}} 29 configFile := &configfile.ConfigFile{ 30 HTTPHeaders: map[string]string{ 31 "My-Header": "Custom-Value", 32 }, 33 } 34 apiclient, err := NewAPIClientFromFlags(opts, configFile) 35 assert.NilError(t, err) 36 assert.Check(t, is.Equal(host, apiclient.DaemonHost())) 37 38 expectedHeaders := map[string]string{ 39 "My-Header": "Custom-Value", 40 "User-Agent": UserAgent(), 41 } 42 assert.Check(t, is.DeepEqual(expectedHeaders, apiclient.(*client.Client).CustomHTTPHeaders())) 43 assert.Check(t, is.Equal(api.DefaultVersion, apiclient.ClientVersion())) 44 } 45 46 func TestNewAPIClientFromFlagsWithAPIVersionFromEnv(t *testing.T) { 47 customVersion := "v3.3.3" 48 defer env.Patch(t, "DOCKER_API_VERSION", customVersion)() 49 50 opts := &flags.CommonOptions{} 51 configFile := &configfile.ConfigFile{} 52 apiclient, err := NewAPIClientFromFlags(opts, configFile) 53 assert.NilError(t, err) 54 assert.Check(t, is.Equal(customVersion, apiclient.ClientVersion())) 55 } 56 57 type fakeClient struct { 58 client.Client 59 pingFunc func() (types.Ping, error) 60 version string 61 negotiated bool 62 } 63 64 func (c *fakeClient) Ping(_ context.Context) (types.Ping, error) { 65 return c.pingFunc() 66 } 67 68 func (c *fakeClient) ClientVersion() string { 69 return c.version 70 } 71 72 func (c *fakeClient) NegotiateAPIVersionPing(types.Ping) { 73 c.negotiated = true 74 } 75 76 func TestInitializeFromClient(t *testing.T) { 77 defaultVersion := "v1.55" 78 79 var testcases = []struct { 80 doc string 81 pingFunc func() (types.Ping, error) 82 expectedServer ServerInfo 83 negotiated bool 84 }{ 85 { 86 doc: "successful ping", 87 pingFunc: func() (types.Ping, error) { 88 return types.Ping{Experimental: true, OSType: "linux", APIVersion: "v1.30"}, nil 89 }, 90 expectedServer: ServerInfo{HasExperimental: true, OSType: "linux"}, 91 negotiated: true, 92 }, 93 { 94 doc: "failed ping, no API version", 95 pingFunc: func() (types.Ping, error) { 96 return types.Ping{}, errors.New("failed") 97 }, 98 expectedServer: ServerInfo{HasExperimental: true}, 99 }, 100 { 101 doc: "failed ping, with API version", 102 pingFunc: func() (types.Ping, error) { 103 return types.Ping{APIVersion: "v1.33"}, errors.New("failed") 104 }, 105 expectedServer: ServerInfo{HasExperimental: true}, 106 negotiated: true, 107 }, 108 } 109 110 for _, testcase := range testcases { 111 t.Run(testcase.doc, func(t *testing.T) { 112 apiclient := &fakeClient{ 113 pingFunc: testcase.pingFunc, 114 version: defaultVersion, 115 } 116 117 cli := &DockerCli{client: apiclient} 118 cli.initializeFromClient() 119 assert.Check(t, is.DeepEqual(testcase.expectedServer, cli.serverInfo)) 120 assert.Check(t, is.Equal(testcase.negotiated, apiclient.negotiated)) 121 }) 122 } 123 } 124 125 func TestExperimentalCLI(t *testing.T) { 126 defaultVersion := "v1.55" 127 128 var testcases = []struct { 129 doc string 130 configfile string 131 expectedExperimentalCLI bool 132 }{ 133 { 134 doc: "default", 135 configfile: `{}`, 136 expectedExperimentalCLI: false, 137 }, 138 { 139 doc: "experimental", 140 configfile: `{ 141 "experimental": "enabled" 142 }`, 143 expectedExperimentalCLI: true, 144 }, 145 } 146 147 for _, testcase := range testcases { 148 t.Run(testcase.doc, func(t *testing.T) { 149 dir := fs.NewDir(t, testcase.doc, fs.WithFile("config.json", testcase.configfile)) 150 defer dir.Remove() 151 apiclient := &fakeClient{ 152 version: defaultVersion, 153 } 154 155 cli := &DockerCli{client: apiclient, err: os.Stderr} 156 cliconfig.SetDir(dir.Path()) 157 err := cli.Initialize(flags.NewClientOptions()) 158 assert.NilError(t, err) 159 assert.Check(t, is.Equal(testcase.expectedExperimentalCLI, cli.ClientInfo().HasExperimental)) 160 }) 161 } 162 } 163 164 func TestGetClientWithPassword(t *testing.T) { 165 expected := "password" 166 167 var testcases = []struct { 168 doc string 169 password string 170 retrieverErr error 171 retrieverGiveup bool 172 newClientErr error 173 expectedErr string 174 }{ 175 { 176 doc: "successful connect", 177 password: expected, 178 }, 179 { 180 doc: "password retriever exhausted", 181 retrieverGiveup: true, 182 retrieverErr: errors.New("failed"), 183 expectedErr: "private key is encrypted, but could not get passphrase", 184 }, 185 { 186 doc: "password retriever error", 187 retrieverErr: errors.New("failed"), 188 expectedErr: "failed", 189 }, 190 { 191 doc: "newClient error", 192 newClientErr: errors.New("failed to connect"), 193 expectedErr: "failed to connect", 194 }, 195 } 196 197 for _, testcase := range testcases { 198 t.Run(testcase.doc, func(t *testing.T) { 199 passRetriever := func(_, _ string, _ bool, attempts int) (passphrase string, giveup bool, err error) { 200 // Always return an invalid pass first to test iteration 201 switch attempts { 202 case 0: 203 return "something else", false, nil 204 default: 205 return testcase.password, testcase.retrieverGiveup, testcase.retrieverErr 206 } 207 } 208 209 newClient := func(currentPassword string) (client.APIClient, error) { 210 if testcase.newClientErr != nil { 211 return nil, testcase.newClientErr 212 } 213 if currentPassword == expected { 214 return &client.Client{}, nil 215 } 216 return &client.Client{}, x509.IncorrectPasswordError 217 } 218 219 _, err := getClientWithPassword(passRetriever, newClient) 220 if testcase.expectedErr != "" { 221 assert.ErrorContains(t, err, testcase.expectedErr) 222 return 223 } 224 225 assert.NilError(t, err) 226 }) 227 } 228 }