Repository: kprestel/pytest-docker-db (language: python)

Issue:
How to pass the postgres user and password ? 
I want the postgres database created with a user and password. How would I do that without a custom docker image ? 


Discussion / hints:
I don't think you would be able to do that without using a custom docker image. At least not currently. 

How would you want to pass the user and password?
so how do you pass a custom docker image? I'm using a dockerfile and it's not working either

I want to send env vars to the run of the docker image - that is the way to pass the username and password

From the README:

`pytest --db-dockerfile=Dockerfile --db-name=test-postgres --db-port=5432 --db-host-port=5434`

Basically pass in a custom Dockerfile with whatever you want baked into it.

Fix patch:
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index 4bdcc6f..f22c51d 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -1,10 +1,10 @@
 repos:
 -   repo: https://github.com/ambv/black
-    rev: stable
+    rev: 20.8b1
     hooks:
     - id: black
-      language_version: python3.6
--   repo: https://github.com/pre-commit/pre-commit-hooks
-    rev: v1.2.3
+      language_version: python3.9
+-   repo: https://gitlab.com/pycqa/flake8 
+    rev: 3.9.0
     hooks:
     - id: flake8
diff --git a/README.rst b/README.rst
index 9d3f6c3..ec38175 100644
--- a/README.rst
+++ b/README.rst
@@ -90,6 +90,11 @@ Configuration
 
     * The directory to use as the docker build context.
 
+* db-docker-env-vars
+
+    * A comma separated list of environment variables to pass to `docker run`
+        * --db-docker-env-vars=FOO=BAR,PASSWORD=BAZ
+
 
 
 Usage
@@ -130,6 +135,11 @@ pytest CLI using a custom image:
 
     $ pytest --db-dockerfile=Dockerfile --db-name=test-postgres --db-port=5432 --db-host-port=5434
 
+pytest CLI using a custom image and passing environment variables to it:
+::
+
+    $ pytest --db-dockerfile=Dockerfile --db-name=test-postgres --db-port=5432 --db-host-port=5434 --db-docker-env-vars=POSTGRES_PASSWORD=FOO,POSTGRES_USER=BAR
+
 Contributing
 ------------
 Contributions are very welcome. Tests can be run with `tox`_, please ensure
diff --git a/requirements-dev.txt b/requirements-dev.txt
deleted file mode 100644
index 42afc7e..0000000
--- a/requirements-dev.txt
+++ /dev/null
@@ -1,62 +0,0 @@
-alabaster==0.7.10
-appdirs==1.4.3
-asciimatics==1.9.0
-aspy.yaml==1.1.1
-atomicwrites==1.2.0
-attrs==17.4.0
-Babel==2.5.3
-black==18.6b4
-bleach==3.3.0
-cached-property==1.4.3
-certifi==2018.1.18
-cfgv==1.1.0
-chardet==3.0.4
-click==6.7
-coverage==4.5.1
-docker==3.1.0
-docker-pycreds==0.2.2
-docutils==0.14
-enum-compat==0.0.2
-eventlet==0.21.0
-future==0.16.0
-greenlet==0.4.13
-html5lib==1.0.1
-identify==1.1.4
-idna==2.6
-imagesize==1.0.0
-Jinja2==2.10
-MarkupSafe==1.0
-more-itertools==4.3.0
-nodeenv==1.3.2
-packaging==16.8
-pathlib2==2.3.0
-Pillow==6.2.0
-pkg-resources==0.0.0
-pkginfo==1.4.2
-pluggy==0.7.1
-pre-commit==1.10.5
-py==1.5.2
-pyfiglet==0.7.5
-Pygments==2.2.0
-pyparsing==2.2.0
-pytest==3.7.2
--e git+git@github.com:kprestel/pytest-docker-db.git@0c427db7f8dd0979592428ea1d5a0dd7a12db70d#egg=pytest_docker_db
-pytz==2018.3
-PyYAML==5.1
-readme-renderer==17.2
-requests==2.20.0
-requests-toolbelt==0.8.0
-retox==1.5.0
-six==1.11.0
-snowballstemmer==1.2.1
-Sphinx==1.7.0
-sphinxcontrib-websupport==1.0.1
-toml==0.9.4
-tox==2.9.1
-tqdm==4.19.5
-twine==1.11.0
-urllib3==1.24.2
-virtualenv==15.1.0
-wcwidth==0.1.7
-webencodings==0.5.1
-websocket-client==0.47.0
diff --git a/tox.ini b/tox.ini
index 5579a99..a436de8 100644
--- a/tox.ini
+++ b/tox.ini
@@ -1,6 +1,6 @@
 # For more information about tox, see https://tox.readthedocs.io/en/latest/
 [tox]
