Ejemplo n.º 1
0
    def test_project_up_with_no_recreate_stopped(self):
        web = self.create_service('web')
        db = self.create_service('db', volumes=['/var/db'])
        project = Project('composetest', [web, db], self.client)
        project.start()
        self.assertEqual(len(project.containers()), 0)

        project.up(['db'])
        project.kill()

        old_containers = project.containers(stopped=True)

        self.assertEqual(len(old_containers), 1)
        old_db_id = old_containers[0].id
        db_volume_path = old_containers[0].inspect()['Volumes']['/var/db']

        project.up(allow_recreate=False)

        new_containers = project.containers(stopped=True)
        self.assertEqual(len(new_containers), 2)
        self.assertEqual([c.is_running for c in new_containers], [True, True])

        db_container = [c for c in new_containers if 'db' in c.name][0]
        self.assertEqual(db_container.id, old_db_id)
        self.assertEqual(db_container.inspect()['Volumes']['/var/db'],
                         db_volume_path)

        project.kill()
        project.remove_stopped()
Ejemplo n.º 2
0
    def test_no_warning_in_normal_mode(self):
        self.mock_client.info.return_value = {'Swarm': {'LocalNodeState': 'inactive'}}
        project = Project('composetest', [], self.mock_client)

        with mock.patch('compose.project.log') as fake_log:
            project.up()
            assert fake_log.warn.call_count == 0
Ejemplo n.º 3
0
    def test_project_up_with_no_recreate_stopped(self):
        web = self.create_service('web')
        db = self.create_service('db', volumes=[VolumeSpec.parse('/var/db')])
        project = Project('composetest', [web, db], self.client)
        project.start()
        self.assertEqual(len(project.containers()), 0)

        project.up(['db'])
        project.kill()

        old_containers = project.containers(stopped=True)

        self.assertEqual(len(old_containers), 1)
        old_container, = old_containers
        old_db_id = old_container.id
        db_volume_path = old_container.get_mount('/var/db')['Source']

        project.up(strategy=ConvergenceStrategy.never)

        new_containers = project.containers(stopped=True)
        self.assertEqual(len(new_containers), 2)
        self.assertEqual([c.is_running for c in new_containers], [True, True])

        db_container = [c for c in new_containers if 'db' in c.name][0]
        self.assertEqual(db_container.id, old_db_id)
        self.assertEqual(
            db_container.get_mount('/var/db')['Source'],
            db_volume_path)
Ejemplo n.º 4
0
    def test_no_warning_with_no_swarm_info(self):
        self.mock_client.info.return_value = {}
        project = Project('composetest', [], self.mock_client)

        with mock.patch('compose.project.log') as fake_log:
            project.up()
            assert fake_log.warn.call_count == 0
Ejemplo n.º 5
0
    def test_project_up_with_no_recreate_stopped(self):
        web = self.create_service("web")
        db = self.create_service("db", volumes=["/var/db"])
        project = Project("composetest", [web, db], self.client)
        project.start()
        self.assertEqual(len(project.containers()), 0)

        project.up(["db"])
        project.kill()

        old_containers = project.containers(stopped=True)

        self.assertEqual(len(old_containers), 1)
        old_db_id = old_containers[0].id
        db_volume_path = old_containers[0].inspect()["Volumes"]["/var/db"]

        project.up(strategy=ConvergenceStrategy.never)

        new_containers = project.containers(stopped=True)
        self.assertEqual(len(new_containers), 2)
        self.assertEqual([c.is_running for c in new_containers], [True, True])

        db_container = [c for c in new_containers if "db" in c.name][0]
        self.assertEqual(db_container.id, old_db_id)
        self.assertEqual(db_container.inspect()["Volumes"]["/var/db"], db_volume_path)
Ejemplo n.º 6
0
class ResilienceTest(DockerClientTestCase):
    def setUp(self):
        self.db = self.create_service("db", volumes=["/var/db"], command="top")
        self.project = Project("composetest", [self.db], self.client)

        container = self.db.create_container()
        self.db.start_container(container)
        self.host_path = container.get("Volumes")["/var/db"]

    def test_successful_recreate(self):
        self.project.up()
        container = self.db.containers()[0]
        self.assertEqual(container.get("Volumes")["/var/db"], self.host_path)

    def test_create_failure(self):
        with mock.patch("compose.service.Service.create_container", crash):
            with self.assertRaises(Crash):
                self.project.up()

        self.project.up()
        container = self.db.containers()[0]
        self.assertEqual(container.get("Volumes")["/var/db"], self.host_path)

    def test_start_failure(self):
        with mock.patch("compose.service.Service.start_container", crash):
            with self.assertRaises(Crash):
                self.project.up()

        self.project.up()
        container = self.db.containers()[0]
        self.assertEqual(container.get("Volumes")["/var/db"], self.host_path)
