import pytest from io import BytesIO from thefuck.types import Command from thefuck.rules.docker_not_command import get_new_command, match _DOCKER_SWARM_OUTPUT = ''' Usage: docker swarm COMMAND Manage Swarm Commands: ca Display and rotate the root CA init Initialize a swarm join Join a swarm as a node and/or manager join-token Manage join tokens leave Leave the swarm unlock Unlock swarm unlock-key Manage the unlock key update Update the swarm Run 'docker swarm COMMAND --help' for more information on a command. ''' _DOCKER_IMAGE_OUTPUT = ''' Usage: docker image COMMAND Manage images Commands: build Build an image from a Dockerfile history Show the history of an image import Import the contents from a tarball to create a filesystem image inspect Display detailed information on one or more images load Load an image from a tar archive or STDIN ls List images prune Remove unused images pull Pull an image or a repository from a registry push Push an image or a repository to a registry rm Remove one or more images save Save one or more images to a tar archive (streamed to STDOUT by default) tag Create a tag TARGET_IMAGE that refers to SOURCE_IMAGE Run 'docker image COMMAND --help' for more information on a command. ''' @pytest.fixture def docker_help(mocker): help = b'''Usage: docker [OPTIONS] COMMAND [arg...] A self-sufficient runtime for linux containers. Options: --api-cors-header= Set CORS headers in the remote API -b, --bridge= Attach containers to a network bridge --bip= Specify network bridge IP -D, --debug=false Enable debug mode -d, --daemon=false Enable daemon mode --default-gateway= Container default gateway IPv4 address --default-gateway-v6= Container default gateway IPv6 address --default-ulimit=[] Set default ulimits for containers --dns=[] DNS server to use --dns-search=[] DNS search domains to use -e, --exec-driver=native Exec driver to use --exec-opt=[] Set exec driver options --exec-root=/var/run/docker Root of the Docker execdriver --fixed-cidr= IPv4 subnet for fixed IPs --fixed-cidr-v6= IPv6 subnet for fixed IPs -G, --group=docker Group for the unix socket -g, --graph=/var/lib/docker Root of the Docker runtime -H, --host=[] Daemon socket(s) to connect to -h, --help=false Print usage --icc=true Enable inter-container communication --insecure-registry=[] Enable insecure registry communication --ip=0.0.0.0 Default IP when binding container ports --ip-forward=true Enable net.ipv4.ip_forward --ip-masq=true Enable IP masquerading --iptables=true Enable addition of iptables rules --ipv6=false Enable IPv6 networking -l, --log-level=info Set the logging level --label=[] Set key=value labels to the daemon --log-driver=json-file Default driver for container logs --log-opt=map[] Set log driver options --mtu=0 Set the containers network MTU -p, --pidfile=/var/run/docker.pid Path to use for daemon PID file --registry-mirror=[] Preferred Docker registry mirror -s, --storage-driver= Storage driver to use --selinux-enabled=false Enable selinux support --storage-opt=[] Set storage driver options --tls=false Use TLS; implied by --tlsverify --tlscacert=~/.docker/ca.pem Trust certs signed only by this CA --tlscert=~/.docker/cert.pem Path to TLS certificate file --tlskey=~/.docker/key.pem Path to TLS key file --tlsverify=false Use TLS and verify the remote --userland-proxy=true Use userland proxy for loopback traffic -v, --version=false Print version information and quit Commands: attach Attach to a running container build Build an image from a Dockerfile commit Create a new image from a container's changes cp Copy files/folders from a container's filesystem to the host path create Create a new container diff Inspect changes on a container's filesystem events Get real time events from the server exec Run a command in a running container export Stream the contents of a container as a tar archive history Show the history of an image images List images import Create a new filesystem image from the contents of a tarball info Display system-wide information inspect Return low-level information on a container or image kill Kill a running container load Load an image from a tar archive login Register or log in to a Docker registry server logout Log out from a Docker registry server logs Fetch the logs of a container pause Pause all processes within a container port Lookup the public-facing port that is NAT-ed to PRIVATE_PORT ps List containers pull Pull an image or a repository from a Docker registry server push Push an image or a repository to a Docker registry server rename Rename an existing container restart Restart a running container rm Remove one or more containers rmi Remove one or more images run Run a command in a new container save Save an image to a tar archive search Search for an image on the Docker Hub start Start a stopped container stats Display a stream of a containers' resource usage statistics stop Stop a running container tag Tag an image into a repository top Lookup the running processes of a container unpause Unpause a paused container version Show the Docker version information wait Block until a container stops, then print its exit code Run 'docker COMMAND --help' for more information on a command. ''' mock = mocker.patch('subprocess.Popen') mock.return_value.stdout = BytesIO(help) return mock @pytest.fixture def docker_help_new(mocker): helptext_new = b''' Usage: docker [OPTIONS] COMMAND A self-sufficient runtime for containers Options: --config string Location of client config files (default "/Users/ik1ne/.docker") -c, --context string Name of the context to use to connect to the daemon (overrides DOCKER_HOST env var and default context set with "docker context use") -D, --debug Enable debug mode -H, --host list Daemon socket(s) to connect to -l, --log-level string Set the logging level ("debug"|"info"|"warn"|"error"|"fatal") (default "info") --tls Use TLS; implied by --tlsverify --tlscacert string Trust certs signed only by this CA (default "/Users/ik1ne/.docker/ca.pem") --tlscert string Path to TLS certificate file (default "/Users/ik1ne/.docker/cert.pem") --tlskey string Path to TLS key file (default "/Users/ik1ne/.docker/key.pem") --tlsverify Use TLS and verify the remote -v, --version Print version information and quit Management Commands: builder Manage builds config Manage Docker configs container Manage containers context Manage contexts image Manage images network Manage networks node Manage Swarm nodes plugin Manage plugins secret Manage Docker secrets service Manage services stack Manage Docker stacks swarm Manage Swarm system Manage Docker trust Manage trust on Docker images volume Manage volumes Commands: attach Attach local standard input, output, and error streams to a running container build Build an image from a Dockerfile commit Create a new image from a container's changes cp Copy files/folders between a container and the local filesystem create Create a new container diff Inspect changes to files or directories on a container's filesystem events Get real time events from the server exec Run a command in a running container export Export a container's filesystem as a tar archive history Show the history of an image images List images import Import the contents from a tarball to create a filesystem image info Display system-wide information inspect Return low-level information on Docker objects kill Kill one or more running containers load Load an image from a tar archive or STDIN login Log in to a Docker registry logout Log out from a Docker registry logs Fetch the logs of a container pause Pause all processes within one or more containers port List port mappings or a specific mapping for the container ps List containers pull Pull an image or a repository from a registry push Push an image or a repository to a registry rename Rename a container restart Restart one or more containers rm Remove one or more containers rmi Remove one or more images run Run a command in a new container save Save one or more images to a tar archive (streamed to STDOUT by default) search Search the Docker Hub for images start Start one or more stopped containers stats Display a live stream of container(s) resource usage statistics stop Stop one or more running containers tag Create a tag TARGET_IMAGE that refers to SOURCE_IMAGE top Display the running processes of a container unpause Unpause all processes within one or more containers update Update configuration of one or more containers version Show the Docker version information wait Block until one or more containers stop, then print their exit codes Run 'docker COMMAND --help' for more information on a command. ''' mock = mocker.patch('subprocess.Popen') mock.return_value.stdout = BytesIO(b'') mock.return_value.stderr = BytesIO(helptext_new) return mock def output(cmd): return "docker: '{}' is not a docker command.\n" \ "See 'docker --help'.".format(cmd) def test_match(): assert match(Command('docker pes', output('pes'))) # tests docker (management command) @pytest.mark.usefixtures('no_memoize') @pytest.mark.parametrize('script, output', [ ('docker swarn', output('swarn')), ('docker imge', output('imge'))]) def test_match_management_cmd(script, output): assert match(Command(script, output)) # tests docker (management cmd) (management subcmd) @pytest.mark.usefixtures('no_memoize') @pytest.mark.parametrize('script, output', [ ('docker swarm int', _DOCKER_SWARM_OUTPUT), ('docker image la', _DOCKER_IMAGE_OUTPUT)]) def test_match_management_subcmd(script, output): assert match(Command(script, output)) @pytest.mark.parametrize('script, output', [ ('docker ps', ''), ('cat pes', output('pes'))]) def test_not_match(script, output): assert not match(Command(script, output)) @pytest.mark.usefixtures('no_memoize', 'docker_help') @pytest.mark.parametrize('wrong, fixed', [ ('pes', ['ps', 'push', 'pause']), ('tags', ['tag', 'stats', 'images'])]) def test_get_new_command(wrong, fixed): command = Command('docker {}'.format(wrong), output(wrong)) assert get_new_command(command) == ['docker {}'.format(x) for x in fixed] @pytest.mark.usefixtures('no_memoize', 'docker_help_new') @pytest.mark.parametrize('wrong, fixed', [ ('swarn', ['swarm', 'start', 'search']), ('inage', ['image', 'images', 'rename'])]) def test_get_new_management_command(wrong, fixed): command = Command('docker {}'.format(wrong), output(wrong)) assert get_new_command(command) == ['docker {}'.format(x) for x in fixed] @pytest.mark.usefixtures('no_memoize', 'docker_help_new') @pytest.mark.parametrize('wrong, fixed, output', [ ('swarm int', ['swarm init', 'swarm join', 'swarm join-token'], _DOCKER_SWARM_OUTPUT), ('image la', ['image load', 'image ls', 'image tag'], _DOCKER_IMAGE_OUTPUT)]) def test_get_new_management_command_subcommand(wrong, fixed, output): command = Command('docker {}'.format(wrong), output) assert get_new_command(command) == ['docker {}'.format(x) for x in fixed]