-envlist = py36,py37,flake8
+envlist = py37,py38,py39,flake8
 
 [testenv]
 ;changedir=tests


Test patch:
diff --git a/pytest_docker_db/plugin.py b/pytest_docker_db/plugin.py
index 3098764..d960543 100644
--- a/pytest_docker_db/plugin.py
+++ b/pytest_docker_db/plugin.py
@@ -115,6 +115,24 @@ def pytest_addoption(parser: "Parser"):
 
     parser.addini("db-docker-context", db_docker_context_help, type="args")
 
+    db_docker_env_vars_help = (
+        "Comma separated list of environment variables "
+        "to pass to 'docker run'"
+    )
+
+    parser.addini(
+        "db-docker-env-vars", help=db_docker_env_vars_help, type="args"
+    )
+
+    group.addoption(
+        "--db-docker-env-vars",
+        action="store",
+        default=None,
+        help=db_docker_env_vars_help,
+    )
+
+    parser.addini("db-docker-context", db_docker_context_help, type="args")
+
 
 @pytest.fixture(scope="session")
 def _docker():
@@ -143,24 +161,9 @@ def docker_db(request, _docker: "DockerClient"):
             break
 
     # create the container
-    if container is None:
+    if container is None and opts.db_image is None:
         if opts.docker_file is not None:
-            img_name = f"{opts.db_name}"
-            try:
-                _ = _docker.images.build(  # noqa: F841
-                    path=opts.context,
-                    rm=True,
-                    tag=opts.db_name,
-                    pull=False,
-                    dockerfile=opts.docker_file,
-                )
-            except APIError as e:
-                pytest.fail(
-                    f"Unable to build image at "
-                    f"path: {os.getcwd() + os.sep + opts.docker_file}."
-                    f"\n{e}"
-                )
-            opts.db_image = img_name
+            opts.db_image = _build_image(_docker, opts)
         else:
             try:
                 _docker.images.pull(opts.db_image)
@@ -182,17 +185,37 @@ def docker_db(request, _docker: "DockerClient"):
                 ports={opts.db_port: opts.host_port},
                 detach=True,
                 volumes=opts.volume_args or None,
+                environment=opts.env_vars,
             )
         except APIError as e:
             pytest.fail(f"Unable to create container.\n{e}")
+    elif opts.db_image is not None:
+        try:
+            container = _docker.containers.run(
+                opts.db_image,
+                ports={opts.db_port: opts.host_port},
+                name=opts.db_name,
+                detach=True,
+                volumes=opts.volume_args or None,
+                environment=opts.env_vars,
+                auto_remove=not opts.persist_container,
+            )
+        except APIError as e:
+            pytest.fail(
+                f"Unable to start container: {opts.db_image}, Error: {e}"
+            )
 
-    try:
-        container.start()
-    except APIError as e:
-        # TODO: make this smart and kill a container that is already running on the port # noqa
-        pytest.fail(
-            f'Unable to start container with ID: {container["Id"]}. ' f"\n{e}"
-        )
+    if container is None:
+        pytest.fail("Could not create container")
+
+    if container.status != "running":
+        try:
+            container.start()
+        except APIError as e:
+            # TODO: make this smart and kill a container that is already running on the port # noqa
+            pytest.fail(
+                f"Unable to start container with ID: {container}. " f"\n{e}"
+            )
 
     yield container
 
