Пример #1
0
    def test__wait_for_log_without_log_specified(self):
        # GIVEN
        docker_container = DockerContainer(image='alpine', )

        docker_container._container = mock.MagicMock()

        # WHEN
        docker_container._wait_for_log()

        # THEN
        docker_container._container.logs.assert_not_called()
Пример #2
0
    def test_start(self, docker_mock):
        # GIVEN
        docker_container = DockerContainer(
            image='alpine',
            command='sh',
            ports=[
                (80, 80),
                (8888, 8888),
            ],
            volumes=[
                ('/toto-1', '/tata-1', 'ro'),
                ('/toto-2', '/tata-2', 'rw'),
            ],
            environment=[
                ('ENV_VAR_1', 'val-1'),
                ('ENV_VAR_2', 'val-2'),
            ],
        )

        # WHEN
        docker_container.start()

        # THEN
        docker_mock.assert_called_once_with()
        docker_mock.return_value.containers.run.assert_called_once_with(
            image='alpine',
            command='sh',
            detach=True,
            environment={
                'ENV_VAR_2': 'val-2',
                'ENV_VAR_1': 'val-1'
            },
            ports={
                80: 80,
                8888: 8888
            },
            volumes={
                '/toto-2': {
                    'bind': '/tata-2',
                    'mode': 'rw'
                },
                '/toto-1': {
                    'bind': '/tata-1',
                    'mode': 'ro'
                }
            })
        self.assertEqual(docker_container._client, docker_mock.return_value,
                         'Docker client should be defined')
        self.assertEqual(
            docker_container._container,
            docker_mock.return_value.containers.run.return_value,
            "Docker container should have been defined from API's call returns"
        )
Пример #3
0
    def test_shutdown_stop_command(self):
        # GIVEN
        docker_container = DockerContainer(image='alpine')
        container = mock.MagicMock()
        container.status = 'running'
        container.id = '55ee6c79294fa2304da51631b435940d78b0e31c56704159ed9644bfea10c86c'
        docker_container._container = container

        # WHEN
        docker_container.shutdown()

        # THEN
        docker_container._container.stop.assert_called_once_with(timeout=10)
Пример #4
0
    def test_shutdown_bad_status(self):
        # GIVEN
        docker_container = DockerContainer(image='alpine')
        container = mock.MagicMock()
        container.status = 'stopped'
        container.id = '55ee6c79294fa2304da51631b435940d78b0e31c56704159ed9644bfea10c86c'
        docker_container._container = container

        # WHEN
        docker_container.shutdown()

        # THEN
        docker_container._container.stop.assert_not_called()
        docker_container._container.kill.assert_not_called()
Пример #5
0
def docker(func=None, **kwargs):
    """
    Decorator to startup and shutdown a docker container.

    :param image: The name of the image to use.
    :param command: The input docker command to run,
    :param ports: The ports bindings to made
    :param volumes: The volumes to mount
    :param environment: The environment value
    :param wait_for_log: A string to wait in the logs before going into the function
    :param wait_for_port: A string to wait before going into the function
    :param kill_signal: If you want to kill the container, the signal to use. Otherwise, only a stop will be made.
    :param func: the function to be decorated
    :return: the decorated function
    """
    docker_container = DockerContainer(**kwargs)

    # Decorator in variable assignment : function is undefined
    if func is None:

        def decorator(func):  # pylint: disable=locally-disabled, missing-docstring
            return decorated(docker_container, func)

        return decorator

    return decorated(docker_container, func)
Пример #6
0
    def test__wait_for_log_with_log_specified(self):
        # GIVEN
        docker_container = DockerContainer(
            image='alpine',
            wait_for_log='wait for log',
        )

        docker_container._container = mock.MagicMock()
        docker_container._container.logs.return_value = [
            b'wait once', b'wait twice with : "wait for log" present !!'
        ]

        # WHEN
        docker_container._wait_for_log()

        # THEN
        docker_container._container.logs.assert_called_once_with(stream=True)
Пример #7
0
    def test_shutdown_kill_command(self):
        # GIVEN
        docker_container = DockerContainer(
            image='alpine',
            kill_signal=signal.SIGKILL,
        )
        container = mock.MagicMock()
        container.status = 'running'
        container.id = '55ee6c79294fa2304da51631b435940d78b0e31c56704159ed9644bfea10c86c'
        docker_container._container = container

        # WHEN
        docker_container.shutdown()

        # THEN
        docker_container._container.kill.assert_called_once_with(
            signal=signal.SIGKILL)