Ejemplo n.º 7
0
class ResilienceTest(DockerClientTestCase):
    def setUp(self):
        self.db = self.create_service(
            'db',
            volumes=[VolumeSpec.parse('/var/db')],
            command='top')
        self.project = Project('composetest', [self.db], self.client)

        container = self.db.create_container()
        container.start()
        self.host_path = container.get_mount('/var/db')['Source']

    def test_successful_recreate(self):
        self.project.up(strategy=ConvergenceStrategy.always)
        container = self.db.containers()[0]
        self.assertEqual(container.get_mount('/var/db')['Source'], self.host_path)

    def test_create_failure(self):
        with mock.patch('compose.service.Service.create_container', crash):
            with self.assertRaises(Crash):
                self.project.up(strategy=ConvergenceStrategy.always)

        self.project.up()
        container = self.db.containers()[0]
        self.assertEqual(container.get_mount('/var/db')['Source'], self.host_path)

    def test_start_failure(self):
        with mock.patch('compose.container.Container.start', crash):
            with self.assertRaises(Crash):
                self.project.up(strategy=ConvergenceStrategy.always)

        self.project.up()
        container = self.db.containers()[0]
        self.assertEqual(container.get_mount('/var/db')['Source'], self.host_path)
Ejemplo n.º 8
0
class ResilienceTest(DockerClientTestCase):
    def setUp(self):
        self.db = self.create_service('db', volumes=['/var/db'], command='top')
        self.project = Project('composetest', [self.db], self.client)

        container = self.db.create_container()
        self.db.start_container(container)
        self.host_path = container.get('Volumes')['/var/db']

    def test_successful_recreate(self):
        self.project.up(force_recreate=True)
        container = self.db.containers()[0]
        self.assertEqual(container.get('Volumes')['/var/db'], self.host_path)

    def test_create_failure(self):
        with mock.patch('compose.service.Service.create_container', crash):
            with self.assertRaises(Crash):
                self.project.up(force_recreate=True)

        self.project.up()
        container = self.db.containers()[0]
        self.assertEqual(container.get('Volumes')['/var/db'], self.host_path)

    def test_start_failure(self):
        with mock.patch('compose.service.Service.start_container', crash):
            with self.assertRaises(Crash):
                self.project.up(force_recreate=True)

        self.project.up()
        container = self.db.containers()[0]
        self.assertEqual(container.get('Volumes')['/var/db'], self.host_path)
Ejemplo n.º 9
0
    def test_containers(self):
        web = self.create_service('web')
        db = self.create_service('db')
        project = Project('composetest', [web, db], self.client)

        project.up()

        containers = project.containers()
        self.assertEqual(len(containers), 2)
Ejemplo n.º 10
0
    def test_containers(self):
        web = self.create_service("web")
        db = self.create_service("db")
        project = Project("composetest", [web, db], self.client)

        project.up()

        containers = project.containers()
        self.assertEqual(len(containers), 2)
Ejemplo n.º 11
0
    def test_containers_with_service_names(self):
        web = self.create_service("web")
        db = self.create_service("db")
        project = Project("composetest", [web, db], self.client)

        project.up()

        containers = project.containers(["web"])
        self.assertEqual([c.name for c in containers], ["composetest_web_1"])
Ejemplo n.º 12
0
    def test_project_up(self):
        web = self.create_service('web')
        db = self.create_service('db', volumes=[VolumeSpec.parse('/var/db')])
        project = Project('composetest', [web, db], self.client)
        project.start()
        self.assertEqual(len(project.containers()), 0)

        project.up(['db'])
        self.assertEqual(len(project.containers()), 1)
        self.assertEqual(len(db.containers()), 1)
        self.assertEqual(len(web.containers()), 0)
