Exemplo n.º 1
0
    def test_get_docker_ps(self, mockLogging, mockClient):
        """
        Assert that the docker_ps task
        calls the docker client.containers() function.
        """
        containers = [{'Id': 'Aaa', 'Status': 'Running'},
                      {'Id': 'Bbb', 'Status': 'Host Down'},
                      {'Id': 'Ccc', 'Status': 'Up'},
                      ]

        def inspect(container=''):
            if container == 'Ccc':
                raise
            else:
                return {'Id': container, 'Config': {'Labels': {'type': 'preprocess'}}}

        mockClient.return_value.containers.return_value = containers
        mockClient.return_value.inspect_container.side_effect = inspect

        get_docker_ps.delay()
        # Call docker ps for all containers, but only once
        mockClient.return_value.containers.assert_called_with(all=True)
        self.assertEqual(mockClient.return_value.containers.call_count, 1)
        # Call inspect for all but Host Down container
        self.assertEqual(
            mockClient.return_value.inspect_container.call_count, 2)
        # Log error only for Ccc container
        self.assertEqual(mockLogging.call_count, 1)
    def _get_latest_docker_status(self):
        """
        Synchronise local Django Container models with remote Docker containers
        """
        ps = get_docker_ps.delay()

        containers_docker = None
        try:
            containers_docker = ps.get(timeout=30)
        except celery.exceptions.TimeoutError as e:
            logging.exception("get_docker_ps timed out (30 seconds)")

        if containers_docker is None:
            # Apparently something is wrong with the remote docker or celery
            # To prevent new task creation by Containers exit beat.
            return

        docker_dict = {x['Id']: x for x in containers_docker}
        docker_set = set(docker_dict.keys())

        # retrieve container from database
        container_set = set(
            Container.objects.values_list('docker_id', flat=True))

        # Work out matching matrix
        #       docker  yes non
        # model x
        # yes           1_1 1_0
        # no            0_1 0_0
        #
        m_1_1 = container_set & docker_set
        m_1_0 = container_set - docker_set
        m_0_1 = docker_set - container_set
        m_0_0 = ((docker_set | container_set) -
                 (docker_set ^ container_set) -
                 (docker_set & container_set)
                 )

        # Update state of all matching containers
        container_match = m_1_1 | m_1_0
        for con_id in container_match:
            snapshot = docker_dict[
                con_id] if con_id in docker_dict else None
            for c in Container.objects.filter(docker_id=con_id):
                c.update_from_docker_snapshot(snapshot)

        # Call error for mismatch
        container_mismatch = m_0_1 | m_0_0
        for container in container_mismatch:
            info = docker_dict[container]
            if ('Config' in info and
                'Labels' in info['Config'] and
                    'type' in info['Config']['Labels']):
                type = info['Config']['Labels']['type']
                if type in [choice[0] for choice in Container.CONTAINER_TYPE_CHOICES]:
                    self.stderr.write(
                        "Docker container {} not found in database!".format(container))
                    do_docker_remove.delay(container, force=True)
            else:
                logging.info("Found non-delft3dgt docker container, ignoring.")
Exemplo n.º 3
0
    def test_get_docker_ps(self, mockLogging, mockClient):
        """
        Assert that the docker_ps task
        calls the docker client.containers() function.
        """

        containers = [
            {
                'Id': 'Aaa',
                'Status': 'Running'
            },
            {
                'Id': 'Bbb',
                'Status': 'Host Down'
            },
            {
                'Id': 'Ccc',
                'Status': 'Up'
            },
        ]

        def inspect(container=''):
            if container == 'Ccc':
                raise
            else:
                return {
                    'Id': container,
                    'Config': {
                        'Labels': {
                            'type': 'preprocess'
                        }
                    }
                }

        mockClient.return_value.containers.return_value = containers
        mockClient.return_value.inspect_container.side_effect = inspect

        get_docker_ps.delay()
        # Call docker ps for all containers, but only once
        mockClient.return_value.containers.assert_called_with(all=True)
        self.assertEqual(mockClient.return_value.containers.call_count, 1)
        # Call inspect for all but Host Down container
        self.assertEqual(mockClient.return_value.inspect_container.call_count,
                         2)
        # Log error only for Ccc container
        self.assertEqual(mockLogging.call_count, 1)