2016-12-25 16:23:35 -05:00
|
|
|
package test
|
|
|
|
|
|
|
|
import (
|
2017-07-05 14:19:52 -04:00
|
|
|
"bytes"
|
2017-09-14 16:16:54 -04:00
|
|
|
"fmt"
|
2016-12-25 16:23:35 -05:00
|
|
|
"io"
|
|
|
|
"io/ioutil"
|
2017-02-27 12:39:35 -05:00
|
|
|
"strings"
|
2016-12-25 16:23:35 -05:00
|
|
|
|
2017-04-17 18:07:56 -04:00
|
|
|
"github.com/docker/cli/cli/command"
|
|
|
|
"github.com/docker/cli/cli/config/configfile"
|
2018-11-09 09:10:41 -05:00
|
|
|
"github.com/docker/cli/cli/context/docker"
|
|
|
|
"github.com/docker/cli/cli/context/store"
|
2017-06-15 14:41:54 -04:00
|
|
|
manifeststore "github.com/docker/cli/cli/manifest/store"
|
|
|
|
registryclient "github.com/docker/cli/cli/registry/client"
|
2019-01-28 08:30:31 -05:00
|
|
|
"github.com/docker/cli/cli/streams"
|
2017-09-26 18:15:04 -04:00
|
|
|
"github.com/docker/cli/cli/trust"
|
2018-09-11 08:46:30 -04:00
|
|
|
clitypes "github.com/docker/cli/types"
|
2017-05-08 12:33:45 -04:00
|
|
|
"github.com/docker/docker/client"
|
2017-10-30 12:21:41 -04:00
|
|
|
notaryclient "github.com/theupdateframework/notary/client"
|
2016-12-25 16:23:35 -05:00
|
|
|
)
|
|
|
|
|
2018-03-08 08:35:17 -05:00
|
|
|
// NotaryClientFuncType defines a function that returns a fake notary client
|
|
|
|
type NotaryClientFuncType func(imgRefAndAuth trust.ImageRefAndAuth, actions []string) (notaryclient.Repository, error)
|
2017-12-26 09:40:17 -05:00
|
|
|
type clientInfoFuncType func() command.ClientInfo
|
2018-09-11 08:46:30 -04:00
|
|
|
type containerizedEngineFuncType func(string) (clitypes.ContainerizedClient, error)
|
2017-09-14 16:16:54 -04:00
|
|
|
|
2016-12-25 16:23:35 -05:00
|
|
|
// FakeCli emulates the default DockerCli
|
|
|
|
type FakeCli struct {
|
|
|
|
command.DockerCli
|
2018-03-19 18:56:51 -04:00
|
|
|
client client.APIClient
|
|
|
|
configfile *configfile.ConfigFile
|
2019-01-28 08:30:31 -05:00
|
|
|
out *streams.Out
|
2018-03-19 18:56:51 -04:00
|
|
|
outBuffer *bytes.Buffer
|
|
|
|
err *bytes.Buffer
|
2019-01-28 08:30:31 -05:00
|
|
|
in *streams.In
|
2018-03-19 18:56:51 -04:00
|
|
|
server command.ServerInfo
|
|
|
|
clientInfoFunc clientInfoFuncType
|
|
|
|
notaryClientFunc NotaryClientFuncType
|
|
|
|
manifestStore manifeststore.Store
|
|
|
|
registryClient registryclient.RegistryClient
|
|
|
|
contentTrust bool
|
|
|
|
containerizedEngineClientFunc containerizedEngineFuncType
|
2018-11-09 09:10:41 -05:00
|
|
|
contextStore store.Store
|
|
|
|
currentContext string
|
|
|
|
dockerEndpoint docker.Endpoint
|
2016-12-25 16:23:35 -05:00
|
|
|
}
|
|
|
|
|
2017-07-05 14:19:52 -04:00
|
|
|
// NewFakeCli returns a fake for the command.Cli interface
|
2018-03-08 08:35:17 -05:00
|
|
|
func NewFakeCli(client client.APIClient, opts ...func(*FakeCli)) *FakeCli {
|
2017-07-05 14:19:52 -04:00
|
|
|
outBuffer := new(bytes.Buffer)
|
|
|
|
errBuffer := new(bytes.Buffer)
|
2018-03-08 08:35:17 -05:00
|
|
|
c := &FakeCli{
|
2018-03-05 19:59:53 -05:00
|
|
|
client: client,
|
2019-01-28 08:30:31 -05:00
|
|
|
out: streams.NewOut(outBuffer),
|
2018-03-05 19:59:53 -05:00
|
|
|
outBuffer: outBuffer,
|
|
|
|
err: errBuffer,
|
2019-01-28 08:30:31 -05:00
|
|
|
in: streams.NewIn(ioutil.NopCloser(strings.NewReader(""))),
|
2018-03-05 19:59:53 -05:00
|
|
|
// Use an empty string for filename so that tests don't create configfiles
|
|
|
|
// Set cli.ConfigFile().Filename to a tempfile to support Save.
|
|
|
|
configfile: configfile.New(""),
|
2016-12-25 16:23:35 -05:00
|
|
|
}
|
2018-03-08 08:35:17 -05:00
|
|
|
for _, opt := range opts {
|
|
|
|
opt(c)
|
|
|
|
}
|
|
|
|
return c
|
2016-12-25 16:23:35 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
// SetIn sets the input of the cli to the specified ReadCloser
|
2019-01-28 08:30:31 -05:00
|
|
|
func (c *FakeCli) SetIn(in *streams.In) {
|
2016-12-25 16:23:35 -05:00
|
|
|
c.in = in
|
|
|
|
}
|
|
|
|
|
2017-02-22 15:43:13 -05:00
|
|
|
// SetErr sets the stderr stream for the cli to the specified io.Writer
|
2017-07-05 14:19:52 -04:00
|
|
|
func (c *FakeCli) SetErr(err *bytes.Buffer) {
|
2017-02-27 12:39:35 -05:00
|
|
|
c.err = err
|
|
|
|
}
|
|
|
|
|
2018-11-09 09:10:41 -05:00
|
|
|
// SetOut sets the stdout stream for the cli to the specified io.Writer
|
2019-01-28 08:30:31 -05:00
|
|
|
func (c *FakeCli) SetOut(out *streams.Out) {
|
2018-11-09 09:10:41 -05:00
|
|
|
c.out = out
|
|
|
|
}
|
|
|
|
|
2017-07-05 14:34:16 -04:00
|
|
|
// SetConfigFile sets the "fake" config file
|
|
|
|
func (c *FakeCli) SetConfigFile(configfile *configfile.ConfigFile) {
|
2017-02-27 12:39:35 -05:00
|
|
|
c.configfile = configfile
|
|
|
|
}
|
|
|
|
|
2018-11-09 09:10:41 -05:00
|
|
|
// SetContextStore sets the "fake" context store
|
|
|
|
func (c *FakeCli) SetContextStore(store store.Store) {
|
|
|
|
c.contextStore = store
|
|
|
|
}
|
|
|
|
|
|
|
|
// SetCurrentContext sets the "fake" current context
|
|
|
|
func (c *FakeCli) SetCurrentContext(name string) {
|
|
|
|
c.currentContext = name
|
|
|
|
}
|
|
|
|
|
|
|
|
// SetDockerEndpoint sets the "fake" docker endpoint
|
|
|
|
func (c *FakeCli) SetDockerEndpoint(ep docker.Endpoint) {
|
|
|
|
c.dockerEndpoint = ep
|
|
|
|
}
|
|
|
|
|
2016-12-25 16:23:35 -05:00
|
|
|
// Client returns a docker API client
|
|
|
|
func (c *FakeCli) Client() client.APIClient {
|
|
|
|
return c.client
|
|
|
|
}
|
|
|
|
|
2017-02-27 12:39:35 -05:00
|
|
|
// Out returns the output stream (stdout) the cli should write on
|
2019-01-28 08:30:31 -05:00
|
|
|
func (c *FakeCli) Out() *streams.Out {
|
2017-03-30 20:21:14 -04:00
|
|
|
return c.out
|
2016-12-25 16:23:35 -05:00
|
|
|
}
|
|
|
|
|
2017-02-27 12:39:35 -05:00
|
|
|
// Err returns the output stream (stderr) the cli should write on
|
|
|
|
func (c *FakeCli) Err() io.Writer {
|
|
|
|
return c.err
|
|
|
|
}
|
|
|
|
|
|
|
|
// In returns the input stream the cli will use
|
2019-01-28 08:30:31 -05:00
|
|
|
func (c *FakeCli) In() *streams.In {
|
2017-03-30 20:21:14 -04:00
|
|
|
return c.in
|
2016-12-25 16:23:35 -05:00
|
|
|
}
|
2017-02-27 12:39:35 -05:00
|
|
|
|
|
|
|
// ConfigFile returns the cli configfile object (to get client configuration)
|
|
|
|
func (c *FakeCli) ConfigFile() *configfile.ConfigFile {
|
|
|
|
return c.configfile
|
|
|
|
}
|
2017-06-21 15:13:44 -04:00
|
|
|
|
2018-11-09 09:10:41 -05:00
|
|
|
// ContextStore returns the cli context store
|
|
|
|
func (c *FakeCli) ContextStore() store.Store {
|
|
|
|
return c.contextStore
|
|
|
|
}
|
|
|
|
|
|
|
|
// CurrentContext returns the cli context
|
|
|
|
func (c *FakeCli) CurrentContext() string {
|
|
|
|
return c.currentContext
|
|
|
|
}
|
|
|
|
|
|
|
|
// DockerEndpoint returns the current DockerEndpoint
|
|
|
|
func (c *FakeCli) DockerEndpoint() docker.Endpoint {
|
|
|
|
return c.dockerEndpoint
|
|
|
|
}
|
|
|
|
|
2017-06-21 15:13:44 -04:00
|
|
|
// ServerInfo returns API server information for the server used by this client
|
|
|
|
func (c *FakeCli) ServerInfo() command.ServerInfo {
|
|
|
|
return c.server
|
|
|
|
}
|
2017-07-05 14:19:52 -04:00
|
|
|
|
2017-12-26 09:40:17 -05:00
|
|
|
// ClientInfo returns client information
|
|
|
|
func (c *FakeCli) ClientInfo() command.ClientInfo {
|
|
|
|
if c.clientInfoFunc != nil {
|
|
|
|
return c.clientInfoFunc()
|
|
|
|
}
|
|
|
|
return c.DockerCli.ClientInfo()
|
|
|
|
}
|
|
|
|
|
|
|
|
// SetClientInfo sets the internal getter for retrieving a ClientInfo
|
|
|
|
func (c *FakeCli) SetClientInfo(clientInfoFunc clientInfoFuncType) {
|
|
|
|
c.clientInfoFunc = clientInfoFunc
|
|
|
|
}
|
|
|
|
|
2017-07-05 14:19:52 -04:00
|
|
|
// OutBuffer returns the stdout buffer
|
|
|
|
func (c *FakeCli) OutBuffer() *bytes.Buffer {
|
|
|
|
return c.outBuffer
|
|
|
|
}
|
|
|
|
|
|
|
|
// ErrBuffer Buffer returns the stderr buffer
|
|
|
|
func (c *FakeCli) ErrBuffer() *bytes.Buffer {
|
|
|
|
return c.err
|
|
|
|
}
|
2017-09-14 16:16:54 -04:00
|
|
|
|
2019-05-13 11:22:02 -04:00
|
|
|
// ResetOutputBuffers resets the .OutBuffer() and.ErrBuffer() back to empty
|
|
|
|
func (c *FakeCli) ResetOutputBuffers() {
|
|
|
|
c.outBuffer.Reset()
|
|
|
|
c.err.Reset()
|
|
|
|
}
|
|
|
|
|
2017-09-14 16:16:54 -04:00
|
|
|
// SetNotaryClient sets the internal getter for retrieving a NotaryClient
|
2018-03-08 08:35:17 -05:00
|
|
|
func (c *FakeCli) SetNotaryClient(notaryClientFunc NotaryClientFuncType) {
|
2017-09-14 16:16:54 -04:00
|
|
|
c.notaryClientFunc = notaryClientFunc
|
|
|
|
}
|
|
|
|
|
|
|
|
// NotaryClient returns an err for testing unless defined
|
|
|
|
func (c *FakeCli) NotaryClient(imgRefAndAuth trust.ImageRefAndAuth, actions []string) (notaryclient.Repository, error) {
|
|
|
|
if c.notaryClientFunc != nil {
|
|
|
|
return c.notaryClientFunc(imgRefAndAuth, actions)
|
|
|
|
}
|
|
|
|
return nil, fmt.Errorf("no notary client available unless defined")
|
2017-09-26 18:15:04 -04:00
|
|
|
}
|
2017-06-15 14:41:54 -04:00
|
|
|
|
|
|
|
// ManifestStore returns a fake store used for testing
|
|
|
|
func (c *FakeCli) ManifestStore() manifeststore.Store {
|
|
|
|
return c.manifestStore
|
|
|
|
}
|
|
|
|
|
|
|
|
// RegistryClient returns a fake client for testing
|
|
|
|
func (c *FakeCli) RegistryClient(insecure bool) registryclient.RegistryClient {
|
|
|
|
return c.registryClient
|
|
|
|
}
|
|
|
|
|
|
|
|
// SetManifestStore on the fake cli
|
|
|
|
func (c *FakeCli) SetManifestStore(store manifeststore.Store) {
|
|
|
|
c.manifestStore = store
|
|
|
|
}
|
|
|
|
|
|
|
|
// SetRegistryClient on the fake cli
|
|
|
|
func (c *FakeCli) SetRegistryClient(client registryclient.RegistryClient) {
|
|
|
|
c.registryClient = client
|
2017-09-14 16:16:54 -04:00
|
|
|
}
|
2018-03-08 08:35:17 -05:00
|
|
|
|
2018-03-08 14:56:56 -05:00
|
|
|
// ContentTrustEnabled on the fake cli
|
|
|
|
func (c *FakeCli) ContentTrustEnabled() bool {
|
|
|
|
return c.contentTrust
|
2018-03-08 08:35:17 -05:00
|
|
|
}
|
|
|
|
|
2018-03-08 14:56:56 -05:00
|
|
|
// EnableContentTrust on the fake cli
|
|
|
|
func EnableContentTrust(c *FakeCli) {
|
|
|
|
c.contentTrust = true
|
2018-03-08 08:35:17 -05:00
|
|
|
}
|
2018-03-19 18:56:51 -04:00
|
|
|
|
|
|
|
// NewContainerizedEngineClient returns a containerized engine client
|
2018-09-11 08:46:30 -04:00
|
|
|
func (c *FakeCli) NewContainerizedEngineClient(sockPath string) (clitypes.ContainerizedClient, error) {
|
2018-03-19 18:56:51 -04:00
|
|
|
if c.containerizedEngineClientFunc != nil {
|
|
|
|
return c.containerizedEngineClientFunc(sockPath)
|
|
|
|
}
|
|
|
|
return nil, fmt.Errorf("no containerized engine client available unless defined")
|
|
|
|
}
|
|
|
|
|
|
|
|
// SetContainerizedEngineClient on the fake cli
|
|
|
|
func (c *FakeCli) SetContainerizedEngineClient(containerizedEngineClientFunc containerizedEngineFuncType) {
|
|
|
|
c.containerizedEngineClientFunc = containerizedEngineClientFunc
|
|
|
|
}
|
2019-03-06 09:01:12 -05:00
|
|
|
|
|
|
|
// StackOrchestrator return the selected stack orchestrator
|
|
|
|
func (c *FakeCli) StackOrchestrator(flagValue string) (command.Orchestrator, error) {
|
|
|
|
configOrchestrator := ""
|
|
|
|
if c.configfile != nil {
|
|
|
|
configOrchestrator = c.configfile.StackOrchestrator
|
|
|
|
}
|
|
|
|
ctxOrchestrator := ""
|
|
|
|
if c.currentContext != "" && c.contextStore != nil {
|
2019-04-18 09:12:30 -04:00
|
|
|
meta, err := c.contextStore.GetMetadata(c.currentContext)
|
2019-03-06 09:01:12 -05:00
|
|
|
if err != nil {
|
|
|
|
return "", err
|
|
|
|
}
|
|
|
|
context, err := command.GetDockerContext(meta)
|
|
|
|
if err != nil {
|
|
|
|
return "", err
|
|
|
|
}
|
|
|
|
ctxOrchestrator = string(context.StackOrchestrator)
|
|
|
|
}
|
|
|
|
return command.GetStackOrchestrator(flagValue, ctxOrchestrator, configOrchestrator, c.err)
|
|
|
|
}
|