Ejemplo n.º 13
0
    def test_project_up_without_all_services(self):
        console = self.create_service('console')
        db = self.create_service('db')
        project = Project('composetest', [console, db], self.client)
        project.start()
        self.assertEqual(len(project.containers()), 0)

        project.up()
        self.assertEqual(len(project.containers()), 2)
        self.assertEqual(len(db.containers()), 1)
        self.assertEqual(len(console.containers()), 1)
Ejemplo n.º 14
0
    def test_containers_with_service_names(self):
        web = self.create_service('web')
        db = self.create_service('db')
        project = Project('composetest', [web, db], self.client)

        project.up()

        containers = project.containers(['web'])
        self.assertEqual(
            [c.name for c in containers],
            ['composetest_web_1'])
Ejemplo n.º 15
0
    def test_project_up_starts_uncreated_services(self):
        db = self.create_service('db')
        web = self.create_service('web', links=[(db, 'db')])
        project = Project('composetest', [db, web], self.client)
        project.up(['db'])
        self.assertEqual(len(project.containers()), 1)

        project.up()
        self.assertEqual(len(project.containers()), 2)
        self.assertEqual(len(db.containers()), 1)
        self.assertEqual(len(web.containers()), 1)
Ejemplo n.º 16
0
    def test_project_up_starts_uncreated_services(self):
        db = self.create_service("db")
        web = self.create_service("web", links=[(db, "db")])
        project = Project("composetest", [db, web], self.client)
        project.up(["db"])
        self.assertEqual(len(project.containers()), 1)

        project.up()
        self.assertEqual(len(project.containers()), 2)
        self.assertEqual(len(db.containers()), 1)
        self.assertEqual(len(web.containers()), 1)
Ejemplo n.º 17
0
    def test_project_up(self):
        web = self.create_service("web")
        db = self.create_service("db", volumes=["/var/db"])
        project = Project("composetest", [web, db], self.client)
        project.start()
        self.assertEqual(len(project.containers()), 0)

        project.up(["db"])
        self.assertEqual(len(project.containers()), 1)
        self.assertEqual(len(db.containers()), 1)
        self.assertEqual(len(web.containers()), 0)
Ejemplo n.º 18
0
    def test_project_up_with_custom_network(self):
        self.require_api_version('1.21')
        client = docker_client(version='1.21')
        network_name = 'composetest-custom'

        client.create_network(network_name)
        self.addCleanup(client.remove_network, network_name)

        web = self.create_service('web', net=Net(network_name))
        project = Project('composetest', [web], client, use_networking=True)
        project.up()

        assert project.get_network() is None
Ejemplo n.º 19
0
    def test_project_up_without_all_services(self):
        console = self.create_service('console')
        db = self.create_service('db')
        project = Project('composetest', [console, db], self.client)
        project.start()
        self.assertEqual(len(project.containers()), 0)

        project.up()
        self.assertEqual(len(project.containers()), 2)
        self.assertEqual(len(db.containers()), 1)
        self.assertEqual(len(console.containers()), 1)

        project.kill()
        project.remove_stopped()
Ejemplo n.º 20
0
    def test_project_up(self):
        web = self.create_service('web')
        db = self.create_service('db', volumes=['/var/db'])
        project = Project('composetest', [web, db], self.client)
        project.start()
        self.assertEqual(len(project.containers()), 0)

        project.up(['db'])
        self.assertEqual(len(project.containers()), 1)
        self.assertEqual(len(db.containers()), 1)
        self.assertEqual(len(web.containers()), 0)

        project.kill()
        project.remove_stopped()
Ejemplo n.º 21
0
    def test_project_up_starts_links(self):
        console = self.create_service('console')
        db = self.create_service('db', volumes=[VolumeSpec.parse('/var/db')])
        web = self.create_service('web', links=[(db, 'db')])

        project = Project('composetest', [web, db, console], self.client)
        project.start()
        self.assertEqual(len(project.containers()), 0)

        project.up(['web'])
        self.assertEqual(len(project.containers()), 2)
        self.assertEqual(len(web.containers()), 1)
        self.assertEqual(len(db.containers()), 1)
        self.assertEqual(len(console.containers()), 0)
