import unittest

import pytest

import docker
from docker.constants import DEFAULT_DATA_CHUNK_SIZE, DEFAULT_DOCKER_API_VERSION
from docker.models.containers import Container, _create_container_args
from docker.models.images import Image
from docker.types import EndpointConfig

from .fake_api import FAKE_CONTAINER_ID, FAKE_EXEC_ID, FAKE_IMAGE_ID
from .fake_api_client import make_fake_client


class ContainerCollectionTest(unittest.TestCase):
    def test_run(self):
        client = make_fake_client()
        out = client.containers.run("alpine", "echo hello world")

        assert out == b'hello world\n'

        client.api.create_container.assert_called_with(
            image="alpine",
            command="echo hello world",
            detach=False,
            host_config={'NetworkMode': 'default'}
        )
        client.api.inspect_container.assert_called_with(FAKE_CONTAINER_ID)
        client.api.start.assert_called_with(FAKE_CONTAINER_ID)
        client.api.wait.assert_called_with(FAKE_CONTAINER_ID)
        client.api.logs.assert_called_with(
            FAKE_CONTAINER_ID, stderr=False, stdout=True, stream=True,
            follow=True
        )

    def test_create_container_args(self):
        networking_config = {
            'foo': EndpointConfig(
                DEFAULT_DOCKER_API_VERSION, aliases=['test'],
                driver_opt={'key1': 'a'}
            )
        }

        create_kwargs = _create_container_args({
            'image': 'alpine',
            'command': 'echo hello world',
            'blkio_weight_device': [{'Path': 'foo', 'Weight': 3}],
            'blkio_weight': 2,
            'cap_add': ['foo'],
            'cap_drop': ['bar'],
            'cgroup_parent': 'foobar',
            'cgroupns': 'host',
            'cpu_period': 1,
            'cpu_quota': 2,
            'cpu_shares': 5,
            'cpuset_cpus': '0-3',
            'detach': False,
            'device_read_bps': [{'Path': 'foo', 'Rate': 3}],
            'device_read_iops': [{'Path': 'foo', 'Rate': 3}],
            'device_write_bps': [{'Path': 'foo', 'Rate': 3}],
            'device_write_iops': [{'Path': 'foo', 'Rate': 3}],
            'devices': ['/dev/sda:/dev/xvda:rwm'],
            'dns': ['8.8.8.8'],
            'domainname': 'example.com',
            'dns_opt': ['foo'],
            'dns_search': ['example.com'],
            'entrypoint': '/bin/sh',
            'environment': {'FOO': 'BAR'},
            'extra_hosts': {'foo': '1.2.3.4'},
            'group_add': ['blah'],
            'ipc_mode': 'foo',
            'kernel_memory': 123,
            'labels': {'key': 'value'},
            'links': {'foo': 'bar'},
            'log_config': {'Type': 'json-file', 'Config': {}},
            'lxc_conf': {'foo': 'bar'},
            'healthcheck': {'test': 'true'},
            'hostname': 'somehost',
            'mac_address': 'abc123',
            'mem_limit': 123,
            'mem_reservation': 123,
            'mem_swappiness': 2,
            'memswap_limit': 456,
            'name': 'somename',
            'network_disabled': False,
            'network': 'foo',
            'networking_config': networking_config,
            'oom_kill_disable': True,
            'oom_score_adj': 5,
            'pid_mode': 'host',
            'pids_limit': 500,
            'platform': 'linux',
            'ports': {1111: 4567, 2222: None},
            'privileged': True,
            'publish_all_ports': True,
            'read_only': True,
            'restart_policy': {'Name': 'always'},
            'security_opt': ['blah'],
            'shm_size': 123,
            'stdin_open': True,
            'stop_signal': 9,
            'sysctls': {'foo': 'bar'},
            'tmpfs': {'/blah': ''},
            'tty': True,
            'ulimits': [{"Name": "nofile", "Soft": 1024, "Hard": 2048}],
            'user': 'bob',
            'userns_mode': 'host',
            'uts_mode': 'host',
            'version': DEFAULT_DOCKER_API_VERSION,
            'volume_driver': 'some_driver', 'volumes': [
                '/home/user1/:/mnt/vol2',
                '/var/www:/mnt/vol1:ro',
                'volumename:/mnt/vol3r',
                '/volumewithnohostpath',
                '/anothervolumewithnohostpath:ro',
                'C:\\windows\\path:D:\\hello\\world:rw'
            ],
            'volumes_from': ['container'],
            'working_dir': '/code',
        })

        expected = {
            'image': 'alpine',
            'command': 'echo hello world',
            'domainname': 'example.com',
            'detach': False,
            'entrypoint': '/bin/sh',
            'environment': {'FOO': 'BAR'},
            'host_config': {
                'Binds': [
                    '/home/user1/:/mnt/vol2',
                    '/var/www:/mnt/vol1:ro',
                    'volumename:/mnt/vol3r',
                    '/volumewithnohostpath',
                    '/anothervolumewithnohostpath:ro',
                    'C:\\windows\\path:D:\\hello\\world:rw'
                ],
                'BlkioDeviceReadBps': [{'Path': 'foo', 'Rate': 3}],
                'BlkioDeviceReadIOps': [{'Path': 'foo', 'Rate': 3}],
                'BlkioDeviceWriteBps': [{'Path': 'foo', 'Rate': 3}],
                'BlkioDeviceWriteIOps': [{'Path': 'foo', 'Rate': 3}],
                'BlkioWeightDevice': [{'Path': 'foo', 'Weight': 3}],
                'BlkioWeight': 2,
                'CapAdd': ['foo'],
                'CapDrop': ['bar'],
                'CgroupnsMode': 'host',
                'CgroupParent': 'foobar',
                'CpuPeriod': 1,
                'CpuQuota': 2,
                'CpuShares': 5,
                'CpusetCpus': '0-3',
                'Devices': [
                    {
                        'PathOnHost': '/dev/sda',
                        'CgroupPermissions': 'rwm',
                        'PathInContainer': '/dev/xvda',
                    },
                ],
                'Dns': ['8.8.8.8'],
                'DnsOptions': ['foo'],
                'DnsSearch': ['example.com'],
                'ExtraHosts': ['foo:1.2.3.4'],
                'GroupAdd': ['blah'],
                'IpcMode': 'foo',
                'KernelMemory': 123,
                'Links': ['foo:bar'],
                'LogConfig': {'Type': 'json-file', 'Config': {}},
                'LxcConf': [{'Key': 'foo', 'Value': 'bar'}],
                'Memory': 123,
                'MemoryReservation': 123,
                'MemorySwap': 456,
                'MemorySwappiness': 2,
                'NetworkMode': 'foo',
                'OomKillDisable': True,
                'OomScoreAdj': 5,
                'PidMode': 'host',
                'PidsLimit': 500,
                'PortBindings': {
                    '1111/tcp': [{'HostIp': '', 'HostPort': '4567'}],
                    '2222/tcp': [{'HostIp': '', 'HostPort': ''}]
                },
                'Privileged': True,
                'PublishAllPorts': True,
                'ReadonlyRootfs': True,
                'RestartPolicy': {'Name': 'always'},
                'SecurityOpt': ['blah'],
                'ShmSize': 123,
                'Sysctls': {'foo': 'bar'},
                'Tmpfs': {'/blah': ''},
                'Ulimits': [
                    {"Name": "nofile", "Soft": 1024, "Hard": 2048},
                ],
                'UsernsMode': 'host',
                'UTSMode': 'host',
                'VolumeDriver': 'some_driver',
                'VolumesFrom': ['container'],
            },
            'healthcheck': {'test': 'true'},
            'hostname': 'somehost',
            'labels': {'key': 'value'},
            'mac_address': 'abc123',
            'name': 'somename',
            'network_disabled': False,
            'networking_config': {
                'EndpointsConfig': {
                    'foo': {
                        'Aliases': ['test'],
                        'DriverOpts': {'key1': 'a'},
                    },
                }
            },
            'platform': 'linux',
            'ports': [('1111', 'tcp'), ('2222', 'tcp')],
            'stdin_open': True,
            'stop_signal': 9,
            'tty': True,
            'user': 'bob',
            'volumes': [
                '/mnt/vol2',
                '/mnt/vol1',
                '/mnt/vol3r',
                '/volumewithnohostpath',
                '/anothervolumewithnohostpath',
                'D:\\hello\\world'
            ],
            'working_dir': '/code',
        }

        assert create_kwargs == expected

    def test_run_detach(self):
        client = make_fake_client()
        container = client.containers.run('alpine', 'sleep 300', detach=True)
        assert isinstance(container, Container)
        assert container.id == FAKE_CONTAINER_ID
        client.api.create_container.assert_called_with(
            image='alpine',
            command='sleep 300',
            detach=True,
            host_config={
                'NetworkMode': 'default',
            }
        )
        client.api.inspect_container.assert_called_with(FAKE_CONTAINER_ID)
        client.api.start.assert_called_with(FAKE_CONTAINER_ID)

    def test_run_pull(self):
        client = make_fake_client()

        # raise exception on first call, then return normal value
        client.api.create_container.side_effect = [
            docker.errors.ImageNotFound(""),
            client.api.create_container.return_value
        ]

        container = client.containers.run('alpine', 'sleep 300', detach=True)

        assert container.id == FAKE_CONTAINER_ID
        client.api.pull.assert_called_with(
            'alpine', platform=None, tag='latest', all_tags=False, stream=True
        )

    def test_run_with_error(self):
        client = make_fake_client()
        client.api.logs.return_value = "some error"
        client.api.wait.return_value = {'StatusCode': 1}

        with pytest.raises(docker.errors.ContainerError) as cm:
            client.containers.run('alpine', 'echo hello world')
        assert cm.value.exit_status == 1
        assert "some error" in cm.exconly()

    def test_run_with_image_object(self):
        client = make_fake_client()
        image = client.images.get(FAKE_IMAGE_ID)
        client.containers.run(image)
        client.api.create_container.assert_called_with(
            image=image.id,
            command=None,
            detach=False,
            host_config={
                'NetworkMode': 'default',
            }
        )

    def test_run_remove(self):
        client = make_fake_client()
        client.containers.run("alpine")
        client.api.remove_container.assert_not_called()

        client = make_fake_client()
        client.api.wait.return_value = {'StatusCode': 1}
        with pytest.raises(docker.errors.ContainerError):
            client.containers.run("alpine")
        client.api.remove_container.assert_not_called()

        client = make_fake_client()
        client.containers.run("alpine", remove=True)
        client.api.remove_container.assert_called_with(FAKE_CONTAINER_ID)

        client = make_fake_client()
        client.api.wait.return_value = {'StatusCode': 1}
        with pytest.raises(docker.errors.ContainerError):
            client.containers.run("alpine", remove=True)
        client.api.remove_container.assert_called_with(FAKE_CONTAINER_ID)

        client = make_fake_client()
        client.api._version = '1.24'
        with pytest.raises(RuntimeError):
            client.containers.run("alpine", detach=True, remove=True)

        client = make_fake_client()
        client.api._version = '1.23'
        with pytest.raises(RuntimeError):
            client.containers.run("alpine", detach=True, remove=True)

        client = make_fake_client()
        client.api._version = '1.25'
        client.containers.run("alpine", detach=True, remove=True)
        client.api.remove_container.assert_not_called()
        client.api.create_container.assert_called_with(
            command=None,
            image='alpine',
            detach=True,
            host_config={'AutoRemove': True,
                         'NetworkMode': 'default'}
        )

        client = make_fake_client()
        client.api._version = '1.26'
        client.containers.run("alpine", detach=True, remove=True)
        client.api.remove_container.assert_not_called()
        client.api.create_container.assert_called_with(
            command=None,
            image='alpine',
            detach=True,
            host_config={'AutoRemove': True,
                         'NetworkMode': 'default'}
        )

    def test_run_platform(self):
        client = make_fake_client()

        # raise exception on first call, then return normal value
        client.api.create_container.side_effect = [
            docker.errors.ImageNotFound(""),
            client.api.create_container.return_value
        ]

        client.containers.run(image='alpine', platform='linux/arm64')

        client.api.pull.assert_called_with(
            'alpine',
            tag='latest',
            all_tags=False,
            stream=True,
            platform='linux/arm64',
        )

        client.api.create_container.assert_called_with(
            detach=False,
            platform='linux/arm64',
            image='alpine',
            command=None,
            host_config={'NetworkMode': 'default'},
        )

    def test_run_networking_config_without_network(self):
        client = make_fake_client()

        with pytest.raises(RuntimeError):
            client.containers.run(
                image='alpine',
                networking_config={'aliases': ['test'],
                                   'driver_opt': {'key1': 'a'}}
            )

    def test_run_networking_config_with_network_mode(self):
        client = make_fake_client()

        with pytest.raises(RuntimeError):
            client.containers.run(
                image='alpine',
                network_mode='none',
                networking_config={'aliases': ['test'],
                                   'driver_opt': {'key1': 'a'}}
            )

    def test_run_networking_config(self):
        client = make_fake_client()

        networking_config = {
            'foo': EndpointConfig(
                DEFAULT_DOCKER_API_VERSION, aliases=['test'],
                driver_opt={'key1': 'a'}
            )
        }

        client.containers.run(
            image='alpine',
            network='foo',
            networking_config=networking_config
        )

        client.api.create_container.assert_called_with(
            detach=False,
            image='alpine',
            command=None,
            networking_config={'EndpointsConfig': {
                'foo': {'Aliases': ['test'], 'DriverOpts': {'key1': 'a'}}}
            },
            host_config={'NetworkMode': 'foo'}
        )

    def test_run_networking_config_with_undeclared_network(self):
        client = make_fake_client()

        networking_config = {
            'foo': EndpointConfig(
                DEFAULT_DOCKER_API_VERSION, aliases=['test_foo'],
                driver_opt={'key2': 'b'}
            ),
            'bar': EndpointConfig(
                DEFAULT_DOCKER_API_VERSION, aliases=['test'],
                driver_opt={'key1': 'a'}
            )
        }

        client.containers.run(
            image='alpine',
            network='foo',
            networking_config=networking_config
        )

        client.api.create_container.assert_called_with(
            detach=False,
            image='alpine',
            command=None,
            networking_config={'EndpointsConfig': {
                'foo': {'Aliases': ['test_foo'], 'DriverOpts': {'key2': 'b'}},
                'bar': {'Aliases': ['test'], 'DriverOpts': {'key1': 'a'}},
            }},
            host_config={'NetworkMode': 'foo'}
        )

    def test_run_networking_config_only_undeclared_network(self):
        client = make_fake_client()

        networking_config = {
            'bar': EndpointConfig(
                DEFAULT_DOCKER_API_VERSION, aliases=['test'],
                driver_opt={'key1': 'a'}
            )
        }

        client.containers.run(
            image='alpine',
            network='foo',
            networking_config=networking_config
        )

        client.api.create_container.assert_called_with(
            detach=False,
            image='alpine',
            command=None,
            networking_config={'foo': None},
            host_config={'NetworkMode': 'foo'}
        )

    def test_create(self):
        client = make_fake_client()
        container = client.containers.create(
            'alpine',
            'echo hello world',
            environment={'FOO': 'BAR'}
        )
        assert isinstance(container, Container)
        assert container.id == FAKE_CONTAINER_ID
        client.api.create_container.assert_called_with(
            image='alpine',
            command='echo hello world',
            environment={'FOO': 'BAR'},
            host_config={'NetworkMode': 'default'}
        )
        client.api.inspect_container.assert_called_with(FAKE_CONTAINER_ID)

    def test_create_with_image_object(self):
        client = make_fake_client()
        image = client.images.get(FAKE_IMAGE_ID)
        client.containers.create(image)
        client.api.create_container.assert_called_with(
            image=image.id,
            command=None,
            host_config={'NetworkMode': 'default'}
        )

    def test_create_networking_config_without_network(self):
        client = make_fake_client()

        client.containers.create(
            image='alpine',
            networking_config={'aliases': ['test'],
                               'driver_opt': {'key1': 'a'}}
        )

        client.api.create_container.assert_called_with(
            image='alpine',
            command=None,
            host_config={'NetworkMode': 'default'}
        )

    def test_create_networking_config_with_network_mode(self):
        client = make_fake_client()

        client.containers.create(
            image='alpine',
            network_mode='none',
            networking_config={'aliases': ['test'],
                               'driver_opt': {'key1': 'a'}}
        )

        client.api.create_container.assert_called_with(
            image='alpine',
            command=None,
            host_config={'NetworkMode': 'none'}
        )

    def test_create_networking_config(self):
        client = make_fake_client()

        networking_config = {
            'foo': EndpointConfig(
                DEFAULT_DOCKER_API_VERSION, aliases=['test'],
                driver_opt={'key1': 'a'}
            )
        }

        client.containers.create(
            image='alpine',
            network='foo',
            networking_config=networking_config
        )

        client.api.create_container.assert_called_with(
            image='alpine',
            command=None,
            networking_config={'EndpointsConfig': {
                'foo': {'Aliases': ['test'], 'DriverOpts': {'key1': 'a'}}}
            },
            host_config={'NetworkMode': 'foo'}
        )

    def test_create_networking_config_with_undeclared_network(self):
        client = make_fake_client()

        networking_config = {
            'foo': EndpointConfig(
                DEFAULT_DOCKER_API_VERSION, aliases=['test_foo'],
                driver_opt={'key2': 'b'}
            ),
            'bar': EndpointConfig(
                DEFAULT_DOCKER_API_VERSION, aliases=['test'],
                driver_opt={'key1': 'a'}
            )
        }

        client.containers.create(
            image='alpine',
            network='foo',
            networking_config=networking_config
        )

        client.api.create_container.assert_called_with(
            image='alpine',
            command=None,
            networking_config={'EndpointsConfig': {
                'foo': {'Aliases': ['test_foo'], 'DriverOpts': {'key2': 'b'}},
                'bar': {'Aliases': ['test'], 'DriverOpts': {'key1': 'a'}},
            }},
            host_config={'NetworkMode': 'foo'}
        )

    def test_create_networking_config_only_undeclared_network(self):
        client = make_fake_client()

        networking_config = {
            'bar': EndpointConfig(
                DEFAULT_DOCKER_API_VERSION, aliases=['test'],
                driver_opt={'key1': 'a'}
            )
        }

        client.containers.create(
            image='alpine',
            network='foo',
            networking_config=networking_config
        )

        client.api.create_container.assert_called_with(
            image='alpine',
            command=None,
            networking_config={'foo': None},
            host_config={'NetworkMode': 'foo'}
        )

    def test_get(self):
        client = make_fake_client()
        container = client.containers.get(FAKE_CONTAINER_ID)
        assert isinstance(container, Container)
        assert container.id == FAKE_CONTAINER_ID
        client.api.inspect_container.assert_called_with(FAKE_CONTAINER_ID)

    def test_list(self):
        client = make_fake_client()
        containers = client.containers.list(all=True)
        client.api.containers.assert_called_with(
            all=True,
            before=None,
            filters=None,
            limit=-1,
            since=None
        )
        client.api.inspect_container.assert_called_with(FAKE_CONTAINER_ID)
        assert len(containers) == 1
        assert isinstance(containers[0], Container)
        assert containers[0].id == FAKE_CONTAINER_ID

    def test_list_ignore_removed(self):
        def side_effect(*args, **kwargs):
            raise docker.errors.NotFound('Container not found')

        client = make_fake_client({
            'inspect_container.side_effect': side_effect
        })

        with pytest.raises(docker.errors.NotFound):
            client.containers.list(all=True, ignore_removed=False)

        assert client.containers.list(all=True, ignore_removed=True) == []


