From 3a98012d5fcdd3f2f0395a455ce49a7ab97c6267 Mon Sep 17 00:00:00 2001 From: romnnn Date: Sun, 6 Sep 2020 22:43:53 +0200 Subject: [PATCH 1/3] add logging, remove crayon and blindspin --- example.py | 7 ++++++ requirements/3.5.txt | 3 --- requirements/3.6.txt | 3 --- requirements/3.7.txt | 3 --- requirements/3.8.txt | 3 --- setup.py | 2 -- testcontainers/compose.py | 32 +++++++++++-------------- testcontainers/core/container.py | 36 +++++++++++++--------------- testcontainers/core/utils.py | 10 ++++++++ testcontainers/core/waiting_utils.py | 31 ++++++++++++------------ 10 files changed, 62 insertions(+), 68 deletions(-) create mode 100644 example.py diff --git a/example.py b/example.py new file mode 100644 index 000000000..9b3d38094 --- /dev/null +++ b/example.py @@ -0,0 +1,7 @@ +import sqlalchemy +from testcontainers.mysql import MySqlContainer + +with MySqlContainer('mysql:5.7.17') as mysql: + engine = sqlalchemy.create_engine(mysql.get_connection_url()) + version, = engine.execute("select version()").fetchone() + print(version) # 5.7.17 diff --git a/requirements/3.5.txt b/requirements/3.5.txt index 40b7971ce..009a01ad4 100644 --- a/requirements/3.5.txt +++ b/requirements/3.5.txt @@ -9,16 +9,13 @@ alabaster==0.7.12 # via sphinx attrs==19.3.0 # via jsonschema, pytest babel==2.8.0 # via sphinx bcrypt==3.1.7 # via paramiko -blindspin==2.0.1 # via testcontainers cached-property==1.5.1 # via docker-compose cachetools==4.1.1 # via google-auth certifi==2020.6.20 # via requests cffi==1.14.2 # via bcrypt, cryptography, pynacl chardet==3.0.4 # via requests codecov==2.1.8 # via -r requirements.in -colorama==0.4.3 # via crayons coverage==5.2.1 # via codecov, pytest-cov -crayons==0.3.1 # via testcontainers cryptography==3.0 # via paramiko cx-oracle==8.0.0 # via testcontainers deprecation==2.1.0 # via testcontainers diff --git a/requirements/3.6.txt b/requirements/3.6.txt index dc3ec6b26..f9e5c517c 100644 --- a/requirements/3.6.txt +++ b/requirements/3.6.txt @@ -9,16 +9,13 @@ alabaster==0.7.12 # via sphinx attrs==19.3.0 # via jsonschema, pytest babel==2.8.0 # via sphinx bcrypt==3.2.0 # via paramiko -blindspin==2.0.1 # via testcontainers cached-property==1.5.1 # via docker-compose cachetools==4.1.1 # via google-auth certifi==2020.6.20 # via requests cffi==1.14.2 # via bcrypt, cryptography, pynacl chardet==3.0.4 # via requests codecov==2.1.8 # via -r requirements.in -colorama==0.4.3 # via crayons coverage==5.2.1 # via codecov, pytest-cov -crayons==0.3.1 # via testcontainers cryptography==3.0 # via paramiko cx-oracle==8.0.0 # via testcontainers deprecation==2.1.0 # via testcontainers diff --git a/requirements/3.7.txt b/requirements/3.7.txt index 38ede0309..c46235555 100644 --- a/requirements/3.7.txt +++ b/requirements/3.7.txt @@ -9,16 +9,13 @@ alabaster==0.7.12 # via sphinx attrs==19.3.0 # via jsonschema, pytest babel==2.8.0 # via sphinx bcrypt==3.2.0 # via paramiko -blindspin==2.0.1 # via testcontainers cached-property==1.5.1 # via docker-compose cachetools==4.1.1 # via google-auth certifi==2020.6.20 # via requests cffi==1.14.2 # via bcrypt, cryptography, pynacl chardet==3.0.4 # via requests codecov==2.1.8 # via -r requirements.in -colorama==0.4.3 # via crayons coverage==5.2.1 # via codecov, pytest-cov -crayons==0.3.1 # via testcontainers cryptography==3.0 # via paramiko cx-oracle==8.0.0 # via testcontainers deprecation==2.1.0 # via testcontainers diff --git a/requirements/3.8.txt b/requirements/3.8.txt index c071c3cc3..b0c455e9d 100644 --- a/requirements/3.8.txt +++ b/requirements/3.8.txt @@ -9,16 +9,13 @@ alabaster==0.7.12 # via sphinx attrs==19.3.0 # via jsonschema, pytest babel==2.8.0 # via sphinx bcrypt==3.2.0 # via paramiko -blindspin==2.0.1 # via testcontainers cached-property==1.5.1 # via docker-compose cachetools==4.1.1 # via google-auth certifi==2020.6.20 # via requests cffi==1.14.2 # via bcrypt, cryptography, pynacl chardet==3.0.4 # via requests codecov==2.1.8 # via -r requirements.in -colorama==0.4.3 # via crayons coverage==5.2.1 # via codecov, pytest-cov -crayons==0.3.1 # via testcontainers cryptography==3.0 # via paramiko cx-oracle==8.0.0 # via testcontainers deprecation==2.1.0 # via testcontainers diff --git a/setup.py b/setup.py index 9eb65262f..209408d49 100644 --- a/setup.py +++ b/setup.py @@ -44,8 +44,6 @@ install_requires=[ 'docker', 'wrapt', - 'crayons', - 'blindspin', 'deprecation', ], extras_require={ diff --git a/testcontainers/compose.py b/testcontainers/compose.py index 3037ae1ad..9e595a605 100644 --- a/testcontainers/compose.py +++ b/testcontainers/compose.py @@ -7,7 +7,6 @@ import subprocess -import blindspin import requests from testcontainers.core.waiting_utils import wait_container_is_ready @@ -81,28 +80,25 @@ def docker_compose_command(self): return docker_compose_cmd def start(self): - with blindspin.spinner(): - if self.pull: - pull_cmd = self.docker_compose_command() + ['pull'] - subprocess.call(pull_cmd, cwd=self.filepath) - up_cmd = self.docker_compose_command() + ['up', '-d'] - subprocess.call(up_cmd, cwd=self.filepath) + if self.pull: + pull_cmd = self.docker_compose_command() + ['pull'] + subprocess.call(pull_cmd, cwd=self.filepath) + up_cmd = self.docker_compose_command() + ['up', '-d'] + subprocess.call(up_cmd, cwd=self.filepath) def stop(self): - with blindspin.spinner(): - down_cmd = self.docker_compose_command() + ['down', '-v'] - subprocess.call(down_cmd, cwd=self.filepath) + down_cmd = self.docker_compose_command() + ['down', '-v'] + subprocess.call(down_cmd, cwd=self.filepath) def get_logs(self): logs_cmd = self.docker_compose_command() + ["logs"] - with blindspin.spinner(): - result = subprocess.run( - logs_cmd, - cwd=self.filepath, - stdout=subprocess.PIPE, - stderr=subprocess.PIPE, - ) - return result.stdout, result.stderr + result = subprocess.run( + logs_cmd, + cwd=self.filepath, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + ) + return result.stdout, result.stderr def get_service_port(self, service_name, port): return self._get_service_info(service_name, port)[1] diff --git a/testcontainers/core/container.py b/testcontainers/core/container.py index 3ee98e399..2d7d85ddc 100644 --- a/testcontainers/core/container.py +++ b/testcontainers/core/container.py @@ -1,11 +1,10 @@ -import blindspin -import crayons from docker.models.containers import Container from testcontainers.core.docker_client import DockerClient from testcontainers.core.exceptions import ContainerStartException -from testcontainers.core.utils import inside_container +from testcontainers.core.utils import setup_logger, inside_container +logger = setup_logger(__name__) class DockerContainer(object): def __init__(self, image, **kargs): @@ -38,23 +37,20 @@ def with_kargs(self, **kargs) -> 'DockerContainer': return self def start(self): - print("") - print("{} {}".format(crayons.yellow("Pulling image"), - crayons.red(self.image))) - with blindspin.spinner(): - docker_client = self.get_docker_client() - self._container = docker_client.run(self.image, - command=self._command, - detach=True, - environment=self.env, - ports=self.ports, - name=self._name, - volumes=self.volumes, - **self._kargs - ) - print("") - print("Container started: ", - crayons.yellow(self._container.short_id, bold=True)) + logger.info("") + logger.info("{} {}".format("Pulling image", self.image)) + docker_client = self.get_docker_client() + self._container = docker_client.run(self.image, + command=self._command, + detach=True, + environment=self.env, + ports=self.ports, + name=self._name, + volumes=self.volumes, + **self._kargs + ) + logger.info("") + logger.info("Container started: {}".format(self._container.short_id)) return self def stop(self, force=True, delete_volume=True): diff --git a/testcontainers/core/utils.py b/testcontainers/core/utils.py index 76d0b4b60..fe14d724d 100644 --- a/testcontainers/core/utils.py +++ b/testcontainers/core/utils.py @@ -1,12 +1,22 @@ import os import sys import subprocess +import logging LINUX = "linux" MAC = "mac" WIN = "win" +def setup_logger(name): + logger = logging.getLogger(name) + logger.setLevel(logging.INFO) + handler = logging.StreamHandler() + handler.setLevel(logging.INFO) + logger.addHandler(handler) + return logger + + def os_name(): pl = sys.platform if pl == "linux" or pl == "linux2": diff --git a/testcontainers/core/waiting_utils.py b/testcontainers/core/waiting_utils.py index 1bb48ea3c..1abe76076 100644 --- a/testcontainers/core/waiting_utils.py +++ b/testcontainers/core/waiting_utils.py @@ -15,13 +15,13 @@ import re import time -import blindspin -import crayons import wrapt from testcontainers.core import config from testcontainers.core.exceptions import TimeoutException +from testcontainers.core.utils import setup_logger +logger = setup_logger(__name__) def wait_container_is_ready(): """ @@ -35,20 +35,19 @@ def wait_container_is_ready(): @wrapt.decorator def wrapper(wrapped, instance, args, kwargs): exception = None - print(crayons.yellow("Waiting to be ready...")) - with blindspin.spinner(): - for _ in range(0, config.MAX_TRIES): - try: - return wrapped(*args, **kwargs) - except Exception as e: - time.sleep(config.SLEEP_TIME) - exception = e - raise TimeoutException( - """Wait time exceeded {0} sec. - Method {1}, args {2} , kwargs {3}. - Exception {4}""".format(config.MAX_TRIES, - wrapped.__name__, - args, kwargs, exception)) + logger.info("Waiting to be ready...") + for _ in range(0, config.MAX_TRIES): + try: + return wrapped(*args, **kwargs) + except Exception as e: + time.sleep(config.SLEEP_TIME) + exception = e + raise TimeoutException( + """Wait time exceeded {0} sec. + Method {1}, args {2} , kwargs {3}. + Exception {4}""".format(config.MAX_TRIES, + wrapped.__name__, + args, kwargs, exception)) return wrapper From 7a19c1503ec48a2db55725c0ca10ca238fe1829f Mon Sep 17 00:00:00 2001 From: romnnn Date: Mon, 7 Sep 2020 11:51:43 +0200 Subject: [PATCH 2/3] remove example and lint --- example.py | 7 ------- testcontainers/core/container.py | 1 + testcontainers/core/waiting_utils.py | 1 + 3 files changed, 2 insertions(+), 7 deletions(-) delete mode 100644 example.py diff --git a/example.py b/example.py deleted file mode 100644 index 9b3d38094..000000000 --- a/example.py +++ /dev/null @@ -1,7 +0,0 @@ -import sqlalchemy -from testcontainers.mysql import MySqlContainer - -with MySqlContainer('mysql:5.7.17') as mysql: - engine = sqlalchemy.create_engine(mysql.get_connection_url()) - version, = engine.execute("select version()").fetchone() - print(version) # 5.7.17 diff --git a/testcontainers/core/container.py b/testcontainers/core/container.py index 2d7d85ddc..1254ad862 100644 --- a/testcontainers/core/container.py +++ b/testcontainers/core/container.py @@ -6,6 +6,7 @@ logger = setup_logger(__name__) + class DockerContainer(object): def __init__(self, image, **kargs): self.env = {} diff --git a/testcontainers/core/waiting_utils.py b/testcontainers/core/waiting_utils.py index 1abe76076..9b224d3b4 100644 --- a/testcontainers/core/waiting_utils.py +++ b/testcontainers/core/waiting_utils.py @@ -23,6 +23,7 @@ logger = setup_logger(__name__) + def wait_container_is_ready(): """ Wait until container is ready. From 332f5e2457464e3ca05f8b215571517e12fd2576 Mon Sep 17 00:00:00 2001 From: romnnn Date: Wed, 9 Sep 2020 12:03:00 +0200 Subject: [PATCH 3/3] use standard approach for logging --- testcontainers/core/container.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/testcontainers/core/container.py b/testcontainers/core/container.py index 1254ad862..25645816f 100644 --- a/testcontainers/core/container.py +++ b/testcontainers/core/container.py @@ -38,8 +38,7 @@ def with_kargs(self, **kargs) -> 'DockerContainer': return self def start(self): - logger.info("") - logger.info("{} {}".format("Pulling image", self.image)) + logger.info("Pulling image %s", self.image) docker_client = self.get_docker_client() self._container = docker_client.run(self.image, command=self._command, @@ -50,8 +49,7 @@ def start(self): volumes=self.volumes, **self._kargs ) - logger.info("") - logger.info("Container started: {}".format(self._container.short_id)) + logger.info("Container started: %s", self._container.short_id) return self def stop(self, force=True, delete_volume=True):