Ejemplo n.º 22
0
    def test_project_up_starts_links(self):
        console = self.create_service("console")
        db = self.create_service("db", volumes=["/var/db"])
        web = self.create_service("web", links=[(db, "db")])

        project = Project("composetest", [web, db, console], self.client)
        project.start()
        self.assertEqual(len(project.containers()), 0)

        project.up(["web"])
        self.assertEqual(len(project.containers()), 2)
        self.assertEqual(len(web.containers()), 1)
        self.assertEqual(len(db.containers()), 1)
        self.assertEqual(len(console.containers()), 0)
Ejemplo n.º 23
0
    def test_project_up_starts_links(self):
        console = self.create_service('console')
        db = self.create_service('db', volumes=[VolumeSpec.parse('/var/db')])
        web = self.create_service('web', links=[(db, 'db')])

        project = Project('composetest', [web, db, console], self.client)
        project.start()
        self.assertEqual(len(project.containers()), 0)

        project.up(['web'])
        self.assertEqual(len(project.containers()), 2)
        self.assertEqual(len(web.containers()), 1)
        self.assertEqual(len(db.containers()), 1)
        self.assertEqual(len(console.containers()), 0)
Ejemplo n.º 24
0
def docker_containers(
        docker_project: Project) -> Iterator[Dict[str, Container]]:
    """
    Spins up a the containers for the Docker project and returns
    them.

    Note that this fixture's scope is a single test; the containers
    will be stopped after the test is finished.

    This is intentional; stopping the containers destroys local
    storage, so that the next test can start with fresh containers.
    """
    containers: List[Container] = docker_project.up(DOCKER_SERVICES)
    if not containers:
        raise ValueError("`docker-compose` didn't launch any containers!")
    containers_by_name = dict([(c.name, c) for c in containers])

    yield containers_by_name

    # Send container logs to stdout, so that they get included in
    # the test report.
    # https://docs.pytest.org/en/latest/capture.html
    for container in sorted(containers, key=lambda c: c.name):
        header = "Logs from {0}:".format(container.name)
        logger.info(header)
        logger.info("=" * len(header))
        logger.info(container.logs().decode("utf-8", errors="replace")
                    or "(no logs)")
        logger.info('')

    docker_project.down(ImageType.none, False)
Ejemplo n.º 25
0
        def scoped_containers_fixture(docker_project: Project, request):
            now = datetime.utcnow()
            if request.config.getoption("--use-running-containers"):
                containers = docker_project.containers(
                )  # type: List[Container]
            else:
                if any(docker_project.containers()):
                    raise ContainersAlreadyExist(
                        'pytest-docker-compose tried to start containers but there are'
                        ' already running containers: %s, you probably scoped your'
                        ' tests wrong' % docker_project.containers())
                containers = docker_project.up()
                if not containers:
                    raise ValueError(
                        "`docker-compose` didn't launch any containers!")

            container_getter = ContainerGetter(docker_project)
            yield container_getter

            if request.config.getoption("--verbose"):
                for container in sorted(containers, key=lambda c: c.name):
                    header = "Logs from {name}:".format(name=container.name)
                    print(header, '\n', "=" * len(header))
                    print(
                        container.logs(since=now).decode("utf-8",
                                                         errors="replace")
                        or "(no logs)", '\n')

            if not request.config.getoption("--use-running-containers"):
                docker_project.down(
                    ImageType.none,
                    request.config.getoption(
                        "--docker-compose-remove-volumes"))
Ejemplo n.º 26
0
    def test_project_up_with_no_deps(self):
        console = self.create_service('console')
        db = self.create_service('db', volumes=['/var/db'])
        web = self.create_service('web', links=[(db, 'db')])

        project = Project('composetest', [web, db, console], self.client)
        project.start()
        self.assertEqual(len(project.containers()), 0)

        project.up(['web'], start_links=False)
        self.assertEqual(len(project.containers()), 1)
        self.assertEqual(len(web.containers()), 1)
        self.assertEqual(len(db.containers()), 0)
        self.assertEqual(len(console.containers()), 0)

        project.kill()
        project.remove_stopped()
Ejemplo n.º 27
0
    def test_project_up_recreates_containers(self):
        web = self.create_service('web')
        db = self.create_service('db', volumes=['/etc'])
        project = Project('composetest', [web, db], self.client)
        project.start()
        self.assertEqual(len(project.containers()), 0)

        project.up(['db'])
        self.assertEqual(len(project.containers()), 1)
        old_db_id = project.containers()[0].id
        db_volume_path = project.containers()[0].get('Volumes./etc')

        project.up()
        self.assertEqual(len(project.containers()), 2)

        db_container = [c for c in project.containers() if 'db' in c.name][0]
        self.assertNotEqual(db_container.id, old_db_id)
        self.assertEqual(db_container.get('Volumes./etc'), db_volume_path)
