github.com/itscaro/cli@v0.0.0-20190705081621-c9db0fe93829/internal/test/cli.go (about) 1 package test 2 3 import ( 4 "bytes" 5 "fmt" 6 "io" 7 "io/ioutil" 8 "strings" 9 10 "github.com/docker/cli/cli/command" 11 "github.com/docker/cli/cli/config/configfile" 12 "github.com/docker/cli/cli/context/docker" 13 "github.com/docker/cli/cli/context/store" 14 manifeststore "github.com/docker/cli/cli/manifest/store" 15 registryclient "github.com/docker/cli/cli/registry/client" 16 "github.com/docker/cli/cli/streams" 17 "github.com/docker/cli/cli/trust" 18 clitypes "github.com/docker/cli/types" 19 "github.com/docker/docker/client" 20 notaryclient "github.com/theupdateframework/notary/client" 21 ) 22 23 // NotaryClientFuncType defines a function that returns a fake notary client 24 type NotaryClientFuncType func(imgRefAndAuth trust.ImageRefAndAuth, actions []string) (notaryclient.Repository, error) 25 type clientInfoFuncType func() command.ClientInfo 26 type containerizedEngineFuncType func(string) (clitypes.ContainerizedClient, error) 27 28 // FakeCli emulates the default DockerCli 29 type FakeCli struct { 30 command.DockerCli 31 client client.APIClient 32 configfile *configfile.ConfigFile 33 out *streams.Out 34 outBuffer *bytes.Buffer 35 err *bytes.Buffer 36 in *streams.In 37 server command.ServerInfo 38 clientInfoFunc clientInfoFuncType 39 notaryClientFunc NotaryClientFuncType 40 manifestStore manifeststore.Store 41 registryClient registryclient.RegistryClient 42 contentTrust bool 43 containerizedEngineClientFunc containerizedEngineFuncType 44 contextStore store.Store 45 currentContext string 46 dockerEndpoint docker.Endpoint 47 } 48 49 // NewFakeCli returns a fake for the command.Cli interface 50 func NewFakeCli(client client.APIClient, opts ...func(*FakeCli)) *FakeCli { 51 outBuffer := new(bytes.Buffer) 52 errBuffer := new(bytes.Buffer) 53 c := &FakeCli{ 54 client: client, 55 out: streams.NewOut(outBuffer), 56 outBuffer: outBuffer, 57 err: errBuffer, 58 in: streams.NewIn(ioutil.NopCloser(strings.NewReader(""))), 59 // Use an empty string for filename so that tests don't create configfiles 60 // Set cli.ConfigFile().Filename to a tempfile to support Save. 61 configfile: configfile.New(""), 62 } 63 for _, opt := range opts { 64 opt(c) 65 } 66 return c 67 } 68 69 // SetIn sets the input of the cli to the specified ReadCloser 70 func (c *FakeCli) SetIn(in *streams.In) { 71 c.in = in 72 } 73 74 // SetErr sets the stderr stream for the cli to the specified io.Writer 75 func (c *FakeCli) SetErr(err *bytes.Buffer) { 76 c.err = err 77 } 78 79 // SetOut sets the stdout stream for the cli to the specified io.Writer 80 func (c *FakeCli) SetOut(out *streams.Out) { 81 c.out = out 82 } 83 84 // SetConfigFile sets the "fake" config file 85 func (c *FakeCli) SetConfigFile(configfile *configfile.ConfigFile) { 86 c.configfile = configfile 87 } 88 89 // SetContextStore sets the "fake" context store 90 func (c *FakeCli) SetContextStore(store store.Store) { 91 c.contextStore = store 92 } 93 94 // SetCurrentContext sets the "fake" current context 95 func (c *FakeCli) SetCurrentContext(name string) { 96 c.currentContext = name 97 } 98 99 // SetDockerEndpoint sets the "fake" docker endpoint 100 func (c *FakeCli) SetDockerEndpoint(ep docker.Endpoint) { 101 c.dockerEndpoint = ep 102 } 103 104 // Client returns a docker API client 105 func (c *FakeCli) Client() client.APIClient { 106 return c.client 107 } 108 109 // Out returns the output stream (stdout) the cli should write on 110 func (c *FakeCli) Out() *streams.Out { 111 return c.out 112 } 113 114 // Err returns the output stream (stderr) the cli should write on 115 func (c *FakeCli) Err() io.Writer { 116 return c.err 117 } 118 119 // In returns the input stream the cli will use 120 func (c *FakeCli) In() *streams.In { 121 return c.in 122 } 123 124 // ConfigFile returns the cli configfile object (to get client configuration) 125 func (c *FakeCli) ConfigFile() *configfile.ConfigFile { 126 return c.configfile 127 } 128 129 // ContextStore returns the cli context store 130 func (c *FakeCli) ContextStore() store.Store { 131 return c.contextStore 132 } 133 134 // CurrentContext returns the cli context 135 func (c *FakeCli) CurrentContext() string { 136 return c.currentContext 137 } 138 139 // DockerEndpoint returns the current DockerEndpoint 140 func (c *FakeCli) DockerEndpoint() docker.Endpoint { 141 return c.dockerEndpoint 142 } 143 144 // ServerInfo returns API server information for the server used by this client 145 func (c *FakeCli) ServerInfo() command.ServerInfo { 146 return c.server 147 } 148 149 // ClientInfo returns client information 150 func (c *FakeCli) ClientInfo() command.ClientInfo { 151 if c.clientInfoFunc != nil { 152 return c.clientInfoFunc() 153 } 154 return c.DockerCli.ClientInfo() 155 } 156 157 // SetClientInfo sets the internal getter for retrieving a ClientInfo 158 func (c *FakeCli) SetClientInfo(clientInfoFunc clientInfoFuncType) { 159 c.clientInfoFunc = clientInfoFunc 160 } 161 162 // OutBuffer returns the stdout buffer 163 func (c *FakeCli) OutBuffer() *bytes.Buffer { 164 return c.outBuffer 165 } 166 167 // ErrBuffer Buffer returns the stderr buffer 168 func (c *FakeCli) ErrBuffer() *bytes.Buffer { 169 return c.err 170 } 171 172 // ResetOutputBuffers resets the .OutBuffer() and.ErrBuffer() back to empty 173 func (c *FakeCli) ResetOutputBuffers() { 174 c.outBuffer.Reset() 175 c.err.Reset() 176 } 177 178 // SetNotaryClient sets the internal getter for retrieving a NotaryClient 179 func (c *FakeCli) SetNotaryClient(notaryClientFunc NotaryClientFuncType) { 180 c.notaryClientFunc = notaryClientFunc 181 } 182 183 // NotaryClient returns an err for testing unless defined 184 func (c *FakeCli) NotaryClient(imgRefAndAuth trust.ImageRefAndAuth, actions []string) (notaryclient.Repository, error) { 185 if c.notaryClientFunc != nil { 186 return c.notaryClientFunc(imgRefAndAuth, actions) 187 } 188 return nil, fmt.Errorf("no notary client available unless defined") 189 } 190 191 // ManifestStore returns a fake store used for testing 192 func (c *FakeCli) ManifestStore() manifeststore.Store { 193 return c.manifestStore 194 } 195 196 // RegistryClient returns a fake client for testing 197 func (c *FakeCli) RegistryClient(insecure bool) registryclient.RegistryClient { 198 return c.registryClient 199 } 200 201 // SetManifestStore on the fake cli 202 func (c *FakeCli) SetManifestStore(store manifeststore.Store) { 203 c.manifestStore = store 204 } 205 206 // SetRegistryClient on the fake cli 207 func (c *FakeCli) SetRegistryClient(client registryclient.RegistryClient) { 208 c.registryClient = client 209 } 210 211 // ContentTrustEnabled on the fake cli 212 func (c *FakeCli) ContentTrustEnabled() bool { 213 return c.contentTrust 214 } 215 216 // EnableContentTrust on the fake cli 217 func EnableContentTrust(c *FakeCli) { 218 c.contentTrust = true 219 } 220 221 // NewContainerizedEngineClient returns a containerized engine client 222 func (c *FakeCli) NewContainerizedEngineClient(sockPath string) (clitypes.ContainerizedClient, error) { 223 if c.containerizedEngineClientFunc != nil { 224 return c.containerizedEngineClientFunc(sockPath) 225 } 226 return nil, fmt.Errorf("no containerized engine client available unless defined") 227 } 228 229 // SetContainerizedEngineClient on the fake cli 230 func (c *FakeCli) SetContainerizedEngineClient(containerizedEngineClientFunc containerizedEngineFuncType) { 231 c.containerizedEngineClientFunc = containerizedEngineClientFunc 232 } 233 234 // StackOrchestrator return the selected stack orchestrator 235 func (c *FakeCli) StackOrchestrator(flagValue string) (command.Orchestrator, error) { 236 configOrchestrator := "" 237 if c.configfile != nil { 238 configOrchestrator = c.configfile.StackOrchestrator 239 } 240 ctxOrchestrator := "" 241 if c.currentContext != "" && c.contextStore != nil { 242 meta, err := c.contextStore.GetMetadata(c.currentContext) 243 if err != nil { 244 return "", err 245 } 246 context, err := command.GetDockerContext(meta) 247 if err != nil { 248 return "", err 249 } 250 ctxOrchestrator = string(context.StackOrchestrator) 251 } 252 return command.GetStackOrchestrator(flagValue, ctxOrchestrator, configOrchestrator, c.err) 253 }