From 55267cb716410e05a55463e761c9a0ebd881a556 Mon Sep 17 00:00:00 2001 From: Till Hoffmann Date: Wed, 9 Sep 2020 14:15:28 +0100 Subject: [PATCH 1/6] Mark redundant classes and methods as deprecated. --- testcontainers/core/container.py | 18 ++++++++++++++---- testcontainers/core/generic.py | 2 +- testcontainers/elasticsearch.py | 4 +++- testcontainers/general.py | 2 +- testcontainers/mysql.py | 2 ++ testcontainers/nginx.py | 6 ++++-- tests/test_db_containers.py | 11 +++++------ tests/test_elasticsearch.py | 5 ++--- tests/test_new_docker_api.py | 4 ++-- 9 files changed, 34 insertions(+), 20 deletions(-) diff --git a/testcontainers/core/container.py b/testcontainers/core/container.py index 25645816f..cfdf030ac 100644 --- a/testcontainers/core/container.py +++ b/testcontainers/core/container.py @@ -1,3 +1,9 @@ +<<<<<<< HEAD +======= +import blindspin +import crayons +from deprecation import deprecated +>>>>>>> Mark redundant classes and methods as deprecated. from docker.models.containers import Container from testcontainers.core.docker_client import DockerClient @@ -8,7 +14,7 @@ class DockerContainer(object): - def __init__(self, image, **kargs): + def __init__(self, image, **kwargs): self.env = {} self.ports = {} self.volumes = {} @@ -17,7 +23,7 @@ def __init__(self, image, **kargs): self._container = None self._command = None self._name = None - self._kargs = kargs + self._kwargs = kwargs def with_env(self, key: str, value: str) -> 'DockerContainer': self.env[key] = value @@ -33,8 +39,12 @@ def with_exposed_ports(self, *ports) -> 'DockerContainer': self.ports[port] = None return self + @deprecated(details='use `with_kwargs` instead') def with_kargs(self, **kargs) -> 'DockerContainer': - self._kargs = kargs + return self.with_kwargs(**kargs) + + def with_kwargs(self, **kwargs) -> 'DockerContainer': + self._kwargs = kwargs return self def start(self): @@ -47,7 +57,7 @@ def start(self): ports=self.ports, name=self._name, volumes=self.volumes, - **self._kargs + **self._kwargs ) logger.info("Container started: %s", self._container.short_id) return self diff --git a/testcontainers/core/generic.py b/testcontainers/core/generic.py index e82e17485..93fd801b4 100644 --- a/testcontainers/core/generic.py +++ b/testcontainers/core/generic.py @@ -51,7 +51,7 @@ def _configure(self): raise NotImplementedError +@deprecated(details="Use `DockerContainer`.") class GenericContainer(DockerContainer): - @deprecated(details="use plain DockerContainer instead") def __init__(self, image): super(GenericContainer, self).__init__(image) diff --git a/testcontainers/elasticsearch.py b/testcontainers/elasticsearch.py index cf587f08b..692b90d2b 100644 --- a/testcontainers/elasticsearch.py +++ b/testcontainers/elasticsearch.py @@ -10,6 +10,7 @@ # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. +from deprecation import deprecated from testcontainers.core.container import DockerContainer from testcontainers.core.waiting_utils import wait_container_is_ready import urllib @@ -51,4 +52,5 @@ def start(self): return self -ElasticsearchContainer = ElasticSearchContainer +ElasticsearchContainer = deprecated(details='Use `ElasticSearchContainer` with a capital S instead ' + 'of `ElasticsearchContainer`.')(ElasticSearchContainer) diff --git a/testcontainers/general.py b/testcontainers/general.py index 1174db23b..623a6cc63 100644 --- a/testcontainers/general.py +++ b/testcontainers/general.py @@ -14,8 +14,8 @@ from testcontainers.core.container import DockerContainer +@deprecated(details="Use `DockerContainer`.") class TestContainer(DockerContainer): - @deprecated(details="use plain DockerContainer instead") def __init__(self, image, port_to_expose=None): super(TestContainer, self).__init__(image) if port_to_expose: diff --git a/testcontainers/mysql.py b/testcontainers/mysql.py index 8f303fb89..943e725bb 100644 --- a/testcontainers/mysql.py +++ b/testcontainers/mysql.py @@ -10,6 +10,7 @@ # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. +from deprecation import deprecated from os import environ from testcontainers.core.generic import DbContainer @@ -69,6 +70,7 @@ def get_connection_url(self): port=self.port_to_expose) +@deprecated(details="Use `MySqlContainer` with 'mariadb:latest' image.") class MariaDbContainer(MySqlContainer): """ Maria database container, a commercially-supported fork of MySql. diff --git a/testcontainers/nginx.py b/testcontainers/nginx.py index 402af47a6..f2134046d 100644 --- a/testcontainers/nginx.py +++ b/testcontainers/nginx.py @@ -10,10 +10,12 @@ # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. -from testcontainers.core.generic import GenericContainer +from deprecation import deprecated +from testcontainers.core.container import DockerContainer -class NginxContainer(GenericContainer): +@deprecated(details="Use `DockerContainer` with 'nginx:latest' image and expose port 80.") +class NginxContainer(DockerContainer): def __init__(self, image="nginx:latest", port_to_expose=80): super(NginxContainer, self).__init__(image) self.port_to_expose = port_to_expose diff --git a/tests/test_db_containers.py b/tests/test_db_containers.py index c9c6242db..4d4ece7b4 100644 --- a/tests/test_db_containers.py +++ b/tests/test_db_containers.py @@ -3,11 +3,11 @@ from pymongo import MongoClient from pymongo.errors import OperationFailure -from testcontainers.core.generic import GenericContainer +from testcontainers.core.container import DockerContainer from testcontainers.core.waiting_utils import wait_for from testcontainers.mongodb import MongoDbContainer from testcontainers.mssql import SqlServerContainer -from testcontainers.mysql import MySqlContainer, MariaDbContainer +from testcontainers.mysql import MySqlContainer from testcontainers.neo4j import Neo4jContainer from testcontainers.oracle import OracleDbContainer from testcontainers.postgres import PostgresContainer @@ -32,7 +32,7 @@ def test_docker_run_postgress(): def test_docker_run_mariadb(): - mariadb_container = MariaDbContainer("mariadb:10.2.9") + mariadb_container = MySqlContainer("mariadb:10.2.9") with mariadb_container as mariadb: e = sqlalchemy.create_engine(mariadb.get_connection_url()) result = e.execute("select version()") @@ -76,8 +76,7 @@ def test_docker_run_mongodb(): def test_docker_run_mongodb_connect_without_credentials(): - mongo_container = MongoDbContainer() - with mongo_container as mongo: + with MongoDbContainer() as mongo: connection_url = "mongodb://{}:{}".format(mongo.get_container_host_ip(), mongo.get_exposed_port(mongo.port_to_expose)) db = MongoClient(connection_url).test @@ -120,7 +119,7 @@ def test_docker_run_neo4j_latest(): def test_docker_generic_db(): - mongo_container = GenericContainer("mongo:latest") + mongo_container = DockerContainer("mongo:latest") mongo_container.with_bind_ports(27017, 27017) with mongo_container: diff --git a/tests/test_elasticsearch.py b/tests/test_elasticsearch.py index 31e9b948e..d4734ad6a 100644 --- a/tests/test_elasticsearch.py +++ b/tests/test_elasticsearch.py @@ -1,11 +1,10 @@ import json import urllib -from testcontainers.elasticsearch import ElasticsearchContainer +from testcontainers.elasticsearch import ElasticSearchContainer def test_docker_run_elasticsearch(): - config = ElasticsearchContainer() - with config as es: + with ElasticSearchContainer() as es: resp = urllib.request.urlopen(es.get_url()) assert json.loads(resp.read().decode())['version']['number'] == '7.5.0' diff --git a/tests/test_new_docker_api.py b/tests/test_new_docker_api.py index e1ce91058..69b5ba950 100644 --- a/tests/test_new_docker_api.py +++ b/tests/test_new_docker_api.py @@ -34,7 +34,7 @@ def test_docker_env_variables(): assert re.match(pattern, url) -def test_docker_kargs(): +def test_docker_kwargs(): code_dir = Path(__file__).parent container_first = GenericContainer("nginx:latest") container_first.with_volume_mapping(code_dir, '/code') @@ -42,7 +42,7 @@ def test_docker_kargs(): container_second = GenericContainer("nginx:latest") with container_first: - container_second.with_kargs(volumes_from=[container_first._container.short_id]) + container_second.with_kwargs(volumes_from=[container_first._container.short_id]) with container_second: files_first = container_first.exec('ls /code').output.decode('utf-8').strip() files_second = container_second.exec('ls /code').output.decode('utf-8').strip() From aa989c853bb945623fa400922cc95c79a2fc17e9 Mon Sep 17 00:00:00 2001 From: Till Hoffmann Date: Wed, 9 Sep 2020 14:21:40 +0100 Subject: [PATCH 2/6] Remove inheritance from deprecated container. --- testcontainers/google/pubsub.py | 4 ++-- tests/test_new_docker_api.py | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/testcontainers/google/pubsub.py b/testcontainers/google/pubsub.py index f6471de9c..2615faf6a 100644 --- a/testcontainers/google/pubsub.py +++ b/testcontainers/google/pubsub.py @@ -11,10 +11,10 @@ # License for the specific language governing permissions and limitations # under the License. -from ..core.generic import GenericContainer +from ..core.container import DockerContainer -class PubSubContainer(GenericContainer): +class PubSubContainer(DockerContainer): """ PubSub container for testing managed message queues. diff --git a/tests/test_new_docker_api.py b/tests/test_new_docker_api.py index 69b5ba950..c1d4677ac 100644 --- a/tests/test_new_docker_api.py +++ b/tests/test_new_docker_api.py @@ -4,7 +4,7 @@ from testcontainers import mysql -from testcontainers.core.generic import GenericContainer +from testcontainers.core.container import DockerContainer from importlib import reload @@ -14,7 +14,7 @@ def setup_module(m): def test_docker_custom_image(): - container = GenericContainer("mysql:5.7.17") + container = DockerContainer("mysql:5.7.17") container.with_exposed_ports(3306) container.with_env("MYSQL_ROOT_PASSWORD", "root") @@ -36,10 +36,10 @@ def test_docker_env_variables(): def test_docker_kwargs(): code_dir = Path(__file__).parent - container_first = GenericContainer("nginx:latest") + container_first = DockerContainer("nginx:latest") container_first.with_volume_mapping(code_dir, '/code') - container_second = GenericContainer("nginx:latest") + container_second = DockerContainer("nginx:latest") with container_first: container_second.with_kwargs(volumes_from=[container_first._container.short_id]) From 45011f8dd35b16273c361a703f108c0b0bd66f61 Mon Sep 17 00:00:00 2001 From: Till Hoffmann Date: Wed, 9 Sep 2020 14:32:16 +0100 Subject: [PATCH 3/6] Simplify deprecation message. --- testcontainers/core/container.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/testcontainers/core/container.py b/testcontainers/core/container.py index cfdf030ac..2d9100374 100644 --- a/testcontainers/core/container.py +++ b/testcontainers/core/container.py @@ -39,7 +39,7 @@ def with_exposed_ports(self, *ports) -> 'DockerContainer': self.ports[port] = None return self - @deprecated(details='use `with_kwargs` instead') + @deprecated(details='Use `with_kwargs`.') def with_kargs(self, **kargs) -> 'DockerContainer': return self.with_kwargs(**kargs) From 26cf7783bb78861b3ecb975f4067664cc79f0eba Mon Sep 17 00:00:00 2001 From: Till Hoffmann Date: Wed, 9 Sep 2020 15:01:01 +0100 Subject: [PATCH 4/6] Resolve merge conflict. --- testcontainers/core/container.py | 5 ----- 1 file changed, 5 deletions(-) diff --git a/testcontainers/core/container.py b/testcontainers/core/container.py index 2d9100374..0ca126ca6 100644 --- a/testcontainers/core/container.py +++ b/testcontainers/core/container.py @@ -1,9 +1,4 @@ -<<<<<<< HEAD -======= -import blindspin -import crayons from deprecation import deprecated ->>>>>>> Mark redundant classes and methods as deprecated. from docker.models.containers import Container from testcontainers.core.docker_client import DockerClient From 2f9d23be198644d11974072e127998ac1dcaf1ac Mon Sep 17 00:00:00 2001 From: Till Hoffmann Date: Wed, 9 Sep 2020 15:28:24 +0100 Subject: [PATCH 5/6] Fix inheritance with deprecation decorator. --- testcontainers/nginx.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/testcontainers/nginx.py b/testcontainers/nginx.py index f2134046d..79d86e044 100644 --- a/testcontainers/nginx.py +++ b/testcontainers/nginx.py @@ -17,6 +17,6 @@ @deprecated(details="Use `DockerContainer` with 'nginx:latest' image and expose port 80.") class NginxContainer(DockerContainer): def __init__(self, image="nginx:latest", port_to_expose=80): - super(NginxContainer, self).__init__(image) + super().__init__(image) self.port_to_expose = port_to_expose self.with_exposed_ports(self.port_to_expose) From d8da3d96e3a479d86aaf7337e9d13ca3fbc9d163 Mon Sep 17 00:00:00 2001 From: Till Hoffmann Date: Thu, 10 Sep 2020 11:52:51 +0100 Subject: [PATCH 6/6] Move deprecation decorator to __init__. --- testcontainers/core/generic.py | 2 +- testcontainers/general.py | 2 +- testcontainers/mysql.py | 2 +- testcontainers/nginx.py | 4 ++-- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/testcontainers/core/generic.py b/testcontainers/core/generic.py index 93fd801b4..1cce71afd 100644 --- a/testcontainers/core/generic.py +++ b/testcontainers/core/generic.py @@ -51,7 +51,7 @@ def _configure(self): raise NotImplementedError -@deprecated(details="Use `DockerContainer`.") class GenericContainer(DockerContainer): + @deprecated(details="Use `DockerContainer`.") def __init__(self, image): super(GenericContainer, self).__init__(image) diff --git a/testcontainers/general.py b/testcontainers/general.py index 623a6cc63..04452655f 100644 --- a/testcontainers/general.py +++ b/testcontainers/general.py @@ -14,8 +14,8 @@ from testcontainers.core.container import DockerContainer -@deprecated(details="Use `DockerContainer`.") class TestContainer(DockerContainer): + @deprecated(details="Use `DockerContainer`.") def __init__(self, image, port_to_expose=None): super(TestContainer, self).__init__(image) if port_to_expose: diff --git a/testcontainers/mysql.py b/testcontainers/mysql.py index 943e725bb..6f1a507c2 100644 --- a/testcontainers/mysql.py +++ b/testcontainers/mysql.py @@ -70,7 +70,6 @@ def get_connection_url(self): port=self.port_to_expose) -@deprecated(details="Use `MySqlContainer` with 'mariadb:latest' image.") class MariaDbContainer(MySqlContainer): """ Maria database container, a commercially-supported fork of MySql. @@ -83,5 +82,6 @@ class MariaDbContainer(MySqlContainer): e = sqlalchemy.create_engine(mariadb.get_connection_url()) result = e.execute("select version()") """ + @deprecated(details="Use `MySqlContainer` with 'mariadb:latest' image.") def __init__(self, image="mariadb:latest", **kwargs): super(MariaDbContainer, self).__init__(image, **kwargs) diff --git a/testcontainers/nginx.py b/testcontainers/nginx.py index 79d86e044..c0c3a4e15 100644 --- a/testcontainers/nginx.py +++ b/testcontainers/nginx.py @@ -14,9 +14,9 @@ from testcontainers.core.container import DockerContainer -@deprecated(details="Use `DockerContainer` with 'nginx:latest' image and expose port 80.") class NginxContainer(DockerContainer): + @deprecated(details="Use `DockerContainer` with 'nginx:latest' image and expose port 80.") def __init__(self, image="nginx:latest", port_to_expose=80): - super().__init__(image) + super(NginxContainer, self).__init__(image) self.port_to_expose = port_to_expose self.with_exposed_ports(self.port_to_expose)