Ejemplo n.º 28
0
    def test_recreate_preserves_volumes(self):
        web = self.create_service('web')
        db = self.create_service('db', volumes=[VolumeSpec.parse('/etc')])
        project = Project('composetest', [web, db], self.client)
        project.start()
        self.assertEqual(len(project.containers()), 0)

        project.up(['db'])
        self.assertEqual(len(project.containers()), 1)
        old_db_id = project.containers()[0].id
        db_volume_path = project.containers()[0].get('Volumes./etc')

        project.up(strategy=ConvergenceStrategy.always)
        self.assertEqual(len(project.containers()), 2)

        db_container = [c for c in project.containers() if 'db' in c.name][0]
        self.assertNotEqual(db_container.id, old_db_id)
        self.assertEqual(db_container.get('Volumes./etc'), db_volume_path)
Ejemplo n.º 29
0
    def test_recreate_preserves_volumes(self):
        web = self.create_service("web")
        db = self.create_service("db", volumes=["/etc"])
        project = Project("composetest", [web, db], self.client)
        project.start()
        self.assertEqual(len(project.containers()), 0)

        project.up(["db"])
        self.assertEqual(len(project.containers()), 1)
        old_db_id = project.containers()[0].id
        db_volume_path = project.containers()[0].get("Volumes./etc")

        project.up(strategy=ConvergenceStrategy.always)
        self.assertEqual(len(project.containers()), 2)

        db_container = [c for c in project.containers() if "db" in c.name][0]
        self.assertNotEqual(db_container.id, old_db_id)
        self.assertEqual(db_container.get("Volumes./etc"), db_volume_path)
Ejemplo n.º 30
0
    def test_project_up_with_no_recreate_running(self):
        web = self.create_service("web")
        db = self.create_service("db", volumes=["/var/db"])
        project = Project("composetest", [web, db], self.client)
        project.start()
        self.assertEqual(len(project.containers()), 0)

        project.up(["db"])
        self.assertEqual(len(project.containers()), 1)
        old_db_id = project.containers()[0].id
        db_volume_path = project.containers()[0].inspect()["Volumes"]["/var/db"]

        project.up(strategy=ConvergenceStrategy.never)
        self.assertEqual(len(project.containers()), 2)

        db_container = [c for c in project.containers() if "db" in c.name][0]
        self.assertEqual(db_container.id, old_db_id)
        self.assertEqual(db_container.inspect()["Volumes"]["/var/db"], db_volume_path)
Ejemplo n.º 31
0
    def test_project_up_with_no_recreate_running(self):
        web = self.create_service('web')
        db = self.create_service('db', volumes=['/var/db'])
        project = Project('composetest', [web, db], self.client)
        project.start()
        self.assertEqual(len(project.containers()), 0)

        project.up(['db'])
        self.assertEqual(len(project.containers()), 1)
        old_db_id = project.containers()[0].id
        db_volume_path = project.containers()[0].inspect()['Volumes']['/var/db']

        project.up(strategy=ConvergenceStrategy.never)
        self.assertEqual(len(project.containers()), 2)

        db_container = [c for c in project.containers() if 'db' in c.name][0]
        self.assertEqual(db_container.id, old_db_id)
        self.assertEqual(db_container.inspect()['Volumes']['/var/db'],
                         db_volume_path)
Ejemplo n.º 32
0
    def _containers_up(cls, docker_project: Project) -> typing.List[Container]:
        """
        Brings up all containers in the specified project.
        """
        containers = docker_project.up()  # type: typing.List[Container]

        if not containers:
            raise ValueError("`docker-compose` didn't launch any containers!")

        return containers
Ejemplo n.º 33
0
    def test_project_up_with_no_recreate_running(self):
        web = self.create_service('web')
        db = self.create_service('db', volumes=['/var/db'])
        project = Project('composetest', [web, db], self.client)
        project.start()
        self.assertEqual(len(project.containers()), 0)

        project.up(['db'])
        self.assertEqual(len(project.containers()), 1)
        old_db_id = project.containers()[0].id
        db_volume_path = project.containers()[0].inspect()['Volumes']['/var/db']

        project.up(allow_recreate=False)
        self.assertEqual(len(project.containers()), 2)

        db_container = [c for c in project.containers() if 'db' in c.name][0]
        self.assertEqual(db_container.id, old_db_id)
        self.assertEqual(db_container.inspect()['Volumes']['/var/db'],
                         db_volume_path)