class ContainerTest(unittest.TestCase):
    def test_short_id(self):
        container = Container(attrs={'Id': '8497fe9244dd45cac543eb3c37d8605077'
                                           '6800eebef1f3ec2ee111e8ccf12db6'})
        assert container.short_id == '8497fe9244dd'

    def test_name(self):
        client = make_fake_client()
        container = client.containers.get(FAKE_CONTAINER_ID)
        assert container.name == 'foobar'

    def test_status(self):
        client = make_fake_client()
        container = client.containers.get(FAKE_CONTAINER_ID)
        assert container.status == "running"

    def test_attach(self):
        client = make_fake_client()
        container = client.containers.get(FAKE_CONTAINER_ID)
        container.attach(stream=True)
        client.api.attach.assert_called_with(FAKE_CONTAINER_ID, stream=True)

    def test_commit(self):
        client = make_fake_client()
        container = client.containers.get(FAKE_CONTAINER_ID)
        image = container.commit()
        client.api.commit.assert_called_with(FAKE_CONTAINER_ID,
                                             repository=None,
                                             tag=None)
        assert isinstance(image, Image)
        assert image.id == FAKE_IMAGE_ID

    def test_diff(self):
        client = make_fake_client()
        container = client.containers.get(FAKE_CONTAINER_ID)
        container.diff()
        client.api.diff.assert_called_with(FAKE_CONTAINER_ID)

    def test_exec_run(self):
        client = make_fake_client()
        container = client.containers.get(FAKE_CONTAINER_ID)
        container.exec_run("echo hello world", privileged=True, stream=True)
        client.api.exec_create.assert_called_with(
            FAKE_CONTAINER_ID, "echo hello world", stdout=True, stderr=True,
            stdin=False, tty=False, privileged=True, user='', environment=None,
            workdir=None,
        )
        client.api.exec_start.assert_called_with(
            FAKE_EXEC_ID, detach=False, tty=False, stream=True, socket=False,
            demux=False,
        )

    def test_exec_run_failure(self):
        client = make_fake_client()
        container = client.containers.get(FAKE_CONTAINER_ID)
        container.exec_run("docker ps", privileged=True, stream=False)
        client.api.exec_create.assert_called_with(
            FAKE_CONTAINER_ID, "docker ps", stdout=True, stderr=True,
            stdin=False, tty=False, privileged=True, user='', environment=None,
            workdir=None,
        )
        client.api.exec_start.assert_called_with(
            FAKE_EXEC_ID, detach=False, tty=False, stream=False, socket=False,
            demux=False,
        )

    def test_export(self):
        client = make_fake_client()
        container = client.containers.get(FAKE_CONTAINER_ID)
        container.export()
        client.api.export.assert_called_with(
            FAKE_CONTAINER_ID, DEFAULT_DATA_CHUNK_SIZE
        )

    def test_get_archive(self):
        client = make_fake_client()
        container = client.containers.get(FAKE_CONTAINER_ID)
        container.get_archive('foo')
        client.api.get_archive.assert_called_with(
            FAKE_CONTAINER_ID, 'foo', DEFAULT_DATA_CHUNK_SIZE, False
        )

    def test_image(self):
        client = make_fake_client()
        container = client.containers.get(FAKE_CONTAINER_ID)
        assert container.image.id == FAKE_IMAGE_ID

    def test_kill(self):
        client = make_fake_client()
        container = client.containers.get(FAKE_CONTAINER_ID)
        container.kill(signal=5)
        client.api.kill.assert_called_with(FAKE_CONTAINER_ID, signal=5)

    def test_labels(self):
        client = make_fake_client()
        container = client.containers.get(FAKE_CONTAINER_ID)
        assert container.labels == {'foo': 'bar'}

    def test_logs(self):
        client = make_fake_client()
        container = client.containers.get(FAKE_CONTAINER_ID)
        container.logs()
        client.api.logs.assert_called_with(FAKE_CONTAINER_ID)

    def test_pause(self):
        client = make_fake_client()
        container = client.containers.get(FAKE_CONTAINER_ID)
        container.pause()
        client.api.pause.assert_called_with(FAKE_CONTAINER_ID)

    def test_put_archive(self):
        client = make_fake_client()
        container = client.containers.get(FAKE_CONTAINER_ID)
        container.put_archive('path', 'foo')
        client.api.put_archive.assert_called_with(FAKE_CONTAINER_ID,
                                                  'path', 'foo')

    def test_remove(self):
        client = make_fake_client()
        container = client.containers.get(FAKE_CONTAINER_ID)
        container.remove()
        client.api.remove_container.assert_called_with(FAKE_CONTAINER_ID)

    def test_rename(self):
        client = make_fake_client()
        container = client.containers.get(FAKE_CONTAINER_ID)
        container.rename("foo")
        client.api.rename.assert_called_with(FAKE_CONTAINER_ID, "foo")

    def test_resize(self):
        client = make_fake_client()
        container = client.containers.get(FAKE_CONTAINER_ID)
        container.resize(1, 2)
        client.api.resize.assert_called_with(FAKE_CONTAINER_ID, 1, 2)

    def test_restart(self):
        client = make_fake_client()
        container = client.containers.get(FAKE_CONTAINER_ID)
        container.restart()
        client.api.restart.assert_called_with(FAKE_CONTAINER_ID)

    def test_start(self):
        client = make_fake_client()
        container = client.containers.get(FAKE_CONTAINER_ID)
        container.start()
        client.api.start.assert_called_with(FAKE_CONTAINER_ID)

    def test_stats(self):
        client = make_fake_client()
        container = client.containers.get(FAKE_CONTAINER_ID)
        container.stats()
        client.api.stats.assert_called_with(FAKE_CONTAINER_ID)

    def test_stop(self):
        client = make_fake_client()
        container = client.containers.get(FAKE_CONTAINER_ID)
        container.stop()
        client.api.stop.assert_called_with(FAKE_CONTAINER_ID)

    def test_top(self):
        client = make_fake_client()
        container = client.containers.get(FAKE_CONTAINER_ID)
        container.top()
        client.api.top.assert_called_with(FAKE_CONTAINER_ID)

    def test_unpause(self):
        client = make_fake_client()
        container = client.containers.get(FAKE_CONTAINER_ID)
        container.unpause()
        client.api.unpause.assert_called_with(FAKE_CONTAINER_ID)

    def test_update(self):
        client = make_fake_client()
        container = client.containers.get(FAKE_CONTAINER_ID)
        container.update(cpu_shares=2)
        client.api.update_container.assert_called_with(FAKE_CONTAINER_ID,
                                                       cpu_shares=2)

    def test_wait(self):
        client = make_fake_client()
        container = client.containers.get(FAKE_CONTAINER_ID)
        container.wait()
        client.api.wait.assert_called_with(FAKE_CONTAINER_ID)