Пример #8
0
    def test__wait_for_port_with_port_specified(self, time_sleep_mock,
                                                socket_mock):
        # GIVEN
        docker_container = DockerContainer(
            image='alpine',
            wait_for_port=1234,
        )

        docker_container._client = mock.MagicMock()
        docker_container._client.containers.get.return_value.attrs = dict(
            NetworkSettings=dict(IPAddress='172.10.0.2'))
        docker_container._container = mock.MagicMock(id='c5f0cad13259')

        socket_mock.return_value.connect_ex.side_effect = [1, 1, 0]

        # WHEN
        docker_container._wait_for_port()

        # THEN
        time_sleep_mock.assert_called()
        socket_mock.assert_called_with(socket.AF_INET, socket.SOCK_STREAM)
        connect_ex_mock = socket_mock.return_value.connect_ex
        connect_ex_mock.assert_called_with(('172.10.0.2', 1234))
        self.assertEqual(
            connect_ex_mock.call_count, 3,
            'Should have been called 3 times instead of {call_nb}'.format(
                call_nb=connect_ex_mock.call_count))
Пример #9
0
    def test_init(self):
        # GIVEN
        inputs = {
            'image': 'alpine',
            'command': 'sh',
            'ports': {
                '80/tcp': 80,
                '8888/tcp': 8888,
            },
            'volumes': {
                '/toto-1': {
                    'bind': '/tata-1',
                    'mode': 'ro'
                },
                '/toto-2': {
                    'bind': '/tata-2',
                    'mode': 'ro'
                },
            },
            'environment': {
                'ENV_VAR_1': 'val-1',
                'ENV_VAR_2': 'val-2',
            },
            'wait_for_log': 'wait for log',
            'wait_for_port': 80,
            'kill_signal': signal.SIGKILL,
        }

        # WHEN
        wrapper = DockerContainer(**inputs)

        # THEN
        [
            self.assertIsNotNone(wrapper.p(key),
                                 'Key %s should be defined' % key)
            for key in inputs.keys()
        ]
Пример #10
0
    def test_init_using_alternatives(self):
        # GIVEN
        inputs = {
            'image':
            'alpine',
            'command':
            'sh',
            'ports': [
                (80, 80),
                (8888, 8888),
            ],
            'volumes': [
                ('/toto-1', '/tata-1', 'ro'),
                ('/toto-2', '/tata-2', 'rw'),
            ],
            'environment': [
                ('ENV_VAR_1', 'val-1'),
                ('ENV_VAR_2', 'val-2'),
            ],
            'wait_for_log':
            'wait for log',
            'wait_for_port':
            80,
            'kill_signal':
            signal.SIGKILL,
        }

        # WHEN
        wrapper = DockerContainer(**inputs)

        # THEN
        [
            self.assertIsNotNone(wrapper.p(key),
                                 'Key %s should be defined' % key)
            for key in inputs.keys()
        ]
Пример #11
0
    def test__wait_for_port_with_unsupported_errors(self, time_sleep_mock,
                                                    socket_mock):
        # GIVEN
        docker_container = DockerContainer(
            image='alpine',
            wait_for_port=1234,
        )

        docker_container._client = mock.MagicMock()
        docker_container._client.containers.get.return_value.attrs = dict(
            NetworkSettings=dict(IPAddress='172.10.0.2'))
        docker_container._container = mock.MagicMock(id='c5f0cad13259')
        docker_container._container.logs.return_value = b'\n'.join(
            [b'some container error ...', b'container failed to start'])

        socket_mock.return_value.connect_ex.side_effect = [
            1, 1, errno.EHOSTUNREACH
        ]

        # WHEN
        with self.assertRaises(DockerContainerError) as cm:
            docker_container._wait_for_port()

        # THEN
        expected_message = '\n'.join([
            '[alpine] Host 172.10.0.2 cannot be reach. The container may exit abnormally. Container logs :',
            'some container error ...', 'container failed to start'
        ])
        self.assertEquals(str(cm.exception), expected_message,
                          'Message should be explicit: %s' % expected_message)
        time_sleep_mock.assert_called()
        socket_mock.assert_called_with(socket.AF_INET, socket.SOCK_STREAM)
        connect_ex_mock = socket_mock.return_value.connect_ex
        connect_ex_mock.assert_called_with(('172.10.0.2', 1234))
        docker_container._container.logs.assert_called_once_with(stream=False)
        self.assertEqual(
            connect_ex_mock.call_count, 3,
            'Should have been called 3 times instead of {call_nb}'.format(
                call_nb=connect_ex_mock.call_count))