@@ -200,6 +223,25 @@ def docker_db(request, _docker: "DockerClient"):
         _kill_rm_container(container.id, _docker)
 
 
+def _build_image(_docker, opts):
+    img_name = f"{opts.db_name}"
+    try:
+        _ = _docker.images.build(  # noqa: F841
+            path=opts.context,
+            rm=True,
+            tag=opts.db_name,
+            pull=False,
+            dockerfile=opts.docker_file,
+        )
+    except APIError as e:
+        pytest.fail(
+            f"Unable to build image at "
+            f"path: {os.getcwd() + os.sep + opts.docker_file}."
+            f"\n{e}"
+        )
+    return img_name
+
+
 def _kill_rm_container(container_id: str, _docker: "DockerClient") -> None:
     """
     Kills and removes the container.
@@ -259,6 +301,7 @@ def __init__(self, request):
         self._volume_args = self._get_config_val("db-volume-args", request)
         self._docker_file = self._get_config_val("db-dockerfile", request)
         self._context = self._get_config_val("db-docker-context", request)
+        self._env_vars = self._get_config_val("db-docker-env-vars", request)
 
         self._validate()
 
@@ -361,6 +404,13 @@ def volume_args(self) -> Optional[List[str]]:
             else:
                 return [self._volume_args]
 
+    @property
+    def env_vars(self) -> Optional[List[str]]:
+        if self._env_vars:
+            return self._env_vars.split(",")
+        else:
+            return None
+
     @staticmethod
     def _find_unused_port():
         with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
diff --git a/test-docker/Dockerfile b/test-docker/Dockerfile
index 7f02499..e2cdf41 100644
--- a/test-docker/Dockerfile
+++ b/test-docker/Dockerfile
@@ -2,4 +2,5 @@ FROM postgres:alpine
 COPY create-user.sh /docker-entrypoint-initdb.d/create-user.sh
 RUN chmod +x /docker-entrypoint-initdb.d/create-user.sh
 
+EXPOSE 5432
 CMD ["postgres"]
diff --git a/tests/test_docker_db.py b/tests/test_docker_db.py
index 677889e..6318324 100644
--- a/tests/test_docker_db.py
+++ b/tests/test_docker_db.py
@@ -55,10 +55,6 @@ def test_bad_container(docker_db):
         "-v",
     )
 
-    result.stdout.fnmatch_lines(
-        ["*Unable to pull image: not-an-image:latest*"]
-    )
-
     assert result.ret == 1
 
 
@@ -112,22 +108,26 @@ def test_container(docker_db, _docker):
     )
 
 
-def test_postgres_options(testdir: "Testdir"):
+def test_postgres_options(testdir: "Testdir", tmpdir):
     """
     Ensure that the container gets set up properly with
     different options.
     """
     db_name = "test-postgres-2"
     host_port = "5434"
-    _make_postgres_pyfile(testdir, host_port=host_port, container_name=db_name)
+    vol = str(tmpdir)
+    _make_postgres_pyfile(
+        testdir, host_port=host_port, container_name=db_name, volume=vol
+    )
 
     result = testdir.runpytest(
-        "--db-volume-args=/tmp/docker:/var/lib/postgresql/data:rw",
+        f"--db-volume-args={vol}:/var/lib/postgresql/data:rw",
         "--db-image=postgres:latest",
         f"--db-name={db_name}",
         "--db-port=5432",
         f"--db-host-port={host_port}",
         "--db-persist-container",
+        "--db-docker-env-vars=POSTGRES_PASSWORD='FOO',POSTGRES_USER=postgres",
         "-v",
     )