Ejemplo n.º 34
0
    def test_project_up_with_no_recreate_running(self):
        web = self.create_service('web')
        db = self.create_service('db', volumes=[VolumeSpec.parse('/var/db')])
        project = Project('composetest', [web, db], self.client)
        project.start()
        self.assertEqual(len(project.containers()), 0)

        project.up(['db'])
        self.assertEqual(len(project.containers()), 1)
        old_db_id = project.containers()[0].id
        container, = project.containers()
        db_volume_path = container.get_mount('/var/db')['Source']

        project.up(strategy=ConvergenceStrategy.never)
        self.assertEqual(len(project.containers()), 2)

        db_container = [c for c in project.containers() if 'db' in c.name][0]
        self.assertEqual(db_container.id, old_db_id)
        self.assertEqual(
            db_container.get_mount('/var/db')['Source'], db_volume_path)
Ejemplo n.º 35
0
class ResilienceTest(DockerClientTestCase):
    def setUp(self):
        self.db = self.create_service('db',
                                      volumes=[VolumeSpec.parse('/var/db')],
                                      command='top')
        self.project = Project('composetest', [self.db], self.client)

        container = self.db.create_container()
        self.db.start_container(container)
        self.host_path = container.get_mount('/var/db')['Source']

    def tearDown(self):
        del self.project
        del self.db
        super(ResilienceTest, self).tearDown()

    def test_successful_recreate(self):
        self.project.up(strategy=ConvergenceStrategy.always)
        container = self.db.containers()[0]
        self.assertEqual(
            container.get_mount('/var/db')['Source'], self.host_path)

    def test_create_failure(self):
        with mock.patch('compose.service.Service.create_container', crash):
            with self.assertRaises(Crash):
                self.project.up(strategy=ConvergenceStrategy.always)

        self.project.up()
        container = self.db.containers()[0]
        self.assertEqual(
            container.get_mount('/var/db')['Source'], self.host_path)

    def test_start_failure(self):
        with mock.patch('compose.service.Service.start_container', crash):
            with self.assertRaises(Crash):
                self.project.up(strategy=ConvergenceStrategy.always)

        self.project.up()
        container = self.db.containers()[0]
        self.assertEqual(
            container.get_mount('/var/db')['Source'], self.host_path)
Ejemplo n.º 36
0
    def test_unscale_after_restart(self):
        web = self.create_service('web')
        project = Project('composetest', [web], self.client)

        project.start()

        service = project.get_service('web')
        service.scale(1)
        self.assertEqual(len(service.containers()), 1)
        service.scale(3)
        self.assertEqual(len(service.containers()), 3)
        project.up()
        service = project.get_service('web')
        self.assertEqual(len(service.containers()), 3)
        service.scale(1)
        self.assertEqual(len(service.containers()), 1)
        project.up()
        service = project.get_service('web')
        self.assertEqual(len(service.containers()), 1)
        # does scale=0 ,makes any sense? after recreating at least 1 container is running
        service.scale(0)
        project.up()
        service = project.get_service('web')
        self.assertEqual(len(service.containers()), 1)
        project.kill()
        project.remove_stopped()
Ejemplo n.º 37
0
    def test_recreate_fails(self):
        db = self.create_service('db', volumes=['/var/db'], command='top')
        project = Project('composetest', [db], self.client)

        container = db.create_container()
        db.start_container(container)
        host_path = container.get('Volumes')['/var/db']

        project.up()
        container = db.containers()[0]
        self.assertEqual(container.get('Volumes')['/var/db'], host_path)

        with mock.patch('compose.service.Service.create_container', crash):
            with self.assertRaises(Crash):
                project.up()

        project.up()
        container = db.containers()[0]
        self.assertEqual(container.get('Volumes')['/var/db'], host_path)
Ejemplo n.º 38
0
async def docker_compose(loop, request, docker_project: Project,
                         postgres_override_addr):
    async def check_postgres(url):
        conn = await asyncpg.connect(url, loop=loop)
        await conn.close()

    checks = {
        ('postgres', 'POSTGRES_DSN', postgres_override_addr,
         'postgresql://[email protected]:%d/postgres'
         '' % COMPOSE_POSTGRES_PORT, check_postgres),
    }

    result = {}

    fns = []
    to_start = []
    for svc, name, override, url, fn in checks:
        if override:
            result[name] = override
        else:
            to_start.append(svc)
            fns.append((fn, url))
            result[name] = url

    if not to_start:
        yield result
    else:
        containers = docker_project.up(to_start, remove_orphans=True)

        if not containers:
            raise ValueError("`docker-compose` didn't launch any containers!")

        try:
            timeout = 60
            start_time = time.time()
            print()
            print('Waiting for docker services...')
            last_err = None
            while start_time + timeout > time.time():
                try:
                    await asyncio.gather(*[fn(url) for fn, url in fns],
                                         loop=loop)
                    break

                except Exception as err:
                    last_err = err
                    await asyncio.sleep(1, loop=loop)
            else:
                last_err_type = type(last_err)
                raise TimeoutError(f'Unable to start all container services'
                                   f' within {timeout} seconds. Last error:'
                                   f' {last_err} ({last_err_type})')
            print('Docker services are ready')
            yield result
        finally:

            # Send container logs to stdout, so that they get included in
            # the test report.
            # https://docs.pytest.org/en/latest/capture.html
            for container in sorted(containers, key=lambda c: c.name):
                if request.config.getoption('show_docker_logs'):
                    header = f"Logs from {container.name}:"
                    print(header)
                    print("=" * len(header))
                    print(container.logs().decode("utf-8", errors="replace")
                          or "(no logs)")
                    print()

            docker_project.down(ImageType.none, False)
Ejemplo n.º 39
0
async def compose(loop,
                  request,
                  docker_project: Project,
                  postgres_override_addr,
                  rabbit_override_addr):
    async def check_postgres(url):
        conn = await asyncpg.connect(url, loop=loop)
        await conn.close()

    async def check_rabbit(url):
        transport, protocol = await aioamqp.from_url(url, loop=loop)
        await protocol.close()

    # async def check_redis(url):
    #     conn = await aioredis.create_connection(url)
    #     conn.close()

    # async def check_http(url):
    #     async with aiohttp.ClientSession(loop=loop) as ses:
    #         resp = await ses.get(url)
    #         assert resp.status == 200

    checks = {
        (
            'postgres',
            'DB_URL',
            postgres_override_addr,
            COMPOSE_POSTGRES_URL,
            check_postgres
        ),
        (
            'rabbit',
            'RABBIT_URL',
            rabbit_override_addr,
            COMPOSE_RABBIT_URL,
            check_rabbit
        ),
    }

    result = {}

    fns = []
    to_start = []
    urls = []
    for svc, name, override, url, fn in checks:
        if override:
            result[name] = override
        else:
            to_start.append(svc)
            urls.append(url)
            fns.append((fn, url))
            result[name] = url

    if not to_start:
        yield result
    else:
        containers = docker_project.up(to_start)

        if not containers:
            raise ValueError("`docker-compose` didn't launch any containers!")

        try:
            timeout = 60
            start_time = time.time()
            print()
            print('Waiting for docker services...')
            print('\n'.join(urls))
            last_err = None
            while start_time + timeout > time.time():
                try:
                    await asyncio.gather(*[fn(url) for fn, url in fns],
                                         loop=loop)
                    break

                except Exception as err:
                    last_err = err
                    await asyncio.sleep(1, loop=loop)
            else:
                last_err_type = type(last_err)
                raise TimeoutError(f'Unable to start all container services'
                                   f' within {timeout} seconds. Last error:'
                                   f' {last_err} ({last_err_type})')
            print('Docker services are ready')
            yield result
        finally:

            # Send container logs to stdout, so that they get included in
            # the test report.
            # https://docs.pytest.org/en/latest/capture.html
            for container in sorted(containers, key=lambda c: c.name):
                if request.config.getoption('show_docker_logs'):
                    header = f"Logs from {container.name}:"
                    print(header)
                    print("=" * len(header))
                    print(
                        container.logs().decode("utf-8", errors="replace") or
                        "(no logs)"
                    )
                    print()

            docker_project.down(ImageType.none, False)